all repos — mgba @ ddc1034d42a2eba9cc367ecddc331012a206bc6c

mGBA Game Boy Advance Emulator

Start GPIO
Jeffrey Pfau jeffrey@endrift.com
Sun, 20 Oct 2013 18:08:18 -0700
commit

ddc1034d42a2eba9cc367ecddc331012a206bc6c

parent

228b6aaa016e7e249ac54504f9c42b2732261cd3

A src/gba/gba-gpio.c

@@ -0,0 +1,46 @@

+#include "gba.h" + +#include "gba-gpio.h" + +static void _readPins(struct GBACartridgeGPIO* gpio); + +static void _rtcReadPins(struct GBACartridgeGPIO* gpio); + +void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* base) { + gpio->gpioDevices = GPIO_NONE; + gpio->direction = GPIO_WRITE_ONLY; + gpio->gpioBase = base; + gpio->pinState = 0; + gpio->pinDirection = 0; +} + +void GBAGPIOWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint16_t value) { + switch (address) { + case GPIO_REG_DATA: + gpio->pinState = value; + _readPins(gpio); + break; + case GPIO_REG_DIRECTION: + gpio->pinDirection = value; + break; + case GPIO_REG_CONTROL: + gpio->direction = value; + break; + default: + GBALog(0, GBA_LOG_WARN, "Invalid GPIO address"); + } +} + +void GBAGPIOInitRTC(struct GBACartridgeGPIO* gpio) { + // TODO +} + +void _readPins(struct GBACartridgeGPIO* gpio) { + if (gpio->gpioDevices & GPIO_RTC) { + _rtcReadPins(gpio); + } +} + +void _rtcReadPins(struct GBACartridgeGPIO* gpio) { + // TODO +}
A src/gba/gba-gpio.h

@@ -0,0 +1,64 @@

+#ifndef GBA_GPIO_H +#define GBA_GPIO_H + +#include <stdint.h> + +#define IS_GPIO_REGISTER(reg) ((reg) == GPIO_REG_DATA || (reg) == GPIO_REG_DIRECTION || (reg) == GPIO_REG_CONTROL) + +enum GPIODevice { + GPIO_NONE = 0, + GPIO_RTC = 1, + GPIO_RUMBLE = 2, + GPIO_LIGHT_SENSOR = 4, + GPIO_GYRO = 8 +}; + +enum GPIORegister { + GPIO_REG_DATA = 0xC4, + GPIO_REG_DIRECTION = 0xC6, + GPIO_REG_CONTROL = 0xC8 +}; + +enum GPIODirection { + GPIO_WRITE_ONLY = 0, + GPIO_READ_WRITE = 1 +}; + +struct GBARTC { + // TODO +}; + +struct GBACartridgeGPIO { + int gpioDevices; + enum GPIODirection direction; + uint16_t* gpioBase; + + union { + struct { + unsigned p0 : 1; + unsigned p1 : 1; + unsigned p2 : 1; + unsigned p3 : 1; + }; + uint16_t pinState; + }; + + union { + struct { + unsigned dir0 : 1; + unsigned dir1 : 1; + unsigned dir2 : 1; + unsigned dir3 : 1; + }; + uint16_t pinDirection; + }; + + struct GBARTC rtc; +}; + +void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* gpioBase); +void GBAGPIOWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint16_t value); + +void GBAGPIOInitRTC(struct GBACartridgeGPIO* gpio); + +#endif
M src/gba/gba-memory.csrc/gba/gba-memory.c

@@ -1,5 +1,6 @@

#include "gba-memory.h" +#include "gba-gpio.h" #include "gba-io.h" #include "hle-bios.h"

@@ -409,7 +410,12 @@ gbaMemory->p->video.oam.raw[(address & (SIZE_OAM - 1)) >> 1] = value;

gbaMemory->p->video.renderer->writeOAM(gbaMemory->p->video.renderer, (address & (SIZE_OAM - 1)) >> 1); break; case BASE_CART0: - GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address); + if (IS_GPIO_REGISTER(address & 0xFFFFFF)) { + uint32_t reg = address & 0xFFFFFF; + GBAGPIOWrite(&gbaMemory->gpio, reg, value); + } else { + GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address); + } break; case BASE_CART2_EX: if (gbaMemory->savedata.type == SAVEDATA_NONE) {
M src/gba/gba-memory.hsrc/gba/gba-memory.h

@@ -3,6 +3,7 @@ #define GBA_MEMORY_H

#include "arm.h" +#include "gba-gpio.h" #include "gba-savedata.h" #include <string.h>

@@ -112,6 +113,7 @@ uint32_t* iwram;

uint32_t* rom; uint16_t io[SIZE_IO >> 1]; + struct GBACartridgeGPIO gpio; struct GBASavedata savedata; size_t romSize; uint16_t romID;
M src/gba/gba-savedata.hsrc/gba/gba-savedata.h

@@ -68,11 +68,6 @@

enum FlashStateMachine flashState; }; -struct SavedataOverride { - uint32_t id; - enum SavedataType type; -}; - void GBASavedataInit(struct GBASavedata* savedata, const char* filename); void GBASavedataDeinit(struct GBASavedata* savedata);
M src/gba/gba.csrc/gba/gba.c

@@ -22,10 +22,16 @@ SP_BASE_IRQ = 0x03FFFFA0,

SP_BASE_SUPERVISOR = 0x03FFFFE0 }; -static const struct SavedataOverride _savedataOverrides[] = { - { 'E4XA', SAVEDATA_FLASH1M }, - { 'EEPB', SAVEDATA_FLASH1M }, - { 0, 0 } +struct GBACartridgeOverride { + uint32_t id; + enum SavedataType type; + int gpio; +}; + +static const struct GBACartridgeOverride _overrides[] = { + { 'E4XA', SAVEDATA_FLASH1M, GPIO_NONE }, + { 'EEPB', SAVEDATA_FLASH1M, GPIO_RTC }, + { 0, 0, 0 } }; static void GBAProcessEvents(struct ARMBoard* board);

@@ -284,6 +290,7 @@ gba->memory.romSize = info.st_size;

if (gba->savefile) { GBASavedataInit(&gba->memory.savedata, gba->savefile); } + GBAGPIOInit(&gba->memory.gpio, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); _checkOverrides(gba, ((struct GBACartridge*) gba->memory.rom)->id); // TODO: error check }

@@ -455,10 +462,10 @@ }

void _checkOverrides(struct GBA* gba, uint32_t id) { int i; - for (i = 0; _savedataOverrides[i].id; ++i) { - if (_savedataOverrides[i].id == id) { - gba->memory.savedata.type = _savedataOverrides[i].type; - switch (_savedataOverrides[i].type) { + for (i = 0; _overrides[i].id; ++i) { + if (_overrides[i].id == id) { + gba->memory.savedata.type = _overrides[i].type; + switch (_overrides[i].type) { case SAVEDATA_FLASH512: case SAVEDATA_FLASH1M: GBASavedataInitFlash(&gba->memory.savedata);

@@ -473,6 +480,10 @@ case SAVEDATA_NONE:

break; } return; + + if (_overrides[i].gpio & GPIO_RTC) { + GBAGPIOInitRTC(&gba->memory.gpio); + } } } }