mirror of https://github.com/mgba-emu/mgba.git
GBA Hardware: Add skeleton for e-Reader support
This commit is contained in:
parent
5e30a7bfd8
commit
62a198357b
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue