GBA: Clean up I/O register read/write

This commit is contained in:
Jeffrey Pfau 2015-11-11 19:46:16 -08:00
parent a2bc814d9c
commit 534d4fe5ba
3 changed files with 77 additions and 22 deletions

View File

@ -254,9 +254,9 @@ static const int _isRSpecialRegister[REG_MAX >> 1] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
// DMA // DMA
0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// Timers // Timers
@ -389,10 +389,11 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
break; break;
case REG_SOUNDCNT_HI: case REG_SOUNDCNT_HI:
GBAAudioWriteSOUNDCNT_HI(&gba->audio, value); GBAAudioWriteSOUNDCNT_HI(&gba->audio, value);
value &= 0x770F;
break; break;
case REG_SOUNDCNT_X: case REG_SOUNDCNT_X:
GBAAudioWriteSOUNDCNT_X(&gba->audio, value); GBAAudioWriteSOUNDCNT_X(&gba->audio, value);
value &= 0xFFFF; value &= 0x00F0;
value |= gba->memory.io[REG_SOUNDCNT_X >> 1] & 0xF; value |= gba->memory.io[REG_SOUNDCNT_X >> 1] & 0xF;
break; break;
case REG_SOUNDBIAS: case REG_SOUNDBIAS:
@ -531,7 +532,7 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
// Some bad interrupt libraries will write to this // Some bad interrupt libraries will write to this
break; break;
default: default:
GBALog(gba, GBA_LOG_STUB, "Stub I/O register write: %03x", address); GBALog(gba, GBA_LOG_STUB, "Stub I/O register write: %03X", address);
if (address >= REG_MAX) { if (address >= REG_MAX) {
GBALog(gba, GBA_LOG_GAME_ERROR, "Write to unused I/O register: %03X", address); GBALog(gba, GBA_LOG_GAME_ERROR, "Write to unused I/O register: %03X", address);
return; return;
@ -620,10 +621,22 @@ bool GBAIOIsReadConstant(uint32_t address) {
case REG_WINOUT: case REG_WINOUT:
case REG_BLDCNT: case REG_BLDCNT:
case REG_BLDALPHA: case REG_BLDALPHA:
case REG_DMA0CNT_LO: case REG_SOUND1CNT_LO:
case REG_DMA1CNT_LO: case REG_SOUND1CNT_HI:
case REG_DMA2CNT_LO: case REG_SOUND1CNT_X:
case REG_DMA3CNT_LO: 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_KEYINPUT:
case REG_IE: case REG_IE:
return true; return true;
@ -671,12 +684,6 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case REG_RCNT: case REG_RCNT:
return gba->sio.rcnt; return gba->sio.rcnt;
case REG_DMA0CNT_LO:
case REG_DMA1CNT_LO:
case REG_DMA2CNT_LO:
case REG_DMA3CNT_LO:
// Write-only register
return 0;
case REG_BG0HOFS: case REG_BG0HOFS:
case REG_BG0VOFS: case REG_BG0VOFS:
case REG_BG1HOFS: case REG_BG1HOFS:
@ -707,9 +714,42 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case REG_WIN1V: case REG_WIN1V:
case REG_MOSAIC: case REG_MOSAIC:
case REG_BLDY: 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_DMA0CNT_LO:
case REG_DMA1SAD_LO:
case REG_DMA1SAD_HI:
case REG_DMA1DAD_LO:
case REG_DMA1DAD_HI:
case REG_DMA1CNT_LO:
case REG_DMA2SAD_LO:
case REG_DMA2SAD_HI:
case REG_DMA2DAD_LO:
case REG_DMA2DAD_HI:
case REG_DMA2CNT_LO:
case REG_DMA3SAD_LO:
case REG_DMA3SAD_HI:
case REG_DMA3DAD_LO:
case REG_DMA3DAD_HI:
case REG_DMA3CNT_LO:
// Write-only register // Write-only register
GBALog(gba, GBA_LOG_GAME_ERROR, "Read from write-only I/O register: %03X", address); GBALog(gba, GBA_LOG_GAME_ERROR, "Read from write-only I/O register: %03X", address);
return GBALoad16(gba->cpu, 0x01000000, 0); // Simulate a bad load return GBALoadBad(gba->cpu);
case REG_SOUNDBIAS:
case REG_JOYCNT:
case REG_JOY_RECV:
case REG_JOY_TRANS:
case REG_KEYCNT:
case REG_POSTFLG:
GBALog(gba, GBA_LOG_STUB, "Stub I/O register read: %03x", address);
break;
case REG_DISPCNT: case REG_DISPCNT:
case REG_DISPSTAT: case REG_DISPSTAT:
case REG_VCOUNT: case REG_VCOUNT:
@ -733,6 +773,15 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case REG_SOUND4CNT_HI: case REG_SOUND4CNT_HI:
case REG_SOUNDCNT_LO: case REG_SOUNDCNT_LO:
case REG_SOUNDCNT_HI: case REG_SOUNDCNT_HI:
case REG_SOUNDCNT_X:
case REG_WAVE_RAM0_LO:
case REG_WAVE_RAM0_HI:
case REG_WAVE_RAM1_LO:
case REG_WAVE_RAM1_HI:
case REG_WAVE_RAM2_LO:
case REG_WAVE_RAM2_HI:
case REG_WAVE_RAM3_LO:
case REG_WAVE_RAM3_HI:
case REG_DMA0CNT_HI: case REG_DMA0CNT_HI:
case REG_DMA1CNT_HI: case REG_DMA1CNT_HI:
case REG_DMA2CNT_HI: case REG_DMA2CNT_HI:
@ -752,12 +801,8 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
// Some bad interrupt libraries will read from this // Some bad interrupt libraries will read from this
break; break;
default: default:
GBALog(gba, GBA_LOG_STUB, "Stub I/O register read: %03x", address); GBALog(gba, GBA_LOG_GAME_ERROR, "Read from unused I/O register: %03X", address);
if (address >= REG_MAX) { return GBALoadBad(gba->cpu);
GBALog(gba, GBA_LOG_GAME_ERROR, "Read from unused I/O register: %03X", address);
return GBALoad16(gba->cpu, 0x01000000, 0);
}
break;
} }
return gba->memory.io[address >> 1]; return gba->memory.io[address >> 1];
} }

