GB MBC: MBC6 skeleton

This commit is contained in:
Vicki Pfau 2017-08-11 18:19:31 -07:00
parent 8b8d846272
commit ec1fc632b2
4 changed files with 66 additions and 7 deletions

View File

@ -19,6 +19,7 @@ struct GBMemory;
void GBMBCInit(struct GB* gb);
void GBMBCSwitchBank(struct GB* gb, int bank);
void GBMBCSwitchBank0(struct GB* gb, int bank);
void GBMBCSwitchHalfBank(struct GB* gb, int half, int bank);
void GBMBCSwitchSramBank(struct GB* gb, int bank);
enum GBCam {

View File

@ -22,6 +22,8 @@ struct GB;
enum {
GB_BASE_CART_BANK0 = 0x0000,
GB_BASE_CART_BANK1 = 0x4000,
GB_BASE_CART_HALFBANK1 = 0x4000,
GB_BASE_CART_HALFBANK2 = 0x6000,
GB_BASE_VRAM = 0x8000,
GB_BASE_EXTERNAL_RAM = 0xA000,
GB_BASE_WORKING_RAM_BANK0 = 0xC000,
@ -46,6 +48,7 @@ enum {
enum {
GB_SIZE_CART_BANK0 = 0x4000,
GB_SIZE_CART_HALFBANK = 0x2000,
GB_SIZE_CART_MAX = 0x800000,
GB_SIZE_VRAM = 0x4000,
GB_SIZE_VRAM_BANK0 = 0x2000,
@ -104,6 +107,11 @@ struct GBMBC1State {
int multicartStride;
};
struct GBMBC6State {
int currentBank1;
uint8_t* romBank1;
};
struct GBMBC7State {
enum GBMBC7MachineState state;
uint16_t sr;
@ -127,6 +135,7 @@ struct GBTAMA5State {
union GBMBCState {
struct GBMBC1State mbc1;
struct GBMBC6State mbc6;
struct GBMBC7State mbc7;
struct GBPocketCamState pocketCam;
struct GBTAMA5State tama5;

View File

@ -68,6 +68,28 @@ void GBMBCSwitchBank0(struct GB* gb, int bank) {
}
}
void GBMBCSwitchHalfBank(struct GB* gb, int half, int bank) {
size_t bankStart = bank * GB_SIZE_CART_HALFBANK;
if (bankStart + GB_SIZE_CART_HALFBANK > gb->memory.romSize) {
mLOG(GB_MBC, GAME_ERROR, "Attempting to switch to an invalid ROM bank: %0X", bank);
bankStart &= (gb->memory.romSize - 1);
bank = bankStart / GB_SIZE_CART_HALFBANK;
if (!bank) {
++bank;
}
}
if (!half) {
gb->memory.romBank = &gb->memory.rom[bankStart];
gb->memory.currentBank = bank;
} else {
gb->memory.mbcState.mbc6.romBank1 = &gb->memory.rom[bankStart];
gb->memory.mbcState.mbc6.currentBank1 = bank;
}
if (gb->cpu->pc < GB_BASE_VRAM) {
gb->cpu->memory.setActiveRegion(gb->cpu, gb->cpu->pc);
}
}
static bool _isMulticart(const uint8_t* mem) {
bool success = true;
struct VFile* vf;
@ -496,11 +518,34 @@ void _GBMBC5(struct GB* gb, uint16_t address, uint8_t value) {
}
void _GBMBC6(struct GB* gb, uint16_t address, uint8_t value) {
// TODO
mLOG(GB_MBC, STUB, "MBC6 unimplemented");
UNUSED(gb);
UNUSED(address);
UNUSED(value);
struct GBMemory* memory = &gb->memory;
int bank = value & 0x7F;
switch (address >> 10) {
case 0:
switch (value) {
case 0:
memory->sramAccess = false;
break;
case 0xA:
memory->sramAccess = true;
GBMBCSwitchSramBank(gb, memory->sramCurrentBank);
break;
default:
// TODO
mLOG(GB_MBC, STUB, "MBC6 unknown value %02X", value);
break;
}
break;
case 0x9:
GBMBCSwitchHalfBank(gb, 0, bank);
break;
case 0xD:
GBMBCSwitchHalfBank(gb, 1, bank);
break;
default:
mLOG(GB_MBC, STUB, "MBC6 unknown address: %04X:%02X", address, value);
break;
}
}
void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {

View File

@ -207,10 +207,14 @@ uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) {
case GB_REGION_CART_BANK0 + 2:
case GB_REGION_CART_BANK0 + 3:
return memory->romBase[address & (GB_SIZE_CART_BANK0 - 1)];
case GB_REGION_CART_BANK1:
case GB_REGION_CART_BANK1 + 1:
case GB_REGION_CART_BANK1 + 2:
case GB_REGION_CART_BANK1 + 3:
if (memory->mbcType == GB_MBC6) {
return memory->mbcState.mbc6.romBank1[address & (GB_SIZE_CART_HALFBANK - 1)];
}
// Fall through
case GB_REGION_CART_BANK1:
case GB_REGION_CART_BANK1 + 1:
return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)];
case GB_REGION_VRAM:
case GB_REGION_VRAM + 1: