SHARP X1 Emulator 'eX1'
SHARP X1twin Emulator 'eX1twin'
SHARP X1turbo Emulator 'eX1turbo'
+ SHARP X1turboZ Emulator 'eX1turboZ'
Author : Takeda.Toshiya
Date : 2009.03.15-
- [ pseudo sub cpu ]
+ [ pseudo sub system ]
*/
#include "psub.h"
#include "../datarec.h"
#include "../i8255.h"
#include "../../fifo.h"
-
//#define DEBUG_COMMAND
#define EVENT_1SEC 0
// TODO: XFER = 0xe8 ???
-static const uint8 keycode[256] = { // normal
+namespace X1 {
+
+static const uint8_t keycode[256] = { // normal
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_s[256] = { // shift
+static const uint8_t keycode_s[256] = { // shift
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_g[256] = { // graph
+static const uint8_t keycode_g[256] = { // graph
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_c[256] = { // ctrl
+static const uint8_t keycode_c[256] = { // ctrl
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_k[256] = { // kana
+static const uint8_t keycode_k[256] = { // kana
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_ks[256] = { // kana+shift
+static const uint8_t keycode_ks[256] = { // kana+shift
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_kb[256] = { // kana (mode b)
+static const uint8_t keycode_kb[256] = { // kana (mode b)
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static const uint8 keycode_ksb[256] = { // kana+shift (mode b)
+static const uint8_t keycode_ksb[256] = { // kana+shift (mode b)
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
void PSUB::initialize()
{
key_buf = new FIFO(8);
- key_stat = emu->key_buffer();
+ key_stat = emu->get_key_buffer();
get_host_time(&cur_time);
d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
}
-void PSUB::write_io8(uint32 addr, uint32 data)
+void PSUB::write_io8(uint32_t addr, uint32_t data)
{
inbuf = data;
set_ibf(true);
}
-uint32 PSUB::read_io8(uint32 addr)
+uint32_t PSUB::read_io8(uint32_t addr)
{
set_obf(true);
intr = false;
return outbuf;
}
-void PSUB::write_signal(int id, uint32 data, uint32 mask)
+void PSUB::write_signal(int id, uint32_t data, uint32_t mask)
{
if(id == SIG_PSUB_TAPE_REMOTE) {
if(!(data & mask) && (play || rec)) {
}
}
-uint32 PSUB::intr_ack()
+uint32_t PSUB::get_intr_ack()
{
return read_io8(0x1900);
}
-void PSUB::intr_reti()
+void PSUB::notify_intr_reti()
{
// NOTE: some software uses RET, not RETI ???
}
d_cpu->set_intr_line(false, true, intr_bit);
}
}
+#if defined(Q_OS_WIN)
+DLL_PREFIX_I struct cur_time_s cur_time;
+#endif
void PSUB::event_callback(int event_id, int err)
{
#ifdef _X1TWIN
// clear key buffer
- if(vm->cart_inserted(0)) {
+ if(vm->is_cart_inserted(0)) {
// clear key
key_buf->clear();
}
// this is command parameter
*datap++ = inbuf;
#ifdef DEBUG_COMMAND
- emu->out_debug_log(_T(" %2x"), inbuf);
+ this->out_debug_log(_T(" %2x"), inbuf);
#endif
cmdlen--;
} else {
// this is new command
mode = inbuf;
#ifdef DEBUG_COMMAND
- emu->out_debug_log(_T("X1 PSUB: cmd %2x"), inbuf);
+ this->out_debug_log(_T("X1 PSUB: cmd %2x"), inbuf);
#endif
if(0xd0 <= mode && mode <= 0xd7) {
cmdlen = 6;
// this command has no parameters or all parameters are received,
// so cpu processes the command
#ifdef DEBUG_COMMAND
- emu->out_debug_log(_T("\n"));
+ this->out_debug_log(_T("\n"));
#endif
process_cmd();
}
key_kana_locked = !key_kana_locked;
break;
}
- uint16 lh = get_key(code, repeat);
+ uint16_t lh = get_key(code, repeat);
if(lh & 0xff00) {
lh &= ~0x40;
if(!databuf[0x14][0]) {
void PSUB::process_cmd()
{
- uint16 lh = 0xff;
+ uint16_t lh = 0xff;
// preset
if(0xd0 <= mode && mode < 0xf0) {
case 0xe3:
// game key read (for turbo)
databuf[0x13][0] = databuf[0x13][1] = databuf[0x13][2] = 0;
- if(config.device_type != 0) {
+ if(config.keyboard_type != 0) {
databuf[0x13][0] |= key_stat[0x51] ? 0x80 : 0; // q
databuf[0x13][0] |= key_stat[0x57] ? 0x40 : 0; // w
databuf[0x13][0] |= key_stat[0x45] ? 0x20 : 0; // e
databuf[0x16][0] |= get_key_low() & 0x1f;
#endif
#ifdef DEBUG_COMMAND
- emu->out_debug_log(_T("X1 PSUB: keycode %2x %2x\n"), databuf[0x16][0], databuf[0x16][1]);
+ this->out_debug_log(_T("X1 PSUB: keycode %2x %2x\n"), databuf[0x16][0], databuf[0x16][1]);
#endif
datalen = 2;
break;
case 0xe9:
// CMT controll
if(databuf[0x1a][0] != databuf[0x19][0]) {
- uint8 new_status = databuf[0x19][0];
+ uint8_t new_status = databuf[0x19][0];
switch(databuf[0x19][0]) {
case CMT_EJECT:
- emu->close_tape();
+ emu->close_tape(0);
break;
case CMT_STOP:
d_drec->set_remote(false);
break;
#ifdef DEBUG_COMMAND
default:
- emu->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
+ this->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
break;
#endif
}
+
databuf[0x1a][0] = new_status;
}
break;
break;
#ifdef DEBUG_COMMAND
default:
- emu->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
+ this->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
#endif
}
}
}
}
-uint8 PSUB::get_key_low()
+uint8_t PSUB::get_key_low()
{
- uint8 l = 0xff;
+ uint8_t l = 0xff;
if(key_ctrl) {
l &= ~0x01; // ctrl
return l;
}
-uint16 PSUB::get_key(int code, bool repeat)
+uint16_t PSUB::get_key(int code, bool repeat)
{
- uint8 l = get_key_low();
- uint8 h = 0;
+ uint8_t l = get_key_low();
+ uint8_t h = 0;
if(repeat) {
l &= ~0x20; // repeat
if(key_kana_locked) {
if(!(l & 0x02)) {
#ifdef _X1TURBO_FEATURE
- if(config.device_type != 0) {
+ if(config.keyboard_type != 0) {
h = keycode_ksb[code]; // kana+shift (mode b)
} else
#endif
h = keycode_ks[code]; // kana+shift
} else {
#ifdef _X1TURBO_FEATURE
- if(config.device_type != 0) {
+ if(config.keyboard_type != 0) {
h = keycode_kb[code]; // kana (mode b)
} else
#endif
#define STATE_VERSION 1
-void PSUB::save_state(FILEIO* state_fio)
+bool PSUB::process_state(FILEIO* state_fio, bool loading)
{
- state_fio->FputUint32(STATE_VERSION);
- state_fio->FputInt32(this_device_id);
-
- cur_time.save_state((void *)state_fio);
- state_fio->FputInt32(time_register_id);
- state_fio->Fwrite(databuf, sizeof(databuf), 1);
- state_fio->FputInt32((int)(datap - &databuf[0][0]));
- state_fio->FputUint8(mode);
- state_fio->FputUint8(inbuf);
- state_fio->FputUint8(outbuf);
- state_fio->FputBool(ibf);
- state_fio->FputBool(obf);
- state_fio->FputInt32(cmdlen);
- state_fio->FputInt32(datalen);
- key_buf->save_state((void *)state_fio);
- state_fio->FputInt32(key_prev);
- state_fio->FputInt32(key_break);
- state_fio->FputBool(key_shift);
- state_fio->FputBool(key_ctrl);
- state_fio->FputBool(key_graph);
- state_fio->FputBool(key_caps_locked);
- state_fio->FputBool(key_kana_locked);
- state_fio->FputInt32(key_register_id);
- state_fio->FputBool(play);
- state_fio->FputBool(rec);
- state_fio->FputBool(eot);
- state_fio->FputBool(iei);
- state_fio->FputBool(intr);
- state_fio->FputUint32(intr_bit);
-}
-
-bool PSUB::load_state(FILEIO* state_fio)
-{
- if(state_fio->FgetUint32() != STATE_VERSION) {
- return false;
- }
- if(state_fio->FgetInt32() != this_device_id) {
- return false;
- }
- if(!cur_time.load_state((void *)state_fio)) {
- return false;
- }
- time_register_id = state_fio->FgetInt32();
- state_fio->Fread(databuf, sizeof(databuf), 1);
- datap = &databuf[0][0] + state_fio->FgetInt32();
- mode = state_fio->FgetUint8();
- inbuf = state_fio->FgetUint8();
- outbuf = state_fio->FgetUint8();
- ibf = state_fio->FgetBool();
- obf = state_fio->FgetBool();
- cmdlen = state_fio->FgetInt32();
- datalen = state_fio->FgetInt32();
- if(!key_buf->load_state((void *)state_fio)) {
- return false;
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+ return false;
+ }
+ if(!state_fio->StateCheckInt32(this_device_id)) {
+ return false;
+ }
+ if(!cur_time.process_state((void *)state_fio, loading)) {
+ return false;
+ }
+ state_fio->StateInt32(time_register_id);
+ state_fio->StateBuffer(databuf, sizeof(databuf), 1);
+ if(loading) {
+ datap = &databuf[0][0] + state_fio->FgetInt32_LE();
+ } else {
+ state_fio->FputInt32_LE((int)(datap - &databuf[0][0]));
}
- key_prev = state_fio->FgetInt32();
- key_break = state_fio->FgetInt32();
- key_shift = state_fio->FgetBool();
- key_ctrl = state_fio->FgetBool();
- key_graph = state_fio->FgetBool();
- key_caps_locked = state_fio->FgetBool();
- key_kana_locked = state_fio->FgetBool();
- key_register_id = state_fio->FgetInt32();
- play = state_fio->FgetBool();
- rec = state_fio->FgetBool();
- eot = state_fio->FgetBool();
- iei = state_fio->FgetBool();
- intr = state_fio->FgetBool();
- intr_bit = state_fio->FgetUint32();
- return true;
+ state_fio->StateUint8(mode);
+ state_fio->StateUint8(inbuf);
+ state_fio->StateUint8(outbuf);
+ state_fio->StateBool(ibf);
+ state_fio->StateBool(obf);
+ state_fio->StateInt32(cmdlen);
+ state_fio->StateInt32(datalen);
+ if(!key_buf->process_state((void *)state_fio, loading)) {
+ return false;
+ }
+ state_fio->StateInt32(key_prev);
+ state_fio->StateInt32(key_break);
+ state_fio->StateBool(key_shift);
+ state_fio->StateBool(key_ctrl);
+ state_fio->StateBool(key_graph);
+ state_fio->StateBool(key_caps_locked);
+ state_fio->StateBool(key_kana_locked);
+ state_fio->StateInt32(key_register_id);
+ state_fio->StateBool(play);
+ state_fio->StateBool(rec);
+ state_fio->StateBool(eot);
+ state_fio->StateBool(iei);
+ state_fio->StateBool(intr);
+ state_fio->StateUint32(intr_bit);
+ return true;
}
+}