View File

@ -374,6 +374,13 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
value |= value << 8; \ value |= value << 8; \
value |= value << 16; value |= value << 16;
uint32_t GBALoadBad(struct ARMCore* cpu) {
struct GBA* gba = (struct GBA*) cpu->master;
uint32_t value = 0;
LOAD_BAD;
return value;
}
uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
struct GBA* gba = (struct GBA*) cpu->master; struct GBA* gba = (struct GBA*) cpu->master;
struct GBAMemory* memory = &gba->memory; struct GBAMemory* memory = &gba->memory;
@ -1364,6 +1371,7 @@ uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
struct GBAMemory* memory = &gba->memory; struct GBAMemory* memory = &gba->memory;
struct GBADMA* currentDma = &memory->dma[dma]; struct GBADMA* currentDma = &memory->dma[dma];
int wasEnabled = GBADMARegisterIsEnable(currentDma->reg); int wasEnabled = GBADMARegisterIsEnable(currentDma->reg);
control &= 0xFFE0;
currentDma->reg = control; currentDma->reg = control;
if (GBADMARegisterIsDRQ(currentDma->reg)) { if (GBADMARegisterIsDRQ(currentDma->reg)) {

View File

@ -151,6 +151,8 @@ uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter); uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter); uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
uint32_t GBALoadBad(struct ARMCore* cpu);
void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter); void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter);
void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter); void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter);
void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter); void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter);