1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
;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
|