all repos — mgba @ 9b1769d67dae4a1f02f146265411c68171e031d3

mGBA Game Boy Advance Emulator

GBA: Implement light sensor GPIO interface with a hardcoded value for the moment
Jeffrey Pfau jeffrey@endrift.com
Thu, 25 Dec 2014 02:38:10 -0800
commit

9b1769d67dae4a1f02f146265411c68171e031d3

parent

a6f895da7d1cc6a7664d7d0aba44c11921cf99f0

2 files changed, 47 insertions(+), 8 deletions(-)

jump to
M src/gba/gba-gpio.csrc/gba/gba-gpio.c

@@ -24,6 +24,8 @@ static void _gyroReadPins(struct GBACartridgeGPIO* gpio);

static void _rumbleReadPins(struct GBACartridgeGPIO* gpio); +static void _lightReadPins(struct GBACartridgeGPIO* gpio); + static const int RTC_BYTES[8] = { 0, // Force reset 0, // Empty

@@ -46,7 +48,13 @@

void GBAGPIOWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint16_t value) { switch (address) { case GPIO_REG_DATA: - gpio->pinState = value; + gpio->pinState &= ~gpio->direction; + gpio->pinState |= value; + if (gpio->readWrite) { + uint16_t old = gpio->gpioBase[0]; + old &= ~gpio->direction; + gpio->gpioBase[0] = old | gpio->pinState; + } _readPins(gpio); break; case GPIO_REG_DIRECTION:

@@ -58,12 +66,6 @@ break;

default: GBALog(gpio->p, GBA_LOG_WARN, "Invalid GPIO address"); } - - if (gpio->readWrite) { - uint16_t old = gpio->gpioBase[0]; - old &= ~gpio->direction; - gpio->gpioBase[0] = old | (value & gpio->direction); - } } void GBAGPIOInitRTC(struct GBACartridgeGPIO* gpio) {

@@ -92,13 +94,18 @@

if (gpio->gpioDevices & GPIO_RUMBLE) { _rumbleReadPins(gpio); } + + if (gpio->gpioDevices & GPIO_LIGHT_SENSOR) { + _lightReadPins(gpio); + } } void _outputPins(struct GBACartridgeGPIO* gpio, unsigned pins) { if (gpio->readWrite) { uint16_t old = gpio->gpioBase[0]; old &= gpio->direction; - gpio->gpioBase[0] = old | (pins & ~gpio->direction & 0xF); + gpio->pinState = old | (pins & ~gpio->direction & 0xF); + gpio->gpioBase[0] = gpio->pinState; } }

@@ -307,6 +314,33 @@ return;

} rumble->setRumble(rumble, gpio->p3); +} + +// == Light sensor + +void GBAGPIOInitLightSensor(struct GBACartridgeGPIO* gpio) { + gpio->gpioDevices |= GPIO_LIGHT_SENSOR; + gpio->lightCounter = 0; + gpio->lightEdge = false; +} + +void _lightReadPins(struct GBACartridgeGPIO* gpio) { + if (gpio->p2) { + // Boktai chip select + return; + } + if (gpio->p1) { + GBALog(0, GBA_LOG_DEBUG, "[SOLAR] Got reset"); + gpio->lightCounter = 0; + } + if (gpio->p0 && gpio->lightEdge) { + ++gpio->lightCounter; + } + gpio->lightEdge = !gpio->p0; + + bool sendBit = gpio->lightCounter >= 0x80; + _outputPins(gpio, sendBit << 3); + GBALog(0, GBA_LOG_DEBUG, "[SOLAR] Output %u with pins %u", gpio->lightCounter, gpio->pinState); } // == Serialization
M src/gba/gba-gpio.hsrc/gba/gba-gpio.h

@@ -103,6 +103,9 @@ struct GBARTC rtc;

uint16_t gyroSample; bool gyroEdge; + + int lightCounter : 12; + bool lightEdge; }; void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* gpioBase);

@@ -113,6 +116,8 @@

void GBAGPIOInitGyro(struct GBACartridgeGPIO* gpio); void GBAGPIOInitRumble(struct GBACartridgeGPIO* gpio); + +void GBAGPIOInitLightSensor(struct GBACartridgeGPIO* gpio); struct GBASerializedState; void GBAGPIOSerialize(struct GBACartridgeGPIO* gpio, struct GBASerializedState* state);