mirror of https://github.com/mgba-emu/mgba.git
GB MBC: Initial TAMA5 support
This commit is contained in:
parent
ef82480a8b
commit
fd7d883e69
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
69
src/gb/mbc.c
69
src/gb/mbc.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue