OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / display.cpp
1 /*
2         NEC PC-9801 Emulator 'ePC-9801'
3         NEC PC-9801E/F/M Emulator 'ePC-9801E'
4         NEC PC-9801U Emulator 'ePC-9801U'
5         NEC PC-9801VF Emulator 'ePC-9801VF'
6         NEC PC-9801VM Emulator 'ePC-9801VM'
7         NEC PC-9801VX Emulator 'ePC-9801VX'
8         NEC PC-9801RA Emulator 'ePC-9801RA'
9         NEC PC-98XA Emulator 'ePC-98XA'
10         NEC PC-98XL Emulator 'ePC-98XL'
11         NEC PC-98RL Emulator 'ePC-98RL'
12         NEC PC-98DO Emulator 'ePC-98DO'
13
14         Author : Takeda.Toshiya
15         Date   : 2010.09.16-
16
17         [ display ]
18 */
19
20 #include "display.h"
21 #include "../i8259.h"
22 #include "../upd7220.h"
23
24 #if !defined(SUPPORT_HIRESO)
25         #define TVRAM_ADDRESS           0xa0000
26         #define VRAM_PLANE_SIZE         0x08000
27         #define VRAM_PLANE_ADDR_MASK    0x07fff
28         #define VRAM_PLANE_ADDR_0       0x08000
29         #define VRAM_PLANE_ADDR_1       0x10000
30         #define VRAM_PLANE_ADDR_2       0x18000
31         #define VRAM_PLANE_ADDR_3       0x00000
32 #else
33         #define TVRAM_ADDRESS           0xe0000
34         #define VRAM_PLANE_SIZE         0x20000
35         #define VRAM_PLANE_ADDR_MASK    0x1ffff
36         #define VRAM_PLANE_ADDR_0       0x00000
37         #define VRAM_PLANE_ADDR_1       0x20000
38         #define VRAM_PLANE_ADDR_2       0x40000
39         #define VRAM_PLANE_ADDR_3       0x60000
40 #endif
41
42 #define SCROLL_PL       0
43 #define SCROLL_BL       1
44 #define SCROLL_CL       2
45 #define SCROLL_SSL      3
46 #define SCROLL_SUR      4
47 #define SCROLL_SDR      5
48
49 #define MODE1_ATRSEL    0
50 #define MODE1_GRAPHIC   1
51 #define MODE1_COLUMN    2
52 #define MODE1_FONTSEL   3
53 #define MODE1_200LINE   4
54 #define MODE1_KAC       5
55 #define MODE1_MEMSW     6
56 #define MODE1_DISP      7
57
58 #define MODE2_16COLOR   0x00
59 #define MODE2_EGC       0x02
60 #define MDOE2_TXTSHIFT  0x20
61
62 #define GRCG_PLANE_0    0x01
63 #define GRCG_PLANE_1    0x02
64 #define GRCG_PLANE_2    0x04
65 #define GRCG_PLANE_3    0x08
66 #define GRCG_RW_MODE    0x40
67 #define GRCG_CG_MODE    0x80
68
69 #define ATTR_ST         0x01
70 #define ATTR_BL         0x02
71 #define ATTR_RV         0x04
72 #define ATTR_UL         0x08
73 #define ATTR_VL         0x10
74 #define ATTR_COL        0xe0
75
76 namespace PC9801 {
77
78 static const uint8_t memsw_default[] = {
79         0xe1, 0x48, 0xe1, 0x05, 0xe1, 0x04, 0xe1, 0x00,
80         0xe1, 0x01, 0xe1, 0x00, 0xe1, 0x00, 0xe1, 0x00,
81 };
82
83 #if defined(SUPPORT_EGC)
84 static const uint8_t egc_bytemask_u0[64] = {
85         0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
86         0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01,
87         0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x03, 0x01,
88         0xf0, 0x78, 0x3c, 0x1e, 0x0f, 0x07, 0x03, 0x01,
89         0xf8, 0x7c, 0x3e, 0x1f, 0x0f, 0x07, 0x03, 0x01,
90         0xfc, 0x7e, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01,
91         0xfe, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01,
92         0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01,
93 };
94
95 static const uint8_t egc_bytemask_u1[8] =  {
96         0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
97 };
98
99 static const uint8_t egc_bytemask_d0[64] = {
100         0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
101         0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
102         0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80,
103         0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xe0, 0xc0, 0x80,
104         0x1f, 0x3e, 0x7c, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
105         0x3f, 0x7e, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
106         0x7f, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
107         0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
108 };
109
110 static const uint8_t egc_bytemask_d1[8] = {
111         0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
112 };
113
114 static const uint16_t egc_maskword[16][4] = {
115         {0x0000, 0x0000, 0x0000, 0x0000}, {0xffff, 0x0000, 0x0000, 0x0000},
116         {0x0000, 0xffff, 0x0000, 0x0000}, {0xffff, 0xffff, 0x0000, 0x0000},
117         {0x0000, 0x0000, 0xffff, 0x0000}, {0xffff, 0x0000, 0xffff, 0x0000},
118         {0x0000, 0xffff, 0xffff, 0x0000}, {0xffff, 0xffff, 0xffff, 0x0000},
119         {0x0000, 0x0000, 0x0000, 0xffff}, {0xffff, 0x0000, 0x0000, 0xffff},
120         {0x0000, 0xffff, 0x0000, 0xffff}, {0xffff, 0xffff, 0x0000, 0xffff},
121         {0x0000, 0x0000, 0xffff, 0xffff}, {0xffff, 0x0000, 0xffff, 0xffff},
122         {0x0000, 0xffff, 0xffff, 0xffff}, {0xffff, 0xffff, 0xffff, 0xffff}
123 };
124 #endif
125
126 void DISPLAY::initialize()
127 {
128         // load font data
129         memset(font, 0xff, sizeof(font));
130         
131         FILEIO* fio = new FILEIO();
132         
133 #if !defined(SUPPORT_HIRESO)
134         uint8_t *p = font + 0x81000;
135         uint8_t *q = font + 0x83000;
136         for(int i = 0; i < 256; i++) {
137                 for(int j = 0; j < 4; j++) {
138                         uint32_t bit = 0;
139                         if(i & (1 << j)) {
140                                 bit |= 0xf0f0f0f0;
141                         }
142                         if(i & (0x10 << j)) {
143                                 bit |= 0x0f0f0f0f;
144                         }
145                         *(uint32_t *)p = bit;
146                         p += 4;
147                         *(uint16_t *)q = (uint16_t)bit;
148                         q += 2;
149                 }
150                 q += 8;
151         }
152         for(int i = 0; i < 0x80; i++) {
153                 q = font + (i << 12);
154                 memset(q + 0x000, 0, 0x0560 - 0x000);
155                 memset(q + 0x580, 0, 0x0d60 - 0x580);
156                 memset(q + 0xd80, 0, 0x1000 - 0xd80);
157         }
158         if(!fio->Fopen(create_local_path(_T("FONT16.ROM")), FILEIO_READ_BINARY)) {
159                 fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY);
160         }
161         if(fio->IsOpened()) {
162                 uint8_t *buf = (uint8_t *)malloc(0x46800);
163                 fio->Fread(buf, 0x46800, 1);
164                 fio->Fclose();
165                 
166                 // 8x8 font
167                 uint8_t *dst = font + 0x82000;
168                 uint8_t *src = buf;
169                 for(int i = 0; i < 256; i++) {
170                         memcpy(dst, src, 8);
171                         dst += 16;
172                         src += 8;
173                 }
174                 // 8x16 font
175                 memcpy(font + 0x80000, buf + 0x0800, 16 * 128);
176                 memcpy(font + 0x80800, buf + 0x1000, 16 * 128);
177                 // kanji font
178                 kanji_copy(font, buf, 0x01, 0x30);
179                 kanji_copy(font, buf, 0x30, 0x56);
180                 kanji_copy(font, buf, 0x58, 0x5d);
181                 
182                 free(buf);
183         }
184 #else
185         if(fio->Fopen(create_local_path(_T("FONT24.ROM")), FILEIO_READ_BINARY)) {
186                 uint8_t pattern[72];
187                 
188                 for(int code = 0x00; code <= 0xff; code++) {
189                         fio->Fread(pattern, 48, 1);
190                         ank_copy(code, pattern);
191                 }
192 #if 1
193                 for(int first = 0x21; first <= 0x7c; first++) {
194                         for(int second = 0x21; second <= 0x7e; second++) {
195                                 fio->Fread(pattern, 72, 1);
196                                 kanji_copy(first, second, pattern);
197                         }
198                 }
199 #else
200                 for(int first = 0x21; first <= 0x27; first++) {
201                         for(int second = 0x21; second <= 0x7e; second++) {
202                                 fio->Fread(pattern, 72, 1);
203                                 kanji_copy(first, second, pattern);
204                         }
205                 }
206                 for(int first = 0x30; first <= 0x73; first++) {
207                         for(int second = 0x21; second <= 0x7e; second++) {
208                                 fio->Fread(pattern, 72, 1);
209                                 kanji_copy(first, second, pattern);
210                         }
211                 }
212                 for(int first = 0x79; first <= 0x7c; first++) {
213                         for(int second = 0x21; second <= 0x7e; second++) {
214                                 fio->Fread(pattern, 72, 1);
215                                 kanji_copy(first, second, pattern);
216                         }
217                 }
218 #endif
219                 memcpy(font + ANK_FONT_OFS + FONT_SIZE * 0x100, font + ANK_FONT_OFS, FONT_SIZE * 0x100);
220                 memcpy(font + ANK_FONT_OFS + FONT_SIZE * 0x200, font + ANK_FONT_OFS, FONT_SIZE * 0x100);
221                 memcpy(font + ANK_FONT_OFS + FONT_SIZE * 0x300, font + ANK_FONT_OFS, FONT_SIZE * 0x100);
222         }
223 #endif
224         
225         // init palette
226         for(int i = 0; i < 8; i++) {
227                 palette_chr[i] = RGB_COLOR((i & 2) ? 0xff : 0, (i & 4) ? 0xff : 0, (i & 1) ? 0xff : 0);
228         }
229         
230         memset(palette_gfx8, 0, sizeof(palette_gfx8));
231         memset(digipal, 0, sizeof(digipal));
232         
233 #if defined(SUPPORT_16_COLORS)
234         memset(palette_gfx16, 0, sizeof(palette_gfx16));
235         memset(anapal, 0, sizeof(anapal));
236         anapal_sel = 0;
237 #endif
238         
239 //      memset(tvram, 0, sizeof(tvram));
240         memset(vram, 0, sizeof(vram));
241         
242 // WIP: MEMSW
243         bool memsw_stat = false;
244         if(fio->Fopen(create_local_path(_T("MEMSW.BIN")), FILEIO_READ_BINARY)) {
245                 if(fio->IsOpened()) {
246                         for(int i = 0; i < 16; i++) {
247                                 tvram[0x3fe0 + (i << 1)] = fio->FgetUint8();
248                                 if(i == 15) memsw_stat = true;
249                         }
250                         fio->Fclose();
251                 }
252         }
253         if(!memsw_stat) {
254                 for(int i = 0; i < 16; i++) {
255                         tvram[0x3fe0 + (i << 1)] = memsw_default[i];
256                 }
257         }
258         delete fio;
259
260 #ifndef HAS_UPD4990A
261         cur_time_t cur_time;
262         get_host_time(&cur_time);
263         tvram[0x3ffe] = TO_BCD(cur_time.year);
264 #endif
265         
266         // set vram pointer to gdc
267         d_gdc_chr->set_vram_ptr(tvram, 0x2000);
268         d_gdc_chr->set_screen_width(80);
269         d_gdc_gfx->set_vram_bus_ptr(this, 0x20000);
270         d_gdc_gfx->set_screen_width(SCREEN_WIDTH >> 3);
271         
272         // register event
273         register_frame_event(this);
274 }
275
276 void DISPLAY::release()
277 {
278         FILEIO *fio = new FILEIO();
279         if(fio == NULL) return;
280         if(fio->Fopen(create_local_path(_T("MEMSW.BIN")), FILEIO_WRITE_BINARY)) {
281                 if(fio->IsOpened()) {
282                         for(int i = 0; i < 16; i++) {
283                                 fio->FputUint8(tvram[0x3fe0 + (i << 1)]);
284                         }
285                         fio->Fclose();
286                 }
287         }
288         delete fio;
289 }
290
291 #if !defined(SUPPORT_HIRESO)
292 void DISPLAY::kanji_copy(uint8_t *dst, uint8_t *src, int from, int to)
293 {
294         for(int i = from; i < to; i++) {
295                 uint8_t *p = src + 0x1800 + (0x60 * 32 * (i - 1));
296                 uint8_t *q = dst + 0x20000 + (i << 4);
297                 for(int j = 0x20; j < 0x80; j++) {
298                         for(int k = 0; k < 16; k++) {
299                                 *(q + 0x800) = *(p + 16);
300                                 *q++ = *p++;
301                         }
302                         p += 16;
303                         q += 0x1000 - 16;
304                 }
305         }
306 }
307 #else
308 void DISPLAY::ank_copy(int code, uint8_t *pattern)
309 {
310         uint16_t *dest = (uint16_t *)(font + ANK_FONT_OFS + FONT_SIZE * code);
311         
312         for(int i = 0; i < 24; i++) {
313                 dest[i] = (pattern[2 * i] << 8) | pattern[2 * i + 1];
314         }
315 }
316
317 void DISPLAY::kanji_copy(int first, int second, uint8_t *pattern)
318 {
319         uint16_t *dest_l = (uint16_t *)(font + FONT_SIZE * ((first - 0x20) | (second << 8)));
320         uint16_t *dest_r = (uint16_t *)(font + FONT_SIZE * ((first - 0x20) | (second << 8)) + KANJI_2ND_OFS);
321         
322         for(int i = 0; i < 24; i++) {
323                 uint32_t p = (pattern[3 * i] << 16) | (pattern[3 * i + 1] << 8) | pattern[3 * i + 2];
324                 dest_l[i] = p >> 12;
325                 dest_r[i] = p << 2;
326         }
327 }
328 #endif
329
330 void DISPLAY::reset()
331 {
332 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
333         vram_disp_sel = 0x00;
334         vram_draw_sel = 0x00;
335 #endif
336         vram_disp_b = vram + VRAM_PLANE_ADDR_0;
337         vram_disp_r = vram + VRAM_PLANE_ADDR_1;
338         vram_disp_g = vram + VRAM_PLANE_ADDR_2;
339 #if defined(SUPPORT_16_COLORS)
340         vram_disp_e = vram + VRAM_PLANE_ADDR_3;
341 #endif
342         vram_draw   = vram + 0x00000;
343         
344         crtv = 2;
345         
346         scroll[SCROLL_PL ] = 0;
347         scroll[SCROLL_BL ] = 0x0f;
348         scroll[SCROLL_CL ] = 0x10;
349         scroll[SCROLL_SSL] = 0;
350         scroll[SCROLL_SUR] = 0;
351         scroll[SCROLL_SDR] = 24;
352         
353         memset(modereg1, 0, sizeof(modereg1));
354 #if defined(SUPPORT_16_COLORS)
355         memset(modereg2, 0, sizeof(modereg2));
356 #endif
357 #if defined(SUPPORT_GRCG)
358         grcg_mode = grcg_tile_ptr = 0;
359 #endif
360 #if defined(SUPPORT_EGC)
361         egc_access = 0xfff0;
362         egc_fgbg = 0x00ff;
363         egc_ope = 0;
364         egc_fg = 0;
365         egc_mask.w = 0xffff;
366         egc_bg = 0;
367         egc_sft = 0;
368         egc_leng = 0x000f;
369         egc_lastvram.q = 0;
370         egc_patreg.q = 0;
371         egc_fgc.q = 0;
372         egc_bgc.q = 0;
373         egc_func = 0;
374         egc_remain = 0;
375         egc_stack = 0;
376         egc_inptr = egc_buf;
377         egc_outptr = egc_buf;
378         egc_mask2.w = 0;
379         egc_srcmask.w = 0;
380         egc_srcbit = 0;
381         egc_dstbit = 0;
382         egc_sft8bitl = 0;
383         egc_sft8bitr = 0;
384         memset(egc_buf, 0, sizeof(egc_buf));
385         egc_vram_src.q = 0;
386         egc_vram_data.q = 0;
387         egc_shift();
388         egc_srcmask.w = 0xffff;
389 #endif
390         
391         font_code = 0;
392         font_line = 0;
393 //      font_lr = 0;
394 }
395
396 void DISPLAY::event_frame()
397 {
398         if(crtv > 1) {
399                 // dont raise irq at first frame
400                 crtv--;
401         } else if(crtv == 1) {
402                 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR2, 1, 1);
403                 crtv = 0;
404         }
405 }
406
407 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
408 {
409         switch(addr) {
410         case 0x64:
411                 crtv = 1;
412                 break;
413         case 0x68:
414                 modereg1[(data >> 1) & 7] = data & 1;
415                 break;
416 #if defined(SUPPORT_16_COLORS)
417         case 0x6a:
418                 modereg2[(data >> 1) & 127] = data & 1;
419                 break;
420 #endif
421         case 0x6c:
422 //              border = (data >> 3) & 7;
423                 break;
424         case 0x6e:
425 //              border = (data >> 3) & 7;
426 #if !defined(_PC9801)
427                 if(data & 1) {
428                         d_gdc_chr->set_horiz_freq(24830);
429                         d_gdc_gfx->set_horiz_freq(24830);
430                 } else {
431                         d_gdc_chr->set_horiz_freq(15750);
432                         d_gdc_gfx->set_horiz_freq(15750);
433                 }
434 #endif
435                 break;
436         case 0x70:
437         case 0x72:
438         case 0x74:
439         case 0x76:
440         case 0x78:
441         case 0x7a:
442                 scroll[(addr >> 1) & 7] = data;
443                 break;
444 #if defined(SUPPORT_GRCG)
445 #if !defined(SUPPORT_HIRESO)
446         case 0x007c:
447 #else
448         case 0x00a4:
449 #endif
450                 grcg_mode = data;
451                 grcg_tile_ptr = 0;
452                 break;
453 #if !defined(SUPPORT_HIRESO)
454         case 0x007e:
455 #else
456         case 0x00a6:
457 #endif
458                 grcg_tile[grcg_tile_ptr] = data;
459                 grcg_tile_ptr = (grcg_tile_ptr + 1) & 3;
460                 break;
461 #endif
462 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
463         // vram select
464         case 0x00a4:
465                 if(data & 1) {
466                         vram_disp_b = vram + 0x28000;
467                         vram_disp_r = vram + 0x30000;
468                         vram_disp_g = vram + 0x38000;
469 #if defined(SUPPORT_16_COLORS)
470                         vram_disp_e = vram + 0x20000;
471 #endif
472                 } else {
473                         vram_disp_b = vram + 0x08000;
474                         vram_disp_r = vram + 0x10000;
475                         vram_disp_g = vram + 0x18000;
476 #if defined(SUPPORT_16_COLORS)
477                         vram_disp_e = vram + 0x00000;
478 #endif
479                 }
480                 vram_disp_sel = data;
481                 break;
482         case 0x00a6:
483                 if(data & 1) {
484                         vram_draw = vram + 0x20000;
485                 } else {
486                         vram_draw = vram + 0x00000;
487                 }
488                 vram_draw_sel = data;
489                 break;
490 #endif
491         // palette
492         case 0xa8:
493 #if defined(SUPPORT_16_COLORS)
494                 if(modereg2[MODE2_16COLOR]) {
495                         anapal_sel = data & 0x0f;
496                         break;
497                 }
498 #endif
499                 digipal[0] = data;
500                 palette_gfx8[7] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
501                 data >>= 4;
502                 palette_gfx8[3] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
503                 break;
504         case 0xaa:
505 #if defined(SUPPORT_16_COLORS)
506                 if(modereg2[MODE2_16COLOR]) {
507                         anapal[anapal_sel][0] = (data & 0x0f) << 4;
508                         palette_gfx16[anapal_sel] = RGB_COLOR(anapal[anapal_sel][1], anapal[anapal_sel][0], anapal[anapal_sel][2]);
509                         break;
510                 }
511 #endif
512                 digipal[1] = data;
513                 palette_gfx8[5] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
514                 data >>= 4;
515                 palette_gfx8[1] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
516                 break;
517         case 0xac:
518 #if defined(SUPPORT_16_COLORS)
519                 if(modereg2[MODE2_16COLOR]) {
520                         anapal[anapal_sel][1] = (data & 0x0f) << 4;
521                         palette_gfx16[anapal_sel] = RGB_COLOR(anapal[anapal_sel][1], anapal[anapal_sel][0], anapal[anapal_sel][2]);
522                         break;
523                 }
524 #endif
525                 digipal[2] = data;
526                 palette_gfx8[6] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
527                 data >>= 4;
528                 palette_gfx8[2] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
529                 break;
530         case 0xae:
531 #if defined(SUPPORT_16_COLORS)
532                 if(modereg2[MODE2_16COLOR]) {
533                         anapal[anapal_sel][2] = (data & 0x0f) << 4;
534                         palette_gfx16[anapal_sel] = RGB_COLOR(anapal[anapal_sel][1], anapal[anapal_sel][0], anapal[anapal_sel][2]);
535                         break;
536                 }
537 #endif
538                 digipal[3] = data;
539                 palette_gfx8[4] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
540                 data >>= 4;
541                 palette_gfx8[0] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0);
542                 break;
543         // cg window
544         case 0xa1:
545                 font_code = (data << 8) | (font_code & 0xff);
546                 break;
547         case 0xa3:
548                 font_code = (font_code & 0xff00) | data;
549                 break;
550         case 0xa5:
551 //              font_line = data & 0x1f;
552 //              font_lr = ((~data) & 0x20) << 6;
553                 font_line = data;
554                 break;
555         case 0xa9:
556                 if((font_code & 0x7e) == 0x56) {
557                         uint16_t font_lr = ((~font_line) & 0x20) << 6;
558                         font[((font_code & 0x7f7f) << 4) + font_lr + (font_line & 0x0f)] = data;
559                 }
560                 break;
561 #if defined(SUPPORT_EGC)
562         // egc
563         case 0x04a0:
564                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
565                         egc_access &= 0xff00;
566                         egc_access |= data;
567                 }
568                 break;
569         case 0x04a1:
570                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
571                         egc_access &= 0x00ff;
572                         egc_access |= data << 8;
573                 }
574                 break;
575         case 0x04a2:
576                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
577                         egc_fgbg &= 0xff00;
578                         egc_fgbg |= data;
579                 }
580                 break;
581         case 0x04a3:
582                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
583                         egc_fgbg &= 0x00ff;
584                         egc_fgbg |= data << 8;
585                 }
586                 break;
587         case 0x04a4:
588                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
589                         egc_ope &= 0xff00;
590                         egc_ope |= data;
591                 }
592                 break;
593         case 0x04a5:
594                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
595                         egc_ope &= 0x00ff;
596                         egc_ope |= data << 8;
597                 }
598                 break;
599         case 0x04a6:
600                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
601                         egc_fg &= 0xff00;
602                         egc_fg |= data;
603                         egc_fgc.d[0] = *(uint32_t *)(egc_maskword[data & 0x0f] + 0);
604                         egc_fgc.d[1] = *(uint32_t *)(egc_maskword[data & 0x0f] + 2);
605                 }
606                 break;
607         case 0x04a7:
608                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
609                         egc_fg &= 0x00ff;
610                         egc_fg |= data << 8;
611                 }
612                 break;
613         case 0x04a8:
614                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
615                         if(!(egc_fgbg & 0x6000)) {
616                                 egc_mask.b[0] = data;
617                         }
618                 }
619                 break;
620         case 0x04a9:
621                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
622                         if(!(egc_fgbg & 0x6000)) {
623                                 egc_mask.b[1] = data;
624                         }
625                 }
626                 break;
627         case 0x04aa:
628                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
629                         egc_bg &= 0xff00;
630                         egc_bg |= data;
631                         egc_bgc.d[0] = *(uint32_t *)(egc_maskword[data & 0x0f] + 0);
632                         egc_bgc.d[1] = *(uint32_t *)(egc_maskword[data & 0x0f] + 2);
633                 }
634                 break;
635         case 0x04ab:
636                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
637                         egc_bg &= 0x00ff;
638                         egc_bg |= data << 8;
639                 }
640                 break;
641         case 0x04ac:
642                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
643                         egc_sft &= 0xff00;
644                         egc_sft |= data;
645                         egc_shift();
646                         egc_srcmask.w = 0xffff;
647                 }
648                 break;
649         case 0x04ad:
650                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
651                         egc_sft &= 0x00ff;
652                         egc_sft |= data << 8;
653                         egc_shift();
654                         egc_srcmask.w = 0xffff;
655                 }
656                 break;
657         case 0x04ae:
658                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
659                         egc_leng &= 0xff00;
660                         egc_leng |= data;
661                         egc_shift();
662                         egc_srcmask.w = 0xffff;
663                 }
664                 break;
665         case 0x04af:
666                 if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) {
667                         egc_leng &= 0x00ff;
668                         egc_leng |= data << 8;
669                         egc_shift();
670                         egc_srcmask.w = 0xffff;
671                 }
672                 break;
673 #endif
674         }
675 }
676
677 uint32_t DISPLAY::read_io8(uint32_t addr)
678 {
679         switch(addr) {
680 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
681         // vram select
682         case 0x00a4:
683                 return vram_disp_sel;
684         case 0x00a6:
685                 return vram_draw_sel;
686 #endif
687         // palette
688         case 0xa8:
689                 return digipal[0];
690         case 0xaa:
691                 return digipal[1];
692         case 0xac:
693                 return digipal[2];
694         case 0xae:
695                 return digipal[3];
696         // cg window
697         case 0xa1:
698                 return (font_code >> 8) & 0xff;
699         case 0xa3:
700                 return (font_code >> 0) & 0xff;
701         case 0xa5:
702                 return font_line;
703         case 0xa9:
704                 if((font_code & 0xff) >= 0x09 && (font_code & 0xff) < 0x0c) {
705                         uint16_t font_lr = ((~font_line) & 0x20) << 6;
706                         if(!font_lr) {
707                                 return font[((font_code & 0x7f7f) << 4) + (font_line & 0x0f)];
708                         }
709                 } else if(font_code & 0xff00) {
710                         uint16_t font_lr = ((~font_line) & 0x20) << 6;
711                         return font[((font_code & 0x7f7f) << 4) + font_lr + (font_line & 0x0f)];
712                 } else if(!(font_line & 0x10)) {
713                         return font[0x80000 + (font_code << 4) + (font_line & 0x1f)];
714                 }
715                 return 0;
716         }
717         return 0xff;
718 }
719
720 //              CPU     GDC
721 //      B       A8000h  08000h
722 //      R       B0000h  10000h
723 //      G       B8000h  18000h
724 //      I       E0000h  00000h
725
726 // CPU memory bus
727
728 void DISPLAY::write_memory_mapped_io8(uint32_t addr, uint32_t data)
729 {
730         if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x3fe2)) {
731                 tvram[addr - TVRAM_ADDRESS] = data;
732         } else if((TVRAM_ADDRESS + 0x3fe2) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) {
733                 // memory switch
734                 if(modereg1[MODE1_MEMSW]) {
735                         tvram[addr - TVRAM_ADDRESS] = data;
736                 }
737         } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) {
738                 if((font_code & 0x7e) == 0x56) {
739                         /* FIXME: need to fix for hireso */
740                         uint32_t low = 0x7fff0, high;
741                         uint8_t code = font_code & 0x7f;
742                         uint16_t lr = ((~font_line) & 0x20) << 6;
743                         if(!(font_code & 0xff00)) {
744                                 high = 0x80000 + (font_code << 4);
745                                 if(!modereg1[MODE1_FONTSEL]) {
746                                         high += 0x2000;
747                                 }
748                         } else {
749                                 high = (font_code & 0x7f7f) << 4;
750                                 if(code >= 0x56 && code < 0x58) {
751                                         high += lr;
752                                 } else if(code >= 0x09 && code < 0x0c) {
753                                         if(lr) {
754                                                 high = low;
755                                         }
756                                 } else if((code >= 0x0c && code < 0x10) || (code >= 0x58 && code < 0x60)) {
757                                         high += lr;
758                                 } else {
759                                         low = high;
760                                         high += 0x800;
761                                 }
762                         }
763                         if(addr & 1) {
764                                 font[high + ((addr >> 1) & 0x0f)] = data;
765                         } else {
766                                 font[low  + ((addr >> 1) & 0x0f)] = data;
767                         }
768                 }
769 #if !defined(SUPPORT_HIRESO)
770         } else if(0xa8000 <= addr && addr < 0xc0000) {
771                 write_dma_io8(addr - 0xa0000, data);
772 #if defined(SUPPORT_16_COLORS)
773         } else if(0xe0000 <= addr && addr < 0xe8000) {
774                 write_dma_io8(addr - 0xe0000, data);
775 #endif
776 #else
777         } else if(0xc0000 <= addr && addr < 0xe0000) {
778                 write_dma_io8(addr - 0xc0000, data);
779 #endif
780         }
781 }
782
783 void DISPLAY::write_memory_mapped_io16(uint32_t addr, uint32_t data)
784 {
785         if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x3fe2)) {
786                 *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]) = data;
787         } else if((TVRAM_ADDRESS + 0x3fe2) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) {
788                 // memory switch
789                 if(modereg1[MODE1_MEMSW]) {
790                         *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]) = data;
791                 }
792         } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) {
793                 write_memory_mapped_io8(addr + 0, (data >> 0) & 0xff);
794                 write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff);
795 #if !defined(SUPPORT_HIRESO)
796         } else if(0xa8000 <= addr && addr < 0xc0000) {
797                 write_dma_io16(addr - 0xa0000, data);
798 #if defined(SUPPORT_16_COLORS)
799         } else if(0xe0000 <= addr && addr < 0xe8000) {
800                 write_dma_io16(addr - 0xe0000, data);
801 #endif
802 #else
803         } else if(0xc0000 <= addr && addr < 0xe0000) {
804                 write_dma_io16(addr - 0xc0000, data);
805 #endif
806         }
807 }
808
809 uint32_t DISPLAY::read_memory_mapped_io8(uint32_t addr)
810 {
811         if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x2000)) {
812                 return tvram[addr - TVRAM_ADDRESS];
813         } else if((TVRAM_ADDRESS + 0x2000) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) {
814                 if(addr & 1) {
815                         return 0xff;
816                 }
817                 return tvram[addr - TVRAM_ADDRESS];
818         } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) {
819                 /* FIXME: need to fix for hireso */
820                 uint32_t low = 0x7fff0, high;
821                 uint8_t code = font_code & 0x7f;
822                 uint16_t lr = ((~font_line) & 0x20) << 6;
823                 if(!(font_code & 0xff00)) {
824                         high = 0x80000 + (font_code << 4);
825                         if(!modereg1[MODE1_FONTSEL]) {
826                                 high += 0x2000;
827                         }
828                 } else {
829                         high = (font_code & 0x7f7f) << 4;
830                         if(code >= 0x56 && code < 0x58) {
831                                 high += lr;
832                         } else if(code >= 0x09 && code < 0x0c) {
833                                 if(lr) {
834                                         high = low;
835                                 }
836                         } else if((code >= 0x0c && code < 0x10) || (code >= 0x58 && code < 0x60)) {
837                                 high += lr;
838                         } else {
839                                 low = high;
840                                 high += 0x800;
841                         }
842                 }
843                 if(addr & 1) {
844                         return font[high + ((addr >> 1) & 0x0f)];
845                 } else {
846                         return font[low  + ((addr >> 1) & 0x0f)];
847                 }
848 #if !defined(SUPPORT_HIRESO)
849         } else if(0xa8000 <= addr && addr < 0xc0000) {
850                 return read_dma_io8(addr - 0xa0000);
851 #if defined(SUPPORT_16_COLORS)
852         } else if(0xe0000 <= addr && addr < 0xe8000) {
853                 return read_dma_io8(addr - 0xe0000);
854 #endif
855 #else
856         } else if(0xc0000 <= addr && addr < 0xe0000) {
857                 return read_dma_io8(addr - 0xc0000);
858 #endif
859         }
860         return 0xff;
861 }
862
863 uint32_t DISPLAY::read_memory_mapped_io16(uint32_t addr)
864 {
865         if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x2000)) {
866                 return *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]);
867         } else if((TVRAM_ADDRESS + 0x2000) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) {
868                 if(addr & 1) {
869                         return 0xffff;
870                 }
871                 return *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]);
872         } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) {
873                 return read_memory_mapped_io8(addr) | (read_memory_mapped_io8(addr + 1) << 8);
874 #if !defined(SUPPORT_HIRESO)
875         } else if(0xa8000 <= addr && addr < 0xc0000) {
876                 return read_dma_io16(addr - 0xa0000);
877 #if defined(SUPPORT_16_COLORS)
878         } else if(0xe0000 <= addr && addr < 0xe8000) {
879                 return read_dma_io16(addr - 0xe0000);
880 #endif
881 #else
882         } else if(0xc0000 <= addr && addr < 0xe0000) {
883                 return read_dma_io16(addr - 0xc0000);
884 #endif
885         }
886         return 0xffff;
887 }
888
889 // Graphic GDC bus
890
891 void DISPLAY::write_dma_io8(uint32_t addr, uint32_t data)
892 {
893 #if defined(SUPPORT_GRCG)
894         if(grcg_mode & GRCG_CG_MODE) {
895 #if defined(SUPPORT_EGC)
896                 if(modereg2[MODE2_EGC]) {
897                         egc_writeb(addr, data);
898                 } else
899 #endif
900                 grcg_writeb(addr, data);
901         } else
902 #endif
903         vram_draw[addr & 0x1ffff] = data;
904 }
905
906 void DISPLAY::write_dma_io16(uint32_t addr, uint32_t data)
907 {
908 #if defined(SUPPORT_GRCG)
909         if(grcg_mode & GRCG_CG_MODE) {
910 #if defined(SUPPORT_EGC)
911                 if(modereg2[MODE2_EGC]) {
912                         egc_writew(addr, data);
913                 } else
914 #endif
915                 grcg_writew(addr, data);
916         } else
917 #endif
918         *(uint16_t *)(&vram_draw[addr & 0x1ffff]) = data;
919 }
920
921 uint32_t DISPLAY::read_dma_io8(uint32_t addr)
922 {
923 #if defined(SUPPORT_GRCG)
924         if(grcg_mode & GRCG_CG_MODE) {
925 #if defined(SUPPORT_EGC)
926                 if(modereg2[MODE2_EGC]) {
927                         return egc_readb(addr);
928                 }
929 #endif
930                 return grcg_readb(addr);
931         }
932 #endif
933         return vram_draw[addr & 0x1ffff];
934 }
935
936 uint32_t DISPLAY::read_dma_io16(uint32_t addr)
937 {
938 #if defined(SUPPORT_GRCG)
939         if(grcg_mode & GRCG_CG_MODE) {
940 #if defined(SUPPORT_EGC)
941                 if(modereg2[MODE2_EGC]) {
942                         return egc_readw(addr);
943                 }
944 #endif
945                 return grcg_readw(addr);
946         }
947 #endif
948         return *(uint16_t *)(&vram_draw[addr & 0x1ffff]);
949 }
950
951 // GRCG
952
953 #if defined(SUPPORT_GRCG)
954 void DISPLAY::grcg_writeb(uint32_t addr1, uint32_t data)
955 {
956         uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK;
957         
958         if(grcg_mode & GRCG_RW_MODE) {
959                 // RMW
960                 if(!(grcg_mode & GRCG_PLANE_0)) {
961                         vram_draw[addr | VRAM_PLANE_ADDR_0] &= ~data;
962                         vram_draw[addr | VRAM_PLANE_ADDR_0] |= grcg_tile[0] & data;
963                 }
964                 if(!(grcg_mode & GRCG_PLANE_1)) {
965                         vram_draw[addr | VRAM_PLANE_ADDR_1] &= ~data;
966                         vram_draw[addr | VRAM_PLANE_ADDR_1] |= grcg_tile[1] & data;
967                 }
968                 if(!(grcg_mode & GRCG_PLANE_2)) {
969                         vram_draw[addr | VRAM_PLANE_ADDR_2] &= ~data;
970                         vram_draw[addr | VRAM_PLANE_ADDR_2] |= grcg_tile[2] & data;
971                 }
972                 if(!(grcg_mode & GRCG_PLANE_3)) {
973                         vram_draw[addr | VRAM_PLANE_ADDR_3] &= ~data;
974                         vram_draw[addr | VRAM_PLANE_ADDR_3] |= grcg_tile[3] & data;
975                 }
976         } else {
977                 // TDW
978                 if(!(grcg_mode & GRCG_PLANE_0)) {
979                         vram_draw[addr | VRAM_PLANE_ADDR_0] = grcg_tile[0];
980                 }
981                 if(!(grcg_mode & GRCG_PLANE_1)) {
982                         vram_draw[addr | VRAM_PLANE_ADDR_1] = grcg_tile[1];
983                 }
984                 if(!(grcg_mode & GRCG_PLANE_2)) {
985                         vram_draw[addr | VRAM_PLANE_ADDR_2] = grcg_tile[2];
986                 }
987                 if(!(grcg_mode & GRCG_PLANE_3)) {
988                         vram_draw[addr | VRAM_PLANE_ADDR_3] = grcg_tile[3];
989                 }
990         }
991 }
992
993 void DISPLAY::grcg_writew(uint32_t addr1, uint32_t data)
994 {
995         grcg_writeb(addr1 + 0, (data >> 0) & 0xff);
996         grcg_writeb(addr1 + 1, (data >> 8) & 0xff);
997 }
998
999 uint32_t DISPLAY::grcg_readb(uint32_t addr1)
1000 {
1001         if(grcg_mode & GRCG_RW_MODE) {
1002                 // VRAM
1003 #if !defined(SUPPORT_HIRESO)
1004                 return vram_draw[addr1 & 0x1ffff];
1005 #else
1006                 int plane = (grcg_mode >> 4) & 3;
1007                 return vram_draw[(addr1 & 0x1ffff) | (0x20000 * plane)];
1008 #endif
1009         } else {
1010                 // TCR
1011                 uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK;
1012                 uint8_t data = 0;
1013                 
1014                 if(!(grcg_mode & GRCG_PLANE_0)) {
1015                         data |= vram_draw[addr | VRAM_PLANE_ADDR_0] ^ grcg_tile[0];
1016                 }
1017                 if(!(grcg_mode & GRCG_PLANE_1)) {
1018                         data |= vram_draw[addr | VRAM_PLANE_ADDR_1] ^ grcg_tile[1];
1019                 }
1020                 if(!(grcg_mode & GRCG_PLANE_2)) {
1021                         data |= vram_draw[addr | VRAM_PLANE_ADDR_2] ^ grcg_tile[2];
1022                 }
1023                 if(!(grcg_mode & GRCG_PLANE_3)) {
1024                         data |= vram_draw[addr | VRAM_PLANE_ADDR_3] ^ grcg_tile[3];
1025                 }
1026                 return data ^ 0xff;
1027         }
1028 }
1029
1030 uint32_t DISPLAY::grcg_readw(uint32_t addr1)
1031 {
1032         return grcg_readb(addr1) | (grcg_readb(addr1 + 1) << 8);
1033 }
1034 #endif
1035
1036 // EGC based on Neko Project 2 and QEMU/9821
1037
1038 #if defined(SUPPORT_EGC)
1039 void DISPLAY::egc_shift()
1040 {
1041         uint8_t src8, dst8;
1042         
1043         egc_remain = (egc_leng & 0xfff) + 1;
1044         egc_func = (egc_sft >> 12) & 1;
1045         if(!egc_func) {
1046                 egc_inptr = egc_buf;
1047                 egc_outptr = egc_buf;
1048         } else {
1049                 egc_inptr = egc_buf + 4096 / 8 + 3;
1050                 egc_outptr = egc_buf + 4096 / 8 + 3;
1051         }
1052         egc_srcbit = egc_sft & 0x0f;
1053         egc_dstbit = (egc_sft >> 4) & 0x0f;
1054         
1055         src8 = egc_srcbit & 0x07;
1056         dst8 = egc_dstbit & 0x07;
1057         if(src8 < dst8) {
1058                 egc_func += 2;
1059                 egc_sft8bitr = dst8 - src8;
1060                 egc_sft8bitl = 8 - egc_sft8bitr;
1061         }
1062         else if(src8 > dst8) {
1063                 egc_func += 4;
1064                 egc_sft8bitl = src8 - dst8;
1065                 egc_sft8bitr = 8 - egc_sft8bitl;
1066         }
1067         egc_stack = 0;
1068 }
1069
1070 void DISPLAY::egc_sftb_upn_sub(uint32_t ext)
1071 {
1072         if(egc_dstbit >= 8) {
1073                 egc_dstbit -= 8;
1074                 egc_srcmask.b[ext] = 0;
1075                 return;
1076         }
1077         if(egc_dstbit) {
1078                 if((egc_dstbit + egc_remain) >= 8) {
1079                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (7 * 8)];
1080                         egc_remain -= (8 - egc_dstbit);
1081                         egc_dstbit = 0;
1082                 } else {
1083                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (egc_remain - 1) * 8];
1084                         egc_remain = 0;
1085                         egc_dstbit = 0;
1086                 }
1087         } else {
1088                 if(egc_remain >= 8) {
1089                         egc_remain -= 8;
1090                 } else {
1091                         egc_srcmask.b[ext] = egc_bytemask_u1[egc_remain - 1];
1092                         egc_remain = 0;
1093                 }
1094         }
1095         egc_vram_src.b[0][ext] = egc_outptr[0];
1096         egc_vram_src.b[1][ext] = egc_outptr[4];
1097         egc_vram_src.b[2][ext] = egc_outptr[8];
1098         egc_vram_src.b[3][ext] = egc_outptr[12];
1099         egc_outptr++;
1100 }
1101
1102 void DISPLAY::egc_sftb_dnn_sub(uint32_t ext)
1103 {
1104         if(egc_dstbit >= 8) {
1105                 egc_dstbit -= 8;
1106                 egc_srcmask.b[ext] = 0;
1107                 return;
1108         }
1109         if(egc_dstbit) {
1110                 if((egc_dstbit + egc_remain) >= 8) {
1111                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (7 * 8)];
1112                         egc_remain -= (8 - egc_dstbit);
1113                         egc_dstbit = 0;
1114                 } else {
1115                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (egc_remain - 1) * 8];
1116                         egc_remain = 0;
1117                         egc_dstbit = 0;
1118                 }
1119         } else {
1120                 if(egc_remain >= 8) {
1121                         egc_remain -= 8;
1122                 } else {
1123                         egc_srcmask.b[ext] = egc_bytemask_d1[egc_remain - 1];
1124                         egc_remain = 0;
1125                 }
1126         }
1127         egc_vram_src.b[0][ext] = egc_outptr[0];
1128         egc_vram_src.b[1][ext] = egc_outptr[4];
1129         egc_vram_src.b[2][ext] = egc_outptr[8];
1130         egc_vram_src.b[3][ext] = egc_outptr[12];
1131         egc_outptr--;
1132 }
1133
1134 void DISPLAY::egc_sftb_upr_sub(uint32_t ext)
1135 {
1136         if(egc_dstbit >= 8) {
1137                 egc_dstbit -= 8;
1138                 egc_srcmask.b[ext] = 0;
1139                 return;
1140         }
1141         if(egc_dstbit) {
1142                 if((egc_dstbit + egc_remain) >= 8) {
1143                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (7 * 8)];
1144                         egc_remain -= (8 - egc_dstbit);
1145                 } else {
1146                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (egc_remain - 1) * 8];
1147                         egc_remain = 0;
1148                 }
1149                 egc_dstbit = 0;
1150                 egc_vram_src.b[0][ext] = (egc_outptr[0] >> egc_sft8bitr);
1151                 egc_vram_src.b[1][ext] = (egc_outptr[4] >> egc_sft8bitr);
1152                 egc_vram_src.b[2][ext] = (egc_outptr[8] >> egc_sft8bitr);
1153                 egc_vram_src.b[3][ext] = (egc_outptr[12] >> egc_sft8bitr);
1154         } else {
1155                 if(egc_remain >= 8) {
1156                         egc_remain -= 8;
1157                 } else {
1158                         egc_srcmask.b[ext] = egc_bytemask_u1[egc_remain - 1];
1159                         egc_remain = 0;
1160                 }
1161                 egc_vram_src.b[0][ext] = (egc_outptr[0] << egc_sft8bitl) | (egc_outptr[1] >> egc_sft8bitr);
1162                 egc_vram_src.b[1][ext] = (egc_outptr[4] << egc_sft8bitl) | (egc_outptr[5] >> egc_sft8bitr);
1163                 egc_vram_src.b[2][ext] = (egc_outptr[8] << egc_sft8bitl) | (egc_outptr[9] >> egc_sft8bitr);
1164                 egc_vram_src.b[3][ext] = (egc_outptr[12] << egc_sft8bitl) | (egc_outptr[13] >> egc_sft8bitr);
1165                 egc_outptr++;
1166         }
1167 }
1168
1169 void DISPLAY::egc_sftb_dnr_sub(uint32_t ext)
1170 {
1171         if(egc_dstbit >= 8) {
1172                 egc_dstbit -= 8;
1173                 egc_srcmask.b[ext] = 0;
1174                 return;
1175         }
1176         if(egc_dstbit) {
1177                 if((egc_dstbit + egc_remain) >= 8) {
1178                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (7 * 8)];
1179                         egc_remain -= (8 - egc_dstbit);
1180                 } else {
1181                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (egc_remain - 1) * 8];
1182                         egc_remain = 0;
1183                 }
1184                 egc_dstbit = 0;
1185                 egc_vram_src.b[0][ext] = (egc_outptr[0] << egc_sft8bitr);
1186                 egc_vram_src.b[1][ext] = (egc_outptr[4] << egc_sft8bitr);
1187                 egc_vram_src.b[2][ext] = (egc_outptr[8] << egc_sft8bitr);
1188                 egc_vram_src.b[3][ext] = (egc_outptr[12] << egc_sft8bitr);
1189         } else {
1190                 if(egc_remain >= 8) {
1191                         egc_remain -= 8;
1192                 } else {
1193                         egc_srcmask.b[ext] = egc_bytemask_d1[egc_remain - 1];
1194                         egc_remain = 0;
1195                 }
1196                 egc_outptr--;
1197                 egc_vram_src.b[0][ext] = (egc_outptr[1] >> egc_sft8bitl) | (egc_outptr[0] << egc_sft8bitr);
1198                 egc_vram_src.b[1][ext] = (egc_outptr[5] >> egc_sft8bitl) | (egc_outptr[4] << egc_sft8bitr);
1199                 egc_vram_src.b[2][ext] = (egc_outptr[9] >> egc_sft8bitl) | (egc_outptr[8] << egc_sft8bitr);
1200                 egc_vram_src.b[3][ext] = (egc_outptr[13] >> egc_sft8bitl) | (egc_outptr[12] << egc_sft8bitr);
1201         }
1202 }
1203
1204 void DISPLAY::egc_sftb_upl_sub(uint32_t ext)
1205 {
1206         if(egc_dstbit >= 8) {
1207                 egc_dstbit -= 8;
1208                 egc_srcmask.b[ext] = 0;
1209                 return;
1210         }
1211         if(egc_dstbit) {
1212                 if((egc_dstbit + egc_remain) >= 8) {
1213                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (7 * 8)];
1214                         egc_remain -= (8 - egc_dstbit);
1215                         egc_dstbit = 0;
1216                 } else {
1217                         egc_srcmask.b[ext] = egc_bytemask_u0[egc_dstbit + (egc_remain - 1) * 8];
1218                         egc_remain = 0;
1219                         egc_dstbit = 0;
1220                 }
1221         } else {
1222                 if(egc_remain >= 8) {
1223                         egc_remain -= 8;
1224                 } else {
1225                         egc_srcmask.b[ext] = egc_bytemask_u1[egc_remain - 1];
1226                         egc_remain = 0;
1227                 }
1228         }
1229         egc_vram_src.b[0][ext] = (egc_outptr[0] << egc_sft8bitl) | (egc_outptr[1] >> egc_sft8bitr);
1230         egc_vram_src.b[1][ext] = (egc_outptr[4] << egc_sft8bitl) | (egc_outptr[5] >> egc_sft8bitr);
1231         egc_vram_src.b[2][ext] = (egc_outptr[8] << egc_sft8bitl) | (egc_outptr[9] >> egc_sft8bitr);
1232         egc_vram_src.b[3][ext] = (egc_outptr[12] << egc_sft8bitl) | (egc_outptr[13] >> egc_sft8bitr);
1233         egc_outptr++;
1234 }
1235
1236 void DISPLAY::egc_sftb_dnl_sub(uint32_t ext)
1237 {
1238         if(egc_dstbit >= 8) {
1239                 egc_dstbit -= 8;
1240                 egc_srcmask.b[ext] = 0;
1241                 return;
1242         }
1243         if(egc_dstbit) {
1244                 if((egc_dstbit + egc_remain) >= 8) {
1245                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (7 * 8)];
1246                         egc_remain -= (8 - egc_dstbit);
1247                         egc_dstbit = 0;
1248                 } else {
1249                         egc_srcmask.b[ext] = egc_bytemask_d0[egc_dstbit + (egc_remain - 1) * 8];
1250                         egc_remain = 0;
1251                         egc_dstbit = 0;
1252                 }
1253         } else {
1254                 if(egc_remain >= 8) {
1255                         egc_remain -= 8;
1256                 } else {
1257                         egc_srcmask.b[ext] = egc_bytemask_d1[egc_remain - 1];
1258                         egc_remain = 0;
1259                 }
1260         }
1261         egc_outptr--;
1262         egc_vram_src.b[0][ext] = (egc_outptr[1] >> egc_sft8bitl) | (egc_outptr[0] << egc_sft8bitr);
1263         egc_vram_src.b[1][ext] = (egc_outptr[5] >> egc_sft8bitl) | (egc_outptr[4] << egc_sft8bitr);
1264         egc_vram_src.b[2][ext] = (egc_outptr[9] >> egc_sft8bitl) | (egc_outptr[8] << egc_sft8bitr);
1265         egc_vram_src.b[3][ext] = (egc_outptr[13] >> egc_sft8bitl) | (egc_outptr[12] << egc_sft8bitr);
1266 }
1267
1268 void DISPLAY::egc_sftb_upn0(uint32_t ext)
1269 {
1270         if(egc_stack < (uint32_t)(8 - egc_dstbit)) {
1271                 egc_srcmask.b[ext] = 0;
1272                 return;
1273         }
1274         egc_stack -= (8 - egc_dstbit);
1275         egc_sftb_upn_sub(ext);
1276         if(!egc_remain) {
1277                 egc_shift();
1278         }
1279 }
1280
1281 void DISPLAY::egc_sftw_upn0()
1282 {
1283         if(egc_stack < (uint32_t)(16 - egc_dstbit)) {
1284                 egc_srcmask.w = 0;
1285                 return;
1286         }
1287         egc_stack -= (16 - egc_dstbit);
1288         egc_sftb_upn_sub(0);
1289         if(egc_remain) {
1290                 egc_sftb_upn_sub(1);
1291                 if(egc_remain) {
1292                         return;
1293                 }
1294         } else {
1295                 egc_srcmask.b[1] = 0;
1296         }
1297         egc_shift();
1298 }
1299
1300 void DISPLAY::egc_sftb_dnn0(uint32_t ext)
1301 {
1302         if(egc_stack < (uint32_t)(8 - egc_dstbit)) {
1303                 egc_srcmask.b[ext] = 0;
1304                 return;
1305         }
1306         egc_stack -= (8 - egc_dstbit);
1307         egc_sftb_dnn_sub(ext);
1308         if(!egc_remain) {
1309                 egc_shift();
1310         }
1311 }
1312
1313 void DISPLAY::egc_sftw_dnn0()
1314 {
1315         if(egc_stack < (uint32_t)(16 - egc_dstbit)) {
1316                 egc_srcmask.w = 0;
1317                 return;
1318         }
1319         egc_stack -= (16 - egc_dstbit);
1320         egc_sftb_dnn_sub(1);
1321         if(egc_remain) {
1322                 egc_sftb_dnn_sub(0);
1323                 if(egc_remain) {
1324                         return;
1325                 }
1326         } else {
1327                 egc_srcmask.b[0] = 0;
1328         }
1329         egc_shift();
1330 }
1331
1332 void DISPLAY::egc_sftb_upr0(uint32_t ext)
1333 {
1334         if(egc_stack < (uint32_t)(8 - egc_dstbit)) {
1335                 egc_srcmask.b[ext] = 0;
1336                 return;
1337         }
1338         egc_stack -= (8 - egc_dstbit);
1339         egc_sftb_upr_sub(ext);
1340         if(!egc_remain) {
1341                 egc_shift();
1342         }
1343 }
1344
1345 void DISPLAY::egc_sftw_upr0()
1346 {
1347         if(egc_stack < (uint32_t)(16 - egc_dstbit)) {
1348                 egc_srcmask.w = 0;
1349                 return;
1350         }
1351         egc_stack -= (16 - egc_dstbit);
1352         egc_sftb_upr_sub(0);
1353         if(egc_remain) {
1354                 egc_sftb_upr_sub(1);
1355                 if(egc_remain) {
1356                         return;
1357                 }
1358         } else {
1359                 egc_srcmask.b[1] = 0;
1360         }
1361         egc_shift();
1362 }
1363
1364 void DISPLAY::egc_sftb_dnr0(uint32_t ext)
1365 {
1366         if(egc_stack < (uint32_t)(8 - egc_dstbit)) {
1367                 egc_srcmask.b[ext] = 0;
1368                 return;
1369         }
1370         egc_stack -= (8 - egc_dstbit);
1371         egc_sftb_dnr_sub(ext);
1372         if(!egc_remain) {
1373                 egc_shift();
1374         }
1375 }
1376
1377 void DISPLAY::egc_sftw_dnr0()
1378 {
1379         if(egc_stack < (uint32_t)(16 - egc_dstbit)) {
1380                 egc_srcmask.w = 0;
1381                 return;
1382         }
1383         egc_stack -= (16 - egc_dstbit);
1384         egc_sftb_dnr_sub(1);
1385         if(egc_remain) {
1386                 egc_sftb_dnr_sub(0);
1387                 if(egc_remain) {
1388                         return;
1389                 }
1390         } else {
1391                 egc_srcmask.b[0] = 0;
1392         }
1393         egc_shift();
1394 }
1395
1396 void DISPLAY::egc_sftb_upl0(uint32_t ext)
1397 {
1398         if(egc_stack < (uint32_t)(8 - egc_dstbit)) {
1399                 egc_srcmask.b[ext] = 0;
1400                 return;
1401         }
1402         egc_stack -= (8 - egc_dstbit);
1403         egc_sftb_upl_sub(ext);
1404         if(!egc_remain) {
1405                 egc_shift();
1406         }
1407 }
1408
1409 void DISPLAY::egc_sftw_upl0()
1410 {
1411         if(egc_stack < (uint32_t)(16 - egc_dstbit)) {
1412                 egc_srcmask.w = 0;
1413                 return;
1414         }
1415         egc_stack -= (16 - egc_dstbit);
1416         egc_sftb_upl_sub(0);
1417         if(egc_remain) {
1418                 egc_sftb_upl_sub(1);
1419                 if(egc_remain) {
1420                         return;
1421                 }
1422         } else {
1423                 egc_srcmask.b[1] = 0;
1424         }
1425         egc_shift();
1426 }
1427
1428 void DISPLAY::egc_sftb_dnl0(uint32_t ext)
1429 {
1430         if(egc_stack < (uint32_t)(8 - egc_dstbit)) {
1431                 egc_srcmask.b[ext] = 0;
1432                 return;
1433         }
1434         egc_stack -= (8 - egc_dstbit);
1435         egc_sftb_dnl_sub(ext);
1436         if(!egc_remain) {
1437                 egc_shift();
1438         }
1439 }
1440
1441 void DISPLAY::egc_sftw_dnl0()
1442 {
1443         if(egc_stack < (uint32_t)(16 - egc_dstbit)) {
1444                 egc_srcmask.w = 0;
1445                 return;
1446         }
1447         egc_stack -= (16 - egc_dstbit);
1448         egc_sftb_dnl_sub(1);
1449         if(egc_remain) {
1450                 egc_sftb_dnl_sub(0);
1451                 if(egc_remain) {
1452                         return;
1453                 }
1454         } else {
1455                 egc_srcmask.b[0] = 0;
1456         }
1457         egc_shift();
1458 }
1459
1460 void DISPLAY::egc_sftb(int func, uint32_t ext)
1461 {
1462         switch(func) {
1463         case 0: egc_sftb_upn0(ext); break;
1464         case 1: egc_sftb_dnn0(ext); break;
1465         case 2: egc_sftb_upr0(ext); break;
1466         case 3: egc_sftb_dnr0(ext); break;
1467         case 4: egc_sftb_upl0(ext); break;
1468         case 5: egc_sftb_dnl0(ext); break;
1469         }
1470 }
1471
1472 void DISPLAY::egc_sftw(int func)
1473 {
1474         switch(func) {
1475         case 0: egc_sftw_upn0(); break;
1476         case 1: egc_sftw_dnn0(); break;
1477         case 2: egc_sftw_upr0(); break;
1478         case 3: egc_sftw_dnr0(); break;
1479         case 4: egc_sftw_upl0(); break;
1480         case 5: egc_sftw_dnl0(); break;
1481         }
1482 }
1483
1484 void DISPLAY::egc_shiftinput_byte(uint32_t ext)
1485 {
1486         if(egc_stack <= 16) {
1487                 if(egc_srcbit >= 8) {
1488                         egc_srcbit -= 8;
1489                 } else {
1490                         egc_stack += (8 - egc_srcbit);
1491                         egc_srcbit = 0;
1492                 }
1493                 if(!(egc_sft & 0x1000)) {
1494                         egc_inptr++;
1495                 } else {
1496                         egc_inptr--;
1497                 }
1498         }
1499         egc_srcmask.b[ext] = 0xff;
1500         egc_sftb(egc_func, ext);
1501 }
1502
1503 void DISPLAY::egc_shiftinput_incw()
1504 {
1505         if(egc_stack <= 16) {
1506                 egc_inptr += 2;
1507                 if(egc_srcbit >= 8) {
1508                         egc_outptr++;
1509                 }
1510                 egc_stack += (16 - egc_srcbit);
1511                 egc_srcbit = 0;
1512         }
1513         egc_srcmask.w = 0xffff;
1514         egc_sftw(egc_func);
1515 }
1516
1517 void DISPLAY::egc_shiftinput_decw()
1518 {
1519         if(egc_stack <= 16) {
1520                 egc_inptr -= 2;
1521                 if(egc_srcbit >= 8) {
1522                         egc_outptr--;
1523                 }
1524                 egc_stack += (16 - egc_srcbit);
1525                 egc_srcbit = 0;
1526         }
1527         egc_srcmask.w = 0xffff;
1528         egc_sftw(egc_func);
1529 }
1530
1531 #define EGC_OPE_SHIFTB(addr, value) \
1532         do { \
1533                 if(egc_ope & 0x400) { \
1534                         egc_inptr[ 0] = (uint8_t)value; \
1535                         egc_inptr[ 4] = (uint8_t)value; \
1536                         egc_inptr[ 8] = (uint8_t)value; \
1537                         egc_inptr[12] = (uint8_t)value; \
1538                         egc_shiftinput_byte(addr & 1); \
1539                 } \
1540         } while (0)
1541
1542 #define EGC_OPE_SHIFTW(value) \
1543         do { \
1544                 if(egc_ope & 0x400) { \
1545                         if(!(egc_sft & 0x1000)) { \
1546                                 egc_inptr[ 0] = (uint8_t)value; \
1547                                 egc_inptr[ 1] = (uint8_t)(value >> 8); \
1548                                 egc_inptr[ 4] = (uint8_t)value; \
1549                                 egc_inptr[ 5] = (uint8_t)(value >> 8); \
1550                                 egc_inptr[ 8] = (uint8_t)value; \
1551                                 egc_inptr[ 9] = (uint8_t)(value >> 8); \
1552                                 egc_inptr[12] = (uint8_t)value; \
1553                                 egc_inptr[13] = (uint8_t)(value >> 8); \
1554                                 egc_shiftinput_incw(); \
1555                         } else { \
1556                                 egc_inptr[-1] = (uint8_t)value; \
1557                                 egc_inptr[ 0] = (uint8_t)(value >> 8); \
1558                                 egc_inptr[ 3] = (uint8_t)value; \
1559                                 egc_inptr[ 4] = (uint8_t)(value >> 8); \
1560                                 egc_inptr[ 7] = (uint8_t)value; \
1561                                 egc_inptr[ 8] = (uint8_t)(value >> 8); \
1562                                 egc_inptr[11] = (uint8_t)value; \
1563                                 egc_inptr[12] = (uint8_t)(value >> 8); \
1564                                 egc_shiftinput_decw(); \
1565                         }  \
1566                 } \
1567         } while (0)
1568
1569 uint64_t DISPLAY::egc_ope_00(uint8_t ope, uint32_t addr)
1570 {
1571         return 0;
1572 }
1573
1574 uint64_t DISPLAY::egc_ope_0f(uint8_t ope, uint32_t addr)
1575 {
1576         egc_vram_data.d[0] = ~egc_vram_src.d[0];
1577         egc_vram_data.d[1] = ~egc_vram_src.d[1];
1578         return egc_vram_data.q;
1579 }
1580
1581 uint64_t DISPLAY::egc_ope_c0(uint8_t ope, uint32_t addr)
1582 {
1583         egcquad_t dst;
1584         
1585         dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]);
1586         dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]);
1587         dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]);
1588         dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]);
1589         egc_vram_data.d[0] = (egc_vram_src.d[0] & dst.d[0]);
1590         egc_vram_data.d[1] = (egc_vram_src.d[1] & dst.d[1]);
1591         return egc_vram_data.q;
1592 }
1593
1594 uint64_t DISPLAY::egc_ope_f0(uint8_t ope, uint32_t addr)
1595 {
1596         return egc_vram_src.q;
1597 }
1598
1599 uint64_t DISPLAY::egc_ope_fc(uint8_t ope, uint32_t addr)
1600 {
1601         egcquad_t dst;
1602
1603         dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]);
1604         dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]);
1605         dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]);
1606         dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]);
1607         egc_vram_data.d[0] = egc_vram_src.d[0];
1608         egc_vram_data.d[0] |= ((~egc_vram_src.d[0]) & dst.d[0]);
1609         egc_vram_data.d[1] = egc_vram_src.d[1];
1610         egc_vram_data.d[1] |= ((~egc_vram_src.d[1]) & dst.d[1]);
1611         return egc_vram_data.q;
1612 }
1613
1614 uint64_t DISPLAY::egc_ope_ff(uint8_t ope, uint32_t addr)
1615 {
1616         return ~0;
1617 }
1618
1619 uint64_t DISPLAY::egc_ope_nd(uint8_t ope, uint32_t addr)
1620 {
1621         egcquad_t pat;
1622
1623         switch(egc_fgbg & 0x6000) {
1624         case 0x2000:
1625                 pat.d[0] = egc_bgc.d[0];
1626                 pat.d[1] = egc_bgc.d[1];
1627                 break;
1628         case 0x4000:
1629                 pat.d[0] = egc_fgc.d[0];
1630                 pat.d[1] = egc_fgc.d[1];
1631                 break;
1632         default:
1633                 if((egc_ope & 0x0300) == 0x0100) {
1634                         pat.d[0] = egc_vram_src.d[0];
1635                         pat.d[1] = egc_vram_src.d[1];
1636                 } else {
1637                         pat.d[0] = egc_patreg.d[0];
1638                         pat.d[1] = egc_patreg.d[1];
1639                 }
1640                 break;
1641         }
1642         egc_vram_data.d[0] = 0;
1643         egc_vram_data.d[1] = 0;
1644         if(ope & 0x80) {
1645                 egc_vram_data.d[0] |= (pat.d[0] & egc_vram_src.d[0]);
1646                 egc_vram_data.d[1] |= (pat.d[1] & egc_vram_src.d[1]);
1647         }
1648         if(ope & 0x40) {
1649                 egc_vram_data.d[0] |= ((~pat.d[0]) & egc_vram_src.d[0]);
1650                 egc_vram_data.d[1] |= ((~pat.d[1]) & egc_vram_src.d[1]);
1651         }
1652         if(ope & 0x08) {
1653                 egc_vram_data.d[0] |= (pat.d[0] & (~egc_vram_src.d[0]));
1654                 egc_vram_data.d[1] |= (pat.d[1] & (~egc_vram_src.d[1]));
1655         }
1656         if(ope & 0x04) {
1657                 egc_vram_data.d[0] |= ((~pat.d[0]) & (~egc_vram_src.d[0]));
1658                 egc_vram_data.d[1] |= ((~pat.d[1]) & (~egc_vram_src.d[1]));
1659         }
1660         return egc_vram_data.q;
1661 }
1662
1663 uint64_t DISPLAY::egc_ope_np(uint8_t ope, uint32_t addr)
1664 {
1665         egcquad_t dst;
1666         
1667         dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]);
1668         dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]);
1669         dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]);
1670         dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]);
1671         
1672         egc_vram_data.d[0] = 0;
1673         egc_vram_data.d[1] = 0;
1674         if(ope & 0x80) {
1675                 egc_vram_data.d[0] |= (egc_vram_src.d[0] & dst.d[0]);
1676                 egc_vram_data.d[1] |= (egc_vram_src.d[1] & dst.d[1]);
1677         }
1678         if(ope & 0x20) {
1679                 egc_vram_data.d[0] |= (egc_vram_src.d[0] & (~dst.d[0]));
1680                 egc_vram_data.d[1] |= (egc_vram_src.d[1] & (~dst.d[1]));
1681         }
1682         if(ope & 0x08) {
1683                 egc_vram_data.d[0] |= ((~egc_vram_src.d[0]) & dst.d[0]);
1684                 egc_vram_data.d[1] |= ((~egc_vram_src.d[1]) & dst.d[1]);
1685         }
1686         if(ope & 0x02) {
1687                 egc_vram_data.d[0] |= ((~egc_vram_src.d[0]) & (~dst.d[0]));
1688                 egc_vram_data.d[1] |= ((~egc_vram_src.d[1]) & (~dst.d[1]));
1689         }
1690         return egc_vram_data.q;
1691 }
1692
1693 uint64_t DISPLAY::egc_ope_xx(uint8_t ope, uint32_t addr)
1694 {
1695         egcquad_t pat;
1696         egcquad_t dst;
1697         
1698         switch(egc_fgbg & 0x6000) {
1699         case 0x2000:
1700                 pat.d[0] = egc_bgc.d[0];
1701                 pat.d[1] = egc_bgc.d[1];
1702                 break;
1703         case 0x4000:
1704                 pat.d[0] = egc_fgc.d[0];
1705                 pat.d[1] = egc_fgc.d[1];
1706                 break;
1707         default:
1708                 if((egc_ope & 0x0300) == 0x0100) {
1709                         pat.d[0] = egc_vram_src.d[0];
1710                         pat.d[1] = egc_vram_src.d[1];
1711                 } else {
1712                         pat.d[0] = egc_patreg.d[0];
1713                         pat.d[1] = egc_patreg.d[1];
1714                 }
1715                 break;
1716         }
1717         dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]);
1718         dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]);
1719         dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]);
1720         dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]);
1721         
1722         egc_vram_data.d[0] = 0;
1723         egc_vram_data.d[1] = 0;
1724         if(ope & 0x80) {
1725                 egc_vram_data.d[0] |= (pat.d[0] & egc_vram_src.d[0] & dst.d[0]);
1726                 egc_vram_data.d[1] |= (pat.d[1] & egc_vram_src.d[1] & dst.d[1]);
1727         }
1728         if(ope & 0x40) {
1729                 egc_vram_data.d[0] |= ((~pat.d[0]) & egc_vram_src.d[0] & dst.d[0]);
1730                 egc_vram_data.d[1] |= ((~pat.d[1]) & egc_vram_src.d[1] & dst.d[1]);
1731         }
1732         if(ope & 0x20) {
1733                 egc_vram_data.d[0] |= (pat.d[0] & egc_vram_src.d[0] & (~dst.d[0]));
1734                 egc_vram_data.d[1] |= (pat.d[1] & egc_vram_src.d[1] & (~dst.d[1]));
1735         }
1736         if(ope & 0x10) {
1737                 egc_vram_data.d[0] |= ((~pat.d[0]) & egc_vram_src.d[0] & (~dst.d[0]));
1738                 egc_vram_data.d[1] |= ((~pat.d[1]) & egc_vram_src.d[1] & (~dst.d[1]));
1739         }
1740         if(ope & 0x08) {
1741                 egc_vram_data.d[0] |= (pat.d[0] & (~egc_vram_src.d[0]) & dst.d[0]);
1742                 egc_vram_data.d[1] |= (pat.d[1] & (~egc_vram_src.d[1]) & dst.d[1]);
1743         }
1744         if(ope & 0x04) {
1745                 egc_vram_data.d[0] |= ((~pat.d[0]) & (~egc_vram_src.d[0]) & dst.d[0]);
1746                 egc_vram_data.d[1] |= ((~pat.d[1]) & (~egc_vram_src.d[1]) & dst.d[1]);
1747         }
1748         if(ope & 0x02) {
1749                 egc_vram_data.d[0] |= (pat.d[0] & (~egc_vram_src.d[0]) & (~dst.d[0]));
1750                 egc_vram_data.d[1] |= (pat.d[1] & (~egc_vram_src.d[1]) & (~dst.d[1]));
1751         }
1752         if(ope & 0x01) {
1753                 egc_vram_data.d[0] |= ((~pat.d[0]) & (~egc_vram_src.d[0]) & (~dst.d[0]));
1754                 egc_vram_data.d[1] |= ((~pat.d[1]) & (~egc_vram_src.d[1]) & (~dst.d[1]));
1755         }
1756         return egc_vram_data.q;
1757 }
1758
1759 uint64_t DISPLAY::egc_opefn(uint32_t func, uint8_t ope, uint32_t addr)
1760 {
1761         switch(func & 0xff) {
1762         case 0x00: return egc_ope_00(ope, addr);
1763         case 0x01: return egc_ope_xx(ope, addr);
1764         case 0x02: return egc_ope_xx(ope, addr);
1765         case 0x03: return egc_ope_np(ope, addr);
1766         case 0x04: return egc_ope_xx(ope, addr);
1767         case 0x05: return egc_ope_nd(ope, addr);
1768         case 0x06: return egc_ope_xx(ope, addr);
1769         case 0x07: return egc_ope_xx(ope, addr);
1770         case 0x08: return egc_ope_xx(ope, addr);
1771         case 0x09: return egc_ope_xx(ope, addr);
1772         case 0x0a: return egc_ope_nd(ope, addr);
1773         case 0x0b: return egc_ope_xx(ope, addr);
1774         case 0x0c: return egc_ope_np(ope, addr);
1775         case 0x0d: return egc_ope_xx(ope, addr);
1776         case 0x0e: return egc_ope_xx(ope, addr);
1777         case 0x0f: return egc_ope_0f(ope, addr);
1778         case 0x10: return egc_ope_xx(ope, addr);
1779         case 0x11: return egc_ope_xx(ope, addr);
1780         case 0x12: return egc_ope_xx(ope, addr);
1781         case 0x13: return egc_ope_xx(ope, addr);
1782         case 0x14: return egc_ope_xx(ope, addr);
1783         case 0x15: return egc_ope_xx(ope, addr);
1784         case 0x16: return egc_ope_xx(ope, addr);
1785         case 0x17: return egc_ope_xx(ope, addr);
1786         case 0x18: return egc_ope_xx(ope, addr);
1787         case 0x19: return egc_ope_xx(ope, addr);
1788         case 0x1a: return egc_ope_xx(ope, addr);
1789         case 0x1b: return egc_ope_xx(ope, addr);
1790         case 0x1c: return egc_ope_xx(ope, addr);
1791         case 0x1d: return egc_ope_xx(ope, addr);
1792         case 0x1e: return egc_ope_xx(ope, addr);
1793         case 0x1f: return egc_ope_xx(ope, addr);
1794         case 0x20: return egc_ope_xx(ope, addr);
1795         case 0x21: return egc_ope_xx(ope, addr);
1796         case 0x22: return egc_ope_xx(ope, addr);
1797         case 0x23: return egc_ope_xx(ope, addr);
1798         case 0x24: return egc_ope_xx(ope, addr);
1799         case 0x25: return egc_ope_xx(ope, addr);
1800         case 0x26: return egc_ope_xx(ope, addr);
1801         case 0x27: return egc_ope_xx(ope, addr);
1802         case 0x28: return egc_ope_xx(ope, addr);
1803         case 0x29: return egc_ope_xx(ope, addr);
1804         case 0x2a: return egc_ope_xx(ope, addr);
1805         case 0x2b: return egc_ope_xx(ope, addr);
1806         case 0x2c: return egc_ope_xx(ope, addr);
1807         case 0x2d: return egc_ope_xx(ope, addr);
1808         case 0x2e: return egc_ope_xx(ope, addr);
1809         case 0x2f: return egc_ope_xx(ope, addr);
1810         case 0x30: return egc_ope_np(ope, addr);
1811         case 0x31: return egc_ope_xx(ope, addr);
1812         case 0x32: return egc_ope_xx(ope, addr);
1813         case 0x33: return egc_ope_np(ope, addr);
1814         case 0x34: return egc_ope_xx(ope, addr);
1815         case 0x35: return egc_ope_xx(ope, addr);
1816         case 0x36: return egc_ope_xx(ope, addr);
1817         case 0x37: return egc_ope_xx(ope, addr);
1818         case 0x38: return egc_ope_xx(ope, addr);
1819         case 0x39: return egc_ope_xx(ope, addr);
1820         case 0x3a: return egc_ope_xx(ope, addr);
1821         case 0x3b: return egc_ope_xx(ope, addr);
1822         case 0x3c: return egc_ope_np(ope, addr);
1823         case 0x3d: return egc_ope_xx(ope, addr);
1824         case 0x3e: return egc_ope_xx(ope, addr);
1825         case 0x3f: return egc_ope_np(ope, addr);
1826         case 0x40: return egc_ope_xx(ope, addr);
1827         case 0x41: return egc_ope_xx(ope, addr);
1828         case 0x42: return egc_ope_xx(ope, addr);
1829         case 0x43: return egc_ope_xx(ope, addr);
1830         case 0x44: return egc_ope_xx(ope, addr);
1831         case 0x45: return egc_ope_xx(ope, addr);
1832         case 0x46: return egc_ope_xx(ope, addr);
1833         case 0x47: return egc_ope_xx(ope, addr);
1834         case 0x48: return egc_ope_xx(ope, addr);
1835         case 0x49: return egc_ope_xx(ope, addr);
1836         case 0x4a: return egc_ope_xx(ope, addr);
1837         case 0x4b: return egc_ope_xx(ope, addr);
1838         case 0x4c: return egc_ope_xx(ope, addr);
1839         case 0x4d: return egc_ope_xx(ope, addr);
1840         case 0x4e: return egc_ope_xx(ope, addr);
1841         case 0x4f: return egc_ope_xx(ope, addr);
1842         case 0x50: return egc_ope_nd(ope, addr);
1843         case 0x51: return egc_ope_xx(ope, addr);
1844         case 0x52: return egc_ope_xx(ope, addr);
1845         case 0x53: return egc_ope_xx(ope, addr);
1846         case 0x54: return egc_ope_xx(ope, addr);
1847         case 0x55: return egc_ope_nd(ope, addr);
1848         case 0x56: return egc_ope_xx(ope, addr);
1849         case 0x57: return egc_ope_xx(ope, addr);
1850         case 0x58: return egc_ope_xx(ope, addr);
1851         case 0x59: return egc_ope_xx(ope, addr);
1852         case 0x5a: return egc_ope_nd(ope, addr);
1853         case 0x5b: return egc_ope_xx(ope, addr);
1854         case 0x5c: return egc_ope_xx(ope, addr);
1855         case 0x5d: return egc_ope_xx(ope, addr);
1856         case 0x5e: return egc_ope_xx(ope, addr);
1857         case 0x5f: return egc_ope_nd(ope, addr);
1858         case 0x60: return egc_ope_xx(ope, addr);
1859         case 0x61: return egc_ope_xx(ope, addr);
1860         case 0x62: return egc_ope_xx(ope, addr);
1861         case 0x63: return egc_ope_xx(ope, addr);
1862         case 0x64: return egc_ope_xx(ope, addr);
1863         case 0x65: return egc_ope_xx(ope, addr);
1864         case 0x66: return egc_ope_xx(ope, addr);
1865         case 0x67: return egc_ope_xx(ope, addr);
1866         case 0x68: return egc_ope_xx(ope, addr);
1867         case 0x69: return egc_ope_xx(ope, addr);
1868         case 0x6a: return egc_ope_xx(ope, addr);
1869         case 0x6b: return egc_ope_xx(ope, addr);
1870         case 0x6c: return egc_ope_xx(ope, addr);
1871         case 0x6d: return egc_ope_xx(ope, addr);
1872         case 0x6e: return egc_ope_xx(ope, addr);
1873         case 0x6f: return egc_ope_xx(ope, addr);
1874         case 0x70: return egc_ope_xx(ope, addr);
1875         case 0x71: return egc_ope_xx(ope, addr);
1876         case 0x72: return egc_ope_xx(ope, addr);
1877         case 0x73: return egc_ope_xx(ope, addr);
1878         case 0x74: return egc_ope_xx(ope, addr);
1879         case 0x75: return egc_ope_xx(ope, addr);
1880         case 0x76: return egc_ope_xx(ope, addr);
1881         case 0x77: return egc_ope_xx(ope, addr);
1882         case 0x78: return egc_ope_xx(ope, addr);
1883         case 0x79: return egc_ope_xx(ope, addr);
1884         case 0x7a: return egc_ope_xx(ope, addr);
1885         case 0x7b: return egc_ope_xx(ope, addr);
1886         case 0x7c: return egc_ope_xx(ope, addr);
1887         case 0x7d: return egc_ope_xx(ope, addr);
1888         case 0x7e: return egc_ope_xx(ope, addr);
1889         case 0x7f: return egc_ope_xx(ope, addr);
1890         case 0x80: return egc_ope_xx(ope, addr);
1891         case 0x81: return egc_ope_xx(ope, addr);
1892         case 0x82: return egc_ope_xx(ope, addr);
1893         case 0x83: return egc_ope_xx(ope, addr);
1894         case 0x84: return egc_ope_xx(ope, addr);
1895         case 0x85: return egc_ope_xx(ope, addr);
1896         case 0x86: return egc_ope_xx(ope, addr);
1897         case 0x87: return egc_ope_xx(ope, addr);
1898         case 0x88: return egc_ope_xx(ope, addr);
1899         case 0x89: return egc_ope_xx(ope, addr);
1900         case 0x8a: return egc_ope_xx(ope, addr);
1901         case 0x8b: return egc_ope_xx(ope, addr);
1902         case 0x8c: return egc_ope_xx(ope, addr);
1903         case 0x8d: return egc_ope_xx(ope, addr);
1904         case 0x8e: return egc_ope_xx(ope, addr);
1905         case 0x8f: return egc_ope_xx(ope, addr);
1906         case 0x90: return egc_ope_xx(ope, addr);
1907         case 0x91: return egc_ope_xx(ope, addr);
1908         case 0x92: return egc_ope_xx(ope, addr);
1909         case 0x93: return egc_ope_xx(ope, addr);
1910         case 0x94: return egc_ope_xx(ope, addr);
1911         case 0x95: return egc_ope_xx(ope, addr);
1912         case 0x96: return egc_ope_xx(ope, addr);
1913         case 0x97: return egc_ope_xx(ope, addr);
1914         case 0x98: return egc_ope_xx(ope, addr);
1915         case 0x99: return egc_ope_xx(ope, addr);
1916         case 0x9a: return egc_ope_xx(ope, addr);
1917         case 0x9b: return egc_ope_xx(ope, addr);
1918         case 0x9c: return egc_ope_xx(ope, addr);
1919         case 0x9d: return egc_ope_xx(ope, addr);
1920         case 0x9e: return egc_ope_xx(ope, addr);
1921         case 0x9f: return egc_ope_xx(ope, addr);
1922         case 0xa0: return egc_ope_nd(ope, addr);
1923         case 0xa1: return egc_ope_xx(ope, addr);
1924         case 0xa2: return egc_ope_xx(ope, addr);
1925         case 0xa3: return egc_ope_xx(ope, addr);
1926         case 0xa4: return egc_ope_xx(ope, addr);
1927         case 0xa5: return egc_ope_nd(ope, addr);
1928         case 0xa6: return egc_ope_xx(ope, addr);
1929         case 0xa7: return egc_ope_xx(ope, addr);
1930         case 0xa8: return egc_ope_xx(ope, addr);
1931         case 0xa9: return egc_ope_xx(ope, addr);
1932         case 0xaa: return egc_ope_nd(ope, addr);
1933         case 0xab: return egc_ope_xx(ope, addr);
1934         case 0xac: return egc_ope_xx(ope, addr);
1935         case 0xad: return egc_ope_xx(ope, addr);
1936         case 0xae: return egc_ope_xx(ope, addr);
1937         case 0xaf: return egc_ope_nd(ope, addr);
1938         case 0xb0: return egc_ope_xx(ope, addr);
1939         case 0xb1: return egc_ope_xx(ope, addr);
1940         case 0xb2: return egc_ope_xx(ope, addr);
1941         case 0xb3: return egc_ope_xx(ope, addr);
1942         case 0xb4: return egc_ope_xx(ope, addr);
1943         case 0xb5: return egc_ope_xx(ope, addr);
1944         case 0xb6: return egc_ope_xx(ope, addr);
1945         case 0xb7: return egc_ope_xx(ope, addr);
1946         case 0xb8: return egc_ope_xx(ope, addr);
1947         case 0xb9: return egc_ope_xx(ope, addr);
1948         case 0xba: return egc_ope_xx(ope, addr);
1949         case 0xbb: return egc_ope_xx(ope, addr);
1950         case 0xbc: return egc_ope_xx(ope, addr);
1951         case 0xbd: return egc_ope_xx(ope, addr);
1952         case 0xbe: return egc_ope_xx(ope, addr);
1953         case 0xbf: return egc_ope_xx(ope, addr);
1954         case 0xc0: return egc_ope_c0(ope, addr);
1955         case 0xc1: return egc_ope_xx(ope, addr);
1956         case 0xc2: return egc_ope_xx(ope, addr);
1957         case 0xc3: return egc_ope_np(ope, addr);
1958         case 0xc4: return egc_ope_xx(ope, addr);
1959         case 0xc5: return egc_ope_xx(ope, addr);
1960         case 0xc6: return egc_ope_xx(ope, addr);
1961         case 0xc7: return egc_ope_xx(ope, addr);
1962         case 0xc8: return egc_ope_xx(ope, addr);
1963         case 0xc9: return egc_ope_xx(ope, addr);
1964         case 0xca: return egc_ope_xx(ope, addr);
1965         case 0xcb: return egc_ope_xx(ope, addr);
1966         case 0xcc: return egc_ope_np(ope, addr);
1967         case 0xcd: return egc_ope_xx(ope, addr);
1968         case 0xce: return egc_ope_xx(ope, addr);
1969         case 0xcf: return egc_ope_np(ope, addr);
1970         case 0xd0: return egc_ope_xx(ope, addr);
1971         case 0xd1: return egc_ope_xx(ope, addr);
1972         case 0xd2: return egc_ope_xx(ope, addr);
1973         case 0xd3: return egc_ope_xx(ope, addr);
1974         case 0xd4: return egc_ope_xx(ope, addr);
1975         case 0xd5: return egc_ope_xx(ope, addr);
1976         case 0xd6: return egc_ope_xx(ope, addr);
1977         case 0xd7: return egc_ope_xx(ope, addr);
1978         case 0xd8: return egc_ope_xx(ope, addr);
1979         case 0xd9: return egc_ope_xx(ope, addr);
1980         case 0xda: return egc_ope_xx(ope, addr);
1981         case 0xdb: return egc_ope_xx(ope, addr);
1982         case 0xdc: return egc_ope_xx(ope, addr);
1983         case 0xdd: return egc_ope_xx(ope, addr);
1984         case 0xde: return egc_ope_xx(ope, addr);
1985         case 0xdf: return egc_ope_xx(ope, addr);
1986         case 0xe0: return egc_ope_xx(ope, addr);
1987         case 0xe1: return egc_ope_xx(ope, addr);
1988         case 0xe2: return egc_ope_xx(ope, addr);
1989         case 0xe3: return egc_ope_xx(ope, addr);
1990         case 0xe4: return egc_ope_xx(ope, addr);
1991         case 0xe5: return egc_ope_xx(ope, addr);
1992         case 0xe6: return egc_ope_xx(ope, addr);
1993         case 0xe7: return egc_ope_xx(ope, addr);
1994         case 0xe8: return egc_ope_xx(ope, addr);
1995         case 0xe9: return egc_ope_xx(ope, addr);
1996         case 0xea: return egc_ope_xx(ope, addr);
1997         case 0xeb: return egc_ope_xx(ope, addr);
1998         case 0xec: return egc_ope_xx(ope, addr);
1999         case 0xed: return egc_ope_xx(ope, addr);
2000         case 0xee: return egc_ope_xx(ope, addr);
2001         case 0xef: return egc_ope_xx(ope, addr);
2002         case 0xf0: return egc_ope_f0(ope, addr);
2003         case 0xf1: return egc_ope_xx(ope, addr);
2004         case 0xf2: return egc_ope_xx(ope, addr);
2005         case 0xf3: return egc_ope_np(ope, addr);
2006         case 0xf4: return egc_ope_xx(ope, addr);
2007         case 0xf5: return egc_ope_nd(ope, addr);
2008         case 0xf6: return egc_ope_xx(ope, addr);
2009         case 0xf7: return egc_ope_xx(ope, addr);
2010         case 0xf8: return egc_ope_xx(ope, addr);
2011         case 0xf9: return egc_ope_xx(ope, addr);
2012         case 0xfa: return egc_ope_nd(ope, addr);
2013         case 0xfb: return egc_ope_xx(ope, addr);
2014         case 0xfc: return egc_ope_fc(ope, addr);
2015         case 0xfd: return egc_ope_xx(ope, addr);
2016         case 0xfe: return egc_ope_xx(ope, addr);
2017         case 0xff: return egc_ope_ff(ope, addr);
2018 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
2019         default: __assume(0);
2020 #endif
2021         }
2022         return 0;
2023 }
2024
2025 uint64_t DISPLAY::egc_opeb(uint32_t addr, uint8_t value)
2026 {
2027         uint32_t tmp;
2028         
2029         egc_mask2.w = egc_mask.w;
2030         switch(egc_ope & 0x1800) {
2031         case 0x0800:
2032                 EGC_OPE_SHIFTB(addr, value);
2033                 egc_mask2.w &= egc_srcmask.w;
2034                 tmp = egc_ope & 0xff;
2035                 return egc_opefn(tmp, (uint8_t)tmp, addr & (~1));
2036         case 0x1000:
2037                 switch(egc_fgbg & 0x6000) {
2038                 case 0x2000:
2039                         return egc_bgc.q;
2040                 case 0x4000:
2041                         return egc_fgc.q;
2042                 default:
2043                         EGC_OPE_SHIFTB(addr, value);
2044                         egc_mask2.w &= egc_srcmask.w;
2045                         return egc_vram_src.q;
2046                 }
2047                 break;
2048         default:
2049                 tmp = value & 0xff;
2050                 tmp = tmp | (tmp << 8);
2051                 egc_vram_data.w[0] = (uint16_t)tmp;
2052                 egc_vram_data.w[1] = (uint16_t)tmp;
2053                 egc_vram_data.w[2] = (uint16_t)tmp;
2054                 egc_vram_data.w[3] = (uint16_t)tmp;
2055                 return egc_vram_data.q;
2056         }
2057 }
2058
2059 uint64_t DISPLAY::egc_opew(uint32_t addr, uint16_t value)
2060 {
2061         uint32_t tmp;
2062
2063         egc_mask2.w = egc_mask.w;
2064         switch(egc_ope & 0x1800) {
2065         case 0x0800:
2066                 EGC_OPE_SHIFTW(value);
2067                 egc_mask2.w &= egc_srcmask.w;
2068                 tmp = egc_ope & 0xff;
2069                 return egc_opefn(tmp, (uint8_t)tmp, addr);
2070         case 0x1000:
2071                 switch(egc_fgbg & 0x6000) {
2072                 case 0x2000:
2073                         return egc_bgc.q;
2074                 case 0x4000:
2075                         return egc_fgc.q;
2076                 default:
2077                         EGC_OPE_SHIFTW(value);
2078                         egc_mask2.w &= egc_srcmask.w;
2079                         return egc_vram_src.q;
2080                 }
2081                 break;
2082         default:
2083 #ifdef __BIG_ENDIAN__
2084                 value = ((value >> 8) & 0xff) | ((value & 0xff) << 8);
2085 #endif
2086                 egc_vram_data.w[0] = (uint16_t)value;
2087                 egc_vram_data.w[1] = (uint16_t)value;
2088                 egc_vram_data.w[2] = (uint16_t)value;
2089                 egc_vram_data.w[3] = (uint16_t)value;
2090                 return egc_vram_data.q;
2091         }
2092 }
2093
2094 uint32_t DISPLAY::egc_readb(uint32_t addr1)
2095 {
2096         uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK;
2097         uint32_t ext = addr1 & 1;
2098         
2099         egc_lastvram.b[0][ext] = vram_draw[addr | VRAM_PLANE_ADDR_0];
2100         egc_lastvram.b[1][ext] = vram_draw[addr | VRAM_PLANE_ADDR_1];
2101         egc_lastvram.b[2][ext] = vram_draw[addr | VRAM_PLANE_ADDR_2];
2102         egc_lastvram.b[3][ext] = vram_draw[addr | VRAM_PLANE_ADDR_3];
2103         
2104         if(!(egc_ope & 0x400)) {
2105                 egc_inptr[0] = egc_lastvram.b[0][ext];
2106                 egc_inptr[4] = egc_lastvram.b[1][ext];
2107                 egc_inptr[8] = egc_lastvram.b[2][ext];
2108                 egc_inptr[12] = egc_lastvram.b[3][ext];
2109                 egc_shiftinput_byte(ext);
2110         }
2111         if((egc_ope & 0x0300) == 0x0100) {
2112                 egc_patreg.b[0][ext] = vram_draw[addr | VRAM_PLANE_ADDR_0];
2113                 egc_patreg.b[1][ext] = vram_draw[addr | VRAM_PLANE_ADDR_1];
2114                 egc_patreg.b[2][ext] = vram_draw[addr | VRAM_PLANE_ADDR_2];
2115                 egc_patreg.b[3][ext] = vram_draw[addr | VRAM_PLANE_ADDR_3];
2116         }
2117         if(!(egc_ope & 0x2000)) {
2118                 int pl = (egc_fgbg >> 8) & 3;
2119                 if(!(egc_ope & 0x400)) {
2120                         return egc_vram_src.b[pl][ext];
2121                 } else {
2122                         return vram_draw[addr | (VRAM_PLANE_SIZE * pl)];
2123                 }
2124         }
2125         return vram_draw[addr1];
2126 }
2127
2128 uint32_t DISPLAY::egc_readw(uint32_t addr1)
2129 {
2130         uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK;
2131         
2132         if(!(addr & 1)) {
2133                 egc_lastvram.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]);
2134                 egc_lastvram.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]);
2135                 egc_lastvram.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]);
2136                 egc_lastvram.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]);
2137                 
2138                 if(!(egc_ope & 0x400)) {
2139                         if(!(egc_sft & 0x1000)) {
2140                                 egc_inptr[ 0] = egc_lastvram.b[0][0];
2141                                 egc_inptr[ 1] = egc_lastvram.b[0][1];
2142                                 egc_inptr[ 4] = egc_lastvram.b[1][0];
2143                                 egc_inptr[ 5] = egc_lastvram.b[1][1];
2144                                 egc_inptr[ 8] = egc_lastvram.b[2][0];
2145                                 egc_inptr[ 9] = egc_lastvram.b[2][1];
2146                                 egc_inptr[12] = egc_lastvram.b[3][0];
2147                                 egc_inptr[13] = egc_lastvram.b[3][1];
2148                                 egc_shiftinput_incw();
2149                         } else {
2150                                 egc_inptr[-1] = egc_lastvram.b[0][0];
2151                                 egc_inptr[ 0] = egc_lastvram.b[0][1];
2152                                 egc_inptr[ 3] = egc_lastvram.b[1][0];
2153                                 egc_inptr[ 4] = egc_lastvram.b[1][1];
2154                                 egc_inptr[ 7] = egc_lastvram.b[2][0];
2155                                 egc_inptr[ 8] = egc_lastvram.b[2][1];
2156                                 egc_inptr[11] = egc_lastvram.b[3][0];
2157                                 egc_inptr[12] = egc_lastvram.b[3][1];
2158                                 egc_shiftinput_decw();
2159                         }
2160                 }
2161                 if((egc_ope & 0x0300) == 0x0100) {
2162                         egc_patreg.d[0] = egc_lastvram.d[0];
2163                         egc_patreg.d[1] = egc_lastvram.d[1];
2164                 }
2165                 if(!(egc_ope & 0x2000)) {
2166                         int pl = (egc_fgbg >> 8) & 3;
2167                         if(!(egc_ope & 0x400)) {
2168                                 return egc_vram_src.w[pl];
2169                         } else {
2170                                 return *(uint16_t *)(&vram_draw[addr | (VRAM_PLANE_SIZE * pl)]);
2171                         }
2172                 }
2173                 return *(uint16_t *)(&vram_draw[addr1]);
2174         } else if(!(egc_sft & 0x1000)) {
2175                 uint16_t value = egc_readb(addr1);
2176                 value |= egc_readb(addr1 + 1) << 8;
2177                 return value;
2178         } else {
2179                 uint16_t value = egc_readb(addr1) << 8;
2180                 value |= egc_readb(addr1 + 1);
2181                 return value;
2182         }
2183 }
2184
2185 void DISPLAY::egc_writeb(uint32_t addr1, uint8_t value)
2186 {
2187         uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK;
2188         uint32_t ext = addr1 & 1;
2189         egcquad_t data;
2190         
2191         if((egc_ope & 0x0300) == 0x0200) {
2192                 egc_patreg.b[0][ext] = vram_draw[addr | VRAM_PLANE_ADDR_0];
2193                 egc_patreg.b[1][ext] = vram_draw[addr | VRAM_PLANE_ADDR_1];
2194                 egc_patreg.b[2][ext] = vram_draw[addr | VRAM_PLANE_ADDR_2];
2195                 egc_patreg.b[3][ext] = vram_draw[addr | VRAM_PLANE_ADDR_3];
2196         }
2197         data.q = egc_opeb(addr, value);
2198         if(egc_mask2.b[ext]) {
2199                 if(!(egc_access & 1)) {
2200                         vram_draw[addr | VRAM_PLANE_ADDR_0] &= ~egc_mask2.b[ext];
2201                         vram_draw[addr | VRAM_PLANE_ADDR_0] |= data.b[0][ext] & egc_mask2.b[ext];
2202                 }
2203                 if(!(egc_access & 2)) {
2204                         vram_draw[addr | VRAM_PLANE_ADDR_1] &= ~egc_mask2.b[ext];
2205                         vram_draw[addr | VRAM_PLANE_ADDR_1] |= data.b[1][ext] & egc_mask2.b[ext];
2206                 }
2207                 if(!(egc_access & 4)) {
2208                         vram_draw[addr | VRAM_PLANE_ADDR_2] &= ~egc_mask2.b[ext];
2209                         vram_draw[addr | VRAM_PLANE_ADDR_2] |= data.b[2][ext] & egc_mask2.b[ext];
2210                 }
2211                 if(!(egc_access & 8)) {
2212                         vram_draw[addr | VRAM_PLANE_ADDR_3] &= ~egc_mask2.b[ext];
2213                         vram_draw[addr | VRAM_PLANE_ADDR_3] |= data.b[3][ext] & egc_mask2.b[ext];
2214                 }
2215         }
2216 }
2217
2218 void DISPLAY::egc_writew(uint32_t addr1, uint16_t value)
2219 {
2220         uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK;
2221         egcquad_t data;
2222         
2223         if(!(addr & 1)) {
2224                 if((egc_ope & 0x0300) == 0x0200) {
2225                         egc_patreg.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]);
2226                         egc_patreg.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]);
2227                         egc_patreg.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]);
2228                         egc_patreg.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]);
2229                 }
2230                 data.q = egc_opew(addr, value);
2231                 if(egc_mask2.w) {
2232                         if(!(egc_access & 1)) {
2233                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]) &= ~egc_mask2.w;
2234                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]) |= data.w[0] & egc_mask2.w;
2235                         }
2236                         if(!(egc_access & 2)) {
2237                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]) &= ~egc_mask2.w;
2238                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]) |= data.w[1] & egc_mask2.w;
2239                         }
2240                         if(!(egc_access & 4)) {
2241                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]) &= ~egc_mask2.w;
2242                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]) |= data.w[2] & egc_mask2.w;
2243                         }
2244                         if(!(egc_access & 8)) {
2245                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]) &= ~egc_mask2.w;
2246                                 *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]) |= data.w[3] & egc_mask2.w;
2247                         }
2248                 }
2249         } else if(!(egc_sft & 0x1000)) {
2250                 egc_writeb(addr1, (uint8_t)value);
2251                 egc_writeb(addr1 + 1, (uint8_t)(value >> 8));
2252         } else {
2253                 egc_writeb(addr1, (uint8_t)(value >> 8));
2254                 egc_writeb(addr1 + 1, (uint8_t)value);
2255         }
2256 }
2257 #endif
2258
2259 void DISPLAY::draw_screen()
2260 {
2261         // render screen
2262         bool gdc_chr_start = d_gdc_chr->get_start();
2263         bool gdc_gfx_start = d_gdc_gfx->get_start();
2264         
2265         if(modereg1[MODE1_DISP] && (gdc_chr_start || gdc_gfx_start)) {
2266                 if(gdc_chr_start) {
2267                         draw_chr_screen();
2268                 } else {
2269                         memset(screen_chr, 0, sizeof(screen_chr));
2270                 }
2271                 if(gdc_gfx_start) {
2272                         draw_gfx_screen();
2273                 } else {
2274                         memset(screen_gfx, 0, sizeof(screen_gfx));
2275                 }
2276                 for(int y = 0; y < SCREEN_HEIGHT; y++) {
2277                         scrntype_t *dest = emu->get_screen_buffer(y);
2278                         uint8_t *src_chr = screen_chr[y];
2279 #if defined(SUPPORT_16_COLORS)
2280                         if(!modereg2[MDOE2_TXTSHIFT]) {
2281                                 src_chr++;
2282                         }
2283 #endif
2284                         uint8_t *src_gfx = screen_gfx[y];
2285                         
2286 #if defined(SUPPORT_16_COLORS)
2287                         if(!modereg2[MODE2_16COLOR]) {
2288 #endif
2289                                 for(int x = 0; x < SCREEN_WIDTH; x++) {
2290                                         uint8_t chr = src_chr[x];
2291                                         dest[x] = chr ? palette_chr[chr & 7] : palette_gfx8[src_gfx[x] & 7];
2292                                 }
2293 #if defined(SUPPORT_16_COLORS)
2294                         } else {
2295                                 for(int x = 0; x < SCREEN_WIDTH; x++) {
2296                                         uint8_t chr = src_chr[x];
2297                                         dest[x] = chr ? palette_chr[chr & 7] : palette_gfx16[src_gfx[x]];
2298                                 }
2299                         }
2300 #endif
2301                 }
2302         } else {
2303                 for(int y = 0; y < SCREEN_HEIGHT; y++) {
2304                         scrntype_t *dest = emu->get_screen_buffer(y);
2305                         memset(dest, 0, SCREEN_WIDTH * sizeof(scrntype_t));
2306                 }
2307         }
2308         emu->set_vm_screen_lines(SCREEN_HEIGHT);
2309         emu->screen_skip_line(false);
2310 }
2311
2312 void DISPLAY::draw_chr_screen()
2313 {
2314         // scroll registers
2315         int pl = scroll[SCROLL_PL] & 31;
2316         if(pl) {
2317                 pl = 32 - pl;
2318         }
2319         int bl = scroll[SCROLL_BL] + pl + 1;
2320         int cl = scroll[SCROLL_CL];
2321 #if defined(SUPPORT_HIRESO)
2322         bl <<= 1;
2323         cl <<= 1;
2324 #endif
2325         int ssl = scroll[SCROLL_SSL];
2326         int sur = scroll[SCROLL_SUR] & 31;
2327         if(sur) {
2328                 sur = 32 - sur;
2329         }
2330         int sdr = scroll[SCROLL_SDR] + 1;
2331         
2332         // address from gdc
2333         uint32_t gdc_addr[25][80] = {0};
2334         
2335         for(int i = 0, ytop = 0; i < 4; i++) {
2336                 uint32_t ra = ra_chr[i * 4];
2337                 ra |= ra_chr[i * 4 + 1] << 8;
2338                 ra |= ra_chr[i * 4 + 2] << 16;
2339                 ra |= ra_chr[i * 4 + 3] << 24;
2340                 uint32_t sad = (ra << 1) & 0x1fff;
2341                 int len = (ra >> 20) & 0x3ff;
2342                 
2343                 if(!len) len = 25;
2344                 
2345                 for(int y = ytop; y < (ytop + len) && y < 25; y++) {
2346                         for(int x = 0; x < 80; x++) {
2347                                 gdc_addr[y][x] = sad;
2348                                 sad = (sad + 2) & 0x1fff;
2349                         }
2350                 }
2351                 if((ytop += len) >= 25) break;
2352         }
2353         uint32_t *addr = &gdc_addr[0][0];
2354         uint32_t *addr2 = addr + 160 * (sur + sdr);
2355         
2356         uint32_t cursor_addr = d_gdc_chr->cursor_addr(0x1fff);
2357         int cursor_top = d_gdc_chr->cursor_top();
2358         int cursor_bottom = d_gdc_chr->cursor_bottom();
2359 #if defined(SUPPORT_HIRESO)
2360         cursor_top <<= 1;
2361         cursor_bottom <<= 1;
2362 #endif
2363         bool attr_blink = d_gdc_chr->attr_blink();
2364         
2365         // render
2366         int ysur = bl * sur;
2367         int ysdr = bl * (sur + sdr);
2368         int xofs = modereg1[MODE1_COLUMN] ? (FONT_WIDTH * 2) : FONT_WIDTH;
2369         int addrofs = modereg1[MODE1_COLUMN] ? 2 : 1;
2370         
2371         memset(screen_chr, 0, sizeof(screen_chr));
2372         
2373         for(int y = 0, cy = 0, ytop = 0; y < SCREEN_HEIGHT && cy < 25; y += bl, cy++) {
2374                 uint32_t gaiji1st = 0, last = 0, offset;
2375                 int kanji2nd = 0;
2376                 if(y == ysur) {
2377                         ytop = y;
2378                         y -= ssl;
2379                         ysur = SCREEN_HEIGHT;
2380                 }
2381                 if(y >= ysdr) {
2382                         y = ytop = ysdr;
2383                         addr = addr2;
2384                         ysdr = SCREEN_HEIGHT;
2385                 }
2386                 for(int x = 0, cx = 0; x < SCREEN_WIDTH && cx < 80; x += xofs, cx++) {
2387                         uint16_t code = *(uint16_t *)(tvram + (*addr));
2388                         uint8_t attr = tvram[(*addr) | 0x2000];
2389                         uint8_t color = (attr & ATTR_COL) ? (attr >> 5) : 8;
2390                         bool cursor = ((*addr) == cursor_addr);
2391                         addr += addrofs;
2392                         if(kanji2nd) {
2393                                 kanji2nd = 0;
2394                                 offset = last + KANJI_2ND_OFS;
2395                         } else if(code & 0xff00) {
2396                                 uint16_t lo = code & 0x7f;
2397                                 uint16_t hi = (code >> 8) & 0x7f;
2398                                 offset = FONT_SIZE * (lo | (hi << 8));
2399                                 if(lo == 0x56 || lo == 0x57) {
2400                                         offset += gaiji1st;
2401                                         gaiji1st = gaiji1st ? 0 : KANJI_2ND_OFS;
2402                                 } else {
2403                                         uint16_t lo = code & 0xff;
2404                                         if(lo < 0x09 || lo >= 0x0c) {
2405                                                 kanji2nd = 1;
2406                                         }
2407                                         gaiji1st = 0;
2408                                 }
2409                         } else {
2410                                 offset = ANK_FONT_OFS + FONT_SIZE * (code & 0xff);
2411 #if !defined(SUPPORT_HIRESO)
2412                                 if((attr & ATTR_VL) && modereg1[MODE1_ATRSEL]) {
2413                                         offset += FONT_SIZE * 0x100;
2414                                 }
2415                                 if(!modereg1[MODE1_FONTSEL]) {
2416                                         offset += FONT_SIZE * 0x200;
2417                                 }
2418 #endif
2419                                 gaiji1st = 0;
2420                         }
2421                         last = offset;
2422                         
2423                         for(int l = 0; l < bl; l++) {
2424                                 int yy = y + l + pl;
2425                                 if(yy >= ytop && yy < SCREEN_HEIGHT) {
2426                                         uint8_t *dest = &screen_chr[yy][x];
2427 #if !defined(SUPPORT_HIRESO)
2428                                         uint8_t pattern = (l < cl && l < FONT_HEIGHT) ? font[offset + l] : 0;
2429 #else
2430                                         uint16_t pattern = (l < cl && l < FONT_HEIGHT) ? *(uint16_t *)(&font[offset + l * 2]) : 0;
2431 #endif
2432                                         if(!(attr & ATTR_ST)) {
2433                                                 pattern = 0;
2434                                         } else if(((attr & ATTR_BL) && attr_blink) || (attr & ATTR_RV)) {
2435                                                 pattern = ~pattern;
2436                                         }
2437                                         if((attr & ATTR_UL) && l == (FONT_HEIGHT - 1)) {
2438 #if !defined(SUPPORT_HIRESO)
2439                                                 pattern = 0xff;
2440 #else
2441                                                 pattern = 0x3ff;
2442 #endif
2443                                         }
2444                                         if((attr & ATTR_VL) && !modereg1[MODE1_ATRSEL]) {
2445 #if !defined(SUPPORT_HIRESO)
2446                                                 pattern |= 0x08;
2447 #else
2448                                                 pattern |= 0x40;
2449 #endif
2450                                         }
2451                                         if(cursor && l >= cursor_top && l < cursor_bottom) {
2452                                                 pattern = ~pattern;
2453                                         }
2454                                         if(modereg1[MODE1_COLUMN]) {
2455 #if !defined(SUPPORT_HIRESO)
2456                                                 if(pattern & 0x80) dest[ 0] = dest[ 1] = color;
2457                                                 if(pattern & 0x40) dest[ 2] = dest[ 3] = color;
2458                                                 if(pattern & 0x20) dest[ 4] = dest[ 5] = color;
2459                                                 if(pattern & 0x10) dest[ 6] = dest[ 7] = color;
2460                                                 if(pattern & 0x08) dest[ 8] = dest[ 9] = color;
2461                                                 if(pattern & 0x04) dest[10] = dest[11] = color;
2462                                                 if(pattern & 0x02) dest[12] = dest[13] = color;
2463                                                 if(pattern & 0x01) dest[14] = dest[15] = color;
2464 #else
2465                                                 if(pattern & 0x2000) dest[ 0] = dest[ 1] = color;
2466                                                 if(pattern & 0x1000) dest[ 2] = dest[ 3] = color;
2467                                                 if(pattern & 0x0800) dest[ 4] = dest[ 5] = color;
2468                                                 if(pattern & 0x0400) dest[ 6] = dest[ 7] = color;
2469                                                 if(pattern & 0x0200) dest[ 8] = dest[ 9] = color;
2470                                                 if(pattern & 0x0100) dest[10] = dest[11] = color;
2471                                                 if(pattern & 0x0080) dest[12] = dest[13] = color;
2472                                                 if(pattern & 0x0040) dest[14] = dest[15] = color;
2473                                                 if(pattern & 0x0020) dest[16] = dest[17] = color;
2474                                                 if(pattern & 0x0010) dest[18] = dest[19] = color;
2475                                                 if(pattern & 0x0008) dest[20] = dest[21] = color;
2476                                                 if(pattern & 0x0004) dest[22] = dest[23] = color;
2477                                                 if(pattern & 0x0002) dest[24] = dest[25] = color;
2478                                                 if(pattern & 0x0001) dest[26] = dest[27] = color;
2479 #endif
2480                                         } else {
2481 #if !defined(SUPPORT_HIRESO)
2482                                                 if(pattern & 0x80) dest[0] = color;
2483                                                 if(pattern & 0x40) dest[1] = color;
2484                                                 if(pattern & 0x20) dest[2] = color;
2485                                                 if(pattern & 0x10) dest[3] = color;
2486                                                 if(pattern & 0x08) dest[4] = color;
2487                                                 if(pattern & 0x04) dest[5] = color;
2488                                                 if(pattern & 0x02) dest[6] = color;
2489                                                 if(pattern & 0x01) dest[7] = color;
2490 #else
2491                                                 if(pattern & 0x2000) dest[ 0] = color;
2492                                                 if(pattern & 0x1000) dest[ 1] = color;
2493                                                 if(pattern & 0x0800) dest[ 2] = color;
2494                                                 if(pattern & 0x0400) dest[ 3] = color;
2495                                                 if(pattern & 0x0200) dest[ 4] = color;
2496                                                 if(pattern & 0x0100) dest[ 5] = color;
2497                                                 if(pattern & 0x0080) dest[ 6] = color;
2498                                                 if(pattern & 0x0040) dest[ 7] = color;
2499                                                 if(pattern & 0x0020) dest[ 8] = color;
2500                                                 if(pattern & 0x0010) dest[ 9] = color;
2501                                                 if(pattern & 0x0008) dest[10] = color;
2502                                                 if(pattern & 0x0004) dest[11] = color;
2503                                                 if(pattern & 0x0002) dest[12] = color;
2504                                                 if(pattern & 0x0001) dest[13] = color;
2505 #endif
2506                                         }
2507                                 }
2508                         }
2509                 }
2510         }
2511 }
2512
2513 void DISPLAY::draw_gfx_screen()
2514 {
2515         // address from gdc
2516         uint32_t gdc_addr[SCREEN_HEIGHT][SCREEN_WIDTH >> 3] = {0};
2517         
2518         for(int i = 0, ytop = 0; i < 4; i++) {
2519                 uint32_t ra = ra_gfx[i * 4];
2520                 ra |= ra_gfx[i * 4 + 1] << 8;
2521                 ra |= ra_gfx[i * 4 + 2] << 16;
2522                 ra |= ra_gfx[i * 4 + 3] << 24;
2523                 uint32_t sad = (ra << 1) & VRAM_PLANE_ADDR_MASK;
2524                 int len = (ra >> 20) & 0x3ff;
2525                 
2526                 if(!len) len = SCREEN_HEIGHT; // Madou Monogatari 1-2-3
2527                 
2528                 for(int y = ytop; y < (ytop + len) && y < SCREEN_HEIGHT; y++) {
2529                         for(int x = 0; x < (SCREEN_WIDTH >> 3); x++) {
2530                                 gdc_addr[y][x] = sad;
2531                                 sad = (sad + 1) & VRAM_PLANE_ADDR_MASK;
2532                         }
2533                 }
2534                 if((ytop += len) >= SCREEN_HEIGHT) break;
2535         }
2536         uint32_t *addr = &gdc_addr[0][0];
2537         uint8_t *dest = &screen_gfx[0][0];
2538         
2539         for(int y = 0; y < SCREEN_HEIGHT; y++) {
2540                 for(int x = 0; x < SCREEN_WIDTH; x += 8) {
2541                         uint8_t b = vram_disp_b[(*addr)];
2542                         uint8_t r = vram_disp_r[(*addr)];
2543                         uint8_t g = vram_disp_g[(*addr)];
2544 #if defined(SUPPORT_16_COLORS)
2545                         uint8_t e = vram_disp_e[(*addr)];
2546 #else
2547                         uint8_t e = 0;
2548 #endif
2549                         addr++;
2550                         
2551                         *dest++ = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5) | ((e & 0x80) >> 4);
2552                         *dest++ = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4) | ((e & 0x40) >> 3);
2553                         *dest++ = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3) | ((e & 0x20) >> 2);
2554                         *dest++ = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2) | ((e & 0x10) >> 1);
2555                         *dest++ = ((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1) | ((e & 0x08)     );
2556                         *dest++ = ((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04)     ) | ((e & 0x04) << 1);
2557                         *dest++ = ((b & 0x02) >> 1) | ((r & 0x02)     ) | ((g & 0x02) << 1) | ((e & 0x02) << 2);
2558                         *dest++ = ((b & 0x01)     ) | ((r & 0x01) << 1) | ((g & 0x01) << 2) | ((e & 0x01) << 3);
2559                 }
2560                 if((cs_gfx[0] & 0x1f) == 1) {
2561                         // 200 line
2562                         if(modereg1[MODE1_200LINE]) {
2563                                 //memset(dest, 0, 640);
2564                                 if(config.scan_line) {
2565                                         memset(dest, 0, SCREEN_WIDTH);
2566                                 } else {
2567                                         my_memcpy(dest, dest - SCREEN_WIDTH, SCREEN_WIDTH);
2568                                 }                                       
2569                         } else {
2570                                 //my_memcpy(dest, dest - 640, 640);
2571                                 my_memcpy(dest, dest - SCREEN_WIDTH, SCREEN_WIDTH);
2572                         }
2573                         dest += 640;
2574                         y++;
2575                 }
2576         }
2577 }
2578
2579 #define STATE_VERSION   3
2580
2581 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
2582 {
2583         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
2584                 return false;
2585         }
2586         if(!state_fio->StateCheckInt32(this_device_id)) {
2587                 return false;
2588         }
2589         state_fio->StateBuffer(tvram, sizeof(tvram), 1);
2590         state_fio->StateBuffer(vram, sizeof(vram), 1);
2591 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
2592         state_fio->StateUint8(vram_disp_sel);
2593         state_fio->StateUint8(vram_draw_sel);
2594 #endif
2595         //state_fio->StateBuffer(palette_gfx8, sizeof(palette_gfx8), 1);
2596         if(loading) {
2597                 for(int i = 0; i < (sizeof(palette_gfx8) / sizeof(scrntype_t)); i++) {
2598                         uint8_t r, g, b;
2599                         r = state_fio->FgetUint8();
2600                         g = state_fio->FgetUint8();
2601                         b = state_fio->FgetUint8();
2602                         palette_gfx8[i] = RGB_COLOR(r, g, b);
2603                 }
2604         } else {
2605                 for(int i = 0; i < (sizeof(palette_gfx8) / sizeof(scrntype_t)); i++) {
2606                         uint8_t r, g, b;
2607                         r = R_OF_COLOR(palette_gfx8[i]);
2608                         g = G_OF_COLOR(palette_gfx8[i]);
2609                         b = B_OF_COLOR(palette_gfx8[i]);
2610                         state_fio->FputUint8(r);
2611                         state_fio->FputUint8(g);
2612                         state_fio->FputUint8(b);
2613                 }
2614         }
2615         state_fio->StateBuffer(digipal, sizeof(digipal), 1);
2616 #if defined(SUPPORT_16_COLORS)
2617         //state_fio->StateBuffer(palette_gfx16, sizeof(palette_gfx16), 1);      
2618         if(loading) {
2619                 for(int i = 0; i < (sizeof(palette_gfx16) / sizeof(scrntype_t)); i++) {
2620                         uint8_t r, g, b;
2621                         r = state_fio->FgetUint8();
2622                         g = state_fio->FgetUint8();
2623                         b = state_fio->FgetUint8();
2624                         palette_gfx16[i] = RGB_COLOR(r, g, b);
2625                 }
2626         } else {
2627                 for(int i = 0; i < (sizeof(palette_gfx16) / sizeof(scrntype_t)); i++) {
2628                         uint8_t r, g, b;
2629                         r = R_OF_COLOR(palette_gfx16[i]);
2630                         g = G_OF_COLOR(palette_gfx16[i]);
2631                         b = B_OF_COLOR(palette_gfx16[i]);
2632                         state_fio->FputUint8(r);
2633                         state_fio->FputUint8(g);
2634                         state_fio->FputUint8(b);
2635                 }
2636         }
2637         state_fio->StateBuffer(anapal, sizeof(anapal), 1);
2638         state_fio->StateUint8(anapal_sel);
2639 #endif
2640         state_fio->StateUint8(crtv);
2641         state_fio->StateBuffer(scroll, sizeof(scroll), 1);
2642         state_fio->StateBuffer(modereg1, sizeof(modereg1), 1);
2643 #if defined(SUPPORT_16_COLORS)
2644         state_fio->StateBuffer(modereg2, sizeof(modereg2), 1);
2645 #endif
2646 #if defined(SUPPORT_GRCG)
2647         state_fio->StateUint8(grcg_mode);
2648         state_fio->StateUint8(grcg_tile_ptr);
2649         state_fio->StateBuffer(grcg_tile, sizeof(grcg_tile), 1);
2650 #endif
2651 #if defined(SUPPORT_EGC)
2652         state_fio->StateUint16(egc_access);
2653         state_fio->StateUint16(egc_fgbg);
2654         state_fio->StateUint16(egc_ope);
2655         state_fio->StateUint16(egc_fg);
2656         state_fio->StateUint16(egc_mask.w);
2657         state_fio->StateUint16(egc_bg);
2658         state_fio->StateUint16(egc_sft);
2659         state_fio->StateUint16(egc_leng);
2660         state_fio->StateUint64(egc_lastvram.q);
2661         state_fio->StateUint64(egc_patreg.q);
2662         state_fio->StateUint64(egc_fgc.q);
2663         state_fio->StateUint64(egc_bgc.q);
2664         state_fio->StateInt32(egc_func);
2665         state_fio->StateUint32(egc_remain);
2666         state_fio->StateUint32(egc_stack);
2667         if(loading) {
2668                 int inptr_ofs = state_fio->FgetInt32_LE();
2669                 int outptr_ofs = state_fio->FgetInt32_LE();
2670                 egc_inptr = egc_buf + inptr_ofs;
2671                 egc_outptr = egc_buf + outptr_ofs;
2672         } else {
2673                 int inptr_ofs = egc_inptr - egc_buf;
2674                 int outptr_ofs = egc_outptr - egc_buf;
2675                 state_fio->FputInt32_LE(inptr_ofs);
2676                 state_fio->FputInt32_LE(outptr_ofs);
2677         }
2678         state_fio->StateUint16(egc_mask2.w);
2679         state_fio->StateUint16(egc_srcmask.w);
2680         state_fio->StateUint8(egc_srcbit);
2681         state_fio->StateUint8(egc_dstbit);
2682         state_fio->StateUint8(egc_sft8bitl);
2683         state_fio->StateUint8(egc_sft8bitr);
2684         state_fio->StateBuffer(egc_buf, sizeof(egc_buf), 1);
2685         state_fio->StateUint64(egc_vram_src.q);
2686         state_fio->StateUint64(egc_vram_data.q);
2687 #endif
2688         state_fio->StateUint16(font_code);
2689         state_fio->StateUint8(font_line);
2690 //      state_fio->StateUint16(font_lr);
2691         
2692         // post process
2693 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
2694         if(loading) {
2695                 if(vram_disp_sel & 1) {
2696                         vram_disp_b = vram + 0x28000;
2697                         vram_disp_r = vram + 0x30000;
2698                         vram_disp_g = vram + 0x38000;
2699 #if defined(SUPPORT_16_COLORS)
2700                         vram_disp_e = vram + 0x20000;
2701 #endif
2702                 } else {
2703                         vram_disp_b = vram + 0x08000;
2704                         vram_disp_r = vram + 0x10000;
2705                         vram_disp_g = vram + 0x18000;
2706 #if defined(SUPPORT_16_COLORS)
2707                         vram_disp_e = vram + 0x00000;
2708 #endif
2709                 }
2710                 if(vram_draw_sel & 1) {
2711                         vram_draw = vram + 0x20000;
2712                 } else {
2713                         vram_draw = vram + 0x00000;
2714                 }
2715         }
2716 #endif
2717         return true;
2718 }
2719
2720 }