mirror of https://github.com/mgba-emu/mgba.git
GB MBC: More detailed TAMA5 implementation, working saves
This commit is contained in:
parent
fd7d883e69
commit
f187fba4fb
|
@ -87,8 +87,16 @@ enum GBMBC7MachineState {
|
|||
};
|
||||
|
||||
enum GBTAMA5Register {
|
||||
GBTAMA5_BANK = 0x0,
|
||||
GBTAMA5_MAX
|
||||
GBTAMA5_BANK_LO = 0x0,
|
||||
GBTAMA5_BANK_HI = 0x1,
|
||||
GBTAMA5_WRITE_LO = 0x4,
|
||||
GBTAMA5_WRITE_HI = 0x5,
|
||||
GBTAMA5_CS = 0x6,
|
||||
GBTAMA5_ADDR_LO = 0x7,
|
||||
GBTAMA5_MAX = 0x8,
|
||||
GBTAMA5_ACTIVE = 0xA,
|
||||
GBTAMA5_READ_LO = 0xC,
|
||||
GBTAMA5_READ_HI = 0xD,
|
||||
};
|
||||
|
||||
struct GBMBC1State {
|
||||
|
@ -112,9 +120,7 @@ struct GBPocketCamState {
|
|||
};
|
||||
|
||||
struct GBTAMA5State {
|
||||
bool unlocked;
|
||||
uint8_t reg;
|
||||
uint8_t value;
|
||||
uint8_t registers[GBTAMA5_MAX];
|
||||
};
|
||||
|
||||
|
|
78
src/gb/mbc.c
78
src/gb/mbc.c
|
@ -224,6 +224,7 @@ void GBMBCInit(struct GB* gb) {
|
|||
memset(gb->memory.rtcRegs, 0, sizeof(gb->memory.rtcRegs));
|
||||
gb->memory.mbcWrite = _GBTAMA5;
|
||||
gb->memory.mbcRead = _GBTAMA5Read;
|
||||
gb->sramSize = 0x20;
|
||||
break;
|
||||
case GB_MBC3_RTC:
|
||||
memset(gb->memory.rtcRegs, 0, sizeof(gb->memory.rtcRegs));
|
||||
|
@ -772,31 +773,39 @@ void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
switch (address >> 13) {
|
||||
case 0x5:
|
||||
if (address & 1) {
|
||||
if (tama5->unlocked) {
|
||||
tama5->reg = value;
|
||||
} else if (value == 0xA) {
|
||||
tama5->unlocked = true;
|
||||
}
|
||||
tama5->reg = value;
|
||||
} 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);
|
||||
value &= 0xF;
|
||||
if (tama5->reg < GBTAMA5_MAX) {
|
||||
tama5->registers[tama5->reg] = value;
|
||||
uint8_t address = ((tama5->registers[GBTAMA5_CS] << 4) & 0x10) | tama5->registers[GBTAMA5_ADDR_LO];
|
||||
uint8_t out = (tama5->registers[GBTAMA5_WRITE_HI] << 4) | tama5->registers[GBTAMA5_WRITE_LO];
|
||||
switch (tama5->reg) {
|
||||
case GBTAMA5_BANK_LO:
|
||||
case GBTAMA5_BANK_HI:
|
||||
GBMBCSwitchBank(gb, tama5->registers[GBTAMA5_BANK_LO] | (tama5->registers[GBTAMA5_BANK_HI] << 4));
|
||||
break;
|
||||
case GBTAMA5_WRITE_LO:
|
||||
case GBTAMA5_WRITE_HI:
|
||||
case GBTAMA5_CS:
|
||||
break;
|
||||
case GBTAMA5_ADDR_LO:
|
||||
switch (tama5->registers[GBTAMA5_CS] >> 1) {
|
||||
case 0x0: // RAM write
|
||||
memory->sram[address] = out;
|
||||
break;
|
||||
case 0x1: // RAM read
|
||||
break;
|
||||
default:
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown address: %X-%02X:%02X", tama5->registers[GBTAMA5_CS] >> 1, address, out);
|
||||
}
|
||||
tama5->unlocked = false;
|
||||
break;
|
||||
default:
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown write: %02X:%X", tama5->reg, value);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown register: %02X", reg);
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown write: %02X", tama5->reg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -807,11 +816,36 @@ void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t 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 & 0x1FFF) > 1) {
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown address: %04X", address);
|
||||
}
|
||||
if (address & 1) {
|
||||
return 0xFF;
|
||||
} else {
|
||||
return 0xF0 | tama5->unlocked;
|
||||
uint8_t value = 0xF0;
|
||||
uint8_t address = ((tama5->registers[GBTAMA5_CS] << 4) & 0x10) | tama5->registers[GBTAMA5_ADDR_LO];
|
||||
switch (tama5->reg) {
|
||||
case GBTAMA5_ACTIVE:
|
||||
return 0xF1;
|
||||
case GBTAMA5_READ_LO:
|
||||
case GBTAMA5_READ_HI:
|
||||
switch (tama5->registers[GBTAMA5_CS] >> 1) {
|
||||
case 1:
|
||||
value = memory->sram[address];
|
||||
break;
|
||||
default:
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown read: %02X", tama5->reg);
|
||||
break;
|
||||
}
|
||||
if (tama5->reg == GBTAMA5_READ_HI) {
|
||||
value >>= 4;
|
||||
}
|
||||
value |= 0xF0;
|
||||
return value;
|
||||
default:
|
||||
mLOG(GB_MBC, STUB, "TAMA5 unknown read: %02X", tama5->reg);
|
||||
return 0xF1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue