📄 shdelay.src
字号:
;
; Copyright(c) 1998,1999 SIC/Hitachi,Ltd.
;
; Module Name:
;
; shdelay.src
;
; Revision History:
;
; 26th April 1999 Released
.include "kxshx.h"
.include "shx.inc"
.include "platform.inc"
.import _IsClockFast
;==============================================================================
; clock cycle time calculations
; assume: SH4 instruction times (3 cycles/loop iteration) CYCLES
; 15 or 20MHz (SPEED)
; no delay in the cache (0 cycle delay from cache->instruction pipeline)
; and 4x overdrive (OVERDRIVE)
; ignore overhead loading into cache and jsr/rts
; input in microseconds
;
; loop count = delay time * conversion factor
; conversion factor = (SPEED*OVERDRIVE)/(CYCLES*10^6)
;
; result is divided into a 32.32 bit fixed point number)
; fast = 20 MHz -> 26 2/3
; slow = 15 MHz -> 20
CLOCK_20_HIGH: .equ 26 ; 26 & 2/3
CLOCK_20_LOW: .equ 0xAAAAAAAA ; 2/3 (as hex fraction)
CLOCK_15_HIGH: .equ 20 ; 20 (assuming exactly 15 MHz)
CLOCK_15_LOW: .equ 0x00000000 ; frac = 0
;/*****************************************************************************
;* FUNCTION : _AdjustMicroSecondsToLoopCount
;* DESCRIPTION : convert micro seconds to loop count
;* INPUTS : DWORD dwLoopCount - the number of iterations to loop
;* OUTPUTS : void
;* DESIGN NOTES :
;* CAUTIONS : this function only works for BusyWait and
;* the InlineDelay macro in shdelay.h
;* THE CALCULATION MUST BE REDONE FOR DIFFERENT
;* CLOCK SPEEDS, CACHE SPEEDS, or DIFFERENT CPUs
;* This function uses the stack, so it doesn't work in ISRs
;* LIMITS : The time limit to wait is about 100-200 seconds
;* (4 billion / 1 million / 20(or27))
;*****************************************************************************/
LEAF_ENTRY _AdjustMicroSecondsToLoopCount
; find the clock speed
sts.l PR,@-R15
mov #_IsClockFast,r0 ; Convert desired usecs to clocks
jsr @r0 ; returns R0=0 if slow, else fast
nop
lds.l @R15+,PR
tst r0,r0 ; if 0 (slow clock), 1->T
bt slow_clock
fast_clock:
; fast clock parameters
mov #CLOCK_20_HIGH,r0
mov #CLOCK_20_LOW,r1
bra continue
nop
slow_clock:
; slow clock parameters
mov #CLOCK_15_HIGH,r0
mov #CLOCK_15_LOW,r1
continue:
; using 32x32->64 bit and 32x32->32 bit multiplies:
; r0 = ((CLKH<<32) * delay + CLKL * delay ) >> 32
dmulu.l r4,r1
sts mach,r1
mul.l r4,r0
sts macl,r0
rts
add r1,r0 ; delayed slot, result into r0
ENTRY_END _AdjustMicroSecondsToLoopCount
;/*****************************************************************************
;* FUNCTION : _BusyWait
;* DESCRIPTION : tight assembly loop for a busy wait
;* INPUTS : R4 = DWORD dwLoopCount - the number of iterations to loop
;* OUTPUTS : void
;* DESIGN NOTES :
;* CAUTIONS : This has a roughly proportional relation to REAL time!
;* a small extra delay needs to be added in for subroutine
;* linkage and cache load delays which is not considered
;* in the calculation from clock speed to real time
;* (use the InlineBusyWait macro for smaller overhead delays)
;*****************************************************************************/
LEAF_ENTRY _BusyWait
tst r4,r4 ; delay already zero? (1 clock)
delay:
bf/s delay ; delayed slot branch (2 clocks, 1 when done)
dt r4 ; decrement count & test for 0 (1 clock)
rts ; done
nop
ENTRY_END _BusyWait
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -