GB MBC: Initial TAMA5 support

This commit is contained in:
Vicki Pfau 2017-07-24 10:26:29 -07:00
parent ef82480a8b
commit fd7d883e69
6 changed files with 85 additions and 8 deletions

View File

@ -31,6 +31,7 @@ enum GBMemoryBankControllerType {
GB_HuC1 = 0x11,
GB_HuC3 = 0x12,
GB_POCKETCAM = 0x13,
GB_TAMA5 = 0x14,
GB_MBC3_RTC = 0x103,
GB_MBC5_RUMBLE = 0x105
};

View File

@ -37,8 +37,6 @@ struct GBMBCRTCSaveBuffer {
void GBMBCRTCRead(struct GB* gb);
void GBMBCRTCWrite(struct GB* gb);
void GBMBC7Write(struct GBMemory*, uint16_t address, uint8_t value);
CXX_GUARD_END
#endif

View File

@ -86,6 +86,11 @@ enum GBMBC7MachineState {
GBMBC7_STATE_EEPROM_ERASE = 0x1C,
};
enum GBTAMA5Register {
GBTAMA5_BANK = 0x0,
GBTAMA5_MAX
};
struct GBMBC1State {
int mode;
int multicartStride;
@ -106,10 +111,18 @@ struct GBPocketCamState {
bool registersActive;
};
struct GBTAMA5State {
bool unlocked;
uint8_t reg;
uint8_t value;
uint8_t registers[GBTAMA5_MAX];
};
union GBMBCState {
struct GBMBC1State mbc1;
struct GBMBC7State mbc7;
struct GBPocketCamState pocketCam;
struct GBTAMA5State tama5;
};
struct mRotationSource;

View File

@ -613,7 +613,7 @@ void GBHalt(struct LR35902Core* cpu) {
void GBStop(struct LR35902Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
if (cpu->bus) {
mLOG(GB, GAME_ERROR, "Hit illegal stop at address %04X:%02X\n", cpu->pc, cpu->bus);
mLOG(GB, GAME_ERROR, "Hit illegal stop at address %04X:%02X", cpu->pc, cpu->bus);
}
if (gb->memory.io[REG_KEY1] & 1) {
gb->doubleSpeed ^= 1;
@ -639,7 +639,7 @@ void GBStop(struct LR35902Core* cpu) {
void GBIllegal(struct LR35902Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
mLOG(GB, GAME_ERROR, "Hit illegal opcode at address %04X:%02X\n", cpu->pc, cpu->bus);
mLOG(GB, GAME_ERROR, "Hit illegal opcode at address %04X:%02X", cpu->pc, cpu->bus);
#ifdef USE_DEBUGGERS
if (cpu->components && cpu->components[CPU_COMPONENT_DEBUGGER]) {
struct mDebuggerEntryInfo info = {

View File

@ -29,8 +29,13 @@ static void _GBMBC6(struct GB*, uint16_t address, uint8_t value);
static void _GBMBC7(struct GB*, uint16_t address, uint8_t value);
static void _GBHuC3(struct GB*, uint16_t address, uint8_t value);
static void _GBPocketCam(struct GB* gb, uint16_t address, uint8_t value);
static void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value);
static uint8_t _GBMBC7Read(struct GBMemory*, uint16_t address);
static void _GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t value);
static uint8_t _GBTAMA5Read(struct GBMemory*, uint16_t address);
static uint8_t _GBPocketCamRead(struct GBMemory*, uint16_t address);
void GBMBCSwitchBank(struct GB* gb, int bank) {
@ -160,11 +165,14 @@ void GBMBCInit(struct GB* gb) {
gb->memory.mbcType = GB_POCKETCAM;
break;
case 0xFD:
gb->memory.mbcType = GB_HuC1;
gb->memory.mbcType = GB_TAMA5;
break;
case 0xFE:
gb->memory.mbcType = GB_HuC3;
break;
case 0xFF:
gb->memory.mbcType = GB_HuC1;
break;
}
}
} else {
@ -211,6 +219,12 @@ void GBMBCInit(struct GB* gb) {
case GB_HuC3:
gb->memory.mbcWrite = _GBHuC3;
break;
case GB_TAMA5:
mLOG(GB_MBC, WARN, "unimplemented MBC: TAMA5");
memset(gb->memory.rtcRegs, 0, sizeof(gb->memory.rtcRegs));
gb->memory.mbcWrite = _GBTAMA5;
gb->memory.mbcRead = _GBTAMA5Read;
break;
case GB_MBC3_RTC:
memset(gb->memory.rtcRegs, 0, sizeof(gb->memory.rtcRegs));
gb->memory.mbcWrite = _GBMBC3;
@ -493,6 +507,8 @@ void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {
gb->memory.mbcState.mbc7.access &= ~2;
}
break;
case 0x5:
_GBMBC7Write(&gb->memory, address, value);
default:
// TODO
mLOG(GB_MBC, STUB, "MBC7 unknown address: %04X:%02X", address, value);
@ -547,7 +563,7 @@ uint8_t _GBMBC7Read(struct GBMemory* memory, uint16_t address) {
}
}
void GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t value) {
static void _GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t value) {
struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
if (mbc7->access != 3) {
return;
@ -750,6 +766,55 @@ uint8_t _GBPocketCamRead(struct GBMemory* memory, uint16_t address) {
return memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)];
}
void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value) {
struct GBMemory* memory = &gb->memory;
struct GBTAMA5State* tama5 = &memory->mbcState.tama5;
switch (address >> 13) {
case 0x5:
if (address & 1) {
if (tama5->unlocked) {
tama5->reg = value;
} else if (value == 0xA) {
tama5->unlocked = true;
}
} else {
uint8_t reg = tama5->reg >> 1;
if (reg < GBTAMA5_MAX) {
uint8_t mask = 0xF << (4 * (tama5->reg & 1));
value <<= (4 * (tama5->reg & 1));
value |= tama5->registers[reg] & ~mask;
tama5->registers[reg] = value;
if (tama5->reg & 1) {
switch (reg) {
case GBTAMA5_BANK:
GBMBCSwitchBank(gb, value & 0x1F);
// Fall through
default:
mLOG(GB_MBC, STUB, "TAMA5 unknown register: %02X:%02X", reg, value);
break;
}
tama5->unlocked = false;
}
} else {
mLOG(GB_MBC, STUB, "TAMA5 unknown register: %02X", reg);
}
}
break;
default:
mLOG(GB_MBC, STUB, "TAMA5 unknown address: %04X:%02X", address, value);
}
}
uint8_t _GBTAMA5Read(struct GBMemory* memory, uint16_t address) {
struct GBTAMA5State* tama5 = &memory->mbcState.tama5;
mLOG(GB_MBC, STUB, "TAMA5 unknown address: %04X", address);
if (address & 1) {
return 0xFF;
} else {
return 0xF0 | tama5->unlocked;
}
}
void GBMBCRTCRead(struct GB* gb) {
struct GBMBCRTCSaveBuffer rtcBuffer;
struct VFile* vf = gb->sramVf;

View File

@ -289,8 +289,8 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
memory->rtcRegs[memory->activeRtcReg] = value;
} else if (memory->sramAccess) {
memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value;
} else if (memory->mbcType == GB_MBC7) {
GBMBC7Write(memory, address, value);
} else {
memory->mbcWrite(gb, address, value);
}
gb->sramDirty |= GB_SRAM_DIRT_NEW;
return;