#include "rom.hpp" #include #include "bus.hpp" #include "mbcs/mbc0.hpp" #include "mbcs/mbc1.hpp" static BYTE bios[0x100] = { 0x31, 0xFE, 0xFF, 0xAF, 0x21, 0xFF, 0x9F, 0x32, 0xCB, 0x7C, 0x20, 0xFB, 0x21, 0x26, 0xFF, 0x0E, 0x11, 0x3E, 0x80, 0x32, 0xE2, 0x0C, 0x3E, 0xF3, 0xE2, 0x32, 0x3E, 0x77, 0x77, 0x3E, 0xFC, 0xE0, 0x47, 0x11, 0x04, 0x01, 0x21, 0x10, 0x80, 0x1A, 0xCD, 0x95, 0x00, 0xCD, 0x96, 0x00, 0x13, 0x7B, 0xFE, 0x34, 0x20, 0xF3, 0x11, 0xD8, 0x00, 0x06, 0x08, 0x1A, 0x13, 0x22, 0x23, 0x05, 0x20, 0xF9, 0x3E, 0x19, 0xEA, 0x10, 0x99, 0x21, 0x2F, 0x99, 0x0E, 0x0C, 0x3D, 0x28, 0x08, 0x32, 0x0D, 0x20, 0xF9, 0x2E, 0x0F, 0x18, 0xF3, 0x67, 0x3E, 0x64, 0x57, 0xE0, 0x42, 0x3E, 0x91, 0xE0, 0x40, 0x04, 0x1E, 0x02, 0x0E, 0x0C, 0xF0, 0x44, 0xFE, 0x90, 0x20, 0xFA, 0x0D, 0x20, 0xF7, 0x1D, 0x20, 0xF2, 0x0E, 0x13, 0x24, 0x7C, 0x1E, 0x83, 0xFE, 0x62, 0x28, 0x06, 0x1E, 0xC1, 0xFE, 0x64, 0x20, 0x06, 0x7B, 0xE2, 0x0C, 0x3E, 0x87, 0xE2, 0xF0, 0x42, 0x90, 0xE0, 0x42, 0x15, 0x20, 0xD2, 0x05, 0x20, 0x4F, 0x16, 0x20, 0x18, 0xCB, 0x4F, 0x06, 0x04, 0xC5, 0xCB, 0x11, 0x17, 0xC1, 0xCB, 0x11, 0x17, 0x05, 0x20, 0xF5, 0x22, 0x23, 0x22, 0x23, 0xC9, 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99, 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E, 0x3C, 0x42, 0xB9, 0xA5, 0xB9, 0xA5, 0x42, 0x3C, 0x21, 0x04, 0x01, 0x11, 0xA8, 0x00, 0x1A, 0x13, 0xBE, 0x20, 0xFE, 0x23, 0x7D, 0xFE, 0x34, 0x20, 0xF5, 0x06, 0x19, 0x78, 0x86, 0x23, 0x05, 0x20, 0xFB, 0x86, 0x20, 0xFE, 0x3E, 0x01, 0xE0, 0x50 }; ROM::ROM(FILE* f) { // read in rom from file fseek(f, 0, SEEK_END); long fsize = ftell(f); rewind(f); data = std::vector(fsize); fread(data.data(), 1, fsize, f); // figure out how much ram we need (or dont need) switch (data[0x149]) { case 0x01: ram = std::vector(0x800); break; case 0x02: ram = std::vector(0x2000); break; case 0x03: ram = std::vector(0x8000); break; case 0x04: ram = std::vector(0x20000); break; case 0x05: ram = std::vector(0x10000); break; } // figure out how many rom banks there are WORD RomBanks = (WORD)0x2 << data[0x0148]; if (data[0x0148] == 0x52) RomBanks = 72; else if (data[0x0148] == 0x53) RomBanks = 80; else if (data[0x0148] == 0x54) RomBanks = 96; // figure out how many ram banks there are WORD RamBanks = 0x00; switch (data[0x0149]) { case 0x03: RamBanks = 4; break; case 0x04: RamBanks = 16; break; case 0x05: RamBanks = 8; break; } // Select MBC switch (data[0x0147]) { case 0x00: mbc = std::make_unique(0); break; case 0x01: case 0x02: case 0x03: mbc = std::make_unique(RomBanks, RamBanks, 8); break; case 0x08: case 0x09: mbc = std::make_unique(1); break; default: EXIT_MSG("This ROM uses an unsupported memory bank controller: %02x\n", data[0x0147]); exit(1); break; } } BYTE ROM::Read(WORD addr) { DWORD mappedAddr = 0x00; if (!mbc->GetMappedRead(addr, mappedAddr)) return 0xFF; switch (bus->Read(0xFF50) + (addr >= 0x100)) { case 0: // Read BIOS return bios[addr]; default: // Read ROM if (addr < 0x8000) return data[mappedAddr]; else return ram[mappedAddr]; break; } return undefined; } void ROM::Write(WORD addr, BYTE val) { DWORD mappedAddr = 0x00; if (!mbc->GetMappedWrite(addr, val, mappedAddr)) return; ram[mappedAddr] = val; }