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