cue/bin finally implemented
[picodrive.git] / Pico / cd / Pico.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
52 ldr r1, =SekCycleCnt
53 ldr r0, =((488<<16)-PS_STEP_M68K)
54 ldr r6, =CycloneJumpTab
55
56 @ schedule m68k for the first time..
57 ldr r1, [r1]
58 str r0, [sp] @ main target 'left cycle' counter
59 sub r1, r2, r1
60 subs r5, r1, r0, asr #16
61 ble schedule_s68k @ m68k has not enough cycles
62
63 str r5, [sp,#4] @ run_cycle_cnt
64 b CycloneRunLocal
65
66
67
68CycloneEnd_M68k:
69 ldr r3, =SekCycleCnt
70 ldr r0, [sp,#4] @ run_cycle_cnt
71 ldr r1, [r3]
72 str r4, [r7,#0x40] ;@ Save Current PC + Memory Base
99464b62 73 strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
7336a99a 74 sub r0, r0, r5 @ subtract leftover cycles (which should be negative)
75 add r0, r0, r1
76 str r0, [r3]
77
78schedule_s68k:
79 ldr r8, =SekCycleCntS68k
99464b62 80 ldr r10,=SekCycleAimS68k
7336a99a 81 ldr r3, [sp]
82 ldr r8, [r8]
99464b62 83 ldr r10,[r10]
7336a99a 84
99464b62 85 sub r0, r10, r8
66fdc0f0 86 mov r2, r3
87 add r3, r3, r2, asr #1
88 add r3, r3, r2, asr #3 @ cycn_s68k = (cycn + cycn/2 + cycn/8)
7336a99a 89
90 subs r5, r0, r3, asr #16
91 ble schedule_m68k @ s68k has not enough cycles
92
3aa1e148 93 ldr r7, =PicoCpuCS68k
7336a99a 94 str r5, [sp,#4] @ run_cycle_cnt
95 b CycloneRunLocal
96
97
98
99CycloneEnd_S68k:
100 ldr r3, =SekCycleCntS68k
101 ldr r0, [sp,#4] @ run_cycle_cnt
102 ldr r1, [r3]
103 str r4, [r7,#0x40] ;@ Save Current PC + Memory Base
99464b62 104 strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
7336a99a 105 sub r0, r0, r5 @ subtract leftover cycles (should be negative)
106 add r0, r0, r1
107 str r0, [r3]
108
109schedule_m68k:
110 ldr r1, =PS_STEP_M68K
111 ldr r3, [sp] @ main_cycle_cnt
112 ldr r8, =SekCycleCnt
99464b62 113 ldr r10,=SekCycleAim
7336a99a 114 subs r3, r3, r1
115 bmi SekRunPS_end
116
117 ldr r8, [r8]
99464b62 118 ldr r10,[r10]
7336a99a 119 str r3, [sp] @ update main_cycle_cnt
99464b62 120 sub r0, r10, r8
7336a99a 121
122 subs r5, r0, r3, asr #16
123 ble schedule_s68k @ m68k has not enough cycles
124
3aa1e148 125 ldr r7, =PicoCpuCM68k
7336a99a 126 str r5, [sp,#4] @ run_cycle_cnt
127 b CycloneRunLocal
128
129
130
131SekRunPS_end:
3aa1e148 132 ldr r7, =PicoCpuCM68k
133 ldr lr, =PicoCpuCS68k
7336a99a 134 mov r0, #0
0af33fe0 135 str r0, [r7,#0x98] @ remove CycloneEnd handler
136 str r0, [lr,#0x98]
7336a99a 137 @ return
138 add sp, sp, #2*4
ce5be1b5 139 ldmfd sp!, {r4-r8,r10,r11,pc}
7336a99a 140
141
142
7336a99a 143CycloneRunLocal:
144 ;@ r0-3 = Temporary registers
145 ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base
146 ;@ r5 = Cycles
147 ;@ r6 = Opcode Jump table
148 ;@ r7 = Pointer to Cpu Context
149 ;@ r8 = Current Opcode
99464b62 150 ldrb r10,[r7,#0x46];@ r10 = Flags (NZCV)
66fdc0f0 151 ldr r1,[r7,#0x44] ;@ get SR high and IRQ level
99464b62 152 orr r10,r10,r10,lsl #28 ;@ r10 = Flags 0xf0000000, cpsr format
7336a99a 153
154;@ CheckInterrupt:
66fdc0f0 155 movs r0,r1,lsr #24 ;@ Get IRQ level
7336a99a 156 beq NoIntsLocal
157 cmp r0,#6 ;@ irq>6 ?
7336a99a 158 andle r1,r1,#7 ;@ Get interrupt mask
159 cmple r0,r1 ;@ irq<=6: Is irq<=mask ?
0af33fe0 160 bgt CycloneDoInterrupt
7336a99a 161NoIntsLocal:
162
0af33fe0 163;@ Check if our processor is in special state
164;@ and jump to opcode handler if not
165 ldr r0,[r7,#0x58] ;@ state_flags
7336a99a 166 ldrh r8,[r4],#2 ;@ Fetch first opcode
0af33fe0 167 tst r0,#0x03 ;@ special state?
99464b62 168 andeq r10,r10,#0xf0000000
7336a99a 169 ldreq pc,[r6,r8,asl #2] ;@ Jump to opcode handler
170
0af33fe0 171CycloneSpecial2:
172 tst r0,#2 ;@ tracing?
173 bne CycloneDoTrace
174;@ stopped or halted
66fdc0f0 175 sub r4,r4,#2
0af33fe0 176 ldr r1,[r7,#0x98]
7336a99a 177 mov r5,#0
178 bx r1
179