; Copyright (c) 2009-2010, Michael Alyn Miller <malyn@strangeGizmo.com>.
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;
; 1. Redistributions of source code must retain the above copyright notice
; unmodified, this list of conditions, and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright notice,
; this list of conditions and the following disclaimer in the documentation
; and/or other materials provided with the distribution.
; 3. Neither the name of Michael Alyn Miller nor the names of the contributors
; to this software may be used to endorse or promote products derived from
; this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; ======================================================================
; DOUBLE Words
; ======================================================================
; ----------------------------------------------------------------------
; D. [DOUBLE] 8.6.1.0160 "d-dot" ( d -- )
;
; Display d in free field format.
;
; ---
; : D. ( d -- )
; BASE @ 10 <> IF UD. EXIT THEN
; 2DUP D0< >R DABS <# #S R> SIGN #> TYPE SPACE ;
LINKTO(LINK_DOUBLE,0,2,'.',"D")
DDOT: JMP ENTER
.WORD BASE,FETCH,LIT,10,NOTEQUALS,zbranch,_ddot1,UDDOT,EXIT
_ddot1: .WORD TWODUP,DZEROLESS,TOR
.WORD DABS,LESSNUMSIGN,NUMSIGNS,RFROM,SIGN,NUMSIGNGRTR
.WORD TYPE,SPACE
.WORD EXIT
; ----------------------------------------------------------------------
; D- [DOUBLE] 8.6.1.1050 "d-minus" ( d1|ud1 d2|ud2 -- d3|ud3 )
;
; Subtract d2|ud2 from d1|ud1, giving the difference d3|ud3.
LINKTO(DDOT,0,2,'-',"D")
DMINUS: SAVEDE
LDES 0 ; Get the address of d2
XCHG ; ..and move that address into HL
LDES 4 ; Get the address of d1 into DE.
ANA A ; Clear the carry flag.
LDAX D ; Get d1ll into A,
SUB M ; ..subtract d2ll from d1ll,
STAX D ; ..and put the result into d1ll.
INX D ; Increment to d1lh.
INX H ; Increment to d2lh.
LDAX D ; Get d1lh into A,
SBB M ; ..subtract d2lh from d1l,
STAX D ; ..and put the result into d1lh.
INX D ; Increment to d1hl.
INX H ; Increment to d2hl.
LDAX D ; Get d1hl into A,
SBB M ; ..subtract d2hl from d1hl,
STAX D ; ..and put the result into d1hl.
INX D ; Increment to d1hh.
INX H ; Increment to d2hh.
LDAX D ; Get d1hh into A,
SBB M ; ..subtract d2hh from d1hh,
STAX D ; ..and put the result into d1hh.
POP H ; Pop d2l.
POP H ; Pop d2h.
RESTOREDE
NEXT
; ----------------------------------------------------------------------
; D0< [DOUBLE] 8.6.1.1075 "d-zero-less" ( d -- flag )
;
; flag is true if and only if d is less than zero.
;
; ---
; : D0< ( d -- flag) SWAP DROP 0< ;
LINKTO(DMINUS,0,3,'<',"0D")
DZEROLESS: JMP ENTER
.WORD SWAP,DROP,ZEROLESS,EXIT
; ----------------------------------------------------------------------
; D2* [DOUBLE] 8.6.1.1090 "d-two-star" ( xd1 -- xd2 )
;
; xd2 is the result of shifting xd1 one bit toward the most-significant
; bit, filling the vacated least-significant bit with zero.
LINKTO(DZEROLESS,0,3,'*',"2D")
DTWOSTAR: POP H ; Pop xd1h,
XTHL ; ..then swap it for xd1l.
DAD H ; Double xd1l.
XTHL ; Swap xd2l with xd1h.
JNC _dtwostar1 ; No carry? Then just double xd1h,
DAD H ; ..otherwise double xd1h
INX H ; ..and then propagate the carry.
JMP _dwostarDONE; We're done.
_dtwostar1: DAD H ; No carry bit, so just double xd1h.
_dwostarDONE:PUSH H ; Push xd2h to the stack.
NEXT
; ----------------------------------------------------------------------
; DABS [DOUBLE] 8.6.1.1160 "d-abs" ( d -- ud )
;
; ud is the absolute value of d.
;
; ---
; : DABS ( d -- ud ) DUP ?DNEGATE ;
LINKTO(DTWOSTAR,0,4,'S',"BAD")
DABS: JMP ENTER
.WORD DUP,QDNEGATE,EXIT
; ----------------------------------------------------------------------
; DNEGATE [DOUBLE] 8.6.1.1230 ( d1 -- d2 )
;
; d2 is the negation of d1.
;
; ---
; : DNEGATE ( d1 -- d2) INVERT SWAP INVERT SWAP 1 M+ ;
LINKTO(DABS,0,7,'E',"TAGEND")
DNEGATE: JMP ENTER
.WORD INVERT,SWAP,INVERT,SWAP,ONE,MPLUS,EXIT
; ----------------------------------------------------------------------
; M+ [DOUBLE] 8.6.1.1830 "m-plus" ( d1|ud1 n -- d2|ud2 )
;
; Add n to d1|ud1, giving the sum d2|ud2.
LINKTO(DNEGATE,0,2,'+',"M")
LAST_DOUBLE:
MPLUS: SAVEDE
POP D ; Pop n into DE.
POP H ; Pop the high 16-bits of d1|ud1 into HL
XTHL ; ..and swap that value with the low 16-bits.
DAD D ; Add n to the low 16-bits of d1|ud1.
XTHL ; Swap the high and low 16-bits again.
JNC _mplusDONE ; We're done if there was no carry.
INX H ; Increment the high 16-bits on carry.
_mplusDONE: PUSH H ; Push the high 16-bits back onto the stack.
RESTOREDE
NEXT