#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
+#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 int16_t 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
dest[6] = dest[7] = ((i & 8) ? 0xf0 : 0) | ((i & 0x80) ? 0x0f : 0);
}
- // initialize text/graph 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
- }
- for(int i = 0; i < 8; i++) {
- palette_graph_pc[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
+#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
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;
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;
{
addr &= 0xff;
#ifdef _IO_DEBUG_LOG
- this->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
}
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();
}
}
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
break;
case 0xe6:
// for Romancia (XM8 version 1.00)
- if((uint8_t)intr_mask2_table[data & 7] != intr_mask2) {
- intr_req &= ((uint8_t)intr_mask2_table[data & 7] & intr_mask2);
+ if(intr_mask2_table[data & 7] != intr_mask2) {
+ intr_req &= (intr_mask2_table[data & 7] & intr_mask2);
}
- intr_mask2 = (uint8_t)intr_mask2_table[data & 7];
+ intr_mask2 = intr_mask2_table[data & 7];
intr_req &= intr_mask2;
update_intr();
break;
#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) {
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:
uint32_t PC88::read_dma_data8(uint32_t addr)
{
+ // from ram
#if defined(_PC8001SR)
return ram[addr & 0xffff];
#else
#endif
}
+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
} 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);
}
}
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) {
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
}
}
// update 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)
draw_text();
// render graph screen
- scrntype_t *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_t 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_t b = (port[0x31] & 4) ? 7 : 0;
- uint8_t r = (i & 1) ? 7 : 0;
- uint8_t 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_t b = (port[0x54 + i] & 1) ? 7 : 0;
- uint8_t r = (port[0x54 + i] & 2) ? 7 : 0;
- uint8_t 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_t palette_text_back = palette_text_pc[0];
- scrntype_t 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_t* dest0 = emu->get_screen_buffer(y * 2);
- scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
- memset(dest0, 0, sizeof(scrntype_t) * 640);
- memset(dest1, 0, sizeof(scrntype_t) * 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_t* dest0 = emu->get_screen_buffer(y * 2);
- scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
- uint8_t* src_t = text[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_t t = src_t[x];
uint32_t g = src_g[x];
- dest0[x] = g ? palette_pc[g] : palette_text_pc[src_t[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 t = src_t[x];
- dest0[x] = t ? palette_text_pc[t] : palette_pc[src_g[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_t));
+#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_t* dest = emu->get_screen_buffer(y);
- uint8_t* src_t = text[y >> 1];
- uint8_t* src_g = graph[y];
-
for(int x = 0; x < 640; x++) {
uint32_t t = src_t[x];
- dest[x] = t ? palette_text_pc[t] : palette_pc[src_g[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()
{
- uint8_t ct = 0;
-
if(crtc.status & 0x88) {
+ // dma underrun
crtc.status &= ~0x80;
- ct = crtc.reverse ? 3 : 2;
+ 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;
- ct = 2;
- }
- if(ct) {
memset(crtc.text.expand, 0, 200 * 80);
- memset(crtc.attrib.expand, ct, 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_t color_mask = Port30_COLOR ? 0 : 7;
+ uint8_t code_expand, attr_expand;
if(!hireso) {
char_height <<= 1;
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_t attrib = crtc.attrib.expand[cy][cx];
+ 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_t 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_t *pattern = ((attrib & 0x10) ? sg_pattern : pcg_pattern) + code * 8;
#else
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];
- 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;
- }
+ 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;
}
}
}
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_t b0 = gvram_b0[addr];
uint8_t r0 = gvram_r0[addr];
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;
}
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_t brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
addr++;
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;
}
uint8_t *gvram_r1 = Port53_G4DS ? gvram_null : (gvram + 0x6000);
uint8_t *gvram_g1 = Port53_G5DS ? gvram_null : (gvram + 0xa000);
- int char_height = crtc.char_height ? crtc.char_height : 8;
- uint8_t color_mask = Port30_COLOR ? 0 : 7;
-
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_t attrib = crtc.attrib.expand[cy][cx];
- uint8_t color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
- uint8_t 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_t *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_t attrib_l = crtc.attrib.expand[cy][cx];
- uint8_t color_l = (attrib_l & 0xe0) ? ((attrib_l >> 5) | color_mask) : 8;
- uint8_t attrib_r = crtc.attrib.expand[cy][cx + 1];
- uint8_t color_r = (attrib_r & 0xe0) ? ((attrib_r >> 5) | color_mask) : 8;
- uint8_t 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_t *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);
+ }
}
}
}
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_t b = gvram_b[addr];
uint8_t r = gvram_r[addr];
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;
}
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_t brg = gvram_b[addr] | gvram_r[addr] | gvram_g[addr];
addr++;
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)) {
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_t 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_t attrib = crtc.attrib.expand[cy][cx];
- color = (attrib & 0xe0) ? ((attrib >> 5) | color_mask) : 8;
+ memcpy(graph[y + 1], graph[y], 640);
}
- uint8_t 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_t *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;
+ 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)) {
uint8_t *gvram_b = Port53_G0DS ? gvram_null : (gvram + 0x0000);
uint8_t *gvram_r = Port53_G1DS ? gvram_null : (gvram + 0x4000);
- int char_height = crtc.char_height ? crtc.char_height : 16;
- uint8_t color_mask = Port30_COLOR ? 0 : 7, color;
-
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_t 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;
+ }
addr++;
uint8_t *dest = &graph[y][x];
dest[0] = (b & 0x80) ? 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_t 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;
+ }
addr++;
uint8_t *dest = &graph[y][x];
dest[0] = (r & 0x80) ? color : 0;
cursor.type = cursor.mode = -1;
cursor.x = cursor.y = -1;
attrib.data = 0xe0;
- attrib.mask = 0xff;
attrib.num = 20;
width = 80;
height = 25;
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;
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(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
}
}
}
// 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;
}
}
} 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;
{
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
+#define STATE_VERSION 10
-void PC88::save_state(FILEIO* state_fio)
+bool PC88::process_state(FILEIO* state_fio, bool loading)
{
- 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_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(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
-}
-
-bool PC88::load_state(FILEIO* state_fio)
-{
- 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_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;
- }
- }
- 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;
}
-
+}
+