OSDN Git Service

b766c30116cae4c2525c7ec642765a015ca637c9
[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 #include "../../statesub.h"
167
168 void LCD::decl_state()
169 {
170         enter_decl_state(STATE_VERSION);
171
172         for(int i = 0; i < 10; i++) {
173                 DECL_STATE_ENTRY_2D_ARRAY_MEMBER((seg[i].vram), 4, 50, i);
174                 DECL_STATE_ENTRY_INT32_MEMBER((seg[i].updown), i);
175                 DECL_STATE_ENTRY_INT32_MEMBER((seg[i].disp), i);
176                 DECL_STATE_ENTRY_INT32_MEMBER((seg[i].spg), i);
177                 DECL_STATE_ENTRY_INT32_MEMBER((seg[i].page), i);
178                 DECL_STATE_ENTRY_INT32_MEMBER((seg[i].ofs), i);
179                 DECL_STATE_ENTRY_INT32_MEMBER((seg[i].ofs2), i);
180         }
181         DECL_STATE_ENTRY_UINT16(sel);
182
183         leave_decl_state();
184 }
185
186 void LCD::save_state(FILEIO* state_fio)
187 {
188         if(state_entry != NULL) {
189                 state_entry->save_state(state_fio);
190         }
191 //      state_fio->FputUint32(STATE_VERSION);
192 //      state_fio->FputInt32(this_device_id);
193 //      
194 //      state_fio->Fwrite(seg, sizeof(seg), 1);
195 //      state_fio->FputUint16(sel);
196 }
197
198 bool LCD::load_state(FILEIO* state_fio)
199 {
200         bool mb = false;
201         if(state_entry != NULL) {
202                 mb = state_entry->load_state(state_fio);
203         }
204         if(!mb) {
205                 return false;
206         }
207 //      if(state_fio->FgetUint32() != STATE_VERSION) {
208 //              return false;
209 //      }
210 //      if(state_fio->FgetInt32() != this_device_id) {
211 //              return false;
212 //      }
213 //      state_fio->Fread(seg, sizeof(seg), 1);
214 //      sel = state_fio->FgetUint16();
215         return true;
216 }
217
218 bool LCD::process_state(FILEIO* state_fio, bool loading)
219 {
220         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
221                 return false;
222         }
223         if(!state_fio->StateCheckInt32(this_device_id)) {
224                 return false;
225         }
226         state_fio->StateBuffer(seg, sizeof(seg), 1);
227         state_fio->StateUint16(sel);
228         return true;
229 }