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 | |
33 | SekRunPS: |
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 | |
73 | CycloneEnd_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 | |
83 | schedule_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 | |
104 | CycloneEnd_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 | |
114 | schedule_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 | |
136 | SekRunPS_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 |
148 | CycloneRunLocal: |
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 |
166 | NoIntsLocal: |
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 |
176 | CycloneSpecial2: |
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 |