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;
70 for(i = 0; i < 4; i++) {
71 multimode_accessflags[i] = ((multimode_accessmask & (1 << i)) != 0) ? true : false;
72 multimode_dispflags[i] = ((multimode_dispmask & (1 << i)) != 0) ? true : false;
75 //cancel_request = false;
76 switch(config.cpu_type){
85 prev_clock = SUBCLOCK_NORMAL;
87 prev_clock = SUBCLOCK_SLOW;
92 for(i = 0; i < 2; i++) {
93 offset_changed[i] = true;
94 tmp_offset_point[i].d = 0;
97 vram_wrote_shadow = true;
98 for(i = 0; i < 411 * 5; i++) vram_wrote_table[i] = true;
99 for(i = 0; i < 411; i++) vram_draw_table[i] = true;
103 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
109 if(hblank_event_id >= 0) cancel_event(this, hblank_event_id);
110 if(hdisp_event_id >= 0) cancel_event(this, hdisp_event_id);
111 if(vsync_event_id >= 0) cancel_event(this, vsync_event_id);
112 if(vstart_event_id >= 0) cancel_event(this, vstart_event_id);
113 hblank_event_id = -1;
116 vstart_event_id = -1;
117 if(display_mode == DISPLAY_MODE_8_400L) {
118 usec = 0.33 * 1000.0;
120 usec = 0.51 * 1000.0;
123 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
124 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
125 mainio->write_signal(SIG_DISPLAY_VSYNC, 0xff, 0xff);
127 #if defined(_FM77AV_VARIANTS)
129 offset_point_bank1 = 0;
131 display_page_bak = 0;
133 subcpu_resetreq = false;
134 subrom_bank_using = subrom_bank;
139 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
141 vram_display_block = 0;
142 vram_active_block = 0;
144 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
149 window_opened = false;
154 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
155 alu->write_signal(SIG_ALU_X_WIDTH, (mode320 || mode256k) ? 40 : 80, 0xffff);
156 alu->write_signal(SIG_ALU_Y_HEIGHT, (display_mode == DISPLAY_MODE_8_400L) ? 400: 200, 0xffff);
157 alu->write_signal(SIG_ALU_400LINE, (display_mode == DISPLAY_MODE_8_400L) ? 0xffffffff : 0, 0xffffffff);
159 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
160 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
161 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
163 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
164 alu->write_signal(SIG_ALU_PLANES, 3, 3);
167 for(i = 0; i < 8; i++) set_dpalette(i, i);
168 do_firq(!firq_mask && key_firq_req);
170 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
172 kanjiaddr.d = 0x00000000;
173 # if defined(_FM77L4)
175 stat_400linecard = false;
180 frame_skip_count_draw = 3;
181 frame_skip_count_transfer = 3;
182 need_transfer_line = true;
183 setup_display_mode();
187 void DISPLAY::reset()
190 memset(io_w_latch, 0xff, sizeof(io_w_latch));
192 vram_accessflag = true;
193 display_mode = DISPLAY_MODE_8_200L;
195 screen_update_flag = true;
198 cancel_request = false;
199 #if defined(_FM77AV_VARIANTS)
201 apalette_index.d = 0;
202 for(i = 0; i < 4096; i++) {
203 analog_palette_r[i] = i & 0x0f0;
204 analog_palette_g[i] = (i & 0xf00) >> 4;
205 analog_palette_b[i] = (i & 0x00f) << 4;
210 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
217 #elif defined(_FM77L4)
220 #if !defined(FIXED_FRAMEBUFFER_SIZE)
221 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
223 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
225 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
226 key_firq_req = false; //firq_mask = true;
230 #if defined(_FM77AV_VARIANTS)
231 power_on_reset = false;
232 for(i = 0; i < 411 * 5; i++) vram_wrote_table[i] = false;
236 for(i = 0; i < 8; i++) set_dpalette(i, i);
237 //multimode_accessmask = 0x00;
238 //multimode_dispmask = 0x00;
239 //for(i = 0; i < 4; i++) {
240 // multimode_accessflags[i] = ((multimode_accessmask & (1 << color)) != 0) ? true : false;
241 // multimode_dispflags[i] = ((multimode_dispmask & (1 << color)) != 0) ? true : false;
247 if(nmi_event_id >= 0) cancel_event(this, nmi_event_id);
248 register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
249 subcpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
250 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
254 void DISPLAY::setup_display_mode(void)
256 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
257 if(display_mode == DISPLAY_MODE_8_400L) {
258 page_offset = 0x0000;
259 pagemod_mask = 0x18000;
261 } else if(display_mode == DISPLAY_MODE_256k) {
262 if(active_page != 0) {
263 page_offset = 0xc000;
265 page_offset = 0x0000;
267 pagemod_mask = 0xe000;
269 } else if(display_mode == DISPLAY_MODE_4096) {
270 if(active_page != 0) {
271 page_offset = 0xc000;
273 page_offset = 0x0000;
275 pagemod_mask = 0xe000;
278 if(active_page != 0) {
279 page_offset = 0xc000;
281 page_offset = 0x0000;
283 pagemod_mask = 0xc000;
286 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
287 if(vram_active_block != 0) page_offset += 0x18000;
289 #elif defined(_FM77AV_VARIANTS)
292 pagemod_mask = 0xe000;
293 } else { // 640x200, 8colors
295 pagemod_mask = 0xc000;
297 if(active_page != 0) {
298 page_offset = 0xc000;
300 page_offset = 0x0000;
302 #elif defined(_FM77L4)
303 if(display_mode == DISPLAY_MODE_8_400L) {
305 pagemod_mask = 0xe000;
306 } else { // 640x200, 8colors
308 pagemod_mask = 0xc000;
310 page_offset = 0x0000;
312 page_offset = 0x0000;
313 pagemod_mask = 0xc000;
317 void DISPLAY::update_config()
321 is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false;
327 * Vram accessing functions moved to vram.cpp .
330 void DISPLAY::do_irq(bool flag)
332 subcpu->write_signal(SIG_CPU_IRQ, flag ? 1: 0, 1);
335 void DISPLAY::do_firq(bool flag)
337 subcpu->write_signal(SIG_CPU_FIRQ, flag ? 1: 0, 1);
340 void DISPLAY::do_nmi(bool flag)
342 #if defined(_FM77AV_VARIANTS)
343 if(!nmi_enable) flag = false;
345 subcpu->write_signal(SIG_CPU_NMI, flag ? 1 : 0, 1);
348 void DISPLAY::set_multimode(uint8_t val)
351 multimode_accessmask = val & 0x07;
352 multimode_dispmask = (val & 0x70) >> 4;
353 for(int i = 0; i < 4; i++) {
354 multimode_accessflags[i] = ((multimode_accessmask & (1 << i)) != 0) ? true : false;
355 multimode_dispflags[i] = ((multimode_dispmask & (1 << i)) != 0) ? true : false;
358 # if defined(_FM77AV_VARIANTS)
359 alu->write_signal(SIG_ALU_MULTIPAGE, multimode_accessmask, 0x07);
364 uint8_t DISPLAY::get_multimode(void)
370 val = multimode_accessmask & 0x07;
371 val |= ((multimode_dispmask << 4) & 0x70);
377 uint8_t DISPLAY::get_cpuaccessmask(void)
379 return multimode_accessmask & 0x07;
382 void DISPLAY::set_dpalette(uint32_t addr, uint8_t val)
386 dpalette_data[addr] = val | 0xf8; //0b11111000;
387 b = ((val & 0x01) != 0x00)? 255 : 0x00;
388 r = ((val & 0x02) != 0x00)? 255 : 0x00;
389 g = ((val & 0x04) != 0x00)? 255 : 0x00;
391 dpalette_pixel[addr] = RGB_COLOR(r, g, b);
392 palette_changed = true;
395 uint8_t DISPLAY::get_dpalette(uint32_t addr)
403 data = dpalette_data[addr];
408 void DISPLAY::halt_subcpu(void)
410 //subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
411 subcpu->write_signal(SIG_CPU_HALTREQ, 0x01, 0x01);
414 void DISPLAY::go_subcpu(void)
416 subcpu->write_signal(SIG_CPU_HALTREQ, 0x00, 0x01);
419 void DISPLAY::enter_display(void)
423 subclock = SUBCLOCK_NORMAL;
425 subclock = SUBCLOCK_SLOW;
427 if(!is_cyclesteal && vram_accessflag) {
428 subclock = subclock / 3;
430 if(prev_clock != subclock) p_vm->set_cpu_clock(subcpu, subclock);
431 prev_clock = subclock;
434 void DISPLAY::leave_display(void)
438 void DISPLAY::halt_subsystem(void)
444 void DISPLAY::restart_subsystem(void)
447 #if defined(_FM77AV_VARIANTS)
448 if(subcpu_resetreq) {
449 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
451 power_on_reset = true;
452 subcpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
453 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
455 do_firq(!firq_mask && key_firq_req);
462 void DISPLAY::set_crtflag(void)
469 void DISPLAY::reset_crtflag(void)
476 uint8_t DISPLAY::acknowledge_irq(void)
478 cancel_request = false;
484 uint8_t DISPLAY::beep(void)
486 mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
487 return 0xff; // True?
492 uint8_t DISPLAY::attention_irq(void)
494 mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
499 void DISPLAY::set_cyclesteal(uint8_t val)
502 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
506 is_cyclesteal = true;
508 is_cyclesteal = false;
516 uint8_t DISPLAY::set_vramaccess(void)
518 vram_accessflag = true;
523 void DISPLAY::reset_vramaccess(void)
525 vram_accessflag = false;
529 uint8_t DISPLAY::reset_subbusy(void)
536 void DISPLAY::set_subbusy(void)
542 #if defined(_FM77AV_VARIANTS)
544 void DISPLAY::alu_write_cmdreg(uint32_t val)
546 alu->write_data8(ALU_CMDREG, val);
547 if((val & 0x80) != 0) {
555 void DISPLAY::alu_write_logical_color(uint8_t val)
557 uint32_t data = (uint32_t)val;
558 alu->write_data8(ALU_LOGICAL_COLOR, data);
562 void DISPLAY::alu_write_mask_reg(uint8_t val)
564 uint32_t data = (uint32_t)val;
565 alu->write_data8(ALU_WRITE_MASKREG, data);
569 void DISPLAY::alu_write_cmpdata_reg(int addr, uint8_t val)
571 uint32_t data = (uint32_t)val;
573 alu->write_data8(ALU_CMPDATA_REG + addr, data);
577 void DISPLAY::alu_write_disable_reg(uint8_t val)
579 uint32_t data = (uint32_t)val;
580 alu->write_data8(ALU_BANK_DISABLE, data);
584 void DISPLAY::alu_write_tilepaint_data(uint32_t addr, uint8_t val)
586 uint32_t data = (uint32_t)val;
589 alu->write_data8(ALU_TILEPAINT_B, data);
592 alu->write_data8(ALU_TILEPAINT_R, data);
595 alu->write_data8(ALU_TILEPAINT_G, data);
598 //alu->write_data8(ALU_TILEPAINT_L, 0xff);
604 void DISPLAY::alu_write_offsetreg_hi(uint8_t val)
606 alu->write_data8(ALU_OFFSET_REG_HIGH, val & 0x7f);
610 void DISPLAY::alu_write_offsetreg_lo(uint8_t val)
612 alu->write_data8(ALU_OFFSET_REG_LO, val);
616 void DISPLAY::alu_write_linepattern_hi(uint8_t val)
618 alu->write_data8(ALU_LINEPATTERN_REG_HIGH, val);
622 void DISPLAY::alu_write_linepattern_lo(uint8_t val)
624 alu->write_data8(ALU_LINEPATTERN_REG_LO, val);
628 void DISPLAY::alu_write_line_position(int addr, uint8_t val)
630 uint32_t data = (uint32_t)val;
633 alu->write_data8(ALU_LINEPOS_START_X_HIGH, data & 0x03);
636 alu->write_data8(ALU_LINEPOS_START_X_LOW, data);
639 alu->write_data8(ALU_LINEPOS_START_Y_HIGH, data & 0x01);
642 alu->write_data8(ALU_LINEPOS_START_Y_LOW, data);
645 alu->write_data8(ALU_LINEPOS_END_X_HIGH, data & 0x03);
648 alu->write_data8(ALU_LINEPOS_END_X_LOW, data);
651 alu->write_data8(ALU_LINEPOS_END_Y_HIGH, data & 0x01);
654 alu->write_data8(ALU_LINEPOS_END_Y_LOW, data);
660 uint8_t DISPLAY::get_miscreg(void)
665 if(!hblank) ret |= 0x80;
666 if(vsync) ret |= 0x04;
667 if(alu->read_signal(SIG_ALU_BUSYSTAT) == 0) ret |= 0x10;
668 if(power_on_reset) ret |= 0x01;
673 void DISPLAY::set_miscreg(uint8_t val)
675 int old_display_page = display_page;
677 nmi_enable = ((val & 0x80) == 0) ? true : false;
678 if(!nmi_enable) do_nmi(false);
680 if((val & 0x40) == 0) {
685 if(display_page != old_display_page) {
688 active_page = ((val & 0x20) == 0) ? 0 : 1;
689 if((val & 0x04) == 0) {
694 cgrom_bank = val & 0x03;
695 setup_display_mode();
699 void DISPLAY::set_monitor_bank(uint8_t var)
701 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
702 if((var & 0x04) != 0){
708 subrom_bank = var & 0x03;
711 subcpu_resetreq = false;
712 power_on_reset = true;
713 firq_mask = (mainio->read_signal(FM7_MAINIO_KEYBOARDIRQ_MASK) != 0) ? false : true;
715 subcpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
716 subcpu->write_signal(SIG_CPU_BUSREQ, 0, 1); // Is needed?
718 do_firq(!firq_mask && key_firq_req);
720 subcpu_resetreq = true;
726 void DISPLAY::set_apalette_index_hi(uint8_t val)
728 apalette_index.b.h = val & 0x0f;
732 void DISPLAY::set_apalette_index_lo(uint8_t val)
734 apalette_index.b.l = val;
737 void DISPLAY::calc_apalette(uint16_t idx)
741 g = analog_palette_g[idx];
742 r = analog_palette_r[idx];
743 b = analog_palette_b[idx];
744 if(g != 0) g |= 0x0f;
745 if(r != 0) r |= 0x0f;
746 if(b != 0) b |= 0x0f;
747 analog_palette_pixel[idx] = RGB_COLOR(r, g, b);
751 void DISPLAY::set_apalette_b(uint8_t val)
755 index = apalette_index.w.l;
756 tmp = (val & 0x0f) << 4;
757 if(analog_palette_b[index] != tmp) {
758 analog_palette_b[index] = tmp;
759 calc_apalette(index);
760 palette_changed = true;
765 void DISPLAY::set_apalette_r(uint8_t val)
769 index = apalette_index.w.l;
770 tmp = (val & 0x0f) << 4;
771 if(analog_palette_r[index] != tmp) {
772 analog_palette_r[index] = tmp;
773 calc_apalette(index);
774 palette_changed = true;
779 void DISPLAY::set_apalette_g(uint8_t val)
783 index = apalette_index.w.l;
784 tmp = (val & 0x0f) << 4;
785 if(analog_palette_g[index] != tmp) {
786 analog_palette_g[index] = tmp;
787 calc_apalette(index);
788 palette_changed = true;
792 #endif // _FM77AV_VARIANTS
795 void DISPLAY::copy_vram_blank_area(void)
799 void DISPLAY::copy_vram_per_line(int begin, int end)
808 uint32_t src_offset_d1;
809 uint32_t src_offset_d2;
810 uint32_t src_offset_d;
815 uint32_t addr_d1, addr_d2;
819 //int dline = (int)displine - 1;
820 int dline = (int)displine;
822 if((begin < 0) || (begin > 4)) return;
823 if((end < 0) || (end > 4)) return;
824 if(begin > end) return;
825 if(dline < 0) return;
827 sectors = end - begin + 1;
829 if(display_mode == DISPLAY_MODE_8_400L) {
830 if(dline >= 400) return;
832 if(dline >= 200) return;
834 #if defined(_FM77AV_VARIANTS)
835 yoff_d1 = offset_point;
836 yoff_d2 = offset_point_bank1;
837 if(display_mode == DISPLAY_MODE_4096) {
838 src_offset = dline * 40 + begin * 8;
839 sectors = sectors * 8;
840 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
843 addr_d1 = (src_offset + yoff_d1) & 0x1fff;
844 addr_d2 = (src_offset + yoff_d2) & 0x1fff;
845 bytes_d1 = 0x2000 - addr_d1;
846 bytes_d2 = 0x2000 - addr_d2;
847 for(k = 0; k < pages; k++) {
849 for(i = 0; i < 3; i++) {
850 for(j = 0; j < 2; j++) {
851 uint32_t _addr_base = src_base + src_offset + poff;
852 if(bytes_d1 < sectors) {
853 my_memcpy(&gvram_shadow[_addr_base],
854 &gvram[addr_d1 + src_base + poff],
856 my_memcpy(&gvram_shadow[_addr_base + bytes_d1],
857 &gvram[src_base + poff],
860 my_memcpy(&gvram_shadow[_addr_base],
861 &gvram[addr_d1 + src_base + poff],
864 _addr_base += 0xc000;
865 if(bytes_d2 < sectors) {
866 my_memcpy(&gvram_shadow[_addr_base],
867 &gvram[addr_d2 + src_base + poff + 0xc000],
869 my_memcpy(&gvram_shadow[_addr_base + bytes_d2],
870 &gvram[src_base + poff + 0xc000],
873 my_memcpy(&gvram_shadow[_addr_base],
874 &gvram[addr_d2 + src_base + poff + 0xc000],
879 src_base = (i + 1) * 0x4000;
883 vram_draw_table[dline] = true;
884 for(int ii = begin; ii <= end; ii++) vram_wrote_table[(dline * 5) + ii] = false;
886 # if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40)
887 else if(display_mode == DISPLAY_MODE_256k) {
888 src_offset = dline * 40 + begin * 8;
889 sectors = sectors * 8;
891 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
893 #elif defined(_FM77AV40)
898 src_offset_d1 = (src_offset + yoff_d1) & 0x1fff;
899 src_offset_d2 = (src_offset + yoff_d2) & 0x1fff;
900 bytes_d1 = 0x2000 - ((src_offset + yoff_d1) & 0x1fff);
901 bytes_d2 = 0x2000 - ((src_offset + yoff_d2) & 0x1fff);
902 for(k = 0; k < pages; k++) {
903 for(i = 0; i < 3; i++) {
904 for(j = 0; j < 2; j++) {
906 src_base = i * 0x4000 + j * 0x2000 + k * 0xc000;
907 src_offset_d = src_offset_d1;
910 src_base = i * 0x4000 + j * 0x2000 + k * 0xc000;
911 src_offset_d = src_offset_d2;
914 if(bytes_d < sectors) {
915 my_memcpy(&gvram_shadow[src_offset + src_base],
916 &gvram[src_offset_d + src_base],
918 my_memcpy(&gvram_shadow[src_offset + bytes_d + src_base],
922 my_memcpy(&gvram_shadow[src_offset + src_base],
923 &gvram[src_offset_d + src_base],
929 vram_draw_table[dline] = true;
930 for(int ii = begin; ii <= end; ii++) vram_wrote_table[(dline * 5) + ii] = false;
932 else if(display_mode == DISPLAY_MODE_8_400L) {
933 src_offset = dline * 80 + begin * 16;
934 sectors = sectors * 16;
935 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
938 if(display_page_bak == 1) { // Is this dirty?
943 yoff_d = (yoff_d << 1) & 0x7fff;
944 src_offset_d = (src_offset + yoff_d) & 0x7fff;
945 bytes_d = 0x8000 - ((src_offset + yoff_d) & 0x7fff);
946 for(i = 0; i < pages; i++) {
947 for(j = 0; j < 3; j++) {
948 src_base = i * 0x18000 + j * 0x8000;
949 if(bytes_d < sectors) {
951 my_memcpy(&gvram_shadow[src_offset + src_base],
952 &gvram[src_offset_d + src_base],
955 my_memcpy(&gvram_shadow[src_offset + bytes_d + src_base],
959 my_memcpy(&gvram_shadow[src_offset + src_base + poff],
960 &gvram[src_offset_d + src_base],
965 vram_draw_table[dline] = true;
966 for(int ii = begin; ii <= end; ii++) vram_wrote_table[(dline * 5) + ii] = false;
970 src_offset = dline * 80 + begin * 16;
971 sectors = sectors * 16;
972 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
974 #elif defined(_FM77AV40)
976 #elif defined(_FM77AV_VARIANTS)
982 src_offset_d1 = (src_offset + yoff_d1) & 0x3fff;
983 src_offset_d2 = (src_offset + yoff_d2) & 0x3fff;
984 bytes_d1 = 0x4000 - ((src_offset + yoff_d1) & 0x3fff);
985 bytes_d2 = 0x4000 - ((src_offset + yoff_d2) & 0x3fff);
986 for(i = 0; i < pages; i++) {
988 src_offset_d = src_offset_d1;
991 src_offset_d = src_offset_d2;
995 for(j = 0; j < 3; j++) {
996 if(bytes_d < sectors) {
997 my_memcpy(&gvram_shadow[src_offset + src_base + poff],
998 &gvram[src_offset_d + src_base + poff],
1000 my_memcpy(&gvram_shadow[src_offset + bytes_d + src_base + poff],
1001 &gvram[src_base + poff],
1004 my_memcpy(&gvram_shadow[src_offset + src_base + poff],
1005 &gvram[src_offset_d + src_base + poff],
1012 vram_draw_table[dline] = true;
1013 for(int ii = begin; ii <= end; ii++) vram_wrote_table[(dline * 5) + ii] = false;
1014 //vram_wrote_table[dline] = false;
1018 src_offset = dline * 80 + begin * 16;
1019 sectors = sectors * 16;
1022 yoff_d = offset_point;
1023 src_offset_d = (src_offset + yoff_d) & 0x3fff;
1024 bytes_d = 0x4000 - ((src_offset + yoff_d) & 0x3fff);
1025 for(j = 0; j < 3; j++) {
1026 src_base = j * 0x4000;
1027 if(bytes_d < sectors) {
1028 my_memcpy(&gvram_shadow[src_offset + src_base + poff],
1029 &gvram[src_offset_d + src_base + poff],
1031 my_memcpy(&gvram_shadow[src_offset + bytes_d + src_base + poff],
1032 &gvram[src_base + poff],
1035 my_memcpy(&gvram_shadow[src_offset + src_base + poff],
1036 &gvram[src_offset_d + src_base + poff],
1040 vram_draw_table[dline] = true;
1041 for(int ii = begin; ii <= end; ii++) vram_wrote_table[(dline * 5) + ii] = false;
1042 //vram_wrote_table[dline] = false;
1048 void DISPLAY::copy_vram_all()
1050 #if defined(_FM77AV_VARIANTS)
1051 uint32_t yoff_d1 = offset_point;
1052 uint32_t yoff_d2 = offset_point_bank1;
1053 uint32_t src_offset_1, src_offset_2;
1055 if(display_mode == DISPLAY_MODE_4096) {
1056 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1061 uint32_t bytes_d1 = 0x2000 - (yoff_d1 & 0x1fff);
1062 uint32_t bytes_d2 = 0x2000 - (yoff_d2 & 0x1fff);
1063 for(int k = 0; k < pages; k++) {
1064 for(int i = 0; i < 3; i++) {
1065 for(int j = 0; j < 2; j++) {
1066 src_offset_1 = i * 0x4000 + j * 0x2000;
1067 src_offset_2 = src_offset_1 + 0xc000;
1068 my_memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + (yoff_d1 & 0x1fff) + poff], bytes_d1);
1069 my_memcpy(&gvram_shadow[src_offset_1 + bytes_d1 + poff], &gvram[src_offset_1 + poff], 0x2000 - bytes_d1);
1070 my_memcpy(&gvram_shadow[src_offset_2 + poff], &gvram[src_offset_2 + (yoff_d2 & 0x1fff) + poff], bytes_d2);
1071 my_memcpy(&gvram_shadow[src_offset_2 + bytes_d2 + poff], &gvram[src_offset_2 + poff], 0x2000 - bytes_d2);
1077 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1078 else if(display_mode == DISPLAY_MODE_256k) {
1079 uint32_t bytes_d1 = 0x2000 - (yoff_d1 & 0x1fff);
1080 uint32_t bytes_d2 = 0x2000 - (yoff_d2 & 0x1fff);
1081 for(int i = 0; i < 3; i++) {
1082 for(int j = 0; j < 2; j++) {
1083 src_offset_1 = i * 0x4000 + j * 0x2000;
1084 src_offset_2 = src_offset_1 + 0xc000;
1085 my_memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + (yoff_d1 & 0x1fff) + poff], bytes_d1);
1086 my_memcpy(&gvram_shadow[src_offset_1 + bytes_d1 + poff], &gvram[src_offset_1 + poff], 0x2000 - bytes_d1);
1087 my_memcpy(&gvram_shadow[src_offset_2 + poff], &gvram[src_offset_2 + (yoff_d2 & 0x1fff) + poff], bytes_d2);
1088 my_memcpy(&gvram_shadow[src_offset_2 + bytes_d2 + poff], &gvram[src_offset_2 + poff], 0x2000 - bytes_d2);
1092 for(int i = 0; i < 3; i++) {
1093 for(int j = 0; j < 2; j++) {
1094 src_offset_1 = i * 0x4000 + j * 0x2000;
1095 my_memcpy(&gvram_shadow[src_offset_1 + poff], &gvram[src_offset_1 + (yoff_d1 & 0x1fff) + poff], bytes_d1);
1096 my_memcpy(&gvram_shadow[src_offset_1 + bytes_d1 + poff], &gvram[src_offset_1 + poff], 0x2000 - bytes_d1);
1099 } else if(display_mode == DISPLAY_MODE_8_400L) {
1101 uint32_t yoff_d, bytes_d;
1102 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1105 if(display_page_bak == 1) { // Is this dirty?
1110 yoff_d = (yoff_d << 1) & 0x7fff;
1111 bytes_d = 0x8000 - yoff_d;
1112 for(int i = 0; i < pages; i++) {
1113 for(int j = 0; j < 3; j++) {
1114 uint32_t src_base = i * 0x18000 + j * 0x8000;
1115 my_memcpy(&gvram_shadow[src_base],
1116 &gvram[yoff_d + src_base],
1118 if(bytes_d < 0x8000) {
1119 my_memcpy(&gvram_shadow[bytes_d + src_base],
1128 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1130 #elif defined(_FM77AV40)
1135 uint32_t bytes_d1 = 0x4000 - (yoff_d1 & 0x3fff);
1136 uint32_t bytes_d2 = 0x4000 - (yoff_d2 & 0x3fff);
1137 uint32_t yoff_d, bytes_d;
1138 for(int k = 0; k < pages; k++) {
1139 yoff_d = ((k & 1) == 0) ? (yoff_d1 & 0x3fff) : (yoff_d2 & 0x3fff);
1140 bytes_d = ((k & 1) == 0) ? bytes_d1 : bytes_d2;
1141 for(int j = 0; j < 3; j++) {
1142 src_offset_1 = k * 0xc000 + j * 0x4000;
1143 my_memcpy(&gvram_shadow[src_offset_1], &gvram[src_offset_1 + yoff_d], bytes_d);
1144 my_memcpy(&gvram_shadow[src_offset_1 + bytes_d], &gvram[src_offset_1], 0x4000 - bytes_d);
1150 uint32_t yoff_d = offset_point & 0x3fff;
1151 uint32_t bytes_d = 0x4000 - (offset_point & 0x3fff);
1152 uint32_t src_offset_1;
1153 for(int j = 0; j < 3; j++) {
1154 src_offset_1 = j * 0x4000;
1155 my_memcpy(&gvram_shadow[src_offset_1], &gvram[src_offset_1 + yoff_d], bytes_d);
1156 my_memcpy(&gvram_shadow[src_offset_1 + bytes_d], &gvram[src_offset_1], 0x4000 - bytes_d);
1162 // Timing values from XM7 . Thanks Ryu.
1163 void DISPLAY::event_callback(int event_id, int err)
1168 case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
1169 #if defined(_FM77AV_VARIANTS)
1179 case EVENT_FM7SUB_DISPLAY_NMI_OFF: // per 20.00ms
1182 #if defined(_FM77AV_VARIANTS) || defined(_FM77L4)
1183 case EVENT_FM7SUB_HDISP:
1186 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x02, 0xff);
1187 if(display_mode == DISPLAY_MODE_8_400L) {
1188 if(displine < 400) f = true;
1190 if(displine < 200) f = true;
1193 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) != 0) {
1195 //copy_vram_per_line(0, 4);
1196 } else if(need_transfer_line) {
1199 for(int iii = 0; iii < 5 ; iii++) {
1200 if(vram_wrote_table[iii + displine * 5]) {
1201 if(begin < 0) begin = iii;
1205 if(end < begin) end = begin;
1206 copy_vram_per_line(begin, end);
1212 if(begin >= 0) end = 4;
1213 copy_vram_per_line(begin, end);
1216 if(display_mode == DISPLAY_MODE_8_400L) {
1217 register_event(this, EVENT_FM7SUB_HBLANK, 30.0, false, &hblank_event_id); // NEXT CYCLE_
1219 register_event(this, EVENT_FM7SUB_HBLANK, 39.5, false, &hblank_event_id); // NEXT CYCLE_
1227 case EVENT_FM7SUB_HBLANK:
1229 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
1231 if(display_mode == DISPLAY_MODE_8_400L) {
1232 if((displine < 400)) f = true;
1234 if((displine < 200)) f = true;
1237 if(display_mode == DISPLAY_MODE_8_400L) {
1242 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id);
1246 case EVENT_FM7SUB_VSTART: // Call first.
1251 display_page_bak = display_page;
1252 // Parameter from XM7/VM/display.c , thanks, Ryu.
1253 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
1254 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x00, 0xff);
1255 if(vblank_count != 0) {
1256 if(display_mode == DISPLAY_MODE_8_400L) {
1257 usec = (0.98 + 16.4) * 1000.0;
1259 usec = (1.91 + 12.7) * 1000.0;
1261 register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id);
1263 if(display_mode == DISPLAY_MODE_8_400L) {
1264 usec = 930.0; // 939.0
1266 usec = 1840.0; // 1846.5
1268 register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
1272 if(display_mode == DISPLAY_MODE_8_400L) {
1273 usec = 0.34 * 1000.0;
1275 usec = 1.52 * 1000.0;
1277 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
1282 case EVENT_FM7SUB_VSYNC:
1286 //write_access_page = (write_access_page + 1) & 1;
1288 if(display_mode == DISPLAY_MODE_8_400L) {
1289 usec = 0.33 * 1000.0;
1291 usec = 0.51 * 1000.0;
1293 mainio->write_signal(SIG_DISPLAY_VSYNC, 0x01, 0xff);
1294 mainio->write_signal(SIG_DISPLAY_DISPLAY, 0x00, 0xff);
1295 register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
1296 if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) {
1299 if(display_mode == DISPLAY_MODE_8_400L) lines = 400;
1300 if(need_transfer_line) {
1301 if(vram_wrote) ff = true;
1302 //if(need_transfer_line) ff = true;
1304 for(displine = 0; displine < lines; displine++) {
1306 for(int iii = 0; iii < 5 ; iii++) {
1307 if(vram_wrote_table[iii + displine * 5]) {
1316 for(int yy = 0; yy < lines; yy++) {
1317 if(!vram_draw_table[yy]) {
1319 copy_vram_per_line(0, 4);
1320 vram_draw_table[yy] = true;
1324 vram_wrote_shadow = true;
1325 screen_update_flag = true;
1330 if(display_mode == DISPLAY_MODE_8_400L) lines = 400;
1331 if(need_transfer_line) {
1333 for(int yy = 0; yy < lines; yy++) {
1334 //if(!vram_draw_table[yy]) {
1336 copy_vram_per_line(0, 4);
1343 for(int yy = 0; yy < lines; yy++) {
1344 if(vram_draw_table[yy]) {
1345 vram_wrote_shadow = true;
1346 screen_update_flag = true;
1350 //vram_wrote = false;
1352 frame_skip_count_transfer++;
1354 uint32_t factor = ((config.dipswitch & FM7_DIPSW_FRAMESKIP) >> 28) & 3;
1355 if((frame_skip_count_transfer > factor) /* || (vram_wrote) */) {
1356 frame_skip_count_transfer = 0;
1357 need_transfer_line = true;
1359 need_transfer_line = false;
1364 case EVENT_FM7SUB_CLR_BUSY:
1367 case EVENT_FM7SUB_CLR_CRTFLAG:
1373 void DISPLAY::event_frame()
1375 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
1379 if(display_mode == DISPLAY_MODE_8_400L) lines = 400;
1380 if(need_transfer_line && vram_wrote) {
1381 for(yy = 0; yy < lines; yy++) {
1382 //if(!vram_draw_table[yy]) {
1384 copy_vram_per_line(0, 4);
1391 for(yy = 0; yy < lines; yy++) {
1392 if(vram_draw_table[yy]) {
1398 screen_update_flag = true;
1399 vram_wrote_shadow = true;
1403 frame_skip_count_transfer++;
1405 uint32_t factor = (config.dipswitch & FM7_DIPSW_FRAMESKIP) >> 28;
1406 if(frame_skip_count_transfer > factor) {
1407 frame_skip_count_transfer = 0;
1408 need_transfer_line = true;
1410 need_transfer_line = false;
1412 //vram_wrote = false;
1419 void DISPLAY::event_vline(int v, int clock)
1421 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
1422 if(need_transfer_line == false) return;
1426 //copy_vram_per_line(0, 4);
1430 for(int iii = 0; iii < 5 ; iii++) {
1431 if(vram_wrote_table[displine * 5 + iii]) {
1432 if(begin < 0) begin = iii;
1436 if(end < begin) end = begin;
1437 copy_vram_per_line(begin, end);
1443 if(begin >= 0) end = 4;
1444 copy_vram_per_line(begin, end);
1451 uint32_t DISPLAY::read_signal(int id)
1453 uint32_t retval = 0;
1455 case SIG_FM7_SUB_HALT:
1456 case SIG_DISPLAY_HALT:
1457 retval = (halt_flag) ? 0xffffffff : 0;
1459 case SIG_DISPLAY_BUSY:
1460 retval = (sub_busy) ? 0x80 : 0;
1462 case SIG_DISPLAY_MULTIPAGE:
1463 retval = multimode_accessmask;
1465 case SIG_DISPLAY_PLANES:
1468 #if defined(_FM77AV_VARIANTS)
1469 case SIG_DISPLAY_VSYNC:
1470 retval = (vsync) ? 0x01 : 0x00;
1472 case SIG_DISPLAY_DISPLAY:
1473 retval = (!hblank) ? 0x02: 0x00;
1475 case SIG_FM7_SUB_BANK: // Main: FD13
1476 retval = subrom_bank & 0x03;
1477 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1478 if(monitor_ram) retval |= 0x04;
1482 #if defined(_FM77AV_VARIANTS)
1483 case SIG_DISPLAY_MODE320:
1484 retval = (mode320) ? 0x40: 0x00;
1487 case SIG_DISPLAY_Y_HEIGHT:
1488 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1489 retval = (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200;
1494 case SIG_DISPLAY_X_WIDTH:
1495 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1496 retval = (mode320 || mode256k) ? 320 : 640;
1497 #elif defined(_FM77AV_VARIANTS)
1498 retval = (mode320) ? 320 : 640;
1509 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
1511 bool flag = ((data & mask) != 0);
1515 case SIG_FM7_SUB_HALT:
1520 //mainio->write_signal(SIG_FM7_SUB_HALT, data, mask);
1522 case SIG_DISPLAY_HALT:
1526 restart_subsystem();
1529 case SIG_FM7_SUB_CANCEL:
1531 cancel_request = true;
1535 case SIG_DISPLAY_CLOCK:
1539 #if defined(_FM77AV_VARIANTS)
1540 case SIG_FM7_SUB_BANK: // Main: FD13
1541 set_monitor_bank(data & 0xff);
1544 case SIG_DISPLAY_EXTRA_MODE: // FD04 bit 4, 3
1545 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1546 //printf("Wrote $FD04: %02x\n", data);
1548 int oldmode = display_mode;
1550 kanjisub = ((data & 0x20) == 0) ? true : false;
1551 mode256k = (((data & 0x10) != 0) && ((data & 0x08) != 0) ) ? true : false;
1552 mode400line = ((data & 0x08) == 0) ? true : false;
1553 ram_protect = ((data & 0x04) == 0) ? true : false;
1554 if(mode400line && !mode320) {
1555 display_mode = DISPLAY_MODE_8_400L;
1556 } else if(mode256k) {
1557 display_mode = DISPLAY_MODE_256k;
1559 display_mode = (mode320) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1561 if(oldmode != display_mode) {
1563 if(mode320 || mode256k) {
1564 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1565 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1566 for(y = 0; y < 200; y++) {
1567 pp = emu->get_screen_buffer(y);
1568 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype_t));
1571 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1572 for(y = 0; y < 400; y++) {
1573 pp = emu->get_screen_buffer(y);
1574 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1577 } else if(display_mode == DISPLAY_MODE_8_400L) {
1578 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1579 for(y = 0; y < 400; y++) {
1580 pp = emu->get_screen_buffer(y);
1581 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1585 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1586 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1587 for(y = 0; y < 200; y++) {
1588 pp = emu->get_screen_buffer(y);
1589 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1592 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1593 for(y = 0; y < 400; y++) {
1594 pp = emu->get_screen_buffer(y);
1595 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1600 alu->write_signal(SIG_ALU_X_WIDTH, (mode320 || mode256k) ? 40 : 80, 0xffff);
1601 alu->write_signal(SIG_ALU_Y_HEIGHT, (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200, 0xffff);
1602 alu->write_signal(SIG_ALU_400LINE, (display_mode == DISPLAY_MODE_8_400L) ? 0xff : 0x00, 0xff);
1603 frame_skip_count_draw = 3;
1604 frame_skip_count_transfer = 3;
1605 setup_display_mode();
1608 #elif defined(_FM77_VARIANTS)
1610 int oldmode = display_mode;
1611 kanjisub = ((data & 0x20) == 0) ? true : false;
1612 # if defined(_FM77L4)
1613 stat_400linecard = ((data & 0x20) != 0) ? true : false;
1614 mode400line = ((data & 0x08) != 0) ? false : true;
1615 if(mode400line && stat_400linecard) {
1616 display_mode = DISPLAY_MODE_8_400L_TEXT;
1617 } else if(stat_400linecard) {
1618 display_mode = DISPLAY_MODE_8_200L_TEXT;
1620 display_mode = DISPLAY_MODE_8_200L;
1623 setup_display_mode();
1627 #if defined(_FM77AV_VARIANTS)
1628 case SIG_DISPLAY_MODE320: // FD12 bit 6
1629 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1631 //printf("Wrote $FD12: %02x\n", data);
1632 int oldmode = display_mode;
1634 if(!mode320 && !mode256k) {
1635 //display_mode = (mode400line) ? DISPLAY_MODE_8_400L : DISPLAY_MODE_8_200L;
1636 display_mode = DISPLAY_MODE_8_200L;
1638 display_mode = (mode256k) ? DISPLAY_MODE_256k : DISPLAY_MODE_4096;
1640 if(oldmode != display_mode) {
1642 if(mode320 || mode256k) {
1643 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1644 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1645 for(y = 0; y < 200; y++) {
1646 pp = emu->get_screen_buffer(y);
1647 if(pp != NULL) memset(pp, 0x00, 320 * sizeof(scrntype_t));
1650 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1651 for(y = 0; y < 400; y++) {
1652 pp = emu->get_screen_buffer(y);
1653 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1656 } else { // 200 lines, 8 colors.
1657 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1658 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1659 for(y = 0; y < 200; y++) {
1660 pp = emu->get_screen_buffer(y);
1661 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1664 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1665 for(y = 0; y < 400; y++) {
1666 pp = emu->get_screen_buffer(y);
1667 if(pp != NULL) memset(pp, 0x00, 640 * sizeof(scrntype_t));
1673 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1674 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1675 alu->write_signal(SIG_ALU_400LINE, 0x00, 0xff);
1676 setup_display_mode();
1677 //frame_skip_count = 3;
1680 # else /* FM77AV/20/20EX */
1686 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1687 emu->set_vm_screen_size(320, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1688 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 320 * sizeof(scrntype_t));
1690 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1691 for(y = 0; y < 400; y++) memset(emu->get_screen_buffer(y), 0x00, 640 * sizeof(scrntype_t));
1694 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1695 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1696 for(y = 0; y < 200; y++) memset(emu->get_screen_buffer(y), 0x00, 640 * sizeof(scrntype_t));
1698 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
1699 for(y = 0; y < 400; y++) memset(emu->get_screen_buffer(y), 0x00, 640 * sizeof(scrntype_t));
1704 display_mode = (mode320 == true) ? DISPLAY_MODE_4096 : DISPLAY_MODE_8_200L;
1705 alu->write_signal(SIG_ALU_X_WIDTH, (mode320) ? 40 : 80, 0xffff);
1706 alu->write_signal(SIG_ALU_Y_HEIGHT, 200, 0xffff);
1707 alu->write_signal(SIG_ALU_400LINE, 0, 0xffffffff);
1709 if(mode320 != oldflag) setup_display_mode();
1713 case SIG_DISPLAY_MULTIPAGE:
1714 set_multimode(data);
1716 case SIG_FM7_SUB_KEY_MASK:
1717 if(firq_mask == flag) {
1718 do_firq(!flag && key_firq_req);
1722 case SIG_FM7_SUB_KEY_FIRQ:
1723 do_firq(flag & !(firq_mask));
1724 key_firq_req = flag;
1726 case SIG_FM7_SUB_USE_CLR:
1728 clr_count = data & 0x03;
1739 * Vram accessing functions moved to vram.cpp .
1742 uint32_t DISPLAY::read_mmio(uint32_t addr)
1744 uint32_t retval = 0xff;
1746 if(addr < 0xd400) return 0xff;
1748 #if !defined(_FM77AV_VARIANTS)
1749 raddr = (addr - 0xd400) & 0x000f;
1750 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
1751 raddr = (addr - 0xd400) & 0x003f;
1752 #else // FM77AV40EX || FM77AV40SX
1753 raddr = (addr - 0xd400) & 0x00ff;
1756 case 0x00: // Read keyboard
1757 retval = (keyboard->read_data8(0x00) != 0) ? 0xff : 0x7f;
1759 case 0x01: // Read keyboard
1760 retval = keyboard->read_data8(0x01) & 0xff;
1762 case 0x02: // Acknowledge
1771 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1772 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
1774 if(!kanjisub) return 0xff;
1775 # if !defined(_FM77_VARIANTS)
1777 return (uint8_t)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1780 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff));
1783 if(!kanjisub) return 0xff;
1784 # if !defined(_FM77_VARIANTS)
1786 return (uint8_t)kanjiclass2->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1789 if(kanjiclass1 != NULL) retval = kanjiclass1->read_data8(KANJIROM_DIRECTADDR + ((kanjiaddr.d << 1) & 0x1ffff) + 1);
1796 retval = set_vramaccess();
1802 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x01, 0x01);
1804 #if defined(_FM77AV_VARIANTS)
1807 retval = alu->read_data8(ALU_CMDREG);
1810 retval = alu->read_data8(ALU_LOGICAL_COLOR);
1813 retval = alu->read_data8(ALU_WRITE_MASKREG);
1816 retval = alu->read_data8(ALU_CMP_STATUS_REG);
1819 retval = alu->read_data8(ALU_BANK_DISABLE);
1821 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1822 case 0x2f: // VRAM BANK
1823 retval = 0xfc | (vram_bank & 0x03);
1828 retval = get_miscreg();
1832 retval = keyboard->read_data8(0x31);
1835 retval = keyboard->read_data8(0x32);
1841 return (uint8_t)retval;
1844 uint32_t DISPLAY::read_vram_data8(uint32_t addr)
1848 uint32_t color = (addr >> 14) & 0x03;
1850 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1851 if(display_mode == DISPLAY_MODE_8_400L) {
1852 color = vram_bank & 0x03;
1853 if(color > 2) color = 0;
1855 color = (addr >> 14) & 0x03;
1859 //if((multimode_accessmask & (1 << color)) != 0) return 0xff;
1860 if(multimode_accessflags[color]) return 0xff;
1862 #if defined(_FM77AV_VARIANTS)
1863 if (active_page != 0) {
1864 offset = offset_point_bank1;
1866 offset = offset_point;
1869 offset = offset_point;
1872 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1873 if(display_mode == DISPLAY_MODE_8_400L) {
1875 uint32_t page_offset_alt = 0;
1876 if(addr >= 0x8000) return 0xff;
1877 color = vram_bank & 0x03;
1878 if(color > 2) color = 0;
1880 pagemod = 0x8000 * color;
1881 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1882 if(vram_active_block != 0) page_offset = 0x18000;
1884 vramaddr = (((addr + offset) & 0x7fff) | pagemod) + page_offset_alt;
1885 return gvram[vramaddr];
1888 uint32_t page_offset_alt;
1889 #if defined(_FM77AV40)
1891 page_offset_alt = 0xc000 * (vram_bank & 0x03);
1893 page_offset_alt = 0; // right?
1896 page_offset_alt = 0xc000 * (vram_bank & 0x03);
1898 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset_alt;
1899 //page_mask = 0x1fff;
1900 //pagemod = addr & 0xe000;
1902 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
1904 return gvram[vramaddr];
1906 #elif defined(_FM77AV_VARIANTS)
1908 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
1909 return gvram[vramaddr];
1911 #elif defined(_FM77L4) //_FM77L4
1913 if(display_mode == DISPLAY_MODE_8_400L) {
1914 return (uint32_t)read_vram_l4_400l(addr, offset);
1916 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
1917 return gvram[vramaddr];
1921 #else // Others (77/7/8)
1922 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
1923 return gvram[vramaddr];
1927 void DISPLAY::write_dma_data8(uint32_t addr, uint32_t data)
1929 uint32_t raddr = (addr & 0xffff) >> 7;
1930 if(write_dma_func_table[raddr] != NULL) {
1931 (this->*write_dma_func_table[raddr])(addr, (uint8_t) data);
1935 void DISPLAY::write_vram_data8(uint32_t addr, uint8_t data)
1938 uint32_t color = (addr >> 14) & 0x03;
1942 #if defined(_FM77AV_VARIANTS)
1943 if (active_page != 0) {
1944 offset = offset_point_bank1;
1946 offset = offset_point;
1949 offset = offset_point;
1952 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1953 if(display_mode == DISPLAY_MODE_8_400L) {
1955 uint32_t page_offset_alt = 0;
1957 if(addr >= 0x8000) {
1960 color = vram_bank & 0x03;
1961 if(color > 2) color = 0;
1963 pagemod = 0x8000 * color;
1964 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1965 if(vram_active_block != 0) page_offset_alt = 0x18000;
1967 vramaddr = (((addr + offset) & 0x7fff) | pagemod) + page_offset_alt;
1968 // Reduce data transfer.
1969 tdata = gvram[vramaddr];
1971 naddr = (addr & 0x7fff) >> 4;
1972 gvram[vramaddr] = data;
1973 vram_wrote_table[naddr] = true;
1975 } else if(display_mode == DISPLAY_MODE_256k) {
1976 uint32_t page_offset_alt;
1978 #if defined(_FM77AV40)
1980 page_offset_alt = 0xc000 * (vram_bank & 0x03);
1982 page_offset_alt = 0; // right?
1985 page_offset_alt = 0xc000 * (vram_bank & 0x03);
1987 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset_alt;
1988 tdata = gvram[vramaddr];
1990 naddr = (addr & page_mask) >> 3;
1991 gvram[vramaddr] = data;
1992 vram_wrote_table[naddr] = true;
1995 } else if(display_mode == DISPLAY_MODE_4096) {
1997 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
1998 tdata = gvram[vramaddr];
2000 naddr = (addr & page_mask) >> 3;
2001 gvram[vramaddr] = data;
2002 vram_wrote_table[naddr] = true;
2006 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
2007 tdata = gvram[vramaddr];
2009 naddr = (addr & page_mask) >> 4;
2010 gvram[vramaddr] = data;
2011 vram_wrote_table[naddr] = true;
2014 #elif defined(_FM77AV_VARIANTS)
2015 if(display_mode == DISPLAY_MODE_4096) {
2017 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
2018 tdata = gvram[vramaddr];
2020 naddr = (addr & page_mask) >> 3;
2021 gvram[vramaddr] = data;
2022 vram_wrote_table[naddr] = true;
2026 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
2027 tdata = gvram[vramaddr];
2029 naddr = (addr & page_mask) >> 4;
2030 gvram[vramaddr] = data;
2031 vram_wrote_table[naddr] = true;
2034 #elif defined(_FM77L4) //_FM77L4
2037 if(display_mode == DISPLAY_MODE_8_400L) {
2038 write_vram_l4_400l(addr, data, offset);
2040 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
2041 tdata = gvram[vramaddr];
2043 naddr = (addr & 0x3fff) >> 4;
2044 gvram[vramaddr] = data;
2045 vram_wrote_table[naddr] = true;
2049 #else // Others (77/7/8)
2052 vramaddr = (((addr + offset) & page_mask) | (pagemod_mask & addr)) + page_offset;
2053 tdata = gvram[vramaddr];
2055 naddr = (addr & 0x3fff) >> 4;
2056 gvram[vramaddr] = data;
2057 vram_wrote_table[naddr] = true;
2063 uint32_t DISPLAY::read_cpu_vram_data8(uint32_t addr)
2066 #if defined(_FM77AV_VARIANTS)
2068 alu->read_data8(addr);
2071 return read_vram_data8(addr);
2074 uint32_t DISPLAY::read_dma_vram_data8(uint32_t addr)
2076 return read_vram_data8(addr);
2079 void DISPLAY::init_read_table(void)
2082 for(_at = 0 ; _at < 0xc000; _at += 0x80) {
2083 read_cpu_func_table[_at >> 7] = &DISPLAY::read_cpu_vram_data8;
2084 read_dma_func_table[_at >> 7] = &DISPLAY::read_dma_vram_data8;
2086 for(_at = 0xc000; _at < 0xd000; _at += 0x80) {
2087 read_cpu_func_table[_at >> 7] = &DISPLAY::read_console_ram;
2088 read_dma_func_table[_at >> 7] = &DISPLAY::read_console_ram;
2090 for(_at = 0xd000; _at < 0xd380; _at += 0x80) {
2091 read_cpu_func_table[_at >> 7] = &DISPLAY::read_work_ram;
2092 read_dma_func_table[_at >> 7] = &DISPLAY::read_work_ram;
2094 for(_at = 0xd380; _at < 0xd400; _at += 0x80) {
2095 read_cpu_func_table[_at >> 7] = &DISPLAY::read_shared_ram;
2096 read_dma_func_table[_at >> 7] = &DISPLAY::read_shared_ram;
2098 #if defined(_FM77AV_VARIANTS)
2099 for(_at = 0xd400; _at < 0xd500; _at += 0x80) {
2100 read_cpu_func_table[_at >> 7] = &DISPLAY::read_mmio;
2101 read_dma_func_table[_at >> 7] = &DISPLAY::read_mmio;
2103 for(_at = 0xd500; _at < 0xd800; _at += 0x80) {
2104 read_cpu_func_table[_at >> 7] = &DISPLAY::read_hidden_ram;
2105 read_dma_func_table[_at >> 7] = &DISPLAY::read_hidden_ram;
2108 for(_at = 0xd400; _at < 0xd800; _at += 0x80) {
2109 read_cpu_func_table[_at >> 7] = &DISPLAY::read_mmio;
2110 read_dma_func_table[_at >> 7] = &DISPLAY::read_mmio;
2113 for(_at = 0xd800; _at < 0xe000; _at += 0x80) {
2114 read_cpu_func_table[_at >> 7] = &DISPLAY::read_cgrom;
2115 read_dma_func_table[_at >> 7] = &DISPLAY::read_cgrom;
2117 for(_at = 0xe000; _at < 0x10000; _at += 0x80) {
2118 read_cpu_func_table[_at >> 7] = &DISPLAY::read_subsys_monitor;
2119 read_dma_func_table[_at >> 7] = &DISPLAY::read_subsys_monitor;
2123 uint32_t DISPLAY::read_console_ram(uint32_t addr)
2125 uint32_t raddr = addr & 0xfff;
2126 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2128 if(console_ram_bank >= 1) {
2129 return submem_console_av40[((console_ram_bank - 1) << 12) + raddr];
2133 return console_ram[raddr];
2136 uint32_t DISPLAY::read_work_ram(uint32_t addr)
2138 addr = addr & 0x3ff;
2139 return work_ram[addr];
2143 uint32_t DISPLAY::read_shared_ram(uint32_t addr)
2145 addr = addr - 0xd380;
2146 return shared_ram[addr];
2149 #if defined(_FM77AV_VARIANTS)
2150 uint32_t DISPLAY::read_hidden_ram(uint32_t addr)
2152 if(addr >= 0xd500) {
2153 return submem_hidden[addr - 0xd500];
2158 uint32_t DISPLAY::read_cgrom(uint32_t addr)
2160 #if defined(_FM77AV_VARIANTS)
2161 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2163 return submem_cgram[cgram_bank * 0x0800 + (addr - 0xd800)]; //FIXME
2166 return subsys_cg[(addr - 0xd800) + cgrom_bank * 0x800];
2168 return subsys_c[addr - 0xd800];
2172 uint32_t DISPLAY::read_subsys_monitor(uint32_t addr)
2174 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2176 return subsys_ram[addr - 0xe000];
2179 #if defined(_FM77AV_VARIANTS)
2180 switch(subrom_bank_using & 3) {
2182 return subsys_c[addr - 0xd800];
2185 return subsys_a[addr - 0xe000];
2188 return subsys_b[addr - 0xe000];
2191 return subsys_cg[addr - 0xe000];
2195 return subsys_c[addr - 0xd800];
2199 uint32_t DISPLAY::read_dma_data8(uint32_t addr)
2201 uint32_t raddr = (addr & 0xffff) >> 7;
2202 if(read_dma_func_table[raddr] != NULL) {
2203 return (this->*read_dma_func_table[raddr])(addr);
2208 uint32_t DISPLAY::read_data8(uint32_t addr)
2210 uint32_t raddr = addr;
2212 if(addr < 0x10000) {
2213 raddr = (addr & 0xffff) >> 7;
2214 if(read_cpu_func_table[raddr] != NULL) {
2215 return (this->*read_cpu_func_table[raddr])(addr);
2220 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
2221 return dpalette_data[addr - FM7_SUBMEM_OFFSET_DPALETTE];
2224 #if defined(_FM77AV_VARIANTS)
2226 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
2227 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
2228 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2229 if(display_mode == DISPLAY_MODE_8_400L) {
2230 uint32_t page_offset_alt = 0;
2231 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2232 if(vram_active_block != 0) page_offset_alt = 0x18000;
2236 color = (addr & 0x18000) >> 15;
2237 if(color > 2) color = 0;
2238 pagemod = 0x8000 * color;
2239 if (active_page != 0) {
2240 offset = offset_point_bank1 << 1;
2242 offset = offset_point << 1;
2244 return gvram[(((addr + offset) & 0x7fff) | pagemod) + page_offset_alt];
2247 return read_vram_data8(addr);
2254 * Vram accessing functions moved to vram.cpp .
2257 void DISPLAY::write_mmio(uint32_t addr, uint8_t data)
2260 uint8_t active_block_old;
2262 if(addr < 0xd400) return;
2264 #if !defined(_FM77AV_VARIANTS)
2265 addr = (addr - 0xd400) & 0x000f;
2266 #elif !defined(_FM77AV40SX) && !defined(_FM77AV40EX)
2267 addr = (addr - 0xd400) & 0x003f;
2268 #else // FM77AV40EX || FM77AV40SX
2269 addr = (addr - 0xd400) & 0x00ff;
2271 io_w_latch[addr] = (uint8_t)data;
2273 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
2276 set_cyclesteal((uint8_t)data);
2279 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2280 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) || defined(_FM77_VARIANTS) // _FM77L4
2283 if(!kanjisub) return;
2284 kanjiaddr.w.h = 0x0000;
2285 kanjiaddr.b.h = (uint8_t) data;
2288 if(!kanjisub) return;
2289 kanjiaddr.w.h = 0x0000;
2290 kanjiaddr.b.l = (uint8_t)data;
2303 if(clr_count <= 0) {
2305 } else { // Read once when using clr_foo() to set busy flag.
2308 usec = (1000.0 * 1000.0) / 2000000.0;
2310 usec = (1000.0 * 1000.0) / 999000.0;
2312 if(!is_cyclesteal && vram_accessflag) usec = usec * 3.0;
2313 usec = (double)clr_count * usec;
2314 register_event(this, EVENT_FM7SUB_CLR_BUSY, usec, false, NULL); // NEXT CYCLE_
2321 keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
2326 rval = (uint8_t)data;
2327 if(offset_changed[active_page]) {
2328 #if defined(_FM77AV_VARIANTS)
2329 if(active_page != 0) {
2330 tmp_offset_point[active_page].d = offset_point_bank1;
2332 tmp_offset_point[active_page].d = offset_point;
2335 tmp_offset_point[active_page].d = offset_point;
2338 tmp_offset_point[active_page].w.h = 0x0000;
2340 tmp_offset_point[active_page].b.h = rval;
2342 tmp_offset_point[active_page].b.l = rval;
2344 offset_changed[active_page] = !offset_changed[active_page];
2345 if(offset_changed[active_page]) {
2347 #if defined(_FM77AV_VARIANTS)
2348 if(active_page != 0) {
2350 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fff;
2352 offset_point_bank1 = tmp_offset_point[active_page].d & 0x007fe0;
2356 offset_point = tmp_offset_point[active_page].d & 0x007fff;
2358 offset_point = tmp_offset_point[active_page].d & 0x007fe0;
2362 offset_point = tmp_offset_point[active_page].d & 0x7fe0;
2366 #if defined(_FM77AV_VARIANTS)
2369 alu_write_cmdreg(data);
2372 alu_write_logical_color(data);
2375 alu_write_mask_reg(data);
2378 alu_write_disable_reg(data);
2381 alu_write_offsetreg_hi(data);
2384 alu_write_offsetreg_lo(data);
2387 alu_write_linepattern_hi(data);
2390 alu_write_linepattern_lo(data);
2392 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2394 console_ram_bank = (data & 0x18) >> 3;
2395 if(console_ram_bank > 2) console_ram_bank = 0;
2396 cgram_bank = data & 0x07;
2397 kanji_level2 = ((data & 0x80) == 0) ? false : true;
2399 case 0x2f: // VRAM BANK
2400 vram_bank = data & 0x03;
2401 if(vram_bank > 2) vram_bank = 0;
2411 keyboard->write_data8(0x31, data);
2413 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2415 active_block_old = vram_active_block;
2416 vram_active_block = data & 0x01;
2417 if(vram_display_block != (((data & 0x10) != 0) ? 1 : 0)) vram_wrote = true;
2418 vram_display_block = ((data & 0x10) != 0) ? 1 : 0;
2419 if(vram_active_block != active_block_old) setup_display_mode();
2424 tmpvar.d = window_xbegin * 8;
2427 tmpvar.b.h = data & 0x03;
2429 tmpvar.b.l = data & 0xf8;
2431 if(mode320 || mode256k) {
2432 if(tmpvar.d > 320) tmpvar.d = 320;
2434 if(tmpvar.d > 640) tmpvar.d = 640;
2436 window_xbegin = tmpvar.d / 8;
2441 tmpvar.d = window_xend * 8;
2444 tmpvar.b.h = data & 0x03;
2446 tmpvar.b.l = data & 0xf8;
2448 if(mode320 || mode256k) {
2449 if(tmpvar.d > 320) tmpvar.d = 320;
2451 if(tmpvar.d > 640) tmpvar.d = 640;
2453 window_xend = tmpvar.d / 8;
2458 tmpvar.d = window_low;
2461 tmpvar.b.h = data & 0x03;
2463 tmpvar.b.l = data & 0xff;
2465 if(display_mode == DISPLAY_MODE_8_400L) {
2466 if(tmpvar.d > 400) tmpvar.d = 400;
2469 if(tmpvar.d > 400) tmpvar.d = 400;
2471 window_low = tmpvar.d;
2476 tmpvar.d = window_high;
2479 tmpvar.b.h = data & 0x03;
2481 tmpvar.b.l = data & 0xff;
2483 if(display_mode == DISPLAY_MODE_8_400L) {
2484 if(tmpvar.d > 400) tmpvar.d = 400;
2487 if(tmpvar.d > 400) tmpvar.d = 400;
2489 window_high = tmpvar.d;
2495 #if defined(_FM77AV_VARIANTS)
2497 if((addr >= 0x13) && (addr <= 0x1a)) {
2498 alu_write_cmpdata_reg(addr - 0x13, data);
2499 } else if((addr >= 0x1c) && (addr <= 0x1e)) {
2500 alu_write_tilepaint_data(addr, data);
2501 } else if((addr >= 0x24) && (addr <= 0x2b)) {
2502 alu_write_line_position(addr - 0x24, data);
2509 void DISPLAY::init_write_table(void)
2512 for(_at = 0 ; _at < 0xc000; _at += 0x80) {
2513 write_cpu_func_table[_at >> 7] = &DISPLAY::write_cpu_vram_data8;
2514 write_dma_func_table[_at >> 7] = &DISPLAY::write_dma_vram_data8;
2516 for(_at = 0xc000; _at < 0xd000; _at += 0x80) {
2517 write_cpu_func_table[_at >> 7] = &DISPLAY::write_console_ram;
2518 write_dma_func_table[_at >> 7] = &DISPLAY::write_console_ram;
2520 for(_at = 0xd000; _at < 0xd380; _at += 0x80) {
2521 write_cpu_func_table[_at >> 7] = &DISPLAY::write_work_ram;
2522 write_dma_func_table[_at >> 7] = &DISPLAY::write_work_ram;
2524 for(_at = 0xd380; _at < 0xd400; _at += 0x80) {
2525 write_cpu_func_table[_at >> 7] = &DISPLAY::write_shared_ram;
2526 write_dma_func_table[_at >> 7] = &DISPLAY::write_shared_ram;
2528 #if defined(_FM77AV_VARIANTS)
2529 for(_at = 0xd400; _at < 0xd500; _at += 0x80) {
2530 write_cpu_func_table[_at >> 7] = &DISPLAY::write_mmio;
2531 write_dma_func_table[_at >> 7] = &DISPLAY::write_mmio;
2533 for(_at = 0xd500; _at < 0xd800; _at += 0x80) {
2534 write_cpu_func_table[_at >> 7] = &DISPLAY::write_hidden_ram;
2535 write_dma_func_table[_at >> 7] = &DISPLAY::write_hidden_ram;
2538 for(_at = 0xd400; _at < 0xd800; _at += 0x80) {
2539 write_cpu_func_table[_at >> 7] = &DISPLAY::write_mmio;
2540 write_dma_func_table[_at >> 7] = &DISPLAY::write_mmio;
2543 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2544 for(_at = 0xd800; _at < 0xe000; _at += 0x80) {
2545 write_cpu_func_table[_at >> 7] = &DISPLAY::write_subsys_cgram;
2546 write_dma_func_table[_at >> 7] = &DISPLAY::write_subsys_cgram;
2548 for(_at = 0xe000; _at < 0x10000; _at += 0x80) {
2549 write_cpu_func_table[_at >> 7] = &DISPLAY::write_subsys_ram;
2550 write_dma_func_table[_at >> 7] = &DISPLAY::write_subsys_ram;
2553 for(_at = 0xd800; _at < 0x10000; _at += 0x80) {
2554 write_cpu_func_table[_at >> 7] = &DISPLAY::write_dummy;
2555 write_dma_func_table[_at >> 7] = &DISPLAY::write_dummy;
2560 void DISPLAY::write_console_ram(uint32_t addr, uint8_t data)
2562 uint32_t raddr = addr & 0xfff;
2563 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2565 if(console_ram_bank >= 1) {
2566 submem_console_av40[((console_ram_bank - 1) << 12) + raddr] = data;
2571 console_ram[raddr] = data;
2575 void DISPLAY::write_work_ram(uint32_t addr, uint8_t data)
2577 uint32_t raddr = addr & 0xfff;
2578 work_ram[raddr] = data;
2582 void DISPLAY::write_shared_ram(uint32_t addr, uint8_t data)
2584 uint32_t raddr = addr & 0x7f;
2585 shared_ram[raddr] = data;
2589 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
2590 void DISPLAY::write_subsys_cgram(uint32_t addr, uint8_t data)
2592 uint32_t raddr = addr - 0xd800;
2593 if(ram_protect) return;
2594 if(!monitor_ram) return;
2595 submem_cgram[cgram_bank * 0x0800 + raddr] = data; //FIXME
2598 void DISPLAY::write_subsys_ram(uint32_t addr, uint8_t data)
2600 if(ram_protect) return;
2601 if(!monitor_ram) return;
2602 subsys_ram[addr - 0xe000] = data; //FIXME
2606 #if defined(_FM77AV_VARIANTS)
2607 void DISPLAY::write_hidden_ram(uint32_t addr, uint8_t data)
2609 submem_hidden[addr - 0xd500] = data;
2614 void DISPLAY::write_cpu_vram_data8(uint32_t addr, uint8_t data)
2616 uint32_t color = (addr & 0xc000) >> 14;
2617 #if defined(_FM77AV_VARIANTS)
2619 alu->read_data8(addr);
2623 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2624 if(display_mode == DISPLAY_MODE_8_400L) {
2625 color = vram_bank & 0x03;
2626 if(color > 2) color = 0;
2630 //if((multimode_accessmask & (1 << color)) != 0) return;
2631 if(multimode_accessflags[color]) return;
2633 write_vram_data8(addr & 0xffff, data);
2636 void DISPLAY::write_dma_vram_data8(uint32_t addr, uint8_t data)
2638 uint32_t color = (addr & 0xc000) >> 14;
2639 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2640 if(display_mode == DISPLAY_MODE_8_400L) {
2641 color = vram_bank & 0x03;
2642 if(color > 2) color = 0;
2646 //if((multimode_accessmask & (1 << color)) != 0) return;
2647 if(multimode_accessflags[color]) return;
2649 write_vram_data8(addr & 0xffff, data);
2652 void DISPLAY::write_dummy(uint32_t addr, uint8_t data)
2656 void DISPLAY::write_data8(uint32_t addr, uint32_t data)
2660 //uint32_t page_offset = 0x0000;
2661 uint8_t val8 = data & 0xff;
2662 uint32_t color = (addr & 0xc000) >> 14;
2665 if(addr < 0x10000) {
2666 void (*_write_func)(uint32_t, uint32_t);
2667 raddr = (addr & 0xffff) >> 7;
2668 if(write_cpu_func_table[raddr] != NULL) {
2669 (this->*write_cpu_func_table[raddr])(addr, (uint8_t)data);
2675 else if((addr >= FM7_SUBMEM_OFFSET_DPALETTE) && (addr < (FM7_SUBMEM_OFFSET_DPALETTE + 8))) {
2676 set_dpalette(addr - FM7_SUBMEM_OFFSET_DPALETTE, val8);
2680 #if defined(_FM77AV_VARIANTS)
2682 else if(addr == FM7_SUBMEM_OFFSET_APALETTE_R) {
2683 set_apalette_r(val8);
2685 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_G) {
2686 set_apalette_g(val8);
2688 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_B) {
2689 set_apalette_b(val8);
2691 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_HI) {
2692 set_apalette_index_hi(val8);
2694 } else if(addr == FM7_SUBMEM_OFFSET_APALETTE_LO) {
2695 set_apalette_index_lo(val8);
2699 else if((addr >= DISPLAY_VRAM_DIRECT_ACCESS) && (addr < (DISPLAY_VRAM_DIRECT_ACCESS + 0x18000))) {
2700 addr = addr - DISPLAY_VRAM_DIRECT_ACCESS;
2701 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2702 if(display_mode == DISPLAY_MODE_8_400L) {
2705 uint32_t page_offset_alt = 0;
2707 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2708 if(vram_active_block != 0) page_offset_alt = 0x18000;
2710 color = (addr & 0x18000) >> 15;
2711 if(color > 2) color = 0;
2712 if (active_page != 0) {
2713 offset = offset_point_bank1 << 1;
2715 offset = offset_point << 1;
2717 naddr = (addr & 0x7fff) >> 4;
2718 pagemod = 0x8000 * color;
2719 vramaddr = (((addr + offset) & 0x7fff) | pagemod) + page_offset_alt;
2720 tdata = gvram[vramaddr];
2721 if(tdata != (uint8_t)data) {
2722 gvram[vramaddr] = data;
2723 vram_wrote_table[naddr] = true;
2727 write_vram_data8(addr, data);
2729 write_vram_data8(addr, data);
2731 //if((config.dipswitch & FM7_DIPSW_SYNC_TO_HSYNC) == 0) vram_wrote = true;
2738 uint32_t DISPLAY::read_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
2744 if((name == NULL) || (ptr == NULL)) return 0;
2745 s = create_local_path(name);
2746 if(s == NULL) return 0;
2748 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
2749 blocks = fio.Fread(ptr, size, 1);
2752 return blocks * size;
2756 void DISPLAY::initialize()
2760 screen_update_flag = true;
2761 memset(gvram, 0x00, sizeof(gvram));
2762 vram_wrote_shadow = false;
2763 memset(gvram_shadow, 0x00, sizeof(gvram_shadow));
2764 for(i = 0; i < 411 * 5; i++) vram_wrote_table[i] = false;
2765 for(i = 0; i < 411; i++) vram_draw_table[i] = false;
2767 memset(console_ram, 0x00, sizeof(console_ram));
2768 memset(work_ram, 0x00, sizeof(work_ram));
2769 memset(shared_ram, 0x00, sizeof(shared_ram));
2770 memset(subsys_c, 0xff, sizeof(subsys_c));
2771 need_transfer_line = true;
2772 frame_skip_count_draw = 3;
2773 frame_skip_count_transfer = 3;
2775 diag_load_subrom_c = false;
2777 if(read_bios(_T("SUBSYS_8.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2778 this->out_debug_log(_T("SUBSYSTEM ROM READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2780 if(read_bios(_T("SUBSYS_C.ROM"), subsys_c, 0x2800) >= 0x2800) diag_load_subrom_c = true;
2781 this->out_debug_log(_T("SUBSYSTEM ROM Type C READING : %s"), diag_load_subrom_c ? "OK" : "NG");
2783 #if defined(_FM77AV_VARIANTS)
2784 memset(subsys_a, 0xff, sizeof(subsys_a));
2785 memset(subsys_b, 0xff, sizeof(subsys_b));
2786 memset(subsys_cg, 0xff, sizeof(subsys_cg));
2787 memset(submem_hidden, 0x00, sizeof(submem_hidden));
2789 diag_load_subrom_a = false;
2790 if(read_bios(_T("SUBSYS_A.ROM"), subsys_a, 0x2000) >= 0x2000) diag_load_subrom_a = true;
2791 this->out_debug_log(_T("SUBSYSTEM ROM Type A READING : %s"), diag_load_subrom_a ? "OK" : "NG");
2793 diag_load_subrom_b = false;
2794 if(read_bios(_T("SUBSYS_B.ROM"), subsys_b, 0x2000) >= 0x2000) diag_load_subrom_b = true;
2795 this->out_debug_log(_T("SUBSYSTEM ROM Type B READING : %s"), diag_load_subrom_b ? "OK" : "NG");
2797 diag_load_subrom_cg = false;
2798 if(read_bios(_T("SUBSYSCG.ROM"), subsys_cg, 0x2000) >= 0x2000) diag_load_subrom_cg = true;
2799 this->out_debug_log(_T("SUBSYSTEM CG ROM READING : %s"), diag_load_subrom_cg ? "OK" : "NG");
2800 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2801 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2802 memset(subsys_ram, 0x00, sizeof(subsys_ram));
2803 memset(submem_cgram, 0x00, sizeof(submem_cgram));
2804 memset(submem_console_av40, 0x00, sizeof(submem_console_av40));
2811 #if defined(_FM77AV_VARIANTS)
2813 apalette_index.d = 0;
2814 for(i = 0; i < 4096; i++) {
2815 analog_palette_r[i] = i & 0x0f0;
2816 analog_palette_g[i] = (i & 0xf00) >> 4;
2817 analog_palette_b[i] = (i & 0x00f) << 4;
2821 #if defined(_FM77AV_VARIANTS)
2822 hblank_event_id = -1;
2823 hdisp_event_id = -1;
2824 vsync_event_id = -1;
2825 vstart_event_id = -1;
2832 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
2833 is_cyclesteal = true;
2835 is_cyclesteal = false;
2837 multimode_accessmask = multimode_dispmask = 0;
2838 for(i = 0; i < 4; i++) {
2839 multimode_accessflags[i] = ((multimode_accessmask & (1 << i)) != 0) ? true : false;
2840 multimode_dispflags[i] = ((multimode_dispmask & (1 << i)) != 0) ? true : false;
2843 #if !defined(FIXED_FRAMEBUFFER_SIZE)
2844 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2846 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2848 prev_clock = SUBCLOCK_NORMAL;
2852 key_firq_req = false; //firq_mask = true;
2853 frame_skip_count_transfer = 3;
2854 frame_skip_count_draw = 3;
2855 #if !defined(FIXED_FRAMEBUFFER_SIZE)
2856 emu->set_vm_screen_size(640, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2858 emu->set_vm_screen_size(640, 400, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
2861 palette_changed = true;
2862 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
2863 //register_vline_event(this);
2864 //register_frame_event(this);
2866 setup_display_mode();
2869 void DISPLAY::release()
2873 #define STATE_VERSION 8
2874 void DISPLAY::save_state(FILEIO *state_fio)
2876 state_fio->FputUint32_BE(STATE_VERSION);
2877 state_fio->FputInt32_BE(this_device_id);
2878 this->out_debug_log(_T("Save State: DISPLAY : id=%d ver=%d\n"), this_device_id, STATE_VERSION);
2882 state_fio->FputInt32_BE(clr_count);
2883 state_fio->FputBool(halt_flag);
2884 state_fio->FputInt32_BE(active_page);
2885 state_fio->FputBool(sub_busy);
2886 state_fio->FputBool(crt_flag);
2887 state_fio->FputBool(vram_wrote);
2888 state_fio->FputBool(is_cyclesteal);
2890 state_fio->FputBool(clock_fast);
2892 #if defined(_FM77AV_VARIANTS)
2893 state_fio->FputBool(subcpu_resetreq);
2894 state_fio->FputBool(power_on_reset);
2896 state_fio->FputBool(cancel_request);
2897 state_fio->FputBool(key_firq_req);
2899 state_fio->FputInt32_BE(display_mode);
2900 state_fio->FputUint32_BE(prev_clock);
2903 state_fio->Fwrite(dpalette_data, sizeof(dpalette_data), 1);
2904 state_fio->FputUint8(multimode_accessmask);
2905 state_fio->FputUint8(multimode_dispmask);
2907 state_fio->FputUint32_BE(offset_point);
2908 #if defined(_FM77AV_VARIANTS)
2909 state_fio->FputUint32_BE(offset_point_bank1);
2911 for(i = 0; i < 2; i++) {
2912 state_fio->FputUint32_BE(tmp_offset_point[i].d);
2913 state_fio->FputBool(offset_changed[i]);
2915 state_fio->FputBool(offset_77av);
2916 state_fio->FputBool(diag_load_subrom_c);
2919 state_fio->Fwrite(io_w_latch, sizeof(io_w_latch), 1);
2920 state_fio->Fwrite(console_ram, sizeof(console_ram), 1);
2921 state_fio->Fwrite(work_ram, sizeof(work_ram), 1);
2922 state_fio->Fwrite(shared_ram, sizeof(shared_ram), 1);
2923 state_fio->Fwrite(subsys_c, sizeof(subsys_c), 1);
2924 state_fio->Fwrite(gvram, sizeof(gvram), 1);
2925 state_fio->Fwrite(gvram_shadow, sizeof(gvram_shadow), 1);
2927 #if defined(_FM77_VARIANTS)
2928 state_fio->FputBool(kanjisub);
2929 state_fio->FputUint16_BE(kanjiaddr.w.l);
2930 # if defined(_FM77L4)
2931 state_fio->FputBool(mode400line);
2932 state_fio->FputBool(stat_400linecard);
2934 #elif defined(_FM77AV_VARIANTS)
2935 state_fio->FputBool(kanjisub);
2936 state_fio->FputUint16_BE(kanjiaddr.w.l);
2938 state_fio->FputBool(vblank);
2939 state_fio->FputBool(vsync);
2940 state_fio->FputBool(hblank);
2941 state_fio->FputInt32_BE(vblank_count);
2943 state_fio->FputBool(mode320);
2944 state_fio->FputInt8(display_page);
2945 state_fio->FputInt8(display_page_bak);
2946 state_fio->FputInt32_BE(cgrom_bank);
2947 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
2948 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2949 state_fio->FputInt32_BE(vram_bank);
2952 state_fio->FputUint32_BE(displine);
2953 state_fio->FputUint8(subrom_bank);
2954 state_fio->FputUint8(subrom_bank_using);
2956 state_fio->FputBool(nmi_enable);
2957 state_fio->FputBool(use_alu);
2959 state_fio->FputUint8(apalette_index.b.l);
2960 state_fio->FputUint8(apalette_index.b.h);
2961 state_fio->Fwrite(analog_palette_r, sizeof(analog_palette_r), 1);
2962 state_fio->Fwrite(analog_palette_g, sizeof(analog_palette_g), 1);
2963 state_fio->Fwrite(analog_palette_b, sizeof(analog_palette_b), 1);
2966 state_fio->FputBool(diag_load_subrom_a);
2967 state_fio->FputBool(diag_load_subrom_b);
2968 state_fio->FputBool(diag_load_subrom_cg);
2970 state_fio->Fwrite(subsys_a, sizeof(subsys_a), 1);
2971 state_fio->Fwrite(subsys_b, sizeof(subsys_b), 1);
2972 state_fio->Fwrite(subsys_cg, sizeof(subsys_cg), 1);
2973 state_fio->Fwrite(submem_hidden, sizeof(submem_hidden), 1);
2974 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
2975 state_fio->FputBool(mode400line);
2976 state_fio->FputBool(mode256k);
2978 state_fio->FputBool(monitor_ram);
2979 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
2980 state_fio->FputUint16_BE(window_low);
2981 state_fio->FputUint16_BE(window_high);
2982 state_fio->FputUint16_BE(window_xbegin);
2983 state_fio->FputUint16_BE(window_xend);
2984 state_fio->FputBool(window_opened);
2986 state_fio->FputBool(kanji_level2);
2988 state_fio->FputUint8(vram_active_block);
2989 state_fio->FputUint8(vram_display_block);
2990 state_fio->FputUint8(console_ram_bank);
2991 state_fio->FputBool(ram_protect);
2993 state_fio->FputUint32_BE(cgram_bank);
2994 state_fio->Fwrite(subsys_ram, sizeof(subsys_ram), 1);
2995 state_fio->Fwrite(submem_cgram, sizeof(submem_cgram), 1);
2996 state_fio->Fwrite(submem_console_av40, sizeof(submem_console_av40), 1);
3002 state_fio->FputInt32_BE(nmi_event_id);
3003 #if defined(_FM77AV_VARIANTS)
3004 state_fio->FputInt32_BE(hblank_event_id);
3005 state_fio->FputInt32_BE(hdisp_event_id);
3006 state_fio->FputInt32_BE(vsync_event_id);
3007 state_fio->FputInt32_BE(vstart_event_id);
3009 state_fio->FputBool(firq_mask);
3010 state_fio->FputBool(vram_accessflag);
3014 bool DISPLAY::load_state(FILEIO *state_fio)
3017 uint32_t version = state_fio->FgetUint32_BE();
3018 if(this_device_id != state_fio->FgetInt32_BE()) {
3021 this->out_debug_log(_T("Load State: DISPLAY : id=%d ver=%d\n"), this_device_id, version);
3026 clr_count = state_fio->FgetInt32_BE();
3027 halt_flag = state_fio->FgetBool();
3028 active_page = state_fio->FgetInt32_BE();
3029 sub_busy = state_fio->FgetBool();
3030 crt_flag = state_fio->FgetBool();
3031 vram_wrote = state_fio->FgetBool();
3032 crt_flag_bak = true;
3033 for(i = 0; i < 411 * 5; i++) vram_wrote_table[i] = true;
3034 for(i = 0; i < 411; i++) vram_draw_table[i] = true;
3035 is_cyclesteal = state_fio->FgetBool();
3037 clock_fast = state_fio->FgetBool();
3039 #if defined(_FM77AV_VARIANTS)
3040 subcpu_resetreq = state_fio->FgetBool();
3041 power_on_reset = state_fio->FgetBool();
3043 cancel_request = state_fio->FgetBool();
3044 key_firq_req = state_fio->FgetBool();
3046 display_mode = state_fio->FgetInt32_BE();
3047 prev_clock = state_fio->FgetUint32_BE();
3050 for(addr = 0; addr < 8; addr++) set_dpalette(addr, addr);
3052 state_fio->Fread(dpalette_data, sizeof(dpalette_data), 1);
3053 for(addr = 0; addr < 8; addr++) set_dpalette(addr, dpalette_data[addr]);
3054 multimode_accessmask = state_fio->FgetUint8();
3055 multimode_dispmask = state_fio->FgetUint8();
3056 for(i = 0; i < 4; i++) {
3057 multimode_accessflags[i] = ((multimode_accessmask & (1 << i)) != 0) ? true : false;
3058 multimode_dispflags[i] = ((multimode_dispmask & (1 << i)) != 0) ? true : false;
3061 offset_point = state_fio->FgetUint32_BE();
3062 #if defined(_FM77AV_VARIANTS)
3063 offset_point_bank1 = state_fio->FgetUint32_BE();
3065 for(i = 0; i < 2; i++) {
3066 tmp_offset_point[i].d = state_fio->FgetUint32_BE();
3067 offset_changed[i] = state_fio->FgetBool();
3069 offset_77av = state_fio->FgetBool();
3070 diag_load_subrom_c = state_fio->FgetBool();
3072 state_fio->Fread(io_w_latch, sizeof(io_w_latch), 1);
3073 state_fio->Fread(console_ram, sizeof(console_ram), 1);
3074 state_fio->Fread(work_ram, sizeof(work_ram), 1);
3075 state_fio->Fread(shared_ram, sizeof(shared_ram), 1);
3076 state_fio->Fread(subsys_c, sizeof(subsys_c), 1);
3077 state_fio->Fread(gvram, sizeof(gvram), 1);
3078 state_fio->Fread(gvram_shadow, sizeof(gvram_shadow), 1);
3079 #if defined(_FM77_VARIANTS)
3080 kanjisub = state_fio->FgetBool();
3082 kanjiaddr.w.l = state_fio->FgetUint16_BE();
3083 # if defined(_FM77L4)
3084 mode400line = state_fio->FgetBool();
3085 stat_400linecard = state_fio->FgetBool();
3087 #elif defined(_FM77AV_VARIANTS)
3088 kanjisub = state_fio->FgetBool();
3090 kanjiaddr.w.l = state_fio->FgetUint16_BE();
3092 vblank = state_fio->FgetBool();
3093 vsync = state_fio->FgetBool();
3094 hblank = state_fio->FgetBool();
3095 vblank_count = state_fio->FgetInt32_BE();
3097 mode320 = state_fio->FgetBool();
3098 display_page = state_fio->FgetInt8();
3099 display_page_bak = state_fio->FgetInt8();
3100 cgrom_bank = state_fio->FgetInt32_BE();
3101 #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \
3102 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
3103 vram_bank = state_fio->FgetInt32_BE();
3105 screen_update_flag = true;
3106 displine = state_fio->FgetUint32_BE();
3107 subrom_bank = state_fio->FgetUint8();
3108 subrom_bank_using = state_fio->FgetUint8();
3110 nmi_enable = state_fio->FgetBool();
3111 use_alu = state_fio->FgetBool();
3113 apalette_index.b.l = state_fio->FgetUint8();
3114 apalette_index.b.h = state_fio->FgetUint8();
3116 state_fio->Fread(analog_palette_r, sizeof(analog_palette_r), 1);
3117 state_fio->Fread(analog_palette_g, sizeof(analog_palette_g), 1);
3118 state_fio->Fread(analog_palette_b, sizeof(analog_palette_b), 1);
3119 for(i = 0; i < 4096; i++) calc_apalette(i);
3121 diag_load_subrom_a = state_fio->FgetBool();
3122 diag_load_subrom_b = state_fio->FgetBool();
3123 diag_load_subrom_cg = state_fio->FgetBool();
3125 state_fio->Fread(subsys_a, sizeof(subsys_a), 1);
3126 state_fio->Fread(subsys_b, sizeof(subsys_b), 1);
3127 state_fio->Fread(subsys_cg, sizeof(subsys_cg), 1);
3128 state_fio->Fread(submem_hidden, sizeof(submem_hidden), 1);
3130 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
3131 mode400line = state_fio->FgetBool();
3132 mode256k = state_fio->FgetBool();
3134 monitor_ram = state_fio->FgetBool();
3135 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
3136 window_low = state_fio->FgetUint16_BE();
3137 window_high = state_fio->FgetUint16_BE();
3138 window_xbegin = state_fio->FgetUint16_BE();
3139 window_xend = state_fio->FgetUint16_BE();
3140 window_opened = state_fio->FgetBool();
3142 kanji_level2 = state_fio->FgetBool();
3144 vram_active_block = state_fio->FgetUint8();
3145 vram_display_block = state_fio->FgetUint8();
3146 console_ram_bank = state_fio->FgetUint8();
3147 ram_protect = state_fio->FgetBool();
3149 cgram_bank = state_fio->FgetUint32_BE();
3150 state_fio->Fread(subsys_ram, sizeof(subsys_ram), 1);
3151 state_fio->Fread(submem_cgram, sizeof(submem_cgram), 1);
3152 state_fio->Fread(submem_console_av40, sizeof(submem_console_av40), 1);
3155 palette_changed = true;
3156 vram_wrote_shadow = true; // Force Draw
3157 this->draw_screen();
3158 if(version == 1) return true;
3160 if(version >= 2) { //V2
3161 nmi_event_id = state_fio->FgetInt32_BE();
3162 #if defined(_FM77AV_VARIANTS)
3163 hblank_event_id = state_fio->FgetInt32_BE();
3164 hdisp_event_id = state_fio->FgetInt32_BE();
3165 vsync_event_id = state_fio->FgetInt32_BE();
3166 vstart_event_id = state_fio->FgetInt32_BE();
3168 firq_mask = state_fio->FgetBool();
3169 vram_accessflag = state_fio->FgetBool();
3170 frame_skip_count_draw = 3;
3171 frame_skip_count_transfer = 3;
3172 need_transfer_line = true;
3174 if(version == STATE_VERSION) return true;
3175 setup_display_mode();