SHARP X1 Emulator 'eX1'
SHARP X1twin Emulator 'eX1twin'
SHARP X1turbo Emulator 'eX1turbo'
+ SHARP X1turboZ Emulator 'eX1turboZ'
Origin : X1EMU by KM (kanji rom)
- X-millenium by Yui (ank16 patch)
+ X-millenium by Yui (ank16 patch)
Author : Takeda.Toshiya
Date : 2009.03.14-
- [ display ]
+ [ display ]
*/
#include "display.h"
#include "../hd46505.h"
#include "../i8255.h"
+#ifdef _X1TURBO_FEATURE
+#define EVENT_AFTER_BLANK 0
+#endif
+
+namespace X1 {
+
#ifdef _X1TURBOZ
#define AEN ((zmode1 & 0x80) != 0)
#define C64 ((zmode1 & 0x10) != 0)
// register event
register_frame_event(this);
register_vline_event(this);
+
+ // Copy images to draw buffers.
+ my_memcpy(dr_text, text, sizeof(dr_text));
+ my_memcpy(dr_cg, cg, sizeof(dr_cg));
+ my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
+ my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+ dr_priority = priority;
+#ifdef _X1TURBOZ
+ dr_zpriority = zpriority;
+ my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
+ my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
+ my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+ zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+ zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+ zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+ zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+ zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+ zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+ zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+ zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+#endif
}
void DISPLAY::reset()
#endif
cur_line = cur_code = 0;
vblank_clock = 0;
+ cur_vline = 0;
+ cur_blank = true;
kaddr = kofs = kflag = 0;
kanji_ptr = &kanji[0];
+
+ // Copy images to draw buffers.
+ my_memcpy(dr_text, text, sizeof(dr_text));
+ my_memcpy(dr_cg, cg, sizeof(dr_cg));
+ my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
+ my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+ dr_priority = priority;
+#ifdef _X1TURBOZ
+ dr_zpriority = zpriority;
+ my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
+ my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
+ my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+ zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+ zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+ zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+ zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+ zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+ zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+ zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+ zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+#endif
}
void DISPLAY::write_io8(uint32_t addr, uint32_t data)
#ifdef _X1TURBOZ
if(AEN) {
if(APEN && !APRD) {
+ if(!cur_blank) {
+ // wait next blank
+ d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ }
int num = get_zpal_num(addr, data);
zpal[num].b = data & 0x0f;
zpalette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
#ifdef _X1TURBOZ
if(AEN) {
if(APEN && !APRD) {
+ if(!cur_blank) {
+ // wait next blank
+ d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ }
int num = get_zpal_num(addr, data);
zpal[num].r = data & 0x0f;
zpalette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
#ifdef _X1TURBOZ
if(AEN) {
if(APEN && !APRD) {
+ if(!cur_blank) {
+ // wait next blank
+ d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ }
int num = get_zpal_num(addr, data);
zpal[num].g = data & 0x0f;
zpalette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15);
} else if(id == SIG_DISPLAY_DETECT_VBLANK) {
// hack: cpu detects vblank
vblank_clock = get_current_clock();
+ } else if(id == SIG_DISPLAY_DISP) {
+ bool prev = cur_blank;
+ cur_blank = ((data & mask) == 0); // blank = not disp
+ if(!prev && cur_blank) {
+ // draw line at start of hblank
+#ifdef _X1TURBO_FEATURE
+ if(hireso) {
+ if(cur_vline < 400) {
+ draw_line(cur_vline);
+ }
+ } else {
+#endif
+ if(cur_vline < 200) {
+ draw_line(cur_vline);
+ }
+#ifdef _X1TURBO_FEATURE
+ }
+ // restart cpu after pcg/cgrom/zpal is accessed
+// d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
+ register_event_by_clock(this, EVENT_AFTER_BLANK, 24, false, NULL);
+#endif
+ }
}
}
int vt_total = ((regs[4] & 0x7f) + 1) * ch_height + (regs[5] & 0x1f);
hireso = (vt_total > 400);
#endif
+ int vlen;
+#ifdef _X1TURBO_FEATURE
+ vlen = (hireso) ? 400 : 200;
+#else
+ vlen = 200;
+#endif
+ if(vlen > 0) {
+ // Copy images to draw buffers.
+ my_memcpy(dr_text, text, sizeof(uint8_t) * vlen * (640 + 8));
+ my_memcpy(dr_cg, cg, sizeof(uint8_t) * vlen * 640);
+ my_memcpy(dr_pri_line, pri_line, sizeof(uint8_t) * vlen * 8 * 8);
+ }
+ my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+ dr_priority = priority;
+ // initialize draw screen
+ memset(text, 0, sizeof(text));
+ memset(cg, 0, sizeof(cg));
+ memset(pri_line, 0, sizeof(pri_line));
+#ifdef _X1TURBOZ
+ if(vlen > 0) {
+ // Copy images to draw buffers.
+ my_memcpy(&(dr_zcg[0][0][0]), &(zcg[0][0][0]), sizeof(uint8_t) * vlen * 640);
+ //my_memcpy(dr_aen_line, aen_line, sizeof(bool) * vlen);
+ }
+ my_memcpy(dr_aen_line, aen_line, sizeof(aen_line));
+ dr_zpriority = zpriority;
+ my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+ zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+ zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+ zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+ zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+ zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+ zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+ zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+ zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+
+ memset(zcg, 0, sizeof(zcg));
+ memset(aen_line, 0, sizeof(aen_line));
+#endif
+ prev_vert_double = false;
+ raster = 0;
}
void DISPLAY::event_vline(int v, int clock)
{
+ cur_vline = v;
+
+#if 0
+ // Copy images to draw buffers.
+ int vlimit;
#ifdef _X1TURBO_FEATURE
- if(hireso) {
- if(v < 400) {
- draw_line(v);
- }
- } else {
+ vlimit = (hireso) ? 400 : 200;
+#else
+ vlimit = 200;
#endif
- if(v < 200) {
- draw_line(v);
- }
-#ifdef _X1TURBO_FEATURE
+ if((v > vlimit) || (v < 0)) return;
+
+ if(v == vlimit) {
+ my_memcpy(dr_palette_pc, palette_pc, sizeof(palette_pc));
+#ifdef _X1TURBOZ
+ my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+#endif
+ // Copy images to draw buffers.
+ //my_memcpy(&(dr_text[v][0]), &(text[v][0]), sizeof(uint8_t) * (640 + 8));
+ //my_memcpy(&(dr_cg[v][0]), &(cg[v][0]), sizeof(uint8_t) * 640);
+ //my_memcpy(&(dr_pri_line[v][0][0]), &(pri_line[v][0][0]), sizeof(uint8_t) * 8 * 8);
+#ifdef _X1TURBOZ
+ //my_memcpy(&(dr_zcg[0][v][0]), &(zcg[0][v][0]), sizeof(uint8_t) * 640);
+ //my_memcpy(&(dr_zcg[1][v][0]), &(zcg[1][v][0]), sizeof(uint8_t) * 640);
+ //dr_aen_line[v] = aen_line[v];
+#endif
+ } else if(v == 0) {
+ return;
}
- // restart cpu after pcg/cgrom is accessed
- d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
+ // Copy images to draw buffers.
+ my_memcpy(&(dr_text[v - 1][0]), &(text[v - 1][0]), sizeof(uint8_t) * (640 + 8));
+ my_memcpy(&(dr_cg[v - 1][0]), &(cg[v -1 ][0]), sizeof(uint8_t) * 640);
+ my_memcpy(&(dr_pri_line[v - 1][0][0]), &(pri_line[v - 1][0][0]), sizeof(uint8_t) * 8 * 8);
+ dr_priority = priority;
+#ifdef _X1TURBOZ
+ my_memcpy(&(dr_zcg[0][v - 1 ][0]), &(zcg[0][v - 1][0]), sizeof(uint8_t) * 640);
+ my_memcpy(&(dr_zcg[1][v - 1][0]), &(zcg[1][v - 1][0]), sizeof(uint8_t) * 640);
+ dr_zpriority = zpriority;
+ dr_aen_line[v - 1] = aen_line[v - 1];
+#endif
#endif
}
+#ifdef _X1TURBO_FEATURE
+void DISPLAY::event_callback(int event_id, int err)
+{
+ if(event_id == EVENT_AFTER_BLANK) {
+ // restart cpu after pcg/cgrom/zpal is accessed
+ d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
+ }
+}
+#endif
+
void DISPLAY::update_crtc()
{
#ifdef _X1TURBO_FEATURE
{
#ifdef _X1TURBO_FEATURE
if(mode1 & 0x20) {
- // wait next raster
+ // wait next blank
d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
// from X1EMU
{
#ifdef _X1TURBO_FEATURE
if(mode1 & 0x20) {
- // wait next raster
+ // wait next blank
d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
// from X1EMU
}
} else
#endif
- get_cur_code_line();
+ get_cur_code_line();
}
void DISPLAY::get_cur_code_line()
//#ifdef _X1TURBO_FEATURE
// int ht_clock = hireso ? 161 : 250;
//#else
- #define ht_clock 250
+#define ht_clock 250
//#endif
int clock = get_passed_clock(vblank_clock);
int vt_line = vt_disp * ch_height + (int)(clock / ht_clock);
void DISPLAY::draw_line(int v)
{
- if(v == 0) {
- memset(text, 0, sizeof(text));
- memset(cg, 0, sizeof(cg));
-#ifdef _X1TURBOZ
- memset(zcg, 0, sizeof(zcg));
-#endif
- prev_vert_double = false;
- raster = 0;
- }
if((regs[8] & 0x30) != 0x30) {
if((v % ch_height) == 0) {
draw_text(v / ch_height);
#endif
draw_cg(v, 0);
memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
- } else {
- memset(&pri_line[v][0][0], 0, sizeof(pri));
+// } else {
+// memset(&pri_line[v][0][0], 0, sizeof(pri));
}
+#ifdef _X1TURBOZ
+ aen_line[v] = AEN;
+#endif
}
void DISPLAY::draw_screen()
{
// copy to real screen
#ifdef _X1TURBOZ
- zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
- zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
- zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
- zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
- zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
- zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
- zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
- zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
-
- if(AEN) {
- if(hireso) {
- // 400 lines
- if(column40) {
- // 40 columns
- for(int y = 0; y < 400; y++) {
- scrntype_t* dest = emu->get_screen_buffer(y);
- uint8_t* src_text = text[y];
- uint16_t* src_cg0 = zcg[0][y];
+ dr_zpalette_pc[8 + 0] = dr_zpalette_pc[16 + 0x000];
+ dr_zpalette_pc[8 + 1] = dr_zpalette_pc[16 + 0x00f];
+ dr_zpalette_pc[8 + 2] = dr_zpalette_pc[16 + 0x0f0];
+ dr_zpalette_pc[8 + 3] = dr_zpalette_pc[16 + 0x0ff];
+ dr_zpalette_pc[8 + 4] = dr_zpalette_pc[16 + 0xf00];
+ dr_zpalette_pc[8 + 5] = dr_zpalette_pc[16 + 0xf0f];
+ dr_zpalette_pc[8 + 6] = dr_zpalette_pc[16 + 0xff0];
+ dr_zpalette_pc[8 + 7] = dr_zpalette_pc[16 + 0xfff];
+#endif
+#ifdef _X1TURBO_FEATURE
+ if(hireso) {
+ // 400 lines
+ emu->set_vm_screen_lines(400);
+ if(column40) {
+ // 40 columns
+ for(int y = 0; y < 400; y++) {
+ scrntype_t* dest = emu->get_screen_buffer(y);
+ uint8_t* src_text = dr_text[y];
+#ifdef _X1TURBOZ
+ if(dr_aen_line[y]) {
+ uint16_t* src_cg0 = dr_zcg[0][y];
for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
dest[x2] = dest[x2 + 1] = get_zpriority(src_text[x], cg00, cg00);
}
+ } else {
+#endif
+ uint8_t* src_cg = dr_cg[y];
+
+ for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
+#ifdef _X1TURBOZ
+ dest[x2] = dest[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
+#else
+ dest[x2] = dest[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
+#endif
+ }
+#ifdef _X1TURBOZ
}
- } else {
- // 80 columns
- for(int y = 0; y < 400; y++) {
- scrntype_t* dest = emu->get_screen_buffer(y);
- uint8_t* src_text = text[y];
- uint16_t* src_cg0 = zcg[0][y];
+#endif
+ }
+ } else {
+ // 80 columns
+ for(int y = 0; y < 400; y++) {
+ scrntype_t* dest = emu->get_screen_buffer(y);
+ uint8_t* src_text = dr_text[y];
+#ifdef _X1TURBOZ
+ if(dr_aen_line[y]) {
+ uint16_t* src_cg0 = dr_zcg[0][y];
for(int x = 0; x < 640; x++) {
uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
dest[x] = get_zpriority(src_text[x], cg00, cg00);
}
+ } else {
+#endif
+ uint8_t* src_cg = dr_cg[y];
+
+ for(int x = 0; x < 640; x++) {
+#ifdef _X1TURBOZ
+ dest[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
+#else
+ dest[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
+#endif
+ }
+#ifdef _X1TURBOZ
}
+#endif
}
- emu->screen_skip_line(false);
- } else {
- // 200 lines
- if(column40) {
- // 40 columns
- for(int y = 0; y < 200; y++) {
- scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
- scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
- uint8_t* src_text = text[y];
- uint16_t* src_cg0 = zcg[0][y];
- uint16_t* src_cg1 = zcg[1][y];
+ }
+ emu->screen_skip_line(false);
+ } else {
+#endif
+ emu->set_vm_screen_lines(200);
+ // 200 lines
+ emu->set_vm_screen_lines(200);
+
+ if(column40) {
+ // 40 columns
+ for(int y = 0; y < 200; y++) {
+ scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
+ scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
+ uint8_t* src_text = dr_text[y];
+#ifdef _X1TURBOZ
+ if(dr_aen_line[y]) {
+ uint16_t* src_cg0 = dr_zcg[0][y];
+ uint16_t* src_cg1 = dr_zcg[1][y];
if(C64) {
for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
dest0[x2] = dest0[x2 + 1] = get_zpriority(src_text[x], cg01, cg01);
}
}
- if(!config.scan_line) {
- memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
- } else {
- memset(dest1, 0, 640 * sizeof(scrntype_t));
- }
- }
- } else {
- // 80 columns
- for(int y = 0; y < 200; y++) {
- scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
- scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
- uint8_t* src_text = text[y];
- uint16_t* src_cg0 = zcg[0][y];
-
- for(int x = 0; x < 640; x++) {
- uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
-
- dest0[x] = get_zpriority(src_text[x], cg00, cg00);
- }
- if(!config.scan_line) {
- memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
- } else {
- memset(dest1, 0, 640 * sizeof(scrntype_t));
- }
- }
- }
- emu->screen_skip_line(true);
- }
- } else
+ } else {
#endif
-#ifdef _X1TURBO_FEATURE
- if(hireso) {
- // 400 lines
- if(column40) {
- // 40 columns
- for(int y = 0; y < 400; y++) {
- scrntype_t* dest = emu->get_screen_buffer(y);
- uint8_t* src_text = text[y];
- uint8_t* src_cg = cg[y];
+ scrntype_t* dest = emu->get_screen_buffer(y);
+ uint8_t* src_cg = dr_cg[y];
- for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
+ for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
#ifdef _X1TURBOZ
- dest[x2] = dest[x2 + 1] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+ dest0[x2] = dest0[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
#else
- dest[x2] = dest[x2 + 1] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+ dest0[x2] = dest0[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
#endif
- }
- }
- } else {
- // 80 columns
- for(int y = 0; y < 400; y++) {
- scrntype_t* dest = emu->get_screen_buffer(y);
- uint8_t* src_text = text[y];
- uint8_t* src_cg = cg[y];
-
- for(int x = 0; x < 640; x++) {
+ }
#ifdef _X1TURBOZ
- dest[x] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
-#else
- dest[x] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
-#endif
}
- }
- }
- emu->screen_skip_line(false);
- } else
-#endif
- {
- // 200 lines
- if(column40) {
- // 40 columns
- for(int y = 0; y < 200; y++) {
- scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
- scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
- uint8_t* src_text = text[y];
- uint8_t* src_cg = cg[y];
-
- for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
-#ifdef _X1TURBOZ
- dest0[x2] = dest0[x2 + 1] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
-#else
- dest0[x2] = dest0[x2 + 1] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
#endif
- }
if(!config.scan_line) {
- memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
+ my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
} else {
memset(dest1, 0, 640 * sizeof(scrntype_t));
}
for(int y = 0; y < 200; y++) {
scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
- uint8_t* src_text = text[y];
- uint8_t* src_cg = cg[y];
-
- for(int x = 0; x < 640; x++) {
+ uint8_t* src_text = dr_text[y];
#ifdef _X1TURBOZ
- dest0[x] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+ if(aen_line[y]) {
+ uint16_t* src_cg0 = dr_zcg[0][y];
+
+ for(int x = 0; x < 640; x++) {
+ uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
+
+ dest0[x] = get_zpriority(src_text[x], cg00, cg00);
+ }
+ } else {
+#endif
+ uint8_t* src_cg = dr_cg[y];
+
+ for(int x = 0; x < 640; x++) {
+#ifdef _X1TURBOZ
+ dest0[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
#else
- dest0[x] = palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+ dest0[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
#endif
+ }
+#ifdef _X1TURBOZ
}
+#endif
if(!config.scan_line) {
- memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
+ my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
} else {
memset(dest1, 0, 640 * sizeof(scrntype_t));
}
}
}
emu->screen_skip_line(true);
+#ifdef _X1TURBO_FEATURE
}
+#endif
+
}
void DISPLAY::draw_text(int y)
int shift = 0;
int max_line = 8;
#else
- #define max_line 8
+#define max_line 8
#endif
if(attr & 0x20) {
// pcg
break;
}
uint8_t* d = &text[yy][x << 3];
-
+
if(attr & 0x80) {
// horizontal doubled char
d[ 0] = d[ 1] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
d[6] = ((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1);
d[7] = ((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2);
}
+ prev_attr = attr;
}
- prev_attr = attr;
}
if(cur_vert_double && !prev_vert_double) {
prev_vert_double = true;
#ifdef _X1TURBOZ
if(AEN) {
/*
- HIRESO=0, WIDTH=40, C64=0: 320x200, 4096 PAGE0:(ADDR 000h-3FFh) + PAGE0:(ADDR 400h-7FFh) + PAGE1:(ADDR 000h-3FFh) + PAGE1:(ADDR 400h-7FFh)
- HIRESO=0, WIDTH=40, C64=1: 320x200, 64x2 PAGE0:(ADDR 000h-3FFh) + PAGE0:(ADDR 400h-7FFh) / PAGE1:(ADDR 000h-3FFh) + PAGE1:(ADDR 400h-7FFh)
- HIRESO=1, WIDTH=40, C64=*: 320x200, 64 PAGE*:(ADDR 000h-3FFh) + PAGE*:(ADDR 400h-7FFh)
- HIRESO=0, WIDTH=80, C64=*: 640x200, 64 PAGE0:(ADDR 000h-7FFh) + PAGE1:(ADDR 000h-7FFh)
- HIRESO=1, WIDTH=80, C64=*: 640x200, 8 PAGE0:(ADDR 000h-7FFh) + PAGE0:(ADDR 000h-7FFh)
+ HIRESO=0, WIDTH=40, C64=0: 320x200, 4096 PAGE0:(ADDR 000h-3FFh) + PAGE0:(ADDR 400h-7FFh) + PAGE1:(ADDR 000h-3FFh) + PAGE1:(ADDR 400h-7FFh)
+ HIRESO=0, WIDTH=40, C64=1: 320x200, 64x2 PAGE0:(ADDR 000h-3FFh) + PAGE0:(ADDR 400h-7FFh) / PAGE1:(ADDR 000h-3FFh) + PAGE1:(ADDR 400h-7FFh)
+ HIRESO=1, WIDTH=40, C64=*: 320x200, 64 PAGE*:(ADDR 000h-3FFh) + PAGE*:(ADDR 400h-7FFh)
+ HIRESO=0, WIDTH=80, C64=*: 640x200, 64 PAGE0:(ADDR 000h-7FFh) + PAGE1:(ADDR 000h-7FFh)
+ HIRESO=1, WIDTH=80, C64=*: 640x200, 8 PAGE0:(ADDR 000h-7FFh) + PAGE0:(ADDR 000h-7FFh)
- HIRESO=0, WIDTH=40, C64=1: 320x200, 64x2
- mode1 zpriority
- SCREEN 0 00 00 PAGE0
- SCREEM 2 18 08 PAGE1
- SCREEN 4 00 10 PAGE0 > PAGE1
- SCREEN 6 18 18 PAGE0 < PAGE1
+ HIRESO=0, WIDTH=40, C64=1: 320x200, 64x2
+ mode1 zpriority
+ SCREEN 0 00 00 PAGE0
+ SCREEM 2 18 08 PAGE1
+ SCREEN 4 00 10 PAGE0 > PAGE1
+ SCREEN 6 18 18 PAGE0 < PAGE1
*/
if(!hireso) {
if(column40) {
if(C64 && !(zpriority & 0x10)) {
if(plane) {
- memcpy(zcg[plane][1], zcg[plane][0], sizeof(uint16_t) * 640);
+ my_memcpy(zcg[plane][1], zcg[plane][0], sizeof(uint16_t) * 640);
return;
}
} else {
{
if((mode2 & 8) && (text == (mode2 & 7))) {
int digital = ((cg0 >> 9) & 4) | ((cg0 >> 6) & 2) | ((cg0 >> 3) & 1);
- if(!(priority & (1 << digital))) {
+ if(!(dr_priority & (1 << digital))) {
return 0;
}
}
- uint16_t fore = ((zpriority & 0x18) != 0x18) ? cg0 : cg1;
- uint16_t back = ((zpriority & 0x18) != 0x18) ? cg1 : cg0;
+ uint16_t fore = ((dr_zpriority & 0x18) != 0x18) ? cg0 : cg1;
+ uint16_t back = ((dr_zpriority & 0x18) != 0x18) ? cg1 : cg0;
uint16_t disp;
- switch(zpriority & 0x13) {
+ switch(dr_zpriority & 0x13) {
case 0x00:
case 0x02:
disp = text ? text : (fore + 16);
// if((mode2 & 0x20) && disp == (0x00f + 16)) {
// return 0;
// }
- return zpalette_pc[disp];
+ return dr_zpalette_pc[disp];
}
#endif
return (c1 << 8) | c2;
}
-#define STATE_VERSION 3
+#define STATE_VERSION 4
-void DISPLAY::save_state(FILEIO* state_fio)
+bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
{
- state_fio->FputUint32(STATE_VERSION);
- state_fio->FputInt32(this_device_id);
-
- state_fio->Fwrite(vram_t, sizeof(vram_t), 1);
- state_fio->Fwrite(vram_a, sizeof(vram_a), 1);
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+ return false;
+ }
+ if(!state_fio->StateCheckInt32(this_device_id)) {
+ return false;
+ }
+ state_fio->StateBuffer(vram_t, sizeof(vram_t), 1);
+ state_fio->StateBuffer(vram_a, sizeof(vram_a), 1);
#ifdef _X1TURBO_FEATURE
- state_fio->Fwrite(vram_k, sizeof(vram_k), 1);
+ state_fio->StateBuffer(vram_k, sizeof(vram_k), 1);
#endif
- state_fio->Fwrite(pcg_b, sizeof(pcg_b), 1);
- state_fio->Fwrite(pcg_r, sizeof(pcg_r), 1);
- state_fio->Fwrite(pcg_g, sizeof(pcg_g), 1);
+ state_fio->StateBuffer(pcg_b, sizeof(pcg_b), 1);
+ state_fio->StateBuffer(pcg_r, sizeof(pcg_r), 1);
+ state_fio->StateBuffer(pcg_g, sizeof(pcg_g), 1);
#ifdef _X1TURBO_FEATURE
- state_fio->Fwrite(gaiji_b, sizeof(gaiji_b), 1);
- state_fio->Fwrite(gaiji_r, sizeof(gaiji_r), 1);
- state_fio->Fwrite(gaiji_g, sizeof(gaiji_g), 1);
-#endif
- state_fio->FputUint8(cur_code);
- state_fio->FputUint8(cur_line);
- state_fio->FputInt32(kaddr);
- state_fio->FputInt32(kofs);
- state_fio->FputInt32(kflag);
- state_fio->FputInt32((int)(kanji_ptr - &kanji[0]));
- state_fio->Fwrite(pal, sizeof(pal), 1);
- state_fio->FputUint8(priority);
- state_fio->Fwrite(pri, sizeof(pri), 1);
- state_fio->FputBool(column40);
+ state_fio->StateBuffer(gaiji_b, sizeof(gaiji_b), 1);
+ state_fio->StateBuffer(gaiji_r, sizeof(gaiji_r), 1);
+ state_fio->StateBuffer(gaiji_g, sizeof(gaiji_g), 1);
+#endif
+ state_fio->StateUint8(cur_code);
+ state_fio->StateUint8(cur_line);
+ state_fio->StateInt32(kaddr);
+ state_fio->StateInt32(kofs);
+ state_fio->StateInt32(kflag);
+ if(loading) {
+ kanji_ptr = &kanji[0] + state_fio->FgetInt32_LE();
+ } else {
+ state_fio->FputInt32_LE((int)(kanji_ptr - &kanji[0]));
+ }
+ state_fio->StateBuffer(pal, sizeof(pal), 1);
+ state_fio->StateUint8(priority);
+ state_fio->StateBuffer(pri, sizeof(pri), 1);
+ state_fio->StateBool(column40);
#ifdef _X1TURBO_FEATURE
- state_fio->FputUint8(mode1);
- state_fio->FputUint8(mode2);
- state_fio->FputBool(hireso);
+ state_fio->StateUint8(mode1);
+ state_fio->StateUint8(mode2);
+ state_fio->StateBool(hireso);
#endif
#ifdef _X1TURBOZ
- state_fio->FputUint8(zmode1);
- state_fio->FputUint8(zpriority);
- state_fio->FputUint8(zadjust);
- state_fio->FputUint8(zmosaic);
- state_fio->FputUint8(zchromakey);
- state_fio->FputUint8(zscroll);
- state_fio->FputUint8(zmode2);
- state_fio->Fwrite(ztpal, sizeof(ztpal), 1);
- state_fio->Fwrite(zpal, sizeof(zpal), 1);
- state_fio->FputInt32(zpal_num);
- state_fio->Fwrite(zpalette_pc, sizeof(zpalette_pc), 1);
-#endif
- state_fio->FputBool(prev_vert_double);
- state_fio->FputInt32(raster);
- state_fio->FputInt32(cblink);
- state_fio->FputInt32(ch_height);
- state_fio->FputInt32(hz_total);
- state_fio->FputInt32(hz_disp);
- state_fio->FputInt32(vt_disp);
- state_fio->FputInt32(st_addr);
- state_fio->FputUint32(vblank_clock);
-}
-
-bool DISPLAY::load_state(FILEIO* state_fio)
-{
- if(state_fio->FgetUint32() != STATE_VERSION) {
- return false;
- }
- if(state_fio->FgetInt32() != this_device_id) {
- return false;
+ state_fio->StateUint8(zmode1);
+ state_fio->StateUint8(zpriority);
+ state_fio->StateUint8(zadjust);
+ state_fio->StateUint8(zmosaic);
+ state_fio->StateUint8(zchromakey);
+ state_fio->StateUint8(zscroll);
+ state_fio->StateUint8(zmode2);
+ state_fio->StateBuffer(ztpal, sizeof(ztpal), 1);
+ //state_fio->StateBuffer(zpal, sizeof(zpal), 1);
+ for(int i = 0; i < 4096; i++) {
+ state_fio->StateUint8(zpal[i].b);
+ state_fio->StateUint8(zpal[i].r);
+ state_fio->StateUint8(zpal[i].g);
+ }
+ state_fio->StateInt32(zpal_num);
+ //state_fio->StateBuffer(zpalette_pc, sizeof(zpalette_pc), 1);
+ if(loading) {
+ for(int i = 0; i < (sizeof(zpalette_pc) / sizeof(scrntype_t)); i++) {
+ uint8_t r, g, b;
+ r = state_fio->FgetUint8();
+ g = state_fio->FgetUint8();
+ b = state_fio->FgetUint8();
+ zpalette_pc[i] = RGB_COLOR(r, g, b);
+ }
+ } else {
+ for(int i = 0; i < (sizeof(zpalette_pc) / sizeof(scrntype_t)); i++) {
+ uint8_t r, g, b;
+ r = R_OF_COLOR(zpalette_pc[i]);
+ g = G_OF_COLOR(zpalette_pc[i]);
+ b = B_OF_COLOR(zpalette_pc[i]);
+ state_fio->FputUint8(r);
+ state_fio->FputUint8(g);
+ state_fio->FputUint8(b);
+ }
}
- state_fio->Fread(vram_t, sizeof(vram_t), 1);
- state_fio->Fread(vram_a, sizeof(vram_a), 1);
-#ifdef _X1TURBO_FEATURE
- state_fio->Fread(vram_k, sizeof(vram_k), 1);
+
#endif
- state_fio->Fread(pcg_b, sizeof(pcg_b), 1);
- state_fio->Fread(pcg_r, sizeof(pcg_r), 1);
- state_fio->Fread(pcg_g, sizeof(pcg_g), 1);
-#ifdef _X1TURBO_FEATURE
- state_fio->Fread(gaiji_b, sizeof(gaiji_b), 1);
- state_fio->Fread(gaiji_r, sizeof(gaiji_r), 1);
- state_fio->Fread(gaiji_g, sizeof(gaiji_g), 1);
-#endif
- cur_code = state_fio->FgetUint8();
- cur_line = state_fio->FgetUint8();
- kaddr = state_fio->FgetInt32();
- kofs = state_fio->FgetInt32();
- kflag = state_fio->FgetInt32();
- kanji_ptr = &kanji[0] + state_fio->FgetInt32();
- state_fio->Fread(pal, sizeof(pal), 1);
- priority = state_fio->FgetUint8();
- state_fio->Fread(pri, sizeof(pri), 1);
- column40 = state_fio->FgetBool();
+ state_fio->StateBool(prev_vert_double);
+ state_fio->StateInt32(raster);
+ state_fio->StateInt32(cblink);
+ state_fio->StateInt32(ch_height);
+ state_fio->StateInt32(hz_total);
+ state_fio->StateInt32(hz_disp);
+ state_fio->StateInt32(vt_disp);
+ state_fio->StateInt32(st_addr);
+ state_fio->StateUint32(vblank_clock);
+ state_fio->StateBool(cur_blank);
+
+ // post process
+ if(loading) {
+ for(int i = 0; i < 8; i++) {
+ palette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
+ palette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // cg
+ }
+ // Copy images to draw buffers.
+ my_memcpy(dr_text, text, sizeof(dr_text));
+ my_memcpy(dr_cg, cg, sizeof(dr_cg));
#ifdef _X1TURBO_FEATURE
- mode1 = state_fio->FgetUint8();
- mode2 = state_fio->FgetUint8();
- hireso = state_fio->FgetBool();
+ for(int v = 0; v < 400; v++) {
+ memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
+ }
+#else
+ for(int v = 0; v < 200; v++) {
+ memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
+ }
#endif
+ my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
+ my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+ dr_priority = priority;
#ifdef _X1TURBOZ
- zmode1 = state_fio->FgetUint8();
- zpriority = state_fio->FgetUint8();
- zadjust = state_fio->FgetUint8();
- zmosaic = state_fio->FgetUint8();
- zchromakey = state_fio->FgetUint8();
- zscroll = state_fio->FgetUint8();
- zmode2 = state_fio->FgetUint8();
- state_fio->Fread(ztpal, sizeof(ztpal), 1);
- state_fio->Fread(zpal, sizeof(zpal), 1);
- zpal_num = state_fio->FgetInt32();
- state_fio->Fread(zpalette_pc, sizeof(zpalette_pc), 1);
-#endif
- prev_vert_double = state_fio->FgetBool();
- raster = state_fio->FgetInt32();
- cblink = state_fio->FgetInt32();
- ch_height = state_fio->FgetInt32();
- hz_total = state_fio->FgetInt32();
- hz_disp = state_fio->FgetInt32();
- vt_disp = state_fio->FgetInt32();
- st_addr = state_fio->FgetInt32();
- vblank_clock = state_fio->FgetUint32();
- return true;
+ dr_zpriority = zpriority;
+ my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
+ my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
+ my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+ zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+ zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+ zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+ zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+ zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+ zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+ zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+ zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+#endif
+ update_crtc(); // force update timing
+ }
+ return true;
}
+}