2 FUJITSU FMR-50 Emulator 'eFMR-50'
3 FUJITSU FMR-60 Emulator 'eFMR-60'
5 Author : Takeda.Toshiya
18 static const uint8_t bios1[] = {
21 0xB8,0xA0,0xF7, // mov ax,F7A0
22 0x8E,0xD0, // mov ss,ax
23 0xBC,0x7E,0x05, // mov sp,057E
25 0xB4,0x80, // mov ah,80
26 0x9A,0x14,0x00,0xFB,0xFF, // call far FFFB:0014
28 0xB4,0x81, // mov ah,81
29 0x9A,0x14,0x00,0xFB,0xFF, // call far FFFB:0014
30 0x73,0x0B, // jnb $+11
33 0xB4,0x82, // mov ah,82
34 0x9A,0x14,0x00,0xFB,0xFF, // call far FFFB:0014
37 0x9A,0x04,0x00,0x00,0xB0, // call far B000:0004
41 static const uint8_t bios2[] = {
42 0xEA,0x00,0x00,0x00,0xFC, // jmp FC00:0000
47 #define SET_BANK(s, e, w, r) { \
48 int sb = (s) >> 11, eb = (e) >> 11; \
49 for(int i = sb; i <= eb; i++) { \
53 wbank[i] = (w) + 0x800 * (i - sb); \
58 rbank[i] = (r) + 0x800 * (i - sb); \
63 void MEMORY::initialize()
66 memset(ram, 0, sizeof(ram));
67 memset(vram, 0, sizeof(vram));
68 memset(cvram, 0, sizeof(cvram));
70 memset(avram, 0, sizeof(avram));
72 memset(kvram, 0, sizeof(kvram));
73 memset(dummy, 0, sizeof(dummy));
75 memset(ipl, 0xff, sizeof(ipl));
77 memset(ank24, 0xff, sizeof(ank24));
78 memset(kanji24, 0xff, sizeof(kanji24));
80 memset(ank8, 0xff, sizeof(ank8));
81 memset(ank16, 0xff, sizeof(ank16));
82 memset(kanji16, 0xff, sizeof(kanji16));
84 memset(rdmy, 0xff, sizeof(rdmy));
87 FILEIO* fio = new FILEIO();
88 if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
89 fio->Fread(ipl, sizeof(ipl), 1);
93 memcpy(ipl + 0x0000, bios1, sizeof(bios1));
94 memcpy(ipl + 0x3ff0, bios2, sizeof(bios2));
97 if(fio->Fopen(create_local_path(_T("ANK24.ROM")), FILEIO_READ_BINARY)) {
98 fio->Fread(ank24, sizeof(ank24), 1);
101 if(fio->Fopen(create_local_path(_T("KANJI24.ROM")), FILEIO_READ_BINARY)) {
102 fio->Fread(kanji24, sizeof(kanji24), 1);
106 if(fio->Fopen(create_local_path(_T("ANK8.ROM")), FILEIO_READ_BINARY)) {
107 fio->Fread(ank8, sizeof(ank8), 1);
110 if(fio->Fopen(create_local_path(_T("ANK16.ROM")), FILEIO_READ_BINARY)) {
111 fio->Fread(ank16, sizeof(ank16), 1);
114 if(fio->Fopen(create_local_path(_T("KANJI16.ROM")), FILEIO_READ_BINARY)) {
115 fio->Fread(kanji16, sizeof(kanji16), 1);
122 SET_BANK(0x000000, 0xffffff, wdmy, rdmy);
123 SET_BANK(0x000000, sizeof(ram) - 1, ram, ram);
125 SET_BANK(0xff8000, 0xff9fff, cvram, cvram);
126 SET_BANK(0xffa000, 0xffbfff, avram, avram);
128 SET_BANK(0xffc000, 0xffffff, wdmy, ipl);
131 for(int i = 0; i < 8; i++) {
133 apal[i][0] = (i & 1) ? 0xf0 : 0;
134 apal[i][1] = (i & 2) ? 0xf0 : 0;
135 apal[i][2] = (i & 4) ? 0xf0 : 0;
137 for(int i = 0; i < 16; i++) {
139 palette_cg[i] = RGB_COLOR(i & 2 ? 255 : 0, i & 4 ? 255 : 0, i & 1 ? 255 : 0);
141 palette_cg[i] = RGB_COLOR(i & 2 ? 127 : 0, i & 4 ? 127 : 0, i & 1 ? 127 : 0);
143 palette_txt[i] = palette_cg[i];
145 palette_txt[0] = RGB_COLOR(63, 63, 63);
149 register_frame_event(this);
156 mainmem = rplane = wplane = 0;
169 accaddr = dispaddr = 0;
170 kj_l = kj_h = kj_ofs = kj_row = 0;
172 // reset logical operation
173 cmdreg = maskreg = compbit = bankdis = 0;
174 memset(compreg, sizeof(compreg), 0xff);
176 dma_addr_reg = dma_wrap_reg = 0;
177 dma_addr_mask = 0x00ffffff;
178 d_cpu->set_address_mask(0x00ffffff);
181 void MEMORY::write_data8(uint32_t addr, uint32_t data)
183 if(addr & 0xff000000) {
189 if(0xc0000 <= addr && addr < 0xe0000) {
191 for(int pl = 0; pl < 4; pl++) {
192 if(wplane & (1 << pl)) {
193 vram[addr + 0x20000 * pl] = data;
198 if(0xc0000 <= addr && addr < 0xc8000) {
201 if(dispctrl & 0x40) {
203 addr = ((pagesel & 0x10) << 13) | (addr & 0x7fff);
207 addr = ((pagesel & 0x18) << 13) | (addr & 0x3fff);
211 // logical operations
212 if((cmdreg & 7) == 7) {
215 for(uint8_t bit = 1; bit <= 0x80; bit <<= 1) {
217 for(int pl = 0; pl < 4; pl++) {
218 if(vram[addr + page * pl] & bit) {
222 for(int i = 0; i < 8; i++) {
223 if((compreg[i] & 0x80) && (compreg[i] & 0xf) == val) {
229 uint8_t mask = maskreg | ~data, val[4];
230 for(int pl = 0; pl < 4; pl++) {
231 val[pl] = (imgcol & (1 << pl)) ? 0xff : 0;
235 for(int pl = 0; pl < 4; pl++) {
236 val[pl] |= vram[addr + page * pl];
240 for(int pl = 0; pl < 4; pl++) {
241 val[pl] &= vram[addr + page * pl];
245 for(int pl = 0; pl < 4; pl++) {
246 val[pl] ^= vram[addr + page * pl];
250 for(int pl = 0; pl < 4; pl++) {
251 val[pl] = ~vram[addr + page * pl];
255 for(int pl = 0; pl < 4; pl++) {
256 val[pl] = tilereg[pl];
260 for(int pl = 0; pl < 4; pl++) {
261 if(!(bankdis & (1 << pl))) {
262 vram[addr + page * pl] &= mask;
263 vram[addr + page * pl] |= val[pl] & ~mask;
268 for(int pl = 0; pl < 4; pl++) {
269 if(wplane & (1 << pl)) {
270 vram[addr + page * pl] = data;
275 } else if(0xcff80 <= addr && addr < 0xcffe0) {
277 // this->out_debug_log(_T("MW\t%4x, %2x\n"), addr, data);
280 switch(addr & 0xffff) {
288 rplane = (data >> 6) & 3;
292 // display ctrl register
297 // page select register
302 // access start register
303 accaddr = (accaddr & 0xff) | ((data & 0x7f) << 8);
306 // access start register
307 accaddr = (accaddr & 0xff00) | (data & 0xfe);
310 // display start register
311 dispaddr = (dispaddr & 0xff) | ((data & 0x7f) << 8);
314 // display start register
315 dispaddr = (dispaddr & 0xff00) | (data & 0xfe);
318 // crtc addr register
319 d_crtc->write_io8(0, data);
322 // crtc data register
323 d_crtc->write_io8(1, data);
332 kj_ofs = (((kj_l - 0x00) & 0x1f) << 5) | (((kj_l - 0x20) & 0x20) << 9) | (((kj_l - 0x20) & 0x40) << 7) | (((kj_h - 0x00) & 0x07) << 10);
333 } else if(kj_h < 0x70) {
334 kj_ofs = (((kj_l - 0x00) & 0x1f) << 5) + (((kj_l - 0x20) & 0x60) << 9) + (((kj_h - 0x00) & 0x0f) << 10) + (((kj_h - 0x30) & 0x70) * 0xc00) + 0x08000;
336 kj_ofs = (((kj_l - 0x00) & 0x1f) << 5) | (((kj_l - 0x20) & 0x20) << 9) | (((kj_l - 0x20) & 0x40) << 7) | (((kj_h - 0x00) & 0x07) << 10) | 0x38000;
340 kanji16[(kj_ofs | ((kj_row & 0xf) << 1)) & 0x3ffff] = data;
343 kanji16[(kj_ofs | ((kj_row++ & 0xf) << 1) | 1) & 0x3ffff] = data;
366 compreg[addr & 7] = data;
375 tilereg[addr & 3] = data;
378 lofs = (lofs & 0xff) | (data << 8);
381 lofs = (lofs & 0xff00) | data;
384 lsty = (lsty & 0xff) | (data << 8);
387 lsty = (lsty & 0xff00) | data;
390 lsx = (lsx & 0xff) | (data << 8);
393 lsx = (lsx & 0xff00) | data;
396 lsy = (lsy & 0xff) | (data << 8);
399 lsy = (lsy & 0xff00) | data;
402 lex = (lex & 0xff) | (data << 8);
405 lex = (lex & 0xff00) | data;
408 ley = (ley & 0xff) | (data << 8);
411 ley = (ley & 0xff00) | data;
412 // start drawing line
420 if((addr & ~3) == 8 && (protect & 0x80)) {
423 wbank[addr >> 11][addr & 0x7ff] = data;
426 uint32_t MEMORY::read_data8(uint32_t addr)
428 if(addr & 0xff000000) {
430 if(addr >= 0xffffc000) {
431 return ipl[addr & 0x3fff];
437 if(0xcff80 <= addr && addr < 0xcffe0) {
439 // this->out_debug_log(_T("MR\t%4x\n"), addr);
442 switch(addr & 0xffff) {
448 return wplane | (rplane << 6);
450 // page select register
454 return (disp ? 0x80 : 0) | (vsync ? 4 : 0) | 0x10;
456 // crtc addr register
457 return d_crtc->read_io8(0);
459 // crtc data register
460 return d_crtc->read_io8(1);
464 return kanji16[(kj_ofs | ((kj_row & 0xf) << 1)) & 0x3ffff];
466 return kanji16[(kj_ofs | ((kj_row++ & 0xf) << 1) | 1) & 0x3ffff];
470 return imgcol | 0xf0;
476 return bankdis & 0xf;
482 return rbank[addr >> 11][addr & 0x7ff];
485 void MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
487 write_data8(addr & dma_addr_mask, data);
490 uint32_t MEMORY::read_dma_data8(uint32_t addr)
492 return read_data8(addr & dma_addr_mask);
495 void MEMORY::write_io8(uint32_t addr, uint32_t data)
497 switch(addr & 0xffff) {
512 #if defined(HAS_I286)
514 d_cpu->set_address_mask(0x00ffffff);
516 d_cpu->set_address_mask(0x000fffff);
519 switch(data & 0x30) {
521 d_cpu->set_address_mask(0x000fffff);
524 d_cpu->set_address_mask(0x00ffffff);
527 d_cpu->set_address_mask(0xffffffff);
531 update_dma_addr_mask();
535 update_dma_addr_mask();
539 update_dma_addr_mask();
542 // video output control
550 mainmem = data & 0x80;
555 // palette code register
556 apalsel = data & 0xf;
559 // blue level register
560 apal[apalsel][0] = data & 0xf0;
561 palette_cg[apalsel] = RGB_COLOR(apal[apalsel][1], apal[apalsel][2], apal[apalsel][0]);
564 // red level register
565 apal[apalsel][1] = data & 0xf0;
566 palette_cg[apalsel] = RGB_COLOR(apal[apalsel][1], apal[apalsel][2], apal[apalsel][0]);
569 // green level register
570 apal[apalsel][2] = data & 0xf0;
571 palette_cg[apalsel] = RGB_COLOR(apal[apalsel][1], apal[apalsel][2], apal[apalsel][0]);
582 dpal[addr & 7] = data;
584 palette_cg[addr & 7] = RGB_COLOR(data & 2 ? 255 : 0, data & 4 ? 255 : 0, data & 1 ? 255 : 0);
586 palette_cg[addr & 7] = RGB_COLOR(data & 2 ? 127 : 0, data & 4 ? 127 : 0, data & 1 ? 127 : 0);
590 // video output control
596 uint32_t MEMORY::read_io8(uint32_t addr)
600 switch(addr & 0xffff) {
602 // reset cause register
603 val = rst | (d_cpu->get_shutdown_flag() << 1);
605 d_cpu->set_shutdown_flag(0);
616 // system status register
625 return wplane | 0xf0;
628 return mainmem | rplane | 0x7c;
630 // blue level register
631 return apal[apalsel][0];
633 // red level register
634 return apal[apalsel][1];
636 // green level register
637 return apal[apalsel][2];
647 return dpal[addr & 7] | 0xf0;
650 return (disp ? 2 : 0) | (vsync ? 1 : 0) | 0xfc;
655 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
657 if(id == SIG_MEMORY_DISP) {
658 disp = ((data & mask) != 0);
659 } else if(id == SIG_MEMORY_VSYNC) {
660 vsync = ((data & mask) != 0);
664 void MEMORY::event_frame()
669 void MEMORY::update_bank()
673 int ofs = rplane * 0x20000;
674 SET_BANK(0xc0000, 0xdffff, vram + ofs, vram + ofs);
675 SET_BANK(0xe0000, 0xeffff, wdmy, rdmy);
677 if(dispctrl & 0x40) {
679 int ofs = (rplane | ((pagesel >> 2) & 4)) * 0x8000;
680 SET_BANK(0xc0000, 0xc7fff, vram + ofs, vram + ofs);
683 int ofs = (rplane | ((pagesel >> 1) & 0xc)) * 0x4000;
684 SET_BANK(0xc0000, 0xc3fff, vram + ofs, vram + ofs);
685 SET_BANK(0xc4000, 0xc7fff, vram + ofs, vram + ofs);
687 SET_BANK(0xc8000, 0xc8fff, cvram, cvram);
688 SET_BANK(0xc9000, 0xc9fff, wdmy, rdmy);
690 SET_BANK(0xca000, 0xca7ff, wdmy, ank8);
691 SET_BANK(0xca800, 0xcafff, wdmy, rdmy);
692 SET_BANK(0xcb000, 0xcbfff, wdmy, ank16);
694 SET_BANK(0xca000, 0xcafff, kvram, kvram);
695 SET_BANK(0xcb000, 0xcbfff, wdmy, rdmy);
697 SET_BANK(0xcc000, 0xeffff, wdmy, rdmy);
700 SET_BANK(0xc0000, 0xeffff, ram + 0xc0000, ram + 0xc0000);
702 if(!(protect & 0x20)) {
704 SET_BANK(0xf8000, 0xf9fff, cvram, cvram);
705 SET_BANK(0xfa000, 0xfbfff, avram, avram);
707 SET_BANK(0xf8000, 0xfbfff, wdmy, rdmy);
709 SET_BANK(0xfc000, 0xfffff, wdmy, ipl);
711 SET_BANK(0xf8000, 0xfffff, ram + 0xf8000, ram + 0xf8000);
715 void MEMORY::update_dma_addr_mask()
717 switch(dma_addr_reg & 3) {
719 dma_addr_mask = d_cpu->get_address_mask();
722 if(!(dma_wrap_reg & 1) && d_cpu->get_address_mask() == 0x000fffff) {
723 dma_addr_mask = 0x000fffff;
725 dma_addr_mask = 0x00ffffff;
729 if(!(dma_wrap_reg & 1) && d_cpu->get_address_mask() == 0x000fffff) {
730 dma_addr_mask = 0x000fffff;
732 dma_addr_mask = 0xffffffff;
739 void MEMORY::point(int x, int y, int col)
741 if(x < 640 && y < 400) {
742 int ofs = ((lofs & 0x3fff) + (x >> 3) + y * 80) & 0x7fff;
743 uint8_t bit = 0x80 >> (x & 7);
744 for(int pl = 0; pl < 4; pl++) {
745 uint8_t pbit = 1 << pl;
746 if(!(bankdis & pbit)) {
748 vram[0x8000 * pl + ofs] |= bit;
750 vram[0x8000 * pl + ofs] &= ~bit;
759 int nx = lsx, ny = lsy;
760 int dx = abs(lex - lsx) * 2;
761 int dy = abs(ley - lsy) * 2;
762 int sx = (lex < lsx) ? -1 : 1;
763 int sy = (ley < lsy) ? -1 : 1;
766 point(lsx, lsy, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
768 int frac = dy - dx / 2;
776 point(nx, ny, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
779 int frac = dx - dy / 2;
787 point(nx, ny, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
790 // point(lex, ley, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
794 void MEMORY::draw_screen()
797 memset(screen_txt, 0, sizeof(screen_txt));
798 memset(screen_cg, 0, sizeof(screen_cg));
814 for(int y = 0; y < SCREEN_HEIGHT; y++) {
815 scrntype_t* dest = emu->get_screen_buffer(y);
816 uint8_t* txt = screen_txt[y];
817 uint8_t* cg = screen_cg[y];
819 for(int x = 0; x < SCREEN_WIDTH; x++) {
820 dest[x] = txt[x] ? palette_txt[txt[x] & 15] : palette_cg[cg[x]];
823 emu->screen_skip_line(false);
827 void MEMORY::draw_text()
829 int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0x1fff;
830 int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1)) & 0x1fff);
831 int ymax = (chreg[6] > 0) ? chreg[6] : 25;
832 int yofs = 750 / ymax;
834 for(int y = 0; y < 25; y++) {
835 for(int x = 0; x < 80; x++) {
836 bool cursor = ((src >> 1) == caddr);
838 uint8_t codel = cvram[src];
839 uint8_t attrl = avram[src];
840 src = (src + 1) & 0x1ffff;
841 uint8_t codeh = cvram[src];
842 uint8_t attrh = avram[src];
843 src = (src + 1) & 0x1ffff;
844 uint8_t col = (attrl & 15) | 16;
845 bool blnk = (attrh & 0x40) || ((blink & 32) && (attrh & 0x10));
846 bool rev = ((attrh & 8) != 0);
847 uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
851 int ofs = (codel | ((codeh & 0x7f) << 8)) * 72;
852 for(int l = 3; l < 27 && l < yofs; l++) {
853 uint8_t pat0 = kanji24[ofs++] ^ xor_mask;
854 uint8_t pat1 = kanji24[ofs++] ^ xor_mask;
855 uint8_t pat2 = kanji24[ofs++] ^ xor_mask;
856 int yy = y * yofs + l;
860 uint8_t* d = &screen_txt[yy][x * 14];
862 d[ 2] = (pat0 & 0x80) ? col : 0;
863 d[ 3] = (pat0 & 0x40) ? col : 0;
864 d[ 4] = (pat0 & 0x20) ? col : 0;
865 d[ 5] = (pat0 & 0x10) ? col : 0;
866 d[ 6] = (pat0 & 0x08) ? col : 0;
867 d[ 7] = (pat0 & 0x04) ? col : 0;
868 d[ 8] = (pat0 & 0x02) ? col : 0;
869 d[ 9] = (pat0 & 0x01) ? col : 0;
870 d[10] = (pat1 & 0x80) ? col : 0;
871 d[11] = (pat1 & 0x40) ? col : 0;
872 d[12] = (pat1 & 0x20) ? col : 0;
873 d[13] = (pat1 & 0x10) ? col : 0;
874 d[14] = (pat1 & 0x08) ? col : 0;
875 d[15] = (pat1 & 0x04) ? col : 0;
876 d[16] = (pat1 & 0x02) ? col : 0;
877 d[17] = (pat1 & 0x01) ? col : 0;
878 d[18] = (pat2 & 0x80) ? col : 0;
879 d[19] = (pat2 & 0x40) ? col : 0;
880 d[20] = (pat2 & 0x20) ? col : 0;
881 d[21] = (pat2 & 0x10) ? col : 0;
882 d[22] = (pat2 & 0x08) ? col : 0;
883 d[23] = (pat2 & 0x04) ? col : 0;
884 d[24] = (pat2 & 0x02) ? col : 0;
885 d[25] = (pat2 & 0x01) ? col : 0;
887 src = (src + 2) & 0x1fff;
892 int ofs = codel * 48;
893 for(int l = 3; l < 27 && l < yofs; l++) {
894 uint8_t pat0 = ank24[ofs++] ^ xor_mask;
895 uint8_t pat1 = ank24[ofs++] ^ xor_mask;
896 int yy = y * yofs + l;
900 uint8_t* d = &screen_txt[yy][x * 14];
902 d[ 0] = (pat0 & 0x80) ? col : 0;
903 d[ 1] = (pat0 & 0x40) ? col : 0;
904 d[ 2] = (pat0 & 0x20) ? col : 0;
905 d[ 3] = (pat0 & 0x10) ? col : 0;
906 d[ 4] = (pat0 & 0x08) ? col : 0;
907 d[ 5] = (pat0 & 0x04) ? col : 0;
908 d[ 6] = (pat0 & 0x02) ? col : 0;
909 d[ 7] = (pat0 & 0x01) ? col : 0;
910 d[ 8] = (pat1 & 0x80) ? col : 0;
911 d[ 9] = (pat1 & 0x40) ? col : 0;
912 d[10] = (pat1 & 0x20) ? col : 0;
913 d[11] = (pat1 & 0x10) ? col : 0;
914 d[12] = (pat1 & 0x08) ? col : 0;
915 d[13] = (pat1 & 0x04) ? col : 0;
920 int bp = chreg[10] & 0x60;
921 if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
922 int st = chreg[10] & 15;
923 int ed = chreg[11] & 15;
924 for(int i = st; i < ed && i < yofs; i++) {
925 memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
934 void MEMORY::draw_text40()
936 int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0xfff;
937 int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1) | (mix & 0x20 ? 1 : 0)) & 0x7ff);
938 int ymax = (chreg[6] > 0) ? chreg[6] : 25;
939 int yofs = 400 / ymax;
941 for(int y = 0; y < ymax; y++) {
942 for(int x = 0; x < 40; x++) {
943 bool cursor = ((src >> 1) == caddr);
945 uint8_t code = cvram[src];
946 uint8_t h = kvram[src] & 0x7f;
947 src = (src + 1) & 0xfff;
948 uint8_t attr = cvram[src];
949 uint8_t l = kvram[src] & 0x7f;
950 src = (src + 1) & 0xfff;
951 uint8_t col = ((attr & 0x20) >> 2) | (attr & 7) | 16;
952 bool blnk = (blink & 32) && (attr & 0x10);
953 bool rev = ((attr & 8) != 0);
954 uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
960 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10);
961 } else if(h < 0x70) {
962 ofs = (((l - 0x00) & 0x1f) << 5) + (((l - 0x20) & 0x60) << 9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
964 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
967 for(int l = 0; l < 16 && l < yofs; l++) {
968 uint8_t pat0 = kanji16[ofs + (l << 1) + 0] ^ xor_mask;
969 uint8_t pat1 = kanji16[ofs + (l << 1) + 1] ^ xor_mask;
970 int yy = y * yofs + l;
974 uint8_t* d = &screen_txt[yy][x << 4];
976 d[ 0] = d[ 1] = (pat0 & 0x80) ? col : 0;
977 d[ 2] = d[ 3] = (pat0 & 0x40) ? col : 0;
978 d[ 4] = d[ 5] = (pat0 & 0x20) ? col : 0;
979 d[ 6] = d[ 7] = (pat0 & 0x10) ? col : 0;
980 d[ 8] = d[ 9] = (pat0 & 0x08) ? col : 0;
981 d[10] = d[11] = (pat0 & 0x04) ? col : 0;
982 d[12] = d[13] = (pat0 & 0x02) ? col : 0;
983 d[14] = d[15] = (pat0 & 0x01) ? col : 0;
984 d[16] = d[17] = (pat1 & 0x80) ? col : 0;
985 d[18] = d[19] = (pat1 & 0x40) ? col : 0;
986 d[20] = d[21] = (pat1 & 0x20) ? col : 0;
987 d[22] = d[23] = (pat1 & 0x10) ? col : 0;
988 d[24] = d[25] = (pat1 & 0x08) ? col : 0;
989 d[26] = d[27] = (pat1 & 0x04) ? col : 0;
990 d[28] = d[29] = (pat1 & 0x02) ? col : 0;
991 d[30] = d[31] = (pat1 & 0x01) ? col : 0;
993 src = (src + 2) & 0xfff;
996 for(int l = 0; l < 16 && l < yofs; l++) {
997 uint8_t pat = ank16[(code << 4) + l] ^ xor_mask;
998 int yy = y * yofs + l;
1002 uint8_t* d = &screen_txt[yy][x << 4];
1004 d[ 0] = d[ 1] = (pat & 0x80) ? col : 0;
1005 d[ 2] = d[ 3] = (pat & 0x40) ? col : 0;
1006 d[ 4] = d[ 5] = (pat & 0x20) ? col : 0;
1007 d[ 6] = d[ 7] = (pat & 0x10) ? col : 0;
1008 d[ 8] = d[ 9] = (pat & 0x08) ? col : 0;
1009 d[10] = d[11] = (pat & 0x04) ? col : 0;
1010 d[12] = d[13] = (pat & 0x02) ? col : 0;
1011 d[14] = d[15] = (pat & 0x01) ? col : 0;
1015 int bp = chreg[10] & 0x60;
1016 if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
1017 int st = chreg[10] & 15;
1018 int ed = chreg[11] & 15;
1019 for(int i = st; i < ed && i < yofs; i++) {
1020 memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
1028 void MEMORY::draw_text80()
1030 int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0xfff;
1031 int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1) | (mix & 0x20 ? 1 : 0)) & 0x7ff);
1032 int ymax = (chreg[6] > 0) ? chreg[6] : 25;
1033 int yofs = 400 / ymax;
1035 for(int y = 0; y < 25; y++) {
1036 for(int x = 0; x < 80; x++) {
1037 bool cursor = ((src >> 1) == caddr);
1039 uint8_t code = cvram[src];
1040 uint8_t h = kvram[src] & 0x7f;
1041 src = (src + 1) & 0xfff;
1042 uint8_t attr = cvram[src];
1043 uint8_t l = kvram[src] & 0x7f;
1044 src = (src + 1) & 0xfff;
1045 uint8_t col = ((attr & 0x20) >> 2) | (attr & 7) | 16;
1046 bool blnk = (blink & 32) && (attr & 0x10);
1047 bool rev = ((attr & 8) != 0);
1048 uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
1054 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10);
1055 } else if(h < 0x70) {
1056 ofs = (((l - 0x00) & 0x1f) << 5) + (((l - 0x20) & 0x60) << 9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
1058 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
1061 for(int l = 0; l < 16 && l < yofs; l++) {
1062 uint8_t pat0 = kanji16[ofs + (l << 1) + 0] ^ xor_mask;
1063 uint8_t pat1 = kanji16[ofs + (l << 1) + 1] ^ xor_mask;
1064 int yy = y * yofs + l;
1068 uint8_t* d = &screen_txt[yy][x << 3];
1070 d[ 0] = (pat0 & 0x80) ? col : 0;
1071 d[ 1] = (pat0 & 0x40) ? col : 0;
1072 d[ 2] = (pat0 & 0x20) ? col : 0;
1073 d[ 3] = (pat0 & 0x10) ? col : 0;
1074 d[ 4] = (pat0 & 0x08) ? col : 0;
1075 d[ 5] = (pat0 & 0x04) ? col : 0;
1076 d[ 6] = (pat0 & 0x02) ? col : 0;
1077 d[ 7] = (pat0 & 0x01) ? col : 0;
1078 d[ 8] = (pat1 & 0x80) ? col : 0;
1079 d[ 9] = (pat1 & 0x40) ? col : 0;
1080 d[10] = (pat1 & 0x20) ? col : 0;
1081 d[11] = (pat1 & 0x10) ? col : 0;
1082 d[12] = (pat1 & 0x08) ? col : 0;
1083 d[13] = (pat1 & 0x04) ? col : 0;
1084 d[14] = (pat1 & 0x02) ? col : 0;
1085 d[15] = (pat1 & 0x01) ? col : 0;
1087 src = (src + 2) & 0xfff;
1090 for(int l = 0; l < 16 && l < yofs; l++) {
1091 uint8_t pat = ank16[(code << 4) + l] ^ xor_mask;
1092 int yy = y * yofs + l;
1096 uint8_t* d = &screen_txt[yy][x << 3];
1098 d[0] = (pat & 0x80) ? col : 0;
1099 d[1] = (pat & 0x40) ? col : 0;
1100 d[2] = (pat & 0x20) ? col : 0;
1101 d[3] = (pat & 0x10) ? col : 0;
1102 d[4] = (pat & 0x08) ? col : 0;
1103 d[5] = (pat & 0x04) ? col : 0;
1104 d[6] = (pat & 0x02) ? col : 0;
1105 d[7] = (pat & 0x01) ? col : 0;
1109 int bp = chreg[10] & 0x60;
1110 if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
1111 int st = chreg[10] & 15;
1112 int ed = chreg[11] & 15;
1113 for(int i = st; i < ed && i < yofs; i++) {
1114 memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
1123 void MEMORY::draw_cg()
1126 uint8_t* p0 = &vram[0x00000];
1127 uint8_t* p1 = &vram[0x20000];
1128 uint8_t* p2 = &vram[0x40000];
1129 uint8_t* p3 = &vram[0x60000];
1132 for(int y = 0; y < 750; y++) {
1133 for(int x = 0; x < 1120; x += 8) {
1134 uint8_t r = p0[ptr];
1135 uint8_t g = p1[ptr];
1136 uint8_t b = p2[ptr];
1137 uint8_t i = p3[ptr++];
1139 uint8_t* d = &screen_cg[y][x];
1141 d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5) | ((i & 0x80) >> 4);
1142 d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4) | ((i & 0x40) >> 3);
1143 d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3) | ((i & 0x20) >> 2);
1144 d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2) | ((i & 0x10) >> 1);
1145 d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1) | ((i & 0x08) >> 0);
1146 d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0) | ((i & 0x04) << 1);
1147 d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1) | ((i & 0x02) << 2);
1148 d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2) | ((i & 0x01) << 3);
1152 if(dispctrl & 0x40) {
1154 int pofs = ((dispctrl >> 3) & 1) * 0x20000;
1155 uint8_t* p0 = (dispctrl & 0x01) ? &vram[pofs | 0x00000] : dummy;
1156 uint8_t* p1 = (dispctrl & 0x02) ? &vram[pofs | 0x08000] : dummy;
1157 uint8_t* p2 = (dispctrl & 0x04) ? &vram[pofs | 0x10000] : dummy;
1158 uint8_t* p3 = (dispctrl & 0x20) ? &vram[pofs | 0x18000] : dummy; // ???
1159 int ptr = dispaddr & 0x7ffe;
1161 for(int y = 0; y < 400; y++) {
1162 for(int x = 0; x < 640; x += 8) {
1163 uint8_t r = p0[ptr];
1164 uint8_t g = p1[ptr];
1165 uint8_t b = p2[ptr];
1166 uint8_t i = p3[ptr++];
1168 uint8_t* d = &screen_cg[y][x];
1170 d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5) | ((i & 0x80) >> 4);
1171 d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4) | ((i & 0x40) >> 3);
1172 d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3) | ((i & 0x20) >> 2);
1173 d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2) | ((i & 0x10) >> 1);
1174 d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1) | ((i & 0x08) >> 0);
1175 d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0) | ((i & 0x04) << 1);
1176 d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1) | ((i & 0x02) << 2);
1177 d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2) | ((i & 0x01) << 3);
1182 int pofs = ((dispctrl >> 3) & 3) * 0x10000;
1183 uint8_t* p0 = (dispctrl & 0x01) ? &vram[pofs | 0x0000] : dummy;
1184 uint8_t* p1 = (dispctrl & 0x02) ? &vram[pofs | 0x4000] : dummy;
1185 uint8_t* p2 = (dispctrl & 0x04) ? &vram[pofs | 0x8000] : dummy;
1186 uint8_t* p3 = (dispctrl & 0x20) ? &vram[pofs | 0xc000] : dummy; // ???
1187 int ptr = dispaddr & 0x3ffe;
1189 for(int y = 0; y < 400; y += 2) {
1190 for(int x = 0; x < 640; x += 8) {
1191 uint8_t r = p0[ptr];
1192 uint8_t g = p1[ptr];
1193 uint8_t b = p2[ptr];
1194 uint8_t i = p3[ptr++];
1196 uint8_t* d = &screen_cg[y][x];
1198 d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5) | ((i & 0x80) >> 4);
1199 d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4) | ((i & 0x40) >> 3);
1200 d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3) | ((i & 0x20) >> 2);
1201 d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2) | ((i & 0x10) >> 1);
1202 d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1) | ((i & 0x08) >> 0);
1203 d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0) | ((i & 0x04) << 1);
1204 d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1) | ((i & 0x02) << 2);
1205 d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2) | ((i & 0x01) << 3);
1207 memcpy(screen_cg[y + 1], screen_cg[y], 640);
1213 #define STATE_VERSION 1
1215 void MEMORY::save_state(FILEIO* state_fio)
1217 state_fio->FputUint32(STATE_VERSION);
1218 state_fio->FputInt32(this_device_id);
1220 state_fio->Fwrite(ram, sizeof(ram), 1);
1221 state_fio->Fwrite(vram, sizeof(vram), 1);
1222 state_fio->Fwrite(cvram, sizeof(cvram), 1);
1224 state_fio->Fwrite(avram, sizeof(avram), 1);
1226 state_fio->Fwrite(kvram, sizeof(kvram), 1);
1228 state_fio->FputUint8(machine_id);
1229 state_fio->FputUint8(protect);
1230 state_fio->FputUint8(rst);
1231 state_fio->FputUint8(mainmem);
1232 state_fio->FputUint8(rplane);
1233 state_fio->FputUint8(wplane);
1234 state_fio->FputUint8(dma_addr_reg);
1235 state_fio->FputUint8(dma_wrap_reg);
1236 state_fio->FputUint32(dma_addr_mask);
1237 state_fio->FputBool(disp);
1238 state_fio->FputBool(vsync);
1239 state_fio->FputInt32(blink);
1240 state_fio->Fwrite(apal, sizeof(apal), 1);
1241 state_fio->FputUint8(apalsel);
1242 state_fio->Fwrite(dpal, sizeof(dpal), 1);
1243 state_fio->FputUint8(outctrl);
1245 state_fio->FputUint8(pagesel);
1246 state_fio->FputUint8(ankcg);
1247 state_fio->FputUint8(dispctrl);
1248 state_fio->FputUint8(mix);
1249 state_fio->FputUint16(accaddr);
1250 state_fio->FputUint16(dispaddr);
1251 state_fio->FputInt32(kj_h);
1252 state_fio->FputInt32(kj_l);
1253 state_fio->FputInt32(kj_ofs);
1254 state_fio->FputInt32(kj_row);
1255 state_fio->FputUint8(cmdreg);
1256 state_fio->FputUint8(imgcol);
1257 state_fio->FputUint8(maskreg);
1258 state_fio->Fwrite(compreg, sizeof(compreg), 1);
1259 state_fio->FputUint8(compbit);
1260 state_fio->FputUint8(bankdis);
1261 state_fio->Fwrite(tilereg, sizeof(tilereg), 1);
1262 state_fio->FputUint16(lofs);
1263 state_fio->FputUint16(lsty);
1264 state_fio->FputUint16(lsx);
1265 state_fio->FputUint16(lsy);
1266 state_fio->FputUint16(lex);
1267 state_fio->FputUint16(ley);
1269 state_fio->Fwrite(palette_cg, sizeof(palette_cg), 1);
1272 bool MEMORY::load_state(FILEIO* state_fio)
1274 if(state_fio->FgetUint32() != STATE_VERSION) {
1277 if(state_fio->FgetInt32() != this_device_id) {
1280 state_fio->Fread(ram, sizeof(ram), 1);
1281 state_fio->Fread(vram, sizeof(vram), 1);
1282 state_fio->Fread(cvram, sizeof(cvram), 1);
1284 state_fio->Fread(avram, sizeof(avram), 1);
1286 state_fio->Fread(kvram, sizeof(kvram), 1);
1288 machine_id = state_fio->FgetUint8();
1289 protect = state_fio->FgetUint8();
1290 rst = state_fio->FgetUint8();
1291 mainmem = state_fio->FgetUint8();
1292 rplane = state_fio->FgetUint8();
1293 wplane = state_fio->FgetUint8();
1294 dma_addr_reg = state_fio->FgetUint8();
1295 dma_wrap_reg = state_fio->FgetUint8();
1296 dma_addr_mask = state_fio->FgetUint32();
1297 disp = state_fio->FgetBool();
1298 vsync = state_fio->FgetBool();
1299 blink = state_fio->FgetInt32();
1300 state_fio->Fread(apal, sizeof(apal), 1);
1301 apalsel = state_fio->FgetUint8();
1302 state_fio->Fread(dpal, sizeof(dpal), 1);
1303 outctrl = state_fio->FgetUint8();
1305 pagesel = state_fio->FgetUint8();
1306 ankcg = state_fio->FgetUint8();
1307 dispctrl = state_fio->FgetUint8();
1308 mix = state_fio->FgetUint8();
1309 accaddr = state_fio->FgetUint16();
1310 dispaddr = state_fio->FgetUint16();
1311 kj_h = state_fio->FgetInt32();
1312 kj_l = state_fio->FgetInt32();
1313 kj_ofs = state_fio->FgetInt32();
1314 kj_row = state_fio->FgetInt32();
1315 cmdreg = state_fio->FgetUint8();
1316 imgcol = state_fio->FgetUint8();
1317 maskreg = state_fio->FgetUint8();
1318 state_fio->Fread(compreg, sizeof(compreg), 1);
1319 compbit = state_fio->FgetUint8();
1320 bankdis = state_fio->FgetUint8();
1321 state_fio->Fread(tilereg, sizeof(tilereg), 1);
1322 lofs = state_fio->FgetUint16();
1323 lsty = state_fio->FgetUint16();
1324 lsx = state_fio->FgetUint16();
1325 lsy = state_fio->FgetUint16();
1326 lex = state_fio->FgetUint16();
1327 ley = state_fio->FgetUint16();
1329 state_fio->Fread(palette_cg, sizeof(palette_cg), 1);