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