OSDN Git Service

5d80d62f5dfb1dd7c712f73cef73db50ebbb590c
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / display.cpp
1 /*
2  * Common source code project -> FM-7 -> Display
3  * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  * History:
5  *  Feb 10, 2015 : Initial.
6  */
7
8 #include "fm7_display.h"
9
10 extern "C" {
11
12   extern void initvramtbl_4096_vec(void);
13   extern void detachvramtbl_4096_vec(void);
14   extern void PutBlank(uint32 *p, int height);
15   extern void CreateVirtualVram8_Line(uint8 *src, uint32 *p, int ybegin, uint32 *pal);
16   extern void CreateVirtualVram8_WindowedLine(uint8 *vram_1, uint8 *vram_w, Uint32 *p, int ybegin, int xbegin, int xend, uint32 *pal);
17 }
18
19
20 DISPLAY::DISPLAY(VM* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu)
21 {
22         p_vm = parent_vm;
23         p_emu = parent_emu;
24         //      initvramtbl_4096_vec();
25 }
26
27 DISPLAY::~DISPLAY()
28 {
29
30 }
31
32 void DISPLAY::reset(void)
33 {
34         int i;
35         
36         if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
37         if(hblank_event_id >= 0) cancel_event(this, hblank_event_id);
38         if(hdisp_event_id >= 0) cancel_event(this, hdisp_event_id);
39         if(vsync_event_id >= 0) cancel_event(this, vsync_event_id);
40         if(vstart_event_id >= 0) cancel_event(this, vstart_event_id);
41         if(halt_event_id >= 0) cancel_event(this, halt_event_id);
42         hblank_event_id = -1;
43         hdisp_event_id = -1;
44         vsync_event_id = -1;
45         halt_event_id = -1;
46         for(i = 0; i < 8; i++) set_dpalette(i, i);
47         
48         offset_77av = false;
49         sub_run = true;
50         crt_flag = true;
51         vram_accessflag = false;
52         display_mode = DISPLAY_MODE_8_200L;
53         vram_wait = false;
54         
55         multimode_accessmask = 0;
56         multimode_dispmask = 0;
57         
58         vblank = false;
59         vsync = false;
60         hblank = true;
61         halt_flag = false;
62         displine = 0;
63         
64         set_cyclesteal(config.dipswitch & 0x01); // CYCLE STEAL = bit0.
65         nmi_count = 0;
66         irq_count = 0;
67         firq_count = 0;
68         vram_wrote = true;
69         window_low = 0;
70         window_high = 200;
71         window_xbegin = 0;
72         window_xend = 80;
73         window_opened = false;
74         subcpu_resetreq = false;
75         is_cyclesteal = false;
76         offset_point = 0;
77         tmp_offset_point = 0;
78         offset_changed = true;
79         halt_count = 0;
80    
81         if((config.dipswitch & 0x01) != 0) is_cyclesteal = true;
82
83         register_event(this, EVENT_FM7SUB_VSTART, 1.0 * 1000.0, false, &vstart_event_id);   
84         register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
85 //      subcpu->reset();
86 }
87
88 void DISPLAY::update_config(void)
89 {
90         set_cyclesteal(config.dipswitch & 0x01); // CYCLE STEAL = bit0.
91 }
92
93 inline int DISPLAY::GETVRAM_8_200L(int yoff, scrntype *p, uint32 rgbmask)
94 {
95         register uint8 b, r, g;
96         register uint32 dot;
97         yoff = yoff & 0x3fff;
98         b = gvram[yoff];
99         r = gvram[yoff + 0x4000];
100         g = gvram[yoff + 0x8000];
101         
102         dot = ((g & 0x80) >> 5) | ((r & 0x80) >> 6) | ((b & 0x80) >> 7);
103         *p++ = dpalette_pixel[dot & rgbmask];
104         dot = ((g & 0x40) >> 4) | ((r & 0x40) >> 5) | ((b & 0x40) >> 6);
105         *p++ = dpalette_pixel[dot & rgbmask];
106         dot = ((g & 0x20) >> 3) | ((r & 0x20) >> 4) | ((b & 0x20) >> 5);
107         *p++ = dpalette_pixel[dot & rgbmask];
108         dot = ((g & 0x10) >> 2) | ((r & 0x10) >> 3) | ((b & 0x10) >> 4);
109         *p++ = dpalette_pixel[dot & rgbmask];
110                                         
111         dot = ((g & 0x8) >> 1) | ((r & 0x8) >> 2) | ((b & 0x8) >> 3);
112         *p++ = dpalette_pixel[dot & rgbmask];
113         dot = (g & 0x4) | ((r & 0x4) >> 1) | ((b & 0x4) >> 2);
114         *p++ = dpalette_pixel[dot & rgbmask];
115         dot = ((g & 0x2) << 1) | (r & 0x2) | ((b & 0x2) >> 1);
116         *p++ = dpalette_pixel[dot & rgbmask];
117         dot = ((g & 0x1) << 2) | ((r & 0x1) << 1) | (b & 0x1);
118         *p = dpalette_pixel[dot & rgbmask];
119         yoff++;
120         return yoff;
121 }
122
123 void DISPLAY::draw_screen(void)
124 {
125         int y;
126         int x;
127         int i;
128         int height = (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200;
129         scrntype *p, *pp, *q;
130         register int yoff;
131         Uint32 planesize = 0x4000;
132         uint32 offset;
133         register uint32 rgbmask;
134         if(!vram_wrote) return;
135         
136 #if defined(_FM77AV_VARIANTS)
137         if(offset_77av) {
138           offset = offset_point;
139         } else {
140           offset = offset_point & 0x7fe0;
141         }
142 #else
143         offset = offset_point & 0x7fe0;
144 #endif
145         if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_400L_TEXT)) {
146                 planesize = 0x8000;
147         } else if((display_mode == DISPLAY_MODE_8_200L) || (display_mode == DISPLAY_MODE_8_200L_TEXT)) {
148                 offset = offset & 0x3fff;
149         } else if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)) {
150                 planesize = 0x2000;
151                 offset = offset & 0x1fff;
152         } else {
153                 return;
154         }
155           // Set blank
156         if(!crt_flag) {
157                 vram_wrote = false;
158                 for(y = 0; y < 400; y++) {
159                         memset(emu->screen_buffer(y), 0x00, 640 * sizeof(scrntype));
160                 }
161         } else  if((display_mode == DISPLAY_MODE_8_200L) || (display_mode == DISPLAY_MODE_8_200L_TEXT)) {
162                 vram_wrote = false;
163                 yoff = offset & 0x3fff;
164                 rgbmask = ~multimode_dispmask & 0x07;
165                 for(y = 0; y < 400; y += 2) {
166                         p = emu->screen_buffer(y);
167                         pp = p;
168                         for(x = 0; x < 10; x++) {
169                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
170                           p += 8;
171                           
172                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
173                           p += 8;
174
175                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
176                           p += 8;
177
178                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
179                           p += 8;
180
181                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
182                           p += 8;
183                           
184                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
185                           p += 8;
186                           
187                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
188                           p += 8;
189                           
190                           yoff = GETVRAM_8_200L(yoff, p, rgbmask);
191                           p += 8;
192                         }
193                         if(config.scan_line == 0) {
194                                 memcpy((void *)emu->screen_buffer(y + 1), pp, 640 * sizeof(scrntype));
195                         } else {
196                                 memset((void *)emu->screen_buffer(y + 1), 0x00, 640 * sizeof(scrntype));
197                         }
198                 }
199         }
200              
201                         
202 #if defined(_FM77AV_VARIANTS)
203         else if(display_mode == DISPLAY_MODE_4096) {
204                 for(y = 0; y < height; y++) {
205                         p = &pvram[y * pitch];
206                         if(((y < window_low) && (y > window_high)) || (!window_opened)) {
207                                 CreateVirtualVram4096_Line(p, y, offset, apalette_pixel, multimode_dispmask);
208                         } else {
209                                 CreateVirtualVram4096_WindowedLine(p, y, window_xbegin, window_xend,
210                                                                    offset, apalette_pixel, multimode_dispmask);
211                         }
212                 }
213         }
214 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
215         else { // 256k
216                 for(y = 0; y < height; y++) {
217                         p = &pvram[y * pitch];
218                         if(((y < window_low) && (y > window_high)) || (!window_opened)) {
219                                 CreateVirtualVram256k_Line(p, y, offset, multimode_dispmask);
220                         } else {
221                                 CreateVirtualVram256k_WindowedLine(p, y, offset, window_xbegin, window_xend,
222                                                                    multimode_dispmask);
223                         }
224                 }
225         }
226 #endif // _FM77AV40
227 #endif //_FM77AV_VARIANTS
228 }
229
230 void DISPLAY::do_irq(bool flag)
231 {
232         if(flag) {
233                 if(irq_count >= 0x7ffffffe) {
234                         irq_count = 0x7ffffffe;
235                         return;
236                 }
237                 irq_count++;
238                 if(irq_count <= 1) subcpu->write_signal(SIG_CPU_IRQ, 1, 1);
239         } else {
240                 if(irq_count <= 0) {
241                         irq_count = 0;
242                         return;
243                 }
244                 irq_count--;
245                 if(irq_count == 0) subcpu->write_signal(SIG_CPU_IRQ, 0, 1);
246         }
247 }
248
249 void DISPLAY::do_firq(bool flag)
250 {
251         if(flag) {
252                 if(firq_count >= 0x7ffffffe) {
253                         firq_count = 0x7ffffffe;
254                         return;
255                 }
256                 firq_count++;
257                 if(firq_count <= 1) subcpu->write_signal(SIG_CPU_FIRQ, 1, 1);
258         } else {
259                 if(firq_count <= 0) {
260                         firq_count = 0;
261                         return;
262                 }
263                 firq_count--;
264                 if(firq_count == 0) subcpu->write_signal(SIG_CPU_FIRQ, 0, 1);
265         }
266 }
267
268 void DISPLAY::do_nmi(bool flag)
269 {
270         if(flag) {
271                 if(nmi_count >= 0x7ffffffe) {
272                         nmi_count = 0x7ffffffe;
273                         return;
274                 }
275                 nmi_count++;
276                 if(nmi_count <= 1) subcpu->write_signal(SIG_CPU_NMI, 1, 1);
277         } else {
278                 if(nmi_count <= 0) {
279                         nmi_count = 0;
280                         return;
281                 }
282                 nmi_count--;
283                 if(nmi_count == 0) subcpu->write_signal(SIG_CPU_NMI, 0, 1);
284         }
285 }
286
287 void DISPLAY::set_multimode(uint8 val)
288 {
289         multimode_accessmask = val & 0x07;
290         multimode_dispmask = (val & 0x70) >> 4;
291         vram_wrote = true;
292 }
293
294 uint8 DISPLAY::get_multimode(void)
295 {
296         uint8 val;
297         val = multimode_accessmask & 0x07;
298         val |= ((multimode_dispmask << 4) & 0x70);
299         val |= 0x80;
300         return val;
301 }
302
303 uint8 DISPLAY::get_cpuaccessmask(void)
304 {
305         return multimode_accessmask & 0x07;
306 }
307
308 void DISPLAY::set_dpalette(uint32 addr, uint8 val)
309 {
310         scrntype r, g, b;
311         addr &= 7;
312         dpalette_data[addr] = val | 0b11110000;
313         vram_wrote = true;
314         b =  ((val & 0x01) != 0x00)? 255 : 0x00;
315         r =  ((val & 0x02) != 0x00)? 255 : 0x00;
316         g =  ((val & 0x04) != 0x00)? 255 : 0x00;
317         
318         dpalette_pixel[addr] = RGB_COLOR(r, g, b);
319 }
320
321 uint8 DISPLAY::get_dpalette(uint32 addr)
322 {
323         uint8 data;
324         addr = addr & 7;
325         
326         data = dpalette_data[addr];
327         return data;
328 }
329
330 void DISPLAY::halt_subcpu(void)
331 {
332         if(!(sub_run)) {
333                 printf("SUB HALT\n");
334                 if(halt_count == 0) subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
335                 halt_count++;
336         }
337         if(halt_count >= 0x7ffffff0) halt_count = 0x7ffffff0; 
338         if(halt_count <= 0) halt_count = 0; 
339 }
340
341 void DISPLAY::go_subcpu(void)
342 {
343         if((sub_run) && (halt_count > 0)) {
344                 printf("SUB RUN\n");
345                 halt_count--;
346                 if(halt_count == 0) subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
347         }
348         if(halt_count < 0) halt_count = 0;
349 }
350
351 void DISPLAY::enter_display(void)
352 {
353         bool tmpf;
354         //sub_run = false;
355         if(is_cyclesteal) {
356                 vram_wait = false;
357                 return;
358         }
359         vram_wait = true;
360 }
361
362 void DISPLAY::leave_display(void)
363 {
364         vram_wait = false;
365         //sub_run = false;
366         //go_subcpu();
367 }
368
369 void DISPLAY::halt_subsystem(void)
370 {
371         halt_flag = false;
372         sub_run = false;
373         if(halt_event_id >= 0) cancel_event(this, halt_event_id);
374         register_event_by_clock(this, EVENT_FM7SUB_HALT, 10, true, &halt_event_id);
375         //mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x00, 0x01);
376 }
377
378 void DISPLAY::restart_subsystem(void)
379 {
380         sub_run = true;
381         halt_flag = false;
382         if(sub_run) {
383                 if(halt_event_id >= 0) cancel_event(this, halt_event_id);
384                 halt_event_id = -1;
385                 go_subcpu();
386                 mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
387         }
388 //      go_subcpu();
389 //      mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
390 }
391
392 //SUB:D408:R
393 void DISPLAY::set_crtflag(void)
394 {
395         crt_flag = true;
396         vram_wrote = true;
397 }
398
399 //SUB:D408:W
400 void DISPLAY::reset_crtflag(void)
401 {
402         crt_flag = false;
403         vram_wrote = true;
404 }
405
406 //SUB:D402:R
407 uint8 DISPLAY::acknowledge_irq(void)
408 {
409         this->do_irq(false);
410         //mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x00, 0x01);
411         return 0xff;
412 }
413
414 //SUB:D403:R
415 uint8 DISPLAY::beep(void)
416 {
417         mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
418         return 0xff; // True?
419 }
420
421
422 // SUB:D404 : R 
423 uint8 DISPLAY::attention_irq(void)
424 {
425         mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
426         return 0xff;
427 }
428
429 // SUB:D405:W
430 void DISPLAY::set_cyclesteal(uint8 val)
431 {
432 #if !defined(_FM8)
433         vram_wrote = true;
434         val &= 0x01;
435         if(val != 0) {
436                 is_cyclesteal = true;
437         } else {
438                 is_cyclesteal = false;
439         }
440 #endif
441 }
442
443 //SUB:D409:R
444 uint8 DISPLAY::set_vramaccess(void)
445 {
446         vram_accessflag = true;
447         return 0xff;
448 }
449
450 //SUB:D409:W
451 void DISPLAY::reset_vramaccess(void)
452 {
453         vram_accessflag = false;
454         leave_display();
455 }
456
457 //SUB:D40A:R
458 uint8 DISPLAY::reset_subbusy(void)
459 {
460         mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x00, 0x01);
461         //sub_run = false;
462         return 0xff;
463 }
464
465 //SUB:D40A:W
466 void DISPLAY::set_subbusy(void)
467 {
468         mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01);
469 }
470
471
472 #if defined(_FM77AV_VARIANTS)
473 // D410
474 void DISPLAY::alu_write_cmdreg(uint8 val)
475 {
476         bool busyflag;
477         uint32 data = (uint32)val;
478         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
479         if(busyflag) return; // DISCARD
480         alu->write_signal(SIG_FM7_ALU_CMDREG, data, 0x07);
481         alu->write_signal(SIG_FM7_ALU_MBITS, (data & 0x60) >> 5, 0x03);
482         alu->write_signal(SIG_FM7_ALU_EXEC, data, 0x80);
483 }
484
485 // D411
486 void DISPLAY::alu_write_logical_color(uint8 val)
487 {
488         bool busyflag;
489         uint32 data = (uint32)val;
490         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
491         if(busyflag) return; // DISCARD
492         alu->write_signal(SIG_FM7_ALU_LOGICAL_COLOR, data, 0x03);
493 }
494
495 // D412
496 void DISPLAY::alu_write_mask_reg(uint8 val)
497 {
498         bool busyflag;
499         uint32 data = (uint32)val;
500         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
501         if(busyflag) return; // DISCARD
502         alu->write_signal(SIG_FM7_ALU_WRITE_MASKREG, data, 0xff);
503         }
504
505 // D413 - D41A
506 void DISPLAY::alu_write_mask_reg(int addr, uint8 val)
507 {
508         bool busyflag;
509         uint32 data = (uint32)val;
510         addr = addr & 7;
511         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
512         if(busyflag) return; // DISCARD
513         alu->write_signal(SIG_FM7_ALU_WRITE_CMPREG_ADDR, data, 0x07);
514 }
515
516 // D41B
517 void DISPLAY::alu_write_disable_reg(uint8 val)
518 {
519         bool busyflag;
520         uint32 data = (uint32)val;
521   
522         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
523         if(busyflag) return; // DISCARD
524         data = data & 0x07 | 0x08;
525         alu->write_signal(SIG_FM7_ALU_BANK_DISABLE, data, 0xff);
526 }
527
528 // D41C - D41F
529 void DISPLAY::alu_write_tilepaint_data(int addr, uint8 val)
530 {
531         bool busyflag;
532         uint32 data = (uint32)val;
533         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
534         if(busyflag) return; // DISCARD
535         switch(addr) {
536                 case 0: // $D41C
537                         alu->write_signal(SIG_FM7_ALU_TILEPAINT_B, data, 0xff);
538                         break;
539                 case 1: // $D41D
540                         alu->write_signal(SIG_FM7_ALU_TILEPAINT_R, data, 0xff);
541                         break;
542                 case 2: // $D41E
543                         alu->write_signal(SIG_FM7_ALU_TILEPAINT_G, data, 0xff);
544                         break;
545                 case 3: // xxxx
546                         //alu->write_signal(SIG_FM7_ALU_TILEPAINT_L, data, 0xff);
547                         alu->write_signal(SIG_FM7_ALU_TILEPAINT_L, 0xff, 0xff);
548                         break;
549         }
550 }
551
552 // D420
553 void DISPLAY::alu_write_offsetreg_hi(uint8 val)
554 {
555         bool busyflag;
556         uint32 data = (uint32)val;
557         uint32 addr;
558         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
559         if(busyflag) return; // DISCARD
560         addr = alu->read_signal(SIG_FM7_ALU_OFFSET_REG); 
561         addr = addr & 0x00ff;
562         data <<= 8;
563         addr = addr | data;
564         alu->write_signal(SIG_FM7_ALU_OFFSET_REG, data, 0x1fff);
565 }
566  
567 // D421
568 void DISPLAY::alu_write_offsetreg_lo(uint8 val)
569 {
570         bool busyflag;
571         uint32 data = (uint32)val;
572         uint32 addr;
573         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
574         if(busyflag) return; // DISCARD
575         addr = alu->read_signal(SIG_FM7_ALU_OFFSET_REG); 
576         addr = addr & 0xff00;
577         addr = addr | data;
578         alu->write_signal(SIG_FM7_ALU_OFFSET_REG, data, 0x1fff);
579 }
580
581 // D422
582 void DISPLAY::alu_write_linepattern_hi(uint8 val)
583 {
584         bool busyflag;
585         uint32 data = (uint32)val;
586         uint32 addr;
587         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
588         if(busyflag) return; // DISCARD
589         addr = alu->read_signal(SIG_FM7_ALU_LINEPATTERN_REG); 
590         addr = addr & 0x00ff;
591         data = data << 8;
592         addr = addr | data;
593         alu->write_signal(SIG_FM7_ALU_LINEPATTERN_REG, data, 0xffff);
594 }
595
596 // D423
597 void DISPLAY::alu_write_linepattern_lo(uint8 val)
598 {
599         bool busyflag;
600         uint32 data = (uint32)val;
601         uint32 addr;
602         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
603         if(busyflag) return; // DISCARD
604         addr = alu->read_signal(SIG_FM7_ALU_LINEPATTERN_REG); 
605         addr = addr & 0xff00;
606         addr = addr | data;
607         alu->write_signal(SIG_FM7_ALU_LINEPATTERN_REG, data, 0xffff);
608 }
609
610 // D424-D42B
611 void DISPLAY::alu_write_line_position(int addr, uint8 val)
612 {
613         bool busyflag;
614         uint32 data = (uint32)val;
615         busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
616         if(busyflag) return; // DISCARD
617         switch(addr) {
618                 case 0:  
619                         alu->write_signal(SIG_FM7_ALU_LINEPOS_START_X_HIGH, data, 0x03); 
620                         break;
621                 case 1:  
622                         alu->write_signal(SIG_FM7_ALU_LINEPOS_START_X_LOW, data, 0xff); 
623                         break;
624                 case 2:  
625                         alu->write_signal(SIG_FM7_ALU_LINEPOS_START_Y_HIGH, data, 0x01); 
626                         break;
627                 case 3:  
628                         alu->write_signal(SIG_FM7_ALU_LINEPOS_START_Y_LOW, data, 0xff); 
629                         break;
630                 case 4:  
631                         alu->write_signal(SIG_FM7_ALU_LINEPOS_END_X_HIGH, data, 0x03); 
632                         break;
633                 case 5:  
634                         alu->write_signal(SIG_FM7_ALU_LINEPOS_END_X_LOW, data, 0xff); 
635                         break;
636                 case 6:  
637                         alu->write_signal(SIG_FM7_ALU_LINEPOS_END_Y_HIGH, data, 0x01); 
638                         break;
639                 case 7:  
640                         alu->write_signal(SIG_FM7_ALU_LINEPOS_END_Y_LOW, data, 0xff); 
641                         break;
642         }
643 }
644
645 // D42E :  AV40
646 void DISPLAY::select_sub_bank(uint8 val)
647 {
648 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX)   
649         kanji_level2 = ((val & 0x80) == 0) ? false : true;
650   //    submem->write_signal(SIG_FM7_SUBMEM_SELECT_BANK val, 0x1f);
651 #endif
652 }
653
654 // D42F
655 void DISPLAY::select_vram_bank_av40(uint8 val)
656 {
657   //    submem->write_signal(SIG_FM7_SUBMEM_AV40_SELECT_BANK val, 0x03);
658 }
659
660
661 //SUB:D430:R
662 uint8 DISPLAY::get_miscreg(void)
663 {
664         uint8 ret;
665 #if defined(_FM77AV_VARIANTS)
666         ret = 0x00;
667         if(!hblank && !vblank) ret |= 0x80;
668         if(vsync) ret |= 0x40;
669         if(alu->read_signal(SIG_ALU_BUSY) == 0) ret |= 0x10;
670         if(subreset) ret |= 0x01;
671 #else // 77 or older.
672         ret = 0xff;
673 #endif
674         return ret;
675 }
676 //SUB:D430:W
677 void DISPLAY::set_miscreg(uint8 val)
678 {
679   
680 #if defined(_FM77AV40) || defined(_FM77AV40EX) || || defined(_FM77AV40SX)
681         nmi_enable = ((val & 0x80) == 0) ? true : false;
682 #endif
683         if((val & 0x40) == 0) {
684                 if(display_page != 0) {
685                   redrawreq();
686                 }
687                 display_page = 0;
688         } else {
689                 if(display_page == 0) {
690                         redrawreq();
691                 }
692                 display_page = 1;
693         }
694         active_page = ((val & 0x20) == 0) ? 0 : 1;
695         if((val & 0x04) == 0) {
696                 offset_77av = false;
697         } else {
698                 offset_77av = true;
699         }
700         submem->write_signal(SIG_FM7SUBMEM_CGROM, val, 0x03);
701 }
702
703 // Main: FD13
704 void DISPLAY::set_monitor_bank(uint8 var)
705 {
706 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
707         if((var & 0x04) != 0){
708                 monitor_ram = true;
709         } else {
710                 monitor_ram = false;
711         }
712 #endif
713         subrom_bank = var & 0x03;
714         subcpu_resetreq = true;
715         mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01);
716 }
717
718
719 // FD30
720 void DISPLAY::set_apalette_index_hi(uint8 val)
721 {
722         uint32 index = (uint32)val;
723         index &= 0x0f;
724         index <<= 8; // right?
725
726         apalette_index = (apalette_index & 0xff) | index;
727 }
728
729 // FD31
730 void DISPLAY::set_apalette_index_lo(uint8 val)
731 {
732         uint32 index = (uint32)val;
733         index &= 0xff;
734
735         apalette_index = (apalette_index & 0xf00) | index;
736 }
737
738 void DISPLAY::calc_apalette(uint32 index)
739 {
740         scrntype r, g, b;
741         vram_wrote = true;
742         r = (apalette_r[index] == 0)? 0 : apalette_r[index] << 4; // + 0x0f?
743         g = (apalette_g[index] == 0)? 0 : apalette_g[index] << 4; // + 0x0f?
744         b = (apalette_b[index] == 0)? 0 : apalette_b[index] << 4; // + 0x0f?
745         apalette_pixel[index] = RGB_COLOR(r, g, b);
746 }
747
748 // FD32
749 void DISPLAY::set_apalette_b(uint8 val)
750 {
751         uint32 index;
752         index = apalette_index & 0xfff;
753         analog_palette_b[index] = val & 0x0f;
754         calc_apalette(index);
755 }
756
757 // FD33
758 void DISPLAY::set_apalette_r(uint8 val)
759 {
760         uint32 index;
761         index = apalette_index & 0xfff;
762         analog_palette_r[index] = val & 0x0f;
763         calc_apalette(index);
764 }
765
766 // FD34
767 void DISPLAY::set_apalette_g(uint8 val)
768 {
769         uint32 index;
770         index = apalette_index & 0xfff;
771         analog_palette_g[index] = val & 0x0f;
772         calc_apalette(index);
773 }
774
775 #endif // _FM77AV_VARIANTS
776
777 // Timing values from XM7 . Thanks Ryu.
778 void DISPLAY::event_callback(int event_id, int err)
779 {
780         double usec;
781         uint64 haltclocks;
782         bool f;
783         switch(event_id) {
784                 case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
785                         do_nmi(true);
786                         register_event(this, EVENT_FM7SUB_DISPLAY_NMI_OFF, 10.0 * 1000.0, false, NULL); // NEXT CYCLE_
787                         break;
788                 case EVENT_FM7SUB_DISPLAY_NMI_OFF: // per 20.00ms
789                         do_nmi(false);
790                         break;
791                 case EVENT_FM7SUB_HDISP:
792                         hblank = false;
793                         usec = 39.5;
794                         if(display_mode == DISPLAY_MODE_8_400L) usec = 30.0;
795                         register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
796                         enter_display();
797                         break;
798                 case EVENT_FM7SUB_HBLANK:
799                         hblank = true;
800                         f = false;
801                         displine++;
802                         //if(!is_cyclesteal && vram_accessflag)  leave_display();
803                         leave_display();
804                         if(display_mode == DISPLAY_MODE_8_400L) {
805                                 usec = 11.0;
806                                 if(displine < 400) f = true; 
807                         } else {
808                                 usec = 24.0;
809                                 if(displine < 200) f = true;
810                         }
811                         if(f) {
812                                 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
813                         } else {
814                                 // Vblank?
815                                 vblank = true;
816                                 vsync = true;
817                                 if(display_mode == DISPLAY_MODE_8_400L) {
818                                         usec = 0.31 * 1000.0;
819                                 } else {
820                                         usec = 0.51 * 1000.0;
821                                 }
822                                 register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id); // NEXT CYCLE_
823                         }
824                         break;
825                 case EVENT_FM7SUB_VSTART: // Call first.
826                         vblank = false;
827                         vsync = false;
828                         hblank = true;
829                         displine = 0;
830                         leave_display();
831                         if(display_mode == DISPLAY_MODE_8_400L) {
832                                 usec = 11.0;
833                         } else {
834                                 usec = 24.0;
835                         }
836                         register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
837                         break;
838                 case EVENT_FM7SUB_VSYNC:
839                         vblank = true;
840                         vsync = false;
841                         if(display_mode == DISPLAY_MODE_8_400L) {
842                                 usec = 0.98 * 1000.0;
843                         } else {
844                                 usec = 1.91 * 1000.0;
845                         }
846                         register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
847                         break;
848                 case EVENT_FM7SUB_HALT:
849                         if(!sub_run) {
850                                 halt_subcpu();
851                                 mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
852                                 cancel_event(this, halt_event_id);
853                                 halt_event_id = -1;
854                                 halt_flag = true;                  
855                         }
856                 break;
857         }
858 }
859
860 void DISPLAY::event_frame()
861 {
862   
863 }
864
865 void DISPLAY::event_vline(int v, int clock)
866 {
867 }
868
869 uint32 DISPLAY::read_signal(int id)
870 {
871         switch(id) {
872                 case SIG_FM7_SUB_HALT:
873                 case SIG_DISPLAY_HALT:
874                         return (halt_flag) ? 0 : 0xffffffff;
875                         break;
876                 default:
877                         return 0;
878                         break;
879         }
880    
881 }
882
883 void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
884 {
885         bool flag = ((data & mask) != 0);
886         switch(id) {
887                 case SIG_DISPLAY_HALT:
888                 case SIG_FM7_SUB_HALT:
889                         if(flag) {
890                                 if(sub_run) halt_subsystem();
891                         } else {
892                                 if(sub_run) return;   
893                                 restart_subsystem();
894                                 if(subcpu_resetreq) {
895                                         vram_wrote = true;
896                                         subcpu->reset();
897                                         subcpu_resetreq = false;
898                                 }
899                         }
900                         break;
901                 case SIG_FM7_SUB_CANCEL:
902                         if(flag) do_irq(true);
903                         break;
904 #if defined(_FM77AV_VARIANTS)
905                 case SIG_FM7_SUB_BANK: // Main: FD13
906                         set_monitor_bank(data & 0xff);
907                         break;
908 #endif // _FM77AV_VARIANTS
909                 case SIG_FM7_SUB_MULTIPAGE:
910                         set_multimode(data & 0xff);
911                         break;
912                 case SIG_FM7_SUB_KEY_FIRQ:
913                         do_firq(flag);
914                         break;
915                 default:
916                         break;
917         }
918 }
919                   
920
921 uint32 DISPLAY::read_data8(uint32 addr)
922 {
923         uint32 raddr = addr;;
924         uint32 mask = 0x3fff;
925         uint32 offset;
926         //      addr = addr & 0x00ffffff;
927         
928 #if defined(_FM77AV_VARIANTS)
929         if(offset_77av) {
930           offset = offset_point;
931         } else {
932           offset = offset_point & 0x7fe0;
933         }
934 #else
935         offset = offset_point & 0x7fe0;
936 #endif
937
938         if(addr < 0xc000) {
939                 uint32 pagemod;
940                 if(!(is_cyclesteal | vram_accessflag)) return 0xff;
941 #if defined(_FM77L4)
942                 if(display_mode == DISPLAY_MODE_8_400L) {
943                         if(addr < 0x8000) {
944                                 if(workram) {
945                                   raddr = addr & 0x3fff;
946                                   if((multimode_accessmask & 0x04) == 0) {
947                                         return gvram[0x8000 + (raddr + offset) & mask];
948                                   }
949                                   return 0xff;
950                                 }
951                                 pagemod = addr & 0x4000;
952                                 return gvram[((addr + offset) & mask) | pagemod];
953                         } else if(addr < 0x9800) {
954                                 return textvram[addr & 0x0fff];
955                         } else { // $9800-$bfff
956                                 return subrom_l4[addr - 0x9800];
957                         }
958                 }
959 #elif defined(_FM77AV_VARIANTS)
960       
961 # if defined(_FM77AV40) || if defined(_FM77AV40EX) || if defined(_FM77AV40SX)
962                 if(display_mode == DISPLAY_MODE_8_400L) {
963                         if(addr < 0x8000) {
964                           // Fixme:Read via ALU
965                           //
966                           pagemod = addr >> 14;
967                           mask = 0x7fff;
968                           addr = (addr + offset) & mask;
969                           if((multimode_accessmask & (1 << vram_bank)) == 0) {
970                                 switch(vram_bank) {
971                                 case 0:
972                                         return gvram[addr];
973                                         break;
974                                 case 1:
975                                         return gvram_1[addr];
976                                         break;
977                                 case 2:
978                                         return gvram_2[addr];
979                                         break;
980                                 default:
981                                         return 0xff;
982                                         break;
983                                 }
984                           }
985                         }
986                         return 0xff;
987                 } else if(display_mode == DISPLAY_MODE_256k) {
988                         if(vram_ac);
989                 }
990 # endif
991                 if(display_mode == DISPLAY_MODE_4096) {
992                         mask = 0x1fff;
993                 } else {
994                         mask = 0x3fff;
995                 }
996                 if(vram_bank) {
997                         pagemod = addr >> 14;
998                         if((multimode_accessmask & (1 << pagemod)) != 0) {
999                                 return 0xff;
1000                         } else {
1001                                 return gvram_1[((addr + offset) & mask) | (pagemod << 14)];
1002                         }
1003                 }
1004 #endif //_FM77L4
1005                 pagemod = addr >> 14;
1006                 if((multimode_accessmask & (1 << pagemod)) != 0) {
1007                         return 0xff;
1008                 } else {
1009                         pagemod = addr & 0xc000;
1010                         return gvram[((addr + offset) & mask) | pagemod];
1011                 }
1012         } else if(addr < 0xd000) { 
1013                 raddr = addr - 0xc000;
1014 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1015                 if(submon_bank == 4) {
1016                         if(cgram_bank >= 1) {
1017                                 return (uint32)submem_cgram[((cgram_bank - 1) << 12) | raddr];
1018                         }
1019                 }
1020 #endif
1021                 return console_ram[raddr];
1022         } else if(addr < 0xd380) {
1023                 raddr = addr - 0xd000;
1024                 return work_ram[raddr];
1025         } else if(addr < 0xd400) {
1026                 raddr = addr - 0xd380;
1027                 return shared_ram[raddr];
1028         } else  if(addr < 0xd800) {
1029                 uint32 retval = 0xff;
1030 #if !defined(_FM77AV_VARIANTS)
1031                 raddr = (addr - 0xd400) & 0x000f;
1032 #else
1033                 raddr = (addr - 0xd400) & 0x003f;
1034 #endif
1035                 switch(raddr) {
1036                         case 0x00: // Read keyboard
1037                                 retval = (keyboard->read_data8(0x0) & 0x80) | 0x7f;
1038                                 break;
1039                         case 0x01: // Read keyboard
1040                                 this->do_firq(false);
1041                                 mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, 0, 1);
1042                                 retval = keyboard->read_data8(1);
1043                                 break;
1044                         case 0x02: // Acknowledge
1045                                 acknowledge_irq();
1046                                 break;
1047                         case 0x03:
1048                                 beep();
1049                                 break;
1050                         case 0x04:
1051                                 attention_irq();
1052                                 break;
1053                 
1054 #if defined(_FM77L4) || defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1055                         case 0x06:
1056  #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX)  
1057                                 if(kanji_level2) {
1058                                         retval = kanjiclass2->read_data8(kanji2_addr);
1059                                 } else {
1060                                         retval = kanjiclass1->read_data8(kanji1_addr);
1061                                 }
1062  #else // _FM77L4
1063                                 retval = kanjiclass1->read_data8(kanji1_addr);
1064 #endif                          
1065                                 break;
1066                         case 0x07:
1067  #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX)  
1068                                 if(kanji_level2) {
1069                                         retval = kanjiclass2->read_data8(kanji2_addr + 1);
1070                                 } else {
1071                                         retval = kanjiclass1->read_data8(kanji1_addr + 1);
1072                                 }
1073  #else // _FM77L4
1074                                 retval = kanjiclass1->read_data8(kanji1_addr + 1);
1075 #endif                          
1076                                 break;
1077 #endif
1078                         case 0x08:
1079                                 vram_wrote = true;
1080                                 set_crtflag();
1081                                 break;
1082                         case 0x09:
1083                                 set_vramaccess();
1084                                 break;
1085                         case 0x0a:
1086                                 reset_subbusy();
1087                                 break;
1088                         case 0x0d:
1089                                 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x01, 0x01);
1090                                 break;
1091                         default:
1092                                 break;
1093                 }
1094                 return retval;
1095         } else if(addr < 0x10000) {
1096 #if !defined(_FM77AV_VARIANTS)
1097                 return subsys_c[addr - 0xd800];
1098 #endif
1099         } else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1100                 return dpalette_data[addr - FM7_SUBMEM_OFFSET_DPALETTE];
1101         }
1102         return 0xff;
1103 }       
1104
1105 void DISPLAY::write_data8(uint32 addr, uint32 data)
1106 {
1107         uint32 mask = 0x3fff;
1108         uint8 val8 = data & 0xff;
1109         uint32 rval;
1110         uint32 offset;
1111         //      addr = addr & 0x00ffffff;
1112         
1113 #if defined(_FM77AV_VARIANTS)
1114         if(offset_77av) {
1115           offset = offset_point;
1116         } else {
1117           offset = offset_point & 0x7fe0;
1118         }
1119 #else
1120         offset = offset_point & 0x7fe0;
1121 #endif
1122         if(addr < 0xc000) {
1123                 uint32 pagemod;
1124                 if(!(is_cyclesteal | vram_accessflag)) return;
1125 #if defined(_FM77L4)
1126                 if(display_mode == DISPLAY_MODE_8_400L) {
1127                         if(addr < 0x8000) {
1128                                 if(workram) {
1129                                   addr = addr & 0x3fff;
1130                                   if((multimode_accessmask & 0x04) == 0) {
1131                                         gvram[0x8000 + (addr + offset) & mask] = val8;
1132                                   }
1133                                   return;
1134                                 }
1135                                 pagemod = addr & 0x4000;
1136                                 gvram[((addr + offset) & mask) | pagemod] = val8;
1137                         } else if(addr < 0x9800) {
1138                                 textvram[addr & 0x0fff] = val8;
1139                         } else { // $9800-$bfff
1140                                 subrom_l4[addr - 0x9800] = val8;
1141                         }
1142                         return;
1143                 }
1144 #elif defined(_FM77AV_VARIANTS)
1145       
1146 # if defined(_FM77AV40) || if defined(_FM77AV40EX) || if defined(_FM77AV40SX)
1147                 if(display_mode == DISPLAY_MODE_8_400L) {
1148                         if(addr < 0x8000) {
1149                           // Fixme:Read via ALU
1150                           //
1151                           pagemod = addr >> 14;
1152                           mask = 0x7fff;
1153                           addr = (addr + offset) & mask;
1154                           if((multimode_accessmask & (1 << vram_bank)) == 0) {
1155                                 switch(vram_bank) {
1156                                         case 0:
1157                                                 gvram[addr] = val8;
1158                                                 break;
1159                                         case 1:
1160                                                 gvram_1[addr] = val8;
1161                                                 break;
1162                                         case 2:
1163                                                 gvram_2[addr] = val8;
1164                                                 break;
1165                                         default:
1166                                                 break;
1167                                 }
1168                           }
1169                           return;
1170                 } else if(display_mode == DISPLAY_MODE_256k) {
1171                         return;
1172                 } else 
1173 #endif
1174                 if(display_mode == DISPLAY_MODE_4096) {
1175                         mask = 0x1fff;
1176                 } else {
1177                         mask = 0x3fff;
1178                 }
1179                 if(vram_bank) {
1180                         pagemod = addr >> 14;
1181                         if((multimode_accessmask & (1 << pagemod)) == 0) {
1182                                 gvram_1[((addr + offset) & mask) | (pagemod << 14)] = val8;
1183                                 if(crt_flag && ((multimode_dispmask & (1 << pagemod)) == 0)) vram_wrote = true;
1184                         }
1185                         return;
1186                 }
1187 #endif //_FM77L4
1188                 pagemod = addr >> 14;
1189                 if((multimode_accessmask & (1 << pagemod)) == 0) {
1190                         pagemod = addr & 0xc000;
1191                         gvram[((addr + offset) & mask) | pagemod] = val8;
1192                         if(crt_flag && ((multimode_dispmask & (1 << pagemod)) == 0)) vram_wrote = true;
1193                 }
1194                 return;
1195         } else if(addr < 0xd000) { 
1196                 addr = addr - 0xc000;
1197 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1198                 if(submon_bank == 4) {
1199                         if(cgram_bank >= 1) {
1200                                 submem_cgram[((cgram_bank - 1) << 12) | addr] = val8;
1201                                 return;
1202                         }
1203                 }
1204 #endif
1205                 console_ram[addr] = val8;
1206                 return;
1207         } else if(addr < 0xd380) {
1208                 addr -= 0xd000;
1209                 work_ram[addr] = val8;
1210                 return;
1211         } else if(addr < 0xd400) {
1212                 addr -= 0xd380;
1213                 shared_ram[addr] = val8;
1214                 return;
1215         } else if(addr < 0xd800) {
1216                 uint32 retval = 0xff;
1217 #if !defined(_FM77AV_VARIANTS)
1218                 addr = (addr - 0xd400) & 0x000f;
1219 #else
1220                 addr = (addr - 0xd400) & 0x003f;
1221 #endif
1222                 switch(addr) {
1223 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
1224                         case 0x05:
1225                                 set_cyclesteal(val8);
1226                                 break;
1227 #endif
1228                         case 0x06:
1229                                 data <<= 9;
1230                                 data = data & 0x1fe00;
1231 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX)
1232                                 if(kanji_level2) {
1233                                         kanji2_addr = data | (kanji2_addr & 0x001fe);
1234                                 } else {
1235                                         kanji1_addr = data | (kanji1_addr & 0x001fe);
1236                                 }
1237 #elif defined(_FM77L4)
1238                                 kanji1_addr = data | (kanji1_addr & 0x001fe);
1239 #endif                          
1240                                 break;
1241                         case 0x07:
1242                                 data <<= 1;
1243                                 data = data & 0x001fe;
1244 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX)
1245                                 if(kanji_level2) {
1246                                         kanji2_addr = data | (kanji2_addr & 0x1fe00);
1247                                 } else {
1248                                         kanji1_addr = data | (kanji1_addr & 0x1fe00);
1249                                 }
1250 #elif defined(_FM77L4)
1251                                 kanji1_addr = data | (kanji1_addr & 0x1fe00);
1252 #endif
1253                                 break;
1254                 
1255                         case 0x08:
1256                                 vram_wrote = true;
1257                                 reset_crtflag();
1258                                 break;
1259                         case 0x09:
1260                                 reset_vramaccess();
1261                                 break;
1262                         case 0x0a:
1263                                 if(data != 0) {
1264                                         set_subbusy();
1265                                 } else {
1266                                         reset_subbusy();
1267                                 }
1268                                 break;
1269                         case 0x0d:
1270                                 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
1271                                 break;
1272                         case 0x0e:
1273 #if defined(_FM77L4) || defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX)
1274                                 rval = (data & 0x7f) << 8;
1275                                 if(display_mode != DISPLAY_MODE_8_400L) rval = rval & 0x3fff;             
1276 #else
1277                                 rval = (data & 0x3f) << 8;
1278 #endif
1279                                 tmp_offset_point = (tmp_offset_point & 0x00ff) | rval;
1280                                 offset_changed = !offset_changed;
1281                                 if(offset_changed) {
1282                                         offset_point = tmp_offset_point;
1283                                         vram_wrote = true;
1284                                 }
1285                                 break;
1286                         case 0x0f:
1287 #if defined(_FM77AV_VARIANTS)
1288                                 rval = data & 0x00ff;
1289                                 if(!offset_77av) rval = rval & 0xe0;              
1290 #else
1291                                 rval = data & 0x00e0;
1292 #endif
1293                                 tmp_offset_point = (tmp_offset_point & 0x7f00) | rval;
1294                                 offset_changed = !offset_changed;
1295                                 if(offset_changed) {
1296                                         offset_point = tmp_offset_point;
1297                                         vram_wrote = true;
1298                                 }
1299                                 break;
1300                         default:
1301                                 break;
1302                 }
1303                 return;
1304         } else if(addr < 0x10000) {
1305 #if defined(_FM77AV_VARIANTS)
1306           //subrom_cg[addr - 0xd800] = val8;
1307 #endif
1308                 return;
1309         } else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1310                 set_dpalette(addr - FM7_SUBMEM_OFFSET_DPALETTE, val8);
1311                 return;
1312         }
1313 #if defined(_FM77AV_VARIANTS)
1314         else if(addr == FM7_SUBMEM_OFFSET_APALETTE_R) {
1315                 set_apalette_r(val8);
1316                 return;
1317         } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_G) {
1318                 set_apalette_g(val8);
1319                 return;
1320         } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_B) {
1321                 set_apalette_b(val8);
1322                 return;
1323         } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_HI) {
1324                 set_apalette_index_hi(val8);
1325                 return;
1326         } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_LO) {
1327                 set_apalette_index_lo(val8);
1328                 return;
1329         }
1330 #endif  
1331         return;
1332 }       
1333
1334
1335 void DISPLAY::initialize()
1336 {
1337         int i;
1338
1339         memset(gvram, 0xff, sizeof(gvram));
1340         memset(console_ram, 0x00, sizeof(console_ram));
1341         memset(work_ram, 0x00, sizeof(work_ram));
1342         memset(shared_ram, 0x00, sizeof(shared_ram));
1343         memset(subsys_c, 0x00, sizeof(subsys_c));
1344
1345         read_bios("SUBSYS_C.ROM", subsys_c, 0x2800);
1346         vram_wrote = true;
1347
1348 #if defined(_FM77AV_VARIANTS)
1349 #endif
1350 }