#include "mouse.h"
#if defined(SUPPORT_SASI_IF)
#include "sasi.h"
+#include "sasi_bios.h"
#endif
#if defined(SUPPORT_SCSI_IF)
#include "scsi.h"
#include "ide.h"
#endif
+#if defined(SUPPORT_CMT_IF)
+using PC9801::CMT;
+#endif
+#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
+using PC9801::CPUREG;
+#endif
+using PC9801::DISPLAY;
+using PC9801::DMAREG;
+using PC9801::FLOPPY;
+using PC9801::FMSOUND;
+using PC9801::JOYSTICK;
+using PC9801::KEYBOARD;
+using PC9801::MEMBUS;
+using PC9801::MOUSE;
+#if defined(SUPPORT_SASI_IF)
+using PC9801::SASI;
+using PC9801::BIOS;
+#endif
+#if defined(SUPPORT_SCSI_IF)
+using PC9801::SCSI;
+#endif
+#if defined(SUPPORT_IDE_IF)
+using PC9801::IDE;
+#endif
+
#if defined(SUPPORT_320KB_FDD_IF)
#include "../pc80s31k.h"
#include "../z80.h"
#include "../pc8801/pc88.h"
#endif
+#if defined(_PC98DO) || defined(_PC98DOPLUS)
+using PC88DEV::PC88;
+#endif
// ----------------------------------------------------------------------------
// initialize
// ----------------------------------------------------------------------------
-VM::VM(EMU* parent_emu) : emu(parent_emu)
+VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
{
// check configs
#if defined(_PC98DO) || defined(_PC98DOPLUS)
noise_head_up = new NOISE(this, emu);
#if defined(SUPPORT_SASI_IF)
sasi_host = new SCSI_HOST(this, emu);
- sasi_hdd = new SCSI_HDD(this, emu);
+ sasi_hdd = new SASI_HDD(this, emu);
sasi_hdd->set_device_name(_T("SASI Hard Disk Drive"));
sasi_hdd->scsi_id = 0;
sasi_hdd->bytes_per_sec = 625 * 1024; // 625KB/s
if(sound_type == 0 || sound_type == 1) {
opn = new YM2203(this, emu);
#ifdef SUPPORT_PC98_OPNA
+ opn->set_device_name(_T("YM2608 OPNA (PC-9801-86)"));
opn->is_ym2608 = true;
+#else
+ opn->set_device_name(_T("YM2203 OPN (PC-9801-26)"));
+ opn->is_ym2608 = false;
#endif
fmsound = new FMSOUND(this, emu);
joystick = new JOYSTICK(this, emu);
mouse = new MOUSE(this, emu);
#if defined(SUPPORT_SASI_IF)
sasi = new SASI(this, emu);
+ sasi_bios = new BIOS(this, emu);
#endif
#if defined(SUPPORT_SCSI_IF)
scsi = new SCSI(this, emu);
sasi->set_context_hdd(sasi_hdd);
sasi->set_context_dma(dma);
sasi->set_context_pic(pic);
+
+ sasi_bios->set_context_sasi(sasi);
+ sasi_bios->set_context_memory(memory);
+ sasi_bios->set_context_cpu(cpu);
+ sasi_bios->set_context_pic(pic);
+ cpu->set_context_bios(sasi_bios);
+
#endif
#if defined(SUPPORT_SCSI_IF)
dma->set_context_ch0(scsi);
pc88rtc = new UPD1990A(this, emu);
pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
pc88rtc->set_context_event_manager(pc88event);
- pc88opn = new YM2203(this, emu);
+ pc88opn1 = new YM2203(this, emu);
#ifdef SUPPORT_PC88_OPNA
- pc88opn->set_device_name(_T("YM2608 OPNA (PC-8801)"));
- pc88opn->is_ym2608 = true;
+ pc88opn1->set_device_name(_T("YM2608 OPNA (PC-8801)"));
+ pc88opn1->is_ym2608 = true;
#else
- pc88opn->set_device_name(_T("YM2203 OPN (PC-8801)"));
+ pc88opn1->set_device_name(_T("YM2203 OPN (PC-8801)"));
+ pc88opn1->is_ym2608 = false;
#endif
- pc88opn->set_context_event_manager(pc88event);
+ pc88opn1->set_context_event_manager(pc88event);
pc88cpu = new Z80(this, emu);
pc88cpu->set_device_name(_T("Z80 CPU (PC-8801)"));
pc88cpu->set_context_event_manager(pc88event);
pc88event->set_context_cpu(pc88cpu, (config.cpu_type == 1) ? 3993624 : 7987248);
pc88event->set_context_cpu(pc88cpu_sub, 3993624);
- pc88event->set_context_sound(pc88opn);
+ pc88event->set_context_sound(pc88opn1);
pc88event->set_context_sound(pc88pcm);
pc88event->set_context_sound(pc88noise_seek);
pc88event->set_context_sound(pc88noise_head_down);
pc88event->set_context_sound(pc88noise_head_up);
pc88->set_context_cpu(pc88cpu);
- pc88->set_context_opn(pc88opn);
+ pc88->set_context_opn1(pc88opn1);
pc88->set_context_pcm(pc88pcm);
pc88->set_context_pio(pc88pio);
pc88->set_context_prn(pc88prn);
#ifdef USE_DEBUGGER
pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
#endif
- pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
+ pc88opn1->set_context_irq(pc88, SIG_PC88_OPN1_IRQ, 1);
pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
#endif
// initialize all devices
+#if defined(__GIT_REPO_VERSION)
+ strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
+#endif
for(DEVICE* device = first_device; device; device = device->next_device) {
device->initialize();
}
- decl_state();
#if defined(_PC9801) || defined(_PC9801E)
fdc_2hd->get_disk_handler(0)->drive_num = 0;
#endif
#if defined(USE_HARD_DISK)
for(int drv = 0; drv < USE_HARD_DISK; drv++) {
+ if(!(config.last_hard_disk_path[drv][0] != _T('\0') && FILEIO::IsFileExisting(config.last_hard_disk_path[drv]))) {
#if defined(SUPPORT_SASI_IF)
- #if defined(OPEN_HARD_DISK_IN_RESET)
- create_local_path(hd_file_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv);
- #else
- open_hard_disk_tmp(drv, create_local_path(_T("SASI%d.DAT"), drv));
- #endif
+ create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv);
#endif
#if defined(SUPPORT_SCSI_IF)
- #if defined(OPEN_HARD_DISK_IN_RESET)
- create_local_path(hd_file_path[drv], _MAX_PATH, _T("SCSI%d.DAT"), drv);
- #else
- open_hard_disk_tmp(drv, create_local_path(_T("SCSI%d.DAT"), drv));
- #endif
+ create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SCSI%d.DAT"), drv);
#endif
#if defined(SUPPORT_IDE_IF)
- #if defined(OPEN_HARD_DISK_IN_RESET)
- create_local_path(hd_file_path[drv], _MAX_PATH, _T("IDE%d.DAT"), drv);
- #else
- open_hard_disk_tmp(drv, create_local_path(_T("IDE%d.DAT"), drv));
- #endif
+ create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("IDE%d.DAT"), drv);
#endif
+ }
}
#endif
}
#endif
#if defined(_PC98DO) || defined(_PC98DOPLUS)
- pc88opn->set_reg(0x29, 3); // for Misty Blue
+ pc88opn1->set_reg(0x29, 3); // for Misty Blue
pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
#endif
-
-#if defined(USE_HARD_DISK) && defined(OPEN_HARD_DISK_IN_RESET)
- // open/close hard disk images
- for(int drv = 0; drv < USE_HARD_DISK; drv++) {
- if(hd_file_path[drv][0] != _T('\0')) {
- open_hard_disk_tmp(drv, hd_file_path[drv]);
- } else {
- close_hard_disk_tmp(drv);
- }
- }
-#endif
}
void VM::run()
beep->initialize_sound(rate, 8000);
#endif
if(sound_type == 0 || sound_type == 1) {
-#ifdef HAS_YM2608
- opn->initialize_sound(rate, 7987248, samples, 0, 0);
-#else
- opn->initialize_sound(rate, 3993624, samples, 0, 0);
-#endif
+ if(opn->is_ym2608) {
+ opn->initialize_sound(rate, 7987248, samples, 0, 0);
+ } else {
+ opn->initialize_sound(rate, 3993624, samples, 0, 0);
+ }
} else if(sound_type == 2 || sound_type == 3) {
tms3631->initialize_sound(rate, 8000);
}
pc88event->initialize_sound(rate, samples);
// init sound gen
-#ifdef HAS_YM2608
- pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
-#else
- pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
-#endif
+ if(pc88opn1->is_ym2608) {
+ pc88opn1->initialize_sound(rate, 7987248, samples, 0, 0);
+ } else {
+ pc88opn1->initialize_sound(rate, 3993624, samples, 0, 0);
+ }
pc88pcm->initialize_sound(rate, 8000);
#endif
}
beep->set_volume(0, decibel_l, decibel_r);
#if defined(_PC98DO) || defined(_PC98DOPLUS)
} else if(ch-- == 0) {
- pc88opn->set_volume(0, decibel_l, decibel_r);
+ pc88opn1->set_volume(0, decibel_l, decibel_r);
} else if(ch-- == 0) {
- pc88opn->set_volume(1, decibel_l, decibel_r);
+ pc88opn1->set_volume(1, decibel_l, decibel_r);
#if defined(SUPPORT_PC88_OPNA)
} else if(ch-- == 0) {
- pc88opn->set_volume(2, decibel_l, decibel_r);
+ pc88opn1->set_volume(2, decibel_l, decibel_r);
} else if(ch-- == 0) {
- pc88opn->set_volume(3, decibel_l, decibel_r);
+ pc88opn1->set_volume(3, decibel_l, decibel_r);
#endif
} else if(ch-- == 0) {
pc88pcm->set_volume(0, decibel_l, decibel_r);
uint32_t VM::is_floppy_disk_accessed()
{
- uint32_t value = 0;
+ uint32_t status = 0;
#if defined(_PC98DO) || defined(_PC98DOPLUS)
if(boot_mode != 0) {
- value = pc88fdc_sub->read_signal(0) & 3;
+ status = pc88fdc_sub->read_signal(0) & 3;
} else {
- value = fdc->read_signal(0) & 3;
+ status = fdc->read_signal(0) & 3;
}
#else
for(int drv = 0; drv < USE_FLOPPY_DISK; drv += 2) {
UPD765A *controller = get_floppy_disk_controller(drv);
if(controller != NULL) {
- value |= (controller->read_signal(0) & 3) << drv;
+ status |= (controller->read_signal(0) & 3) << drv;
}
}
#endif
- return value;
+ return status;
}
UPD765A *VM::get_floppy_disk_controller(int drv)
void VM::open_hard_disk(int drv, const _TCHAR* file_path)
{
if(drv < USE_HARD_DISK) {
-#if defined(OPEN_HARD_DISK_IN_RESET)
- my_tcscpy_s(hd_file_path[drv], _MAX_PATH, file_path);
-#else
- open_hard_disk_tmp(drv, file_path);
+#if defined(SUPPORT_SASI_IF)
+ sasi_hdd->open(drv, file_path, 256);
+#endif
+#if defined(SUPPORT_SCSI_IF)
+ scsi_hdd[drv]->open(0, file_path, 512);
+#endif
+#if defined(SUPPORT_IDE_IF)
+ ide_hdd[drv]->open(0, file_path, 512);
#endif
}
}
void VM::close_hard_disk(int drv)
{
if(drv < USE_HARD_DISK) {
-#if defined(OPEN_HARD_DISK_IN_RESET)
- hd_file_path[drv][0] = _T('\0');
-#else
- close_hard_disk_tmp(drv);
+#if defined(SUPPORT_SASI_IF)
+ sasi_hdd->close(drv);
+#endif
+#if defined(SUPPORT_SCSI_IF)
+ scsi_hdd[drv]->close(0);
+#endif
+#if defined(SUPPORT_IDE_IF)
+ ide_hdd[drv]->close(0);
#endif
}
}
bool VM::is_hard_disk_inserted(int drv)
{
if(drv < USE_HARD_DISK) {
-#if defined(OPEN_HARD_DISK_IN_RESET)
- return (hd_file_path[drv][0] != _T('\0'));
-#else
- return is_hard_disk_inserted_tmp(drv);
+#if defined(SUPPORT_SASI_IF)
+ return sasi_hdd->mounted(drv);
+#endif
+#if defined(SUPPORT_SCSI_IF)
+ return scsi_hdd[drv]->mounted(0);
+#endif
+#if defined(SUPPORT_IDE_IF)
+ return ide_hdd[drv]->mounted(0);
#endif
}
return false;
uint32_t status = 0;
for(int drv = 0; drv < USE_HARD_DISK; drv++) {
- HARDDISK *handler = get_hard_disk_handler(drv);
-
- if(handler != NULL && handler->accessed()) {
+#if defined(SUPPORT_SASI_IF)
+ if(sasi_hdd->accessed(drv)) {
status |= 1 << drv;
}
- }
- return status;
-}
-
-void VM::open_hard_disk_tmp(int drv, const _TCHAR* file_path)
-{
- HARDDISK *handler = get_hard_disk_handler(drv);
-
- if(handler != NULL) {
- handler->open(file_path);
- }
-}
-
-void VM::close_hard_disk_tmp(int drv)
-{
- HARDDISK *handler = get_hard_disk_handler(drv);
-
- if(handler != NULL) {
- handler->close();
- }
-}
-
-bool VM::is_hard_disk_inserted_tmp(int drv)
-{
- HARDDISK *handler = get_hard_disk_handler(drv);
-
- if(handler != NULL) {
- return handler->mounted();
- }
- return false;
-}
-
-HARDDISK *VM::get_hard_disk_handler(int drv)
-{
- if(drv < USE_HARD_DISK) {
-#if defined(SUPPORT_SASI_IF)
- return sasi_hdd->get_disk_handler(drv);
#endif
#if defined(SUPPORT_SCSI_IF)
- return scsi_hdd[drv]->get_disk_handler(0);
+ if(scsi_hdd[drv]->accessed(0)) {
+ status |= 1 << drv;
+ }
#endif
#if defined(SUPPORT_IDE_IF)
- return ide_hdd[drv]->get_disk_handler(0);
+ if(ide_hdd[drv]->accessed(0)) {
+ status |= 1 << drv;
+ }
#endif
}
- return NULL;
+ return status;
}
#endif
}
}
-#define STATE_VERSION 13
-
-#include "../../statesub.h"
-
-void VM::decl_state(void)
-{
- state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98_SERIES_HEAD")));
- DECL_STATE_ENTRY_BOOL(pit_clock_8mhz);
-#if defined(_PC98DO) || defined(_PC98DOPLUS)
- DECL_STATE_ENTRY_INT32(boot_mode);
-#endif
- DECL_STATE_ENTRY_INT32(sound_type);
-#if defined(USE_HARD_DISK) && defined(OPEN_HARD_DISK_IN_RESET)
- DECL_STATE_ENTRY_MULTI(void, hd_file_path, sizeof(hd_file_path));
-
-#endif
- for(DEVICE* device = first_device; device; device = device->next_device) {
- device->decl_state();
- }
-}
-
-void VM::save_state(FILEIO* state_fio)
-{
- if(state_entry != NULL) {
- state_entry->save_state(state_fio);
- }
- for(DEVICE* device = first_device; device; device = device->next_device) {
- device->save_state(state_fio);
- }
-}
+#define STATE_VERSION 14
-bool VM::load_state(FILEIO* state_fio)
+bool VM::process_state(FILEIO* state_fio, bool loading)
{
- bool mb = false;
- if(state_entry != NULL) {
- mb = state_entry->load_state(state_fio);
- }
- if(!mb) {
- emu->out_debug_log("INFO: HEADER DATA ERROR");
- return false;
- }
- for(DEVICE* device = first_device; device; device = device->next_device) {
- if(!device->load_state(state_fio)) {
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+ return false;
+ }
+ for(DEVICE* device = first_device; device; device = device->next_device) {
+ // Note: typeid(foo).name is fixed by recent ABI.Not dec 6.
+ // const char *name = typeid(*device).name();
+ // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
+ const char *name = device->get_device_name();
+ int len = strlen(name);
+ if(!state_fio->StateCheckInt32(len)) {
+ if(loading) {
+ printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
+ }
return false;
}
- }
- return true;
+ if(!state_fio->StateCheckBuffer(name, len, 1)) {
+ if(loading) {
+ printf("Class name Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
+ }
+ return false;
+ }
+ if(!device->process_state(state_fio, loading)) {
+ if(loading) {
+ printf("Data loading Error: DEVID=%d\n", device->this_device_id);
+ }
+ return false;
+ }
+ }
+ state_fio->StateValue(pit_clock_8mhz);
+#if defined(_PC98DO) || defined(_PC98DOPLUS)
+ state_fio->StateValue(boot_mode);
+#endif
+ state_fio->StateValue(sound_type);
+ return true;
}
-