pass jumptable ptr from C
[cyclone68000.git] / tools / idle.s
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 idle_data:
12 have_patches:
13   .word 0
14   .word Op____
15   .word Op6002
16   .word Op6602
17   .word Op6702
18
19 .equ patch_desc_table_size, 10
20
21 @       to             from
22 patch_desc_table:
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
33
34
35 .text
36 .align 2
37
38
39 .global CycloneInitIdleJT @ jt
40
41 CycloneInitIdleJT:
42     adr     r12,offset_table
43     ldr     r2, [r12, #1*4] @ =patch_desc_table-ot
44     mov     r3, r0          @ =CycloneJumpTab
45     add     r2, r2, r12
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
62     adr     r12,offset_table
63     ldr     r0, [r12, #0*4] @ =idle_data-ot
64     mov     r1, #1
65     str     r1, [r0, r12]   @ have_patches
66     bx      lr
67
68
69 .global CycloneFinishIdleJT @ jt
70
71 CycloneFinishIdleJT:
72     adr     r12,offset_table
73     ldr     r3, [r12, #0*4] @ =idle_data-ot
74     ldr     r1, [r3, r12]!  @ have_patches
75     tst     r1, r1
76     bxeq    lr
77
78     stmfd   sp!, {r4,r5}
79     mov     r5, r3
80     ldr     r2, [r12, #1*4] @ =patch_desc_table-ot
81     mov     r3, r0          @ =CycloneJumpTab
82     ldr     r4, [r5, #1*4]  @ =Op____
83     add     r2, r2, r12     @ =patch_desc_table
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]
91     add     r0, r3, r0, lsl #2
92     str     r4, [r0]              @ Op____
93     str     r4, [r0, #0x800]
94     add     r2, r2, #16
95     subs    r12,r12,#1
96     bgt     cfi_loop
97
98     mov     r1, #0
99     str     r1, [r5]              @ have_patches
100     ldmfd   sp!, {r4,r5}
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
117     b       Op6002
118
119 idle_bne:
120     tst     r10, #0x40000000      @ Z set?
121     moveq   r5, #2                @ 2 is intentional due to strange timing issues
122     inc_counter eq
123     b       Op6602
124
125 idle_beq:
126     tst     r10, #0x40000000      @ Z set?
127     movne   r5, #2
128     inc_counter ne
129     b       Op6702
130
131
132 @ @@@ @
133
134 idle_detector_bcc8:
135     bl      SekIsIdleReady
136     tst     r0, r0
137     beq     exit_detector         @ not yet
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
170     adr     r12,offset_table
171     ldr     r1, [r12]       @ =idle_data-ot
172     mov     r0, r8, lsr #8
173     cmp     r0, #0x66
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
178
179     str     r1, [r6, r8, lsl #2]
180     bx      r1
181
182 exit_detector:
183     mov     r0, r8, lsr #8
184     cmp     r0, #0x66
185     blt     Op6002
186     beq     Op6602
187     b       Op6702
188
189 offset_table:
190     .word idle_data - offset_table
191     .word patch_desc_table - offset_table