Begin SIO

This commit is contained in:
Jeffrey Pfau 2014-02-04 00:39:55 -08:00
parent 20a5fa8476
commit 70e1661342
5 changed files with 117 additions and 1 deletions

View File

@ -1,6 +1,7 @@
#include "gba-io.h"
#include "gba-serialize.h"
#include "gba-sio.h"
#include "gba-video.h"
static const int _isValidRegister[REG_MAX >> 1] = {
@ -89,7 +90,7 @@ static const int _isSpecialRegister[REG_MAX >> 1] = {
void GBAIOInit(struct GBA* gba) {
gba->memory.io[REG_DISPCNT >> 1] = 0x0080;
gba->memory.io[REG_RCNT >> 1] = 0x8000;
gba->memory.io[REG_RCNT >> 1] = RCNT_INITIAL;
gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF;
}
@ -250,6 +251,15 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
GBATimerWriteTMCNT_HI(gba, 3, value);
break;
// SIO
case REG_SIOCNT:
GBASIOWriteSIOCNT(&gba->sio, value);
break;
case REG_RCNT:
value &= 0xC1FF;
GBASIOWriteRCNT(&gba->sio, value);
break;
// Interrupts and misc
case REG_WAITCNT:
GBAAdjustWaitstates(&gba->memory, value);

29
src/gba/gba-sio.c Normal file
View File

@ -0,0 +1,29 @@
#include "gba-sio.h"
#include "gba-io.h"
static void _switchMode(struct GBASIO* sio) {
int mode = ((sio->rcnt >> 14) & 0xC) | ((sio->siocnt >> 12) & 0x3);
if (mode < 8) {
sio->mode = (enum GBASIOMode) (mode & 0x3);
} else {
sio->mode = (enum GBASIOMode) (mode & 0xC);
}
// TODO: hangup if we have an existing connection
}
void GBASIOInit(struct GBASIO* sio) {
sio->rcnt = RCNT_INITIAL;
sio->siocnt = 0;
_switchMode(sio);
}
void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
sio->rcnt = value;
_switchMode(sio);
}
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
sio->siocnt = value;
_switchMode(sio);
}

72
src/gba/gba-sio.h Normal file
View File

@ -0,0 +1,72 @@
#ifndef GBA_SIO_H
#define GBA_SIO_H
#include <stdint.h>
enum GBASIOMode {
SIO_NORMAL_8 = 0,
SIO_NORMAL_32 = 1,
SIO_MULTI = 2,
SIO_UART = 3,
SIO_GPIO = 8,
SIO_JOYBUS = 12
};
enum GBASIOMultiMode {
VBA_LINK_COMPAT
};
enum {
RCNT_INITIAL = 0x8000
};
struct GBASIODriver {
int (*attach)(struct GBASIODriver* driver);
};
struct GBASIO {
struct GBA* p;
enum GBASIOMode mode;
enum GBASIOMultiMode multiMode;
struct GBASIODriver* driver;
uint16_t rcnt;
union {
struct {
unsigned sc : 1;
unsigned internalSc : 1;
unsigned si : 1;
unsigned idleSo : 1;
unsigned : 4;
unsigned start : 1;
unsigned : 3;
unsigned length : 1;
unsigned : 1;
unsigned irq : 1;
unsigned : 1;
} normalControl;
struct {
unsigned baud : 2;
unsigned slave : 1;
unsigned ready : 1;
unsigned id : 2;
unsigned error : 1;
unsigned busy : 1;
unsigned : 6;
unsigned irq : 1;
unsigned : 1;
} multiplayerControl;
uint16_t siocnt;
};
};
void GBASIOInit(struct GBASIO* sio);
void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value);
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value);
void GBASIOWriteSIOMLT_SEND(struct GBASIO* sio, uint16_t value);
#endif

View File

@ -122,6 +122,9 @@ void GBAInit(struct GBA* gba) {
GBAIOInit(gba);
gba->sio.p = gba;
GBASIOInit(&gba->sio);
gba->timersEnabled = 0;
memset(gba->timers, 0, sizeof(gba->timers));

View File

@ -7,6 +7,7 @@
#include "gba-memory.h"
#include "gba-video.h"
#include "gba-audio.h"
#include "gba-sio.h"
#include <stdarg.h>
@ -74,6 +75,7 @@ struct GBA {
struct GBAMemory memory;
struct GBAVideo video;
struct GBAAudio audio;
struct GBASIO sio;
struct GBASync* sync;