2 FUJITSU FM16beta Emulator 'eFM16beta'
4 Author : Takeda.Toshiya
12 #include "../pcm1bit.h"
14 void SUB::initialize()
19 memset(wram, 0, sizeof(wram));
20 memset(sram, 0, sizeof(sram));
21 memset(gvram, 0, sizeof(gvram));
22 memset(dummy, 0, sizeof(dummy));
23 memset(cvram, 0, sizeof(cvram));
24 memset(kvram, 0, sizeof(kvram));
25 memset(rom, 0xff, sizeof(rom));
26 memset(ank8, 0xff, sizeof(ank8));
27 memset(ank16, 0xff, sizeof(ank16));
28 memset(kanji16, 0xff, sizeof(kanji16));
31 FILEIO* fio = new FILEIO();
32 if(fio->Fopen(create_local_path(_T("SUBSYS.ROM")), FILEIO_READ_BINARY) ||
33 fio->Fopen(create_local_path(_T("SUB.ROM")), FILEIO_READ_BINARY)) {
34 fio->Fread(rom, sizeof(rom), 1);
36 if(rom[0x4ff2] == 0xff && rom[0x4ff3] == 0xff) { // SWI3
40 if(rom[0x4ff4] == 0xff && rom[0x4ff5] == 0xff) { // SWI2
44 if(rom[0x4ff6] == 0xff && rom[0x4ff7] == 0xff) { // FIRQ
48 if(rom[0x4ff8] == 0xff && rom[0x4ff9] == 0xff) { // IRQ
52 if(rom[0x4ffa] == 0xff && rom[0x4ffb] == 0xff) { // SWI
56 if(rom[0x4ffc] == 0xff && rom[0x4ffd] == 0xff) { // NMI
60 if(rom[0x4ffe] == 0xff && rom[0x4fff] == 0xff) { // RESET
61 for(int i = 0; i < sizeof(rom) - 4; i++) {
62 static const uint8_t boot[4] = {0x86, 0x90, 0x1f, 0x8b};
63 if(memcmp(rom + i, boot, sizeof(boot)) == 0) {
65 rom[0x4ffe] = (i >> 8) & 0xff;
66 rom[0x4fff] = (i >> 0) & 0xff;
72 if(fio->Fopen(create_local_path(_T("ANK8.ROM")), FILEIO_READ_BINARY)) {
73 fio->Fread(ank8, sizeof(ank8), 1);
76 if(fio->Fopen(create_local_path(_T("ANK16.ROM")), FILEIO_READ_BINARY)) {
77 fio->Fread(ank16, sizeof(ank16), 1);
80 if(fio->Fopen(create_local_path(_T("KANJI16.ROM")), FILEIO_READ_BINARY)) {
81 fio->Fread(kanji16, sizeof(kanji16), 1);
86 set_memory_rw(0x9000, 0x9f7f, wram + 0x1000);
87 set_memory_rw(0x9f80, 0x9fff, sram);
88 set_memory_r (0xb000, 0xffff, rom);
90 for(int i = 0; i < 8; i++) {
91 palette_txt[i] = palette_cg[i] = RGB_COLOR(i & 2 ? 255 : 0, i & 4 ? 255 : 0, i & 1 ? 255 : 0);
110 d_main->write_signal(SIG_MAIN_SUB_BUSY, 1, 1);
113 update = dispctrl = pagesel = 0;
115 accaddr = dispaddr = 0;
120 memset(attention, 0, sizeof(attention));
123 irq_cancel = irq_vsync = firq_key = firq_pen = false;
125 kj_l = kj_h = kj_ofs = kj_row = 0;
127 cmdreg = maskreg = compbit = bankdis = 0;
128 memset(compreg, 0xff, sizeof(compreg));
131 void SUB::write_data8(uint32_t addr, uint32_t data)
133 // sub cpu memory bus
134 write_memory(addr, data);
136 if((addr >= 0x9f80 && addr < 0xa000) || (addr >= 0xff80 && addr < 0xffe0)) {
137 this->out_debug_log(_T("SUB %06x\tOUT8\t%04x,%02x\n"), get_cpu_pc(1), addr, data);
142 uint32_t SUB::read_data8(uint32_t addr)
144 // sub cpu memory bus
145 uint32_t val = read_memory(addr);
147 if((addr >= 0x9f80 && addr < 0xa000) || (addr >= 0xff80 && addr < 0xffe0)) {
148 this->out_debug_log(_T("SUB %06x\tIN8\t%04x,%02x\n"), get_cpu_pc(1), addr, val);
154 void SUB::write_memory_mapped_io8(uint32_t addr, uint32_t data)
156 // main cpu direct access
158 write_memory(addr, data);
160 if((addr >= 0x9f80 && addr < 0xa000) || (addr >= 0xff80 && addr < 0xffe0)) {
161 this->out_debug_log(_T("MAIN %06x\tOUT8\t%04x,%02x\n"), get_cpu_pc(0), addr, data);
166 uint32_t SUB::read_memory_mapped_io8(uint32_t addr)
168 // main cpu direct access
170 uint32_t val = read_memory(addr);
172 if((addr >= 0x9f80 && addr < 0xa000) || (addr >= 0xff80 && addr < 0xffe0)) {
173 this->out_debug_log(_T("MAIN %06x\tIN8\t%04x,%02x\n"), get_cpu_pc(1), addr, val);
179 void SUB::write_memory(uint32_t addr, uint32_t data)
182 if(dispctrl & 0x40) {
183 uint32_t bank = (pagesel >> 4) & 1;
187 uint32_t bank = (pagesel >> 3) & 3;
191 if(update & 1) gvram[addr | 0x00000] = data;
192 if(update & 2) gvram[addr | 0x10000] = data;
193 if(update & 4) gvram[addr | 0x20000] = data;
194 } else if(addr >= 0xff80 && addr < 0xffe0) {
199 d_main->write_signal(SIG_MAIN_SUB_BUSY, ~data, 1);
209 change = pagesel ^ data;
220 d_main->write_signal(SIG_MAIN_FIRQ0, 1, 1);
225 accaddr = (accaddr & 0x00ff) | (data << 8);
228 accaddr = (accaddr & 0xff00) | (data << 0);
231 dispaddr = (dispaddr & 0x00ff) | (data << 8);
234 dispaddr = (dispaddr & 0xff00) | (data << 0);
239 d_crtc->write_io8(addr, data);
245 attention[addr & 3] = data;
254 kj_ofs = (((kj_l - 0x00) & 0x1f) << 5) | (((kj_l - 0x20) & 0x20) << 9) | (((kj_l - 0x20) & 0x40) << 7) | (((kj_h - 0x00) & 0x07) << 10);
255 } else if(kj_h < 0x70) {
256 kj_ofs = (((kj_l - 0x00) & 0x1f) << 5) + (((kj_l - 0x20) & 0x60) << 9) + (((kj_h - 0x00) & 0x0f) << 10) + (((kj_h - 0x30) & 0x70) * 0xc00) + 0x08000;
258 kj_ofs = (((kj_l - 0x00) & 0x1f) << 5) | (((kj_l - 0x20) & 0x20) << 9) | (((kj_l - 0x20) & 0x40) << 7) | (((kj_h - 0x00) & 0x07) << 10) | 0x38000;
262 kanji16[(kj_ofs | ((kj_row & 0xf) << 1)) & 0x3ffff] = data;
265 kanji16[(kj_ofs | ((kj_row++ & 0xf) << 1) | 1) & 0x3ffff] = data;
269 d_pcm->write_signal(SIG_PCM1BIT_ON, 0, 0);
273 change = ankcg ^ data;
300 compreg[addr & 7] = data;
309 tilereg[addr & 3] = data;
312 lofs = (lofs & 0xff) | (data << 8);
315 lofs = (lofs & 0xff00) | data;
318 lsty = (lsty & 0xff) | (data << 8);
321 lsty = (lsty & 0xff00) | data;
324 lsx = (lsx & 0xff) | (data << 8);
327 lsx = (lsx & 0xff00) | data;
330 lsy = (lsy & 0xff) | (data << 8);
333 lsy = (lsy & 0xff00) | data;
336 lex = (lex & 0xff) | (data << 8);
339 lex = (lex & 0xff00) | data;
342 ley = (ley & 0xff) | (data << 8);
345 ley = (ley & 0xff00) | data;
346 // start drawing line
351 this->out_debug_log(_T("UNKNOWN:\t"));
356 MEMORY::write_data8(addr, data);
360 uint32_t SUB::read_memory(uint32_t addr)
363 if(dispctrl & 0x40) {
364 uint32_t bank = (pagesel >> 4) & 1;
368 uint32_t bank = (pagesel >> 3) & 3;
372 switch(update & 0xc0) {
373 case 0x00: return gvram[addr | 0x00000];
374 case 0x40: return gvram[addr | 0x10000];
375 case 0x80: return gvram[addr | 0x20000];
378 } else if(addr >= 0xff80 && addr < 0xffe0) {
382 // bit4: Light Pen FIRQ 0:Disabled 1:Enabled
383 // bit3: WIDTH 0:40 1:80
384 // bit2: FLASH 0:OFF 1:ON
385 // bit1: INSLED 0:OFF 1:ON
386 // bit0: SUB BUSY 0:BUSY 1:READY
389 // bit7: Read Out Control RC2
390 // bit6: Read Out Control RC1
391 // bit2: RAM Select Bit RAM3
392 // bit1: RAM Select Bit RAM2
393 // bit0: RAM Select Bit RAM1
394 return update | 0x38;
396 return pagesel | 0xc7;
400 uint8_t val = (firq_key ? 0x01 : 0) | (firq_pen ? 0x80 : 0);
401 firq_key = firq_pen = false;
408 uint8_t val = (irq_cancel ? 0x01 : 0) | (irq_vsync ? 0x02 : 0) | 0x7e;
409 irq_cancel = irq_vsync = false;
417 return (disp ? 0x80 : 0) | (vsync ? 0x04 : 0) | 0x70;
420 d_main->write_signal(SIG_MAIN_FIRQ0, 1, 1);
426 return d_keyboard->read_io8(addr);
429 return d_crtc->read_io8(addr);
433 return attention[addr & 3];
437 return 0x80; //
\91æ
\93ñ
\90\85\8f\80\82Â
\82è
439 return kanji16[(kj_ofs | ((kj_row & 0xf) << 1)) & 0x3ffff];
441 return kanji16[(kj_ofs | ((kj_row++ & 0xf) << 1) | 1) & 0x3ffff];
443 d_pcm->write_signal(SIG_PCM1BIT_ON, 1, 1);
451 return imgcol | 0xf0;
457 return bankdis & 0x0f;
460 return (lofs >> 8) & 0xff;
462 return (lofs >> 0) & 0xff;
465 this->out_debug_log(_T("UNKNOWN:\t"));
471 return MEMORY::read_data8(addr);
475 void SUB::write_io8(uint32_t addr, uint32_t data)
489 palette_cg[addr & 7] = RGB_COLOR(data & 2 ? 255 : 0, data & 4 ? 255 : 0, data & 1 ? 255 : 0);
491 palette_cg[addr & 7] = RGB_COLOR(data & 2 ? 127 : 0, data & 4 ? 127 : 0, data & 1 ? 127 : 0);
493 dpal[addr & 7] = data;
500 sram[addr & 0x7f] = data;
505 uint32_t SUB::read_io8(uint32_t addr)
512 return attention[addr & 3];
523 return dpal[addr & 7] | 0xf0;
526 return sram[addr & 0x7f];
531 void SUB::write_signal(int id, uint32_t data, uint32_t mask)
533 if(id == SIG_SUB_DISP) {
534 disp = ((data & mask) != 0);
535 } else if(id == SIG_SUB_VSYNC) {
536 irq_vsync = vsync = ((data & mask) != 0);
538 } else if(id == SIG_SUB_CANCEL) {
539 irq_cancel = ((data & mask) != 0);
541 this->out_debug_log("MAIN -> SUB: CANCEL = %d\n", irq_cancel);
543 } else if(id == SIG_SUB_KEY) {
544 firq_key = ((data & mask) != 0);
546 } else if(id == SIG_SUB_HALT) {
547 this->out_debug_log("MAIN -> SUB: HALT = %d\n", data & mask ?1 : 0);
549 d_main->write_signal(SIG_MAIN_SUB_BUSY, 1, 1);
552 d_subcpu->write_signal(SIG_CPU_BUSREQ, data, mask);
553 } else if(id == SIG_SUB_MAINACK) {
554 this->out_debug_log("MAIN -> SUB: MAINACK = %d\n", data & mask ? 1 : 0);
556 d_main->write_signal(SIG_MAIN_FIRQ0, 0, 0);
562 void SUB::update_irq()
564 d_subcpu->write_signal(SIG_CPU_IRQ, irq_cancel || (irq_vsync && (ankcg & 0x80)) ? 1 : 0, 1);
567 void SUB::update_firq()
569 d_subcpu->write_signal(SIG_CPU_FIRQ, firq_key || (firq_pen && (mix & 0x10)) ? 1 : 0, 1);
572 void SUB::update_cvram_bank()
575 set_memory_rw(0x8000, 0x8fff, wram);
577 set_memory_rw(0x8000, 0x8fff, cvram);
581 void SUB::update_kvram_bank()
584 set_memory_r(0xa000, 0xa7ff, ank8);
585 set_memory_r(0xa800, 0xafff, ank8);
587 set_memory_rw(0xa000, 0xafff, kvram);
591 void SUB::key_down(int code)
596 void SUB::key_up(int code)
601 void SUB::point(int x, int y, int col)
603 if(x < 640 && y < 400) {
604 int ofs = ((lofs & 0x3fff) + (x >> 3) + y * 80) & 0x7fff;
605 uint8_t bit = 0x80 >> (x & 7);
606 for(int pl = 0; pl < 3; pl++) {
607 uint8_t pbit = 1 << pl;
608 if(!(bankdis & pbit)) {
610 gvram[0x8000 * pl + ofs] |= bit;
612 gvram[0x8000 * pl + ofs] &= ~bit;
621 int nx = lsx, ny = lsy;
622 int dx = abs(lex - lsx) * 2;
623 int dy = abs(ley - lsy) * 2;
624 int sx = (lex < lsx) ? -1 : 1;
625 int sy = (ley < lsy) ? -1 : 1;
628 point(lsx, lsy, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
630 int frac = dy - dx / 2;
638 point(nx, ny, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
641 int frac = dx - dy / 2;
649 point(nx, ny, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
652 // point(lex, ley, (lsty & (0x8000 >> (c++ & 15))) ? imgcol : 0);
655 void SUB::draw_screen()
658 memset(screen_txt, 0, sizeof(screen_txt));
659 memset(screen_cg, 0, sizeof(screen_cg));
667 } else if(outctrl & 2) {
672 } else if(outctrl & 8) {
676 for(int y = 0; y < SCREEN_HEIGHT; y++) {
677 scrntype_t* dest = emu->get_screen_buffer(y);
678 uint8_t* txt = screen_txt[y];
679 uint8_t* cg = screen_cg[y];
681 for(int x = 0; x < SCREEN_WIDTH; x++) {
682 dest[x] = txt[x] ? palette_txt[txt[x] & 15] : palette_cg[cg[x]];
685 emu->screen_skip_line(false);
688 void SUB::draw_text40()
690 int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0xfff;
691 int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1) | (mix & 0x20 ? 1 : 0)) & 0x7ff);
692 int ymax = (chreg[6] > 0) ? chreg[6] : 25;
693 int yofs = 400 / ymax;
695 for(int y = 0; y < ymax; y++) {
696 for(int x = 0; x < 40; x++) {
697 bool cursor = ((src >> 1) == caddr);
699 uint8_t code = cvram[src];
700 uint8_t h = kvram[src] & 0x7f;
701 src = (src + 1) & 0xfff;
702 uint8_t attr = cvram[src];
703 uint8_t l = kvram[src] & 0x7f;
704 src = (src + 1) & 0xfff;
705 uint8_t col = ((attr & 0x20) >> 2) | (attr & 7) | 16;
706 bool blnk = (blink & 32) && (attr & 0x10);
707 bool rev = ((attr & 8) != 0);
708 uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
714 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10);
715 } else if(h < 0x70) {
716 ofs = (((l - 0x00) & 0x1f) << 5) + (((l - 0x20) & 0x60) << 9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
718 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
721 for(int l = 0; l < 16 && l < yofs; l++) {
722 uint8_t pat0 = kanji16[ofs + (l << 1) + 0] ^ xor_mask;
723 uint8_t pat1 = kanji16[ofs + (l << 1) + 1] ^ xor_mask;
724 int yy = y * yofs + l;
728 uint8_t* d = &screen_txt[yy][x << 4];
730 d[ 0] = d[ 1] = (pat0 & 0x80) ? col : 0;
731 d[ 2] = d[ 3] = (pat0 & 0x40) ? col : 0;
732 d[ 4] = d[ 5] = (pat0 & 0x20) ? col : 0;
733 d[ 6] = d[ 7] = (pat0 & 0x10) ? col : 0;
734 d[ 8] = d[ 9] = (pat0 & 0x08) ? col : 0;
735 d[10] = d[11] = (pat0 & 0x04) ? col : 0;
736 d[12] = d[13] = (pat0 & 0x02) ? col : 0;
737 d[14] = d[15] = (pat0 & 0x01) ? col : 0;
738 d[16] = d[17] = (pat1 & 0x80) ? col : 0;
739 d[18] = d[19] = (pat1 & 0x40) ? col : 0;
740 d[20] = d[21] = (pat1 & 0x20) ? col : 0;
741 d[22] = d[23] = (pat1 & 0x10) ? col : 0;
742 d[24] = d[25] = (pat1 & 0x08) ? col : 0;
743 d[26] = d[27] = (pat1 & 0x04) ? col : 0;
744 d[28] = d[29] = (pat1 & 0x02) ? col : 0;
745 d[30] = d[31] = (pat1 & 0x01) ? col : 0;
747 src = (src + 2) & 0xfff;
750 for(int l = 0; l < 16 && l < yofs; l++) {
751 uint8_t pat = ank16[(code << 4) + l] ^ xor_mask;
752 int yy = y * yofs + l;
756 uint8_t* d = &screen_txt[yy][x << 4];
758 d[ 0] = d[ 1] = (pat & 0x80) ? col : 0;
759 d[ 2] = d[ 3] = (pat & 0x40) ? col : 0;
760 d[ 4] = d[ 5] = (pat & 0x20) ? col : 0;
761 d[ 6] = d[ 7] = (pat & 0x10) ? col : 0;
762 d[ 8] = d[ 9] = (pat & 0x08) ? col : 0;
763 d[10] = d[11] = (pat & 0x04) ? col : 0;
764 d[12] = d[13] = (pat & 0x02) ? col : 0;
765 d[14] = d[15] = (pat & 0x01) ? col : 0;
769 int bp = chreg[10] & 0x60;
770 if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
771 int st = chreg[10] & 15;
772 int ed = chreg[11] & 15;
773 for(int i = st; i < ed && i < yofs; i++) {
774 memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
782 void SUB::draw_text80()
784 int src = ((chreg[12] << 9) | (chreg[13] << 1)) & 0xfff;
785 int caddr = ((chreg[8] & 0xc0) == 0xc0) ? -1 : (((chreg[14] << 9) | (chreg[15] << 1) | (mix & 0x20 ? 1 : 0)) & 0x7ff);
786 int ymax = (chreg[6] > 0) ? chreg[6] : 25;
787 int yofs = 400 / ymax;
789 for(int y = 0; y < 25; y++) {
790 for(int x = 0; x < 80; x++) {
791 bool cursor = ((src >> 1) == caddr);
793 uint8_t code = cvram[src];
794 uint8_t h = kvram[src] & 0x7f;
795 src = (src + 1) & 0xfff;
796 uint8_t attr = cvram[src];
797 uint8_t l = kvram[src] & 0x7f;
798 src = (src + 1) & 0xfff;
799 uint8_t col = ((attr & 0x20) >> 2) | (attr & 7) | 16;
800 bool blnk = (blink & 32) && (attr & 0x10);
801 bool rev = ((attr & 8) != 0);
802 uint8_t xor_mask = (rev != blnk) ? 0xff : 0;
808 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10);
809 } else if(h < 0x70) {
810 ofs = (((l - 0x00) & 0x1f) << 5) + (((l - 0x20) & 0x60) << 9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
812 ofs = (((l - 0x00) & 0x1f) << 5) | (((l - 0x20) & 0x20) << 9) | (((l - 0x20) & 0x40) << 7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
815 for(int l = 0; l < 16 && l < yofs; l++) {
816 uint8_t pat0 = kanji16[ofs + (l << 1) + 0] ^ xor_mask;
817 uint8_t pat1 = kanji16[ofs + (l << 1) + 1] ^ xor_mask;
818 int yy = y * yofs + l;
822 uint8_t* d = &screen_txt[yy][x << 3];
824 d[ 0] = (pat0 & 0x80) ? col : 0;
825 d[ 1] = (pat0 & 0x40) ? col : 0;
826 d[ 2] = (pat0 & 0x20) ? col : 0;
827 d[ 3] = (pat0 & 0x10) ? col : 0;
828 d[ 4] = (pat0 & 0x08) ? col : 0;
829 d[ 5] = (pat0 & 0x04) ? col : 0;
830 d[ 6] = (pat0 & 0x02) ? col : 0;
831 d[ 7] = (pat0 & 0x01) ? col : 0;
832 d[ 8] = (pat1 & 0x80) ? col : 0;
833 d[ 9] = (pat1 & 0x40) ? col : 0;
834 d[10] = (pat1 & 0x20) ? col : 0;
835 d[11] = (pat1 & 0x10) ? col : 0;
836 d[12] = (pat1 & 0x08) ? col : 0;
837 d[13] = (pat1 & 0x04) ? col : 0;
838 d[14] = (pat1 & 0x02) ? col : 0;
839 d[15] = (pat1 & 0x01) ? col : 0;
841 src = (src + 2) & 0xfff;
844 for(int l = 0; l < 16 && l < yofs; l++) {
845 uint8_t pat = ank16[(code << 4) + l] ^ xor_mask;
846 int yy = y * yofs + l;
850 uint8_t* d = &screen_txt[yy][x << 3];
852 d[0] = (pat & 0x80) ? col : 0;
853 d[1] = (pat & 0x40) ? col : 0;
854 d[2] = (pat & 0x20) ? col : 0;
855 d[3] = (pat & 0x10) ? col : 0;
856 d[4] = (pat & 0x08) ? col : 0;
857 d[5] = (pat & 0x04) ? col : 0;
858 d[6] = (pat & 0x02) ? col : 0;
859 d[7] = (pat & 0x01) ? col : 0;
863 int bp = chreg[10] & 0x60;
864 if(bp == 0 || (bp == 0x40 && (blink & 8)) || (bp == 0x60 && (blink & 0x10))) {
865 int st = chreg[10] & 15;
866 int ed = chreg[11] & 15;
867 for(int i = st; i < ed && i < yofs; i++) {
868 memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
878 if(dispctrl & 0x40) {
880 int pofs = ((dispctrl >> 3) & 1) * 0x20000;
881 uint8_t* p0 = (dispctrl & 0x01) ? &gvram[pofs | 0x00000] : dummy;
882 uint8_t* p1 = (dispctrl & 0x02) ? &gvram[pofs | 0x08000] : dummy;
883 uint8_t* p2 = (dispctrl & 0x04) ? &gvram[pofs | 0x10000] : dummy;
884 int ptr = dispaddr & 0x7ffe;
886 for(int y = 0; y < 400; y++) {
887 for(int x = 0; x < 640; x += 8) {
890 uint8_t b = p2[ptr++];
892 uint8_t* d = &screen_cg[y][x];
894 d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5);
895 d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4);
896 d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3);
897 d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2);
898 d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1);
899 d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0);
900 d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1);
901 d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2);
906 int pofs = ((dispctrl >> 3) & 3) * 0x10000;
907 uint8_t* p0 = (dispctrl & 0x01) ? &gvram[pofs | 0x0000] : dummy;
908 uint8_t* p1 = (dispctrl & 0x02) ? &gvram[pofs | 0x4000] : dummy;
909 uint8_t* p2 = (dispctrl & 0x04) ? &gvram[pofs | 0x8000] : dummy;
910 int ptr = dispaddr & 0x3ffe;
912 for(int y = 0; y < 400; y += 2) {
913 for(int x = 0; x < 640; x += 8) {
916 uint8_t b = p2[ptr++];
918 uint8_t* d = &screen_cg[y][x];
920 d[0] = ((r & 0x80) >> 7) | ((g & 0x80) >> 6) | ((b & 0x80) >> 5);
921 d[1] = ((r & 0x40) >> 6) | ((g & 0x40) >> 5) | ((b & 0x40) >> 4);
922 d[2] = ((r & 0x20) >> 5) | ((g & 0x20) >> 4) | ((b & 0x20) >> 3);
923 d[3] = ((r & 0x10) >> 4) | ((g & 0x10) >> 3) | ((b & 0x10) >> 2);
924 d[4] = ((r & 0x08) >> 3) | ((g & 0x08) >> 2) | ((b & 0x08) >> 1);
925 d[5] = ((r & 0x04) >> 2) | ((g & 0x04) >> 1) | ((b & 0x04) >> 0);
926 d[6] = ((r & 0x02) >> 1) | ((g & 0x02) >> 0) | ((b & 0x02) << 1);
927 d[7] = ((r & 0x01) >> 0) | ((g & 0x01) << 1) | ((b & 0x01) << 2);
929 memcpy(screen_cg[y + 1], screen_cg[y], 640);
934 #define STATE_VERSION 1
936 void SUB::save_state(FILEIO* state_fio)
938 state_fio->FputUint32(STATE_VERSION);
939 state_fio->FputInt32(this_device_id);
941 MEMORY::save_state(state_fio);
944 bool SUB::load_state(FILEIO* state_fio)
946 if(state_fio->FgetUint32() != STATE_VERSION) {
949 if(state_fio->FgetInt32() != this_device_id) {
952 if(!MEMORY::load_state(state_fio)) {