2 * Common source code project -> FM-7 -> Display
3 * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
5 * Feb 10, 2015 : Initial.
8 #include "../../fileio.h"
9 #include "fm7_display.h"
10 #if defined(_FM77AV_VARIANTS)
11 # include "mb61vh010.h"
14 DISPLAY::DISPLAY(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
25 void DISPLAY::reset_cpuonly()
29 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
30 mainio->write_signal(SIG_FM7_SUB_HALT, 0x00, 0xff);
33 multimode_accessmask = 0;
34 multimode_dispmask = 0;
36 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
37 //cancel_request = false;
38 switch(config.cpu_type){
46 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
50 for(i = 0; i < 2; i++) {
51 offset_changed[i] = true;
52 tmp_offset_point[i].d = 0;
55 #if defined(_FM77AV_VARIANTS)
57 offset_point_bank1 = 0;
59 offset_point_bank1_bak = 0;
63 subcpu_resetreq = false;
64 //offset_77av = false;
65 subrom_bank_using = subrom_bank;
70 vram_wrote_shadow = false;
71 for(i = 0; i < 400; i++) vram_wrote_table[i] = true;
72 for(i = 0; i < 400; i++) vram_draw_table[i] = true;
80 if(hblank_event_id >= 0) cancel_event(this, hblank_event_id);
81 if(hdisp_event_id >= 0) cancel_event(this, hdisp_event_id);
82 if(vsync_event_id >= 0) cancel_event(this, vsync_event_id);
83 if(vstart_event_id >= 0) cancel_event(this, vstart_event_id);
88 if(display_mode == DISPLAY_MODE_8_400L) {
94 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
95 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
96 mainio->write_signal(SIG_DISPLAY_VSYNC, 0xff, 0xff);
98 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
100 vram_display_block = 0;
101 vram_active_block = 0;
103 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
108 window_opened = false;
113 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
114 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
115 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400: 200, 0xffff);
116 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xffffffff : 0, 0xffffffff);
118 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
119 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
120 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
122 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
123 alu->write_signal(SIG_ALU_PLANES, 3, 3);
125 if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
127 register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
130 for(i = 0; i < 8; i++) set_dpalette(i, i);
131 do_firq(!firq_mask && key_firq_req);
133 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
135 kanjiaddr.d = 0x00000000;
136 # if defined(_FM77L4)
138 stat_400linecard = false;
143 frame_skip_count = 3;
147 void DISPLAY::reset()
151 memset(io_w_latch, 0xff, sizeof(io_w_latch));
153 vram_accessflag = true;
154 display_mode = DISPLAY_MODE_8_200L;
157 cancel_request = false;
158 #if defined(_FM77AV_VARIANTS)
160 apalette_index.d = 0;
161 for(i = 0; i < 4096; i++) {
162 analog_palette_r[i] = i & 0x0f0;
163 analog_palette_g[i] = i & 0xf00;
164 analog_palette_b[i] = i & 0x00f;
168 #if defined(_FM77AV_VARIANTS)
171 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
179 #elif defined(_FM77L4)
183 mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, 0x00 , 0xff);
185 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
186 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
189 #if defined(_FM77AV_VARIANTS)
190 power_on_reset = false;
191 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
194 //if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
196 //register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
197 //for(i = 0; i < 8; i++) set_dpalette(i, i);
198 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
199 do_firq(!firq_mask && key_firq_req);
201 if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
203 register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
209 void DISPLAY::update_config()
212 switch(config.cpu_type) {
221 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
227 * Vram accessing functions moved to vram.cpp .
230 void DISPLAY::do_irq(bool flag)
232 subcpu->write_signal(SIG_CPU_IRQ, flag ? 1: 0, 1);
235 void DISPLAY::do_firq(bool flag)
237 subcpu->write_signal(SIG_CPU_FIRQ, flag ? 1: 0, 1);
240 void DISPLAY::do_nmi(bool flag)
242 #if defined(_FM77AV_VARIANTS)
243 if(!nmi_enable) flag = false;
245 subcpu->write_signal(SIG_CPU_NMI, flag ? 1 : 0, 1);
248 void DISPLAY::set_multimode(uint8 val)
250 multimode_accessmask = val & 0x07;
251 multimode_dispmask = (val & 0x70) >> 4;
253 #if defined(_FM77AV_VARIANTS)
254 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
258 uint8 DISPLAY::get_multimode(void)
261 val = multimode_accessmask & 0x07;
262 val |= ((multimode_dispmask << 4) & 0x70);
267 uint8 DISPLAY::get_cpuaccessmask(void)
269 return multimode_accessmask & 0x07;
272 void DISPLAY::set_dpalette(uint32 addr, uint8 val)
276 dpalette_data[addr] = val | 0xf8; //0b11111000;
278 b = ((val & 0x01) != 0x00)? 255 : 0x00;
279 r = ((val & 0x02) != 0x00)? 255 : 0x00;
280 g = ((val & 0x04) != 0x00)? 255 : 0x00;
282 dpalette_pixel[addr] = RGB_COLOR(r, g, b);
285 uint8 DISPLAY::get_dpalette(uint32 addr)
290 data = dpalette_data[addr];
294 void DISPLAY::halt_subcpu(void)
296 subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
299 void DISPLAY::go_subcpu(void)
301 subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
304 void DISPLAY::enter_display(void)
308 subclock = SUBCLOCK_NORMAL;
310 subclock = SUBCLOCK_SLOW;
312 if(!is_cyclesteal && vram_accessflag) {
313 if((config.dipswitch & FM7_DIPSW_CYCLESTEAL) == 0) subclock = subclock / 3;
315 if(prev_clock != subclock) p_vm->set_cpu_clock(subcpu, subclock);
316 prev_clock = subclock;
319 void DISPLAY::leave_display(void)
323 void DISPLAY::halt_subsystem(void)
329 void DISPLAY::restart_subsystem(void)
332 #if defined(_FM77AV_VARIANTS)
333 if(subcpu_resetreq) {
335 power_on_reset = true;
336 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
338 do_firq(!firq_mask && key_firq_req);
345 void DISPLAY::set_crtflag(void)
352 void DISPLAY::reset_crtflag(void)
359 uint8 DISPLAY::acknowledge_irq(void)
361 cancel_request = false;
367 uint8 DISPLAY::beep(void)
369 mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
370 return 0xff; // True?
375 uint8 DISPLAY::attention_irq(void)
377 mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
382 void DISPLAY::set_cyclesteal(uint8 val)
387 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
389 is_cyclesteal = true;
391 is_cyclesteal = false;
399 uint8 DISPLAY::set_vramaccess(void)
401 vram_accessflag = true;
406 void DISPLAY::reset_vramaccess(void)
408 vram_accessflag = false;
412 uint8 DISPLAY::reset_subbusy(void)
419 void DISPLAY::set_subbusy(void)
425 #if defined(_FM77AV_VARIANTS)
427 void DISPLAY::alu_write_cmdreg(uint32 val)
429 alu->write_data8(ALU_CMDREG, val);
430 if((val & 0x80) != 0) {
438 void DISPLAY::alu_write_logical_color(uint8 val)
440 uint32 data = (uint32)val;
441 alu->write_data8(ALU_LOGICAL_COLOR, data);
445 void DISPLAY::alu_write_mask_reg(uint8 val)
447 uint32 data = (uint32)val;
448 alu->write_data8(ALU_WRITE_MASKREG, data);
452 void DISPLAY::alu_write_cmpdata_reg(int addr, uint8 val)
454 uint32 data = (uint32)val;
456 alu->write_data8(ALU_CMPDATA_REG + addr, data);
460 void DISPLAY::alu_write_disable_reg(uint8 val)
462 uint32 data = (uint32)val;
463 alu->write_data8(ALU_BANK_DISABLE, data);
467 void DISPLAY::alu_write_tilepaint_data(uint32 addr, uint8 val)
469 uint32 data = (uint32)val;
472 alu->write_data8(ALU_TILEPAINT_B, data);
475 alu->write_data8(ALU_TILEPAINT_R, data);
478 alu->write_data8(ALU_TILEPAINT_G, data);
481 //alu->write_data8(ALU_TILEPAINT_L, 0xff);
487 void DISPLAY::alu_write_offsetreg_hi(uint8 val)
489 alu->write_data8(ALU_OFFSET_REG_HIGH, val & 0x7f);
493 void DISPLAY::alu_write_offsetreg_lo(uint8 val)
495 alu->write_data8(ALU_OFFSET_REG_LO, val);
499 void DISPLAY::alu_write_linepattern_hi(uint8 val)
501 alu->write_data8(ALU_LINEPATTERN_REG_HIGH, val);
505 void DISPLAY::alu_write_linepattern_lo(uint8 val)
507 alu->write_data8(ALU_LINEPATTERN_REG_LO, val);
511 void DISPLAY::alu_write_line_position(int addr, uint8 val)
513 uint32 data = (uint32)val;
516 alu->write_data8(ALU_LINEPOS_START_X_HIGH, data & 0x03);
519 alu->write_data8(ALU_LINEPOS_START_X_LOW, data);
522 alu->write_data8(ALU_LINEPOS_START_Y_HIGH, data & 0x01);
525 alu->write_data8(ALU_LINEPOS_START_Y_LOW, data);
528 alu->write_data8(ALU_LINEPOS_END_X_HIGH, data & 0x03);
531 alu->write_data8(ALU_LINEPOS_END_X_LOW, data);
534 alu->write_data8(ALU_LINEPOS_END_Y_HIGH, data & 0x01);
537 alu->write_data8(ALU_LINEPOS_END_Y_LOW, data);
543 uint8 DISPLAY::get_miscreg(void)
548 if(!hblank) ret |= 0x80;
549 if(vsync) ret |= 0x04;
550 if(alu->read_signal(SIG_ALU_BUSYSTAT) == 0) ret |= 0x10;
551 if(power_on_reset) ret |= 0x01;
556 void DISPLAY::set_miscreg(uint8 val)
558 int old_display_page = display_page;
560 nmi_enable = ((val & 0x80) == 0) ? true : false;
561 if(!nmi_enable) do_nmi(false);
563 if((val & 0x40) == 0) {
568 if(display_page != old_display_page) {
571 active_page = ((val & 0x20) == 0) ? 0 : 1;
572 if((val & 0x04) == 0) {
577 cgrom_bank = val & 0x03;
581 void DISPLAY::set_monitor_bank(uint8 var)
583 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
584 if((var & 0x04) != 0){
590 subrom_bank = var & 0x03;
593 subcpu_resetreq = false;
594 power_on_reset = true;
596 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
598 do_firq(!firq_mask && key_firq_req);
600 subcpu_resetreq = true;
606 void DISPLAY::set_apalette_index_hi(uint8 val)
608 apalette_index.b.h = val & 0x0f;
612 void DISPLAY::set_apalette_index_lo(uint8 val)
614 apalette_index.b.l = val;
617 void DISPLAY::calc_apalette(uint16 idx)
621 g = analog_palette_g[idx];
622 r = analog_palette_r[idx];
623 b = analog_palette_b[idx];
624 analog_palette_pixel[idx] = RGB_COLOR(r, g, b);
628 void DISPLAY::set_apalette_b(uint8 val)
632 index = apalette_index.w.l;
633 tmp = (val & 0x0f) << 4;
634 if(analog_palette_b[index] != tmp) {
635 analog_palette_b[index] = tmp;
636 calc_apalette(index);
642 void DISPLAY::set_apalette_r(uint8 val)
646 index = apalette_index.w.l;
647 tmp = (val & 0x0f) << 4;
648 if(analog_palette_r[index] != tmp) {
649 analog_palette_r[index] = tmp;
650 calc_apalette(index);
656 void DISPLAY::set_apalette_g(uint8 val)
660 index = apalette_index.w.l;
661 tmp = (val & 0x0f) << 4;
662 if(analog_palette_g[index] != tmp) {
663 analog_palette_g[index] = tmp;
664 calc_apalette(index);
669 #endif // _FM77AV_VARIANTS
672 // Timing values from XM7 . Thanks Ryu.
673 void DISPLAY::event_callback(int event_id, int err)
678 case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
679 #if defined(_FM77AV_VARIANTS)
689 case EVENT_FM7SUB_DISPLAY_NMI_OFF: // per 20.00ms
692 #if defined(_FM77AV_VARIANTS)
693 case EVENT_FM7SUB_HDISP:
697 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x02, 0xff);
699 if(display_mode == DISPLAY_MODE_8_400L) usec = 30.0;
700 register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
703 case EVENT_FM7SUB_HBLANK:
707 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
709 if(display_mode == DISPLAY_MODE_8_400L) {
710 if(displine < 400) f = true;
712 if(displine < 200) f = true;
715 if(display_mode == DISPLAY_MODE_8_400L) {
720 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id);
722 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
723 if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)){
724 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
726 # elif defined(_FM77AV40)
731 if(vram_wrote_table[displine] || vram_wrote) {
732 uint32 baseaddr1 = (displine * 40) & 0x1fff;
733 uint32 baseaddr2 = baseaddr1 + 0xc000;
734 vram_wrote_table[displine] = false;
735 for(int i = 0; i < planes; i++) {
736 for(int j = 0; j < 6; j++) {
737 memcpy(&gvram_shadow[j * 0x2000 + baseaddr1],
738 &gvram[j * 0x2000 + baseaddr1], 40);
739 memcpy(&gvram_shadow[j * 0x2000 + baseaddr2],
740 &gvram[j * 0x2000 + baseaddr2], 40);
742 baseaddr1 += 0x18000;
743 baseaddr2 += 0x18000;
745 # if defined(_FM77AV40)
746 for(int j = 0; j < 6; j++) {
747 memcpy(&gvram_shadow[j * 0x2000 + baseaddr1],
748 &gvram[j * 0x2000 + baseaddr1], 40);
751 vram_draw_table[displine] = true;
753 } else if(display_mode == DISPLAY_MODE_8_400L) {
754 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
756 # elif defined(_FM77AV40)
761 if(vram_wrote_table[displine] || vram_wrote) {
762 uint32 baseaddr1 = (displine * 80) & 0x7fff;
763 vram_wrote_table[displine] = false;
764 for(int i = 0; i < planes; i++) {
765 for(int j = 0; j < 3; j++) {
766 memcpy(&gvram_shadow[j * 0x8000 + baseaddr1],
767 &gvram[j * 0x8000 + baseaddr1], 80);
769 baseaddr1 += 0x18000;
772 # if defined(_FM77AV40)
773 for(int j = 0; j < 3; j++) {
774 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
775 &gvram[j * 0x4000 + baseaddr1], 80);
778 vram_draw_table[displine] = true;
781 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
783 # elif defined(_FM77AV40)
788 if(vram_wrote_table[displine] || vram_wrote) {
789 uint32 baseaddr1 = (displine * 80) & 0x3fff;
790 uint32 baseaddr2 = baseaddr1 + 0xc000;
791 vram_wrote_table[displine] = false;
792 for(int i = 0; i < planes; i++) {
793 for(int j = 0; j < 3; j++) {
794 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
795 &gvram[j * 0x4000 + baseaddr1], 80);
796 memcpy(&gvram_shadow[j * 0x4000 + baseaddr2],
797 &gvram[j * 0x4000 + baseaddr2], 80);
799 baseaddr1 += 0x18000;
800 baseaddr2 += 0x18000;
802 # if defined(_FM77AV40)
803 for(int j = 0; j < 3; j++) {
804 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
805 &gvram[j * 0x4000 + baseaddr1], 80);
808 vram_draw_table[displine] = true;
813 //vram_wrote_shadow = true;
816 case EVENT_FM7SUB_VSTART: // Call first.
822 // Parameter from XM7/VM/display.c , thanks, Ryu.
823 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
824 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x00, 0xff);
825 if(vblank_count != 0) {
826 if(display_mode == DISPLAY_MODE_8_400L) {
827 usec = (0.98 + 16.4) * 1000.0;
829 usec = (1.91 + 12.7) * 1000.0;
831 register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id);
833 if(display_mode == DISPLAY_MODE_8_400L) {
834 usec = 930.0; // 939.0
836 usec = 1840.0; // 1846.5
838 //offset_point_bank1_bak = offset_point_bank1;
839 //offset_point_bak = offset_point;
840 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
843 if(display_mode == DISPLAY_MODE_8_400L) {
844 usec = 0.34 * 1000.0;
846 usec = 1.52 * 1000.0;
848 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
852 case EVENT_FM7SUB_VSYNC:
857 if(display_mode == DISPLAY_MODE_8_400L) {
858 usec = 0.33 * 1000.0;
860 usec = 0.51 * 1000.0;
862 offset_point_bank1_bak = offset_point_bank1;
863 offset_point_bak = offset_point;
864 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x01, 0xff);
865 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
866 if(vram_wrote && ((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0)) {
867 //for(int i = 0; i < 411; i++) vram_wrote_table[i] = false;
868 memcpy(gvram_shadow, gvram, sizeof(gvram_shadow));
869 vram_wrote_shadow = true;
871 for(int i = 0; i < 411; i++) vram_draw_table[i] = true;
872 } else if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
873 if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)){
876 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
878 # elif defined(_FM77AV40)
885 for(int j = 200; j < 206; j++) {
886 if(vram_wrote_table[j]) {
889 vram_wrote_table[j] = false;
893 for(int j = 200; j < 205; j++) {
894 vram_draw_table[(((j * 40) + offset_point_bak) & 0x1fff) / 40] = true;
895 vram_draw_table[(((j * 40) + offset_point_bank1_bak) & 0x1fff) / 40] = true;
897 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x2000 + 200 * 40],
898 &gvram[i * 0x2000 + 200 * 40], 0x2000 - 200 * 40);
900 } else if(display_mode == DISPLAY_MODE_8_400L) {
903 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
905 # elif defined(_FM77AV40)
912 for(int j = 400; j < 411; j++) {
913 if(vram_wrote_table[j]) {
916 vram_wrote_table[j] = false;
920 for(int j = 400; j < 410; j++) {
921 vram_draw_table[(((j * 80) + offset_point_bak) & 0x7fff) / 80] = true;
922 vram_draw_table[(((j * 80) + offset_point_bank1_bak) & 0x7fff) / 80] = true;
924 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x8000 + 400 * 80],
925 &gvram[i * 0x8000 + 400 * 80], 0x8000 - 400 * 80);
930 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
932 # elif defined(_FM77AV40)
939 for(int j = 200; j < 206; j++) {
940 if(vram_wrote_table[j]) {
943 vram_wrote_table[j] = false;
947 for(int j = 200; j < 205; j++) {
948 vram_draw_table[(((j * 80) + offset_point_bak) & 0x3fff) / 80] = true;
949 vram_draw_table[(((j * 80) + offset_point_bank1_bak) & 0x3fff) / 80] = true;
951 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x4000 + 200 * 80],
952 &gvram[i * 0x4000 + 200 * 80], 0x4000 - 200 * 80);
957 vram_wrote_shadow = true;
960 if(display_mode == DISPLAY_MODE_8_400L) {
961 for(int yy = 0; yy < 400; yy++) {
962 if(vram_draw_table[yy]) fy = true;
963 vram_draw_table[yy] = false;
966 for(int yy = 0; yy < 200; yy++) {
967 if(vram_draw_table[yy]) fy = true;
968 vram_draw_table[yy] = false;
971 vram_wrote_shadow = fy;
976 case EVENT_FM7SUB_CLR_BUSY:
979 case EVENT_FM7SUB_CLR_CRTFLAG:
985 void DISPLAY::event_frame()
990 void DISPLAY::event_vline(int v, int clock)
995 uint32 DISPLAY::read_signal(int id)
999 case SIG_FM7_SUB_HALT:
1000 case SIG_DISPLAY_HALT:
1001 retval = (halt_flag) ? 0xffffffff : 0;
1003 case SIG_DISPLAY_BUSY:
1004 retval = (sub_busy) ? 0x80 : 0;
1006 case SIG_DISPLAY_MULTIPAGE:
1007 retval = multimode_accessmask;
1009 case SIG_DISPLAY_PLANES:
1012 #if defined(_FM77AV_VARIANTS)
1013 case SIG_DISPLAY_VSYNC:
1014 retval = (vsync) ? 0x01 : 0x00;
1016 case SIG_DISPLAY_DISPLAY:
1017 retval = (!hblank) ? 0x02: 0x00;
1019 case SIG_FM7_SUB_BANK: // Main: FD13
1020 retval = subrom_bank & 0x03;
1021 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1022 if(monitor_ram) retval |= 0x04;
1026 #if defined(_FM77AV_VARIANTS)
1027 case SIG_DISPLAY_MODE320:
1028 retval = (mode320) ? 0x40: 0x00;
1031 case SIG_DISPLAY_Y_HEIGHT:
1032 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1033 retval = (mode400line) ? 400 : 200;
1038 case SIG_DISPLAY_X_WIDTH:
1039 #if defined(_FM77AV_VARIANTS)
1040 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1041 retval = (mode320 || mode256k) ? 40 : 80;
1043 retval = (mode320) ? 40 : 80;
1055 void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
1057 bool flag = ((data & mask) != 0);
1060 case SIG_FM7_SUB_HALT:
1065 //mainio->write_signal(SIG_FM7_SUB_HALT, data, mask);
1067 case SIG_DISPLAY_HALT:
1071 restart_subsystem();
1074 case SIG_FM7_SUB_CANCEL:
1076 cancel_request = true;
1080 case SIG_DISPLAY_CLOCK:
1081 if(clock_fast != flag) {
1084 clk = SUBCLOCK_NORMAL;
1086 clk = SUBCLOCK_SLOW;
1088 if((config.dipswitch & FM7_DIPSW_CYCLESTEAL) == 0) clk = clk / 3;
1089 if(clk != prev_clock) p_vm->set_cpu_clock(subcpu, clk);
1094 #if defined(_FM77AV_VARIANTS)
1095 case SIG_FM7_SUB_BANK: // Main: FD13
1096 set_monitor_bank(data & 0xff);
1099 case SIG_DISPLAY_EXTRA_MODE: // FD04 bit 4, 3
1100 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1102 int oldmode = display_mode;
1103 kanjisub = ((data & 0x20) == 0) ? true : false;
1104 mode256k = ((data & 0x10) != 0) ? true : false;
1105 mode400line = ((data & 0x08) != 0) ? false : true;
1106 ram_protect = ((data & 0x04) != 0) ? false : true;
1108 display_mode = DISPLAY_MODE_8_400L;
1109 } else if(mode256k) {
1110 display_mode = DISPLAY_MODE_256k;
1112 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1114 if(oldmode != display_mode) {
1115 for(y = 0; y < 400; y++) memset(emu->screen_buffer(y), 0x00, 640 * sizeof(scrntype));
1117 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
1118 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400 : 200, 0xffff);
1119 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff);
1120 frame_skip_count = 3;
1123 #elif defined(_FM77_VARIANTS)
1125 int oldmode = display_mode;
1126 kanjisub = ((data & 0x20) == 0) ? true : false;
1127 # if defined(_FM77L4)
1128 stat_400linecard = ((data & 0x20) != 0) ? true : false;
1129 mode400line = ((data & 0x08) != 0) ? false : true;
1130 if(mode400line && stat_400linecard) {
1131 display_mode = DISPLAY_MODE_8_400L_TEXT;
1132 } else if(stat_400linecard) {
1133 display_mode = DISPLAY_MODE_8_200L_TEXT;
1135 display_mode = DISPLAY_MODE_8_200L;
1141 #if defined(_FM77AV_VARIANTS)
1142 case SIG_DISPLAY_MODE320: // FD12 bit 6
1143 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1145 int oldmode = display_mode;
1147 if((!mode400line) && (!mode256k)){
1148 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1150 if(oldmode != display_mode) {
1151 for(y = 0; y < 400; y++) memset(emu->screen_buffer(y), 0x00, 640 * sizeof(scrntype));
1153 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
1154 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400 : 200, 0xffff);
1155 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff);
1156 frame_skip_count = 3;
1160 if(mode320 != flag) {
1161 for(y = 0; y < 400; y++) memset(emu->screen_buffer(y), 0x00, 640 * sizeof(scrntype));
1164 display_mode = (mode320 == true) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1165 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1166 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1167 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
1172 case SIG_DISPLAY_MULTIPAGE:
1173 set_multimode(data);
1175 case SIG_FM7_SUB_KEY_MASK:
1176 if(firq_mask == flag) {
1177 do_firq(!flag && key_firq_req);
1181 case SIG_FM7_SUB_KEY_FIRQ:
1182 do_firq(flag & !(firq_mask));
1183 key_firq_req = flag;
1185 case SIG_FM7_SUB_USE_CLR:
1187 clr_count = data & 0x03;
1198 * Vram accessing functions moved to vram.cpp .
1201 uint8 DISPLAY::read_mmio(uint32 addr)
1203 uint32 retval = 0xff;
1205 if(addr < 0xd400) return 0xff;
1207 #if !defined(_FM77AV_VARIANTS)
1208 raddr = (addr - 0xd400) & 0x000f;
1209 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1210 raddr = (addr - 0xd400) & 0x003f;
1211 #else // FM77AV40EX || FM77AV40SX
1212 raddr = (addr - 0xd400) & 0x00ff;
1215 case 0x00: // Read keyboard
1216 retval = (keyboard->read_data8(0x00) != 0) ? 0xff : 0x7f;
1218 case 0x01: // Read keyboard
1219 retval = keyboard->read_data8(0x01) & 0xff;
1221 case 0x02: // Acknowledge
1230 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1231 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1233 if(!kanjisub) return 0xff;
1234 # if !defined(_FM77_VARIANTS)
1236 return (uint8)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1239 retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1242 if(!kanjisub) return 0xff;
1243 # if !defined(_FM77_VARIANTS)
1245 return (uint8)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1248 retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1255 retval = set_vramaccess();
1261 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x01, 0x01);
1263 #if defined(_FM77AV_VARIANTS)
1266 retval = alu->read_data8(ALU_CMDREG);
1269 retval = alu->read_data8(ALU_LOGICAL_COLOR);
1272 retval = alu->read_data8(ALU_WRITE_MASKREG);
1275 retval = alu->read_data8(ALU_CMP_STATUS_REG);
1278 retval = alu->read_data8(ALU_BANK_DISABLE);
1280 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1281 case 0x2f: // VRAM BANK
1282 retval = 0xfc | (vram_bank & 0x03);
1287 retval = get_miscreg();
1291 retval = keyboard->read_data8(0x31);
1294 retval = keyboard->read_data8(0x32);
1300 return (uint8)retval;
1303 uint32 DISPLAY::read_vram_data8(uint32 addr)
1306 uint32 page_offset = 0;
1307 uint32 page_mask = 0x3fff;
1308 uint32 color = (addr >> 14) & 0x03;
1311 #if defined(_FM77AV_VARIANTS)
1312 if (active_page != 0) {
1313 offset = offset_point_bank1;
1315 offset = offset_point;
1318 offset = offset_point;
1321 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1322 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1323 if(vram_active_block != 0) page_offset = 0x18000;
1325 if(display_mode == DISPLAY_MODE_8_400L) {
1326 if(addr >= 0x8000) return 0xff;
1327 color = vram_bank & 0x03;
1328 if(color > 2) color = 0;
1330 pagemod = 0x8000 * color;
1331 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1334 #if defined(_FM77AV40)
1336 page_offset = 0xc000 * (vram_bank & 0x03);
1338 page_offset = 0; // right?
1341 page_offset = 0xc000 * (vram_bank & 0x03);
1344 pagemod = addr & 0xe000;
1348 pagemod = addr & 0xe000;
1350 pagemod = addr & 0xc000;
1352 if(active_page != 0) {
1353 page_offset += 0xc000;
1356 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1358 #elif defined(_FM77AV_VARIANTS)
1360 if(active_page != 0) {
1361 page_offset += 0xc000;
1365 pagemod = addr & 0xe000;
1367 pagemod = addr & 0xc000;
1369 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1371 #elif defined(_FM77L4) //_FM77L4
1373 if(display_mode == DISPLAY_MODE_8_400L) {
1374 return (uint32)read_vram_l4_400l(addr, offset);
1376 pagemod = addr & 0xc000;
1377 return gvram[((addr + offset) & 0x3fff) | pagemod];
1381 #else // Others (77/7/8)
1382 pagemod = addr & 0xc000;
1383 return gvram[((addr + offset) & 0x3fff) | pagemod];
1387 void DISPLAY::write_dma_data8(uint32 addr, uint32 data)
1389 uint32 raddr = addr & 0xffff;
1392 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1393 if(display_mode == DISPLAY_MODE_8_400L) {
1394 color = vram_bank & 0x03;
1395 if(color > 2) color = 0;
1397 color = (addr >> 14) & 0x03;
1400 if((multimode_accessmask & (1 << color)) != 0) return;
1401 return write_vram_data8(raddr, (uint8)data);
1403 return write_data8_main(raddr, (uint8)data);
1408 void DISPLAY::write_vram_data8(uint32 addr, uint8 data)
1411 uint32 page_offset = 0;
1412 uint32 page_mask = 0x3fff;
1413 uint32 color = (addr >> 14) & 0x03;
1416 #if defined(_FM77AV_VARIANTS)
1417 if (active_page != 0) {
1418 offset = offset_point_bank1;
1420 offset = offset_point;
1423 offset = offset_point;
1426 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1427 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1428 if(vram_active_block != 0) page_offset = 0x18000;
1430 if(display_mode == DISPLAY_MODE_8_400L) {
1431 if(addr >= 0x8000) return;
1432 color = vram_bank & 0x03;
1433 if(color > 2) color = 0;
1435 pagemod = 0x8000 * color;
1436 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
1437 vram_wrote_table[((addr + offset) % 0x8000) / 80] = true;
1438 } else if(display_mode == DISPLAY_MODE_256k) {
1439 #if defined(_FM77AV40)
1441 page_offset = 0xc000 * (vram_bank & 0x03);
1443 page_offset = 0; // right?
1446 page_offset = 0xc000 * (vram_bank & 0x03);
1449 pagemod = addr & 0xe000;
1450 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1451 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1453 } else if(display_mode == DISPLAY_MODE_4096) {
1454 if(active_page != 0) {
1455 page_offset += 0xc000;
1458 pagemod = addr & 0xe000;
1459 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1460 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1462 if(active_page != 0) {
1463 page_offset += 0xc000;
1466 pagemod = addr & 0xc000;
1467 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1468 vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1471 #elif defined(_FM77AV_VARIANTS)
1472 if(display_mode == DISPLAY_MODE_4096) {
1473 if(active_page != 0) {
1474 page_offset = 0xc000;
1477 pagemod = addr & 0xe000;
1478 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1479 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1481 if(active_page != 0) {
1482 page_offset = 0xc000;
1485 pagemod = addr & 0xc000;
1486 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1487 vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1489 #elif defined(_FM77L4) //_FM77L4
1491 if(display_mode == DISPLAY_MODE_8_400L) {
1492 write_vram_l4_400l(addr, data, offset);
1494 pagemod = addr & 0xc000;
1495 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1497 //vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1499 #else // Others (77/7/8)
1500 pagemod = addr & 0xc000;
1501 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1502 //vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1505 #if defined(_FM77AV_VARIANTS)
1506 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
1512 uint32 DISPLAY::read_data8_main(uint32 addr)
1515 if(addr < 0xc000) return 0xff;
1517 raddr = addr - 0xc000;
1518 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1520 if(console_ram_bank >= 1) {
1521 return submem_console_av40[((console_ram_bank - 1) << 12) + raddr];
1525 return console_ram[raddr];
1526 } else if(addr < 0xd380) {
1527 raddr = addr - 0xd000;
1528 return work_ram[raddr];
1529 } else if(addr < 0xd400) {
1530 raddr = addr - 0xd380;
1531 return shared_ram[raddr];
1532 } else if(addr < 0xd800) {
1533 #if defined(_FM77AV_VARIANTS)
1534 if(addr >= 0xd500) {
1535 return submem_hidden[addr - 0xd500];
1538 return read_mmio(addr);
1539 } else if(addr < 0x10000) {
1540 #if !defined(_FM77AV_VARIANTS)
1541 return subsys_c[addr - 0xd800];
1544 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1546 return submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)]; //FIXME
1549 return subsys_cg[(addr - 0xd800) + cgrom_bank * 0x800];
1550 } else if(addr < 0x10000) {
1551 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1553 return subsys_ram[addr - 0xe000];
1556 switch(subrom_bank_using & 3) {
1558 return subsys_c[addr - 0xd800];
1561 return subsys_a[addr - 0xe000];
1564 return subsys_b[addr - 0xe000];
1567 return subsys_cg[addr - 0xe000];
1576 uint32 DISPLAY::read_dma_data8(uint32 addr)
1578 uint32 raddr = addr & 0xffff;
1581 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1582 if(display_mode == DISPLAY_MODE_8_400L) {
1583 color = vram_bank & 0x03;
1584 if(color > 2) color = 0;
1586 color = (addr >> 14) & 0x03;
1589 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1590 return read_vram_data8(raddr);
1592 return read_data8_main(raddr);
1597 uint32 DISPLAY::read_data8(uint32 addr)
1599 uint32 raddr = addr;
1601 uint32 color = (addr & 0x0c000) >> 14;
1603 #if defined(_FM77AV_VARIANTS)
1605 alu->read_data8(addr + ALU_WRITE_PROXY);
1608 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1609 if(display_mode == DISPLAY_MODE_8_400L) {
1610 color = vram_bank & 0x03;
1611 if(color > 2) color = 0;
1613 color = (addr >> 14) & 0x03;
1616 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1617 return read_vram_data8(addr);
1618 } else if(addr < 0x10000) {
1619 return read_data8_main(addr);
1620 } else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1621 return dpalette_data[addr - FM7_SUBMEM_OFFSET_DPALETTE];
1623 #if defined(_FM77AV_VARIANTS)
1625 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
1626 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
1627 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1628 if(display_mode == DISPLAY_MODE_8_400L) {
1629 uint32 page_offset = 0;
1630 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1631 if(vram_active_block != 0) page_offset = 0x18000;
1633 color = (addr & 0x18000) >> 15;
1634 if(color > 2) color = 0;
1636 if (active_page != 0) {
1637 offset = offset_point_bank1 << 1;
1639 offset = offset_point << 1;
1641 if(color > 2) color = 0;
1642 uint32 pagemod = 0x8000 * color;
1643 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1646 return read_vram_data8(addr);
1653 * Vram accessing functions moved to vram.cpp .
1656 void DISPLAY::write_mmio(uint32 addr, uint32 data)
1660 if(addr < 0xd400) return;
1662 #if !defined(_FM77AV_VARIANTS)
1663 addr = (addr - 0xd400) & 0x000f;
1664 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1665 addr = (addr - 0xd400) & 0x003f;
1666 #else // FM77AV40EX || FM77AV40SX
1667 addr = (addr - 0xd400) & 0x00ff;
1669 io_w_latch[addr] = (uint8)data;
1671 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
1674 set_cyclesteal((uint8)data);
1677 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1678 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1681 if(!kanjisub) return;
1682 kanjiaddr.w.h = 0x0000;
1683 kanjiaddr.b.h = (uint8) data;
1686 if(!kanjisub) return;
1687 kanjiaddr.w.h = 0x0000;
1688 kanjiaddr.b.l = (uint8)data;
1701 if(clr_count <= 0) {
1703 } else { // Read once when using clr_foo() to set busy flag.
1706 usec = (1000.0 * 1000.0) / 2000000.0;
1708 usec = (1000.0 * 1000.0) / 999000.0;
1710 if(!is_cyclesteal) usec = usec * 3.0;
1711 usec = (double)clr_count * usec;
1712 register_event(this, EVENT_FM7SUB_CLR_BUSY, usec, false, NULL); // NEXT CYCLE_
1719 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
1725 if(offset_changed[active_page]) {
1726 #if defined(_FM77AV_VARIANTS)
1727 if(active_page != 0) {
1728 tmp_offset_point[active_page].d = offset_point_bank1;
1730 tmp_offset_point[active_page].d = offset_point;
1733 tmp_offset_point[active_page].d = offset_point;
1736 tmp_offset_point[active_page].w.h = 0x0000;
1738 tmp_offset_point[active_page].b.h = rval;
1740 tmp_offset_point[active_page].b.l = rval;
1742 offset_changed[active_page] = !offset_changed[active_page];
1743 if(offset_changed[active_page]) {
1745 #if defined(_FM77AV_VARIANTS)
1746 if(active_page != 0) {
1748 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fff;
1750 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fe0;
1754 offset_point = tmp_offset_point[active_page].d & 0x007fff;
1756 offset_point = tmp_offset_point[active_page].d & 0x007fe0;
1760 offset_point = tmp_offset_point[active_page].d & 0x7fe0;
1764 #if defined(_FM77AV_VARIANTS)
1767 alu_write_cmdreg(data);
1770 alu_write_logical_color(data);
1773 alu_write_mask_reg(data);
1776 alu_write_disable_reg(data);
1779 alu_write_offsetreg_hi(data);
1782 alu_write_offsetreg_lo(data);
1785 alu_write_linepattern_hi(data);
1788 alu_write_linepattern_lo(data);
1790 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1792 console_ram_bank = (data & 0x18) >> 3;
1793 if(console_ram_bank > 2) console_ram_bank = 0;
1794 cgram_bank = data & 0x07;
1795 kanji_level2 = ((data & 0x80) == 0) ? false : true;
1797 case 0x2f: // VRAM BANK
1798 vram_bank = data & 0x03;
1799 if(vram_bank > 2) vram_bank = 0;
1809 keyboard->write_data8(0x31, data);
1811 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1813 vram_active_block = data & 0x01;
1814 if(vram_display_block != (((data & 0x10) != 0) ? 1 : 0)) vram_wrote = true;
1815 vram_display_block = ((data & 0x10) != 0) ? 1 : 0;
1820 tmpvar.d = window_xbegin * 8;
1823 tmpvar.b.h = data & 0x03;
1825 tmpvar.b.l = data & 0xf8;
1827 if(mode320 || mode256k) {
1828 if(tmpvar.d > 320) tmpvar.d = 320;
1830 if(tmpvar.d > 640) tmpvar.d = 640;
1832 window_xbegin = tmpvar.d / 8;
1837 tmpvar.d = window_xend * 8;
1840 tmpvar.b.h = data & 0x03;
1842 tmpvar.b.l = data & 0xf8;
1844 if(mode320 || mode256k) {
1845 if(tmpvar.d > 320) tmpvar.d = 320;
1847 if(tmpvar.d > 640) tmpvar.d = 640;
1849 window_xend = tmpvar.d / 8;
1854 tmpvar.d = window_low;
1857 tmpvar.b.h = data & 0x03;
1859 tmpvar.b.l = data & 0xff;
1862 if(tmpvar.d > 400) tmpvar.d = 400;
1865 if(tmpvar.d > 400) tmpvar.d = 400;
1867 window_low = tmpvar.d;
1872 tmpvar.d = window_high;
1875 tmpvar.b.h = data & 0x03;
1877 tmpvar.b.l = data & 0xff;
1880 if(tmpvar.d > 400) tmpvar.d = 400;
1883 if(tmpvar.d > 400) tmpvar.d = 400;
1885 window_high = tmpvar.d;
1891 #if defined(_FM77AV_VARIANTS)
1893 if((addr >= 0x13) && (addr <= 0x1a)) {
1894 alu_write_cmpdata_reg(addr - 0x13, data);
1895 } else if((addr >= 0x1c) && (addr <= 0x1e)) {
1896 alu_write_tilepaint_data(addr, data);
1897 } else if((addr >= 0x24) && (addr <= 0x2b)) {
1898 alu_write_line_position(addr - 0x24, data);
1905 void DISPLAY::write_data8_main(uint32 addr, uint8 data)
1909 uint32 page_offset = 0x0000;
1911 if(addr < 0xc000) return;
1914 raddr = addr - 0xc000;
1915 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1917 if(console_ram_bank >= 1) {
1918 submem_console_av40[((console_ram_bank - 1) << 12) + raddr] = data;
1923 console_ram[raddr] = data;
1925 } else if(addr < 0xd380) {
1926 raddr = addr - 0xd000;
1927 work_ram[raddr] = data;
1929 } else if(addr < 0xd400) {
1930 raddr = addr - 0xd380;
1931 shared_ram[raddr] = data;
1933 } else if(addr < 0xd800) {
1934 #if defined(_FM77AV_VARIANTS)
1935 if(addr >= 0xd500) {
1936 submem_hidden[addr - 0xd500] = data;
1940 write_mmio(addr, data);
1942 } else if(addr < 0x10000) {
1943 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1944 if(ram_protect) return;
1947 submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)] = data; //FIXME
1949 subsys_ram[addr - 0xe000] = data;
1957 void DISPLAY::write_data8(uint32 addr, uint32 data)
1961 uint32 page_offset = 0x0000;
1962 uint8 val8 = data & 0xff;
1964 uint32 color = (addr & 0xc000) >> 14;
1967 #if defined(_FM77AV_VARIANTS)
1969 alu->read_data8(addr + ALU_WRITE_PROXY);
1972 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1973 if(display_mode == DISPLAY_MODE_8_400L) {
1974 color = vram_bank & 0x03;
1975 if(color > 2) color = 0;
1979 if((multimode_accessmask & (1 << color)) != 0) return;
1980 write_vram_data8(addr, val8);
1982 } else if(addr < 0x10000) {
1983 write_data8_main(addr, val8);
1985 } else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1986 set_dpalette(addr - FM7_SUBMEM_OFFSET_DPALETTE, val8);
1989 #if defined(_FM77AV_VARIANTS)
1991 else if(addr == FM7_SUBMEM_OFFSET_APALETTE_R) {
1992 set_apalette_r(val8);
1994 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_G) {
1995 set_apalette_g(val8);
1997 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_B) {
1998 set_apalette_b(val8);
2000 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_HI) {
2001 set_apalette_index_hi(val8);
2003 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_LO) {
2004 set_apalette_index_lo(val8);
2008 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
2009 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
2010 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2011 if(display_mode == DISPLAY_MODE_8_400L) {
2012 color = (addr & 0x18000) >> 15;
2013 if(color > 2) color = 0;
2015 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2016 if(vram_active_block != 0) page_offset = 0x18000;
2018 if(color > 2) color = 0;
2019 if (active_page != 0) {
2020 offset = offset_point_bank1 << 1;
2022 offset = offset_point << 1;
2024 pagemod = 0x8000 * color;
2025 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
2026 vram_wrote_table[((addr + offset) % 0x8000) / 80] = true;
2029 write_vram_data8(addr, data);
2031 write_vram_data8(addr, data);
2033 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2040 uint32 DISPLAY::read_bios(const char *name, uint8 *ptr, uint32 size)
2046 if((name == NULL) || (ptr == NULL)) return 0;
2047 s = emu->bios_path((const _TCHAR *)name);
2048 if(s == NULL) return 0;
2050 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
2051 blocks = fio.Fread(ptr, size, 1);
2054 return blocks * size;
2058 void DISPLAY::initialize()
2062 memset(gvram, 0x00, sizeof(gvram));
2063 #if defined(_FM77AV_VARIANTS)
2064 memset(gvram_shadow, 0x00, sizeof(gvram_shadow));
2065 vram_wrote_shadow = false;
2066 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
2067 for(i = 0; i < 411; i++) vram_draw_table[i] = false;
2069 memset(console_ram, 0x00, sizeof(console_ram));
2070 memset(work_ram, 0x00, sizeof(work_ram));
2071 memset(shared_ram, 0x00, sizeof(shared_ram));
2072 memset(subsys_c, 0xff, sizeof(subsys_c));
2074 diag_load_subrom_c = false;
2075 if(read_bios(_T("SUBSYS_C.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2076 emu->out_debug_log("SUBSYSTEM ROM Type C READING : %s", diag_load_subrom_c ? "OK" : "NG");
2078 #if defined(_FM77AV_VARIANTS)
2079 memset(subsys_a, 0xff, sizeof(subsys_a));
2080 memset(subsys_b, 0xff, sizeof(subsys_b));
2081 memset(subsys_cg, 0xff, sizeof(subsys_cg));
2082 memset(submem_hidden, 0x00, sizeof(submem_hidden));
2084 diag_load_subrom_a = false;
2085 if(read_bios(_T("SUBSYS_A.ROM"), subsys_a, 0x2000) >= 0x2000) diag_load_subrom_a = true;
2086 emu->out_debug_log("SUBSYSTEM ROM Type A READING : %s", diag_load_subrom_a ? "OK" : "NG");
2088 diag_load_subrom_b = false;
2089 if(read_bios(_T("SUBSYS_B.ROM"), subsys_b, 0x2000) >= 0x2000) diag_load_subrom_b = true;
2090 emu->out_debug_log("SUBSYSTEM ROM Type B READING : %s", diag_load_subrom_b ? "OK" : "NG");
2092 diag_load_subrom_cg = false;
2093 if(read_bios(_T("SUBSYSCG.ROM"), subsys_cg, 0x2000) >= 0x2000) diag_load_subrom_cg = true;
2094 emu->out_debug_log("SUBSYSTEM CG ROM READING : %s", diag_load_subrom_cg ? "OK" : "NG");
2095 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2096 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2097 memset(subsys_ram, 0x00, sizeof(subsys_ram));
2098 memset(submem_cgram, 0x00, sizeof(submem_cgram));
2099 memset(submem_console_av40, 0x00, sizeof(submem_console_av40));
2103 #if defined(_FM77AV_VARIANTS)
2105 apalette_index.d = 0;
2106 for(i = 0; i < 4096; i++) {
2107 analog_palette_r[i] = i & 0x0f0;
2108 analog_palette_g[i] = i & 0xf00;
2109 analog_palette_b[i] = i & 0x00f;
2113 #if defined(_FM77AV_VARIANTS)
2114 hblank_event_id = -1;
2115 hdisp_event_id = -1;
2116 vsync_event_id = -1;
2117 vstart_event_id = -1;
2119 switch(config.cpu_type){
2127 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
2131 key_firq_req = false; //firq_mask = true;
2132 frame_skip_count = 3;
2135 void DISPLAY::release()
2139 #define STATE_VERSION 2
2140 void DISPLAY::save_state(FILEIO *state_fio)
2142 state_fio->FputUint32_BE(STATE_VERSION);
2143 state_fio->FputInt32_BE(this_device_id);
2147 state_fio->FputInt32_BE(clr_count);
2148 state_fio->FputBool(halt_flag);
2149 state_fio->FputInt32_BE(active_page);
2150 state_fio->FputBool(sub_busy);
2151 state_fio->FputBool(crt_flag);
2152 state_fio->FputBool(vram_wrote);
2153 #if defined(_FM77AV_VARIANTS)
2154 state_fio->FputBool(vram_wrote_shadow);
2155 for(i = 0; i < 411; i++) state_fio->FputBool(vram_wrote_table[i]);
2156 for(i = 0; i < 411; i++) state_fio->FputBool(vram_draw_table[i]);
2158 state_fio->FputBool(is_cyclesteal);
2160 state_fio->FputBool(clock_fast);
2162 #if defined(_FM77AV_VARIANTS)
2163 state_fio->FputBool(subcpu_resetreq);
2164 state_fio->FputBool(power_on_reset);
2166 state_fio->FputBool(cancel_request);
2167 state_fio->FputBool(key_firq_req);
2169 state_fio->FputInt32_BE(display_mode);
2170 state_fio->FputUint32_BE(prev_clock);
2172 state_fio->Fwrite(dpalette_data, sizeof(dpalette_data), 1);
2173 state_fio->FputUint8(multimode_accessmask);
2174 state_fio->FputUint8(multimode_dispmask);
2175 state_fio->FputUint32_BE(offset_point);
2176 #if defined(_FM77AV_VARIANTS)
2177 state_fio->FputUint32_BE(offset_point_bank1);
2178 state_fio->FputUint32_BE(offset_point_bak);
2179 state_fio->FputUint32_BE(offset_point_bank1_bak);
2181 for(i = 0; i < 2; i++) {
2182 state_fio->FputUint32_BE(tmp_offset_point[i].d);
2183 state_fio->FputBool(offset_changed[i]);
2185 state_fio->FputBool(offset_77av);
2186 state_fio->FputBool(diag_load_subrom_c);
2189 state_fio->Fwrite(io_w_latch, sizeof(io_w_latch), 1);
2190 state_fio->Fwrite(console_ram, sizeof(console_ram), 1);
2191 state_fio->Fwrite(work_ram, sizeof(work_ram), 1);
2192 state_fio->Fwrite(shared_ram, sizeof(shared_ram), 1);
2193 state_fio->Fwrite(subsys_c, sizeof(subsys_c), 1);
2194 state_fio->Fwrite(gvram, sizeof(gvram), 1);
2195 #if defined(_FM77AV_VARIANTS)
2196 state_fio->Fwrite(gvram_shadow, sizeof(gvram_shadow), 1);
2199 #if defined(_FM77_VARIANTS)
2200 state_fio->FputBool(kanjisub);
2201 state_fio->FputUint16_BE(kanjiaddr.w.l);
2202 # if defined(_FM77L4)
2203 state_fio->FputBool(mode400line);
2204 state_fio->FputBool(stat_400linecard);
2206 #elif defined(_FM77AV_VARIANTS)
2207 state_fio->FputBool(kanjisub);
2208 state_fio->FputUint16_BE(kanjiaddr.w.l);
2210 state_fio->FputBool(vblank);
2211 state_fio->FputBool(vsync);
2212 state_fio->FputBool(hblank);
2213 state_fio->FputInt32_BE(vblank_count);
2214 state_fio->FputUint32_BE(displine);
2216 state_fio->FputBool(mode320);
2217 state_fio->FputInt32_BE(display_page);
2218 state_fio->FputInt32_BE(cgrom_bank);
2219 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2220 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2221 state_fio->FputInt32_BE(vram_bank);
2224 state_fio->FputUint8(subrom_bank);
2225 state_fio->FputUint8(subrom_bank_using);
2227 state_fio->FputBool(nmi_enable);
2228 state_fio->FputBool(use_alu);
2230 state_fio->FputUint8(apalette_index.b.l);
2231 state_fio->FputUint8(apalette_index.b.h);
2232 state_fio->Fwrite(analog_palette_r, sizeof(analog_palette_r), 1);
2233 state_fio->Fwrite(analog_palette_g, sizeof(analog_palette_g), 1);
2234 state_fio->Fwrite(analog_palette_b, sizeof(analog_palette_b), 1);
2237 state_fio->FputBool(diag_load_subrom_a);
2238 state_fio->FputBool(diag_load_subrom_b);
2239 state_fio->FputBool(diag_load_subrom_cg);
2241 state_fio->Fwrite(subsys_a, sizeof(subsys_a), 1);
2242 state_fio->Fwrite(subsys_b, sizeof(subsys_b), 1);
2243 state_fio->Fwrite(subsys_cg, sizeof(subsys_cg), 1);
2244 state_fio->Fwrite(submem_hidden, sizeof(submem_hidden), 1);
2245 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2246 state_fio->FputBool(mode400line);
2247 state_fio->FputBool(mode256k);
2249 state_fio->FputBool(monitor_ram);
2250 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2251 state_fio->FputUint16_BE(window_low);
2252 state_fio->FputUint16_BE(window_high);
2253 state_fio->FputUint16_BE(window_xbegin);
2254 state_fio->FputUint16_BE(window_xend);
2255 state_fio->FputBool(window_opened);
2257 state_fio->FputBool(kanji_level2);
2259 state_fio->FputUint8(vram_active_block);
2260 state_fio->FputUint8(vram_display_block);
2261 state_fio->FputUint8(console_ram_bank);
2262 state_fio->FputBool(ram_protect);
2264 state_fio->FputUint32_BE(cgram_bank);
2265 state_fio->Fwrite(subsys_ram, sizeof(subsys_ram), 1);
2266 state_fio->Fwrite(submem_cgram, sizeof(submem_cgram), 1);
2267 state_fio->Fwrite(submem_console_av40, sizeof(submem_console_av40), 1);
2273 state_fio->FputInt32_BE(nmi_event_id);
2274 #if defined(_FM77AV_VARIANTS)
2275 state_fio->FputInt32_BE(hblank_event_id);
2276 state_fio->FputInt32_BE(hdisp_event_id);
2277 state_fio->FputInt32_BE(vsync_event_id);
2278 state_fio->FputInt32_BE(vstart_event_id);
2280 state_fio->FputBool(firq_mask);
2281 state_fio->FputBool(vram_accessflag);
2282 state_fio->FputUint32_BE(frame_skip_count);
2286 bool DISPLAY::load_state(FILEIO *state_fio)
2289 uint32 version = state_fio->FgetUint32_BE();
2290 if(this_device_id != state_fio->FgetInt32_BE()) {
2297 clr_count = state_fio->FgetInt32_BE();
2298 halt_flag = state_fio->FgetBool();
2299 active_page = state_fio->FgetInt32_BE();
2300 sub_busy = state_fio->FgetBool();
2301 crt_flag = state_fio->FgetBool();
2302 vram_wrote = state_fio->FgetBool();
2303 #if defined(_FM77AV_VARIANTS)
2304 vram_wrote_shadow = state_fio->FgetBool();
2305 for(i = 0; i < 411; i++) vram_wrote_table[i] = state_fio->FgetBool();
2306 for(i = 0; i < 411; i++) vram_draw_table[i] = state_fio->FgetBool();
2308 is_cyclesteal = state_fio->FgetBool();
2310 clock_fast = state_fio->FgetBool();
2312 #if defined(_FM77AV_VARIANTS)
2313 subcpu_resetreq = state_fio->FgetBool();
2314 power_on_reset = state_fio->FgetBool();
2316 cancel_request = state_fio->FgetBool();
2317 key_firq_req = state_fio->FgetBool();
2319 display_mode = state_fio->FgetInt32_BE();
2320 prev_clock = state_fio->FgetUint32_BE();
2322 state_fio->Fread(dpalette_data, sizeof(dpalette_data), 1);
2323 for(addr = 0; addr < 8; addr++) set_dpalette(addr, dpalette_data[addr]);
2325 multimode_accessmask = state_fio->FgetUint8();
2326 multimode_dispmask = state_fio->FgetUint8();
2327 offset_point = state_fio->FgetUint32_BE();
2328 #if defined(_FM77AV_VARIANTS)
2329 offset_point_bank1 = state_fio->FgetUint32_BE();
2330 offset_point_bak = state_fio->FgetUint32_BE();
2331 offset_point_bank1_bak = state_fio->FgetUint32_BE();
2333 for(i = 0; i < 2; i++) {
2334 tmp_offset_point[i].d = state_fio->FgetUint32_BE();
2335 offset_changed[i] = state_fio->FgetBool();
2337 offset_77av = state_fio->FgetBool();
2338 diag_load_subrom_c = state_fio->FgetBool();
2340 state_fio->Fread(io_w_latch, sizeof(io_w_latch), 1);
2341 state_fio->Fread(console_ram, sizeof(console_ram), 1);
2342 state_fio->Fread(work_ram, sizeof(work_ram), 1);
2343 state_fio->Fread(shared_ram, sizeof(shared_ram), 1);
2344 state_fio->Fread(subsys_c, sizeof(subsys_c), 1);
2345 state_fio->Fread(gvram, sizeof(gvram), 1);
2346 #if defined(_FM77AV_VARIANTS)
2347 state_fio->Fread(gvram_shadow, sizeof(gvram_shadow), 1);
2349 #if defined(_FM77_VARIANTS)
2350 kanjisub = state_fio->FgetBool();
2352 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2353 # if defined(_FM77L4)
2354 mode400line = state_fio->FgetBool();
2355 stat_400linecard = state_fio->FgetBool();
2357 #elif defined(_FM77AV_VARIANTS)
2358 kanjisub = state_fio->FgetBool();
2360 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2362 vblank = state_fio->FgetBool();
2363 vsync = state_fio->FgetBool();
2364 hblank = state_fio->FgetBool();
2365 vblank_count = state_fio->FgetInt32_BE();
2366 displine = state_fio->FgetUint32_BE();
2368 mode320 = state_fio->FgetBool();
2369 display_page = state_fio->FgetInt32_BE();
2370 cgrom_bank = state_fio->FgetInt32_BE();
2371 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2372 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2373 vram_bank = state_fio->FgetInt32_BE();
2376 subrom_bank = state_fio->FgetUint8();
2377 subrom_bank_using = state_fio->FgetUint8();
2379 nmi_enable = state_fio->FgetBool();
2380 use_alu = state_fio->FgetBool();
2382 apalette_index.b.l = state_fio->FgetUint8();
2383 apalette_index.b.h = state_fio->FgetUint8();
2385 state_fio->Fread(analog_palette_r, sizeof(analog_palette_r), 1);
2386 state_fio->Fread(analog_palette_g, sizeof(analog_palette_g), 1);
2387 state_fio->Fread(analog_palette_b, sizeof(analog_palette_b), 1);
2388 for(i = 0; i < 4096; i++) calc_apalette(i);
2390 diag_load_subrom_a = state_fio->FgetBool();
2391 diag_load_subrom_b = state_fio->FgetBool();
2392 diag_load_subrom_cg = state_fio->FgetBool();
2394 state_fio->Fread(subsys_a, sizeof(subsys_a), 1);
2395 state_fio->Fread(subsys_b, sizeof(subsys_b), 1);
2396 state_fio->Fread(subsys_cg, sizeof(subsys_cg), 1);
2397 state_fio->Fread(submem_hidden, sizeof(submem_hidden), 1);
2399 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2400 mode400line = state_fio->FgetBool();
2401 mode256k = state_fio->FgetBool();
2403 monitor_ram = state_fio->FgetBool();
2404 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2405 window_low = state_fio->FgetUint16_BE();
2406 window_high = state_fio->FgetUint16_BE();
2407 window_xbegin = state_fio->FgetUint16_BE();
2408 window_xend = state_fio->FgetUint16_BE();
2409 window_opened = state_fio->FgetBool();
2411 kanji_level2 = state_fio->FgetBool();
2413 vram_active_block = state_fio->FgetUint8();
2414 vram_display_block = state_fio->FgetUint8();
2415 console_ram_bank = state_fio->FgetUint8();
2416 ram_protect = state_fio->FgetBool();
2418 cgram_bank = state_fio->FgetUint32_BE();
2419 state_fio->Fread(subsys_ram, sizeof(subsys_ram), 1);
2420 state_fio->Fread(submem_cgram, sizeof(submem_cgram), 1);
2421 state_fio->Fread(submem_console_av40, sizeof(submem_console_av40), 1);
2424 #if defined(_FM77AV_VARIANTS)
2425 bool vram_wrote_shadow_bak = vram_wrote_shadow;
2426 vram_wrote_shadow = true; // Force Draw
2428 this->draw_screen();
2429 #if defined(_FM77AV_VARIANTS)
2430 vram_wrote_shadow = vram_wrote_shadow_bak;
2432 if(version == 1) return true;
2434 if(version >= 2) { //V2
2435 nmi_event_id = state_fio->FgetInt32_BE();
2436 #if defined(_FM77AV_VARIANTS)
2437 hblank_event_id = state_fio->FgetInt32_BE();
2438 hdisp_event_id = state_fio->FgetInt32_BE();
2439 vsync_event_id = state_fio->FgetInt32_BE();
2440 vstart_event_id = state_fio->FgetInt32_BE();
2442 firq_mask = state_fio->FgetBool();
2443 vram_accessflag = state_fio->FgetBool();
2444 frame_skip_count = state_fio->FgetUint32_BE();