ところで、SC-3000が遊べるならば、マークIII以降も遊びたいものです。例によって改造したら動くんじゃないかと言う試みです。
まずは、現状のeSC-3000で動かないメガロム対応から着手してみます。
memory.cpp
/* SEGA GAME GEAR Emulator 'yaGAME GEAR' Author : tanam Date : 2013.08.24- [ memory ] */ #include "memory.h" #include "../../fileio.h" void MEMORY::sms_mapper_w(uint32 addr, uint32 data) { /* Calculate ROM page index */ uint8 page = (data % pages); /* Save frame control register data */ fcr[addr] = data; switch(addr) { case 0: if(data & 8) { save = 1; /* Page in ROM */ cpu_readmap[4] = &sram[(data & 4) ? 0x4000 : 0x0000]; cpu_readmap[5] = &sram[(data & 4) ? 0x6000 : 0x2000]; cpu_writemap[4] = &sram[(data & 4) ? 0x4000 : 0x0000]; cpu_writemap[5] = &sram[(data & 4) ? 0x6000 : 0x2000]; } else { /* Page in RAM */ cpu_readmap[4] = &cart[((fcr[3] % pages) << 14) + 0x0000]; cpu_readmap[5] = &cart[((fcr[3] % pages) << 14) + 0x2000]; cpu_writemap[4] = ram + 0x8000; cpu_writemap[5] = ram + 0xA000; } break; case 1: cpu_readmap[0] = &cart[(page << 14) + 0x0000]; cpu_readmap[1] = &cart[(page << 14) + 0x2000]; break; case 2: cpu_readmap[2] = &cart[(page << 14) + 0x0000]; cpu_readmap[3] = &cart[(page << 14) + 0x2000]; break; case 3: if(!(fcr[0] & 0x08)) { cpu_readmap[4] = &cart[(page << 14) + 0x0000]; cpu_readmap[5] = &cart[(page << 14) + 0x2000]; } break; } } void MEMORY::initialize() { cart=NULL; memset(ram, 0, sizeof(ram)); memset(rdmy, 0xff, sizeof(rdmy)); memset(sram, 0, sizeof(sram)); // set memory map cpu_readmap[0] = ram; cpu_readmap[1] = ram + 0x2000; cpu_readmap[2] = ram + 0x4000; cpu_readmap[3] = ram + 0x6000; cpu_readmap[4] = ram + 0x8000; cpu_readmap[5] = ram + 0xA000; cpu_readmap[6] = ram + 0xC000; cpu_readmap[7] = ram + 0xE000; cpu_writemap[0] = ram; cpu_writemap[1] = ram + 0x2000; cpu_writemap[2] = ram + 0x4000; cpu_writemap[3] = ram + 0x6000; cpu_writemap[4] = ram + 0x8000; cpu_writemap[5] = ram + 0xA000; cpu_writemap[6] = ram + 0xC000; cpu_writemap[7] = ram + 0xE000; fcr[0] = 0x00; fcr[1] = 0x00; fcr[2] = 0x01; fcr[3] = 0x00; inserted = false; } void MEMORY::write_data8(uint32 addr, uint32 data) { cpu_writemap[(addr >> 13)][(addr & 0x1FFF)] = data; if (pages < 4) return; if (addr >= 0xFFFC) sms_mapper_w(addr & 3, data); } uint32 MEMORY::read_data8(uint32 addr) { return cpu_readmap[(addr >> 13)][(addr & 0x1FFF)]; } void MEMORY::write_signal(int id, uint32 data, uint32 mask) { // from PIO-P6 if(data & mask) { cpu_readmap[0] = ram; cpu_readmap[1] = ram + 0x2000; cpu_readmap[2] = ram + 0x4000; cpu_readmap[3] = ram + 0x6000; cpu_readmap[4] = ram + 0x8000; cpu_writemap[0] = ram; cpu_writemap[1] = ram + 0x2000; cpu_writemap[2] = ram + 0x4000; cpu_writemap[3] = ram + 0x6000; cpu_writemap[4] = ram + 0x8000; } else { // ROM cpu_readmap[0] = cart; cpu_readmap[1] = rdmy; cpu_readmap[2] = ram + 0x4000; cpu_readmap[3] = ram + 0x6000; cpu_readmap[4] = ram + 0x8000; cpu_writemap[0] = ram; cpu_writemap[1] = ram + 0x2000; cpu_writemap[2] = ram + 0x4000; cpu_writemap[3] = ram + 0x6000; cpu_writemap[4] = ram + 0x8000; } } void MEMORY::open_cart(_TCHAR* file_path) { FILEIO* fio = new FILEIO(); if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { fio->Fseek(0, FILEIO_SEEK_END); size=fio->Ftell(); pages = (size / 0x4000); fio->Fseek(0, FILEIO_SEEK_SET); if (cart) free(cart); cart=(uint8 *)malloc(size); fio->Fread(cart, size, 1); fio->Fclose(); inserted = true; } delete fio; // set memory map cpu_readmap[0] = cart; if (size>0x2000) cpu_readmap[1] = cart + 0x2000; else cpu_readmap[1] = rdmy; if (size>0x4000) cpu_readmap[2] = cart + 0x4000; else cpu_readmap[2] = rdmy; if (size>0x6000) cpu_readmap[3] = cart + 0x6000; else cpu_readmap[3] = rdmy; if (size>0x8000) cpu_readmap[4] = cart + 0x8000; else cpu_readmap[4] = ram + 0x8000; if (size>0xA000) cpu_readmap[5] = cart + 0xA000; else cpu_readmap[5] = ram + 0xA000; cpu_readmap[6] = ram + 0xC000; cpu_readmap[7] = ram + 0xE000; cpu_writemap[0] = ram; cpu_writemap[1] = ram + 0x2000; cpu_writemap[2] = ram + 0x4000; cpu_writemap[3] = ram + 0x6000; cpu_writemap[4] = ram + 0x8000; cpu_writemap[5] = ram + 0xA000; cpu_writemap[6] = ram + 0xC000; cpu_writemap[7] = ram + 0xE000; fcr[0] = 0x00; fcr[1] = 0x00; fcr[2] = 0x01; fcr[3] = 0x00; } void MEMORY::close_cart() { if (cart) free(cart); initialize(); }
memory.h
/* SEGA GAME GEAR Emulator 'yaGAME GEAR' Author : tanam Date : 2013.08.24- [ memory ] */ #ifndef _MEMORY_H_ #define _MEMORY_H_ #include "../vm.h" #include "../../emu.h" #include "../device.h" #define SIG_MEMORY_SEL 0 class MEMORY : public DEVICE { private: // memory uint8 *cart; uint32 size; uint8 pages; uint8 ram[0x10000]; uint8 rdmy[0x2000]; uint8 sram[0x8000]; uint8 *cpu_readmap[8]; uint8 *cpu_writemap[8]; uint8 fcr[4]; uint8 save; bool inserted; void sms_mapper_w(uint32 addr, uint32 data); public: MEMORY(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {} ~MEMORY() {} // common functions void initialize(); void write_data8(uint32 addr, uint32 data); uint32 read_data8(uint32 addr); void write_data16(uint32 addr, uint32 data) { write_data8(addr, data & 0xff); write_data8(addr + 1, data >> 8); } uint32 read_data16(uint32 addr) { return read_data8(addr) | (read_data8(addr + 1) << 8); } void write_signal(int id, uint32 data, uint32 mask); // unique functions void open_cart(_TCHAR* file_path); void close_cart(); bool cart_inserted() { return inserted; } }; #endif