mirror of https://github.com/mgba-emu/mgba.git
GBA Hardware: RTC accuracy improvements
This commit is contained in:
parent
ea8561347c
commit
0ce3b9a2b7
1
CHANGES
1
CHANGES
|
@ -47,6 +47,7 @@ Bugfixes:
|
||||||
- PSP2: Fix issues causing poor audio
|
- PSP2: Fix issues causing poor audio
|
||||||
- Wii: Fix screen tear when unpausing
|
- Wii: Fix screen tear when unpausing
|
||||||
- GBA: Fix some GBA ROM misdetection (fixes mgba.io/i/978)
|
- GBA: Fix some GBA ROM misdetection (fixes mgba.io/i/978)
|
||||||
|
- GBA Hardware: RTC accuracy improvements
|
||||||
Misc:
|
Misc:
|
||||||
- GBA Timer: Use global cycles for timers
|
- GBA Timer: Use global cycles for timers
|
||||||
- GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)
|
- GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)
|
||||||
|
|
|
@ -67,7 +67,7 @@ void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) {
|
||||||
|
|
||||||
void GBAHardwareClear(struct GBACartridgeHardware* hw) {
|
void GBAHardwareClear(struct GBACartridgeHardware* hw) {
|
||||||
hw->devices = HW_NONE | (hw->devices & HW_GB_PLAYER_DETECTION);
|
hw->devices = HW_NONE | (hw->devices & HW_GB_PLAYER_DETECTION);
|
||||||
hw->direction = GPIO_WRITE_ONLY;
|
hw->readWrite = GPIO_WRITE_ONLY;
|
||||||
hw->pinState = 0;
|
hw->pinState = 0;
|
||||||
hw->direction = 0;
|
hw->direction = 0;
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uin
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case GPIO_REG_DATA:
|
case GPIO_REG_DATA:
|
||||||
hw->pinState &= ~hw->direction;
|
hw->pinState &= ~hw->direction;
|
||||||
hw->pinState |= value;
|
hw->pinState |= value & hw->direction;
|
||||||
_readPins(hw);
|
_readPins(hw);
|
||||||
break;
|
break;
|
||||||
case GPIO_REG_DIRECTION:
|
case GPIO_REG_DIRECTION:
|
||||||
|
@ -96,13 +96,13 @@ void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uin
|
||||||
mLOG(GBA_HW, WARN, "Invalid GPIO address");
|
mLOG(GBA_HW, WARN, "Invalid GPIO address");
|
||||||
}
|
}
|
||||||
if (hw->readWrite) {
|
if (hw->readWrite) {
|
||||||
uint16_t old;
|
STORE_16(hw->pinState, 0, hw->gpioBase);
|
||||||
LOAD_16(old, 0, hw->gpioBase);
|
STORE_16(hw->direction, 2, hw->gpioBase);
|
||||||
old &= ~hw->direction;
|
STORE_16(hw->readWrite, 4, hw->gpioBase);
|
||||||
old |= hw->pinState;
|
|
||||||
STORE_16(old, 0, hw->gpioBase);
|
|
||||||
} else {
|
} else {
|
||||||
hw->gpioBase[0] = 0;
|
hw->gpioBase[0] = 0;
|
||||||
|
hw->gpioBase[1] = 0;
|
||||||
|
hw->gpioBase[2] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +167,13 @@ void _rtcReadPins(struct GBACartridgeHardware* hw) {
|
||||||
if ((hw->pinState & 5) == 1) {
|
if ((hw->pinState & 5) == 1) {
|
||||||
hw->rtc.transferStep = 1;
|
hw->rtc.transferStep = 1;
|
||||||
}
|
}
|
||||||
|
_outputPins(hw, 1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if ((hw->pinState & 5) == 5) {
|
if ((hw->pinState & 5) == 5) {
|
||||||
hw->rtc.transferStep = 2;
|
hw->rtc.transferStep = 2;
|
||||||
}
|
}
|
||||||
|
_outputPins(hw, 5);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (!(hw->pinState & 1)) {
|
if (!(hw->pinState & 1)) {
|
||||||
|
@ -179,11 +181,7 @@ void _rtcReadPins(struct GBACartridgeHardware* hw) {
|
||||||
hw->rtc.bits |= ((hw->pinState & 2) >> 1) << hw->rtc.bitsRead;
|
hw->rtc.bits |= ((hw->pinState & 2) >> 1) << hw->rtc.bitsRead;
|
||||||
} else {
|
} else {
|
||||||
if (hw->pinState & 4) {
|
if (hw->pinState & 4) {
|
||||||
// GPIO direction should always != reading
|
if (!RTCCommandDataIsReading(hw->rtc.command)) {
|
||||||
if (hw->direction & 2) {
|
|
||||||
if (RTCCommandDataIsReading(hw->rtc.command)) {
|
|
||||||
mLOG(GBA_HW, GAME_ERROR, "Attempting to write to RTC while in read mode");
|
|
||||||
}
|
|
||||||
++hw->rtc.bitsRead;
|
++hw->rtc.bitsRead;
|
||||||
if (hw->rtc.bitsRead == 8) {
|
if (hw->rtc.bitsRead == 8) {
|
||||||
_rtcProcessByte(hw);
|
_rtcProcessByte(hw);
|
||||||
|
@ -195,7 +193,7 @@ void _rtcReadPins(struct GBACartridgeHardware* hw) {
|
||||||
--hw->rtc.bytesRemaining;
|
--hw->rtc.bytesRemaining;
|
||||||
if (hw->rtc.bytesRemaining <= 0) {
|
if (hw->rtc.bytesRemaining <= 0) {
|
||||||
hw->rtc.commandActive = 0;
|
hw->rtc.commandActive = 0;
|
||||||
hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command);
|
hw->rtc.command = 0;
|
||||||
}
|
}
|
||||||
hw->rtc.bitsRead = 0;
|
hw->rtc.bitsRead = 0;
|
||||||
}
|
}
|
||||||
|
@ -204,8 +202,9 @@ void _rtcReadPins(struct GBACartridgeHardware* hw) {
|
||||||
hw->rtc.bitsRead = 0;
|
hw->rtc.bitsRead = 0;
|
||||||
hw->rtc.bytesRemaining = 0;
|
hw->rtc.bytesRemaining = 0;
|
||||||
hw->rtc.commandActive = 0;
|
hw->rtc.commandActive = 0;
|
||||||
hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command);
|
hw->rtc.command = 0;
|
||||||
hw->rtc.transferStep = 0;
|
hw->rtc.transferStep = 0;
|
||||||
|
_outputPins(hw, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -256,12 +255,16 @@ void _rtcProcessByte(struct GBACartridgeHardware* hw) {
|
||||||
hw->rtc.bitsRead = 0;
|
hw->rtc.bitsRead = 0;
|
||||||
if (!hw->rtc.bytesRemaining) {
|
if (!hw->rtc.bytesRemaining) {
|
||||||
hw->rtc.commandActive = 0;
|
hw->rtc.commandActive = 0;
|
||||||
hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command);
|
hw->rtc.command = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned _rtcOutput(struct GBACartridgeHardware* hw) {
|
unsigned _rtcOutput(struct GBACartridgeHardware* hw) {
|
||||||
uint8_t outputByte = 0;
|
uint8_t outputByte = 0;
|
||||||
|
if (!hw->rtc.commandActive) {
|
||||||
|
mLOG(GBA_HW, GAME_ERROR, "Attempting to use RTC without an active command");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
switch (RTCCommandDataGetCommand(hw->rtc.command)) {
|
switch (RTCCommandDataGetCommand(hw->rtc.command)) {
|
||||||
case RTC_CONTROL:
|
case RTC_CONTROL:
|
||||||
outputByte = hw->rtc.control;
|
outputByte = hw->rtc.control;
|
||||||
|
|
Loading…
Reference in New Issue