mirror of https://github.com/mgba-emu/mgba.git
GBA I/O: Prefix GBA registers with GBA_REG_
This commit is contained in:
parent
4c03970ffe
commit
8520ad8f1f
|
@ -12,160 +12,160 @@ CXX_GUARD_START
|
|||
|
||||
#include <mgba/core/log.h>
|
||||
|
||||
#define GBA_REG(X) (REG_ ## X >> 1)
|
||||
#define GBA_REG(X) (GBA_REG_ ## X >> 1)
|
||||
|
||||
enum GBAIORegisters {
|
||||
// Video
|
||||
REG_DISPCNT = 0x000,
|
||||
REG_GREENSWP = 0x002,
|
||||
REG_DISPSTAT = 0x004,
|
||||
REG_VCOUNT = 0x006,
|
||||
REG_BG0CNT = 0x008,
|
||||
REG_BG1CNT = 0x00A,
|
||||
REG_BG2CNT = 0x00C,
|
||||
REG_BG3CNT = 0x00E,
|
||||
REG_BG0HOFS = 0x010,
|
||||
REG_BG0VOFS = 0x012,
|
||||
REG_BG1HOFS = 0x014,
|
||||
REG_BG1VOFS = 0x016,
|
||||
REG_BG2HOFS = 0x018,
|
||||
REG_BG2VOFS = 0x01A,
|
||||
REG_BG3HOFS = 0x01C,
|
||||
REG_BG3VOFS = 0x01E,
|
||||
REG_BG2PA = 0x020,
|
||||
REG_BG2PB = 0x022,
|
||||
REG_BG2PC = 0x024,
|
||||
REG_BG2PD = 0x026,
|
||||
REG_BG2X_LO = 0x028,
|
||||
REG_BG2X_HI = 0x02A,
|
||||
REG_BG2Y_LO = 0x02C,
|
||||
REG_BG2Y_HI = 0x02E,
|
||||
REG_BG3PA = 0x030,
|
||||
REG_BG3PB = 0x032,
|
||||
REG_BG3PC = 0x034,
|
||||
REG_BG3PD = 0x036,
|
||||
REG_BG3X_LO = 0x038,
|
||||
REG_BG3X_HI = 0x03A,
|
||||
REG_BG3Y_LO = 0x03C,
|
||||
REG_BG3Y_HI = 0x03E,
|
||||
REG_WIN0H = 0x040,
|
||||
REG_WIN1H = 0x042,
|
||||
REG_WIN0V = 0x044,
|
||||
REG_WIN1V = 0x046,
|
||||
REG_WININ = 0x048,
|
||||
REG_WINOUT = 0x04A,
|
||||
REG_MOSAIC = 0x04C,
|
||||
REG_BLDCNT = 0x050,
|
||||
REG_BLDALPHA = 0x052,
|
||||
REG_BLDY = 0x054,
|
||||
GBA_REG_DISPCNT = 0x000,
|
||||
GBA_REG_GREENSWP = 0x002,
|
||||
GBA_REG_DISPSTAT = 0x004,
|
||||
GBA_REG_VCOUNT = 0x006,
|
||||
GBA_REG_BG0CNT = 0x008,
|
||||
GBA_REG_BG1CNT = 0x00A,
|
||||
GBA_REG_BG2CNT = 0x00C,
|
||||
GBA_REG_BG3CNT = 0x00E,
|
||||
GBA_REG_BG0HOFS = 0x010,
|
||||
GBA_REG_BG0VOFS = 0x012,
|
||||
GBA_REG_BG1HOFS = 0x014,
|
||||
GBA_REG_BG1VOFS = 0x016,
|
||||
GBA_REG_BG2HOFS = 0x018,
|
||||
GBA_REG_BG2VOFS = 0x01A,
|
||||
GBA_REG_BG3HOFS = 0x01C,
|
||||
GBA_REG_BG3VOFS = 0x01E,
|
||||
GBA_REG_BG2PA = 0x020,
|
||||
GBA_REG_BG2PB = 0x022,
|
||||
GBA_REG_BG2PC = 0x024,
|
||||
GBA_REG_BG2PD = 0x026,
|
||||
GBA_REG_BG2X_LO = 0x028,
|
||||
GBA_REG_BG2X_HI = 0x02A,
|
||||
GBA_REG_BG2Y_LO = 0x02C,
|
||||
GBA_REG_BG2Y_HI = 0x02E,
|
||||
GBA_REG_BG3PA = 0x030,
|
||||
GBA_REG_BG3PB = 0x032,
|
||||
GBA_REG_BG3PC = 0x034,
|
||||
GBA_REG_BG3PD = 0x036,
|
||||
GBA_REG_BG3X_LO = 0x038,
|
||||
GBA_REG_BG3X_HI = 0x03A,
|
||||
GBA_REG_BG3Y_LO = 0x03C,
|
||||
GBA_REG_BG3Y_HI = 0x03E,
|
||||
GBA_REG_WIN0H = 0x040,
|
||||
GBA_REG_WIN1H = 0x042,
|
||||
GBA_REG_WIN0V = 0x044,
|
||||
GBA_REG_WIN1V = 0x046,
|
||||
GBA_REG_WININ = 0x048,
|
||||
GBA_REG_WINOUT = 0x04A,
|
||||
GBA_REG_MOSAIC = 0x04C,
|
||||
GBA_REG_BLDCNT = 0x050,
|
||||
GBA_REG_BLDALPHA = 0x052,
|
||||
GBA_REG_BLDY = 0x054,
|
||||
|
||||
// Sound
|
||||
REG_SOUND1CNT_LO = 0x060,
|
||||
REG_SOUND1CNT_HI = 0x062,
|
||||
REG_SOUND1CNT_X = 0x064,
|
||||
REG_SOUND2CNT_LO = 0x068,
|
||||
REG_SOUND2CNT_HI = 0x06C,
|
||||
REG_SOUND3CNT_LO = 0x070,
|
||||
REG_SOUND3CNT_HI = 0x072,
|
||||
REG_SOUND3CNT_X = 0x074,
|
||||
REG_SOUND4CNT_LO = 0x078,
|
||||
REG_SOUND4CNT_HI = 0x07C,
|
||||
REG_SOUNDCNT_LO = 0x080,
|
||||
REG_SOUNDCNT_HI = 0x082,
|
||||
REG_SOUNDCNT_X = 0x084,
|
||||
REG_SOUNDBIAS = 0x088,
|
||||
REG_WAVE_RAM0_LO = 0x090,
|
||||
REG_WAVE_RAM0_HI = 0x092,
|
||||
REG_WAVE_RAM1_LO = 0x094,
|
||||
REG_WAVE_RAM1_HI = 0x096,
|
||||
REG_WAVE_RAM2_LO = 0x098,
|
||||
REG_WAVE_RAM2_HI = 0x09A,
|
||||
REG_WAVE_RAM3_LO = 0x09C,
|
||||
REG_WAVE_RAM3_HI = 0x09E,
|
||||
REG_FIFO_A_LO = 0x0A0,
|
||||
REG_FIFO_A_HI = 0x0A2,
|
||||
REG_FIFO_B_LO = 0x0A4,
|
||||
REG_FIFO_B_HI = 0x0A6,
|
||||
GBA_REG_SOUND1CNT_LO = 0x060,
|
||||
GBA_REG_SOUND1CNT_HI = 0x062,
|
||||
GBA_REG_SOUND1CNT_X = 0x064,
|
||||
GBA_REG_SOUND2CNT_LO = 0x068,
|
||||
GBA_REG_SOUND2CNT_HI = 0x06C,
|
||||
GBA_REG_SOUND3CNT_LO = 0x070,
|
||||
GBA_REG_SOUND3CNT_HI = 0x072,
|
||||
GBA_REG_SOUND3CNT_X = 0x074,
|
||||
GBA_REG_SOUND4CNT_LO = 0x078,
|
||||
GBA_REG_SOUND4CNT_HI = 0x07C,
|
||||
GBA_REG_SOUNDCNT_LO = 0x080,
|
||||
GBA_REG_SOUNDCNT_HI = 0x082,
|
||||
GBA_REG_SOUNDCNT_X = 0x084,
|
||||
GBA_REG_SOUNDBIAS = 0x088,
|
||||
GBA_REG_WAVE_RAM0_LO = 0x090,
|
||||
GBA_REG_WAVE_RAM0_HI = 0x092,
|
||||
GBA_REG_WAVE_RAM1_LO = 0x094,
|
||||
GBA_REG_WAVE_RAM1_HI = 0x096,
|
||||
GBA_REG_WAVE_RAM2_LO = 0x098,
|
||||
GBA_REG_WAVE_RAM2_HI = 0x09A,
|
||||
GBA_REG_WAVE_RAM3_LO = 0x09C,
|
||||
GBA_REG_WAVE_RAM3_HI = 0x09E,
|
||||
GBA_REG_FIFO_A_LO = 0x0A0,
|
||||
GBA_REG_FIFO_A_HI = 0x0A2,
|
||||
GBA_REG_FIFO_B_LO = 0x0A4,
|
||||
GBA_REG_FIFO_B_HI = 0x0A6,
|
||||
|
||||
// DMA
|
||||
REG_DMA0SAD_LO = 0x0B0,
|
||||
REG_DMA0SAD_HI = 0x0B2,
|
||||
REG_DMA0DAD_LO = 0x0B4,
|
||||
REG_DMA0DAD_HI = 0x0B6,
|
||||
REG_DMA0CNT_LO = 0x0B8,
|
||||
REG_DMA0CNT_HI = 0x0BA,
|
||||
REG_DMA1SAD_LO = 0x0BC,
|
||||
REG_DMA1SAD_HI = 0x0BE,
|
||||
REG_DMA1DAD_LO = 0x0C0,
|
||||
REG_DMA1DAD_HI = 0x0C2,
|
||||
REG_DMA1CNT_LO = 0x0C4,
|
||||
REG_DMA1CNT_HI = 0x0C6,
|
||||
REG_DMA2SAD_LO = 0x0C8,
|
||||
REG_DMA2SAD_HI = 0x0CA,
|
||||
REG_DMA2DAD_LO = 0x0CC,
|
||||
REG_DMA2DAD_HI = 0x0CE,
|
||||
REG_DMA2CNT_LO = 0x0D0,
|
||||
REG_DMA2CNT_HI = 0x0D2,
|
||||
REG_DMA3SAD_LO = 0x0D4,
|
||||
REG_DMA3SAD_HI = 0x0D6,
|
||||
REG_DMA3DAD_LO = 0x0D8,
|
||||
REG_DMA3DAD_HI = 0x0DA,
|
||||
REG_DMA3CNT_LO = 0x0DC,
|
||||
REG_DMA3CNT_HI = 0x0DE,
|
||||
GBA_REG_DMA0SAD_LO = 0x0B0,
|
||||
GBA_REG_DMA0SAD_HI = 0x0B2,
|
||||
GBA_REG_DMA0DAD_LO = 0x0B4,
|
||||
GBA_REG_DMA0DAD_HI = 0x0B6,
|
||||
GBA_REG_DMA0CNT_LO = 0x0B8,
|
||||
GBA_REG_DMA0CNT_HI = 0x0BA,
|
||||
GBA_REG_DMA1SAD_LO = 0x0BC,
|
||||
GBA_REG_DMA1SAD_HI = 0x0BE,
|
||||
GBA_REG_DMA1DAD_LO = 0x0C0,
|
||||
GBA_REG_DMA1DAD_HI = 0x0C2,
|
||||
GBA_REG_DMA1CNT_LO = 0x0C4,
|
||||
GBA_REG_DMA1CNT_HI = 0x0C6,
|
||||
GBA_REG_DMA2SAD_LO = 0x0C8,
|
||||
GBA_REG_DMA2SAD_HI = 0x0CA,
|
||||
GBA_REG_DMA2DAD_LO = 0x0CC,
|
||||
GBA_REG_DMA2DAD_HI = 0x0CE,
|
||||
GBA_REG_DMA2CNT_LO = 0x0D0,
|
||||
GBA_REG_DMA2CNT_HI = 0x0D2,
|
||||
GBA_REG_DMA3SAD_LO = 0x0D4,
|
||||
GBA_REG_DMA3SAD_HI = 0x0D6,
|
||||
GBA_REG_DMA3DAD_LO = 0x0D8,
|
||||
GBA_REG_DMA3DAD_HI = 0x0DA,
|
||||
GBA_REG_DMA3CNT_LO = 0x0DC,
|
||||
GBA_REG_DMA3CNT_HI = 0x0DE,
|
||||
|
||||
// Timers
|
||||
REG_TM0CNT_LO = 0x100,
|
||||
REG_TM0CNT_HI = 0x102,
|
||||
REG_TM1CNT_LO = 0x104,
|
||||
REG_TM1CNT_HI = 0x106,
|
||||
REG_TM2CNT_LO = 0x108,
|
||||
REG_TM2CNT_HI = 0x10A,
|
||||
REG_TM3CNT_LO = 0x10C,
|
||||
REG_TM3CNT_HI = 0x10E,
|
||||
GBA_REG_TM0CNT_LO = 0x100,
|
||||
GBA_REG_TM0CNT_HI = 0x102,
|
||||
GBA_REG_TM1CNT_LO = 0x104,
|
||||
GBA_REG_TM1CNT_HI = 0x106,
|
||||
GBA_REG_TM2CNT_LO = 0x108,
|
||||
GBA_REG_TM2CNT_HI = 0x10A,
|
||||
GBA_REG_TM3CNT_LO = 0x10C,
|
||||
GBA_REG_TM3CNT_HI = 0x10E,
|
||||
|
||||
// SIO (note: some of these are repeated)
|
||||
REG_SIODATA32_LO = 0x120,
|
||||
REG_SIOMULTI0 = 0x120,
|
||||
REG_SIODATA32_HI = 0x122,
|
||||
REG_SIOMULTI1 = 0x122,
|
||||
REG_SIOMULTI2 = 0x124,
|
||||
REG_SIOMULTI3 = 0x126,
|
||||
REG_SIOCNT = 0x128,
|
||||
REG_SIOMLT_SEND = 0x12A,
|
||||
REG_SIODATA8 = 0x12A,
|
||||
REG_RCNT = 0x134,
|
||||
REG_JOYCNT = 0x140,
|
||||
REG_JOY_RECV_LO = 0x150,
|
||||
REG_JOY_RECV_HI = 0x152,
|
||||
REG_JOY_TRANS_LO = 0x154,
|
||||
REG_JOY_TRANS_HI = 0x156,
|
||||
REG_JOYSTAT = 0x158,
|
||||
GBA_REG_SIODATA32_LO = 0x120,
|
||||
GBA_REG_SIOMULTI0 = 0x120,
|
||||
GBA_REG_SIODATA32_HI = 0x122,
|
||||
GBA_REG_SIOMULTI1 = 0x122,
|
||||
GBA_REG_SIOMULTI2 = 0x124,
|
||||
GBA_REG_SIOMULTI3 = 0x126,
|
||||
GBA_REG_SIOCNT = 0x128,
|
||||
GBA_REG_SIOMLT_SEND = 0x12A,
|
||||
GBA_REG_SIODATA8 = 0x12A,
|
||||
GBA_REG_RCNT = 0x134,
|
||||
GBA_REG_JOYCNT = 0x140,
|
||||
GBA_REG_JOY_RECV_LO = 0x150,
|
||||
GBA_REG_JOY_RECV_HI = 0x152,
|
||||
GBA_REG_JOY_TRANS_LO = 0x154,
|
||||
GBA_REG_JOY_TRANS_HI = 0x156,
|
||||
GBA_REG_JOYSTAT = 0x158,
|
||||
|
||||
// Keypad
|
||||
REG_KEYINPUT = 0x130,
|
||||
REG_KEYCNT = 0x132,
|
||||
GBA_REG_KEYINPUT = 0x130,
|
||||
GBA_REG_KEYCNT = 0x132,
|
||||
|
||||
// Interrupts, etc
|
||||
REG_IE = 0x200,
|
||||
REG_IF = 0x202,
|
||||
REG_WAITCNT = 0x204,
|
||||
REG_IME = 0x208,
|
||||
GBA_REG_IE = 0x200,
|
||||
GBA_REG_IF = 0x202,
|
||||
GBA_REG_WAITCNT = 0x204,
|
||||
GBA_REG_IME = 0x208,
|
||||
|
||||
REG_MAX = 0x20A,
|
||||
GBA_REG_MAX = 0x20A,
|
||||
|
||||
REG_POSTFLG = 0x300,
|
||||
REG_HALTCNT = 0x301,
|
||||
GBA_REG_POSTFLG = 0x300,
|
||||
GBA_REG_HALTCNT = 0x301,
|
||||
|
||||
REG_EXWAITCNT_LO = 0x800,
|
||||
REG_EXWAITCNT_HI = 0x802,
|
||||
GBA_REG_EXWAITCNT_LO = 0x800,
|
||||
GBA_REG_EXWAITCNT_HI = 0x802,
|
||||
|
||||
REG_INTERNAL_EXWAITCNT_LO = 0x210,
|
||||
REG_INTERNAL_EXWAITCNT_HI = 0x212,
|
||||
REG_INTERNAL_MAX = 0x214,
|
||||
GBA_REG_INTERNAL_EXWAITCNT_LO = 0x210,
|
||||
GBA_REG_INTERNAL_EXWAITCNT_HI = 0x212,
|
||||
GBA_REG_INTERNAL_MAX = 0x214,
|
||||
|
||||
REG_DEBUG_STRING = 0xFFF600,
|
||||
REG_DEBUG_FLAGS = 0xFFF700,
|
||||
REG_DEBUG_ENABLE = 0xFFF780,
|
||||
GBA_REG_DEBUG_STRING = 0xFFF600,
|
||||
GBA_REG_DEBUG_FLAGS = 0xFFF700,
|
||||
GBA_REG_DEBUG_ENABLE = 0xFFF780,
|
||||
};
|
||||
|
||||
mLOG_DECLARE_CATEGORY(GBA_IO);
|
||||
|
|
|
@ -136,9 +136,9 @@ struct GBAVideoSoftwareRenderer {
|
|||
int16_t objOffsetY;
|
||||
|
||||
uint32_t scanlineDirty[5];
|
||||
uint16_t nextIo[REG_SOUND1CNT_LO >> 1];
|
||||
uint16_t nextIo[GBA_REG(SOUND1CNT_LO)];
|
||||
struct ScanlineCache {
|
||||
uint16_t io[REG_SOUND1CNT_LO >> 1];
|
||||
uint16_t io[GBA_REG(SOUND1CNT_LO)];
|
||||
int32_t scale[2][2];
|
||||
} cache[GBA_VIDEO_VERTICAL_PIXELS];
|
||||
int nextY;
|
||||
|
|
|
@ -37,7 +37,7 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
|
|||
audio->sampleEvent.callback = _sample;
|
||||
audio->sampleEvent.priority = 0x18;
|
||||
audio->psg.p = NULL;
|
||||
uint8_t* nr52 = (uint8_t*) &audio->p->memory.io[REG_SOUNDCNT_X >> 1];
|
||||
uint8_t* nr52 = (uint8_t*) &audio->p->memory.io[GBA_REG(SOUNDCNT_X)];
|
||||
#ifdef __BIG_ENDIAN__
|
||||
++nr52;
|
||||
#endif
|
||||
|
@ -121,10 +121,10 @@ void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA*
|
|||
info->reg = GBADMARegisterSetDestControl(info->reg, GBA_DMA_FIXED);
|
||||
info->reg = GBADMARegisterSetWidth(info->reg, 1);
|
||||
switch (info->dest) {
|
||||
case GBA_BASE_IO | REG_FIFO_A_LO:
|
||||
case GBA_BASE_IO | GBA_REG_FIFO_A_LO:
|
||||
audio->chA.dmaSource = number;
|
||||
break;
|
||||
case GBA_BASE_IO | REG_FIFO_B_LO:
|
||||
case GBA_BASE_IO | GBA_REG_FIFO_B_LO:
|
||||
audio->chB.dmaSource = number;
|
||||
break;
|
||||
default:
|
||||
|
@ -239,7 +239,7 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
|
|||
GBAudioWriteNR52(&audio->psg, value);
|
||||
if (!audio->enable) {
|
||||
int i;
|
||||
for (i = REG_SOUND1CNT_LO; i < REG_SOUNDCNT_HI; i += 2) {
|
||||
for (i = GBA_REG_SOUND1CNT_LO; i < GBA_REG_SOUNDCNT_HI; i += 2) {
|
||||
audio->p->memory.io[i >> 1] = 0;
|
||||
}
|
||||
audio->psg.ch3.size = 0;
|
||||
|
@ -248,7 +248,7 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
|
|||
audio->volume = 0;
|
||||
audio->volumeChA = 0;
|
||||
audio->volumeChB = 0;
|
||||
audio->p->memory.io[REG_SOUNDCNT_HI >> 1] &= 0xFF00;
|
||||
audio->p->memory.io[GBA_REG(SOUNDCNT_HI)] &= 0xFF00;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,10 +296,10 @@ uint32_t GBAAudioReadWaveRAM(struct GBAAudio* audio, int address) {
|
|||
uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
|
||||
struct GBAAudioFIFO* channel;
|
||||
switch (address) {
|
||||
case REG_FIFO_A_LO:
|
||||
case GBA_REG_FIFO_A_LO:
|
||||
channel = &audio->chA;
|
||||
break;
|
||||
case REG_FIFO_B_LO:
|
||||
case GBA_REG_FIFO_B_LO:
|
||||
channel = &audio->chB;
|
||||
break;
|
||||
default:
|
||||
|
@ -530,14 +530,14 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState
|
|||
GBAudioPSGDeserialize(&audio->psg, &state->audio.psg, &state->audio.flags);
|
||||
|
||||
uint16_t reg;
|
||||
LOAD_16(reg, REG_SOUND1CNT_X, state->io);
|
||||
GBAIOWrite(audio->p, REG_SOUND1CNT_X, reg & 0x7FFF);
|
||||
LOAD_16(reg, REG_SOUND2CNT_HI, state->io);
|
||||
GBAIOWrite(audio->p, REG_SOUND2CNT_HI, reg & 0x7FFF);
|
||||
LOAD_16(reg, REG_SOUND3CNT_X, state->io);
|
||||
GBAIOWrite(audio->p, REG_SOUND3CNT_X, reg & 0x7FFF);
|
||||
LOAD_16(reg, REG_SOUND4CNT_HI, state->io);
|
||||
GBAIOWrite(audio->p, REG_SOUND4CNT_HI, reg & 0x7FFF);
|
||||
LOAD_16(reg, GBA_REG_SOUND1CNT_X, state->io);
|
||||
GBAIOWrite(audio->p, GBA_REG_SOUND1CNT_X, reg & 0x7FFF);
|
||||
LOAD_16(reg, GBA_REG_SOUND2CNT_HI, state->io);
|
||||
GBAIOWrite(audio->p, GBA_REG_SOUND2CNT_HI, reg & 0x7FFF);
|
||||
LOAD_16(reg, GBA_REG_SOUND3CNT_X, state->io);
|
||||
GBAIOWrite(audio->p, GBA_REG_SOUND3CNT_X, reg & 0x7FFF);
|
||||
LOAD_16(reg, GBA_REG_SOUND4CNT_HI, state->io);
|
||||
GBAIOWrite(audio->p, GBA_REG_SOUND4CNT_HI, reg & 0x7FFF);
|
||||
|
||||
LOAD_32(audio->chA.internalSample, 0, &state->audio.internalA);
|
||||
LOAD_32(audio->chB.internalSample, 0, &state->audio.internalB);
|
||||
|
|
190
src/gba/bios.c
190
src/gba/bios.c
|
@ -62,7 +62,7 @@ static void _SoftReset(struct GBA* gba) {
|
|||
static void _RegisterRamReset(struct GBA* gba) {
|
||||
uint32_t registers = gba->cpu->gprs[0];
|
||||
struct ARMCore* cpu = gba->cpu;
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DISPCNT, 0x0080, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DISPCNT, 0x0080, 0);
|
||||
if (registers & 0x01) {
|
||||
memset(gba->memory.wram, 0, GBA_SIZE_EWRAM);
|
||||
}
|
||||
|
@ -79,109 +79,109 @@ static void _RegisterRamReset(struct GBA* gba) {
|
|||
memset(gba->video.oam.raw, 0, GBA_SIZE_OAM);
|
||||
}
|
||||
if (registers & 0x20) {
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SIOCNT, 0x0000, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_RCNT, RCNT_INITIAL, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SIOMLT_SEND, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_JOYCNT, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | REG_JOY_RECV_LO, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | REG_JOY_TRANS_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SIOCNT, 0x0000, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_RCNT, RCNT_INITIAL, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SIOMLT_SEND, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_JOYCNT, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | GBA_REG_JOY_RECV_LO, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | GBA_REG_JOY_TRANS_LO, 0, 0);
|
||||
}
|
||||
if (registers & 0x40) {
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND1CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND1CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND1CNT_X, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND2CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND2CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND3CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND3CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND3CNT_X, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND4CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUND4CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUNDCNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUNDCNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUNDCNT_X, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_SOUNDBIAS, 0x200, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND1CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND1CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND1CNT_X, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND2CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND2CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND3CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND3CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND3CNT_X, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND4CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUND4CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUNDCNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUNDCNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUNDCNT_X, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_SOUNDBIAS, 0x200, 0);
|
||||
memset(gba->audio.psg.ch3.wavedata32, 0, sizeof(gba->audio.psg.ch3.wavedata32));
|
||||
}
|
||||
if (registers & 0x80) {
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DISPSTAT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_VCOUNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG0CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG1CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG0HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG0VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG1HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG1VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2PA, 0x100, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2PB, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2PC, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG2PD, 0x100, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | REG_BG2X_LO, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | REG_BG2Y_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3PA, 0x100, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3PB, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3PC, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BG3PD, 0x100, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | REG_BG3X_LO, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | REG_BG3Y_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WIN0H, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WIN1H, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WIN0V, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WIN1V, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WININ, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WINOUT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_MOSAIC, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BLDCNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BLDALPHA, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_BLDY, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA0SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA0SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA0DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA0DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA0CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA0CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA1SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA1SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA1DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA1DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA1CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA1CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA2SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA2SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA2DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA2DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA2CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA2CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA3SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA3SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA3DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA3DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA3CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_DMA3CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM0CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM0CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM1CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM1CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM2CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM2CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM3CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_TM3CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_IE, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_IF, 0xFFFF, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_WAITCNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | REG_IME, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DISPSTAT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_VCOUNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG0CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG1CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3CNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG0HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG0VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG1HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG1VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3HOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3VOFS, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2PA, 0x100, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2PB, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2PC, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG2PD, 0x100, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | GBA_REG_BG2X_LO, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | GBA_REG_BG2Y_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3PA, 0x100, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3PB, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3PC, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BG3PD, 0x100, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | GBA_REG_BG3X_LO, 0, 0);
|
||||
cpu->memory.store32(cpu, GBA_BASE_IO | GBA_REG_BG3Y_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WIN0H, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WIN1H, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WIN0V, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WIN1V, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WININ, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WINOUT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_MOSAIC, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BLDCNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BLDALPHA, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_BLDY, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA0SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA0SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA0DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA0DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA0CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA0CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA1SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA1SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA1DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA1DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA1CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA1CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA2SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA2SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA2DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA2DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA2CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA2CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA3SAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA3SAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA3DAD_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA3DAD_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA3CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_DMA3CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM0CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM0CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM1CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM1CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM2CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM2CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM3CNT_LO, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_TM3CNT_HI, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_IE, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_IF, 0xFFFF, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_WAITCNT, 0, 0);
|
||||
cpu->memory.store16(cpu, GBA_BASE_IO | GBA_REG_IME, 0, 0);
|
||||
}
|
||||
if (registers & 0x9C) {
|
||||
gba->video.renderer->reset(gba->video.renderer);
|
||||
gba->video.renderer->writeVideoRegister(gba->video.renderer, REG_DISPCNT, gba->memory.io[REG_DISPCNT >> 1]);
|
||||
gba->video.renderer->writeVideoRegister(gba->video.renderer, GBA_REG_DISPCNT, gba->memory.io[GBA_REG(DISPCNT)]);
|
||||
int i;
|
||||
for (i = REG_BG0CNT; i < REG_SOUND1CNT_LO; i += 2) {
|
||||
for (i = GBA_REG_BG0CNT; i < GBA_REG_SOUND1CNT_LO; i += 2) {
|
||||
gba->video.renderer->writeVideoRegister(gba->video.renderer, i, gba->memory.io[i >> 1]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -524,7 +524,7 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer
|
|||
LOAD_32(when, 0, &state->hw.gbpNextEvent);
|
||||
if (hw->devices & HW_GB_PLAYER) {
|
||||
GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, SIO_NORMAL_32);
|
||||
if (hw->p->memory.io[REG_SIOCNT >> 1] & 0x0080) {
|
||||
if (hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) {
|
||||
mTimingSchedule(&hw->p->timing, &hw->p->sio.gbp.event, when);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ bool GBACheatAddCodeBreaker(struct GBACheatSet* cheats, uint32_t op1, uint16_t o
|
|||
cheat = mCheatListAppend(&cheats->d.list);
|
||||
cheat->type = CHEAT_IF_NAND;
|
||||
cheat->width = 2;
|
||||
cheat->address = GBA_BASE_IO | REG_KEYINPUT;
|
||||
cheat->address = GBA_BASE_IO | GBA_REG_KEYINPUT;
|
||||
cheat->operand = op2;
|
||||
cheat->repeat = 1;
|
||||
return true;
|
||||
|
|
|
@ -1210,7 +1210,7 @@ static bool _GBACoreLookupIdentifier(struct mCore* core, const char* name, int32
|
|||
UNUSED(core);
|
||||
*segment = -1;
|
||||
int i;
|
||||
for (i = 0; i < REG_MAX; i += 2) {
|
||||
for (i = 0; i < GBA_REG_MAX; i += 2) {
|
||||
const char* reg = GBAIORegisterNames[i >> 1];
|
||||
if (reg && strcasecmp(reg, name) == 0) {
|
||||
*value = GBA_BASE_IO | i;
|
||||
|
@ -1555,8 +1555,8 @@ static void _GBAVLPReset(struct mCore* core) {
|
|||
|
||||
// Make sure CPU loop never spins
|
||||
GBAHalt(gba);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | REG_IME, 0, NULL);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | REG_IE, 0, NULL);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | GBA_REG_IME, 0, NULL);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | GBA_REG_IE, 0, NULL);
|
||||
}
|
||||
|
||||
static bool _GBAVLPLoadROM(struct mCore* core, struct VFile* vf) {
|
||||
|
@ -1580,8 +1580,8 @@ static bool _GBAVLPLoadState(struct mCore* core, const void* state) {
|
|||
|
||||
// Make sure CPU loop never spins
|
||||
GBAHalt(gba);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | REG_IME, 0, NULL);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | REG_IE, 0, NULL);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | GBA_REG_IME, 0, NULL);
|
||||
gba->cpu->memory.store16(gba->cpu, GBA_BASE_IO | GBA_REG_IE, 0, NULL);
|
||||
GBAVideoDeserialize(&gba->video, state);
|
||||
GBAIODeserialize(gba, state);
|
||||
GBAAudioReset(&gba->audio);
|
||||
|
|
|
@ -56,12 +56,12 @@ static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem* debugger) {
|
|||
struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
|
||||
|
||||
if (gbaDebugger->frameAdvance) {
|
||||
if (!gbaDebugger->inVblank && GBARegisterDISPSTATIsInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1])) {
|
||||
if (!gbaDebugger->inVblank && GBARegisterDISPSTATIsInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[GBA_REG(DISPSTAT)])) {
|
||||
mDebuggerEnter(gbaDebugger->d.p->d.p, DEBUGGER_ENTER_MANUAL, 0);
|
||||
gbaDebugger->frameAdvance = false;
|
||||
return false;
|
||||
}
|
||||
gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1]);
|
||||
gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[GBA_REG(DISPSTAT)]);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
@ -74,7 +74,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
|||
|
||||
struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
|
||||
gbaDebugger->frameAdvance = true;
|
||||
gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1]);
|
||||
gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[GBA_REG(DISPSTAT)]);
|
||||
}
|
||||
|
||||
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||
|
|
|
@ -202,7 +202,7 @@ void _dmaEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
dma->reg = GBADMARegisterClearEnable(dma->reg);
|
||||
|
||||
// Clear the enable bit in memory
|
||||
memory->io[(REG_DMA0CNT_HI + memory->activeDMA * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
|
||||
memory->io[(GBA_REG_DMA0CNT_HI + memory->activeDMA * (GBA_REG_DMA1CNT_HI - GBA_REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
|
||||
}
|
||||
if (GBADMARegisterGetDestControl(dma->reg) == GBA_DMA_INCREMENT_RELOAD) {
|
||||
dma->nextDest = dma->dest;
|
||||
|
|
|
@ -65,16 +65,16 @@ bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) {
|
|||
uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) {
|
||||
struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver;
|
||||
switch (address) {
|
||||
case REG_SIOCNT:
|
||||
case GBA_REG_SIOCNT:
|
||||
value &= ~0xC;
|
||||
value |= 0x8;
|
||||
if (value & 0x80) {
|
||||
_battlechipTransfer(gate);
|
||||
}
|
||||
break;
|
||||
case REG_SIOMLT_SEND:
|
||||
case GBA_REG_SIOMLT_SEND:
|
||||
break;
|
||||
case REG_RCNT:
|
||||
case GBA_REG_RCNT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -98,8 +98,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
|
|||
struct GBASIOBattlechipGate* gate = user;
|
||||
|
||||
if (gate->d.p->mode == SIO_NORMAL_32) {
|
||||
gate->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = 0;
|
||||
gate->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0;
|
||||
gate->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0;
|
||||
gate->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0;
|
||||
gate->d.p->siocnt = GBASIONormalClearStart(gate->d.p->siocnt);
|
||||
if (GBASIONormalIsIrq(gate->d.p->siocnt)) {
|
||||
GBARaiseIRQ(gate->d.p->p, GBA_IRQ_SIO, cyclesLate);
|
||||
|
@ -107,11 +107,11 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
|
|||
return;
|
||||
}
|
||||
|
||||
uint16_t cmd = gate->d.p->p->memory.io[REG_SIOMLT_SEND >> 1];
|
||||
uint16_t cmd = gate->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)];
|
||||
uint16_t reply = 0xFFFF;
|
||||
gate->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = cmd;
|
||||
gate->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF;
|
||||
gate->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF;
|
||||
gate->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = cmd;
|
||||
gate->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF;
|
||||
gate->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF;
|
||||
gate->d.p->siocnt = GBASIOMultiplayerClearBusy(gate->d.p->siocnt);
|
||||
gate->d.p->siocnt = GBASIOMultiplayerSetId(gate->d.p->siocnt, 0);
|
||||
|
||||
|
@ -191,7 +191,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
|
|||
mLOG(GBA_BATTLECHIP, DEBUG, "Gate: %04X (%i)", reply, gate->state);
|
||||
++gate->state;
|
||||
|
||||
gate->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = reply;
|
||||
gate->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = reply;
|
||||
|
||||
if (GBASIOMultiplayerIsIrq(gate->d.p->siocnt)) {
|
||||
GBARaiseIRQ(gate->d.p->p, GBA_IRQ_SIO, cyclesLate);
|
||||
|
|
|
@ -243,29 +243,29 @@ static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address) {
|
|||
uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
case GBA_REG_DISPCNT:
|
||||
value &= 0xFFF7;
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
case REG_BG1CNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
value &= 0xDFFF;
|
||||
break;
|
||||
case REG_BG2CNT:
|
||||
case REG_BG3CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
value &= 0xFFFF;
|
||||
break;
|
||||
case REG_BG0HOFS:
|
||||
case REG_BG0VOFS:
|
||||
case REG_BG1HOFS:
|
||||
case REG_BG1VOFS:
|
||||
case REG_BG2HOFS:
|
||||
case REG_BG2VOFS:
|
||||
case REG_BG3HOFS:
|
||||
case REG_BG3VOFS:
|
||||
case GBA_REG_BG0HOFS:
|
||||
case GBA_REG_BG0VOFS:
|
||||
case GBA_REG_BG1HOFS:
|
||||
case GBA_REG_BG1VOFS:
|
||||
case GBA_REG_BG2HOFS:
|
||||
case GBA_REG_BG2VOFS:
|
||||
case GBA_REG_BG3HOFS:
|
||||
case GBA_REG_BG3VOFS:
|
||||
value &= 0x01FF;
|
||||
break;
|
||||
}
|
||||
if (address > REG_BLDY) {
|
||||
if (address > GBA_REG_BLDY) {
|
||||
return value;
|
||||
}
|
||||
if (renderer->cache) {
|
||||
|
|
|
@ -281,10 +281,10 @@ void GBASkipBIOS(struct GBA* gba) {
|
|||
cpu->gprs[ARM_PC] = GBA_BASE_EWRAM;
|
||||
}
|
||||
gba->video.vcount = 0x7E;
|
||||
gba->memory.io[REG_VCOUNT >> 1] = 0x7E;
|
||||
gba->memory.io[GBA_REG(VCOUNT)] = 0x7E;
|
||||
mTimingDeschedule(&gba->timing, &gba->video.event);
|
||||
mTimingSchedule(&gba->timing, &gba->video.event, 117);
|
||||
gba->memory.io[REG_POSTFLG >> 1] = 1;
|
||||
gba->memory.io[GBA_REG(POSTFLG)] = 1;
|
||||
ARMWritePC(cpu);
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) {
|
|||
cpu->nextEvent = nextEvent;
|
||||
if (cpu->halted) {
|
||||
cpu->cycles = nextEvent;
|
||||
if (!gba->memory.io[REG_IME >> 1] || !gba->memory.io[REG_IE >> 1]) {
|
||||
if (!gba->memory.io[GBA_REG(IME)] || !gba->memory.io[GBA_REG(IE)]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ void GBAApplyPatch(struct GBA* gba, struct Patch* patch) {
|
|||
}
|
||||
|
||||
void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq, uint32_t cyclesLate) {
|
||||
gba->memory.io[REG_IF >> 1] |= 1 << irq;
|
||||
gba->memory.io[GBA_REG(IF)] |= 1 << irq;
|
||||
GBATestIRQ(gba, cyclesLate);
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ void GBATestIRQNoDelay(struct ARMCore* cpu) {
|
|||
}
|
||||
|
||||
void GBATestIRQ(struct GBA* gba, uint32_t cyclesLate) {
|
||||
if (gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
|
||||
if (gba->memory.io[GBA_REG(IE)] & gba->memory.io[GBA_REG(IF)]) {
|
||||
if (!mTimingIsScheduled(&gba->timing, &gba->irqEvent)) {
|
||||
mTimingSchedule(&gba->timing, &gba->irqEvent, GBA_IRQ_DELAY - cyclesLate);
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ void GBAHalt(struct GBA* gba) {
|
|||
|
||||
void GBAStop(struct GBA* gba) {
|
||||
int validIrqs = (1 << GBA_IRQ_GAMEPAK) | (1 << GBA_IRQ_KEYPAD) | (1 << GBA_IRQ_SIO);
|
||||
int sleep = gba->memory.io[REG_IE >> 1] & validIrqs;
|
||||
int sleep = gba->memory.io[GBA_REG(IE)] & validIrqs;
|
||||
size_t c;
|
||||
for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
|
||||
struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
|
||||
|
@ -982,7 +982,7 @@ void GBATestKeypadIRQ(struct GBA* gba) {
|
|||
uint16_t keysLast = gba->keysLast;
|
||||
uint16_t keysActive = gba->keysActive;
|
||||
|
||||
uint16_t keycnt = gba->memory.io[REG_KEYCNT >> 1];
|
||||
uint16_t keycnt = gba->memory.io[GBA_REG(KEYCNT)];
|
||||
if (!(keycnt & 0x4000)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1007,11 +1007,11 @@ static void _triggerIRQ(struct mTiming* timing, void* user, uint32_t cyclesLate)
|
|||
UNUSED(cyclesLate);
|
||||
struct GBA* gba = user;
|
||||
gba->cpu->halted = 0;
|
||||
if (!(gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1])) {
|
||||
if (!(gba->memory.io[GBA_REG(IE)] & gba->memory.io[GBA_REG(IF)])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gba->memory.io[REG_IME >> 1] && !gba->cpu->cpsr.i) {
|
||||
if (gba->memory.io[GBA_REG(IME)] && !gba->cpu->cpsr.i) {
|
||||
ARMRaiseIRQ(gba->cpu);
|
||||
}
|
||||
}
|
||||
|
|
580
src/gba/io.c
580
src/gba/io.c
|
@ -144,7 +144,7 @@ const char* const GBAIORegisterNames[] = {
|
|||
[GBA_REG(IME)] = "IME",
|
||||
};
|
||||
|
||||
static const int _isValidRegister[REG_INTERNAL_MAX >> 1] = {
|
||||
static const int _isValidRegister[GBA_REG(INTERNAL_MAX)] = {
|
||||
/* 0 2 4 6 8 A C E */
|
||||
/* Video */
|
||||
/* 00 */ 1, 0, 1, 1, 1, 1, 1, 1,
|
||||
|
@ -189,7 +189,7 @@ static const int _isValidRegister[REG_INTERNAL_MAX >> 1] = {
|
|||
1, 1
|
||||
};
|
||||
|
||||
static const int _isRSpecialRegister[REG_INTERNAL_MAX >> 1] = {
|
||||
static const int _isRSpecialRegister[GBA_REG(INTERNAL_MAX)] = {
|
||||
/* 0 2 4 6 8 A C E */
|
||||
/* Video */
|
||||
/* 00 */ 0, 0, 1, 1, 0, 0, 0, 0,
|
||||
|
@ -234,7 +234,7 @@ static const int _isRSpecialRegister[REG_INTERNAL_MAX >> 1] = {
|
|||
1, 1
|
||||
};
|
||||
|
||||
static const int _isWSpecialRegister[REG_INTERNAL_MAX >> 1] = {
|
||||
static const int _isWSpecialRegister[GBA_REG(INTERNAL_MAX)] = {
|
||||
/* 0 2 4 6 8 A C E */
|
||||
/* Video */
|
||||
/* 00 */ 0, 0, 1, 1, 0, 0, 0, 0,
|
||||
|
@ -280,230 +280,230 @@ static const int _isWSpecialRegister[REG_INTERNAL_MAX >> 1] = {
|
|||
};
|
||||
|
||||
void GBAIOInit(struct GBA* gba) {
|
||||
gba->memory.io[REG_DISPCNT >> 1] = 0x0080;
|
||||
gba->memory.io[REG_RCNT >> 1] = RCNT_INITIAL;
|
||||
gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF;
|
||||
gba->memory.io[REG_SOUNDBIAS >> 1] = 0x200;
|
||||
gba->memory.io[REG_BG2PA >> 1] = 0x100;
|
||||
gba->memory.io[REG_BG2PD >> 1] = 0x100;
|
||||
gba->memory.io[REG_BG3PA >> 1] = 0x100;
|
||||
gba->memory.io[REG_BG3PD >> 1] = 0x100;
|
||||
gba->memory.io[REG_INTERNAL_EXWAITCNT_LO >> 1] = 0x20;
|
||||
gba->memory.io[REG_INTERNAL_EXWAITCNT_HI >> 1] = 0xD00;
|
||||
gba->memory.io[GBA_REG(DISPCNT)] = 0x0080;
|
||||
gba->memory.io[GBA_REG(RCNT)] = RCNT_INITIAL;
|
||||
gba->memory.io[GBA_REG(KEYINPUT)] = 0x3FF;
|
||||
gba->memory.io[GBA_REG(SOUNDBIAS)] = 0x200;
|
||||
gba->memory.io[GBA_REG(BG2PA)] = 0x100;
|
||||
gba->memory.io[GBA_REG(BG2PD)] = 0x100;
|
||||
gba->memory.io[GBA_REG(BG3PA)] = 0x100;
|
||||
gba->memory.io[GBA_REG(BG3PD)] = 0x100;
|
||||
gba->memory.io[GBA_REG(INTERNAL_EXWAITCNT_LO)] = 0x20;
|
||||
gba->memory.io[GBA_REG(INTERNAL_EXWAITCNT_HI)] = 0xD00;
|
||||
|
||||
if (!gba->biosVf) {
|
||||
gba->memory.io[REG_VCOUNT >> 1] = 0x7E;
|
||||
gba->memory.io[REG_POSTFLG >> 1] = 1;
|
||||
gba->memory.io[GBA_REG(VCOUNT)] = 0x7E;
|
||||
gba->memory.io[GBA_REG(POSTFLG)] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
||||
if (address < REG_SOUND1CNT_LO && (address > REG_VCOUNT || address < REG_DISPSTAT)) {
|
||||
if (address < GBA_REG_SOUND1CNT_LO && (address > GBA_REG_VCOUNT || address < GBA_REG_DISPSTAT)) {
|
||||
gba->memory.io[address >> 1] = gba->video.renderer->writeVideoRegister(gba->video.renderer, address, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (address >= REG_SOUND1CNT_LO && address <= REG_SOUNDCNT_LO && !gba->audio.enable) {
|
||||
if (address >= GBA_REG_SOUND1CNT_LO && address <= GBA_REG_SOUNDCNT_LO && !gba->audio.enable) {
|
||||
// Ignore writes to most audio registers if the hardware is off.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (address) {
|
||||
// Video
|
||||
case REG_DISPSTAT:
|
||||
case GBA_REG_DISPSTAT:
|
||||
value &= 0xFFF8;
|
||||
GBAVideoWriteDISPSTAT(&gba->video, value);
|
||||
return;
|
||||
|
||||
case REG_VCOUNT:
|
||||
case GBA_REG_VCOUNT:
|
||||
mLOG(GBA_IO, GAME_ERROR, "Write to read-only I/O register: %03X", address);
|
||||
return;
|
||||
|
||||
// Audio
|
||||
case REG_SOUND1CNT_LO:
|
||||
case GBA_REG_SOUND1CNT_LO:
|
||||
GBAAudioWriteSOUND1CNT_LO(&gba->audio, value);
|
||||
value &= 0x007F;
|
||||
break;
|
||||
case REG_SOUND1CNT_HI:
|
||||
case GBA_REG_SOUND1CNT_HI:
|
||||
GBAAudioWriteSOUND1CNT_HI(&gba->audio, value);
|
||||
break;
|
||||
case REG_SOUND1CNT_X:
|
||||
case GBA_REG_SOUND1CNT_X:
|
||||
GBAAudioWriteSOUND1CNT_X(&gba->audio, value);
|
||||
value &= 0x47FF;
|
||||
break;
|
||||
case REG_SOUND2CNT_LO:
|
||||
case GBA_REG_SOUND2CNT_LO:
|
||||
GBAAudioWriteSOUND2CNT_LO(&gba->audio, value);
|
||||
break;
|
||||
case REG_SOUND2CNT_HI:
|
||||
case GBA_REG_SOUND2CNT_HI:
|
||||
GBAAudioWriteSOUND2CNT_HI(&gba->audio, value);
|
||||
value &= 0x47FF;
|
||||
break;
|
||||
case REG_SOUND3CNT_LO:
|
||||
case GBA_REG_SOUND3CNT_LO:
|
||||
GBAAudioWriteSOUND3CNT_LO(&gba->audio, value);
|
||||
value &= 0x00E0;
|
||||
break;
|
||||
case REG_SOUND3CNT_HI:
|
||||
case GBA_REG_SOUND3CNT_HI:
|
||||
GBAAudioWriteSOUND3CNT_HI(&gba->audio, value);
|
||||
value &= 0xE03F;
|
||||
break;
|
||||
case REG_SOUND3CNT_X:
|
||||
case GBA_REG_SOUND3CNT_X:
|
||||
GBAAudioWriteSOUND3CNT_X(&gba->audio, value);
|
||||
// TODO: The low bits need to not be readable, but still 8-bit writable
|
||||
value &= 0x47FF;
|
||||
break;
|
||||
case REG_SOUND4CNT_LO:
|
||||
case GBA_REG_SOUND4CNT_LO:
|
||||
GBAAudioWriteSOUND4CNT_LO(&gba->audio, value);
|
||||
value &= 0xFF3F;
|
||||
break;
|
||||
case REG_SOUND4CNT_HI:
|
||||
case GBA_REG_SOUND4CNT_HI:
|
||||
GBAAudioWriteSOUND4CNT_HI(&gba->audio, value);
|
||||
value &= 0x40FF;
|
||||
break;
|
||||
case REG_SOUNDCNT_LO:
|
||||
case GBA_REG_SOUNDCNT_LO:
|
||||
GBAAudioWriteSOUNDCNT_LO(&gba->audio, value);
|
||||
value &= 0xFF77;
|
||||
break;
|
||||
case REG_SOUNDCNT_HI:
|
||||
case GBA_REG_SOUNDCNT_HI:
|
||||
GBAAudioWriteSOUNDCNT_HI(&gba->audio, value);
|
||||
value &= 0x770F;
|
||||
break;
|
||||
case REG_SOUNDCNT_X:
|
||||
case GBA_REG_SOUNDCNT_X:
|
||||
GBAAudioWriteSOUNDCNT_X(&gba->audio, value);
|
||||
value &= 0x0080;
|
||||
value |= gba->memory.io[REG_SOUNDCNT_X >> 1] & 0xF;
|
||||
value |= gba->memory.io[GBA_REG(SOUNDCNT_X)] & 0xF;
|
||||
break;
|
||||
case REG_SOUNDBIAS:
|
||||
case GBA_REG_SOUNDBIAS:
|
||||
value &= 0xC3FE;
|
||||
GBAAudioWriteSOUNDBIAS(&gba->audio, value);
|
||||
break;
|
||||
|
||||
case REG_WAVE_RAM0_LO:
|
||||
case REG_WAVE_RAM1_LO:
|
||||
case REG_WAVE_RAM2_LO:
|
||||
case REG_WAVE_RAM3_LO:
|
||||
case GBA_REG_WAVE_RAM0_LO:
|
||||
case GBA_REG_WAVE_RAM1_LO:
|
||||
case GBA_REG_WAVE_RAM2_LO:
|
||||
case GBA_REG_WAVE_RAM3_LO:
|
||||
GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
|
||||
break;
|
||||
|
||||
case REG_WAVE_RAM0_HI:
|
||||
case REG_WAVE_RAM1_HI:
|
||||
case REG_WAVE_RAM2_HI:
|
||||
case REG_WAVE_RAM3_HI:
|
||||
case GBA_REG_WAVE_RAM0_HI:
|
||||
case GBA_REG_WAVE_RAM1_HI:
|
||||
case GBA_REG_WAVE_RAM2_HI:
|
||||
case GBA_REG_WAVE_RAM3_HI:
|
||||
GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
|
||||
break;
|
||||
|
||||
case REG_FIFO_A_LO:
|
||||
case REG_FIFO_B_LO:
|
||||
case GBA_REG_FIFO_A_LO:
|
||||
case GBA_REG_FIFO_B_LO:
|
||||
GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
|
||||
return;
|
||||
|
||||
case REG_FIFO_A_HI:
|
||||
case REG_FIFO_B_HI:
|
||||
case GBA_REG_FIFO_A_HI:
|
||||
case GBA_REG_FIFO_B_HI:
|
||||
GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
|
||||
return;
|
||||
|
||||
// DMA
|
||||
case REG_DMA0SAD_LO:
|
||||
case REG_DMA0DAD_LO:
|
||||
case REG_DMA1SAD_LO:
|
||||
case REG_DMA1DAD_LO:
|
||||
case REG_DMA2SAD_LO:
|
||||
case REG_DMA2DAD_LO:
|
||||
case REG_DMA3SAD_LO:
|
||||
case REG_DMA3DAD_LO:
|
||||
case GBA_REG_DMA0SAD_LO:
|
||||
case GBA_REG_DMA0DAD_LO:
|
||||
case GBA_REG_DMA1SAD_LO:
|
||||
case GBA_REG_DMA1DAD_LO:
|
||||
case GBA_REG_DMA2SAD_LO:
|
||||
case GBA_REG_DMA2DAD_LO:
|
||||
case GBA_REG_DMA3SAD_LO:
|
||||
case GBA_REG_DMA3DAD_LO:
|
||||
GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
|
||||
break;
|
||||
|
||||
case REG_DMA0SAD_HI:
|
||||
case REG_DMA0DAD_HI:
|
||||
case REG_DMA1SAD_HI:
|
||||
case REG_DMA1DAD_HI:
|
||||
case REG_DMA2SAD_HI:
|
||||
case REG_DMA2DAD_HI:
|
||||
case REG_DMA3SAD_HI:
|
||||
case REG_DMA3DAD_HI:
|
||||
case GBA_REG_DMA0SAD_HI:
|
||||
case GBA_REG_DMA0DAD_HI:
|
||||
case GBA_REG_DMA1SAD_HI:
|
||||
case GBA_REG_DMA1DAD_HI:
|
||||
case GBA_REG_DMA2SAD_HI:
|
||||
case GBA_REG_DMA2DAD_HI:
|
||||
case GBA_REG_DMA3SAD_HI:
|
||||
case GBA_REG_DMA3DAD_HI:
|
||||
GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
|
||||
break;
|
||||
|
||||
case REG_DMA0CNT_LO:
|
||||
case GBA_REG_DMA0CNT_LO:
|
||||
GBADMAWriteCNT_LO(gba, 0, value & 0x3FFF);
|
||||
break;
|
||||
case REG_DMA0CNT_HI:
|
||||
case GBA_REG_DMA0CNT_HI:
|
||||
value = GBADMAWriteCNT_HI(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA1CNT_LO:
|
||||
case GBA_REG_DMA1CNT_LO:
|
||||
GBADMAWriteCNT_LO(gba, 1, value & 0x3FFF);
|
||||
break;
|
||||
case REG_DMA1CNT_HI:
|
||||
case GBA_REG_DMA1CNT_HI:
|
||||
value = GBADMAWriteCNT_HI(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA2CNT_LO:
|
||||
case GBA_REG_DMA2CNT_LO:
|
||||
GBADMAWriteCNT_LO(gba, 2, value & 0x3FFF);
|
||||
break;
|
||||
case REG_DMA2CNT_HI:
|
||||
case GBA_REG_DMA2CNT_HI:
|
||||
value = GBADMAWriteCNT_HI(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA3CNT_LO:
|
||||
case GBA_REG_DMA3CNT_LO:
|
||||
GBADMAWriteCNT_LO(gba, 3, value);
|
||||
break;
|
||||
case REG_DMA3CNT_HI:
|
||||
case GBA_REG_DMA3CNT_HI:
|
||||
value = GBADMAWriteCNT_HI(gba, 3, value);
|
||||
break;
|
||||
|
||||
// Timers
|
||||
case REG_TM0CNT_LO:
|
||||
case GBA_REG_TM0CNT_LO:
|
||||
GBATimerWriteTMCNT_LO(gba, 0, value);
|
||||
return;
|
||||
case REG_TM1CNT_LO:
|
||||
case GBA_REG_TM1CNT_LO:
|
||||
GBATimerWriteTMCNT_LO(gba, 1, value);
|
||||
return;
|
||||
case REG_TM2CNT_LO:
|
||||
case GBA_REG_TM2CNT_LO:
|
||||
GBATimerWriteTMCNT_LO(gba, 2, value);
|
||||
return;
|
||||
case REG_TM3CNT_LO:
|
||||
case GBA_REG_TM3CNT_LO:
|
||||
GBATimerWriteTMCNT_LO(gba, 3, value);
|
||||
return;
|
||||
|
||||
case REG_TM0CNT_HI:
|
||||
case GBA_REG_TM0CNT_HI:
|
||||
value &= 0x00C7;
|
||||
GBATimerWriteTMCNT_HI(gba, 0, value);
|
||||
break;
|
||||
case REG_TM1CNT_HI:
|
||||
case GBA_REG_TM1CNT_HI:
|
||||
value &= 0x00C7;
|
||||
GBATimerWriteTMCNT_HI(gba, 1, value);
|
||||
break;
|
||||
case REG_TM2CNT_HI:
|
||||
case GBA_REG_TM2CNT_HI:
|
||||
value &= 0x00C7;
|
||||
GBATimerWriteTMCNT_HI(gba, 2, value);
|
||||
break;
|
||||
case REG_TM3CNT_HI:
|
||||
case GBA_REG_TM3CNT_HI:
|
||||
value &= 0x00C7;
|
||||
GBATimerWriteTMCNT_HI(gba, 3, value);
|
||||
break;
|
||||
|
||||
// SIO
|
||||
case REG_SIOCNT:
|
||||
case GBA_REG_SIOCNT:
|
||||
GBASIOWriteSIOCNT(&gba->sio, value);
|
||||
break;
|
||||
case REG_RCNT:
|
||||
case GBA_REG_RCNT:
|
||||
value &= 0xC1FF;
|
||||
GBASIOWriteRCNT(&gba->sio, value);
|
||||
break;
|
||||
case REG_JOY_TRANS_LO:
|
||||
case REG_JOY_TRANS_HI:
|
||||
gba->memory.io[REG_JOYSTAT >> 1] |= JOYSTAT_TRANS;
|
||||
case GBA_REG_JOY_TRANS_LO:
|
||||
case GBA_REG_JOY_TRANS_HI:
|
||||
gba->memory.io[GBA_REG(JOYSTAT)] |= JOYSTAT_TRANS;
|
||||
// Fall through
|
||||
case REG_SIODATA32_LO:
|
||||
case REG_SIODATA32_HI:
|
||||
case REG_SIOMLT_SEND:
|
||||
case REG_JOYCNT:
|
||||
case REG_JOYSTAT:
|
||||
case REG_JOY_RECV_LO:
|
||||
case REG_JOY_RECV_HI:
|
||||
case GBA_REG_SIODATA32_LO:
|
||||
case GBA_REG_SIODATA32_HI:
|
||||
case GBA_REG_SIOMLT_SEND:
|
||||
case GBA_REG_JOYCNT:
|
||||
case GBA_REG_JOYSTAT:
|
||||
case GBA_REG_JOY_RECV_LO:
|
||||
case GBA_REG_JOY_RECV_HI:
|
||||
value = GBASIOWriteRegister(&gba->sio, address, value);
|
||||
break;
|
||||
|
||||
// Interrupts and misc
|
||||
case REG_KEYCNT:
|
||||
case GBA_REG_KEYCNT:
|
||||
value &= 0xC3FF;
|
||||
if (gba->keysLast < 0x400) {
|
||||
gba->keysLast &= gba->memory.io[address >> 1] | ~value;
|
||||
|
@ -511,36 +511,36 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
gba->memory.io[address >> 1] = value;
|
||||
GBATestKeypadIRQ(gba);
|
||||
return;
|
||||
case REG_WAITCNT:
|
||||
case GBA_REG_WAITCNT:
|
||||
value &= 0x5FFF;
|
||||
GBAAdjustWaitstates(gba, value);
|
||||
break;
|
||||
case REG_IE:
|
||||
gba->memory.io[REG_IE >> 1] = value;
|
||||
case GBA_REG_IE:
|
||||
gba->memory.io[GBA_REG(IE)] = value;
|
||||
GBATestIRQ(gba, 1);
|
||||
return;
|
||||
case REG_IF:
|
||||
value = gba->memory.io[REG_IF >> 1] & ~value;
|
||||
gba->memory.io[REG_IF >> 1] = value;
|
||||
case GBA_REG_IF:
|
||||
value = gba->memory.io[GBA_REG(IF)] & ~value;
|
||||
gba->memory.io[GBA_REG(IF)] = value;
|
||||
GBATestIRQ(gba, 1);
|
||||
return;
|
||||
case REG_IME:
|
||||
gba->memory.io[REG_IME >> 1] = value & 1;
|
||||
case GBA_REG_IME:
|
||||
gba->memory.io[GBA_REG(IME)] = value & 1;
|
||||
GBATestIRQ(gba, 1);
|
||||
return;
|
||||
case REG_MAX:
|
||||
case GBA_REG_MAX:
|
||||
// Some bad interrupt libraries will write to this
|
||||
break;
|
||||
case REG_EXWAITCNT_HI:
|
||||
case GBA_REG_EXWAITCNT_HI:
|
||||
// This register sits outside of the normal I/O block, so we need to stash it somewhere unused
|
||||
address = REG_INTERNAL_EXWAITCNT_HI;
|
||||
address = GBA_REG_INTERNAL_EXWAITCNT_HI;
|
||||
value &= 0xFF00;
|
||||
GBAAdjustEWRAMWaitstates(gba, value);
|
||||
break;
|
||||
case REG_DEBUG_ENABLE:
|
||||
case GBA_REG_DEBUG_ENABLE:
|
||||
gba->debug = value == 0xC0DE;
|
||||
return;
|
||||
case REG_DEBUG_FLAGS:
|
||||
case GBA_REG_DEBUG_FLAGS:
|
||||
if (gba->debug) {
|
||||
GBADebug(gba, value);
|
||||
|
||||
|
@ -548,12 +548,12 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
}
|
||||
// Fall through
|
||||
default:
|
||||
if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
|
||||
STORE_16LE(value, address - REG_DEBUG_STRING, gba->debugString);
|
||||
if (address >= GBA_REG_DEBUG_STRING && address - GBA_REG_DEBUG_STRING < sizeof(gba->debugString)) {
|
||||
STORE_16LE(value, address - GBA_REG_DEBUG_STRING, gba->debugString);
|
||||
return;
|
||||
}
|
||||
mLOG(GBA_IO, STUB, "Stub I/O register write: %03X", address);
|
||||
if (address >= REG_MAX) {
|
||||
if (address >= GBA_REG_MAX) {
|
||||
mLOG(GBA_IO, GAME_ERROR, "Write to unused I/O register: %03X", address);
|
||||
return;
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
}
|
||||
|
||||
void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
|
||||
if (address == REG_HALTCNT) {
|
||||
if (address == GBA_REG_HALTCNT) {
|
||||
value &= 0x80;
|
||||
if (!value) {
|
||||
GBAHalt(gba);
|
||||
|
@ -572,12 +572,12 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (address == REG_POSTFLG) {
|
||||
if (address == GBA_REG_POSTFLG) {
|
||||
gba->memory.io[(address & (GBA_SIZE_IO - 1)) >> 1] = value;
|
||||
return;
|
||||
}
|
||||
if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
|
||||
gba->debugString[address - REG_DEBUG_STRING] = value;
|
||||
if (address >= GBA_REG_DEBUG_STRING && address - GBA_REG_DEBUG_STRING < sizeof(gba->debugString)) {
|
||||
gba->debugString[address - GBA_REG_DEBUG_STRING] = value;
|
||||
return;
|
||||
}
|
||||
if (address > GBA_SIZE_IO) {
|
||||
|
@ -593,49 +593,49 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
|
|||
// Wave RAM can be written and read even if the audio hardware is disabled.
|
||||
// However, it is not possible to switch between the two banks because it
|
||||
// isn't possible to write to register SOUND3CNT_LO.
|
||||
case REG_WAVE_RAM0_LO:
|
||||
case GBA_REG_WAVE_RAM0_LO:
|
||||
GBAAudioWriteWaveRAM(&gba->audio, 0, value);
|
||||
break;
|
||||
case REG_WAVE_RAM1_LO:
|
||||
case GBA_REG_WAVE_RAM1_LO:
|
||||
GBAAudioWriteWaveRAM(&gba->audio, 1, value);
|
||||
break;
|
||||
case REG_WAVE_RAM2_LO:
|
||||
case GBA_REG_WAVE_RAM2_LO:
|
||||
GBAAudioWriteWaveRAM(&gba->audio, 2, value);
|
||||
break;
|
||||
case REG_WAVE_RAM3_LO:
|
||||
case GBA_REG_WAVE_RAM3_LO:
|
||||
GBAAudioWriteWaveRAM(&gba->audio, 3, value);
|
||||
break;
|
||||
case REG_FIFO_A_LO:
|
||||
case REG_FIFO_B_LO:
|
||||
case GBA_REG_FIFO_A_LO:
|
||||
case GBA_REG_FIFO_B_LO:
|
||||
value = GBAAudioWriteFIFO(&gba->audio, address, value);
|
||||
break;
|
||||
case REG_DMA0SAD_LO:
|
||||
case GBA_REG_DMA0SAD_LO:
|
||||
value = GBADMAWriteSAD(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA0DAD_LO:
|
||||
case GBA_REG_DMA0DAD_LO:
|
||||
value = GBADMAWriteDAD(gba, 0, value);
|
||||
break;
|
||||
case REG_DMA1SAD_LO:
|
||||
case GBA_REG_DMA1SAD_LO:
|
||||
value = GBADMAWriteSAD(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA1DAD_LO:
|
||||
case GBA_REG_DMA1DAD_LO:
|
||||
value = GBADMAWriteDAD(gba, 1, value);
|
||||
break;
|
||||
case REG_DMA2SAD_LO:
|
||||
case GBA_REG_DMA2SAD_LO:
|
||||
value = GBADMAWriteSAD(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA2DAD_LO:
|
||||
case GBA_REG_DMA2DAD_LO:
|
||||
value = GBADMAWriteDAD(gba, 2, value);
|
||||
break;
|
||||
case REG_DMA3SAD_LO:
|
||||
case GBA_REG_DMA3SAD_LO:
|
||||
value = GBADMAWriteSAD(gba, 3, value);
|
||||
break;
|
||||
case REG_DMA3DAD_LO:
|
||||
case GBA_REG_DMA3DAD_LO:
|
||||
value = GBADMAWriteDAD(gba, 3, value);
|
||||
break;
|
||||
default:
|
||||
if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
|
||||
STORE_32LE(value, address - REG_DEBUG_STRING, gba->debugString);
|
||||
if (address >= GBA_REG_DEBUG_STRING && address - GBA_REG_DEBUG_STRING < sizeof(gba->debugString)) {
|
||||
STORE_32LE(value, address - GBA_REG_DEBUG_STRING, gba->debugString);
|
||||
return;
|
||||
}
|
||||
GBAIOWrite(gba, address, value & 0xFFFF);
|
||||
|
@ -650,33 +650,33 @@ bool GBAIOIsReadConstant(uint32_t address) {
|
|||
switch (address) {
|
||||
default:
|
||||
return false;
|
||||
case REG_BG0CNT:
|
||||
case REG_BG1CNT:
|
||||
case REG_BG2CNT:
|
||||
case REG_BG3CNT:
|
||||
case REG_WININ:
|
||||
case REG_WINOUT:
|
||||
case REG_BLDCNT:
|
||||
case REG_BLDALPHA:
|
||||
case REG_SOUND1CNT_LO:
|
||||
case REG_SOUND1CNT_HI:
|
||||
case REG_SOUND1CNT_X:
|
||||
case REG_SOUND2CNT_LO:
|
||||
case REG_SOUND2CNT_HI:
|
||||
case REG_SOUND3CNT_LO:
|
||||
case REG_SOUND3CNT_HI:
|
||||
case REG_SOUND3CNT_X:
|
||||
case REG_SOUND4CNT_LO:
|
||||
case REG_SOUND4CNT_HI:
|
||||
case REG_SOUNDCNT_LO:
|
||||
case REG_SOUNDCNT_HI:
|
||||
case REG_TM0CNT_HI:
|
||||
case REG_TM1CNT_HI:
|
||||
case REG_TM2CNT_HI:
|
||||
case REG_TM3CNT_HI:
|
||||
case REG_KEYINPUT:
|
||||
case REG_KEYCNT:
|
||||
case REG_IE:
|
||||
case GBA_REG_BG0CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
case GBA_REG_WININ:
|
||||
case GBA_REG_WINOUT:
|
||||
case GBA_REG_BLDCNT:
|
||||
case GBA_REG_BLDALPHA:
|
||||
case GBA_REG_SOUND1CNT_LO:
|
||||
case GBA_REG_SOUND1CNT_HI:
|
||||
case GBA_REG_SOUND1CNT_X:
|
||||
case GBA_REG_SOUND2CNT_LO:
|
||||
case GBA_REG_SOUND2CNT_HI:
|
||||
case GBA_REG_SOUND3CNT_LO:
|
||||
case GBA_REG_SOUND3CNT_HI:
|
||||
case GBA_REG_SOUND3CNT_X:
|
||||
case GBA_REG_SOUND4CNT_LO:
|
||||
case GBA_REG_SOUND4CNT_HI:
|
||||
case GBA_REG_SOUNDCNT_LO:
|
||||
case GBA_REG_SOUNDCNT_HI:
|
||||
case GBA_REG_TM0CNT_HI:
|
||||
case GBA_REG_TM1CNT_HI:
|
||||
case GBA_REG_TM2CNT_HI:
|
||||
case GBA_REG_TM3CNT_HI:
|
||||
case GBA_REG_KEYINPUT:
|
||||
case GBA_REG_KEYCNT:
|
||||
case GBA_REG_IE:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -689,20 +689,20 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||
|
||||
switch (address) {
|
||||
// Reading this takes two cycles (1N+1I), so let's remove them preemptively
|
||||
case REG_TM0CNT_LO:
|
||||
case GBA_REG_TM0CNT_LO:
|
||||
GBATimerUpdateRegister(gba, 0, 2);
|
||||
break;
|
||||
case REG_TM1CNT_LO:
|
||||
case GBA_REG_TM1CNT_LO:
|
||||
GBATimerUpdateRegister(gba, 1, 2);
|
||||
break;
|
||||
case REG_TM2CNT_LO:
|
||||
case GBA_REG_TM2CNT_LO:
|
||||
GBATimerUpdateRegister(gba, 2, 2);
|
||||
break;
|
||||
case REG_TM3CNT_LO:
|
||||
case GBA_REG_TM3CNT_LO:
|
||||
GBATimerUpdateRegister(gba, 3, 2);
|
||||
break;
|
||||
|
||||
case REG_KEYINPUT: {
|
||||
case GBA_REG_KEYINPUT: {
|
||||
size_t c;
|
||||
for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
|
||||
struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
|
||||
|
@ -732,157 +732,157 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||
gba->memory.io[address >> 1] = 0x3FF ^ input;
|
||||
}
|
||||
break;
|
||||
case REG_SIOCNT:
|
||||
case GBA_REG_SIOCNT:
|
||||
return gba->sio.siocnt;
|
||||
case REG_RCNT:
|
||||
case GBA_REG_RCNT:
|
||||
return gba->sio.rcnt;
|
||||
|
||||
case REG_BG0HOFS:
|
||||
case REG_BG0VOFS:
|
||||
case REG_BG1HOFS:
|
||||
case REG_BG1VOFS:
|
||||
case REG_BG2HOFS:
|
||||
case REG_BG2VOFS:
|
||||
case REG_BG3HOFS:
|
||||
case REG_BG3VOFS:
|
||||
case REG_BG2PA:
|
||||
case REG_BG2PB:
|
||||
case REG_BG2PC:
|
||||
case REG_BG2PD:
|
||||
case REG_BG2X_LO:
|
||||
case REG_BG2X_HI:
|
||||
case REG_BG2Y_LO:
|
||||
case REG_BG2Y_HI:
|
||||
case REG_BG3PA:
|
||||
case REG_BG3PB:
|
||||
case REG_BG3PC:
|
||||
case REG_BG3PD:
|
||||
case REG_BG3X_LO:
|
||||
case REG_BG3X_HI:
|
||||
case REG_BG3Y_LO:
|
||||
case REG_BG3Y_HI:
|
||||
case REG_WIN0H:
|
||||
case REG_WIN1H:
|
||||
case REG_WIN0V:
|
||||
case REG_WIN1V:
|
||||
case REG_MOSAIC:
|
||||
case REG_BLDY:
|
||||
case REG_FIFO_A_LO:
|
||||
case REG_FIFO_A_HI:
|
||||
case REG_FIFO_B_LO:
|
||||
case REG_FIFO_B_HI:
|
||||
case REG_DMA0SAD_LO:
|
||||
case REG_DMA0SAD_HI:
|
||||
case REG_DMA0DAD_LO:
|
||||
case REG_DMA0DAD_HI:
|
||||
case REG_DMA1SAD_LO:
|
||||
case REG_DMA1SAD_HI:
|
||||
case REG_DMA1DAD_LO:
|
||||
case REG_DMA1DAD_HI:
|
||||
case REG_DMA2SAD_LO:
|
||||
case REG_DMA2SAD_HI:
|
||||
case REG_DMA2DAD_LO:
|
||||
case REG_DMA2DAD_HI:
|
||||
case REG_DMA3SAD_LO:
|
||||
case REG_DMA3SAD_HI:
|
||||
case REG_DMA3DAD_LO:
|
||||
case REG_DMA3DAD_HI:
|
||||
case GBA_REG_BG0HOFS:
|
||||
case GBA_REG_BG0VOFS:
|
||||
case GBA_REG_BG1HOFS:
|
||||
case GBA_REG_BG1VOFS:
|
||||
case GBA_REG_BG2HOFS:
|
||||
case GBA_REG_BG2VOFS:
|
||||
case GBA_REG_BG3HOFS:
|
||||
case GBA_REG_BG3VOFS:
|
||||
case GBA_REG_BG2PA:
|
||||
case GBA_REG_BG2PB:
|
||||
case GBA_REG_BG2PC:
|
||||
case GBA_REG_BG2PD:
|
||||
case GBA_REG_BG2X_LO:
|
||||
case GBA_REG_BG2X_HI:
|
||||
case GBA_REG_BG2Y_LO:
|
||||
case GBA_REG_BG2Y_HI:
|
||||
case GBA_REG_BG3PA:
|
||||
case GBA_REG_BG3PB:
|
||||
case GBA_REG_BG3PC:
|
||||
case GBA_REG_BG3PD:
|
||||
case GBA_REG_BG3X_LO:
|
||||
case GBA_REG_BG3X_HI:
|
||||
case GBA_REG_BG3Y_LO:
|
||||
case GBA_REG_BG3Y_HI:
|
||||
case GBA_REG_WIN0H:
|
||||
case GBA_REG_WIN1H:
|
||||
case GBA_REG_WIN0V:
|
||||
case GBA_REG_WIN1V:
|
||||
case GBA_REG_MOSAIC:
|
||||
case GBA_REG_BLDY:
|
||||
case GBA_REG_FIFO_A_LO:
|
||||
case GBA_REG_FIFO_A_HI:
|
||||
case GBA_REG_FIFO_B_LO:
|
||||
case GBA_REG_FIFO_B_HI:
|
||||
case GBA_REG_DMA0SAD_LO:
|
||||
case GBA_REG_DMA0SAD_HI:
|
||||
case GBA_REG_DMA0DAD_LO:
|
||||
case GBA_REG_DMA0DAD_HI:
|
||||
case GBA_REG_DMA1SAD_LO:
|
||||
case GBA_REG_DMA1SAD_HI:
|
||||
case GBA_REG_DMA1DAD_LO:
|
||||
case GBA_REG_DMA1DAD_HI:
|
||||
case GBA_REG_DMA2SAD_LO:
|
||||
case GBA_REG_DMA2SAD_HI:
|
||||
case GBA_REG_DMA2DAD_LO:
|
||||
case GBA_REG_DMA2DAD_HI:
|
||||
case GBA_REG_DMA3SAD_LO:
|
||||
case GBA_REG_DMA3SAD_HI:
|
||||
case GBA_REG_DMA3DAD_LO:
|
||||
case GBA_REG_DMA3DAD_HI:
|
||||
// Write-only register
|
||||
mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address);
|
||||
return GBALoadBad(gba->cpu);
|
||||
|
||||
case REG_DMA0CNT_LO:
|
||||
case REG_DMA1CNT_LO:
|
||||
case REG_DMA2CNT_LO:
|
||||
case REG_DMA3CNT_LO:
|
||||
case GBA_REG_DMA0CNT_LO:
|
||||
case GBA_REG_DMA1CNT_LO:
|
||||
case GBA_REG_DMA2CNT_LO:
|
||||
case GBA_REG_DMA3CNT_LO:
|
||||
// Many, many things read from the DMA register
|
||||
case REG_MAX:
|
||||
case GBA_REG_MAX:
|
||||
// Some bad interrupt libraries will read from this
|
||||
// (Silent) write-only register
|
||||
return 0;
|
||||
|
||||
case REG_JOY_RECV_LO:
|
||||
case REG_JOY_RECV_HI:
|
||||
gba->memory.io[REG_JOYSTAT >> 1] &= ~JOYSTAT_RECV;
|
||||
case GBA_REG_JOY_RECV_LO:
|
||||
case GBA_REG_JOY_RECV_HI:
|
||||
gba->memory.io[GBA_REG(JOYSTAT)] &= ~JOYSTAT_RECV;
|
||||
break;
|
||||
|
||||
case REG_POSTFLG:
|
||||
case GBA_REG_POSTFLG:
|
||||
mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address);
|
||||
break;
|
||||
|
||||
// Wave RAM can be written and read even if the audio hardware is disabled.
|
||||
// However, it is not possible to switch between the two banks because it
|
||||
// isn't possible to write to register SOUND3CNT_LO.
|
||||
case REG_WAVE_RAM0_LO:
|
||||
case GBA_REG_WAVE_RAM0_LO:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 0) & 0xFFFF;
|
||||
case REG_WAVE_RAM0_HI:
|
||||
case GBA_REG_WAVE_RAM0_HI:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 0) >> 16;
|
||||
case REG_WAVE_RAM1_LO:
|
||||
case GBA_REG_WAVE_RAM1_LO:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 1) & 0xFFFF;
|
||||
case REG_WAVE_RAM1_HI:
|
||||
case GBA_REG_WAVE_RAM1_HI:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 1) >> 16;
|
||||
case REG_WAVE_RAM2_LO:
|
||||
case GBA_REG_WAVE_RAM2_LO:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 2) & 0xFFFF;
|
||||
case REG_WAVE_RAM2_HI:
|
||||
case GBA_REG_WAVE_RAM2_HI:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 2) >> 16;
|
||||
case REG_WAVE_RAM3_LO:
|
||||
case GBA_REG_WAVE_RAM3_LO:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 3) & 0xFFFF;
|
||||
case REG_WAVE_RAM3_HI:
|
||||
case GBA_REG_WAVE_RAM3_HI:
|
||||
return GBAAudioReadWaveRAM(&gba->audio, 3) >> 16;
|
||||
|
||||
case REG_SOUND1CNT_LO:
|
||||
case REG_SOUND1CNT_HI:
|
||||
case REG_SOUND1CNT_X:
|
||||
case REG_SOUND2CNT_LO:
|
||||
case REG_SOUND2CNT_HI:
|
||||
case REG_SOUND3CNT_LO:
|
||||
case REG_SOUND3CNT_HI:
|
||||
case REG_SOUND3CNT_X:
|
||||
case REG_SOUND4CNT_LO:
|
||||
case REG_SOUND4CNT_HI:
|
||||
case REG_SOUNDCNT_LO:
|
||||
if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
|
||||
case GBA_REG_SOUND1CNT_LO:
|
||||
case GBA_REG_SOUND1CNT_HI:
|
||||
case GBA_REG_SOUND1CNT_X:
|
||||
case GBA_REG_SOUND2CNT_LO:
|
||||
case GBA_REG_SOUND2CNT_HI:
|
||||
case GBA_REG_SOUND3CNT_LO:
|
||||
case GBA_REG_SOUND3CNT_HI:
|
||||
case GBA_REG_SOUND3CNT_X:
|
||||
case GBA_REG_SOUND4CNT_LO:
|
||||
case GBA_REG_SOUND4CNT_HI:
|
||||
case GBA_REG_SOUNDCNT_LO:
|
||||
if (!GBAudioEnableIsEnable(gba->memory.io[GBA_REG(SOUNDCNT_X)])) {
|
||||
// TODO: Is writing allowed when the circuit is disabled?
|
||||
return 0;
|
||||
}
|
||||
// Fall through
|
||||
case REG_DISPCNT:
|
||||
case REG_GREENSWP:
|
||||
case REG_DISPSTAT:
|
||||
case REG_VCOUNT:
|
||||
case REG_BG0CNT:
|
||||
case REG_BG1CNT:
|
||||
case REG_BG2CNT:
|
||||
case REG_BG3CNT:
|
||||
case REG_WININ:
|
||||
case REG_WINOUT:
|
||||
case REG_BLDCNT:
|
||||
case REG_BLDALPHA:
|
||||
case REG_SOUNDCNT_HI:
|
||||
case REG_SOUNDCNT_X:
|
||||
case REG_SOUNDBIAS:
|
||||
case REG_DMA0CNT_HI:
|
||||
case REG_DMA1CNT_HI:
|
||||
case REG_DMA2CNT_HI:
|
||||
case REG_DMA3CNT_HI:
|
||||
case REG_TM0CNT_HI:
|
||||
case REG_TM1CNT_HI:
|
||||
case REG_TM2CNT_HI:
|
||||
case REG_TM3CNT_HI:
|
||||
case REG_KEYCNT:
|
||||
case REG_SIOMULTI0:
|
||||
case REG_SIOMULTI1:
|
||||
case REG_SIOMULTI2:
|
||||
case REG_SIOMULTI3:
|
||||
case REG_SIOMLT_SEND:
|
||||
case REG_JOYCNT:
|
||||
case REG_JOY_TRANS_LO:
|
||||
case REG_JOY_TRANS_HI:
|
||||
case REG_JOYSTAT:
|
||||
case REG_IE:
|
||||
case REG_IF:
|
||||
case REG_WAITCNT:
|
||||
case REG_IME:
|
||||
case GBA_REG_DISPCNT:
|
||||
case GBA_REG_GREENSWP:
|
||||
case GBA_REG_DISPSTAT:
|
||||
case GBA_REG_VCOUNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
case GBA_REG_WININ:
|
||||
case GBA_REG_WINOUT:
|
||||
case GBA_REG_BLDCNT:
|
||||
case GBA_REG_BLDALPHA:
|
||||
case GBA_REG_SOUNDCNT_HI:
|
||||
case GBA_REG_SOUNDCNT_X:
|
||||
case GBA_REG_SOUNDBIAS:
|
||||
case GBA_REG_DMA0CNT_HI:
|
||||
case GBA_REG_DMA1CNT_HI:
|
||||
case GBA_REG_DMA2CNT_HI:
|
||||
case GBA_REG_DMA3CNT_HI:
|
||||
case GBA_REG_TM0CNT_HI:
|
||||
case GBA_REG_TM1CNT_HI:
|
||||
case GBA_REG_TM2CNT_HI:
|
||||
case GBA_REG_TM3CNT_HI:
|
||||
case GBA_REG_KEYCNT:
|
||||
case GBA_REG_SIOMULTI0:
|
||||
case GBA_REG_SIOMULTI1:
|
||||
case GBA_REG_SIOMULTI2:
|
||||
case GBA_REG_SIOMULTI3:
|
||||
case GBA_REG_SIOMLT_SEND:
|
||||
case GBA_REG_JOYCNT:
|
||||
case GBA_REG_JOY_TRANS_LO:
|
||||
case GBA_REG_JOY_TRANS_HI:
|
||||
case GBA_REG_JOYSTAT:
|
||||
case GBA_REG_IE:
|
||||
case GBA_REG_IF:
|
||||
case GBA_REG_WAITCNT:
|
||||
case GBA_REG_IME:
|
||||
// Handled transparently by registers
|
||||
break;
|
||||
case 0x066:
|
||||
|
@ -900,11 +900,11 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||
mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
|
||||
return 0;
|
||||
// These registers sit outside of the normal I/O block, so we need to stash them somewhere unused
|
||||
case REG_EXWAITCNT_LO:
|
||||
case REG_EXWAITCNT_HI:
|
||||
address += REG_INTERNAL_EXWAITCNT_LO - REG_EXWAITCNT_LO;
|
||||
case GBA_REG_EXWAITCNT_LO:
|
||||
case GBA_REG_EXWAITCNT_HI:
|
||||
address += GBA_REG_INTERNAL_EXWAITCNT_LO - GBA_REG_EXWAITCNT_LO;
|
||||
break;
|
||||
case REG_DEBUG_ENABLE:
|
||||
case GBA_REG_DEBUG_ENABLE:
|
||||
if (gba->debug) {
|
||||
return 0x1DEA;
|
||||
}
|
||||
|
@ -918,7 +918,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||
|
||||
void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
|
||||
int i;
|
||||
for (i = 0; i < REG_INTERNAL_MAX; i += 2) {
|
||||
for (i = 0; i < GBA_REG_INTERNAL_MAX; i += 2) {
|
||||
if (_isRSpecialRegister[i >> 1]) {
|
||||
STORE_16(gba->memory.io[i >> 1], i, state->io);
|
||||
} else if (_isValidRegister[i >> 1]) {
|
||||
|
@ -928,7 +928,7 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
STORE_16(gba->memory.io[(REG_DMA0CNT_LO + i * 12) >> 1], (REG_DMA0CNT_LO + i * 12), state->io);
|
||||
STORE_16(gba->memory.io[(GBA_REG_DMA0CNT_LO + i * 12) >> 1], (GBA_REG_DMA0CNT_LO + i * 12), state->io);
|
||||
STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload);
|
||||
STORE_32(gba->timers[i].lastEvent - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].lastEvent);
|
||||
STORE_32(gba->timers[i].event.when - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].nextEvent);
|
||||
|
@ -946,11 +946,11 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
}
|
||||
|
||||
void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
||||
LOAD_16(gba->memory.io[REG_SOUNDCNT_X >> 1], REG_SOUNDCNT_X, state->io);
|
||||
GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
|
||||
LOAD_16(gba->memory.io[GBA_REG(SOUNDCNT_X)], GBA_REG_SOUNDCNT_X, state->io);
|
||||
GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[GBA_REG(SOUNDCNT_X)]);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < REG_MAX; i += 2) {
|
||||
for (i = 0; i < GBA_REG_MAX; i += 2) {
|
||||
if (_isWSpecialRegister[i >> 1]) {
|
||||
LOAD_16(gba->memory.io[i >> 1], i, state->io);
|
||||
} else if (_isValidRegister[i >> 1]) {
|
||||
|
@ -960,7 +960,7 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
}
|
||||
}
|
||||
if (state->versionMagic >= 0x01000006) {
|
||||
GBAIOWrite(gba, REG_EXWAITCNT_HI, gba->memory.io[REG_INTERNAL_EXWAITCNT_HI >> 1]);
|
||||
GBAIOWrite(gba, GBA_REG_EXWAITCNT_HI, gba->memory.io[GBA_REG(INTERNAL_EXWAITCNT_HI)]);
|
||||
}
|
||||
|
||||
uint32_t when;
|
||||
|
@ -976,14 +976,14 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
gba->timers[i].event.when = when + mTimingCurrentTime(&gba->timing);
|
||||
}
|
||||
|
||||
LOAD_16(gba->memory.dma[i].reg, (REG_DMA0CNT_HI + i * 12), state->io);
|
||||
LOAD_16(gba->memory.dma[i].reg, (GBA_REG_DMA0CNT_HI + i * 12), state->io);
|
||||
LOAD_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
|
||||
LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
|
||||
LOAD_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
|
||||
LOAD_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
|
||||
}
|
||||
gba->sio.siocnt = gba->memory.io[REG_SIOCNT >> 1];
|
||||
GBASIOWriteRCNT(&gba->sio, gba->memory.io[REG_RCNT >> 1]);
|
||||
gba->sio.siocnt = gba->memory.io[GBA_REG(SIOCNT)];
|
||||
GBASIOWriteRCNT(&gba->sio, gba->memory.io[GBA_REG(RCNT)]);
|
||||
|
||||
LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
|
||||
LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC);
|
||||
|
|
|
@ -387,7 +387,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||
|
||||
#define LOAD_VRAM \
|
||||
if ((address & 0x0001FFFF) >= GBA_SIZE_VRAM) { \
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3)) { \
|
||||
mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load32: 0x%08X", address); \
|
||||
value = 0; \
|
||||
} else { \
|
||||
|
@ -397,7 +397,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||
LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \
|
||||
} \
|
||||
++wait; \
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) { \
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \
|
||||
wait += GBAMemoryStallVRAM(gba, wait, 1); \
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
|||
break;
|
||||
case GBA_REGION_VRAM:
|
||||
if ((address & 0x0001FFFF) >= GBA_SIZE_VRAM) {
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3)) {
|
||||
mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load16: 0x%08X", address);
|
||||
value = 0;
|
||||
break;
|
||||
|
@ -557,7 +557,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
|||
} else {
|
||||
LOAD_16(value, address & 0x0001FFFE, gba->video.vram);
|
||||
}
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) {
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) {
|
||||
wait += GBAMemoryStallVRAM(gba, wait, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -663,7 +663,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
|||
break;
|
||||
case GBA_REGION_VRAM:
|
||||
if ((address & 0x0001FFFF) >= GBA_SIZE_VRAM) {
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3)) {
|
||||
mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load8: 0x%08X", address);
|
||||
value = 0;
|
||||
break;
|
||||
|
@ -758,7 +758,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
|||
|
||||
#define STORE_VRAM \
|
||||
if ((address & 0x0001FFFF) >= GBA_SIZE_VRAM) { \
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3)) { \
|
||||
mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store32: 0x%08X", address); \
|
||||
} else { \
|
||||
LOAD_32(oldValue, address & 0x00017FFC, gba->video.vram); \
|
||||
|
@ -777,7 +777,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
|||
} \
|
||||
} \
|
||||
++wait; \
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) { \
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \
|
||||
wait += GBAMemoryStallVRAM(gba, wait, 1); \
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,7 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
|
|||
break;
|
||||
case GBA_REGION_VRAM:
|
||||
if ((address & 0x0001FFFF) >= GBA_SIZE_VRAM) {
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
|
||||
if ((address & (GBA_SIZE_VRAM | 0x00014000)) == GBA_SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3)) {
|
||||
mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store16: 0x%08X", address);
|
||||
break;
|
||||
}
|
||||
|
@ -904,7 +904,7 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
|
|||
gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE);
|
||||
}
|
||||
}
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) {
|
||||
if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) {
|
||||
wait += GBAMemoryStallVRAM(gba, wait, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -1025,7 +1025,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
|
|||
GBAStore16(cpu, address & ~1, ((uint8_t) value) | ((uint8_t) value << 8), cycleCounter);
|
||||
break;
|
||||
case GBA_REGION_VRAM:
|
||||
if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) {
|
||||
if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) {
|
||||
mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
|
||||
break;
|
||||
}
|
||||
|
@ -1114,7 +1114,7 @@ uint32_t GBAView32(struct ARMCore* cpu, uint32_t address) {
|
|||
value = GBALoad32(cpu, address, 0);
|
||||
break;
|
||||
case GBA_REGION_IO:
|
||||
if ((address & OFFSET_MASK) < REG_MAX) {
|
||||
if ((address & OFFSET_MASK) < GBA_REG_MAX) {
|
||||
value = gba->memory.io[(address & OFFSET_MASK) >> 1];
|
||||
value |= gba->memory.io[((address & OFFSET_MASK) >> 1) + 1] << 16;
|
||||
}
|
||||
|
@ -1155,7 +1155,7 @@ uint16_t GBAView16(struct ARMCore* cpu, uint32_t address) {
|
|||
value = GBALoad16(cpu, address, 0);
|
||||
break;
|
||||
case GBA_REGION_IO:
|
||||
if ((address & OFFSET_MASK) < REG_MAX) {
|
||||
if ((address & OFFSET_MASK) < GBA_REG_MAX) {
|
||||
value = gba->memory.io[(address & OFFSET_MASK) >> 1];
|
||||
}
|
||||
break;
|
||||
|
@ -1775,7 +1775,7 @@ int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait) {
|
|||
int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra) {
|
||||
UNUSED(extra);
|
||||
// TODO
|
||||
uint16_t dispcnt = gba->memory.io[REG_DISPCNT >> 1];
|
||||
uint16_t dispcnt = gba->memory.io[GBA_REG(DISPCNT)];
|
||||
int32_t stall = 0;
|
||||
switch (GBARegisterDISPCNTGetMode(dispcnt)) {
|
||||
case 2:
|
||||
|
|
|
@ -64,11 +64,11 @@ void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) {
|
|||
for (i = 0; i < GBA_SIZE_PALETTE_RAM / 2; ++i) {
|
||||
mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
|
||||
}
|
||||
GBAVideoCacheWriteVideoRegister(cache, REG_DISPCNT, video->p->memory.io[REG_DISPCNT >> 1]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, REG_BG0CNT, video->p->memory.io[REG_BG0CNT >> 1]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, REG_BG1CNT, video->p->memory.io[REG_BG1CNT >> 1]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, REG_BG2CNT, video->p->memory.io[REG_BG2CNT >> 1]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, REG_BG3CNT, video->p->memory.io[REG_BG3CNT >> 1]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, GBA_REG_DISPCNT, video->p->memory.io[GBA_REG(DISPCNT)]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, GBA_REG_BG0CNT, video->p->memory.io[GBA_REG(BG0CNT)]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, GBA_REG_BG1CNT, video->p->memory.io[GBA_REG(BG1CNT)]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, GBA_REG_BG2CNT, video->p->memory.io[GBA_REG(BG2CNT)]);
|
||||
GBAVideoCacheWriteVideoRegister(cache, GBA_REG_BG3CNT, video->p->memory.io[GBA_REG(BG3CNT)]);
|
||||
}
|
||||
|
||||
static void mapParser0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
|
||||
|
@ -195,23 +195,23 @@ static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t
|
|||
|
||||
void GBAVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint32_t address, uint16_t value) {
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
case GBA_REG_DISPCNT:
|
||||
GBAVideoCacheWriteDISPCNT(cache, value);
|
||||
GBAVideoCacheWriteBGCNT(cache, 0, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 0)->context);
|
||||
GBAVideoCacheWriteBGCNT(cache, 1, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 1)->context);
|
||||
GBAVideoCacheWriteBGCNT(cache, 2, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 2)->context);
|
||||
GBAVideoCacheWriteBGCNT(cache, 3, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 3)->context);
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 0, value);
|
||||
break;
|
||||
case REG_BG1CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 1, value);
|
||||
break;
|
||||
case REG_BG2CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 2, value);
|
||||
break;
|
||||
case REG_BG3CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 3, value);
|
||||
break;
|
||||
|
||||
|
|
|
@ -894,7 +894,7 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) {
|
|||
glRenderer->nextPalette = 0;
|
||||
glRenderer->paletteDirtyScanlines = GBA_VIDEO_VERTICAL_PIXELS;
|
||||
memset(glRenderer->shadowRegs, 0, sizeof(glRenderer->shadowRegs));
|
||||
glRenderer->shadowRegs[REG_DISPCNT >> 1] = glRenderer->dispcnt;
|
||||
glRenderer->shadowRegs[GBA_REG(DISPCNT)] = glRenderer->dispcnt;
|
||||
glRenderer->regsDirty = 0xFFFFFFFFFFFEULL;
|
||||
|
||||
glRenderer->objOffsetX = 0;
|
||||
|
@ -978,107 +978,107 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer,
|
|||
|
||||
bool dirty = false;
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
case GBA_REG_DISPCNT:
|
||||
value &= 0xFFF7;
|
||||
dirty = true;
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
case REG_BG1CNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
value &= 0xDFFF;
|
||||
dirty = true;
|
||||
break;
|
||||
case REG_BG0HOFS:
|
||||
case GBA_REG_BG0HOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[0].x = value;
|
||||
break;
|
||||
case REG_BG0VOFS:
|
||||
case GBA_REG_BG0VOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[0].y = value;
|
||||
break;
|
||||
case REG_BG1HOFS:
|
||||
case GBA_REG_BG1HOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[1].x = value;
|
||||
break;
|
||||
case REG_BG1VOFS:
|
||||
case GBA_REG_BG1VOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[1].y = value;
|
||||
break;
|
||||
case REG_BG2HOFS:
|
||||
case GBA_REG_BG2HOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[2].x = value;
|
||||
break;
|
||||
case REG_BG2VOFS:
|
||||
case GBA_REG_BG2VOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[2].y = value;
|
||||
break;
|
||||
case REG_BG3HOFS:
|
||||
case GBA_REG_BG3HOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[3].x = value;
|
||||
break;
|
||||
case REG_BG3VOFS:
|
||||
case GBA_REG_BG3VOFS:
|
||||
value &= 0x01FF;
|
||||
glRenderer->bg[3].y = value;
|
||||
break;
|
||||
case REG_BG2PA:
|
||||
case GBA_REG_BG2PA:
|
||||
glRenderer->bg[2].affine.dx = value;
|
||||
break;
|
||||
case REG_BG2PB:
|
||||
case GBA_REG_BG2PB:
|
||||
glRenderer->bg[2].affine.dmx = value;
|
||||
break;
|
||||
case REG_BG2PC:
|
||||
case GBA_REG_BG2PC:
|
||||
glRenderer->bg[2].affine.dy = value;
|
||||
break;
|
||||
case REG_BG2PD:
|
||||
case GBA_REG_BG2PD:
|
||||
glRenderer->bg[2].affine.dmy = value;
|
||||
break;
|
||||
case REG_BG2X_LO:
|
||||
case GBA_REG_BG2X_LO:
|
||||
GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[2], value);
|
||||
break;
|
||||
case REG_BG2X_HI:
|
||||
case GBA_REG_BG2X_HI:
|
||||
GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[2], value);
|
||||
break;
|
||||
case REG_BG2Y_LO:
|
||||
case GBA_REG_BG2Y_LO:
|
||||
GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[2], value);
|
||||
break;
|
||||
case REG_BG2Y_HI:
|
||||
case GBA_REG_BG2Y_HI:
|
||||
GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[2], value);
|
||||
break;
|
||||
case REG_BG3PA:
|
||||
case GBA_REG_BG3PA:
|
||||
glRenderer->bg[3].affine.dx = value;
|
||||
break;
|
||||
case REG_BG3PB:
|
||||
case GBA_REG_BG3PB:
|
||||
glRenderer->bg[3].affine.dmx = value;
|
||||
break;
|
||||
case REG_BG3PC:
|
||||
case GBA_REG_BG3PC:
|
||||
glRenderer->bg[3].affine.dy = value;
|
||||
break;
|
||||
case REG_BG3PD:
|
||||
case GBA_REG_BG3PD:
|
||||
glRenderer->bg[3].affine.dmy = value;
|
||||
break;
|
||||
case REG_BG3X_LO:
|
||||
case GBA_REG_BG3X_LO:
|
||||
GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[3], value);
|
||||
break;
|
||||
case REG_BG3X_HI:
|
||||
case GBA_REG_BG3X_HI:
|
||||
GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[3], value);
|
||||
break;
|
||||
case REG_BG3Y_LO:
|
||||
case GBA_REG_BG3Y_LO:
|
||||
GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[3], value);
|
||||
break;
|
||||
case REG_BG3Y_HI:
|
||||
case GBA_REG_BG3Y_HI:
|
||||
GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[3], value);
|
||||
break;
|
||||
case REG_BLDALPHA:
|
||||
case GBA_REG_BLDALPHA:
|
||||
value &= 0x1F1F;
|
||||
dirty = true;
|
||||
break;
|
||||
case REG_BLDY:
|
||||
case GBA_REG_BLDY:
|
||||
value &= 0x1F;
|
||||
if (value > 0x10) {
|
||||
value = 0x10;
|
||||
}
|
||||
dirty = true;
|
||||
break;
|
||||
case REG_WIN0H:
|
||||
case GBA_REG_WIN0H:
|
||||
glRenderer->winN[0].h.end = value;
|
||||
glRenderer->winN[0].h.start = value >> 8;
|
||||
if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h.start > glRenderer->winN[0].h.end) {
|
||||
|
@ -1091,7 +1091,7 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WIN1H:
|
||||
case GBA_REG_WIN1H:
|
||||
glRenderer->winN[1].h.end = value;
|
||||
glRenderer->winN[1].h.start = value >> 8;
|
||||
if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h.start > glRenderer->winN[1].h.end) {
|
||||
|
@ -1104,7 +1104,7 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WIN0V:
|
||||
case GBA_REG_WIN0V:
|
||||
glRenderer->winN[0].v.end = value;
|
||||
glRenderer->winN[0].v.start = value >> 8;
|
||||
if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[0].v.start > glRenderer->winN[0].v.end) {
|
||||
|
@ -1117,7 +1117,7 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WIN1V:
|
||||
case GBA_REG_WIN1V:
|
||||
glRenderer->winN[1].v.end = value;
|
||||
glRenderer->winN[1].v.start = value >> 8;
|
||||
if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[1].v.start > glRenderer->winN[1].v.end) {
|
||||
|
@ -1130,8 +1130,8 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WININ:
|
||||
case REG_WINOUT:
|
||||
case GBA_REG_WININ:
|
||||
case GBA_REG_WINOUT:
|
||||
value &= 0x3F3F;
|
||||
dirty = true;
|
||||
break;
|
||||
|
@ -1152,26 +1152,26 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer,
|
|||
|
||||
void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t value) {
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
case GBA_REG_DISPCNT:
|
||||
glRenderer->dispcnt = value;
|
||||
GBAVideoGLRendererUpdateDISPCNT(glRenderer);
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[0], value);
|
||||
break;
|
||||
case REG_BG1CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[1], value);
|
||||
break;
|
||||
case REG_BG2CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[2], value);
|
||||
break;
|
||||
case REG_BG3CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[3], value);
|
||||
break;
|
||||
case REG_BLDCNT:
|
||||
case GBA_REG_BLDCNT:
|
||||
GBAVideoGLRendererWriteBLDCNT(glRenderer, value);
|
||||
break;
|
||||
case REG_BLDALPHA:
|
||||
case GBA_REG_BLDALPHA:
|
||||
glRenderer->blda = value & 0x1F;
|
||||
if (glRenderer->blda > 0x10) {
|
||||
glRenderer->blda = 0x10;
|
||||
|
@ -1181,18 +1181,18 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t
|
|||
glRenderer->bldb = 0x10;
|
||||
}
|
||||
break;
|
||||
case REG_BLDY:
|
||||
case GBA_REG_BLDY:
|
||||
glRenderer->bldy = value;
|
||||
break;
|
||||
case REG_WININ:
|
||||
case GBA_REG_WININ:
|
||||
glRenderer->winN[0].control = value;
|
||||
glRenderer->winN[1].control = value >> 8;
|
||||
break;
|
||||
case REG_WINOUT:
|
||||
case GBA_REG_WINOUT:
|
||||
glRenderer->winout = value;
|
||||
glRenderer->objwin = value >> 8;
|
||||
break;
|
||||
case REG_MOSAIC:
|
||||
case GBA_REG_MOSAIC:
|
||||
glRenderer->mosaic = value;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -161,139 +161,139 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
}
|
||||
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
case GBA_REG_DISPCNT:
|
||||
value &= 0xFFF7;
|
||||
softwareRenderer->dispcnt = value;
|
||||
GBAVideoSoftwareRendererUpdateDISPCNT(softwareRenderer);
|
||||
break;
|
||||
case REG_GREENSWP:
|
||||
case GBA_REG_GREENSWP:
|
||||
softwareRenderer->greenswap = value & 1;
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
value &= 0xDFFF;
|
||||
GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[0], value);
|
||||
break;
|
||||
case REG_BG1CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
value &= 0xDFFF;
|
||||
GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[1], value);
|
||||
break;
|
||||
case REG_BG2CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
value &= 0xFFFF;
|
||||
GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[2], value);
|
||||
break;
|
||||
case REG_BG3CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
value &= 0xFFFF;
|
||||
GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[3], value);
|
||||
break;
|
||||
case REG_BG0HOFS:
|
||||
case GBA_REG_BG0HOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[0].x = value;
|
||||
break;
|
||||
case REG_BG0VOFS:
|
||||
case GBA_REG_BG0VOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[0].y = value;
|
||||
break;
|
||||
case REG_BG1HOFS:
|
||||
case GBA_REG_BG1HOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[1].x = value;
|
||||
break;
|
||||
case REG_BG1VOFS:
|
||||
case GBA_REG_BG1VOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[1].y = value;
|
||||
break;
|
||||
case REG_BG2HOFS:
|
||||
case GBA_REG_BG2HOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[2].x = value;
|
||||
break;
|
||||
case REG_BG2VOFS:
|
||||
case GBA_REG_BG2VOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[2].y = value;
|
||||
break;
|
||||
case REG_BG3HOFS:
|
||||
case GBA_REG_BG3HOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[3].x = value;
|
||||
break;
|
||||
case REG_BG3VOFS:
|
||||
case GBA_REG_BG3VOFS:
|
||||
value &= 0x01FF;
|
||||
softwareRenderer->bg[3].y = value;
|
||||
break;
|
||||
case REG_BG2PA:
|
||||
case GBA_REG_BG2PA:
|
||||
softwareRenderer->bg[2].dx = value;
|
||||
break;
|
||||
case REG_BG2PB:
|
||||
case GBA_REG_BG2PB:
|
||||
softwareRenderer->bg[2].dmx = value;
|
||||
break;
|
||||
case REG_BG2PC:
|
||||
case GBA_REG_BG2PC:
|
||||
softwareRenderer->bg[2].dy = value;
|
||||
break;
|
||||
case REG_BG2PD:
|
||||
case GBA_REG_BG2PD:
|
||||
softwareRenderer->bg[2].dmy = value;
|
||||
break;
|
||||
case REG_BG2X_LO:
|
||||
case GBA_REG_BG2X_LO:
|
||||
GBAVideoSoftwareRendererWriteBGX_LO(&softwareRenderer->bg[2], value);
|
||||
if (softwareRenderer->bg[2].sx != softwareRenderer->cache[softwareRenderer->nextY].scale[0][0]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG2X_HI:
|
||||
case GBA_REG_BG2X_HI:
|
||||
GBAVideoSoftwareRendererWriteBGX_HI(&softwareRenderer->bg[2], value);
|
||||
if (softwareRenderer->bg[2].sx != softwareRenderer->cache[softwareRenderer->nextY].scale[0][0]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG2Y_LO:
|
||||
case GBA_REG_BG2Y_LO:
|
||||
GBAVideoSoftwareRendererWriteBGY_LO(&softwareRenderer->bg[2], value);
|
||||
if (softwareRenderer->bg[2].sy != softwareRenderer->cache[softwareRenderer->nextY].scale[0][1]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG2Y_HI:
|
||||
case GBA_REG_BG2Y_HI:
|
||||
GBAVideoSoftwareRendererWriteBGY_HI(&softwareRenderer->bg[2], value);
|
||||
if (softwareRenderer->bg[2].sy != softwareRenderer->cache[softwareRenderer->nextY].scale[0][1]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG3PA:
|
||||
case GBA_REG_BG3PA:
|
||||
softwareRenderer->bg[3].dx = value;
|
||||
break;
|
||||
case REG_BG3PB:
|
||||
case GBA_REG_BG3PB:
|
||||
softwareRenderer->bg[3].dmx = value;
|
||||
break;
|
||||
case REG_BG3PC:
|
||||
case GBA_REG_BG3PC:
|
||||
softwareRenderer->bg[3].dy = value;
|
||||
break;
|
||||
case REG_BG3PD:
|
||||
case GBA_REG_BG3PD:
|
||||
softwareRenderer->bg[3].dmy = value;
|
||||
break;
|
||||
case REG_BG3X_LO:
|
||||
case GBA_REG_BG3X_LO:
|
||||
GBAVideoSoftwareRendererWriteBGX_LO(&softwareRenderer->bg[3], value);
|
||||
if (softwareRenderer->bg[3].sx != softwareRenderer->cache[softwareRenderer->nextY].scale[1][0]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG3X_HI:
|
||||
case GBA_REG_BG3X_HI:
|
||||
GBAVideoSoftwareRendererWriteBGX_HI(&softwareRenderer->bg[3], value);
|
||||
if (softwareRenderer->bg[3].sx != softwareRenderer->cache[softwareRenderer->nextY].scale[1][0]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG3Y_LO:
|
||||
case GBA_REG_BG3Y_LO:
|
||||
GBAVideoSoftwareRendererWriteBGY_LO(&softwareRenderer->bg[3], value);
|
||||
if (softwareRenderer->bg[3].sy != softwareRenderer->cache[softwareRenderer->nextY].scale[1][1]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BG3Y_HI:
|
||||
case GBA_REG_BG3Y_HI:
|
||||
GBAVideoSoftwareRendererWriteBGY_HI(&softwareRenderer->bg[3], value);
|
||||
if (softwareRenderer->bg[3].sy != softwareRenderer->cache[softwareRenderer->nextY].scale[1][1]) {
|
||||
DIRTY_SCANLINE(softwareRenderer, softwareRenderer->nextY);
|
||||
}
|
||||
break;
|
||||
case REG_BLDCNT:
|
||||
case GBA_REG_BLDCNT:
|
||||
GBAVideoSoftwareRendererWriteBLDCNT(softwareRenderer, value);
|
||||
value &= 0x3FFF;
|
||||
break;
|
||||
case REG_BLDALPHA:
|
||||
case GBA_REG_BLDALPHA:
|
||||
softwareRenderer->blda = value & 0x1F;
|
||||
if (softwareRenderer->blda > 0x10) {
|
||||
softwareRenderer->blda = 0x10;
|
||||
|
@ -304,7 +304,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
}
|
||||
value &= 0x1F1F;
|
||||
break;
|
||||
case REG_BLDY:
|
||||
case GBA_REG_BLDY:
|
||||
value &= 0x1F;
|
||||
if (value > 0x10) {
|
||||
value = 0x10;
|
||||
|
@ -314,7 +314,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
softwareRenderer->blendDirty = true;
|
||||
}
|
||||
break;
|
||||
case REG_WIN0H:
|
||||
case GBA_REG_WIN0H:
|
||||
softwareRenderer->winN[0].h.end = value;
|
||||
softwareRenderer->winN[0].h.start = value >> 8;
|
||||
if (softwareRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[0].h.start > softwareRenderer->winN[0].h.end) {
|
||||
|
@ -327,7 +327,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WIN1H:
|
||||
case GBA_REG_WIN1H:
|
||||
softwareRenderer->winN[1].h.end = value;
|
||||
softwareRenderer->winN[1].h.start = value >> 8;
|
||||
if (softwareRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[1].h.start > softwareRenderer->winN[1].h.end) {
|
||||
|
@ -340,7 +340,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WIN0V:
|
||||
case GBA_REG_WIN0V:
|
||||
softwareRenderer->winN[0].v.end = value;
|
||||
softwareRenderer->winN[0].v.start = value >> 8;
|
||||
if (softwareRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[0].v.start > softwareRenderer->winN[0].v.end) {
|
||||
|
@ -353,7 +353,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WIN1V:
|
||||
case GBA_REG_WIN1V:
|
||||
softwareRenderer->winN[1].v.end = value;
|
||||
softwareRenderer->winN[1].v.start = value >> 8;
|
||||
if (softwareRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[1].v.start > softwareRenderer->winN[1].v.end) {
|
||||
|
@ -366,17 +366,17 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_WININ:
|
||||
case GBA_REG_WININ:
|
||||
value &= 0x3F3F;
|
||||
softwareRenderer->winN[0].control.packed = value;
|
||||
softwareRenderer->winN[1].control.packed = value >> 8;
|
||||
break;
|
||||
case REG_WINOUT:
|
||||
case GBA_REG_WINOUT:
|
||||
value &= 0x3F3F;
|
||||
softwareRenderer->winout.packed = value;
|
||||
softwareRenderer->objwin.packed = value >> 8;
|
||||
break;
|
||||
case REG_MOSAIC:
|
||||
case GBA_REG_MOSAIC:
|
||||
softwareRenderer->mosaic = value;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -62,7 +62,7 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
|
||||
GBASerializedMiscFlags miscFlags = 0;
|
||||
miscFlags = GBASerializedMiscFlagsSetHalted(miscFlags, gba->cpu->halted);
|
||||
miscFlags = GBASerializedMiscFlagsSetPOSTFLG(miscFlags, gba->memory.io[REG_POSTFLG >> 1] & 1);
|
||||
miscFlags = GBASerializedMiscFlagsSetPOSTFLG(miscFlags, gba->memory.io[GBA_REG(POSTFLG)] & 1);
|
||||
if (mTimingIsScheduled(&gba->timing, &gba->irqEvent)) {
|
||||
miscFlags = GBASerializedMiscFlagsFillIrqPending(miscFlags);
|
||||
STORE_32(gba->irqEvent.when - mTimingCurrentTime(&gba->timing), 0, &state->nextIrq);
|
||||
|
@ -191,7 +191,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
GBASerializedMiscFlags miscFlags = 0;
|
||||
LOAD_32(miscFlags, 0, &state->miscFlags);
|
||||
gba->cpu->halted = GBASerializedMiscFlagsGetHalted(miscFlags);
|
||||
gba->memory.io[REG_POSTFLG >> 1] = GBASerializedMiscFlagsGetPOSTFLG(miscFlags);
|
||||
gba->memory.io[GBA_REG(POSTFLG)] = GBASerializedMiscFlagsGetPOSTFLG(miscFlags);
|
||||
if (GBASerializedMiscFlagsIsIrqPending(miscFlags)) {
|
||||
int32_t when;
|
||||
LOAD_32(when, 0, &state->nextIrq);
|
||||
|
|
|
@ -168,7 +168,7 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
|
|||
sio->rcnt |= value & ~0xF;
|
||||
_switchMode(sio);
|
||||
if (sio->activeDriver && sio->activeDriver->writeRegister) {
|
||||
sio->activeDriver->writeRegister(sio->activeDriver, REG_RCNT, value);
|
||||
sio->activeDriver->writeRegister(sio->activeDriver, GBA_REG_RCNT, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
_switchMode(sio);
|
||||
}
|
||||
if (sio->activeDriver && sio->activeDriver->writeRegister) {
|
||||
value = sio->activeDriver->writeRegister(sio->activeDriver, REG_SIOCNT, value);
|
||||
value = sio->activeDriver->writeRegister(sio->activeDriver, GBA_REG_SIOCNT, value);
|
||||
} else {
|
||||
// Dummy drivers
|
||||
switch (sio->mode) {
|
||||
|
@ -213,10 +213,10 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu
|
|||
switch (sio->mode) {
|
||||
case SIO_JOYBUS:
|
||||
switch (address) {
|
||||
case REG_JOYCNT:
|
||||
return (value & 0x0040) | (sio->p->memory.io[REG_JOYCNT >> 1] & ~(value & 0x7) & ~0x0040);
|
||||
case REG_JOYSTAT:
|
||||
return (value & 0x0030) | (sio->p->memory.io[REG_JOYSTAT >> 1] & ~0x30);
|
||||
case GBA_REG_JOYCNT:
|
||||
return (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040);
|
||||
case GBA_REG_JOYSTAT:
|
||||
return (value & 0x0030) | (sio->p->memory.io[GBA_REG(JOYSTAT)] & ~0x30);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -102,9 +102,9 @@ uint16_t _gbpRead(struct mKeyCallback* callback) {
|
|||
|
||||
uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) {
|
||||
struct GBASIOPlayer* gbp = (struct GBASIOPlayer*) driver;
|
||||
if (address == REG_SIOCNT) {
|
||||
if (address == GBA_REG_SIOCNT) {
|
||||
if (value & 0x0080) {
|
||||
uint32_t rx = gbp->p->memory.io[REG_SIODATA32_LO >> 1] | (gbp->p->memory.io[REG_SIODATA32_HI >> 1] << 16);
|
||||
uint32_t rx = gbp->p->memory.io[GBA_REG(SIODATA32_LO)] | (gbp->p->memory.io[GBA_REG(SIODATA32_HI)] << 16);
|
||||
if (gbp->txPosition < 12 && gbp->txPosition > 0) {
|
||||
// TODO: Check expected
|
||||
} else if (gbp->txPosition >= 12) {
|
||||
|
@ -138,11 +138,11 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat
|
|||
}
|
||||
tx = _gbpTxData[txPosition];
|
||||
++gbp->txPosition;
|
||||
gbp->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
|
||||
gbp->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
|
||||
gbp->p->memory.io[GBA_REG(SIODATA32_LO)] = tx;
|
||||
gbp->p->memory.io[GBA_REG(SIODATA32_HI)] = tx >> 16;
|
||||
if (GBASIONormalIsIrq(gbp->d.p->siocnt)) {
|
||||
GBARaiseIRQ(gbp->p, GBA_IRQ_SIO, cyclesLate);
|
||||
}
|
||||
gbp->d.p->siocnt = GBASIONormalClearStart(gbp->d.p->siocnt);
|
||||
gbp->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080;
|
||||
gbp->p->memory.io[GBA_REG(SIOCNT)] = gbp->d.p->siocnt & ~0x0080;
|
||||
}
|
||||
|
|
|
@ -20,22 +20,22 @@ void GBASIOJOYCreate(struct GBASIODriver* sio) {
|
|||
|
||||
uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value) {
|
||||
switch (address) {
|
||||
case REG_JOYCNT:
|
||||
case GBA_REG_JOYCNT:
|
||||
mLOG(GBA_SIO, DEBUG, "JOY write: CNT <- %04X", value);
|
||||
return (value & 0x0040) | (sio->p->p->memory.io[REG_JOYCNT >> 1] & ~(value & 0x7) & ~0x0040);
|
||||
case REG_JOYSTAT:
|
||||
return (value & 0x0040) | (sio->p->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040);
|
||||
case GBA_REG_JOYSTAT:
|
||||
mLOG(GBA_SIO, DEBUG, "JOY write: STAT <- %04X", value);
|
||||
return (value & 0x0030) | (sio->p->p->memory.io[REG_JOYSTAT >> 1] & ~0x30);
|
||||
case REG_JOY_TRANS_LO:
|
||||
return (value & 0x0030) | (sio->p->p->memory.io[GBA_REG(JOYSTAT)] & ~0x30);
|
||||
case GBA_REG_JOY_TRANS_LO:
|
||||
mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_LO <- %04X", value);
|
||||
break;
|
||||
case REG_JOY_TRANS_HI:
|
||||
case GBA_REG_JOY_TRANS_HI:
|
||||
mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_HI <- %04X", value);
|
||||
break;
|
||||
default:
|
||||
mLOG(GBA_SIO, DEBUG, "JOY write: Unknown reg %03X <- %04X", address, value);
|
||||
// Fall through
|
||||
case REG_RCNT:
|
||||
case GBA_REG_RCNT:
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
|
@ -44,46 +44,46 @@ uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint
|
|||
int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) {
|
||||
switch (command) {
|
||||
case JOY_RESET:
|
||||
sio->p->p->memory.io[REG_JOYCNT >> 1] |= JOYCNT_RESET;
|
||||
if (sio->p->p->memory.io[REG_JOYCNT >> 1] & 0x40) {
|
||||
sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_RESET;
|
||||
if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) {
|
||||
GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0);
|
||||
}
|
||||
// Fall through
|
||||
case JOY_POLL:
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x04;
|
||||
data[2] = sio->p->p->memory.io[REG_JOYSTAT >> 1];
|
||||
data[2] = sio->p->p->memory.io[GBA_REG(JOYSTAT)];
|
||||
|
||||
mLOG(GBA_SIO, DEBUG, "JOY %s: %02X (%02X)", command == JOY_POLL ? "poll" : "reset", data[2], sio->p->p->memory.io[REG_JOYCNT >> 1]);
|
||||
mLOG(GBA_SIO, DEBUG, "JOY %s: %02X (%02X)", command == JOY_POLL ? "poll" : "reset", data[2], sio->p->p->memory.io[GBA_REG(JOYCNT)]);
|
||||
return 3;
|
||||
case JOY_RECV:
|
||||
sio->p->p->memory.io[REG_JOYCNT >> 1] |= JOYCNT_RECV;
|
||||
sio->p->p->memory.io[REG_JOYSTAT >> 1] |= JOYSTAT_RECV;
|
||||
sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_RECV;
|
||||
sio->p->p->memory.io[GBA_REG(JOYSTAT)] |= JOYSTAT_RECV;
|
||||
|
||||
sio->p->p->memory.io[REG_JOY_RECV_LO >> 1] = data[0] | (data[1] << 8);
|
||||
sio->p->p->memory.io[REG_JOY_RECV_HI >> 1] = data[2] | (data[3] << 8);
|
||||
sio->p->p->memory.io[GBA_REG(JOY_RECV_LO)] = data[0] | (data[1] << 8);
|
||||
sio->p->p->memory.io[GBA_REG(JOY_RECV_HI)] = data[2] | (data[3] << 8);
|
||||
|
||||
data[0] = sio->p->p->memory.io[REG_JOYSTAT >> 1];
|
||||
data[0] = sio->p->p->memory.io[GBA_REG(JOYSTAT)];
|
||||
|
||||
mLOG(GBA_SIO, DEBUG, "JOY recv: %02X (%02X)", data[0], sio->p->p->memory.io[REG_JOYCNT >> 1]);
|
||||
mLOG(GBA_SIO, DEBUG, "JOY recv: %02X (%02X)", data[0], sio->p->p->memory.io[GBA_REG(JOYCNT)]);
|
||||
|
||||
if (sio->p->p->memory.io[REG_JOYCNT >> 1] & 0x40) {
|
||||
if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) {
|
||||
GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0);
|
||||
}
|
||||
return 1;
|
||||
case JOY_TRANS:
|
||||
data[0] = sio->p->p->memory.io[REG_JOY_TRANS_LO >> 1];
|
||||
data[1] = sio->p->p->memory.io[REG_JOY_TRANS_LO >> 1] >> 8;
|
||||
data[2] = sio->p->p->memory.io[REG_JOY_TRANS_HI >> 1];
|
||||
data[3] = sio->p->p->memory.io[REG_JOY_TRANS_HI >> 1] >> 8;
|
||||
data[4] = sio->p->p->memory.io[REG_JOYSTAT >> 1];
|
||||
data[0] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_LO)];
|
||||
data[1] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_LO)] >> 8;
|
||||
data[2] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_HI)];
|
||||
data[3] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_HI)] >> 8;
|
||||
data[4] = sio->p->p->memory.io[GBA_REG(JOYSTAT)];
|
||||
|
||||
sio->p->p->memory.io[REG_JOYCNT >> 1] |= JOYCNT_TRANS;
|
||||
sio->p->p->memory.io[REG_JOYSTAT >> 1] &= ~JOYSTAT_TRANS;
|
||||
sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_TRANS;
|
||||
sio->p->p->memory.io[GBA_REG(JOYSTAT)] &= ~JOYSTAT_TRANS;
|
||||
|
||||
mLOG(GBA_SIO, DEBUG, "JOY trans: %02X%02X%02X%02X:%02X (%02X)", data[0], data[1], data[2], data[3], data[4], sio->p->p->memory.io[REG_JOYCNT >> 1]);
|
||||
mLOG(GBA_SIO, DEBUG, "JOY trans: %02X%02X%02X%02X:%02X (%02X)", data[0], data[1], data[2], data[3], data[4], sio->p->p->memory.io[GBA_REG(JOYCNT)]);
|
||||
|
||||
if (sio->p->p->memory.io[REG_JOYCNT >> 1] & 0x40) {
|
||||
if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) {
|
||||
GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0);
|
||||
}
|
||||
return 5;
|
||||
|
|
|
@ -192,7 +192,7 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver
|
|||
|
||||
mLockstepLock(&node->p->d);
|
||||
|
||||
if (address == REG_SIOCNT) {
|
||||
if (address == GBA_REG_SIOCNT) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value);
|
||||
|
||||
enum mLockstepPhase transferActive;
|
||||
|
@ -219,7 +219,7 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver
|
|||
}
|
||||
value &= 0xFF83;
|
||||
value |= driver->p->siocnt & 0x00FC;
|
||||
} else if (address == REG_SIOMLT_SEND) {
|
||||
} else if (address == GBA_REG_SIOMLT_SEND) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOMLT_SEND <- %04X", node->id, value);
|
||||
} else {
|
||||
mLOG(GBA_SIO, STUB, "Lockstep %i: Unknown reg %03X <- %04X", node->id, address, value);
|
||||
|
@ -238,10 +238,10 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) {
|
|||
struct GBASIO* sio = node->d.p;
|
||||
switch (node->mode) {
|
||||
case SIO_MULTI:
|
||||
sio->p->memory.io[REG_SIOMULTI0 >> 1] = node->p->multiRecv[0];
|
||||
sio->p->memory.io[REG_SIOMULTI1 >> 1] = node->p->multiRecv[1];
|
||||
sio->p->memory.io[REG_SIOMULTI2 >> 1] = node->p->multiRecv[2];
|
||||
sio->p->memory.io[REG_SIOMULTI3 >> 1] = node->p->multiRecv[3];
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI0)] = node->p->multiRecv[0];
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI1)] = node->p->multiRecv[1];
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI2)] = node->p->multiRecv[2];
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI3)] = node->p->multiRecv[3];
|
||||
sio->rcnt |= 1;
|
||||
sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt);
|
||||
sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, node->id);
|
||||
|
@ -254,9 +254,9 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) {
|
|||
sio->siocnt = GBASIONormalClearStart(sio->siocnt);
|
||||
if (node->id) {
|
||||
sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt));
|
||||
node->d.p->p->memory.io[REG_SIODATA8 >> 1] = node->p->normalRecv[node->id - 1] & 0xFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIODATA8)] = node->p->normalRecv[node->id - 1] & 0xFF;
|
||||
} else {
|
||||
node->d.p->p->memory.io[REG_SIODATA8 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIODATA8)] = 0xFFFF;
|
||||
}
|
||||
if (GBASIONormalIsIrq(sio->siocnt)) {
|
||||
GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0);
|
||||
|
@ -267,11 +267,11 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) {
|
|||
sio->siocnt = GBASIONormalClearStart(sio->siocnt);
|
||||
if (node->id) {
|
||||
sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt));
|
||||
node->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = node->p->normalRecv[node->id - 1];
|
||||
node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = node->p->normalRecv[node->id - 1] >> 16;
|
||||
node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = node->p->normalRecv[node->id - 1];
|
||||
node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = node->p->normalRecv[node->id - 1] >> 16;
|
||||
} else {
|
||||
node->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0xFFFF;
|
||||
}
|
||||
if (GBASIONormalIsIrq(sio->siocnt)) {
|
||||
GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0);
|
||||
|
@ -310,25 +310,25 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) {
|
|||
node->transferFinished = false;
|
||||
switch (node->mode) {
|
||||
case SIO_MULTI:
|
||||
node->p->multiRecv[0] = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1];
|
||||
node->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF;
|
||||
node->p->multiRecv[0] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)];
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF;
|
||||
node->p->multiRecv[1] = 0xFFFF;
|
||||
node->p->multiRecv[2] = 0xFFFF;
|
||||
node->p->multiRecv[3] = 0xFFFF;
|
||||
break;
|
||||
case SIO_NORMAL_8:
|
||||
node->p->multiRecv[0] = 0xFFFF;
|
||||
node->p->normalRecv[0] = node->d.p->p->memory.io[REG_SIODATA8 >> 1] & 0xFF;
|
||||
node->p->normalRecv[0] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF;
|
||||
break;
|
||||
case SIO_NORMAL_32:
|
||||
node->p->multiRecv[0] = 0xFFFF;
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, node->d.p->p->memory.io[REG_SIODATA32_LO >> 1]);
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, node->d.p->p->memory.io[REG_SIODATA32_HI >> 1]);
|
||||
node->p->normalRecv[0] = node->d.p->p->memory.io[REG_SIODATA32_LO >> 1];
|
||||
node->p->normalRecv[0] |= node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] << 16;
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]);
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)]);
|
||||
node->p->normalRecv[0] = node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)];
|
||||
node->p->normalRecv[0] |= node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] << 16;
|
||||
break;
|
||||
default:
|
||||
node->p->multiRecv[0] = 0xFFFF;
|
||||
|
@ -419,21 +419,21 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) {
|
|||
switch (node->mode) {
|
||||
case SIO_MULTI:
|
||||
node->d.p->rcnt &= ~1;
|
||||
node->p->multiRecv[node->id] = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1];
|
||||
node->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF;
|
||||
node->p->multiRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)];
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF;
|
||||
node->d.p->siocnt = GBASIOMultiplayerFillBusy(node->d.p->siocnt);
|
||||
break;
|
||||
case SIO_NORMAL_8:
|
||||
node->p->multiRecv[node->id] = 0xFFFF;
|
||||
node->p->normalRecv[node->id] = node->d.p->p->memory.io[REG_SIODATA8 >> 1] & 0xFF;
|
||||
node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF;
|
||||
break;
|
||||
case SIO_NORMAL_32:
|
||||
node->p->multiRecv[node->id] = 0xFFFF;
|
||||
node->p->normalRecv[node->id] = node->d.p->p->memory.io[REG_SIODATA32_LO >> 1];
|
||||
node->p->normalRecv[node->id] |= node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] << 16;
|
||||
node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)];
|
||||
node->p->normalRecv[node->id] |= node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] << 16;
|
||||
break;
|
||||
default:
|
||||
node->p->multiRecv[node->id] = 0xFFFF;
|
||||
|
@ -509,7 +509,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive
|
|||
|
||||
mLockstepLock(&node->p->d);
|
||||
|
||||
if (address == REG_SIOCNT) {
|
||||
if (address == GBA_REG_SIOCNT) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value);
|
||||
int attached;
|
||||
ATOMIC_LOAD(attached, node->p->attachedNormal);
|
||||
|
@ -562,11 +562,11 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive
|
|||
// TODO
|
||||
}
|
||||
}
|
||||
} else if (address == REG_SIODATA32_LO) {
|
||||
} else if (address == GBA_REG_SIODATA32_LO) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, value);
|
||||
} else if (address == REG_SIODATA32_HI) {
|
||||
} else if (address == GBA_REG_SIODATA32_HI) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, value);
|
||||
} else if (address == REG_SIODATA8) {
|
||||
} else if (address == GBA_REG_SIODATA8) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA8 <- %02X", node->id, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
|
||||
#define REG_TMCNT_LO(X) (REG_TM0CNT_LO + ((X) << 2))
|
||||
#define GBA_REG_TMCNT_LO(X) (GBA_REG_TM0CNT_LO + ((X) << 2))
|
||||
|
||||
static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) {
|
||||
struct GBATimer* timer = &gba->timers[timerId];
|
||||
if (GBATimerFlagsIsCountUp(timer->flags)) {
|
||||
gba->memory.io[REG_TMCNT_LO(timerId) >> 1] = timer->reload;
|
||||
gba->memory.io[GBA_REG_TMCNT_LO(timerId) >> 1] = timer->reload;
|
||||
} else {
|
||||
GBATimerUpdateRegister(gba, timerId, cyclesLate);
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) {
|
|||
if (timerId < 3) {
|
||||
struct GBATimer* nextTimer = &gba->timers[timerId + 1];
|
||||
if (GBATimerFlagsIsCountUp(nextTimer->flags) && GBATimerFlagsIsEnable(nextTimer->flags)) {
|
||||
++gba->memory.io[REG_TMCNT_LO(timerId + 1) >> 1];
|
||||
if (!gba->memory.io[REG_TMCNT_LO(timerId + 1) >> 1] && GBATimerFlagsIsEnable(nextTimer->flags)) {
|
||||
++gba->memory.io[GBA_REG_TMCNT_LO(timerId + 1) >> 1];
|
||||
if (!gba->memory.io[GBA_REG_TMCNT_LO(timerId + 1) >> 1] && GBATimerFlagsIsEnable(nextTimer->flags)) {
|
||||
GBATimerUpdate(gba, timerId + 1, cyclesLate);
|
||||
}
|
||||
}
|
||||
|
@ -99,11 +99,11 @@ void GBATimerUpdateRegister(struct GBA* gba, int timer, int32_t cyclesLate) {
|
|||
int32_t tickIncrement = currentTime - currentTimer->lastEvent;
|
||||
currentTimer->lastEvent = currentTime;
|
||||
tickIncrement >>= prescaleBits;
|
||||
tickIncrement += gba->memory.io[REG_TMCNT_LO(timer) >> 1];
|
||||
tickIncrement += gba->memory.io[GBA_REG_TMCNT_LO(timer) >> 1];
|
||||
while (tickIncrement >= 0x10000) {
|
||||
tickIncrement -= 0x10000 - currentTimer->reload;
|
||||
}
|
||||
gba->memory.io[REG_TMCNT_LO(timer) >> 1] = tickIncrement;
|
||||
gba->memory.io[GBA_REG_TMCNT_LO(timer) >> 1] = tickIncrement;
|
||||
|
||||
// Schedule next update
|
||||
tickIncrement = (0x10000 - tickIncrement) << prescaleBits;
|
||||
|
@ -134,7 +134,7 @@ void GBATimerWriteTMCNT_HI(struct GBA* gba, int timer, uint16_t control) {
|
|||
if (GBATimerFlagsIsEnable(oldFlags) != GBATimerFlagsIsEnable(currentTimer->flags)) {
|
||||
reschedule = true;
|
||||
if (GBATimerFlagsIsEnable(currentTimer->flags)) {
|
||||
gba->memory.io[REG_TMCNT_LO(timer) >> 1] = currentTimer->reload;
|
||||
gba->memory.io[GBA_REG_TMCNT_LO(timer) >> 1] = currentTimer->reload;
|
||||
}
|
||||
} else if (GBATimerFlagsIsCountUp(oldFlags) != GBATimerFlagsIsCountUp(currentTimer->flags)) {
|
||||
reschedule = true;
|
||||
|
|
|
@ -71,7 +71,7 @@ void GBAVideoReset(struct GBAVideo* video) {
|
|||
video->vcount = 0x7E;
|
||||
nextEvent = 117;
|
||||
}
|
||||
video->p->memory.io[REG_VCOUNT >> 1] = video->vcount;
|
||||
video->p->memory.io[GBA_REG(VCOUNT)] = video->vcount;
|
||||
|
||||
video->event.callback = _startHblank;
|
||||
mTimingSchedule(&video->p->timing, &video->event, nextEvent);
|
||||
|
@ -126,10 +126,10 @@ void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer*
|
|||
renderer->oam = &video->oam;
|
||||
video->renderer->init(video->renderer);
|
||||
video->renderer->reset(video->renderer);
|
||||
renderer->writeVideoRegister(renderer, REG_DISPCNT, video->p->memory.io[REG_DISPCNT >> 1]);
|
||||
renderer->writeVideoRegister(renderer, REG_GREENSWP, video->p->memory.io[REG_GREENSWP >> 1]);
|
||||
renderer->writeVideoRegister(renderer, GBA_REG_DISPCNT, video->p->memory.io[GBA_REG(DISPCNT)]);
|
||||
renderer->writeVideoRegister(renderer, GBA_REG_GREENSWP, video->p->memory.io[GBA_REG(GREENSWP)]);
|
||||
int address;
|
||||
for (address = REG_BG0CNT; address < 0x56; address += 2) {
|
||||
for (address = GBA_REG_BG0CNT; address < 0x56; address += 2) {
|
||||
if (address == 0x4E) {
|
||||
continue;
|
||||
}
|
||||
|
@ -146,13 +146,13 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
if (video->vcount == VIDEO_VERTICAL_TOTAL_PIXELS) {
|
||||
video->vcount = 0;
|
||||
}
|
||||
video->p->memory.io[REG_VCOUNT >> 1] = video->vcount;
|
||||
video->p->memory.io[GBA_REG(VCOUNT)] = video->vcount;
|
||||
|
||||
if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS) {
|
||||
video->shouldStall = 1;
|
||||
}
|
||||
|
||||
GBARegisterDISPSTAT dispstat = video->p->memory.io[REG_DISPSTAT >> 1];
|
||||
GBARegisterDISPSTAT dispstat = video->p->memory.io[GBA_REG(DISPSTAT)];
|
||||
dispstat = GBARegisterDISPSTATClearInHblank(dispstat);
|
||||
if (video->vcount == GBARegisterDISPSTATGetVcountSetting(dispstat)) {
|
||||
dispstat = GBARegisterDISPSTATFillVcounter(dispstat);
|
||||
|
@ -162,7 +162,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
} else {
|
||||
dispstat = GBARegisterDISPSTATClearVcounter(dispstat);
|
||||
}
|
||||
video->p->memory.io[REG_DISPSTAT >> 1] = dispstat;
|
||||
video->p->memory.io[GBA_REG(DISPSTAT)] = dispstat;
|
||||
|
||||
// Note: state may be recorded during callbacks, so ensure it is consistent!
|
||||
switch (video->vcount) {
|
||||
|
@ -170,7 +170,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
GBAFrameStarted(video->p);
|
||||
break;
|
||||
case GBA_VIDEO_VERTICAL_PIXELS:
|
||||
video->p->memory.io[REG_DISPSTAT >> 1] = GBARegisterDISPSTATFillInVblank(dispstat);
|
||||
video->p->memory.io[GBA_REG(DISPSTAT)] = GBARegisterDISPSTATFillInVblank(dispstat);
|
||||
if (video->frameskipCounter <= 0) {
|
||||
video->renderer->finishFrame(video->renderer);
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
video->p->earlyExit = true;
|
||||
break;
|
||||
case VIDEO_VERTICAL_TOTAL_PIXELS - 1:
|
||||
video->p->memory.io[REG_DISPSTAT >> 1] = GBARegisterDISPSTATClearInVblank(dispstat);
|
||||
video->p->memory.io[GBA_REG(DISPSTAT)] = GBARegisterDISPSTATClearInVblank(dispstat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ void _startHblank(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
mTimingSchedule(timing, &video->event, VIDEO_HBLANK_LENGTH - cyclesLate);
|
||||
|
||||
// Begin Hblank
|
||||
GBARegisterDISPSTAT dispstat = video->p->memory.io[REG_DISPSTAT >> 1];
|
||||
GBARegisterDISPSTAT dispstat = video->p->memory.io[GBA_REG(DISPSTAT)];
|
||||
dispstat = GBARegisterDISPSTATFillInHblank(dispstat);
|
||||
if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS && video->frameskipCounter <= 0) {
|
||||
video->renderer->drawScanline(video->renderer, video->vcount);
|
||||
|
@ -215,12 +215,12 @@ void _startHblank(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
GBARaiseIRQ(video->p, GBA_IRQ_HBLANK, cyclesLate - 6); // TODO: Where does this fudge factor come from?
|
||||
}
|
||||
video->shouldStall = 0;
|
||||
video->p->memory.io[REG_DISPSTAT >> 1] = dispstat;
|
||||
video->p->memory.io[GBA_REG(DISPSTAT)] = dispstat;
|
||||
}
|
||||
|
||||
void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value) {
|
||||
video->p->memory.io[REG_DISPSTAT >> 1] &= 0x7;
|
||||
video->p->memory.io[REG_DISPSTAT >> 1] |= value;
|
||||
video->p->memory.io[GBA_REG(DISPSTAT)] &= 0x7;
|
||||
video->p->memory.io[GBA_REG(DISPSTAT)] |= value;
|
||||
// TODO: Does a VCounter IRQ trigger on write?
|
||||
}
|
||||
|
||||
|
@ -244,35 +244,35 @@ static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer*
|
|||
GBAVideoCacheWriteVideoRegister(renderer->cache, address, value);
|
||||
}
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
case GBA_REG_DISPCNT:
|
||||
value &= 0xFFF7;
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
case REG_BG1CNT:
|
||||
case GBA_REG_BG0CNT:
|
||||
case GBA_REG_BG1CNT:
|
||||
value &= 0xDFFF;
|
||||
break;
|
||||
case REG_BG2CNT:
|
||||
case REG_BG3CNT:
|
||||
case GBA_REG_BG2CNT:
|
||||
case GBA_REG_BG3CNT:
|
||||
value &= 0xFFFF;
|
||||
break;
|
||||
case REG_BG0HOFS:
|
||||
case REG_BG0VOFS:
|
||||
case REG_BG1HOFS:
|
||||
case REG_BG1VOFS:
|
||||
case REG_BG2HOFS:
|
||||
case REG_BG2VOFS:
|
||||
case REG_BG3HOFS:
|
||||
case REG_BG3VOFS:
|
||||
case GBA_REG_BG0HOFS:
|
||||
case GBA_REG_BG0VOFS:
|
||||
case GBA_REG_BG1HOFS:
|
||||
case GBA_REG_BG1VOFS:
|
||||
case GBA_REG_BG2HOFS:
|
||||
case GBA_REG_BG2VOFS:
|
||||
case GBA_REG_BG3HOFS:
|
||||
case GBA_REG_BG3VOFS:
|
||||
value &= 0x01FF;
|
||||
break;
|
||||
case REG_BLDCNT:
|
||||
case GBA_REG_BLDCNT:
|
||||
value &= 0x3FFF;
|
||||
break;
|
||||
case REG_BLDALPHA:
|
||||
case GBA_REG_BLDALPHA:
|
||||
value &= 0x1F1F;
|
||||
break;
|
||||
case REG_WININ:
|
||||
case REG_WINOUT:
|
||||
case GBA_REG_WININ:
|
||||
case GBA_REG_WINOUT:
|
||||
value &= 0x3F3F;
|
||||
break;
|
||||
default:
|
||||
|
@ -356,7 +356,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState
|
|||
video->shouldStall = 0;
|
||||
int32_t flags;
|
||||
LOAD_32(flags, 0, &state->video.flags);
|
||||
GBARegisterDISPSTAT dispstat = state->io[REG_DISPSTAT >> 1];
|
||||
GBARegisterDISPSTAT dispstat = state->io[GBA_REG(DISPSTAT)];
|
||||
switch (GBASerializedVideoFlagsGetMode(flags)) {
|
||||
case 0:
|
||||
if (GBARegisterDISPSTATIsInHblank(dispstat)) {
|
||||
|
@ -385,6 +385,6 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState
|
|||
}
|
||||
mTimingSchedule(&video->p->timing, &video->event, when);
|
||||
|
||||
LOAD_16(video->vcount, REG_VCOUNT, state->io);
|
||||
LOAD_16(video->vcount, GBA_REG_VCOUNT, state->io);
|
||||
video->renderer->reset(video->renderer);
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ void FrameView::updateTilesGBA(bool) {
|
|||
|
||||
uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io;
|
||||
QRgb backdrop = M_RGB5_TO_RGB8(static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[0]);
|
||||
GBARegisterDISPCNT gbaDispcnt = io[REG_DISPCNT >> 1];
|
||||
GBARegisterDISPCNT gbaDispcnt = io[GBA_REG(DISPCNT)];
|
||||
int mode = GBARegisterDISPCNTGetMode(gbaDispcnt);
|
||||
|
||||
std::array<bool, 4> enabled{
|
||||
|
@ -233,14 +233,14 @@ void FrameView::updateTilesGBA(bool) {
|
|||
if (!enabled[bg]) {
|
||||
continue;
|
||||
}
|
||||
if (GBARegisterBGCNTGetPriority(io[(REG_BG0CNT >> 1) + bg]) != priority) {
|
||||
if (GBARegisterBGCNTGetPriority(io[GBA_REG(BG0CNT) + bg]) != priority) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QPointF offset;
|
||||
if (mode == 0) {
|
||||
offset.setX(-(io[(REG_BG0HOFS >> 1) + (bg << 1)] & 0x1FF));
|
||||
offset.setY(-(io[(REG_BG0VOFS >> 1) + (bg << 1)] & 0x1FF));
|
||||
offset.setX(-(io[GBA_REG(BG0HOFS) + (bg << 1)] & 0x1FF));
|
||||
offset.setY(-(io[GBA_REG(BG0VOFS) + (bg << 1)] & 0x1FF));
|
||||
};
|
||||
m_queue.append({
|
||||
{ LayerId::BACKGROUND, bg },
|
||||
|
|
|
@ -1579,7 +1579,7 @@ IOViewer::IOViewer(std::shared_ptr<CoreController> controller, QWidget* parent)
|
|||
#ifdef M_CORE_GBA
|
||||
case mPLATFORM_GBA:
|
||||
regs = GBAIORegisterNames;
|
||||
maxRegs = REG_MAX >> 1;
|
||||
maxRegs = GBA_REG_MAX >> 1;
|
||||
m_base = GBA_BASE_IO;
|
||||
m_width = 1;
|
||||
break;
|
||||
|
|
|
@ -180,40 +180,40 @@ void MapView::updateTilesGBA(bool) {
|
|||
#ifdef M_CORE_GBA
|
||||
if (m_controller->platform() == mPLATFORM_GBA) {
|
||||
uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io;
|
||||
int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]);
|
||||
int mode = GBARegisterDISPCNTGetMode(io[GBA_REG(DISPCNT)]);
|
||||
if (m_map == 2 && mode > 2) {
|
||||
bitmap = mode == 4 ? 1 : 0;
|
||||
if (mode != 3) {
|
||||
frame = GBARegisterDISPCNTGetFrameSelect(io[REG_DISPCNT >> 1]);
|
||||
frame = GBARegisterDISPCNTGetFrameSelect(io[GBA_REG(DISPCNT)]);
|
||||
}
|
||||
}
|
||||
m_boundary = 1024;
|
||||
m_ui.tile->setMaxTile(1536);
|
||||
priority = GBARegisterBGCNTGetPriority(io[(REG_BG0CNT >> 1) + m_map]);
|
||||
priority = GBARegisterBGCNTGetPriority(io[GBA_REG(BG0CNT) + m_map]);
|
||||
if (mode == 0 || (mode == 1 && m_map != 2)) {
|
||||
offset = QString("%1, %2")
|
||||
.arg(io[(REG_BG0HOFS >> 1) + (m_map << 1)])
|
||||
.arg(io[(REG_BG0VOFS >> 1) + (m_map << 1)]);
|
||||
.arg(io[GBA_REG(BG0HOFS) + (m_map << 1)])
|
||||
.arg(io[GBA_REG(BG0VOFS) + (m_map << 1)]);
|
||||
|
||||
if (!GBARegisterBGCNTIs256Color(io[(REG_BG0CNT >> 1) + m_map])) {
|
||||
if (!GBARegisterBGCNTIs256Color(io[GBA_REG(BG0CNT) + m_map])) {
|
||||
m_boundary = 2048;
|
||||
m_ui.tile->setMaxTile(3072);
|
||||
}
|
||||
} else if ((mode > 0 && m_map == 2) || (mode == 2 && m_map == 3)) {
|
||||
int32_t refX = io[(REG_BG2X_LO >> 1) + ((m_map - 2) << 2)];
|
||||
refX |= io[(REG_BG2X_HI >> 1) + ((m_map - 2) << 2)] << 16;
|
||||
int32_t refY = io[(REG_BG2Y_LO >> 1) + ((m_map - 2) << 2)];
|
||||
refY |= io[(REG_BG2Y_HI >> 1) + ((m_map - 2) << 2)] << 16;
|
||||
int32_t refX = io[GBA_REG(BG2X_LO) + ((m_map - 2) << 2)];
|
||||
refX |= io[GBA_REG(BG2X_HI) + ((m_map - 2) << 2)] << 16;
|
||||
int32_t refY = io[GBA_REG(BG2Y_LO) + ((m_map - 2) << 2)];
|
||||
refY |= io[GBA_REG(BG2Y_HI) + ((m_map - 2) << 2)] << 16;
|
||||
refX <<= 4;
|
||||
refY <<= 4;
|
||||
refX >>= 4;
|
||||
refY >>= 4;
|
||||
offset = QString("%1\n%2").arg(refX / 65536., 0, 'f', 3).arg(refY / 65536., 0, 'f', 3);
|
||||
transform = QString("%1 %2\n%3 %4")
|
||||
.arg(io[(REG_BG2PA >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
|
||||
.arg(io[(REG_BG2PB >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
|
||||
.arg(io[(REG_BG2PC >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
|
||||
.arg(io[(REG_BG2PD >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2);
|
||||
.arg(io[GBA_REG(BG2PA) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
|
||||
.arg(io[GBA_REG(BG2PB) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
|
||||
.arg(io[GBA_REG(BG2PC) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
|
||||
.arg(io[GBA_REG(BG2PD) + ((m_map - 2) << 2)] / 256., 3, 'f', 2);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue