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;
137 frame_skip_count = 3;
141 void DISPLAY::reset()
145 memset(io_w_latch, 0xff, sizeof(io_w_latch));
147 vram_accessflag = true;
148 display_mode = DISPLAY_MODE_8_200L;
150 screen_update_flag = true;
153 cancel_request = false;
154 #if defined(_FM77AV_VARIANTS)
156 apalette_index.d = 0;
157 for(i = 0; i < 4096; i++) {
158 analog_palette_r[i] = i & 0x0f0;
159 analog_palette_g[i] = i & 0xf00;
160 analog_palette_b[i] = i & 0x00f;
165 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
172 #elif defined(_FM77L4)
175 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
176 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
177 key_firq_req = false; //firq_mask = true;
181 #if defined(_FM77AV_VARIANTS)
182 power_on_reset = false;
183 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
187 for(i = 0; i < 8; i++) set_dpalette(i, i);
188 multimode_accessmask = 0x00;
189 multimode_dispmask = 0x00;
194 if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
195 register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
196 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
200 void DISPLAY::update_config()
204 //is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
210 * Vram accessing functions moved to vram.cpp .
213 void DISPLAY::do_irq(bool flag)
215 subcpu->write_signal(SIG_CPU_IRQ, flag ? 1: 0, 1);
218 void DISPLAY::do_firq(bool flag)
220 subcpu->write_signal(SIG_CPU_FIRQ, flag ? 1: 0, 1);
223 void DISPLAY::do_nmi(bool flag)
225 #if defined(_FM77AV_VARIANTS)
226 if(!nmi_enable) flag = false;
228 subcpu->write_signal(SIG_CPU_NMI, flag ? 1 : 0, 1);
231 void DISPLAY::set_multimode(uint8_t val)
234 multimode_accessmask = val & 0x07;
235 multimode_dispmask = (val & 0x70) >> 4;
237 # if defined(_FM77AV_VARIANTS)
238 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
243 uint8_t DISPLAY::get_multimode(void)
249 val = multimode_accessmask & 0x07;
250 val |= ((multimode_dispmask << 4) & 0x70);
256 uint8_t DISPLAY::get_cpuaccessmask(void)
258 return multimode_accessmask & 0x07;
261 void DISPLAY::set_dpalette(uint32_t addr, uint8_t val)
265 dpalette_data[addr] = val | 0xf8; //0b11111000;
267 b = ((val & 0x01) != 0x00)? 255 : 0x00;
268 r = ((val & 0x02) != 0x00)? 255 : 0x00;
269 g = ((val & 0x04) != 0x00)? 255 : 0x00;
271 dpalette_pixel[addr] = RGB_COLOR(r, g, b);
274 uint8_t DISPLAY::get_dpalette(uint32_t addr)
282 data = dpalette_data[addr];
287 void DISPLAY::halt_subcpu(void)
289 subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
292 void DISPLAY::go_subcpu(void)
294 subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
297 void DISPLAY::enter_display(void)
301 subclock = SUBCLOCK_NORMAL;
303 subclock = SUBCLOCK_SLOW;
305 if(!is_cyclesteal && vram_accessflag) {
306 subclock = subclock / 3;
308 if(prev_clock != subclock) p_vm->set_cpu_clock(subcpu, subclock);
309 prev_clock = subclock;
312 void DISPLAY::leave_display(void)
316 void DISPLAY::halt_subsystem(void)
322 void DISPLAY::restart_subsystem(void)
325 #if defined(_FM77AV_VARIANTS)
326 if(subcpu_resetreq) {
327 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
329 power_on_reset = true;
330 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
332 do_firq(!firq_mask && key_firq_req);
339 void DISPLAY::set_crtflag(void)
346 void DISPLAY::reset_crtflag(void)
353 uint8_t DISPLAY::acknowledge_irq(void)
355 cancel_request = false;
361 uint8_t DISPLAY::beep(void)
363 mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
364 return 0xff; // True?
369 uint8_t DISPLAY::attention_irq(void)
371 mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
376 void DISPLAY::set_cyclesteal(uint8_t val)
381 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
383 is_cyclesteal = true;
385 is_cyclesteal = false;
393 uint8_t DISPLAY::set_vramaccess(void)
395 vram_accessflag = true;
400 void DISPLAY::reset_vramaccess(void)
402 vram_accessflag = false;
406 uint8_t DISPLAY::reset_subbusy(void)
413 void DISPLAY::set_subbusy(void)
419 #if defined(_FM77AV_VARIANTS)
421 void DISPLAY::alu_write_cmdreg(uint32_t val)
423 alu->write_data8(ALU_CMDREG, val);
424 if((val & 0x80) != 0) {
432 void DISPLAY::alu_write_logical_color(uint8_t val)
434 uint32_t data = (uint32_t)val;
435 alu->write_data8(ALU_LOGICAL_COLOR, data);
439 void DISPLAY::alu_write_mask_reg(uint8_t val)
441 uint32_t data = (uint32_t)val;
442 alu->write_data8(ALU_WRITE_MASKREG, data);
446 void DISPLAY::alu_write_cmpdata_reg(int addr, uint8_t val)
448 uint32_t data = (uint32_t)val;
450 alu->write_data8(ALU_CMPDATA_REG + addr, data);
454 void DISPLAY::alu_write_disable_reg(uint8_t val)
456 uint32_t data = (uint32_t)val;
457 alu->write_data8(ALU_BANK_DISABLE, data);
461 void DISPLAY::alu_write_tilepaint_data(uint32_t addr, uint8_t val)
463 uint32_t data = (uint32_t)val;
466 alu->write_data8(ALU_TILEPAINT_B, data);
469 alu->write_data8(ALU_TILEPAINT_R, data);
472 alu->write_data8(ALU_TILEPAINT_G, data);
475 //alu->write_data8(ALU_TILEPAINT_L, 0xff);
481 void DISPLAY::alu_write_offsetreg_hi(uint8_t val)
483 alu->write_data8(ALU_OFFSET_REG_HIGH, val & 0x7f);
487 void DISPLAY::alu_write_offsetreg_lo(uint8_t val)
489 alu->write_data8(ALU_OFFSET_REG_LO, val);
493 void DISPLAY::alu_write_linepattern_hi(uint8_t val)
495 alu->write_data8(ALU_LINEPATTERN_REG_HIGH, val);
499 void DISPLAY::alu_write_linepattern_lo(uint8_t val)
501 alu->write_data8(ALU_LINEPATTERN_REG_LO, val);
505 void DISPLAY::alu_write_line_position(int addr, uint8_t val)
507 uint32_t data = (uint32_t)val;
510 alu->write_data8(ALU_LINEPOS_START_X_HIGH, data & 0x03);
513 alu->write_data8(ALU_LINEPOS_START_X_LOW, data);
516 alu->write_data8(ALU_LINEPOS_START_Y_HIGH, data & 0x01);
519 alu->write_data8(ALU_LINEPOS_START_Y_LOW, data);
522 alu->write_data8(ALU_LINEPOS_END_X_HIGH, data & 0x03);
525 alu->write_data8(ALU_LINEPOS_END_X_LOW, data);
528 alu->write_data8(ALU_LINEPOS_END_Y_HIGH, data & 0x01);
531 alu->write_data8(ALU_LINEPOS_END_Y_LOW, data);
537 uint8_t DISPLAY::get_miscreg(void)
542 if(!hblank) ret |= 0x80;
543 if(vsync) ret |= 0x04;
544 if(alu->read_signal(SIG_ALU_BUSYSTAT) == 0) ret |= 0x10;
545 if(power_on_reset) ret |= 0x01;
550 void DISPLAY::set_miscreg(uint8_t val)
552 int old_display_page = display_page;
554 nmi_enable = ((val & 0x80) == 0) ? true : false;
555 if(!nmi_enable) do_nmi(false);
557 if((val & 0x40) == 0) {
562 if(display_page != old_display_page) {
565 active_page = ((val & 0x20) == 0) ? 0 : 1;
566 if((val & 0x04) == 0) {
571 cgrom_bank = val & 0x03;
575 void DISPLAY::set_monitor_bank(uint8_t var)
577 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
578 if((var & 0x04) != 0){
584 subrom_bank = var & 0x03;
587 subcpu_resetreq = false;
588 power_on_reset = true;
589 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
591 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
593 do_firq(!firq_mask && key_firq_req);
595 subcpu_resetreq = true;
601 void DISPLAY::set_apalette_index_hi(uint8_t val)
603 apalette_index.b.h = val & 0x0f;
607 void DISPLAY::set_apalette_index_lo(uint8_t val)
609 apalette_index.b.l = val;
612 void DISPLAY::calc_apalette(uint16_t idx)
616 g = analog_palette_g[idx];
617 r = analog_palette_r[idx];
618 b = analog_palette_b[idx];
619 analog_palette_pixel[idx] = RGB_COLOR(r, g, b);
623 void DISPLAY::set_apalette_b(uint8_t val)
627 index = apalette_index.w.l;
628 tmp = (val & 0x0f) << 4;
629 if(analog_palette_b[index] != tmp) {
630 analog_palette_b[index] = tmp;
631 calc_apalette(index);
637 void DISPLAY::set_apalette_r(uint8_t val)
641 index = apalette_index.w.l;
642 tmp = (val & 0x0f) << 4;
643 if(analog_palette_r[index] != tmp) {
644 analog_palette_r[index] = tmp;
645 calc_apalette(index);
651 void DISPLAY::set_apalette_g(uint8_t val)
655 index = apalette_index.w.l;
656 tmp = (val & 0x0f) << 4;
657 if(analog_palette_g[index] != tmp) {
658 analog_palette_g[index] = tmp;
659 calc_apalette(index);
664 #endif // _FM77AV_VARIANTS
667 // Timing values from XM7 . Thanks Ryu.
668 void DISPLAY::event_callback(int event_id, int err)
673 case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
674 #if defined(_FM77AV_VARIANTS)
684 case EVENT_FM7SUB_DISPLAY_NMI_OFF: // per 20.00ms
687 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
688 case EVENT_FM7SUB_HDISP:
691 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x02, 0xff);
692 //if(displine == 0) enter_display();
693 if(display_mode == DISPLAY_MODE_8_400L) {
695 if(displine < 400) f = true;
698 if(displine < 200) f = true;
701 register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
708 case EVENT_FM7SUB_HBLANK:
710 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
712 if(display_mode == DISPLAY_MODE_8_400L) {
713 if(displine < 400) f = true;
715 if(displine < 200) f = true;
718 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
719 if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)){
720 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
722 # elif defined(_FM77AV40)
727 if(vram_wrote_table[displine] || vram_wrote) {
728 uint32_t baseaddr1 = ((displine) * 40) & 0x1fff;
729 uint32_t baseaddr2 = baseaddr1 + 0xc000;
730 vram_wrote_table[displine] = false;
731 for(int i = 0; i < planes; i++) {
732 for(int j = 0; j < 6; j++) {
733 memcpy(&gvram_shadow[j * 0x2000 + baseaddr1],
734 &gvram[j * 0x2000 + baseaddr1], 40);
735 memcpy(&gvram_shadow[j * 0x2000 + baseaddr2],
736 &gvram[j * 0x2000 + baseaddr2], 40);
738 baseaddr1 += 0x18000;
739 baseaddr2 += 0x18000;
741 # if defined(_FM77AV40)
742 for(int j = 0; j < 6; j++) {
743 memcpy(&gvram_shadow[j * 0x2000 + baseaddr1],
744 &gvram[j * 0x2000 + baseaddr1], 40);
747 //screen_update_flag = true;
748 vram_draw_table[displine] = true;
750 } else if(display_mode == DISPLAY_MODE_8_400L) {
751 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
753 # elif defined(_FM77AV40)
758 if(vram_wrote_table[displine] || vram_wrote) {
759 uint32_t baseaddr1 = ((displine) * 80) & 0x7fff;
760 vram_wrote_table[displine] = false;
761 for(int i = 0; i < planes; i++) {
762 for(int j = 0; j < 3; j++) {
763 memcpy(&gvram_shadow[j * 0x8000 + baseaddr1],
764 &gvram[j * 0x8000 + baseaddr1], 80);
766 baseaddr1 += 0x18000;
769 # if defined(_FM77AV40)
770 for(int j = 0; j < 3; j++) {
771 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
772 &gvram[j * 0x4000 + baseaddr1], 80);
775 //screen_update_flag = true;
776 vram_draw_table[displine] = true;
779 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
781 # elif defined(_FM77AV40)
786 if(vram_wrote_table[displine] || vram_wrote) {
787 uint32_t baseaddr1 = ((displine) * 80) & 0x3fff;
788 uint32_t baseaddr2 = baseaddr1 + 0xc000;
789 for(int i = 0; i < planes; i++) {
790 vram_wrote_table[displine] = false;
791 for(int j = 0; j < 3; j++) {
792 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
793 &gvram[j * 0x4000 + baseaddr1], 80);
794 memcpy(&gvram_shadow[j * 0x4000 + baseaddr2],
795 &gvram[j * 0x4000 + baseaddr2], 80);
797 baseaddr1 += 0x18000;
798 baseaddr2 += 0x18000;
800 # if defined(_FM77AV40)
801 for(int j = 0; j < 3; j++) {
802 memcpy(&gvram_shadow[j * 0x4000 + baseaddr1],
803 &gvram[j * 0x4000 + baseaddr1], 80);
806 //screen_update_flag = true;
807 vram_draw_table[displine] = true;
811 if(display_mode == DISPLAY_MODE_8_400L) {
816 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id);
819 //vram_wrote_shadow = true;
822 case EVENT_FM7SUB_VSTART: // Call first.
827 // Parameter from XM7/VM/display.c , thanks, Ryu.
828 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
829 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x00, 0xff);
830 if(vblank_count != 0) {
831 if(display_mode == DISPLAY_MODE_8_400L) {
832 usec = (0.98 + 16.4) * 1000.0;
834 usec = (1.91 + 12.7) * 1000.0;
836 register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id);
838 if(display_mode == DISPLAY_MODE_8_400L) {
839 usec = 930.0; // 939.0
841 usec = 1840.0; // 1846.5
843 //offset_point_bank1_bak = offset_point_bank1;
844 //offset_point_bak = offset_point;
845 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
848 if(display_mode == DISPLAY_MODE_8_400L) {
849 usec = 0.34 * 1000.0;
851 usec = 1.52 * 1000.0;
853 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
856 if(vram_wrote && ((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0)) {
857 //for(int i = 0; i < 411; i++) vram_wrote_table[i] = false;
858 memcpy(gvram_shadow, gvram, sizeof(gvram_shadow));
859 //vram_wrote_shadow = true;
860 //for(int i = 0; i < 411; i++) vram_draw_table[i] = true;
861 } else if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
862 if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)){
865 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
867 # elif defined(_FM77AV40)
874 for(int j = 200; j < 206; j++) {
875 if(vram_wrote_table[j]) {
878 vram_wrote_table[j] = false;
882 for(int j = 200; j < 205; j++) {
883 vram_draw_table[(((j * 40) + offset_point_bak) & 0x1fff) / 40] = true;
884 vram_draw_table[(((j * 40) + offset_point_bank1_bak) & 0x1fff) / 40] = true;
886 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x2000 + 200 * 40],
887 &gvram[i * 0x2000 + 200 * 40], 0x2000 - 200 * 40);
889 } else if(display_mode == DISPLAY_MODE_8_400L) {
892 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
894 # elif defined(_FM77AV40)
901 for(int j = 400; j < 411; j++) {
902 if(vram_wrote_table[j]) {
905 vram_wrote_table[j] = false;
909 for(int j = 400; j < 410; j++) {
910 vram_draw_table[(((j * 80) + offset_point_bak) & 0x7fff) / 80] = true;
911 vram_draw_table[(((j * 80) + offset_point_bank1_bak) & 0x7fff) / 80] = true;
913 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x8000 + 400 * 80],
914 &gvram[i * 0x8000 + 400 * 80], 0x8000 - 400 * 80);
915 //screen_update_flag = true;
920 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
922 # elif defined(_FM77AV40)
929 for(int j = 200; j < 206; j++) {
930 if(vram_wrote_table[j]) {
933 vram_wrote_table[j] = false;
937 for(int j = 200; j < 205; j++) {
938 vram_draw_table[(((j * 80) + offset_point_bak) & 0x3fff) / 80] = true;
939 vram_draw_table[(((j * 80) + offset_point_bank1_bak) & 0x3fff) / 80] = true;
941 for(int i = 0; i < planes; i++) memcpy(&gvram_shadow[i * 0x4000 + 200 * 80],
942 &gvram[i * 0x4000 + 200 * 80], 0x4000 - 200 * 80);
943 //screen_update_flag = true;
948 vram_wrote_shadow = true;
949 screen_update_flag = true;
952 if(display_mode == DISPLAY_MODE_8_400L) {
953 for(int yy = 0; yy < 411; yy++) {
954 if(vram_draw_table[yy]) fy = true;
955 vram_draw_table[yy] = false;
958 for(int yy = 0; yy < 205; yy++) {
959 if(vram_draw_table[yy]) fy = true;
960 vram_draw_table[yy] = false;
963 vram_wrote_shadow |= fy;
964 screen_update_flag |= fy;
968 case EVENT_FM7SUB_VSYNC:
973 if(display_mode == DISPLAY_MODE_8_400L) {
974 usec = 0.33 * 1000.0;
976 usec = 0.51 * 1000.0;
978 offset_point_bank1_bak = offset_point_bank1;
979 offset_point_bak = offset_point;
980 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x01, 0xff);
981 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
984 case EVENT_FM7SUB_CLR_BUSY:
987 case EVENT_FM7SUB_CLR_CRTFLAG:
993 void DISPLAY::event_frame()
995 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
997 screen_update_flag = true;
998 vram_wrote_shadow = true;
1005 void DISPLAY::event_vline(int v, int clock)
1010 uint32_t DISPLAY::read_signal(int id)
1012 uint32_t retval = 0;
1014 case SIG_FM7_SUB_HALT:
1015 case SIG_DISPLAY_HALT:
1016 retval = (halt_flag) ? 0xffffffff : 0;
1018 case SIG_DISPLAY_BUSY:
1019 retval = (sub_busy) ? 0x80 : 0;
1021 case SIG_DISPLAY_MULTIPAGE:
1022 retval = multimode_accessmask;
1024 case SIG_DISPLAY_PLANES:
1027 #if defined(_FM77AV_VARIANTS)
1028 case SIG_DISPLAY_VSYNC:
1029 retval = (vsync) ? 0x01 : 0x00;
1031 case SIG_DISPLAY_DISPLAY:
1032 retval = (!hblank) ? 0x02: 0x00;
1034 case SIG_FM7_SUB_BANK: // Main: FD13
1035 retval = subrom_bank & 0x03;
1036 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1037 if(monitor_ram) retval |= 0x04;
1041 #if defined(_FM77AV_VARIANTS)
1042 case SIG_DISPLAY_MODE320:
1043 retval = (mode320) ? 0x40: 0x00;
1046 case SIG_DISPLAY_Y_HEIGHT:
1047 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1048 retval = (mode400line) ? 400 : 200;
1053 case SIG_DISPLAY_X_WIDTH:
1054 #if defined(_FM77AV_VARIANTS)
1055 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1056 retval = (mode320 || mode256k) ? 40 : 80;
1058 retval = (mode320) ? 40 : 80;
1070 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
1072 bool flag = ((data & mask) != 0);
1075 case SIG_FM7_SUB_HALT:
1080 //mainio->write_signal(SIG_FM7_SUB_HALT, data, mask);
1082 case SIG_DISPLAY_HALT:
1086 restart_subsystem();
1089 case SIG_FM7_SUB_CANCEL:
1091 cancel_request = true;
1095 case SIG_DISPLAY_CLOCK:
1099 #if defined(_FM77AV_VARIANTS)
1100 case SIG_FM7_SUB_BANK: // Main: FD13
1101 set_monitor_bank(data & 0xff);
1104 case SIG_DISPLAY_EXTRA_MODE: // FD04 bit 4, 3
1105 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1107 int oldmode = display_mode;
1109 kanjisub = ((data & 0x20) == 0) ? true : false;
1110 mode256k = ((data & 0x10) != 0) ? true : false;
1111 mode400line = ((data & 0x08) != 0) ? false : true;
1112 ram_protect = ((data & 0x04) != 0) ? false : true;
1114 display_mode = DISPLAY_MODE_8_400L;
1115 } else if(mode256k) {
1116 display_mode = DISPLAY_MODE_256k;
1118 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1120 if(oldmode != display_mode) {
1123 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1124 for(y = 0; y < 400; y++) {
1125 pp = emu->get_screen_buffer(y);
1126 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1128 } else if(mode320 || mode256k) {
1129 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1130 for(y = 0; y < 200; y++) {
1131 pp = emu->get_screen_buffer(y);
1132 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype_t));
1135 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1136 for(y = 0; y < 200; y++) {
1137 pp = emu->get_screen_buffer(y);
1138 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1142 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
1143 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400 : 200, 0xffff);
1144 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff);
1145 frame_skip_count = 3;
1148 #elif defined(_FM77_VARIANTS)
1150 int oldmode = display_mode;
1151 kanjisub = ((data & 0x20) == 0) ? true : false;
1152 # if defined(_FM77L4)
1153 stat_400linecard = ((data & 0x20) != 0) ? true : false;
1154 mode400line = ((data & 0x08) != 0) ? false : true;
1155 if(mode400line && stat_400linecard) {
1156 display_mode = DISPLAY_MODE_8_400L_TEXT;
1157 } else if(stat_400linecard) {
1158 display_mode = DISPLAY_MODE_8_200L_TEXT;
1160 display_mode = DISPLAY_MODE_8_200L;
1166 #if defined(_FM77AV_VARIANTS)
1167 case SIG_DISPLAY_MODE320: // FD12 bit 6
1168 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1170 int oldmode = display_mode;
1172 if((!mode400line) && (!mode256k)){
1173 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1175 if(oldmode != display_mode) {
1178 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1179 for(y = 0; y < 400; y++) {
1180 pp = emu->get_screen_buffer(y);
1181 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1183 } else if(mode320 || mode256k) {
1184 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1185 for(y = 0; y < 200; y++) {
1186 pp = emu->get_screen_buffer(y);
1187 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype_t));
1190 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1191 for(y = 0; y < 200; y++) {
1192 pp = emu->get_screen_buffer(y);
1193 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1197 alu->write_signal(SIG_ALU_X_WIDTH, ((mode320 || mode256k) && !(mode400line)) ? 40 : 80, 0xffff);
1198 alu->write_signal(SIG_ALU_Y_HEIGHT, (mode400line) ? 400 : 200, 0xffff);
1199 alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff);
1200 frame_skip_count = 3;
1208 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1209 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 320 * sizeof(scrntype_t));
1211 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1212 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 640 * sizeof(scrntype_t));
1215 display_mode = (mode320 == true) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1216 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1217 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1218 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
1223 case SIG_DISPLAY_MULTIPAGE:
1224 set_multimode(data);
1226 case SIG_FM7_SUB_KEY_MASK:
1227 if(firq_mask == flag) {
1228 do_firq(!flag && key_firq_req);
1232 case SIG_FM7_SUB_KEY_FIRQ:
1233 do_firq(flag & !(firq_mask));
1234 key_firq_req = flag;
1236 case SIG_FM7_SUB_USE_CLR:
1238 clr_count = data & 0x03;
1249 * Vram accessing functions moved to vram.cpp .
1252 uint8_t DISPLAY::read_mmio(uint32_t addr)
1254 uint32_t retval = 0xff;
1256 if(addr < 0xd400) return 0xff;
1258 #if !defined(_FM77AV_VARIANTS)
1259 raddr = (addr - 0xd400) & 0x000f;
1260 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1261 raddr = (addr - 0xd400) & 0x003f;
1262 #else // FM77AV40EX || FM77AV40SX
1263 raddr = (addr - 0xd400) & 0x00ff;
1266 case 0x00: // Read keyboard
1267 retval = (keyboard->read_data8(0x00) != 0) ? 0xff : 0x7f;
1269 case 0x01: // Read keyboard
1270 retval = keyboard->read_data8(0x01) & 0xff;
1272 case 0x02: // Acknowledge
1281 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1282 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1284 if(!kanjisub) return 0xff;
1285 # if !defined(_FM77_VARIANTS)
1287 return (uint8_t)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1290 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1293 if(!kanjisub) return 0xff;
1294 # if !defined(_FM77_VARIANTS)
1296 return (uint8_t)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1299 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1306 retval = set_vramaccess();
1312 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x01, 0x01);
1314 #if defined(_FM77AV_VARIANTS)
1317 retval = alu->read_data8(ALU_CMDREG);
1320 retval = alu->read_data8(ALU_LOGICAL_COLOR);
1323 retval = alu->read_data8(ALU_WRITE_MASKREG);
1326 retval = alu->read_data8(ALU_CMP_STATUS_REG);
1329 retval = alu->read_data8(ALU_BANK_DISABLE);
1331 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1332 case 0x2f: // VRAM BANK
1333 retval = 0xfc | (vram_bank & 0x03);
1338 retval = get_miscreg();
1342 retval = keyboard->read_data8(0x31);
1345 retval = keyboard->read_data8(0x32);
1351 return (uint8_t)retval;
1354 uint32_t DISPLAY::read_vram_data8(uint32_t addr)
1357 uint32_t page_offset = 0;
1358 uint32_t page_mask = 0x3fff;
1359 uint32_t color = (addr >> 14) & 0x03;
1362 #if defined(_FM77AV_VARIANTS)
1363 if (active_page != 0) {
1364 offset = offset_point_bank1;
1366 offset = offset_point;
1369 offset = offset_point;
1372 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1373 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1374 if(vram_active_block != 0) page_offset = 0x18000;
1376 if(display_mode == DISPLAY_MODE_8_400L) {
1377 if(addr >= 0x8000) return 0xff;
1378 color = vram_bank & 0x03;
1379 if(color > 2) color = 0;
1381 pagemod = 0x8000 * color;
1382 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1385 #if defined(_FM77AV40)
1387 page_offset = 0xc000 * (vram_bank & 0x03);
1389 page_offset = 0; // right?
1392 page_offset = 0xc000 * (vram_bank & 0x03);
1395 pagemod = addr & 0xe000;
1399 pagemod = addr & 0xe000;
1401 pagemod = addr & 0xc000;
1403 if(active_page != 0) {
1404 page_offset += 0xc000;
1407 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1409 #elif defined(_FM77AV_VARIANTS)
1411 if(active_page != 0) {
1412 page_offset += 0xc000;
1416 pagemod = addr & 0xe000;
1418 pagemod = addr & 0xc000;
1420 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1422 #elif defined(_FM77L4) //_FM77L4
1424 if(display_mode == DISPLAY_MODE_8_400L) {
1425 return (uint32_t)read_vram_l4_400l(addr, offset);
1427 pagemod = addr & 0xc000;
1428 return gvram[((addr + offset) & 0x3fff) | pagemod];
1432 #else // Others (77/7/8)
1433 pagemod = addr & 0xc000;
1434 return gvram[((addr + offset) & 0x3fff) | pagemod];
1438 void DISPLAY::write_dma_data8(uint32_t addr, uint32_t data)
1440 uint32_t raddr = addr & 0xffff;
1443 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1444 if(display_mode == DISPLAY_MODE_8_400L) {
1445 color = vram_bank & 0x03;
1446 if(color > 2) color = 0;
1448 color = (addr >> 14) & 0x03;
1452 if((multimode_accessmask & (1 << color)) != 0) return;
1454 return write_vram_data8(raddr, (uint8_t)data);
1456 return write_data8_main(raddr, (uint8_t)data);
1461 void DISPLAY::write_vram_data8(uint32_t addr, uint8_t data)
1464 uint32_t page_offset = 0;
1465 uint32_t page_mask = 0x3fff;
1466 uint32_t color = (addr >> 14) & 0x03;
1469 #if defined(_FM77AV_VARIANTS)
1470 if (active_page != 0) {
1471 offset = offset_point_bank1;
1473 offset = offset_point;
1476 offset = offset_point;
1479 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1480 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1481 if(vram_active_block != 0) page_offset = 0x18000;
1483 if(display_mode == DISPLAY_MODE_8_400L) {
1484 if(addr >= 0x8000) {
1487 color = vram_bank & 0x03;
1488 if(color > 2) color = 0;
1490 pagemod = 0x8000 * color;
1491 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
1492 vram_wrote_table[((addr + offset) % 0x8000) / 80] = true;
1493 } else if(display_mode == DISPLAY_MODE_256k) {
1494 #if defined(_FM77AV40)
1496 page_offset = 0xc000 * (vram_bank & 0x03);
1498 page_offset = 0; // right?
1501 page_offset = 0xc000 * (vram_bank & 0x03);
1504 pagemod = addr & 0xe000;
1505 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1506 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1508 } else if(display_mode == DISPLAY_MODE_4096) {
1509 if(active_page != 0) {
1510 page_offset += 0xc000;
1513 pagemod = addr & 0xe000;
1514 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1515 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1517 if(active_page != 0) {
1518 page_offset += 0xc000;
1521 pagemod = addr & 0xc000;
1522 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1523 vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1526 #elif defined(_FM77AV_VARIANTS)
1527 if(display_mode == DISPLAY_MODE_4096) {
1528 if(active_page != 0) {
1529 page_offset = 0xc000;
1532 pagemod = addr & 0xe000;
1533 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1534 vram_wrote_table[((addr + offset) % 0x2000) / 40] = true;
1536 if(active_page != 0) {
1537 page_offset = 0xc000;
1540 pagemod = addr & 0xc000;
1541 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1542 vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1544 #elif defined(_FM77L4) //_FM77L4
1546 if(display_mode == DISPLAY_MODE_8_400L) {
1547 write_vram_l4_400l(addr, data, offset);
1549 pagemod = addr & 0xc000;
1550 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1552 //vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1554 #else // Others (77/7/8)
1555 pagemod = addr & 0xc000;
1556 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1557 //vram_wrote_table[((addr + offset) % 0x4000) / 80] = true;
1559 #if defined(_FM77AV_VARIANTS)
1560 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
1566 uint32_t DISPLAY::read_data8_main(uint32_t addr)
1569 if(addr < 0xc000) return 0xff;
1571 raddr = addr - 0xc000;
1572 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1574 if(console_ram_bank >= 1) {
1575 return submem_console_av40[((console_ram_bank - 1) << 12) + raddr];
1579 return console_ram[raddr];
1580 } else if(addr < 0xd380) {
1581 raddr = addr - 0xd000;
1582 return work_ram[raddr];
1583 } else if(addr < 0xd400) {
1584 raddr = addr - 0xd380;
1585 return shared_ram[raddr];
1586 } else if(addr < 0xd800) {
1587 #if defined(_FM77AV_VARIANTS)
1588 if(addr >= 0xd500) {
1589 return submem_hidden[addr - 0xd500];
1592 return read_mmio(addr);
1593 } else if(addr < 0x10000) {
1594 #if !defined(_FM77AV_VARIANTS)
1595 return subsys_c[addr - 0xd800];
1598 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1600 return submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)]; //FIXME
1603 return subsys_cg[(addr - 0xd800) + cgrom_bank * 0x800];
1604 } else if(addr < 0x10000) {
1605 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1607 return subsys_ram[addr - 0xe000];
1610 switch(subrom_bank_using & 3) {
1612 return subsys_c[addr - 0xd800];
1615 return subsys_a[addr - 0xe000];
1618 return subsys_b[addr - 0xe000];
1621 return subsys_cg[addr - 0xe000];
1630 uint32_t DISPLAY::read_dma_data8(uint32_t addr)
1632 uint32_t raddr = addr & 0xffff;
1635 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1636 if(display_mode == DISPLAY_MODE_8_400L) {
1637 color = vram_bank & 0x03;
1638 if(color > 2) color = 0;
1640 color = (addr >> 14) & 0x03;
1644 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1646 return read_vram_data8(raddr);
1648 return read_data8_main(raddr);
1653 uint32_t DISPLAY::read_data8(uint32_t addr)
1655 uint32_t raddr = addr;
1657 uint32_t color = (addr & 0x0c000) >> 14;
1659 #if defined(_FM77AV_VARIANTS)
1661 alu->read_data8(addr + ALU_WRITE_PROXY);
1664 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1665 if(display_mode == DISPLAY_MODE_8_400L) {
1666 color = vram_bank & 0x03;
1667 if(color > 2) color = 0;
1669 color = (addr >> 14) & 0x03;
1673 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1675 return read_vram_data8(addr);
1676 } else if(addr < 0x10000) {
1677 return read_data8_main(addr);
1680 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1681 return dpalette_data[addr - FM7_SUBMEM_OFFSET_DPALETTE];
1684 #if defined(_FM77AV_VARIANTS)
1686 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
1687 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
1688 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1689 if(display_mode == DISPLAY_MODE_8_400L) {
1690 uint32_t page_offset = 0;
1691 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1692 if(vram_active_block != 0) page_offset = 0x18000;
1694 color = (addr & 0x18000) >> 15;
1695 if(color > 2) color = 0;
1697 if (active_page != 0) {
1698 offset = offset_point_bank1 << 1;
1700 offset = offset_point << 1;
1702 if(color > 2) color = 0;
1703 uint32_t pagemod = 0x8000 * color;
1704 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1707 return read_vram_data8(addr);
1714 * Vram accessing functions moved to vram.cpp .
1717 void DISPLAY::write_mmio(uint32_t addr, uint32_t data)
1721 if(addr < 0xd400) return;
1723 #if !defined(_FM77AV_VARIANTS)
1724 addr = (addr - 0xd400) & 0x000f;
1725 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1726 addr = (addr - 0xd400) & 0x003f;
1727 #else // FM77AV40EX || FM77AV40SX
1728 addr = (addr - 0xd400) & 0x00ff;
1730 io_w_latch[addr] = (uint8_t)data;
1732 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
1735 set_cyclesteal((uint8_t)data);
1738 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1739 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1742 if(!kanjisub) return;
1743 kanjiaddr.w.h = 0x0000;
1744 kanjiaddr.b.h = (uint8_t) data;
1747 if(!kanjisub) return;
1748 kanjiaddr.w.h = 0x0000;
1749 kanjiaddr.b.l = (uint8_t)data;
1762 if(clr_count <= 0) {
1764 } else { // Read once when using clr_foo() to set busy flag.
1767 usec = (1000.0 * 1000.0) / 2000000.0;
1769 usec = (1000.0 * 1000.0) / 999000.0;
1771 if(!is_cyclesteal) usec = usec * 3.0;
1772 usec = (double)clr_count * usec;
1773 register_event(this, EVENT_FM7SUB_CLR_BUSY, usec, false, NULL); // NEXT CYCLE_
1780 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
1785 rval = (uint8_t)data;
1786 if(offset_changed[active_page]) {
1787 #if defined(_FM77AV_VARIANTS)
1788 if(active_page != 0) {
1789 tmp_offset_point[active_page].d = offset_point_bank1;
1791 tmp_offset_point[active_page].d = offset_point;
1794 tmp_offset_point[active_page].d = offset_point;
1797 tmp_offset_point[active_page].w.h = 0x0000;
1799 tmp_offset_point[active_page].b.h = rval;
1801 tmp_offset_point[active_page].b.l = rval;
1803 offset_changed[active_page] = !offset_changed[active_page];
1804 if(offset_changed[active_page]) {
1806 #if defined(_FM77AV_VARIANTS)
1807 if(active_page != 0) {
1809 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fff;
1811 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fe0;
1815 offset_point = tmp_offset_point[active_page].d & 0x007fff;
1817 offset_point = tmp_offset_point[active_page].d & 0x007fe0;
1821 offset_point = tmp_offset_point[active_page].d & 0x7fe0;
1825 #if defined(_FM77AV_VARIANTS)
1828 alu_write_cmdreg(data);
1831 alu_write_logical_color(data);
1834 alu_write_mask_reg(data);
1837 alu_write_disable_reg(data);
1840 alu_write_offsetreg_hi(data);
1843 alu_write_offsetreg_lo(data);
1846 alu_write_linepattern_hi(data);
1849 alu_write_linepattern_lo(data);
1851 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1853 console_ram_bank = (data & 0x18) >> 3;
1854 if(console_ram_bank > 2) console_ram_bank = 0;
1855 cgram_bank = data & 0x07;
1856 kanji_level2 = ((data & 0x80) == 0) ? false : true;
1858 case 0x2f: // VRAM BANK
1859 vram_bank = data & 0x03;
1860 if(vram_bank > 2) vram_bank = 0;
1870 keyboard->write_data8(0x31, data);
1872 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1874 vram_active_block = data & 0x01;
1875 if(vram_display_block != (((data & 0x10) != 0) ? 1 : 0)) vram_wrote = true;
1876 vram_display_block = ((data & 0x10) != 0) ? 1 : 0;
1881 tmpvar.d = window_xbegin * 8;
1884 tmpvar.b.h = data & 0x03;
1886 tmpvar.b.l = data & 0xf8;
1888 if(mode320 || mode256k) {
1889 if(tmpvar.d > 320) tmpvar.d = 320;
1891 if(tmpvar.d > 640) tmpvar.d = 640;
1893 window_xbegin = tmpvar.d / 8;
1898 tmpvar.d = window_xend * 8;
1901 tmpvar.b.h = data & 0x03;
1903 tmpvar.b.l = data & 0xf8;
1905 if(mode320 || mode256k) {
1906 if(tmpvar.d > 320) tmpvar.d = 320;
1908 if(tmpvar.d > 640) tmpvar.d = 640;
1910 window_xend = tmpvar.d / 8;
1915 tmpvar.d = window_low;
1918 tmpvar.b.h = data & 0x03;
1920 tmpvar.b.l = data & 0xff;
1923 if(tmpvar.d > 400) tmpvar.d = 400;
1926 if(tmpvar.d > 400) tmpvar.d = 400;
1928 window_low = tmpvar.d;
1933 tmpvar.d = window_high;
1936 tmpvar.b.h = data & 0x03;
1938 tmpvar.b.l = data & 0xff;
1941 if(tmpvar.d > 400) tmpvar.d = 400;
1944 if(tmpvar.d > 400) tmpvar.d = 400;
1946 window_high = tmpvar.d;
1952 #if defined(_FM77AV_VARIANTS)
1954 if((addr >= 0x13) && (addr <= 0x1a)) {
1955 alu_write_cmpdata_reg(addr - 0x13, data);
1956 } else if((addr >= 0x1c) && (addr <= 0x1e)) {
1957 alu_write_tilepaint_data(addr, data);
1958 } else if((addr >= 0x24) && (addr <= 0x2b)) {
1959 alu_write_line_position(addr - 0x24, data);
1966 void DISPLAY::write_data8_main(uint32_t addr, uint8_t data)
1970 uint32_t page_offset = 0x0000;
1972 if(addr < 0xc000) return;
1975 raddr = addr - 0xc000;
1976 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1978 if(console_ram_bank >= 1) {
1979 submem_console_av40[((console_ram_bank - 1) << 12) + raddr] = data;
1984 console_ram[raddr] = data;
1986 } else if(addr < 0xd380) {
1987 raddr = addr - 0xd000;
1988 work_ram[raddr] = data;
1990 } else if(addr < 0xd400) {
1991 raddr = addr - 0xd380;
1992 shared_ram[raddr] = data;
1994 } else if(addr < 0xd800) {
1995 #if defined(_FM77AV_VARIANTS)
1996 if(addr >= 0xd500) {
1997 submem_hidden[addr - 0xd500] = data;
2001 write_mmio(addr, data);
2003 } else if(addr < 0x10000) {
2004 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2005 if(ram_protect) return;
2008 submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)] = data; //FIXME
2010 subsys_ram[addr - 0xe000] = data;
2018 void DISPLAY::write_data8(uint32_t addr, uint32_t data)
2022 uint32_t page_offset = 0x0000;
2023 uint8_t val8 = data & 0xff;
2025 uint32_t color = (addr & 0xc000) >> 14;
2028 #if defined(_FM77AV_VARIANTS)
2030 alu->read_data8(addr + ALU_WRITE_PROXY);
2033 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2034 if(display_mode == DISPLAY_MODE_8_400L) {
2035 color = vram_bank & 0x03;
2036 if(color > 2) color = 0;
2041 if((multimode_accessmask & (1 << color)) != 0) return;
2043 write_vram_data8(addr, val8);
2045 } else if(addr < 0x10000) {
2046 write_data8_main(addr, val8);
2050 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
2051 set_dpalette(addr - FM7_SUBMEM_OFFSET_DPALETTE, val8);
2055 #if defined(_FM77AV_VARIANTS)
2057 else if(addr == FM7_SUBMEM_OFFSET_APALETTE_R) {
2058 set_apalette_r(val8);
2060 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_G) {
2061 set_apalette_g(val8);
2063 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_B) {
2064 set_apalette_b(val8);
2066 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_HI) {
2067 set_apalette_index_hi(val8);
2069 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_LO) {
2070 set_apalette_index_lo(val8);
2074 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
2075 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
2076 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2077 if(display_mode == DISPLAY_MODE_8_400L) {
2078 color = (addr & 0x18000) >> 15;
2079 if(color > 2) color = 0;
2081 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2082 if(vram_active_block != 0) page_offset = 0x18000;
2084 if(color > 2) color = 0;
2085 if (active_page != 0) {
2086 offset = offset_point_bank1 << 1;
2088 offset = offset_point << 1;
2090 pagemod = 0x8000 * color;
2091 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
2092 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2093 vram_wrote_table[((addr + offset) % 0x8000) / 80] = true;
2096 write_vram_data8(addr, data);
2098 write_vram_data8(addr, data);
2100 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2107 uint32_t DISPLAY::read_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
2113 if((name == NULL) || (ptr == NULL)) return 0;
2114 s = create_local_path(name);
2115 if(s == NULL) return 0;
2117 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
2118 blocks = fio.Fread(ptr, size, 1);
2121 return blocks * size;
2125 void DISPLAY::initialize()
2129 screen_update_flag = true;
2130 memset(gvram, 0x00, sizeof(gvram));
2131 vram_wrote_shadow = false;
2132 #if defined(_FM77AV_VARIANTS)
2133 memset(gvram_shadow, 0x00, sizeof(gvram_shadow));
2134 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
2135 for(i = 0; i < 411; i++) vram_draw_table[i] = false;
2137 memset(console_ram, 0x00, sizeof(console_ram));
2138 memset(work_ram, 0x00, sizeof(work_ram));
2139 memset(shared_ram, 0x00, sizeof(shared_ram));
2140 memset(subsys_c, 0xff, sizeof(subsys_c));
2142 diag_load_subrom_c = false;
2144 if(read_bios(_T("SUBSYS_8.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2145 emu->out_debug_log(_T("SUBSYSTEM ROM READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2147 if(read_bios(_T("SUBSYS_C.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2148 emu->out_debug_log(_T("SUBSYSTEM ROM Type C READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2150 #if defined(_FM77AV_VARIANTS)
2151 memset(subsys_a, 0xff, sizeof(subsys_a));
2152 memset(subsys_b, 0xff, sizeof(subsys_b));
2153 memset(subsys_cg, 0xff, sizeof(subsys_cg));
2154 memset(submem_hidden, 0x00, sizeof(submem_hidden));
2156 diag_load_subrom_a = false;
2157 if(read_bios(_T("SUBSYS_A.ROM"), subsys_a, 0x2000) >= 0x2000) diag_load_subrom_a = true;
2158 emu->out_debug_log(_T("SUBSYSTEM ROM Type A READING : %s"), diag_load_subrom_a ? "OK" : "NG");
2160 diag_load_subrom_b = false;
2161 if(read_bios(_T("SUBSYS_B.ROM"), subsys_b, 0x2000) >= 0x2000) diag_load_subrom_b = true;
2162 emu->out_debug_log(_T("SUBSYSTEM ROM Type B READING : %s"), diag_load_subrom_b ? "OK" : "NG");
2164 diag_load_subrom_cg = false;
2165 if(read_bios(_T("SUBSYSCG.ROM"), subsys_cg, 0x2000) >= 0x2000) diag_load_subrom_cg = true;
2166 emu->out_debug_log(_T("SUBSYSTEM CG ROM READING : %s"), diag_load_subrom_cg ? "OK" : "NG");
2167 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2168 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2169 memset(subsys_ram, 0x00, sizeof(subsys_ram));
2170 memset(submem_cgram, 0x00, sizeof(submem_cgram));
2171 memset(submem_console_av40, 0x00, sizeof(submem_console_av40));
2175 #if defined(_FM77AV_VARIANTS)
2177 apalette_index.d = 0;
2178 for(i = 0; i < 4096; i++) {
2179 analog_palette_r[i] = i & 0x0f0;
2180 analog_palette_g[i] = i & 0xf00;
2181 analog_palette_b[i] = i & 0x00f;
2185 #if defined(_FM77AV_VARIANTS)
2186 hblank_event_id = -1;
2187 hdisp_event_id = -1;
2188 vsync_event_id = -1;
2189 vstart_event_id = -1;
2196 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
2197 is_cyclesteal = true;
2199 is_cyclesteal = false;
2201 // emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2202 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2206 key_firq_req = false; //firq_mask = true;
2207 frame_skip_count = 3;
2208 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2211 void DISPLAY::release()
2215 #define STATE_VERSION 3
2216 void DISPLAY::save_state(FILEIO *state_fio)
2218 state_fio->FputUint32_BE(STATE_VERSION);
2219 state_fio->FputInt32_BE(this_device_id);
2223 state_fio->FputInt32_BE(clr_count);
2224 state_fio->FputBool(halt_flag);
2225 state_fio->FputInt32_BE(active_page);
2226 state_fio->FputBool(sub_busy);
2227 state_fio->FputBool(crt_flag);
2228 state_fio->FputBool(vram_wrote);
2229 state_fio->FputBool(vram_wrote_shadow);
2230 #if defined(_FM77AV_VARIANTS)
2231 for(i = 0; i < 411; i++) state_fio->FputBool(vram_wrote_table[i]);
2232 for(i = 0; i < 411; i++) state_fio->FputBool(vram_draw_table[i]);
2234 state_fio->FputBool(is_cyclesteal);
2236 state_fio->FputBool(clock_fast);
2238 #if defined(_FM77AV_VARIANTS)
2239 state_fio->FputBool(subcpu_resetreq);
2240 state_fio->FputBool(power_on_reset);
2242 state_fio->FputBool(cancel_request);
2243 state_fio->FputBool(key_firq_req);
2245 state_fio->FputInt32_BE(display_mode);
2246 state_fio->FputUint32_BE(prev_clock);
2249 state_fio->Fwrite(dpalette_data, sizeof(dpalette_data), 1);
2250 state_fio->FputUint8(multimode_accessmask);
2251 state_fio->FputUint8(multimode_dispmask);
2253 state_fio->FputUint32_BE(offset_point);
2254 #if defined(_FM77AV_VARIANTS)
2255 state_fio->FputUint32_BE(offset_point_bank1);
2256 state_fio->FputUint32_BE(offset_point_bak);
2257 state_fio->FputUint32_BE(offset_point_bank1_bak);
2259 for(i = 0; i < 2; i++) {
2260 state_fio->FputUint32_BE(tmp_offset_point[i].d);
2261 state_fio->FputBool(offset_changed[i]);
2263 state_fio->FputBool(offset_77av);
2264 state_fio->FputBool(diag_load_subrom_c);
2267 state_fio->Fwrite(io_w_latch, sizeof(io_w_latch), 1);
2268 state_fio->Fwrite(console_ram, sizeof(console_ram), 1);
2269 state_fio->Fwrite(work_ram, sizeof(work_ram), 1);
2270 state_fio->Fwrite(shared_ram, sizeof(shared_ram), 1);
2271 state_fio->Fwrite(subsys_c, sizeof(subsys_c), 1);
2272 state_fio->Fwrite(gvram, sizeof(gvram), 1);
2273 #if defined(_FM77AV_VARIANTS)
2274 state_fio->Fwrite(gvram_shadow, sizeof(gvram_shadow), 1);
2277 #if defined(_FM77_VARIANTS)
2278 state_fio->FputBool(kanjisub);
2279 state_fio->FputUint16_BE(kanjiaddr.w.l);
2280 # if defined(_FM77L4)
2281 state_fio->FputBool(mode400line);
2282 state_fio->FputBool(stat_400linecard);
2284 #elif defined(_FM77AV_VARIANTS)
2285 state_fio->FputBool(kanjisub);
2286 state_fio->FputUint16_BE(kanjiaddr.w.l);
2288 state_fio->FputBool(vblank);
2289 state_fio->FputBool(vsync);
2290 state_fio->FputBool(hblank);
2291 state_fio->FputInt32_BE(vblank_count);
2292 state_fio->FputUint32_BE(displine);
2294 state_fio->FputBool(mode320);
2295 state_fio->FputInt32_BE(display_page);
2296 state_fio->FputInt32_BE(cgrom_bank);
2297 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2298 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2299 state_fio->FputInt32_BE(vram_bank);
2302 state_fio->FputUint8(subrom_bank);
2303 state_fio->FputUint8(subrom_bank_using);
2305 state_fio->FputBool(nmi_enable);
2306 state_fio->FputBool(use_alu);
2308 state_fio->FputUint8(apalette_index.b.l);
2309 state_fio->FputUint8(apalette_index.b.h);
2310 state_fio->Fwrite(analog_palette_r, sizeof(analog_palette_r), 1);
2311 state_fio->Fwrite(analog_palette_g, sizeof(analog_palette_g), 1);
2312 state_fio->Fwrite(analog_palette_b, sizeof(analog_palette_b), 1);
2315 state_fio->FputBool(diag_load_subrom_a);
2316 state_fio->FputBool(diag_load_subrom_b);
2317 state_fio->FputBool(diag_load_subrom_cg);
2319 state_fio->Fwrite(subsys_a, sizeof(subsys_a), 1);
2320 state_fio->Fwrite(subsys_b, sizeof(subsys_b), 1);
2321 state_fio->Fwrite(subsys_cg, sizeof(subsys_cg), 1);
2322 state_fio->Fwrite(submem_hidden, sizeof(submem_hidden), 1);
2323 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2324 state_fio->FputBool(mode400line);
2325 state_fio->FputBool(mode256k);
2327 state_fio->FputBool(monitor_ram);
2328 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2329 state_fio->FputUint16_BE(window_low);
2330 state_fio->FputUint16_BE(window_high);
2331 state_fio->FputUint16_BE(window_xbegin);
2332 state_fio->FputUint16_BE(window_xend);
2333 state_fio->FputBool(window_opened);
2335 state_fio->FputBool(kanji_level2);
2337 state_fio->FputUint8(vram_active_block);
2338 state_fio->FputUint8(vram_display_block);
2339 state_fio->FputUint8(console_ram_bank);
2340 state_fio->FputBool(ram_protect);
2342 state_fio->FputUint32_BE(cgram_bank);
2343 state_fio->Fwrite(subsys_ram, sizeof(subsys_ram), 1);
2344 state_fio->Fwrite(submem_cgram, sizeof(submem_cgram), 1);
2345 state_fio->Fwrite(submem_console_av40, sizeof(submem_console_av40), 1);
2351 state_fio->FputInt32_BE(nmi_event_id);
2352 #if defined(_FM77AV_VARIANTS)
2353 state_fio->FputInt32_BE(hblank_event_id);
2354 state_fio->FputInt32_BE(hdisp_event_id);
2355 state_fio->FputInt32_BE(vsync_event_id);
2356 state_fio->FputInt32_BE(vstart_event_id);
2358 state_fio->FputBool(firq_mask);
2359 state_fio->FputBool(vram_accessflag);
2360 state_fio->FputUint32_BE(frame_skip_count);
2364 bool DISPLAY::load_state(FILEIO *state_fio)
2367 uint32_t version = state_fio->FgetUint32_BE();
2368 if(this_device_id != state_fio->FgetInt32_BE()) {
2375 clr_count = state_fio->FgetInt32_BE();
2376 halt_flag = state_fio->FgetBool();
2377 active_page = state_fio->FgetInt32_BE();
2378 sub_busy = state_fio->FgetBool();
2379 crt_flag = state_fio->FgetBool();
2380 vram_wrote = state_fio->FgetBool();
2381 crt_flag_bak = true;
2382 screen_update_flag = true;
2383 vram_wrote_shadow = state_fio->FgetBool();
2384 #if defined(_FM77AV_VARIANTS)
2385 for(i = 0; i < 411; i++) vram_wrote_table[i] = state_fio->FgetBool();
2386 for(i = 0; i < 411; i++) vram_draw_table[i] = state_fio->FgetBool();
2388 is_cyclesteal = state_fio->FgetBool();
2390 clock_fast = state_fio->FgetBool();
2392 #if defined(_FM77AV_VARIANTS)
2393 subcpu_resetreq = state_fio->FgetBool();
2394 power_on_reset = state_fio->FgetBool();
2396 cancel_request = state_fio->FgetBool();
2397 key_firq_req = state_fio->FgetBool();
2399 display_mode = state_fio->FgetInt32_BE();
2400 prev_clock = state_fio->FgetUint32_BE();
2403 for(addr = 0; addr < 8; addr++) set_dpalette(addr, addr);
2405 state_fio->Fread(dpalette_data, sizeof(dpalette_data), 1);
2406 for(addr = 0; addr < 8; addr++) set_dpalette(addr, dpalette_data[addr]);
2407 multimode_accessmask = state_fio->FgetUint8();
2408 multimode_dispmask = state_fio->FgetUint8();
2410 offset_point = state_fio->FgetUint32_BE();
2411 #if defined(_FM77AV_VARIANTS)
2412 offset_point_bank1 = state_fio->FgetUint32_BE();
2413 offset_point_bak = state_fio->FgetUint32_BE();
2414 offset_point_bank1_bak = state_fio->FgetUint32_BE();
2416 for(i = 0; i < 2; i++) {
2417 tmp_offset_point[i].d = state_fio->FgetUint32_BE();
2418 offset_changed[i] = state_fio->FgetBool();
2420 offset_77av = state_fio->FgetBool();
2421 diag_load_subrom_c = state_fio->FgetBool();
2423 state_fio->Fread(io_w_latch, sizeof(io_w_latch), 1);
2424 state_fio->Fread(console_ram, sizeof(console_ram), 1);
2425 state_fio->Fread(work_ram, sizeof(work_ram), 1);
2426 state_fio->Fread(shared_ram, sizeof(shared_ram), 1);
2427 state_fio->Fread(subsys_c, sizeof(subsys_c), 1);
2428 state_fio->Fread(gvram, sizeof(gvram), 1);
2429 #if defined(_FM77AV_VARIANTS)
2430 state_fio->Fread(gvram_shadow, sizeof(gvram_shadow), 1);
2432 #if defined(_FM77_VARIANTS)
2433 kanjisub = state_fio->FgetBool();
2435 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2436 # if defined(_FM77L4)
2437 mode400line = state_fio->FgetBool();
2438 stat_400linecard = state_fio->FgetBool();
2440 #elif defined(_FM77AV_VARIANTS)
2441 kanjisub = state_fio->FgetBool();
2443 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2445 vblank = state_fio->FgetBool();
2446 vsync = state_fio->FgetBool();
2447 hblank = state_fio->FgetBool();
2448 vblank_count = state_fio->FgetInt32_BE();
2449 displine = state_fio->FgetUint32_BE();
2451 mode320 = state_fio->FgetBool();
2452 display_page = state_fio->FgetInt32_BE();
2453 cgrom_bank = state_fio->FgetInt32_BE();
2454 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2455 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2456 vram_bank = state_fio->FgetInt32_BE();
2459 subrom_bank = state_fio->FgetUint8();
2460 subrom_bank_using = state_fio->FgetUint8();
2462 nmi_enable = state_fio->FgetBool();
2463 use_alu = state_fio->FgetBool();
2465 apalette_index.b.l = state_fio->FgetUint8();
2466 apalette_index.b.h = state_fio->FgetUint8();
2468 state_fio->Fread(analog_palette_r, sizeof(analog_palette_r), 1);
2469 state_fio->Fread(analog_palette_g, sizeof(analog_palette_g), 1);
2470 state_fio->Fread(analog_palette_b, sizeof(analog_palette_b), 1);
2471 for(i = 0; i < 4096; i++) calc_apalette(i);
2473 diag_load_subrom_a = state_fio->FgetBool();
2474 diag_load_subrom_b = state_fio->FgetBool();
2475 diag_load_subrom_cg = state_fio->FgetBool();
2477 state_fio->Fread(subsys_a, sizeof(subsys_a), 1);
2478 state_fio->Fread(subsys_b, sizeof(subsys_b), 1);
2479 state_fio->Fread(subsys_cg, sizeof(subsys_cg), 1);
2480 state_fio->Fread(submem_hidden, sizeof(submem_hidden), 1);
2482 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2483 mode400line = state_fio->FgetBool();
2484 mode256k = state_fio->FgetBool();
2486 monitor_ram = state_fio->FgetBool();
2487 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2488 window_low = state_fio->FgetUint16_BE();
2489 window_high = state_fio->FgetUint16_BE();
2490 window_xbegin = state_fio->FgetUint16_BE();
2491 window_xend = state_fio->FgetUint16_BE();
2492 window_opened = state_fio->FgetBool();
2494 kanji_level2 = state_fio->FgetBool();
2496 vram_active_block = state_fio->FgetUint8();
2497 vram_display_block = state_fio->FgetUint8();
2498 console_ram_bank = state_fio->FgetUint8();
2499 ram_protect = state_fio->FgetBool();
2501 cgram_bank = state_fio->FgetUint32_BE();
2502 state_fio->Fread(subsys_ram, sizeof(subsys_ram), 1);
2503 state_fio->Fread(submem_cgram, sizeof(submem_cgram), 1);
2504 state_fio->Fread(submem_console_av40, sizeof(submem_console_av40), 1);
2507 bool vram_wrote_shadow_bak = vram_wrote_shadow;
2508 vram_wrote_shadow = true; // Force Draw
2509 this->draw_screen();
2510 vram_wrote_shadow = vram_wrote_shadow_bak;
2511 if(version == 1) return true;
2513 if(version >= 2) { //V2
2514 nmi_event_id = state_fio->FgetInt32_BE();
2515 #if defined(_FM77AV_VARIANTS)
2516 hblank_event_id = state_fio->FgetInt32_BE();
2517 hdisp_event_id = state_fio->FgetInt32_BE();
2518 vsync_event_id = state_fio->FgetInt32_BE();
2519 vstart_event_id = state_fio->FgetInt32_BE();
2521 firq_mask = state_fio->FgetBool();
2522 vram_accessflag = state_fio->FgetBool();
2523 frame_skip_count = state_fio->FgetUint32_BE();
2525 if(version == 3) return true;