2 SHARP MZ-700 Emulator 'EmuZ-700'
3 SHARP MZ-800 Emulator 'EmuZ-800'
4 SHARP MZ-1500 Emulator 'EmuZ-1500'
6 Author : Takeda.Toshiya
16 #include "../z80pio.h"
21 #define EVENT_HBLANK 2
22 #define EVENT_HSYNC_S 3
23 #define EVENT_HSYNC_E 4
25 #define EVENT_HBLANK_PCG 5
28 #define MEM_BANK_MON_L 0x01
29 #define MEM_BANK_MON_H 0x02
31 #define MEM_BANK_CGROM_R 0x04
32 #define MEM_BANK_CGROM_W 0x08
33 #define MEM_BANK_CGROM (MEM_BANK_CGROM_R | MEM_BANK_CGROM_W)
34 #define MEM_BANK_VRAM 0x10
36 #if defined(_MZ800) || defined(_MZ1500)
37 #define MEM_BANK_PCG 0x20
41 #define MZ700_MODE (dmd & 8)
44 #define SET_BANK(s, e, w, r) { \
45 int sb = (s) >> 11, eb = (e) >> 11; \
46 for(int i = sb; i <= eb; i++) { \
50 wbank[i] = (w) + 0x800 * (i - sb); \
55 rbank[i] = (r) + 0x800 * (i - sb); \
61 #define IPL_FILE_NAME "MZ700IPL.ROM"
62 #define EXT_FILE_NAME "MZ800IPL.ROM"
64 #define IPL_FILE_NAME "IPL.ROM"
65 #define EXT_FILE_NAME "EXT.ROM"
68 void MEMORY::initialize()
71 memset(ipl, 0xff, sizeof(ipl));
72 memset(ram, 0, sizeof(ram));
73 memset(vram, 0, sizeof(vram));
74 #if defined(_MZ700) || defined(_MZ1500)
75 memset(vram + 0x800, 0x71, 0x400);
77 #if defined(_MZ800) || defined(_MZ1500)
78 memset(ext, 0xff, sizeof(ext));
81 memset(pcg, 0, sizeof(pcg));
83 memset(font, 0, sizeof(font));
84 memset(rdmy, 0xff, sizeof(rdmy));
87 FILEIO* fio = new FILEIO();
88 if(fio->Fopen(create_local_path(_T(IPL_FILE_NAME)), FILEIO_READ_BINARY)) {
89 fio->Fread(ipl, sizeof(ipl), 1);
92 #if defined(_MZ800) || defined(_MZ1500)
93 if(fio->Fopen(create_local_path(_T(EXT_FILE_NAME)), FILEIO_READ_BINARY)) {
94 fio->Fread(ext, sizeof(ext), 1);
98 if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
99 fio->Fread(font, sizeof(font), 1);
106 memset(pcg, 0, sizeof(pcg));
107 memcpy(pcg + 0x000, font + 0x000, 0x400);
108 memcpy(pcg + 0x800, font + 0x800, 0x400);
112 SET_BANK(0x0000, 0xffff, ram, ram);
118 for(int i = 0; i < 8; i++) {
119 palette_pc[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
124 register_vline_event(this);
125 register_event_by_clock(this, EVENT_TEMPO, CPU_CLOCKS / 64, true, NULL); // 32hz * 2
126 register_event_by_clock(this, EVENT_BLINK, CPU_CLOCKS / 3, true, NULL); // 1.5hz * 2
134 is_mz800 = (config.boot_mode == 0);
138 mem_bank = MEM_BANK_MON_L | MEM_BANK_MON_H;
140 // TODO: check initial params
143 vram_addr_top = 0x9fff;
144 #elif defined(_MZ1500)
158 blink = tempo = false;
159 vblank = vsync = true;
160 hblank = hsync = true;
161 #if defined(_MZ700) || defined(_MZ1500)
170 pcg_data = pcg_addr = 0;
177 for(int i = 0; i < 4; i++) {
180 for(int i = 0; i < 16; i++) {
183 #elif defined(_MZ1500)
184 for(int i = 0; i < 8; i++) {
189 // motor is always rotating...
190 d_pio->write_signal(SIG_I8255_PORT_C, 0xff, 0x10);
194 void MEMORY::update_config()
196 if(config.monitor_type == 0) {
198 for(int i = 0; i < 8; i++) {
199 palette_pc[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
201 for(int i = 0; i < 16; i++) {
202 int val = (i & 8) ? 255 : 127;
203 palette_mz800_pc[i] = RGB_COLOR((i & 2) ? val : 0, (i & 4) ? val : 0, (i & 1) ? val : 0);
207 for(int i = 0; i < 8; i++) {
208 palette_pc[i] = RGB_COLOR(255 * i / 7, 255 * i / 7, 255 * i / 7);
210 for(int i = 0; i < 16; i++) {
211 palette_mz800_pc[i] = RGB_COLOR(255 * i / 15, 255 * i / 15, 255 * i / 15);
214 palette_mz800_pc[8] = palette_mz800_pc[7];
218 void MEMORY::event_vline(int v, int clock)
221 set_vblank(v >= 200);
223 vsync = (v >= 240 && v <= 242);
225 vsync = (v >= 221 && v <= 223);
231 register_event_by_clock(this, EVENT_HBLANK, 128, false, NULL); // PAL 50Hz
232 register_event_by_clock(this, EVENT_HSYNC_S, 161, false, NULL);
233 register_event_by_clock(this, EVENT_HSYNC_E, 177, false, NULL);
235 register_event_by_clock(this, EVENT_HBLANK, 165, false, NULL); // NTSC 60Hz
236 // register_event_by_clock(this, EVENT_HSYNC_S, 180, false, NULL);
237 // register_event_by_clock(this, EVENT_HSYNC_E, 194, false, NULL);
240 #if defined(_MZ700) || defined(_MZ1500)
241 // memory wait for vram
244 // memory wait for pcg
245 register_event_by_clock(this, EVENT_HBLANK_PCG, 170, false, NULL);
254 case 0x00: // 320x200,4col
256 draw_line_320x200_2bpp(v);
258 case 0x02: // 320x200,16col
259 draw_line_320x200_4bpp(v);
261 case 0x04: // 640x200,2col
263 draw_line_640x200_1bpp(v);
265 case 0x06: // 640x200,4col
266 draw_line_640x200_2bpp(v);
278 void MEMORY::event_callback(int event_id, int err)
280 if(event_id == EVENT_TEMPO) {
283 } else if(event_id == EVENT_BLINK) {
284 // 556 OUT (1.5KHz) -> 8255:PC6
285 d_pio->write_signal(SIG_I8255_PORT_C, (blink = !blink) ? 0xff : 0, 0x40);
286 } else if(event_id == EVENT_HBLANK) {
288 #if defined(_MZ700) || defined(_MZ1500)
290 // wait because vram is accessed
291 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
295 } else if(event_id == EVENT_HSYNC_S) {
297 } else if(event_id == EVENT_HSYNC_E) {
300 } else if(event_id == EVENT_HBLANK_PCG) {
302 // wait because pcg is accessed
303 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
310 void MEMORY::write_data8(uint32_t addr, uint32_t data)
316 if(0xe000 <= addr && addr <= 0xe00f && (mem_bank & MEM_BANK_MON_H)) {
318 switch(addr & 0x0f) {
319 case 0: case 1: case 2: case 3:
320 d_pio->write_io8(addr & 3, data);
322 case 4: case 5: case 6: case 7:
323 d_pit->write_io8(addr & 3, data);
327 // d_pit->write_signal(SIG_I8253_GATE_0, data, 1);
333 if(0x8000 <= addr && addr <= vram_addr_top && (mem_bank & MEM_BANK_VRAM)) {
334 addr = vram_addr(addr & 0x3fff);
337 case 0x00: // single write
338 page = (dmd & 4) ? (wf & 5) : wf;
339 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
346 page = (dmd & 4) ? (wf & 5) : wf;
347 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
354 page = (dmd & 4) ? (wf & 5) : wf;
355 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
362 page = (dmd & 4) ? (wf & 5) : wf;
363 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
369 case 0x80: // replace
371 page = vram_page_mask(wf);
372 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
384 page = vram_page_mask(wf);
385 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
402 if(mem_bank & MEM_BANK_PCG) {
403 if(0xd000 <= addr && addr <= 0xefff) {
406 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
412 if(mem_bank & MEM_BANK_MON_H) {
413 if(0xd000 <= addr && addr <= 0xdfff) {
416 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
419 } else if(0xe000 <= addr && addr <= 0xe00f) {
421 switch(addr & 0x0f) {
422 case 0: case 1: case 2: case 3:
423 d_pio->write_io8(addr & 3, data);
425 case 4: case 5: case 6: case 7:
426 d_pit->write_io8(addr & 3, data);
430 d_pit->write_signal(SIG_I8253_GATE_0, data, 1);
435 } else if(addr == 0xe010) {
438 } else if(addr == 0xe011) {
441 } else if(addr == 0xe012) {
442 if(!(pcg_ctrl & 0x10) && (data & 0x10)) {
443 int offset = pcg_addr | ((data & 3) << 8);
444 offset |= (data & 4) ? 0xc00 : 0x400;
445 pcg[offset] = (data & 0x20) ? font[offset] : pcg_data;
456 wbank[addr >> 11][addr & 0x7ff] = data;
459 uint32_t MEMORY::read_data8(uint32_t addr)
465 if(0xe000 <= addr && addr <= 0xe00f && (mem_bank & MEM_BANK_MON_H)) {
467 switch(addr & 0x0f) {
468 case 0: case 1: case 2: case 3:
469 return d_pio->read_io8(addr & 3);
470 case 4: case 5: case 6: case 7:
471 return d_pit->read_io8(addr & 3);
473 return (hblank ? 0 : 0x80) | (tempo ? 1 : 0) | 0x7e;
478 if(0x8000 <= addr && addr <= vram_addr_top && (mem_bank & MEM_BANK_VRAM)) {
479 addr = vram_addr(addr & 0x3fff);
481 int page = vram_page_mask(rf);
482 uint32_t result = 0xff;
483 for(int bit2 = 1; bit2 <= 0x80; bit2 <<= 1) {
484 uint32_t addr2 = addr;
485 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr2 += 0x2000) {
486 if((page & bit) && (vram[addr2] & bit2) != ((rf & bit) ? bit2 : 0)) {
494 int page = vram_page_mask(rf) & rf;
495 for(int i = 0, bit = 1; i < 4; i++, bit <<= 1, addr += 0x2000) {
507 if(mem_bank & MEM_BANK_PCG) {
508 if(0xd000 <= addr && addr <= 0xefff) {
511 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
517 if(mem_bank & MEM_BANK_MON_H) {
518 if(0xd000 <= addr && addr <= 0xdfff) {
521 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
524 } else if(0xe000 <= addr && addr <= 0xe00f) {
526 switch(addr & 0x0f) {
527 case 0: case 1: case 2: case 3:
528 return d_pio->read_io8(addr & 3);
529 case 4: case 5: case 6: case 7:
530 return d_pit->read_io8(addr & 3);
532 return (hblank ? 0 : 0x80) | (tempo ? 1 : 0) | 0x7e;
541 return rbank[addr >> 11][addr & 0x7ff];
544 void MEMORY::write_data8w(uint32_t addr, uint32_t data, int* wait)
546 *wait = ((mem_bank & MEM_BANK_MON_L) && addr < 0x1000) ? 1 : 0;
547 write_data8(addr, data);
550 uint32_t MEMORY::read_data8w(uint32_t addr, int* wait)
552 *wait = ((mem_bank & MEM_BANK_MON_L) && addr < 0x1000) ? 1 : 0;
553 return read_data8(addr);
556 void MEMORY::write_io8(uint32_t addr, uint32_t data)
558 switch(addr & 0xff) {
567 vram_addr_top = (data & 4) ? 0xbfff : 0x9fff;
572 switch(addr & 0x7ff) {
574 sof = (sof & 0xf00) | data;
577 sof = (sof & 0x0ff) | ((data & 3) << 8);
592 mem_bank &= ~MEM_BANK_MON_L;
594 mem_bank &= ~MEM_BANK_CGROM;
600 mem_bank &= ~MEM_BANK_MON_H;
604 mem_bank |= MEM_BANK_MON_L;
608 mem_bank |= MEM_BANK_MON_H;
612 mem_bank |= MEM_BANK_MON_L | MEM_BANK_MON_H;
614 mem_bank &= ~MEM_BANK_CGROM_R;
615 mem_bank |= MEM_BANK_CGROM_W | MEM_BANK_VRAM;
616 #elif defined(_MZ1500)
617 mem_bank &= ~MEM_BANK_PCG;
623 #if defined(_MZ800) || defined(_MZ1500)
625 mem_bank |= MEM_BANK_PCG;
632 mem_bank &= ~MEM_BANK_PCG;
639 palette_sw = (data & 3) << 2;
641 palette[(data >> 4) & 3] = data & 0x0f;
643 for(int i = 0; i < 16; i++) {
644 palette16[i] = ((i & 0x0c) == palette_sw) ? palette[i & 3] : i;
647 #elif defined(_MZ1500)
652 palette[(data >> 4) & 7] = data & 7;
659 uint32_t MEMORY::read_io8(uint32_t addr)
661 switch(addr & 0xff) {
663 return (hblank ? 0 : 0x80) | (vblank ? 0 : 0x40) | (hsync ? 0 : 0x20) | (vsync ? 0 : 0x10) | (is_mz800 ? 2 : 0) | (tempo ? 1 : 0) | 0x0c;
665 mem_bank &= ~MEM_BANK_CGROM_W;
666 mem_bank |= MEM_BANK_CGROM_R | MEM_BANK_VRAM;
670 mem_bank &= ~(MEM_BANK_CGROM | MEM_BANK_VRAM);
678 void MEMORY::set_vblank(bool val)
681 // VBLANK -> 8255:PC7
682 d_pio->write_signal(SIG_I8255_PORT_C, val ? 0 : 0xff, 0x80);
684 // VBLANK -> Z80PIO:PA5
685 d_pio_int->write_signal(SIG_Z80PIO_PORT_A, val ? 0 : 0xff, 0x20);
691 void MEMORY::set_hblank(bool val)
698 void MEMORY::update_map_low()
700 if(mem_bank & MEM_BANK_MON_L) {
701 SET_BANK(0x0000, 0x0fff, wdmy, ipl);
703 SET_BANK(0x0000, 0x0fff, ram, ram);
707 void MEMORY::update_map_middle()
711 if(mem_bank & MEM_BANK_CGROM_R) {
712 SET_BANK(0x1000, 0x1fff, wdmy, font);
713 SET_BANK(0xc000, 0xcfff, vram + 0x2000, vram + 0x2000);
715 SET_BANK(0x1000, 0x1fff, ram + 0x1000, ram + 0x1000);
716 SET_BANK(0xc000, 0xcfff, ram + 0xc000, ram + 0xc000);
719 if(mem_bank & MEM_BANK_CGROM) {
720 SET_BANK(0x1000, 0x1fff, wdmy, font);
722 SET_BANK(0x1000, 0x1fff, ram + 0x1000, ram + 0x1000);
724 SET_BANK(0xc000, 0xcfff, ram + 0xc000, ram + 0xc000);
729 void MEMORY::update_map_high()
734 if(mem_bank & MEM_BANK_PCG) {
735 SET_BANK(0xd000, 0xffff, wdmy, rdmy);
736 } else if(mem_bank & MEM_BANK_MON_H) {
737 SET_BANK(0xd000, 0xdfff, vram + 0x3000, vram + 0x3000);
738 SET_BANK(0xe000, 0xffff, wdmy, ext);
740 SET_BANK(0xd000, 0xffff, ram + 0xd000, ram + 0xd000);
743 SET_BANK(0xd000, 0xdfff, ram + 0xd000, ram + 0xd000);
744 if(mem_bank & MEM_BANK_PCG) {
745 SET_BANK(0xe000, 0xffff, wdmy, rdmy);
746 } else if(mem_bank & MEM_BANK_MON_H) {
747 SET_BANK(0xe000, 0xffff, wdmy, ext);
749 SET_BANK(0xe000, 0xffff, ram + 0xe000, ram + 0xe000);
755 if(mem_bank & MEM_BANK_PCG) {
757 uint8_t *bank = pcg + ((pcg_bank & 3) - 1) * 0x2000;
758 SET_BANK(0xd000, 0xefff, bank, bank);
760 SET_BANK(0xd000, 0xdfff, wdmy, font); // read only
761 SET_BANK(0xe000, 0xefff, wdmy, font);
763 SET_BANK(0xf000, 0xffff, wdmy, rdmy);
766 if(mem_bank & MEM_BANK_MON_H) {
767 SET_BANK(0xd000, 0xdfff, vram, vram);
769 SET_BANK(0xe000, 0xe7ff, wdmy, rdmy);
770 SET_BANK(0xe800, 0xffff, wdmy, ext );
772 SET_BANK(0xe000, 0xffff, wdmy, rdmy);
775 SET_BANK(0xd000, 0xffff, ram + 0xd000, ram + 0xd000);
784 int MEMORY::vram_page_mask(uint8_t f)
787 case 0: // 320x200,4col
789 return (f & 0x10) ? (4 + 8) : (1 + 2);
790 case 2: // 320x200,16col
791 return (1 + 2 + 4 + 8);
792 case 4: // 640x200,2col
794 return (f & 0x10) ? 4 : 1;
795 case 6: // 640x200,4col
801 int MEMORY::vram_addr(int addr)
805 if(ssa * 128 <= addr && addr < sea * 128) {
807 if(addr >= sea * 128) {
813 if(ssa * 64 <= addr && addr < sea * 64) {
815 if(addr >= sea * 64) {
824 #if defined(_MZ700) || defined(_MZ1500)
825 void MEMORY::draw_line(int v)
827 int ptr = 40 * (v >> 3);
829 bool pcg_active = ((config.dipswitch & 1) && !(pcg_ctrl & 8));
832 for(int x = 0; x < 320; x += 8) {
833 uint8_t attr = vram[ptr | 0x800];
835 uint8_t pcg_attr = vram[ptr | 0xc00];
837 uint16_t code = (vram[ptr] << 3) | ((attr & 0x80) << 4);
838 uint8_t col_b = attr & 7;
839 uint8_t col_f = (attr >> 4) & 7;
841 uint8_t pat_t = pcg_active ? pcg[code | (v & 7)] : font[code | (v & 7)];
843 uint8_t pat_t = font[code | (v & 7)];
845 uint8_t* dest = &screen[v][x];
848 if((priority & 1) && (pcg_attr & 8)) {
849 uint16_t pcg_code = (vram[ptr | 0x400] << 3) | ((pcg_attr & 0xc0) << 5);
851 uint8_t pat_b = pcg[pcg_code | (v & 7) | 0x0000];
852 uint8_t pat_r = pcg[pcg_code | (v & 7) | 0x2000];
853 uint8_t pat_g = pcg[pcg_code | (v & 7) | 0x4000];
854 pcg_dot[0] = ((pat_b & 0x80) >> 7) | ((pat_r & 0x80) >> 6) | ((pat_g & 0x80) >> 5);
855 pcg_dot[1] = ((pat_b & 0x40) >> 6) | ((pat_r & 0x40) >> 5) | ((pat_g & 0x40) >> 4);
856 pcg_dot[2] = ((pat_b & 0x20) >> 5) | ((pat_r & 0x20) >> 4) | ((pat_g & 0x20) >> 3);
857 pcg_dot[3] = ((pat_b & 0x10) >> 4) | ((pat_r & 0x10) >> 3) | ((pat_g & 0x10) >> 2);
858 pcg_dot[4] = ((pat_b & 0x08) >> 3) | ((pat_r & 0x08) >> 2) | ((pat_g & 0x08) >> 1);
859 pcg_dot[5] = ((pat_b & 0x04) >> 2) | ((pat_r & 0x04) >> 1) | ((pat_g & 0x04) >> 0);
860 pcg_dot[6] = ((pat_b & 0x02) >> 1) | ((pat_r & 0x02) >> 0) | ((pat_g & 0x02) << 1);
861 pcg_dot[7] = ((pat_b & 0x01) >> 0) | ((pat_r & 0x01) << 1) | ((pat_g & 0x01) << 2);
865 dest[0] = pcg_dot[0] ? pcg_dot[0] : (pat_t & 0x80) ? col_f : col_b;
866 dest[1] = pcg_dot[1] ? pcg_dot[1] : (pat_t & 0x40) ? col_f : col_b;
867 dest[2] = pcg_dot[2] ? pcg_dot[2] : (pat_t & 0x20) ? col_f : col_b;
868 dest[3] = pcg_dot[3] ? pcg_dot[3] : (pat_t & 0x10) ? col_f : col_b;
869 dest[4] = pcg_dot[4] ? pcg_dot[4] : (pat_t & 0x08) ? col_f : col_b;
870 dest[5] = pcg_dot[5] ? pcg_dot[5] : (pat_t & 0x04) ? col_f : col_b;
871 dest[6] = pcg_dot[6] ? pcg_dot[6] : (pat_t & 0x02) ? col_f : col_b;
872 dest[7] = pcg_dot[7] ? pcg_dot[7] : (pat_t & 0x01) ? col_f : col_b;
874 // text_fore > pcg > text_back
875 dest[0] = (pat_t & 0x80) ? col_f : pcg_dot[0] ? pcg_dot[0] : col_b;
876 dest[1] = (pat_t & 0x40) ? col_f : pcg_dot[1] ? pcg_dot[1] : col_b;
877 dest[2] = (pat_t & 0x20) ? col_f : pcg_dot[2] ? pcg_dot[2] : col_b;
878 dest[3] = (pat_t & 0x10) ? col_f : pcg_dot[3] ? pcg_dot[3] : col_b;
879 dest[4] = (pat_t & 0x08) ? col_f : pcg_dot[4] ? pcg_dot[4] : col_b;
880 dest[5] = (pat_t & 0x04) ? col_f : pcg_dot[5] ? pcg_dot[5] : col_b;
881 dest[6] = (pat_t & 0x02) ? col_f : pcg_dot[6] ? pcg_dot[6] : col_b;
882 dest[7] = (pat_t & 0x01) ? col_f : pcg_dot[7] ? pcg_dot[7] : col_b;
887 dest[0] = (pat_t & 0x80) ? col_f : col_b;
888 dest[1] = (pat_t & 0x40) ? col_f : col_b;
889 dest[2] = (pat_t & 0x20) ? col_f : col_b;
890 dest[3] = (pat_t & 0x10) ? col_f : col_b;
891 dest[4] = (pat_t & 0x08) ? col_f : col_b;
892 dest[5] = (pat_t & 0x04) ? col_f : col_b;
893 dest[6] = (pat_t & 0x02) ? col_f : col_b;
894 dest[7] = (pat_t & 0x01) ? col_f : col_b;
902 void MEMORY::draw_screen()
904 // copy to real screen
905 emu->set_vm_screen_lines(200);
906 for(int y = 0; y < 200; y++) {
907 scrntype_t* dest0 = emu->get_screen_buffer(2 * y);
908 scrntype_t* dest1 = emu->get_screen_buffer(2 * y + 1);
909 uint8_t* src = screen[y];
911 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
913 dest0[x2] = dest0[x2 + 1] = palette_pc[palette[src[x] & 7]];
915 dest0[x2] = dest0[x2 + 1] = palette_pc[src[x] & 7];
918 if(!config.scan_line) {
919 my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
921 memset(dest1, 0, 640 * sizeof(scrntype_t));
924 emu->screen_skip_line(true);
927 void MEMORY::draw_line_320x200_2bpp(int v)
929 int ofs1 = (dmd & 1) ? 0x4000 : 0;
930 int ofs2 = ofs1 | 0x2000;
933 for(int x = 0; x < 320; x += 8) {
934 int addr = vram_addr(ptr++);
935 uint8_t pat1 = vram[addr | ofs1];
936 uint8_t pat2 = vram[addr | ofs2];
937 uint8_t* dest = &screen[v][x];
939 dest[0] = palette[((pat1 & 0x01) ) | ((pat2 & 0x01) << 1)];
940 dest[1] = palette[((pat1 & 0x02) >> 1) | ((pat2 & 0x02) )];
941 dest[2] = palette[((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1)];
942 dest[3] = palette[((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2)];
943 dest[4] = palette[((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3)];
944 dest[5] = palette[((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4)];
945 dest[6] = palette[((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5)];
946 dest[7] = palette[((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6)];
950 void MEMORY::draw_line_320x200_4bpp(int v)
954 for(int x = 0; x < 320; x += 8) {
955 int addr = vram_addr(ptr++);
956 uint8_t pat1 = vram[addr ];
957 uint8_t pat2 = vram[addr | 0x2000];
958 uint8_t pat3 = vram[addr | 0x4000];
959 uint8_t pat4 = vram[addr | 0x6000];
960 uint8_t* dest = &screen[v][x];
962 dest[0] = palette16[((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2) | ((pat4 & 0x01) << 3)];
963 dest[1] = palette16[((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1) | ((pat4 & 0x02) << 2)];
964 dest[2] = palette16[((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ) | ((pat4 & 0x04) << 1)];
965 dest[3] = palette16[((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1) | ((pat4 & 0x08) )];
966 dest[4] = palette16[((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2) | ((pat4 & 0x10) >> 1)];
967 dest[5] = palette16[((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3) | ((pat4 & 0x20) >> 2)];
968 dest[6] = palette16[((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4) | ((pat4 & 0x40) >> 3)];
969 dest[7] = palette16[((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5) | ((pat4 & 0x80) >> 4)];
973 void MEMORY::draw_line_640x200_1bpp(int v)
975 int ofs = (dmd & 1) ? 0x4000 : 0;
978 for(int x = 0; x < 640; x += 8) {
979 int addr = vram_addr(ptr++);
980 uint8_t pat = vram[addr | ofs];
981 uint8_t* dest = &screen[v][x];
983 dest[0] = palette[(pat & 0x01) ];
984 dest[1] = palette[(pat & 0x02) >> 1];
985 dest[2] = palette[(pat & 0x04) >> 2];
986 dest[3] = palette[(pat & 0x08) >> 3];
987 dest[4] = palette[(pat & 0x10) >> 4];
988 dest[5] = palette[(pat & 0x20) >> 5];
989 dest[6] = palette[(pat & 0x40) >> 6];
990 dest[7] = palette[(pat & 0x80) >> 7];
994 void MEMORY::draw_line_640x200_2bpp(int v)
998 for(int x = 0; x < 640; x += 8) {
999 int addr = vram_addr(ptr++);
1000 uint8_t pat1 = vram[addr ];
1001 uint8_t pat2 = vram[addr | 0x4000];
1002 uint8_t* dest = &screen[v][x];
1004 dest[0] = palette[((pat1 & 0x01) ) | ((pat2 & 0x01) << 1)];
1005 dest[1] = palette[((pat1 & 0x02) >> 1) | ((pat2 & 0x02) )];
1006 dest[2] = palette[((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1)];
1007 dest[3] = palette[((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2)];
1008 dest[4] = palette[((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3)];
1009 dest[5] = palette[((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4)];
1010 dest[6] = palette[((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5)];
1011 dest[7] = palette[((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6)];
1015 void MEMORY::draw_line_mz700(int v)
1017 int ptr = (40 * (v >> 3)) | 0x3000;
1019 for(int x = 0; x < 320; x += 8) {
1020 uint8_t attr = vram[ptr | 0x800];
1021 uint16_t code = (vram[ptr] << 3) | ((attr & 0x80) << 4);
1022 uint8_t col_b = attr & 7;
1023 uint8_t col_f = (attr >> 4) & 7;
1024 uint8_t pat_t = vram[code | (v & 7) | 0x2000];
1025 uint8_t* dest = &screen[v][x];
1028 dest[0] = (pat_t & 0x01) ? col_f : col_b;
1029 dest[1] = (pat_t & 0x02) ? col_f : col_b;
1030 dest[2] = (pat_t & 0x04) ? col_f : col_b;
1031 dest[3] = (pat_t & 0x08) ? col_f : col_b;
1032 dest[4] = (pat_t & 0x10) ? col_f : col_b;
1033 dest[5] = (pat_t & 0x20) ? col_f : col_b;
1034 dest[6] = (pat_t & 0x40) ? col_f : col_b;
1035 dest[7] = (pat_t & 0x80) ? col_f : col_b;
1040 void MEMORY::draw_screen()
1042 // copy to real screen
1043 emu->set_vm_screen_lines(200);
1044 for(int y = 0; y < 200; y++) {
1045 scrntype_t* dest0 = emu->get_screen_buffer(2 * y);
1046 scrntype_t* dest1 = emu->get_screen_buffer(2 * y + 1);
1047 uint8_t* src = screen[y];
1051 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
1052 dest0[x2] = dest0[x2 + 1] = palette_pc[src[x] & 7];
1054 } else if(dmd & 4) {
1056 for(int x = 0; x < 640; x++) {
1057 dest0[x] = palette_mz800_pc[src[x] & 15];
1061 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
1062 dest0[x2] = dest0[x2 + 1] = palette_mz800_pc[src[x] & 15];
1065 if(!config.scan_line) {
1066 my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
1068 memset(dest1, 0, 640 * sizeof(scrntype_t));
1071 emu->screen_skip_line(true);
1075 #define STATE_VERSION 2
1077 #include "../../statesub.h"
1079 void MEMORY::decl_state()
1081 enter_decl_state(STATE_VERSION);
1084 DECL_STATE_ENTRY_1D_ARRAY(&(pcg[0x400]), 0x400);
1085 DECL_STATE_ENTRY_1D_ARRAY(&(pcg[0xc00]), 0x400);
1086 #elif defined(_MZ1500)
1087 DECL_STATE_ENTRY_1D_ARRAY(pcg, sizeof(pcg));
1089 DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
1090 DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
1091 DECL_STATE_ENTRY_UINT8(mem_bank);
1093 DECL_STATE_ENTRY_UINT8(pcg_data);
1094 DECL_STATE_ENTRY_UINT8(pcg_addr);
1095 DECL_STATE_ENTRY_UINT8(pcg_ctrl);
1096 #elif defined(_MZ800)
1097 DECL_STATE_ENTRY_UINT8(wf);
1098 DECL_STATE_ENTRY_UINT8(rf);
1099 DECL_STATE_ENTRY_UINT8(dmd);
1100 DECL_STATE_ENTRY_UINT32(vram_addr_top);
1101 DECL_STATE_ENTRY_BOOL(is_mz800);
1102 #elif defined(_MZ1500)
1103 DECL_STATE_ENTRY_UINT8(pcg_bank);
1106 DECL_STATE_ENTRY_UINT16(sof);
1107 DECL_STATE_ENTRY_UINT8(sw);
1108 DECL_STATE_ENTRY_UINT8(ssa);
1109 DECL_STATE_ENTRY_UINT8(sea);
1110 DECL_STATE_ENTRY_UINT8(palette_sw);
1111 DECL_STATE_ENTRY_1D_ARRAY(palette, sizeof(palette));
1112 DECL_STATE_ENTRY_1D_ARRAY(palette16, sizeof(palette16));
1113 #elif defined(_MZ1500)
1114 DECL_STATE_ENTRY_UINT8(priority);
1115 DECL_STATE_ENTRY_1D_ARRAY(palette, sizeof(palette));
1117 DECL_STATE_ENTRY_BOOL(blink);
1118 DECL_STATE_ENTRY_BOOL(tempo);
1119 DECL_STATE_ENTRY_BOOL(hblank);
1120 DECL_STATE_ENTRY_BOOL(hsync);
1121 DECL_STATE_ENTRY_BOOL(vblank);
1122 DECL_STATE_ENTRY_BOOL(vsync);
1123 #if defined(_MZ700) || defined(_MZ1500)
1124 DECL_STATE_ENTRY_BOOL(hblank_vram);
1126 #if defined(_MZ1500)
1127 DECL_STATE_ENTRY_BOOL(hblank_pcg);
1130 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette_mz800_pc, sizeof(palette_mz800_pc) / sizeof(scrntype_t));
1132 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette_pc, sizeof(palette_pc) / sizeof(scrntype_t));
1137 void MEMORY::save_state(FILEIO* state_fio)
1139 if(state_entry != NULL) {
1140 state_entry->save_state(state_fio);
1142 // state_fio->FputUint32(STATE_VERSION);
1143 // state_fio->FputInt32(this_device_id);
1145 //#if defined(_MZ700)
1146 // state_fio->Fwrite(pcg + 0x400, 0x400, 1);
1147 // state_fio->Fwrite(pcg + 0xc00, 0x400, 1);
1148 //#elif defined(_MZ1500)
1149 // state_fio->Fwrite(pcg, sizeof(pcg), 1);
1151 // state_fio->Fwrite(ram, sizeof(ram), 1);
1152 // state_fio->Fwrite(vram, sizeof(vram), 1);
1153 // state_fio->FputUint8(mem_bank);
1154 //#if defined(_MZ700)
1155 // state_fio->FputUint8(pcg_data);
1156 // state_fio->FputUint8(pcg_addr);
1157 // state_fio->FputUint8(pcg_ctrl);
1158 //#elif defined(_MZ800)
1159 // state_fio->FputUint8(wf);
1160 // state_fio->FputUint8(rf);
1161 // state_fio->FputUint8(dmd);
1162 // state_fio->FputUint32(vram_addr_top);
1163 // state_fio->FputBool(is_mz800);
1164 //#elif defined(_MZ1500)
1165 // state_fio->FputUint8(pcg_bank);
1167 //#if defined(_MZ800)
1168 // state_fio->FputUint16(sof);
1169 // state_fio->FputUint8(sw);
1170 // state_fio->FputUint8(ssa);
1171 // state_fio->FputUint8(sea);
1172 // state_fio->FputUint8(palette_sw);
1173 // state_fio->Fwrite(palette, sizeof(palette), 1);
1174 // state_fio->Fwrite(palette16, sizeof(palette16), 1);
1175 //#elif defined(_MZ1500)
1176 // state_fio->FputUint8(priority);
1177 // state_fio->Fwrite(palette, sizeof(palette), 1);
1179 // state_fio->FputBool(blink);
1180 // state_fio->FputBool(tempo);
1181 // state_fio->FputBool(hblank);
1182 // state_fio->FputBool(hsync);
1183 // state_fio->FputBool(vblank);
1184 // state_fio->FputBool(vsync);
1185 //#if defined(_MZ700) || defined(_MZ1500)
1186 // state_fio->FputBool(hblank_vram);
1188 //#if defined(_MZ1500)
1189 // state_fio->FputBool(hblank_pcg);
1191 //#if defined(_MZ800)
1192 // state_fio->Fwrite(palette_mz800_pc, sizeof(palette_mz800_pc), 1);
1194 // state_fio->Fwrite(palette_pc, sizeof(palette_pc), 1);
1197 bool MEMORY::load_state(FILEIO* state_fio)
1200 if(state_entry != NULL) {
1201 mb = state_entry->load_state(state_fio);
1206 // if(state_fio->FgetUint32() != STATE_VERSION) {
1209 // if(state_fio->FgetInt32() != this_device_id) {
1212 //#if defined(_MZ700)
1213 // state_fio->Fread(pcg + 0x400, 0x400, 1);
1214 // state_fio->Fread(pcg + 0xc00, 0x400, 1);
1215 //#elif defined(_MZ1500)
1216 // state_fio->Fread(pcg, sizeof(pcg), 1);
1218 // state_fio->Fread(ram, sizeof(ram), 1);
1219 // state_fio->Fread(vram, sizeof(vram), 1);
1220 // mem_bank = state_fio->FgetUint8();
1221 //#if defined(_MZ700)
1222 // pcg_data = state_fio->FgetUint8();
1223 // pcg_addr = state_fio->FgetUint8();
1224 // pcg_ctrl = state_fio->FgetUint8();
1225 //#elif defined(_MZ800)
1226 // wf = state_fio->FgetUint8();
1227 // rf = state_fio->FgetUint8();
1228 // dmd = state_fio->FgetUint8();
1229 // vram_addr_top = state_fio->FgetUint32();
1230 // is_mz800 = state_fio->FgetBool();
1231 //#elif defined(_MZ1500)
1232 // pcg_bank = state_fio->FgetUint8();
1234 //#if defined(_MZ800)
1235 // sof = state_fio->FgetUint16();
1236 // sw = state_fio->FgetUint8();
1237 // ssa = state_fio->FgetUint8();
1238 // sea = state_fio->FgetUint8();
1239 // palette_sw = state_fio->FgetUint8();
1240 // state_fio->Fread(palette, sizeof(palette), 1);
1241 // state_fio->Fread(palette16, sizeof(palette16), 1);
1242 //#elif defined(_MZ1500)
1243 // priority = state_fio->FgetUint8();
1244 // state_fio->Fread(palette, sizeof(palette), 1);
1246 // blink = state_fio->FgetBool();
1247 // tempo = state_fio->FgetBool();
1248 // hblank = state_fio->FgetBool();
1249 // hsync = state_fio->FgetBool();
1250 // vblank = state_fio->FgetBool();
1251 // vsync = state_fio->FgetBool();
1252 //#if defined(_MZ700) || defined(_MZ1500)
1253 // hblank_vram = state_fio->FgetBool();
1255 //#if defined(_MZ1500)
1256 // hblank_pcg = state_fio->FgetBool();
1258 //#if defined(_MZ800)
1259 // state_fio->Fread(palette_mz800_pc, sizeof(palette_mz800_pc), 1);
1261 // state_fio->Fread(palette_pc, sizeof(palette_pc), 1);
1265 update_map_middle();
1270 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
1272 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1275 if(!state_fio->StateCheckInt32(this_device_id)) {
1279 state_fio->StateBuffer(pcg + 0x400, 0x400, 1);
1280 state_fio->StateBuffer(pcg + 0xc00, 0x400, 1);
1281 #elif defined(_MZ1500)
1282 state_fio->StateBuffer(pcg, sizeof(pcg), 1);
1284 state_fio->StateBuffer(ram, sizeof(ram), 1);
1285 state_fio->StateBuffer(vram, sizeof(vram), 1);
1286 state_fio->StateUint8(mem_bank);
1288 state_fio->StateUint8(pcg_data);
1289 state_fio->StateUint8(pcg_addr);
1290 state_fio->StateUint8(pcg_ctrl);
1291 #elif defined(_MZ800)
1292 state_fio->StateUint8(wf);
1293 state_fio->StateUint8(rf);
1294 state_fio->StateUint8(dmd);
1295 state_fio->StateUint32(vram_addr_top);
1296 state_fio->StateBool(is_mz800);
1297 #elif defined(_MZ1500)
1298 state_fio->StateUint8(pcg_bank);
1301 state_fio->StateUint16(sof);
1302 state_fio->StateUint8(sw);
1303 state_fio->StateUint8(ssa);
1304 state_fio->StateUint8(sea);
1305 state_fio->StateUint8(palette_sw);
1306 state_fio->StateBuffer(palette, sizeof(palette), 1);
1307 state_fio->StateBuffer(palette16, sizeof(palette16), 1);
1308 #elif defined(_MZ1500)
1309 state_fio->StateUint8(priority);
1310 state_fio->StateBuffer(palette, sizeof(palette), 1);
1312 state_fio->StateBool(blink);
1313 state_fio->StateBool(tempo);
1314 state_fio->StateBool(hblank);
1315 state_fio->StateBool(hsync);
1316 state_fio->StateBool(vblank);
1317 state_fio->StateBool(vsync);
1318 #if defined(_MZ700) || defined(_MZ1500)
1319 state_fio->StateBool(hblank_vram);
1321 #if defined(_MZ1500)
1322 state_fio->StateBool(hblank_pcg);
1325 state_fio->StateBuffer(palette_mz800_pc, sizeof(palette_mz800_pc), 1);
1327 state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
1332 update_map_middle();