| ... | ... |
@@ -23,6 +23,12 @@ |
| 23 | 23 |
|
| 24 | 24 |
class XSFPlayer_2SF : public XSFPlayer |
| 25 | 25 |
{
|
| 26 |
+ std::vector<uint8_t> rom; |
|
| 27 |
+ |
|
| 28 |
+ void Map2SFSection(const std::vector<uint8_t> §ion); |
|
| 29 |
+ bool Map2SF(XSFFile *xSFToLoad); |
|
| 30 |
+ bool RecursiveLoad2SF(XSFFile *xSFToLoad, int level); |
|
| 31 |
+ bool Load2SF(XSFFile *xSFToLoad); |
|
| 26 | 32 |
public: |
| 27 | 33 |
XSFPlayer_2SF(const std::string &filename); |
| 28 | 34 |
XSFPlayer_2SF(const std::wstring &filename); |
| ... | ... |
@@ -47,329 +53,6 @@ XSFPlayer *XSFPlayer::Create(const std::wstring &fn) |
| 47 | 53 |
|
| 48 | 54 |
volatile bool execute = false; |
| 49 | 55 |
|
| 50 |
-static struct |
|
| 51 |
-{
|
|
| 52 |
- std::vector<uint8_t> rom, state; |
|
| 53 |
- unsigned stateptr; |
|
| 54 |
-} loaderwork; |
|
| 55 |
- |
|
| 56 |
-static inline uint16_t Get16BitsLE(const uint8_t *input) |
|
| 57 |
-{
|
|
| 58 |
- return input[0] | (input[1] << 8); |
|
| 59 |
-} |
|
| 60 |
- |
|
| 61 |
-static void load_getstateinit(unsigned ptr) |
|
| 62 |
-{
|
|
| 63 |
- loaderwork.stateptr = ptr; |
|
| 64 |
-} |
|
| 65 |
- |
|
| 66 |
-static void load_getsta(Status_Reg *ptr, unsigned l) |
|
| 67 |
-{
|
|
| 68 |
- unsigned s = l << 2; |
|
| 69 |
- if (loaderwork.stateptr > loaderwork.state.size() || loaderwork.stateptr + s > loaderwork.state.size()) |
|
| 70 |
- return; |
|
| 71 |
- if (ptr) |
|
| 72 |
- for (unsigned i = 0; i < l; ++i) |
|
| 73 |
- {
|
|
| 74 |
- uint32_t st = Get32BitsLE(&loaderwork.state[loaderwork.stateptr + (i << 2)]); |
|
| 75 |
- ptr[i].bits.N = (st >> 31) & 1; |
|
| 76 |
- ptr[i].bits.Z = (st >> 30) & 1; |
|
| 77 |
- ptr[i].bits.C = (st >> 29) & 1; |
|
| 78 |
- ptr[i].bits.V = (st >> 28) & 1; |
|
| 79 |
- ptr[i].bits.Q = (st >> 27) & 1; |
|
| 80 |
- ptr[i].bits.RAZ = (st >> 8) & ((1 << 19) - 1); |
|
| 81 |
- ptr[i].bits.I = (st >> 7) & 1; |
|
| 82 |
- ptr[i].bits.F = (st >> 6) & 1; |
|
| 83 |
- ptr[i].bits.T = (st >> 5) & 1; |
|
| 84 |
- ptr[i].bits.mode = (st >> 0) & 0x1f; |
|
| 85 |
- } |
|
| 86 |
- loaderwork.stateptr += s; |
|
| 87 |
-} |
|
| 88 |
- |
|
| 89 |
-static void load_getbool(bool *ptr, unsigned l) |
|
| 90 |
-{
|
|
| 91 |
- unsigned s = l << 2; |
|
| 92 |
- if (loaderwork.stateptr > loaderwork.state.size() || loaderwork.stateptr + s > loaderwork.state.size()) |
|
| 93 |
- return; |
|
| 94 |
- if (ptr) |
|
| 95 |
- for (unsigned i = 0; i < l; ++i) |
|
| 96 |
- ptr[i] = !!Get32BitsLE(&loaderwork.state[loaderwork.stateptr + (i << 2)]); |
|
| 97 |
- loaderwork.stateptr += s; |
|
| 98 |
-} |
|
| 99 |
- |
|
| 100 |
-#ifdef SIGNED_IS_NOT_2S_COMPLEMENT |
|
| 101 |
-/* 2's complement */ |
|
| 102 |
-static inline int32_t u32tos32(uint32_t v) { return static_cast<int32_t>((static_cast<int64_t>(v) ^ 0x8000) - 0x8000); }
|
|
| 103 |
-#else |
|
| 104 |
-/* 2's complement */ |
|
| 105 |
-static inline int32_t u32tos32(uint32_t v) { return static_cast<int32_t>(v); }
|
|
| 106 |
-#endif |
|
| 107 |
- |
|
| 108 |
-static void load_gets32(int32_t *ptr, unsigned l) |
|
| 109 |
-{
|
|
| 110 |
- unsigned s = l << 2; |
|
| 111 |
- if (loaderwork.stateptr > loaderwork.state.size() || loaderwork.stateptr + s > loaderwork.state.size()) |
|
| 112 |
- return; |
|
| 113 |
- if (ptr) |
|
| 114 |
- for (unsigned i = 0; i < l; ++i) |
|
| 115 |
- ptr[i] = u32tos32(Get32BitsLE(&loaderwork.state[loaderwork.stateptr + (i << 2)])); |
|
| 116 |
- loaderwork.stateptr += s; |
|
| 117 |
-} |
|
| 118 |
- |
|
| 119 |
-static void load_getu32(uint32_t *ptr, unsigned l) |
|
| 120 |
-{
|
|
| 121 |
- unsigned s = l << 2; |
|
| 122 |
- if (loaderwork.stateptr > loaderwork.state.size() || loaderwork.stateptr + s > loaderwork.state.size()) |
|
| 123 |
- return; |
|
| 124 |
- if (ptr) |
|
| 125 |
- for (unsigned i = 0; i < l; ++i) |
|
| 126 |
- ptr[i] = Get32BitsLE(&loaderwork.state[loaderwork.stateptr + (i << 2)]); |
|
| 127 |
- loaderwork.stateptr += s; |
|
| 128 |
-} |
|
| 129 |
- |
|
| 130 |
-static void load_getu16(uint16_t *ptr, unsigned l) |
|
| 131 |
-{
|
|
| 132 |
- unsigned s = l << 1; |
|
| 133 |
- if (loaderwork.stateptr > loaderwork.state.size() || loaderwork.stateptr + s > loaderwork.state.size()) |
|
| 134 |
- return; |
|
| 135 |
- if (ptr) |
|
| 136 |
- for (unsigned i = 0; i < l; ++i) |
|
| 137 |
- ptr[i] = Get16BitsLE(&loaderwork.state[loaderwork.stateptr + (i << 1)]); |
|
| 138 |
- loaderwork.stateptr += s; |
|
| 139 |
-} |
|
| 140 |
- |
|
| 141 |
-static void load_getu8(uint8_t *ptr, unsigned l) |
|
| 142 |
-{
|
|
| 143 |
- unsigned s = l; |
|
| 144 |
- if (loaderwork.stateptr > loaderwork.state.size() || loaderwork.stateptr + s > loaderwork.state.size()) |
|
| 145 |
- return; |
|
| 146 |
- if (ptr) |
|
| 147 |
- for (unsigned i = 0; i < l; ++i) |
|
| 148 |
- ptr[i] = loaderwork.state[loaderwork.stateptr + i]; |
|
| 149 |
- loaderwork.stateptr += s; |
|
| 150 |
-} |
|
| 151 |
- |
|
| 152 |
-/*static void gdb_stub_fix(armcpu_t *armcpu) |
|
| 153 |
-{*/
|
|
| 154 |
- /* armcpu->R[15] = armcpu->instruct_adr; */ |
|
| 155 |
- /*armcpu->next_instruction = armcpu->instruct_adr; |
|
| 156 |
- if(armcpu->CPSR.bits.T == 0) |
|
| 157 |
- {
|
|
| 158 |
- armcpu->instruction = MMU_read32(armcpu->proc_ID, armcpu->next_instruction); |
|
| 159 |
- armcpu->instruct_adr = armcpu->next_instruction; |
|
| 160 |
- armcpu->next_instruction += 4; |
|
| 161 |
- armcpu->R[15] = armcpu->next_instruction + 4; |
|
| 162 |
- } |
|
| 163 |
- else |
|
| 164 |
- {
|
|
| 165 |
- armcpu->instruction = MMU_read16(armcpu->proc_ID, armcpu->next_instruction); |
|
| 166 |
- armcpu->instruct_adr = armcpu->next_instruction; |
|
| 167 |
- armcpu->next_instruction += 2; |
|
| 168 |
- armcpu->R[15] = armcpu->next_instruction + 2; |
|
| 169 |
- } |
|
| 170 |
-}*/ |
|
| 171 |
- |
|
| 172 |
-static void load_setstate() |
|
| 173 |
-{
|
|
| 174 |
- if (loaderwork.state.empty()) |
|
| 175 |
- return; |
|
| 176 |
- |
|
| 177 |
- //std::vector<uint8_t> savestate = std::vector<uint8_t>(&loaderwork.state[0], &loaderwork.state[loaderwork.state.size()]); |
|
| 178 |
- EMUFILE_MEMORY f(&loaderwork.state); |
|
| 179 |
- if (!savestate_load(&f)) |
|
| 180 |
- {
|
|
| 181 |
- //reset the emulator first to clean out the host's state |
|
| 182 |
- |
|
| 183 |
- //while the series of resets below should work, |
|
| 184 |
- //we are testing the robustness of the savestate system with this full reset. |
|
| 185 |
- //the full reset wipes more things, so we can make sure that they are being restored correctly |
|
| 186 |
- //extern bool _HACK_DONT_STOPMOVIE; |
|
| 187 |
- //_HACK_DONT_STOPMOVIE = true; |
|
| 188 |
- NDS_Reset(); |
|
| 189 |
- //_HACK_DONT_STOPMOVIE = false; |
|
| 190 |
- |
|
| 191 |
- //reset some options to their old defaults which werent saved |
|
| 192 |
- //nds.debugConsole = false; |
|
| 193 |
- |
|
| 194 |
- /* Skip over "Desmume Save File" crap */ |
|
| 195 |
- load_getstateinit(0x17); |
|
| 196 |
- |
|
| 197 |
- /* Read ARM7 cpu registers */ |
|
| 198 |
- //load_getu32(&NDS_ARM7.proc_ID, 1); |
|
| 199 |
- load_getu32(nullptr, 1); |
|
| 200 |
- load_getu32(&NDS_ARM7.instruction, 1); |
|
| 201 |
- load_getu32(&NDS_ARM7.instruct_adr, 1); |
|
| 202 |
- load_getu32(&NDS_ARM7.next_instruction, 1); |
|
| 203 |
- load_getu32(NDS_ARM7.R, 16); |
|
| 204 |
- load_getsta(&NDS_ARM7.CPSR, 1); |
|
| 205 |
- load_getsta(&NDS_ARM7.SPSR, 1); |
|
| 206 |
- load_getu32(&NDS_ARM7.R13_usr, 1); |
|
| 207 |
- load_getu32(&NDS_ARM7.R14_usr, 1); |
|
| 208 |
- load_getu32(&NDS_ARM7.R13_svc, 1); |
|
| 209 |
- load_getu32(&NDS_ARM7.R14_svc, 1); |
|
| 210 |
- load_getu32(&NDS_ARM7.R13_abt, 1); |
|
| 211 |
- load_getu32(&NDS_ARM7.R14_abt, 1); |
|
| 212 |
- load_getu32(&NDS_ARM7.R13_und, 1); |
|
| 213 |
- load_getu32(&NDS_ARM7.R14_und, 1); |
|
| 214 |
- load_getu32(&NDS_ARM7.R13_irq, 1); |
|
| 215 |
- load_getu32(&NDS_ARM7.R14_irq, 1); |
|
| 216 |
- load_getu32(&NDS_ARM7.R8_fiq, 1); |
|
| 217 |
- load_getu32(&NDS_ARM7.R9_fiq, 1); |
|
| 218 |
- load_getu32(&NDS_ARM7.R10_fiq, 1); |
|
| 219 |
- load_getu32(&NDS_ARM7.R11_fiq, 1); |
|
| 220 |
- load_getu32(&NDS_ARM7.R12_fiq, 1); |
|
| 221 |
- load_getu32(&NDS_ARM7.R13_fiq, 1); |
|
| 222 |
- load_getu32(&NDS_ARM7.R14_fiq, 1); |
|
| 223 |
- load_getsta(&NDS_ARM7.SPSR_svc, 1); |
|
| 224 |
- load_getsta(&NDS_ARM7.SPSR_abt, 1); |
|
| 225 |
- load_getsta(&NDS_ARM7.SPSR_und, 1); |
|
| 226 |
- load_getsta(&NDS_ARM7.SPSR_irq, 1); |
|
| 227 |
- load_getsta(&NDS_ARM7.SPSR_fiq, 1); |
|
| 228 |
- load_getu32(&NDS_ARM7.intVector, 1); |
|
| 229 |
- load_getu8(&NDS_ARM7.LDTBit, 1); |
|
| 230 |
- load_getbool(&NDS_ARM7.waitIRQ, 1); |
|
| 231 |
- bool tmpbool; |
|
| 232 |
- //load_getbool(&NDS_ARM7.wIRQ, 1); |
|
| 233 |
- //loaderwork.stateptr += 4; |
|
| 234 |
- load_getbool(nullptr, 1); |
|
| 235 |
- //load_getbool(&NDS_ARM7.halt_IE_and_IF, 1); |
|
| 236 |
- //load_getbool(&NDS_ARM7.wirq, 1); |
|
| 237 |
- //loaderwork.stateptr += 4; |
|
| 238 |
- //load_getbool(nullptr, 1); |
|
| 239 |
- //load_getbool(&NDS_ARM7.intrWaitARM_state, 1); |
|
| 240 |
- load_getbool(&tmpbool, 1); |
|
| 241 |
- //NDS_ARM7.intrWaitARM_state = tmpbool; |
|
| 242 |
- |
|
| 243 |
- /* Read ARM9 cpu registers */ |
|
| 244 |
- //load_getu32(&NDS_ARM9.proc_ID, 1); |
|
| 245 |
- load_getu32(nullptr, 1); |
|
| 246 |
- load_getu32(&NDS_ARM9.instruction, 1); |
|
| 247 |
- load_getu32(&NDS_ARM9.instruct_adr, 1); |
|
| 248 |
- load_getu32(&NDS_ARM9.next_instruction, 1); |
|
| 249 |
- load_getu32(NDS_ARM9.R, 16); |
|
| 250 |
- load_getsta(&NDS_ARM9.CPSR, 1); |
|
| 251 |
- load_getsta(&NDS_ARM9.SPSR, 1); |
|
| 252 |
- load_getu32(&NDS_ARM9.R13_usr, 1); |
|
| 253 |
- load_getu32(&NDS_ARM9.R14_usr, 1); |
|
| 254 |
- load_getu32(&NDS_ARM9.R13_svc, 1); |
|
| 255 |
- load_getu32(&NDS_ARM9.R14_svc, 1); |
|
| 256 |
- load_getu32(&NDS_ARM9.R13_abt, 1); |
|
| 257 |
- load_getu32(&NDS_ARM9.R14_abt, 1); |
|
| 258 |
- load_getu32(&NDS_ARM9.R13_und, 1); |
|
| 259 |
- load_getu32(&NDS_ARM9.R14_und, 1); |
|
| 260 |
- load_getu32(&NDS_ARM9.R13_irq, 1); |
|
| 261 |
- load_getu32(&NDS_ARM9.R14_irq, 1); |
|
| 262 |
- load_getu32(&NDS_ARM9.R8_fiq, 1); |
|
| 263 |
- load_getu32(&NDS_ARM9.R9_fiq, 1); |
|
| 264 |
- load_getu32(&NDS_ARM9.R10_fiq, 1); |
|
| 265 |
- load_getu32(&NDS_ARM9.R11_fiq, 1); |
|
| 266 |
- load_getu32(&NDS_ARM9.R12_fiq, 1); |
|
| 267 |
- load_getu32(&NDS_ARM9.R13_fiq, 1); |
|
| 268 |
- load_getu32(&NDS_ARM9.R14_fiq, 1); |
|
| 269 |
- load_getsta(&NDS_ARM9.SPSR_svc, 1); |
|
| 270 |
- load_getsta(&NDS_ARM9.SPSR_abt, 1); |
|
| 271 |
- load_getsta(&NDS_ARM9.SPSR_und, 1); |
|
| 272 |
- load_getsta(&NDS_ARM9.SPSR_irq, 1); |
|
| 273 |
- load_getsta(&NDS_ARM9.SPSR_fiq, 1); |
|
| 274 |
- load_getu32(&NDS_ARM9.intVector, 1); |
|
| 275 |
- load_getu8(&NDS_ARM9.LDTBit, 1); |
|
| 276 |
- load_getbool(&NDS_ARM9.waitIRQ, 1); |
|
| 277 |
- //load_getbool(&NDS_ARM9.wIRQ, 1); |
|
| 278 |
- //loaderwork.stateptr += 4; |
|
| 279 |
- load_getbool(nullptr, 1); |
|
| 280 |
- //load_getbool(&NDS_ARM9.halt_IE_and_IF, 1); |
|
| 281 |
- //load_getbool(&NDS_ARM9.wirq, 1); |
|
| 282 |
- //loaderwork.stateptr += 4; |
|
| 283 |
- //load_getbool(nullptr, 1); |
|
| 284 |
- //load_getbool(&NDS_ARM9.intrWaitARM_state, 1); |
|
| 285 |
- load_getbool(&tmpbool, 1); |
|
| 286 |
- //NDS_ARM9.intrWaitARM_state = tmpbool; |
|
| 287 |
- |
|
| 288 |
- /* Read in other internal variables that are important */ |
|
| 289 |
- //int32_t tmps32; |
|
| 290 |
- //load_gets32(&nds.ARM9Cycle, 1); |
|
| 291 |
- load_gets32(nullptr, 1); |
|
| 292 |
- //load_gets32(&nds.ARM7Cycle, 1); |
|
| 293 |
- load_gets32(nullptr, 1); |
|
| 294 |
- load_gets32(&nds.cycles, 1); |
|
| 295 |
- int32_t tmps32_array[4]; |
|
| 296 |
- //load_getu64(nds.timerCycle[0], 4); |
|
| 297 |
- load_gets32(tmps32_array, 4); |
|
| 298 |
- for (int i = 0; i < 4; ++i) |
|
| 299 |
- nds.timerCycle[0][i] = tmps32_array[i]; |
|
| 300 |
- //load_getu64(nds.timerCycle[1], 4); |
|
| 301 |
- load_gets32(tmps32_array, 4); |
|
| 302 |
- for (int i = 0; i < 4; ++i) |
|
| 303 |
- nds.timerCycle[1][i] = tmps32_array[i]; |
|
| 304 |
- //bool tmpbool_array[4]; |
|
| 305 |
- //load_getbool(nds.timerOver[0], 4); |
|
| 306 |
- //loaderwork.stateptr += 16; |
|
| 307 |
- load_getbool(nullptr, 4); |
|
| 308 |
- //load_getbool(nds.timerOver[1], 4); |
|
| 309 |
- //loaderwork.stateptr += 16; |
|
| 310 |
- load_getbool(nullptr, 4); |
|
| 311 |
- //load_gets32(&nds.nextHBlank, 1); |
|
| 312 |
- //loaderwork.stateptr += 4; |
|
| 313 |
- load_gets32(nullptr, 1); |
|
| 314 |
- load_getu32(&nds.VCount, 1); |
|
| 315 |
- load_getu32(&nds.old, 1); |
|
| 316 |
- //load_gets32(&nds.diff, 1); |
|
| 317 |
- //loaderwork.stateptr += 4; |
|
| 318 |
- load_gets32(nullptr, 1); |
|
| 319 |
- //load_getbool(&nds.lignerendu, 1); |
|
| 320 |
- //loaderwork.stateptr += 4; |
|
| 321 |
- load_getbool(nullptr, 1); |
|
| 322 |
- load_getu16(nullptr, 1); |
|
| 323 |
- load_getu16(nullptr, 1); |
|
| 324 |
- |
|
| 325 |
- /* Read in memory/registers specific to the ARM9 */ |
|
| 326 |
- //load_getu8 (MMU.ARM9_ITCM, 0x8000); |
|
| 327 |
- load_getu8(nullptr, 0x8000); |
|
| 328 |
- load_getu8 (MMU.ARM9_DTCM, 0x4000); |
|
| 329 |
- //load_getu8 (MMU.MAIN_MEM, 0x1000000); |
|
| 330 |
- //load_getu8(MMU.MAIN_MEM, 0x800000); |
|
| 331 |
- //load_getu8(nullptr, 0x800000); |
|
| 332 |
- //load_getu8(nullptr, 0x1000000); |
|
| 333 |
- load_getu8(nullptr, 0xFF8000); |
|
| 334 |
- load_getu8(MMU.ARM9_ITCM, 0x8000); |
|
| 335 |
- load_getu8 (MMU.MAIN_MEM/*+0x400000*/, 0x400000); |
|
| 336 |
- load_getu8 (MMU.ARM9_REG, 0x10000); |
|
| 337 |
- load_getu8 (MMU.ARM9_VMEM, 0x800); |
|
| 338 |
- load_getu8 (MMU.ARM9_OAM, 0x800); |
|
| 339 |
- //uint8_t tmpu8_ABG[0x80000]; |
|
| 340 |
- //load_getu8 (ARM9Mem.ARM9_ABG, 0x80000); |
|
| 341 |
- //loaderwork.stateptr += 0x80000; |
|
| 342 |
- load_getu8(nullptr, 0x80000); |
|
| 343 |
- //uint8_t tmpu8_BBG[0x20000]; |
|
| 344 |
- //load_getu8 (ARM9Mem.ARM9_BBG, 0x20000); |
|
| 345 |
- //loaderwork.stateptr += 0x20000; |
|
| 346 |
- load_getu8(nullptr, 0x20000); |
|
| 347 |
- //uint8_t tmpu8_AOBJ[0x40000]; |
|
| 348 |
- //load_getu8 (ARM9Mem.ARM9_AOBJ, 0x40000); |
|
| 349 |
- //loaderwork.stateptr += 0x40000; |
|
| 350 |
- load_getu8(nullptr, 0x40000); |
|
| 351 |
- //uint8_t tmpu8_BOBJ[0x20000]; |
|
| 352 |
- //load_getu8 (ARM9Mem.ARM9_BOBJ, 0x20000); |
|
| 353 |
- //loaderwork.stateptr += 0x20000; |
|
| 354 |
- load_getu8(nullptr, 0x20000); |
|
| 355 |
- load_getu8 (MMU.ARM9_LCD, 0xA4000); |
|
| 356 |
- //loaderwork.stateptr += 12; |
|
| 357 |
- |
|
| 358 |
- /* Read in memory/registers specific to the ARM7 */ |
|
| 359 |
- load_getu8 (MMU.ARM7_ERAM, 0x10000); |
|
| 360 |
- load_getu8 (MMU.ARM7_REG, 0x10000); |
|
| 361 |
- load_getu8 (MMU.ARM7_WIRAM, 0x10000); |
|
| 362 |
- |
|
| 363 |
- /* Read in shared memory */ |
|
| 364 |
- load_getu8 (MMU.SWIRAM, 0x8000); |
|
| 365 |
- |
|
| 366 |
- //gdb_stub_fix(&NDS_ARM9); |
|
| 367 |
- //gdb_stub_fix(&NDS_ARM7); |
|
| 368 |
- |
|
| 369 |
- loadstate(); |
|
| 370 |
- } |
|
| 371 |
-} |
|
| 372 |
- |
|
| 373 | 56 |
static struct |
| 374 | 57 |
{
|
| 375 | 58 |
std::vector<uint8_t> buf; |
| ... | ... |
@@ -432,71 +115,44 @@ SoundInterface_struct *SNDCoreList[] = |
| 432 | 115 |
nullptr |
| 433 | 116 |
}; |
| 434 | 117 |
|
| 435 |
-static void Map2SFSection(const std::vector<uint8_t> §ion, bool isSave) |
|
| 118 |
+void XSFPlayer_2SF::Map2SFSection(const std::vector<uint8_t> §ion) |
|
| 436 | 119 |
{
|
| 437 |
- auto &data = isSave ? loaderwork.state : loaderwork.rom; |
|
| 438 |
- |
|
| 439 | 120 |
uint32_t offset = Get32BitsLE(§ion[0]), size = Get32BitsLE(§ion[4]), finalSize = size + offset; |
| 440 |
- if (!isSave) |
|
| 441 |
- finalSize = NextHighestPowerOf2(finalSize); |
|
| 442 |
- if (data.empty()) |
|
| 443 |
- data.resize(finalSize + 10, 0); |
|
| 444 |
- else if (data.size() < size + offset) |
|
| 445 |
- data.resize(offset + finalSize + 10); |
|
| 446 |
- memcpy(&data[offset], §ion[8], size); |
|
| 121 |
+ finalSize = NextHighestPowerOf2(finalSize); |
|
| 122 |
+ if (this->rom.empty()) |
|
| 123 |
+ this->rom.resize(finalSize + 10, 0); |
|
| 124 |
+ else if (this->rom.size() < size + offset) |
|
| 125 |
+ this->rom.resize(offset + finalSize + 10); |
|
| 126 |
+ memcpy(&this->rom[offset], §ion[8], size); |
|
| 447 | 127 |
} |
| 448 | 128 |
|
| 449 |
-static bool Map2SF(XSFFile *xSF) |
|
| 129 |
+bool XSFPlayer_2SF::Map2SF(XSFFile *xSFToLoad) |
|
| 450 | 130 |
{
|
| 451 |
- if (!xSF->IsValidType(0x24)) |
|
| 131 |
+ if (!xSFToLoad->IsValidType(0x24)) |
|
| 452 | 132 |
return false; |
| 453 | 133 |
|
| 454 |
- auto &reservedSection = xSF->GetReservedSection(), &programSection = xSF->GetProgramSection(); |
|
| 455 |
- |
|
| 456 |
- if (!reservedSection.empty()) |
|
| 457 |
- {
|
|
| 458 |
- size_t reservedPosition = 0, reservedSize = reservedSection.size(); |
|
| 459 |
- while (reservedPosition + 12 < reservedSize) |
|
| 460 |
- {
|
|
| 461 |
- uint32_t saveSize = Get32BitsLE(&reservedSection[reservedPosition + 4]); |
|
| 462 |
- if (Get32BitsLE(&reservedSection[reservedPosition]) == 0x45564153) // "SAVE" |
|
| 463 |
- {
|
|
| 464 |
- if (reservedPosition + 12 + saveSize > reservedSize) |
|
| 465 |
- return false; |
|
| 466 |
- |
|
| 467 |
- uint8_t tmpSaveUncompressed[8]; |
|
| 468 |
- unsigned long saveUncompressedSize = 8; |
|
| 469 |
- uncompress(tmpSaveUncompressed, &saveUncompressedSize, &reservedSection[reservedPosition + 12], saveSize); |
|
| 470 |
- saveUncompressedSize = Get32BitsLE(&tmpSaveUncompressed[4]) + 8; |
|
| 471 |
- auto saveUncompressed = std::vector<uint8_t>(saveUncompressedSize); |
|
| 472 |
- uncompress(&saveUncompressed[0], &saveUncompressedSize, &reservedSection[reservedPosition + 12], saveSize); |
|
| 473 |
- |
|
| 474 |
- Map2SFSection(saveUncompressed, true); |
|
| 475 |
- } |
|
| 476 |
- reservedPosition += saveSize + 12; |
|
| 477 |
- } |
|
| 478 |
- } |
|
| 134 |
+ const auto &programSection = xSFToLoad->GetProgramSection(); |
|
| 479 | 135 |
|
| 480 | 136 |
if (!programSection.empty()) |
| 481 |
- Map2SFSection(programSection, false); |
|
| 137 |
+ this->Map2SFSection(programSection); |
|
| 482 | 138 |
|
| 483 | 139 |
return true; |
| 484 | 140 |
} |
| 485 | 141 |
|
| 486 |
-static bool RecursiveLoad2SF(XSFFile *xSF, int level) |
|
| 142 |
+bool XSFPlayer_2SF::RecursiveLoad2SF(XSFFile *xSFToLoad, int level) |
|
| 487 | 143 |
{
|
| 488 |
- if (level <= 10 && xSF->GetTagExists("_lib"))
|
|
| 144 |
+ if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
|
|
| 489 | 145 |
{
|
| 490 | 146 |
#ifdef _WIN32 |
| 491 |
- auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue("_lib").GetWStr(), 4, 8));
|
|
| 147 |
+ auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 4, 8));
|
|
| 492 | 148 |
#else |
| 493 |
- auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue("_lib").GetAnsi(), 4, 8));
|
|
| 149 |
+ auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 4, 8));
|
|
| 494 | 150 |
#endif |
| 495 |
- if (!RecursiveLoad2SF(libxSF.get(), level + 1)) |
|
| 151 |
+ if (!this->RecursiveLoad2SF(libxSF.get(), level + 1)) |
|
| 496 | 152 |
return false; |
| 497 | 153 |
} |
| 498 | 154 |
|
| 499 |
- if (!Map2SF(xSF)) |
|
| 155 |
+ if (!this->Map2SF(xSFToLoad)) |
|
| 500 | 156 |
return false; |
| 501 | 157 |
|
| 502 | 158 |
unsigned n = 2; |
| ... | ... |
@@ -505,15 +161,15 @@ static bool RecursiveLoad2SF(XSFFile *xSF, int level) |
| 505 | 161 |
{
|
| 506 | 162 |
found = false; |
| 507 | 163 |
std::string libTag = "_lib" + stringify(n++); |
| 508 |
- if (xSF->GetTagExists(libTag)) |
|
| 164 |
+ if (xSFToLoad->GetTagExists(libTag)) |
|
| 509 | 165 |
{
|
| 510 | 166 |
found = true; |
| 511 | 167 |
#ifdef _WIN32 |
| 512 |
- auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue(libTag).GetWStr(), 4, 8)); |
|
| 168 |
+ auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 4, 8)); |
|
| 513 | 169 |
#else |
| 514 |
- auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue(libTag).GetAnsi(), 4, 8)); |
|
| 170 |
+ auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 4, 8)); |
|
| 515 | 171 |
#endif |
| 516 |
- if (!RecursiveLoad2SF(libxSF.get(), level + 1)) |
|
| 172 |
+ if (!this->RecursiveLoad2SF(libxSF.get(), level + 1)) |
|
| 517 | 173 |
return false; |
| 518 | 174 |
} |
| 519 | 175 |
} while (found); |
| ... | ... |
@@ -521,13 +177,11 @@ static bool RecursiveLoad2SF(XSFFile *xSF, int level) |
| 521 | 177 |
return true; |
| 522 | 178 |
} |
| 523 | 179 |
|
| 524 |
-static bool Load2SF(XSFFile *xSF) |
|
| 180 |
+bool XSFPlayer_2SF::Load2SF(XSFFile *xSFToLoad) |
|
| 525 | 181 |
{
|
| 526 |
- loaderwork.rom.clear(); |
|
| 527 |
- loaderwork.state.clear(); |
|
| 528 |
- loaderwork.stateptr = 0; |
|
| 182 |
+ this->rom.clear(); |
|
| 529 | 183 |
|
| 530 |
- return RecursiveLoad2SF(xSF, 1); |
|
| 184 |
+ return this->RecursiveLoad2SF(xSFToLoad, 1); |
|
| 531 | 185 |
} |
| 532 | 186 |
|
| 533 | 187 |
XSFPlayer_2SF::XSFPlayer_2SF(const std::string &filename) : XSFPlayer() |
| ... | ... |
@@ -542,11 +196,11 @@ XSFPlayer_2SF::XSFPlayer_2SF(const std::wstring &filename) : XSFPlayer() |
| 542 | 196 |
|
| 543 | 197 |
bool XSFPlayer_2SF::Load() |
| 544 | 198 |
{
|
| 545 |
- int frames = xSF->GetTagValue("_frames", -1);
|
|
| 546 |
- sndifwork.sync_type = xSF->GetTagValue("_2sf_sync_type", 0);
|
|
| 199 |
+ int frames = this->xSF->GetTagValue("_frames", -1);
|
|
| 200 |
+ sndifwork.sync_type = this->xSF->GetTagValue("_2sf_sync_type", 0);
|
|
| 547 | 201 |
|
| 548 | 202 |
sndifwork.xfs_load = false; |
| 549 |
- if (!Load2SF(this->xSF)) |
|
| 203 |
+ if (!this->Load2SF(this->xSF)) |
|
| 550 | 204 |
return false; |
| 551 | 205 |
|
| 552 | 206 |
if (NDS_Init()) |
| ... | ... |
@@ -557,103 +211,23 @@ bool XSFPlayer_2SF::Load() |
| 557 | 211 |
execute = false; |
| 558 | 212 |
|
| 559 | 213 |
MMU_unsetRom(); |
| 560 |
- if (!loaderwork.rom.empty()) |
|
| 214 |
+ if (!this->rom.empty()) |
|
| 561 | 215 |
{
|
| 562 |
- NDS_SetROM(&loaderwork.rom[0], loaderwork.rom.size() - 1); |
|
| 563 |
- gameInfo.loadData(reinterpret_cast<char *>(&loaderwork.rom[0]), loaderwork.rom.size() - 1); |
|
| 216 |
+ NDS_SetROM(&this->rom[0], this->rom.size() - 1); |
|
| 217 |
+ gameInfo.loadData(reinterpret_cast<char *>(&this->rom[0]), this->rom.size() - 1); |
|
| 564 | 218 |
} |
| 565 | 219 |
|
| 566 | 220 |
NDS_Reset(); |
| 567 | 221 |
|
| 568 | 222 |
execute = true; |
| 569 | 223 |
|
| 570 |
- if (!loaderwork.state.empty()) |
|
| 571 |
- {
|
|
| 572 |
- armcp15_t *c9 = reinterpret_cast<armcp15_t *>(NDS_ARM9.coproc[15]); |
|
| 573 |
- //int proc; |
|
| 574 |
- if (frames == -1) |
|
| 575 |
- {
|
|
| 576 |
- /* set initial ARM9 coprocessor state */ |
|
| 577 |
- |
|
| 578 |
- armcp15_moveARM2CP(c9, 0x00000000, 0x01, 0x00, 0, 0); |
|
| 579 |
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x05, 0, 0); |
|
| 580 |
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x06, 0, 0); |
|
| 581 |
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4); |
|
| 582 |
- armcp15_moveARM2CP(c9, 0x04000033, 0x06, 0x00, 0, 4); |
|
| 583 |
- armcp15_moveARM2CP(c9, 0x0200002d, 0x06, 0x01, 0, 0); |
|
| 584 |
- armcp15_moveARM2CP(c9, 0x027e0021, 0x06, 0x02, 0, 0); |
|
| 585 |
- armcp15_moveARM2CP(c9, 0x08000035, 0x06, 0x03, 0, 0); |
|
| 586 |
- armcp15_moveARM2CP(c9, 0x027e001b, 0x06, 0x04, 0, 0); |
|
| 587 |
- armcp15_moveARM2CP(c9, 0x0100002f, 0x06, 0x05, 0, 0); |
|
| 588 |
- armcp15_moveARM2CP(c9, 0xffff001d, 0x06, 0x06, 0, 0); |
|
| 589 |
- armcp15_moveARM2CP(c9, 0x027ff017, 0x06, 0x07, 0, 0); |
|
| 590 |
- armcp15_moveARM2CP(c9, 0x00000020, 0x09, 0x01, 0, 1); |
|
| 591 |
- |
|
| 592 |
- armcp15_moveARM2CP(c9, 0x027e000a, 0x09, 0x01, 0, 0); |
|
| 593 |
- |
|
| 594 |
- armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 1); |
|
| 595 |
- armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 0); |
|
| 596 |
- armcp15_moveARM2CP(c9, 0x00000002, 0x03, 0x00, 0, 0); |
|
| 597 |
- armcp15_moveARM2CP(c9, 0x05100011, 0x05, 0x00, 0, 3); |
|
| 598 |
- armcp15_moveARM2CP(c9, 0x15111011, 0x05, 0x00, 0, 2); |
|
| 599 |
- armcp15_moveARM2CP(c9, 0x07dd1e10, 0x01, 0x00, 0, 0); |
|
| 600 |
- armcp15_moveARM2CP(c9, 0x0005707d, 0x01, 0x00, 0, 0); |
|
| 601 |
- |
|
| 602 |
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4); |
|
| 603 |
- armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x05, 0, 1); |
|
| 604 |
- armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x0e, 0, 1); |
|
| 605 |
- |
|
| 606 |
- /* set initial timer state */ |
|
| 607 |
- |
|
| 608 |
- /*MMU_write16(0, REG_TM0CNTL, 0x0000); |
|
| 609 |
- MMU_write16(0, REG_TM0CNTH, 0x00C1); |
|
| 610 |
- MMU_write16(1, REG_TM0CNTL, 0x0000); |
|
| 611 |
- MMU_write16(1, REG_TM0CNTH, 0x00C1); |
|
| 612 |
- MMU_write16(1, REG_TM1CNTL, 0xf7e7); |
|
| 613 |
- MMU_write16(1, REG_TM1CNTH, 0x00C1);*/ |
|
| 614 |
- |
|
| 615 |
- /* set initial interrupt state */ |
|
| 616 |
- |
|
| 617 |
- MMU.reg_IME[0] = 0x00000001; |
|
| 618 |
- MMU.reg_IE[0] = 0x00042001; |
|
| 619 |
- MMU.reg_IME[1] = 0x00000001; |
|
| 620 |
- MMU.reg_IE[1] = 0x0104009d; |
|
| 621 |
- } |
|
| 622 |
- else if (frames > 0) |
|
| 623 |
- {
|
|
| 624 |
- /* execute boot code */ |
|
| 625 |
- for (int i = 0; i < frames; ++i) |
|
| 626 |
- NDS_exec<true>(); |
|
| 627 |
- } |
|
| 628 |
- |
|
| 629 |
- /* load state */ |
|
| 630 |
- |
|
| 631 |
- execute = false; |
|
| 632 |
- SPU_Reset(); |
|
| 633 |
- |
|
| 634 |
- load_setstate(); |
|
| 635 |
- loaderwork.state.clear(); |
|
| 636 |
- |
|
| 637 |
- if (frames == -1) |
|
| 638 |
- armcp15_moveARM2CP(c9, (NDS_ARM9.R13_irq & 0x0fff0000) | 0x0a, 0x09, 0x01, 0, 0); |
|
| 639 |
- |
|
| 640 |
- /* restore timer state */ |
|
| 641 |
- |
|
| 642 |
- /*for (proc = 0; proc < 2; proc++) |
|
| 643 |
- {
|
|
| 644 |
- MMU_write16(proc, REG_TM0CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM0CNTH & 0xFFF)); |
|
| 645 |
- MMU_write16(proc, REG_TM1CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM1CNTH & 0xFFF)); |
|
| 646 |
- MMU_write16(proc, REG_TM2CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM2CNTH & 0xFFF)); |
|
| 647 |
- MMU_write16(proc, REG_TM3CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM3CNTH & 0xFFF)); |
|
| 648 |
- }*/ |
|
| 649 |
- } |
|
| 650 |
- else if (frames > 0) |
|
| 224 |
+ if (frames > 0) |
|
| 651 | 225 |
{
|
| 652 | 226 |
/* skip 1 sec */ |
| 653 | 227 |
for (int i = 0; i < frames; ++i) |
| 654 | 228 |
NDS_exec<false>(); |
| 655 | 229 |
} |
| 656 |
- execute = true; |
|
| 230 |
+ |
|
| 657 | 231 |
sndifwork.xfs_load = true; |
| 658 | 232 |
//CommonSettings.spu_advanced = true; |
| 659 | 233 |
//CommonSettings.advanced_timing = false; |
| ... | ... |
@@ -728,7 +302,5 @@ void XSFPlayer_2SF::Terminate() |
| 728 | 302 |
MMU_unsetRom(); |
| 729 | 303 |
NDS_DeInit(); |
| 730 | 304 |
|
| 731 |
- loaderwork.rom.clear(); |
|
| 732 |
- loaderwork.state.clear(); |
|
| 733 |
- loaderwork.stateptr = 0; |
|
| 305 |
+ this->rom.clear(); |
|
| 734 | 306 |
} |
| ... | ... |
@@ -356,7 +356,11 @@ static void count(u32 opcode, int cond_res) |
| 356 | 356 |
EMIT2(and, KONST(0x1F), ecx) |
| 357 | 357 |
#define VALUE_LOAD_REG \ |
| 358 | 358 |
EMIT2(and, KONST(0x0F), eax) \ |
| 359 |
+ EMIT2(cmp, KONST(0x0F), eax) \ |
|
| 359 | 360 |
EMIT2(mov, REGREF2(eax,4), eax) \ |
| 361 |
+ EMIT1(jne, LABELREF(3,f)) \ |
|
| 362 |
+ EMIT2(add, KONST(4), eax) \ |
|
| 363 |
+ LABEL(3) \ |
|
| 360 | 364 |
EMIT2(movzx, ch, ecx) \ |
| 361 | 365 |
EMIT2(and, KONST(0x0F), ecx) \ |
| 362 | 366 |
EMIT2(mov, REGREF2(ecx,4), ecx) |
| ... | ... |
@@ -753,13 +757,17 @@ static void count(u32 opcode, int cond_res) |
| 753 | 757 |
// OP Rd,Rb,Rm LSL Rs |
| 754 | 758 |
#ifndef VALUE_LSL_REG_C |
| 755 | 759 |
#define VALUE_LSL_REG_C \ |
| 756 |
- unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ |
|
| 760 |
+ u32 shift = reg[(opcode >> 8)&15].B.B0; \ |
|
| 761 |
+ u32 rm = reg[opcode & 0x0F].I; \ |
|
| 762 |
+ if((opcode & 0x0F) == 15) { \
|
|
| 763 |
+ rm += 4; \ |
|
| 764 |
+ } \ |
|
| 757 | 765 |
if (LIKELY(shift)) { \
|
| 758 | 766 |
if (shift == 32) { \
|
| 759 | 767 |
value = 0; \ |
| 760 |
- C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\ |
|
| 768 |
+ C_OUT = (rm & 1 ? true : false); \ |
|
| 761 | 769 |
} else if (LIKELY(shift < 32)) { \
|
| 762 |
- u32 v = reg[opcode & 0x0F].I; \ |
|
| 770 |
+ u32 v = rm; \ |
|
| 763 | 771 |
C_OUT = (v >> (32 - shift)) & 1 ? true : false;\ |
| 764 | 772 |
value = v << shift; \ |
| 765 | 773 |
} else { \
|
| ... | ... |
@@ -767,13 +775,13 @@ static void count(u32 opcode, int cond_res) |
| 767 | 775 |
C_OUT = false; \ |
| 768 | 776 |
} \ |
| 769 | 777 |
} else { \
|
| 770 |
- value = reg[opcode & 0x0F].I; \ |
|
| 778 |
+ value = rm; \ |
|
| 771 | 779 |
} |
| 772 | 780 |
#endif |
| 773 | 781 |
// OP Rd,Rb,Rm LSR # |
| 774 | 782 |
#ifndef VALUE_LSR_IMM_C |
| 775 | 783 |
#define VALUE_LSR_IMM_C \ |
| 776 |
- unsigned int shift = (opcode >> 7) & 0x1F; \ |
|
| 784 |
+ u32 shift = (opcode >> 7) & 0x1F; \ |
|
| 777 | 785 |
if (LIKELY(shift)) { \
|
| 778 | 786 |
u32 v = reg[opcode & 0x0F].I; \ |
| 779 | 787 |
C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ |
| ... | ... |
@@ -787,12 +795,16 @@ static void count(u32 opcode, int cond_res) |
| 787 | 795 |
#ifndef VALUE_LSR_REG_C |
| 788 | 796 |
#define VALUE_LSR_REG_C \ |
| 789 | 797 |
unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ |
| 798 |
+ u32 rm = reg[opcode & 0x0F].I; \ |
|
| 799 |
+ if((opcode & 0x0F) == 15) { \
|
|
| 800 |
+ rm += 4; \ |
|
| 801 |
+ } \ |
|
| 790 | 802 |
if (LIKELY(shift)) { \
|
| 791 | 803 |
if (shift == 32) { \
|
| 792 | 804 |
value = 0; \ |
| 793 |
- C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\ |
|
| 805 |
+ C_OUT = (rm & 0x80000000 ? true : false);\ |
|
| 794 | 806 |
} else if (LIKELY(shift < 32)) { \
|
| 795 |
- u32 v = reg[opcode & 0x0F].I; \ |
|
| 807 |
+ u32 v = rm; \ |
|
| 796 | 808 |
C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ |
| 797 | 809 |
value = v >> shift; \ |
| 798 | 810 |
} else { \
|
| ... | ... |
@@ -800,7 +812,7 @@ static void count(u32 opcode, int cond_res) |
| 800 | 812 |
C_OUT = false; \ |
| 801 | 813 |
} \ |
| 802 | 814 |
} else { \
|
| 803 |
- value = reg[opcode & 0x0F].I; \ |
|
| 815 |
+ value = rm; \ |
|
| 804 | 816 |
} |
| 805 | 817 |
#endif |
| 806 | 818 |
// OP Rd,Rb,Rm ASR # |
| ... | ... |
@@ -826,13 +838,17 @@ static void count(u32 opcode, int cond_res) |
| 826 | 838 |
#ifndef VALUE_ASR_REG_C |
| 827 | 839 |
#define VALUE_ASR_REG_C \ |
| 828 | 840 |
unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ |
| 841 |
+ u32 rm = reg[opcode & 0x0F].I; \ |
|
| 842 |
+ if((opcode & 0x0F) == 15) { \
|
|
| 843 |
+ rm += 4; \ |
|
| 844 |
+ } \ |
|
| 829 | 845 |
if (LIKELY(shift < 32)) { \
|
| 830 | 846 |
if (LIKELY(shift)) { \
|
| 831 |
- s32 v = reg[opcode & 0x0F].I; \ |
|
| 847 |
+ s32 v = rm; \ |
|
| 832 | 848 |
C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false;\ |
| 833 | 849 |
value = v >> (int)shift; \ |
| 834 | 850 |
} else { \
|
| 835 |
- value = reg[opcode & 0x0F].I; \ |
|
| 851 |
+ value = rm; \ |
|
| 836 | 852 |
} \ |
| 837 | 853 |
} else { \
|
| 838 | 854 |
if (reg[opcode & 0x0F].I & 0x80000000) { \
|
| ... | ... |
@@ -864,13 +880,17 @@ static void count(u32 opcode, int cond_res) |
| 864 | 880 |
#ifndef VALUE_ROR_REG_C |
| 865 | 881 |
#define VALUE_ROR_REG_C \ |
| 866 | 882 |
unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ |
| 883 |
+ u32 rm = reg[opcode & 0x0F].I; \ |
|
| 884 |
+ if((opcode & 0x0F) == 15) { \
|
|
| 885 |
+ rm += 4; \ |
|
| 886 |
+ } \ |
|
| 867 | 887 |
if (LIKELY(shift & 0x1F)) { \
|
| 868 |
- u32 v = reg[opcode & 0x0F].I; \ |
|
| 888 |
+ u32 v = rm; \ |
|
| 869 | 889 |
C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ |
| 870 | 890 |
value = ((v << (32 - shift)) | \ |
| 871 | 891 |
(v >> shift)); \ |
| 872 | 892 |
} else { \
|
| 873 |
- value = reg[opcode & 0x0F].I; \ |
|
| 893 |
+ value = rm; \ |
|
| 874 | 894 |
if (shift) \ |
| 875 | 895 |
C_OUT = (value & 0x80000000 ? true : false);\ |
| 876 | 896 |
} |
| ... | ... |
@@ -951,9 +971,9 @@ static void count(u32 opcode, int cond_res) |
| 951 | 971 |
#endif |
| 952 | 972 |
#ifndef OP_RSB |
| 953 | 973 |
#define OP_RSB \ |
| 954 |
- u32 lhs = reg[(opcode>>16)&15].I; \ |
|
| 955 |
- u32 rhs = value; \ |
|
| 956 |
- u32 res = rhs - lhs; \ |
|
| 974 |
+ u32 lhs = value; \ |
|
| 975 |
+ u32 rhs = reg[(opcode>>16)&15].I; \ |
|
| 976 |
+ u32 res = lhs - rhs; \ |
|
| 957 | 977 |
reg[dest].I = res; |
| 958 | 978 |
#endif |
| 959 | 979 |
#ifndef OP_RSBS |
| ... | ... |
@@ -991,9 +1011,9 @@ static void count(u32 opcode, int cond_res) |
| 991 | 1011 |
#endif |
| 992 | 1012 |
#ifndef OP_RSC |
| 993 | 1013 |
#define OP_RSC \ |
| 994 |
- u32 lhs = reg[(opcode>>16)&15].I; \ |
|
| 995 |
- u32 rhs = value; \ |
|
| 996 |
- u32 res = rhs - lhs - !((u32)C_FLAG); \ |
|
| 1014 |
+ u32 lhs = value; \ |
|
| 1015 |
+ u32 rhs = reg[(opcode>>16)&15].I; \ |
|
| 1016 |
+ u32 res = lhs - rhs - !((u32)C_FLAG); \ |
|
| 997 | 1017 |
reg[dest].I = res; |
| 998 | 1018 |
#endif |
| 999 | 1019 |
#ifndef OP_RSCS |
| ... | ... |
@@ -1517,7 +1537,7 @@ static INSN_REGPARM void arm121(u32 opcode) |
| 1517 | 1537 |
#define OP_LDR reg[dest].I = CPUReadMemory(address) |
| 1518 | 1538 |
#define OP_LDRH reg[dest].I = CPUReadHalfWord(address) |
| 1519 | 1539 |
#define OP_LDRB reg[dest].I = CPUReadByte(address) |
| 1520 |
-#define OP_LDRSH reg[dest].I = (s16)CPUReadHalfWordSigned(address) |
|
| 1540 |
+#define OP_LDRSH reg[dest].I = (u32)CPUReadHalfWordSigned(address) |
|
| 1521 | 1541 |
#define OP_LDRSB reg[dest].I = (s8)CPUReadByte(address) |
| 1522 | 1542 |
|
| 1523 | 1543 |
#define WRITEBACK_NONE /*nothing*/ |
| ... | ... |
@@ -2592,8 +2612,7 @@ static INSN_REGPARM void armA00(u32 opcode) |
| 2592 | 2612 |
reg[15].I += 4; |
| 2593 | 2613 |
ARM_PREFETCH; |
| 2594 | 2614 |
clockTicks = codeTicksAccessSeq32(armNextPC) + 1; |
| 2595 |
- clockTicks += 2 + codeTicksAccess32(armNextPC) |
|
| 2596 |
- + codeTicksAccessSeq32(armNextPC); |
|
| 2615 |
+ clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1; |
|
| 2597 | 2616 |
busPrefetchCount = 0; |
| 2598 | 2617 |
} |
| 2599 | 2618 |
|
| ... | ... |
@@ -2629,8 +2648,7 @@ static INSN_REGPARM void armE01(u32 opcode) |
| 2629 | 2648 |
static INSN_REGPARM void armF00(u32 opcode) |
| 2630 | 2649 |
{
|
| 2631 | 2650 |
clockTicks = codeTicksAccessSeq32(armNextPC) + 1; |
| 2632 |
- clockTicks += 2 + codeTicksAccess32(armNextPC) |
|
| 2633 |
- + codeTicksAccessSeq32(armNextPC); |
|
| 2651 |
+ clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1; |
|
| 2634 | 2652 |
busPrefetchCount = 0; |
| 2635 | 2653 |
CPUSoftwareInterrupt(opcode & 0x00FFFFFF); |
| 2636 | 2654 |
} |
| ... | ... |
@@ -2682,9 +2700,9 @@ static insnfunc_t armInsnTable[4096] = {
|
| 2682 | 2700 |
arm0D0,arm0D1,arm0D2,arm0D3,arm0D4,arm0D5,arm0D6,arm0D7, // 0D0 |
| 2683 | 2701 |
arm0D0,arm0D9,arm0D2,arm0DB,arm0D4,arm0DD,arm0D6,arm0DF, // 0D8 |
| 2684 | 2702 |
arm0E0,arm0E1,arm0E2,arm0E3,arm0E4,arm0E5,arm0E6,arm0E7, // 0E0 |
| 2685 |
- arm0E0,arm0E9,arm0E2,arm_UI,arm0E4,arm_UI,arm0E6,arm_UI, // 0E8 |
|
| 2703 |
+ arm0E0,arm0E9,arm0E2,arm0CB,arm0E4,arm_UI,arm0E6,arm_UI, // 0E8 |
|
| 2686 | 2704 |
arm0F0,arm0F1,arm0F2,arm0F3,arm0F4,arm0F5,arm0F6,arm0F7, // 0F0 |
| 2687 |
- arm0F0,arm0F9,arm0F2,arm_UI,arm0F4,arm0DD,arm0F6,arm0DF, // 0F8 |
|
| 2705 |
+ arm0F0,arm0F9,arm0F2,arm0DB,arm0F4,arm0DD,arm0F6,arm0DF, // 0F8 |
|
| 2688 | 2706 |
|
| 2689 | 2707 |
arm100,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI, // 100 |
| 2690 | 2708 |
arm_UI,arm109,arm_UI,arm10B,arm_UI,arm_UI,arm_UI,arm_UI, // 108 |
| ... | ... |
@@ -1417,10 +1417,18 @@ static INSN_REGPARM void thumb45_3(u32 opcode) |
| 1417 | 1417 |
CMP_RD_RS; |
| 1418 | 1418 |
} |
| 1419 | 1419 |
|
| 1420 |
+// MOV Rd, Rs |
|
| 1421 |
+static INSN_REGPARM void thumb46_0(u32 opcode) |
|
| 1422 |
+{
|
|
| 1423 |
+ reg[opcode&7].I = reg[((opcode>>3)&7)].I; |
|
| 1424 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1425 |
+} |
|
| 1426 |
+ |
|
| 1420 | 1427 |
// MOV Rd, Hs |
| 1421 | 1428 |
static INSN_REGPARM void thumb46_1(u32 opcode) |
| 1422 | 1429 |
{
|
| 1423 | 1430 |
reg[opcode&7].I = reg[((opcode>>3)&7)+8].I; |
| 1431 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1424 | 1432 |
} |
| 1425 | 1433 |
|
| 1426 | 1434 |
// MOV Hd, Rs |
| ... | ... |
@@ -1467,16 +1475,14 @@ static INSN_REGPARM void thumb47(u32 opcode) |
| 1467 | 1475 |
armNextPC = reg[15].I; |
| 1468 | 1476 |
reg[15].I += 2; |
| 1469 | 1477 |
THUMB_PREFETCH; |
| 1470 |
- clockTicks = codeTicksAccessSeq16(armNextPC) |
|
| 1471 |
- + codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 3; |
|
| 1478 |
+ clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC) + 3; |
|
| 1472 | 1479 |
} else {
|
| 1473 | 1480 |
armState = true; |
| 1474 | 1481 |
reg[15].I &= 0xFFFFFFFC; |
| 1475 | 1482 |
armNextPC = reg[15].I; |
| 1476 | 1483 |
reg[15].I += 4; |
| 1477 | 1484 |
ARM_PREFETCH; |
| 1478 |
- clockTicks = codeTicksAccessSeq32(armNextPC) |
|
| 1479 |
- + codeTicksAccessSeq32(armNextPC) + codeTicksAccess32(armNextPC) + 3; |
|
| 1485 |
+ clockTicks = codeTicksAccessSeq32(armNextPC)*2 + codeTicksAccess32(armNextPC) + 3; |
|
| 1480 | 1486 |
} |
| 1481 | 1487 |
} |
| 1482 | 1488 |
|
| ... | ... |
@@ -1570,7 +1576,7 @@ static INSN_REGPARM void thumb5E(u32 opcode) |
| 1570 | 1576 |
if (busPrefetchCount == 0) |
| 1571 | 1577 |
busPrefetch = busPrefetchEnable; |
| 1572 | 1578 |
u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; |
| 1573 |
- reg[opcode&7].I = (s16)CPUReadHalfWordSigned(address); |
|
| 1579 |
+ reg[opcode&7].I = (u32)CPUReadHalfWordSigned(address); |
|
| 1574 | 1580 |
clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); |
| 1575 | 1581 |
} |
| 1576 | 1582 |
|
| ... | ... |
@@ -1663,6 +1669,7 @@ static INSN_REGPARM void thumbA0(u32 opcode) |
| 1663 | 1669 |
{
|
| 1664 | 1670 |
u8 regist = (opcode >> 8) & 7; |
| 1665 | 1671 |
reg[regist].I = (reg[15].I & 0xFFFFFFFC) + ((opcode&255)<<2); |
| 1672 |
+ clockTicks = 1 + codeTicksAccess16(armNextPC); |
|
| 1666 | 1673 |
} |
| 1667 | 1674 |
|
| 1668 | 1675 |
// ADD R0~R7, SP, Imm |
| ... | ... |
@@ -1670,6 +1677,7 @@ static INSN_REGPARM void thumbA8(u32 opcode) |
| 1670 | 1677 |
{
|
| 1671 | 1678 |
u8 regist = (opcode >> 8) & 7; |
| 1672 | 1679 |
reg[regist].I = reg[13].I + ((opcode&255)<<2); |
| 1680 |
+ clockTicks = 1 + codeTicksAccess16(armNextPC); |
|
| 1673 | 1681 |
} |
| 1674 | 1682 |
|
| 1675 | 1683 |
// ADD SP, Imm |
| ... | ... |
@@ -1679,6 +1687,7 @@ static INSN_REGPARM void thumbB0(u32 opcode) |
| 1679 | 1687 |
if(opcode & 0x80) |
| 1680 | 1688 |
offset = -offset; |
| 1681 | 1689 |
reg[13].I += offset; |
| 1690 |
+ clockTicks = 1 + codeTicksAccess16(armNextPC); |
|
| 1682 | 1691 |
} |
| 1683 | 1692 |
|
| 1684 | 1693 |
// Push and pop /////////////////////////////////////////////////////////// |
| ... | ... |
@@ -1876,13 +1885,13 @@ static INSN_REGPARM void thumbC8(u32 opcode) |
| 1876 | 1885 |
static INSN_REGPARM void thumbD0(u32 opcode) |
| 1877 | 1886 |
{
|
| 1878 | 1887 |
UPDATE_OLDREG; |
| 1888 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1879 | 1889 |
if(Z_FLAG) {
|
| 1880 | 1890 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1881 | 1891 |
armNextPC = reg[15].I; |
| 1882 | 1892 |
reg[15].I += 2; |
| 1883 | 1893 |
THUMB_PREFETCH; |
| 1884 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1885 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1894 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1886 | 1895 |
busPrefetchCount=0; |
| 1887 | 1896 |
} |
| 1888 | 1897 |
} |
| ... | ... |
@@ -1891,13 +1900,13 @@ static INSN_REGPARM void thumbD0(u32 opcode) |
| 1891 | 1900 |
static INSN_REGPARM void thumbD1(u32 opcode) |
| 1892 | 1901 |
{
|
| 1893 | 1902 |
UPDATE_OLDREG; |
| 1903 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1894 | 1904 |
if(!Z_FLAG) {
|
| 1895 | 1905 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1896 | 1906 |
armNextPC = reg[15].I; |
| 1897 | 1907 |
reg[15].I += 2; |
| 1898 | 1908 |
THUMB_PREFETCH; |
| 1899 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1900 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1909 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1901 | 1910 |
busPrefetchCount=0; |
| 1902 | 1911 |
} |
| 1903 | 1912 |
} |
| ... | ... |
@@ -1906,13 +1915,13 @@ static INSN_REGPARM void thumbD1(u32 opcode) |
| 1906 | 1915 |
static INSN_REGPARM void thumbD2(u32 opcode) |
| 1907 | 1916 |
{
|
| 1908 | 1917 |
UPDATE_OLDREG; |
| 1918 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1909 | 1919 |
if(C_FLAG) {
|
| 1910 | 1920 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1911 | 1921 |
armNextPC = reg[15].I; |
| 1912 | 1922 |
reg[15].I += 2; |
| 1913 | 1923 |
THUMB_PREFETCH; |
| 1914 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1915 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1924 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1916 | 1925 |
busPrefetchCount=0; |
| 1917 | 1926 |
} |
| 1918 | 1927 |
} |
| ... | ... |
@@ -1921,13 +1930,13 @@ static INSN_REGPARM void thumbD2(u32 opcode) |
| 1921 | 1930 |
static INSN_REGPARM void thumbD3(u32 opcode) |
| 1922 | 1931 |
{
|
| 1923 | 1932 |
UPDATE_OLDREG; |
| 1933 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1924 | 1934 |
if(!C_FLAG) {
|
| 1925 | 1935 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1926 | 1936 |
armNextPC = reg[15].I; |
| 1927 | 1937 |
reg[15].I += 2; |
| 1928 | 1938 |
THUMB_PREFETCH; |
| 1929 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1930 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1939 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1931 | 1940 |
busPrefetchCount=0; |
| 1932 | 1941 |
} |
| 1933 | 1942 |
} |
| ... | ... |
@@ -1936,13 +1945,13 @@ static INSN_REGPARM void thumbD3(u32 opcode) |
| 1936 | 1945 |
static INSN_REGPARM void thumbD4(u32 opcode) |
| 1937 | 1946 |
{
|
| 1938 | 1947 |
UPDATE_OLDREG; |
| 1948 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1939 | 1949 |
if(N_FLAG) {
|
| 1940 | 1950 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1941 | 1951 |
armNextPC = reg[15].I; |
| 1942 | 1952 |
reg[15].I += 2; |
| 1943 | 1953 |
THUMB_PREFETCH; |
| 1944 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1945 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1954 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1946 | 1955 |
busPrefetchCount=0; |
| 1947 | 1956 |
} |
| 1948 | 1957 |
} |
| ... | ... |
@@ -1951,13 +1960,13 @@ static INSN_REGPARM void thumbD4(u32 opcode) |
| 1951 | 1960 |
static INSN_REGPARM void thumbD5(u32 opcode) |
| 1952 | 1961 |
{
|
| 1953 | 1962 |
UPDATE_OLDREG; |
| 1963 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1954 | 1964 |
if(!N_FLAG) {
|
| 1955 | 1965 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1956 | 1966 |
armNextPC = reg[15].I; |
| 1957 | 1967 |
reg[15].I += 2; |
| 1958 | 1968 |
THUMB_PREFETCH; |
| 1959 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1960 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1969 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1961 | 1970 |
busPrefetchCount=0; |
| 1962 | 1971 |
} |
| 1963 | 1972 |
} |
| ... | ... |
@@ -1966,13 +1975,13 @@ static INSN_REGPARM void thumbD5(u32 opcode) |
| 1966 | 1975 |
static INSN_REGPARM void thumbD6(u32 opcode) |
| 1967 | 1976 |
{
|
| 1968 | 1977 |
UPDATE_OLDREG; |
| 1978 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1969 | 1979 |
if(V_FLAG) {
|
| 1970 | 1980 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1971 | 1981 |
armNextPC = reg[15].I; |
| 1972 | 1982 |
reg[15].I += 2; |
| 1973 | 1983 |
THUMB_PREFETCH; |
| 1974 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1975 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1984 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1976 | 1985 |
busPrefetchCount=0; |
| 1977 | 1986 |
} |
| 1978 | 1987 |
} |
| ... | ... |
@@ -1981,13 +1990,13 @@ static INSN_REGPARM void thumbD6(u32 opcode) |
| 1981 | 1990 |
static INSN_REGPARM void thumbD7(u32 opcode) |
| 1982 | 1991 |
{
|
| 1983 | 1992 |
UPDATE_OLDREG; |
| 1993 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1984 | 1994 |
if(!V_FLAG) {
|
| 1985 | 1995 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 1986 | 1996 |
armNextPC = reg[15].I; |
| 1987 | 1997 |
reg[15].I += 2; |
| 1988 | 1998 |
THUMB_PREFETCH; |
| 1989 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 1990 |
- codeTicksAccess16(armNextPC)+3; |
|
| 1999 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 1991 | 2000 |
busPrefetchCount=0; |
| 1992 | 2001 |
} |
| 1993 | 2002 |
} |
| ... | ... |
@@ -1996,13 +2005,13 @@ static INSN_REGPARM void thumbD7(u32 opcode) |
| 1996 | 2005 |
static INSN_REGPARM void thumbD8(u32 opcode) |
| 1997 | 2006 |
{
|
| 1998 | 2007 |
UPDATE_OLDREG; |
| 2008 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 1999 | 2009 |
if(C_FLAG && !Z_FLAG) {
|
| 2000 | 2010 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 2001 | 2011 |
armNextPC = reg[15].I; |
| 2002 | 2012 |
reg[15].I += 2; |
| 2003 | 2013 |
THUMB_PREFETCH; |
| 2004 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2005 |
- codeTicksAccess16(armNextPC)+3; |
|
| 2014 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 2006 | 2015 |
busPrefetchCount=0; |
| 2007 | 2016 |
} |
| 2008 | 2017 |
} |
| ... | ... |
@@ -2011,13 +2020,13 @@ static INSN_REGPARM void thumbD8(u32 opcode) |
| 2011 | 2020 |
static INSN_REGPARM void thumbD9(u32 opcode) |
| 2012 | 2021 |
{
|
| 2013 | 2022 |
UPDATE_OLDREG; |
| 2023 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 2014 | 2024 |
if(!C_FLAG || Z_FLAG) {
|
| 2015 | 2025 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 2016 | 2026 |
armNextPC = reg[15].I; |
| 2017 | 2027 |
reg[15].I += 2; |
| 2018 | 2028 |
THUMB_PREFETCH; |
| 2019 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2020 |
- codeTicksAccess16(armNextPC)+3; |
|
| 2029 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 2021 | 2030 |
busPrefetchCount=0; |
| 2022 | 2031 |
} |
| 2023 | 2032 |
} |
| ... | ... |
@@ -2026,13 +2035,13 @@ static INSN_REGPARM void thumbD9(u32 opcode) |
| 2026 | 2035 |
static INSN_REGPARM void thumbDA(u32 opcode) |
| 2027 | 2036 |
{
|
| 2028 | 2037 |
UPDATE_OLDREG; |
| 2038 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 2029 | 2039 |
if(N_FLAG == V_FLAG) {
|
| 2030 | 2040 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 2031 | 2041 |
armNextPC = reg[15].I; |
| 2032 | 2042 |
reg[15].I += 2; |
| 2033 | 2043 |
THUMB_PREFETCH; |
| 2034 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2035 |
- codeTicksAccess16(armNextPC)+3; |
|
| 2044 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 2036 | 2045 |
busPrefetchCount=0; |
| 2037 | 2046 |
} |
| 2038 | 2047 |
} |
| ... | ... |
@@ -2041,13 +2050,13 @@ static INSN_REGPARM void thumbDA(u32 opcode) |
| 2041 | 2050 |
static INSN_REGPARM void thumbDB(u32 opcode) |
| 2042 | 2051 |
{
|
| 2043 | 2052 |
UPDATE_OLDREG; |
| 2053 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 2044 | 2054 |
if(N_FLAG != V_FLAG) {
|
| 2045 | 2055 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 2046 | 2056 |
armNextPC = reg[15].I; |
| 2047 | 2057 |
reg[15].I += 2; |
| 2048 | 2058 |
THUMB_PREFETCH; |
| 2049 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2050 |
- codeTicksAccess16(armNextPC)+3; |
|
| 2059 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 2051 | 2060 |
busPrefetchCount=0; |
| 2052 | 2061 |
} |
| 2053 | 2062 |
} |
| ... | ... |
@@ -2056,13 +2065,13 @@ static INSN_REGPARM void thumbDB(u32 opcode) |
| 2056 | 2065 |
static INSN_REGPARM void thumbDC(u32 opcode) |
| 2057 | 2066 |
{
|
| 2058 | 2067 |
UPDATE_OLDREG; |
| 2068 |
+ clockTicks = codeTicksAccessSeq16(armNextPC) + 1; |
|
| 2059 | 2069 |
if(!Z_FLAG && (N_FLAG == V_FLAG)) {
|
| 2060 | 2070 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 2061 | 2071 |
armNextPC = reg[15].I; |
| 2062 | 2072 |
reg[15].I += 2; |
| 2063 | 2073 |
THUMB_PREFETCH; |
| 2064 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2065 |
- codeTicksAccess16(armNextPC)+3; |
|
| 2074 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 2066 | 2075 |
busPrefetchCount=0; |
| 2067 | 2076 |
} |
| 2068 | 2077 |
} |
| ... | ... |
@@ -2071,13 +2080,13 @@ static INSN_REGPARM void thumbDC(u32 opcode) |
| 2071 | 2080 |
static INSN_REGPARM void thumbDD(u32 opcode) |
| 2072 | 2081 |
{
|
| 2073 | 2082 |
UPDATE_OLDREG; |
| 2083 |
+ clockTicks = codeTicksAccessSeq16(armNextPC); |
|
| 2074 | 2084 |
if(Z_FLAG || (N_FLAG != V_FLAG)) {
|
| 2075 | 2085 |
reg[15].I += ((s8)(opcode & 0xFF)) << 1; |
| 2076 | 2086 |
armNextPC = reg[15].I; |
| 2077 | 2087 |
reg[15].I += 2; |
| 2078 | 2088 |
THUMB_PREFETCH; |
| 2079 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2080 |
- codeTicksAccess16(armNextPC)+3; |
|
| 2089 |
+ clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; |
|
| 2081 | 2090 |
busPrefetchCount=0; |
| 2082 | 2091 |
} |
| 2083 | 2092 |
} |
| ... | ... |
@@ -2088,8 +2097,8 @@ static INSN_REGPARM void thumbDD(u32 opcode) |
| 2088 | 2097 |
static INSN_REGPARM void thumbDF(u32 opcode) |
| 2089 | 2098 |
{
|
| 2090 | 2099 |
u32 address = 0; |
| 2091 |
- clockTicks = codeTicksAccessSeq16(address) + codeTicksAccessSeq16(address) + |
|
| 2092 |
- codeTicksAccess16(address)+3; |
|
| 2100 |
+ //clockTicks = codeTicksAccessSeq16(address)*2 + codeTicksAccess16(address)+3; |
|
| 2101 |
+ clockTicks = 3; |
|
| 2093 | 2102 |
busPrefetchCount=0; |
| 2094 | 2103 |
CPUSoftwareInterrupt(opcode & 0xFF); |
| 2095 | 2104 |
} |
| ... | ... |
@@ -2104,8 +2113,7 @@ static INSN_REGPARM void thumbE0(u32 opcode) |
| 2104 | 2113 |
armNextPC = reg[15].I; |
| 2105 | 2114 |
reg[15].I += 2; |
| 2106 | 2115 |
THUMB_PREFETCH; |
| 2107 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) + |
|
| 2108 |
- codeTicksAccess16(armNextPC) + 3; |
|
| 2116 |
+ clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC)+3; |
|
| 2109 | 2117 |
busPrefetchCount=0; |
| 2110 | 2118 |
} |
| 2111 | 2119 |
|
| ... | ... |
@@ -2135,8 +2143,7 @@ static INSN_REGPARM void thumbF8(u32 opcode) |
| 2135 | 2143 |
reg[15].I += 2; |
| 2136 | 2144 |
reg[14].I = temp|1; |
| 2137 | 2145 |
THUMB_PREFETCH; |
| 2138 |
- clockTicks = codeTicksAccessSeq16(armNextPC) + |
|
| 2139 |
- codeTicksAccess16(armNextPC) + codeTicksAccessSeq16(armNextPC) + 3; |
|
| 2146 |
+ clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC) + 3; |
|
| 2140 | 2147 |
busPrefetchCount = 0; |
| 2141 | 2148 |
} |
| 2142 | 2149 |
|
| ... | ... |
@@ -2185,7 +2192,7 @@ static insnfunc_t thumbInsnTable[1024] = {
|
| 2185 | 2192 |
thumb40_0,thumb40_1,thumb40_2,thumb40_3,thumb41_0,thumb41_1,thumb41_2,thumb41_3, // 40 |
| 2186 | 2193 |
thumb42_0,thumb42_1,thumb42_2,thumb42_3,thumb43_0,thumb43_1,thumb43_2,thumb43_3, |
| 2187 | 2194 |
thumbUI,thumb44_1,thumb44_2,thumb44_3,thumbUI,thumb45_1,thumb45_2,thumb45_3, |
| 2188 |
- thumbUI,thumb46_1,thumb46_2,thumb46_3,thumb47,thumb47,thumbUI,thumbUI, |
|
| 2195 |
+ thumb46_0,thumb46_1,thumb46_2,thumb46_3,thumb47,thumb47,thumbUI,thumbUI, |
|
| 2189 | 2196 |
thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, // 48 |
| 2190 | 2197 |
thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, |
| 2191 | 2198 |
thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, |
| ... | ... |
@@ -44,7 +44,6 @@ bool busPrefetchEnable = false; |
| 44 | 44 |
u32 busPrefetchCount = 0; |
| 45 | 45 |
int cpuDmaTicksToUpdate = 0; |
| 46 | 46 |
int cpuDmaCount = 0; |
| 47 |
-bool cpuDmaHack = false; |
|
| 48 | 47 |
u32 cpuDmaLast = 0; |
| 49 | 48 |
int dummyAddress = 0; |
| 50 | 49 |
|
| ... | ... |
@@ -936,7 +935,7 @@ bool CPUReadGSASnapshot(const char *fileName) |
| 936 | 935 |
fseek(file, 0x0, SEEK_SET); |
| 937 | 936 |
fread(&i, 1, 4, file); |
| 938 | 937 |
fseek(file, i, SEEK_CUR); // Skip SharkPortSave |
| 939 |
- fseek(file, 4, SEEK_CUR); // skip some sort of flag |
|
| 938 |
+// fseek(file, 4, SEEK_CUR); // skip some sort of flag |
|
| 940 | 939 |
fread(&i, 1, 4, file); // name length |
| 941 | 940 |
fseek(file, i, SEEK_CUR); // skip name |
| 942 | 941 |
fread(&i, 1, 4, file); // desc length |
| ... | ... |
@@ -1812,8 +1811,8 @@ void CPUSoftwareInterrupt(int comment) |
| 1812 | 1811 |
case 0x02: |
| 1813 | 1812 |
#ifdef GBA_LOGGING |
| 1814 | 1813 |
if(systemVerbose & VERBOSE_SWI) {
|
| 1815 |
- log("Halt: (VCOUNT = %2d)\n",
|
|
| 1816 |
- VCOUNT); |
|
| 1814 |
+ /*log("Halt: (VCOUNT = %2d)\n",
|
|
| 1815 |
+ VCOUNT);*/ |
|
| 1817 | 1816 |
} |
| 1818 | 1817 |
#endif |
| 1819 | 1818 |
holdState = true; |
| ... | ... |
@@ -1823,8 +1822,8 @@ void CPUSoftwareInterrupt(int comment) |
| 1823 | 1822 |
case 0x03: |
| 1824 | 1823 |
#ifdef GBA_LOGGING |
| 1825 | 1824 |
if(systemVerbose & VERBOSE_SWI) {
|
| 1826 |
- log("Stop: (VCOUNT = %2d)\n",
|
|
| 1827 |
- VCOUNT); |
|
| 1825 |
+ /*log("Stop: (VCOUNT = %2d)\n",
|
|
| 1826 |
+ VCOUNT);*/ |
|
| 1828 | 1827 |
} |
| 1829 | 1828 |
#endif |
| 1830 | 1829 |
holdState = true; |
| ... | ... |
@@ -2190,7 +2189,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2190 | 2189 |
doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, |
| 2191 | 2190 |
DM0CNT_L ? DM0CNT_L : 0x4000, |
| 2192 | 2191 |
DM0CNT_H & 0x0400); |
| 2193 |
- cpuDmaHack = true; |
|
| 2194 | 2192 |
|
| 2195 | 2193 |
if(DM0CNT_H & 0x4000) {
|
| 2196 | 2194 |
IF |= 0x0100; |
| ... | ... |
@@ -2259,7 +2257,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2259 | 2257 |
DM1CNT_L ? DM1CNT_L : 0x4000, |
| 2260 | 2258 |
DM1CNT_H & 0x0400); |
| 2261 | 2259 |
} |
| 2262 |
- cpuDmaHack = true; |
|
| 2263 | 2260 |
|
| 2264 | 2261 |
if(DM1CNT_H & 0x4000) {
|
| 2265 | 2262 |
IF |= 0x0200; |
| ... | ... |
@@ -2329,7 +2326,6 @@ void CPUCheckDMA(int reason, int dmamask) |
| 2329 | 2326 |
DM2CNT_L ? DM2CNT_L : 0x4000, |
| 2330 | 2327 |
DM2CNT_H & 0x0400); |
| 2331 | 2328 |
} |
| 2332 |
- cpuDmaHack = true; |
|
| 2333 | 2329 |
|
| 2334 | 2330 |
if(DM2CNT_H & 0x4000) {
|
| 2335 | 2331 |
IF |= 0x0400; |
| ... | ... |
@@ -3412,8 +3408,6 @@ void CPUReset() |
| 3412 | 3408 |
|
| 3413 | 3409 |
//systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; |
| 3414 | 3410 |
|
| 3415 |
- cpuDmaHack = false; |
|
| 3416 |
- |
|
| 3417 | 3411 |
lastTime = /*systemGetClock()*/0; |
| 3418 | 3412 |
|
| 3419 | 3413 |
SWITicks = 0; |
| ... | ... |
@@ -3512,7 +3506,6 @@ void CPULoop(int ticks) |
| 3512 | 3506 |
|
| 3513 | 3507 |
clockTicks = cpuNextEvent; |
| 3514 | 3508 |
cpuTotalTicks = 0; |
| 3515 |
- cpuDmaHack = false; |
|
| 3516 | 3509 |
|
| 3517 | 3510 |
updateLoop: |
| 3518 | 3511 |
|
| ... | ... |
@@ -3914,7 +3907,6 @@ void CPULoop(int ticks) |
| 3914 | 3907 |
cpuDmaTicksToUpdate -= clockTicks; |
| 3915 | 3908 |
if(cpuDmaTicksToUpdate < 0) |
| 3916 | 3909 |
cpuDmaTicksToUpdate = 0; |
| 3917 |
- cpuDmaHack = true; |
|
| 3918 | 3910 |
goto updateLoop; |
| 3919 | 3911 |
} |
| 3920 | 3912 |
|
| ... | ... |
@@ -19,7 +19,6 @@ extern bool cpuSramEnabled; |
| 19 | 19 |
extern bool cpuFlashEnabled; |
| 20 | 20 |
extern bool cpuEEPROMEnabled; |
| 21 | 21 |
extern bool cpuEEPROMSensorEnabled; |
| 22 |
-extern bool cpuDmaHack; |
|
| 23 | 22 |
extern u32 cpuDmaLast; |
| 24 | 23 |
extern bool timer0On; |
| 25 | 24 |
extern int timer0Ticks; |
| ... | ... |
@@ -46,23 +45,20 @@ extern int cpuTotalTicks; |
| 46 | 45 |
|
| 47 | 46 |
static inline u32 CPUReadMemory(u32 address) |
| 48 | 47 |
{
|
| 49 |
-#ifdef GBA_LOGGING |
|
| 48 |
+ u32 value; |
|
| 49 |
+ u32 oldAddress = address; |
|
| 50 |
+ |
|
| 50 | 51 |
if(address & 3) {
|
| 51 |
- if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
| 52 |
- log("Unaligned word read: %08x at %08x\n", address, armMode ?
|
|
| 53 |
- armNextPC - 4 : armNextPC - 2); |
|
| 54 |
- } |
|
| 52 |
+ address &= ~0x03; |
|
| 55 | 53 |
} |
| 56 |
-#endif |
|
| 57 | 54 |
|
| 58 |
- u32 value; |
|
| 59 | 55 |
switch(address >> 24) {
|
| 60 | 56 |
case 0: |
| 61 | 57 |
if(reg[15].I >> 24) {
|
| 62 | 58 |
if(address < 0x4000) {
|
| 63 | 59 |
#ifdef GBA_LOGGING |
| 64 | 60 |
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
| 65 |
- log("Illegal word read: %08x at %08x\n", address, armMode ?
|
|
| 61 |
+ log("Illegal word read from bios: %08x at %08x\n", address, armMode ?
|
|
| 66 | 62 |
armNextPC - 4 : armNextPC - 2); |
| 67 | 63 |
} |
| 68 | 64 |
#endif |
| ... | ... |
@@ -135,21 +131,17 @@ unreadable: |
| 135 | 131 |
} |
| 136 | 132 |
#endif |
| 137 | 133 |
|
| 138 |
- if(cpuDmaHack) {
|
|
| 139 |
- value = cpuDmaLast; |
|
| 140 |
- } else {
|
|
| 141 | 134 |
if(armState) {
|
| 142 |
- value = CPUReadMemoryQuick(reg[15].I); |
|
| 135 |
+ return CPUReadMemoryQuick(reg[15].I); |
|
| 143 | 136 |
} else {
|
| 144 |
- value = CPUReadHalfWordQuick(reg[15].I) | |
|
| 137 |
+ return CPUReadHalfWordQuick(reg[15].I) | |
|
| 145 | 138 |
CPUReadHalfWordQuick(reg[15].I) << 16; |
| 146 | 139 |
} |
| 147 | 140 |
} |
| 148 |
- } |
|
| 149 | 141 |
|
| 150 |
- if(address & 3) {
|
|
| 142 |
+ if(oldAddress & 3) {
|
|
| 151 | 143 |
#ifdef C_CORE |
| 152 |
- int shift = (address & 3) << 3; |
|
| 144 |
+ int shift = (oldAddress & 3) << 3; |
|
| 153 | 145 |
value = (value >> shift) | (value << (32 - shift)); |
| 154 | 146 |
#else |
| 155 | 147 |
#ifdef __GNUC__ |
| ... | ... |
@@ -157,10 +149,10 @@ unreadable: |
| 157 | 149 |
"shl $3 ,%%ecx;" |
| 158 | 150 |
"ror %%cl, %0" |
| 159 | 151 |
: "=r" (value) |
| 160 |
- : "r" (value), "c" (address)); |
|
| 152 |
+ : "r" (value), "c" (oldAddress)); |
|
| 161 | 153 |
#else |
| 162 | 154 |
__asm {
|
| 163 |
- mov ecx, address; |
|
| 155 |
+ mov ecx, oldAddress; |
|
| 164 | 156 |
and ecx, 3; |
| 165 | 157 |
shl ecx, 3; |
| 166 | 158 |
ror [dword ptr value], cl; |
| ... | ... |
@@ -168,6 +160,15 @@ unreadable: |
| 168 | 160 |
#endif |
| 169 | 161 |
#endif |
| 170 | 162 |
} |
| 163 |
+ |
|
| 164 |
+#ifdef GBA_LOGGING |
|
| 165 |
+ if(oldAddress & 3) {
|
|
| 166 |
+ if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
| 167 |
+ log("Unaligned word read from: %08x at %08x (%08x)\n", oldAddress, armMode ?
|
|
| 168 |
+ armNextPC - 4 : armNextPC - 2, value); |
|
| 169 |
+ } |
|
| 170 |
+ } |
|
| 171 |
+#endif |
|
| 171 | 172 |
return value; |
| 172 | 173 |
} |
| 173 | 174 |
|
| ... | ... |
@@ -175,16 +176,12 @@ extern u32 myROM[]; |
| 175 | 176 |
|
| 176 | 177 |
static inline u32 CPUReadHalfWord(u32 address) |
| 177 | 178 |
{
|
| 178 |
-#ifdef GBA_LOGGING |
|
| 179 |
+ u32 value; |
|
| 180 |
+ u32 oldAddress = address; |
|
| 181 |
+ |
|
| 179 | 182 |
if(address & 1) {
|
| 180 |
- if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
| 181 |
- log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
|
|
| 182 |
- armNextPC - 4 : armNextPC - 2); |
|
| 183 |
- } |
|
| 183 |
+ address &= ~0x01; |
|
| 184 | 184 |
} |
| 185 |
-#endif |
|
| 186 |
- |
|
| 187 |
- u32 value; |
|
| 188 | 185 |
|
| 189 | 186 |
switch(address >> 24) {
|
| 190 | 187 |
case 0: |
| ... | ... |
@@ -192,7 +189,7 @@ static inline u32 CPUReadHalfWord(u32 address) |
| 192 | 189 |
if(address < 0x4000) {
|
| 193 | 190 |
#ifdef GBA_LOGGING |
| 194 | 191 |
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
| 195 |
- log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
|
| 192 |
+ log("Illegal halfword read from bios: %08x at %08x\n", oldAddress, armMode ?
|
|
| 196 | 193 |
armNextPC - 4 : armNextPC - 2); |
| 197 | 194 |
} |
| 198 | 195 |
#endif |
| ... | ... |
@@ -269,34 +266,48 @@ static inline u32 CPUReadHalfWord(u32 address) |
| 269 | 266 |
unreadable: |
| 270 | 267 |
#ifdef GBA_LOGGING |
| 271 | 268 |
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
| 272 |
- log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
|
| 269 |
+ log("Illegal halfword read: %08x at %08x\n", oldAddress, armMode ?
|
|
| 273 | 270 |
armNextPC - 4 : armNextPC - 2); |
| 274 | 271 |
} |
| 275 | 272 |
#endif |
| 276 |
- if(cpuDmaHack) {
|
|
| 277 |
- value = cpuDmaLast & 0xFFFF; |
|
| 278 |
- } else {
|
|
| 279 | 273 |
if(armState) {
|
| 280 |
- value = CPUReadHalfWordQuick(reg[15].I + (address & 2)); |
|
| 274 |
+ return CPUReadMemoryQuick(reg[15].I); |
|
| 281 | 275 |
} else {
|
| 282 |
- value = CPUReadHalfWordQuick(reg[15].I); |
|
| 276 |
+ return CPUReadHalfWordQuick(reg[15].I) | |
|
| 277 |
+ CPUReadHalfWordQuick(reg[15].I) << 16; |
|
| 283 | 278 |
} |
| 284 | 279 |
} |
| 285 |
- break; |
|
| 286 |
- } |
|
| 287 | 280 |
|
| 288 |
- if(address & 1) {
|
|
| 281 |
+ if(oldAddress & 1) {
|
|
| 289 | 282 |
value = (value >> 8) | (value << 24); |
| 283 |
+#ifdef GBA_LOGGING |
|
| 284 |
+ if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
| 285 |
+ log("Unaligned halfword read from: %08x at %08x (%08x)\n", oldAddress, armMode ?
|
|
| 286 |
+ armNextPC - 4 : armNextPC - 2, value); |
|
| 287 |
+ } |
|
| 288 |
+#endif |
|
| 290 | 289 |
} |
| 291 | 290 |
|
| 292 | 291 |
return value; |
| 293 | 292 |
} |
| 294 | 293 |
|
| 295 |
-static inline u16 CPUReadHalfWordSigned(u32 address) |
|
| 294 |
+static inline s16 CPUReadHalfWordSigned(u32 address) |
|
| 296 | 295 |
{
|
| 297 |
- u16 value = CPUReadHalfWord(address); |
|
| 298 |
- if((address & 1)) |
|
| 296 |
+ u32 oldAddress = address; |
|
| 297 |
+ if(address & 1) {
|
|
| 298 |
+ address &= ~0x01; |
|
| 299 |
+ } |
|
| 300 |
+ s16 value = (s16)CPUReadHalfWord(address); |
|
| 301 |
+ if((oldAddress & 1)) |
|
| 302 |
+ {
|
|
| 299 | 303 |
value = (s8)value; |
| 304 |
+#ifdef GBA_LOGGING |
|
| 305 |
+ if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
|
|
| 306 |
+ log("Unaligned signed halfword read from: %08x at %08x (%08x)\n", oldAddress, armMode ?
|
|
| 307 |
+ armNextPC - 4 : armNextPC - 2, value); |
|
| 308 |
+ } |
|
| 309 |
+#endif |
|
| 310 |
+ } |
|
| 300 | 311 |
return value; |
| 301 | 312 |
} |
| 302 | 313 |
|
| ... | ... |
@@ -308,7 +319,7 @@ static inline u8 CPUReadByte(u32 address) |
| 308 | 319 |
if(address < 0x4000) {
|
| 309 | 320 |
#ifdef GBA_LOGGING |
| 310 | 321 |
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
|
| 311 |
- log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
|
| 322 |
+ log("Illegal byte read from bios: %08x at %08x\n", address, armMode ?
|
|
| 312 | 323 |
armNextPC - 4 : armNextPC - 2); |
| 313 | 324 |
} |
| 314 | 325 |
#endif |
| ... | ... |
@@ -369,17 +380,13 @@ unreadable: |
| 369 | 380 |
armNextPC - 4 : armNextPC - 2); |
| 370 | 381 |
} |
| 371 | 382 |
#endif |
| 372 |
- if(cpuDmaHack) {
|
|
| 373 |
- return cpuDmaLast & 0xFF; |
|
| 374 |
- } else {
|
|
| 375 | 383 |
if(armState) {
|
| 376 |
- return CPUReadByteQuick(reg[15].I+(address & 3)); |
|
| 384 |
+ return CPUReadMemoryQuick(reg[15].I); |
|
| 377 | 385 |
} else {
|
| 378 |
- return CPUReadByteQuick(reg[15].I+(address & 1)); |
|
| 386 |
+ return CPUReadHalfWordQuick(reg[15].I) | |
|
| 387 |
+ CPUReadHalfWordQuick(reg[15].I) << 16; |
|
| 379 | 388 |
} |
| 380 | 389 |
} |
| 381 |
- break; |
|
| 382 |
- } |
|
| 383 | 390 |
} |
| 384 | 391 |
|
| 385 | 392 |
static inline void CPUWriteMemory(u32 address, u32 value) |
| ... | ... |
@@ -396,6 +403,8 @@ static inline void CPUWriteMemory(u32 address, u32 value) |
| 396 | 403 |
} |
| 397 | 404 |
#endif |
| 398 | 405 |
|
| 406 |
+ address &= 0xFFFFFFFC; |
|
| 407 |
+ |
|
| 399 | 408 |
switch(address >> 24) {
|
| 400 | 409 |
case 0x02: |
| 401 | 410 |
#ifdef BKPT_SUPPORT |
| ... | ... |
@@ -493,6 +502,8 @@ static inline void CPUWriteHalfWord(u32 address, u16 value) |
| 493 | 502 |
} |
| 494 | 503 |
#endif |
| 495 | 504 |
|
| 505 |
+ address &= 0xFFFFFFFE; |
|
| 506 |
+ |
|
| 496 | 507 |
switch(address >> 24) {
|
| 497 | 508 |
case 2: |
| 498 | 509 |
#ifdef BKPT_SUPPORT |
| ... | ... |
@@ -42,7 +42,7 @@ extern bool stopState; // TODO: silence sound when true |
| 42 | 42 |
|
| 43 | 43 |
int const SOUND_CLOCK_TICKS_ = 167772; // 1/100 second |
| 44 | 44 |
|
| 45 |
-static u16 soundFinalWave [1600]; |
|
| 45 |
+static u16 soundFinalWave [6400]; |
|
| 46 | 46 |
long soundSampleRate = 44100; |
| 47 | 47 |
bool soundInterpolation = true; |
| 48 | 48 |
bool soundPaused = true; |
| ... | ... |
@@ -452,6 +452,13 @@ static void remake_stereo_buffer() |
| 452 | 452 |
pcm [0].pcm.init(); |
| 453 | 453 |
pcm [1].pcm.init(); |
| 454 | 454 |
|
| 455 |
+ // APU |
|
| 456 |
+ if ( !gb_apu ) |
|
| 457 |
+ {
|
|
| 458 |
+ gb_apu = new Gb_Apu; // TODO: handle out of memory |
|
| 459 |
+ reset_apu(); |
|
| 460 |
+ } |
|
| 461 |
+ |
|
| 455 | 462 |
// Stereo_Buffer |
| 456 | 463 |
delete stereo_buffer; |
| 457 | 464 |
stereo_buffer = 0; |
| ... | ... |
@@ -465,13 +472,7 @@ static void remake_stereo_buffer() |
| 465 | 472 |
pcm [1].which = 1; |
| 466 | 473 |
apply_filtering(); |
| 467 | 474 |
|
| 468 |
- // APU |
|
| 469 |
- if ( !gb_apu ) |
|
| 470 |
- {
|
|
| 471 |
- gb_apu = new Gb_Apu; // TODO: handle out of memory |
|
| 472 |
- reset_apu(); |
|
| 473 |
- } |
|
| 474 |
- |
|
| 475 |
+ // Volume Level |
|
| 475 | 476 |
apply_muting(); |
| 476 | 477 |
apply_volume(); |
| 477 | 478 |
} |