mirror of https://github.com/mgba-emu/mgba.git
Begin SIO
This commit is contained in:
parent
20a5fa8476
commit
70e1661342
|
@ -1,6 +1,7 @@
|
||||||
#include "gba-io.h"
|
#include "gba-io.h"
|
||||||
|
|
||||||
#include "gba-serialize.h"
|
#include "gba-serialize.h"
|
||||||
|
#include "gba-sio.h"
|
||||||
#include "gba-video.h"
|
#include "gba-video.h"
|
||||||
|
|
||||||
static const int _isValidRegister[REG_MAX >> 1] = {
|
static const int _isValidRegister[REG_MAX >> 1] = {
|
||||||
|
@ -89,7 +90,7 @@ static const int _isSpecialRegister[REG_MAX >> 1] = {
|
||||||
|
|
||||||
void GBAIOInit(struct GBA* gba) {
|
void GBAIOInit(struct GBA* gba) {
|
||||||
gba->memory.io[REG_DISPCNT >> 1] = 0x0080;
|
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;
|
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);
|
GBATimerWriteTMCNT_HI(gba, 3, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// SIO
|
||||||
|
case REG_SIOCNT:
|
||||||
|
GBASIOWriteSIOCNT(&gba->sio, value);
|
||||||
|
break;
|
||||||
|
case REG_RCNT:
|
||||||
|
value &= 0xC1FF;
|
||||||
|
GBASIOWriteRCNT(&gba->sio, value);
|
||||||
|
break;
|
||||||
|
|
||||||
// Interrupts and misc
|
// Interrupts and misc
|
||||||
case REG_WAITCNT:
|
case REG_WAITCNT:
|
||||||
GBAAdjustWaitstates(&gba->memory, value);
|
GBAAdjustWaitstates(&gba->memory, value);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -122,6 +122,9 @@ void GBAInit(struct GBA* gba) {
|
||||||
|
|
||||||
GBAIOInit(gba);
|
GBAIOInit(gba);
|
||||||
|
|
||||||
|
gba->sio.p = gba;
|
||||||
|
GBASIOInit(&gba->sio);
|
||||||
|
|
||||||
gba->timersEnabled = 0;
|
gba->timersEnabled = 0;
|
||||||
memset(gba->timers, 0, sizeof(gba->timers));
|
memset(gba->timers, 0, sizeof(gba->timers));
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "gba-memory.h"
|
#include "gba-memory.h"
|
||||||
#include "gba-video.h"
|
#include "gba-video.h"
|
||||||
#include "gba-audio.h"
|
#include "gba-audio.h"
|
||||||
|
#include "gba-sio.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ struct GBA {
|
||||||
struct GBAMemory memory;
|
struct GBAMemory memory;
|
||||||
struct GBAVideo video;
|
struct GBAVideo video;
|
||||||
struct GBAAudio audio;
|
struct GBAAudio audio;
|
||||||
|
struct GBASIO sio;
|
||||||
|
|
||||||
struct GBASync* sync;
|
struct GBASync* sync;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue