#else
#include "../upd7752.h"
#endif
+#include "../noise.h"
#include "../pc6031.h"
#include "../pc80s31k.h"
#include "../prnfile.h"
#include "../upd765a.h"
+#if defined(_PC6001MK2SR) || defined(_PC6601SR)
#include "../ym2203.h"
+#else
+#include "../ay_3_891x.h"
+#endif
#include "../z80.h"
#include "../datarec.h"
// initialize
// ----------------------------------------------------------------------------
-VM::VM(EMU* parent_emu) : emu(parent_emu)
+VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
{
support_pc80s31k = FILEIO::IsFileExisting(create_local_path(_T("DISK.ROM")));
#ifdef _PC6601SR
first_device = last_device = NULL;
dummy = new DEVICE(this, emu); // must be 1st device
event = new EVENT(this, emu); // must be 2nd device
-#if defined(_USE_QT)
- dummy->set_device_name(_T("1st Dummy"));
-#endif
- d_pc80s31k_seek = d_pc6031_seek = d_floppy_seek = NULL;
+
pio_sub = new I8255(this, emu);
io = new IO(this, emu);
+ noise_seek = new NOISE(this, emu);
+ noise_head_down = new NOISE(this, emu);
+ noise_head_up = new NOISE(this, emu);
+#if defined(_PC6001MK2SR) || defined(_PC6601SR)
psg = new YM2203(this, emu);
- cpu = new Z80(this, emu);
-#if defined(_USE_QT)
-#ifdef _PC6001
- pio_sub->set_device_name(_T("i8255 PIO(PRINTER/SOUND/SUB/VDP)"));
#else
- pio_sub->set_device_name(_T("i8255 PIO(PRINTER/SOUND/SUB)"));
+ psg = new AY_3_891X(this, emu);
#endif
-#if defined(_PC6601SR) || defined(_PC6001MK2SR)
- psg->set_device_name(_T("YM2203 OPN"));
-#else
- psg->set_device_name(_T("AY-3-8910 PSG"));
-#endif
- cpu->set_device_name(_T("CPU(Z80)"));
-#endif
+ cpu = new Z80(this, emu);
- if(config.printer_device_type == 0) {
+ if(config.printer_type == 0) {
printer = new PRNFILE(this, emu);
} else {
printer = dummy;
#if defined(_PC6601) || defined(_PC6601SR)
floppy = new FLOPPY(this, emu);
-#if defined(_USE_QT)
- floppy->set_device_name(_T("FLOPPY I/F"));
-#endif
+ floppy->set_context_noise_seek(noise_seek);
+// floppy->set_context_noise_head_down(noise_head_down);
+// floppy->set_context_noise_head_up(noise_head_up);
#endif
joystick = new JOYSTICK(this, emu);
- memory = new MEMORY(this, emu);
+ memory = new PC6001_MEMORY(this, emu);
timer = new TIMER(this, emu);
-#if defined(_USE_QT)
- joystick->set_device_name(_T("JOYSTICK I/F"));
- memory->set_device_name(_T("MEMORY"));
- timer->set_device_name(_T("TIMER"));
-#endif
// set contexts
event->set_context_cpu(cpu);
event->set_context_sound(psg);
+ event->set_context_sound(noise_seek);
+ event->set_context_sound(noise_head_down);
+ event->set_context_sound(noise_head_up);
pio_sub->set_context_port_b(printer, SIG_PRINTER_DATA, 0xff, 0);
pio_sub->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x01, 0);
vdp->load_font_image(create_local_path(_T("CGROM60.60")));
vdp->set_context_cpu(cpu);
pio_sub->set_context_port_c(vdp, SIG_MC6847_ENABLE, 0x02, 0); // CRTKILL
-#if defined(_USE_QT)
- display->set_device_name(_T("DISPLAY I/F"));
-#endif
#else
voice = new UPD7752(this, emu);
event->set_context_sound(voice);
#endif
if(support_sub_cpu) {
cpu_sub = new MCS48(this, emu);
+ cpu_sub->set_device_name(_T("MCS48 MCU (Sub)"));
sub = new SUB(this, emu);
drec = new DATAREC(this, emu);
+ drec->set_device_name(_T("Data Recorder (Sub)"));
+ drec->set_context_noise_play(new NOISE(this, emu));
+ drec->set_context_noise_stop(new NOISE(this, emu));
+ drec->set_context_noise_fast(new NOISE(this, emu));
event->set_context_cpu(cpu_sub, 8000000);
event->set_context_sound(drec);
-#if defined(USE_SOUND_FILES)
- drec->load_sound_data(DATAREC_SNDFILE_RELAY_ON, _T("RELAY_ON.WAV"));
- drec->load_sound_data(DATAREC_SNDFILE_RELAY_OFF, _T("RELAY_OFF.WAV"));
-#endif
+ event->set_context_sound(drec->get_context_noise_play());
+ event->set_context_sound(drec->get_context_noise_stop());
+ event->set_context_sound(drec->get_context_noise_fast());
cpu_sub->set_context_mem(new MCS48MEM(this, emu));
cpu_sub->set_context_io(sub);
#ifdef USE_DEBUGGER
timer->set_context_sub(sub);
} else {
psub = new PSUB(this, emu);
-#if defined(_USE_QT)
- psub->set_device_name(_T("PSEUDO SUB SYSTEM"));
-#endif
psub->set_context_pio(pio_sub);
psub->set_context_timer(timer);
timer->set_context_sub(psub);
}
if(support_pc80s31k) {
pio_fdd = new I8255(this, emu);
+ pio_fdd->set_device_name(_T("8255 PIO (FDD I/F)"));
pio_pc80s31k = new I8255(this, emu);
+ pio_pc80s31k->set_device_name(_T("8255 PIO (320KB FDD)"));
pc80s31k = new PC80S31K(this, emu);
+ pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)"));
fdc_pc80s31k = new UPD765A(this, emu);
+ fdc_pc80s31k->set_device_name(_T("uPD765A FDC (320KB FDD)"));
cpu_pc80s31k = new Z80(this, emu);
-#if defined(_USE_QT)
- pio_fdd->set_device_name(_T("i8255 PIO(FDD)"));
- pio_pc80s31k->set_device_name(_T("i8255 PIO(PC-80S31K)"));
- pc80s31k->set_device_name(_T("PC-80S31K FDD"));
- fdc_pc80s31k->set_device_name(_T("uPD765A FDC(PC-80S31K)"));
- cpu_pc80s31k->set_device_name(_T("Z80 CPU(PC-80S31K)"));
-#endif
-#if defined(USE_SOUND_FILES)
- if(fdc_pc80s31k->load_sound_data(UPD765A_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) {
- event->set_context_sound(fdc_pc80s31k);
- }
-#endif
+ cpu_pc80s31k->set_device_name(_T("Z80 CPU (320KB FDD)"));
+
event->set_context_cpu(cpu_pc80s31k, 4000000);
+
pc80s31k->set_context_cpu(cpu_pc80s31k);
pc80s31k->set_context_fdc(fdc_pc80s31k);
pc80s31k->set_context_pio(pio_pc80s31k);
pio_pc80s31k->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4);
pio_pc80s31k->clear_ports_by_cmdreg = true;
fdc_pc80s31k->set_context_irq(cpu_pc80s31k, SIG_CPU_IRQ, 1);
+ fdc_pc80s31k->set_context_noise_seek(noise_seek);
+ fdc_pc80s31k->set_context_noise_head_down(noise_head_down);
+ fdc_pc80s31k->set_context_noise_head_up(noise_head_up);
cpu_pc80s31k->set_context_mem(pc80s31k);
cpu_pc80s31k->set_context_io(pc80s31k);
cpu_pc80s31k->set_context_intr(pc80s31k);
#endif
} else {
pc6031 = new PC6031(this, emu);
+ pc6031->set_context_noise_seek(noise_seek);
+// pc6031->set_context_noise_head_down(noise_head_down);
+// pc6031->set_context_noise_head_up(noise_head_up);
#if defined(_PC6601) || defined(_PC6601SR)
floppy->set_context_ext(pc6031);
#endif
-#if defined(USE_SOUND_FILES)
- if(pc6031->load_sound_data(PC6031_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) {
- event->set_context_sound(pc6031);
- }
- if(floppy->load_sound_data(FLOPPY_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) {
- event->set_context_sound(floppy);
- }
-#endif
cpu_pc80s31k = NULL;
}
io->set_iomap_range_rw(0xf0, 0xf2, memory); // MEMORY MAP
// 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();
}
+
if(support_sub_cpu) {
// load rom images after cpustate is allocated
#ifdef _PC6601SR
if(support_sub_cpu) {
drec->set_volume(0, decibel_l, decibel_r);
}
+ } else if(ch-- == 0) {
+ noise_seek->set_volume(0, decibel_l, decibel_r);
+ noise_head_down->set_volume(0, decibel_l, decibel_r);
+ noise_head_up->set_volume(0, decibel_l, decibel_r);
+ } else if(ch-- == 0) {
+ if(support_sub_cpu) {
+ drec->get_context_noise_play()->set_volume(0, decibel_l, decibel_r);
+ drec->get_context_noise_stop()->set_volume(0, decibel_l, decibel_r);
+ drec->get_context_noise_fast()->set_volume(0, decibel_l, decibel_r);
+ }
}
-#if defined(USE_SOUND_FILES)
- else if(ch-- == 0) {
- if(support_pc80s31k) {
- if(fdc_pc80s31k != NULL) fdc_pc80s31k->set_volume(0, decibel_l, decibel_r);
- } else {
- if(pc6031 != NULL) pc6031->set_volume(0, decibel_l, decibel_r);
- if(floppy != NULL) floppy->set_volume(0, decibel_l, decibel_r);
- }
- }
-#endif
}
#endif
}
}
-uint32_t VM::get_access_lamp_status()
-{
- uint32_t status = 0; /// fdc->read_signal(0);
-#if defined(_PC6601) || defined(_PC6601SR)
- status = floppy->read_signal(0);
-#endif
- if(support_pc80s31k) {
- status |= fdc_pc80s31k->read_signal(0);
- } else {
- status |= pc6031->read_signal(0);
- }
- return status;
-}
-
void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
{
#if defined(_PC6601) || defined(_PC6601SR)
}
}
-void VM::play_tape(const _TCHAR* file_path)
+uint32_t VM::is_floppy_disk_accessed()
+{
+ uint32_t status = 0; /// fdc->read_signal(0);
+ if(support_pc80s31k) {
+ status |= fdc_pc80s31k->read_signal(0);
+ } else {
+ status |= pc6031->read_signal(0);
+ }
+#if defined(_PC6601) || defined(_PC6601SR)
+ status <<= 2;
+ status |= floppy->read_signal(0);
+#endif
+ return status;
+}
+
+void VM::play_tape(int drv, const _TCHAR* file_path)
{
if(support_sub_cpu) {
// support both p6/p6t and wav
drec->play_tape(file_path);
+// drec->set_remote(true);
} else {
// support only p6/p6t
psub->play_tape(file_path);
}
}
-void VM::rec_tape(const _TCHAR* file_path)
+void VM::rec_tape(int drv, const _TCHAR* file_path)
{
if(support_sub_cpu) {
// support both p6/p6t and wav
sub->rec_tape(file_path); // temporary
// drec->rec_tape(file_path);
+// drec->set_remote(true);
} else {
// support both p6/p6t and wav
psub->rec_tape(file_path);
}
}
-void VM::close_tape()
+void VM::close_tape(int drv)
{
if(support_sub_cpu) {
if(sub->is_tape_inserted()) {
sub->close_tape(); // temporary
} else {
+ emu->lock_vm();
drec->close_tape();
+ emu->unlock_vm();
+// drec->set_remote(false);
}
} else {
psub->close_tape();
}
}
-bool VM::is_tape_inserted()
+bool VM::is_tape_inserted(int drv)
{
if(support_sub_cpu) {
return drec->is_tape_inserted() || sub->is_tape_inserted();
}
}
-bool VM::is_tape_playing()
+bool VM::is_tape_playing(int drv)
{
if(support_sub_cpu) {
return drec->is_tape_playing();
}
}
-bool VM::is_tape_recording()
+bool VM::is_tape_recording(int drv)
{
if(support_sub_cpu) {
return drec->is_tape_recording();
}
}
-int VM::get_tape_position()
+int VM::get_tape_position(int drv)
{
if(support_sub_cpu) {
return drec->get_tape_position();
}
}
-bool VM::is_frame_skippable()
+const _TCHAR* VM::get_tape_message(int drv)
{
- return event->is_frame_skippable();
+ if(support_sub_cpu) {
+ return drec->get_message();
+ } else {
+ return NULL;
+ }
}
-void VM::update_config()
+void VM::push_play(int drv)
{
- for(DEVICE* device = first_device; device; device = device->next_device) {
- device->update_config();
+ if(support_sub_cpu) {
+ drec->set_ff_rew(0);
+ drec->set_remote(true);
}
}
-#define STATE_VERSION 3
+void VM::push_stop(int drv)
+{
+ if(support_sub_cpu) {
+ drec->set_remote(false);
+ }
+}
-void VM::save_state(FILEIO* state_fio)
+void VM::push_fast_forward(int drv)
+{
+ if(support_sub_cpu) {
+ drec->set_ff_rew(1);
+ drec->set_remote(true);
+ }
+}
+
+void VM::push_fast_rewind(int drv)
+{
+ if(support_sub_cpu) {
+ drec->set_ff_rew(-1);
+ drec->set_remote(true);
+ }
+}
+
+bool VM::is_frame_skippable()
+{
+ return event->is_frame_skippable();
+}
+
+void VM::update_config()
{
- state_fio->FputUint32(STATE_VERSION);
-
for(DEVICE* device = first_device; device; device = device->next_device) {
- device->save_state(state_fio);
+ device->update_config();
}
- state_fio->FputInt32(sr_mode);
}
-bool VM::load_state(FILEIO* state_fio)
+#define STATE_VERSION 6
+
+bool VM::process_state(FILEIO* state_fio, bool loading)
{
- if(state_fio->FgetUint32() != STATE_VERSION) {
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
return false;
}
- for(DEVICE* device = first_device; device; device = device->next_device) {
- if(!device->load_state(state_fio)) {
+ 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;
}
- }
- sr_mode = state_fio->FgetInt32();
+ 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;
+ }
+ }
+ // Machine specified.
+ state_fio->StateInt32(sr_mode);
return true;
}
-