OSDN Git Service

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