diff --git a/src/agb/GBA.cpp b/src/agb/GBA.cpp index 0fbb9a0b..06425f9a 100644 --- a/src/agb/GBA.cpp +++ b/src/agb/GBA.cpp @@ -2356,25 +2356,28 @@ void CPUCheckDMA(int reason, int dmamask) void CPUUpdateRegister(u32 address, u16 value) { - switch(address) { + switch(address) + { case 0x00: - { - if ((value & 7) >5) - DISPCNT = (value &7); - bool change = ((DISPCNT ^ value) & 0x80) ? true : false; - bool changeBG = ((DISPCNT ^ value) & 0x0F00) ? true : false; - u16 changeBGon = (((~DISPCNT) & value) & 0x0F00); - DISPCNT = (value & 0xFFF7); + { // we need to place the following code in { } because we declare & initialize variables in a case statement + if((value & 7) > 5) { + // display modes above 0-5 are prohibited + DISPCNT = (value & 7); + } + bool change = (0 != ((DISPCNT ^ value) & 0x80)); + bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00)); + u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated + + DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode UPDATE_REG(0x00, DISPCNT); - if (changeBGon) - { - layerEnableDelay=4; - layerEnable = layerSettings & value & (~changeBGon); + if(changeBGon) { + layerEnableDelay = 4; + layerEnable = layerSettings & value & (~changeBGon); + } else { + layerEnable = layerSettings & value; + // CPUUpdateTicks(); } - else - layerEnable = layerSettings & value; - // CPUUpdateTicks(); windowOn = (layerEnable & 0x6000) ? true : false; if(change && !((value & 0x80))) { @@ -2390,10 +2393,11 @@ void CPUUpdateRegister(u32 address, u16 value) } CPUUpdateRender(); // we only care about changes in BG0-BG3 - if(changeBG) + if(changeBG) { CPUUpdateRenderBuffers(false); + } + break; } - break; case 0x04: DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); UPDATE_REG(0x04, DISPSTAT); @@ -2739,9 +2743,9 @@ void CPUUpdateRegister(u32 address, u16 value) } } break; - case 0x100: + case 0x100: timer0Reload = value; - interp_rate(); + interp_rate(); break; case 0x102: timer0Value = value; @@ -2750,7 +2754,7 @@ void CPUUpdateRegister(u32 address, u16 value) break; case 0x104: timer1Reload = value; - interp_rate(); + interp_rate(); break; case 0x106: timer1Value = value; @@ -2774,35 +2778,35 @@ void CPUUpdateRegister(u32 address, u16 value) cpuNextEvent = cpuTotalTicks; break; case 0x128: - #ifdef LINK_EMULATION - if (linkenable) - { - StartLink(value); - } - else +#ifdef LINK_EMULATION + if (linkenable) + { + StartLink(value); + } + else #endif - { - if(value & 0x80) { - value &= 0xff7f; - if(value & 1 && (value & 0x4000)) { - UPDATE_REG(0x12a, 0xFF); - IF |= 0x80; - UPDATE_REG(0x202, IF); - value &= 0x7f7f; - } - } - UPDATE_REG(0x128, value); - } + { + if(value & 0x80) { + value &= 0xff7f; + if(value & 1 && (value & 0x4000)) { + UPDATE_REG(0x12a, 0xFF); + IF |= 0x80; + UPDATE_REG(0x202, IF); + value &= 0x7f7f; + } + } + UPDATE_REG(0x128, value); + } + break; + case 0x12a: +#ifdef LINK_EMULATION + if(linkenable && lspeed) + LinkSSend(value); +#endif + { + UPDATE_REG(0x134, value); + } break; - case 0x12a: - #ifdef LINK_EMULATION - if(linkenable && lspeed) - LinkSSend(value); - #endif - { - UPDATE_REG(0x134, value); - } - break; case 0x130: P1 |= (value & 0x3FF); UPDATE_REG(0x130, P1); @@ -2812,22 +2816,22 @@ void CPUUpdateRegister(u32 address, u16 value) break; case 0x134: #ifdef LINK_EMULATION - if (linkenable) - StartGPLink(value); - else + if (linkenable) + StartGPLink(value); + else #endif - UPDATE_REG(0x134, value); + UPDATE_REG(0x134, value); - break; + break; case 0x140: #ifdef LINK_EMULATION - if (linkenable) - StartJOYLink(value); - else + if (linkenable) + StartJOYLink(value); + else #endif - UPDATE_REG(0x140, value); + UPDATE_REG(0x140, value); - break; + break; case 0x200: IE = value & 0x3FFF; UPDATE_REG(0x200, IE); diff --git a/src/agb/GBAinline.h b/src/agb/GBAinline.h index 833e3f30..53d75c6d 100644 --- a/src/agb/GBAinline.h +++ b/src/agb/GBAinline.h @@ -17,8 +17,8 @@ // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef VBA_GBAinline_H -#define VBA_GBAinline_H +#ifndef GBAINLINE_H +#define GBAINLINE_H #include "../System.h" #include "../Port.h" @@ -67,7 +67,7 @@ static inline u32 CPUReadMemory(u32 address) if(address & 3) { if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) { log("Unaligned word read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } } #endif @@ -80,7 +80,7 @@ static inline u32 CPUReadMemory(u32 address) #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_READ) { log("Illegal word read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } #endif @@ -111,8 +111,8 @@ static inline u32 CPUReadMemory(u32 address) address = (address & 0x1fffc); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000)) { - value = 0; - break; + value = 0; + break; } if ((address & 0x18000) == 0x18000) address &= 0x17fff; @@ -139,11 +139,11 @@ static inline u32 CPUReadMemory(u32 address) return flashRead(address); // default default: - unreadable: +unreadable: #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_READ) { log("Illegal word read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } #endif @@ -166,10 +166,10 @@ static inline u32 CPUReadMemory(u32 address) #else #ifdef __GNUC__ asm("and $3, %%ecx;" - "shl $3 ,%%ecx;" - "ror %%cl, %0" - : "=r" (value) - : "r" (value), "c" (address)); + "shl $3 ,%%ecx;" + "ror %%cl, %0" + : "=r" (value) + : "r" (value), "c" (address)); #else __asm { mov ecx, address; @@ -191,7 +191,7 @@ static inline u32 CPUReadHalfWord(u32 address) if(address & 1) { if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) { log("Unaligned halfword read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } } #endif @@ -205,7 +205,7 @@ static inline u32 CPUReadHalfWord(u32 address) #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_READ) { log("Illegal halfword read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } #endif value = READ16LE(((u16 *)&biosProtected[address&2])); @@ -228,14 +228,14 @@ static inline u32 CPUReadHalfWord(u32 address) if (((address & 0x3fe) == 0x100) && timer0On) value = 0xFFFF - ((timer0Ticks-cpuTotalTicks) >> timer0ClockReload); else - if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4)) - value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload); - else - if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4)) - value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload); - else - if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4)) - value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload); + if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4)) + value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload); + else + if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4)) + value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload); + else + if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4)) + value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload); } } else goto unreadable; @@ -247,8 +247,8 @@ static inline u32 CPUReadHalfWord(u32 address) address = (address & 0x1fffe); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000)) { - value = 0; - break; + value = 0; + break; } if ((address & 0x18000) == 0x18000) address &= 0x17fff; @@ -278,11 +278,11 @@ static inline u32 CPUReadHalfWord(u32 address) return flashRead(address); // default default: - unreadable: +unreadable: #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_READ) { log("Illegal halfword read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } #endif if(cpuDmaHack) { @@ -321,7 +321,7 @@ static inline u8 CPUReadByte(u32 address) #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_READ) { log("Illegal byte read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } #endif return biosProtected[address & 3]; @@ -341,7 +341,7 @@ static inline u8 CPUReadByte(u32 address) case 6: address = (address & 0x1ffff); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000)) - return 0; + return 0; if ((address & 0x18000) == 0x18000) address &= 0x17fff; return vram[address]; @@ -362,23 +362,23 @@ static inline u8 CPUReadByte(u32 address) return flashRead(address); if(cpuEEPROMSensorEnabled) { switch(address & 0x00008f00) { - case 0x8200: - return systemGetSensorX() & 255; - case 0x8300: - return (systemGetSensorX() >> 8)|0x80; - case 0x8400: - return systemGetSensorY() & 255; - case 0x8500: - return systemGetSensorY() >> 8; + case 0x8200: + return systemGetSensorX() & 255; + case 0x8300: + return (systemGetSensorX() >> 8)|0x80; + case 0x8400: + return systemGetSensorY() & 255; + case 0x8500: + return systemGetSensorY() >> 8; } } // default default: - unreadable: +unreadable: #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_READ) { log("Illegal byte read: %08x at %08x\n", address, armMode ? - armNextPC - 4 : armNextPC - 2); + armNextPC - 4 : armNextPC - 2); } #endif if(cpuDmaHack) { @@ -401,9 +401,9 @@ static inline void CPUWriteMemory(u32 address, u32 value) if(address & 3) { if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) { log("Unaligned word write: %08x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } } #endif @@ -413,7 +413,7 @@ static inline void CPUWriteMemory(u32 address, u32 value) #ifdef BKPT_SUPPORT if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC])) cheatsWriteMemory(address & 0x203FFFC, - value); + value); else #endif WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value); @@ -422,7 +422,7 @@ static inline void CPUWriteMemory(u32 address, u32 value) #ifdef BKPT_SUPPORT if(*((u32 *)&freezeInternalRAM[address & 0x7ffc])) cheatsWriteMemory(address & 0x3007FFC, - value); + value); else #endif WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value); @@ -437,15 +437,15 @@ static inline void CPUWriteMemory(u32 address, u32 value) #ifdef BKPT_SUPPORT if(*((u32 *)&freezePRAM[address & 0x3fc])) cheatsWriteMemory(address & 0x70003FC, - value); + value); else #endif - WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value); + WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value); break; case 0x06: address = (address & 0x1fffc); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000)) - return; + return; if ((address & 0x18000) == 0x18000) address &= 0x17fff; @@ -455,16 +455,16 @@ static inline void CPUWriteMemory(u32 address, u32 value) else #endif - WRITE32LE(((u32 *)&vram[address]), value); + WRITE32LE(((u32 *)&vram[address]), value); break; case 0x07: #ifdef BKPT_SUPPORT if(*((u32 *)&freezeOAM[address & 0x3fc])) cheatsWriteMemory(address & 0x70003FC, - value); + value); else #endif - WRITE32LE(((u32 *)&oam[address & 0x3fc]), value); + WRITE32LE(((u32 *)&oam[address & 0x3fc]), value); break; case 0x0D: if(cpuEEPROMEnabled) { @@ -479,13 +479,13 @@ static inline void CPUWriteMemory(u32 address, u32 value) } // default default: - unwritable: +unwritable: #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_WRITE) { log("Illegal word write: %08x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } #endif break; @@ -498,9 +498,9 @@ static inline void CPUWriteHalfWord(u32 address, u16 value) if(address & 1) { if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) { log("Unaligned halfword write: %04x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } } #endif @@ -510,7 +510,7 @@ static inline void CPUWriteHalfWord(u32 address, u16 value) #ifdef BKPT_SUPPORT if(*((u16 *)&freezeWorkRAM[address & 0x3FFFE])) cheatsWriteHalfWord(address & 0x203FFFE, - value); + value); else #endif WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]),value); @@ -519,7 +519,7 @@ static inline void CPUWriteHalfWord(u32 address, u16 value) #ifdef BKPT_SUPPORT if(*((u16 *)&freezeInternalRAM[address & 0x7ffe])) cheatsWriteHalfWord(address & 0x3007ffe, - value); + value); else #endif WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value); @@ -533,33 +533,33 @@ static inline void CPUWriteHalfWord(u32 address, u16 value) #ifdef BKPT_SUPPORT if(*((u16 *)&freezePRAM[address & 0x03fe])) cheatsWriteHalfWord(address & 0x70003fe, - value); + value); else #endif - WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value); + WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value); break; case 6: address = (address & 0x1fffe); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000)) - return; + return; if ((address & 0x18000) == 0x18000) address &= 0x17fff; #ifdef BKPT_SUPPORT if(*((u16 *)&freezeVRAM[address])) cheatsWriteHalfWord(address + 0x06000000, - value); + value); else #endif - WRITE16LE(((u16 *)&vram[address]), value); + WRITE16LE(((u16 *)&vram[address]), value); break; case 7: #ifdef BKPT_SUPPORT if(*((u16 *)&freezeOAM[address & 0x03fe])) cheatsWriteHalfWord(address & 0x70003fe, - value); + value); else #endif - WRITE16LE(((u16 *)&oam[address & 0x3fe]), value); + WRITE16LE(((u16 *)&oam[address & 0x3fe]), value); break; case 8: case 9: @@ -581,13 +581,13 @@ static inline void CPUWriteHalfWord(u32 address, u16 value) } goto unwritable; default: - unwritable: +unwritable: #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_WRITE) { log("Illegal halfword write: %04x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } #endif break; @@ -599,11 +599,11 @@ static inline void CPUWriteByte(u32 address, u8 b) switch(address >> 24) { case 2: #ifdef BKPT_SUPPORT - if(freezeWorkRAM[address & 0x3FFFF]) - cheatsWriteByte(address & 0x203FFFF, b); - else + if(freezeWorkRAM[address & 0x3FFFF]) + cheatsWriteByte(address & 0x203FFFF, b); + else #endif - workRAM[address & 0x3FFFF] = b; + workRAM[address & 0x3FFFF] = b; break; case 3: #ifdef BKPT_SUPPORT @@ -616,13 +616,6 @@ static inline void CPUWriteByte(u32 address, u8 b) case 4: if(address < 0x4000400) { switch(address & 0x3FF) { - case 0x301: - if(b == 0x80) - stopState = true; - holdState = 1; - holdType = -1; - cpuNextEvent = cpuTotalTicks; - break; case 0x60: case 0x61: case 0x62: @@ -663,17 +656,22 @@ static inline void CPUWriteByte(u32 address, u8 b) case 0x9d: case 0x9e: case 0x9f: - soundEvent(address&0xFF, b); - break; - default: - if(address & 1) - CPUUpdateRegister(address & 0x3fe, - ((READ16LE(((u16 *)&ioMem[address & 0x3fe]))) - & 0x00FF) | - b<<8); - else - CPUUpdateRegister(address & 0x3fe, - ((READ16LE(((u16 *)&ioMem[address & 0x3fe])) & 0xFF00) | b)); + soundEvent(address&0xFF, b); + break; + case 0x301: // HALTCNT, undocumented + if(b == 0x80) + stopState = true; + holdState = 1; + holdType = -1; + cpuNextEvent = cpuTotalTicks; + break; + default: // every other register + u32 lowerBits = address & 0x3fe; + if(address & 1) { + CPUUpdateRegister(lowerBits, (READ16LE(&ioMem[lowerBits]) & 0x00FF) | (b << 8)); + } else { + CPUUpdateRegister(lowerBits, (READ16LE(&ioMem[lowerBits]) & 0xFF00) | b); + } } break; } else goto unwritable; @@ -685,7 +683,7 @@ static inline void CPUWriteByte(u32 address, u8 b) case 6: address = (address & 0x1fffe); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000)) - return; + return; if ((address & 0x18000) == 0x18000) address &= 0x17fff; @@ -698,7 +696,7 @@ static inline void CPUWriteByte(u32 address, u8 b) cheatsWriteByte(address + 0x06000000, b); else #endif - *((u16 *)&vram[address]) = (b << 8) | b; + *((u16 *)&vram[address]) = (b << 8) | b; } break; case 7: @@ -713,26 +711,26 @@ static inline void CPUWriteByte(u32 address, u8 b) } goto unwritable; case 14: - if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) { + if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) { - //if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) { + //if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) { - (*cpuSaveGameFunc)(address, b); + (*cpuSaveGameFunc)(address, b); break; } // default default: - unwritable: +unwritable: #ifdef GBA_LOGGING if(systemVerbose & VERBOSE_ILLEGAL_WRITE) { log("Illegal byte write: %02x to %08x from %08x\n", - b, - address, - armMode ? armNextPC - 4 : armNextPC -2 ); + b, + address, + armMode ? armNextPC - 4 : armNextPC -2 ); } #endif break; } } -#endif //VBA_GBAinline_H +#endif //GBAINLINE_H