yabgbe/src/rom.cpp
2021-07-12 05:26:38 +02:00

108 lines
3.4 KiB
C++

#include "rom.hpp"
#include <stdlib.h>
#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<BYTE>(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<BYTE>(0x800); break;
case 0x02: ram = std::vector<BYTE>(0x2000); break;
case 0x03: ram = std::vector<BYTE>(0x8000); break;
case 0x04: ram = std::vector<BYTE>(0x20000); break;
case 0x05: ram = std::vector<BYTE>(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<MBC0>(0);
break;
case 0x01:
case 0x02:
case 0x03:
mbc = std::make_unique<MBC1>(RomBanks, RamBanks, 8);
break;
case 0x08:
case 0x09:
mbc = std::make_unique<MBC0>(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;
}