| 1 | @ vim:filetype=armasm |
| 2 | |
| 3 | @ ranges/opcodes (idle, normal): |
| 4 | @ 71xx, 73xx - bne.s (8bit offset) |
| 5 | @ 75xx, 77xx - beq.s (8bit offset) |
| 6 | @ 7dxx, 7fxx - bra.s (8bit offset) |
| 7 | |
| 8 | .data |
| 9 | .align 2 |
| 10 | |
| 11 | have_patches: |
| 12 | .word 0 |
| 13 | |
| 14 | .equ patch_desc_table_size, 10 |
| 15 | |
| 16 | patch_desc_table: |
| 17 | .word (0x71fa<<16) | 0x66fa, idle_detector_bcc8, idle_bne, Op6601 @ bne.s |
| 18 | .word (0x71f8<<16) | 0x66f8, idle_detector_bcc8, idle_bne, Op6601 @ bne.s |
| 19 | .word (0x71f6<<16) | 0x66f6, idle_detector_bcc8, idle_bne, Op6601 @ bne.s |
| 20 | .word (0x71f2<<16) | 0x66f2, idle_detector_bcc8, idle_bne, Op6601 @ bne.s |
| 21 | .word (0x75fa<<16) | 0x67fa, idle_detector_bcc8, idle_beq, Op6701 @ beq.s |
| 22 | .word (0x75f8<<16) | 0x67f8, idle_detector_bcc8, idle_beq, Op6701 @ beq.s |
| 23 | .word (0x75f6<<16) | 0x67f6, idle_detector_bcc8, idle_beq, Op6701 @ beq.s |
| 24 | .word (0x75f2<<16) | 0x67f2, idle_detector_bcc8, idle_beq, Op6701 @ beq.s |
| 25 | .word (0x7dfe<<16) | 0x60fe, idle_detector_bcc8, idle_bra, Op6001 @ bra.s |
| 26 | .word (0x7dfc<<16) | 0x60fc, idle_detector_bcc8, idle_bra, Op6001 @ bra.s |
| 27 | |
| 28 | |
| 29 | .text |
| 30 | .align 2 |
| 31 | |
| 32 | |
| 33 | .global CycloneInitIdle |
| 34 | |
| 35 | CycloneInitIdle: |
| 36 | ldr r3, =CycloneJumpTab |
| 37 | ldr r2, =patch_desc_table |
| 38 | mov r12,#patch_desc_table_size |
| 39 | |
| 40 | cii_loop: |
| 41 | ldrh r0, [r2] |
| 42 | ldr r1, [r2, #4] @ detector |
| 43 | str r1, [r3, r0, lsl #2] |
| 44 | ldrh r0, [r2, #2] |
| 45 | ldr r1, [r2, #8] @ idle |
| 46 | add r0, r3, r0, lsl #2 |
| 47 | str r1, [r0] |
| 48 | ldr r1, [r2, #12] @ normal |
| 49 | str r1, [r0, #0x800] |
| 50 | add r2, r2, #16 |
| 51 | subs r12,r12,#1 |
| 52 | bgt cii_loop |
| 53 | |
| 54 | ldr r0, =have_patches |
| 55 | mov r1, #1 |
| 56 | str r1, [r0] |
| 57 | bx lr |
| 58 | |
| 59 | |
| 60 | .global CycloneFinishIdle |
| 61 | |
| 62 | CycloneFinishIdle: |
| 63 | ldr r0, =have_patches |
| 64 | ldr r0, [r0] |
| 65 | tst r0, r0 |
| 66 | bxeq lr |
| 67 | |
| 68 | ldr r3, =CycloneJumpTab |
| 69 | ldr r2, =patch_desc_table |
| 70 | mov r12,#patch_desc_table_size |
| 71 | |
| 72 | cfi_loop: |
| 73 | ldrh r0, [r2] |
| 74 | ldr r1, [r2, #12] @ normal |
| 75 | str r1, [r3, r0, lsl #2] |
| 76 | ldrh r0, [r2, #2] |
| 77 | ldr r1, =Op____ |
| 78 | add r0, r3, r0, lsl #2 |
| 79 | str r1, [r0] |
| 80 | str r1, [r0, #0x800] |
| 81 | add r2, r2, #16 |
| 82 | subs r12,r12,#1 |
| 83 | bgt cfi_loop |
| 84 | |
| 85 | ldr r0, =have_patches |
| 86 | mov r1, #0 |
| 87 | str r1, [r0] |
| 88 | bx lr |
| 89 | |
| 90 | |
| 91 | |
| 92 | .macro inc_counter cond |
| 93 | @ ldr\cond r0, [r7, #0x60] |
| 94 | @ mov r11,lr |
| 95 | @ sub r0, r4, r0 |
| 96 | @ sub r0, r0, #2 |
| 97 | @ bl\cond SekRegisterIdleHit |
| 98 | @ mov lr, r11 |
| 99 | .endm |
| 100 | |
| 101 | idle_bra: |
| 102 | mov r5, #2 |
| 103 | inc_counter |
| 104 | b Op6001 |
| 105 | |
| 106 | idle_bne: |
| 107 | msr cpsr_flg, r10 |
| 108 | movne r5, #2 @ 2 is intentional due to strange timing issues |
| 109 | inc_counter ne |
| 110 | b Op6601 |
| 111 | |
| 112 | idle_beq: |
| 113 | msr cpsr_flg, r10 ;@ ARM flags = 68000 flags |
| 114 | moveq r5, #2 |
| 115 | inc_counter eq |
| 116 | b Op6701 |
| 117 | |
| 118 | |
| 119 | @ @@@ @ |
| 120 | |
| 121 | idle_detector_bcc8: |
| 122 | ldr r0, =(Pico+0x22208) @ Pico.m |
| 123 | ldr r1, =idledet_start_frame |
| 124 | ldr r0, [r0, #0x1c] @ ..frame_count |
| 125 | ldr r1, [r1] |
| 126 | cmp r0, r1 |
| 127 | blt exit_detector @ not yet |
| 128 | |
| 129 | mov r0, r8, asl #24 @ Shift 8-bit signed offset up... |
| 130 | add r0, r4, r0, asr #24 @ jump dest |
| 131 | bic r0, r0, #1 |
| 132 | |
| 133 | mov r1, #0 |
| 134 | sub r1, r1, r8, lsl #24 |
| 135 | mov r1, r1, lsr #24 |
| 136 | sub r1, r1, #2 |
| 137 | bic r1, r1, #1 |
| 138 | |
| 139 | bl SekIsIdleCode |
| 140 | tst r0, r0 |
| 141 | and r2, r8, #0x00ff |
| 142 | orr r2, r2, #0x7100 |
| 143 | orreq r2, r2, #0x0200 |
| 144 | mov r0, r8, lsr #8 |
| 145 | cmp r0, #0x66 |
| 146 | orrgt r2, r2, #0x0400 @ 67xx (beq) |
| 147 | orrlt r2, r2, #0x0c00 @ 60xx (bra) |
| 148 | |
| 149 | @ r2 = patch_opcode |
| 150 | sub r0, r4, #2 |
| 151 | ldrh r1, [r0] |
| 152 | mov r11,r2 |
| 153 | mov r3, r7 |
| 154 | bl SekRegisterIdlePatch |
| 155 | cmp r0, #1 @ 0 - ok to patch, 1 - no patch, 2 - remove detector |
| 156 | strlth r11,[r4, #-2] |
| 157 | ble exit_detector |
| 158 | |
| 159 | @ remove detector from Cyclone |
| 160 | mov r0, r8, lsr #8 |
| 161 | cmp r0, #0x66 |
| 162 | ldrlt r1, =Op6001 |
| 163 | ldreq r1, =Op6601 |
| 164 | ldrgt r1, =Op6701 |
| 165 | |
| 166 | ldr r3, =CycloneJumpTab |
| 167 | str r1, [r3, r8, lsl #2] |
| 168 | bx r1 |
| 169 | |
| 170 | exit_detector: |
| 171 | mov r0, r8, lsr #8 |
| 172 | cmp r0, #0x66 |
| 173 | blt Op6001 |
| 174 | beq Op6601 |
| 175 | b Op6701 |
| 176 | |