fix operator spr change ARM code bugs
[picodrive.git] / pico / cd / pico_arm.s
... / ...
CommitLineData
1@ vim:filetype=armasm
2
3@ SekRunPS runs PicoCpuCM68k and PicoCpuCS68k interleaved in steps of PS_STEP_M68K
4@ cycles. This is done without calling CycloneRun and jumping directly to
5@ Cyclone code to avoid pushing/popping all the registers every time.
6
7@ (c) Copyright 2007, Grazvydas "notaz" Ignotas
8@ All Rights Reserved
9
10
11.equiv PS_STEP_M68K, ((488<<16)/20) @ ~24
12
13@ .extern is ignored by gas, we add these here just to see what we depend on.
14.extern CycloneJumpTab
15.extern CycloneDoInterrupt
16.extern PicoCpuCM68k
17.extern PicoCpuCS68k
18.extern SekCycleAim
19.extern SekCycleCnt
20.extern SekCycleAimS68k
21.extern SekCycleCntS68k
22
23
24.text
25.align 4
26
27
28.global SekRunPS @ cyc_m68k, cyc_s68k
29
30SekRunPS:
31 stmfd sp!, {r4-r8,r10,r11,lr}
32 sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt
33
34 @ override CycloneEnd for both contexts
35 ldr r7, =PicoCpuCM68k
36 ldr lr, =PicoCpuCS68k
37 ldr r2, =CycloneEnd_M68k
38 ldr r3, =CycloneEnd_S68k
39 str r2, [r7,#0x98]
40 str r3, [lr,#0x98]
41
42 @ update aims
43 ldr r8, =SekCycleAim
44 ldr r10,=SekCycleAimS68k
45 ldr r2, [r8]
46 ldr r3, [r10]
47 add r2, r2, r0
48 add r3, r3, r1
49 str r2, [r8]
50 str r3, [r10]
51
52 ldr r6, =CycloneJumpTab
53 ldr r1, =SekCycleCnt
54 ldr r0, =((488<<16)-PS_STEP_M68K)
55 str r6, [r7,#0x54]
56 str r6, [lr,#0x54] @ make copies to avoid literal pools
57
58 @ schedule m68k for the first time..
59 ldr r1, [r1]
60 str r0, [sp] @ main target 'left cycle' counter
61 sub r1, r2, r1
62 subs r5, r1, r0, asr #16
63 ble schedule_s68k @ m68k has not enough cycles
64
65 str r5, [sp,#4] @ run_cycle_cnt
66 b CycloneRunLocal
67
68
69
70CycloneEnd_M68k:
71 ldr r3, =SekCycleCnt
72 ldr r0, [sp,#4] @ run_cycle_cnt
73 ldr r1, [r3]
74 str r4, [r7,#0x40] ;@ Save Current PC + Memory Base
75 strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
76 sub r0, r0, r5 @ subtract leftover cycles (which should be negative)
77 add r0, r0, r1
78 str r0, [r3]
79
80schedule_s68k:
81 ldr r8, =SekCycleCntS68k
82 ldr r10,=SekCycleAimS68k
83 ldr r3, [sp]
84 ldr r8, [r8]
85 ldr r10,[r10]
86
87 sub r0, r10, r8
88 mov r2, r3
89 add r3, r3, r2, asr #1
90 add r3, r3, r2, asr #3 @ cycn_s68k = (cycn + cycn/2 + cycn/8)
91
92 subs r5, r0, r3, asr #16
93 ble schedule_m68k @ s68k has not enough cycles
94
95 ldr r7, =PicoCpuCS68k
96 str r5, [sp,#4] @ run_cycle_cnt
97 b CycloneRunLocal
98
99
100
101CycloneEnd_S68k:
102 ldr r3, =SekCycleCntS68k
103 ldr r0, [sp,#4] @ run_cycle_cnt
104 ldr r1, [r3]
105 str r4, [r7,#0x40] ;@ Save Current PC + Memory Base
106 strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
107 sub r0, r0, r5 @ subtract leftover cycles (should be negative)
108 add r0, r0, r1
109 str r0, [r3]
110
111schedule_m68k:
112 ldr r1, =PS_STEP_M68K
113 ldr r3, [sp] @ main_cycle_cnt
114 ldr r8, =SekCycleCnt
115 ldr r10,=SekCycleAim
116 subs r3, r3, r1
117 bmi SekRunPS_end
118
119 ldr r8, [r8]
120 ldr r10,[r10]
121 str r3, [sp] @ update main_cycle_cnt
122 sub r0, r10, r8
123
124 subs r5, r0, r3, asr #16
125 ble schedule_s68k @ m68k has not enough cycles
126
127 ldr r7, =PicoCpuCM68k
128 str r5, [sp,#4] @ run_cycle_cnt
129 b CycloneRunLocal
130
131
132
133SekRunPS_end:
134 ldr r7, =PicoCpuCM68k
135 ldr lr, =PicoCpuCS68k
136 mov r0, #0
137 str r0, [r7,#0x98] @ remove CycloneEnd handler
138 str r0, [lr,#0x98]
139 @ return
140 add sp, sp, #2*4
141 ldmfd sp!, {r4-r8,r10,r11,pc}
142
143
144
145CycloneRunLocal:
146 ;@ r0-3 = Temporary registers
147 ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base
148 ;@ r5 = Cycles
149 ;@ r6 = Opcode Jump table
150 ;@ r7 = Pointer to Cpu Context
151 ;@ r8 = Current Opcode
152 ldrb r10,[r7,#0x46];@ r10 = Flags (NZCV)
153 ldr r1,[r7,#0x44] ;@ get SR high and IRQ level
154 orr r10,r10,r10,lsl #28 ;@ r10 = Flags 0xf0000000, cpsr format
155
156;@ CheckInterrupt:
157 movs r0,r1,lsr #24 ;@ Get IRQ level
158 beq NoIntsLocal
159 cmp r0,#6 ;@ irq>6 ?
160 andle r1,r1,#7 ;@ Get interrupt mask
161 cmple r0,r1 ;@ irq<=6: Is irq<=mask ?
162 bgt CycloneDoInterrupt
163NoIntsLocal:
164
165;@ Check if our processor is in special state
166;@ and jump to opcode handler if not
167 ldr r0,[r7,#0x58] ;@ state_flags
168 ldrh r8,[r4],#2 ;@ Fetch first opcode
169 tst r0,#0x03 ;@ special state?
170 andeq r10,r10,#0xf0000000
171 ldreq pc,[r6,r8,asl #2] ;@ Jump to opcode handler
172
173CycloneSpecial2:
174 tst r0,#2 ;@ tracing?
175 bne CycloneDoTrace
176;@ stopped or halted
177 sub r4,r4,#2
178 ldr r1,[r7,#0x98]
179 mov r5,#0
180 bx r1
181