#include "../ym2203.h"
#include "../z80.h"
+#ifdef SUPPORT_PC88_CDROM
+#include "../scsi_cdrom.h"
+#include "../scsi_host.h"
+#endif
+
#define DEVICE_JOYSTICK 0
#define DEVICE_MOUSE 1
#define DEVICE_JOYMOUSE 2 // not supported yet
#define EVENT_CMT_SEND 2
#define EVENT_CMT_DCD 3
#define EVENT_BEEP 4
-#define EVENT_CMT_SOUND 5
+#ifdef SUPPORT_PC88_CDROM
+#define EVENT_FADE_IN 5
+#define EVENT_FADE_OUT 6
+#endif
#define IRQ_USART 0
#define IRQ_VRTC 1
#define IRQ_TIMER 2
#define IRQ_SOUND 4
+namespace PC88DEV
+{
+
#define Port30_40 !(port[0x30] & 0x01)
#define Port30_COLOR !(port[0x30] & 0x02)
#define Port30_MTON (port[0x30] & 0x08)
#define Port31_V1_320x200 (port[0x31] & 0x10) // PC-8001 (V1)
#define Port31_V1_MONO (port[0x31] & 0x04) // PC-8001 (V1)
-#define Port31_COLOR (port[0x31] & 0x10) // PC-8001
#define Port31_320x200 (port[0x31] & 0x04) // PC-8001
#define Port32_EROMSL (port[0x32] & 0x03)
#define Port32_TMODE (port[0x32] & 0x10)
+#if !defined(_PC8001SR)
#define Port32_PMODE (port[0x32] & 0x20)
+#else
+#define Port32_PMODE false
+#endif
#define Port32_GVAM (port[0x32] & 0x40)
#define Port32_SINTM (port[0x32] & 0x80)
#define Port71_EROM port[0x71]
+#ifdef SUPPORT_PC88_CDROM
+#define Port99_CDREN (port[0x99] & 0x10)
+#endif
+
// XM8 version 1.20
#define PortA8_OPNCH port[0xa8]
#define PortAA_S2INTM (port[0xaa] & 0x80)
#define PortF0_DICROMSL (port[0xf0] & 0x1f)
#define PortF1_DICROM !(port[0xf1] & 0x01)
+#if defined(SUPPORT_PC88_VAB)
+// X88000
+#define PortB4_VAB_DISP ((port[0xb4] & 0x41) == 0x41)
+#define PortE3_VAB_SEL (((port[0xe3] >> 2) & 3) == PC88_VAB_PAGE)
+#endif
+
#define SET_BANK(s, e, w, r) { \
int sb = (s) >> 12, eb = (e) >> 12; \
for(int i = sb; i <= eb; i++) { \
{ 0x58, 0x59, 0x5a, 0xdb, 0xdc, 0xdd, 0xde, 0xbd },
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },
{ 0x38, 0x39, 0xba, 0xbb, 0xbc, 0xbe, 0xbf, 0xe2 },
- { 0x24, 0x26, 0x27, 0x2e, 0x12, 0x15, 0x10, 0x11 },
+// { 0x24, 0x26, 0x27, 0x2e, 0x12, 0x15, 0x10, 0x11 },
+ { 0x24, 0x26, 0x27, 0x08, 0x12, 0x15, 0x10, 0x11 },
{ 0x13, 0x70, 0x71, 0x72, 0x73, 0x74, 0x20, 0x1b },
{ 0x09, 0x28, 0x25, 0x23, 0x7b, 0x6d, 0x6f, 0x14 },
{ 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x75, 0x76, 0x77, 0x78, 0x79, 0x08, 0x2d, 0x2e },
- { 0x1c, 0x1d, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00 },
+ { 0x1c, 0x1d, 0x7a, 0x19, 0x00, 0x00, 0x00, 0x00 },
{ 0x0d, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00 }
};
-static const int key_conv_table[9][3] = {
+static const int key_conv_table[][3] = {
{0x2d, 0x2e, 1}, // INS -> SHIFT + DEL
{0x75, 0x70, 1}, // F6 -> SHIFT + F1
{0x76, 0x71, 1}, // F7 -> SHIFT + F2
{0x77, 0x72, 1}, // F8 -> SHIFT + F3
{0x78, 0x73, 1}, // F9 -> SHIFT + F4
{0x79, 0x74, 1}, // F10 -> SHIFT + F5
- {0x08, 0x2e, 0}, // BS -> DEL
+// {0x08, 0x2e, 0}, // BS -> DEL
+ {0x2e, 0x08, 0}, // DEL -> BS
{0x1c, 0x20, 0}, // \95Ï\8a·-> SPACE
{0x1d, 0x20, 0}, // \8c\88\92è-> SPACE
};
-static const uint8 intr_mask2_table[8] = {
- ~7, ~3, ~5, ~1, ~6, ~2, ~4, ~0
+static const uint8_t intr_mask2_table[8] = {
+ (uint8_t)~7, (uint8_t)~3, (uint8_t)~5, (uint8_t)~1, (uint8_t)~6, (uint8_t)~2, (uint8_t)~4, (uint8_t)~0
};
void PC88::initialize()
#ifdef SUPPORT_PC88_DICTIONARY
memset(dicrom, 0xff, sizeof(dicrom));
#endif
+#ifdef SUPPORT_PC88_CDROM
+ memset(cdbios, 0xff, sizeof(cdbios));
+ cdbios_loaded = false;
+#endif
// load rom images
FILEIO* fio = new FILEIO();
fio->Fclose();
}
#endif
+#ifdef SUPPORT_PC88_CDROM
+ if(config.boot_mode == MODE_PC88_V2) {
+ if(fio->Fopen(create_local_path(_T("CDBIOS.ROM")), FILEIO_READ_BINARY)) {
+ fio->Fread(cdbios, 0x10000, 1);
+ fio->Fclose();
+ cdbios_loaded = true;
+ }
+ }
+#endif
delete fio;
// memory pattern
for(int i = 0, ofs = 0; i < 256; i++) {
for(int j = 0; j < 16; j++) {
- static const uint8 p0[256] = {
+ static const uint8_t p0[256] = {
0,1,0,1,0,1,0,0,0,0,0,0,1,0,1,0, // 0000
0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0, // 1000
0,1,0,1,0,0,0,0,0,0,1,0,1,0,1,0, // 2000
0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0, // e000
0,1,0,1,0,0,0,0,0,0,1,0,1,0,1,0, // f000
};
- static const uint8 p1[16] = {
+ static const uint8_t p1[16] = {
0x00,0xff,0x00,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0x00,
};
memset(ram + ofs, (p0[i] == 0) ? p1[j] : ~p1[j], 16);
// create semi graphics pattern
for(int i = 0; i < 256; i++) {
- uint8 *dest = sg_pattern + 8 * i;
+ uint8_t *dest = sg_pattern + 8 * i;
dest[0] = dest[1] = ((i & 1) ? 0xf0 : 0) | ((i & 0x10) ? 0x0f : 0);
dest[2] = dest[3] = ((i & 2) ? 0xf0 : 0) | ((i & 0x20) ? 0x0f : 0);
dest[4] = dest[5] = ((i & 4) ? 0xf0 : 0) | ((i & 0x40) ? 0x0f : 0);
dest[6] = dest[7] = ((i & 8) ? 0xf0 : 0) | ((i & 0x80) ? 0x0f : 0);
}
- // initialize text palette
- for(int i = 0; i < 9; i++) {
- palette_text_pc[i] = RGBA_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0, 255); // A is a flag for crt filter
+#ifdef SUPPORT_PC88_VAB
+ // X88000
+ for(uint32_t g = 0; g < 64; g++) {
+ uint32_t gg = (255 * g) / 63;
+ for(uint32_t r = 0; r < 32; r++) {
+ uint32_t rr = (255 * r) / 31;
+ for(uint32_t b = 0; b < 32; b++) {
+ uint32_t bb = (255 * b) / 31;
+ palette_vab_pc[b | (r << 5) | (g << 10)] = RGB_COLOR(rr, gg, bb);
+ }
+ }
}
+#endif
#ifdef SUPPORT_PC88_HIGH_CLOCK
cpu_clock_low = (config.cpu_type == 1); // 4MHz
#endif
#ifdef SUPPORT_PC88_JOYSTICK
- joystick_status = emu->joy_buffer();
- mouse_status = emu->mouse_buffer();
+ joystick_status = emu->get_joy_buffer();
+ mouse_status = emu->get_mouse_buffer();
mouse_strobe_clock_lim = (int)((cpu_clock_low ? 720 : 1440) * 1.25);
#endif
// initialize cmt
cmt_fio = new FILEIO();
cmt_play = cmt_rec = false;
-#ifdef DATAREC_SOUND
- cmt_mix = config.tape_sound;
-#ifdef USE_MULTIPLE_SOUNDCARDS
- cmt_volume = (config.sound_device_level[0] + 0x8000) >> 2;
- if(cmt_volume <= 0) cmt_volume = 0;
- if(cmt_volume >= 0x4000) cmt_volume = 0;
-#else
- cmt_volume = 0x1000;
-#endif
- cmt_level_flag = false;
- cmt_sound_flag = false;
- cmt_sound_count = 0;
- cmt_sound_data = 0;
-#endif
+
register_frame_event(this);
register_vline_event(this);
register_event(this, EVENT_TIMER, 1000000.0 / 600.0, true, NULL);
register_event(this, EVENT_BEEP, 1000000.0 / 4800.0, true, NULL);
+
+#if !defined(_PC8001SR)
+ // hack to update config.scan_line at first
+ hireso = !(config.monitor_type == 0);
+#endif
+#ifdef SUPPORT_PC88_CDROM
+ cdda_register_id = -1;
+#endif
}
void PC88::release()
#if defined(_PC8001SR)
hireso = false;
#else
- hireso = (config.monitor_type == 0);
+ bool value = (config.monitor_type == 0);
+ if(hireso != value) {
+ // update config.scan_line when config.monitor_type is changed
+ //hireso = config.scan_line = value;
+ hireso = value; // Revert 20181217 K.O
+ }
#endif
// memory
}
// port[0x70] = 0x80; // XM8 version 1.10
port[0x71] = port[0xf1] = 0xff;
-
+#if defined(SUPPORT_PC88_CDROM)
+ if (cdbios_loaded) {
+ port[0x99] = 0x10;
+ }
+#endif
memset(alu_reg, 0, sizeof(alu_reg));
gvram_plane = gvram_sel = 0;
}
SET_BANK(0x8000, 0xffff, ram + 0x8000, ram + 0x8000);
#else
- SET_BANK(0x0000, 0x7fff, ram, n88rom);
+// SET_BANK(0x0000, 0x7fff, ram, n88rom);
SET_BANK(0x8000, 0xefff, ram + 0x8000, ram + 0x8000);
+ update_low_memmap();
update_tvram_memmap(); // XM8 version 1.10
#endif
crtc.reset(hireso);
update_timing();
- for(int i = 0; i < 9; i++) {
+ memset(palette, 0, sizeof(palette));
+ for(int i = 1; i < 8; i++) {
palette[i].b = (i & 1) ? 7 : 0;
palette[i].r = (i & 2) ? 7 : 0;
palette[i].g = (i & 4) ? 7 : 0;
// dma
memset(&dmac, 0, sizeof(dmac));
- dmac.mem = dmac.ch[2].io = this;
- dmac.ch[0].io = dmac.ch[1].io = dmac.ch[3].io = vm->dummy;
+ dmac.ch[0].io = dmac.ch[3].io = vm->dummy;
+#ifdef SUPPORT_PC88_CDROM
+ if(cdbios_loaded) {
+ dmac.ch[1].io = d_scsi_host;
+ } else
+#endif
+ dmac.ch[1].io = vm->dummy;;
+ dmac.ch[2].io = dmac.mem = this;
dmac.ch[0].addr.b.l = 0x56; // XM8 version 1.10
dmac.ch[0].addr.b.h = 0x56;
dmac.ch[1].addr.b.l = 0x7a;
// mouse
#ifdef SUPPORT_PC88_JOYSTICK
- mouse_strobe_clock = current_clock();
+ mouse_strobe_clock = get_current_clock();
mouse_phase = -1;
mouse_dx = mouse_dy = mouse_lx = mouse_ly = 0;
#endif
write_io8(2, 0);
write_io8(3, 0);
#endif
+#ifdef SUPPORT_PC88_CDROM
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ cdda_register_id = -1;
+ }
+ cdda_volume = 100.0;
+ d_scsi_cdrom->set_volume((int)cdda_volume);
+#endif
#ifdef NIPPY_PATCH
// dirty patch for NIPPY
nippy_patch = false;
#endif
}
-void PC88::write_data8w(uint32 addr, uint32 data, int* wait)
+void PC88::write_data8w(uint32_t addr, uint32_t data, int* wait)
{
addr &= 0xffff;
*wait = mem_wait_clocks_w;
wbank[addr >> 12][addr & 0xfff] = data;
}
-uint32 PC88::read_data8w(uint32 addr, int* wait)
+uint32_t PC88::read_data8w(uint32_t addr, int* wait)
{
addr &= 0xffff;
*wait = mem_wait_clocks_r;
#else
if((addr & 0xc000) == 0x8000) {
#endif
- uint8 b, r, g;
+ uint8_t b, r, g;
switch(gvram_sel) {
case 1:
*wait = gvram_wait_clocks_r;
return rbank[addr >> 12][addr & 0xfff];
}
-uint32 PC88::fetch_op(uint32 addr, int *wait)
+uint32_t PC88::fetch_op(uint32_t addr, int *wait)
{
- uint32 data = read_data8w(addr, wait);
+ uint32_t data = read_data8w(addr, wait);
if((addr & 0xf000) == 0xf000) {
*wait += f000_m1_wait_clocks;
} else {
return data;
}
-void PC88::write_io8(uint32 addr, uint32 data)
+void PC88::write_io8(uint32_t addr, uint32_t data)
{
addr &= 0xff;
#ifdef _IO_DEBUG_LOG
- emu->out_debug_log(_T("%6x\tOUT8\t%02x,%02x\n"), d_cpu->get_pc(), addr, data);
+ this->out_debug_log(_T("%06x\tOUT8\t%02x,%02x\n"), d_cpu->get_pc(), addr, data);
#endif
#ifdef NIPPY_PATCH
// dirty patch for NIPPY
}
// poke &haa4e, &h39
#endif
- uint8 mod = port[addr] ^ data;
+ uint8_t mod = port[addr] ^ data;
port[addr] = data;
switch(addr) {
#endif
break;
case 0x10:
- emu->printer_out(data);
+ d_prn->write_signal(SIG_PRINTER_DATA, data, 0xff);
d_rtc->write_signal(SIG_UPD1990A_C0, data, 1);
d_rtc->write_signal(SIG_UPD1990A_C1, data, 2);
d_rtc->write_signal(SIG_UPD1990A_C2, data, 4);
}
if(mod & 0x08) {
update_gvram_wait();
+ update_palette = true;
}
if(mod & 0x11) {
update_timing();
break;
case 0x32:
if(mod & 0x03) {
- if(Port71_EROM == 0xfe) {
+ if(!(Port71_EROM & 1)) {
update_low_memmap();
}
}
}
break;
case 0x40:
- emu->printer_strobe((data & 1) == 0);
+ d_prn->write_signal(SIG_PRINTER_STROBE, data, 1);
d_rtc->write_signal(SIG_UPD1990A_STB, ~data, 2);
d_rtc->write_signal(SIG_UPD1990A_CLK, data, 4);
// bit3: crtc i/f sync mode
beep_on = ((data & 0x20) != 0);
#ifdef SUPPORT_PC88_JOYSTICK
if(mod & 0x40) {
- if(Port40_JOP1 && (mouse_phase == -1 || passed_clock(mouse_strobe_clock) > mouse_strobe_clock_lim)) {
+ if(Port40_JOP1 && (mouse_phase == -1 || get_passed_clock(mouse_strobe_clock) > mouse_strobe_clock_lim)) {
mouse_phase = 0;//mouse_dx = mouse_dy = 0;
} else {
mouse_phase = (mouse_phase + 1) & 3;
mouse_ly = -((mouse_dy > 127) ? 127 : (mouse_dy < -127) ? -127 : mouse_dy);
mouse_dx = mouse_dy = 0;
}
- mouse_strobe_clock = current_clock();
+ mouse_strobe_clock = get_current_clock();
}
#endif
sing_signal = ((data & 0x80) != 0);
case 0x5b:
#if !defined(_PC8001SR)
if(Port32_PMODE) {
- int n = (data & 0x80) ? 8 : (addr - 0x54);
+ int n = (data & 0x80) ? 9 : (addr - 0x54);
if(data & 0x40) {
palette[n].g = data & 7;
} else {
break;
#else
case 0x71:
- if(mod) {
+ if(mod & 0x01) {
update_low_memmap();
}
break;
case 0x78:
Port70_TEXTWND++;
break;
+#ifdef SUPPORT_PC88_HMB20
+ case 0x88:
+ case 0x89:
+ d_opm->write_io8(addr, data);
+ break;
+#endif
+#ifdef SUPPORT_PC88_CDROM
+ // M88 cdif
+ case 0x90:
+ if(cdbios_loaded && (mod & 0x01)) {
+ if(data & 0x01) {
+ if(port[0x9f] & 0x01) {
+ d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1);
+ d_scsi_host->write_signal(SIG_SCSI_SEL, 1, 1);
+ d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1);
+ }
+ } else {
+ d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1);
+ }
+// d_scsi_host->write_signal(SIG_SCSI_SEL, data, 1);
+ }
+ break;
+ case 0x91:
+ if(cdbios_loaded) {
+ d_scsi_host->write_dma_io8(0, data);
+ }
+ break;
+ case 0x94:
+ if(cdbios_loaded) {
+ d_scsi_host->write_signal(SIG_SCSI_RST, data, 0x80);
+ }
+ break;
+ case 0x98:
+ if(cdbios_loaded) {
+ switch(data & 7) {
+ case 0:
+ case 1:
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ }
+ d_scsi_cdrom->set_volume((int)(cdda_volume = 100.0));
+ break;
+ case 2:
+ case 3:
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ }
+ d_scsi_cdrom->set_volume((int)(cdda_volume = 0.0));
+ break;
+ case 4:
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ }
+ register_event(this, EVENT_FADE_IN, 100, true, &cdda_register_id); // 100ms
+ d_scsi_cdrom->set_volume((int)(cdda_volume = 0.0));
+ break;
+ case 5:
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ }
+ register_event(this, EVENT_FADE_IN, 1500, true, &cdda_register_id); // 1500ms
+ d_scsi_cdrom->set_volume((int)(cdda_volume = 0.0));
+ break;
+ case 6:
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ }
+ register_event(this, EVENT_FADE_OUT, 100, true, &cdda_register_id); // 100ms
+ d_scsi_cdrom->set_volume((int)(cdda_volume = 100.0));
+ break;
+ case 7:
+ if(cdda_register_id != -1) {
+ cancel_event(this, cdda_register_id);
+ }
+ register_event(this, EVENT_FADE_OUT, 5000, true, &cdda_register_id); // 5000ms
+ d_scsi_cdrom->set_volume((int)(cdda_volume = 100.0));
+ break;
+ }
+ }
+ break;
+ case 0x99:
+ if(cdbios_loaded && (mod & 0x10)) {
+ update_low_memmap();
+ }
+ break;
+#endif
#ifdef SUPPORT_PC88_SB2
case 0xa8:
case 0xa9:
}
break;
case 0xe3:
+#ifdef PC88_IODATA_EXRAM
if(mod) {
- update_low_memmap();
+#else
+ if(mod & 0x0f) {
+#endif
+ if(PortE2_RDEN || PortE2_WREN) {
+ update_low_memmap();
+ }
}
break;
#endif
}
}
-uint32 PC88::read_io8(uint32 addr)
+uint32_t PC88::read_io8(uint32_t addr)
#ifdef _IO_DEBUG_LOG
{
- uint32 val = read_io8_debug(addr);
- emu->out_debug_log(_T("%06x\tIN8\t%02x = %02x\n"), d_cpu->get_pc(), addr & 0xff, val);
+ uint32_t val = read_io8_debug(addr);
+ this->out_debug_log(_T("%06x\tIN8\t%02x = %02x\n"), d_cpu->get_pc(), addr & 0xff, val);
return val;
}
-uint32 PC88::read_io8_debug(uint32 addr)
+uint32_t PC88::read_io8_debug(uint32_t addr)
#endif
{
- uint32 val = 0xff;
+ uint32_t val = 0xff;
addr &= 0xff;
switch(addr) {
#endif
case 0x40:
// XM8 version 1.10
- return (crtc.vblank ? 0x20 : 0) | (d_rtc->read_signal(0) ? 0x10 : 0) | (usart_dcd ? 4 : 0) | (hireso ? 0 : 2) | 0xc1;
-// return (crtc.vblank ? 0x20 : 0) | (d_rtc->read_signal(0) ? 0x10 : 0) | (usart_dcd ? 4 : 0) | (hireso ? 0 : 2) | 0xc0;
+// return (crtc.vblank ? 0x20 : 0) | (d_rtc->read_signal(0) ? 0x10 : 0) | (usart_dcd ? 4 : 0) | (hireso ? 0 : 2) | 0xc1;
+ return (crtc.vblank ? 0x20 : 0) | (d_rtc->read_signal(0) ? 0x10 : 0) | (usart_dcd ? 4 : 0) | (hireso ? 0 : 2) | (d_prn->read_signal(SIG_PRINTER_BUSY) ? 1 : 0) | 0xc0;
case 0x44:
val = d_opn->read_io8(addr);
if(opn_busy) {
case 0x45:
if(Port44_OPNCH == 14) {
#ifdef SUPPORT_PC88_JOYSTICK
- if(config.device_type == DEVICE_JOYSTICK) {
+ if(config.joystick_type == DEVICE_JOYSTICK) {
return (~(joystick_status[0] >> 0) & 0x0f) | 0xf0;
- } else if(config.device_type == DEVICE_MOUSE) {
+ } else if(config.joystick_type == DEVICE_MOUSE) {
switch(mouse_phase) {
case 0:
return ((mouse_lx >> 4) & 0x0f) | 0xf0;
return 0xff;
} else if(Port44_OPNCH == 15) {
#ifdef SUPPORT_PC88_JOYSTICK
- if(config.device_type == DEVICE_JOYSTICK) {
+ if(config.joystick_type == DEVICE_JOYSTICK) {
return (~(joystick_status[0] >> 4) & 0x03) | 0xfc;
- } else if(config.device_type == DEVICE_MOUSE) {
+ } else if(config.joystick_type == DEVICE_MOUSE) {
return (~mouse_status[2] & 0x03) | 0xfc;
}
#endif
#endif
case 0x71:
return port[0x71];
+#ifdef SUPPORT_PC88_HMB20
+// case 0x88:
+ case 0x89:
+ return d_opm->read_io8(addr);
+#endif
+#ifdef SUPPORT_PC88_CDROM
+ // M88 cdif
+ case 0x90:
+ if(cdbios_loaded) {
+ val = d_scsi_host->read_signal(SIG_SCSI_BSY) ? 0x80 : 0;
+ val |= d_scsi_host->read_signal(SIG_SCSI_REQ) ? 0x40 : 0;
+ val |= d_scsi_host->read_signal(SIG_SCSI_MSG) ? 0x20 : 0;
+ val |= d_scsi_host->read_signal(SIG_SCSI_CD ) ? 0x10 : 0;
+ val |= d_scsi_host->read_signal(SIG_SCSI_IO ) ? 0x08 : 0;
+ // do not show BSY,MSG,CxD,IxD when SEL=1 (\90M\92·\82Ì\96ì\96] \95\90\8f«\95\97\89_\98^)
+ if(port[0x90] & 0x01) {
+ val &= ~(0x80 | 0x20 | 0x10 | 0x08);
+ val |= (port[0x9f] & 0x01); // correct ???
+ }
+ #ifdef _SCSI_DEBUG_LOG
+ this->out_debug_log(_T("[SCSI_PC88] Status = %02X\n"), val);
+ #endif
+ return val;
+ }
+ break;
+ case 0x91:
+ if(cdbios_loaded) {
+ return d_scsi_host->read_dma_io8(0);
+ }
+ break;
+ case 0x92:
+ case 0x93:
+ case 0x96:
+ if(cdbios_loaded) {
+ return 0x00;
+ }
+ break;
+ case 0x99:
+ if(cdbios_loaded) {
+// return 0xcd; // PC-8801MC
+ return 0x00;
+ }
+ break;
+ case 0x98:
+ if(cdbios_loaded) {
+ port[0x98] ^= 0x80; // clock ???
+ return port[0x98];
+ }
+ break;
+ case 0x9b:
+ case 0x9d:
+ if(cdbios_loaded) {
+ return 60;
+ }
+ break;
+#endif
#ifdef SUPPORT_PC88_SB2
case 0xa8:
if(d_sb2 != NULL) {
if(d_sb2 != NULL) {
if(PortA8_OPNCH == 14) {
#ifdef SUPPORT_PC88_JOYSTICK
- if(config.device_type == DEVICE_JOYSTICK) {
+ if(config.joystick_type == DEVICE_JOYSTICK) {
return (~(joystick_status[0] >> 0) & 0x0f) | 0xf0;
- } else if(config.device_type == DEVICE_MOUSE) {
+ } else if(config.joystick_type == DEVICE_MOUSE) {
switch(mouse_phase) {
case 0:
return ((mouse_lx >> 4) & 0x0f) | 0xf0;
return 0xff;
} else if(PortA8_OPNCH == 15) {
#ifdef SUPPORT_PC88_JOYSTICK
- if(config.device_type == DEVICE_JOYSTICK) {
+ if(config.joystick_type == DEVICE_JOYSTICK) {
return (~(joystick_status[0] >> 4) & 0x03) | 0xfc;
- } else if(config.device_type == DEVICE_MOUSE) {
+ } else if(config.joystick_type == DEVICE_MOUSE) {
return (~mouse_status[2] & 0x03) | 0xfc;
}
#endif
break;
#endif
#endif
+#if defined(SUPPORT_PC88_VAB)
+ // X88000
+ case 0xb4:
+ case 0xb5:
+ if(PortE3_VAB_SEL) {
+ return port[addr];
+ }
+ break;
+#endif
case 0xe2:
return (~port[0xe2]) | 0xee;
case 0xe3:
return 0xff;
}
-uint32 PC88::read_dma_data8(uint32 addr)
+uint32_t PC88::read_dma_data8(uint32_t addr)
{
+ // from ram
#if defined(_PC8001SR)
return ram[addr & 0xffff];
#else
#endif
}
-void PC88::write_dma_io8(uint32 addr, uint32 data)
+void PC88::write_dma_data8(uint32_t addr, uint32_t data)
+{
+ // to ram
+ ram[addr & 0xffff] = data;
+}
+
+void PC88::write_dma_io8(uint32_t addr, uint32_t data)
{
// to crtc
crtc.write_buffer(data);
SET_BANK_R(0x0000, 0x7fff, exram + 0x8000 * PortE3_ERAMSL);
} else {
#endif
- SET_BANK_R(0x0000, 0x7fff, rdmy);
+// SET_BANK_R(0x0000, 0x7fff, rdmy);
#ifdef PC88_EXRAM_BANKS
}
#endif
} else if(Port31_MMODE) {
// 64K RAM
SET_BANK_R(0x0000, 0x7fff, ram);
+#ifdef SUPPORT_PC88_CDROM
+ } else if(cdbios_loaded && Port99_CDREN) {
+ if(Port31_RMODE) {
+ SET_BANK_R(0x0000, 0x7fff, cdbios + 0x8000);
+ } else {
+ SET_BANK_R(0x0000, 0x7fff, cdbios + 0x0000);
+ }
+#endif
} else if(Port31_RMODE) {
// N-BASIC
SET_BANK_R(0x0000, 0x7fff, n80rom);
} else {
// N-88BASIC
SET_BANK_R(0x0000, 0x5fff, n88rom);
- if(Port71_EROM == 0xff) {
+ if(Port71_EROM & 1) {
SET_BANK_R(0x6000, 0x7fff, n88rom + 0x6000);
- } else if(Port71_EROM == 0xfe) {
- SET_BANK_R(0x6000, 0x7fff, n88exrom + 0x2000 * Port32_EROMSL);
} else {
- SET_BANK_R(0x6000, 0x7fff, rdmy);
+ SET_BANK_R(0x6000, 0x7fff, n88exrom + 0x2000 * Port32_EROMSL);
}
}
SET_BANK_W(0x0000, 0x7fff, exram + 0x8000 * PortE3_ERAMSL);
} else {
#endif
- SET_BANK_W(0x0000, 0x7fff, wdmy);
+// SET_BANK_W(0x0000, 0x7fff, wdmy);
+ SET_BANK_W(0x0000, 0x7fff, ram);
#ifdef PC88_EXRAM_BANKS
}
#endif
}
#endif
-void PC88::write_signal(int id, uint32 data, uint32 mask)
+void PC88::write_signal(int id, uint32_t data, uint32_t mask)
{
if(id == SIG_PC88_USART_IRQ) {
request_intr(IRQ_USART, ((data & mask) != 0));
request_intr(IRQ_SOUND, true);
}
#endif
+#ifdef SUPPORT_PC88_CDROM
+ } else if(id == SIG_PC88_SCSI_DRQ) {
+ if((data & mask) && cdbios_loaded) {
+ if(!dmac.ch[1].running) {
+ dmac.start(1);
+ }
+ if(dmac.ch[1].running) {
+ dmac.run(1, 1);
+ }
+ }
+#endif
} else if(id == SIG_PC88_USART_OUT) {
// recv from sio
if(Port30_CMT) {
// send to rs-232c
}
}
-#ifdef DATAREC_SOUND
- else if(id == SIG_PC88_DATAREC_MIX) {
- if((data & mask) != 0) {
- cmt_mix = true;
- } else {
- cmt_mix = false;
- }
- } else if(id == SIG_PC88_DATAREC_VOLUME) {
- if(data >= 0x4000) {
- cmt_volume = 0x4000;
- } else {
- cmt_volume = data;
- }
- }
-#endif
}
-void PC88::update_config(void)
-{
-#if defined(DATAREC_SOUND) && defined(USE_MULTIPLE_SOUNDCARDS)
- int vv;
- cmt_mix = config.tape_sound;
- vv = (config.sound_device_level[0] + 0x8000) >> 2;
- if(vv >= 0x4000) {
- cmt_volume = 0x4000;
- } else if(vv <= 0) {
- cmt_volume = 0;
- } else {
- cmt_volume = vv;
- }
-#endif
-}
-
-#ifdef DATAREC_SOUND
-void PC88::mix(int32* buffer, int cnt)
-{
- int vol = 0;
- if(!cmt_mix) return;
- if(cmt_play || cmt_rec) {
- if(cmt_level_flag) {
- vol = cmt_volume;
- } else {
- vol = -cmt_volume;
- }
- if(!cmt_sound_flag) vol = 0;
- } else {
- return;
- }
- for(int i = 0; i < cnt; i++) {
- *buffer++ += vol;
- *buffer++ += vol;
- }
-}
-#endif
-
void PC88::event_callback(int event_id, int err)
{
switch(event_id) {
case EVENT_CMT_DCD:
// send data to sio
usart_dcd = false;
-#ifdef DATAREC_SOUND
- cmt_sound_data = cmt_buffer[cmt_bufptr];
- cmt_sound_count = 0;
- cmt_local_count = 0;
-#endif
-#ifdef DATAREC_SOUND
- register_event(this, EVENT_CMT_SOUND, 1000000.0 / 4800.0, false, NULL);
-#endif
if(cmt_play && cmt_bufptr < cmt_bufcnt && Port30_MTON) {
d_sio->write_signal(SIG_I8251_RECV, cmt_buffer[cmt_bufptr++], 0xff);
if(cmt_bufptr < cmt_bufcnt) {
register_event(this, EVENT_CMT_SEND, 5000, false, &cmt_register_id);
break;
}
- } else {
-#ifdef DATAREC_SOUND
- //cmt_level_flag = false;
- //cmt_sound_flag = false;
-#endif
}
usart_dcd = true; // Jackie Chan no Spartan X
cmt_register_id = -1;
break;
- case EVENT_CMT_SOUND:
-#ifdef DATAREC_SOUND
- if(cmt_sound_count < 8) {
- if((cmt_sound_data & 0x80) != 0) {
- cmt_sound_flag = true;
- cmt_level_flag = ((cmt_local_count & 0x01) != 0);
- if(cmt_local_count & 0x01 != 0) {
- cmt_sound_data <<= 1;
- cmt_sound_count++;
- cmt_local_count = 0;
- }
- } else {
- cmt_sound_flag = true;
- cmt_level_flag = ((cmt_local_count & 0x02) != 0);
- if((cmt_local_count & 0x03) == 3) {
- cmt_sound_data <<= 1;
- cmt_sound_count++;
- cmt_local_count = 0;
- }
- }
- cmt_local_count++;
- register_event(this, EVENT_CMT_SOUND, 1000000.0 / 4800.0, false, NULL);
- } else if(cmt_sound_count < 11) {
- // STOP BIT = 1.5
- cmt_sound_flag = true;
- cmt_level_flag = true;
- cmt_sound_count++;
- register_event(this, EVENT_CMT_SOUND, 1000000.0 / 4800.0, false, NULL);
-
- } else if(cmt_sound_count == 12) {
- // Fall down
- cmt_sound_flag = true;
- cmt_level_flag = false;
- cmt_sound_count++;
- register_event(this, EVENT_CMT_SOUND, 1000000.0 / 4800.0, false, NULL);
- } else {
- cmt_sound_flag = false;
- cmt_level_flag = false;
- cmt_sound_count = 0;
- cmt_local_count = 0;
- }
-#endif
- break;
case EVENT_BEEP:
beep_signal = !beep_signal;
d_pcm->write_signal(SIG_PCM1BIT_SIGNAL, ((beep_on && beep_signal) || sing_signal) ? 1 : 0, 1);
break;
+#ifdef SUPPORT_PC88_CDROM
+ case EVENT_FADE_IN:
+ if((cdda_volume += 0.1) >= 100.0) {
+ cancel_event(this, cdda_register_id);
+ cdda_register_id = -1;
+ cdda_volume = 100.0;
+ }
+ d_scsi_cdrom->set_volume((int)cdda_volume);
+ break;
+ case EVENT_FADE_OUT:
+ if((cdda_volume -= 0.1) <= 0) {
+ cancel_event(this, cdda_register_id);
+ cdda_register_id = -1;
+ cdda_volume = 0.0;
+ }
+ d_scsi_cdrom->set_volume((int)cdda_volume);
+ break;
+#endif
}
}
void PC88::event_frame()
{
// update key status
- memcpy(key_status, emu->key_buffer(), sizeof(key_status));
+ memcpy(key_status, emu->get_key_buffer(), sizeof(key_status));
- for(int i = 0; i < 9; i++) {
+ for(int i = 0; i < array_length(key_conv_table); i++) {
// INS or F6-F10 -> SHIFT + DEL or F1-F5
if(key_status[key_conv_table[i][0]]) {
key_status[key_conv_table[i][1]] = 1;
request_intr(IRQ_VRTC, true);
update_gvram_wait();
}
+ // update palette
+#if !defined(_PC8001SR)
+ if(v < (disp_line <= 200 ? 200 : 400)) {
+#else
+ if(v < 200) {
+#endif
+ if(update_palette) {
+ static bool initialized = false;
+ static palette_t initial[9] = {0};
+
+ if(!initialized) {
+ for(int i = 1; i < 8; i++) {
+ initial[i].b = (i & 1) ? 7 : 0;
+ initial[i].r = (i & 2) ? 7 : 0;
+ initial[i].g = (i & 4) ? 7 : 0;
+ }
+ initialized = true;
+ }
+ for(int i = 0; i < 9; i++) {
+ palette_digital[i] = palette_analog[i] = initial[i];
+ }
+#if defined(_PC8001SR)
+ if(config.boot_mode != MODE_PC80_V2) {
+ if(Port31_V1_320x200) {
+ for(int i = 0; i < 3; i++) {
+ palette_analog[i].b = (port[0x31] & 4) ? 7 : 0;
+ palette_analog[i].r = (i & 1) ? 7 : 0;
+ palette_analog[i].g = (i & 2) ? 7 : 0;
+ }
+ palette_analog[3] = palette[8];
+ } else if(Port31_V1_MONO) {
+// palette_analog[0] = {0, 0, 0};
+ palette_analog[1] = palette[8];
+ } else {
+// for(int i = 1; i < 8; i++) {
+// palette_analog[i].b = (i & 1) ? 7 : 0;
+// palette_analog[i].r = (i & 2) ? 7 : 0;
+// palette_analog[i].g = (i & 4) ? 7 : 0;
+// }
+ palette_analog[0] = palette[8];
+ }
+ if(Port31_V1_320x200) {
+// palette_digital[0] = {0, 0, 0};
+ } else {
+ palette_digital[0] = palette_analog[0];
+ }
+ } else {
+ for(int i = 0; i < 8; i++) {
+ palette_analog[i].b = (port[0x54 + i] & 1) ? 7 : 0;
+ palette_analog[i].r = (port[0x54 + i] & 2) ? 7 : 0;
+ palette_analog[i].g = (port[0x54 + i] & 4) ? 7 : 0;
+ }
+ if(!Port31_HCOLOR) {
+ palette_analog[0] = palette[8];
+ }
+ palette_digital[0] = palette_analog[0];
+ }
+#else
+ for(int i = 0; i < 8; i++) {
+ palette_analog[i] = palette[i];
+ }
+ if(!Port31_HCOLOR) {
+ if(!Port32_PMODE) {
+ palette_analog[0] = palette[8];
+ } else {
+ palette_analog[0] = palette[9];
+ }
+ }
+ palette_digital[0] = palette_analog[0];
+#endif
+ }
+ if(v == 0) {
+ memset(palette_line_changed, 0, sizeof(palette_line_changed));
+ }
+ if((palette_line_changed[v] = (update_palette || v == 0)) == true) {
+ for(int i = 0; i < 9; i++) {
+ palette_line_digital[v][i] = palette_digital[i];
+ palette_line_analog [v][i] = palette_analog [i];
+ }
+ update_palette = false;
+ }
+ }
}
void PC88::key_down(int code, bool repeat)
if(cmt_register_id != -1) {
cancel_event(this, cmt_register_id);
}
-#ifdef DATAREC_SOUND
- cmt_sound_count = 0;
- cmt_sound_data = 0;
- cmt_level_flag = false;
- cmt_sound_flag = true;
-#endif
register_event(this, EVENT_CMT_SEND, 5000, false, &cmt_register_id);
}
}
cmt_play = cmt_rec = false;
}
-bool PC88::now_skip()
+bool PC88::is_frame_skippable()
{
return (cmt_play && cmt_bufptr < cmt_bufcnt && Port30_MTON);
}
draw_text();
// render graph screen
- scrntype *palette_pc = palette_graph_pc;
bool disp_color_graph = true;
+ bool draw_scanline_black = config.scan_line;
#if defined(_PC8001SR)
if(config.boot_mode != MODE_PC80_V2) {
if(Port31_V1_320x200) {
} else if(Port31_V1_MONO) {
draw_640x200_mono_graph();
} else {
+ if(hireso) {
+ draw_scanline_black = false;
+ }
draw_640x200_attrib_graph();
- palette_pc = palette_text_pc;
}
+ emu->set_vm_screen_lines(200);
} else {
- if(Port31_COLOR) {
+ if(Port31_HCOLOR) {
if(Port31_320x200) {
disp_color_graph = draw_320x200_color_graph();
} else {
disp_color_graph = draw_640x200_color_graph();
}
+ emu->set_vm_screen_lines(200);
} else {
if(Port31_320x200) {
draw_320x200_attrib_graph();
} else {
draw_640x200_attrib_graph();
}
- palette_pc = palette_text_pc;
+ if(hireso) {
+ draw_scanline_black = false;
+ }
+ emu->set_vm_screen_lines(200);
}
}
#else
if(Port31_HCOLOR) {
disp_color_graph = draw_640x200_color_graph();
+ emu->set_vm_screen_lines(200);
} else if(!Port31_400LINE) {
- draw_640x200_mono_graph();
+ if(hireso) {
+ draw_scanline_black = false;
+ }
+ draw_640x200_attrib_graph();
+// draw_640x200_mono_graph();
+ emu->set_vm_screen_lines(200);
} else {
+ if(hireso) {
+ draw_scanline_black = false;
+ }
draw_640x400_attrib_graph();
- palette_pc = palette_text_pc;
+// draw_640x400_mono_graph();
+ emu->set_vm_screen_lines(400);
}
#endif
- // update palette
- if(update_palette) {
- static const int pex[8] = {
- 0, 36, 73, 109, 146, 182, 219, 255 // from m88
- };
- scrntype back_color = 0;
-#if defined(_PC8001SR)
- if(config.boot_mode != MODE_PC80_V2) {
- if(Port31_V1_320x200) {
- for(int i = 0; i < 3; i++) {
- uint8 b = (port[0x31] & 4) ? 7 : 0;
- uint8 r = (i & 1) ? 7 : 0;
- uint8 g = (i & 2) ? 7 : 0;
- palette_graph_pc[i] = RGB_COLOR(pex[r], pex[g], pex[b]);
- }
- palette_graph_pc[3] = RGB_COLOR(pex[palette[8].r], pex[palette[8].g], pex[palette[8].b]);
- } else if(Port31_V1_MONO) {
- palette_graph_pc[0] = 0;
- palette_graph_pc[1] = RGB_COLOR(pex[palette[8].r], pex[palette[8].g], pex[palette[8].b]);
- } else {
- back_color = RGB_COLOR(pex[palette[8].r], pex[palette[8].g], pex[palette[8].b]);
+ // create palette for each scanline
+#if !defined(_PC8001SR)
+ int disp_line = crtc.height * crtc.char_height;
+ int ymax = (disp_line <= 200) ? 200 : 400;
+#else
+ int ymax = 200;
+#endif
+ static const uint32_t pex[8] = {
+ 0, 36, 73, 109, 146, 182, 219, 255 // from m88
+ };
+ scrntype_t palette_digital_text_pc [9];
+ scrntype_t palette_analog_text_pc [9];
+ scrntype_t palette_digital_graph_pc[9];
+ scrntype_t palette_analog_graph_pc [9];
+
+ scrntype_t palette_line_digital_text_pc [400][9];
+ scrntype_t palette_line_analog_graph_pc [400][9];
+#if !defined(_PC8001SR)
+ scrntype_t palette_line_analog_text_pc [400][9];
+ scrntype_t palette_line_digital_graph_pc[400][9];
+#endif
+
+ for(int y = 0; y < ymax; y++) {
+ if(palette_line_changed[y]) {
+ for(int i = 0; i < 9; i++) {
+ // A is a flag for crt filter
+ palette_digital_text_pc [i] = RGBA_COLOR(pex[palette_line_digital[y][i].r], pex[palette_line_digital[y][i].g], pex[palette_line_digital[y][i].b], 255);
+ palette_analog_text_pc [i] = RGBA_COLOR(pex[palette_line_analog [y][i].r], pex[palette_line_analog [y][i].g], pex[palette_line_analog [y][i].b], 255);
+ palette_digital_graph_pc[i] = RGBA_COLOR(pex[palette_line_digital[y][i].r], pex[palette_line_digital[y][i].g], pex[palette_line_digital[y][i].b], 0);
+ palette_analog_graph_pc [i] = RGBA_COLOR(pex[palette_line_analog [y][i].r], pex[palette_line_analog [y][i].g], pex[palette_line_analog [y][i].b], 0);
}
- } else {
- if(Port31_COLOR) {
- for(int i = 0; i < 8; i++) {
- uint8 b = (port[0x54 + i] & 1) ? 7 : 0;
- uint8 r = (port[0x54 + i] & 2) ? 7 : 0;
- uint8 g = (port[0x54 + i] & 4) ? 7 : 0;
- palette_graph_pc[i] = RGB_COLOR(pex[r], pex[g], pex[b]);
- }
- back_color = palette_graph_pc[0];
- } else {
- back_color = RGB_COLOR(pex[palette[8].r], pex[palette[8].g], pex[palette[8].b]);
+ // set back color to black if cg screen is off in color mode
+ if(!disp_color_graph) {
+ palette_digital_text_pc [0] =
+ palette_analog_text_pc [0] =
+ palette_digital_graph_pc[0] =
+ palette_analog_graph_pc [0] = 0;
}
- }
-#else
- if(Port31_HCOLOR) {
- for(int i = 0; i < 8; i++) {
- palette_graph_pc[i] = RGB_COLOR(pex[palette[i].r], pex[palette[i].g], pex[palette[i].b]);
+ palette_analog_text_pc [8] = palette_digital_text_pc [0];
+ palette_analog_graph_pc[8] = palette_digital_graph_pc[0];
+ }
+ if(ymax == 200) {
+ for(int i = 0; i < 9; i++) {
+ palette_line_digital_text_pc [2 * y ][i] =
+ palette_line_digital_text_pc [2 * y + 1][i] = palette_digital_text_pc [i];
+ palette_line_analog_graph_pc [2 * y ][i] =
+ palette_line_analog_graph_pc [2 * y + 1][i] = palette_analog_graph_pc [i];
+#if !defined(_PC8001SR)
+ palette_line_analog_text_pc [2 * y ][i] =
+ palette_line_analog_text_pc [2 * y + 1][i] = palette_analog_text_pc [i];
+ palette_line_digital_graph_pc[2 * y ][i] =
+ palette_line_digital_graph_pc[2 * y + 1][i] = palette_digital_graph_pc[i];
+#endif
}
- } else if(!Port31_400LINE) {
- palette_graph_pc[0] = RGB_COLOR(pex[palette[8].r], pex[palette[8].g], pex[palette[8].b]);
- palette_graph_pc[1] = RGB_COLOR(255, 255, 255);
- }
- back_color = RGB_COLOR(pex[palette[8].r], pex[palette[8].g], pex[palette[8].b]);
+ } else {
+ for(int i = 0; i < 9; i++) {
+ palette_line_digital_text_pc [y][i] = palette_digital_text_pc [i];
+ palette_line_analog_graph_pc [y][i] = palette_analog_graph_pc [i];
+#if !defined(_PC8001SR)
+ palette_line_analog_text_pc [y][i] = palette_analog_text_pc [i];
+ palette_line_digital_graph_pc[y][i] = palette_digital_graph_pc[i];
#endif
- // back color for attrib mode
- palette_text_pc[0] = back_color;
- update_palette = false;
- }
-
- // set back color to black if cg screen is off in color mode
- scrntype palette_text_back = palette_text_pc[0];
- scrntype palette_graph_back = palette_graph_pc[0];
-
- if(!disp_color_graph) {
- palette_text_pc[0] = palette_graph_pc[0] = 0;
+ }
+ }
}
// copy to screen buffer
#if !defined(_PC8001SR)
- if(!Port31_400LINE) {
-#endif
- for(int y = 0; y < 200; y++) {
- // for Xak2 opening (XM8 version 1.00)
- if(crtc.char_height == 0x10) {
- if(y >= (crtc.height * crtc.char_height / 2)) {
- while(y < 200) {
- scrntype* dest0 = emu->screen_buffer(y * 2);
- scrntype* dest1 = emu->screen_buffer(y * 2 + 1);
- memset(dest0, 0, sizeof(scrntype) * 640);
- memset(dest1, 0, sizeof(scrntype) * 640);
- y++;
- }
- break;
- }
+#if defined(SUPPORT_PC88_VAB)
+ // X88000
+ if(PortB4_VAB_DISP) {
+ uint8_t *src = &exram[(0x8000 * 4) * PC88_VAB_PAGE];
+
+ for(int y = 0; y < 400; y += 2) {
+ scrntype_t* dest0 = emu->get_screen_buffer(y);
+ scrntype_t* dest1 = emu->get_screen_buffer(y + 1);
+
+ for(int x = 0; x < 640; x += 2) {
+ pair16_t c;
+ c.b.l = *src++;
+ c.b.h = *src++;
+ dest0[x] = dest0[x + 1] = palette_vab_pc[c.w];
}
- scrntype* dest0 = emu->screen_buffer(y * 2);
- scrntype* dest1 = emu->screen_buffer(y * 2 + 1);
- uint8* src_t = text[y];
- uint8* src_g = graph[y];
+ if(config.scan_line) {
+ memset(dest1, 0, sizeof(scrntype_t) * 640);
+ } else {
+ memcpy(dest1, dest0, sizeof(scrntype_t) * 640);
+ }
+ }
+ emu->screen_skip_line(true);
+ } else
+#endif
+ if(!Port31_HCOLOR && Port31_400LINE) {
+ for(int y = 0; y < 400; y++) {
+ scrntype_t* dest = emu->get_screen_buffer(y);
+ uint8_t* src_t = text[y >> 1];
+ uint8_t* src_g = graph[y];
+ scrntype_t* pal_t;
+ scrntype_t* pal_g;
+// if(Port31_HCOLOR) {
+// pal_t = palette_line_digital_text_pc [y];
+// pal_g = palette_line_analog_graph_pc [y];
+// } else
+ if(Port32_PMODE) {
+ pal_t = palette_line_analog_text_pc [y];
+ pal_g = palette_line_analog_graph_pc [y];
+ } else {
+ pal_t = palette_line_digital_text_pc [y];
+ pal_g = palette_line_digital_graph_pc[y];
+ }
+ for(int x = 0; x < 640; x++) {
+ uint32_t t = src_t[x];
+ dest[x] = t ? pal_t[t] : pal_g[src_g[x]];
+ }
+ }
+ emu->screen_skip_line(false);
+ } else
+#endif
+ {
+ for(int y = 0; y < 400; y++) {
+ scrntype_t* dest = emu->get_screen_buffer(y);
+ uint8_t* src_t = text[y >> 1];
+ uint8_t* src_g = graph[y];
+ scrntype_t* pal_t;
+ scrntype_t* pal_g;
#if defined(_PC8001SR)
+ pal_t = palette_line_digital_text_pc[y];
+ pal_g = palette_line_analog_graph_pc[y];
+
if(port[0x33] & 8) {
for(int x = 0; x < 640; x++) {
- uint32 g = src_g[x];
- dest0[x] = g ? palette_pc[g] : palette_text_pc[src_t[x]];
+ uint32_t t = src_t[x];
+ uint32_t g = src_g[x];
+ dest[x] = (!g && t) ? pal_t[t] : ((y & 1) && draw_scanline_black) ? 0 : pal_g[g];
}
} else {
-#endif
for(int x = 0; x < 640; x++) {
- uint32 t = src_t[x];
- dest0[x] = t ? palette_text_pc[t] : palette_pc[src_g[x]];
+ uint32_t t = src_t[x];
+ dest[x] = t ? pal_t[t] : ((y & 1) && draw_scanline_black) ? 0 : pal_g[src_g[x]];
}
-#if defined(_PC8001SR)
}
-#endif
- if(config.scan_line) {
- memset(dest1, 0, 640 * sizeof(scrntype));
+#else
+ if(Port31_HCOLOR) {
+ pal_t = palette_line_digital_text_pc [y];
+ pal_g = palette_line_analog_graph_pc [y];
+ } else if(Port32_PMODE) {
+ pal_t = palette_line_analog_text_pc [y];
+ pal_g = palette_line_analog_graph_pc [y];
} else {
- for(int x = 0; x < 640; x++) {
- dest1[x] = dest0[x];
- }
+ pal_t = palette_line_digital_text_pc [y];
+ pal_g = palette_line_digital_graph_pc[y];
}
- }
- emu->screen_skip_line(true);
-#if !defined(_PC8001SR)
- } else {
- for(int y = 0; y < 400; y++) {
- scrntype* dest = emu->screen_buffer(y);
- uint8* src_t = text[y >> 1];
- uint8* src_g = graph[y];
-
for(int x = 0; x < 640; x++) {
- uint32 t = src_t[x];
- dest[x] = t ? palette_text_pc[t] : palette_pc[src_g[x]];
+ uint32_t t = src_t[x];
+ dest[x] = t ? pal_t[t] : ((y & 1) && draw_scanline_black) ? 0 : pal_g[src_g[x]];
}
+#endif
}
- emu->screen_skip_line(false);
+ emu->screen_skip_line(true);
}
-#endif
-
- // restore back color palette
- palette_text_pc[0] = palette_text_back;
- palette_graph_pc[0] = palette_graph_back;
}
/*
void PC88::draw_text()
{
+ if(crtc.status & 0x88) {
+ // dma underrun
+ crtc.status &= ~0x80;
+ memset(crtc.text.expand, 0, 200 * 80);
+ memset(crtc.attrib.expand, crtc.reverse ? 3 : 2, 200 * 80);
+ }
// for Advanced Fantasian Opening (20line) (XM8 version 1.00)
if(!(crtc.status & 0x10) || Port53_TEXTDS) {
// if(!(crtc.status & 0x10) || (crtc.status & 8) || Port53_TEXTDS) {
- memset(text, 0, sizeof(text));
- return;
+ memset(crtc.text.expand, 0, 200 * 80);
+ for(int y = 0; y < 200; y++) {
+ for(int x = 0; x < 80; x++) {
+ crtc.attrib.expand[y][x] &= 0xe0;
+ crtc.attrib.expand[y][x] |= 0x02;
+ }
+ }
+// memset(crtc.attrib.expand, 2, 200 * 80);
}
+ // for Xak2 opening
+ memset(text, 8, sizeof(text));
+ memset(text_color, 7, sizeof(text_color));
+ memset(text_reverse, 0, sizeof(text_reverse));
+
int char_height = crtc.char_height;
- uint8 color_mask = Port30_COLOR ? 0 : 7;
+ uint8_t color_mask = Port30_COLOR ? 0 : 7;
+ uint8_t code_expand, attr_expand;
if(!hireso) {
char_height <<= 1;
}
- if(Port31_400LINE || !crtc.skip_line) {
- char_height >>= 1;
+// if(Port31_400LINE || !crtc.skip_line) {
+// char_height >>= 1;
+// }
+ if(crtc.skip_line) {
+ char_height <<= 1;
}
- for(int cy = 0, ytop = 0; cy < crtc.height && ytop < 200; cy++, ytop += char_height) {
+// for(int cy = 0, ytop = 0; cy < 64 && ytop < 400; cy++, ytop += char_height) {
+ for(int cy = 0, ytop = 0; cy < crtc.height && ytop < 400; cy++, ytop += char_height) {
for(int x = 0, cx = 0; cx < crtc.width; x += 8, cx++) {
if(Port30_40 && (cx & 1)) {
- continue;
+ // don't update code/attrib
+ } else {
+ code_expand = crtc.text.expand[cy][cx];
+ attr_expand = crtc.attrib.expand[cy][cx];
}
- uint8 attrib = crtc.attrib.expand[cy][cx];
- uint8 color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
+ uint8_t attrib = attr_expand;//crtc.attrib.expand[cy][cx];
+// uint8_t color = !(Port30_COLOR && (attrib & 8)) ? 7 : (attrib & 0xe0) ? (attrib >> 5) : 8;
+ uint8_t color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
bool under_line = ((attrib & 8) != 0);
bool upper_line = ((attrib & 4) != 0);
bool secret = ((attrib & 2) != 0);
bool reverse = ((attrib & 1) != 0);
- uint8 code = secret ? 0 : crtc.text.expand[cy][cx];
+ uint8_t color_tmp = color;
+ bool reverse_tmp = reverse;
+
+ // from ePC-8801MA\89ü
+ if(Port31_GRAPH && !Port31_HCOLOR) {
+ if(reverse) {
+ reverse = false;
+ color = 8;
+ }
+ }
+ uint8_t code = secret ? 0 : code_expand;//crtc.text.expand[cy][cx];
#ifdef SUPPORT_PC88_PCG8100
- uint8 *pattern = ((attrib & 0x10) ? sg_pattern : pcg_pattern) + code * 8;
+ uint8_t *pattern = ((attrib & 0x10) ? sg_pattern : pcg_pattern) + code * 8;
#else
- uint8 *pattern = ((attrib & 0x10) ? sg_pattern : kanji1 + 0x1000) + code * 8;
+ uint8_t *pattern = ((attrib & 0x10) ? sg_pattern : kanji1 + 0x1000) + code * 8;
#endif
- for(int l = 0, y = ytop; l < char_height && y < 200; l++, y++) {
- uint8 pat = (l < 8) ? pattern[l] : 0;
+ for(int l = 0, y = ytop; l < char_height / 2 && y < 400; l++, y += 2) {
+ uint8_t pat = (l < 8) ? pattern[l] : 0;
+
+ if(Port30_40) {
+ // from ePC-8801MA\89ü
+ static const uint8_t wct[16] = {
+ 0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f, 0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff
+ };
+ pat = wct[(cx & 1) ? (pat & 0x0f) : (pat >> 4)];
+ }
if((upper_line && l == 0) || (under_line && l >= 7)) {
pat = 0xff;
}
if(reverse) {
- pat = ~pat;
+ pat ^= 0xff;
}
+ uint8_t *dest = &text[y >> 1][x];
+ dest[0] = (pat & 0x80) ? color : 0;
+ dest[1] = (pat & 0x40) ? color : 0;
+ dest[2] = (pat & 0x20) ? color : 0;
+ dest[3] = (pat & 0x10) ? color : 0;
+ dest[4] = (pat & 0x08) ? color : 0;
+ dest[5] = (pat & 0x04) ? color : 0;
+ dest[6] = (pat & 0x02) ? color : 0;
+ dest[7] = (pat & 0x01) ? color : 0;
- uint8 *dest = &text[y][x];
- if(Port30_40) {
- dest[ 0] = dest[ 1] = (pat & 0x80) ? color : 0;
- dest[ 2] = dest[ 3] = (pat & 0x40) ? color : 0;
- dest[ 4] = dest[ 5] = (pat & 0x20) ? color : 0;
- dest[ 6] = dest[ 7] = (pat & 0x10) ? color : 0;
- dest[ 8] = dest[ 9] = (pat & 0x08) ? color : 0;
- dest[10] = dest[11] = (pat & 0x04) ? color : 0;
- dest[12] = dest[13] = (pat & 0x02) ? color : 0;
- dest[14] = dest[15] = (pat & 0x01) ? color : 0;
- } else {
- dest[0] = (pat & 0x80) ? color : 0;
- dest[1] = (pat & 0x40) ? color : 0;
- dest[2] = (pat & 0x20) ? color : 0;
- dest[3] = (pat & 0x10) ? color : 0;
- dest[4] = (pat & 0x08) ? color : 0;
- dest[5] = (pat & 0x04) ? color : 0;
- dest[6] = (pat & 0x02) ? color : 0;
- dest[7] = (pat & 0x01) ? color : 0;
- }
+ // store text attributes for monocolor graph screen
+ text_color[y >> 1][cx] = color_tmp;
+ text_reverse[y >> 1][cx] = reverse_tmp;
}
}
}
memset(graph, 0, sizeof(graph));
return false;
}
- uint8 *gvram_b0 = Port53_G0DS ? gvram_null : (gvram + 0x0000);
- uint8 *gvram_r0 = Port53_G0DS ? gvram_null : (gvram + 0x4000);
- uint8 *gvram_g0 = Port53_G0DS ? gvram_null : (gvram + 0x8000);
- uint8 *gvram_b1 = Port53_G1DS ? gvram_null : (gvram + 0x2000);
- uint8 *gvram_r1 = Port53_G1DS ? gvram_null : (gvram + 0x6000);
- uint8 *gvram_g1 = Port53_G1DS ? gvram_null : (gvram + 0xa000);
+ uint8_t *gvram_b0 = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r0 = Port53_G0DS ? gvram_null : (gvram + 0x4000);
+ uint8_t *gvram_g0 = Port53_G0DS ? gvram_null : (gvram + 0x8000);
+ uint8_t *gvram_b1 = Port53_G1DS ? gvram_null : (gvram + 0x2000);
+ uint8_t *gvram_r1 = Port53_G1DS ? gvram_null : (gvram + 0x6000);
+ uint8_t *gvram_g1 = Port53_G1DS ? gvram_null : (gvram + 0xa000);
if(port[0x33] & 4) {
// G1>G0
- uint8 *tmp;
+ uint8_t *tmp;
tmp = gvram_b0; gvram_b0 = gvram_b1; gvram_b1 = tmp;
tmp = gvram_r0; gvram_r0 = gvram_r1; gvram_r1 = tmp;
tmp = gvram_g0; gvram_g0 = gvram_g1; gvram_g1 = tmp;
}
- for(int y = 0, addr = 0; y < 200; y++) {
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0; x < 640; x += 16) {
- uint8 b0 = gvram_b0[addr];
- uint8 r0 = gvram_r0[addr];
- uint8 g0 = gvram_g0[addr];
- uint8 b1 = gvram_b1[addr];
- uint8 r1 = gvram_r1[addr];
- uint8 g1 = gvram_g1[addr];
+ uint8_t b0 = gvram_b0[addr];
+ uint8_t r0 = gvram_r0[addr];
+ uint8_t g0 = gvram_g0[addr];
+ uint8_t b1 = gvram_b1[addr];
+ uint8_t r1 = gvram_r1[addr];
+ uint8_t g1 = gvram_g1[addr];
addr++;
- uint8 *dest = &graph[y][x];
- uint8 brg0, brg1;
+ uint8_t *dest = &graph[y][x];
+ uint8_t brg0, brg1;
brg0 = ((b0 & 0x80) >> 7) | ((r0 & 0x80) >> 6) | ((g0 & 0x80) >> 5);
brg1 = ((b1 & 0x80) >> 7) | ((r1 & 0x80) >> 6) | ((g1 & 0x80) >> 5);
dest[ 0] = dest[ 1] = brg0 ? brg0 : brg1;
brg1 = ((b1 & 0x01) ) | ((r1 & 0x01) << 1) | ((g1 & 0x01) << 2);
dest[14] = dest[15] = brg0 ? brg0 : brg1;
}
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
+ } else {
+ memcpy(graph[y + 1], graph[y], 640);
+ }
}
return true;
}
memset(graph, 0, sizeof(graph));
return false;
}
- uint8 *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
- uint8 *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
- uint8 *gvram_g = Port53_G2DS ? gvram_null : (gvram + 0x8000);
+ uint8_t *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
+ uint8_t *gvram_g = Port53_G2DS ? gvram_null : (gvram + 0x8000);
- for(int y = 0, addr = 0; y < 200; y++) {
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0; x < 640; x += 8) {
- uint8 brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
+ uint8_t brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
addr++;
- uint8 *dest = &graph[y][x];
+ uint8_t *dest = &graph[y][x];
dest[0] = dest[1] = (brg >> 6) & 3;
dest[2] = dest[3] = (brg >> 4) & 3;
dest[4] = dest[5] = (brg >> 2) & 3;
dest[6] = dest[7] = (brg ) & 3;
}
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
+ } else {
+ memcpy(graph[y + 1], graph[y], 640);
+ }
}
return true;
}
memset(graph, 0, sizeof(graph));
return;
}
- uint8 *gvram_b0 = Port53_G0DS ? gvram_null : (gvram + 0x0000);
- uint8 *gvram_r0 = Port53_G1DS ? gvram_null : (gvram + 0x4000);
- uint8 *gvram_g0 = Port53_G2DS ? gvram_null : (gvram + 0x8000);
- uint8 *gvram_b1 = Port53_G3DS ? gvram_null : (gvram + 0x2000);
- uint8 *gvram_r1 = Port53_G4DS ? gvram_null : (gvram + 0x6000);
- uint8 *gvram_g1 = Port53_G5DS ? gvram_null : (gvram + 0xa000);
-
- int char_height = crtc.char_height ? crtc.char_height : 8;
- uint8 color_mask = Port30_COLOR ? 0 : 7;
+ uint8_t *gvram_b0 = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r0 = Port53_G1DS ? gvram_null : (gvram + 0x4000);
+ uint8_t *gvram_g0 = Port53_G2DS ? gvram_null : (gvram + 0x8000);
+ uint8_t *gvram_b1 = Port53_G3DS ? gvram_null : (gvram + 0x2000);
+ uint8_t *gvram_r1 = Port53_G4DS ? gvram_null : (gvram + 0x6000);
+ uint8_t *gvram_g1 = Port53_G5DS ? gvram_null : (gvram + 0xa000);
if(Port30_40) {
- for(int y = 0, addr = 0; y < 200; y++) {
- int cy = y / char_height;
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0, cx = 0; x < 640; x += 16, cx += 2) {
- uint8 attrib = crtc.attrib.expand[cy][cx];
- uint8 color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
- uint8 brg = gvram_b0[addr] | gvram_r0[addr] | gvram_g0[addr] |
- gvram_b1[addr] | gvram_r1[addr] | gvram_g1[addr];
+ uint8_t color = text_color[y >> 1][cx];
+ uint8_t brg0 = gvram_b0[addr] | gvram_r0[addr] | gvram_g0[addr] |
+ gvram_b1[addr] | gvram_r1[addr] | gvram_g1[addr];
+ uint8_t brg1 = 0;
+ if(text_reverse[y >> 1][cx]) {
+ brg0 ^= 0xff;
+ brg1 ^= 0xff;
+ }
addr++;
- uint8 *dest = &graph[y][x];
- dest[ 0] = dest[ 1] = (brg & 0x80) ? color : 0;
- dest[ 2] = dest[ 3] = (brg & 0x40) ? color : 0;
- dest[ 4] = dest[ 5] = (brg & 0x20) ? color : 0;
- dest[ 6] = dest[ 7] = (brg & 0x10) ? color : 0;
- dest[ 8] = dest[ 9] = (brg & 0x08) ? color : 0;
- dest[10] = dest[11] = (brg & 0x04) ? color : 0;
- dest[12] = dest[13] = (brg & 0x02) ? color : 0;
- dest[14] = dest[15] = (brg & 0x01) ? color : 0;
+ uint8_t *dest0 = &graph[y ][x];
+ uint8_t *dest1 = &graph[y + 1][x];
+ dest0[ 0] = dest0[ 1] = (brg0 & 0x80) ? color : 0;
+ dest0[ 2] = dest0[ 3] = (brg0 & 0x40) ? color : 0;
+ dest0[ 4] = dest0[ 5] = (brg0 & 0x20) ? color : 0;
+ dest0[ 6] = dest0[ 7] = (brg0 & 0x10) ? color : 0;
+ dest0[ 8] = dest0[ 9] = (brg0 & 0x08) ? color : 0;
+ dest0[10] = dest0[11] = (brg0 & 0x04) ? color : 0;
+ dest0[12] = dest0[13] = (brg0 & 0x02) ? color : 0;
+ dest0[14] = dest0[15] = (brg0 & 0x01) ? color : 0;
+ if(!hireso) continue;
+ dest1[ 0] = dest1[ 1] = (brg1 & 0x80) ? color : 0;
+ dest1[ 2] = dest1[ 3] = (brg1 & 0x40) ? color : 0;
+ dest1[ 4] = dest1[ 5] = (brg1 & 0x20) ? color : 0;
+ dest1[ 6] = dest1[ 7] = (brg1 & 0x10) ? color : 0;
+ dest1[ 8] = dest1[ 9] = (brg1 & 0x08) ? color : 0;
+ dest1[10] = dest1[11] = (brg1 & 0x04) ? color : 0;
+ dest1[12] = dest1[13] = (brg1 & 0x02) ? color : 0;
+ dest1[14] = dest1[15] = (brg1 & 0x01) ? color : 0;
+ }
+ if(!hireso) {
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
+ } else {
+ memcpy(graph[y + 1], graph[y], 640);
+ }
}
}
} else {
- for(int y = 0, addr = 0; y < 200; y++) {
- int cy = y / char_height;
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0, cx = 0; x < 640; x += 16, cx += 2) {
- uint8 attrib_l = crtc.attrib.expand[cy][cx];
- uint8 color_l = (attrib_l & 0xe0) ? ((attrib_l >> 5) | color_mask) : 8;
- uint8 attrib_r = crtc.attrib.expand[cy][cx + 1];
- uint8 color_r = (attrib_r & 0xe0) ? ((attrib_r >> 5) | color_mask) : 8;
- uint8 brg = gvram_b0[addr] | gvram_r0[addr] | gvram_g0[addr] |
- gvram_b1[addr] | gvram_r1[addr] | gvram_g1[addr];
+ uint8_t color_l = text_color[y >> 1][cx + 0];
+ uint8_t color_r = text_color[y >> 1][cx + 1];
+ uint8_t brg0 = gvram_b0[addr] | gvram_r0[addr] | gvram_g0[addr] |
+ gvram_b1[addr] | gvram_r1[addr] | gvram_g1[addr];
+ uint8_t brg1 = 0;
+ if(text_reverse[y >> 1][cx + 0]) {
+ brg0 ^= 0xf0;
+ brg0 ^= 0xf0;
+ }
+ if(text_reverse[y >> 1][cx + 1]) {
+ brg1 ^= 0x0f;
+ brg1 ^= 0x0f;
+ }
addr++;
- uint8 *dest = &graph[y][x];
- dest[ 0] = dest[ 1] = (brg & 0x80) ? color_l : 0;
- dest[ 2] = dest[ 3] = (brg & 0x40) ? color_l : 0;
- dest[ 4] = dest[ 5] = (brg & 0x20) ? color_l : 0;
- dest[ 6] = dest[ 7] = (brg & 0x10) ? color_l : 0;
- dest[ 8] = dest[ 9] = (brg & 0x08) ? color_r : 0;
- dest[10] = dest[11] = (brg & 0x04) ? color_r : 0;
- dest[12] = dest[13] = (brg & 0x02) ? color_r : 0;
- dest[14] = dest[15] = (brg & 0x01) ? color_r : 0;
+ uint8_t *dest0 = &graph[y ][x];
+ uint8_t *dest1 = &graph[y + 1][x];
+ dest0[ 0] = dest0[ 1] = (brg0 & 0x80) ? color_l : 0;
+ dest0[ 2] = dest0[ 3] = (brg0 & 0x40) ? color_l : 0;
+ dest0[ 4] = dest0[ 5] = (brg0 & 0x20) ? color_l : 0;
+ dest0[ 6] = dest0[ 7] = (brg0 & 0x10) ? color_l : 0;
+ dest0[ 8] = dest0[ 9] = (brg0 & 0x08) ? color_r : 0;
+ dest0[10] = dest0[11] = (brg0 & 0x04) ? color_r : 0;
+ dest0[12] = dest0[13] = (brg0 & 0x02) ? color_r : 0;
+ dest0[14] = dest0[15] = (brg0 & 0x01) ? color_r : 0;
+ if(!hireso) continue;
+ dest1[ 0] = dest1[ 1] = (brg1 & 0x80) ? color_l : 0;
+ dest1[ 2] = dest1[ 3] = (brg1 & 0x40) ? color_l : 0;
+ dest1[ 4] = dest1[ 5] = (brg1 & 0x20) ? color_l : 0;
+ dest1[ 6] = dest1[ 7] = (brg1 & 0x10) ? color_l : 0;
+ dest1[ 8] = dest1[ 9] = (brg1 & 0x08) ? color_r : 0;
+ dest1[10] = dest1[11] = (brg1 & 0x04) ? color_r : 0;
+ dest1[12] = dest1[13] = (brg1 & 0x02) ? color_r : 0;
+ dest1[14] = dest1[15] = (brg1 & 0x01) ? color_r : 0;
+ }
+ if(!hireso) {
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
+ } else {
+ memcpy(graph[y + 1], graph[y], 640);
+ }
}
}
}
memset(graph, 0, sizeof(graph));
return false;
}
- uint8 *gvram_b = /*Port53_G0DS ? gvram_null : */(gvram + 0x0000);
- uint8 *gvram_r = /*Port53_G1DS ? gvram_null : */(gvram + 0x4000);
- uint8 *gvram_g = /*Port53_G2DS ? gvram_null : */(gvram + 0x8000);
+ uint8_t *gvram_b = /*Port53_G0DS ? gvram_null : */(gvram + 0x0000);
+ uint8_t *gvram_r = /*Port53_G1DS ? gvram_null : */(gvram + 0x4000);
+ uint8_t *gvram_g = /*Port53_G2DS ? gvram_null : */(gvram + 0x8000);
- for(int y = 0, addr = 0; y < 200; y++) {
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0; x < 640; x += 8) {
- uint8 b = gvram_b[addr];
- uint8 r = gvram_r[addr];
- uint8 g = gvram_g[addr];
+ uint8_t b = gvram_b[addr];
+ uint8_t r = gvram_r[addr];
+ uint8_t g = gvram_g[addr];
addr++;
- uint8 *dest = &graph[y][x];
+ uint8_t *dest = &graph[y][x];
dest[0] = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5);
dest[1] = ((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4);
dest[2] = ((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3);
dest[6] = ((b & 0x02) >> 1) | ((r & 0x02) ) | ((g & 0x02) << 1);
dest[7] = ((b & 0x01) ) | ((r & 0x01) << 1) | ((g & 0x01) << 2);
}
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
+ } else {
+ memcpy(graph[y + 1], graph[y], 640);
+ }
}
return true;
}
memset(graph, 0, sizeof(graph));
return;
}
- uint8 *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
- uint8 *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
- uint8 *gvram_g = Port53_G2DS ? gvram_null : (gvram + 0x8000);
+ uint8_t *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
+ uint8_t *gvram_g = Port53_G2DS ? gvram_null : (gvram + 0x8000);
- for(int y = 0, addr = 0; y < 200; y++) {
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0; x < 640; x += 8) {
- uint8 brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
+ uint8_t brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
addr++;
- uint8 *dest = &graph[y][x];
+ uint8_t *dest = &graph[y][x];
dest[0] = (brg & 0x80) >> 7;
dest[1] = (brg & 0x40) >> 6;
dest[2] = (brg & 0x20) >> 5;
dest[6] = (brg & 0x02) >> 1;
dest[7] = (brg & 0x01) ;
}
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
+ } else {
+ memcpy(graph[y + 1], graph[y], 640);
+ }
}
}
-#if defined(_PC8001SR)
void PC88::draw_640x200_attrib_graph()
{
if(!Port31_GRAPH || (Port53_G0DS && Port53_G1DS && Port53_G2DS)) {
memset(graph, 0, sizeof(graph));
return;
}
- uint8 *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
- uint8 *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
- uint8 *gvram_g = Port53_G2DS ? gvram_null : (gvram + 0x8000);
+ uint8_t *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
+ uint8_t *gvram_g = Port53_G2DS ? gvram_null : (gvram + 0x8000);
- int char_height = crtc.char_height ? crtc.char_height : 8;
- uint8 color_mask = Port30_COLOR ? 0 : 7, color;
-
- for(int y = 0, addr = 0; y < 200; y++) {
- int cy = y / char_height;
+ for(int y = 0, addr = 0; y < 400; y += 2) {
for(int x = 0, cx = 0; x < 640; x += 8, cx++) {
- if(Port30_40 && (cx & 1)) {
- // don't update color
+ uint8_t color = text_color[y >> 1][cx];
+ uint8_t brg0 = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
+ uint8_t brg1 = 0;
+ if(text_reverse[y >> 1][cx]) {
+ brg0 ^= 0xff;
+ brg1 ^= 0xff;
+ }
+ addr++;
+ uint8_t *dest0 = &graph[y ][x];
+ uint8_t *dest1 = &graph[y + 1][x];
+ dest0[0] = (brg0 & 0x80) ? color : 0;
+ dest0[1] = (brg0 & 0x40) ? color : 0;
+ dest0[2] = (brg0 & 0x20) ? color : 0;
+ dest0[3] = (brg0 & 0x10) ? color : 0;
+ dest0[4] = (brg0 & 0x08) ? color : 0;
+ dest0[5] = (brg0 & 0x04) ? color : 0;
+ dest0[6] = (brg0 & 0x02) ? color : 0;
+ dest0[7] = (brg0 & 0x01) ? color : 0;
+ if(!hireso) continue;
+ dest1[0] = (brg1 & 0x80) ? color : 0;
+ dest1[1] = (brg1 & 0x40) ? color : 0;
+ dest1[2] = (brg1 & 0x20) ? color : 0;
+ dest1[3] = (brg1 & 0x10) ? color : 0;
+ dest1[4] = (brg1 & 0x08) ? color : 0;
+ dest1[5] = (brg1 & 0x04) ? color : 0;
+ dest1[6] = (brg1 & 0x02) ? color : 0;
+ dest1[7] = (brg1 & 0x01) ? color : 0;
+ }
+ if(!hireso) {
+ if(config.scan_line) {
+ memset(graph[y + 1], 0, 640);
} else {
- uint8 attrib = crtc.attrib.expand[cy][cx];
- color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
+ memcpy(graph[y + 1], graph[y], 640);
}
- uint8 brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
+ }
+ }
+}
+
+#if !defined(_PC8001SR)
+void PC88::draw_640x400_mono_graph()
+{
+ if(!Port31_GRAPH || (Port53_G0DS && Port53_G1DS)) {
+ memset(graph, 0, sizeof(graph));
+ return;
+ }
+ uint8_t *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
+
+ for(int y = 0, addr = 0; y < 200; y++) {
+ for(int x = 0; x < 640; x += 8) {
+ uint8_t b = gvram_b[addr];
addr++;
- uint8 *dest = &graph[y][x];
- dest[0] = (brg & 0x80) ? color : 0;
- dest[1] = (brg & 0x40) ? color : 0;
- dest[2] = (brg & 0x20) ? color : 0;
- dest[3] = (brg & 0x10) ? color : 0;
- dest[4] = (brg & 0x08) ? color : 0;
- dest[5] = (brg & 0x04) ? color : 0;
- dest[6] = (brg & 0x02) ? color : 0;
- dest[7] = (brg & 0x01) ? color : 0;
+ uint8_t *dest = &graph[y][x];
+ dest[0] = (b & 0x80) >> 7;
+ dest[1] = (b & 0x40) >> 6;
+ dest[2] = (b & 0x20) >> 5;
+ dest[3] = (b & 0x10) >> 4;
+ dest[4] = (b & 0x08) >> 3;
+ dest[5] = (b & 0x04) >> 2;
+ dest[6] = (b & 0x02) >> 1;
+ dest[7] = (b & 0x01) ;
+ }
+ }
+ for(int y = 200, addr = 0; y < 400; y++) {
+ for(int x = 0; x < 640; x += 8) {
+ uint8_t r = gvram_r[addr];
+ addr++;
+ uint8_t *dest = &graph[y][x];
+ dest[0] = (r & 0x80) >> 7;
+ dest[1] = (r & 0x40) >> 6;
+ dest[2] = (r & 0x20) >> 5;
+ dest[3] = (r & 0x10) >> 4;
+ dest[4] = (r & 0x08) >> 3;
+ dest[5] = (r & 0x04) >> 2;
+ dest[6] = (r & 0x02) >> 1;
+ dest[7] = (r & 0x01) ;
}
}
}
-#else
+
void PC88::draw_640x400_attrib_graph()
{
if(!Port31_GRAPH || (Port53_G0DS && Port53_G1DS)) {
memset(graph, 0, sizeof(graph));
return;
}
- uint8 *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
- uint8 *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
-
- int char_height = crtc.char_height ? crtc.char_height : 16;
- uint8 color_mask = Port30_COLOR ? 0 : 7, color;
+ uint8_t *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
+ uint8_t *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
for(int y = 0, addr = 0; y < 200; y++) {
- int cy = y / char_height;
for(int x = 0, cx = 0; x < 640; x += 8, cx++) {
- if(Port30_40 && (cx & 1)) {
- // don't update color
- } else {
- uint8 attrib = crtc.attrib.expand[cy][cx];
- // for SORCERIAN music library (XM8 version 1.20)
- color = (attrib >> 5) | color_mask;
-// color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
+ uint8_t color = text_color[y >> 1][cx];
+ uint8_t b = gvram_b[addr];
+ if(text_reverse[y >> 1][cx]) {
+ b ^= 0xff;
}
- uint8 b = gvram_b[addr];
addr++;
- uint8 *dest = &graph[y][x];
+ uint8_t *dest = &graph[y][x];
dest[0] = (b & 0x80) ? color : 0;
dest[1] = (b & 0x40) ? color : 0;
dest[2] = (b & 0x20) ? color : 0;
}
}
for(int y = 200, addr = 0; y < 400; y++) {
- int cy = y / char_height;
for(int x = 0, cx = 0; x < 640; x += 8, cx++) {
- if(Port30_40 && (cx & 1)) {
- // don't update color
- } else {
- uint8 attrib = crtc.attrib.expand[cy][cx];
- // for SORCERIAN music library (XM8 version 1.20)
- color = (attrib >> 5) | color_mask;
-// color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
+ uint8_t color = text_color[y >> 1][cx];
+ uint8_t r = gvram_r[addr];
+ if(text_reverse[y >> 1][cx]) {
+ r ^= 0xff;
}
- uint8 r = gvram_r[addr];
addr++;
- uint8 *dest = &graph[y][x];
+ uint8_t *dest = &graph[y][x];
dest[0] = (r & 0x80) ? color : 0;
dest[1] = (r & 0x40) ? color : 0;
dest[2] = (r & 0x20) ? color : 0;
void PC88::request_intr(int level, bool status)
{
- uint8 bit = 1 << level;
+ uint8_t bit = 1 << level;
if(status) {
// for Nobunaga Fuunroku Opening & MID-GARTS Opening (XM8 version 1.00)
d_cpu->set_intr_line(((intr_req & intr_mask1 & intr_mask2) != 0), true, 0);
}
-uint32 PC88::intr_ack()
+uint32_t PC88::get_intr_ack()
{
- uint8 ai = intr_req & intr_mask1 & intr_mask2;
+ uint8_t ai = intr_req & intr_mask1 & intr_mask2;
for(int i = 0; i < 8; i++, ai >>= 1) {
if(ai & 1) {
return 0;
}
-void PC88::intr_ei()
+void PC88::notify_intr_ei()
{
update_intr();
}
cursor.type = cursor.mode = -1;
cursor.x = cursor.y = -1;
attrib.data = 0xe0;
- attrib.mask = 0xff;
attrib.num = 20;
width = 80;
height = 25;
intr_mask = 3;
}
-void pc88_crtc_t::write_cmd(uint8 data)
+void pc88_crtc_t::write_cmd(uint8_t data)
{
cmd = (data >> 5) & 7;
cmd_ptr = 0;
switch(cmd) {
case 0: // reset
status &= ~0x16;
+ status |= 0x80; // fix
cursor.x = cursor.y = -1;
break;
case 1: // start display
reverse = data & 1;
- status |= 0x10;
+// status |= 0x10;
+ status |= 0x90; // fix
status &= ~8;
break;
case 2: // set interrupt mask
if(!(data & 1)) {
- status = 0; // from M88
+// status = 0; // from M88
+ status = 0x80; // fix
}
intr_mask = data & 3;
break;
}
}
-void pc88_crtc_t::write_param(uint8 data)
+void pc88_crtc_t::write_param(uint8_t data)
{
switch(cmd) {
case 0:
break;
}
break;
+ case 6:
+ status = 0;
+ break;
}
cmd_ptr++;
}
-uint32 pc88_crtc_t::read_param()
+uint32_t pc88_crtc_t::read_param()
{
- uint32 val = 0xff;
+ uint32_t val = 0xff;
switch(cmd) {
case 3: // read light pen
return val;
}
-uint32 pc88_crtc_t::read_status()
+uint32_t pc88_crtc_t::read_status()
{
if(status & 8) {
return status & ~0x10;
vblank = true;
}
-void pc88_crtc_t::write_buffer(uint8 data)
+void pc88_crtc_t::write_buffer(uint8_t data)
{
buffer[(buffer_ptr++) & 0x3fff] = data;
}
-uint8 pc88_crtc_t::read_buffer(int ofs)
+uint8_t pc88_crtc_t::read_buffer(int ofs)
{
if(ofs < buffer_ptr) {
return buffer[ofs];
for(int cy = 0, ytop = 0, ofs = 0; cy < height && ytop < 200; cy++, ytop += char_height_tmp, ofs += 80 + attrib.num * 2) {
for(int cx = 0; cx < width; cx += 2) {
set_attrib(read_buffer(ofs + cx + 1));
- attrib.expand[cy][cx] = attrib.expand[cy][cx + 1] = attrib.data & attrib.mask;
+ attrib.expand[cy][cx] = attrib.expand[cy][cx + 1] = attrib.data;
}
if((status & 8) && exitline == -1) {
exitline = cy;
memset(attrib.expand, 0xe0, sizeof(attrib.expand));
} else {
for(int cy = 0, ytop = 0, ofs = 0; cy < height && ytop < 200; cy++, ytop += char_height_tmp, ofs += 80 + attrib.num * 2) {
- uint8 flags[128];
+ uint8_t flags[128];
memset(flags, 0, sizeof(flags));
for(int i = 2 * (attrib.num - 1); i >= 0; i -= 2) {
flags[read_buffer(ofs + i + 80) & 0x7f] = 1;
}
+ attrib.data &= 0xf3; // for PC-8801mkIIFR \95t\91®\83f\83\82
+
for(int cx = 0, pos = 0; cx < width; cx++) {
if(flags[cx]) {
set_attrib(read_buffer(ofs + pos + 81));
pos += 2;
}
- attrib.expand[cy][cx] = attrib.data & attrib.mask;
+ attrib.expand[cy][cx] = attrib.data;
}
if((status & 8) && exitline == -1) {
exitline = cy;
if((cursor.type & 1) && blink.cursor) {
// no cursor
} else {
- static const uint8 ctype[5] = {0, 8, 8, 1, 1};
+ static const uint8_t ctype[5] = {0, 8, 8, 1, 1};
attrib.expand[cursor.y][cursor.x] ^= ctype[cursor.type + 1];
}
}
if(exitline != -1) {
for(int cy = exitline; cy < 200; cy++) {
memset(&text.expand[cy][0], 0, width);
- memset(&attrib.expand[cy][0], 0, width);
+#if 1
+ // SORCERIAN Music Library ver-2.1
+ memset(&attrib.expand[cy][0], 0xe0, width); // color=7
+#else
+ // from ePC-8801MA\89ü
+ memset(&attrib.expand[cy][0], 0x00, width);
+#endif
}
}
}
-void pc88_crtc_t::set_attrib(uint8 code)
+void pc88_crtc_t::set_attrib(uint8_t code)
{
if(mode & 2) {
// color
if(code & 8) {
attrib.data = (attrib.data & 0x0f) | (code & 0xf0);
- attrib.mask = 0xf3; //for PC-8801mkIIFR \95t\91®\83f\83\82
} else {
attrib.data = (attrib.data & 0xf0) | ((code >> 2) & 0x0d) | ((code << 1) & 2);
attrib.data ^= reverse;
attrib.data ^= ((code & 2) && !(code & 1)) ? blink.attrib : 0;
- attrib.mask = 0xff;
}
} else {
attrib.data = 0xe0 | ((code >> 3) & 0x10) | ((code >> 2) & 0x0d) | ((code << 1) & 2);
attrib.data ^= reverse;
attrib.data ^= ((code & 2) && !(code & 1)) ? blink.attrib : 0;
- attrib.mask = 0xff;
}
}
DMAC (uPD8257)
---------------------------------------------------------------------------- */
-void pc88_dmac_t::write_io8(uint32 addr, uint32 data)
+void pc88_dmac_t::write_io8(uint32_t addr, uint32_t data)
{
int c = (addr >> 1) & 3;
} else {
if((mode & 0x80) && c == 2) {
ch[3].addr.b.h = data;
+ ch[3].addr.b.h2 = ch[3].addr.b.h3 = 0;
}
ch[c].addr.b.h = data;
+ ch[c].addr.b.h2 = ch[c].addr.b.h3 = 0;
}
high_low = !high_low;
break;
} else {
if((mode & 0x80) && c == 2) {
ch[3].count.b.h = data & 0x3f;
+ ch[3].count.b.h2 = ch[3].count.b.h3 = 0;
ch[3].mode = data & 0xc0;
}
ch[c].count.b.h = data & 0x3f;
+ ch[c].count.b.h2 = ch[c].count.b.h3 = 0;
ch[c].mode = data & 0xc0;
}
high_low = !high_low;
}
}
-uint32 pc88_dmac_t::read_io8(uint32 addr)
+uint32_t pc88_dmac_t::read_io8(uint32_t addr)
{
- uint32 val = 0xff;
+ uint32_t val = 0xff;
int c = (addr >> 1) & 3;
switch(addr & 0x0f) {
{
if(ch[c].running) {
while(nbytes > 0 && ch[c].count.sd >= 0) {
-// if(ch[c].mode == 0x80) {
+ if(ch[c].mode == 0x80) {
ch[c].io->write_dma_io8(0, mem->read_dma_data8(ch[c].addr.w.l));
-// } else if(ch[c].mode == 0x40) {
-// mem->write_dma_data8(ch[c].addr.w.l, ch[c].io->read_dma_io8(0));
-// }
+ } else if(ch[c].mode == 0x40) {
+ mem->write_dma_data8(ch[c].addr.w.l, ch[c].io->read_dma_io8(0));
+ } else if(ch[c].mode == 0x00) {
+ ch[c].io->read_dma_io8(0); // verify
+ }
ch[c].addr.sd++;
ch[c].count.sd--;
nbytes--;
}
+ if(ch[c].count.sd < 0) {
+ finish(c);
+ }
}
}
{
if(ch[c].running) {
while(ch[c].count.sd >= 0) {
-// if(ch[c].mode == 0x80) {
+ if(ch[c].mode == 0x80) {
ch[c].io->write_dma_io8(0, mem->read_dma_data8(ch[c].addr.w.l));
-// } else if(ch[c].mode == 0x40) {
-// mem->write_dma_data8(ch[c].addr.w.l, ch[c].io->read_dma_io8(0));
-// }
+ } else if(ch[c].mode == 0x40) {
+ mem->write_dma_data8(ch[c].addr.w.l, ch[c].io->read_dma_io8(0));
+ } else if(ch[c].mode == 0x00) {
+ ch[c].io->read_dma_io8(0); // verify
+ }
ch[c].addr.sd++;
ch[c].count.sd--;
}
}
}
-
-#define STATE_VERSION 5
-
-void PC88::save_state(FILEIO* state_fio)
-{
- state_fio->FputUint32(STATE_VERSION);
- state_fio->FputInt32(this_device_id);
-
- state_fio->Fwrite(ram, sizeof(ram), 1);
-#if defined(PC88_EXRAM_BANKS)
- state_fio->Fwrite(exram, sizeof(exram), 1);
-#endif
- state_fio->Fwrite(gvram, sizeof(gvram), 1);
- state_fio->Fwrite(tvram, sizeof(tvram), 1);
- state_fio->Fwrite(port, sizeof(port), 1);
- state_fio->Fwrite(&crtc, sizeof(crtc), 1);
- state_fio->Fwrite(&dmac, sizeof(dmac), 1);
- state_fio->Fwrite(alu_reg, sizeof(alu_reg), 1);
- state_fio->FputUint8(gvram_plane);
- state_fio->FputUint8(gvram_sel);
- state_fio->FputBool(cpu_clock_low);
-#if defined(SUPPORT_PC88_HIGH_CLOCK)
- state_fio->FputBool(cpu_clock_high_fe2);
-#endif
- state_fio->FputBool(mem_wait_on);
- state_fio->FputInt32(m1_wait_clocks);
- state_fio->FputInt32(f000_m1_wait_clocks);
- state_fio->FputInt32(mem_wait_clocks_r);
- state_fio->FputInt32(mem_wait_clocks_w);
- state_fio->FputInt32(tvram_wait_clocks_r);
- state_fio->FputInt32(tvram_wait_clocks_w);
- state_fio->FputInt32(gvram_wait_clocks_r);
- state_fio->FputInt32(gvram_wait_clocks_w);
- state_fio->FputInt32(busreq_clocks);
- state_fio->Fwrite(palette, sizeof(palette), 1);
- state_fio->FputBool(update_palette);
- state_fio->FputBool(hireso);
- state_fio->Fwrite(text, sizeof(text), 1);
- state_fio->Fwrite(graph, sizeof(graph), 1);
- state_fio->Fwrite(palette_text_pc, sizeof(palette_text_pc), 1);
- state_fio->Fwrite(palette_graph_pc, sizeof(palette_graph_pc), 1);
- state_fio->FputBool(usart_dcd);
- state_fio->FputBool(opn_busy);
- state_fio->FputUint8(key_caps);
- state_fio->FputUint8(key_kana);
-#ifdef SUPPORT_PC88_JOYSTICK
- state_fio->FputUint32(mouse_strobe_clock);
- state_fio->FputUint32(mouse_strobe_clock_lim);
- state_fio->FputInt32(mouse_phase);
- state_fio->FputInt32(mouse_dx);
- state_fio->FputInt32(mouse_dy);
- state_fio->FputInt32(mouse_lx);
- state_fio->FputInt32(mouse_ly);
-#endif
- state_fio->FputUint8(intr_req);
- state_fio->FputBool(intr_req_sound);
-#ifdef SUPPORT_PC88_SB2
- state_fio->FputBool(intr_req_sb2);
-#endif
- state_fio->FputUint8(intr_mask1);
- state_fio->FputUint8(intr_mask2);
- state_fio->FputBool(cmt_play);
- state_fio->FputBool(cmt_rec);
- state_fio->Fwrite(rec_file_path, sizeof(rec_file_path), 1);
- if(cmt_rec && cmt_fio->IsOpened()) {
- int length_tmp = (int)cmt_fio->Ftell();
- cmt_fio->Fseek(0, FILEIO_SEEK_SET);
- state_fio->FputInt32(length_tmp);
- while(length_tmp != 0) {
- uint8 buffer[1024];
- int length_rw = min(length_tmp, (int)sizeof(buffer));
- cmt_fio->Fread(buffer, length_rw, 1);
- state_fio->Fwrite(buffer, length_rw, 1);
- length_tmp -= length_rw;
- }
- } else {
- state_fio->FputInt32(0);
- }
- state_fio->FputInt32(cmt_bufptr);
- state_fio->FputInt32(cmt_bufcnt);
- state_fio->Fwrite(cmt_buffer, sizeof(cmt_buffer), 1);
- state_fio->Fwrite(cmt_data_carrier, sizeof(cmt_data_carrier), 1);
- state_fio->FputInt32(cmt_data_carrier_cnt);
- state_fio->FputInt32(cmt_register_id);
- state_fio->FputBool(beep_on);
- state_fio->FputBool(beep_signal);
- state_fio->FputBool(sing_signal);
-#ifdef SUPPORT_PC88_PCG8100
- state_fio->FputUint16(pcg_addr);
- state_fio->FputUint8(pcg_data);
- state_fio->FputUint8(pcg_ctrl);
- state_fio->Fwrite(pcg_pattern, sizeof(pcg_pattern), 1);
-#endif
-#ifdef NIPPY_PATCH
- state_fio->FputBool(nippy_patch);
-#endif
-}
+#define STATE_VERSION 10
-bool PC88::load_state(FILEIO* state_fio)
+bool PC88::process_state(FILEIO* state_fio, bool loading)
{
- release_tape();
-
- if(state_fio->FgetUint32() != STATE_VERSION) {
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
return false;
}
- if(state_fio->FgetInt32() != this_device_id) {
+ if(!state_fio->StateCheckInt32(this_device_id)) {
return false;
}
- state_fio->Fread(ram, sizeof(ram), 1);
+ state_fio->StateArray(ram, sizeof(ram), 1);
#if defined(PC88_EXRAM_BANKS)
- state_fio->Fread(exram, sizeof(exram), 1);
-#endif
- state_fio->Fread(gvram, sizeof(gvram), 1);
- state_fio->Fread(tvram, sizeof(tvram), 1);
- state_fio->Fread(port, sizeof(port), 1);
- state_fio->Fread(&crtc, sizeof(crtc), 1);
- state_fio->Fread(&dmac, sizeof(dmac), 1);
- state_fio->Fread(alu_reg, sizeof(alu_reg), 1);
- gvram_plane = state_fio->FgetUint8();
- gvram_sel = state_fio->FgetUint8();
- cpu_clock_low = state_fio->FgetBool();
+ state_fio->StateArray(exram, sizeof(exram), 1);
+#endif
+ state_fio->StateArray(gvram, sizeof(gvram), 1);
+ state_fio->StateArray(tvram, sizeof(tvram), 1);
+ state_fio->StateArray(port, sizeof(port), 1);
+ state_fio->StateValue(crtc.blink.rate);
+ state_fio->StateValue(crtc.blink.counter);
+ state_fio->StateValue(crtc.blink.cursor);
+ state_fio->StateValue(crtc.blink.attrib);
+ state_fio->StateValue(crtc.cursor.type);
+ state_fio->StateValue(crtc.cursor.mode);
+ state_fio->StateValue(crtc.cursor.x);
+ state_fio->StateValue(crtc.cursor.y);
+ state_fio->StateValue(crtc.attrib.data);
+ state_fio->StateValue(crtc.attrib.num);
+ state_fio->StateArray(&crtc.attrib.expand[0][0], sizeof(crtc.attrib.expand), 1);
+ state_fio->StateArray(&crtc.text.expand[0][0], sizeof(crtc.text.expand), 1);
+ state_fio->StateValue(crtc.width);
+ state_fio->StateValue(crtc.height);
+ state_fio->StateValue(crtc.char_height);
+ state_fio->StateValue(crtc.skip_line);
+ state_fio->StateValue(crtc.vretrace);
+ state_fio->StateValue(crtc.timing_changed);
+ state_fio->StateArray(crtc.buffer, sizeof(crtc.buffer), 1);
+ state_fio->StateValue(crtc.buffer_ptr);
+ state_fio->StateValue(crtc.cmd);
+ state_fio->StateValue(crtc.cmd_ptr);
+ state_fio->StateValue(crtc.mode);
+ state_fio->StateValue(crtc.reverse);
+ state_fio->StateValue(crtc.intr_mask);
+ state_fio->StateValue(crtc.status);
+ state_fio->StateValue(crtc.vblank);
+ for(int i = 0; i < array_length(dmac.ch); i++) {
+ state_fio->StateValue(dmac.ch[i].addr);
+ state_fio->StateValue(dmac.ch[i].count);
+ state_fio->StateValue(dmac.ch[i].mode);
+ state_fio->StateValue(dmac.ch[i].nbytes);
+ state_fio->StateValue(dmac.ch[i].running);
+ }
+ state_fio->StateValue(dmac.mode);
+ state_fio->StateValue(dmac.status);
+ state_fio->StateValue(dmac.high_low);
+ state_fio->StateArray(alu_reg, sizeof(alu_reg), 1);
+ state_fio->StateValue(gvram_plane);
+ state_fio->StateValue(gvram_sel);
+ state_fio->StateValue(cpu_clock_low);
#if defined(SUPPORT_PC88_HIGH_CLOCK)
- cpu_clock_high_fe2 = state_fio->FgetBool();
-#endif
- mem_wait_on = state_fio->FgetBool();
- m1_wait_clocks = state_fio->FgetInt32();
- f000_m1_wait_clocks = state_fio->FgetInt32();
- mem_wait_clocks_r = state_fio->FgetInt32();
- mem_wait_clocks_w = state_fio->FgetInt32();
- tvram_wait_clocks_r = state_fio->FgetInt32();
- tvram_wait_clocks_w = state_fio->FgetInt32();
- gvram_wait_clocks_r = state_fio->FgetInt32();
- gvram_wait_clocks_w = state_fio->FgetInt32();
- busreq_clocks = state_fio->FgetInt32();
- state_fio->Fread(palette, sizeof(palette), 1);
- update_palette = state_fio->FgetBool();
- hireso = state_fio->FgetBool();
- state_fio->Fread(text, sizeof(text), 1);
- state_fio->Fread(graph, sizeof(graph), 1);
- state_fio->Fread(palette_text_pc, sizeof(palette_text_pc), 1);
- state_fio->Fread(palette_graph_pc, sizeof(palette_graph_pc), 1);
- usart_dcd = state_fio->FgetBool();
- opn_busy = state_fio->FgetBool();
- key_caps = state_fio->FgetUint8();
- key_kana = state_fio->FgetUint8();
+ state_fio->StateValue(cpu_clock_high_fe2);
+#endif
+ state_fio->StateValue(mem_wait_on);
+ state_fio->StateValue(m1_wait_clocks);
+ state_fio->StateValue(f000_m1_wait_clocks);
+ state_fio->StateValue(mem_wait_clocks_r);
+ state_fio->StateValue(mem_wait_clocks_w);
+ state_fio->StateValue(tvram_wait_clocks_r);
+ state_fio->StateValue(tvram_wait_clocks_w);
+ state_fio->StateValue(gvram_wait_clocks_r);
+ state_fio->StateValue(gvram_wait_clocks_w);
+ state_fio->StateValue(busreq_clocks);
+ for(int i = 0; i < array_length(palette); i++) {
+ state_fio->StateValue(palette[i].r);
+ state_fio->StateValue(palette[i].g);
+ state_fio->StateValue(palette[i].b);
+ }
+// state_fio->StateValue(update_palette);
+ state_fio->StateValue(hireso);
+ state_fio->StateArray(&text[0][0], sizeof(text), 1);
+ state_fio->StateArray(&graph[0][0], sizeof(graph), 1);
+/*
+ for(int i = 0; i < 9; i++) {
+ state_fio->StateValue(palette_digital[i].b);
+ state_fio->StateValue(palette_digital[i].r);
+ state_fio->StateValue(palette_digital[i].g);
+ state_fio->StateValue(palette_analog [i].b);
+ state_fio->StateValue(palette_analog [i].r);
+ state_fio->StateValue(palette_analog [i].g);
+ }
+*/
+ state_fio->StateValue(usart_dcd);
+ state_fio->StateValue(opn_busy);
+ state_fio->StateValue(key_caps);
+ state_fio->StateValue(key_kana);
#ifdef SUPPORT_PC88_JOYSTICK
- mouse_strobe_clock = state_fio->FgetUint32();
- mouse_strobe_clock_lim = state_fio->FgetUint32();
- mouse_phase = state_fio->FgetInt32();
- mouse_dx = state_fio->FgetInt32();
- mouse_dy = state_fio->FgetInt32();
- mouse_lx = state_fio->FgetInt32();
- mouse_ly = state_fio->FgetInt32();
-#endif
- intr_req = state_fio->FgetUint8();
- intr_req_sound = state_fio->FgetBool();
+ state_fio->StateValue(mouse_strobe_clock);
+ state_fio->StateValue(mouse_strobe_clock_lim);
+ state_fio->StateValue(mouse_phase);
+ state_fio->StateValue(mouse_dx);
+ state_fio->StateValue(mouse_dy);
+ state_fio->StateValue(mouse_lx);
+ state_fio->StateValue(mouse_ly);
+#endif
+ state_fio->StateValue(intr_req);
+ state_fio->StateValue(intr_req_sound);
#ifdef SUPPORT_PC88_SB2
- intr_req_sb2 = state_fio->FgetBool();
-#endif
- intr_mask1 = state_fio->FgetUint8();
- intr_mask2 = state_fio->FgetUint8();
- cmt_play = state_fio->FgetBool();
- cmt_rec = state_fio->FgetBool();
- state_fio->Fread(rec_file_path, sizeof(rec_file_path), 1);
- int length_tmp = state_fio->FgetInt32();
- if(cmt_rec) {
- cmt_fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
- while(length_tmp != 0) {
- uint8 buffer[1024];
- int length_rw = min(length_tmp, (int)sizeof(buffer));
- state_fio->Fread(buffer, length_rw, 1);
- if(cmt_fio->IsOpened()) {
- cmt_fio->Fwrite(buffer, length_rw, 1);
- }
- length_tmp -= length_rw;
- }
- }
- cmt_bufptr = state_fio->FgetInt32();
- cmt_bufcnt = state_fio->FgetInt32();
- state_fio->Fread(cmt_buffer, sizeof(cmt_buffer), 1);
- state_fio->Fread(cmt_data_carrier, sizeof(cmt_data_carrier), 1);
- cmt_data_carrier_cnt = state_fio->FgetInt32();
- cmt_register_id = state_fio->FgetInt32();
- beep_on = state_fio->FgetBool();
- beep_signal = state_fio->FgetBool();
- sing_signal = state_fio->FgetBool();
+ state_fio->StateValue(intr_req_sb2);
+#endif
+ state_fio->StateValue(intr_mask1);
+ state_fio->StateValue(intr_mask2);
+ state_fio->StateValue(cmt_play);
+ state_fio->StateValue(cmt_rec);
+ state_fio->StateArray(rec_file_path, sizeof(rec_file_path), 1);
+ if(loading) {
+ int length_tmp = state_fio->FgetInt32_LE();
+ if(cmt_rec) {
+ cmt_fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
+ while(length_tmp != 0) {
+ uint8_t buffer[1024];
+ int length_rw = min(length_tmp, (int)sizeof(buffer));
+ state_fio->Fread(buffer, length_rw, 1);
+ if(cmt_fio->IsOpened()) {
+ cmt_fio->Fwrite(buffer, length_rw, 1);
+ }
+ length_tmp -= length_rw;
+ }
+ }
+ } else {
+ if(cmt_rec && cmt_fio->IsOpened()) {
+ int length_tmp = (int)cmt_fio->Ftell();
+ cmt_fio->Fseek(0, FILEIO_SEEK_SET);
+ state_fio->FputInt32_LE(length_tmp);
+ while(length_tmp != 0) {
+ uint8_t buffer[1024];
+ int length_rw = min(length_tmp, (int)sizeof(buffer));
+ cmt_fio->Fread(buffer, length_rw, 1);
+ state_fio->Fwrite(buffer, length_rw, 1);
+ length_tmp -= length_rw;
+ }
+ } else {
+ state_fio->FputInt32_LE(0);
+ }
+ }
+ state_fio->StateValue(cmt_bufptr);
+ state_fio->StateValue(cmt_bufcnt);
+ state_fio->StateArray(cmt_buffer, sizeof(cmt_buffer), 1);
+ state_fio->StateArray(cmt_data_carrier, sizeof(cmt_data_carrier), 1);
+ state_fio->StateValue(cmt_data_carrier_cnt);
+ state_fio->StateValue(cmt_register_id);
+ state_fio->StateValue(beep_on);
+ state_fio->StateValue(beep_signal);
+ state_fio->StateValue(sing_signal);
#ifdef SUPPORT_PC88_PCG8100
- pcg_addr = state_fio->FgetUint16();
- pcg_data = state_fio->FgetUint8();
- pcg_ctrl = state_fio->FgetUint8();
- state_fio->Fread(pcg_pattern, sizeof(pcg_pattern), 1);
+ state_fio->StateValue(pcg_addr);
+ state_fio->StateValue(pcg_data);
+ state_fio->StateValue(pcg_ctrl);
+ state_fio->StateArray(pcg_pattern, sizeof(pcg_pattern), 1);
+#endif
+#ifdef SUPPORT_PC88_CDROM
+ state_fio->StateValue(cdda_register_id);
+ state_fio->StateValue(cdda_volume);
#endif
#ifdef NIPPY_PATCH
- nippy_patch = state_fio->FgetBool();
+ state_fio->StateValue(nippy_patch);
#endif
// post process
- dmac.mem = dmac.ch[2].io = this;
- dmac.ch[0].io = dmac.ch[1].io = dmac.ch[3].io = vm->dummy;
+ if(loading) {
#if defined(_PC8001SR)
- update_n80_write();
- update_n80_read();
+ update_n80_write();
+ update_n80_read();
#else
- update_low_memmap();
- update_tvram_memmap();
+ update_low_memmap();
+ update_tvram_memmap();
#endif
+ // force update palette when state file is loaded
+ update_palette = true;
+ }
return true;
}
-
+}
+