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 //cancel_request = false;
37 switch(config.cpu_type){
48 for(i = 0; i < 2; i++) {
49 offset_changed[i] = true;
50 tmp_offset_point[i].d = 0;
53 vram_wrote_shadow = false;
54 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
55 for(i = 0; i < 400; i++) vram_wrote_table[i] = true;
56 for(i = 0; i < 400; i++) vram_draw_table[i] = true;
64 if(hblank_event_id >= 0) cancel_event(this, hblank_event_id);
65 if(hdisp_event_id >= 0) cancel_event(this, hdisp_event_id);
66 if(vsync_event_id >= 0) cancel_event(this, vsync_event_id);
67 if(vstart_event_id >= 0) cancel_event(this, vstart_event_id);
72 if(display_mode == DISPLAY_MODE_8_400L) {
78 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
79 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
80 mainio->write_signal(SIG_DISPLAY_VSYNC, 0xff, 0xff);
82 #if defined(_FM77AV_VARIANTS)
84 offset_point_bank1 = 0;
86 offset_point_bank1_bak = 0;
90 subcpu_resetreq = false;
91 subrom_bank_using = subrom_bank;
96 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
98 vram_display_block = 0;
99 vram_active_block = 0;
101 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
106 window_opened = false;
111 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
112 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
113 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400: 200, 0xffff);
114 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xffffffff : 0, 0xffffffff);
116 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
117 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
118 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
120 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
121 alu->write_signal(SIG_ALU_PLANES, 3, 3);
124 for(i = 0; i < 8; i++) set_dpalette(i, i);
125 do_firq(!firq_mask && key_firq_req);
127 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
129 kanjiaddr.d = 0x00000000;
130 # if defined(_FM77L4)
132 stat_400linecard = false;
135 //if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
136 //register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
139 frame_skip_count = 3;
143 void DISPLAY::reset()
147 memset(io_w_latch, 0xff, sizeof(io_w_latch));
149 vram_accessflag = true;
150 display_mode = DISPLAY_MODE_8_200L;
152 screen_update_flag = true;
155 cancel_request = false;
156 #if defined(_FM77AV_VARIANTS)
158 apalette_index.d = 0;
159 for(i = 0; i < 4096; i++) {
160 analog_palette_r[i] = i & 0x0f0;
161 analog_palette_g[i] = i & 0xf00;
162 analog_palette_b[i] = i & 0x00f;
167 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
174 #elif defined(_FM77L4)
177 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
178 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
179 key_firq_req = false; //firq_mask = true;
183 #if defined(_FM77AV_VARIANTS)
184 power_on_reset = false;
185 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
189 for(i = 0; i < 8; i++) set_dpalette(i, i);
190 multimode_accessmask = 0x00;
191 multimode_dispmask = 0x00;
196 if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
197 register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
198 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
202 void DISPLAY::update_config()
205 switch(config.cpu_type) {
214 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
220 * Vram accessing functions moved to vram.cpp .
223 void DISPLAY::do_irq(bool flag)
225 subcpu->write_signal(SIG_CPU_IRQ, flag ? 1: 0, 1);
228 void DISPLAY::do_firq(bool flag)
230 subcpu->write_signal(SIG_CPU_FIRQ, flag ? 1: 0, 1);
233 void DISPLAY::do_nmi(bool flag)
235 #if defined(_FM77AV_VARIANTS)
236 if(!nmi_enable) flag = false;
238 subcpu->write_signal(SIG_CPU_NMI, flag ? 1 : 0, 1);
241 void DISPLAY::set_multimode(uint8 val)
244 multimode_accessmask = val & 0x07;
245 multimode_dispmask = (val & 0x70) >> 4;
247 # if defined(_FM77AV_VARIANTS)
248 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
253 uint8 DISPLAY::get_multimode(void)
259 val = multimode_accessmask & 0x07;
260 val |= ((multimode_dispmask << 4) & 0x70);
266 uint8 DISPLAY::get_cpuaccessmask(void)
268 return multimode_accessmask & 0x07;
271 void DISPLAY::set_dpalette(uint32 addr, uint8 val)
275 dpalette_data[addr] = val | 0xf8; //0b11111000;
277 b = ((val & 0x01) != 0x00)? 255 : 0x00;
278 r = ((val & 0x02) != 0x00)? 255 : 0x00;
279 g = ((val & 0x04) != 0x00)? 255 : 0x00;
281 dpalette_pixel[addr] = RGB_COLOR(r, g, b);
284 uint8 DISPLAY::get_dpalette(uint32 addr)
292 data = dpalette_data[addr];
297 void DISPLAY::halt_subcpu(void)
299 subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
302 void DISPLAY::go_subcpu(void)
304 subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
307 void DISPLAY::enter_display(void)
311 subclock = SUBCLOCK_NORMAL;
313 subclock = SUBCLOCK_SLOW;
315 if(!is_cyclesteal && vram_accessflag) {
316 subclock = subclock / 3;
318 if(prev_clock != subclock) p_vm->set_cpu_clock(subcpu, subclock);
319 prev_clock = subclock;
322 void DISPLAY::leave_display(void)
326 void DISPLAY::halt_subsystem(void)
332 void DISPLAY::restart_subsystem(void)
335 #if defined(_FM77AV_VARIANTS)
336 if(subcpu_resetreq) {
337 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
339 power_on_reset = true;
340 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
342 do_firq(!firq_mask && key_firq_req);
349 void DISPLAY::set_crtflag(void)
356 void DISPLAY::reset_crtflag(void)
363 uint8 DISPLAY::acknowledge_irq(void)
365 cancel_request = false;
371 uint8 DISPLAY::beep(void)
373 mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
374 return 0xff; // True?
379 uint8 DISPLAY::attention_irq(void)
381 mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
386 void DISPLAY::set_cyclesteal(uint8 val)
391 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
393 is_cyclesteal = true;
395 is_cyclesteal = false;
403 uint8 DISPLAY::set_vramaccess(void)
405 vram_accessflag = true;
410 void DISPLAY::reset_vramaccess(void)
412 vram_accessflag = false;
416 uint8 DISPLAY::reset_subbusy(void)
423 void DISPLAY::set_subbusy(void)
429 #if defined(_FM77AV_VARIANTS)
431 void DISPLAY::alu_write_cmdreg(uint32 val)
433 alu->write_data8(ALU_CMDREG, val);
434 if((val & 0x80) != 0) {
442 void DISPLAY::alu_write_logical_color(uint8 val)
444 uint32 data = (uint32)val;
445 alu->write_data8(ALU_LOGICAL_COLOR, data);
449 void DISPLAY::alu_write_mask_reg(uint8 val)
451 uint32 data = (uint32)val;
452 alu->write_data8(ALU_WRITE_MASKREG, data);
456 void DISPLAY::alu_write_cmpdata_reg(int addr, uint8 val)
458 uint32 data = (uint32)val;
460 alu->write_data8(ALU_CMPDATA_REG + addr, data);
464 void DISPLAY::alu_write_disable_reg(uint8 val)
466 uint32 data = (uint32)val;
467 alu->write_data8(ALU_BANK_DISABLE, data);
471 void DISPLAY::alu_write_tilepaint_data(uint32 addr, uint8 val)
473 uint32 data = (uint32)val;
476 alu->write_data8(ALU_TILEPAINT_B, data);
479 alu->write_data8(ALU_TILEPAINT_R, data);
482 alu->write_data8(ALU_TILEPAINT_G, data);
485 //alu->write_data8(ALU_TILEPAINT_L, 0xff);
491 void DISPLAY::alu_write_offsetreg_hi(uint8 val)
493 alu->write_data8(ALU_OFFSET_REG_HIGH, val & 0x7f);
497 void DISPLAY::alu_write_offsetreg_lo(uint8 val)
499 alu->write_data8(ALU_OFFSET_REG_LO, val);
503 void DISPLAY::alu_write_linepattern_hi(uint8 val)
505 alu->write_data8(ALU_LINEPATTERN_REG_HIGH, val);
509 void DISPLAY::alu_write_linepattern_lo(uint8 val)
511 alu->write_data8(ALU_LINEPATTERN_REG_LO, val);
515 void DISPLAY::alu_write_line_position(int addr, uint8 val)
517 uint32 data = (uint32)val;
520 alu->write_data8(ALU_LINEPOS_START_X_HIGH, data & 0x03);
523 alu->write_data8(ALU_LINEPOS_START_X_LOW, data);
526 alu->write_data8(ALU_LINEPOS_START_Y_HIGH, data & 0x01);
529 alu->write_data8(ALU_LINEPOS_START_Y_LOW, data);
532 alu->write_data8(ALU_LINEPOS_END_X_HIGH, data & 0x03);
535 alu->write_data8(ALU_LINEPOS_END_X_LOW, data);
538 alu->write_data8(ALU_LINEPOS_END_Y_HIGH, data & 0x01);
541 alu->write_data8(ALU_LINEPOS_END_Y_LOW, data);
547 uint8 DISPLAY::get_miscreg(void)
552 if(!hblank) ret |= 0x80;
553 if(vsync) ret |= 0x04;
554 if(alu->read_signal(SIG_ALU_BUSYSTAT) == 0) ret |= 0x10;
555 if(power_on_reset) ret |= 0x01;
560 void DISPLAY::set_miscreg(uint8 val)
562 int old_display_page = display_page;
564 nmi_enable = ((val & 0x80) == 0) ? true : false;
565 if(!nmi_enable) do_nmi(false);
567 if((val & 0x40) == 0) {
572 if(display_page != old_display_page) {
575 active_page = ((val & 0x20) == 0) ? 0 : 1;
576 if((val & 0x04) == 0) {
581 cgrom_bank = val & 0x03;
585 void DISPLAY::set_monitor_bank(uint8 var)
587 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
588 if((var & 0x04) != 0){
594 subrom_bank = var & 0x03;
597 subcpu_resetreq = false;
598 power_on_reset = true;
599 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
601 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
603 do_firq(!firq_mask && key_firq_req);
605 subcpu_resetreq = true;
611 void DISPLAY::set_apalette_index_hi(uint8 val)
613 apalette_index.b.h = val & 0x0f;
617 void DISPLAY::set_apalette_index_lo(uint8 val)
619 apalette_index.b.l = val;
622 void DISPLAY::calc_apalette(uint16 idx)
626 g = analog_palette_g[idx];
627 r = analog_palette_r[idx];
628 b = analog_palette_b[idx];
629 analog_palette_pixel[idx] = RGB_COLOR(r, g, b);
633 void DISPLAY::set_apalette_b(uint8 val)
637 index = apalette_index.w.l;
638 tmp = (val & 0x0f) << 4;
639 if(analog_palette_b[index] != tmp) {
640 analog_palette_b[index] = tmp;
641 calc_apalette(index);
647 void DISPLAY::set_apalette_r(uint8 val)
651 index = apalette_index.w.l;
652 tmp = (val & 0x0f) << 4;
653 if(analog_palette_r[index] != tmp) {
654 analog_palette_r[index] = tmp;
655 calc_apalette(index);
661 void DISPLAY::set_apalette_g(uint8 val)
665 index = apalette_index.w.l;
666 tmp = (val & 0x0f) << 4;
667 if(analog_palette_g[index] != tmp) {
668 analog_palette_g[index] = tmp;
669 calc_apalette(index);
674 #endif // _FM77AV_VARIANTS
677 // Timing values from XM7 . Thanks Ryu.
678 void DISPLAY::event_callback(int event_id, int err)
683 case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
684 #if defined(_FM77AV_VARIANTS)
694 case EVENT_FM7SUB_DISPLAY_NMI_OFF: // per 20.00ms
697 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
698 case EVENT_FM7SUB_HDISP:
701 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x02, 0xff);
702 //if(displine == 0) enter_display();
703 if(display_mode == DISPLAY_MODE_8_400L) {
705 if(displine < 400) f = true;
708 if(displine < 200) f = true;
711 register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
718 case EVENT_FM7SUB_HBLANK:
720 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
722 if(display_mode == DISPLAY_MODE_8_400L) {
723 if(displine < 400) f = true;
725 if(displine < 200) f = true;
728 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
729 if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)){
730 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
732 # elif defined(_FM77AV40)
737 if(vram_wrote_table[displine] || vram_wrote) {
738 uint32 baseaddr1 = ((displine) * 40) & 0x1fff;
739 uint32 baseaddr2 = baseaddr1 + 0xc000;
740 vram_wrote_table[displine] = false;
741 for(int i = 0; i < planes; i++) {
742 for(int j = 0; j < 6; j++) {
743 memcpy(&gvram_shadow[j * 0x2000 + baseaddr1],
744 &gvram[j * 0x2000 + baseaddr1], 40);
745 memcpy(&gvram_shadow[j * 0x2000 + baseaddr2],
746 &gvram[j * 0x2000 + baseaddr2], 40);
748 baseaddr1 += 0x18000;
749 baseaddr2 += 0x18000;
751 # if defined(_FM77AV40)
752 for(int j = 0; j < 6; j++) {
753 memcpy(&gvram_shadow[j * 0x2000 + baseaddr1],
754 &gvram[j * 0x2000 + baseaddr1], 40);
757 //screen_update_flag = true;
758 vram_draw_table[displine] = true;
760 } else if(display_mode == DISPLAY_MODE_8_400L) {
761 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
763 # elif defined(_FM77AV40)
768 if(vram_wrote_table[displine] || vram_wrote) {
769 uint32 baseaddr1 = ((displine) * 80) & 0x7fff;
770 vram_wrote_table[displine] = false;
771 for(int i = 0; i < planes; i++) {
772 for(int j = 0; j < 3; j++) {
773 memcpy(&gvram_shadow[j * 0x8000 + baseaddr1],
774 &gvram[j * 0x8000 + baseaddr1], 80);
776 baseaddr1 += 0x18000;
779 # if defined(_FM77AV40)
780 for(int j = 0; j < 3; j++) {
781 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
782 &gvram[j * 0x4000 + baseaddr1], 80);
785 //screen_update_flag = true;
786 vram_draw_table[displine] = true;
789 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
791 # elif defined(_FM77AV40)
796 if(vram_wrote_table[displine] || vram_wrote) {
797 uint32 baseaddr1 = ((displine) * 80) & 0x3fff;
798 uint32 baseaddr2 = baseaddr1 + 0xc000;
799 for(int i = 0; i < planes; i++) {
800 vram_wrote_table[displine] = false;
801 for(int j = 0; j < 3; j++) {
802 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
803 &gvram[j * 0x4000 + baseaddr1], 80);
804 memcpy(&gvram_shadow[j * 0x4000 + baseaddr2],
805 &gvram[j * 0x4000 + baseaddr2], 80);
807 baseaddr1 += 0x18000;
808 baseaddr2 += 0x18000;
810 # if defined(_FM77AV40)
811 for(int j = 0; j < 3; j++) {
812 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
813 &gvram[j * 0x4000 + baseaddr1], 80);
816 //screen_update_flag = true;
817 vram_draw_table[displine] = true;
821 if(display_mode == DISPLAY_MODE_8_400L) {
826 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id);
829 //vram_wrote_shadow = true;
832 case EVENT_FM7SUB_VSTART: // Call first.
837 // Parameter from XM7/VM/display.c , thanks, Ryu.
838 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
839 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x00, 0xff);
840 if(vblank_count != 0) {
841 if(display_mode == DISPLAY_MODE_8_400L) {
842 usec = (0.98 + 16.4) * 1000.0;
844 usec = (1.91 + 12.7) * 1000.0;
846 register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id);
848 if(display_mode == DISPLAY_MODE_8_400L) {
849 usec = 930.0; // 939.0
851 usec = 1840.0; // 1846.5
853 //offset_point_bank1_bak = offset_point_bank1;
854 //offset_point_bak = offset_point;
855 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
858 if(display_mode == DISPLAY_MODE_8_400L) {
859 usec = 0.34 * 1000.0;
861 usec = 1.52 * 1000.0;
863 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;
870 //for(int i = 0; i < 411; i++) vram_draw_table[i] = true;
871 } else if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
872 if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)){
875 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
877 # elif defined(_FM77AV40)
884 for(int j = 200; j < 206; j++) {
885 if(vram_wrote_table[j]) {
888 vram_wrote_table[j] = false;
892 for(int j = 200; j < 205; j++) {
893 vram_draw_table[(((j * 40) + offset_point_bak) & 0x1fff) / 40] = true;
894 vram_draw_table[(((j * 40) + offset_point_bank1_bak) & 0x1fff) / 40] = true;
896 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x2000 + 200 * 40],
897 &gvram[i * 0x2000 + 200 * 40], 0x2000 - 200 * 40);
899 } else if(display_mode == DISPLAY_MODE_8_400L) {
902 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
904 # elif defined(_FM77AV40)
911 for(int j = 400; j < 411; j++) {
912 if(vram_wrote_table[j]) {
915 vram_wrote_table[j] = false;
919 for(int j = 400; j < 410; j++) {
920 vram_draw_table[(((j * 80) + offset_point_bak) & 0x7fff) / 80] = true;
921 vram_draw_table[(((j * 80) + offset_point_bank1_bak) & 0x7fff) / 80] = true;
923 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x8000 + 400 * 80],
924 &gvram[i * 0x8000 + 400 * 80], 0x8000 - 400 * 80);
925 //screen_update_flag = true;
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);
953 //screen_update_flag = true;
958 vram_wrote_shadow = true;
959 screen_update_flag = true;
962 if(display_mode == DISPLAY_MODE_8_400L) {
963 for(int yy = 0; yy < 411; yy++) {
964 if(vram_draw_table[yy]) fy = true;
965 vram_draw_table[yy] = false;
968 for(int yy = 0; yy < 205; yy++) {
969 if(vram_draw_table[yy]) fy = true;
970 vram_draw_table[yy] = false;
973 vram_wrote_shadow |= fy;
974 screen_update_flag |= fy;
978 case EVENT_FM7SUB_VSYNC:
983 if(display_mode == DISPLAY_MODE_8_400L) {
984 usec = 0.33 * 1000.0;
986 usec = 0.51 * 1000.0;
988 offset_point_bank1_bak = offset_point_bank1;
989 offset_point_bak = offset_point;
990 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x01, 0xff);
991 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
994 case EVENT_FM7SUB_CLR_BUSY:
997 case EVENT_FM7SUB_CLR_CRTFLAG:
1003 void DISPLAY::event_frame()
1005 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
1007 screen_update_flag = true;
1008 vram_wrote_shadow = true;
1015 void DISPLAY::event_vline(int v, int clock)
1020 uint32 DISPLAY::read_signal(int id)
1024 case SIG_FM7_SUB_HALT:
1025 case SIG_DISPLAY_HALT:
1026 retval = (halt_flag) ? 0xffffffff : 0;
1028 case SIG_DISPLAY_BUSY:
1029 retval = (sub_busy) ? 0x80 : 0;
1031 case SIG_DISPLAY_MULTIPAGE:
1032 retval = multimode_accessmask;
1034 case SIG_DISPLAY_PLANES:
1037 #if defined(_FM77AV_VARIANTS)
1038 case SIG_DISPLAY_VSYNC:
1039 retval = (vsync) ? 0x01 : 0x00;
1041 case SIG_DISPLAY_DISPLAY:
1042 retval = (!hblank) ? 0x02: 0x00;
1044 case SIG_FM7_SUB_BANK: // Main: FD13
1045 retval = subrom_bank & 0x03;
1046 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1047 if(monitor_ram) retval |= 0x04;
1051 #if defined(_FM77AV_VARIANTS)
1052 case SIG_DISPLAY_MODE320:
1053 retval = (mode320) ? 0x40: 0x00;
1056 case SIG_DISPLAY_Y_HEIGHT:
1057 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1058 retval = (mode400line) ? 400 : 200;
1063 case SIG_DISPLAY_X_WIDTH:
1064 #if defined(_FM77AV_VARIANTS)
1065 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1066 retval = (mode320 || mode256k) ? 40 : 80;
1068 retval = (mode320) ? 40 : 80;
1080 void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
1082 bool flag = ((data & mask) != 0);
1085 case SIG_FM7_SUB_HALT:
1090 //mainio->write_signal(SIG_FM7_SUB_HALT, data, mask);
1092 case SIG_DISPLAY_HALT:
1096 restart_subsystem();
1099 case SIG_FM7_SUB_CANCEL:
1101 cancel_request = true;
1105 case SIG_DISPLAY_CLOCK:
1109 #if defined(_FM77AV_VARIANTS)
1110 case SIG_FM7_SUB_BANK: // Main: FD13
1111 set_monitor_bank(data & 0xff);
1114 case SIG_DISPLAY_EXTRA_MODE: // FD04 bit 4, 3
1115 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1117 int oldmode = display_mode;
1119 kanjisub = ((data & 0x20) == 0) ? true : false;
1120 mode256k = ((data & 0x10) != 0) ? true : false;
1121 mode400line = ((data & 0x08) != 0) ? false : true;
1122 ram_protect = ((data & 0x04) != 0) ? false : true;
1124 display_mode = DISPLAY_MODE_8_400L;
1125 } else if(mode256k) {
1126 display_mode = DISPLAY_MODE_256k;
1128 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1130 if(oldmode != display_mode) {
1133 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1134 for(y = 0; y < 400; y++) {
1135 pp = emu->get_screen_buffer(y);
1136 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype));
1138 } else if(mode320 || mode256k) {
1139 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1140 for(y = 0; y < 200; y++) {
1141 pp = emu->get_screen_buffer(y);
1142 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype));
1145 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1146 for(y = 0; y < 200; y++) {
1147 pp = emu->get_screen_buffer(y);
1148 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype));
1152 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
1153 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400 : 200, 0xffff);
1154 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff);
1155 frame_skip_count = 3;
1158 #elif defined(_FM77_VARIANTS)
1160 int oldmode = display_mode;
1161 kanjisub = ((data & 0x20) == 0) ? true : false;
1162 # if defined(_FM77L4)
1163 stat_400linecard = ((data & 0x20) != 0) ? true : false;
1164 mode400line = ((data & 0x08) != 0) ? false : true;
1165 if(mode400line && stat_400linecard) {
1166 display_mode = DISPLAY_MODE_8_400L_TEXT;
1167 } else if(stat_400linecard) {
1168 display_mode = DISPLAY_MODE_8_200L_TEXT;
1170 display_mode = DISPLAY_MODE_8_200L;
1176 #if defined(_FM77AV_VARIANTS)
1177 case SIG_DISPLAY_MODE320: // FD12 bit 6
1178 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1180 int oldmode = display_mode;
1182 if((!mode400line) && (!mode256k)){
1183 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1185 if(oldmode != display_mode) {
1188 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1189 for(y = 0; y < 400; y++) {
1190 pp = emu->get_screen_buffer(y);
1191 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype));
1193 } else if(mode320 || mode256k) {
1194 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1195 for(y = 0; y < 200; y++) {
1196 pp = emu->get_screen_buffer(y);
1197 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype));
1200 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1201 for(y = 0; y < 200; y++) {
1202 pp = emu->get_screen_buffer(y);
1203 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype));
1207 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
1208 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400 : 200, 0xffff);
1209 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff);
1210 frame_skip_count = 3;
1218 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1219 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 320 * sizeof(scrntype));
1221 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1222 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 640 * sizeof(scrntype));
1225 display_mode = (mode320 == true) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1226 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1227 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1228 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
1233 case SIG_DISPLAY_MULTIPAGE:
1234 set_multimode(data);
1236 case SIG_FM7_SUB_KEY_MASK:
1237 if(firq_mask == flag) {
1238 do_firq(!flag && key_firq_req);
1242 case SIG_FM7_SUB_KEY_FIRQ:
1243 do_firq(flag & !(firq_mask));
1244 key_firq_req = flag;
1246 case SIG_FM7_SUB_USE_CLR:
1248 clr_count = data & 0x03;
1259 * Vram accessing functions moved to vram.cpp .
1262 uint8 DISPLAY::read_mmio(uint32 addr)
1264 uint32 retval = 0xff;
1266 if(addr < 0xd400) return 0xff;
1268 #if !defined(_FM77AV_VARIANTS)
1269 raddr = (addr - 0xd400) & 0x000f;
1270 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1271 raddr = (addr - 0xd400) & 0x003f;
1272 #else // FM77AV40EX || FM77AV40SX
1273 raddr = (addr - 0xd400) & 0x00ff;
1276 case 0x00: // Read keyboard
1277 retval = (keyboard->read_data8(0x00) != 0) ? 0xff : 0x7f;
1279 case 0x01: // Read keyboard
1280 retval = keyboard->read_data8(0x01) & 0xff;
1282 case 0x02: // Acknowledge
1291 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1292 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1294 if(!kanjisub) return 0xff;
1295 # if !defined(_FM77_VARIANTS)
1297 return (uint8)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1300 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1303 if(!kanjisub) return 0xff;
1304 # if !defined(_FM77_VARIANTS)
1306 return (uint8)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1309 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1316 retval = set_vramaccess();
1322 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x01, 0x01);
1324 #if defined(_FM77AV_VARIANTS)
1327 retval = alu->read_data8(ALU_CMDREG);
1330 retval = alu->read_data8(ALU_LOGICAL_COLOR);
1333 retval = alu->read_data8(ALU_WRITE_MASKREG);
1336 retval = alu->read_data8(ALU_CMP_STATUS_REG);
1339 retval = alu->read_data8(ALU_BANK_DISABLE);
1341 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1342 case 0x2f: // VRAM BANK
1343 retval = 0xfc | (vram_bank & 0x03);
1348 retval = get_miscreg();
1352 retval = keyboard->read_data8(0x31);
1355 retval = keyboard->read_data8(0x32);
1361 return (uint8)retval;
1364 uint32 DISPLAY::read_vram_data8(uint32 addr)
1367 uint32 page_offset = 0;
1368 uint32 page_mask = 0x3fff;
1369 uint32 color = (addr >> 14) & 0x03;
1372 #if defined(_FM77AV_VARIANTS)
1373 if (active_page != 0) {
1374 offset = offset_point_bank1;
1376 offset = offset_point;
1379 offset = offset_point;
1382 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1383 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1384 if(vram_active_block != 0) page_offset = 0x18000;
1386 if(display_mode == DISPLAY_MODE_8_400L) {
1387 if(addr >= 0x8000) return 0xff;
1388 color = vram_bank & 0x03;
1389 if(color > 2) color = 0;
1391 pagemod = 0x8000 * color;
1392 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1395 #if defined(_FM77AV40)
1397 page_offset = 0xc000 * (vram_bank & 0x03);
1399 page_offset = 0; // right?
1402 page_offset = 0xc000 * (vram_bank & 0x03);
1405 pagemod = addr & 0xe000;
1409 pagemod = addr & 0xe000;
1411 pagemod = addr & 0xc000;
1413 if(active_page != 0) {
1414 page_offset += 0xc000;
1417 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1419 #elif defined(_FM77AV_VARIANTS)
1421 if(active_page != 0) {
1422 page_offset += 0xc000;
1426 pagemod = addr & 0xe000;
1428 pagemod = addr & 0xc000;
1430 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1432 #elif defined(_FM77L4) //_FM77L4
1434 if(display_mode == DISPLAY_MODE_8_400L) {
1435 return (uint32)read_vram_l4_400l(addr, offset);
1437 pagemod = addr & 0xc000;
1438 return gvram[((addr + offset) & 0x3fff) | pagemod];
1442 #else // Others (77/7/8)
1443 pagemod = addr & 0xc000;
1444 return gvram[((addr + offset) & 0x3fff) | pagemod];
1448 void DISPLAY::write_dma_data8(uint32 addr, uint32 data)
1450 uint32 raddr = addr & 0xffff;
1453 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1454 if(display_mode == DISPLAY_MODE_8_400L) {
1455 color = vram_bank & 0x03;
1456 if(color > 2) color = 0;
1458 color = (addr >> 14) & 0x03;
1462 if((multimode_accessmask & (1 << color)) != 0) return;
1464 return write_vram_data8(raddr, (uint8)data);
1466 return write_data8_main(raddr, (uint8)data);
1471 void DISPLAY::write_vram_data8(uint32 addr, uint8 data)
1474 uint32 page_offset = 0;
1475 uint32 page_mask = 0x3fff;
1476 uint32 color = (addr >> 14) & 0x03;
1479 #if defined(_FM77AV_VARIANTS)
1480 if (active_page != 0) {
1481 offset = offset_point_bank1;
1483 offset = offset_point;
1486 offset = offset_point;
1489 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1490 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1491 if(vram_active_block != 0) page_offset = 0x18000;
1493 if(display_mode == DISPLAY_MODE_8_400L) {
1494 if(addr >= 0x8000) {
1497 color = vram_bank & 0x03;
1498 if(color > 2) color = 0;
1500 pagemod = 0x8000 * color;
1501 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
1502 vram_wrote_table[((addr + offset) % 0x8000) / 80] = true;
1503 } else if(display_mode == DISPLAY_MODE_256k) {
1504 #if defined(_FM77AV40)
1506 page_offset = 0xc000 * (vram_bank & 0x03);
1508 page_offset = 0; // right?
1511 page_offset = 0xc000 * (vram_bank & 0x03);
1514 pagemod = addr & 0xe000;
1515 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1516 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1518 } else if(display_mode == DISPLAY_MODE_4096) {
1519 if(active_page != 0) {
1520 page_offset += 0xc000;
1523 pagemod = addr & 0xe000;
1524 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1525 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1527 if(active_page != 0) {
1528 page_offset += 0xc000;
1531 pagemod = addr & 0xc000;
1532 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1533 vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1536 #elif defined(_FM77AV_VARIANTS)
1537 if(display_mode == DISPLAY_MODE_4096) {
1538 if(active_page != 0) {
1539 page_offset = 0xc000;
1542 pagemod = addr & 0xe000;
1543 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1544 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1546 if(active_page != 0) {
1547 page_offset = 0xc000;
1550 pagemod = addr & 0xc000;
1551 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1552 vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1554 #elif defined(_FM77L4) //_FM77L4
1556 if(display_mode == DISPLAY_MODE_8_400L) {
1557 write_vram_l4_400l(addr, data, offset);
1559 pagemod = addr & 0xc000;
1560 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1562 //vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1564 #else // Others (77/7/8)
1565 pagemod = addr & 0xc000;
1566 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1567 //vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1569 #if defined(_FM77AV_VARIANTS)
1570 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
1576 uint32 DISPLAY::read_data8_main(uint32 addr)
1579 if(addr < 0xc000) return 0xff;
1581 raddr = addr - 0xc000;
1582 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1584 if(console_ram_bank >= 1) {
1585 return submem_console_av40[((console_ram_bank - 1) << 12) + raddr];
1589 return console_ram[raddr];
1590 } else if(addr < 0xd380) {
1591 raddr = addr - 0xd000;
1592 return work_ram[raddr];
1593 } else if(addr < 0xd400) {
1594 raddr = addr - 0xd380;
1595 return shared_ram[raddr];
1596 } else if(addr < 0xd800) {
1597 #if defined(_FM77AV_VARIANTS)
1598 if(addr >= 0xd500) {
1599 return submem_hidden[addr - 0xd500];
1602 return read_mmio(addr);
1603 } else if(addr < 0x10000) {
1604 #if !defined(_FM77AV_VARIANTS)
1605 return subsys_c[addr - 0xd800];
1608 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1610 return submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)]; //FIXME
1613 return subsys_cg[(addr - 0xd800) + cgrom_bank * 0x800];
1614 } else if(addr < 0x10000) {
1615 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1617 return subsys_ram[addr - 0xe000];
1620 switch(subrom_bank_using & 3) {
1622 return subsys_c[addr - 0xd800];
1625 return subsys_a[addr - 0xe000];
1628 return subsys_b[addr - 0xe000];
1631 return subsys_cg[addr - 0xe000];
1640 uint32 DISPLAY::read_dma_data8(uint32 addr)
1642 uint32 raddr = addr & 0xffff;
1645 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1646 if(display_mode == DISPLAY_MODE_8_400L) {
1647 color = vram_bank & 0x03;
1648 if(color > 2) color = 0;
1650 color = (addr >> 14) & 0x03;
1654 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1656 return read_vram_data8(raddr);
1658 return read_data8_main(raddr);
1663 uint32 DISPLAY::read_data8(uint32 addr)
1665 uint32 raddr = addr;
1667 uint32 color = (addr & 0x0c000) >> 14;
1669 #if defined(_FM77AV_VARIANTS)
1671 alu->read_data8(addr + ALU_WRITE_PROXY);
1674 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1675 if(display_mode == DISPLAY_MODE_8_400L) {
1676 color = vram_bank & 0x03;
1677 if(color > 2) color = 0;
1679 color = (addr >> 14) & 0x03;
1683 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1685 return read_vram_data8(addr);
1686 } else if(addr < 0x10000) {
1687 return read_data8_main(addr);
1690 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1691 return dpalette_data[addr - FM7_SUBMEM_OFFSET_DPALETTE];
1694 #if defined(_FM77AV_VARIANTS)
1696 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
1697 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
1698 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1699 if(display_mode == DISPLAY_MODE_8_400L) {
1700 uint32 page_offset = 0;
1701 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1702 if(vram_active_block != 0) page_offset = 0x18000;
1704 color = (addr & 0x18000) >> 15;
1705 if(color > 2) color = 0;
1707 if (active_page != 0) {
1708 offset = offset_point_bank1 << 1;
1710 offset = offset_point << 1;
1712 if(color > 2) color = 0;
1713 uint32 pagemod = 0x8000 * color;
1714 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1717 return read_vram_data8(addr);
1724 * Vram accessing functions moved to vram.cpp .
1727 void DISPLAY::write_mmio(uint32 addr, uint32 data)
1731 if(addr < 0xd400) return;
1733 #if !defined(_FM77AV_VARIANTS)
1734 addr = (addr - 0xd400) & 0x000f;
1735 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1736 addr = (addr - 0xd400) & 0x003f;
1737 #else // FM77AV40EX || FM77AV40SX
1738 addr = (addr - 0xd400) & 0x00ff;
1740 io_w_latch[addr] = (uint8)data;
1742 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
1745 set_cyclesteal((uint8)data);
1748 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1749 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1752 if(!kanjisub) return;
1753 kanjiaddr.w.h = 0x0000;
1754 kanjiaddr.b.h = (uint8) data;
1757 if(!kanjisub) return;
1758 kanjiaddr.w.h = 0x0000;
1759 kanjiaddr.b.l = (uint8)data;
1772 if(clr_count <= 0) {
1774 } else { // Read once when using clr_foo() to set busy flag.
1777 usec = (1000.0 * 1000.0) / 2000000.0;
1779 usec = (1000.0 * 1000.0) / 999000.0;
1781 if(!is_cyclesteal) usec = usec * 3.0;
1782 usec = (double)clr_count * usec;
1783 register_event(this, EVENT_FM7SUB_CLR_BUSY, usec, false, NULL); // NEXT CYCLE_
1790 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
1796 if(offset_changed[active_page]) {
1797 #if defined(_FM77AV_VARIANTS)
1798 if(active_page != 0) {
1799 tmp_offset_point[active_page].d = offset_point_bank1;
1801 tmp_offset_point[active_page].d = offset_point;
1804 tmp_offset_point[active_page].d = offset_point;
1807 tmp_offset_point[active_page].w.h = 0x0000;
1809 tmp_offset_point[active_page].b.h = rval;
1811 tmp_offset_point[active_page].b.l = rval;
1813 offset_changed[active_page] = !offset_changed[active_page];
1814 if(offset_changed[active_page]) {
1816 #if defined(_FM77AV_VARIANTS)
1817 if(active_page != 0) {
1819 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fff;
1821 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fe0;
1825 offset_point = tmp_offset_point[active_page].d & 0x007fff;
1827 offset_point = tmp_offset_point[active_page].d & 0x007fe0;
1831 offset_point = tmp_offset_point[active_page].d & 0x7fe0;
1835 #if defined(_FM77AV_VARIANTS)
1838 alu_write_cmdreg(data);
1841 alu_write_logical_color(data);
1844 alu_write_mask_reg(data);
1847 alu_write_disable_reg(data);
1850 alu_write_offsetreg_hi(data);
1853 alu_write_offsetreg_lo(data);
1856 alu_write_linepattern_hi(data);
1859 alu_write_linepattern_lo(data);
1861 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1863 console_ram_bank = (data & 0x18) >> 3;
1864 if(console_ram_bank > 2) console_ram_bank = 0;
1865 cgram_bank = data & 0x07;
1866 kanji_level2 = ((data & 0x80) == 0) ? false : true;
1868 case 0x2f: // VRAM BANK
1869 vram_bank = data & 0x03;
1870 if(vram_bank > 2) vram_bank = 0;
1880 keyboard->write_data8(0x31, data);
1882 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1884 vram_active_block = data & 0x01;
1885 if(vram_display_block != (((data & 0x10) != 0) ? 1 : 0)) vram_wrote = true;
1886 vram_display_block = ((data & 0x10) != 0) ? 1 : 0;
1891 tmpvar.d = window_xbegin * 8;
1894 tmpvar.b.h = data & 0x03;
1896 tmpvar.b.l = data & 0xf8;
1898 if(mode320 || mode256k) {
1899 if(tmpvar.d > 320) tmpvar.d = 320;
1901 if(tmpvar.d > 640) tmpvar.d = 640;
1903 window_xbegin = tmpvar.d / 8;
1908 tmpvar.d = window_xend * 8;
1911 tmpvar.b.h = data & 0x03;
1913 tmpvar.b.l = data & 0xf8;
1915 if(mode320 || mode256k) {
1916 if(tmpvar.d > 320) tmpvar.d = 320;
1918 if(tmpvar.d > 640) tmpvar.d = 640;
1920 window_xend = tmpvar.d / 8;
1925 tmpvar.d = window_low;
1928 tmpvar.b.h = data & 0x03;
1930 tmpvar.b.l = data & 0xff;
1933 if(tmpvar.d > 400) tmpvar.d = 400;
1936 if(tmpvar.d > 400) tmpvar.d = 400;
1938 window_low = tmpvar.d;
1943 tmpvar.d = window_high;
1946 tmpvar.b.h = data & 0x03;
1948 tmpvar.b.l = data & 0xff;
1951 if(tmpvar.d > 400) tmpvar.d = 400;
1954 if(tmpvar.d > 400) tmpvar.d = 400;
1956 window_high = tmpvar.d;
1962 #if defined(_FM77AV_VARIANTS)
1964 if((addr >= 0x13) && (addr <= 0x1a)) {
1965 alu_write_cmpdata_reg(addr - 0x13, data);
1966 } else if((addr >= 0x1c) && (addr <= 0x1e)) {
1967 alu_write_tilepaint_data(addr, data);
1968 } else if((addr >= 0x24) && (addr <= 0x2b)) {
1969 alu_write_line_position(addr - 0x24, data);
1976 void DISPLAY::write_data8_main(uint32 addr, uint8 data)
1980 uint32 page_offset = 0x0000;
1982 if(addr < 0xc000) return;
1985 raddr = addr - 0xc000;
1986 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1988 if(console_ram_bank >= 1) {
1989 submem_console_av40[((console_ram_bank - 1) << 12) + raddr] = data;
1994 console_ram[raddr] = data;
1996 } else if(addr < 0xd380) {
1997 raddr = addr - 0xd000;
1998 work_ram[raddr] = data;
2000 } else if(addr < 0xd400) {
2001 raddr = addr - 0xd380;
2002 shared_ram[raddr] = data;
2004 } else if(addr < 0xd800) {
2005 #if defined(_FM77AV_VARIANTS)
2006 if(addr >= 0xd500) {
2007 submem_hidden[addr - 0xd500] = data;
2011 write_mmio(addr, data);
2013 } else if(addr < 0x10000) {
2014 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2015 if(ram_protect) return;
2018 submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)] = data; //FIXME
2020 subsys_ram[addr - 0xe000] = data;
2028 void DISPLAY::write_data8(uint32 addr, uint32 data)
2032 uint32 page_offset = 0x0000;
2033 uint8 val8 = data & 0xff;
2035 uint32 color = (addr & 0xc000) >> 14;
2038 #if defined(_FM77AV_VARIANTS)
2040 alu->read_data8(addr + ALU_WRITE_PROXY);
2043 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2044 if(display_mode == DISPLAY_MODE_8_400L) {
2045 color = vram_bank & 0x03;
2046 if(color > 2) color = 0;
2051 if((multimode_accessmask & (1 << color)) != 0) return;
2053 write_vram_data8(addr, val8);
2055 } else if(addr < 0x10000) {
2056 write_data8_main(addr, val8);
2060 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
2061 set_dpalette(addr - FM7_SUBMEM_OFFSET_DPALETTE, val8);
2065 #if defined(_FM77AV_VARIANTS)
2067 else if(addr == FM7_SUBMEM_OFFSET_APALETTE_R) {
2068 set_apalette_r(val8);
2070 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_G) {
2071 set_apalette_g(val8);
2073 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_B) {
2074 set_apalette_b(val8);
2076 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_HI) {
2077 set_apalette_index_hi(val8);
2079 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_LO) {
2080 set_apalette_index_lo(val8);
2084 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
2085 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
2086 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2087 if(display_mode == DISPLAY_MODE_8_400L) {
2088 color = (addr & 0x18000) >> 15;
2089 if(color > 2) color = 0;
2091 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2092 if(vram_active_block != 0) page_offset = 0x18000;
2094 if(color > 2) color = 0;
2095 if (active_page != 0) {
2096 offset = offset_point_bank1 << 1;
2098 offset = offset_point << 1;
2100 pagemod = 0x8000 * color;
2101 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
2102 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2103 vram_wrote_table[((addr + offset) % 0x8000) / 80] = true;
2106 write_vram_data8(addr, data);
2108 write_vram_data8(addr, data);
2110 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2117 uint32 DISPLAY::read_bios(const _TCHAR *name, uint8 *ptr, uint32 size)
2123 if((name == NULL) || (ptr == NULL)) return 0;
2124 s = create_local_path(name);
2125 if(s == NULL) return 0;
2127 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
2128 blocks = fio.Fread(ptr, size, 1);
2131 return blocks * size;
2135 void DISPLAY::initialize()
2139 screen_update_flag = true;
2140 memset(gvram, 0x00, sizeof(gvram));
2141 vram_wrote_shadow = false;
2142 #if defined(_FM77AV_VARIANTS)
2143 memset(gvram_shadow, 0x00, sizeof(gvram_shadow));
2144 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
2145 for(i = 0; i < 411; i++) vram_draw_table[i] = false;
2147 memset(console_ram, 0x00, sizeof(console_ram));
2148 memset(work_ram, 0x00, sizeof(work_ram));
2149 memset(shared_ram, 0x00, sizeof(shared_ram));
2150 memset(subsys_c, 0xff, sizeof(subsys_c));
2152 diag_load_subrom_c = false;
2154 if(read_bios(_T("SUBSYS_8.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2155 emu->out_debug_log(_T("SUBSYSTEM ROM READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2157 if(read_bios(_T("SUBSYS_C.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2158 emu->out_debug_log(_T("SUBSYSTEM ROM Type C READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2160 #if defined(_FM77AV_VARIANTS)
2161 memset(subsys_a, 0xff, sizeof(subsys_a));
2162 memset(subsys_b, 0xff, sizeof(subsys_b));
2163 memset(subsys_cg, 0xff, sizeof(subsys_cg));
2164 memset(submem_hidden, 0x00, sizeof(submem_hidden));
2166 diag_load_subrom_a = false;
2167 if(read_bios(_T("SUBSYS_A.ROM"), subsys_a, 0x2000) >= 0x2000) diag_load_subrom_a = true;
2168 emu->out_debug_log(_T("SUBSYSTEM ROM Type A READING : %s"), diag_load_subrom_a ? "OK" : "NG");
2170 diag_load_subrom_b = false;
2171 if(read_bios(_T("SUBSYS_B.ROM"), subsys_b, 0x2000) >= 0x2000) diag_load_subrom_b = true;
2172 emu->out_debug_log(_T("SUBSYSTEM ROM Type B READING : %s"), diag_load_subrom_b ? "OK" : "NG");
2174 diag_load_subrom_cg = false;
2175 if(read_bios(_T("SUBSYSCG.ROM"), subsys_cg, 0x2000) >= 0x2000) diag_load_subrom_cg = true;
2176 emu->out_debug_log(_T("SUBSYSTEM CG ROM READING : %s"), diag_load_subrom_cg ? "OK" : "NG");
2177 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2178 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2179 memset(subsys_ram, 0x00, sizeof(subsys_ram));
2180 memset(submem_cgram, 0x00, sizeof(submem_cgram));
2181 memset(submem_console_av40, 0x00, sizeof(submem_console_av40));
2185 #if defined(_FM77AV_VARIANTS)
2187 apalette_index.d = 0;
2188 for(i = 0; i < 4096; i++) {
2189 analog_palette_r[i] = i & 0x0f0;
2190 analog_palette_g[i] = i & 0xf00;
2191 analog_palette_b[i] = i & 0x00f;
2195 #if defined(_FM77AV_VARIANTS)
2196 hblank_event_id = -1;
2197 hdisp_event_id = -1;
2198 vsync_event_id = -1;
2199 vstart_event_id = -1;
2206 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
2207 is_cyclesteal = true;
2209 is_cyclesteal = false;
2211 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2215 key_firq_req = false; //firq_mask = true;
2216 frame_skip_count = 3;
2219 void DISPLAY::release()
2223 #define STATE_VERSION 3
2224 void DISPLAY::save_state(FILEIO *state_fio)
2226 state_fio->FputUint32_BE(STATE_VERSION);
2227 state_fio->FputInt32_BE(this_device_id);
2231 state_fio->FputInt32_BE(clr_count);
2232 state_fio->FputBool(halt_flag);
2233 state_fio->FputInt32_BE(active_page);
2234 state_fio->FputBool(sub_busy);
2235 state_fio->FputBool(crt_flag);
2236 state_fio->FputBool(vram_wrote);
2237 state_fio->FputBool(vram_wrote_shadow);
2238 #if defined(_FM77AV_VARIANTS)
2239 for(i = 0; i < 411; i++) state_fio->FputBool(vram_wrote_table[i]);
2240 for(i = 0; i < 411; i++) state_fio->FputBool(vram_draw_table[i]);
2242 state_fio->FputBool(is_cyclesteal);
2244 state_fio->FputBool(clock_fast);
2246 #if defined(_FM77AV_VARIANTS)
2247 state_fio->FputBool(subcpu_resetreq);
2248 state_fio->FputBool(power_on_reset);
2250 state_fio->FputBool(cancel_request);
2251 state_fio->FputBool(key_firq_req);
2253 state_fio->FputInt32_BE(display_mode);
2254 state_fio->FputUint32_BE(prev_clock);
2257 state_fio->Fwrite(dpalette_data, sizeof(dpalette_data), 1);
2258 state_fio->FputUint8(multimode_accessmask);
2259 state_fio->FputUint8(multimode_dispmask);
2261 state_fio->FputUint32_BE(offset_point);
2262 #if defined(_FM77AV_VARIANTS)
2263 state_fio->FputUint32_BE(offset_point_bank1);
2264 state_fio->FputUint32_BE(offset_point_bak);
2265 state_fio->FputUint32_BE(offset_point_bank1_bak);
2267 for(i = 0; i < 2; i++) {
2268 state_fio->FputUint32_BE(tmp_offset_point[i].d);
2269 state_fio->FputBool(offset_changed[i]);
2271 state_fio->FputBool(offset_77av);
2272 state_fio->FputBool(diag_load_subrom_c);
2275 state_fio->Fwrite(io_w_latch, sizeof(io_w_latch), 1);
2276 state_fio->Fwrite(console_ram, sizeof(console_ram), 1);
2277 state_fio->Fwrite(work_ram, sizeof(work_ram), 1);
2278 state_fio->Fwrite(shared_ram, sizeof(shared_ram), 1);
2279 state_fio->Fwrite(subsys_c, sizeof(subsys_c), 1);
2280 state_fio->Fwrite(gvram, sizeof(gvram), 1);
2281 #if defined(_FM77AV_VARIANTS)
2282 state_fio->Fwrite(gvram_shadow, sizeof(gvram_shadow), 1);
2285 #if defined(_FM77_VARIANTS)
2286 state_fio->FputBool(kanjisub);
2287 state_fio->FputUint16_BE(kanjiaddr.w.l);
2288 # if defined(_FM77L4)
2289 state_fio->FputBool(mode400line);
2290 state_fio->FputBool(stat_400linecard);
2292 #elif defined(_FM77AV_VARIANTS)
2293 state_fio->FputBool(kanjisub);
2294 state_fio->FputUint16_BE(kanjiaddr.w.l);
2296 state_fio->FputBool(vblank);
2297 state_fio->FputBool(vsync);
2298 state_fio->FputBool(hblank);
2299 state_fio->FputInt32_BE(vblank_count);
2300 state_fio->FputUint32_BE(displine);
2302 state_fio->FputBool(mode320);
2303 state_fio->FputInt32_BE(display_page);
2304 state_fio->FputInt32_BE(cgrom_bank);
2305 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2306 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2307 state_fio->FputInt32_BE(vram_bank);
2310 state_fio->FputUint8(subrom_bank);
2311 state_fio->FputUint8(subrom_bank_using);
2313 state_fio->FputBool(nmi_enable);
2314 state_fio->FputBool(use_alu);
2316 state_fio->FputUint8(apalette_index.b.l);
2317 state_fio->FputUint8(apalette_index.b.h);
2318 state_fio->Fwrite(analog_palette_r, sizeof(analog_palette_r), 1);
2319 state_fio->Fwrite(analog_palette_g, sizeof(analog_palette_g), 1);
2320 state_fio->Fwrite(analog_palette_b, sizeof(analog_palette_b), 1);
2323 state_fio->FputBool(diag_load_subrom_a);
2324 state_fio->FputBool(diag_load_subrom_b);
2325 state_fio->FputBool(diag_load_subrom_cg);
2327 state_fio->Fwrite(subsys_a, sizeof(subsys_a), 1);
2328 state_fio->Fwrite(subsys_b, sizeof(subsys_b), 1);
2329 state_fio->Fwrite(subsys_cg, sizeof(subsys_cg), 1);
2330 state_fio->Fwrite(submem_hidden, sizeof(submem_hidden), 1);
2331 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2332 state_fio->FputBool(mode400line);
2333 state_fio->FputBool(mode256k);
2335 state_fio->FputBool(monitor_ram);
2336 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2337 state_fio->FputUint16_BE(window_low);
2338 state_fio->FputUint16_BE(window_high);
2339 state_fio->FputUint16_BE(window_xbegin);
2340 state_fio->FputUint16_BE(window_xend);
2341 state_fio->FputBool(window_opened);
2343 state_fio->FputBool(kanji_level2);
2345 state_fio->FputUint8(vram_active_block);
2346 state_fio->FputUint8(vram_display_block);
2347 state_fio->FputUint8(console_ram_bank);
2348 state_fio->FputBool(ram_protect);
2350 state_fio->FputUint32_BE(cgram_bank);
2351 state_fio->Fwrite(subsys_ram, sizeof(subsys_ram), 1);
2352 state_fio->Fwrite(submem_cgram, sizeof(submem_cgram), 1);
2353 state_fio->Fwrite(submem_console_av40, sizeof(submem_console_av40), 1);
2359 state_fio->FputInt32_BE(nmi_event_id);
2360 #if defined(_FM77AV_VARIANTS)
2361 state_fio->FputInt32_BE(hblank_event_id);
2362 state_fio->FputInt32_BE(hdisp_event_id);
2363 state_fio->FputInt32_BE(vsync_event_id);
2364 state_fio->FputInt32_BE(vstart_event_id);
2366 state_fio->FputBool(firq_mask);
2367 state_fio->FputBool(vram_accessflag);
2368 state_fio->FputUint32_BE(frame_skip_count);
2372 bool DISPLAY::load_state(FILEIO *state_fio)
2375 uint32 version = state_fio->FgetUint32_BE();
2376 if(this_device_id != state_fio->FgetInt32_BE()) {
2383 clr_count = state_fio->FgetInt32_BE();
2384 halt_flag = state_fio->FgetBool();
2385 active_page = state_fio->FgetInt32_BE();
2386 sub_busy = state_fio->FgetBool();
2387 crt_flag = state_fio->FgetBool();
2388 vram_wrote = state_fio->FgetBool();
2389 crt_flag_bak = true;
2390 screen_update_flag = true;
2391 vram_wrote_shadow = state_fio->FgetBool();
2392 #if defined(_FM77AV_VARIANTS)
2393 for(i = 0; i < 411; i++) vram_wrote_table[i] = state_fio->FgetBool();
2394 for(i = 0; i < 411; i++) vram_draw_table[i] = state_fio->FgetBool();
2396 is_cyclesteal = state_fio->FgetBool();
2398 clock_fast = state_fio->FgetBool();
2400 #if defined(_FM77AV_VARIANTS)
2401 subcpu_resetreq = state_fio->FgetBool();
2402 power_on_reset = state_fio->FgetBool();
2404 cancel_request = state_fio->FgetBool();
2405 key_firq_req = state_fio->FgetBool();
2407 display_mode = state_fio->FgetInt32_BE();
2408 prev_clock = state_fio->FgetUint32_BE();
2411 for(addr = 0; addr < 8; addr++) set_dpalette(addr, addr);
2413 state_fio->Fread(dpalette_data, sizeof(dpalette_data), 1);
2414 for(addr = 0; addr < 8; addr++) set_dpalette(addr, dpalette_data[addr]);
2415 multimode_accessmask = state_fio->FgetUint8();
2416 multimode_dispmask = state_fio->FgetUint8();
2418 offset_point = state_fio->FgetUint32_BE();
2419 #if defined(_FM77AV_VARIANTS)
2420 offset_point_bank1 = state_fio->FgetUint32_BE();
2421 offset_point_bak = state_fio->FgetUint32_BE();
2422 offset_point_bank1_bak = state_fio->FgetUint32_BE();
2424 for(i = 0; i < 2; i++) {
2425 tmp_offset_point[i].d = state_fio->FgetUint32_BE();
2426 offset_changed[i] = state_fio->FgetBool();
2428 offset_77av = state_fio->FgetBool();
2429 diag_load_subrom_c = state_fio->FgetBool();
2431 state_fio->Fread(io_w_latch, sizeof(io_w_latch), 1);
2432 state_fio->Fread(console_ram, sizeof(console_ram), 1);
2433 state_fio->Fread(work_ram, sizeof(work_ram), 1);
2434 state_fio->Fread(shared_ram, sizeof(shared_ram), 1);
2435 state_fio->Fread(subsys_c, sizeof(subsys_c), 1);
2436 state_fio->Fread(gvram, sizeof(gvram), 1);
2437 #if defined(_FM77AV_VARIANTS)
2438 state_fio->Fread(gvram_shadow, sizeof(gvram_shadow), 1);
2440 #if defined(_FM77_VARIANTS)
2441 kanjisub = state_fio->FgetBool();
2443 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2444 # if defined(_FM77L4)
2445 mode400line = state_fio->FgetBool();
2446 stat_400linecard = state_fio->FgetBool();
2448 #elif defined(_FM77AV_VARIANTS)
2449 kanjisub = state_fio->FgetBool();
2451 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2453 vblank = state_fio->FgetBool();
2454 vsync = state_fio->FgetBool();
2455 hblank = state_fio->FgetBool();
2456 vblank_count = state_fio->FgetInt32_BE();
2457 displine = state_fio->FgetUint32_BE();
2459 mode320 = state_fio->FgetBool();
2460 display_page = state_fio->FgetInt32_BE();
2461 cgrom_bank = state_fio->FgetInt32_BE();
2462 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2463 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2464 vram_bank = state_fio->FgetInt32_BE();
2467 subrom_bank = state_fio->FgetUint8();
2468 subrom_bank_using = state_fio->FgetUint8();
2470 nmi_enable = state_fio->FgetBool();
2471 use_alu = state_fio->FgetBool();
2473 apalette_index.b.l = state_fio->FgetUint8();
2474 apalette_index.b.h = state_fio->FgetUint8();
2476 state_fio->Fread(analog_palette_r, sizeof(analog_palette_r), 1);
2477 state_fio->Fread(analog_palette_g, sizeof(analog_palette_g), 1);
2478 state_fio->Fread(analog_palette_b, sizeof(analog_palette_b), 1);
2479 for(i = 0; i < 4096; i++) calc_apalette(i);
2481 diag_load_subrom_a = state_fio->FgetBool();
2482 diag_load_subrom_b = state_fio->FgetBool();
2483 diag_load_subrom_cg = state_fio->FgetBool();
2485 state_fio->Fread(subsys_a, sizeof(subsys_a), 1);
2486 state_fio->Fread(subsys_b, sizeof(subsys_b), 1);
2487 state_fio->Fread(subsys_cg, sizeof(subsys_cg), 1);
2488 state_fio->Fread(submem_hidden, sizeof(submem_hidden), 1);
2490 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2491 mode400line = state_fio->FgetBool();
2492 mode256k = state_fio->FgetBool();
2494 monitor_ram = state_fio->FgetBool();
2495 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2496 window_low = state_fio->FgetUint16_BE();
2497 window_high = state_fio->FgetUint16_BE();
2498 window_xbegin = state_fio->FgetUint16_BE();
2499 window_xend = state_fio->FgetUint16_BE();
2500 window_opened = state_fio->FgetBool();
2502 kanji_level2 = state_fio->FgetBool();
2504 vram_active_block = state_fio->FgetUint8();
2505 vram_display_block = state_fio->FgetUint8();
2506 console_ram_bank = state_fio->FgetUint8();
2507 ram_protect = state_fio->FgetBool();
2509 cgram_bank = state_fio->FgetUint32_BE();
2510 state_fio->Fread(subsys_ram, sizeof(subsys_ram), 1);
2511 state_fio->Fread(submem_cgram, sizeof(submem_cgram), 1);
2512 state_fio->Fread(submem_console_av40, sizeof(submem_console_av40), 1);
2515 bool vram_wrote_shadow_bak = vram_wrote_shadow;
2516 vram_wrote_shadow = true; // Force Draw
2517 this->draw_screen();
2518 vram_wrote_shadow = vram_wrote_shadow_bak;
2519 if(version == 1) return true;
2521 if(version >= 2) { //V2
2522 nmi_event_id = state_fio->FgetInt32_BE();
2523 #if defined(_FM77AV_VARIANTS)
2524 hblank_event_id = state_fio->FgetInt32_BE();
2525 hdisp_event_id = state_fio->FgetInt32_BE();
2526 vsync_event_id = state_fio->FgetInt32_BE();
2527 vstart_event_id = state_fio->FgetInt32_BE();
2529 firq_mask = state_fio->FgetBool();
2530 vram_accessflag = state_fio->FgetBool();
2531 frame_skip_count = state_fio->FgetUint32_BE();
2533 if(version == 3) return true;