OSDN Git Service

4bf0f97ac0793a369cc8fc285105e05d01cff56a
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc8201 / lcd.cpp
1 /*
2         NEC PC-8201 Emulator 'ePC-8201'
3
4         Author : Takeda.Toshiya
5         Date   : 2009.04.01-
6
7         [ lcd ]
8 */
9
10 #include "lcd.h"
11
12 void LCD::initialize()
13 {
14         memset(seg, 0, sizeof(seg));
15         sel = 0;
16 }
17
18 void LCD::write_io8(uint32_t addr, uint32_t data)
19 {
20         if(addr & 1) {
21                 // data
22                 for(int b = 0; b < 10; b++) {
23                         if(sel & (1 << b)) {
24                                 seg[b].vram[seg[b].page][seg[b].ofs] = data;
25 //                              seg[b].ofs2 = seg[b].ofs;
26                                 if(!seg[b].updown) {
27                                         if(++seg[b].ofs > 49) {
28                                                 seg[b].ofs = 0;
29                                         }
30                                 } else {
31                                         if(--seg[b].ofs < 0) {
32                                                 seg[b].ofs = 49;
33                                         }
34                                 }
35                         }
36                 }
37         } else {
38                 for(int b = 0; b < 10; b++) {
39                         if(sel & (1 << b)) {
40                                 // command
41                                 switch(data) {
42                                 case 0x32:
43                                 case 0x33:
44                                         seg[b].updown = data & 1;
45                                         break;
46                                 case 0x38:
47                                 case 0x39:
48                                         seg[b].disp = data & 1;
49                                         break;
50                                 case 0x3a:
51                                 case 0x3b:
52                                         seg[b].updown = (data ^ 1) & 1;
53                                         break;
54                                 case 0x3e:
55                                 case 0x3f:
56                                 case 0x7e:
57                                 case 0x7f:
58                                 case 0xbe:
59                                 case 0xbf:
60                                 case 0xfe:
61                                 case 0xff:
62                                         seg[b].spg = data >> 6;
63                                         break;
64                                 default:
65                                         seg[b].page = data >> 6;
66                                         seg[b].ofs = data & 0x3f;
67                                         if(seg[b].ofs > 49) {
68                                                 seg[b].ofs = 49;
69                                         }
70                                         break;
71                                 }
72                         }
73                 }
74         }
75 }
76
77 uint32_t LCD::read_io8(uint32_t addr)
78 {
79         uint8_t val = 0xff;
80         
81         if(addr & 1) {
82                 // data
83                 for(int b = 0; b < 10; b++) {
84                         if(sel & (1 << b)) {
85                                 val &= seg[b].vram[seg[b].page][seg[b].ofs2];
86                                 seg[b].ofs2 = seg[b].ofs;
87                                 if(!seg[b].updown) {
88                                         if(++seg[b].ofs > 49) {
89                                                 seg[b].ofs = 0;
90                                         }
91                                 } else {
92                                         if(--seg[b].ofs < 0) {
93                                                 seg[b].ofs = 49;
94                                         }
95                                 }
96                         }
97                 }
98         } else {
99                 // status
100                 for(int b = 0; b < 10; b++) {
101                         if(sel & (1 << b)) {
102                                 val &= (seg[b].updown ? 0x40 : 0) | (seg[b].disp ? 0x20 : 0) | 0xf;
103                         }
104                 }
105         }
106         return val;
107 }
108
109 void LCD::write_signal(int id, uint32_t data, uint32_t mask)
110 {
111         if(id == SIG_LCD_CHIPSEL_L) {
112                 sel = (sel & 0x300) | (data);
113         } else if(id == SIG_LCD_CHIPSEL_H) {
114                 sel = (sel & 0xff) | ((data & 3) << 8);
115         }
116 }
117
118 void LCD::draw_screen()
119 {
120         // render screen
121         memset(screen, 0, sizeof(screen));
122         for(int b = 0; b < 10; b++) {
123                 if(seg[b].disp) {
124                         int xofs = (b % 5) * 50;
125                         for(int p = 0; p < 4; p++) {
126                                 uint8_t* src = seg[b].vram[(seg[b].spg + p) & 3];
127                                 int yofs = (b < 5 ? 0 : 32) + p * 8;
128                                 uint8_t* dst0 = &screen[yofs + 0][xofs];
129                                 uint8_t* dst1 = &screen[yofs + 1][xofs];
130                                 uint8_t* dst2 = &screen[yofs + 2][xofs];
131                                 uint8_t* dst3 = &screen[yofs + 3][xofs];
132                                 uint8_t* dst4 = &screen[yofs + 4][xofs];
133                                 uint8_t* dst5 = &screen[yofs + 5][xofs];
134                                 uint8_t* dst6 = &screen[yofs + 6][xofs];
135                                 uint8_t* dst7 = &screen[yofs + 7][xofs];
136                                 for(int i = 0; i < 50; i++) {
137                                         uint8_t pat = src[i];
138                                         dst0[i] = pat & 0x01;
139                                         dst1[i] = pat & 0x02;
140                                         dst2[i] = pat & 0x04;
141                                         dst3[i] = pat & 0x08;
142                                         dst4[i] = pat & 0x10;
143                                         dst5[i] = pat & 0x20;
144                                         dst6[i] = pat & 0x40;
145                                         dst7[i] = pat & 0x80;
146                                 }
147                         }
148                 }
149         }
150         
151         // copy to real screen
152         scrntype_t cd = RGB_COLOR(48, 56, 16);
153         scrntype_t cb = RGB_COLOR(160, 168, 160);
154         for(int y = 0; y < 64; y++) {
155                 scrntype_t* dst = emu->get_screen_buffer(y);
156                 uint8_t* src = screen[y];
157                 
158                 for(int x = 0; x < 240; x++) {
159                         dst[x] = src[x] ? cd : cb;
160                 }
161         }
162 }
163
164 #define STATE_VERSION   1
165
166 bool LCD::process_state(FILEIO* state_fio, bool loading)
167 {
168         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
169                 return false;
170         }
171         if(!state_fio->StateCheckInt32(this_device_id)) {
172                 return false;
173         }
174         //state_fio->StateBuffer(seg, sizeof(seg), 1);
175         for(int i = 0; i < 10; i++) {
176                 state_fio->StateBuffer(&(seg[i].vram[0][0]), sizeof(seg[i].vram), 1);
177                 state_fio->StateInt32(seg[i].updown);
178                 state_fio->StateInt32(seg[i].disp);
179                 state_fio->StateInt32(seg[i].spg);
180                 state_fio->StateInt32(seg[i].page);
181                 state_fio->StateInt32(seg[i].ofs);
182                 state_fio->StateInt32(seg[i].ofs2);
183         }               
184         state_fio->StateUint16(sel);
185         return true;
186 }