32x: built-in BIOS; reset handling; 68k memhandler split
[picodrive.git] / pico / cd / pico_arm.s
CommitLineData
7336a99a 1@ vim:filetype=armasm
2
3aa1e148 3@ SekRunPS runs PicoCpuCM68k and PicoCpuCS68k interleaved in steps of PS_STEP_M68K
7336a99a 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
3aa1e148 16.extern PicoCpuCM68k
17.extern PicoCpuCS68k
7336a99a 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:
ce5be1b5 31 stmfd sp!, {r4-r8,r10,r11,lr}
7336a99a 32 sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt
33
34 @ override CycloneEnd for both contexts
3aa1e148 35 ldr r7, =PicoCpuCM68k
36 ldr lr, =PicoCpuCS68k
7336a99a 37 ldr r2, =CycloneEnd_M68k
38 ldr r3, =CycloneEnd_S68k
0af33fe0 39 str r2, [r7,#0x98]
40 str r3, [lr,#0x98]
7336a99a 41
42 @ update aims
43 ldr r8, =SekCycleAim
99464b62 44 ldr r10,=SekCycleAimS68k
7336a99a 45 ldr r2, [r8]
99464b62 46 ldr r3, [r10]
7336a99a 47 add r2, r2, r0
48 add r3, r3, r1
49 str r2, [r8]
99464b62 50 str r3, [r10]
7336a99a 51
58b75cc5 52 ldr r6, =CycloneJumpTab
7336a99a 53 ldr r1, =SekCycleCnt
54 ldr r0, =((488<<16)-PS_STEP_M68K)
58b75cc5 55 str r6, [r7,#0x54]
56 str r6, [lr,#0x54] @ make copies to avoid literal pools
7336a99a 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
99464b62 75 strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
7336a99a 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
99464b62 82 ldr r10,=SekCycleAimS68k
7336a99a 83 ldr r3, [sp]
84 ldr r8, [r8]
99464b62 85 ldr r10,[r10]
7336a99a 86
99464b62 87 sub r0, r10, r8
66fdc0f0 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)
7336a99a 91
92 subs r5, r0, r3, asr #16
93 ble schedule_m68k @ s68k has not enough cycles
94
3aa1e148 95 ldr r7, =PicoCpuCS68k
7336a99a 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
99464b62 106 strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
7336a99a 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
99464b62 115 ldr r10,=SekCycleAim
7336a99a 116 subs r3, r3, r1
117 bmi SekRunPS_end
118
119 ldr r8, [r8]
99464b62 120 ldr r10,[r10]
7336a99a 121 str r3, [sp] @ update main_cycle_cnt
99464b62 122 sub r0, r10, r8
7336a99a 123
124 subs r5, r0, r3, asr #16
125 ble schedule_s68k @ m68k has not enough cycles
126
3aa1e148 127 ldr r7, =PicoCpuCM68k
7336a99a 128 str r5, [sp,#4] @ run_cycle_cnt
129 b CycloneRunLocal
130
131
132
133SekRunPS_end:
3aa1e148 134 ldr r7, =PicoCpuCM68k
135 ldr lr, =PicoCpuCS68k
7336a99a 136 mov r0, #0
0af33fe0 137 str r0, [r7,#0x98] @ remove CycloneEnd handler
138 str r0, [lr,#0x98]
7336a99a 139 @ return
140 add sp, sp, #2*4
ce5be1b5 141 ldmfd sp!, {r4-r8,r10,r11,pc}
7336a99a 142
143
144
7336a99a 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
99464b62 152 ldrb r10,[r7,#0x46];@ r10 = Flags (NZCV)
66fdc0f0 153 ldr r1,[r7,#0x44] ;@ get SR high and IRQ level
99464b62 154 orr r10,r10,r10,lsl #28 ;@ r10 = Flags 0xf0000000, cpsr format
7336a99a 155
156;@ CheckInterrupt:
66fdc0f0 157 movs r0,r1,lsr #24 ;@ Get IRQ level
7336a99a 158 beq NoIntsLocal
159 cmp r0,#6 ;@ irq>6 ?
7336a99a 160 andle r1,r1,#7 ;@ Get interrupt mask
161 cmple r0,r1 ;@ irq<=6: Is irq<=mask ?
0af33fe0 162 bgt CycloneDoInterrupt
7336a99a 163NoIntsLocal:
164
0af33fe0 165;@ Check if our processor is in special state
166;@ and jump to opcode handler if not
167 ldr r0,[r7,#0x58] ;@ state_flags
7336a99a 168 ldrh r8,[r4],#2 ;@ Fetch first opcode
0af33fe0 169 tst r0,#0x03 ;@ special state?
99464b62 170 andeq r10,r10,#0xf0000000
7336a99a 171 ldreq pc,[r6,r8,asl #2] ;@ Jump to opcode handler
172
0af33fe0 173CycloneSpecial2:
174 tst r0,#2 ;@ tracing?
175 bne CycloneDoTrace
176;@ stopped or halted
66fdc0f0 177 sub r4,r4,#2
0af33fe0 178 ldr r1,[r7,#0x98]
7336a99a 179 mov r5,#0
180 bx r1
181