forked from KolibriOS/kolibrios
136 lines
5.7 KiB
NASM
136 lines
5.7 KiB
NASM
;throttle_divide.asm
|
|
;
|
|
;********************************************************************************
|
|
;* div16u *
|
|
;* Second Level Subroutine *
|
|
;* *
|
|
;* Program from Atmel file avr200.asm *
|
|
;* *
|
|
;* Since the 25kHz pwm cycle is 64 clock cycles long, this subroutine *
|
|
;* requires 3.67 to 3.92 25kHz clock cycles. *
|
|
;* *
|
|
;* A single line was added which adds 3 to Cycle_count *
|
|
;* *
|
|
;* Inputs: HILOCAL2:HILOCAL1 and B_TEMPLOCAL1:B_TEMPLOCAL *
|
|
;* Returns: HILOCAL2:HILOCAL1 = HILOCAL2:HILOCAL1 / B_TEMPLOCAL1:B_TEMPLOCAL *
|
|
;* LOLOCAL2:LOLOCAL1 = remainder *
|
|
;* Changed: B_TEMPLOCAL2 *
|
|
;* *
|
|
;* Calls: Not allowed *
|
|
;********************************************************************************
|
|
|
|
|
|
B_TEMPLOCAL2 dcnt16u ; Local counter
|
|
|
|
HILOCAL1 dd16uL ; 16 bit Innput
|
|
HILOCAL2 dd16uH
|
|
|
|
B_TEMPLOCAL dv16uL ; 16 bit Input
|
|
B_TEMPLOCAL1 dv16uH
|
|
|
|
HILOCAL1 dres16uL ; 16 bit Output
|
|
HILOCAL2 dres16uH
|
|
|
|
LOWLOCAL1 drem16uL ; 16 bit Remainder
|
|
LOWLOCAL2 drem16uH ;
|
|
|
|
|
|
|
|
;<ATMEL ROUTINE>
|
|
;***************************************************************************
|
|
;*
|
|
;* "div16u" - 16/16 Bit Unsigned Division
|
|
;*
|
|
;* This subroutine divides the two 16-bit numbers
|
|
;* "dd16uH:dd16uL" (dividend) and "dv16uH:dv16uL" (divisor).
|
|
;* The result is placed in "dres16uH:dres16uL" and the remainder in
|
|
;* "drem16uH:drem16uL".
|
|
;*
|
|
;* Number of words :19
|
|
;* Number of cycles :235/251 (Min/Max)
|
|
;* Low registers used :2 (drem16uL,drem16uH)
|
|
;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH,
|
|
;* dcnt16u)
|
|
;*
|
|
;***************************************************************************
|
|
|
|
;***** Subroutine Register Variables
|
|
|
|
;.def drem16uL= r14 ; Reassigned
|
|
;.def drem16uH= r15
|
|
;.def dres16uL= r16
|
|
;.def dres16uH= r17
|
|
;.def dd16uL= r16
|
|
;.def dd16uH= r17
|
|
;.def dv16uL= r18
|
|
;.def dv16uH= r19
|
|
;.def dcnt16u= r20
|
|
|
|
;***** Code
|
|
|
|
div16u:
|
|
clr drem16uL ; clear remainder Low byte
|
|
sub drem16uH,drem16uH ; clear remainder High byte and carry
|
|
ldi dcnt16u,17 ; init loop counter
|
|
|
|
d16u_1:
|
|
rol dd16uL ; shift left dividend
|
|
rol dd16uH
|
|
dec dcnt16u ; decrement counter
|
|
brne d16u_2 ; if done
|
|
|
|
subi Cycle_count,256-3 ; Add 3 to Cycle_count
|
|
|
|
ret ; return
|
|
|
|
d16u_2:
|
|
rol drem16uL ; shift dividend into remainder
|
|
rol drem16uH
|
|
|
|
sub drem16uL,dv16uL ; remainder = remainder - divisor
|
|
sbc drem16uH,dv16uH ;
|
|
|
|
brcc d16u_3 ;
|
|
|
|
add drem16uL,dv16uL ; if result negative
|
|
adc drem16uH,dv16uH ; restore remainder
|
|
clc ; clear carry to be shifted into result
|
|
rjmp d16u_1 ;
|
|
|
|
d16u_3: ; if result NOT negative
|
|
sec ; set carry to be shifted into result
|
|
rjmp d16u_1
|
|
|
|
;<END ATMEL ROUTINE>
|
|
|
|
;********************************************************************************
|
|
;* DIVIDE_16_SIMPLE *
|
|
;* Second Level Subroutine *
|
|
;* *
|
|
;* Inputs: dd16uH:dd16ul and dv16uL *
|
|
;* Returns: dres16uH:dres16uL = dd8uH:dd8uL / 2^dv16uL *
|
|
;* *
|
|
;* Changed: nothing else *
|
|
;* N.B that dd16uH, dd16uL, dv16uH and dv16uL are aliases for: *
|
|
;* dd16uH=error_hi *
|
|
;* dd16uL=error_lo *
|
|
;* dv16uH=B_TempX *
|
|
;* dv16uL=B_TempX *
|
|
;* dcnt16u=B_TempX *
|
|
;* Calls: Not allowed *
|
|
;********************************************************************************
|
|
|
|
|
|
DIVIDE_16_SIMPLE:
|
|
inc dv16uL
|
|
DIVIDE_16_SIMPLE_LOOP:
|
|
dec dv16uL ; decrement counter
|
|
brne DIVIDE_BY_2
|
|
ret
|
|
|
|
DIVIDE_BY_2:
|
|
asr dd16uH ; divide by two
|
|
ror dd16uL
|
|
rjmp DIVIDE_16_SIMPLE_LOOP
|
|
|