2 SHARP X1 Emulator 'eX1'
3 SHARP X1twin Emulator 'eX1twin'
4 SHARP X1turbo Emulator 'eX1turbo'
5 SHARP X1turboZ Emulator 'eX1turboZ'
7 Origin : X1EMU by KM (kanji rom)
8 X-millenium by Yui (ank16 patch)
9 Author : Takeda.Toshiya
16 #include "../hd46505.h"
19 #ifdef _X1TURBO_FEATURE
20 #define EVENT_AFTER_BLANK 0
26 #define AEN ((zmode1 & 0x80) != 0)
27 #define C64 ((zmode1 & 0x10) != 0)
28 #define APEN ((zmode2 & 0x80) != 0)
29 #define APRD ((zmode2 & 0x08) != 0)
32 void DISPLAY::initialize()
35 FILEIO* fio = new FILEIO();
38 if(fio->Fopen(create_local_path(_T("ANK8.ROM")), FILEIO_READ_BINARY)) {
39 fio->Fread(font, sizeof(font), 1);
41 } else if(fio->Fopen(create_local_path(_T("FNT0808.X1")), FILEIO_READ_BINARY)) {
43 fio->Fread(font, sizeof(font), 1);
48 if(fio->Fopen(create_local_path(_T("ANK16.ROM")), FILEIO_READ_BINARY)) {
49 fio->Fread(kanji, 0x1000, 1);
51 } else if(fio->Fopen(create_local_path(_T("FNT0816.X1")), FILEIO_READ_BINARY)) {
53 fio->Fread(kanji, 0x1000, 1);
56 memcpy(kanji + 0x7f * 16, ANKFONT7f_9f, sizeof(ANKFONT7f_9f));
57 memcpy(kanji + 0xe0 * 16, ANKFONTe0_ff, sizeof(ANKFONTe0_ff));
60 if(fio->Fopen(create_local_path(_T("KANJI.ROM")), FILEIO_READ_BINARY)) {
61 fio->Fread(kanji + 0x1000, 0x4ac00, 1);
63 } else if(fio->Fopen(create_local_path(_T("FNT1616.X1")), FILEIO_READ_BINARY)) {
65 fio->Fread(kanji + 0x1000, 0x4ac00, 1);
68 for(int ofs = 0x1000; ofs < 0x4bc00; ofs += 32) {
71 for(int i = 0; i < 16; i++) {
72 buf[i ] = kanji[ofs + i * 2 ];
73 buf[i + 16] = kanji[ofs + i * 2 + 1];
75 memcpy(kanji + ofs, buf, 32);
80 for(int i = 0; i < 8; i++) {
81 palette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
82 palette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // cg
85 for(int i = 0; i < 8; i++) {
86 ztpal[i] = ((i & 1) ? 0x03 : 0) | ((i & 2) ? 0x0c : 0) | ((i & 4) ? 0x30 : 0);
87 zpalette_tmp[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
88 zpalette_tmp[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // digital
90 for(int g = 0; g < 16; g++) {
91 for(int r = 0; r < 16; r++) {
92 for(int b = 0; b < 16; b++) {
93 int num = b + r * 16 + g * 256;
97 zpalette_tmp[num + 16] = RGB_COLOR((r * 255) / 15, (g * 255) / 15, (b * 255) / 15);
101 zpalette_changed = true;
112 memset(vram_t, 0, sizeof(vram_t));
113 memset(vram_a, 0, sizeof(vram_a));
114 #ifdef _X1TURBO_FEATURE
115 memset(vram_k, 0, sizeof(vram_k));
117 memset(pcg_b, 0, sizeof(pcg_b));
118 memset(pcg_r, 0, sizeof(pcg_r));
119 memset(pcg_g, 0, sizeof(pcg_g));
120 #ifdef _X1TURBO_FEATURE
121 memset(gaiji_b, 0, sizeof(gaiji_b));
122 memset(gaiji_r, 0, sizeof(gaiji_r));
123 memset(gaiji_g, 0, sizeof(gaiji_g));
127 register_frame_event(this);
128 register_vline_event(this);
130 // Copy images to draw buffers.
131 my_memcpy(dr_text, text, sizeof(dr_text));
132 my_memcpy(dr_cg, cg, sizeof(dr_cg));
133 my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
134 my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
135 dr_priority = priority;
137 dr_zpriority = zpriority;
138 my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
139 my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
140 my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
141 zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
142 zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
143 zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
144 zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
145 zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
146 zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
147 zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
148 zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
151 PrepareBitTransTableUint16(&bit_trans_table_b0, 0x01, 0x00);
152 PrepareBitTransTableUint16(&bit_trans_table_r0, 0x02, 0x00);
153 PrepareBitTransTableUint16(&bit_trans_table_g0, 0x04, 0x00);
156 void DISPLAY::reset()
158 #ifdef _X1TURBO_FEATURE
162 emu->set_vm_screen_lines(400);
164 emu->set_vm_screen_lines(200);
176 cur_line = cur_code = 0;
181 kaddr = kofs = kflag = 0;
182 kanji_ptr = &kanji[0];
184 // Copy images to draw buffers.
185 my_memcpy(dr_text, text, sizeof(dr_text));
186 my_memcpy(dr_cg, cg, sizeof(dr_cg));
187 my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
188 my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
189 dr_priority = priority;
191 dr_zpriority = zpriority;
192 my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
193 my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
194 my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
195 zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
196 zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
197 zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
198 zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
199 zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
200 zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
201 zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
202 zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
206 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
208 switch(addr & 0xff00) {
210 write_kanji(addr, data);
218 d_cpu->write_signal(SIG_CPU_WAIT, 1, 1);
220 int num = get_zpal_num(addr, data);
221 if(zpal[num].b != (data & 0x0f)) {
222 zpal[num].b = data & 0x0f;
223 zpalette_tmp[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
224 zpalette_changed = true;
226 } else if(APEN && APRD) {
227 zpal_num = get_zpal_num(addr, data);
242 d_cpu->write_signal(SIG_CPU_WAIT, 1, 1);
244 int num = get_zpal_num(addr, data);
245 if(zpal[num].r != (data & 0x0f)) {
246 zpal[num].r = data & 0x0f;
247 zpalette_tmp[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
248 zpalette_changed = true;
250 } else if(APEN && APRD) {
251 // zpal_num = get_zpal_num(addr, data);
266 d_cpu->write_signal(SIG_CPU_WAIT, 1, 1);
268 int num = get_zpal_num(addr, data);
269 if(zpal[num].g != (data & 0x0f)) {
270 zpal[num].g = data & 0x0f;
271 zpalette_tmp[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
272 zpalette_changed = true;
274 } else if(APEN && APRD) {
275 // zpal_num = get_zpal_num(addr, data);
290 pcg_b[cur_code][cur_line] = data;
291 #ifdef _X1TURBO_FEATURE
292 gaiji_b[cur_code >> 1][(cur_line << 1) | (cur_code & 1)] = data;
297 pcg_r[cur_code][cur_line] = data;
298 #ifdef _X1TURBO_FEATURE
299 gaiji_r[cur_code >> 1][(cur_line << 1) | (cur_code & 1)] = data;
304 pcg_g[cur_code][cur_line] = data;
305 #ifdef _X1TURBO_FEATURE
306 gaiji_g[cur_code >> 1][(cur_line << 1) | (cur_code & 1)] = data;
309 #ifdef _X1TURBO_FEATURE
325 if(ztpal[addr & 7] != data) {
326 ztpal[addr & 7] = data;
327 zpalette_tmp[addr & 7] = RGB_COLOR((((data >> 2) & 3) * 255) / 3, (((data >> 4) & 3) * 255) / 3, (((data >> 0) & 3) * 255) / 3);
328 zpalette_changed = true;
366 // hireso = !((mode1 & 3) == 0 || (mode1 & 3) == 2);
383 vram_a[addr & 0x7ff] = data;
393 vram_a[addr & 0x7ff] = data; // mirror
403 vram_t[addr & 0x7ff] = data;
413 #ifdef _X1TURBO_FEATURE
414 vram_k[addr & 0x7ff] = data;
416 vram_t[addr & 0x7ff] = data; // mirror
422 uint32_t DISPLAY::read_io8(uint32_t addr)
424 switch(addr & 0xff00) {
426 return read_kanji(addr);
429 if(AEN && APEN && APRD) {
430 return zpal[zpal_num].b;
434 if(AEN && APEN && APRD) {
435 return zpal[zpal_num].r;
439 if(AEN && APEN && APRD) {
440 return zpal[zpal_num].g;
447 return get_cur_font(addr);
450 return pcg_b[cur_code][cur_line];
453 return pcg_r[cur_code][cur_line];
456 return pcg_g[cur_code][cur_line];
471 return ztpal[addr & 7];
519 return vram_a[addr & 0x7ff];
528 return vram_a[addr & 0x7ff]; // mirror
537 return vram_t[addr & 0x7ff];
546 #ifdef _X1TURBO_FEATURE
547 return vram_k[addr & 0x7ff];
549 return vram_t[addr & 0x7ff]; // mirror
555 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
557 if(id == SIG_DISPLAY_VBLANK) {
560 vblank_clock = get_current_clock();
562 } else if(id == SIG_DISPLAY_COLUMN40) {
563 column40 = ((data & mask) != 0);
565 } else if(id == SIG_DISPLAY_DETECT_VBLANK) {
566 // hack: cpu detects vblank
567 vblank_clock = get_current_clock();
568 } else if(id == SIG_DISPLAY_DISP) {
569 bool prev = cur_blank;
570 cur_blank = ((data & mask) == 0); // blank = not disp
571 if(!prev && cur_blank) {
572 // draw line at start of hblank
573 #ifdef _X1TURBO_FEATURE
575 if(cur_vline < 400) {
576 draw_line(cur_vline);
580 if(cur_vline < 200) {
581 draw_line(cur_vline);
583 #ifdef _X1TURBO_FEATURE
585 // restart cpu after pcg/cgrom/zpal is accessed
586 // d_cpu->write_signal(SIG_CPU_WAIT, 0, 0);
587 register_event_by_clock(this, EVENT_AFTER_BLANK, 24, false, NULL);
593 void DISPLAY::event_frame()
595 cblink = (cblink + 1) & 0x3f;
597 // update crtc parameters
598 ch_height = (regs[9] & 0x1f) + 1;
599 hz_total = regs[0] + 1;
601 vt_disp = regs[6] & 0x7f;
602 vt_ofs = regs[5] & 0x1f;
603 st_addr = (regs[12] << 8) | regs[13];
604 #ifdef _X1TURBO_FEATURE
605 int vt_total = ((regs[4] & 0x7f) + 1) * ch_height + (regs[5] & 0x1f);
606 bool hireso_old = hireso;
607 hireso = (vt_total >= 400);
608 if(!hireso) vt_ofs = max(vt_ofs - 2, 0);
610 vt_ofs = max(vt_ofs - 2, 0);
613 #ifdef _X1TURBO_FEATURE
614 vlen = (hireso) ? 400 : 200;
615 // if(hireso_old != hireso) {
616 // emu->set_vm_screen_lines(vlen);
622 // Copy images to draw buffers.
623 my_memcpy(dr_text, text, sizeof(uint8_t) * vlen * (640 + 8));
624 my_memcpy(dr_cg, cg, sizeof(uint8_t) * vlen * 640);
625 my_memcpy(dr_pri_line, pri_line, sizeof(uint8_t) * vlen * 8 * 8);
627 my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
628 dr_priority = priority;
629 // initialize draw screen
630 memset(text, 0, sizeof(text));
631 memset(cg, 0, sizeof(cg));
632 memset(pri_line, 0, sizeof(pri_line));
635 // Copy images to draw buffers.
636 my_memcpy(&(dr_zcg[0][0][0]), &(zcg[0][0][0]), sizeof(uint8_t) * vlen * 640);
637 //my_memcpy(dr_aen_line, aen_line, sizeof(bool) * vlen);
639 my_memcpy(dr_aen_line, aen_line, sizeof(aen_line));
640 dr_zpriority = zpriority;
641 my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
642 zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
643 zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
644 zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
645 zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
646 zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
647 zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
648 zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
649 zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
651 memset(zcg, 0, sizeof(zcg));
652 memset(aen_line, 0, sizeof(aen_line));
654 prev_vert_double = false;
658 void DISPLAY::event_vline(int v, int clock)
661 // if(zpalette_changed && v == (hireso ? 400 : 200)) {
662 if(zpalette_changed && v == 0) {
664 zpalette_changed = false;
670 // Copy images to draw buffers.
672 #ifdef _X1TURBO_FEATURE
673 vlimit = (hireso) ? 400 : 200;
677 if((v > vlimit) || (v < 0)) return;
680 my_memcpy(dr_palette_pc, palette_pc, sizeof(palette_pc));
682 my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
684 // Copy images to draw buffers.
685 //my_memcpy(&(dr_text[v][0]), &(text[v][0]), sizeof(uint8_t) * (640 + 8));
686 //my_memcpy(&(dr_cg[v][0]), &(cg[v][0]), sizeof(uint8_t) * 640);
687 //my_memcpy(&(dr_pri_line[v][0][0]), &(pri_line[v][0][0]), sizeof(uint8_t) * 8 * 8);
689 //my_memcpy(&(dr_zcg[0][v][0]), &(zcg[0][v][0]), sizeof(uint8_t) * 640);
690 //my_memcpy(&(dr_zcg[1][v][0]), &(zcg[1][v][0]), sizeof(uint8_t) * 640);
691 //dr_aen_line[v] = aen_line[v];
696 // Copy images to draw buffers.
697 my_memcpy(&(dr_text[v - 1][0]), &(text[v - 1][0]), sizeof(uint8_t) * (640 + 8));
698 my_memcpy(&(dr_cg[v - 1][0]), &(cg[v -1 ][0]), sizeof(uint8_t) * 640);
699 my_memcpy(&(dr_pri_line[v - 1][0][0]), &(pri_line[v - 1][0][0]), sizeof(uint8_t) * 8 * 8);
700 dr_priority = priority;
702 my_memcpy(&(dr_zcg[0][v - 1 ][0]), &(zcg[0][v - 1][0]), sizeof(uint8_t) * 640);
703 my_memcpy(&(dr_zcg[1][v - 1][0]), &(zcg[1][v - 1][0]), sizeof(uint8_t) * 640);
704 dr_zpriority = zpriority;
705 dr_aen_line[v - 1] = aen_line[v - 1];
710 #ifdef _X1TURBO_FEATURE
711 void DISPLAY::event_callback(int event_id, int err)
713 if(event_id == EVENT_AFTER_BLANK) {
714 // restart cpu after pcg/cgrom/zpal is accessed
715 d_cpu->write_signal(SIG_CPU_WAIT, 0, 0);
720 void DISPLAY::update_crtc()
722 #ifdef _X1TURBO_FEATURE
724 d_crtc->set_char_clock((mode1 & 1) ? VDP_CLOCK * 1.5 / 32.0 : VDP_CLOCK / 32.0);
726 d_crtc->set_char_clock((mode1 & 1) ? VDP_CLOCK * 1.5 / 16.0 : VDP_CLOCK / 16.0);
730 d_crtc->set_char_clock(VDP_CLOCK / 32.0);
732 d_crtc->set_char_clock(VDP_CLOCK / 16.0);
737 void DISPLAY::update_pal()
740 for(int i = 0; i < 8; i++) {
741 uint8_t bit = 1 << i;
742 pal2[i] = ((pal[0] & bit) ? 1 : 0) | ((pal[1] & bit) ? 2 : 0) | ((pal[2] & bit) ? 4 : 0) | 8;
744 #ifdef _X1TURBO_FEATURE
745 if(mode2 & 0x10) pal2[0] = 8;
746 if(mode2 & 0x20) pal2[1] = 8;
748 for(int c = 0; c < 8; c++) {
749 for(int t = 0; t < 8; t++) {
750 if(priority & (1 << c)) {
753 #ifdef _X1TURBO_FEATURE
754 pri[c][t] = ((mode2 & 8) && (mode2 & 7) == t) ? 0 : t;
765 uint8_t DISPLAY::get_cur_font(uint32_t addr)
767 #ifdef _X1TURBO_FEATURE
770 d_cpu->write_signal(SIG_CPU_WAIT, 1, 1);
774 if(!(vram_a[0x7ff] & 0x20)) {
776 } else if(!(vram_a[0x3ff] & 0x20)) {
778 } else if(!(vram_a[0x5ff] & 0x20)) {
780 } else if(!(vram_a[0x1ff] & 0x20)) {
785 uint16_t ank = vram_t[vaddr];
786 uint16_t knj = vram_k[vaddr];
789 uint32_t ofs = adr2knj_x1t((knj << 8) | ank);
793 return kanji[ofs | (addr & 15)];
794 } else if(mode1 & 0x40) {
795 return kanji[(ank << 4) | (addr & 15)];
797 return font[(ank << 3) | ((addr >> 1) & 7)];
802 return font[(cur_code << 3) | (cur_line & 7)];
805 void DISPLAY::get_cur_pcg(uint32_t addr)
807 #ifdef _X1TURBO_FEATURE
810 d_cpu->write_signal(SIG_CPU_WAIT, 1, 1);
814 if(vram_a[0x7ff] & 0x20) {
816 } else if(vram_a[0x3ff] & 0x20) {
818 } else if(vram_a[0x5ff] & 0x20) {
820 } else if(vram_a[0x1ff] & 0x20) {
825 cur_code = vram_t[vaddr];
826 cur_line = (addr >> 1) & 7;
828 if(vram_k[vaddr] & 0x90) {
830 cur_code += addr & 1;
837 void DISPLAY::get_cur_code_line()
839 //#ifdef _X1TURBO_FEATURE
840 // int ht_clock = hireso ? 161 : 250;
844 int clock = get_passed_clock(vblank_clock);
845 int vt_line = vt_disp * ch_height + (int)(clock / ht_clock);
847 int addr = (hz_total * (clock % ht_clock)) / ht_clock;
848 addr += hz_disp * (int)(vt_line / ch_height);
849 addr &= 0x7ff; // thanks Mr.YAT
852 cur_code = vram_t[addr & 0x7ff];
853 cur_line = (vt_line % ch_height) & 7;
856 void DISPLAY::draw_line(int v)
858 if((regs[8] & 0x30) != 0x30) {
859 if((v % ch_height) == 0) {
860 draw_text(v / ch_height);
863 if(AEN && !hireso && column40) {
868 memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
870 // memset(&pri_line[v][0][0], 0, sizeof(pri));
877 void DISPLAY::draw_screen()
879 if(emu->now_waiting_in_debugger) {
881 #ifdef _X1TURBO_FEATURE
882 for(int v = 0; v < (hireso ? 400 : 200); v++) {
884 for(int v = 0; v < 200; v++) {
889 if(zpalette_changed && cur_vline < (hireso ? 400 : 200)) {
891 zpalette_changed = false;
896 // total raster_adjust
897 #ifdef _X1TURBO_FEATURE
898 for(int y = 0; y < vt_ofs * (hireso ? 1 : 2); y++) {
900 for(int y = 0; y < vt_ofs * 2; y++) {
902 scrntype_t* dest = emu->get_screen_buffer(y);
903 memset(dest, 0, 640 * sizeof(scrntype_t));
906 // copy to real screen
907 __DECL_ALIGNED(16) scrntype_t dbuf[640];
908 #ifdef _X1TURBO_FEATURE
911 // emu->set_vm_screen_lines(400);
914 for(int y = 0; (y + vt_ofs) < 400; y++) {
915 scrntype_t* dest = emu->get_screen_buffer(y + vt_ofs);
916 uint8_t* src_text = dr_text[y];
919 uint16_t* src_cg0 = dr_zcg[0][y];
921 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
922 uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
924 dbuf[x2] = dbuf[x2 + 1] = get_zpriority(src_text[x], cg00, cg00);
928 uint8_t* src_cg = dr_cg[y];
930 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
932 dbuf[x2] = dbuf[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
934 dbuf[x2] = dbuf[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
940 __DECL_VECTORIZED_LOOP
941 for(int xx = 0; xx < 640; xx++) {
947 for(int y = 0; (y + vt_ofs) < 400; y++) {
948 scrntype_t* dest = emu->get_screen_buffer(y + vt_ofs);
949 uint8_t* src_text = dr_text[y];
952 uint16_t* src_cg0 = dr_zcg[0][y];
954 for(int x = 0; x < 640; x++) {
955 uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
957 dbuf[x] = get_zpriority(src_text[x], cg00, cg00);
961 uint8_t* src_cg = dr_cg[y];
963 for(int x = 0; x < 640; x++) {
965 dbuf[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
967 dbuf[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
973 __DECL_VECTORIZED_LOOP
974 for(int xx = 0; xx < 640; xx++) {
979 emu->screen_skip_line(false);
982 // emu->set_vm_screen_lines(200);
984 // emu->set_vm_screen_lines(200);
988 for(int y = 0; (y + vt_ofs) < 200; y++) {
989 scrntype_t* dest0 = emu->get_screen_buffer((y + vt_ofs) * 2 + 0);
990 scrntype_t* dest1 = emu->get_screen_buffer((y + vt_ofs) * 2 + 1);
991 uint8_t* src_text = dr_text[y];
994 uint16_t* src_cg0 = dr_zcg[0][y];
995 uint16_t* src_cg1 = dr_zcg[1][y];
998 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
999 uint16_t cg00 = src_cg0[x];// | (src_cg0[x] >> 2);
1000 uint16_t cg11 = src_cg1[x];// | (src_cg1[x] >> 2);
1002 dbuf[x2] = dbuf[x2 + 1] = get_zpriority(src_text[x], cg00, cg11);
1005 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
1006 uint16_t cg01 = src_cg0[x] | (src_cg1[x] >> 2);
1008 dbuf[x2] = dbuf[x2 + 1] = get_zpriority(src_text[x], cg01, cg01);
1014 // scrntype_t* dest = emu->get_screen_buffer(y);
1015 uint8_t* src_cg = dr_cg[y];
1017 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
1019 dbuf[x2] = dbuf[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
1021 dbuf[x2] = dbuf[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
1027 __DECL_VECTORIZED_LOOP
1028 for(int xx = 0; xx < 640; xx++) {
1029 dest0[xx] = dbuf[xx];
1031 if(!config.scan_line) {
1032 __DECL_VECTORIZED_LOOP
1033 for(int xx = 0; xx < 640; xx++) {
1034 dest1[xx] = dbuf[xx];
1037 memset(dest1, 0, 640 * sizeof(scrntype_t));
1042 for(int y = 0; (y + vt_ofs) < 200; y++) {
1043 scrntype_t* dest0 = emu->get_screen_buffer((y + vt_ofs) * 2 + 0);
1044 scrntype_t* dest1 = emu->get_screen_buffer((y + vt_ofs) * 2 + 1);
1045 uint8_t* src_text = dr_text[y];
1048 uint16_t* src_cg0 = dr_zcg[0][y];
1050 for(int x = 0; x < 640; x++) {
1051 uint16_t cg00 = src_cg0[x];// | (src_cg0[x] >> 2);
1053 dbuf[x] = get_zpriority(src_text[x], cg00, cg00);
1057 uint8_t* src_cg = dr_cg[y];
1058 //__DECL_VECTORIZED_LOOP
1059 for(int x = 0; x < 640; x++) {
1061 dbuf[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
1063 dbuf[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
1066 __DECL_VECTORIZED_LOOP
1067 for(int xx = 0; xx < 640; xx++) {
1068 dest0[xx] = dbuf[xx];
1070 if(!config.scan_line) {
1071 __DECL_VECTORIZED_LOOP
1072 for(int xx = 0; xx < 640; xx++) {
1073 dest1[xx] = dbuf[xx];
1076 memset(dest1, 0, 640 * sizeof(scrntype_t));
1083 emu->screen_skip_line(true);
1084 #ifdef _X1TURBO_FEATURE
1089 void DISPLAY::draw_text(int y)
1091 int width = column40 ? 40 : 80;
1092 uint16_t src = st_addr + hz_disp * y;
1094 bool cur_vert_double = true;
1095 uint8_t prev_attr = 0, prev_pattern_b[32], prev_pattern_r[32], prev_pattern_g[32];
1097 for(int x = 0; x < hz_disp && x < width; x++) {
1099 uint8_t code = vram_t[src];
1100 #ifdef _X1TURBO_FEATURE
1101 uint8_t knj = vram_k[src];
1103 uint8_t attr = vram_a[src];
1106 uint8_t col = attr & 7;
1107 bool reverse = ((attr & 8) != 0);
1108 bool blink = ((attr & 0x10) && (cblink & 0x20));
1109 reverse = (reverse != blink);
1111 // select pcg or ank
1112 const uint8_t *pattern_b, *pattern_r, *pattern_g;
1113 #ifdef _X1TURBO_FEATURE
1121 #ifdef _X1TURBO_FEATURE
1123 pattern_b = gaiji_b[code >> 1];
1124 pattern_r = gaiji_r[code >> 1];
1125 pattern_g = gaiji_g[code >> 1];
1129 pattern_b = pcg_b[code];
1130 pattern_r = pcg_r[code];
1131 pattern_g = pcg_g[code];
1132 #ifdef _X1TURBO_FEATURE
1133 shift = (mode1 & 1) ? 1 : 0;
1136 #ifdef _X1TURBO_FEATURE
1137 } else if(knj & 0x80) {
1138 uint32_t ofs = adr2knj_x1t((knj << 8) | code);
1142 pattern_b = pattern_r = pattern_g = &kanji[ofs];
1144 } else if((mode1 & 5) != 0) {
1145 // ank 8x16 or kanji
1146 pattern_b = pattern_r = pattern_g = &kanji[code << 4];
1151 pattern_b = pattern_r = pattern_g = &font[code << 3];
1153 #ifdef _X1TURBO_FEATURE
1154 if(max_line == 16) {
1155 shift = ((mode1 & 5) == 5) ? 1 : ((mode1 & 5) != 0) ? 0 : -1;
1159 // check vertical doubled char
1160 if(!(attr & 0x40)) {
1161 cur_vert_double = false;
1165 for(int l = 0; l < ch_height; l++) {
1167 int line = cur_vert_double ? raster + (l >> 1) : l;
1168 #ifdef _X1TURBO_FEATURE
1171 } else if(shift == -1) {
1173 if(cur_vert_double) {
1178 if((x & 1) && (prev_attr & 0x80)) {
1179 b = prev_pattern_b[line] << 4;
1180 r = prev_pattern_r[line] << 4;
1181 g = prev_pattern_g[line] << 4;
1183 b = prev_pattern_b[line] = pattern_b[line % max_line];
1184 r = prev_pattern_r[line] = pattern_r[line % max_line];
1185 g = prev_pattern_g[line] = pattern_g[line % max_line];
1188 b = (!(col & 1)) ? 0xff : ~b;
1189 r = (!(col & 2)) ? 0xff : ~r;
1190 g = (!(col & 4)) ? 0xff : ~g;
1192 b = (!(col & 1)) ? 0 : b;
1193 r = (!(col & 2)) ? 0 : r;
1194 g = (!(col & 4)) ? 0 : g;
1197 int yy = y * ch_height + l;
1198 #ifdef _X1TURBO_FEATURE
1205 uint8_t* d = &text[yy][x << 3];
1208 // horizontal doubled char
1210 d[ 0] = d[ 1] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
1211 d[ 2] = d[ 3] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
1212 d[ 4] = d[ 5] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
1213 d[ 6] = d[ 7] = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2);
1215 ConvertRGBTo8ColorsUint8_Zoom2Left(r, g, b, d, &bit_trans_table_r0, &bit_trans_table_g0, &bit_trans_table_b0, 0);
1219 d[0] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
1220 d[1] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
1221 d[2] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
1222 d[3] = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2);
1223 d[4] = ((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1);
1224 d[5] = ((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) >> 0);
1225 d[6] = ((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1);
1226 d[7] = ((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2);
1228 ConvertRGBTo8ColorsUint8(r, g, b, d, &bit_trans_table_r0, &bit_trans_table_g0, &bit_trans_table_b0, 0);
1234 if(cur_vert_double && !prev_vert_double) {
1235 prev_vert_double = true;
1236 raster = ch_height >> 1;
1238 prev_vert_double = false;
1243 void DISPLAY::draw_cg(int line, int plane)
1245 int width = column40 ? 40 : 80;
1247 int y = line / ch_height;
1248 int l = line % ch_height;
1252 int ofs, src = st_addr + hz_disp * y;
1253 #ifdef _X1TURBO_FEATURE
1254 int page = (hireso && !(mode1 & 2)) ? (l & 1) : (mode1 & 8);
1255 int ll = hireso ? (l >> 1) : l;
1258 ofs = (0x400 * (ll & 15));// + (page ? 0xc000 : 0);
1260 ofs = (0x800 * (ll & 7));// + (page ? 0xc000 : 0);
1263 ofs = 0x800 * (l & 7);
1268 HIRESO=0, WIDTH=40, C64=0: 320x200, 4096 PAGE0:(ADDR 000h-3FFh) + PAGE0:(ADDR 400h-7FFh) + PAGE1:(ADDR 000h-3FFh) + PAGE1:(ADDR 400h-7FFh)
1269 HIRESO=0, WIDTH=40, C64=1: 320x200, 64x2 PAGE0:(ADDR 000h-3FFh) + PAGE0:(ADDR 400h-7FFh) / PAGE1:(ADDR 000h-3FFh) + PAGE1:(ADDR 400h-7FFh)
1270 HIRESO=1, WIDTH=40, C64=*: 320x200, 64 PAGE*:(ADDR 000h-3FFh) + PAGE*:(ADDR 400h-7FFh)
1271 HIRESO=0, WIDTH=80, C64=*: 640x200, 64 PAGE0:(ADDR 000h-7FFh) + PAGE1:(ADDR 000h-7FFh)
1272 HIRESO=1, WIDTH=80, C64=*: 640x200, 8 PAGE0:(ADDR 000h-7FFh) + PAGE0:(ADDR 000h-7FFh)
1274 HIRESO=0, WIDTH=40, C64=1: 320x200, 64x2
1276 SCREEN 0 00 00 PAGE0
1277 SCREEM 2 18 08 PAGE1
1278 SCREEN 4 00 10 PAGE0 > PAGE1
1279 SCREEN 6 18 18 PAGE0 < PAGE1
1283 if(C64 && !(zpriority & 0x10)) {
1285 my_memcpy(zcg[plane][1], zcg[plane][0], sizeof(uint16_t) * 640);
1298 int ofs_b0 = ofs + 0x0000;
1299 int ofs_r0 = ofs + 0x4000;
1300 int ofs_g0 = ofs + 0x8000;
1301 int ofs_b1 = column40 ? (ofs_b0 ^ 0x400) : hireso ? ofs_b0 : (ofs_b0 + 0xc000);
1302 int ofs_r1 = column40 ? (ofs_r0 ^ 0x400) : hireso ? ofs_r0 : (ofs_r0 + 0xc000);
1303 int ofs_g1 = column40 ? (ofs_g0 ^ 0x400) : hireso ? ofs_g0 : (ofs_g0 + 0xc000);
1305 for(int x = 0; x < hz_disp && x < width; x++) {
1306 src &= column40 ? 0x3ff : 0x7ff;
1307 uint16_t b0 = vram_ptr[ofs_b0 | src];
1308 uint16_t r0 = vram_ptr[ofs_r0 | src];
1309 uint16_t g0 = vram_ptr[ofs_g0 | src];
1310 uint16_t b1 = vram_ptr[ofs_b1 | src];
1311 uint16_t r1 = vram_ptr[ofs_r1 | src];
1312 uint16_t g1 = vram_ptr[ofs_g1 | src++];
1313 uint16_t* d = &zcg[plane][line][x << 3];
1315 // MSB <- G0,G1,0,0, R0,R1,0,0, B0,B1,0,0 -> LSB
1316 d[0] = ((b0 & 0x80) >> 4) | ((b1 & 0x80) >> 5) | ((r0 & 0x80) >> 0) | ((r1 & 0x80) >> 1) | ((g0 & 0x80) << 4) | ((g1 & 0x80) << 3);
1317 d[1] = ((b0 & 0x40) >> 3) | ((b1 & 0x40) >> 4) | ((r0 & 0x40) << 1) | ((r1 & 0x40) >> 0) | ((g0 & 0x40) << 5) | ((g1 & 0x40) << 4);
1318 d[2] = ((b0 & 0x20) >> 2) | ((b1 & 0x20) >> 3) | ((r0 & 0x20) << 2) | ((r1 & 0x20) << 1) | ((g0 & 0x20) << 6) | ((g1 & 0x20) << 5);
1319 d[3] = ((b0 & 0x10) >> 1) | ((b1 & 0x10) >> 2) | ((r0 & 0x10) << 3) | ((r1 & 0x10) << 2) | ((g0 & 0x10) << 7) | ((g1 & 0x10) << 6);
1320 d[4] = ((b0 & 0x08) >> 0) | ((b1 & 0x08) >> 1) | ((r0 & 0x08) << 4) | ((r1 & 0x08) << 3) | ((g0 & 0x08) << 8) | ((g1 & 0x08) << 7);
1321 d[5] = ((b0 & 0x04) << 1) | ((b1 & 0x04) >> 0) | ((r0 & 0x04) << 5) | ((r1 & 0x04) << 4) | ((g0 & 0x04) << 9) | ((g1 & 0x04) << 8);
1322 d[6] = ((b0 & 0x02) << 2) | ((b1 & 0x02) << 1) | ((r0 & 0x02) << 6) | ((r1 & 0x02) << 5) | ((g0 & 0x02) << 10) | ((g1 & 0x02) << 9);
1323 d[7] = ((b0 & 0x01) << 3) | ((b1 & 0x01) << 2) | ((r0 & 0x01) << 7) | ((r1 & 0x01) << 6) | ((g0 & 0x01) << 11) | ((g1 & 0x01) << 10);
1326 // zpriorityで処理すると、プレーンの取得に遅延がでるので
1327 // ここで2ビット下へ移動してしまおう
1328 if(!hireso && column40 && C64 && page) {
1329 for(int x = 0; x < hz_disp && x < width; x++) {
1330 uint16_t* d = &zcg[plane][line][x << 3];
1332 // MSB <- G0,G1,0,0, R0,R1,0,0, B0,B1,0,0 -> LSB
1347 #ifdef _X1TURBO_FEATURE
1352 int ofs_b = ofs + 0x0000;
1353 int ofs_r = ofs + 0x4000;
1354 int ofs_g = ofs + 0x8000;
1357 for(int x = 0; x < hz_disp && x < width; x++) {
1359 uint8_t b = vram_ptr[ofs_b | src];
1360 uint8_t r = vram_ptr[ofs_r | src];
1361 uint8_t g = vram_ptr[ofs_g | src++];
1362 uint8_t* d = &cg[line][x << 3];
1364 d[0] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
1365 d[1] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
1366 d[2] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
1367 d[3] = ((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2);
1368 d[4] = ((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1);
1369 d[5] = ((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) >> 0);
1370 d[6] = ((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1);
1371 d[7] = ((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2);
1374 _render_command_data_t cmd;
1375 for(int i = 0; i < 3; i++) {
1376 cmd.data[i] = vram_ptr;
1377 cmd.baseaddress[i] = 0;
1379 cmd.voffset[0] = ofs_b;
1380 cmd.voffset[1] = ofs_r;
1381 cmd.voffset[2] = ofs_g;
1382 cmd.bit_trans_table[0] = &bit_trans_table_b0;
1383 cmd.bit_trans_table[1] = &bit_trans_table_r0;
1384 cmd.bit_trans_table[2] = &bit_trans_table_g0;
1385 cmd.addrmask = 0xffffffff;
1386 cmd.addrmask2 = 0x07ff;
1387 cmd.begin_pos = src;
1389 int iwidth = (hz_disp > width) ? width : hz_disp;
1390 uint8_t* d = &(cg[line][0]);
1391 cmd.render_width = (iwidth <= 0) ? 0 : (uint32_t)iwidth;
1393 Convert8ColorsToByte_Line(&cmd, d);
1399 int DISPLAY::get_zpal_num(uint32_t addr, uint32_t data)
1401 int num = ((data >> 4) & 0x0f) | ((addr << 4) & 0xff0);
1406 // 8 colors (use asic palette ram)
1411 // 64 colors (single set)
1416 if(!column40 || C64) {
1417 // 64 colors (dual set)
1418 num &= 0xccc; // BANK0 GRAM
1419 if(C64 && (mode1 & 0x10)) {
1420 num >>=2; // BANK1 GRAM
1425 if(hireso && !column40) {
1430 } else if(!(!hireso && column40 && !C64)) {
1439 void DISPLAY::update_zpalette()
1441 memcpy(zpalette_pc, zpalette_tmp, sizeof(zpalette_pc));
1442 zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
1443 zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
1444 zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
1445 zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
1446 zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
1447 zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
1448 zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
1449 zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
1451 dr_zpalette_pc[8 + 0] = dr_zpalette_pc[16 + 0x000];
1452 dr_zpalette_pc[8 + 1] = dr_zpalette_pc[16 + 0x00f];
1453 dr_zpalette_pc[8 + 2] = dr_zpalette_pc[16 + 0x0f0];
1454 dr_zpalette_pc[8 + 3] = dr_zpalette_pc[16 + 0x0ff];
1455 dr_zpalette_pc[8 + 4] = dr_zpalette_pc[16 + 0xf00];
1456 dr_zpalette_pc[8 + 5] = dr_zpalette_pc[16 + 0xf0f];
1457 dr_zpalette_pc[8 + 6] = dr_zpalette_pc[16 + 0xff0];
1458 dr_zpalette_pc[8 + 7] = dr_zpalette_pc[16 + 0xfff];
1462 scrntype_t DISPLAY::get_zpriority(uint8_t text, uint16_t cg0, uint16_t cg1)
1464 if((mode2 & 8) && (text == (mode2 & 7))) {
1465 int digital = ((cg0 >> 9) & 4) | ((cg0 >> 6) & 2) | ((cg0 >> 3) & 1);
1466 if(!(dr_priority & (1 << digital))) {
1470 uint16_t fore = ((dr_zpriority & 0x18) != 0x18) ? cg0 : cg1;
1471 uint16_t back = ((dr_zpriority & 0x18) != 0x18) ? cg1 : cg0;
1474 switch(dr_zpriority & 0x13) {
1477 disp = text ? text : (fore + 16);
1481 disp = fore ? (fore + 16) : text;
1484 disp = text ? text : fore ? (fore + 16) : (back + 16);
1487 disp = fore ? (fore + 16) : back ? (back + 16) : text;
1490 disp = fore ? (fore + 16) : text ? text : (back + 16);
1492 default: // undefined case :-(
1493 disp = text ? text : fore ? (fore + 16) : (back + 16);
1496 // if((mode2 & 0x10) && disp == (0x000 + 16)) {
1499 // if((mode2 & 0x20) && disp == (0x00f + 16)) {
1502 return dr_zpalette_pc[disp];
1506 // kanji rom (from X1EMU by KM)
1508 void DISPLAY::write_kanji(uint32_t addr, uint32_t data)
1512 kaddr = (kaddr & 0xff00) | data;
1515 kaddr = (kaddr & 0xff) | (data << 8);
1518 // TODO: bit0 L->H: Latch
1519 kanji_ptr = &kanji[adr2knj_x1(kaddr & 0xfff0)];
1524 uint32_t DISPLAY::read_kanji(uint32_t addr)
1528 if(kaddr & 0xff00) {
1529 uint32_t val = kanji_ptr[kofs];
1532 kofs = (kofs + 1) & 15;
1537 return jis2adr_x1(kaddr << 8) >> 8;
1539 if(kaddr & 0xff00) {
1540 uint32_t val = kanji_ptr[kofs + 16];
1543 kofs = (kofs + 1) & 15;
1553 uint16_t DISPLAY::jis2adr_x1(uint16_t jis)
1555 uint16_t jh, jl, adr;
1560 adr = 0x4000 + (jh - 0x30) * 0x600;
1562 adr = 0x0100 + (jh - 0x21) * 0x600;
1565 adr += (jl - 0x20) * 0x10;
1570 uint32_t DISPLAY::adr2knj_x1(uint16_t adr)
1572 uint16_t jh, jl, jis;
1576 jh = 0x21 + jh / 0x600;
1579 jh = 0x30 + jh / 0x600;
1582 adr -= 0x4000 + (jh - 0x30) * 0x600;
1584 adr -= 0x0100 + (jh - 0x21) * 0x600;
1591 jis = (jh << 8) | jl;
1592 return jis2knj(jis);
1595 #ifdef _X1TURBO_FEATURE
1596 uint32_t DISPLAY::adr2knj_x1t(uint16_t adr)
1609 j2 = rl & 0x1f; // rl4,3,2,1,0
1610 j1 = (rl / 0x20) & 7; // rl7,6,5
1616 case 0: j2 |= 0x20; break;
1617 case 1: j2 |= 0x60; break;
1618 case 2: j2 |= 0x40; break;
1619 default: j1 = j2 = 0; break;
1621 } else if(rh > 0x1c) {
1625 case 0: j2 |= 0x20; break;
1626 case 1: j2 |= 0x60; break;
1627 case 2: j2 |= 0x40; break;
1628 default: j1 = j2 = 0; break;
1631 j1 |= (((rh >> 1) + 7) / 3) * 0x10;
1633 j2 |= ((((rh >> 1) + 1) % 3) + 1) * 0x20;
1636 jis = (j1 << 8) | j2;
1637 return jis2knj(jis);
1641 uint32_t DISPLAY::jis2knj(uint16_t jis)
1643 uint32_t sjis = jis2sjis(jis);
1647 } else if(sjis >= 0x8140 && sjis < 0x84c0) {
1648 return 0x01000 + (sjis - 0x8140) * 32;
1649 } else if(sjis >= 0x8890 && sjis < 0xa000) {
1650 return 0x08000 + (sjis - 0x8890) * 32;
1651 } else if(sjis >= 0xe040 && sjis < 0xeab0) {
1652 return 0x36e00 + (sjis - 0xe040) * 32;
1658 uint16_t DISPLAY::jis2sjis(uint16_t jis)
1676 c1 = (c1 - 0x20 - 1) / 2 + 0x81;
1680 return (c1 << 8) | c2;
1683 #define STATE_VERSION 6
1685 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
1687 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1690 if(!state_fio->StateCheckInt32(this_device_id)) {
1693 state_fio->StateArray(vram_t, sizeof(vram_t), 1);
1694 state_fio->StateArray(vram_a, sizeof(vram_a), 1);
1695 #ifdef _X1TURBO_FEATURE
1696 state_fio->StateArray(vram_k, sizeof(vram_k), 1);
1698 state_fio->StateArray(&pcg_b[0][0], sizeof(pcg_b), 1);
1699 state_fio->StateArray(&pcg_r[0][0], sizeof(pcg_r), 1);
1700 state_fio->StateArray(&pcg_g[0][0], sizeof(pcg_g), 1);
1701 #ifdef _X1TURBO_FEATURE
1702 state_fio->StateArray(&gaiji_b[0][0], sizeof(gaiji_b), 1);
1703 state_fio->StateArray(&gaiji_r[0][0], sizeof(gaiji_r), 1);
1704 state_fio->StateArray(&gaiji_g[0][0], sizeof(gaiji_g), 1);
1706 state_fio->StateValue(cur_code);
1707 state_fio->StateValue(cur_line);
1708 state_fio->StateValue(kaddr);
1709 state_fio->StateValue(kofs);
1710 state_fio->StateValue(kflag);
1712 intptr_t p = (intptr_t)(&kanji[0]);
1713 kanji_ptr = (uint8_t*)(p + state_fio->FgetInt32_LE());
1715 intptr_t p = (intptr_t)(&kanji[0]);
1716 intptr_t q = (intptr_t)kanji_ptr;
1717 state_fio->FputInt32_LE((int)(q - p));
1719 state_fio->StateArray(pal, sizeof(pal), 1);
1720 state_fio->StateValue(priority);
1721 state_fio->StateArray(&pri[0][0], sizeof(pri), 1);
1722 state_fio->StateValue(column40);
1723 #ifdef _X1TURBO_FEATURE
1724 state_fio->StateValue(mode1);
1725 state_fio->StateValue(mode2);
1726 state_fio->StateValue(hireso);
1729 state_fio->StateValue(zmode1);
1730 state_fio->StateValue(zpriority);
1731 state_fio->StateValue(zadjust);
1732 state_fio->StateValue(zmosaic);
1733 state_fio->StateValue(zchromakey);
1734 state_fio->StateValue(zscroll);
1735 state_fio->StateValue(zmode2);
1736 state_fio->StateArray(ztpal, sizeof(ztpal), 1);
1737 for(int i = 0; i < array_length(zpal); i++){
1738 state_fio->StateValue(zpal[i].r);
1739 state_fio->StateValue(zpal[i].g);
1740 state_fio->StateValue(zpal[i].b);
1742 state_fio->StateValue(zpal_num);
1743 state_fio->StateArrayScrnType_t(zpalette_tmp, sizeof(zpalette_tmp), 1);
1745 state_fio->StateValue(prev_vert_double);
1746 state_fio->StateValue(raster);
1747 state_fio->StateValue(cblink);
1748 state_fio->StateValue(ch_height);
1749 state_fio->StateValue(hz_total);
1750 state_fio->StateValue(hz_disp);
1751 state_fio->StateValue(vt_disp);
1752 state_fio->StateValue(vt_ofs);
1753 state_fio->StateValue(st_addr);
1754 state_fio->StateValue(vblank_clock);
1755 state_fio->StateValue(cur_blank);
1760 zpalette_changed = true;
1762 for(int i = 0; i < 8; i++) {
1763 palette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
1764 palette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // cg
1766 // Copy images to draw buffers.
1767 my_memcpy(dr_text, text, sizeof(dr_text));
1768 my_memcpy(dr_cg, cg, sizeof(dr_cg));
1769 #ifdef _X1TURBO_FEATURE
1770 for(int v = 0; v < 400; v++) {
1771 memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
1774 for(int v = 0; v < 200; v++) {
1775 memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
1778 my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
1779 my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
1780 dr_priority = priority;
1782 // ToDo: Chack save/load.
1783 dr_zpriority = zpriority;
1784 my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
1785 my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
1786 my_memcpy(dr_zpalette_pc, zpalette_tmp, sizeof(zpalette_tmp));
1788 update_crtc(); // force update timing