| 1 | # gameplaySP |
| 2 | # |
| 3 | # Copyright (C) 2006 Exophase <exophase@gmail.com> |
| 4 | # |
| 5 | # This program is free software; you can redistribute it and/or |
| 6 | # modify it under the terms of the GNU General Public License as |
| 7 | # published by the Free Software Foundation; either version 2 of |
| 8 | # the License, or (at your option) any later version. |
| 9 | # |
| 10 | # This program is distributed in the hope that it will be useful, |
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | # General Public License for more details. |
| 14 | # |
| 15 | # You should have received a copy of the GNU General Public License |
| 16 | # along with this program; if not, write to the Free Software |
| 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | |
| 19 | .align 4 |
| 20 | |
| 21 | #ifndef _WIN32 |
| 22 | #define _x86_update_gba x86_update_gba |
| 23 | #define _x86_indirect_branch_arm x86_indirect_branch_arm |
| 24 | #define _x86_indirect_branch_thumb x86_indirect_branch_thumb |
| 25 | #define _x86_indirect_branch_dual x86_indirect_branch_dual |
| 26 | #define _execute_store_u8 execute_store_u8 |
| 27 | #define _execute_store_u16 execute_store_u16 |
| 28 | #define _execute_store_u32 execute_store_u32 |
| 29 | #define _execute_store_cpsr execute_store_cpsr |
| 30 | #define _execute_arm_translate execute_arm_translate |
| 31 | #define _step_debug_x86 step_debug_x86 |
| 32 | #define _memory_map_read memory_map_read |
| 33 | #define _memory_map_write memory_map_write |
| 34 | #define _reg reg |
| 35 | #define _oam_update oam_update |
| 36 | #define _iwram iwram |
| 37 | #define _ewram ewram |
| 38 | #define _vram vram |
| 39 | #define _oam_ram oam_ram |
| 40 | #define _bios_rom bios_rom |
| 41 | #define _io_registers io_registers |
| 42 | #define _spsr spsr |
| 43 | |
| 44 | #define _step_debug step_debug |
| 45 | #define _update_gba update_gba |
| 46 | #define _block_lookup_address_arm block_lookup_address_arm |
| 47 | #define _block_lookup_address_thumb block_lookup_address_thumb |
| 48 | #define _block_lookup_address_dual block_lookup_address_dual |
| 49 | #define _write_io_register8 write_io_register8 |
| 50 | #define _write_io_register16 write_io_register16 |
| 51 | #define _write_io_register32 write_io_register32 |
| 52 | #define _palette_ram palette_ram |
| 53 | #define _palette_ram_converted palette_ram_converted |
| 54 | #define _flush_translation_cache_ram flush_translation_cache_ram |
| 55 | #define _write_eeprom write_eeprom |
| 56 | #define _write_backup write_backup |
| 57 | #define _write_rtc write_rtc |
| 58 | #define _execute_store_cpsr_body execute_store_cpsr_body |
| 59 | #endif |
| 60 | |
| 61 | .global _x86_update_gba |
| 62 | .global _x86_indirect_branch_arm |
| 63 | .global _x86_indirect_branch_thumb |
| 64 | .global _x86_indirect_branch_dual |
| 65 | .global _execute_store_u8 |
| 66 | .global _execute_store_u16 |
| 67 | .global _execute_store_u32 |
| 68 | .global _execute_store_cpsr |
| 69 | .global _execute_arm_translate |
| 70 | .global _step_debug_x86 |
| 71 | |
| 72 | .global _memory_map_read |
| 73 | .global _memory_map_write |
| 74 | .global _reg |
| 75 | |
| 76 | .global _oam_update |
| 77 | |
| 78 | .global _iwram |
| 79 | .global _ewram |
| 80 | .global _vram |
| 81 | .global _oam_ram |
| 82 | .global _bios_rom |
| 83 | .global _io_registers |
| 84 | |
| 85 | .extern _spsr |
| 86 | |
| 87 | .equ REG_SP, (13 * 4) |
| 88 | .equ REG_LR, (14 * 4) |
| 89 | .equ REG_PC, (15 * 4) |
| 90 | .equ REG_N_FLAG, (16 * 4) |
| 91 | .equ REG_Z_FLAG, (17 * 4) |
| 92 | .equ REG_C_FLAG, (18 * 4) |
| 93 | .equ REG_V_FLAG, (19 * 4) |
| 94 | .equ REG_CPSR, (20 * 4) |
| 95 | .equ REG_SAVE, (21 * 4) |
| 96 | .equ REG_SAVE2, (22 * 4) |
| 97 | .equ REG_SAVE3, (23 * 4) |
| 98 | .equ CPU_MODE, (29 * 4) |
| 99 | .equ CPU_HALT_STATE, (30 * 4) |
| 100 | .equ CHANGED_PC_STATUS, (31 * 4) |
| 101 | |
| 102 | # destroys ecx and edx |
| 103 | |
| 104 | .macro collapse_flag offset, shift |
| 105 | mov \offset(%ebx), %ecx |
| 106 | shl $\shift, %ecx |
| 107 | or %ecx, %edx |
| 108 | .endm |
| 109 | |
| 110 | .macro collapse_flags_no_update |
| 111 | xor %edx, %edx |
| 112 | collapse_flag REG_N_FLAG, 31 |
| 113 | collapse_flag REG_Z_FLAG, 30 |
| 114 | collapse_flag REG_C_FLAG, 29 |
| 115 | collapse_flag REG_V_FLAG, 28 |
| 116 | mov REG_CPSR(%ebx), %ecx |
| 117 | and $0xFF, %ecx |
| 118 | or %ecx, %edx |
| 119 | .endm |
| 120 | |
| 121 | |
| 122 | .macro collapse_flags |
| 123 | collapse_flags_no_update |
| 124 | mov %edx, REG_CPSR(%ebx) |
| 125 | .endm |
| 126 | |
| 127 | .macro extract_flag shift, offset |
| 128 | mov REG_CPSR(%ebx), %edx |
| 129 | shr $\shift, %edx |
| 130 | and $0x01, %edx |
| 131 | mov %edx, \offset(%ebx) |
| 132 | .endm |
| 133 | |
| 134 | .macro extract_flags |
| 135 | extract_flag 31, REG_N_FLAG |
| 136 | extract_flag 30, REG_Z_FLAG |
| 137 | extract_flag 29, REG_C_FLAG |
| 138 | extract_flag 28, REG_V_FLAG |
| 139 | .endm |
| 140 | |
| 141 | # Process a hardware event. Since an interrupt might be |
| 142 | # raised we have to check if the PC has changed. |
| 143 | |
| 144 | # eax: current address |
| 145 | |
| 146 | st: |
| 147 | .asciz "u\n" |
| 148 | |
| 149 | _x86_update_gba: |
| 150 | mov %eax, REG_PC(%ebx) # current PC = eax |
| 151 | collapse_flags # update cpsr, trashes ecx and edx |
| 152 | |
| 153 | call _update_gba # process the next event |
| 154 | |
| 155 | mov %eax, %edi # edi = new cycle count |
| 156 | # did the PC change? |
| 157 | cmpl $1, CHANGED_PC_STATUS(%ebx) |
| 158 | je lookup_pc |
| 159 | ret # if not, go back to caller |
| 160 | |
| 161 | # Perform this on an indirect branch that will definitely go to |
| 162 | # ARM code, IE anything that changes the PC in ARM mode except |
| 163 | # for BX and data processing to PC with the S bit set. |
| 164 | |
| 165 | # eax: GBA address to branch to |
| 166 | # edi: Cycle counter |
| 167 | |
| 168 | _x86_indirect_branch_arm: |
| 169 | call _block_lookup_address_arm |
| 170 | jmp *%eax |
| 171 | |
| 172 | # For indirect branches that'll definitely go to Thumb. In |
| 173 | # Thumb mode any indirect branches except for BX. |
| 174 | |
| 175 | _x86_indirect_branch_thumb: |
| 176 | call _block_lookup_address_thumb |
| 177 | jmp *%eax |
| 178 | |
| 179 | # For indirect branches that can go to either Thumb or ARM, |
| 180 | # mainly BX (also data processing to PC with S bit set, be |
| 181 | # sure to adjust the target with a 1 in the lowest bit for this) |
| 182 | |
| 183 | _x86_indirect_branch_dual: |
| 184 | call _block_lookup_address_dual |
| 185 | jmp *%eax |
| 186 | |
| 187 | |
| 188 | # General ext memory routines |
| 189 | |
| 190 | ext_store_ignore: |
| 191 | ret # ignore these writes |
| 192 | |
| 193 | write_epilogue: |
| 194 | cmp $0, %eax # 0 return means nothing happened |
| 195 | jz no_alert # if so we can leave |
| 196 | |
| 197 | collapse_flags # make sure flags are good for function call |
| 198 | cmp $2, %eax # see if it was an SMC trigger |
| 199 | je smc_write |
| 200 | |
| 201 | alert_loop: |
| 202 | call _update_gba # process the next event |
| 203 | |
| 204 | # see if the halt status has changed |
| 205 | mov CPU_HALT_STATE(%ebx), %edx |
| 206 | |
| 207 | cmp $0, %edx # 0 means it has |
| 208 | jnz alert_loop # if not go again |
| 209 | |
| 210 | mov %eax, %edi # edi = new cycle count |
| 211 | jmp lookup_pc # pc has definitely changed |
| 212 | |
| 213 | no_alert: |
| 214 | ret |
| 215 | |
| 216 | ext_store_eeprom: |
| 217 | jmp _write_eeprom # perform eeprom write |
| 218 | |
| 219 | |
| 220 | # 8bit ext memory routines |
| 221 | |
| 222 | ext_store_io8: |
| 223 | and $0x3FF, %eax # wrap around address |
| 224 | and $0xFF, %edx |
| 225 | call _write_io_register8 # perform 8bit I/O register write |
| 226 | jmp write_epilogue # see if it requires any system update |
| 227 | |
| 228 | ext_store_palette8: |
| 229 | and $0x3FE, %eax # wrap around address and align to 16bits |
| 230 | jmp ext_store_palette16b # perform 16bit palette write |
| 231 | |
| 232 | ext_store_vram8: |
| 233 | and $0x1FFFE, %eax # wrap around address and align to 16bits |
| 234 | mov %dl, %dh # copy lower 8bits of value into full 16bits |
| 235 | cmp $0x18000, %eax # see if address is in upper region |
| 236 | jb ext_store_vram8b |
| 237 | sub $0x8000, %eax # if so wrap down |
| 238 | |
| 239 | ext_store_vram8b: |
| 240 | mov %dx, _vram(%eax) # perform 16bit store |
| 241 | ret |
| 242 | |
| 243 | ext_store_oam8: |
| 244 | movl $1, _oam_update # flag OAM update |
| 245 | and $0x3FE, %eax # wrap around address and align to 16bits |
| 246 | mov %dl, %dh # copy lower 8bits of value into full 16bits |
| 247 | mov %dx, _oam_ram(%eax) # perform 16bit store |
| 248 | ret |
| 249 | |
| 250 | ext_store_backup: |
| 251 | and $0xFF, %edx # make value 8bit |
| 252 | and $0xFFFF, %eax # mask address |
| 253 | jmp _write_backup # perform backup write |
| 254 | |
| 255 | ext_store_u8_jtable: |
| 256 | .long ext_store_ignore # 0x00 BIOS, ignore |
| 257 | .long ext_store_ignore # 0x01 invalid, ignore |
| 258 | .long ext_store_ignore # 0x02 EWRAM, should have been hit already |
| 259 | .long ext_store_ignore # 0x03 IWRAM, should have been hit already |
| 260 | .long ext_store_io8 # 0x04 I/O registers |
| 261 | .long ext_store_palette8 # 0x05 Palette RAM |
| 262 | .long ext_store_vram8 # 0x06 VRAM |
| 263 | .long ext_store_oam8 # 0x07 OAM RAM |
| 264 | .long ext_store_ignore # 0x08 gamepak (no RTC accepted in 8bit) |
| 265 | .long ext_store_ignore # 0x09 gamepak, ignore |
| 266 | .long ext_store_ignore # 0x0A gamepak, ignore |
| 267 | .long ext_store_ignore # 0x0B gamepak, ignore |
| 268 | .long ext_store_ignore # 0x0C gamepak, ignore |
| 269 | .long ext_store_eeprom # 0x0D EEPROM (possibly) |
| 270 | .long ext_store_backup # 0x0E Flash ROM/SRAM |
| 271 | |
| 272 | ext_store_u8: |
| 273 | mov %eax, %ecx # ecx = address |
| 274 | shr $24, %ecx # ecx = address >> 24 |
| 275 | cmp $15, %ecx |
| 276 | ja ext_store_ignore |
| 277 | # ecx = ext_store_u8_jtable[address >> 24] |
| 278 | mov ext_store_u8_jtable(, %ecx, 4), %ecx |
| 279 | jmp *%ecx # jump to table index |
| 280 | |
| 281 | # eax: address to write to |
| 282 | # edx: value to write |
| 283 | # ecx: current pc |
| 284 | |
| 285 | _execute_store_u8: |
| 286 | mov %ecx, REG_PC(%ebx) # write out the PC |
| 287 | mov %eax, %ecx # ecx = address |
| 288 | test $0xF0000000, %ecx # check address range |
| 289 | jnz ext_store_u8 # if above perform an extended write |
| 290 | shr $15, %ecx # ecx = page number of address |
| 291 | # load the corresponding memory map offset |
| 292 | mov _memory_map_write(, %ecx, 4), %ecx |
| 293 | test %ecx, %ecx # see if it's NULL |
| 294 | jz ext_store_u8 # if so perform an extended write |
| 295 | and $0x7FFF, %eax # isolate the lower 15bits of the address |
| 296 | mov %dl, (%eax, %ecx) # store the value |
| 297 | # check for self-modifying code |
| 298 | testb $0xFF, -32768(%eax, %ecx) |
| 299 | jne smc_write |
| 300 | ret # return |
| 301 | |
| 302 | _execute_store_u16: |
| 303 | mov %ecx, REG_PC(%ebx) # write out the PC |
| 304 | and $~0x01, %eax # fix alignment |
| 305 | mov %eax, %ecx # ecx = address |
| 306 | test $0xF0000000, %ecx # check address range |
| 307 | jnz ext_store_u16 # if above perform an extended write |
| 308 | shr $15, %ecx # ecx = page number of address |
| 309 | # load the corresponding memory map offset |
| 310 | mov _memory_map_write(, %ecx, 4), %ecx |
| 311 | test %ecx, %ecx # see if it's NULL |
| 312 | jz ext_store_u16 # if so perform an extended write |
| 313 | and $0x7FFF, %eax # isolate the lower 15bits of the address |
| 314 | mov %dx, (%eax, %ecx) # store the value |
| 315 | # check for self-modifying code |
| 316 | testw $0xFFFF, -32768(%eax, %ecx) |
| 317 | jne smc_write |
| 318 | ret # return |
| 319 | |
| 320 | # 16bit ext memory routines |
| 321 | |
| 322 | ext_store_io16: |
| 323 | and $0x3FF, %eax # wrap around address |
| 324 | and $0xFFFF, %edx |
| 325 | call _write_io_register16 # perform 16bit I/O register write |
| 326 | jmp write_epilogue # see if it requires any system update |
| 327 | |
| 328 | ext_store_palette16: |
| 329 | and $0x3FF, %eax # wrap around address |
| 330 | |
| 331 | ext_store_palette16b: # entry point for 8bit write |
| 332 | mov %dx, _palette_ram(%eax) # write out palette value |
| 333 | mov %edx, %ecx # cx = dx |
| 334 | shl $11, %ecx # cx <<= 11 (red component is in high bits) |
| 335 | mov %dh, %cl # bottom bits of cx = top bits of dx |
| 336 | shr $2, %cl # move the blue component to the bottom of cl |
| 337 | and $0x03E0, %dx # isolate green component of dx |
| 338 | shl $1, %dx # make green component 6bits |
| 339 | or %edx, %ecx # combine green component into ecx |
| 340 | # write out the freshly converted palette value |
| 341 | mov %cx, _palette_ram_converted(%eax) |
| 342 | ret # done |
| 343 | |
| 344 | ext_store_vram16: |
| 345 | and $0x1FFFF, %eax # wrap around address |
| 346 | cmp $0x18000, %eax # see if address is in upper region |
| 347 | jb ext_store_vram16b |
| 348 | sub $0x8000, %eax # if so wrap down |
| 349 | |
| 350 | ext_store_vram16b: |
| 351 | mov %dx, _vram(%eax) # perform 16bit store |
| 352 | ret |
| 353 | |
| 354 | ext_store_oam16: |
| 355 | movl $1, _oam_update # flag OAM update |
| 356 | and $0x3FF, %eax # wrap around address |
| 357 | mov %dx, _oam_ram(%eax) # perform 16bit store |
| 358 | ret |
| 359 | |
| 360 | ext_store_rtc: |
| 361 | and $0xFFFF, %edx # make value 16bit |
| 362 | and $0xFF, %eax # mask address |
| 363 | jmp _write_rtc # write out RTC register |
| 364 | |
| 365 | ext_store_u16_jtable: |
| 366 | .long ext_store_ignore # 0x00 BIOS, ignore |
| 367 | .long ext_store_ignore # 0x01 invalid, ignore |
| 368 | .long ext_store_ignore # 0x02 EWRAM, should have been hit already |
| 369 | .long ext_store_ignore # 0x03 IWRAM, should have been hit already |
| 370 | .long ext_store_io16 # 0x04 I/O registers |
| 371 | .long ext_store_palette16 # 0x05 Palette RAM |
| 372 | .long ext_store_vram16 # 0x06 VRAM |
| 373 | .long ext_store_oam16 # 0x07 OAM RAM |
| 374 | .long ext_store_rtc # 0x08 gamepak or RTC |
| 375 | .long ext_store_ignore # 0x09 gamepak, ignore |
| 376 | .long ext_store_ignore # 0x0A gamepak, ignore |
| 377 | .long ext_store_ignore # 0x0B gamepak, ignore |
| 378 | .long ext_store_ignore # 0x0C gamepak, ignore |
| 379 | .long ext_store_eeprom # 0x0D EEPROM (possibly) |
| 380 | .long ext_store_ignore # 0x0E Flash ROM/SRAM must be 8bit |
| 381 | |
| 382 | ext_store_u16: |
| 383 | mov %eax, %ecx # ecx = address |
| 384 | shr $24, %ecx # ecx = address >> 24 |
| 385 | cmp $15, %ecx |
| 386 | ja ext_store_ignore |
| 387 | # ecx = ext_store_u16_jtable[address >> 24] |
| 388 | mov ext_store_u16_jtable(, %ecx, 4), %ecx |
| 389 | jmp *%ecx # jump to table index |
| 390 | |
| 391 | _execute_store_u32: |
| 392 | mov %ecx, REG_PC(%ebx) # write out the PC |
| 393 | and $~0x03, %eax # fix alignment |
| 394 | mov %eax, %ecx # ecx = address |
| 395 | test $0xF0000000, %ecx # check address range |
| 396 | jnz ext_store_u32 # if above perform an extended write |
| 397 | shr $15, %ecx # ecx = page number of address |
| 398 | # load the corresponding memory map offset |
| 399 | mov _memory_map_write(, %ecx, 4), %ecx |
| 400 | test %ecx, %ecx # see if it's NULL |
| 401 | jz ext_store_u32 # if so perform an extended write |
| 402 | and $0x7FFF, %eax # isolate the lower 15bits of the address |
| 403 | mov %edx, (%eax, %ecx) # store the value |
| 404 | # check for self-modifying code |
| 405 | testl $0xFFFFFFFF, -32768(%eax, %ecx) |
| 406 | jne smc_write |
| 407 | ret # return it |
| 408 | |
| 409 | # 32bit ext memory routines |
| 410 | |
| 411 | ext_store_io32: |
| 412 | and $0x3FF, %eax # wrap around address |
| 413 | call _write_io_register32 # perform 32bit I/O register write |
| 414 | jmp write_epilogue # see if it requires any system update |
| 415 | |
| 416 | ext_store_palette32: |
| 417 | and $0x3FF, %eax # wrap around address |
| 418 | call ext_store_palette16b # write first 16bits |
| 419 | add $2, %eax # go to next address |
| 420 | shr $16, %edx # go to next 16bits |
| 421 | jmp ext_store_palette16b # write next 16bits |
| 422 | |
| 423 | ext_store_vram32: |
| 424 | and $0x1FFFF, %eax # wrap around address |
| 425 | cmp $0x18000, %eax # see if address is in upper region |
| 426 | jb ext_store_vram32b |
| 427 | sub $0x8000, %eax # if so wrap down |
| 428 | |
| 429 | ext_store_vram32b: |
| 430 | mov %edx, _vram(%eax) # perform 32bit store |
| 431 | ret |
| 432 | |
| 433 | ext_store_oam32: |
| 434 | movl $1, _oam_update # flag OAM update |
| 435 | and $0x3FF, %eax # wrap around address |
| 436 | mov %edx, _oam_ram(%eax) # perform 32bit store |
| 437 | ret |
| 438 | |
| 439 | ext_store_u32_jtable: |
| 440 | .long ext_store_ignore # 0x00 BIOS, ignore |
| 441 | .long ext_store_ignore # 0x01 invalid, ignore |
| 442 | .long ext_store_ignore # 0x02 EWRAM, should have been hit already |
| 443 | .long ext_store_ignore # 0x03 IWRAM, should have been hit already |
| 444 | .long ext_store_io32 # 0x04 I/O registers |
| 445 | .long ext_store_palette32 # 0x05 Palette RAM |
| 446 | .long ext_store_vram32 # 0x06 VRAM |
| 447 | .long ext_store_oam32 # 0x07 OAM RAM |
| 448 | .long ext_store_ignore # 0x08 gamepak, ignore (no RTC in 32bit) |
| 449 | .long ext_store_ignore # 0x09 gamepak, ignore |
| 450 | .long ext_store_ignore # 0x0A gamepak, ignore |
| 451 | .long ext_store_ignore # 0x0B gamepak, ignore |
| 452 | .long ext_store_ignore # 0x0C gamepak, ignore |
| 453 | .long ext_store_eeprom # 0x0D EEPROM (possibly) |
| 454 | .long ext_store_ignore # 0x0E Flash ROM/SRAM must be 8bit |
| 455 | |
| 456 | |
| 457 | ext_store_u32: |
| 458 | mov %eax, %ecx # ecx = address |
| 459 | shr $24, %ecx # ecx = address >> 24 |
| 460 | cmp $15, %ecx |
| 461 | ja ext_store_ignore |
| 462 | # ecx = ext_store_u32_jtable[address >> 24] |
| 463 | mov ext_store_u32_jtable(, %ecx, 4), %ecx |
| 464 | jmp *%ecx |
| 465 | |
| 466 | # %eax = new_cpsr |
| 467 | # %edx = store_mask |
| 468 | |
| 469 | _execute_store_cpsr: |
| 470 | mov %edx, REG_SAVE(%ebx) # save store_mask |
| 471 | mov %ecx, REG_SAVE2(%ebx) # save PC too |
| 472 | |
| 473 | mov %eax, %ecx # ecx = new_cpsr |
| 474 | and %edx, %ecx # ecx = new_cpsr & store_mask |
| 475 | mov REG_CPSR(%ebx), %eax # eax = cpsr |
| 476 | not %edx # edx = ~store_mask |
| 477 | and %edx, %eax # eax = cpsr & ~store_mask |
| 478 | or %ecx, %eax # eax = new cpsr combined with old |
| 479 | |
| 480 | call _execute_store_cpsr_body # do the dirty work in this C function |
| 481 | |
| 482 | extract_flags # pull out flag vars from new CPSR |
| 483 | |
| 484 | cmp $0, %eax # see if return value is 0 |
| 485 | jnz changed_pc_cpsr # might have changed the PC |
| 486 | |
| 487 | ret # return |
| 488 | |
| 489 | changed_pc_cpsr: |
| 490 | add $4, %esp # get rid of current return address |
| 491 | call _block_lookup_address_arm # lookup new PC |
| 492 | jmp *%eax |
| 493 | |
| 494 | smc_write: |
| 495 | call _flush_translation_cache_ram |
| 496 | |
| 497 | lookup_pc: |
| 498 | add $4, %esp |
| 499 | movl $0, CHANGED_PC_STATUS(%ebx) |
| 500 | mov REG_PC(%ebx), %eax |
| 501 | testl $0x20, REG_CPSR(%ebx) |
| 502 | jz lookup_pc_arm |
| 503 | |
| 504 | lookup_pc_thumb: |
| 505 | call _block_lookup_address_thumb |
| 506 | jmp *%eax |
| 507 | |
| 508 | lookup_pc_arm: |
| 509 | call _block_lookup_address_arm |
| 510 | jmp *%eax |
| 511 | |
| 512 | # eax: cycle counter |
| 513 | |
| 514 | _execute_arm_translate: |
| 515 | movl (_reg), %ebx # load base register |
| 516 | extract_flags # load flag variables |
| 517 | movl %eax, %edi # load edi cycle counter |
| 518 | |
| 519 | movl REG_PC(%ebx), %eax # load PC |
| 520 | |
| 521 | testl $0x20, REG_CPSR(%ebx) |
| 522 | jnz 1f |
| 523 | |
| 524 | call _block_lookup_address_arm |
| 525 | jmp *%eax # jump to it |
| 526 | |
| 527 | 1: |
| 528 | call _block_lookup_address_thumb |
| 529 | jmp *%eax |
| 530 | |
| 531 | _step_debug_x86: |
| 532 | collapse_flags |
| 533 | # mov $100, %edi |
| 534 | mov %edi, %edx |
| 535 | jmp _step_debug |
| 536 | |
| 537 | .comm _memory_map_read 0x8000 |
| 538 | .comm _memory_map_write 0x8000 |
| 539 | .comm _reg 4 |
| 540 | |
| 541 | |