2 SHARP X1 Emulator 'eX1'
3 SHARP X1twin Emulator 'eX1twin'
4 SHARP X1turbo Emulator 'eX1turbo'
6 Origin : X1EMU by KM (kanji rom)
7 X-millenium by Yui (ank16 patch)
8 Author : Takeda.Toshiya
15 #include "../hd46505.h"
19 #define AEN ((zmode1 & 0x80) != 0)
20 #define APEN ((zmode2 & 0x80) != 0)
21 #define APRD ((zmode2 & 0x08) != 0)
24 void DISPLAY::initialize()
27 FILEIO* fio = new FILEIO();
30 if(fio->Fopen(create_local_path(_T("ANK8.ROM")), FILEIO_READ_BINARY)) {
31 fio->Fread(font, sizeof(font), 1);
33 } else if(fio->Fopen(create_local_path(_T("FNT0808.X1")), FILEIO_READ_BINARY)) {
35 fio->Fread(font, sizeof(font), 1);
40 if(fio->Fopen(create_local_path(_T("ANK16.ROM")), FILEIO_READ_BINARY)) {
41 fio->Fread(kanji, 0x1000, 1);
43 } else if(fio->Fopen(create_local_path(_T("FNT0816.X1")), FILEIO_READ_BINARY)) {
45 fio->Fread(kanji, 0x1000, 1);
48 memcpy(kanji + 0x7f * 16, ANKFONT7f_9f, sizeof(ANKFONT7f_9f));
49 memcpy(kanji + 0xe0 * 16, ANKFONTe0_ff, sizeof(ANKFONTe0_ff));
52 if(fio->Fopen(create_local_path(_T("KANJI.ROM")), FILEIO_READ_BINARY)) {
53 fio->Fread(kanji + 0x1000, 0x4ac00, 1);
55 } else if(fio->Fopen(create_local_path(_T("FNT1616.X1")), FILEIO_READ_BINARY)) {
57 fio->Fread(kanji + 0x1000, 0x4ac00, 1);
60 for(int ofs = 0x1000; ofs < 0x4bc00; ofs += 32) {
63 for(int i = 0; i < 16; i++) {
64 buf[i ] = kanji[ofs + i * 2 ];
65 buf[i + 16] = kanji[ofs + i * 2 + 1];
67 memcpy(kanji + ofs, buf, 32);
72 for(int i = 0; i < 8; i++) {
73 palette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
74 palette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // cg
85 memset(vram_t, 0, sizeof(vram_t));
86 memset(vram_a, 0, sizeof(vram_a));
87 #ifdef _X1TURBO_FEATURE
88 memset(vram_k, 0, sizeof(vram_k));
90 memset(pcg_b, 0, sizeof(pcg_b));
91 memset(pcg_r, 0, sizeof(pcg_r));
92 memset(pcg_g, 0, sizeof(pcg_g));
93 #ifdef _X1TURBO_FEATURE
94 memset(gaiji_b, 0, sizeof(gaiji_b));
95 memset(gaiji_r, 0, sizeof(gaiji_r));
96 memset(gaiji_g, 0, sizeof(gaiji_g));
98 memset((void *)text_bak, 0x00, sizeof(text_bak));
99 memset((void *)cg_bak, 0x00, sizeof(cg_bak));
102 register_frame_event(this);
103 register_vline_event(this);
106 void DISPLAY::reset()
108 #ifdef _X1TURBO_FEATURE
114 for(int i = 0; i < 8; i++) {
115 palette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
116 ztpal[i] = ((i & 1) ? 0x03 : 0) | ((i & 2) ? 3 : 0x0c) | ((i & 4) ? 0x30 : 0);
118 for(int g = 0; g < 16; g++) {
119 for(int r = 0; r < 16; r++) {
120 for(int b = 0; b < 16; b++) {
121 int num = b + r * 16 + g * 256;
125 palette_pc[num + 16] = RGB_COLOR((r * 255) / 15, (g * 255) / 15, (b * 255) / 15);
129 zmode1 = zpriority = zscroll = zmode2 = 0;
132 cur_line = cur_code = 0;
135 kaddr = kofs = kflag = 0;
136 kanji_ptr = &kanji[0];
140 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
142 switch(addr & 0xff00) {
144 write_kanji(addr, data);
148 if(AEN && APEN && !APRD) {
149 int num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
150 zpal[num].b = data & 0x0f;
151 palette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
152 } else if(AEN && APEN && APRD) {
153 zpal_num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
164 if(AEN && APEN && !APRD) {
165 int num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
166 zpal[num].r = data & 0x0f;
167 palette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
168 // } else if(AEN && APEN && APRD) {
169 // zpal_num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
180 if(AEN && APEN && !APRD) {
181 int num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
182 zpal[num].g = data & 0x0f;
183 palette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
184 // } else if(AEN && APEN && APRD) {
185 // zpal_num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
200 pcg_b[cur_code][cur_line] = data;
201 #ifdef _X1TURBO_FEATURE
202 gaiji_b[cur_code >> 1][(cur_line << 1) | (cur_code & 1)] = data;
207 pcg_r[cur_code][cur_line] = data;
208 #ifdef _X1TURBO_FEATURE
209 gaiji_r[cur_code >> 1][(cur_line << 1) | (cur_code & 1)] = data;
214 pcg_g[cur_code][cur_line] = data;
215 #ifdef _X1TURBO_FEATURE
216 gaiji_g[cur_code >> 1][(cur_line << 1) | (cur_code & 1)] = data;
219 #ifdef _X1TURBO_FEATURE
233 ztpal[addr & 7] = data;
234 palette_pc[addr & 7] = RGB_COLOR((((data >> 2) & 3) * 255) / 3, (((data >> 4) & 3) * 255) / 3, (((data >> 0) & 3) * 255) / 3);
249 // hireso = !((mode1 & 3) == 0 || (mode1 & 3) == 2);
266 vram_a[addr & 0x7ff] = data;
276 vram_a[addr & 0x7ff] = data; // mirror
286 vram_t[addr & 0x7ff] = data;
296 #ifdef _X1TURBO_FEATURE
297 vram_k[addr & 0x7ff] = data;
299 vram_t[addr & 0x7ff] = data; // mirror
305 uint32_t DISPLAY::read_io8(uint32_t addr)
307 switch(addr & 0xff00) {
309 return read_kanji(addr);
312 if(AEN && APEN && APRD) {
313 return zpal[zpal_num].b;
317 if(AEN && APEN && APRD) {
318 return zpal[zpal_num].r;
322 if(AEN && APEN && APRD) {
323 return zpal[zpal_num].g;
330 return get_cur_font(addr);
333 return pcg_b[cur_code][cur_line];
336 return pcg_r[cur_code][cur_line];
339 return pcg_g[cur_code][cur_line];
352 return ztpal[addr & 7];
374 return vram_a[addr & 0x7ff];
383 return vram_a[addr & 0x7ff]; // mirror
392 return vram_t[addr & 0x7ff];
401 #ifdef _X1TURBO_FEATURE
402 return vram_k[addr & 0x7ff];
404 return vram_t[addr & 0x7ff]; // mirror
410 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
412 if(id == SIG_DISPLAY_VBLANK) {
415 vblank_clock = get_current_clock();
417 } else if(id == SIG_DISPLAY_COLUMN40) {
418 column40 = ((data & mask) != 0);
420 } else if(id == SIG_DISPLAY_DETECT_VBLANK) {
421 // hack: cpu detects vblank
422 vblank_clock = get_current_clock();
426 void DISPLAY::event_frame()
428 cblink = (cblink + 1) & 0x3f;
430 // update crtc parameters
431 ch_height = (regs[9] & 0x1f) + 1;
432 hz_total = regs[0] + 1;
434 vt_disp = regs[6] & 0x7f;
435 st_addr = (regs[12] << 8) | regs[13];
437 #ifdef _X1TURBO_FEATURE
438 int vt_total = ((regs[4] & 0x7f) + 1) * ch_height + (regs[5] & 0x1f);
439 hireso = (vt_total > 400);
443 void DISPLAY::event_vline(int v, int clock)
445 #ifdef _X1TURBO_FEATURE
455 #ifdef _X1TURBO_FEATURE
457 // restart cpu after pcg/cgrom is accessed
458 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
460 #ifdef _X1TURBO_FEATURE
463 memcpy((void *)text_bak, (void *)text, sizeof(text));
464 memcpy((void *)cg_bak, (void *)cg, sizeof(cg));
469 memcpy((void *)text_bak, (void *)text, sizeof(text));
470 memcpy((void *)cg_bak, (void *)cg, sizeof(cg));
472 #ifdef _X1TURBO_FEATURE
478 void DISPLAY::update_crtc()
480 #ifdef _X1TURBO_FEATURE
482 d_crtc->set_char_clock((mode1 & 1) ? VDP_CLOCK * 1.5 / 32.0 : VDP_CLOCK / 32.0);
484 d_crtc->set_char_clock((mode1 & 1) ? VDP_CLOCK * 1.5 / 16.0 : VDP_CLOCK / 16.0);
488 d_crtc->set_char_clock(VDP_CLOCK / 32.0);
490 d_crtc->set_char_clock(VDP_CLOCK / 16.0);
495 void DISPLAY::update_pal()
498 for(int i = 0; i < 8; i++) {
499 uint8_t bit = 1 << i;
500 pal2[i] = ((pal[0] & bit) ? 1 : 0) | ((pal[1] & bit) ? 2 : 0) | ((pal[2] & bit) ? 4 : 0) | 8;
502 #ifdef _X1TURBO_FEATURE
503 if(mode2 & 0x10) pal2[0] = 8;
504 if(mode2 & 0x20) pal2[1] = 8;
506 for(int c = 0; c < 8; c++) {
507 for(int t = 0; t < 8; t++) {
508 if(priority & (1 << c)) {
511 #ifdef _X1TURBO_FEATURE
512 pri[c][t] = ((mode2 & 8) && (mode2 & 7) == t) ? 0 : t;
523 uint8_t DISPLAY::get_cur_font(uint32_t addr)
525 #ifdef _X1TURBO_FEATURE
528 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
532 if(!(vram_a[0x7ff] & 0x20)) {
534 } else if(!(vram_a[0x3ff] & 0x20)) {
536 } else if(!(vram_a[0x5ff] & 0x20)) {
538 } else if(!(vram_a[0x1ff] & 0x20)) {
543 uint16_t ank = vram_t[vaddr];
544 uint16_t knj = vram_k[vaddr];
547 uint32_t ofs = adr2knj_x1t((knj << 8) | ank);
551 return kanji[ofs | (addr & 15)];
552 } else if(mode1 & 0x40) {
553 return kanji[(ank << 4) | (addr & 15)];
555 return font[(ank << 3) | ((addr >> 1) & 7)];
560 return font[(cur_code << 3) | (cur_line & 7)];
563 void DISPLAY::get_cur_pcg(uint32_t addr)
565 #ifdef _X1TURBO_FEATURE
568 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
572 if(vram_a[0x7ff] & 0x20) {
574 } else if(vram_a[0x3ff] & 0x20) {
576 } else if(vram_a[0x5ff] & 0x20) {
578 } else if(vram_a[0x1ff] & 0x20) {
583 cur_code = vram_t[vaddr];
584 cur_line = (addr >> 1) & 7;
586 if(vram_k[vaddr] & 0x90) {
588 cur_code += addr & 1;
595 void DISPLAY::get_cur_code_line()
597 //#ifdef _X1TURBO_FEATURE
598 // int ht_clock = hireso ? 161 : 250;
602 int clock = get_passed_clock(vblank_clock);
603 int vt_line = vt_disp * ch_height + (int)(clock / ht_clock);
605 int addr = (hz_total * (clock % ht_clock)) / ht_clock;
606 addr += hz_disp * (int)(vt_line / ch_height);
612 cur_code = vram_t[addr & 0x7ff];
613 cur_line = (vt_line % ch_height) & 7;
616 void DISPLAY::draw_line(int v)
619 memset(text, 0, sizeof(text));
620 memset(cg, 0, sizeof(cg));
621 prev_vert_double = false;
624 if((regs[8] & 0x30) != 0x30) {
625 if((v % ch_height) == 0) {
626 draw_text(v / ch_height);
629 memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
631 memset(&pri_line[v][0][0], 0, sizeof(pri));
635 void DISPLAY::draw_screen()
637 // copy to real screen
638 #ifdef _X1TURBO_FEATURE
643 for(int y = 0; y < 400; y++) {
644 scrntype* dest = emu->get_screen_buffer(y);
645 uint8* src_text = text_bak[y];
646 uint8* src_cg = cg_bak[y];
648 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
649 dest[x2] = dest[x2 + 1] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
654 for(int y = 0; y < 400; y++) {
655 scrntype* dest = emu->get_screen_buffer(y);
656 uint8* src_text = text_bak[y];
657 uint8* src_cg = cg_bak[y];
659 for(int x = 0; x < 640; x++) {
660 dest[x] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
664 emu->screen_skip_line(false);
670 for(int y = 0; y < 200; y++) {
671 scrntype* dest0 = emu->get_screen_buffer(y * 2 + 0);
672 scrntype* dest1 = emu->get_screen_buffer(y * 2 + 1);
673 uint8* src_text = text_bak[y];
674 uint8* src_cg = cg_bak[y];
676 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
677 dest0[x2] = dest0[x2 + 1] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
679 if(!config.scan_line) {
680 memcpy(dest1, dest0, 640 * sizeof(scrntype));
682 memset(dest1, 0, 640 * sizeof(scrntype));
687 for(int y = 0; y < 200; y++) {
688 scrntype* dest0 = emu->get_screen_buffer(y * 2 + 0);
689 scrntype* dest1 = emu->get_screen_buffer(y * 2 + 1);
690 uint8* src_text = text_bak[y];
691 uint8* src_cg = cg_bak[y];
693 for(int x = 0; x < 640; x++) {
694 dest0[x] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
696 if(!config.scan_line) {
697 memcpy(dest1, dest0, 640 * sizeof(scrntype));
699 memset(dest1, 0, 640 * sizeof(scrntype));
703 emu->screen_skip_line(true);
704 #ifdef _X1TURBO_FEATURE
709 void DISPLAY::draw_text(int y)
711 int width = column40 ? 40 : 80;
712 uint16_t src = st_addr + hz_disp * y;
714 bool cur_vert_double = true;
715 uint8_t prev_attr = 0, prev_pattern_b[32], prev_pattern_r[32], prev_pattern_g[32];
717 for(int x = 0; x < hz_disp && x < width; x++) {
719 uint8_t code = vram_t[src];
720 #ifdef _X1TURBO_FEATURE
721 uint8_t knj = vram_k[src];
723 uint8_t attr = vram_a[src];
726 uint8_t col = attr & 7;
727 bool reverse = ((attr & 8) != 0);
728 bool blink = ((attr & 0x10) && (cblink & 0x20));
729 reverse = (reverse != blink);
732 const uint8_t *pattern_b, *pattern_r, *pattern_g;
733 #ifdef _X1TURBO_FEATURE
741 #ifdef _X1TURBO_FEATURE
743 pattern_b = gaiji_b[code >> 1];
744 pattern_r = gaiji_r[code >> 1];
745 pattern_g = gaiji_g[code >> 1];
749 pattern_b = pcg_b[code];
750 pattern_r = pcg_r[code];
751 pattern_g = pcg_g[code];
752 #ifdef _X1TURBO_FEATURE
753 shift = hireso ? 1 : 0;
756 #ifdef _X1TURBO_FEATURE
757 } else if(knj & 0x80) {
758 uint32_t ofs = adr2knj_x1t((knj << 8) | code);
762 pattern_b = pattern_r = pattern_g = &kanji[ofs];
763 shift = hireso ? ((ch_height >= 32) ? 1 : 0) : ((ch_height >= 16) ? 0 : -1);
765 } else if(hireso || (mode1 & 4)) {
767 pattern_b = pattern_r = pattern_g = &kanji[code << 4];
768 shift = hireso ? ((ch_height >= 32) ? 1 : 0) : ((ch_height >= 16) ? 0 : -1);
773 pattern_b = pattern_r = pattern_g = &font[code << 3];
776 // check vertical doubled char
778 cur_vert_double = false;
782 for(int l = 0; l < ch_height; l++) {
784 int line = cur_vert_double ? raster + (l >> 1) : l;
785 #ifdef _X1TURBO_FEATURE
788 } else if(shift == -1) {
790 if(cur_vert_double) {
795 if((x & 1) && (prev_attr & 0x80)) {
796 b = prev_pattern_b[line] << 4;
797 r = prev_pattern_r[line] << 4;
798 g = prev_pattern_g[line] << 4;
799 } else if(line >= max_line) {
800 b = prev_pattern_b[line] = 0;
801 r = prev_pattern_r[line] = 0;
802 g = prev_pattern_g[line] = 0;
804 b = prev_pattern_b[line] = pattern_b[line];
805 r = prev_pattern_r[line] = pattern_r[line];
806 g = prev_pattern_g[line] = pattern_g[line];
809 b = (!(col & 1)) ? 0xff : ~b;
810 r = (!(col & 2)) ? 0xff : ~r;
811 g = (!(col & 4)) ? 0xff : ~g;
813 b = (!(col & 1)) ? 0 : b;
814 r = (!(col & 2)) ? 0 : r;
815 g = (!(col & 4)) ? 0 : g;
818 int yy = y * ch_height + l;
819 #ifdef _X1TURBO_FEATURE
826 uint8_t* d = &text[yy][x << 3];
829 // horizontal doubled char
830 d[ 0] = d[ 1] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
831 d[ 2] = d[ 3] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
832 d[ 4] = d[ 5] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
833 d[ 6] = d[ 7] = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2);
835 d[0] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
836 d[1] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
837 d[2] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
838 d[3] = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2);
839 d[4] = ((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1);
840 d[5] = ((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) >> 0);
841 d[6] = ((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1);
842 d[7] = ((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2);
847 if(cur_vert_double && !prev_vert_double) {
848 prev_vert_double = true;
849 raster = ch_height >> 1;
851 prev_vert_double = false;
856 void DISPLAY::draw_cg(int line)
858 int width = column40 ? 40 : 80;
860 int y = line / ch_height;
861 int l = line % ch_height;
865 int ofs, src = st_addr + hz_disp * y;
866 #ifdef _X1TURBO_FEATURE
867 int page = (hireso && !(mode1 & 2)) ? (l & 1) : (mode1 & 8);
868 int ll = hireso ? (l >> 1) : l;
871 ofs = (0x400 * (ll & 15)) + (page ? 0xc000 : 0);
873 ofs = (0x800 * (ll & 7)) + (page ? 0xc000 : 0);
876 ofs = 0x800 * (l & 7);
878 int ofs_b = ofs + 0x0000;
879 int ofs_r = ofs + 0x4000;
880 int ofs_g = ofs + 0x8000;
882 for(int x = 0; x < hz_disp && x < width; x++) {
884 uint8_t b = vram_ptr[ofs_b | src];
885 uint8_t r = vram_ptr[ofs_r | src];
886 uint8_t g = vram_ptr[ofs_g | src++];
887 uint8_t* d = &cg[line][x << 3];
889 d[0] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
890 d[1] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
891 d[2] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
892 d[3] = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2);
893 d[4] = ((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1);
894 d[5] = ((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) >> 0);
895 d[6] = ((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1);
896 d[7] = ((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2);
900 // kanji rom (from X1EMU by KM)
902 void DISPLAY::write_kanji(uint32_t addr, uint32_t data)
906 kaddr = (kaddr & 0xff00) | data;
909 kaddr = (kaddr & 0xff) | (data << 8);
912 // TODO: bit0 L->H: Latch
913 kanji_ptr = &kanji[adr2knj_x1(kaddr & 0xfff0)];
918 uint32_t DISPLAY::read_kanji(uint32_t addr)
923 uint32_t val = kanji_ptr[kofs];
926 kofs = (kofs + 1) & 15;
931 return jis2adr_x1(kaddr << 8) >> 8;
934 uint32_t val = kanji_ptr[kofs + 16];
937 kofs = (kofs + 1) & 15;
947 uint16_t DISPLAY::jis2adr_x1(uint16_t jis)
949 uint16_t jh, jl, adr;
954 adr = 0x4000 + (jh - 0x30) * 0x600;
956 adr = 0x0100 + (jh - 0x21) * 0x600;
959 adr += (jl - 0x20) * 0x10;
964 uint32_t DISPLAY::adr2knj_x1(uint16_t adr)
966 uint16_t jh, jl, jis;
970 jh = 0x21 + jh / 0x600;
973 jh = 0x30 + jh / 0x600;
976 adr -= 0x4000 + (jh - 0x30) * 0x600;
978 adr -= 0x0100 + (jh - 0x21) * 0x600;
985 jis = (jh << 8) | jl;
989 #ifdef _X1TURBO_FEATURE
990 uint32_t DISPLAY::adr2knj_x1t(uint16_t adr)
1003 j2 = rl & 0x1f; // rl4,3,2,1,0
1004 j1 = (rl / 0x20) & 7; // rl7,6,5
1010 case 0: j2 |= 0x20; break;
1011 case 1: j2 |= 0x60; break;
1012 case 2: j2 |= 0x40; break;
1013 default: j1 = j2 = 0; break;
1015 } else if(rh > 0x1c) {
1019 case 0: j2 |= 0x20; break;
1020 case 1: j2 |= 0x60; break;
1021 case 2: j2 |= 0x40; break;
1022 default: j1 = j2 = 0; break;
1025 j1 |= (((rh >> 1) + 7) / 3) * 0x10;
1027 j2 |= ((((rh >> 1) + 1) % 3) + 1) * 0x20;
1030 jis = (j1 << 8) | j2;
1031 return jis2knj(jis);
1035 uint32_t DISPLAY::jis2knj(uint16_t jis)
1037 uint32_t sjis = jis2sjis(jis);
1041 } else if(sjis >= 0x8140 && sjis < 0x84c0) {
1042 return 0x01000 + (sjis - 0x8140) * 32;
1043 } else if(sjis >= 0x8890 && sjis < 0xa000) {
1044 return 0x08000 + (sjis - 0x8890) * 32;
1045 } else if(sjis >= 0xe040 && sjis < 0xeab0) {
1046 return 0x36e00 + (sjis - 0xe040) * 32;
1052 uint16_t DISPLAY::jis2sjis(uint16_t jis)
1070 c1 = (c1 - 0x20 - 1) / 2 + 0x81;
1074 return (c1 << 8) | c2;
1077 #define STATE_VERSION 2
1079 void DISPLAY::save_state(FILEIO* state_fio)
1081 state_fio->FputUint32(STATE_VERSION);
1082 state_fio->FputInt32(this_device_id);
1084 state_fio->Fwrite(vram_t, sizeof(vram_t), 1);
1085 state_fio->Fwrite(vram_a, sizeof(vram_a), 1);
1086 #ifdef _X1TURBO_FEATURE
1087 state_fio->Fwrite(vram_k, sizeof(vram_k), 1);
1089 state_fio->Fwrite(pcg_b, sizeof(pcg_b), 1);
1090 state_fio->Fwrite(pcg_r, sizeof(pcg_r), 1);
1091 state_fio->Fwrite(pcg_g, sizeof(pcg_g), 1);
1092 #ifdef _X1TURBO_FEATURE
1093 state_fio->Fwrite(gaiji_b, sizeof(gaiji_b), 1);
1094 state_fio->Fwrite(gaiji_r, sizeof(gaiji_r), 1);
1095 state_fio->Fwrite(gaiji_g, sizeof(gaiji_g), 1);
1097 state_fio->FputUint8(cur_code);
1098 state_fio->FputUint8(cur_line);
1099 state_fio->FputInt32(kaddr);
1100 state_fio->FputInt32(kofs);
1101 state_fio->FputInt32(kflag);
1102 state_fio->FputInt32((int)(kanji_ptr - &kanji[0]));
1103 state_fio->Fwrite(pal, sizeof(pal), 1);
1104 state_fio->FputUint8(priority);
1105 state_fio->Fwrite(pri, sizeof(pri), 1);
1106 state_fio->FputBool(column40);
1107 #ifdef _X1TURBO_FEATURE
1108 state_fio->FputUint8(mode1);
1109 state_fio->FputUint8(mode2);
1110 state_fio->FputBool(hireso);
1113 state_fio->FputUint8(zmode1);
1114 state_fio->FputUint8(zpriority);
1115 state_fio->FputUint8(zscroll);
1116 state_fio->FputUint8(zmode2);
1117 state_fio->Fwrite(ztpal, sizeof(ztpal), 1);
1118 state_fio->Fwrite(zpal, sizeof(zpal), 1);
1119 state_fio->FputInt32(zpal_num);
1120 state_fio->Fwrite(palette_pc, sizeof(palette_pc), 1);
1122 state_fio->FputBool(prev_vert_double);
1123 state_fio->FputInt32(raster);
1124 state_fio->FputInt32(cblink);
1125 state_fio->FputInt32(ch_height);
1126 state_fio->FputInt32(hz_total);
1127 state_fio->FputInt32(hz_disp);
1128 state_fio->FputInt32(vt_disp);
1129 state_fio->FputInt32(st_addr);
1130 state_fio->FputUint32(vblank_clock);
1133 bool DISPLAY::load_state(FILEIO* state_fio)
1135 if(state_fio->FgetUint32() != STATE_VERSION) {
1138 if(state_fio->FgetInt32() != this_device_id) {
1141 state_fio->Fread(vram_t, sizeof(vram_t), 1);
1142 state_fio->Fread(vram_a, sizeof(vram_a), 1);
1143 #ifdef _X1TURBO_FEATURE
1144 state_fio->Fread(vram_k, sizeof(vram_k), 1);
1146 state_fio->Fread(pcg_b, sizeof(pcg_b), 1);
1147 state_fio->Fread(pcg_r, sizeof(pcg_r), 1);
1148 state_fio->Fread(pcg_g, sizeof(pcg_g), 1);
1149 #ifdef _X1TURBO_FEATURE
1150 state_fio->Fread(gaiji_b, sizeof(gaiji_b), 1);
1151 state_fio->Fread(gaiji_r, sizeof(gaiji_r), 1);
1152 state_fio->Fread(gaiji_g, sizeof(gaiji_g), 1);
1154 cur_code = state_fio->FgetUint8();
1155 cur_line = state_fio->FgetUint8();
1156 kaddr = state_fio->FgetInt32();
1157 kofs = state_fio->FgetInt32();
1158 kflag = state_fio->FgetInt32();
1159 kanji_ptr = &kanji[0] + state_fio->FgetInt32();
1160 state_fio->Fread(pal, sizeof(pal), 1);
1161 priority = state_fio->FgetUint8();
1162 state_fio->Fread(pri, sizeof(pri), 1);
1163 column40 = state_fio->FgetBool();
1164 #ifdef _X1TURBO_FEATURE
1165 mode1 = state_fio->FgetUint8();
1166 mode2 = state_fio->FgetUint8();
1167 hireso = state_fio->FgetBool();
1170 zmode1 = state_fio->FgetUint8();
1171 zpriority = state_fio->FgetUint8();
1172 zscroll = state_fio->FgetUint8();
1173 zmode2 = state_fio->FgetUint8();
1174 state_fio->Fread(ztpal, sizeof(ztpal), 1);
1175 state_fio->Fread(zpal, sizeof(zpal), 1);
1176 zpal_num = state_fio->FgetInt32();
1177 state_fio->Fread(palette_pc, sizeof(palette_pc), 1);
1179 prev_vert_double = state_fio->FgetBool();
1180 raster = state_fio->FgetInt32();
1181 cblink = state_fio->FgetInt32();
1182 ch_height = state_fio->FgetInt32();
1183 hz_total = state_fio->FgetInt32();
1184 hz_disp = state_fio->FgetInt32();
1185 vt_disp = state_fio->FgetInt32();
1186 st_addr = state_fio->FgetInt32();
1187 vblank_clock = state_fio->FgetUint32();