Start GPIO

This commit is contained in:
Jeffrey Pfau 2013-10-20 18:08:18 -07:00
parent 228b6aaa01
commit ddc1034d42
6 changed files with 138 additions and 14 deletions

46
src/gba/gba-gpio.c Normal file
View File

@ -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
}

64
src/gba/gba-gpio.h Normal file
View File

@ -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

View File

@ -1,5 +1,6 @@
#include "gba-memory.h"
#include "gba-gpio.h"
#include "gba-io.h"
#include "hle-bios.h"
@ -409,7 +410,12 @@ void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value, int*
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) {

View File

@ -3,6 +3,7 @@
#include "arm.h"
#include "gba-gpio.h"
#include "gba-savedata.h"
#include <string.h>
@ -112,6 +113,7 @@ struct GBAMemory {
uint32_t* rom;
uint16_t io[SIZE_IO >> 1];
struct GBACartridgeGPIO gpio;
struct GBASavedata savedata;
size_t romSize;
uint16_t romID;

View File

@ -68,11 +68,6 @@ struct GBASavedata {
enum FlashStateMachine flashState;
};
struct SavedataOverride {
uint32_t id;
enum SavedataType type;
};
void GBASavedataInit(struct GBASavedata* savedata, const char* filename);
void GBASavedataDeinit(struct GBASavedata* savedata);

View File

@ -22,10 +22,16 @@ enum {
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 @@ void GBALoadROM(struct GBA* gba, int fd, const char* fname) {
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 GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
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 @@ void _checkOverrides(struct GBA* gba, uint32_t id) {
break;
}
return;
if (_overrides[i].gpio & GPIO_RTC) {
GBAGPIOInitRTC(&gba->memory.gpio);
}
}
}
}