OSDN Git Service

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