OpenCores
URL https://opencores.org/ocsvn/8051/8051/trunk

Subversion Repositories 8051

[/] [8051/] [trunk/] [asm/] [DIV16U.asm] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 simont
        mov r5, #0a1h;
2
        mov r4, #054h;
3
        mov r1, #001h;
4
        mov r0, #070h;
5
        lcall DIV16U;
6
        mov p0, r5;
7
        mov p0, r4;
8
        mov p0, r1;
9
        mov p0, r0;
10
 
11
 
12
 
13
 
14
 
15
;26 Oct 00 added code to zero remainder when dividend is zero
16
;26 Oct 00 Change labels from duxxx to duaxxx
17
;19 Dec 99 corrected comments
18
;16 Dec 99 made from DIV32U
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
;
21
;DIV16U is called to divide (unsigned) a 16-bit dividend using a
22
; 16-bit divisor.
23
;
24
;DIV16U solves for quotient and remainder the equation:
25
;
26
; dividend = divisor*quotient + remainder
27
;
28
;Call:
29
;  r5,r4 = dividend
30
;  r1,r0 = divisor
31
;  lcall DIV16U
32
;  jc   divide_by_zero
33
;
34
;Return:
35
; r5,r4 = quotient
36
; r7,r6 = remainder
37
; c flag set to 1 if divide by zero attempted
38
; All registers, acc, b and have been changed.
39
; Data pointer has not been disturbed
40
;
41
;Note:
42
; (1)Most significant (ms) register always listed first when comma
43
;  separates two in a comment. Example: r5,r4 (r5 contains the ms bits)
44
; (2) The algorithm used in this code borrows heavily from work posted
45
;   by John C. Wren who said he got it from a C complier.
46
;
47
;Original author: John Veazey, Ridgecrest, CA, 16 Dec 99
48
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49
;
50
;cseg
51
DIV16U:
52
;
53
;Clear the working quotient
54
;
55
      clr   a
56
      mov   r2,a
57
      mov   r3,a
58
;
59
;b counts the number of places+1 the divisor was initially
60
; shifted left to align its ms bit set with the ms bit set
61
; in the dividend
62
;
63
      mov   b,#1
64
;
65
;Make an error return if trying to divide by zero
66
;
67
      mov   a,r1
68
      orl   a,r0
69
      jz    dua920
70
;
71
;Just return with quotient and remainder zero if dividend is zero
72
;
73
      mov   a,r5;
74
      orl   a,r4;
75
      jnz   dua200;
76
      mov   r7,a;
77
      mov   r6,a;
78
      ajmp  dua910      ;Make a normal return
79
;
80
;Align the msb set in the demoninator with the msb set in the
81
; numerator. Increment the shift count in b each time a shift left
82
; is performed.
83
;
84
dua200:
85
      mov   a,r1        ;Stop if MSB set
86
      rlc   a
87
      jc    dua600
88
      clr   c
89
      mov   a,r5        ;Compare r1 & r5
90
      subb  a,r1
91
      jc    dua600      ; jump if r1>r5
92
      jnz   dua240      ; jump if r1
93
      mov   a,r4        ;r1=r5, so compare r0 & r4
94
      subb  a,r0
95
      jc    dua600      ; jump if r0>r4
96
dua240:
97
      clr   c           ;Now shift the denominator
98
      mov   a,r0        ; left 1 bit position
99
      rlc   a
100
      mov   r0,a
101
      mov   a,r1
102
      rlc   a
103
      mov   r1,a
104
      inc   b           ;Increment b counter and
105
      sjmp  dua200      ; continue
106
;
107
;Compare the shifted divisor with the remainder (what's
108
; left of the dividend)
109
;
110
dua600:
111
      clr   c
112
      mov   a,r5
113
      subb  a,r1
114
      jc    dua720      ;jump if r1>r5
115
      jnz   dua700      ;jump if r1
116
      mov   a,r4
117
      subb  a,r0
118
      jc    dua720      ;jump if r0>r4
119
;
120
;Divisor is equal or smaller, so subtract it off and
121
; get a 1 for the quotient
122
;
123
dua700:
124
      mov   a,r4
125
      clr   c
126
      subb  a,r0
127
      mov   r4,a
128
      mov   a,r5
129
      subb  a,r1
130
      mov   r5,a
131
      clr   c
132
      cpl   c           ;Get a 1 for the quotient
133
      sjmp  dua730
134
;
135
;Divisor is greater, get a 0 for the quotient
136
;
137
dua720:
138
      clr   c
139
;
140
;Shift 0 or 1 into quotient
141
;
142
dua730:
143
      mov   a,r2
144
      rlc   a
145
      mov   r2,a
146
      mov   a,r3
147
      rlc   a           ;Test for overlow removed here because
148
      mov   r3,a        ; it can't happen when dividing 16 by 16
149
;
150
;Now shift the denominator right 1, decrement the counter
151
; in b until b = 0
152
;
153
dua740:
154
      clr   c
155
      mov   a,r1
156
      rrc   a
157
      mov   r1,a
158
      mov   a,r0
159
      rrc   a
160
      mov   r0,a
161
      djnz  b,dua600
162
;
163
;Move quotient and remainder so that quotient is returned in the same
164
; registers as the dividend. This makes it easier to divide repeatedly
165
; by the same number as you would do when converting to a new radix.
166
;
167
      mov   a,r5
168
      mov   r7,a
169
      mov   a,r4
170
      mov   r6,a
171
      mov   a,r3
172
      mov   r5,a
173
      mov   a,r2
174
      mov   r4,a
175
;
176
;Make the normal return
177
;
178
dua910:
179
      clr   c
180
      ret
181
;
182
;Make the error return
183
;
184
dua920:
185
      clr   c
186
      cpl   c
187
      ret
188
;End of DIV16U

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.