Mercurial > vba-clojure
diff src/gba/GBAinline.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gba/GBAinline.h Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,490 @@ 1.4 +#ifndef VBA_GBAINLINE_H 1.5 +#define VBA_GBAINLINE_H 1.6 + 1.7 +#if _MSC_VER > 1000 1.8 +#pragma once 1.9 +#endif // _MSC_VER > 1000 1.10 + 1.11 +#include "../Port.h" 1.12 +#include "../common/System.h" 1.13 +#include "../common/vbalua.h" 1.14 +#include "GBAGlobals.h" 1.15 +#include "EEprom.h" 1.16 +#include "Flash.h" 1.17 +#include "RTC.h" 1.18 + 1.19 +extern bool8 cpuSramEnabled; 1.20 +extern bool8 cpuFlashEnabled; 1.21 +extern bool8 cpuEEPROMEnabled; 1.22 +extern bool8 cpuEEPROMSensorEnabled; 1.23 + 1.24 +#define CPUReadByteQuick(addr) \ 1.25 + map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] 1.26 + 1.27 +#define CPUReadHalfWordQuick(addr) \ 1.28 + READ16LE(((u16 *)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 1.29 + 1.30 +#define CPUReadMemoryQuick(addr) \ 1.31 + READ32LE(((u32 *)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 1.32 + 1.33 +//inline u32 CPUReadMemoryQuick(u32 addr) 1.34 +//{ 1.35 +// u32 addrShift = (addr)>>24; 1.36 +// u32 rt = (addr) & map[addrShift].mask; 1.37 +// return READ32LE(((u32*)&map[addrShift].address[rt])); 1.38 +//} 1.39 + 1.40 +inline u32 CPUReadMemory(u32 address) 1.41 +{ 1.42 +#ifdef GBA_LOGGING 1.43 + if (address & 3) 1.44 + { 1.45 + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) 1.46 + { 1.47 + log("Unaligned word read: %08x at %08x\n", address, armMode ? 1.48 + armNextPC - 4 : armNextPC - 2); 1.49 + } 1.50 + } 1.51 +#endif 1.52 + 1.53 + u32 value; 1.54 + switch (address >> 24) 1.55 + { 1.56 + case 0: 1.57 + if (reg[15].I >> 24) 1.58 + { 1.59 + if (address < 0x4000) 1.60 + { 1.61 +#ifdef GBA_LOGGING 1.62 + if (systemVerbose & VERBOSE_ILLEGAL_READ) 1.63 + { 1.64 + log("Illegal word read: %08x at %08x\n", address, armMode ? 1.65 + armNextPC - 4 : armNextPC - 2); 1.66 + } 1.67 +#endif 1.68 + 1.69 + value = READ32LE(((u32 *)&biosProtected)); 1.70 + } 1.71 + else 1.72 + goto unreadable; 1.73 + } 1.74 + else 1.75 + value = READ32LE(((u32 *)&bios[address & 0x3FFC])); 1.76 + break; 1.77 + case 2: 1.78 + value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC])); 1.79 + break; 1.80 + case 3: 1.81 + value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC])); 1.82 + break; 1.83 + case 4: 1.84 + if ((address < 0x4000400) && ioReadable[address & 0x3fc]) 1.85 + { 1.86 + if (ioReadable[(address & 0x3fc) + 2]) 1.87 + { 1.88 + if (address >= 0x400012d && address <= 0x4000131) 1.89 + GBASystemCounters.lagged = false; 1.90 + value = READ32LE(((u32 *)&ioMem[address & 0x3fC])); 1.91 + } 1.92 + else 1.93 + { 1.94 + if (address >= 0x400012f && address <= 0x4000131) 1.95 + GBASystemCounters.lagged = false; 1.96 + value = READ16LE(((u16 *)&ioMem[address & 0x3fc])); 1.97 + } 1.98 + } 1.99 + else 1.100 + goto unreadable; 1.101 + break; 1.102 + case 5: 1.103 + value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC])); 1.104 + break; 1.105 + case 6: 1.106 + value = READ32LE(((u32 *)&vram[address & 0x1fffc])); 1.107 + break; 1.108 + case 7: 1.109 + value = READ32LE(((u32 *)&oam[address & 0x3FC])); 1.110 + break; 1.111 + case 8: 1.112 + case 9: 1.113 + case 10: 1.114 + case 11: 1.115 + case 12: 1.116 + value = READ32LE(((u32 *)&rom[address&0x1FFFFFC])); 1.117 + break; 1.118 + case 13: 1.119 + if (cpuEEPROMEnabled) 1.120 + // no need to swap this 1.121 + return eepromRead(address); 1.122 + goto unreadable; 1.123 + case 14: 1.124 + if (cpuFlashEnabled | cpuSramEnabled) 1.125 + // no need to swap this 1.126 + return flashRead(address); 1.127 + // default 1.128 + default: 1.129 +unreadable: 1.130 +#ifdef GBA_LOGGING 1.131 + if (systemVerbose & VERBOSE_ILLEGAL_READ) 1.132 + { 1.133 + log("Illegal word read: %08x at %08x\n", address, armMode ? 1.134 + armNextPC - 4 : armNextPC - 2); 1.135 + } 1.136 +#endif 1.137 + 1.138 + // if(ioMem[0x205] & 0x40) { 1.139 + if (armState) 1.140 + { 1.141 + value = CPUReadMemoryQuick(reg[15].I); 1.142 + } 1.143 + else 1.144 + { 1.145 + value = CPUReadHalfWordQuick(reg[15].I) | 1.146 + CPUReadHalfWordQuick(reg[15].I) << 16; 1.147 + } 1.148 + // } else { 1.149 + // value = *((u32 *)&bios[address & 0x3ffc]); 1.150 + // } 1.151 + // return 0xFFFFFFFF; 1.152 + } 1.153 + 1.154 + if (address & 3) 1.155 + { 1.156 +#ifdef C_CORE 1.157 + int shift = (address & 3) << 3; 1.158 + value = (value >> shift) | (value << (32 - shift)); 1.159 +#else 1.160 +#ifdef __GNUC__ 1.161 + asm ("and $3, %%ecx;" 1.162 + "shl $3 ,%%ecx;" 1.163 + "ror %%cl, %0" 1.164 + : "=r" (value) 1.165 + : "r" (value), "c" (address)); 1.166 +#else 1.167 + __asm { 1.168 + mov ecx, address; 1.169 + and ecx, 3; 1.170 + shl ecx, 3; 1.171 + ror [dword ptr value], cl; 1.172 + } 1.173 +#endif 1.174 +#endif 1.175 + } 1.176 + return value; 1.177 +} 1.178 + 1.179 +extern u32 myROM[]; 1.180 + 1.181 +inline u32 CPUReadHalfWord(u32 address) 1.182 +{ 1.183 +#ifdef GBA_LOGGING 1.184 + if (address & 1) 1.185 + { 1.186 + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) 1.187 + { 1.188 + log("Unaligned halfword read: %08x at %08x\n", address, armMode ? 1.189 + armNextPC - 4 : armNextPC - 2); 1.190 + } 1.191 + } 1.192 +#endif 1.193 + 1.194 + u32 value; 1.195 + 1.196 + switch (address >> 24) 1.197 + { 1.198 + case 0: 1.199 + if (reg[15].I >> 24) 1.200 + { 1.201 + if (address < 0x4000) 1.202 + { 1.203 +#ifdef GBA_LOGGING 1.204 + if (systemVerbose & VERBOSE_ILLEGAL_READ) 1.205 + { 1.206 + log("Illegal halfword read: %08x at %08x\n", address, armMode ? 1.207 + armNextPC - 4 : armNextPC - 2); 1.208 + } 1.209 +#endif 1.210 + value = READ16LE(((u16 *)&biosProtected[address&2])); 1.211 + } 1.212 + else 1.213 + goto unreadable; 1.214 + } 1.215 + else 1.216 + value = READ16LE(((u16 *)&bios[address & 0x3FFE])); 1.217 + break; 1.218 + case 2: 1.219 + value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE])); 1.220 + break; 1.221 + case 3: 1.222 + value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe])); 1.223 + break; 1.224 + case 4: 1.225 + if ((address < 0x4000400) && ioReadable[address & 0x3fe]) 1.226 + { 1.227 + if (address >= 0x400012f && address <= 0x4000131) 1.228 + GBASystemCounters.lagged = false; 1.229 + value = READ16LE(((u16 *)&ioMem[address & 0x3fe])); 1.230 + } 1.231 + else 1.232 + goto unreadable; 1.233 + break; 1.234 + case 5: 1.235 + value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe])); 1.236 + break; 1.237 + case 6: 1.238 + value = READ16LE(((u16 *)&vram[address & 0x1fffe])); 1.239 + break; 1.240 + case 7: 1.241 + value = READ16LE(((u16 *)&oam[address & 0x3fe])); 1.242 + break; 1.243 + case 8: 1.244 + case 9: 1.245 + case 10: 1.246 + case 11: 1.247 + case 12: 1.248 + if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) 1.249 + value = rtcRead(address); 1.250 + else 1.251 + value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE])); 1.252 + break; 1.253 + case 13: 1.254 + if (cpuEEPROMEnabled) 1.255 + // no need to swap this 1.256 + return eepromRead(address); 1.257 + goto unreadable; 1.258 + case 14: 1.259 + if (cpuFlashEnabled | cpuSramEnabled) 1.260 + // no need to swap this 1.261 + return flashRead(address); 1.262 + // default 1.263 + default: 1.264 +unreadable: 1.265 +#ifdef GBA_LOGGING 1.266 + if (systemVerbose & VERBOSE_ILLEGAL_READ) 1.267 + { 1.268 + log("Illegal halfword read: %08x at %08x\n", address, armMode ? 1.269 + armNextPC - 4 : armNextPC - 2); 1.270 + } 1.271 +#endif 1.272 + extern bool8 cpuDmaHack; 1.273 + extern u32 cpuDmaLast; 1.274 + extern int32 cpuDmaCount; 1.275 + if (cpuDmaHack && cpuDmaCount) 1.276 + { 1.277 + value = (u16)cpuDmaLast; 1.278 + } 1.279 + else 1.280 + { 1.281 + if (armState) 1.282 + { 1.283 + value = CPUReadHalfWordQuick(reg[15].I + (address & 2)); 1.284 + } 1.285 + else 1.286 + { 1.287 + value = CPUReadHalfWordQuick(reg[15].I); 1.288 + } 1.289 + } 1.290 + // return value; 1.291 + // if(address & 1) 1.292 + // value = (value >> 8) | ((value & 0xFF) << 24); 1.293 + // return 0xFFFF; 1.294 + break; 1.295 + } 1.296 + 1.297 + if (address & 1) 1.298 + { 1.299 + value = (value >> 8) | (value << 24); 1.300 + } 1.301 + 1.302 + return value; 1.303 +} 1.304 + 1.305 +inline u16 CPUReadHalfWordSigned(u32 address) 1.306 +{ 1.307 + u16 value = CPUReadHalfWord(address); 1.308 + if ((address & 1)) 1.309 + value = (s8)value; 1.310 + return value; 1.311 +} 1.312 + 1.313 +inline u8 CPUReadByte(u32 address) 1.314 +{ 1.315 + switch (address >> 24) 1.316 + { 1.317 + case 0: 1.318 + if (reg[15].I >> 24) 1.319 + { 1.320 + if (address < 0x4000) 1.321 + { 1.322 +#ifdef GBA_LOGGING 1.323 + if (systemVerbose & VERBOSE_ILLEGAL_READ) 1.324 + { 1.325 + log("Illegal byte read: %08x at %08x\n", address, armMode ? 1.326 + armNextPC - 4 : armNextPC - 2); 1.327 + } 1.328 +#endif 1.329 + return biosProtected[address & 3]; 1.330 + } 1.331 + else 1.332 + goto unreadable; 1.333 + } 1.334 + return bios[address & 0x3FFF]; 1.335 + case 2: 1.336 + return workRAM[address & 0x3FFFF]; 1.337 + case 3: 1.338 + return internalRAM[address & 0x7fff]; 1.339 + case 4: 1.340 + if ((address < 0x4000400) && ioReadable[address & 0x3ff]) 1.341 + { 1.342 + if (address == 0x4000130 || address == 0x4000131) 1.343 + GBASystemCounters.lagged = false; 1.344 + return ioMem[address & 0x3ff]; 1.345 + } 1.346 + else 1.347 + goto unreadable; 1.348 + case 5: 1.349 + return paletteRAM[address & 0x3ff]; 1.350 + case 6: 1.351 + return vram[address & 0x1ffff]; 1.352 + case 7: 1.353 + return oam[address & 0x3ff]; 1.354 + case 8: 1.355 + case 9: 1.356 + case 10: 1.357 + case 11: 1.358 + case 12: 1.359 + return rom[address & 0x1FFFFFF]; 1.360 + case 13: 1.361 + if (cpuEEPROMEnabled) 1.362 + return eepromRead(address); 1.363 + goto unreadable; 1.364 + case 14: 1.365 + if (cpuSramEnabled | cpuFlashEnabled) 1.366 + return flashRead(address); 1.367 + if (cpuEEPROMSensorEnabled) 1.368 + { 1.369 + switch (address & 0x00008f00) 1.370 + { 1.371 + case 0x8200: 1.372 + return systemGetSensorX() & 255; 1.373 + case 0x8300: 1.374 + return (systemGetSensorX() >> 8)|0x80; 1.375 + case 0x8400: 1.376 + return systemGetSensorY() & 255; 1.377 + case 0x8500: 1.378 + return systemGetSensorY() >> 8; 1.379 + } 1.380 + } 1.381 + // default 1.382 + default: 1.383 +unreadable: 1.384 +#ifdef GBA_LOGGING 1.385 + if (systemVerbose & VERBOSE_ILLEGAL_READ) 1.386 + { 1.387 + log("Illegal byte read: %08x at %08x\n", address, armMode ? 1.388 + armNextPC - 4 : armNextPC - 2); 1.389 + } 1.390 +#endif 1.391 + 1.392 + if (armState) 1.393 + { 1.394 + return CPUReadByteQuick(reg[15].I+(address & 3)); 1.395 + } 1.396 + else 1.397 + { 1.398 + return CPUReadByteQuick(reg[15].I+(address & 1)); 1.399 + } 1.400 + // return 0xFF; 1.401 + break; 1.402 + } 1.403 +} 1.404 + 1.405 +inline void CPUWriteMemoryWrapped(u32 address, u32 value) 1.406 +{ 1.407 +#ifdef GBA_LOGGING 1.408 + if (address & 3) 1.409 + { 1.410 + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) 1.411 + { 1.412 + log("Unaliagned word write: %08x to %08x from %08x\n", 1.413 + value, 1.414 + address, 1.415 + armMode ? armNextPC - 4 : armNextPC - 2); 1.416 + } 1.417 + } 1.418 +#endif 1.419 + 1.420 + switch (address >> 24) 1.421 + { 1.422 + case 0x02: 1.423 +#ifdef SDL 1.424 + if (*((u32 *)&freezeWorkRAM[address & 0x3FFFC])) 1.425 + cheatsWriteMemory((u32 *)&workRAM[address & 0x3FFFC], 1.426 + value, 1.427 + *((u32 *)&freezeWorkRAM[address & 0x3FFFC])); 1.428 + else 1.429 +#endif 1.430 + WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value); 1.431 + break; 1.432 + case 0x03: 1.433 +#ifdef SDL 1.434 + if (*((u32 *)&freezeInternalRAM[address & 0x7ffc])) 1.435 + cheatsWriteMemory((u32 *)&internalRAM[address & 0x7FFC], 1.436 + value, 1.437 + *((u32 *)&freezeInternalRAM[address & 0x7ffc])); 1.438 + else 1.439 +#endif 1.440 + WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value); 1.441 + break; 1.442 + case 0x04: 1.443 + CPUUpdateRegister((address & 0x3FC), value & 0xFFFF); 1.444 + CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16)); 1.445 + break; 1.446 + case 0x05: 1.447 + WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value); 1.448 + break; 1.449 + case 0x06: 1.450 + if (address & 0x10000) 1.451 + WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value); 1.452 + else 1.453 + WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value); 1.454 + break; 1.455 + case 0x07: 1.456 + WRITE32LE(((u32 *)&oam[address & 0x3fc]), value); 1.457 + break; 1.458 + case 0x0D: 1.459 + if (cpuEEPROMEnabled) 1.460 + { 1.461 + eepromWrite(address, value); 1.462 + break; 1.463 + } 1.464 + goto unwritable; 1.465 + case 0x0E: 1.466 + if (!eepromInUse | cpuSramEnabled | cpuFlashEnabled) 1.467 + { 1.468 + (*cpuSaveGameFunc)(address, (u8)value); 1.469 + break; 1.470 + } 1.471 + // default 1.472 + default: 1.473 +unwritable: 1.474 +#ifdef GBA_LOGGING 1.475 + if (systemVerbose & VERBOSE_ILLEGAL_WRITE) 1.476 + { 1.477 + log("Illegal word write: %08x to %08x from %08x\n", 1.478 + value, 1.479 + address, 1.480 + armMode ? armNextPC - 4 : armNextPC - 2); 1.481 + } 1.482 +#endif 1.483 + break; 1.484 + } 1.485 +} 1.486 + 1.487 +inline void CPUWriteMemory(u32 address, u32 value) 1.488 +{ 1.489 + CPUWriteMemoryWrapped(address, value); 1.490 + CallRegisteredLuaMemHook(address, 4, value, LUAMEMHOOK_WRITE); 1.491 +} 1.492 + 1.493 +#endif // VBA_GBAINLINE_H