all repos — mgba @ 70e16613420f3f84149810e9621c4cb65c52bd2c

mGBA Game Boy Advance Emulator

Begin SIO
Jeffrey Pfau jeffrey@endrift.com
Tue, 04 Feb 2014 00:39:55 -0800
commit

70e16613420f3f84149810e9621c4cb65c52bd2c

parent

20a5fa8476993eb5ca89b3d974641f65489b8dfa

5 files changed, 117 insertions(+), 1 deletions(-)

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

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

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

@@ -248,6 +249,15 @@ break;

case REG_TM3CNT_HI: value &= 0x00C7; 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
A src/gba/gba-sio.c

@@ -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); +}
A src/gba/gba-sio.h

@@ -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
M src/gba/gba.csrc/gba/gba.c

@@ -122,6 +122,9 @@ GBAAudioInit(&gba->audio);

GBAIOInit(gba); + gba->sio.p = gba; + GBASIOInit(&gba->sio); + gba->timersEnabled = 0; memset(gba->timers, 0, sizeof(gba->timers));
M src/gba/gba.hsrc/gba/gba.h

@@ -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 GBABoard board;

struct GBAMemory memory; struct GBAVideo video; struct GBAAudio audio; + struct GBASIO sio; struct GBASync* sync;