mirror of
				https://github.com/RaySollium99/picodrive.git
				synced 2025-10-27 00:29:39 -04:00 
			
		
		
		
	 1cfc5cc4ce
			
		
	
	
		1cfc5cc4ce
		
	
	
	
	
		
			
			git-svn-id: file:///home/notaz/opt/svn/PicoDrive@576 be3aeb3a-fb24-0410-a615-afba39da0efa
		
			
				
	
	
		
			181 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| @ vim:filetype=armasm
 | |
| 
 | |
| @ 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.
 | |
| 
 | |
| @ (c) Copyright 2007, Grazvydas "notaz" Ignotas
 | |
| @ All Rights Reserved
 | |
| 
 | |
| 
 | |
| .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
 | |
| 
 |