ほとんどの実装はSC-3000そのままなのですが、PSGとJOYSTICKの部分は、ほとんどPHC-25そのままです(笑)
msx1.cpp
/* ASCII MSX1 Emulator 'yaMSX1' Skelton for retropc emulator Author : tanam Date : 2013.06.29- [ virtual machine ] */ #include "msx1.h" #include "../../emu.h" #include "../device.h" #include "../event.h" #include "../datarec.h" #include "../i8251.h" #include "../i8255.h" #include "../io.h" #include "../ym2203.h" #include "../tms9918a.h" #include "../upd765a.h" #include "../z80.h" #include "joystick.h" #include "keyboard.h" #include "memory.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); sio = new I8251(this, emu); pio_k = new I8255(this, emu); pio_f = new I8255(this, emu); io = new IO(this, emu); psg = new YM2203(this, emu); vdp = new TMS9918A(this, emu); /// fdc = new UPD765A(this, emu); cpu = new Z80(this, emu); joystick = new JOYSTICK(this, emu); keyboard = new KEYBOARD(this, emu); memory = new MEMORY(this, emu); // set contexts event->set_context_cpu(cpu); event->set_context_sound(psg); /// drec->set_context_out(pio_k, SIG_I8255_PORT_B, 0x80); pio_k->set_context_port_c(keyboard, SIG_KEYBOARD_COLUMN, 0x0f, 0); /// pio_k->set_context_port_c(drec, SIG_DATAREC_REMOTE, 0x08, 0); /// pio_k->set_context_port_c(drec, SIG_DATAREC_OUT, 0x10, 0); /// pio_f->set_context_port_c(fdc, SIG_UPD765A_MOTOR_NEG, 2, 0); /// pio_f->set_context_port_c(fdc, SIG_UPD765A_TC, 4, 0); /// pio_f->set_context_port_c(fdc, SIG_UPD765A_RESET, 8, 0); pio_f->set_context_port_a(memory, SIG_MEMORY_SEL, 0xff, 0); vdp->set_context_irq(cpu, SIG_CPU_IRQ, 1); /// fdc->set_context_irq(pio_f, SIG_I8255_PORT_A, 1); /// fdc->set_context_index(pio_f, SIG_I8255_PORT_A, 4); #ifdef _FDC_DEBUG_LOG fdc->set_context_cpu(cpu); #endif joystick->set_context_psg(psg); keyboard->set_context_cpu(cpu); keyboard->set_context_pio(pio_k); // cpu bus cpu->set_context_mem(memory); cpu->set_context_io(io); cpu->set_context_intr(dummy); // i/o bus io->set_iomap_range_rw(0x98, 0x99, vdp); io->set_iomap_range_rw(0xa9, 0xab, pio_k); /// io->set_iomap_range_rw(0xe0, 0xe3, fdc); io->set_iomap_range_rw(0xa8, 0xa8, pio_f); io->set_iomap_range_rw(0x80, 0x88, sio); io->set_iomap_alias_w(0xa0, psg, 0); // PSG ch io->set_iomap_alias_w(0xa1, psg, 1); // PSG data io->set_iomap_alias_r(0xa2, psg, 1); // PSG data // 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(); } int VM::access_lamp() { return 0; /// uint32 status = fdc->read_signal(0); /// return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0; } // ---------------------------------------------------------------------------- // 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, 0, 0); } 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::open_disk(int drv, _TCHAR* file_path, int offset) { fdc->open_disk(drv, file_path, offset); } void VM::close_disk(int drv) { fdc->close_disk(drv); } bool VM::disk_inserted(int drv) { return fdc->disk_inserted(drv); } 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(); } }
msx1.h
/* ASCII MSX1 Emulator 'yaMSX1' Skelton for retropc emulator Author : tanam Date : 2013.06.29- [ virtual machine ] */ #ifndef _MSX1_H_ #define _MSX1_H_ #define DEVICE_NAME "ASCII MSX1" #define CONFIG_NAME "msx1" #define CONFIG_VERSION 0x02 // device informations for virtual machine #define FRAMES_PER_SEC 60 #define LINES_PER_FRAME 262 #define CPU_CLOCKS 3579545 #define SCREEN_WIDTH 256 #define SCREEN_HEIGHT 192 #define TMS9918A_VRAM_SIZE 0x4000 #define TMS9918A_LIMIT_SPRITES #define MAX_DRIVE 4 // device informations for win32 #define MIN_WINDOW_WIDTH 320 #define USE_CART1 #define USE_FD1 #define USE_TAPE #define USE_ALT_F10_KEY #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 8 #define USE_ACCESS_LAMP #include "../../common.h" class EMU; class DEVICE; class EVENT; class DATAREC; class I8251; class I8255; class IO; class YM2203; class TMS9918A; class UPD765A; class Z80; class JOYSTICK; class KEYBOARD; class MEMORY; class VM { protected: EMU* emu; // devices EVENT* event; DATAREC* drec; I8251* sio; I8255* pio_k; I8255* pio_f; IO* io; YM2203* psg; TMS9918A* vdp; UPD765A* fdc; Z80* cpu; JOYSTICK* joystick; KEYBOARD* keyboard; MEMORY* memory; public: // ---------------------------------------- // initialize // ---------------------------------------- VM(EMU* parent_emu); ~VM(); // ---------------------------------------- // for emulation class // ---------------------------------------- // drive virtual machine void reset(); void run(); // draw screen void draw_screen(); int access_lamp(); // sound generation void initialize_sound(int rate, int samples); uint16* create_sound(int* extra_frames); int sound_buffer_ptr(); // user interface void open_cart(int drv, _TCHAR* file_path); void close_cart(int drv); bool cart_inserted(int drv); void open_disk(int drv, _TCHAR* file_path, int offset); void close_disk(int drv); bool disk_inserted(int drv); void play_tape(_TCHAR* file_path); void rec_tape(_TCHAR* file_path); void close_tape(); bool tape_inserted(); bool now_skip(); void update_config(); // ---------------------------------------- // for each device // ---------------------------------------- // devices DEVICE* get_device(int id); DEVICE* dummy; DEVICE* first_device; DEVICE* last_device; }; #endif
joystick.cpp
/* ASCII MSX1 Emulator 'yaMSX1' Skelton for retropc emulator Author : tanam Date : 2013.06.29- [ joystick ] */ #include "joystick.h" #include "../ym2203.h" void JOYSTICK::initialize() { joy_stat = emu->joy_buffer(); // register event to update the key status register_frame_event(this); } void JOYSTICK::event_frame() { /// d_psg->write_signal(SIG_YM2203_PORT_A, ~(joy_stat[0] & 0x1f), 0xff); d_psg->write_signal(SIG_YM2203_PORT_A, ~(joy_stat[0] & 0x3f), 0xff); d_psg->write_signal(SIG_YM2203_PORT_B, ~(joy_stat[1] & 0x1f), 0xff); }