mirror of https://github.com/mgba-emu/mgba.git
Start GPIO
This commit is contained in:
parent
228b6aaa01
commit
ddc1034d42
|
@ -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
|
||||||
|
}
|
|
@ -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
|
|
@ -1,5 +1,6 @@
|
||||||
#include "gba-memory.h"
|
#include "gba-memory.h"
|
||||||
|
|
||||||
|
#include "gba-gpio.h"
|
||||||
#include "gba-io.h"
|
#include "gba-io.h"
|
||||||
#include "hle-bios.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);
|
gbaMemory->p->video.renderer->writeOAM(gbaMemory->p->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
|
||||||
break;
|
break;
|
||||||
case BASE_CART0:
|
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;
|
break;
|
||||||
case BASE_CART2_EX:
|
case BASE_CART2_EX:
|
||||||
if (gbaMemory->savedata.type == SAVEDATA_NONE) {
|
if (gbaMemory->savedata.type == SAVEDATA_NONE) {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "arm.h"
|
#include "arm.h"
|
||||||
|
|
||||||
|
#include "gba-gpio.h"
|
||||||
#include "gba-savedata.h"
|
#include "gba-savedata.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -112,6 +113,7 @@ struct GBAMemory {
|
||||||
uint32_t* rom;
|
uint32_t* rom;
|
||||||
uint16_t io[SIZE_IO >> 1];
|
uint16_t io[SIZE_IO >> 1];
|
||||||
|
|
||||||
|
struct GBACartridgeGPIO gpio;
|
||||||
struct GBASavedata savedata;
|
struct GBASavedata savedata;
|
||||||
size_t romSize;
|
size_t romSize;
|
||||||
uint16_t romID;
|
uint16_t romID;
|
||||||
|
|
|
@ -68,11 +68,6 @@ struct GBASavedata {
|
||||||
enum FlashStateMachine flashState;
|
enum FlashStateMachine flashState;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SavedataOverride {
|
|
||||||
uint32_t id;
|
|
||||||
enum SavedataType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
void GBASavedataInit(struct GBASavedata* savedata, const char* filename);
|
void GBASavedataInit(struct GBASavedata* savedata, const char* filename);
|
||||||
void GBASavedataDeinit(struct GBASavedata* savedata);
|
void GBASavedataDeinit(struct GBASavedata* savedata);
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,16 @@ enum {
|
||||||
SP_BASE_SUPERVISOR = 0x03FFFFE0
|
SP_BASE_SUPERVISOR = 0x03FFFFE0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct SavedataOverride _savedataOverrides[] = {
|
struct GBACartridgeOverride {
|
||||||
{ 'E4XA', SAVEDATA_FLASH1M },
|
uint32_t id;
|
||||||
{ 'EEPB', SAVEDATA_FLASH1M },
|
enum SavedataType type;
|
||||||
{ 0, 0 }
|
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);
|
static void GBAProcessEvents(struct ARMBoard* board);
|
||||||
|
@ -284,6 +290,7 @@ void GBALoadROM(struct GBA* gba, int fd, const char* fname) {
|
||||||
if (gba->savefile) {
|
if (gba->savefile) {
|
||||||
GBASavedataInit(&gba->memory.savedata, 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);
|
_checkOverrides(gba, ((struct GBACartridge*) gba->memory.rom)->id);
|
||||||
// TODO: error check
|
// TODO: error check
|
||||||
}
|
}
|
||||||
|
@ -455,10 +462,10 @@ void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
|
||||||
|
|
||||||
void _checkOverrides(struct GBA* gba, uint32_t id) {
|
void _checkOverrides(struct GBA* gba, uint32_t id) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; _savedataOverrides[i].id; ++i) {
|
for (i = 0; _overrides[i].id; ++i) {
|
||||||
if (_savedataOverrides[i].id == id) {
|
if (_overrides[i].id == id) {
|
||||||
gba->memory.savedata.type = _savedataOverrides[i].type;
|
gba->memory.savedata.type = _overrides[i].type;
|
||||||
switch (_savedataOverrides[i].type) {
|
switch (_overrides[i].type) {
|
||||||
case SAVEDATA_FLASH512:
|
case SAVEDATA_FLASH512:
|
||||||
case SAVEDATA_FLASH1M:
|
case SAVEDATA_FLASH1M:
|
||||||
GBASavedataInitFlash(&gba->memory.savedata);
|
GBASavedataInitFlash(&gba->memory.savedata);
|
||||||
|
@ -473,6 +480,10 @@ void _checkOverrides(struct GBA* gba, uint32_t id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_overrides[i].gpio & GPIO_RTC) {
|
||||||
|
GBAGPIOInitRTC(&gba->memory.gpio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue