X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=source%2Fsrc%2Fvm%2Fpyuta%2Fpyuta.cpp;h=d98e3cd7b23e3ad239d7cfa7713f563af21fa264;hb=9657068762e0ebc1ed5a42638db31cdcdda7c9db;hp=c9cd28b8c39fbbec0ad27f097ad2c425b0686b65;hpb=633011a2c4a89b451e155ae8c364fd8e143708a1;p=csp-qt%2Fcommon_source_project-fm7.git diff --git a/source/src/vm/pyuta/pyuta.cpp b/source/src/vm/pyuta/pyuta.cpp index c9cd28b8c..d98e3cd7b 100644 --- a/source/src/vm/pyuta/pyuta.cpp +++ b/source/src/vm/pyuta/pyuta.cpp @@ -1,216 +1,323 @@ -/* - TOMY PyuTa Emulator 'ePyuTa' - - Author : Takeda.Toshiya - Date : 2007.07.15 - - - [ virtual machine ] -*/ - -#include "pyuta.h" -#include "../../emu.h" -#include "../device.h" -#include "../event.h" - -#include "../datarec.h" -#include "../sn76489an.h" -#include "../tms9918a.h" -#include "../tms9995.h" - -#include "memory.h" - -#include "../../fileio.h" - -// ---------------------------------------------------------------------------- -// initialize -// ---------------------------------------------------------------------------- - -VM::VM(EMU* parent_emu) : emu(parent_emu) -{ - // create devices - first_device = last_device = NULL; - dummy = new DEVICE(this, emu); // must be 1st device - event = new EVENT(this, emu); // must be 2nd device - - drec = new DATAREC(this, emu); - psg = new SN76489AN(this, emu); - vdp = new TMS9918A(this, emu); - cpu = new TMS9995(this, emu); - - memory = new MEMORY(this, emu); - - // set contexts - event->set_context_cpu(cpu); - event->set_context_sound(psg); - - drec->set_context_out(memory, 0, 1); - memory->set_context_cmt(drec); - memory->set_context_cpu(cpu); - memory->set_context_psg(psg); - memory->set_context_vdp(vdp); - - // cpu bus - cpu->set_context_mem(memory); - cpu->set_context_io(memory); - - // initialize all devices - for(DEVICE* device = first_device; device; device = device->next_device) { - device->initialize(); - } -} - -VM::~VM() -{ - // delete all devices - for(DEVICE* device = first_device; device;) { - DEVICE *next_device = device->next_device; - device->release(); - delete device; - device = next_device; - } -} - -DEVICE* VM::get_device(int id) -{ - for(DEVICE* device = first_device; device; device = device->next_device) { - if(device->this_device_id == id) { - return device; - } - } - return NULL; -} - -// ---------------------------------------------------------------------------- -// drive virtual machine -// ---------------------------------------------------------------------------- - -void VM::reset() -{ - // reset all devices - for(DEVICE* device = first_device; device; device = device->next_device) { - device->reset(); - } -} - -void VM::run() -{ - event->drive(); -} - -// ---------------------------------------------------------------------------- -// draw screen -// ---------------------------------------------------------------------------- - -void VM::draw_screen() -{ - vdp->draw_screen(); -} - -// ---------------------------------------------------------------------------- -// soud manager -// ---------------------------------------------------------------------------- - -void VM::initialize_sound(int rate, int samples) -{ - // init sound manager - event->initialize_sound(rate, samples); - - // init sound gen - psg->init(rate, 3579545, 8000); -} - -uint16* VM::create_sound(int* extra_frames) -{ - return event->create_sound(extra_frames); -} - -int VM::sound_buffer_ptr() -{ - return event->sound_buffer_ptr(); -} - -// ---------------------------------------------------------------------------- -// user interface -// ---------------------------------------------------------------------------- - -void VM::open_cart(int drv, _TCHAR* file_path) -{ - if(drv == 0) { - memory->open_cart(file_path); - reset(); - } -} - -void VM::close_cart(int drv) -{ - if(drv == 0) { - memory->close_cart(); - reset(); - } -} - -bool VM::cart_inserted(int drv) -{ - if(drv == 0) { - return memory->cart_inserted(); - } else { - return false; - } -} - -void VM::play_tape(_TCHAR* file_path) -{ - drec->play_tape(file_path); -} - -void VM::rec_tape(_TCHAR* file_path) -{ - drec->rec_tape(file_path); -} - -void VM::close_tape() -{ - drec->close_tape(); -} - -bool VM::tape_inserted() -{ - return drec->tape_inserted(); -} - -bool VM::now_skip() -{ - return event->now_skip(); -} - -void VM::update_config() -{ - for(DEVICE* device = first_device; device; device = device->next_device) { - device->update_config(); - } -} - -#define STATE_VERSION 1 - -void VM::save_state(FILEIO* state_fio) -{ - state_fio->FputUint32(STATE_VERSION); - - for(DEVICE* device = first_device; device; device = device->next_device) { - device->save_state(state_fio); - } -} - -bool VM::load_state(FILEIO* state_fio) -{ - if(state_fio->FgetUint32() != STATE_VERSION) { - return false; - } - for(DEVICE* device = first_device; device; device = device->next_device) { - if(!device->load_state(state_fio)) { - return false; - } - } - return true; -} - +/* + TOMY PyuTa Emulator 'ePyuTa' + + Author : Takeda.Toshiya + Date : 2007.07.15 - + + [ virtual machine ] +*/ + +#include "pyuta.h" +#include "../../emu.h" +#include "../device.h" +#include "../event.h" + +#include "../datarec.h" +#include "../noise.h" +#include "../sn76489an.h" +#include "../tms9918a.h" +#include "../tms9995.h" + +#ifdef USE_DEBUGGER +#include "../debugger.h" +#endif + +#include "./memory.h" + +// ---------------------------------------------------------------------------- +// initialize +// ---------------------------------------------------------------------------- +using PYUTA::MEMORY; + +VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +{ + // create devices + first_device = last_device = NULL; + dummy = new DEVICE(this, emu); // must be 1st device + event = new EVENT(this, emu); // must be 2nd device + dummy->set_device_name(_T("1st Dummy")); + + drec = new DATAREC(this, emu); + 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)); + psg = new SN76489AN(this, emu); + vdp = new TMS9918A(this, emu); + cpu = new TMS9995(this, emu); + + memory = new MEMORY(this, emu); + + // set contexts + event->set_context_cpu(cpu); + event->set_context_sound(psg); + event->set_context_sound(drec); + 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()); + + drec->set_context_ear(memory, 0, 1); + memory->set_context_cmt(drec); + memory->set_context_cpu(cpu); + memory->set_context_psg(psg); + memory->set_context_vdp(vdp); + + // cpu bus + cpu->set_context_mem(memory); + cpu->set_context_io(memory); +#ifdef USE_DEBUGGER + cpu->set_context_debugger(new DEBUGGER(this, emu)); +#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(); + } +} + +VM::~VM() +{ + // delete all devices + for(DEVICE* device = first_device; device;) { + DEVICE *next_device = device->next_device; + device->release(); + delete device; + device = next_device; + } +} + +DEVICE* VM::get_device(int id) +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + if(device->this_device_id == id) { + return device; + } + } + return NULL; +} + +// ---------------------------------------------------------------------------- +// drive virtual machine +// ---------------------------------------------------------------------------- + +void VM::reset() +{ + // reset all devices + for(DEVICE* device = first_device; device; device = device->next_device) { + device->reset(); + } +} + +void VM::run() +{ + event->drive(); +} + +// ---------------------------------------------------------------------------- +// debugger +// ---------------------------------------------------------------------------- + +#ifdef USE_DEBUGGER +DEVICE *VM::get_cpu(int index) +{ + if(index == 0) { + return cpu; + } + return NULL; +} +#endif + +// ---------------------------------------------------------------------------- +// draw screen +// ---------------------------------------------------------------------------- + +void VM::draw_screen() +{ + vdp->draw_screen(); +} + +// ---------------------------------------------------------------------------- +// soud manager +// ---------------------------------------------------------------------------- + +void VM::initialize_sound(int rate, int samples) +{ + // init sound manager + event->initialize_sound(rate, samples); + + // init sound gen + psg->initialize_sound(rate, 3579545, 8000); +} + +uint16_t* VM::create_sound(int* extra_frames) +{ + return event->create_sound(extra_frames); +} + +int VM::get_sound_buffer_ptr() +{ + return event->get_sound_buffer_ptr(); +} + +#ifdef USE_SOUND_VOLUME +void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) +{ + if(ch == 0) { + psg->set_volume(0, decibel_l, decibel_r); + } else if(ch == 1) { + drec->set_volume(0, decibel_l, decibel_r); + } else if(ch == 2) { + 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); + } +} +#endif + +// ---------------------------------------------------------------------------- +// user interface +// ---------------------------------------------------------------------------- + +void VM::open_cart(int drv, const _TCHAR* file_path) +{ + if(drv == 0) { + memory->open_cart(file_path); + reset(); + } +} + +void VM::close_cart(int drv) +{ + if(drv == 0) { + memory->close_cart(); + reset(); + } +} + +bool VM::is_cart_inserted(int drv) +{ + if(drv == 0) { + return memory->is_cart_inserted(); + } else { + return false; + } +} + +void VM::play_tape(int drv, const _TCHAR* file_path) +{ + drec->play_tape(file_path); +// drec->set_remote(true); +} + +void VM::rec_tape(int drv, const _TCHAR* file_path) +{ + drec->rec_tape(file_path); +// drec->set_remote(true); +} + +void VM::close_tape(int drv) +{ + emu->lock_vm(); + drec->close_tape(); + emu->unlock_vm(); +// drec->set_remote(false); +} + +bool VM::is_tape_inserted(int drv) +{ + return drec->is_tape_inserted(); +} + +bool VM::is_tape_playing(int drv) +{ + return drec->is_tape_playing(); +} + +bool VM::is_tape_recording(int drv) +{ + return drec->is_tape_recording(); +} + +int VM::get_tape_position(int drv) +{ + return drec->get_tape_position(); +} + +const _TCHAR* VM::get_tape_message(int drv) +{ + return drec->get_message(); +} + +void VM::push_play(int drv) +{ + drec->set_ff_rew(0); + drec->set_remote(true); +} + +void VM::push_stop(int drv) +{ + drec->set_remote(false); +} + +void VM::push_fast_forward(int drv) +{ + drec->set_ff_rew(1); + drec->set_remote(true); +} + +void VM::push_fast_rewind(int drv) +{ + drec->set_ff_rew(-1); + drec->set_remote(true); +} + +bool VM::is_frame_skippable() +{ + return event->is_frame_skippable(); +} + +void VM::update_config() +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + device->update_config(); + } +} + +#define STATE_VERSION 4 + +bool VM::process_state(FILEIO* state_fio, bool loading) +{ + 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; + } + 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. + return true; +}