2 * Common source code project -> FM-7 -> Display
3 * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
5 * Feb 10, 2015 : Initial.
10 #include "../../fileio.h"
11 #include "fm7_display.h"
12 #if defined(_FM77AV_VARIANTS)
13 # include "mb61vh010.h"
16 DISPLAY::DISPLAY(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
23 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
26 #elif defined(_FM77_VARIANTS)
29 #if defined(_FM77AV_VARIANTS)
35 for(int i = 0; i < 256; i++) {
36 uint16_t n = (uint16_t)i;
37 for(int j = 0; j < 8; j++) {
38 bit_trans_table_0[i][j] = n & 0x80;
39 bit_trans_table_1[i][j] = ((n & 0x80) != 0) ? 0x40 : 0;
40 bit_trans_table_2[i][j] = ((n & 0x80) != 0) ? 0x20 : 0;
41 bit_trans_table_3[i][j] = ((n & 0x80) != 0) ? 0x10 : 0;
42 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
43 bit_trans_table_4[i][j] = ((n & 0x80) != 0) ? 0x08 : 0;
44 bit_trans_table_5[i][j] = ((n & 0x80) != 0) ? 0x04 : 0;
51 set_device_name(_T("DISPLAY SUBSYSTEM"));
59 void DISPLAY::reset_cpuonly()
63 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
64 mainio->write_signal(SIG_FM7_SUB_HALT, 0x00, 0xff);
67 palette_changed = true;
68 multimode_accessmask = 0;
69 multimode_dispmask = 0;
71 //cancel_request = false;
72 switch(config.cpu_type){
83 for(i = 0; i < 2; i++) {
84 offset_changed[i] = true;
85 tmp_offset_point[i].d = 0;
88 vram_wrote_shadow = true;
89 for(i = 0; i < 411; i++) vram_wrote_table[i] = true;
90 for(i = 0; i < 411; i++) vram_draw_table[i] = true;
94 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
100 if(hblank_event_id >= 0) cancel_event(this, hblank_event_id);
101 if(hdisp_event_id >= 0) cancel_event(this, hdisp_event_id);
102 if(vsync_event_id >= 0) cancel_event(this, vsync_event_id);
103 if(vstart_event_id >= 0) cancel_event(this, vstart_event_id);
104 hblank_event_id = -1;
107 vstart_event_id = -1;
108 if(display_mode == DISPLAY_MODE_8_400L) {
109 usec = 0.33 * 1000.0;
111 usec = 0.51 * 1000.0;
114 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
115 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
116 mainio->write_signal(SIG_DISPLAY_VSYNC, 0xff, 0xff);
118 #if defined(_FM77AV_VARIANTS)
120 offset_point_bank1 = 0;
122 display_page_bak = 0;
124 subcpu_resetreq = false;
125 subrom_bank_using = subrom_bank;
130 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
132 vram_display_block = 0;
133 vram_active_block = 0;
135 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
140 window_opened = false;
145 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
146 alu->write_signal(SIG_ALU_X_WIDTH, (mode320 || mode256k) ? 40 : 80, 0xffff);
147 alu->write_signal(SIG_ALU_Y_HEIGHT, (display_mode == DISPLAY_MODE_8_400L) ? 400: 200, 0xffff);
148 alu->write_signal(SIG_ALU_400LINE, (display_mode == DISPLAY_MODE_8_400L) ? 0xffffffff : 0, 0xffffffff);
150 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
151 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
152 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
154 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
155 alu->write_signal(SIG_ALU_PLANES, 3, 3);
158 for(i = 0; i < 8; i++) set_dpalette(i, i);
159 do_firq(!firq_mask && key_firq_req);
161 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
163 kanjiaddr.d = 0x00000000;
164 # if defined(_FM77L4)
166 stat_400linecard = false;
171 frame_skip_count = 3;
175 void DISPLAY::reset()
178 memset(io_w_latch, 0xff, sizeof(io_w_latch));
180 vram_accessflag = true;
181 display_mode = DISPLAY_MODE_8_200L;
183 screen_update_flag = true;
186 cancel_request = false;
187 #if defined(_FM77AV_VARIANTS)
189 apalette_index.d = 0;
190 for(i = 0; i < 4096; i++) {
191 analog_palette_r[i] = i & 0x0f0;
192 analog_palette_g[i] = (i & 0xf00) >> 4;
193 analog_palette_b[i] = (i & 0x00f) << 4;
198 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
205 #elif defined(_FM77L4)
208 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
209 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
210 key_firq_req = false; //firq_mask = true;
214 #if defined(_FM77AV_VARIANTS)
215 power_on_reset = false;
216 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
220 for(i = 0; i < 8; i++) set_dpalette(i, i);
221 multimode_accessmask = 0x00;
222 multimode_dispmask = 0x00;
227 if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
228 register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
229 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
233 void DISPLAY::update_config()
237 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
243 * Vram accessing functions moved to vram.cpp .
246 void DISPLAY::do_irq(bool flag)
248 subcpu->write_signal(SIG_CPU_IRQ, flag ? 1: 0, 1);
251 void DISPLAY::do_firq(bool flag)
253 subcpu->write_signal(SIG_CPU_FIRQ, flag ? 1: 0, 1);
256 void DISPLAY::do_nmi(bool flag)
258 #if defined(_FM77AV_VARIANTS)
259 if(!nmi_enable) flag = false;
261 subcpu->write_signal(SIG_CPU_NMI, flag ? 1 : 0, 1);
264 void DISPLAY::set_multimode(uint8_t val)
267 multimode_accessmask = val & 0x07;
268 multimode_dispmask = (val & 0x70) >> 4;
270 # if defined(_FM77AV_VARIANTS)
271 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
276 uint8_t DISPLAY::get_multimode(void)
282 val = multimode_accessmask & 0x07;
283 val |= ((multimode_dispmask << 4) & 0x70);
289 uint8_t DISPLAY::get_cpuaccessmask(void)
291 return multimode_accessmask & 0x07;
294 void DISPLAY::set_dpalette(uint32_t addr, uint8_t val)
298 dpalette_data[addr] = val | 0xf8; //0b11111000;
299 b = ((val & 0x01) != 0x00)? 255 : 0x00;
300 r = ((val & 0x02) != 0x00)? 255 : 0x00;
301 g = ((val & 0x04) != 0x00)? 255 : 0x00;
303 dpalette_pixel[addr] = RGB_COLOR(r, g, b);
304 palette_changed = true;
307 uint8_t DISPLAY::get_dpalette(uint32_t addr)
315 data = dpalette_data[addr];
320 void DISPLAY::halt_subcpu(void)
322 subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
325 void DISPLAY::go_subcpu(void)
327 subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
330 void DISPLAY::enter_display(void)
334 subclock = SUBCLOCK_NORMAL;
336 subclock = SUBCLOCK_SLOW;
338 if(!is_cyclesteal && vram_accessflag) {
339 subclock = subclock / 3;
341 if(prev_clock != subclock) p_vm->set_cpu_clock(subcpu, subclock);
342 prev_clock = subclock;
345 void DISPLAY::leave_display(void)
349 void DISPLAY::halt_subsystem(void)
355 void DISPLAY::restart_subsystem(void)
358 #if defined(_FM77AV_VARIANTS)
359 if(subcpu_resetreq) {
360 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
362 power_on_reset = true;
363 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
365 do_firq(!firq_mask && key_firq_req);
372 void DISPLAY::set_crtflag(void)
379 void DISPLAY::reset_crtflag(void)
386 uint8_t DISPLAY::acknowledge_irq(void)
388 cancel_request = false;
394 uint8_t DISPLAY::beep(void)
396 mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
397 return 0xff; // True?
402 uint8_t DISPLAY::attention_irq(void)
404 mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
409 void DISPLAY::set_cyclesteal(uint8_t val)
412 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
416 is_cyclesteal = true;
418 is_cyclesteal = false;
426 uint8_t DISPLAY::set_vramaccess(void)
428 vram_accessflag = true;
433 void DISPLAY::reset_vramaccess(void)
435 vram_accessflag = false;
439 uint8_t DISPLAY::reset_subbusy(void)
446 void DISPLAY::set_subbusy(void)
452 #if defined(_FM77AV_VARIANTS)
454 void DISPLAY::alu_write_cmdreg(uint32_t val)
456 alu->write_data8(ALU_CMDREG, val);
457 if((val & 0x80) != 0) {
465 void DISPLAY::alu_write_logical_color(uint8_t val)
467 uint32_t data = (uint32_t)val;
468 alu->write_data8(ALU_LOGICAL_COLOR, data);
472 void DISPLAY::alu_write_mask_reg(uint8_t val)
474 uint32_t data = (uint32_t)val;
475 alu->write_data8(ALU_WRITE_MASKREG, data);
479 void DISPLAY::alu_write_cmpdata_reg(int addr, uint8_t val)
481 uint32_t data = (uint32_t)val;
483 alu->write_data8(ALU_CMPDATA_REG + addr, data);
487 void DISPLAY::alu_write_disable_reg(uint8_t val)
489 uint32_t data = (uint32_t)val;
490 alu->write_data8(ALU_BANK_DISABLE, data);
494 void DISPLAY::alu_write_tilepaint_data(uint32_t addr, uint8_t val)
496 uint32_t data = (uint32_t)val;
499 alu->write_data8(ALU_TILEPAINT_B, data);
502 alu->write_data8(ALU_TILEPAINT_R, data);
505 alu->write_data8(ALU_TILEPAINT_G, data);
508 //alu->write_data8(ALU_TILEPAINT_L, 0xff);
514 void DISPLAY::alu_write_offsetreg_hi(uint8_t val)
516 alu->write_data8(ALU_OFFSET_REG_HIGH, val & 0x7f);
520 void DISPLAY::alu_write_offsetreg_lo(uint8_t val)
522 alu->write_data8(ALU_OFFSET_REG_LO, val);
526 void DISPLAY::alu_write_linepattern_hi(uint8_t val)
528 alu->write_data8(ALU_LINEPATTERN_REG_HIGH, val);
532 void DISPLAY::alu_write_linepattern_lo(uint8_t val)
534 alu->write_data8(ALU_LINEPATTERN_REG_LO, val);
538 void DISPLAY::alu_write_line_position(int addr, uint8_t val)
540 uint32_t data = (uint32_t)val;
543 alu->write_data8(ALU_LINEPOS_START_X_HIGH, data & 0x03);
546 alu->write_data8(ALU_LINEPOS_START_X_LOW, data);
549 alu->write_data8(ALU_LINEPOS_START_Y_HIGH, data & 0x01);
552 alu->write_data8(ALU_LINEPOS_START_Y_LOW, data);
555 alu->write_data8(ALU_LINEPOS_END_X_HIGH, data & 0x03);
558 alu->write_data8(ALU_LINEPOS_END_X_LOW, data);
561 alu->write_data8(ALU_LINEPOS_END_Y_HIGH, data & 0x01);
564 alu->write_data8(ALU_LINEPOS_END_Y_LOW, data);
570 uint8_t DISPLAY::get_miscreg(void)
575 if(!hblank) ret |= 0x80;
576 if(vsync) ret |= 0x04;
577 if(alu->read_signal(SIG_ALU_BUSYSTAT) == 0) ret |= 0x10;
578 if(power_on_reset) ret |= 0x01;
583 void DISPLAY::set_miscreg(uint8_t val)
585 int old_display_page = display_page;
587 nmi_enable = ((val & 0x80) == 0) ? true : false;
588 if(!nmi_enable) do_nmi(false);
590 if((val & 0x40) == 0) {
595 if(display_page != old_display_page) {
598 active_page = ((val & 0x20) == 0) ? 0 : 1;
599 if((val & 0x04) == 0) {
604 cgrom_bank = val & 0x03;
608 void DISPLAY::set_monitor_bank(uint8_t var)
610 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
611 if((var & 0x04) != 0){
617 subrom_bank = var & 0x03;
620 subcpu_resetreq = false;
621 power_on_reset = true;
622 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
624 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
626 do_firq(!firq_mask && key_firq_req);
628 subcpu_resetreq = true;
634 void DISPLAY::set_apalette_index_hi(uint8_t val)
636 apalette_index.b.h = val & 0x0f;
640 void DISPLAY::set_apalette_index_lo(uint8_t val)
642 apalette_index.b.l = val;
645 void DISPLAY::calc_apalette(uint16_t idx)
649 g = analog_palette_g[idx];
650 r = analog_palette_r[idx];
651 b = analog_palette_b[idx];
652 if(g != 0) g |= 0x0f;
653 if(r != 0) r |= 0x0f;
654 if(b != 0) b |= 0x0f;
655 analog_palette_pixel[idx] = RGB_COLOR(r, g, b);
659 void DISPLAY::set_apalette_b(uint8_t val)
663 index = apalette_index.w.l;
664 tmp = (val & 0x0f) << 4;
665 if(analog_palette_b[index] != tmp) {
666 analog_palette_b[index] = tmp;
667 calc_apalette(index);
668 palette_changed = true;
673 void DISPLAY::set_apalette_r(uint8_t val)
677 index = apalette_index.w.l;
678 tmp = (val & 0x0f) << 4;
679 if(analog_palette_r[index] != tmp) {
680 analog_palette_r[index] = tmp;
681 calc_apalette(index);
682 palette_changed = true;
687 void DISPLAY::set_apalette_g(uint8_t val)
691 index = apalette_index.w.l;
692 tmp = (val & 0x0f) << 4;
693 if(analog_palette_g[index] != tmp) {
694 analog_palette_g[index] = tmp;
695 calc_apalette(index);
696 palette_changed = true;
700 #endif // _FM77AV_VARIANTS
703 void DISPLAY::copy_vram_blank_area(void)
708 void DISPLAY::copy_vram_per_line(void)
717 uint32_t src_offset_d1;
718 uint32_t src_offset_d2;
719 uint32_t src_offset_d;
724 //int dline = (int)displine - 1;
725 int dline = (int)displine;
727 if(dline < 0) return;
728 if(display_mode == DISPLAY_MODE_8_400L) {
729 if(dline >= 400) return;
731 if(dline >= 200) return;
733 #if defined(_FM77AV_VARIANTS)
734 yoff_d1 = offset_point;
735 yoff_d2 = offset_point_bank1;
736 if(display_mode == DISPLAY_MODE_4096) {
737 src_offset = dline * 40;
738 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
741 bytes_d1 = 0x2000 - ((src_offset + yoff_d1) & 0x1fff);
742 bytes_d2 = 0x2000 - ((src_offset + yoff_d2) & 0x1fff);
743 for(k = 0; k < pages; k++) {
744 for(i = 0; i < 3; i++) {
745 for(j = 0; j < 2; j++) {
746 src_base = i * 0x4000 + j * 0x2000;
748 memcpy(&gvram_shadow[src_offset + src_base + poff],
749 &gvram[((src_offset + yoff_d1) & 0x1fff) + src_base + poff],
751 memcpy(&gvram_shadow[src_offset + bytes_d1 + src_base + poff],
752 &gvram[src_base + poff],
755 memcpy(&gvram_shadow[src_offset + src_base + poff],
756 &gvram[((src_offset + yoff_d1) & 0x1fff) + src_base + poff],
759 src_base = i * 0x4000 + j * 0x2000 + 0xc000;
761 memcpy(&gvram_shadow[src_offset + src_base + poff],
762 &gvram[((src_offset + yoff_d2) & 0x1fff) + src_base + poff],
764 memcpy(&gvram_shadow[src_offset + bytes_d2 + src_base + poff],
765 &gvram[src_base + poff],
768 memcpy(&gvram_shadow[src_offset + src_base + poff],
769 &gvram[((src_offset + yoff_d2) & 0x1fff) + src_base + poff],
776 vram_draw_table[dline] = true;
777 vram_wrote_table[dline] = false;
779 # if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40)
780 else if(display_mode == DISPLAY_MODE_256k) {
781 src_offset = dline * 40;
783 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
785 #elif defined(_FM77AV40)
790 src_offset_d1 = (src_offset + yoff_d1) & 0x1fff;
791 src_offset_d2 = (src_offset + yoff_d2) & 0x1fff;
792 bytes_d1 = 0x2000 - ((src_offset + yoff_d1) & 0x1fff);
793 bytes_d2 = 0x2000 - ((src_offset + yoff_d2) & 0x1fff);
794 for(k = 0; k < pages; k++) {
795 for(i = 0; i < 3; i++) {
796 for(j = 0; j < 2; j++) {
798 src_base = i * 0x4000 + j * 0x2000 + k * 0xc000;
799 src_offset_d = src_offset_d1;
802 src_base = i * 0x4000 + j * 0x2000 + k * 0xc000;
803 src_offset_d = src_offset_d2;
807 memcpy(&gvram_shadow[src_offset + src_base],
808 &gvram[src_offset_d + src_base],
810 memcpy(&gvram_shadow[src_offset + bytes_d + src_base],
814 memcpy(&gvram_shadow[src_offset + src_base],
815 &gvram[src_offset_d + src_base],
821 vram_draw_table[dline] = true;
822 vram_wrote_table[dline] = false;
824 else if(display_mode == DISPLAY_MODE_8_400L) {
825 src_offset = dline * 80;
826 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
828 # elif defined(_FM77AV40)
831 if(display_page_bak == 1) { // Is this dirty?
836 yoff_d = (yoff_d << 1) & 0x7fff;
837 src_offset_d = (src_offset + yoff_d) & 0x7fff;
838 bytes_d = 0x8000 - ((src_offset + yoff_d) & 0x7fff);
839 for(i = 0; i < pages; i++) {
840 for(j = 0; j < 3; j++) {
841 src_base = i * 0x18000 + j * 0x8000;
843 memcpy(&gvram_shadow[src_offset + src_base],
844 &gvram[src_offset_d + src_base],
846 memcpy(&gvram_shadow[src_offset + bytes_d + src_base],
850 memcpy(&gvram_shadow[src_offset + src_base + poff],
851 &gvram[src_offset_d + src_base],
856 vram_draw_table[dline] = true;
857 vram_wrote_table[dline] = false;
861 src_offset = dline * 80;
862 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
864 #elif defined(_FM77AV40)
866 #elif defined(_FM77AV_VARIANTS)
872 src_offset_d1 = (src_offset + yoff_d1) & 0x3fff;
873 src_offset_d2 = (src_offset + yoff_d2) & 0x3fff;
874 bytes_d1 = 0x4000 - ((src_offset + yoff_d1) & 0x3fff);
875 bytes_d2 = 0x4000 - ((src_offset + yoff_d2) & 0x3fff);
876 for(i = 0; i < pages; i++) {
877 for(j = 0; j < 3; j++) {
878 src_base = j * 0x4000;
880 src_offset_d = src_offset_d1;
883 src_offset_d = src_offset_d2;
887 memcpy(&gvram_shadow[src_offset + src_base + poff],
888 &gvram[src_offset_d + src_base + poff],
890 memcpy(&gvram_shadow[src_offset + bytes_d + src_base + poff],
891 &gvram[src_base + poff],
894 memcpy(&gvram_shadow[src_offset + src_base + poff],
895 &gvram[src_offset_d + src_base + poff],
901 vram_draw_table[dline] = true;
902 vram_wrote_table[dline] = false;
906 src_offset = dline * 80;
909 yoff_d = offset_point;
910 src_offset_d = (src_offset + yoff_d) & 0x3fff;
911 bytes_d = 0x4000 - ((src_offset + yoff_d) & 0x3fff);
912 for(j = 0; j < 3; j++) {
913 src_base = j * 0x4000;
915 memcpy(&gvram_shadow[src_offset + src_base + poff],
916 &gvram[src_offset_d + src_base + poff],
918 memcpy(&gvram_shadow[src_offset + bytes_d + src_base + poff],
919 &gvram[src_base + poff],
922 memcpy(&gvram_shadow[src_offset + src_base + poff],
923 &gvram[src_offset_d + src_base + poff],
927 vram_draw_table[dline] = true;
928 vram_wrote_table[dline] = false;
934 void DISPLAY::copy_vram_all()
936 #if defined(_FM77AV_VARIANTS)
937 uint32_t yoff_d1 = offset_point;
938 uint32_t yoff_d2 = offset_point_bank1;
939 uint32_t src_offset_1, src_offset_2;
941 if(display_mode == DISPLAY_MODE_4096) {
942 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
947 uint32_t bytes_d1 = 0x2000 - (yoff_d1 & 0x1fff);
948 uint32_t bytes_d2 = 0x2000 - (yoff_d2 & 0x1fff);
949 for(int k = 0; k < pages; k++) {
950 for(int i = 0; i < 3; i++) {
951 for(int j = 0; j < 2; j++) {
952 src_offset_1 = i * 0x4000 + j * 0x2000;
953 src_offset_2 = src_offset_1 + 0xc000;
954 memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + (yoff_d1 & 0x1fff) + poff], bytes_d1);
955 memcpy(&gvram_shadow[src_offset_1 + bytes_d1 + poff], &gvram[src_offset_1 + poff], 0x2000 - bytes_d1);
956 memcpy(&gvram_shadow[src_offset_2 + poff], &gvram[src_offset_2 + (yoff_d2 & 0x1fff) + poff], bytes_d2);
957 memcpy(&gvram_shadow[src_offset_2 + bytes_d2 + poff], &gvram[src_offset_2 + poff], 0x2000 - bytes_d2);
963 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
964 else if(display_mode == DISPLAY_MODE_256k) {
965 uint32_t bytes_d1 = 0x2000 - (yoff_d1 & 0x1fff);
966 uint32_t bytes_d2 = 0x2000 - (yoff_d2 & 0x1fff);
967 for(int i = 0; i < 3; i++) {
968 for(int j = 0; j < 2; j++) {
969 src_offset_1 = i * 0x4000 + j * 0x2000;
970 src_offset_2 = src_offset_1 + 0xc000;
971 memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + (yoff_d1 & 0x1fff) + poff], bytes_d1);
972 memcpy(&gvram_shadow[src_offset_1 + bytes_d1 + poff], &gvram[src_offset_1 + poff], 0x2000 - bytes_d1);
973 memcpy(&gvram_shadow[src_offset_2 + poff], &gvram[src_offset_2 + (yoff_d2 & 0x1fff) + poff], bytes_d2);
974 memcpy(&gvram_shadow[src_offset_2 + bytes_d2 + poff], &gvram[src_offset_2 + poff], 0x2000 - bytes_d2);
978 for(int i = 0; i < 3; i++) {
979 for(int j = 0; j < 2; j++) {
980 src_offset_1 = i * 0x4000 + j * 0x2000;
981 memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + (yoff_d1 & 0x1fff) + poff], bytes_d1);
982 memcpy(&gvram_shadow[src_offset_1 + bytes_d1 + poff], &gvram[src_offset_1 + poff], 0x2000 - bytes_d1);
985 } else if(display_mode == DISPLAY_MODE_8_400L) {
986 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
994 if(display_page_bak == 1) { // Is this dirty?
999 yoff_d = (yoff_d << 1) & 0x7fff;
1000 bytes_d = 0x8000 - yoff_d;
1001 for(int k = 0; k < pages; k++) {
1002 for(int i = 0; i < 3; i++) {
1003 src_offset_1 = i * 0x8000;
1004 memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + yoff_d + poff], bytes_d);
1005 memcpy(&gvram_shadow[src_offset_1 + bytes_d + poff], &gvram[src_offset_1 + poff], 0x8000 - bytes_d);
1012 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1014 #elif defined(_FM77AV40)
1019 uint32_t bytes_d1 = 0x4000 - (yoff_d1 & 0x3fff);
1020 uint32_t bytes_d2 = 0x4000 - (yoff_d2 & 0x3fff);
1021 uint32_t yoff_d, bytes_d;
1022 for(int k = 0; k < pages; k++) {
1023 yoff_d = ((k & 1) == 0) ? (yoff_d1 & 0x3fff) : (yoff_d2 & 0x3fff);
1024 bytes_d = ((k & 1) == 0) ? bytes_d1 : bytes_d2;
1025 for(int j = 0; j < 3; j++) {
1026 src_offset_1 = k * 0xc000 + j * 0x4000;
1027 memcpy(&gvram_shadow[src_offset_1], &gvram[src_offset_1 + yoff_d], bytes_d);
1028 memcpy(&gvram_shadow[src_offset_1 + bytes_d], &gvram[src_offset_1], 0x4000 - bytes_d);
1034 uint32_t yoff_d = offset_point & 0x3fff;
1035 uint32_t bytes_d = 0x4000 - (offset_point & 0x3fff);
1036 uint32_t src_offset_1;
1037 for(int j = 0; j < 3; j++) {
1038 src_offset_1 = j * 0x4000;
1039 memcpy(&gvram_shadow[src_offset_1], &gvram[src_offset_1 + yoff_d], bytes_d);
1040 memcpy(&gvram_shadow[src_offset_1 + bytes_d], &gvram[src_offset_1], 0x4000 - bytes_d);
1046 // Timing values from XM7 . Thanks Ryu.
1047 void DISPLAY::event_callback(int event_id, int err)
1052 case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
1053 #if defined(_FM77AV_VARIANTS)
1063 case EVENT_FM7SUB_DISPLAY_NMI_OFF: // per 20.00ms
1066 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
1067 case EVENT_FM7SUB_HDISP:
1070 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x02, 0xff);
1071 if(display_mode == DISPLAY_MODE_8_400L) {
1073 if(displine < 400) f = true;
1076 if(displine < 200) f = true;
1079 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
1080 if(vram_wrote_table[displine] || vram_wrote) copy_vram_per_line();
1082 register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
1089 case EVENT_FM7SUB_HBLANK:
1091 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
1093 if(display_mode == DISPLAY_MODE_8_400L) {
1094 if((displine < 400)) f = true;
1096 if((displine < 200)) f = true;
1099 if(display_mode == DISPLAY_MODE_8_400L) {
1104 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id);
1108 case EVENT_FM7SUB_VSTART: // Call first.
1113 display_page_bak = display_page;
1115 // Parameter from XM7/VM/display.c , thanks, Ryu.
1116 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
1117 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x00, 0xff);
1118 if(vblank_count != 0) {
1119 if(display_mode == DISPLAY_MODE_8_400L) {
1120 usec = (0.98 + 16.4) * 1000.0;
1122 usec = (1.91 + 12.7) * 1000.0;
1124 register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id);
1126 if(display_mode == DISPLAY_MODE_8_400L) {
1127 usec = 930.0; // 939.0
1129 usec = 1840.0; // 1846.5
1131 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
1135 if(display_mode == DISPLAY_MODE_8_400L) {
1136 usec = 0.34 * 1000.0;
1138 usec = 1.52 * 1000.0;
1140 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
1145 case EVENT_FM7SUB_VSYNC:
1150 if(display_mode == DISPLAY_MODE_8_400L) {
1151 usec = 0.33 * 1000.0;
1153 usec = 0.51 * 1000.0;
1155 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x01, 0xff);
1156 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
1157 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
1158 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) {
1162 if(display_mode == DISPLAY_MODE_8_400L) lines = 400;
1163 for(int yy = 0; yy < lines; yy++) {
1164 if(vram_wrote_table[yy]) {
1165 vram_wrote_table[yy] = false;
1173 for(int yy = 0; yy < 400; yy++) vram_draw_table[yy] = true;
1175 vram_wrote_shadow = true;
1176 screen_update_flag = true;
1180 for(int yy = 0; yy < 400; yy++) {
1181 if(!vram_draw_table[yy]) {
1183 copy_vram_per_line();
1188 for(int yy = 0; yy < 400; yy++) {
1189 if(vram_draw_table[yy]) {
1190 vram_wrote_shadow = true;
1191 screen_update_flag = true;
1199 case EVENT_FM7SUB_CLR_BUSY:
1202 case EVENT_FM7SUB_CLR_CRTFLAG:
1208 void DISPLAY::event_frame()
1210 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
1215 for(yy = 0; yy < 400; yy++) {
1216 if(!vram_draw_table[yy]) {
1218 copy_vram_per_line();
1223 for(yy = 0; yy < 400; yy++) {
1224 if(vram_draw_table[yy]) {
1230 screen_update_flag = true;
1231 vram_wrote_shadow = true;
1240 void DISPLAY::event_vline(int v, int clock)
1242 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
1243 // if((v >= 200) || (v < 0)) return;
1245 if(vram_wrote_table[displine] || vram_wrote) {
1246 copy_vram_per_line();
1253 uint32_t DISPLAY::read_signal(int id)
1255 uint32_t retval = 0;
1257 case SIG_FM7_SUB_HALT:
1258 case SIG_DISPLAY_HALT:
1259 retval = (halt_flag) ? 0xffffffff : 0;
1261 case SIG_DISPLAY_BUSY:
1262 retval = (sub_busy) ? 0x80 : 0;
1264 case SIG_DISPLAY_MULTIPAGE:
1265 retval = multimode_accessmask;
1267 case SIG_DISPLAY_PLANES:
1270 #if defined(_FM77AV_VARIANTS)
1271 case SIG_DISPLAY_VSYNC:
1272 retval = (vsync) ? 0x01 : 0x00;
1274 case SIG_DISPLAY_DISPLAY:
1275 retval = (!hblank) ? 0x02: 0x00;
1277 case SIG_FM7_SUB_BANK: // Main: FD13
1278 retval = subrom_bank & 0x03;
1279 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1280 if(monitor_ram) retval |= 0x04;
1284 #if defined(_FM77AV_VARIANTS)
1285 case SIG_DISPLAY_MODE320:
1286 retval = (mode320) ? 0x40: 0x00;
1289 case SIG_DISPLAY_Y_HEIGHT:
1290 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1291 retval = (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200;
1296 case SIG_DISPLAY_X_WIDTH:
1297 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1298 retval = (mode320 || mode256k) ? 320 : 640;
1299 #elif defined(_FM77AV_VARIANTS)
1300 retval = (mode320) ? 320 : 640;
1311 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
1313 bool flag = ((data & mask) != 0);
1316 case SIG_FM7_SUB_HALT:
1321 //mainio->write_signal(SIG_FM7_SUB_HALT, data, mask);
1323 case SIG_DISPLAY_HALT:
1327 restart_subsystem();
1330 case SIG_FM7_SUB_CANCEL:
1332 cancel_request = true;
1336 case SIG_DISPLAY_CLOCK:
1340 #if defined(_FM77AV_VARIANTS)
1341 case SIG_FM7_SUB_BANK: // Main: FD13
1342 set_monitor_bank(data & 0xff);
1345 case SIG_DISPLAY_EXTRA_MODE: // FD04 bit 4, 3
1346 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1347 //printf("Wrote $FD04: %02x\n", data);
1349 int oldmode = display_mode;
1351 kanjisub = ((data & 0x20) == 0) ? true : false;
1352 mode256k = (((data & 0x10) != 0) && ((data & 0x08) != 0) ) ? true : false;
1353 mode400line = ((data & 0x08) == 0) ? true : false;
1354 ram_protect = ((data & 0x04) == 0) ? true : false;
1355 if(mode400line && !mode320) {
1356 display_mode = DISPLAY_MODE_8_400L;
1357 } else if(mode256k) {
1358 display_mode = DISPLAY_MODE_256k;
1360 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1362 if(oldmode != display_mode) {
1364 if(mode320 || mode256k) {
1365 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1366 for(y = 0; y < 200; y++) {
1367 pp = emu->get_screen_buffer(y);
1368 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype_t));
1370 } else if(display_mode == DISPLAY_MODE_8_400L) {
1371 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1372 for(y = 0; y < 400; y++) {
1373 pp = emu->get_screen_buffer(y);
1374 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1377 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1378 for(y = 0; y < 200; y++) {
1379 pp = emu->get_screen_buffer(y);
1380 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1384 alu->write_signal(SIG_ALU_X_WIDTH, (mode320 || mode256k) ? 40 : 80, 0xffff);
1385 alu->write_signal(SIG_ALU_Y_HEIGHT, (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200, 0xffff);
1386 alu->write_signal(SIG_ALU_400LINE, (display_mode == DISPLAY_MODE_8_400L) ? 0xff : 0x00, 0xff);
1387 frame_skip_count = 3;
1390 #elif defined(_FM77_VARIANTS)
1392 int oldmode = display_mode;
1393 kanjisub = ((data & 0x20) == 0) ? true : false;
1394 # if defined(_FM77L4)
1395 stat_400linecard = ((data & 0x20) != 0) ? true : false;
1396 mode400line = ((data & 0x08) != 0) ? false : true;
1397 if(mode400line && stat_400linecard) {
1398 display_mode = DISPLAY_MODE_8_400L_TEXT;
1399 } else if(stat_400linecard) {
1400 display_mode = DISPLAY_MODE_8_200L_TEXT;
1402 display_mode = DISPLAY_MODE_8_200L;
1408 #if defined(_FM77AV_VARIANTS)
1409 case SIG_DISPLAY_MODE320: // FD12 bit 6
1410 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1412 //printf("Wrote $FD12: %02x\n", data);
1413 int oldmode = display_mode;
1415 if(!mode320 && !mode256k) {
1416 //display_mode = (mode400line) ? DISPLAY_MODE_8_400L : DISPLAY_MODE_8_200L;
1417 display_mode = DISPLAY_MODE_8_200L;
1419 display_mode = (mode256k) ? DISPLAY_MODE_256k : DISPLAY_MODE_4096;
1421 if(oldmode != display_mode) {
1423 if(mode320 || mode256k) {
1424 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1425 for(y = 0; y < 200; y++) {
1426 pp = emu->get_screen_buffer(y);
1427 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype_t));
1429 } else { // 200 lines, 8 colors.
1430 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1431 for(y = 0; y < 200; y++) {
1432 pp = emu->get_screen_buffer(y);
1433 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1437 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1438 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1439 alu->write_signal(SIG_ALU_400LINE, 0x00, 0xff);
1440 //frame_skip_count = 3;
1448 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1449 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 320 * sizeof(scrntype_t));
1451 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1452 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 640 * sizeof(scrntype_t));
1455 display_mode = (mode320 == true) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1456 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1457 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1458 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
1463 case SIG_DISPLAY_MULTIPAGE:
1464 set_multimode(data);
1466 case SIG_FM7_SUB_KEY_MASK:
1467 if(firq_mask == flag) {
1468 do_firq(!flag && key_firq_req);
1472 case SIG_FM7_SUB_KEY_FIRQ:
1473 do_firq(flag & !(firq_mask));
1474 key_firq_req = flag;
1476 case SIG_FM7_SUB_USE_CLR:
1478 clr_count = data & 0x03;
1489 * Vram accessing functions moved to vram.cpp .
1492 uint8_t DISPLAY::read_mmio(uint32_t addr)
1494 uint32_t retval = 0xff;
1496 if(addr < 0xd400) return 0xff;
1498 #if !defined(_FM77AV_VARIANTS)
1499 raddr = (addr - 0xd400) & 0x000f;
1500 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1501 raddr = (addr - 0xd400) & 0x003f;
1502 #else // FM77AV40EX || FM77AV40SX
1503 raddr = (addr - 0xd400) & 0x00ff;
1506 case 0x00: // Read keyboard
1507 retval = (keyboard->read_data8(0x00) != 0) ? 0xff : 0x7f;
1509 case 0x01: // Read keyboard
1510 retval = keyboard->read_data8(0x01) & 0xff;
1512 case 0x02: // Acknowledge
1521 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1522 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1524 if(!kanjisub) return 0xff;
1525 # if !defined(_FM77_VARIANTS)
1527 return (uint8_t)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1530 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1533 if(!kanjisub) return 0xff;
1534 # if !defined(_FM77_VARIANTS)
1536 return (uint8_t)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1539 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1546 retval = set_vramaccess();
1552 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x01, 0x01);
1554 #if defined(_FM77AV_VARIANTS)
1557 retval = alu->read_data8(ALU_CMDREG);
1560 retval = alu->read_data8(ALU_LOGICAL_COLOR);
1563 retval = alu->read_data8(ALU_WRITE_MASKREG);
1566 retval = alu->read_data8(ALU_CMP_STATUS_REG);
1569 retval = alu->read_data8(ALU_BANK_DISABLE);
1571 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1572 case 0x2f: // VRAM BANK
1573 retval = 0xfc | (vram_bank & 0x03);
1578 retval = get_miscreg();
1582 retval = keyboard->read_data8(0x31);
1585 retval = keyboard->read_data8(0x32);
1591 return (uint8_t)retval;
1594 uint32_t DISPLAY::read_vram_data8(uint32_t addr)
1597 uint32_t page_offset = 0;
1598 uint32_t page_mask = 0x3fff;
1599 uint32_t color = (addr >> 14) & 0x03;
1602 #if defined(_FM77AV_VARIANTS)
1603 if (active_page != 0) {
1604 offset = offset_point_bank1;
1606 offset = offset_point;
1609 offset = offset_point;
1612 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1613 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1614 if(vram_active_block != 0) page_offset = 0x18000;
1616 if(display_mode == DISPLAY_MODE_8_400L) {
1617 if(addr >= 0x8000) return 0xff;
1618 color = vram_bank & 0x03;
1619 if(color > 2) color = 0;
1621 pagemod = 0x8000 * color;
1622 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1625 #if defined(_FM77AV40)
1627 page_offset = 0xc000 * (vram_bank & 0x03);
1629 page_offset = 0; // right?
1632 page_offset = 0xc000 * (vram_bank & 0x03);
1635 pagemod = addr & 0xe000;
1639 pagemod = addr & 0xe000;
1641 pagemod = addr & 0xc000;
1643 if(active_page != 0) {
1644 page_offset += 0xc000;
1647 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1649 #elif defined(_FM77AV_VARIANTS)
1651 if(active_page != 0) {
1652 page_offset += 0xc000;
1656 pagemod = addr & 0xe000;
1658 pagemod = addr & 0xc000;
1660 return gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1662 #elif defined(_FM77L4) //_FM77L4
1664 if(display_mode == DISPLAY_MODE_8_400L) {
1665 return (uint32_t)read_vram_l4_400l(addr, offset);
1667 pagemod = addr & 0xc000;
1668 return gvram[((addr + offset) & 0x3fff) | pagemod];
1672 #else // Others (77/7/8)
1673 pagemod = addr & 0xc000;
1674 return gvram[((addr + offset) & 0x3fff) | pagemod];
1678 void DISPLAY::write_dma_data8(uint32_t addr, uint32_t data)
1680 uint32_t raddr = addr & 0xffff;
1683 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1684 if(display_mode == DISPLAY_MODE_8_400L) {
1685 color = vram_bank & 0x03;
1686 if(color > 2) color = 0;
1690 color = (addr >> 14) & 0x03;
1693 if((multimode_accessmask & (1 << color)) != 0) return;
1695 return write_vram_data8(raddr, (uint8_t)data);
1697 return write_data8_main(raddr, (uint8_t)data);
1702 void DISPLAY::write_vram_data8(uint32_t addr, uint8_t data)
1705 uint32_t page_offset = 0;
1706 uint32_t page_mask = 0x3fff;
1707 uint32_t color = (addr >> 14) & 0x03;
1711 #if defined(_FM77AV_VARIANTS)
1712 if (active_page != 0) {
1713 offset = offset_point_bank1;
1715 offset = offset_point;
1718 offset = offset_point;
1721 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1722 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1723 if(vram_active_block != 0) page_offset = 0x18000;
1725 if(display_mode == DISPLAY_MODE_8_400L) {
1726 if(addr >= 0x8000) {
1729 color = vram_bank & 0x03;
1730 if(color > 2) color = 0;
1732 pagemod = 0x8000 * color;
1733 // Reduce data transfer.
1734 tdata = gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1736 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
1737 vram_wrote_table[(addr & 0x7fff) / 80] = true;
1739 } else if(display_mode == DISPLAY_MODE_256k) {
1740 #if defined(_FM77AV40)
1742 page_offset = 0xc000 * (vram_bank & 0x03);
1744 page_offset = 0; // right?
1747 page_offset = 0xc000 * (vram_bank & 0x03);
1750 pagemod = addr & 0xe000;
1751 tdata = gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1753 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1754 vram_wrote_table[(addr & page_mask) / 40] = true;
1757 } else if(display_mode == DISPLAY_MODE_4096) {
1758 if(active_page != 0) {
1759 page_offset += 0xc000;
1762 pagemod = addr & 0xe000;
1763 tdata = gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1765 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1766 vram_wrote_table[(addr & page_mask) / 40] = true;
1769 if(active_page != 0) {
1770 page_offset += 0xc000;
1773 pagemod = addr & 0xc000;
1774 tdata = gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1776 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1777 vram_wrote_table[(addr & page_mask) / 80] = true;
1780 #elif defined(_FM77AV_VARIANTS)
1781 if(display_mode == DISPLAY_MODE_4096) {
1782 if(active_page != 0) {
1783 page_offset = 0xc000;
1786 pagemod = addr & 0xe000;
1787 tdata = gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1789 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1790 vram_wrote_table[(addr & page_mask) / 40] = true;
1793 if(active_page != 0) {
1794 page_offset = 0xc000;
1797 pagemod = addr & 0xc000;
1798 tdata = gvram[(((addr + offset) & page_mask) | pagemod) + page_offset];
1800 gvram[(((addr + offset) & page_mask) | pagemod) + page_offset] = data;
1801 vram_wrote_table[(addr & page_mask) / 80] = true;
1804 #elif defined(_FM77L4) //_FM77L4
1806 if(display_mode == DISPLAY_MODE_8_400L) {
1807 write_vram_l4_400l(addr, data, offset);
1809 pagemod = addr & 0xc000;
1810 tdata = gvram[((addr + offset) & 0x3fff) | pagemod];
1812 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1813 vram_wrote_table[(addr & 0x3fff) / 80] = true;
1817 #else // Others (77/7/8)
1818 pagemod = addr & 0xc000;
1819 tdata = gvram[((addr + offset) & 0x3fff) | pagemod];
1821 gvram[((addr + offset) & 0x3fff) | pagemod] = data;
1822 vram_wrote_table[(addr & 0x3fff) / 80] = true;
1827 uint32_t DISPLAY::read_data8_main(uint32_t addr)
1830 if(addr < 0xc000) return 0xff;
1832 raddr = addr - 0xc000;
1833 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1835 if(console_ram_bank >= 1) {
1836 return submem_console_av40[((console_ram_bank - 1) << 12) + raddr];
1840 return console_ram[raddr];
1841 } else if(addr < 0xd380) {
1842 raddr = addr - 0xd000;
1843 return work_ram[raddr];
1844 } else if(addr < 0xd400) {
1845 raddr = addr - 0xd380;
1846 return shared_ram[raddr];
1847 } else if(addr < 0xd800) {
1848 #if defined(_FM77AV_VARIANTS)
1849 if(addr >= 0xd500) {
1850 return submem_hidden[addr - 0xd500];
1853 return read_mmio(addr);
1854 } else if(addr < 0x10000) {
1855 #if !defined(_FM77AV_VARIANTS)
1856 return subsys_c[addr - 0xd800];
1859 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1861 return submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)]; //FIXME
1864 return subsys_cg[(addr - 0xd800) + cgrom_bank * 0x800];
1865 } else if(addr < 0x10000) {
1866 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1868 return subsys_ram[addr - 0xe000];
1871 switch(subrom_bank_using & 3) {
1873 return subsys_c[addr - 0xd800];
1876 return subsys_a[addr - 0xe000];
1879 return subsys_b[addr - 0xe000];
1882 return subsys_cg[addr - 0xe000];
1891 uint32_t DISPLAY::read_dma_data8(uint32_t addr)
1893 uint32_t raddr = addr & 0xffff;
1896 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1897 if(display_mode == DISPLAY_MODE_8_400L) {
1898 color = vram_bank & 0x03;
1899 if(color > 2) color = 0;
1903 color = (addr >> 14) & 0x03;
1906 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1908 return read_vram_data8(raddr);
1910 return read_data8_main(raddr);
1915 uint32_t DISPLAY::read_data8(uint32_t addr)
1917 uint32_t raddr = addr;
1919 uint32_t color = (addr & 0x0c000) >> 14;
1921 #if defined(_FM77AV_VARIANTS)
1923 alu->read_data8(addr + ALU_WRITE_PROXY);
1926 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1927 if(display_mode == DISPLAY_MODE_8_400L) {
1928 color = vram_bank & 0x03;
1929 if(color > 2) color = 0;
1931 color = (addr >> 14) & 0x03;
1935 if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1937 return read_vram_data8(addr);
1938 } else if(addr < 0x10000) {
1939 return read_data8_main(addr);
1942 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
1943 return dpalette_data[addr - FM7_SUBMEM_OFFSET_DPALETTE];
1946 #if defined(_FM77AV_VARIANTS)
1948 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
1949 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
1950 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1951 if(display_mode == DISPLAY_MODE_8_400L) {
1952 uint32_t page_offset = 0;
1953 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1954 if(vram_active_block != 0) page_offset = 0x18000;
1956 color = (addr & 0x18000) >> 15;
1957 if(color > 2) color = 0;
1959 if (active_page != 0) {
1960 offset = offset_point_bank1 << 1;
1962 offset = offset_point << 1;
1964 if(color > 2) color = 0;
1965 uint32_t pagemod = 0x8000 * color;
1966 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
1969 return read_vram_data8(addr);
1976 * Vram accessing functions moved to vram.cpp .
1979 void DISPLAY::write_mmio(uint32_t addr, uint32_t data)
1983 if(addr < 0xd400) return;
1985 #if !defined(_FM77AV_VARIANTS)
1986 addr = (addr - 0xd400) & 0x000f;
1987 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1988 addr = (addr - 0xd400) & 0x003f;
1989 #else // FM77AV40EX || FM77AV40SX
1990 addr = (addr - 0xd400) & 0x00ff;
1992 io_w_latch[addr] = (uint8_t)data;
1994 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
1997 set_cyclesteal((uint8_t)data);
2000 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2001 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
2004 if(!kanjisub) return;
2005 kanjiaddr.w.h = 0x0000;
2006 kanjiaddr.b.h = (uint8_t) data;
2009 if(!kanjisub) return;
2010 kanjiaddr.w.h = 0x0000;
2011 kanjiaddr.b.l = (uint8_t)data;
2024 if(clr_count <= 0) {
2026 } else { // Read once when using clr_foo() to set busy flag.
2029 usec = (1000.0 * 1000.0) / 2000000.0;
2031 usec = (1000.0 * 1000.0) / 999000.0;
2033 if(!is_cyclesteal && vram_accessflag) usec = usec * 3.0;
2034 usec = (double)clr_count * usec;
2035 register_event(this, EVENT_FM7SUB_CLR_BUSY, usec, false, NULL); // NEXT CYCLE_
2042 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
2047 rval = (uint8_t)data;
2048 if(offset_changed[active_page]) {
2049 #if defined(_FM77AV_VARIANTS)
2050 if(active_page != 0) {
2051 tmp_offset_point[active_page].d = offset_point_bank1;
2053 tmp_offset_point[active_page].d = offset_point;
2056 tmp_offset_point[active_page].d = offset_point;
2059 tmp_offset_point[active_page].w.h = 0x0000;
2061 tmp_offset_point[active_page].b.h = rval;
2063 tmp_offset_point[active_page].b.l = rval;
2065 offset_changed[active_page] = !offset_changed[active_page];
2066 if(offset_changed[active_page]) {
2068 #if defined(_FM77AV_VARIANTS)
2069 if(active_page != 0) {
2071 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fff;
2073 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fe0;
2077 offset_point = tmp_offset_point[active_page].d & 0x007fff;
2079 offset_point = tmp_offset_point[active_page].d & 0x007fe0;
2083 offset_point = tmp_offset_point[active_page].d & 0x7fe0;
2087 #if defined(_FM77AV_VARIANTS)
2090 alu_write_cmdreg(data);
2093 alu_write_logical_color(data);
2096 alu_write_mask_reg(data);
2099 alu_write_disable_reg(data);
2102 alu_write_offsetreg_hi(data);
2105 alu_write_offsetreg_lo(data);
2108 alu_write_linepattern_hi(data);
2111 alu_write_linepattern_lo(data);
2113 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2115 console_ram_bank = (data & 0x18) >> 3;
2116 if(console_ram_bank > 2) console_ram_bank = 0;
2117 cgram_bank = data & 0x07;
2118 kanji_level2 = ((data & 0x80) == 0) ? false : true;
2120 case 0x2f: // VRAM BANK
2121 vram_bank = data & 0x03;
2122 if(vram_bank > 2) vram_bank = 0;
2132 keyboard->write_data8(0x31, data);
2134 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2136 vram_active_block = data & 0x01;
2137 if(vram_display_block != (((data & 0x10) != 0) ? 1 : 0)) vram_wrote = true;
2138 vram_display_block = ((data & 0x10) != 0) ? 1 : 0;
2143 tmpvar.d = window_xbegin * 8;
2146 tmpvar.b.h = data & 0x03;
2148 tmpvar.b.l = data & 0xf8;
2150 if(mode320 || mode256k) {
2151 if(tmpvar.d > 320) tmpvar.d = 320;
2153 if(tmpvar.d > 640) tmpvar.d = 640;
2155 window_xbegin = tmpvar.d / 8;
2160 tmpvar.d = window_xend * 8;
2163 tmpvar.b.h = data & 0x03;
2165 tmpvar.b.l = data & 0xf8;
2167 if(mode320 || mode256k) {
2168 if(tmpvar.d > 320) tmpvar.d = 320;
2170 if(tmpvar.d > 640) tmpvar.d = 640;
2172 window_xend = tmpvar.d / 8;
2177 tmpvar.d = window_low;
2180 tmpvar.b.h = data & 0x03;
2182 tmpvar.b.l = data & 0xff;
2184 if(display_mode == DISPLAY_MODE_8_400L) {
2185 if(tmpvar.d > 400) tmpvar.d = 400;
2188 if(tmpvar.d > 400) tmpvar.d = 400;
2190 window_low = tmpvar.d;
2195 tmpvar.d = window_high;
2198 tmpvar.b.h = data & 0x03;
2200 tmpvar.b.l = data & 0xff;
2202 if(display_mode == DISPLAY_MODE_8_400L) {
2203 if(tmpvar.d > 400) tmpvar.d = 400;
2206 if(tmpvar.d > 400) tmpvar.d = 400;
2208 window_high = tmpvar.d;
2214 #if defined(_FM77AV_VARIANTS)
2216 if((addr >= 0x13) && (addr <= 0x1a)) {
2217 alu_write_cmpdata_reg(addr - 0x13, data);
2218 } else if((addr >= 0x1c) && (addr <= 0x1e)) {
2219 alu_write_tilepaint_data(addr, data);
2220 } else if((addr >= 0x24) && (addr <= 0x2b)) {
2221 alu_write_line_position(addr - 0x24, data);
2228 void DISPLAY::write_data8_main(uint32_t addr, uint8_t data)
2232 uint32_t page_offset = 0x0000;
2234 if(addr < 0xc000) return;
2237 raddr = addr - 0xc000;
2238 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2240 if(console_ram_bank >= 1) {
2241 submem_console_av40[((console_ram_bank - 1) << 12) + raddr] = data;
2246 console_ram[raddr] = data;
2248 } else if(addr < 0xd380) {
2249 raddr = addr - 0xd000;
2250 work_ram[raddr] = data;
2252 } else if(addr < 0xd400) {
2253 raddr = addr - 0xd380;
2254 shared_ram[raddr] = data;
2256 } else if(addr < 0xd800) {
2257 #if defined(_FM77AV_VARIANTS)
2258 if(addr >= 0xd500) {
2259 submem_hidden[addr - 0xd500] = data;
2263 write_mmio(addr, data);
2265 } else if(addr < 0x10000) {
2266 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2267 if(ram_protect) return;
2270 submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)] = data; //FIXME
2272 subsys_ram[addr - 0xe000] = data;
2280 void DISPLAY::write_data8(uint32_t addr, uint32_t data)
2284 uint32_t page_offset = 0x0000;
2285 uint8_t val8 = data & 0xff;
2287 uint32_t color = (addr & 0xc000) >> 14;
2291 #if defined(_FM77AV_VARIANTS)
2293 alu->read_data8(addr + ALU_WRITE_PROXY);
2296 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2297 if(display_mode == DISPLAY_MODE_8_400L) {
2298 color = vram_bank & 0x03;
2299 if(color > 2) color = 0;
2304 if((multimode_accessmask & (1 << color)) != 0) return;
2306 write_vram_data8(addr, val8);
2308 } else if(addr < 0x10000) {
2309 write_data8_main(addr, val8);
2313 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
2314 set_dpalette(addr - FM7_SUBMEM_OFFSET_DPALETTE, val8);
2318 #if defined(_FM77AV_VARIANTS)
2320 else if(addr == FM7_SUBMEM_OFFSET_APALETTE_R) {
2321 set_apalette_r(val8);
2323 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_G) {
2324 set_apalette_g(val8);
2326 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_B) {
2327 set_apalette_b(val8);
2329 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_HI) {
2330 set_apalette_index_hi(val8);
2332 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_LO) {
2333 set_apalette_index_lo(val8);
2337 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
2338 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
2339 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2340 if(display_mode == DISPLAY_MODE_8_400L) {
2341 color = (addr & 0x18000) >> 15;
2342 if(color > 2) color = 0;
2344 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2345 if(vram_active_block != 0) page_offset = 0x18000;
2347 if(color > 2) color = 0;
2348 if (active_page != 0) {
2349 offset = offset_point_bank1 << 1;
2351 offset = offset_point << 1;
2353 pagemod = 0x8000 * color;
2354 tdata = gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset];
2355 if(tdata != (uint8_t)data) {
2356 gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset] = data;
2357 vram_wrote_table[(addr & 0x7fff) / 80] = true;
2361 write_vram_data8(addr, data);
2363 write_vram_data8(addr, data);
2365 //if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2372 uint32_t DISPLAY::read_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
2378 if((name == NULL) || (ptr == NULL)) return 0;
2379 s = create_local_path(name);
2380 if(s == NULL) return 0;
2382 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
2383 blocks = fio.Fread(ptr, size, 1);
2386 return blocks * size;
2390 void DISPLAY::initialize()
2394 screen_update_flag = true;
2395 memset(gvram, 0x00, sizeof(gvram));
2396 vram_wrote_shadow = false;
2397 memset(gvram_shadow, 0x00, sizeof(gvram_shadow));
2398 for(i = 0; i < 411; i++) vram_wrote_table[i] = false;
2399 for(i = 0; i < 411; i++) vram_draw_table[i] = false;
2401 memset(console_ram, 0x00, sizeof(console_ram));
2402 memset(work_ram, 0x00, sizeof(work_ram));
2403 memset(shared_ram, 0x00, sizeof(shared_ram));
2404 memset(subsys_c, 0xff, sizeof(subsys_c));
2406 diag_load_subrom_c = false;
2408 if(read_bios(_T("SUBSYS_8.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2409 this->out_debug_log(_T("SUBSYSTEM ROM READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2411 if(read_bios(_T("SUBSYS_C.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2412 this->out_debug_log(_T("SUBSYSTEM ROM Type C READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2414 #if defined(_FM77AV_VARIANTS)
2415 memset(subsys_a, 0xff, sizeof(subsys_a));
2416 memset(subsys_b, 0xff, sizeof(subsys_b));
2417 memset(subsys_cg, 0xff, sizeof(subsys_cg));
2418 memset(submem_hidden, 0x00, sizeof(submem_hidden));
2420 diag_load_subrom_a = false;
2421 if(read_bios(_T("SUBSYS_A.ROM"), subsys_a, 0x2000) >= 0x2000) diag_load_subrom_a = true;
2422 this->out_debug_log(_T("SUBSYSTEM ROM Type A READING : %s"), diag_load_subrom_a ? "OK" : "NG");
2424 diag_load_subrom_b = false;
2425 if(read_bios(_T("SUBSYS_B.ROM"), subsys_b, 0x2000) >= 0x2000) diag_load_subrom_b = true;
2426 this->out_debug_log(_T("SUBSYSTEM ROM Type B READING : %s"), diag_load_subrom_b ? "OK" : "NG");
2428 diag_load_subrom_cg = false;
2429 if(read_bios(_T("SUBSYSCG.ROM"), subsys_cg, 0x2000) >= 0x2000) diag_load_subrom_cg = true;
2430 this->out_debug_log(_T("SUBSYSTEM CG ROM READING : %s"), diag_load_subrom_cg ? "OK" : "NG");
2431 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2432 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2433 memset(subsys_ram, 0x00, sizeof(subsys_ram));
2434 memset(submem_cgram, 0x00, sizeof(submem_cgram));
2435 memset(submem_console_av40, 0x00, sizeof(submem_console_av40));
2439 #if defined(_FM77AV_VARIANTS)
2441 apalette_index.d = 0;
2442 for(i = 0; i < 4096; i++) {
2443 analog_palette_r[i] = i & 0x0f0;
2444 analog_palette_g[i] = (i & 0xf00) >> 4;
2445 analog_palette_b[i] = (i & 0x00f) << 4;
2449 #if defined(_FM77AV_VARIANTS)
2450 hblank_event_id = -1;
2451 hdisp_event_id = -1;
2452 vsync_event_id = -1;
2453 vstart_event_id = -1;
2460 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
2461 is_cyclesteal = true;
2463 is_cyclesteal = false;
2465 // emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2466 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2470 key_firq_req = false; //firq_mask = true;
2471 frame_skip_count = 3;
2472 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2473 palette_changed = true;
2474 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
2475 //register_vline_event(this);
2476 //register_frame_event(this);
2481 void DISPLAY::release()
2485 #define STATE_VERSION 7
2486 void DISPLAY::save_state(FILEIO *state_fio)
2488 state_fio->FputUint32_BE(STATE_VERSION);
2489 state_fio->FputInt32_BE(this_device_id);
2490 this->out_debug_log("Save State: DISPLAY : id=%d ver=%d\n", this_device_id, STATE_VERSION);
2494 state_fio->FputInt32_BE(clr_count);
2495 state_fio->FputBool(halt_flag);
2496 state_fio->FputInt32_BE(active_page);
2497 state_fio->FputBool(sub_busy);
2498 state_fio->FputBool(crt_flag);
2499 state_fio->FputBool(vram_wrote);
2500 state_fio->FputBool(is_cyclesteal);
2502 state_fio->FputBool(clock_fast);
2504 #if defined(_FM77AV_VARIANTS)
2505 state_fio->FputBool(subcpu_resetreq);
2506 state_fio->FputBool(power_on_reset);
2508 state_fio->FputBool(cancel_request);
2509 state_fio->FputBool(key_firq_req);
2511 state_fio->FputInt32_BE(display_mode);
2512 state_fio->FputUint32_BE(prev_clock);
2515 state_fio->Fwrite(dpalette_data, sizeof(dpalette_data), 1);
2516 state_fio->FputUint8(multimode_accessmask);
2517 state_fio->FputUint8(multimode_dispmask);
2519 state_fio->FputUint32_BE(offset_point);
2520 #if defined(_FM77AV_VARIANTS)
2521 state_fio->FputUint32_BE(offset_point_bank1);
2523 for(i = 0; i < 2; i++) {
2524 state_fio->FputUint32_BE(tmp_offset_point[i].d);
2525 state_fio->FputBool(offset_changed[i]);
2527 state_fio->FputBool(offset_77av);
2528 state_fio->FputBool(diag_load_subrom_c);
2531 state_fio->Fwrite(io_w_latch, sizeof(io_w_latch), 1);
2532 state_fio->Fwrite(console_ram, sizeof(console_ram), 1);
2533 state_fio->Fwrite(work_ram, sizeof(work_ram), 1);
2534 state_fio->Fwrite(shared_ram, sizeof(shared_ram), 1);
2535 state_fio->Fwrite(subsys_c, sizeof(subsys_c), 1);
2536 state_fio->Fwrite(gvram, sizeof(gvram), 1);
2537 state_fio->Fwrite(gvram_shadow, sizeof(gvram_shadow), 1);
2539 #if defined(_FM77_VARIANTS)
2540 state_fio->FputBool(kanjisub);
2541 state_fio->FputUint16_BE(kanjiaddr.w.l);
2542 # if defined(_FM77L4)
2543 state_fio->FputBool(mode400line);
2544 state_fio->FputBool(stat_400linecard);
2546 #elif defined(_FM77AV_VARIANTS)
2547 state_fio->FputBool(kanjisub);
2548 state_fio->FputUint16_BE(kanjiaddr.w.l);
2550 state_fio->FputBool(vblank);
2551 state_fio->FputBool(vsync);
2552 state_fio->FputBool(hblank);
2553 state_fio->FputInt32_BE(vblank_count);
2555 state_fio->FputBool(mode320);
2556 state_fio->FputInt8(display_page);
2557 state_fio->FputInt8(display_page_bak);
2558 state_fio->FputInt32_BE(cgrom_bank);
2559 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2560 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2561 state_fio->FputInt32_BE(vram_bank);
2564 state_fio->FputUint32_BE(displine);
2565 state_fio->FputUint8(subrom_bank);
2566 state_fio->FputUint8(subrom_bank_using);
2568 state_fio->FputBool(nmi_enable);
2569 state_fio->FputBool(use_alu);
2571 state_fio->FputUint8(apalette_index.b.l);
2572 state_fio->FputUint8(apalette_index.b.h);
2573 state_fio->Fwrite(analog_palette_r, sizeof(analog_palette_r), 1);
2574 state_fio->Fwrite(analog_palette_g, sizeof(analog_palette_g), 1);
2575 state_fio->Fwrite(analog_palette_b, sizeof(analog_palette_b), 1);
2578 state_fio->FputBool(diag_load_subrom_a);
2579 state_fio->FputBool(diag_load_subrom_b);
2580 state_fio->FputBool(diag_load_subrom_cg);
2582 state_fio->Fwrite(subsys_a, sizeof(subsys_a), 1);
2583 state_fio->Fwrite(subsys_b, sizeof(subsys_b), 1);
2584 state_fio->Fwrite(subsys_cg, sizeof(subsys_cg), 1);
2585 state_fio->Fwrite(submem_hidden, sizeof(submem_hidden), 1);
2586 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2587 state_fio->FputBool(mode400line);
2588 state_fio->FputBool(mode256k);
2590 state_fio->FputBool(monitor_ram);
2591 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2592 state_fio->FputUint16_BE(window_low);
2593 state_fio->FputUint16_BE(window_high);
2594 state_fio->FputUint16_BE(window_xbegin);
2595 state_fio->FputUint16_BE(window_xend);
2596 state_fio->FputBool(window_opened);
2598 state_fio->FputBool(kanji_level2);
2600 state_fio->FputUint8(vram_active_block);
2601 state_fio->FputUint8(vram_display_block);
2602 state_fio->FputUint8(console_ram_bank);
2603 state_fio->FputBool(ram_protect);
2605 state_fio->FputUint32_BE(cgram_bank);
2606 state_fio->Fwrite(subsys_ram, sizeof(subsys_ram), 1);
2607 state_fio->Fwrite(submem_cgram, sizeof(submem_cgram), 1);
2608 state_fio->Fwrite(submem_console_av40, sizeof(submem_console_av40), 1);
2614 state_fio->FputInt32_BE(nmi_event_id);
2615 #if defined(_FM77AV_VARIANTS)
2616 state_fio->FputInt32_BE(hblank_event_id);
2617 state_fio->FputInt32_BE(hdisp_event_id);
2618 state_fio->FputInt32_BE(vsync_event_id);
2619 state_fio->FputInt32_BE(vstart_event_id);
2621 state_fio->FputBool(firq_mask);
2622 state_fio->FputBool(vram_accessflag);
2623 state_fio->FputUint32_BE(frame_skip_count);
2627 bool DISPLAY::load_state(FILEIO *state_fio)
2630 uint32_t version = state_fio->FgetUint32_BE();
2631 if(this_device_id != state_fio->FgetInt32_BE()) {
2634 this->out_debug_log("Load State: DISPLAY : id=%d ver=%d\n", this_device_id, version);
2639 clr_count = state_fio->FgetInt32_BE();
2640 halt_flag = state_fio->FgetBool();
2641 active_page = state_fio->FgetInt32_BE();
2642 sub_busy = state_fio->FgetBool();
2643 crt_flag = state_fio->FgetBool();
2644 vram_wrote = state_fio->FgetBool();
2645 crt_flag_bak = true;
2646 for(i = 0; i < 411; i++) vram_wrote_table[i] = true;
2647 for(i = 0; i < 411; i++) vram_draw_table[i] = true;
2648 is_cyclesteal = state_fio->FgetBool();
2650 clock_fast = state_fio->FgetBool();
2652 #if defined(_FM77AV_VARIANTS)
2653 subcpu_resetreq = state_fio->FgetBool();
2654 power_on_reset = state_fio->FgetBool();
2656 cancel_request = state_fio->FgetBool();
2657 key_firq_req = state_fio->FgetBool();
2659 display_mode = state_fio->FgetInt32_BE();
2660 prev_clock = state_fio->FgetUint32_BE();
2663 for(addr = 0; addr < 8; addr++) set_dpalette(addr, addr);
2665 state_fio->Fread(dpalette_data, sizeof(dpalette_data), 1);
2666 for(addr = 0; addr < 8; addr++) set_dpalette(addr, dpalette_data[addr]);
2667 multimode_accessmask = state_fio->FgetUint8();
2668 multimode_dispmask = state_fio->FgetUint8();
2670 offset_point = state_fio->FgetUint32_BE();
2671 #if defined(_FM77AV_VARIANTS)
2672 offset_point_bank1 = state_fio->FgetUint32_BE();
2674 for(i = 0; i < 2; i++) {
2675 tmp_offset_point[i].d = state_fio->FgetUint32_BE();
2676 offset_changed[i] = state_fio->FgetBool();
2678 offset_77av = state_fio->FgetBool();
2679 diag_load_subrom_c = state_fio->FgetBool();
2681 state_fio->Fread(io_w_latch, sizeof(io_w_latch), 1);
2682 state_fio->Fread(console_ram, sizeof(console_ram), 1);
2683 state_fio->Fread(work_ram, sizeof(work_ram), 1);
2684 state_fio->Fread(shared_ram, sizeof(shared_ram), 1);
2685 state_fio->Fread(subsys_c, sizeof(subsys_c), 1);
2686 state_fio->Fread(gvram, sizeof(gvram), 1);
2687 state_fio->Fread(gvram_shadow, sizeof(gvram_shadow), 1);
2688 #if defined(_FM77_VARIANTS)
2689 kanjisub = state_fio->FgetBool();
2691 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2692 # if defined(_FM77L4)
2693 mode400line = state_fio->FgetBool();
2694 stat_400linecard = state_fio->FgetBool();
2696 #elif defined(_FM77AV_VARIANTS)
2697 kanjisub = state_fio->FgetBool();
2699 kanjiaddr.w.l = state_fio->FgetUint16_BE();
2701 vblank = state_fio->FgetBool();
2702 vsync = state_fio->FgetBool();
2703 hblank = state_fio->FgetBool();
2704 vblank_count = state_fio->FgetInt32_BE();
2706 mode320 = state_fio->FgetBool();
2707 display_page = state_fio->FgetInt8();
2708 display_page_bak = state_fio->FgetInt8();
2709 cgrom_bank = state_fio->FgetInt32_BE();
2710 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2711 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2712 vram_bank = state_fio->FgetInt32_BE();
2714 screen_update_flag = true;
2715 displine = state_fio->FgetUint32_BE();
2716 subrom_bank = state_fio->FgetUint8();
2717 subrom_bank_using = state_fio->FgetUint8();
2719 nmi_enable = state_fio->FgetBool();
2720 use_alu = state_fio->FgetBool();
2722 apalette_index.b.l = state_fio->FgetUint8();
2723 apalette_index.b.h = state_fio->FgetUint8();
2725 state_fio->Fread(analog_palette_r, sizeof(analog_palette_r), 1);
2726 state_fio->Fread(analog_palette_g, sizeof(analog_palette_g), 1);
2727 state_fio->Fread(analog_palette_b, sizeof(analog_palette_b), 1);
2728 for(i = 0; i < 4096; i++) calc_apalette(i);
2730 diag_load_subrom_a = state_fio->FgetBool();
2731 diag_load_subrom_b = state_fio->FgetBool();
2732 diag_load_subrom_cg = state_fio->FgetBool();
2734 state_fio->Fread(subsys_a, sizeof(subsys_a), 1);
2735 state_fio->Fread(subsys_b, sizeof(subsys_b), 1);
2736 state_fio->Fread(subsys_cg, sizeof(subsys_cg), 1);
2737 state_fio->Fread(submem_hidden, sizeof(submem_hidden), 1);
2739 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2740 mode400line = state_fio->FgetBool();
2741 mode256k = state_fio->FgetBool();
2743 monitor_ram = state_fio->FgetBool();
2744 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2745 window_low = state_fio->FgetUint16_BE();
2746 window_high = state_fio->FgetUint16_BE();
2747 window_xbegin = state_fio->FgetUint16_BE();
2748 window_xend = state_fio->FgetUint16_BE();
2749 window_opened = state_fio->FgetBool();
2751 kanji_level2 = state_fio->FgetBool();
2753 vram_active_block = state_fio->FgetUint8();
2754 vram_display_block = state_fio->FgetUint8();
2755 console_ram_bank = state_fio->FgetUint8();
2756 ram_protect = state_fio->FgetBool();
2758 cgram_bank = state_fio->FgetUint32_BE();
2759 state_fio->Fread(subsys_ram, sizeof(subsys_ram), 1);
2760 state_fio->Fread(submem_cgram, sizeof(submem_cgram), 1);
2761 state_fio->Fread(submem_console_av40, sizeof(submem_console_av40), 1);
2764 palette_changed = true;
2765 vram_wrote_shadow = true; // Force Draw
2766 this->draw_screen();
2767 if(version == 1) return true;
2769 if(version >= 2) { //V2
2770 nmi_event_id = state_fio->FgetInt32_BE();
2771 #if defined(_FM77AV_VARIANTS)
2772 hblank_event_id = state_fio->FgetInt32_BE();
2773 hdisp_event_id = state_fio->FgetInt32_BE();
2774 vsync_event_id = state_fio->FgetInt32_BE();
2775 vstart_event_id = state_fio->FgetInt32_BE();
2777 firq_mask = state_fio->FgetBool();
2778 vram_accessflag = state_fio->FgetBool();
2779 frame_skip_count = state_fio->FgetUint32_BE();
2781 if(version == STATE_VERSION) return true;