3 \ Double wordset words for hForth
\r
5 \ Worning: Not fully tested yet. Maybe contains some bugs.
\r
8 \ Facelift to be used with other CPUs.
\r
10 \ Fix 'M+'. Thanks M. Edward Borasky.
\r
13 CHAR " PARSE model" ENVIRONMENT? DROP
\r
14 CHAR " PARSE ROM Model" COMPARE 0=
\r
15 [IF] RAM/ROM@ [THEN]
\r
16 GET-ORDER GET-CURRENT
\r
18 FORTH-WORDLIST SET-CURRENT
\r
20 \ 2LITERAL Compilation: ( x1 x2 -- ) \ DOUBLE
\r
21 \ Run-time: ( -- x1 x2 )
\r
22 \ Append the run-time semantics below to the current definition.
\r
23 \ On run-time, place cell pair x1 x2 on the stack.
\r
24 : 2LITERAL SWAP POSTPONE LITERAL POSTPONE LITERAL ; IMMEDIATE COMPILE-ONLY
\r
26 \ 2CONSTANT ( x1 x2 '<spaces>name' -- ) \ DOUBLE
\r
27 \ name Execution: ( -- x1 x2 )
\r
28 \ Create a definition for name with the execution semantics.
\r
29 CHAR " PARSE model" ENVIRONMENT? DROP
\r
30 CHAR " PARSE ROM Model" COMPARE 0=
\r
31 CHAR " PARSE model" ENVIRONMENT? DROP
\r
32 CHAR " PARSE RAM Model" COMPARE 0= OR
\r
34 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
36 : 2CONSTANT CREATE SWAP , , DOES> DUP @ SWAP CELL+ @ ;
\r
38 : 2CONSTANT CREATE SWAP , , DOES>
\r
41 1 CELLS [BX] BX MOV,
\r
46 CHAR " PARSE model" ENVIRONMENT? DROP
\r
47 CHAR " PARSE EXE Model" COMPARE 0=
\r
49 :NONAME EXECUTE POSTPONE 2LITERAL ;
\r
50 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
52 : 2CONSTANT CREATE SWAP , , compiles> DOES> DUP @ SWAP CELL+ @ ;
\r
54 : 2CONSTANT CREATE SWAP , , compiles> DOES>
\r
57 1 CELLS [BX] BX MOV,
\r
63 \ 2VARIABLE ( '<spaces>name' -- ) \ DOUBLE
\r
64 \ name Execution: ( -- a_addr )
\r
65 \ Create a definition for name with the execution semantics.
\r
66 : 2VARIABLE CREATE 2 CELLS ALLOT ;
\r
68 \ D+ ( d1|ud1 d2|ud2 -- d3|ud3 ) \ DOUBLE
\r
69 \ Add two double numbers, giving the double sum.
\r
71 \ Already defined in .ASM source.
\r
73 \ D- ( d1|ud1 d2|ud2 -- d3|ud3 ) \ DOUBLE
\r
74 \ Subtract d2|ud2 from d1|ud1, giving the difference d3|ud3.
\r
75 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
91 \ D. ( d -- ) \ DOUBLE
\r
92 \ Display d in free field format followed by a space.
\r
94 \ Already defined in .ASM source.
\r
96 \ D.R ( d n -- ) \ DOUBLE
\r
97 \ Display d right-justified in field of width n.
\r
99 \ Already defined in OPTIONAL.F .
\r
101 \ D0< ( d -- flag ) \ DOUBLE
\r
102 \ flag is true if and only if d is less than 0.
\r
103 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
116 \ D0= ( xd -- flag ) \ DOUBLE
\r
117 \ flag is true if and only if d is 0.
\r
118 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
133 \ D2* ( xd1 -- xd2 ) \ DOUBLE
\r
134 \ xd2 is the result of shifting xd1 one bit toward the
\r
135 \ most-significant bit, filling the vacated least-significant
\r
137 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
150 \ D2/ ( xd1 -- xd2 ) \ DOUBLE
\r
151 \ xd2 is the result of shifting xd1 one bit toward the least-
\r
152 \ significant bit, leaving the most-significant bit unchanged.
\r
153 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
155 : D2/ >R 1 RSHIFT R@ 1 AND IF TRUE 1 RSHIFT INVERT OR THEN R> 2/ ; \ by W. Baden
\r
166 \ D< ( d1 d2 --- flag ) \ DOUBLE
\r
167 \ flag is true if and only if d1 is less than d2.
\r
168 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
170 : D< ROT 2DUP = IF 2DROP U< EXIT THEN
\r
192 \ D= ( xd1 xd2 --- flag ) \ DOUBLE
\r
193 \ flag is true if and only if xd1 is bit-for-bit the same as xd2.
\r
194 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
213 \ D>S ( d -- n ) \ DOUBLE
\r
214 \ n is the equivalent of d. An ambiguous condition exists if
\r
215 \ d lies outside the range of a signed single-cell number.
\r
216 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
218 : D>S OVER S>D NIP <> IF -11 THROW THEN ; \ result out of range
\r
228 -11 # BX MOV, \ result out of range
\r
233 \ DABS ( d --- ud ) \ DOUBLE
\r
234 \ ud is the absolute value of d.
\r
235 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
237 : DABS DUP 0< IF DNEGATE THEN ;
\r
252 \ DMAX ( d1 d2 --- d3 ) \ DOUBLE
\r
253 \ d3 is the greater of d1 and d2.
\r
254 : DMAX 2OVER 2OVER D< IF 2SWAP THEN 2DROP ;
\r
256 \ DMIN ( d1 d2 --- d3 ) \ DOUBLE
\r
257 \ d3 is the lesser of d1 and d2.
\r
258 : DMIN 2OVER 2OVER D< 0= IF 2SWAP THEN 2DROP ;
\r
260 \ DNEGATE ( d1 --- d2 ) \ DOUBLE
\r
261 \ d2 is the negation of d1.
\r
262 \ Already defined in .ASM source.
\r
264 \ M*/ ( d1 n1 +n2 --- d2 ) \ DOUBLE
\r
265 \ Multiply d1 by n1 producing the triple-cell intermediate
\r
266 \ result t. Divide t by +n2 giving the double-cell quotient d2.
\r
267 \ An ambiguous condition exists if +n2 is zero or negative, or
\r
268 \ the quotient lies outside of the range of a double-precision
\r
270 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
273 : T* TUCK UM* 2SWAP UM* SWAP >R 0 D+ R> ROT ROT ; ( u . u -- u . . )
\r
274 : T/ DUP >R UM/MOD ROT ROT R> UM/MOD NIP SWAP ; ( u . . u -- u . )
\r
275 : M*/ >R T* R> T/ ; ( u . u u -- u . )
\r
282 DI POP, \ high significant part of d1
\r
283 AX POP, \ low significant part of d1
\r
286 DX PUSH, \ save sign of the result
\r
298 CX MUL, \ lower partial product DX:AX
\r
299 AX DI XCHG, \ lower partial product DX:DI
\r
300 DX BX MOV, \ lower partial product BX:DI
\r
301 CX MUL, \ lower partial product BX:DI, upper partial product DX:AX
\r
303 0 # DX ADC, \ intermediate product DX:AX:DI
\r
304 BX POP, \ restore n2
\r
308 AX DI XCHG, \ upper part of the quotient in DI
\r
309 BX DIV, \ quotient DI:AX
\r
311 5 L# JS, \ DI:AX does not fit in double signed integer
\r
312 CX POP, \ restore sign of the result
\r
323 -11 # BX MOV, \ result out of range
\r
326 -12 # BX MOV, \ argument type mismatch
\r
329 -10 # BX MOV, \ divide by zero
\r
334 \ M+ ( d1|ud1 n --- d2|ud2 ) \ DOUBLE
\r
335 \ Add n to d1|ud1, giving the sum d2|ud2.
\r
336 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
341 BX AX MOV, \ move stack top to AX for sign-extend
\r
342 CWD, \ DX:AX now has 32-bit value
\r
343 BX POP, \ upper half of second argument
\r
344 CX POP, \ lower half of second argument
\r
345 AX CX ADD, \ add lower halves
\r
346 DX BX ADC, \ add upper halves with carry - sum now in BX:CX
\r
347 CX PUSH, \ push lower half of result to stack
\r
352 \ 2ROT ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 ) \ DOUBLE EXT
\r
353 \ Rotate the top three cell pairs on the stack bringing cell
\r
354 \ pair x1 x2 to the top of the stack.
\r
355 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
357 : 2ROT 2>R 2SWAP 2R> 2SWAP ;
\r
364 1 CELLS [DI] AX XCHG,
\r
374 \ DU< ( ud1 ud2 --- flag ) \ DOUBLE EXT
\r
375 \ flag is true if and only if ud1 is less than ud2.
\r
376 CHAR " PARSE ASM8086" ENVIRONMENT? 0=
\r
378 : DU< ROT 2DUP = IF 2DROP U< EXIT THEN
\r
400 envQList SET-CURRENT
\r
402 -1 CONSTANT DOUBLE-EXT
\r
404 SET-CURRENT SET-ORDER
\r
406 CHAR " PARSE model" ENVIRONMENT? DROP
\r
407 CHAR " PARSE ROM Model" COMPARE 0=
\r
408 [IF] RAM/ROM! [THEN]
\r
411 CHAR " PARSE FILE" ENVIRONMENT?
\r
413 0= [IF] << CON [THEN]
\r