GBA Hardware: Add skeleton for e-Reader support

This commit is contained in:
Vicki Pfau 2017-10-16 22:42:50 -07:00
parent 5e30a7bfd8
commit 62a198357b
4 changed files with 97 additions and 4 deletions

View File

@ -34,7 +34,8 @@ enum GBAHardwareDevice {
HW_GYRO = 8,
HW_TILT = 16,
HW_GB_PLAYER = 32,
HW_GB_PLAYER_DETECTION = 64
HW_GB_PLAYER_DETECTION = 64,
HW_EREADER = 128
};
enum GPIORegister {
@ -122,6 +123,12 @@ struct GBACartridgeHardware {
struct mTimingEvent gbpNextEvent;
struct GBAGBPKeyCallback gbpCallback;
struct GBAGBPSIODriver gbpDriver;
uint16_t eReaderData[44];
uint16_t eReaderRegisterUnk;
uint16_t eReaderRegisterReset;
uint16_t eReaderRegisterControl;
uint16_t eReaderRegisterLed;
};
void GBAHardwareInit(struct GBACartridgeHardware* gpio, uint16_t* gpioBase);
@ -141,6 +148,12 @@ struct GBAVideo;
void GBAHardwarePlayerUpdate(struct GBA* gba);
bool GBAHardwarePlayerCheckScreen(const struct GBAVideo* video);
void GBAHardwareInitEReader(struct GBACartridgeHardware* hw);
void GBAHardwareEReaderWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value);
void GBAHardwareEReaderWriteFlash(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value);
uint16_t GBAHardwareEReaderRead(struct GBACartridgeHardware* hw, uint32_t address);
uint8_t GBAHardwareEReaderReadFlash(struct GBACartridgeHardware* hw, uint32_t address);
void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba);
struct GBASerializedState;

View File

@ -36,6 +36,8 @@ static uint16_t _gbpRead(struct mKeyCallback*);
static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate);
static void _eReaderReset(struct GBACartridgeHardware* hw);
static const int RTC_BYTES[8] = {
0, // Force reset
0, // Empty
@ -591,6 +593,67 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat
gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080;
}
// == e-Reader
void GBAHardwareInitEReader(struct GBACartridgeHardware* hw) {
hw->devices |= HW_EREADER;
_eReaderReset(hw);
}
void GBAHardwareEReaderWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) {
address &= 0x700FF;
switch (address >> 17) {
case 0:
hw->eReaderRegisterUnk = value & 0xF;
break;
case 1:
hw->eReaderRegisterReset = (value & 0x8A) | 4;
if (value & 2) {
_eReaderReset(hw);
}
break;
case 2:
mLOG(GBA_HW, GAME_ERROR, "e-Reader write to read-only registers: %05X:%04X", address, value);
break;
default:
mLOG(GBA_HW, STUB, "Unimplemented e-Reader write: %05X:%04X", address, value);
}
}
void GBAHardwareEReaderWriteFlash(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value) {
address &= 0xFFFF;
mLOG(GBA_HW, STUB, "Unimplemented e-Reader write to flash: %04X:%02X", address, value);
}
uint16_t GBAHardwareEReaderRead(struct GBACartridgeHardware* hw, uint32_t address) {
address &= 0x700FF;
switch (address >> 17) {
case 0:
return hw->eReaderRegisterUnk;
case 1:
return hw->eReaderRegisterReset;
case 2:
if (address > 0x40088) {
return 0;
}
return hw->eReaderData[(address & 0xFE) >> 1];
}
mLOG(GBA_HW, STUB, "Unimplemented e-Reader read: %05X", address);
return 0;
}
uint8_t GBAHardwareEReaderReadFlash(struct GBACartridgeHardware* hw, uint32_t address) {
address &= 0xFFFF;
mLOG(GBA_HW, STUB, "Unimplemented e-Reader read from flash: %04X", address);
return 0;
}
void _eReaderReset(struct GBACartridgeHardware* hw) {
memset(hw->eReaderData, 0, sizeof(hw->eReaderData));
hw->eReaderRegisterUnk = 0;
hw->eReaderRegisterReset = 4;
}
// == Serialization
void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASerializedState* state) {

View File

@ -570,6 +570,8 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) {
value = GBASavedataReadEEPROM(&memory->savedata);
} else if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) {
value = GBAHardwareEReaderRead(&memory->hw, address);
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
@ -683,7 +685,9 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
if (gba->performingDMA == 1) {
break;
}
if (memory->savedata.type == SAVEDATA_SRAM) {
if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) {
value = GBAHardwareEReaderReadFlash(&memory->hw, address);
} else if (memory->savedata.type == SAVEDATA_SRAM) {
value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
value = GBASavedataReadFlash(&memory->savedata, address);
@ -911,7 +915,9 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
mLOG(GBA_MEM, GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
break;
case REGION_CART2_EX:
if (memory->savedata.type == SAVEDATA_AUTODETECT) {
if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) {
GBAHardwareEReaderWrite(&memory->hw, address, value);
} else if (memory->savedata.type == SAVEDATA_AUTODETECT) {
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
GBASavedataInitEEPROM(&memory->savedata);
}
@ -992,7 +998,9 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
GBASavedataInitSRAM(&memory->savedata);
}
}
if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) {
GBAHardwareEReaderWriteFlash(&memory->hw, address, value);
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
GBASavedataWriteFlash(&memory->savedata, address, value);
} else if (memory->savedata.type == SAVEDATA_SRAM) {
if (memory->vfame.cartType) {

View File

@ -50,6 +50,11 @@ static const struct GBACartridgeOverride _overrides[] = {
{ "V49J", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
{ "V49E", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
// e-Reader
{ "PEAJ", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE },
{ "PSAJ", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE },
{ "PSAE", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE },
// Final Fantasy Tactics Advance
{ "AFXE", SAVEDATA_FLASH512, HW_NONE, 0x8000428, false },
@ -328,6 +333,10 @@ void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* overri
GBAHardwareInitTilt(&gba->memory.hw);
}
if (override->hardware & HW_EREADER) {
GBAHardwareInitEReader(&gba->memory.hw);
}
if (override->hardware & HW_GB_PLAYER_DETECTION) {
gba->memory.hw.devices |= HW_GB_PLAYER_DETECTION;
} else {