OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc100 / crtc.cpp
1 /*
2         NEC PC-100 Emulator 'ePC-100'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.07.14 -
6
7         [ crtc ]
8 */
9
10 #include "crtc.h"
11 #include "../i8259.h"
12
13 namespace PC100 {
14
15 void CRTC::initialize()
16 {
17         // init vram
18         memset(vram, 0, sizeof(vram));
19         
20         // init bit control
21         shift = 0;
22         maskl = maskh = busl = bush = 0;
23         
24         // init vram plane
25         write_plane = 1;
26         read_plane = 0;
27         
28         // init pallete
29         for(int i = 1; i < 16; i++) {
30                 palette[i] = 0x1ff;
31                 update_palette(i);
32         }
33         palette[0] = 0;
34         update_palette(0);
35         
36         // register event
37         register_vline_event(this);
38 }
39
40 void CRTC::event_vline(int v, int clock)
41 {
42         if(v == 512) {
43                 d_pic->write_signal(SIG_I8259_IR4, 1, 1);
44         }
45 }
46
47 void CRTC::write_io8(uint32_t addr, uint32_t data)
48 {
49         switch(addr & 0xff) {
50         case 0x30:
51                 shift = data & 0x0f;
52                 break;
53         case 0x38:
54                 sel = data;
55                 break;
56         case 0x3a:
57                 regs[sel & 7] = data;
58                 break;
59         case 0x3c:
60                 vs = (vs & 0xff00) | data;
61                 break;
62         case 0x3e:
63                 vs = (vs & 0xff) | (data << 8);
64                 break;
65         case 0x40:
66         case 0x42:
67         case 0x44:
68         case 0x46:
69         case 0x48:
70         case 0x4a:
71         case 0x4c:
72         case 0x4e:
73         case 0x50:
74         case 0x52:
75         case 0x54:
76         case 0x56:
77         case 0x58:
78         case 0x5a:
79         case 0x5c:
80         case 0x5e:
81                 palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff00) | data;
82                 update_palette((addr >> 1) & 0x0f);
83                 break;
84         case 0x41:
85         case 0x43:
86         case 0x45:
87         case 0x47:
88         case 0x49:
89         case 0x4b:
90         case 0x4d:
91         case 0x4f:
92         case 0x51:
93         case 0x53:
94         case 0x55:
95         case 0x57:
96         case 0x59:
97         case 0x5b:
98         case 0x5d:
99         case 0x5f:
100                 palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff) | (data << 8);
101                 update_palette((addr >> 1) & 0x0f);
102                 break;
103         case 0x60:
104                 cmd = (cmd & 0xff00) | data;
105                 break;
106         case 0x61:
107                 cmd = (cmd & 0xff) | (data << 8);
108                 break;
109         }
110 }
111
112 uint32_t CRTC::read_io8(uint32_t addr)
113 {
114         uint32_t val = 0xff;
115         
116         switch(addr & 0x3ff) {
117         case 0x30:
118                 return shift;
119         case 0x38:
120                 return sel;
121         case 0x3a:
122                 return regs[sel & 7];
123         case 0x3c:
124                 return vs & 0xff;
125         case 0x3e:
126                 return vs >> 8;
127         case 0x40:
128         case 0x42:
129         case 0x44:
130         case 0x46:
131         case 0x48:
132         case 0x4a:
133         case 0x4c:
134         case 0x4e:
135         case 0x50:
136         case 0x52:
137         case 0x54:
138         case 0x56:
139         case 0x58:
140         case 0x5a:
141         case 0x5c:
142         case 0x5e:
143                 return palette[(addr >> 1) & 0x0f] & 0xff;
144         case 0x41:
145         case 0x43:
146         case 0x45:
147         case 0x47:
148         case 0x49:
149         case 0x4b:
150         case 0x4d:
151         case 0x4f:
152         case 0x51:
153         case 0x53:
154         case 0x55:
155         case 0x57:
156         case 0x59:
157         case 0x5b:
158         case 0x5d:
159         case 0x5f:
160                 return palette[(addr >> 1) & 0x0f] >> 8;
161         case 0x60:
162                 return cmd & 0xff;
163         case 0x61:
164                 return cmd >> 8;
165         }
166         return 0xff;
167 }
168
169 void CRTC::write_memory_mapped_io8(uint32_t addr, uint32_t data)
170 {
171         if(addr & 1) {
172                 bush = data;
173         } else {
174                 busl = data;
175         }
176         uint32_t bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
177         bus >>= shift;
178         
179         if(addr & 1) {
180                 uint32_t h = (bus >> 8) & 0xff;
181                 for(int pl = 0; pl < 4; pl++) {
182                         if(write_plane & (1 << pl)) {
183                                 int ofsh = (addr & 0x1ffff) | (0x20000 * pl);
184                                 vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
185                         }
186                 }
187         } else {
188                 uint32_t l = bus & 0xff;
189                 for(int pl = 0; pl < 4; pl++) {
190                         if(write_plane & (1 << pl)) {
191                                 int ofsl = (addr & 0x1ffff) | (0x20000 * pl);
192                                 vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
193                         }
194                 }
195         }
196 }
197
198 uint32_t CRTC::read_memory_mapped_io8(uint32_t addr)
199 {
200         return vram[(addr & 0x1ffff) | (0x20000 * read_plane)];
201 }
202
203 void CRTC::write_memory_mapped_io16(uint32_t addr, uint32_t data)
204 {
205         busl = (addr & 1) ? (data >> 8) : (data & 0xff);
206         bush = (addr & 1) ? (data & 0xff) : (data >> 8);
207         uint32_t bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
208         bus >>= shift;
209         uint32_t l = bus & 0xff;
210         uint32_t h = (bus >> 8) & 0xff;
211         
212         for(int pl = 0; pl < 4; pl++) {
213                 if(write_plane & (1 << pl)) {
214                         int ofsl = ((addr & 1 ? (addr + 1) : addr) & 0x1ffff) | (0x20000 * pl);
215                         int ofsh = ((addr & 1 ? addr : (addr + 1)) & 0x1ffff) | (0x20000 * pl);
216                         vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
217                         vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
218                 }
219         }
220 }
221
222 uint32_t CRTC::read_memory_mapped_io16(uint32_t addr)
223 {
224         uint32_t val = read_memory_mapped_io8(addr);
225         val |= read_memory_mapped_io8(addr + 1) << 8;
226         return val;
227 }
228
229 void CRTC::write_signal(int id, uint32_t data, uint32_t mask)
230 {
231         if(id == SIG_CRTC_BITMASK_LOW) {
232                 // $18: 8255 PA
233                 maskl = data & 0xff;
234         } else if(id == SIG_CRTC_BITMASK_HIGH) {
235                 // $1A: 8255 PB
236                 maskh = data & 0xff;
237         } else if(id == SIG_CRTC_VRAM_PLANE) {
238                 // $1C: 8255 PC
239                 write_plane = data & 0x0f;
240                 read_plane = (data >> 4) & 3;
241         }
242 }
243
244 void CRTC::draw_screen()
245 {
246         // display region
247         int hd = (regs[2] >> 1) & 0x3f;
248         int vd = (regs[6] >> 1) & 0x3f;
249         int hs = (int)(int8_t)((regs[0] & 0x40) ? (regs[0] | 0x80) : (regs[0] & 0x3f));
250 //      int hs = (int)(int8_t)regs[0];
251         int vs_tmp = (int)(int16_t)((vs & 0x400) ? (vs | 0xf800) : (vs & 0x3ff));
252         int sa = (hs + hd + 1) * 2 + (vs_tmp + vd) * 0x80;
253 //      int sa = (hs + hd + 1) * 2 + ((vs & 0x3ff) + vd) * 0x80;
254         
255         if(cmd != 0xffff) {
256                 // mono
257                 scrntype_t col = RGB_COLOR(255, 255, 255);
258                 for(int y = 0; y < 512; y++) {
259                         int ptr = sa & 0x1ffff;
260                         sa += 0x80;
261                         scrntype_t *dest = emu->get_screen_buffer(y);
262                         
263                         for(int x = 0; x < 720; x += 8) {
264                                 uint8_t pat = vram[ptr];
265                                 ptr = (ptr + 1) & 0x1ffff;
266                                 
267                                 dest[x + 0] = pat & 0x01 ? col : 0;
268                                 dest[x + 1] = pat & 0x02 ? col : 0;
269                                 dest[x + 2] = pat & 0x04 ? col : 0;
270                                 dest[x + 3] = pat & 0x08 ? col : 0;
271                                 dest[x + 4] = pat & 0x10 ? col : 0;
272                                 dest[x + 5] = pat & 0x20 ? col : 0;
273                                 dest[x + 6] = pat & 0x40 ? col : 0;
274                                 dest[x + 7] = pat & 0x80 ? col : 0;
275                         }
276                 }
277         } else {
278                 // color
279                 for(int y = 0; y < 512; y++) {
280                         int ptr = sa & 0x1ffff;
281                         sa += 0x80;
282                         scrntype_t *dest = emu->get_screen_buffer(y);
283                         
284                         for(int x = 0; x < 720; x += 8) {
285                                 uint8_t p0 = vram[0x00000 | ptr];
286                                 uint8_t p1 = vram[0x20000 | ptr];
287                                 uint8_t p2 = vram[0x40000 | ptr];
288                                 uint8_t p3 = vram[0x60000 | ptr];
289                                 ptr = (ptr + 1) & 0x1ffff;
290                                 
291                                 dest[x + 0] = palette_pc[((p0 & 0x01) << 0) | ((p1 & 0x01) << 1) | ((p2 & 0x01) << 2) | ((p3 & 0x01) << 3)];
292                                 dest[x + 1] = palette_pc[((p0 & 0x02) >> 1) | ((p1 & 0x02) << 0) | ((p2 & 0x02) << 1) | ((p3 & 0x02) << 2)];
293                                 dest[x + 2] = palette_pc[((p0 & 0x04) >> 2) | ((p1 & 0x04) >> 1) | ((p2 & 0x04) << 0) | ((p3 & 0x04) << 1)];
294                                 dest[x + 3] = palette_pc[((p0 & 0x08) >> 3) | ((p1 & 0x08) >> 2) | ((p2 & 0x08) >> 1) | ((p3 & 0x08) << 0)];
295                                 dest[x + 4] = palette_pc[((p0 & 0x10) >> 4) | ((p1 & 0x10) >> 3) | ((p2 & 0x10) >> 2) | ((p3 & 0x10) >> 1)];
296                                 dest[x + 5] = palette_pc[((p0 & 0x20) >> 5) | ((p1 & 0x20) >> 4) | ((p2 & 0x20) >> 3) | ((p3 & 0x20) >> 2)];
297                                 dest[x + 6] = palette_pc[((p0 & 0x40) >> 6) | ((p1 & 0x40) >> 5) | ((p2 & 0x40) >> 4) | ((p3 & 0x40) >> 3)];
298                                 dest[x + 7] = palette_pc[((p0 & 0x80) >> 7) | ((p1 & 0x80) >> 6) | ((p2 & 0x80) >> 5) | ((p3 & 0x80) >> 4)];
299                         }
300                 }
301         }
302         emu->screen_skip_line(false);
303 }
304
305 void CRTC::update_palette(int num)
306 {
307         int r = (palette[num] >> 0) & 7;
308         int g = (palette[num] >> 3) & 7;
309         int b = (palette[num] >> 6) & 7;
310         palette_pc[num] = RGB_COLOR(r << 5, g << 5, b << 5);
311 }
312
313 #define STATE_VERSION   1
314
315 bool CRTC::process_state(FILEIO* state_fio, bool loading)
316 {
317         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
318                 return false;
319         }
320         if(!state_fio->StateCheckInt32(this_device_id)) {
321                 return false;
322         }
323         //state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
324         for(int i = 0; i < (sizeof(palette_pc) / sizeof(scrntype_t)); i++) {
325                 if(loading) {
326                         uint8_t r, g, b;
327                         r = state_fio->FgetUint8();
328                         g = state_fio->FgetUint8();
329                         b = state_fio->FgetUint8();
330                         palette_pc[i] = RGB_COLOR(r, g, b);
331                 } else {
332                         uint8_t r, g, b;
333                         r = R_OF_COLOR(palette_pc[i]);
334                         g = G_OF_COLOR(palette_pc[i]);
335                         b = B_OF_COLOR(palette_pc[i]);
336                         state_fio->FputUint8(r);
337                         state_fio->FputUint8(g);
338                         state_fio->FputUint8(b);
339                 }
340         }
341         //state_fio->StateBuffer(palette, sizeof(palette), 1);
342         for(int i = 0; i < (sizeof(palette) / sizeof(uint16_t)); i++) {
343                 state_fio->StateUint16(palette[i]);
344         }
345         state_fio->StateUint8(sel);
346         state_fio->StateBuffer(regs, sizeof(regs), 1);
347         state_fio->StateUint16(vs);
348         state_fio->StateUint16(cmd);
349         state_fio->StateBuffer(vram, sizeof(vram), 1);
350         state_fio->StateUint32(shift);
351         state_fio->StateUint32(maskl);
352         state_fio->StateUint32(maskh);
353         state_fio->StateUint32(busl);
354         state_fio->StateUint32(bush);
355         state_fio->StateUint32(write_plane);
356         state_fio->StateUint32(read_plane);
357         return true;
358 }
359
360 }