mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-04 14:57:45 -04:00

- PicoDrive was originally released by fDave with simple "free for non-commercial use / For commercial use, separate licencing terms must be obtained" license and I kept it in my releases. - in 2011, fDave re-released his code (same that I used as base many years ago) dual licensed with GPLv2 and MAME licenses: https://code.google.com/p/cyclone68000/ Based on the above I now proclaim that the whole source code is licensed under the MAME license as more elaborate form of "for non-commercial use". If that raises any doubt, I announce that all my modifications (which is the vast majority of code by now) is licensed under the MAME license, as it reads in COPYING file in this commit. This does not affect ym2612.c/sn76496.c that were MAME licensed already from the beginning.
185 lines
4.9 KiB
ArmAsm
185 lines
4.9 KiB
ArmAsm
@*
|
|
@* CPU scheduling code
|
|
@* (C) notaz, 2007-2008
|
|
@*
|
|
@* This work is licensed under the terms of MAME license.
|
|
@* See COPYING file in the top-level directory.
|
|
@*
|
|
|
|
@ SekRunPS runs PicoCpuCM68k and PicoCpuCS68k interleaved in steps of PS_STEP_M68K
|
|
@ cycles. This is done without calling CycloneRun and jumping directly to
|
|
@ Cyclone code to avoid pushing/popping all the registers every time.
|
|
|
|
|
|
.equiv PS_STEP_M68K, ((488<<16)/20) @ ~24
|
|
|
|
@ .extern is ignored by gas, we add these here just to see what we depend on.
|
|
.extern CycloneJumpTab
|
|
.extern CycloneDoInterrupt
|
|
.extern PicoCpuCM68k
|
|
.extern PicoCpuCS68k
|
|
.extern SekCycleAim
|
|
.extern SekCycleCnt
|
|
.extern SekCycleAimS68k
|
|
.extern SekCycleCntS68k
|
|
|
|
|
|
.text
|
|
.align 4
|
|
|
|
|
|
.global SekRunPS @ cyc_m68k, cyc_s68k
|
|
|
|
SekRunPS:
|
|
stmfd sp!, {r4-r8,r10,r11,lr}
|
|
sub sp, sp, #2*4 @ sp[0] = main_cycle_cnt, sp[4] = run_cycle_cnt
|
|
|
|
@ override CycloneEnd for both contexts
|
|
ldr r7, =PicoCpuCM68k
|
|
ldr lr, =PicoCpuCS68k
|
|
ldr r2, =CycloneEnd_M68k
|
|
ldr r3, =CycloneEnd_S68k
|
|
str r2, [r7,#0x98]
|
|
str r3, [lr,#0x98]
|
|
|
|
@ update aims
|
|
ldr r8, =SekCycleAim
|
|
ldr r10,=SekCycleAimS68k
|
|
ldr r2, [r8]
|
|
ldr r3, [r10]
|
|
add r2, r2, r0
|
|
add r3, r3, r1
|
|
str r2, [r8]
|
|
str r3, [r10]
|
|
|
|
ldr r6, =CycloneJumpTab
|
|
ldr r1, =SekCycleCnt
|
|
ldr r0, =((488<<16)-PS_STEP_M68K)
|
|
str r6, [r7,#0x54]
|
|
str r6, [lr,#0x54] @ make copies to avoid literal pools
|
|
|
|
@ schedule m68k for the first time..
|
|
ldr r1, [r1]
|
|
str r0, [sp] @ main target 'left cycle' counter
|
|
sub r1, r2, r1
|
|
subs r5, r1, r0, asr #16
|
|
ble schedule_s68k @ m68k has not enough cycles
|
|
|
|
str r5, [sp,#4] @ run_cycle_cnt
|
|
b CycloneRunLocal
|
|
|
|
|
|
|
|
CycloneEnd_M68k:
|
|
ldr r3, =SekCycleCnt
|
|
ldr r0, [sp,#4] @ run_cycle_cnt
|
|
ldr r1, [r3]
|
|
str r4, [r7,#0x40] ;@ Save Current PC + Memory Base
|
|
strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
|
|
sub r0, r0, r5 @ subtract leftover cycles (which should be negative)
|
|
add r0, r0, r1
|
|
str r0, [r3]
|
|
|
|
schedule_s68k:
|
|
ldr r8, =SekCycleCntS68k
|
|
ldr r10,=SekCycleAimS68k
|
|
ldr r3, [sp]
|
|
ldr r8, [r8]
|
|
ldr r10,[r10]
|
|
|
|
sub r0, r10, r8
|
|
mov r2, r3
|
|
add r3, r3, r2, asr #1
|
|
add r3, r3, r2, asr #3 @ cycn_s68k = (cycn + cycn/2 + cycn/8)
|
|
|
|
subs r5, r0, r3, asr #16
|
|
ble schedule_m68k @ s68k has not enough cycles
|
|
|
|
ldr r7, =PicoCpuCS68k
|
|
str r5, [sp,#4] @ run_cycle_cnt
|
|
b CycloneRunLocal
|
|
|
|
|
|
|
|
CycloneEnd_S68k:
|
|
ldr r3, =SekCycleCntS68k
|
|
ldr r0, [sp,#4] @ run_cycle_cnt
|
|
ldr r1, [r3]
|
|
str r4, [r7,#0x40] ;@ Save Current PC + Memory Base
|
|
strb r10,[r7,#0x46] ;@ Save Flags (NZCV)
|
|
sub r0, r0, r5 @ subtract leftover cycles (should be negative)
|
|
add r0, r0, r1
|
|
str r0, [r3]
|
|
|
|
schedule_m68k:
|
|
ldr r1, =PS_STEP_M68K
|
|
ldr r3, [sp] @ main_cycle_cnt
|
|
ldr r8, =SekCycleCnt
|
|
ldr r10,=SekCycleAim
|
|
subs r3, r3, r1
|
|
bmi SekRunPS_end
|
|
|
|
ldr r8, [r8]
|
|
ldr r10,[r10]
|
|
str r3, [sp] @ update main_cycle_cnt
|
|
sub r0, r10, r8
|
|
|
|
subs r5, r0, r3, asr #16
|
|
ble schedule_s68k @ m68k has not enough cycles
|
|
|
|
ldr r7, =PicoCpuCM68k
|
|
str r5, [sp,#4] @ run_cycle_cnt
|
|
b CycloneRunLocal
|
|
|
|
|
|
|
|
SekRunPS_end:
|
|
ldr r7, =PicoCpuCM68k
|
|
ldr lr, =PicoCpuCS68k
|
|
mov r0, #0
|
|
str r0, [r7,#0x98] @ remove CycloneEnd handler
|
|
str r0, [lr,#0x98]
|
|
@ return
|
|
add sp, sp, #2*4
|
|
ldmfd sp!, {r4-r8,r10,r11,pc}
|
|
|
|
|
|
|
|
CycloneRunLocal:
|
|
;@ r0-3 = Temporary registers
|
|
ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base
|
|
;@ r5 = Cycles
|
|
;@ r6 = Opcode Jump table
|
|
;@ r7 = Pointer to Cpu Context
|
|
;@ r8 = Current Opcode
|
|
ldrb r10,[r7,#0x46];@ r10 = Flags (NZCV)
|
|
ldr r1,[r7,#0x44] ;@ get SR high and IRQ level
|
|
orr r10,r10,r10,lsl #28 ;@ r10 = Flags 0xf0000000, cpsr format
|
|
|
|
;@ CheckInterrupt:
|
|
movs r0,r1,lsr #24 ;@ Get IRQ level
|
|
beq NoIntsLocal
|
|
cmp r0,#6 ;@ irq>6 ?
|
|
andle r1,r1,#7 ;@ Get interrupt mask
|
|
cmple r0,r1 ;@ irq<=6: Is irq<=mask ?
|
|
bgt CycloneDoInterrupt
|
|
NoIntsLocal:
|
|
|
|
;@ Check if our processor is in special state
|
|
;@ and jump to opcode handler if not
|
|
ldr r0,[r7,#0x58] ;@ state_flags
|
|
ldrh r8,[r4],#2 ;@ Fetch first opcode
|
|
tst r0,#0x03 ;@ special state?
|
|
andeq r10,r10,#0xf0000000
|
|
ldreq pc,[r6,r8,asl #2] ;@ Jump to opcode handler
|
|
|
|
CycloneSpecial2:
|
|
tst r0,#2 ;@ tracing?
|
|
bne CycloneDoTrace
|
|
;@ stopped or halted
|
|
sub r4,r4,#2
|
|
ldr r1,[r7,#0x98]
|
|
mov r5,#0
|
|
bx r1
|
|
|
|
@ vim:filetype=armasm
|