rtoss - Blame information for rev 79

Subversion Repositories:
Rev:
Rev Author Line No. Line
74 roytam 1 /*
77 roytam 2  * QEMU NEC PC-9821 VGA
74 roytam 3  *
4  * Copyright (c) 2009 TAKEDA, toshiya
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24  
25 /* TODO: TARGET_WORDS_BIGENDIAN */
26  
27 #include "hw.h"
28 #include "pc.h"
29 #include "isa.h"
30 #include "sysemu.h"
31 #include "console.h"
32 #include "pixel_ops.h"
33 #include "qemu-timer.h"
34 #include "loader.h"
35  
36 #define TVRAM_SIZE      0x4000
37 #define VRAM16_SIZE     0x40000
38 #define VRAM256_SIZE    0x80000
39 #define EMS_SIZE        0x10000
78 roytam 40 #define SMRAM_SIZE      0x20000
74 roytam 41  
42 #define GDC_BUFFERS     1024
43 #define GDC_TABLEMAX    0x1000
44  
45 struct gdc_t;
46 typedef struct gdc_t gdc_t;
47  
48 struct egc_t;
49 typedef struct egc_t egc_t;
50  
51 struct vga_t;
52 typedef struct vga_t vga_t;
53  
54 struct gdc_t {
55     void *vga;
56  
78 roytam 57     /* vram access */
58     IOPortReadFunc *vram_read;
59     IOPortWriteFunc *vram_write;
74 roytam 60  
61     /* address */
62     uint32_t address[480][80];
63  
64     /* registers */
65     int cmdreg;
66     uint8_t statreg;
67  
68     /* params */
69     uint8_t sync[16];
70     uint8_t zoom, zr, zw;
71     uint8_t ra[16];
72     uint8_t cs[3];
73     uint8_t pitch;
74     uint32_t lad;
75     uint8_t vect[11];
76     uint32_t ead, dad;
77     uint8_t maskl, maskh;
78     uint8_t mod;
79     uint8_t start;
80     uint8_t dirty;
81  
82     /* fifo buffers */
83     uint8_t params[16];
84     int params_count;
85     uint8_t data[GDC_BUFFERS];
86     int data_count, data_read, data_write;
87  
88     /* draw */
89     int rt[GDC_TABLEMAX + 1];
90     int dx, dy;
91     int dir, diff, sl, dc, d, d2, d1, dm;
92     uint16_t pattern;
93 };
94  
95 typedef union {
96     uint8_t b[2];
97     uint16_t w;
98 } egcword_t;
99  
100 typedef union {
101     uint8_t b[4][2];
102     uint16_t w[4];
103     uint32_t d[2];
104     uint64_t q;
105 } egcquad_t;
106  
107 struct egc_t {
108     void *vga;
109  
110     uint16_t access;
111     uint16_t fgbg;
112     uint16_t ope;
113     uint16_t fg;
114     egcword_t mask;
115     uint16_t bg;
116     uint16_t sft;
117     uint16_t leng;
118     egcquad_t lastvram;
119     egcquad_t patreg;
120     egcquad_t fgc;
121     egcquad_t bgc;
122     int func;
123     uint32_t remain;
124     uint32_t stack;
125     uint8_t *inptr;
126     int inptr_vmstate;
127     uint8_t *outptr;
128     int outptr_vmstate;
129     egcword_t mask2;
130     egcword_t srcmask;
131     uint8_t srcbit;
132     uint8_t dstbit;
133     uint8_t sft8bitl;
134     uint8_t sft8bitr;
135     uint32_t padding_b[4];
136     uint32_t padding_a[4];
137     uint8_t buf[528];   /* 4096/8 + 4*4 */
138  
139     /* vram */
140     uint8_t *vram_ptr;
141     uint8_t *vram_b;
142     uint8_t *vram_r;
143     uint8_t *vram_g;
144     uint8_t *vram_e;
145     egcquad_t vram_src;
146     egcquad_t vram_data;
147 };
148  
149 struct vga_t {
150     DisplayState *ds;
151     uint8_t tvram_buffer[480 * 640];
152     uint8_t vram0_buffer[480 * 640];
153     uint8_t vram1_buffer[480 * 640];
154     uint8_t null_buffer[480 * 640];
155     int width;
156     int height;
157     int last_width;
158     int last_height;
159     uint8_t dirty;
78 roytam 160     uint8_t blink;
74 roytam 161     uint32_t palette_chr[8];
162     uint32_t palette_gfx[256];
163  
164     uint8_t font[0x84000];
165     uint8_t tvram[TVRAM_SIZE];
166     uint8_t vram16[VRAM16_SIZE];
167     uint8_t vram256[VRAM256_SIZE];
168     uint8_t ems[EMS_SIZE];
169     uint8_t *vram16_disp_b;
170     uint8_t *vram16_disp_r;
171     uint8_t *vram16_disp_g;
172     uint8_t *vram16_disp_e;
173     uint8_t *vram16_draw_b;
174     uint8_t *vram16_draw_r;
175     uint8_t *vram16_draw_g;
176     uint8_t *vram16_draw_e;
177     uint8_t *vram256_disp;
178     uint8_t *vram256_draw_0;
179     uint8_t *vram256_draw_1;
180  
181     struct gdc_t gdc_chr;
182     struct gdc_t gdc_gfx;
183     struct egc_t egc;
184  
185     uint8_t grcg_mode;
186     uint8_t grcg_tile_cnt;
187     uint8_t grcg_tile_b[4];
188     uint16_t grcg_tile_w[4];
189  
190     uint8_t crtv;
191     uint8_t pl;
192     uint8_t bl;
193     uint8_t cl;
194     uint8_t ssl;
195     uint8_t sur;
196     uint8_t sdr;
197  
77 roytam 198     uint8_t mode1[8];
199     uint8_t mode2[128];
200     uint8_t mode3[128];
74 roytam 201     uint8_t mode_select;
202  
203     uint8_t digipal[4];
204     uint8_t anapal[3][256];
205     uint8_t anapal_select;
206  
207     uint8_t bank_draw;
208     uint8_t bank_disp;
209     uint8_t bank256_draw_0;
210     uint8_t bank256_draw_1;
211     uint16_t vram256_bank_0;
212     uint16_t vram256_bank_1;
213     uint8_t ems_selected;
214  
215     uint8_t swdip[24];
216     uint8_t swdip_bank;
217  
218     uint8_t gaiji[512 * 64];
219     uint8_t font_code1;
220     uint8_t font_code2;
221     uint8_t font_line;
222  
79 roytam 223     void* cirrus_vga;
224     uint8_t cirrus_regnum;
225     uint8_t cirrus_reg[256];
226     uint8_t prev_vga;
227  
74 roytam 228     QEMUTimer *vsync_timer;
229     qemu_irq irq;
230     int64_t vsync_clock;
231 };
232  
79 roytam 233 enum {
234     MODE1_ATRSEL        = 0x00,
235     MODE1_GRAPHIC       = 0x01,
236     MODE1_COLUMN        = 0x02,
237     MODE1_FONTSEL       = 0x03,
238     MODE1_200LINE       = 0x04,
239     MODE1_KAC           = 0x05,
240     MODE1_MEMSW         = 0x06,
241     MODE1_DISP          = 0x07,
242 };
243  
244 enum {
245     MODE2_16COLOR       = 0x00,
246     MODE2_EGC           = 0x02,
247     MODE2_WRITE_MASK    = 0x03,
248     MODE2_256COLOR      = 0x10,
249     MODE2_480LINE       = 0x34,
250     MODE2_CIRRUS        = 0x47,
251 };
252  
253 enum {
254     MODE3_WRITE_MASK    = 0x01,
255     MODE3_LINE_COLOR    = 0x09,
256     MODE3_NPC_COLOR     = 0x0b,
257     MODE3_LINE_CONNECT  = 0x0f,
258 };
259  
260 enum {
261     GRCG_PLANE_0        = 0x01,
262     GRCG_PLANE_1        = 0x02,
263     GRCG_PLANE_2        = 0x04,
264     GRCG_PLANE_3        = 0x08,
265     GRCG_PLANE_SEL      = 0x30,
266     GRCG_RW_MODE        = 0x40,
267     GRCG_CG_MODE        = 0x80,
268 };
269  
74 roytam 270 /***********************************************************/
77 roytam 271 /* NEC uPD7220 GDC */
74 roytam 272  
273 /*
77 roytam 274  * PC-9821 CRT sync timing (24.83KHz/400L monitor)
74 roytam 275  *
276  * VCLOCK = 56.43;
277  * VLINES = 440;
278 */
279  
79 roytam 280 #define GDC_VTICKS   18
281 #define GDC_VSTICKS  2
74 roytam 282  
77 roytam 283 enum {
79 roytam 284     GDC_CMD_RESET    = 0x00,
285     GDC_CMD_SYNC     = 0x0e,
286     GDC_CMD_SLAVE    = 0x6e,
287     GDC_CMD_MASTER   = 0x6f,
288     GDC_CMD_START    = 0x6b,
289     GDC_CMD_BCTRL    = 0x0c,
290     GDC_CMD_ZOOM     = 0x46,
291     GDC_CMD_SCROLL   = 0x70,
292     GDC_CMD_CSRFORM  = 0x4b,
293     GDC_CMD_PITCH    = 0x47,
294     GDC_CMD_LPEN     = 0xc0,
295     GDC_CMD_VECTW    = 0x4c,
296     GDC_CMD_VECTE    = 0x6c,
297     GDC_CMD_TEXTW    = 0x78,
298     GDC_CMD_TEXTE    = 0x68,
299     GDC_CMD_CSRW     = 0x49,
300     GDC_CMD_CSRR     = 0xe0,
301     GDC_CMD_MASK     = 0x4a,
302     GDC_CMD_WRITE    = 0x20,
303     GDC_CMD_READ     = 0xa0,
304     GDC_CMD_DMAR     = 0xa4,
305     GDC_CMD_DMAW     = 0x24,
77 roytam 306     /* unknown command (3 params) */
79 roytam 307     GDC_CMD_UNK_5A   = 0x5a,
77 roytam 308 };
74 roytam 309  
77 roytam 310 enum {
79 roytam 311     GDC_STAT_DRDY    = 0x01,
312     GDC_STAT_FULL    = 0x02,
313     GDC_STAT_EMPTY   = 0x04,
314     GDC_STAT_DRAW    = 0x08,
315     GDC_STAT_DMA     = 0x10,
316     GDC_STAT_VSYNC   = 0x20,
317     GDC_STAT_HBLANK  = 0x40,
318     GDC_STAT_LPEN    = 0x80,
77 roytam 319 };
74 roytam 320  
77 roytam 321 enum {
79 roytam 322     GDC_DIRTY_VRAM   = 0x01,
323     GDC_DIRTY_START  = 0x02,
324     GDC_DIRTY_SCROLL = 0x04,
325     GDC_DIRTY_CURSOR = 0x08,
326     GDC_DIRTY_GFX    = GDC_DIRTY_VRAM | GDC_DIRTY_SCROLL,
327     GDC_DIRTY_CHR    = GDC_DIRTY_GFX | GDC_DIRTY_CURSOR,
77 roytam 328 };
329  
79 roytam 330 #define GDC_MULBIT   15
331 #define GDC_TABLEBIT 12
74 roytam 332  
333 /* draw command */
334  
335 static const int gdc_vectdir[16][4] = {
336     { 0, 1, 1, 0}, { 1, 1, 1,-1}, { 1, 0, 0,-1}, { 1,-1,-1,-1},
337     { 0,-1,-1, 0}, {-1,-1,-1, 1}, {-1, 0, 0, 1}, {-1, 1, 1, 1},
338     { 0, 1, 1, 1}, { 1, 1, 1, 0}, { 1, 0, 1,-1}, { 1,-1, 0,-1},
339     { 0,-1,-1,-1}, {-1,-1,-1, 0}, {-1, 0,-1, 1}, {-1, 1, 0, 1}
340 };
341  
342 static void gdc_draw_pset(void *opaque, int x, int y)
343 {
344     gdc_t *s = opaque;
78 roytam 345     vga_t *v = s->vga;
346     uint16_t dot = s->pattern & 1;
347     uint32_t addr = y * 80 + (x >> 3) + 0x8000;
348     uint8_t bit = 0x80 >> (x & 7);
349     uint8_t cur = s->vram_read(v, addr);
74 roytam 350  
78 roytam 351     s->pattern = (s->pattern >> 1) | (dot << 15);
74 roytam 352  
78 roytam 353     switch (s->mod) {
354     case 0: /* replace */
355         s->vram_write(v, addr, (cur & ~bit) | (dot ? bit : 0));
356         break;
357     case 1: /* complement */
358         s->vram_write(v, addr, (cur & ~bit) | ((cur ^ (dot ? 0xff : 0)) & bit));
359         break;
360     case 2: /* reset */
361         s->vram_write(v, addr, cur & (dot ? ~bit : 0xff));
362         break;
363     case 3: /* set */
364         s->vram_write(v, addr, cur | (dot ? bit : 0));
365         break;
74 roytam 366     }
78 roytam 367     s->dirty |= GDC_DIRTY_VRAM;
74 roytam 368 }
369  
370 static void gdc_draw_vectl(void *opaque)
371 {
372     gdc_t *s = opaque;
373  
374     s->pattern = s->ra[8] | (s->ra[9] << 8);
375     if (s->dc) {
376         int x = s->dx, y = s->dy;
377         int i;
378  
379         switch (s->dir) {
380         case 0:
381             for (i = 0; i <= s->dc; i++) {
382                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
383                 gdc_draw_pset(s, x + step, y++);
384             }
385             break;
386         case 1:
387             for (i = 0; i <= s->dc; i++) {
388                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
389                 gdc_draw_pset(s, x++, y + step);
390             }
391             break;
392         case 2:
393             for (i = 0; i <= s->dc; i++) {
394                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
395                 gdc_draw_pset(s, x++, y - step);
396             }
397             break;
398         case 3:
399             for (i = 0; i <= s->dc; i++) {
400                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
401                 gdc_draw_pset(s, x + step, y--);
402             }
403             break;
404         case 4:
405             for (i = 0; i <= s->dc; i++) {
406                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
407                 gdc_draw_pset(s, x - step, y--);
408             }
409             break;
410         case 5:
411             for (i = 0; i <= s->dc; i++) {
412                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
413                 gdc_draw_pset(s, x--, y - step);
414             }
415             break;
416         case 6:
417             for (i = 0; i <= s->dc; i++) {
418                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
419                 gdc_draw_pset(s, x--, y + step);
420             }
421             break;
422         case 7:
423             for (i = 0; i <= s->dc; i++) {
424                 int step = (int)((((s->d1 * i) / s->dc) + 1) >> 1);
425                 gdc_draw_pset(s, x - step, y++);
426             }
427             break;
428         }
429     } else {
430         gdc_draw_pset(s, s->dx, s->dy);
431     }
432 }
433  
434 static void gdc_draw_vectt(void *opaque)
435 {
436     gdc_t *s = opaque;
437     int vx1 = gdc_vectdir[s->dir][0];
438     int vy1 = gdc_vectdir[s->dir][1];
439     int vx2 = gdc_vectdir[s->dir][2];
440     int vy2 = gdc_vectdir[s->dir][3];
441     int muly = s->zw + 1;
442     uint16_t draw = s->ra[8] | (s->ra[9] << 8);
443  
444     if (s->sl) {
445         draw = (draw & 0x0001 ? 0x8000 : 0) | (draw & 0x0002 ? 0x4000 : 0) |
446                (draw & 0x0004 ? 0x2000 : 0) | (draw & 0x0008 ? 0x1000 : 0) |
447                (draw & 0x0010 ? 0x0800 : 0) | (draw & 0x0020 ? 0x0400 : 0) |
448                (draw & 0x0040 ? 0x0200 : 0) | (draw & 0x0080 ? 0x0100 : 0) |
449                (draw & 0x0100 ? 0x0080 : 0) | (draw & 0x0200 ? 0x0040 : 0) |
450                (draw & 0x0400 ? 0x0020 : 0) | (draw & 0x0800 ? 0x0010 : 0) |
451                (draw & 0x1000 ? 0x0008 : 0) | (draw & 0x2000 ? 0x0004 : 0) |
452                (draw & 0x8000 ? 0x0002 : 0) | (draw & 0x8000 ? 0x0001 : 0);
453     }
454     s->pattern = 0xffff;
455     while(muly--) {
456         int cx = s->dx;
457         int cy = s->dy;
458         int xrem = s->d;
459         while(xrem--) {
460             int mulx = s->zw + 1;
461             if (draw & 1) {
462                 draw >>= 1;
463                 draw |= 0x8000;
464                 while(mulx--) {
465                     gdc_draw_pset(s, cx, cy);
466                     cx += vx1;
467                     cy += vy1;
468                 }
469             } else {
470                 draw >>= 1;
471                 while(mulx--) {
472                     cx += vx1;
473                     cy += vy1;
474                 }
475             }
476         }
477         s->dx += vx2;
478         s->dy += vy2;
479     }
480     s->ead = (s->dx >> 4) + s->dy * s->pitch;
481     s->dad = s->dx & 0x0f;
482 }
483  
484 static void gdc_draw_vectc(void *opaque)
485 {
486     gdc_t *s = opaque;
487     int m = (s->d * 10000 + 14141) / 14142;
488     int t = (s->dc > m) ? m : s->dc;
489     int i;
490  
491     s->pattern = s->ra[8] | (s->ra[9] << 8);
492     if (m) {
493         switch (s->dir) {
494         case 0:
495             for (i = s->dm; i <= t; i++) {
496                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
497                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
498                 gdc_draw_pset(s, (s->dx + c), (s->dy + i));
499             }
500             break;
501         case 1:
502             for (i = s->dm; i <= t; i++) {
503                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
504                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
505                 gdc_draw_pset(s, (s->dx + i), (s->dy + c));
506             }
507             break;
508         case 2:
509             for (i = s->dm; i <= t; i++) {
510                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
511                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
512                 gdc_draw_pset(s, (s->dx + i), (s->dy - c));
513             }
514             break;
515         case 3:
516             for (i = s->dm; i <= t; i++) {
517                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
518                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
519                 gdc_draw_pset(s, (s->dx + c), (s->dy - i));
520             }
521             break;
522         case 4:
523             for (i = s->dm; i <= t; i++) {
524                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
525                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
526                 gdc_draw_pset(s, (s->dx - c), (s->dy - i));
527             }
528             break;
529         case 5:
530             for (i = s->dm; i <= t; i++) {
531                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
532                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
533                 gdc_draw_pset(s, (s->dx - i), (s->dy - c));
534             }
535             break;
536         case 6:
537             for (i = s->dm; i <= t; i++) {
538                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
539                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
540                 gdc_draw_pset(s, (s->dx - i), (s->dy + c));
541             }
542             break;
543         case 7:
544             for (i = s->dm; i <= t; i++) {
545                 int c = (s->rt[(i << GDC_TABLEBIT) / m] * s->d);
546                 c = (c + (1 << (GDC_MULBIT - 1))) >> GDC_MULBIT;
547                 gdc_draw_pset(s, (s->dx - c), (s->dy + i));
548             }
549             break;
550         }
551     } else {
552         gdc_draw_pset(s, s->dx, s->dy);
553     }
554 }
555  
556 static void gdc_draw_vectr(void *opaque)
557 {
558     gdc_t *s = opaque;
559     int vx1 = gdc_vectdir[s->dir][0];
560     int vy1 = gdc_vectdir[s->dir][1];
561     int vx2 = gdc_vectdir[s->dir][2];
562     int vy2 = gdc_vectdir[s->dir][3];
563     int i;
564  
565     s->pattern = s->ra[8] | (s->ra[9] << 8);
566     for (i = 0; i < s->d; i++) {
567         gdc_draw_pset(s, s->dx, s->dy);
568         s->dx += vx1;
569         s->dy += vy1;
570     }
571     for (i = 0; i < s->d2; i++) {
572         gdc_draw_pset(s, s->dx, s->dy);
573         s->dx += vx2;
574         s->dy += vy2;
575     }
576     for (i = 0; i < s->d; i++) {
577         gdc_draw_pset(s, s->dx, s->dy);
578         s->dx -= vx1;
579         s->dy -= vy1;
580     }
581     for (i = 0; i < s->d2; i++) {
582         gdc_draw_pset(s, s->dx, s->dy);
583         s->dx -= vx2;
584         s->dy -= vy2;
585     }
586     s->ead = (s->dx >> 4) + s->dy * s->pitch;
587     s->dad = s->dx & 0x0f;
588 }
589  
590 static void gdc_draw_text(void *opaque)
591 {
592     gdc_t *s = opaque;
593     int dir = s->dir + (s->sl ? 8 : 0);
594     int vx1 = gdc_vectdir[dir][0];
595     int vy1 = gdc_vectdir[dir][1];
596     int vx2 = gdc_vectdir[dir][2];
597     int vy2 = gdc_vectdir[dir][3];
598     int sx = s->d;
599     int sy = s->dc + 1;
600     int index = 15;
601  
602     while(sy--) {
603         int muly = s->zw + 1;
604         while(muly--) {
605             int cx = s->dx;
606             int cy = s->dy;
607             uint8_t bit = s->ra[index];
608             int xrem = sx;
609             while(xrem--) {
610                 s->pattern = (bit & 1) ? 0xffff : 0;
611                 bit = (bit >> 1) | ((bit & 1) ? 0x80 : 0);
612                 int mulx = s->zw + 1;
613                 while(mulx--) {
614                     gdc_draw_pset(s, cx, cy);
615                     cx += vx1;
616                     cy += vy1;
617                 }
618             }
619             s->dx += vx2;
620             s->dy += vy2;
621         }
622         index = ((index - 1) & 7) | 8;
623     }
624     s->ead = (s->dx >> 4) + s->dy * s->pitch;
625     s->dad = s->dx & 0x0f;
626 }
627  
628 /* command sub */
629  
630 static void gdc_update_vect(void *opaque)
631 {
632     gdc_t *s = opaque;
633  
634     s->dir = s->vect[0] & 7;
635     s->diff = gdc_vectdir[s->dir][0] + gdc_vectdir[s->dir][1] * s->pitch;
636     s->sl = s->vect[0] & 0x80;
637     s->dc = (s->vect[1] | (s->vect[ 2] << 8)) & 0x3fff;
638     s->d  = (s->vect[3] | (s->vect[ 4] << 8)) & 0x3fff;
639     s->d2 = (s->vect[5] | (s->vect[ 6] << 8)) & 0x3fff;
640     s->d1 = (s->vect[7] | (s->vect[ 8] << 8)) & 0x3fff;
641     s->dm = (s->vect[9] | (s->vect[10] << 8)) & 0x3fff;
642 }
643  
644 static void gdc_reset_vect(void *opaque)
645 {
646     gdc_t *s = opaque;
647  
648     s->vect[ 1] = 0;
649     s->vect[ 2] = 0;
650     s->vect[ 3] = 8;
651     s->vect[ 4] = 0;
652     s->vect[ 5] = 8;
653     s->vect[ 6] = 0;
654     s->vect[ 7] = 0;
655     s->vect[ 8] = 0;
656     s->vect[ 9] = 0;
657     s->vect[10] = 0;
658     gdc_update_vect(s);
659 }
660  
661 static void gdc_write_sub(void *opaque, uint32_t addr, uint8_t value)
662 {
663     gdc_t *s = opaque;
78 roytam 664     vga_t *v = s->vga;
74 roytam 665  
78 roytam 666     switch (s->mod) {
667     case 0: /* replace */
668         s->vram_write(v, addr, value);
669         break;
670     case 1: /* complement */
671         s->vram_write(v, addr, s->vram_read(v, addr) ^ value);
672         break;
673     case 2: /* reset */
674         s->vram_write(v, addr, s->vram_read(v, addr) & ~value);
675         break;
676     case 3: /* set */
677         s->vram_write(v, addr, s->vram_read(v, addr) | value);
678         break;
74 roytam 679     }
78 roytam 680     s->dirty |= GDC_DIRTY_VRAM;
74 roytam 681 }
682  
683 static uint8_t gdc_read_sub(void *opaque, uint32_t addr)
684 {
685     gdc_t *s = opaque;
78 roytam 686     vga_t *v = s->vga;
74 roytam 687  
78 roytam 688     return s->vram_read(v, addr);
74 roytam 689 }
690  
691 static void gdc_fifo_write(void *opaque, uint8_t value)
692 {
693     gdc_t *s = opaque;
694  
695     if (s->data_count < GDC_BUFFERS) {
696         s->data[(s->data_write++) & (GDC_BUFFERS - 1)] = value;
697         s->data_count++;
698     }
699 }
700  
701 static uint8_t gdc_fifo_read(void *opaque)
702 {
703     gdc_t *s = opaque;
704  
705     if (s->data_count > 0) {
706         uint8_t value = s->data[(s->data_read++) & (GDC_BUFFERS - 1)];
707         s->data_count--;
708         return value;
709     }
710     return 0;
711 }
712  
713 /* command */
714  
715 static void gdc_cmd_reset(void *opaque)
716 {
717     gdc_t *s = opaque;
718  
719     s->sync[6] = 0x90;
720     s->sync[7] = 0x01;
721     s->zoom = s->zr = s->zw = 0;
722     s->ra[0] = s->ra[1] = s->ra[2] = 0;
723     s->ra[3] = 0x1e; /*0x19;*/
724     s->cs[0] = s->cs[1] = s->cs[2] = 0;
725     s->ead = s->dad = 0;
726     s->maskl = s->maskh = 0xff;
727     s->mod = 0;
728     s->start = 0;
729  
730     s->params_count = 0;
731     s->data_count = s->data_read = s->data_write = 0;
732  
733     s->statreg = 0;
734     s->cmdreg = -1;
735     s->dirty = 0xff;
736 }
737  
738 static void gdc_cmd_sync(void *opaque)
739 {
740     gdc_t *s = opaque;
741     int i;
742  
743     for (i = 0; i < 8 && i < s->params_count; i++) {
744         s->sync[i] = s->params[i];
745     }
746     s->cmdreg = -1;
747 }
748  
749 static void gdc_cmd_master(void *opaque)
750 {
751     gdc_t *s = opaque;
752  
753     s->cmdreg = -1;
754 }
755  
756 static void gdc_cmd_slave(void *opaque)
757 {
758     gdc_t *s = opaque;
759  
760     s->cmdreg = -1;
761 }
762  
763 static void gdc_cmd_start(void *opaque)
764 {
765     gdc_t *s = opaque;
766  
767     if (!s->start) {
768         s->start = 1;
77 roytam 769         s->dirty |= GDC_DIRTY_START;
74 roytam 770     }
771     s->cmdreg = -1;
772 }
773  
774 static void gdc_cmd_stop(void *opaque)
775 {
776     gdc_t *s = opaque;
777  
778     if (s->start) {
779         s->start = 0;
77 roytam 780         s->dirty |= GDC_DIRTY_START;
74 roytam 781     }
782     s->cmdreg = -1;
783 }
784  
785 static void gdc_cmd_zoom(void *opaque)
786 {
787     gdc_t *s = opaque;
788  
789     if (s->params_count > 0) {
790         uint8_t tmp = s->params[0];
791         s->zr = tmp >> 4;
792         s->zw = tmp & 0x0f;
793         s->cmdreg = -1;
794     }
795 }
796  
797 static void gdc_cmd_scroll(void *opaque)
798 {
799     gdc_t *s = opaque;
800  
801     if (s->params_count > 0) {
802         if (s->ra[s->cmdreg & 0x0f] != s->params[0]) {
803             s->ra[s->cmdreg & 0x0f] = s->params[0];
77 roytam 804             s->dirty |= GDC_DIRTY_SCROLL;
74 roytam 805         }
806         if (s->cmdreg < 0x7f) {
807             s->cmdreg++;
808             s->params_count = 0;
809         } else {
810             s->cmdreg = -1;
811         }
812     }
813 }
814  
815 static void gdc_cmd_csrform(void *opaque)
816 {
817     gdc_t *s = opaque;
79 roytam 818     int i;
74 roytam 819  
79 roytam 820     for (i = 0; i < s->params_count; i++) {
821         if (s->cs[i] != s->params[i]) {
822             s->cs[i] = s->params[i];
823             s->dirty |= GDC_DIRTY_CURSOR;
824         }
825     }
74 roytam 826     if (s->params_count > 2) {
827         s->cmdreg = -1;
828     }
829 }
830  
831 static void gdc_cmd_pitch(void *opaque)
832 {
833     gdc_t *s = opaque;
834  
835     if (s->params_count > 0) {
836         s->pitch = s->params[0];
837         s->cmdreg = -1;
838     }
839 }
840  
841 static void gdc_cmd_lpen(void *opaque)
842 {
843     gdc_t *s = opaque;
844  
845     gdc_fifo_write(s, s->lad & 0xff);
846     gdc_fifo_write(s, (s->lad >> 8) & 0xff);
847     gdc_fifo_write(s, (s->lad >> 16) & 0xff);
848     s->cmdreg = -1;
849 }
850  
851 static void gdc_cmd_vectw(void *opaque)
852 {
853     gdc_t *s = opaque;
854     int i;
855  
856     for (i = 0; i < 11 && i < s->params_count; i++) {
857         s->vect[i] = s->params[i];
858     }
859     gdc_update_vect(s);
860     s->cmdreg = -1;
861 }
862  
863 static void gdc_cmd_vecte(void *opaque)
864 {
865     gdc_t *s = opaque;
866  
867     s->dx = ((s->ead % s->pitch) << 4) | (s->dad & 0x0f);
868     s->dy = s->ead / s->pitch;
869     if (!(s->vect[0] & 0x78)) {
870         s->pattern = s->ra[8] | (s->ra[9] << 8);
871         gdc_draw_pset(s, s->dx, s->dy);
872     }
873     if (s->vect[0] & 0x08) {
874         gdc_draw_vectl(s);
875     }
876     if (s->vect[0] & 0x10) {
877         gdc_draw_vectt(s);
878     }
879     if (s->vect[0] & 0x20) {
880         gdc_draw_vectc(s);
881     }
882     if (s->vect[0] & 0x40) {
883         gdc_draw_vectr(s);
884     }
885     gdc_reset_vect(s);
886     s->statreg |= GDC_STAT_DRAW;
887     s->cmdreg = -1;
888 }
889  
890 static void gdc_cmd_texte(void *opaque)
891 {
892     gdc_t *s = opaque;
893  
894     s->dx = ((s->ead % s->pitch) << 4) | (s->dad & 0x0f);
895     s->dy = s->ead / s->pitch;
896     if (!(s->vect[0] & 0x78)) {
897         s->pattern = s->ra[8] | (s->ra[9] << 8);
898         gdc_draw_pset(s, s->dx, s->dy);
899     }
900     if (s->vect[0] & 0x08) {
901         gdc_draw_vectl(s);
902     }
903     if (s->vect[0] & 0x10) {
904         gdc_draw_text(s);
905     }
906     if (s->vect[0] & 0x20) {
907         gdc_draw_vectc(s);
908     }
909     if (s->vect[0] & 0x40) {
910         gdc_draw_vectr(s);
911     }
912     gdc_reset_vect(s);
913     s->statreg |= GDC_STAT_DRAW;
914     s->cmdreg = -1;
915 }
916  
917 static void gdc_cmd_csrw(void *opaque)
918 {
919     gdc_t *s = opaque;
920  
921     if (s->params_count > 0) {
922         s->ead = s->params[0];
923         if (s->params_count > 1) {
924             s->ead |= s->params[1] << 8;
925             if (s->params_count > 2) {
926                 s->ead |= s->params[2] << 16;
79 roytam 927                 s->cmdreg = -1;
74 roytam 928             }
929         }
930         s->dad = (s->ead >> 20) & 0x0f;
931         s->ead &= 0x3ffff;
79 roytam 932         s->dirty |= GDC_DIRTY_CURSOR;
74 roytam 933     }
934 }
935  
936 static void gdc_cmd_csrr(void *opaque)
937 {
938     gdc_t *s = opaque;
939  
940     gdc_fifo_write(s, s->ead & 0xff);
941     gdc_fifo_write(s, (s->ead >> 8) & 0xff);
942     gdc_fifo_write(s, (s->ead >> 16) & 0x03);
943     gdc_fifo_write(s, s->dad & 0xff);
944     gdc_fifo_write(s, (s->dad >> 8) & 0xff);
945     s->cmdreg = -1;
946 }
947  
948 static void gdc_cmd_mask(void *opaque)
949 {
950     gdc_t *s = opaque;
951  
952     if (s->params_count > 1) {
953         s->maskl = s->params[0];
954         s->maskh = s->params[1];
955         s->cmdreg = -1;
956     }
957 }
958  
959 static void gdc_cmd_write(void *opaque)
960 {
961     gdc_t *s = opaque;
962     uint8_t l, h;
963     int i;
964  
965     s->mod = s->cmdreg & 3;
966     switch (s->cmdreg & 0x18) {
78 roytam 967     case 0x00: /* low and high */
74 roytam 968         if (s->params_count > 1) {
969             l = s->params[0] & s->maskl;
970             h = s->params[1] & s->maskh;
971             for (i = 0; i < s->dc + 1; i++) {
972                 gdc_write_sub(s, s->ead * 2 + 0, l);
973                 gdc_write_sub(s, s->ead * 2 + 1, h);
974                 s->ead += s->diff;
975             }
976             gdc_reset_vect(s);
977             s->cmdreg = -1;
978         }
979         break;
78 roytam 980     case 0x10: /* low byte */
74 roytam 981         if (s->params_count > 0) {
982             l = s->params[0] & s->maskl;
983             for (i = 0; i < s->dc + 1; i++) {
984                 gdc_write_sub(s, s->ead * 2 + 0, l);
985                 s->ead += s->diff;
986             }
987             gdc_reset_vect(s);
988             s->cmdreg = -1;
989         }
990         break;
78 roytam 991     case 0x18: /* high byte */
74 roytam 992         if (s->params_count > 0) {
993             h = s->params[0] & s->maskh;
994             for (i = 0; i < s->dc + 1; i++) {
995                 gdc_write_sub(s, s->ead * 2 + 1, h);
996                 s->ead += s->diff;
997             }
998             gdc_reset_vect(s);
999             s->cmdreg = -1;
1000         }
1001         break;
1002     default:    /* invalid */
1003         s->cmdreg = -1;
1004         break;
1005     }
1006 }
1007  
1008 static void gdc_cmd_read(void *opaque)
1009 {
1010     gdc_t *s = opaque;
1011     int i;
1012  
1013     s->mod = s->cmdreg & 3;
1014     switch (s->cmdreg & 0x18) {
78 roytam 1015     case 0x00: /* low and high */
74 roytam 1016         for (i = 0; i < s->dc; i++) {
1017             gdc_fifo_write(s, gdc_read_sub(s, s->ead * 2 + 0));
1018             gdc_fifo_write(s, gdc_read_sub(s, s->ead * 2 + 1));
1019             s->ead += s->diff;
1020         }
1021         break;
78 roytam 1022     case 0x10: /* low byte */
74 roytam 1023         for (i = 0; i < s->dc; i++) {
1024             gdc_fifo_write(s, gdc_read_sub(s, s->ead * 2 + 0));
1025             s->ead += s->diff;
1026         }
1027         break;
78 roytam 1028     case 0x18: /* high byte */
74 roytam 1029         for (i = 0; i < s->dc; i++) {
1030             gdc_fifo_write(s, gdc_read_sub(s, s->ead * 2 + 1));
1031             s->ead += s->diff;
1032         }
1033         break;
78 roytam 1034     default: /* invalid */
74 roytam 1035         break;
1036     }
1037     gdc_reset_vect(s);
1038     s->cmdreg = -1;
1039 }
1040  
1041 static void gdc_cmd_dmaw(void *opaque)
1042 {
1043     gdc_t *s = opaque;
1044  
1045     s->mod = s->cmdreg & 3;
1046     gdc_reset_vect(s);
1047 //    s->statreg |= GDC_STAT_DMA;
1048     s->cmdreg = -1;
1049 }
1050  
1051 static void gdc_cmd_dmar(void *opaque)
1052 {
1053     gdc_t *s = opaque;
1054  
1055     s->mod = s->cmdreg & 3;
1056     gdc_reset_vect(s);
1057 //    s->statreg |= GDC_STAT_DMA;
1058     s->cmdreg = -1;
1059 }
1060  
1061 static void gdc_cmd_unk_5a(void *opaque)
1062 {
1063     gdc_t *s = opaque;
1064  
1065     if (s->params_count > 2) {
1066         s->cmdreg = -1;
1067     }
1068 }
1069  
1070 static void gdc_check_cmd(void *opaque)
1071 {
1072     gdc_t *s = opaque;
1073  
1074     switch (s->cmdreg) {
1075     case GDC_CMD_RESET:
1076         gdc_cmd_reset(s);
1077         break;
1078     case GDC_CMD_SYNC + 0:
1079     case GDC_CMD_SYNC + 1:
1080         if (s->params_count > 7) {
1081             gdc_cmd_sync(s);
1082         }
1083         break;
1084     case GDC_CMD_MASTER:
1085         gdc_cmd_master(s);
1086         break;
1087     case GDC_CMD_SLAVE:
1088         gdc_cmd_slave(s);
1089         break;
1090     case GDC_CMD_START:
1091         gdc_cmd_start(s);
1092         break;
1093     case GDC_CMD_BCTRL + 0:
1094         gdc_cmd_stop(s);
1095         break;
1096     case GDC_CMD_BCTRL + 1:
1097         gdc_cmd_start(s);
1098         break;
1099     case GDC_CMD_ZOOM:
1100         gdc_cmd_zoom(s);
1101         break;
1102     case GDC_CMD_SCROLL + 0:
1103     case GDC_CMD_SCROLL + 1:
1104     case GDC_CMD_SCROLL + 2:
1105     case GDC_CMD_SCROLL + 3:
1106     case GDC_CMD_SCROLL + 4:
1107     case GDC_CMD_SCROLL + 5:
1108     case GDC_CMD_SCROLL + 6:
1109     case GDC_CMD_SCROLL + 7:
1110     case GDC_CMD_TEXTW + 0:
1111     case GDC_CMD_TEXTW + 1:
1112     case GDC_CMD_TEXTW + 2:
1113     case GDC_CMD_TEXTW + 3:
1114     case GDC_CMD_TEXTW + 4:
1115     case GDC_CMD_TEXTW + 5:
1116     case GDC_CMD_TEXTW + 6:
1117     case GDC_CMD_TEXTW + 7:
1118         gdc_cmd_scroll(s);
1119         break;
1120     case GDC_CMD_CSRFORM:
1121         gdc_cmd_csrform(s);
1122         break;
1123     case GDC_CMD_PITCH:
1124         gdc_cmd_pitch(s);
1125         break;
1126     case GDC_CMD_LPEN:
1127         gdc_cmd_lpen(s);
1128         break;
1129     case GDC_CMD_VECTW:
1130         if (s->params_count > 10) {
1131             gdc_cmd_vectw(s);
1132         }
1133         break;
1134     case GDC_CMD_VECTE:
1135         gdc_cmd_vecte(s);
1136         break;
1137     case GDC_CMD_TEXTE:
1138         gdc_cmd_texte(s);
1139         break;
1140     case GDC_CMD_CSRW:
79 roytam 1141         gdc_cmd_csrw(s);
74 roytam 1142         break;
1143     case GDC_CMD_CSRR:
1144         gdc_cmd_csrr(s);
1145         break;
1146     case GDC_CMD_MASK:
1147         gdc_cmd_mask(s);
1148         break;
1149     case GDC_CMD_WRITE + 0x00:
1150     case GDC_CMD_WRITE + 0x01:
1151     case GDC_CMD_WRITE + 0x02:
1152     case GDC_CMD_WRITE + 0x03:
1153     case GDC_CMD_WRITE + 0x08:
1154     case GDC_CMD_WRITE + 0x09:
1155     case GDC_CMD_WRITE + 0x0a:
1156     case GDC_CMD_WRITE + 0x0b:
1157     case GDC_CMD_WRITE + 0x10:
1158     case GDC_CMD_WRITE + 0x11:
1159     case GDC_CMD_WRITE + 0x12:
1160     case GDC_CMD_WRITE + 0x13:
1161     case GDC_CMD_WRITE + 0x18:
1162     case GDC_CMD_WRITE + 0x19:
1163     case GDC_CMD_WRITE + 0x1a:
1164     case GDC_CMD_WRITE + 0x1b:
1165         gdc_cmd_write(s);
1166         break;
1167     case GDC_CMD_READ + 0x00:
1168     case GDC_CMD_READ + 0x01:
1169     case GDC_CMD_READ + 0x02:
1170     case GDC_CMD_READ + 0x03:
1171     case GDC_CMD_READ + 0x08:
1172     case GDC_CMD_READ + 0x09:
1173     case GDC_CMD_READ + 0x0a:
1174     case GDC_CMD_READ + 0x0b:
1175     case GDC_CMD_READ + 0x10:
1176     case GDC_CMD_READ + 0x11:
1177     case GDC_CMD_READ + 0x12:
1178     case GDC_CMD_READ + 0x13:
1179     case GDC_CMD_READ + 0x18:
1180     case GDC_CMD_READ + 0x19:
1181     case GDC_CMD_READ + 0x1a:
1182     case GDC_CMD_READ + 0x1b:
1183         gdc_cmd_read(s);
1184         break;
1185     case GDC_CMD_DMAW + 0x00:
1186     case GDC_CMD_DMAW + 0x01:
1187     case GDC_CMD_DMAW + 0x02:
1188     case GDC_CMD_DMAW + 0x03:
1189     case GDC_CMD_DMAW + 0x08:
1190     case GDC_CMD_DMAW + 0x09:
1191     case GDC_CMD_DMAW + 0x0a:
1192     case GDC_CMD_DMAW + 0x0b:
1193     case GDC_CMD_DMAW + 0x10:
1194     case GDC_CMD_DMAW + 0x11:
1195     case GDC_CMD_DMAW + 0x12:
1196     case GDC_CMD_DMAW + 0x13:
1197     case GDC_CMD_DMAW + 0x18:
1198     case GDC_CMD_DMAW + 0x19:
1199     case GDC_CMD_DMAW + 0x1a:
1200     case GDC_CMD_DMAW + 0x1b:
1201         gdc_cmd_dmaw(s);
1202         break;
1203     case GDC_CMD_DMAR + 0x00:
1204     case GDC_CMD_DMAR + 0x01:
1205     case GDC_CMD_DMAR + 0x02:
1206     case GDC_CMD_DMAR + 0x03:
1207     case GDC_CMD_DMAR + 0x08:
1208     case GDC_CMD_DMAR + 0x09:
1209     case GDC_CMD_DMAR + 0x0a:
1210     case GDC_CMD_DMAR + 0x0b:
1211     case GDC_CMD_DMAR + 0x10:
1212     case GDC_CMD_DMAR + 0x11:
1213     case GDC_CMD_DMAR + 0x12:
1214     case GDC_CMD_DMAR + 0x13:
1215     case GDC_CMD_DMAR + 0x18:
1216     case GDC_CMD_DMAR + 0x19:
1217     case GDC_CMD_DMAR + 0x1a:
1218     case GDC_CMD_DMAR + 0x1b:
1219         gdc_cmd_dmar(s);
1220         break;
1221     case GDC_CMD_UNK_5A:
1222         gdc_cmd_unk_5a(s);
1223         break;
1224     }
1225 }
1226  
1227 static void gdc_process_cmd(void *opaque)
1228 {
1229     gdc_t *s = opaque;
1230  
1231     switch (s->cmdreg) {
1232     case GDC_CMD_RESET:
1233         gdc_cmd_reset(s);
1234         break;
1235     case GDC_CMD_SYNC + 0:
1236     case GDC_CMD_SYNC + 1:
1237         gdc_cmd_sync(s);
1238         break;
1239     case GDC_CMD_SCROLL + 0:
1240     case GDC_CMD_SCROLL + 1:
1241     case GDC_CMD_SCROLL + 2:
1242     case GDC_CMD_SCROLL + 3:
1243     case GDC_CMD_SCROLL + 4:
1244     case GDC_CMD_SCROLL + 5:
1245     case GDC_CMD_SCROLL + 6:
1246     case GDC_CMD_SCROLL + 7:
1247     case GDC_CMD_TEXTW + 0:
1248     case GDC_CMD_TEXTW + 1:
1249     case GDC_CMD_TEXTW + 2:
1250     case GDC_CMD_TEXTW + 3:
1251     case GDC_CMD_TEXTW + 4:
1252     case GDC_CMD_TEXTW + 5:
1253     case GDC_CMD_TEXTW + 6:
1254     case GDC_CMD_TEXTW + 7:
1255         gdc_cmd_scroll(s);
1256         break;
1257     case GDC_CMD_VECTW:
1258         gdc_cmd_vectw(s);
1259         break;
1260     case GDC_CMD_CSRW:
1261         gdc_cmd_csrw(s);
1262         break;
1263     }
1264 }
1265  
1266 /* i/o */
1267  
1268 static void gdc_param_write(void *opaque, uint32_t addr, uint32_t value)
1269 {
1270     gdc_t *s = opaque;
1271  
1272     if (s->cmdreg != -1) {
1273         if (s->params_count < 16) {
1274             s->params[s->params_count++] = (uint8_t)(value & 0xff);
1275         }
1276         gdc_check_cmd(s);
1277         if (s->cmdreg == -1) {
1278             s->params_count = 0;
1279         }
1280     }
1281 }
1282  
1283 static void gdc_cmdreg_write(void *opaque, uint32_t addr, uint32_t value)
1284 {
1285     gdc_t *s = opaque;
1286  
1287     if (s->cmdreg != -1) {
1288         gdc_process_cmd(s);
1289     }
1290     s->cmdreg = (uint8_t)(value & 0xff);
1291     s->params_count = 0;
1292     gdc_check_cmd(s);
1293 }
1294  
1295 static uint32_t gdc_statreg_read(void *opaque, uint32_t addr)
1296 {
1297     gdc_t *s = opaque;
1298     vga_t *v = s->vga;
1299     uint32_t value = s->statreg;
79 roytam 1300     int64_t vticks = qemu_get_clock(rt_clock) - v->vsync_clock;
74 roytam 1301  
1302     if (vticks < GDC_VSTICKS) {
1303         value |= GDC_STAT_VSYNC;
1304     }
1305     /*if (s->params_count == 0) {*/
1306         value |= GDC_STAT_EMPTY;
1307     /*}*/
1308     if (s->params_count == 16) {
1309         value |= GDC_STAT_FULL;
1310     }
1311     if (s->data_count > 0) {
1312         value |= GDC_STAT_DRDY;
1313     }
1314     s->statreg &= ~(GDC_STAT_DMA | GDC_STAT_DRAW);
79 roytam 1315     /* toggle hblank bit */
1316     s->statreg ^= GDC_STAT_HBLANK;
74 roytam 1317     return value;
1318 }
1319  
1320 static uint32_t gdc_data_read(void *opaque, uint32_t addr)
1321 {
1322     gdc_t *s = opaque;
1323  
1324     return gdc_fifo_read(s);
1325 }
1326  
79 roytam 1327 /* display */
74 roytam 1328  
1329 static uint32_t *gdc_get_address(void *opaque, int ofs, uint32_t mask)
1330 {
1331     gdc_t *s = opaque;
1332  
77 roytam 1333     if (s->dirty & GDC_DIRTY_SCROLL) {
74 roytam 1334         int x, y, ytop = 0, i;
1335         uint32_t ra, sad;
1336         int len;
1337  
1338         for(i = 0; i < 4; i++) {
1339             ra  = s->ra[4 * i + 0];
1340             ra |= s->ra[4 * i + 1] << 8;
1341             ra |= s->ra[4 * i + 2] << 16;
1342             ra |= s->ra[4 * i + 3] << 24;
1343             sad = (ra << 1) & mask;
1344             len = (ra >> 20) & 0x3ff;
1345  
1346             for(y = ytop; y < (ytop + len) && y < 480; y++) {
1347                 for(x = 0; x < 80; x++) {
1348                     s->address[y][x] = sad;
1349                     sad = (sad + ofs) & mask;
1350                 }
1351             }
1352             ytop += len;
1353         }
77 roytam 1354         s->dirty &= ~GDC_DIRTY_SCROLL;
74 roytam 1355     }
1356     return s->address[0];
1357 }
1358  
79 roytam 1359 static void gdc_get_cursor_address(void *opaque, uint32_t mask,
1360                                    uint32_t *addr, int *top, int *bottom)
1361 {
1362     gdc_t *s = opaque;
1363     vga_t *v = s->vga;
1364  
1365     if ((s->cs[0] & 0x80) && ((s->cs[1] & 0x20) || !(v->blink & 0x20))) {
1366         *addr = (s->ead << 1) & mask;
1367         *top = s->cs[1] & 0x1f;
1368         *bottom = s->cs[2] >> 3;
1369     } else {
1370         *addr = -1;
1371     }
1372 }
1373  
1374 /* interface */
1375  
74 roytam 1376 static int gdc_post_load(void *opaque)
1377 {
1378     gdc_t *s = opaque;
1379  
1380     /* force update address */
1381     s->dirty = 0xff;
1382     return 0;
1383 }
1384  
1385 static const VMStateDescription vmstate_gdc = {
1386     .name = "pc98-gdc",
1387     .version_id = 1,
1388     .minimum_version_id = 1,
1389     .minimum_version_id_old = 1,
1390     .fields      = (VMStateField []) {
1391         VMSTATE_INT32(cmdreg, struct gdc_t),
1392         VMSTATE_UINT8(statreg, struct gdc_t),
1393         VMSTATE_UINT8_ARRAY(sync, gdc_t, 16),
1394         VMSTATE_UINT8(zoom, gdc_t),
1395         VMSTATE_UINT8(zr, gdc_t),
1396         VMSTATE_UINT8(zw, gdc_t),
1397         VMSTATE_UINT8_ARRAY(ra, gdc_t, 16),
1398         VMSTATE_UINT8_ARRAY(cs, gdc_t, 3),
1399         VMSTATE_UINT8(pitch, gdc_t),
1400         VMSTATE_UINT32(lad, gdc_t),
1401         VMSTATE_UINT8_ARRAY(vect, gdc_t, 11),
1402         VMSTATE_UINT32(ead, gdc_t),
1403         VMSTATE_UINT32(dad, gdc_t),
1404         VMSTATE_UINT8(maskl, gdc_t),
1405         VMSTATE_UINT8(maskh, gdc_t),
1406         VMSTATE_UINT8(mod, gdc_t),
1407         VMSTATE_UINT8(start, gdc_t),
1408         VMSTATE_UINT8(dirty, gdc_t),
1409         VMSTATE_UINT8_ARRAY(params, gdc_t, 16),
1410         VMSTATE_INT32(params_count, gdc_t),
1411         VMSTATE_UINT8_ARRAY(data, gdc_t, GDC_BUFFERS),
1412         VMSTATE_INT32(data_count, gdc_t),
1413         VMSTATE_INT32(data_read, gdc_t),
1414         VMSTATE_INT32(data_write, gdc_t),
1415         VMSTATE_END_OF_LIST()
1416     }
1417 };
1418  
1419 static void gdc_reset(void *opaque)
1420 {
1421     gdc_t *s = opaque;
1422  
1423     gdc_cmd_reset(s);
1424 }
1425  
78 roytam 1426 static void gdc_init(void *opaque, void *vga,
1427                      IOPortReadFunc *vram_read, IOPortWriteFunc *vram_write)
74 roytam 1428 {
1429     gdc_t *s = opaque;
1430     int i;
1431  
1432     for(i = 0; i <= GDC_TABLEMAX; i++) {
1433         s->rt[i] = (int)((double)(1 << GDC_MULBIT) * (1 - sqrt(1 - pow((0.70710678118654 * i) / GDC_TABLEMAX, 2))));
1434     }
1435     s->vga = vga;
78 roytam 1436     s->vram_read = vram_read;
1437     s->vram_write = vram_write;
74 roytam 1438 }
1439  
1440 /***********************************************************/
1441 /* EGC (based on Neko Project 2) */
1442  
1443 /* shift sub */
1444  
1445 static const uint8_t egc_bytemask_u0[64] = {
1446     0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
1447     0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01,
1448     0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x03, 0x01,
1449     0xf0, 0x78, 0x3c, 0x1e, 0x0f, 0x07, 0x03, 0x01,
1450     0xf8, 0x7c, 0x3e, 0x1f, 0x0f, 0x07, 0x03, 0x01,
1451     0xfc, 0x7e, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01,
1452     0xfe, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01,
1453     0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01
1454 };
1455 static const uint8_t egc_bytemask_u1[8] =  {
1456     0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
1457 };
1458 static const uint8_t egc_bytemask_d0[64] = {
1459     0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
1460     0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
1461     0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80,
1462     0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xe0, 0xc0, 0x80,
1463     0x1f, 0x3e, 0x7c, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
1464     0x3f, 0x7e, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
1465     0x7f, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
1466     0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80
1467 };
1468 static const uint8_t egc_bytemask_d1[8] = {
1469     0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
1470 };
1471  
1472 static void egc_shift(void *opaque)
1473 {
1474     egc_t *s = opaque;
1475     uint8_t src8, dst8;
1476  
1477     s->remain = (s->leng & 0xfff) + 1;
1478     s->func = (s->sft >> 12) & 1;
1479     if (!s->func) {
1480         s->inptr = s->buf;
1481         s->outptr = s->buf;
1482     } else {
1483         s->inptr = s->buf + 4096 / 8 + 3;
1484         s->outptr = s->buf + 4096 / 8 + 3;
1485     }
1486     s->srcbit = s->sft & 0x0f;
1487     s->dstbit = (s->sft >> 4) & 0x0f;
1488  
1489     src8 = s->srcbit & 0x07;
1490     dst8 = s->dstbit & 0x07;
1491     if (src8 < dst8) {
1492         s->func += 2;
1493         s->sft8bitr = dst8 - src8;
1494         s->sft8bitl = 8 - s->sft8bitr;
1495     }
1496     else if (src8 > dst8) {
1497         s->func += 4;
1498         s->sft8bitl = src8 - dst8;
1499         s->sft8bitr = 8 - s->sft8bitl;
1500     }
1501     s->stack = 0;
1502 }
1503  
1504 static void egc_sftb_upn_sub(void *opaque, uint32_t ext)
1505 {
1506     egc_t *s = opaque;
1507  
1508     if (s->dstbit >= 8) {
1509         s->dstbit -= 8;
1510         s->srcmask.b[ext] = 0;
1511         return;
1512     }
1513     if (s->dstbit) {
1514         if ((s->dstbit + s->remain) >= 8) {
1515             s->srcmask.b[ext] = egc_bytemask_u0[s->dstbit + (7 * 8)];
1516             s->remain -= (8 - s->dstbit);
1517             s->dstbit = 0;
1518         } else {
1519             s->srcmask.b[ext] = egc_bytemask_u0[s->dstbit + (s->remain - 1) * 8];
1520             s->remain = 0;
1521             s->dstbit = 0;
1522         }
1523     } else {
1524         if (s->remain >= 8) {
1525             s->remain -= 8;
1526         } else {
1527             s->srcmask.b[ext] = egc_bytemask_u1[s->remain - 1];
1528             s->remain = 0;
1529         }
1530     }
1531     s->vram_src.b[0][ext] = s->outptr[0];
1532     s->vram_src.b[1][ext] = s->outptr[4];
1533     s->vram_src.b[2][ext] = s->outptr[8];
1534     s->vram_src.b[3][ext] = s->outptr[12];
1535     s->outptr++;
1536 }
1537  
1538 static void egc_sftb_dnn_sub(void *opaque, uint32_t ext)
1539 {
1540     egc_t *s = opaque;
1541  
1542     if (s->dstbit >= 8) {
1543         s->dstbit -= 8;
1544         s->srcmask.b[ext] = 0;
1545         return;
1546     }
1547     if (s->dstbit) {
1548         if ((s->dstbit + s->remain) >= 8) {
1549             s->srcmask.b[ext] = egc_bytemask_d0[s->dstbit + (7 * 8)];
1550             s->remain -= (8 - s->dstbit);
1551             s->dstbit = 0;
1552         } else {
1553             s->srcmask.b[ext] = egc_bytemask_d0[s->dstbit + (s->remain - 1) * 8];
1554             s->remain = 0;
1555             s->dstbit = 0;
1556         }
1557     } else {
1558         if (s->remain >= 8) {
1559             s->remain -= 8;
1560         } else {
1561             s->srcmask.b[ext] = egc_bytemask_d1[s->remain - 1];
1562             s->remain = 0;
1563         }
1564     }
1565     s->vram_src.b[0][ext] = s->outptr[0];
1566     s->vram_src.b[1][ext] = s->outptr[4];
1567     s->vram_src.b[2][ext] = s->outptr[8];
1568     s->vram_src.b[3][ext] = s->outptr[12];
1569     s->outptr--;
1570 }
1571  
1572 static void egc_sftb_upr_sub(void *opaque, uint32_t ext)
1573 {
1574     egc_t *s = opaque;
1575  
1576     if (s->dstbit >= 8) {
1577         s->dstbit -= 8;
1578         s->srcmask.b[ext] = 0;
1579         return;
1580     }
1581     if (s->dstbit) {
1582         if ((s->dstbit + s->remain) >= 8) {
1583             s->srcmask.b[ext] = egc_bytemask_u0[s->dstbit + (7 * 8)];
1584             s->remain -= (8 - s->dstbit);
1585         } else {
1586             s->srcmask.b[ext] = egc_bytemask_u0[s->dstbit + (s->remain - 1) * 8];
1587             s->remain = 0;
1588         }
1589         s->dstbit = 0;
1590         s->vram_src.b[0][ext] = (s->outptr[0] >> s->sft8bitr);
1591         s->vram_src.b[1][ext] = (s->outptr[4] >> s->sft8bitr);
1592         s->vram_src.b[2][ext] = (s->outptr[8] >> s->sft8bitr);
1593         s->vram_src.b[3][ext] = (s->outptr[12] >> s->sft8bitr);
1594     } else {
1595         if (s->remain >= 8) {
1596             s->remain -= 8;
1597         } else {
1598             s->srcmask.b[ext] = egc_bytemask_u1[s->remain - 1];
1599             s->remain = 0;
1600         }
1601         s->vram_src.b[0][ext] = (s->outptr[0] << s->sft8bitl) | (s->outptr[1] >> s->sft8bitr);
1602         s->vram_src.b[1][ext] = (s->outptr[4] << s->sft8bitl) | (s->outptr[5] >> s->sft8bitr);
1603         s->vram_src.b[2][ext] = (s->outptr[8] << s->sft8bitl) | (s->outptr[9] >> s->sft8bitr);
1604         s->vram_src.b[3][ext] = (s->outptr[12] << s->sft8bitl) | (s->outptr[13] >> s->sft8bitr);
1605         s->outptr++;
1606     }
1607 }
1608  
1609 static void egc_sftb_dnr_sub(void *opaque, uint32_t ext)
1610 {
1611     egc_t *s = opaque;
1612  
1613     if (s->dstbit >= 8) {
1614         s->dstbit -= 8;
1615         s->srcmask.b[ext] = 0;
1616         return;
1617     }
1618     if (s->dstbit) {
1619         if ((s->dstbit + s->remain) >= 8) {
1620             s->srcmask.b[ext] = egc_bytemask_d0[s->dstbit + (7 * 8)];
1621             s->remain -= (8 - s->dstbit);
1622         } else {
1623             s->srcmask.b[ext] = egc_bytemask_d0[s->dstbit + (s->remain - 1) * 8];
1624             s->remain = 0;
1625         }
1626         s->dstbit = 0;
1627         s->vram_src.b[0][ext] = (s->outptr[0] << s->sft8bitr);
1628         s->vram_src.b[1][ext] = (s->outptr[4] << s->sft8bitr);
1629         s->vram_src.b[2][ext] = (s->outptr[8] << s->sft8bitr);
1630         s->vram_src.b[3][ext] = (s->outptr[12] << s->sft8bitr);
1631     } else {
1632         if (s->remain >= 8) {
1633             s->remain -= 8;
1634         } else {
1635             s->srcmask.b[ext] = egc_bytemask_d1[s->remain - 1];
1636             s->remain = 0;
1637         }
1638         s->outptr--;
1639         s->vram_src.b[0][ext] = (s->outptr[1] >> s->sft8bitl) | (s->outptr[0] << s->sft8bitr);
1640         s->vram_src.b[1][ext] = (s->outptr[5] >> s->sft8bitl) | (s->outptr[4] << s->sft8bitr);
1641         s->vram_src.b[2][ext] = (s->outptr[9] >> s->sft8bitl) | (s->outptr[8] << s->sft8bitr);
1642         s->vram_src.b[3][ext] = (s->outptr[13] >> s->sft8bitl) | (s->outptr[12] << s->sft8bitr);
1643     }
1644 }
1645  
1646 static void egc_sftb_upl_sub(void *opaque, uint32_t ext)
1647 {
1648     egc_t *s = opaque;
1649  
1650     if (s->dstbit >= 8) {
1651         s->dstbit -= 8;
1652         s->srcmask.b[ext] = 0;
1653         return;
1654     }
1655     if (s->dstbit) {
1656         if ((s->dstbit + s->remain) >= 8) {
1657             s->srcmask.b[ext] = egc_bytemask_u0[s->dstbit + (7 * 8)];
1658             s->remain -= (8 - s->dstbit);
1659             s->dstbit = 0;
1660         } else {
1661             s->srcmask.b[ext] = egc_bytemask_u0[s->dstbit + (s->remain - 1) * 8];
1662             s->remain = 0;
1663             s->dstbit = 0;
1664         }
1665     } else {
1666         if (s->remain >= 8) {
1667             s->remain -= 8;
1668         } else {
1669             s->srcmask.b[ext] = egc_bytemask_u1[s->remain - 1];
1670             s->remain = 0;
1671         }
1672     }
1673     s->vram_src.b[0][ext] = (s->outptr[0] << s->sft8bitl) | (s->outptr[1] >> s->sft8bitr);
1674     s->vram_src.b[1][ext] = (s->outptr[4] << s->sft8bitl) | (s->outptr[5] >> s->sft8bitr);
1675     s->vram_src.b[2][ext] = (s->outptr[8] << s->sft8bitl) | (s->outptr[9] >> s->sft8bitr);
1676     s->vram_src.b[3][ext] = (s->outptr[12] << s->sft8bitl) | (s->outptr[13] >> s->sft8bitr);
1677     s->outptr++;
1678 }
1679  
1680 static void egc_sftb_dnl_sub(void *opaque, uint32_t ext)
1681 {
1682     egc_t *s = opaque;
1683  
1684     if (s->dstbit >= 8) {
1685         s->dstbit -= 8;
1686         s->srcmask.b[ext] = 0;
1687         return;
1688     }
1689     if (s->dstbit) {
1690         if ((s->dstbit + s->remain) >= 8) {
1691             s->srcmask.b[ext] = egc_bytemask_d0[s->dstbit + (7 * 8)];
1692             s->remain -= (8 - s->dstbit);
1693             s->dstbit = 0;
1694         } else {
1695             s->srcmask.b[ext] = egc_bytemask_d0[s->dstbit + (s->remain - 1) * 8];
1696             s->remain = 0;
1697             s->dstbit = 0;
1698         }
1699     } else {
1700         if (s->remain >= 8) {
1701             s->remain -= 8;
1702         } else {
1703             s->srcmask.b[ext] = egc_bytemask_d1[s->remain - 1];
1704             s->remain = 0;
1705         }
1706     }
1707     s->outptr--;
1708     s->vram_src.b[0][ext] = (s->outptr[1] >> s->sft8bitl) | (s->outptr[0] << s->sft8bitr);
1709     s->vram_src.b[1][ext] = (s->outptr[5] >> s->sft8bitl) | (s->outptr[4] << s->sft8bitr);
1710     s->vram_src.b[2][ext] = (s->outptr[9] >> s->sft8bitl) | (s->outptr[8] << s->sft8bitr);
1711     s->vram_src.b[3][ext] = (s->outptr[13] >> s->sft8bitl) | (s->outptr[12] << s->sft8bitr);
1712 }
1713  
1714 static void egc_sftb_upn0(void *opaque, uint32_t ext)
1715 {
1716     egc_t *s = opaque;
1717  
1718     if (s->stack < (uint32_t)(8 - s->dstbit)) {
1719         s->srcmask.b[ext] = 0;
1720         return;
1721     }
1722     s->stack -= (8 - s->dstbit);
1723     egc_sftb_upn_sub(s, ext);
1724     if (!s->remain) {
1725         egc_shift(s);
1726     }
1727 }
1728  
1729 static void egc_sftw_upn0(void *opaque)
1730 {
1731     egc_t *s = opaque;
1732  
1733     if (s->stack < (uint32_t)(16 - s->dstbit)) {
1734         s->srcmask.w = 0;
1735         return;
1736     }
1737     s->stack -= (16 - s->dstbit);
1738     egc_sftb_upn_sub(s, 0);
1739     if (s->remain) {
1740         egc_sftb_upn_sub(s, 1);
1741         if (s->remain) {
1742             return;
1743         }
1744     } else {
1745         s->srcmask.b[1] = 0;
1746     }
1747     egc_shift(s);
1748 }
1749  
1750 static void egc_sftb_dnn0(void *opaque, uint32_t ext)
1751 {
1752     egc_t *s = opaque;
1753  
1754     if (s->stack < (uint32_t)(8 - s->dstbit)) {
1755         s->srcmask.b[ext] = 0;
1756         return;
1757     }
1758     s->stack -= (8 - s->dstbit);
1759     egc_sftb_dnn_sub(s, ext);
1760     if (!s->remain) {
1761         egc_shift(s);
1762     }
1763 }
1764  
1765 static void egc_sftw_dnn0(void *opaque)
1766 {
1767     egc_t *s = opaque;
1768  
1769     if (s->stack < (uint32_t)(16 - s->dstbit)) {
1770         s->srcmask.w = 0;
1771         return;
1772     }
1773     s->stack -= (16 - s->dstbit);
1774     egc_sftb_dnn_sub(s, 1);
1775     if (s->remain) {
1776         egc_sftb_dnn_sub(s, 0);
1777         if (s->remain) {
1778             return;
1779         }
1780     } else {
1781         s->srcmask.b[0] = 0;
1782     }
1783     egc_shift(s);
1784 }
1785  
1786 static void egc_sftb_upr0(void *opaque, uint32_t ext)
1787 {
1788     egc_t *s = opaque;
1789  
1790     if (s->stack < (uint32_t)(8 - s->dstbit)) {
1791         s->srcmask.b[ext] = 0;
1792         return;
1793     }
1794     s->stack -= (8 - s->dstbit);
1795     egc_sftb_upr_sub(s, ext);
1796     if (!s->remain) {
1797         egc_shift(s);
1798     }
1799 }
1800  
1801 static void egc_sftw_upr0(void *opaque)
1802 {
1803     egc_t *s = opaque;
1804  
1805     if (s->stack < (uint32_t)(16 - s->dstbit)) {
1806         s->srcmask.w = 0;
1807         return;
1808     }
1809     s->stack -= (16 - s->dstbit);
1810     egc_sftb_upr_sub(s, 0);
1811     if (s->remain) {
1812         egc_sftb_upr_sub(s, 1);
1813         if (s->remain) {
1814             return;
1815         }
1816     } else {
1817         s->srcmask.b[1] = 0;
1818     }
1819     egc_shift(s);
1820 }
1821  
1822 static void egc_sftb_dnr0(void *opaque, uint32_t ext)
1823 {
1824     egc_t *s = opaque;
1825  
1826     if (s->stack < (uint32_t)(8 - s->dstbit)) {
1827         s->srcmask.b[ext] = 0;
1828         return;
1829     }
1830     s->stack -= (8 - s->dstbit);
1831     egc_sftb_dnr_sub(s, ext);
1832     if (!s->remain) {
1833         egc_shift(s);
1834     }
1835 }
1836  
1837 static void egc_sftw_dnr0(void *opaque)
1838 {
1839     egc_t *s = opaque;
1840  
1841     if (s->stack < (uint32_t)(16 - s->dstbit)) {
1842         s->srcmask.w = 0;
1843         return;
1844     }
1845     s->stack -= (16 - s->dstbit);
1846     egc_sftb_dnr_sub(s, 1);
1847     if (s->remain) {
1848         egc_sftb_dnr_sub(s, 0);
1849         if (s->remain) {
1850             return;
1851         }
1852     } else {
1853         s->srcmask.b[0] = 0;
1854     }
1855     egc_shift(s);
1856 }
1857  
1858 static void egc_sftb_upl0(void *opaque, uint32_t ext)
1859 {
1860     egc_t *s = opaque;
1861  
1862     if (s->stack < (uint32_t)(8 - s->dstbit)) {
1863         s->srcmask.b[ext] = 0;
1864         return;
1865     }
1866     s->stack -= (8 - s->dstbit);
1867     egc_sftb_upl_sub(s, ext);
1868     if (!s->remain) {
1869         egc_shift(s);
1870     }
1871 }
1872  
1873 static void egc_sftw_upl0(void *opaque)
1874 {
1875     egc_t *s = opaque;
1876  
1877     if (s->stack < (uint32_t)(16 - s->dstbit)) {
1878         s->srcmask.w = 0;
1879         return;
1880     }
1881     s->stack -= (16 - s->dstbit);
1882     egc_sftb_upl_sub(s, 0);
1883     if (s->remain) {
1884         egc_sftb_upl_sub(s, 1);
1885         if (s->remain) {
1886             return;
1887         }
1888     } else {
1889         s->srcmask.b[1] = 0;
1890     }
1891     egc_shift(s);
1892 }
1893  
1894 static void egc_sftb_dnl0(void *opaque, uint32_t ext)
1895 {
1896     egc_t *s = opaque;
1897  
1898     if (s->stack < (uint32_t)(8 - s->dstbit)) {
1899         s->srcmask.b[ext] = 0;
1900         return;
1901     }
1902     s->stack -= (8 - s->dstbit);
1903     egc_sftb_dnl_sub(s, ext);
1904     if (!s->remain) {
1905         egc_shift(s);
1906     }
1907 }
1908  
1909 static void egc_sftw_dnl0(void *opaque)
1910 {
1911     egc_t *s = opaque;
1912  
1913     if (s->stack < (uint32_t)(16 - s->dstbit)) {
1914         s->srcmask.w = 0;
1915         return;
1916     }
1917     s->stack -= (16 - s->dstbit);
1918     egc_sftb_dnl_sub(s, 1);
1919     if (s->remain) {
1920         egc_sftb_dnl_sub(s, 0);
1921         if (s->remain) {
1922             return;
1923         }
1924     } else {
1925         s->srcmask.b[0] = 0;
1926     }
1927     egc_shift(s);
1928 }
1929  
1930 /* shift */
1931  
1932 typedef void (*PC98EGCSFTB)(void *opaque, uint32_t ext);
1933 typedef void (*PC98EGCSFTW)(void *opaque);
1934  
1935 static const PC98EGCSFTB egc_sftb[6] = {
1936     egc_sftb_upn0, egc_sftb_dnn0,
1937     egc_sftb_upr0, egc_sftb_dnr0,
1938     egc_sftb_upl0, egc_sftb_dnl0
1939 };
1940 static const PC98EGCSFTW egc_sftw[6] = {
1941     egc_sftw_upn0, egc_sftw_dnn0,
1942     egc_sftw_upr0, egc_sftw_dnr0,
1943     egc_sftw_upl0, egc_sftw_dnl0
1944 };
1945  
1946 static void egc_shiftinput_byte(void *opaque, uint32_t ext)
1947 {
1948     egc_t *s = opaque;
1949  
1950     if (s->stack <= 16) {
1951         if (s->srcbit >= 8) {
1952             s->srcbit -= 8;
1953         } else {
1954             s->stack += (8 - s->srcbit);
1955             s->srcbit = 0;
1956         }
1957         if (!(s->sft & 0x1000)) {
1958             s->inptr++;
1959         } else {
1960             s->inptr--;
1961         }
1962     }
1963     s->srcmask.b[ext] = 0xff;
1964     (*egc_sftb[s->func])(s, ext);
1965 }
1966  
1967 static void egc_shiftinput_incw(void *opaque)
1968 {
1969     egc_t *s = opaque;
1970  
1971     if (s->stack <= 16) {
1972         s->inptr += 2;
1973         if (s->srcbit >= 8) {
1974             s->outptr++;
1975         }
1976         s->stack += (16 - s->srcbit);
1977         s->srcbit = 0;
1978     }
1979     s->srcmask.w = 0xffff;
1980     (*egc_sftw[s->func])(s);
1981 }
1982  
1983 static void egc_shiftinput_decw(void *opaque)
1984 {
1985     egc_t *s = opaque;
1986  
1987     if (s->stack <= 16) {
1988         s->inptr -= 2;
1989         if (s->srcbit >= 8) {
1990             s->outptr--;
1991         }
1992         s->stack += (16 - s->srcbit);
1993         s->srcbit = 0;
1994     }
1995     s->srcmask.w = 0xffff;
1996     (*egc_sftw[s->func])(s);
1997 }
1998  
1999 /* operation */
2000  
2001 #define PC98EGC_OPE_SHIFTB \
2002     do { \
2003         if (s->ope & 0x400) { \
2004             s->inptr[ 0] = (uint8_t)value; \
2005             s->inptr[ 4] = (uint8_t)value; \
2006             s->inptr[ 8] = (uint8_t)value; \
2007             s->inptr[12] = (uint8_t)value; \
2008             egc_shiftinput_byte(s, addr & 1); \
2009         } \
2010     } while(0)
2011  
2012 #define PC98EGC_OPE_SHIFTW \
2013     do { \
2014         if (s->ope & 0x400) { \
2015             if (!(s->sft & 0x1000)) { \
2016                 s->inptr[ 0] = (uint8_t)value; \
2017                 s->inptr[ 1] = (uint8_t)(value >> 8); \
2018                 s->inptr[ 4] = (uint8_t)value; \
2019                 s->inptr[ 5] = (uint8_t)(value >> 8); \
2020                 s->inptr[ 8] = (uint8_t)value; \
2021                 s->inptr[ 9] = (uint8_t)(value >> 8); \
2022                 s->inptr[12] = (uint8_t)value; \
2023                 s->inptr[13] = (uint8_t)(value >> 8); \
2024                 egc_shiftinput_incw(s); \
2025             } else { \
2026                 s->inptr[-1] = (uint8_t)value; \
2027                 s->inptr[ 0] = (uint8_t)(value >> 8); \
2028                 s->inptr[ 3] = (uint8_t)value; \
2029                 s->inptr[ 4] = (uint8_t)(value >> 8); \
2030                 s->inptr[ 7] = (uint8_t)value; \
2031                 s->inptr[ 8] = (uint8_t)(value >> 8); \
2032                 s->inptr[11] = (uint8_t)value; \
2033                 s->inptr[12] = (uint8_t)(value >> 8); \
2034                 egc_shiftinput_decw(s); \
2035             }  \
2036         } \
2037     } while(0)
2038  
2039 static uint64_t egc_ope_00(void *opaque, uint8_t ope, uint32_t addr)
2040 {
2041     return 0;
2042 }
2043  
2044 static uint64_t egc_ope_0f(void *opaque, uint8_t ope, uint32_t addr)
2045 {
2046     egc_t *s = opaque;
2047  
2048     s->vram_data.d[0] = ~s->vram_src.d[0];
2049     s->vram_data.d[1] = ~s->vram_src.d[1];
2050     return s->vram_data.q;
2051 }
2052  
2053 static uint64_t egc_ope_c0(void *opaque, uint8_t ope, uint32_t addr)
2054 {
2055     egc_t *s = opaque;
2056     egcquad_t dst;
2057  
2058     dst.w[0] = *(uint16_t *)(&s->vram_b[addr]);
2059     dst.w[1] = *(uint16_t *)(&s->vram_r[addr]);
2060     dst.w[2] = *(uint16_t *)(&s->vram_g[addr]);
2061     dst.w[3] = *(uint16_t *)(&s->vram_e[addr]);
2062     s->vram_data.d[0] = (s->vram_src.d[0] & dst.d[0]);
2063     s->vram_data.d[1] = (s->vram_src.d[1] & dst.d[1]);
2064     return s->vram_data.q;
2065 }
2066  
2067 static uint64_t egc_ope_f0(void *opaque, uint8_t ope, uint32_t addr)
2068 {
2069     egc_t *s = opaque;
2070  
2071     return s->vram_src.q;
2072 }
2073  
2074 static uint64_t egc_ope_fc(void *opaque, uint8_t ope, uint32_t addr)
2075 {
2076     egc_t *s = opaque;
2077     egcquad_t dst;
2078  
2079     dst.w[0] = *(uint16_t *)(&s->vram_b[addr]);
2080     dst.w[1] = *(uint16_t *)(&s->vram_r[addr]);
2081     dst.w[2] = *(uint16_t *)(&s->vram_g[addr]);
2082     dst.w[3] = *(uint16_t *)(&s->vram_e[addr]);
2083     s->vram_data.d[0] = s->vram_src.d[0];
2084     s->vram_data.d[0] |= ((~s->vram_src.d[0]) & dst.d[0]);
2085     s->vram_data.d[1] = s->vram_src.d[1];
2086     s->vram_data.d[1] |= ((~s->vram_src.d[1]) & dst.d[1]);
2087     return s->vram_data.q;
2088 }
2089  
2090 static uint64_t egc_ope_ff(void *opaque, uint8_t ope, uint32_t addr)
2091 {
2092     return ~0;
2093 }
2094  
2095 static uint64_t egc_ope_nd(void *opaque, uint8_t ope, uint32_t addr)
2096 {
2097     egc_t *s = opaque;
2098     egcquad_t pat;
2099  
2100     switch(s->fgbg & 0x6000) {
2101     case 0x2000:
2102         pat.d[0] = s->bgc.d[0];
2103         pat.d[1] = s->bgc.d[1];
2104         break;
2105     case 0x4000:
2106         pat.d[0] = s->fgc.d[0];
2107         pat.d[1] = s->fgc.d[1];
2108         break;
2109     default:
2110         if ((s->ope & 0x0300) == 0x0100) {
2111             pat.d[0] = s->vram_src.d[0];
2112             pat.d[1] = s->vram_src.d[1];
2113         } else {
2114             pat.d[0] = s->patreg.d[0];
2115             pat.d[1] = s->patreg.d[1];
2116         }
2117         break;
2118     }
2119     s->vram_data.d[0] = 0;
2120     s->vram_data.d[1] = 0;
2121     if (ope & 0x80) {
2122         s->vram_data.d[0] |= (pat.d[0] & s->vram_src.d[0]);
2123         s->vram_data.d[1] |= (pat.d[1] & s->vram_src.d[1]);
2124     }
2125     if (ope & 0x40) {
2126         s->vram_data.d[0] |= ((~pat.d[0]) & s->vram_src.d[0]);
2127         s->vram_data.d[1] |= ((~pat.d[1]) & s->vram_src.d[1]);
2128     }
2129     if (ope & 0x08) {
2130         s->vram_data.d[0] |= (pat.d[0] & (~s->vram_src.d[0]));
2131         s->vram_data.d[1] |= (pat.d[1] & (~s->vram_src.d[1]));
2132     }
2133     if (ope & 0x04) {
2134         s->vram_data.d[0] |= ((~pat.d[0]) & (~s->vram_src.d[0]));
2135         s->vram_data.d[1] |= ((~pat.d[1]) & (~s->vram_src.d[1]));
2136     }
2137     return s->vram_data.q;
2138 }
2139  
2140 static uint64_t egc_ope_np(void *opaque, uint8_t ope, uint32_t addr)
2141 {
2142     egc_t *s = opaque;
2143     egcquad_t dst;
2144  
2145     dst.w[0] = *(uint16_t *)(&s->vram_b[addr]);
2146     dst.w[1] = *(uint16_t *)(&s->vram_r[addr]);
2147     dst.w[2] = *(uint16_t *)(&s->vram_g[addr]);
2148     dst.w[3] = *(uint16_t *)(&s->vram_e[addr]);
2149  
2150     s->vram_data.d[0] = 0;
2151     s->vram_data.d[1] = 0;
2152     if (ope & 0x80) {
2153         s->vram_data.d[0] |= (s->vram_src.d[0] & dst.d[0]);
2154         s->vram_data.d[1] |= (s->vram_src.d[1] & dst.d[1]);
2155     }
2156     if (ope & 0x20) {
2157         s->vram_data.d[0] |= (s->vram_src.d[0] & (~dst.d[0]));
2158         s->vram_data.d[1] |= (s->vram_src.d[1] & (~dst.d[1]));
2159     }
2160     if (ope & 0x08) {
2161         s->vram_data.d[0] |= ((~s->vram_src.d[0]) & dst.d[0]);
2162         s->vram_data.d[1] |= ((~s->vram_src.d[1]) & dst.d[1]);
2163     }
2164     if (ope & 0x02) {
2165         s->vram_data.d[0] |= ((~s->vram_src.d[0]) & (~dst.d[0]));
2166         s->vram_data.d[1] |= ((~s->vram_src.d[1]) & (~dst.d[1]));
2167     }
2168     return s->vram_data.q;
2169 }
2170  
2171 static uint64_t egc_ope_xx(void *opaque, uint8_t ope, uint32_t addr)
2172 {
2173     egc_t *s = opaque;
2174     egcquad_t pat;
2175     egcquad_t dst;
2176  
2177     switch(s->fgbg & 0x6000) {
2178     case 0x2000:
2179         pat.d[0] = s->bgc.d[0];
2180         pat.d[1] = s->bgc.d[1];
2181         break;
2182     case 0x4000:
2183         pat.d[0] = s->fgc.d[0];
2184         pat.d[1] = s->fgc.d[1];
2185         break;
2186     default:
2187         if ((s->ope & 0x0300) == 0x0100) {
2188             pat.d[0] = s->vram_src.d[0];
2189             pat.d[1] = s->vram_src.d[1];
2190         } else {
2191             pat.d[0] = s->patreg.d[0];
2192             pat.d[1] = s->patreg.d[1];
2193         }
2194         break;
2195     }
2196     dst.w[0] = *(uint16_t *)(&s->vram_b[addr]);
2197     dst.w[1] = *(uint16_t *)(&s->vram_r[addr]);
2198     dst.w[2] = *(uint16_t *)(&s->vram_g[addr]);
2199     dst.w[3] = *(uint16_t *)(&s->vram_e[addr]);
2200  
2201     s->vram_data.d[0] = 0;
2202     s->vram_data.d[1] = 0;
2203     if (ope & 0x80) {
2204         s->vram_data.d[0] |= (pat.d[0] & s->vram_src.d[0] & dst.d[0]);
2205         s->vram_data.d[1] |= (pat.d[1] & s->vram_src.d[1] & dst.d[1]);
2206     }
2207     if (ope & 0x40) {
2208         s->vram_data.d[0] |= ((~pat.d[0]) & s->vram_src.d[0] & dst.d[0]);
2209         s->vram_data.d[1] |= ((~pat.d[1]) & s->vram_src.d[1] & dst.d[1]);
2210     }
2211     if (ope & 0x20) {
2212         s->vram_data.d[0] |= (pat.d[0] & s->vram_src.d[0] & (~dst.d[0]));
2213         s->vram_data.d[1] |= (pat.d[1] & s->vram_src.d[1] & (~dst.d[1]));
2214     }
2215     if (ope & 0x10) {
2216         s->vram_data.d[0] |= ((~pat.d[0]) & s->vram_src.d[0] & (~dst.d[0]));
2217         s->vram_data.d[1] |= ((~pat.d[1]) & s->vram_src.d[1] & (~dst.d[1]));
2218     }
2219     if (ope & 0x08) {
2220         s->vram_data.d[0] |= (pat.d[0] & (~s->vram_src.d[0]) & dst.d[0]);
2221         s->vram_data.d[1] |= (pat.d[1] & (~s->vram_src.d[1]) & dst.d[1]);
2222     }
2223     if (ope & 0x04) {
2224         s->vram_data.d[0] |= ((~pat.d[0]) & (~s->vram_src.d[0]) & dst.d[0]);
2225         s->vram_data.d[1] |= ((~pat.d[1]) & (~s->vram_src.d[1]) & dst.d[1]);
2226     }
2227     if (ope & 0x02) {
2228         s->vram_data.d[0] |= (pat.d[0] & (~s->vram_src.d[0]) & (~dst.d[0]));
2229         s->vram_data.d[1] |= (pat.d[1] & (~s->vram_src.d[1]) & (~dst.d[1]));
2230     }
2231     if (ope & 0x01) {
2232         s->vram_data.d[0] |= ((~pat.d[0]) & (~s->vram_src.d[0]) & (~dst.d[0]));
2233         s->vram_data.d[1] |= ((~pat.d[1]) & (~s->vram_src.d[1]) & (~dst.d[1]));
2234     }
2235     return s->vram_data.q;
2236 }
2237  
2238 typedef uint64_t (*PC98EGCOPEFN)(void *opaque, uint8_t ope, uint32_t addr);
2239  
2240 static const PC98EGCOPEFN egc_opefn[256] = {
2241     egc_ope_00, egc_ope_xx, egc_ope_xx, egc_ope_np,
2242     egc_ope_xx, egc_ope_nd, egc_ope_xx, egc_ope_xx,
2243     egc_ope_xx, egc_ope_xx, egc_ope_nd, egc_ope_xx,
2244     egc_ope_np, egc_ope_xx, egc_ope_xx, egc_ope_0f,
2245     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2246     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2247     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2248     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2249     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2250     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2251     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2252     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2253     egc_ope_np, egc_ope_xx, egc_ope_xx, egc_ope_np,
2254     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2255     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2256     egc_ope_np, egc_ope_xx, egc_ope_xx, egc_ope_np,
2257     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2258     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2259     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2260     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2261     egc_ope_nd, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2262     egc_ope_xx, egc_ope_nd, egc_ope_xx, egc_ope_xx,
2263     egc_ope_xx, egc_ope_xx, egc_ope_nd, egc_ope_xx,
2264     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_nd,
2265     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2266     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2267     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2268     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2269     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2270     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2271     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2272     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2273     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2274     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2275     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2276     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2277     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2278     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2279     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2280     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2281     egc_ope_nd, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2282     egc_ope_xx, egc_ope_nd, egc_ope_xx, egc_ope_xx,
2283     egc_ope_xx, egc_ope_xx, egc_ope_nd, egc_ope_xx,
2284     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_nd,
2285     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2286     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2287     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2288     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2289     egc_ope_c0, egc_ope_xx, egc_ope_xx, egc_ope_np,
2290     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2291     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2292     egc_ope_np, egc_ope_xx, egc_ope_xx, egc_ope_np,
2293     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2294     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2295     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2296     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2297     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2298     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2299     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2300     egc_ope_xx, egc_ope_xx, egc_ope_xx, egc_ope_xx,
2301     egc_ope_f0, egc_ope_xx, egc_ope_xx, egc_ope_np,
2302     egc_ope_xx, egc_ope_nd, egc_ope_xx, egc_ope_xx,
2303     egc_ope_xx, egc_ope_xx, egc_ope_nd, egc_ope_xx,
2304     egc_ope_fc, egc_ope_xx, egc_ope_xx, egc_ope_ff
2305 };
2306  
2307 static uint64_t egc_opeb(void *opaque, uint32_t addr, uint8_t value)
2308 {
2309     egc_t *s = opaque;
2310     uint32_t tmp;
2311  
2312     s->mask2.w = s->mask.w;
2313     switch(s->ope & 0x1800) {
2314     case 0x0800:
2315         PC98EGC_OPE_SHIFTB;
2316         s->mask2.w &= s->srcmask.w;
2317         tmp = s->ope & 0xff;
2318         return (*egc_opefn[tmp])(s, (uint8_t)tmp, addr & (~1));
2319     case 0x1000:
2320         switch(s->fgbg & 0x6000) {
2321         case 0x2000:
2322             return s->bgc.q;
2323         case 0x4000:
2324             return s->fgc.q;
2325         default:
2326             PC98EGC_OPE_SHIFTB;
2327             s->mask2.w &= s->srcmask.w;
2328             return s->vram_src.q;
2329         }
2330         break;
2331     default:
2332         tmp = value & 0xff;
2333         tmp = tmp | (tmp << 8);
2334         s->vram_data.w[0] = (uint16_t)tmp;
2335         s->vram_data.w[1] = (uint16_t)tmp;
2336         s->vram_data.w[2] = (uint16_t)tmp;
2337         s->vram_data.w[3] = (uint16_t)tmp;
2338         return s->vram_data.q;
2339     }
2340 }
2341  
2342 static uint64_t egc_opew(void *opaque, uint32_t addr, uint16_t value)
2343 {
2344     egc_t *s = opaque;
2345     uint32_t tmp;
2346  
2347     s->mask2.w = s->mask.w;
2348     switch(s->ope & 0x1800) {
2349     case 0x0800:
2350         PC98EGC_OPE_SHIFTW;
2351         s->mask2.w &= s->srcmask.w;
2352         tmp = s->ope & 0xff;
2353         return (*egc_opefn[tmp])(s, (uint8_t)tmp, addr);
2354     case 0x1000:
2355         switch(s->fgbg & 0x6000) {
2356         case 0x2000:
2357             return s->bgc.q;
2358         case 0x4000:
2359             return s->fgc.q;
2360         default:
2361             PC98EGC_OPE_SHIFTW;
2362             s->mask2.w &= s->srcmask.w;
2363             return s->vram_src.q;
2364         }
2365         break;
2366     default:
2367 #ifdef WORDS_BIGENDIAN
2368         value = ((value >> 8) & 0xff) | ((value & 0xff) << 8);
2369 #endif
2370         s->vram_data.w[0] = (uint16_t)value;
2371         s->vram_data.w[1] = (uint16_t)value;
2372         s->vram_data.w[2] = (uint16_t)value;
2373         s->vram_data.w[3] = (uint16_t)value;
2374         return s->vram_data.q;
2375     }
2376 }
2377  
2378 /* memory */
2379  
2380 static const uint16_t egc_maskword[16][4] = {
2381     {0x0000, 0x0000, 0x0000, 0x0000}, {0xffff, 0x0000, 0x0000, 0x0000},
2382     {0x0000, 0xffff, 0x0000, 0x0000}, {0xffff, 0xffff, 0x0000, 0x0000},
2383     {0x0000, 0x0000, 0xffff, 0x0000}, {0xffff, 0x0000, 0xffff, 0x0000},
2384     {0x0000, 0xffff, 0xffff, 0x0000}, {0xffff, 0xffff, 0xffff, 0x0000},
2385     {0x0000, 0x0000, 0x0000, 0xffff}, {0xffff, 0x0000, 0x0000, 0xffff},
2386     {0x0000, 0xffff, 0x0000, 0xffff}, {0xffff, 0xffff, 0x0000, 0xffff},
2387     {0x0000, 0x0000, 0xffff, 0xffff}, {0xffff, 0x0000, 0xffff, 0xffff},
2388     {0x0000, 0xffff, 0xffff, 0xffff}, {0xffff, 0xffff, 0xffff, 0xffff}
2389 };
2390  
2391 static uint32_t egc_mem_readb(void *opaque, uint32_t addr1)
2392 {
2393     egc_t *s = opaque;
2394     uint32_t addr = addr1 & 0x7fff;
2395     uint32_t ext = addr1 & 1;
2396  
2397     s->lastvram.b[0][ext] = s->vram_b[addr];
2398     s->lastvram.b[1][ext] = s->vram_r[addr];
2399     s->lastvram.b[2][ext] = s->vram_g[addr];
2400     s->lastvram.b[3][ext] = s->vram_e[addr];
2401  
2402     if (!(s->ope & 0x400)) {
2403         s->inptr[0] = s->lastvram.b[0][ext];
2404         s->inptr[4] = s->lastvram.b[1][ext];
2405         s->inptr[8] = s->lastvram.b[2][ext];
2406         s->inptr[12] = s->lastvram.b[3][ext];
2407         egc_shiftinput_byte(s, ext);
2408     }
2409     if ((s->ope & 0x0300) == 0x0100) {
2410         s->patreg.b[0][ext] = s->vram_b[addr];
2411         s->patreg.b[1][ext] = s->vram_r[addr];
2412         s->patreg.b[2][ext] = s->vram_g[addr];
2413         s->patreg.b[3][ext] = s->vram_e[addr];
2414     }
2415     if (!(s->ope & 0x2000)) {
2416         int pl = (s->fgbg >> 8) & 3;
2417         if (!(s->ope & 0x400)) {
2418             return s->vram_src.b[pl][ext];
2419         } else {
2420             return s->vram_ptr[addr | (0x8000 * pl)];
2421         }
2422     }
2423     return s->vram_ptr[addr1];
2424 }
2425  
2426 static uint32_t egc_mem_readw(void *opaque, uint32_t addr1)
2427 {
2428     egc_t *s = opaque;
2429     uint32_t addr = addr1 & 0x7fff;
2430  
2431     if (!(addr & 1)) {
2432         s->lastvram.w[0] = *(uint16_t *)(&s->vram_b[addr]);
2433         s->lastvram.w[1] = *(uint16_t *)(&s->vram_r[addr]);
2434         s->lastvram.w[2] = *(uint16_t *)(&s->vram_g[addr]);
2435         s->lastvram.w[3] = *(uint16_t *)(&s->vram_e[addr]);
2436  
2437         if (!(s->ope & 0x400)) {
2438             if (!(s->sft & 0x1000)) {
2439                 s->inptr[ 0] = s->lastvram.b[0][0];
2440                 s->inptr[ 1] = s->lastvram.b[0][1];
2441                 s->inptr[ 4] = s->lastvram.b[1][0];
2442                 s->inptr[ 5] = s->lastvram.b[1][1];
2443                 s->inptr[ 8] = s->lastvram.b[2][0];
2444                 s->inptr[ 9] = s->lastvram.b[2][1];
2445                 s->inptr[12] = s->lastvram.b[3][0];
2446                 s->inptr[13] = s->lastvram.b[3][1];
2447                 egc_shiftinput_incw(s);
2448             } else {
2449                 s->inptr[-1] = s->lastvram.b[0][0];
2450                 s->inptr[ 0] = s->lastvram.b[0][1];
2451                 s->inptr[ 3] = s->lastvram.b[1][0];
2452                 s->inptr[ 4] = s->lastvram.b[1][1];
2453                 s->inptr[ 7] = s->lastvram.b[2][0];
2454                 s->inptr[ 8] = s->lastvram.b[2][1];
2455                 s->inptr[11] = s->lastvram.b[3][0];
2456                 s->inptr[12] = s->lastvram.b[3][1];
2457                 egc_shiftinput_decw(s);
2458             }
2459         }
2460         if ((s->ope & 0x0300) == 0x0100) {
2461             s->patreg.d[0] = s->lastvram.d[0];
2462             s->patreg.d[1] = s->lastvram.d[1];
2463         }
2464         if (!(s->ope & 0x2000)) {
2465             int pl = (s->fgbg >> 8) & 3;
2466             if (!(s->ope & 0x400)) {
2467                 return s->vram_src.w[pl];
2468             } else {
2469                 return *(uint16_t *)(&s->vram_ptr[addr | (0x8000 * pl)]);
2470             }
2471         }
2472         return *(uint16_t *)(&s->vram_ptr[addr1]);
2473     } else if (!(s->sft & 0x1000)) {
2474         uint16_t value = egc_mem_readb(s, addr1);
2475         value |= egc_mem_readb(s, addr1 + 1) << 8;
2476         return value;
2477     } else {
2478         uint16_t value = egc_mem_readb(s, addr1) << 8;
2479         value |= egc_mem_readb(s, addr1 + 1);
2480         return value;
2481     }
2482 }
2483  
2484 static void egc_mem_writeb(void *opaque, uint32_t addr1, uint8_t value)
2485 {
2486     egc_t *s = opaque;
2487     uint32_t addr = addr1 & 0x7fff;
2488     uint32_t ext = addr1 & 1;
2489     egcquad_t data;
2490  
2491     if ((s->ope & 0x0300) == 0x0200) {
2492         s->patreg.b[0][ext] = s->vram_b[addr];
2493         s->patreg.b[1][ext] = s->vram_r[addr];
2494         s->patreg.b[2][ext] = s->vram_g[addr];
2495         s->patreg.b[3][ext] = s->vram_e[addr];
2496     }
2497     data.q = egc_opeb(s, addr, value);
2498     if (s->mask2.b[ext]) {
2499         if (!(s->access & 1)) {
2500             s->vram_b[addr] &= ~s->mask2.b[ext];
2501             s->vram_b[addr] |= data.b[0][ext] & s->mask2.b[ext];
2502         }
2503         if (!(s->access & 2)) {
2504             s->vram_r[addr] &= ~s->mask2.b[ext];
2505             s->vram_r[addr] |= data.b[1][ext] & s->mask2.b[ext];
2506         }
2507         if (!(s->access & 4)) {
2508             s->vram_g[addr] &= ~s->mask2.b[ext];
2509             s->vram_g[addr] |= data.b[2][ext] & s->mask2.b[ext];
2510         }
2511         if (!(s->access & 8)) {
2512             s->vram_e[addr] &= ~s->mask2.b[ext];
2513             s->vram_e[addr] |= data.b[3][ext] & s->mask2.b[ext];
2514         }
2515     }
2516 }
2517  
2518 static void egc_mem_writew(void *opaque, uint32_t addr1, uint16_t value)
2519 {
2520     egc_t *s = opaque;
2521     uint32_t addr = addr1 & 0x7fff;
2522     egcquad_t data;
2523  
2524     if (!(addr & 1)) {
2525         if ((s->ope & 0x0300) == 0x0200) {
2526             s->patreg.w[0] = *(uint16_t *)(&s->vram_b[addr]);
2527             s->patreg.w[1] = *(uint16_t *)(&s->vram_r[addr]);
2528             s->patreg.w[2] = *(uint16_t *)(&s->vram_g[addr]);
2529             s->patreg.w[3] = *(uint16_t *)(&s->vram_e[addr]);
2530         }
2531         data.q = egc_opew(s, addr, value);
2532         if (s->mask2.w) {
2533             if (!(s->access & 1)) {
2534                 *(uint16_t *)(&s->vram_b[addr]) &= ~s->mask2.w;
2535                 *(uint16_t *)(&s->vram_b[addr]) |= data.w[0] & s->mask2.w;
2536             }
2537             if (!(s->access & 2)) {
2538                 *(uint16_t *)(&s->vram_r[addr]) &= ~s->mask2.w;
2539                 *(uint16_t *)(&s->vram_r[addr]) |= data.w[1] & s->mask2.w;
2540             }
2541             if (!(s->access & 4)) {
2542                 *(uint16_t *)(&s->vram_g[addr]) &= ~s->mask2.w;
2543                 *(uint16_t *)(&s->vram_g[addr]) |= data.w[2] & s->mask2.w;
2544             }
2545             if (!(s->access & 8)) {
2546                 *(uint16_t *)(&s->vram_e[addr]) &= ~s->mask2.w;
2547                 *(uint16_t *)(&s->vram_e[addr]) |= data.w[3] & s->mask2.w;
2548             }
2549         }
2550     } else if (!(s->sft & 0x1000)) {
2551         egc_mem_writeb(s, addr1, (uint8_t)value);
2552         egc_mem_writeb(s, addr1 + 1, (uint8_t)(value >> 8));
2553     } else {
2554         egc_mem_writeb(s, addr1, (uint8_t)(value >> 8));
2555         egc_mem_writeb(s, addr1 + 1, (uint8_t)value);
2556     }
2557 }
2558  
2559 /* i/o */
2560  
2561 static void egc_ioport_writeb(void *opaque, uint32_t addr, uint32_t value)
2562 {
2563     egc_t *s = opaque;
2564     vga_t *v = s->vga;
2565  
79 roytam 2566     if (!((v->grcg_mode & GRCG_CG_MODE) && v->mode2[MODE2_EGC])) {
74 roytam 2567         return;
2568     }
2569     switch(addr) {
2570     case 0x4a0:
2571         s->access &= 0xff00;
2572         s->access |= value;
2573         break;
2574     case 0x4a1:
2575         s->access &= 0x00ff;
2576         s->access |= value << 8;
2577         break;
2578     case 0x4a2:
2579         s->fgbg &= 0xff00;
2580         s->fgbg |= value;
2581         break;
2582     case 0x4a3:
2583         s->fgbg &= 0x00ff;
2584         s->fgbg |= value << 8;
2585         break;
2586     case 0x4a4:
2587         s->ope &= 0xff00;
2588         s->ope |= value;
2589         break;
2590     case 0x4a5:
2591         s->ope &= 0x00ff;
2592         s->ope |= value << 8;
2593         break;
2594     case 0x4a6:
2595         s->fg &= 0xff00;
2596         s->fg |= value;
2597         s->fgc.d[0] = *(uint32_t *)(egc_maskword[value & 0x0f] + 0);
2598         s->fgc.d[1] = *(uint32_t *)(egc_maskword[value & 0x0f] + 2);
2599         break;
2600     case 0x4a7:
2601         s->fg &= 0x00ff;
2602         s->fg |= value << 8;
2603         break;
2604     case 0x4a8:
2605         if (!(s->fgbg & 0x6000)) {
2606             s->mask.b[0] = value;
2607         }
2608         break;
2609     case 0x4a9:
2610         if (!(s->fgbg & 0x6000)) {
2611             s->mask.b[1] = value;
2612         }
2613         break;
2614     case 0x4aa:
2615         s->bg &= 0xff00;
2616         s->bg |= value;
2617         s->bgc.d[0] = *(uint32_t *)(egc_maskword[value & 0x0f] + 0);
2618         s->bgc.d[1] = *(uint32_t *)(egc_maskword[value & 0x0f] + 2);
2619         break;
2620     case 0x4ab:
2621         s->bg &= 0x00ff;
2622         s->bg |= value << 8;
2623         break;
2624     case 0x4ac:
2625         s->sft &= 0xff00;
2626         s->sft |= value;
2627         egc_shift(s);
2628         s->srcmask.w = 0xffff;
2629         break;
2630     case 0x4ad:
2631         s->sft &= 0x00ff;
2632         s->sft |= value << 8;
2633         egc_shift(s);
2634         s->srcmask.w = 0xffff;
2635         break;
2636     case 0x4ae:
2637         s->leng &= 0xff00;
2638         s->leng |= value;
2639         egc_shift(s);
2640         s->srcmask.w = 0xffff;
2641         break;
2642     case 0x4af:
2643         s->leng &= 0x00ff;
2644         s->leng |= value << 8;
2645         egc_shift(s);
2646         s->srcmask.w = 0xffff;
2647         break;
2648     }
2649 }
2650  
2651 static void egc_ioport_writew(void *opaque, uint32_t addr, uint32_t value)
2652 {
2653     egc_t *s = opaque;
2654     vga_t *v = s->vga;
2655  
79 roytam 2656     if (!((v->grcg_mode & GRCG_CG_MODE) && v->mode2[MODE2_EGC])) {
74 roytam 2657         return;
2658     }
2659     switch(addr) {
2660     case 0x4a0:
2661         s->access = value;
2662         break;
2663     case 0x4a2:
2664         s->fgbg = value;
2665         break;
2666     case 0x4a4:
2667         s->ope = value;
2668         break;
2669     case 0x4a6:
2670         s->fg = value;
2671         s->fgc.d[0] = *(uint32_t *)(egc_maskword[value & 0x0f] + 0);
2672         s->fgc.d[1] = *(uint32_t *)(egc_maskword[value & 0x0f] + 2);
2673         break;
2674     case 0x4a8:
2675         if (!(s->fgbg & 0x6000)) {
2676             s->mask.w = value;
2677         }
2678         break;
2679     case 0x4aa:
2680         s->bg = value;
2681         s->bgc.d[0] = *(uint32_t *)(egc_maskword[value & 0x0f] + 0);
2682         s->bgc.d[1] = *(uint32_t *)(egc_maskword[value & 0x0f] + 2);
2683         break;
2684     case 0x4ac:
2685         s->sft = value;
2686         egc_shift(s);
2687         s->srcmask.w = 0xffff;
2688         break;
2689     case 0x4ae:
2690         s->leng = value;
2691         egc_shift(s);
2692         s->srcmask.w = 0xffff;
2693         break;
2694     }
2695 }
2696  
2697 /* interface */
2698  
2699 static void egc_set_vram(void *opaque, uint8_t *vram_ptr)
2700 {
2701     egc_t *s = opaque;
2702  
2703     s->vram_ptr = vram_ptr;
2704     s->vram_b = vram_ptr + 0x00000;
2705     s->vram_r = vram_ptr + 0x08000;
2706     s->vram_g = vram_ptr + 0x10000;
2707     s->vram_e = vram_ptr + 0x18000;
2708 }
2709  
77 roytam 2710 static void egc_pre_save(void *opaque)
74 roytam 2711 {
77 roytam 2712     egc_t *s = opaque;
74 roytam 2713  
2714     s->inptr_vmstate = s->inptr - s->buf;
2715     s->outptr_vmstate = s->outptr - s->buf;
2716 }
2717  
2718 static int egc_post_load(void *opaque)
2719 {
2720     egc_t *s = opaque;
2721  
2722     s->inptr = s->buf + s->inptr_vmstate;
2723     s->outptr = s->buf + s->outptr_vmstate;
2724     return 0;
2725 }
2726  
2727 static const VMStateDescription vmstate_egc = {
2728     .name = "pc98-egc",
2729     .version_id = 1,
2730     .minimum_version_id = 1,
2731     .minimum_version_id_old = 1,
2732     .fields      = (VMStateField []) {
2733         VMSTATE_UINT16(access, egc_t),
2734         VMSTATE_UINT16(fgbg, egc_t),
2735         VMSTATE_UINT16(ope, egc_t),
2736         VMSTATE_UINT16(fg, egc_t),
2737         VMSTATE_UINT16(mask.w, egc_t),
2738         VMSTATE_UINT16(bg, egc_t),
2739         VMSTATE_UINT16(sft, egc_t),
2740         VMSTATE_UINT16(leng, egc_t),
2741         VMSTATE_UINT64(lastvram.q, egc_t),
2742         VMSTATE_UINT64(patreg.q, egc_t),
2743         VMSTATE_UINT64(fgc.q, egc_t),
2744         VMSTATE_UINT64(bgc.q, egc_t),
2745         VMSTATE_INT32(func, egc_t),
2746         VMSTATE_UINT32(remain, egc_t),
2747         VMSTATE_UINT32(stack, egc_t),
2748         VMSTATE_INT32(inptr_vmstate, egc_t),
2749         VMSTATE_INT32(outptr_vmstate, egc_t),
2750         VMSTATE_UINT16(mask2.w, egc_t),
2751         VMSTATE_UINT16(srcmask.w, egc_t),
2752<