これで全部公開しました!「和製MESSでPC-6001 その4」から読んで頂ければビルド出来るはずです。
未実装な機能(実装予定)
- TAPE関連機能
- RS232C関連機能
pc6001.cpp
/* NEC PC-6001 Emulator 'yaPC-6001' Skelton for retropc emulator Author : tanam Date : 2013.07.15- [ virtual machine ] */ #include "pc6001.h" #include "../../emu.h" #include "../device.h" #include "../event.h" #include "../datarec.h" ///#include "../i8251.h" #include "../i8255.h" #include "../io.h" #include "../upd765a.h" #include "../mc6847.h" #include "../ym2203.h" #include "../z80.h" #include "joystick.h" #include "keyboard.h" #include "memory.h" #include "system.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); fdc = new UPD765A(this, emu); vdp = new MC6847(this, emu); psg = new YM2203(this, emu); cpu = new Z80(this, emu); joystick = new JOYSTICK(this, emu); keyboard = new KEYBOARD(this, emu); memory = new MEMORY(this, emu); system = new SYSTEM(this, emu); // set contexts event->set_context_cpu(cpu); event->set_context_sound(psg); system->set_context_pio(pio_f); system->set_context_fdc(fdc); joystick->set_context_psg(psg); vdp->set_context_cpu(cpu); keyboard->set_context_cpu(cpu); keyboard->set_context_pio(pio_k); keyboard->set_context_memory(memory); // cpu bus cpu->set_context_mem(memory); cpu->set_context_io(io); cpu->set_context_intr(vdp); cpu->set_context_intr(keyboard); // i/o bus io->set_iomap_range_rw(0x90, 0x93, pio_k); io->set_iomap_range_rw(0xd0, 0xd3, system); io->set_iomap_range_rw(0xf0, 0xf3, memory); 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 io->set_iomap_single_rw(0xb0, vdp); // initialize all devices for(DEVICE* device = first_device; device; device = device->next_device) { device->initialize(); } vdp->set_vram_ptr(memory->get_vram(), 0x1800); fdc->open_disk(0, emu->bios_path(_T("D1/INIT.D88")) ,0); system->open_disk(0, emu->bios_path(_T("D1/INIT.D88")) ,0); } 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() { uint32 status = 0; /// 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); psg->init(rate, 1996750, samples, 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); system->open_disk(drv, file_path, offset); } void VM::close_disk(int drv) { fdc->close_disk(drv); system->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(); } }
pc6001.h
/* NEC PC-6001 Emulator 'yaPC-6001' Skelton for retropc emulator Author : tanam Date : 2013.07.15- [ virtual machine ] */ #ifndef _PC6001_H_ #define _PC6001_H_ #define DEVICE_NAME "NEC PC-6001" #define CONFIG_NAME "pc6001" #define CONFIG_VERSION 0x01 // device informations for virtual machine #define FRAMES_PER_SEC 60 #define LINES_PER_FRAME 262 #define CPU_CLOCKS 3993600 #define SCREEN_WIDTH 256 #define SCREEN_HEIGHT 192 #define MAX_DRIVE 4 #define HAS_AY_3_8912 #define MC6847_ATTR_OFS 0 #define MC6847_VRAM_OFS 0x200 #define MC6847_ATTR_AG 0x80 #define MC6847_ATTR_AS 0x40 #define MC6847_ATTR_INTEXT 0x20 #define MC6847_ATTR_GM0 0x10 #define MC6847_ATTR_GM1 0x08 #define MC6847_ATTR_GM2 0x04 #define MC6847_ATTR_CSS 0x02 #define MC6847_ATTR_INV 0x01 // device informations for win32 #define MIN_WINDOW_WIDTH 320 #define USE_CART1 #define USE_FD1 #define USE_FD2 #define USE_FD3 #define USE_FD4 #define USE_TAPE #define USE_ALT_F10_KEY #define USE_AUTO_KEY 6 #define USE_AUTO_KEY_RELEASE 10 #define USE_AUTO_KEY_CAPS #include "../../common.h" class EMU; class DEVICE; class EVENT; class DATAREC; ///class I8251; class I8255; class IO; class UPD765A; class MC6847; class YM2203; class Z80; class JOYSTICK; class KEYBOARD; class MEMORY; class SYSTEM; class VM { protected: EMU* emu; int vdata; // devices EVENT* event; DATAREC* drec; /// I8251* sio; I8255* pio_k; I8255* pio_f; IO* io; UPD765A* fdc; MC6847* vdp; YM2203* psg; Z80* cpu; JOYSTICK* joystick; KEYBOARD* keyboard; MEMORY* memory; SYSTEM* system; 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