57
|
1 ; 6809 32/16 divison for a forth environment
|
|
2 ; 2012-06-20, 2014-07-01 J.E. Klasek j+forth@klasek.at
|
|
3 ;
|
|
4 ; There are two implementations:
|
|
5 ; TALBOT just for analysis, not really used here.
|
|
6 ; EFORTH advanced and optimized version for ef09
|
|
7 ;
|
|
8 ; EFORTH version's special cases:
|
|
9 ; overflow: quotient = $FFFF, remainder = divisor
|
|
10 ; underflow: quotient = $0000, remainder = dividend low
|
|
11 ; division by zero: quotient = $FFFF, remainder = $0000
|
|
12
|
|
13 org $100
|
|
14 lds #$100
|
|
15 ldu #$8000
|
|
16
|
|
17 ; Testvalues:
|
|
18 ;
|
|
19 ; DIVH DIVL DVSR QUOT REM comment
|
|
20 ;
|
|
21 ; 0100 0000 FFFF 0100 0100 maximum divisor
|
|
22 ; 0000 0001 8000 0000 0001 underflow (REM = DIVL)
|
|
23 ; 0000 5800 3000 0001 1800 normal divsion
|
|
24 ; 5800 0000 3000 FFFF 3000 overflow
|
|
25 ; 0000 0001 0000 FFFF 0000 overflow (division by zero)
|
|
26 ;
|
|
27
|
|
28 DIVH EQU $0000
|
|
29 DIVL EQU $5800
|
|
30 DVSR EQU $3000
|
|
31
|
|
32 bra EFORTH ; comment out to try TALBOT's version
|
|
33
|
|
34 ; ------------------------------------
|
|
35 ; Version from Talbot System FIG Forth
|
|
36 ; ------------------------------------
|
|
37
|
|
38 TALBOT:
|
|
39
|
|
40 ; sample parameters on forth parameter stack (U) ...
|
|
41 ldd #DIVL ; dividend low word
|
|
42 pshu d
|
|
43 ldd #DIVH ; dividend high word
|
|
44 pshu d
|
|
45 ldd #DVSR ; divisor
|
|
46 pshu d
|
|
47
|
|
48 USLASH: ldd 2,u ; dividend swap H/L word
|
|
49 ldx 4,u
|
|
50 stx 2,u
|
|
51 std 4,u
|
|
52 asl 3,u ; initial shift of L word
|
|
53 rol 2,u
|
|
54 ldx #$10
|
|
55 USL1: rol 5,u ; shift H word
|
|
56 rol 4,u
|
|
57 ldd 4,u
|
|
58 subd ,u ; does divisor fit?
|
|
59 andcc #$fe ; clc - clear carry flag
|
|
60 bmi USL2
|
|
61 std 4,u ; fits -> quotient = 1
|
|
62 orcc #$01 ; sec - set carry flag
|
|
63 USL2: rol 3,u ; L word/quotient
|
|
64 rol 2,u
|
|
65 leax -1,x
|
|
66 bne USL1
|
|
67 leau 2,u ; drop divisor from parameter stack
|
|
68
|
|
69 ; into registers for simulator ...
|
|
70
|
|
71 ldx ,u ; quotient on TOS
|
|
72 ldd 2,u ; remainder on 2nd
|
|
73
|
|
74 realexit:
|
|
75 sync
|
|
76
|
|
77
|
|
78
|
|
79
|
|
80 ; ------------------------------------
|
|
81 ; Version from J.E. Klasek, replacing
|
|
82 ; high-level variant in eFORTH.
|
|
83 ; ------------------------------------
|
|
84
|
|
85 EFORTH:
|
|
86 ; sample parameters on forth parameter stack (S) ...
|
|
87 ldd #DIVL ; dividend low word
|
|
88 pshs d
|
|
89 ldd #DIVH ; dividend high word
|
|
90 pshs d
|
|
91 ldd #DVSR ; divisor
|
|
92 pshs d
|
|
93
|
|
94 ; U/ ( udl udh un -- ur uq )
|
|
95 ; Unsigned divide of a double by a single. Return mod and quotient.
|
|
96 ;
|
|
97 ; Special cases:
|
|
98 ; 1. overflow: quotient overflow if dividend is to great (remainder = divisor),
|
|
99 ; remainder is set to $FFFF -> special handling.
|
|
100 ; This is checked also right before the main loop.
|
|
101 ; 2. underflow: divisor does not fit into dividend -> remainder
|
|
102 ; get the value of the dividend -> automatically covered.
|
|
103
|
|
104 USLASH2:
|
|
105 ldx #16
|
|
106 ldd 2,s ; udh
|
|
107 cmpd ,s ; dividend to great?
|
|
108 bhs UMMODOV ; quotient overflow!
|
|
109 asl 5,s ; udl low
|
|
110 rol 4,s ; udl high
|
|
111
|
|
112 UMMOD1: rolb ; got one bit from udl
|
|
113 rola
|
|
114 bcs UMMOD2 ; bit 16 means always greater as divisor
|
|
115 cmpd ,s ; divide by un
|
|
116 bhs UMMOD2 ; higher or same as divisor?
|
|
117 andcc #$fe ; clc - clear carry flag
|
|
118 bra UMMOD3
|
|
119 UMMOD2: subd ,s
|
|
120 orcc #$01 ; sec - set carry flag
|
|
121 UMMOD3: rol 5,s ; udl, quotient shifted in
|
|
122 rol 4,s
|
|
123 leax -1,x
|
|
124 bne UMMOD1
|
|
125
|
|
126 ldx 4,s ; quotient
|
|
127 cmpd ,s ; remainder >= divisor -> overflow
|
|
128 blo UMMOD4
|
|
129 UMMODOV:
|
|
130 ldd ,s ; remainder set to divisor
|
|
131 ldx #$FFFF ; quotient = FFFF (-1) marks overflow
|
|
132 ; (case 1)
|
|
133 UMMOD4:
|
|
134 leas 2,s ; un (divisor thrown away)
|
|
135 stx ,s ; quotient to TOS
|
|
136 std 2,s ; remainder 2nd
|
|
137
|
|
138 bra realexit
|
|
139
|
|
140 ; not reached
|
|
141 pulu pc ; eFORTH NEXT
|
|
142
|
|
143 enddata
|
|
144
|
|
145 end
|