all repos — mgba @ 1bdde7e91dcdfc6240d07c7259bab9d3f3bb4dca

mGBA Game Boy Advance Emulator

GBA Hardware: RTC accuracy improvements
Vicki Pfau vi@endrift.com
Thu, 01 Feb 2018 09:29:07 -0800
commit

1bdde7e91dcdfc6240d07c7259bab9d3f3bb4dca

parent

ec52a47dd01ab35db1fa6a33b2b470ce63a04118

2 files changed, 19 insertions(+), 15 deletions(-)

jump to
M CHANGESCHANGES

@@ -21,6 +21,7 @@ - GBA Memory: Partially revert prefetch changes (fixes mgba.io/i/840)

- PSP2: Fix issues causing poor audio - Wii: Fix screen tear when unpausing - GBA: Fix some GBA ROM misdetection (fixes mgba.io/i/978) + - GBA Hardware: RTC accuracy improvements Misc: - GBA: Improve multiboot image detection - GB MBC: Remove erroneous bank 0 wrapping
M src/gba/hardware.csrc/gba/hardware.c

@@ -67,7 +67,7 @@ }

void GBAHardwareClear(struct GBACartridgeHardware* hw) { hw->devices = HW_NONE | (hw->devices & HW_GB_PLAYER_DETECTION); - hw->direction = GPIO_WRITE_ONLY; + hw->readWrite = GPIO_WRITE_ONLY; hw->pinState = 0; hw->direction = 0;

@@ -83,7 +83,7 @@ }

switch (address) { case GPIO_REG_DATA: hw->pinState &= ~hw->direction; - hw->pinState |= value; + hw->pinState |= value & hw->direction; _readPins(hw); break; case GPIO_REG_DIRECTION:

@@ -96,13 +96,13 @@ default:

mLOG(GBA_HW, WARN, "Invalid GPIO address"); } if (hw->readWrite) { - uint16_t old; - LOAD_16(old, 0, hw->gpioBase); - old &= ~hw->direction; - old |= hw->pinState; - STORE_16(old, 0, hw->gpioBase); + STORE_16(hw->pinState, 0, hw->gpioBase); + STORE_16(hw->direction, 2, hw->gpioBase); + STORE_16(hw->readWrite, 4, hw->gpioBase); } else { hw->gpioBase[0] = 0; + hw->gpioBase[1] = 0; + hw->gpioBase[2] = 0; } }

@@ -167,11 +167,13 @@ case 0:

if ((hw->pinState & 5) == 1) { hw->rtc.transferStep = 1; } + _outputPins(hw, 1); break; case 1: if ((hw->pinState & 5) == 5) { hw->rtc.transferStep = 2; } + _outputPins(hw, 5); break; case 2: if (!(hw->pinState & 1)) {

@@ -179,11 +181,7 @@ hw->rtc.bits &= ~(1 << hw->rtc.bitsRead);

hw->rtc.bits |= ((hw->pinState & 2) >> 1) << hw->rtc.bitsRead; } else { if (hw->pinState & 4) { - // GPIO direction should always != reading - if (hw->direction & 2) { - if (RTCCommandDataIsReading(hw->rtc.command)) { - mLOG(GBA_HW, GAME_ERROR, "Attempting to write to RTC while in read mode"); - } + if (!RTCCommandDataIsReading(hw->rtc.command)) { ++hw->rtc.bitsRead; if (hw->rtc.bitsRead == 8) { _rtcProcessByte(hw);

@@ -195,7 +193,7 @@ if (hw->rtc.bitsRead == 8) {

--hw->rtc.bytesRemaining; if (hw->rtc.bytesRemaining <= 0) { hw->rtc.commandActive = 0; - hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command); + hw->rtc.command = 0; } hw->rtc.bitsRead = 0; }

@@ -204,8 +202,9 @@ } else {

hw->rtc.bitsRead = 0; hw->rtc.bytesRemaining = 0; hw->rtc.commandActive = 0; - hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command); + hw->rtc.command = 0; hw->rtc.transferStep = 0; + _outputPins(hw, 1); } } break;

@@ -256,12 +255,16 @@ hw->rtc.bits = 0;

hw->rtc.bitsRead = 0; if (!hw->rtc.bytesRemaining) { hw->rtc.commandActive = 0; - hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command); + hw->rtc.command = 0; } } unsigned _rtcOutput(struct GBACartridgeHardware* hw) { 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)) { case RTC_CONTROL: outputByte = hw->rtc.control;