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