

-----------------
FILE : BCDABS.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdAbs
;//	Desc	Find absolute value of a packed signed BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Destination = abs(destination).
;//		Acc undefined.

bcdAbs	proc
arg	dstBCD	:dataptr, \	; Addr of BCD
	dstsz	:@uint		; Byte size of BCD


-----------------
FILE : BCDADD.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdAdd
;//	Desc	Add two packed signed BCD numbers (dest += src).
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed BCD sum returned to destination.
;//		Accumulator (and sf,zf,cf flags) determined:
;//		Acc = 0: No carry
;//		Acc = 1: Carry (overflow)
;//
;//	Note	Destination and source may be the same.

bcdAdd	proc
arg	dstBCD	:dataptr, \	; Addr of 1st addend (=result)
	srcBCD	:dataptr, \	; Addr of 2nd addend
	BCDsz	:@uint		; Byte size of each BCD


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdSub
;//	Desc	Subtract two packed signed BCD numbers (dest -= src).
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed BCD difference returned to destination.
;//		Accumulator (and sf,zf,cf flags) determined:
;//		Acc = 0: No borrow
;//		Acc = 1: Borrow (overflow)
;//
;//	Note	Destination and source may be the same
	@alignn
bcdSub	proc
arg	dstBCD	:dataptr, \	; Addr of minuend (=result)
	srcBCD	:dataptr, \	; Addr of subtrahend
	BCDsz	:@uint		; Byte size of each BCD


-------------------
FILE : BCDBE2LE.ASM
-------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdBe2le
;//	Desc	Convert packed signed BCD from big-endian format
;//		to little-endian format.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed little-endian BCD returned to destination
;//		Acc undefined.
;//
;//	Note	Destination and source *cannot* overlap.
;//
;//		Little-endian format stores the least-significant byte
;//		lowest in memory (the usual on Intel PCs).

bcdBe2le proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD storage
	srcBCD	:dataptr, \	; Addr of source big-endian BCD
	srcsz	:@uint		; Byte size of each BCD


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdLe2be
;//	Desc	Convert packed signed BCD from little-endian format
;//		to big-endian format.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed big-endian BCD returned to destination.
;//		Acc undefined.
;//
;//	Note	Destination and source *cannot* overlap.

bcdLe2be proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD storage
	srcBCD	:dataptr, \	; Addr of source little-endian BCD
	srcsz	:@uint		; Byte size of each BCD


-----------------
FILE : BCDCMP.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdCmp
;//	Desc	Compare two packed signed BCD numbers.
;//
;//
;//	Entry	Passed args
;//	Exit	Accumulator (and cf,zf,sf flags) set according to the
;//		(string) comparison: BCD1st - BCD2nd
;//		Acc = -1:  1st < 2nd
;//		Acc =  0:  1st = 2nd
;//		Acc = +1:  1st > 2nd
;//
;//	Note	Unlike bcdSub, this procedure returns the result based
;//		on a string comparison of the operands.

bcdCmp	proc
arg	BCD1st	:dataptr, \	; Addr of 1st BCD
	BCD2nd	:dataptr, \	; Addr of 2nd BCD
	BCDsz	:@uint		; Byte size of each BCD


------------------
FILE : BCDCMPZ.ASM
------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdCmpz
;//	Desc	Compare a packed signed BCD number against zero.
;//
;//
;//	Entry	Passed args
;//	Exit	Accumulator (and cf,zf,sf flags) determined:
;//		Acc = -1: Number is negative
;//		Acc =  0: Number is zero
;//		Acc = +1: Number is positive
;//
;//	Note	Disregards sign of zero.

bcdCmpz proc
arg	dstBCD	:dataptr, \	; Addr of BCD
	dstsz	:@uint		; Byte size of BCD


-----------------
FILE : BCDFMT.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdFmt
;//	Desc	Format a packed signed BCD for Ascii output.
;//		(Write BCD to string.)
;//
;//
;//	Entry	Passed args
;//		- pass (-1) to use default value (see below)
;//		- width defaults to string length (may expand
;//		  to strsz-1)
;//		- numDec indicates how many decimals the BCD has
;//		  (decimal dot moves left by numDec positions)
;//		- prec indicates how many decimals to output
;//		- for positive numbers/zero, signCh can be
;//		  ' ' to replace '+', or 00h to suppress '+'
;//		- fillCh can be in range 21h..7Fh to replace
;//		  ' ' as string fill character
;//		- sepMCh can be 00h to suppress grouping by 1000's
;//
;//	Exit	Zero-ended Ascii string returned to destination buffer.
;//		Acc = string length (0 if bad args or string exceeds
;//		destination's size)
;//
;//	Note	Here's the number -123456789012 in various formats:
;//		;0----+----1----+----2	(w=width, nD=numDec)
;//		"    123,456,789,012-"	w 20
;//		"   1,234,567,890.12-"	w 20, nD 2
;//		"1,234,567,890.12-"	w -1, nD 2
;//		"1234567890.12-"	w -1, nD 2, sepMCh 0
;//		"1234.56789012-   "	w 17, nD 8, sepMCh 0, rtJust 0
;//		"        1,234.57-"	w 17, nD 8, prec 2
;//		"        0.001235-"	w 17, nD 14, prec 6
;//		"12.3456789012000-"     w 17, nD 10, prec 13
;//		" 0.0123456789012000-"  w 20, nD 13, prec 16

bcdFmt	proc
arg	pStr	:dataptr, \	; Addr of Ascii result buffer
	strsz	:@uint, \ 	; Byte size of buffer   (min. width+1)
	pBCD	:dataptr, \	; Addr of packed signed BCD
	bcdsz	:@uint, \	; Byte size of BCD
	width	:@uint, \	; Field width	    (default: length)
	numDec	:@uint, \	; Number of decimals   (default: zero)
	prec	:@uint, \	; Decimals to output    (default: all)
	rtJust	:byte, \	; Right justify 	(default: yes)
	signCh	:byte, \	; Sign character (default: '+' or '-')
	fillCh	:byte, \	; Fill character	(default: ' ')
	sepCh	:byte, \	; Decimal separator	(default: '.')
	sepMCh	:byte		; Thousands separator	(default: ',')


------------------
FILE : BCDIDIV.ASM
------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdIdiv
;//	Desc	Signed division and modulo of two packed signed BCDs
;//		(lo(dst) = dst / src,  hi(dst) = dst % src)
;//
;//
;//	Entry	Passed args (see note)
;//	Exit	Acc > 0:
;//		  Low (destination) = packed signed BCD quotient
;//		  high(destination) = packed signed BCD remainder
;//		  replacing the dividend.
;//		  The byte size of each of these results is half the
;//		  size of the original destination operand.
;//
;//		  The sign of the quotient is determined from the
;//		  signs of divisor and dividend.
;//		  The remainder keeps the sign of the dividend.
;//
;//		Acc = 0:
;//		  Error: division by zero or overflow (result would
;//		  exceed destination's size); in these cases, the
;//		  dividend is unchanged.
;//
;//
;//	Note	Before calling this procedure, both operands must be
;//		scaled to double-size, for example after a call to
;//		bcdImul (dividend) or bcdSx (divisor) both of which
;//		create a double-size packed signed BCD result.
;//		The most-significant half of the divisor must not
;//		contain any significant BCD digits (i.e. all zeros,
;//		except for the sign bit).
;//
;//		The divisor is left unchanged by this procedure (but
;//		provides temporary work space used during execution).
;//
;//
;//	ToDo	Write wrapper to make 'bcdMod' procedure.

bcdIdiv proc			; NZB = non-zero byte ('MSB')
arg	dstBCD	:dataptr, \	; Addr of dividend (size = srcsz)
	srcBCD	:dataptr, \	; Addr of divisor
	srcsz	:@uint		; Byte size of divisor (see note)


------------------
FILE : BCDIMUL.ASM
------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdImul
;//	Desc	Signed multiplication of two packed signed BCDs.
;//
;//
;//	Entry	Passed args
;//	Exit	Double-size packed signed BCD product returned to
;//		destination _replacing_ the multiplicand.
;//		Acc undefined.
;//
;//	Note	Both BCD operands must be defined as double-size, e.g.
;//			mplic  dt 456512,?
;//			mplier dt 888644,?
;//		where the high-order is undefined (because the result
;//		is returned as double-precision and the multiplier
;//		provides temporary work space for this procedure).
;//
;//		Destination and source may be the same.
;//
;//	Note	This procedure was inspired by:
;//		MPMUL1.ASM by Ray Duncan * PC Magazine Vol. 8 no. 20
;//		Copyright (C) 1989 Ziff Davis Communications
;//
;//
;//	ToDo	Rewrite loop to skip non-significant zeros.

bcdImul proc
arg	dstBCD	:dataptr, \	; Addr of multiplicand
	srcBCD	:dataptr, \	; Addr of multiplier
	srcsz	:@uint		; Byte size of each BCD (double-size)


-------------------
FILE : BCDISBCD.ASM
-------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdIsbcd
;//	Desc	Validate the format of a packed signed BCD number,
;//		i.e. does it contain non-BCD digits.
;//
;//
;//	Entry	Passed args
;//	Exit	Acc = 0: Error, contains non-BCD digit(s)
;//		Acc > 0: No error
;//
;//	Note	A packed BCD number stored by the FPU (using the
;//		FBSTP instruction) may contain 0FFh in the sign byte,
;//		indicating that the number is a 'BCD indefinite'.
;//		This function does not flag this as an error (assuming
;//		it is handled by an FPU exception handler routine),
;//		and accepts any value in the sign byte.

bcdIsbcd proc
arg	srcBCD	:dataptr, \	; Addr of BCD
	srcsz	:@uint		; Byte size of BCD


----------------
FILE : BCDLD.ASM
----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdLdz
;//	Desc	Load zero as a packed BCD value.
;//
;//
;//	Entry	Passed args
;//	Exit	Destination = zero. Acc undefined.

bcdLdz	proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD
	dstsz	:@uint		; Byte size of dest.


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdLd1
;//	Desc	Load +1 as a packed signed BCD value.
;//
;//
;//	Entry	Passed args
;//	Exit	Destination = +1. Acc undefined.

bcdLd1	proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD
	dstsz	:@uint		; Byte size of dest.


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdLd100
;//	Desc	Load +100 (decimal) as a packed signed BCD value.
;//
;//
;//	Entry	Passed args
;//	Exit	Destination = +100. Acc undefined.

bcdLd100 proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD
	dstsz	:@uint		; Byte size of dest.


-----------------
FILE : BCDMOV.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdMov
;//	Desc	Move (copy) a packed BCD value.
;//
;//
;//	Entry	Passed args
;//	Exit	Destination = source. Acc undefined.

bcdMov	proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD (size=srcsz)
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of source BCD


-----------------
FILE : BCDNEG.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdNeg
;//	Desc	Reverse the sign of a packed signed BCD number.
;//
;//
;//	Entry	Passed args
;//	Exit	Accumulator (and cf,zf,sf flags) determined:
;//		Acc = -1: Number became negative
;//		Acc =  0: Number is zero
;//		Acc = +1: Number became positive
;//
;//	Note	Disregards sign of zero.

bcdNeg	proc
arg	dstBCD	:dataptr, \	; Addr of BCD
	dstsz	:@uint		; Byte size of BCD


-----------------
FILE : BCDP2A.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdA2p
;//	Desc	Convert decimal Ascii string to packed signed BCD.
;//		String format: [whitespace][sign]digits
;//		Digit parsing stops at 1st non-digit.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed BCD returned to destination.
;//		Acc = 0: error: bad digits/overflow (dest. = zero)
;//		Acc > 0: no errors

bcdA2p	proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD
	dstsz	:@uint, \	; Byte size of destination
	pStr	:dataptr	; Addr of Ascii string


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdP2a
;//	Desc	Convert a packed signed BCD to (unformatted) decimal
;//		Ascii. Outputs a leading '+' or '-' and min. one digit.
;//
;//
;//	Entry	Passed args
;//	Exit	Zero-terminated Ascii string returned to destination.
;//		Acc = length of destination string (less trailing 0).
;//
;//	Note	Maximum output to the destination string (incl. the
;//		trailing zero) equals twice the BCD's byte size.

bcdP2a	proc
arg	pStr	:dataptr, \	; Addr of AsciiZ destination
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of source BCD


-----------------
FILE : BCDP2B.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdP2b
;//	Desc	Convert packed signed BCD to signed binary.
;//
;//
;//	Entry	Passed args
;//	Exit	Signed binary value returned to destination.
;//		Acc undefined.
;//
;//	Note	The parameter [dstsz] which indicates the byte size
;//		of the binary destination, must be even-sized and 
;//		large enough to ensure no overflow during the 
;//		conversion. A qword (8 bytes) is required to convert
;//		a tbyte (10 bytes) source BCD.
;//
;//	ToDo	Return error if overflow/loss of significance/bad size.

bcdP2b	proc
arg	dstBIN	:dataptr, \	; Addr of binary destination
	dstsz	:@uint, \	; Byte size of dest. (see note)
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of src


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdB2p
;//	Desc	Convert signed binary to packed signed BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Acc > 0: Packed signed BCD returned to destination
;//		Acc = 0: Error (bad srcsz)
;//
;//	Note	The parameter [srcsz] which indicates the byte size of
;//		the binary source must be even (min. 2), and contain
;//		no more significant bits than can be converted to
;//		packed BCD format without overflow (for example, max.
;//		59 significant bits of a qword, plus sign bit).
;//
;//	ToDo	Return error if overflow/loss of significance.

	MAX_SIZEOF_BIN = 20h

bcdB2p	proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD
	dstsz	:@uint, \	; Byte size of dst
	srcBIN	:dataptr, \	; Addr of source binary
	srcsz	:@uint		; Byte size of src (even, min. 2)


-----------------
FILE : BCDP2U.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdP2u
;//	Desc	Convert packed signed BCD to un-packed signed BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Un-packed signed BCD returned to destination.
;//		Acc undefined.
;//
;//	Note	Size of destination must be double-size.

bcdP2u	proc
arg	dstBCD	:dataptr, \	; Addr of destination (size = 2*srcsz)
	srcBCD	:dataptr, \	; Addr of source packed BCD value
	srcsz	:@uint		; Byte size of source BCD


;//////////////////////////////////////////////////////////////////////
;//	Name	bcdU2p
;//	Desc	Convert un-packed signed BCD to packed signed BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed BCD returned to destination.
;//		Acc = 0: Source BCD contains significant information
;//			 that cannot be packed (see note)
;//		Acc > 0: No error
;//
;//	Note	Since the top byte is used for the sign, a 10-byte
;//		packed BCD can contain (10-1)*2 digits (=18); a 20-
;//		byte un-packed BCD can contain (20-1) digits (=19).
;//		Hence, an un-packed number may contain information
;//		that cannot be converted (this is unusual since an
;//		unpacked BCD is generally used as temporary storage
;//		for a packed BCD; it's also compromising the BCD
;//		format).

bcdU2p	proc
arg	dstBCD	:dataptr, \	; Addr of destination (size = srcsz/2)
	srcBCD	:dataptr, \	; Addr of source un-packed BCD value
	srcsz	:@uint		; Byte size of source


-----------------
FILE : BCDSHL.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdShl
;//	Desc	Perform a digit left-shift of a packed signed BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed BCD returned to destination.
;//		Accumulator (and cf,zf flags) determined:
;//             Acc = 0: Result is zero (zf=1)
;//		Acc > 0: Result is non-zero (zf=0)
;//
;//		If any significant digits were shifted out
;//		of the high-order, cf=1, else cf=0
;//		(sign and overflow flags should be ignored).
;//
;//	Note	A 10-byte BCD holds 18 BCD digits ( 2*(10-1) ).
;//
;//	Note	This procedure shifts one digit, i.e. one nibble, 
;//		per shift count effectively performing a
;//		MUL 10-to-the-n'th-power operation.
;//		Zeros are shifted into the low-order. The sign of
;//		the destination is changed only if the result is
;//		zero. If the shift count is larger than or equals
;//		the number of digits in the BCD, the result will
;//		be zero.

bcdShl	proc
arg	dstBCD	:dataptr, \	; Addr of BCD
	dstsz	:@uint, \	; Byte size of BCD
	count	:@uint		; No. of BCD digits to shift


-----------------
FILE : BCDSHR.ASM
-----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdShr
;//	Desc	Perform a digit right-shift of a packed signed BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed signed BCD returned to destination.
;//		Accumulator (and zf flag) determined:
;//		Acc = 0: Result is zero
;//		Acc > 0: Result is non-zero
;//		(carry, sign, and overflow flags should be ignored)
;//
;//	Note	A 10-byte BCD holds 18 BCD digits ( 2*(10-1) ).
;//
;//	Note	This procedure shifts one digit, i.e. one nibble, per
;//		shift count effectively performing a
;//		DIV 10-to-the-n'th-power operation.
;//		Zeros are shifted into the high-order of destination.
;//		The sign of the BCD is changed only if the result is
;//		zero. If the shift count is larger than or equals the
;//		number of digits in the BCD, the result will be zero.

bcdShr	proc
arg	dstBCD	:dataptr, \	; Addr of destination BCD
	dstsz	:@uint, \	; Byte size of BCD
	count	:@uint		; No. of BCD digits to shift


------------------
FILE : BCDSWAP.ASM
------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdSwap
;//	Desc	Exchange (swap) two packed signed BCD numbers.
;//
;//
;//	Entry	Passed args
;//	Exit	Contents of numbers exchanged.
;//		Acc undefined.

bcdSwap proc
arg	dstBCD	:dataptr, \	; Addr of 1st BCD
	srcBCD	:dataptr, \	; Addr of 2nd BCD
	BCDsz	:@uint		; Byte size of each BCD


----------------
FILE : BCDSX.ASM
----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bcdSx
;//	Desc	Sign-extend a packed signed BCD number into a
;//		double-size packed signed BCD (convert to double-size).
;//
;//
;//	Entry	Passed args
;//	Exit	Double-size packed signed BCD returned to destination.
;//		Acc undefined.
;//
;//	Note	Destination and source may be the same.

bcdSx	proc
arg	dstBCD	:dataptr, \	; Addr of dest BCD (size = 2*srcsz)
	srcBCD	:dataptr, \	; Addr of source BCD (OK if = dstBCD)
	srcsz	:@uint		; Byte size of source BCD


----------------
FILE : BCDUU.ASM
----------------

;//////////////////////////////////////////////////////////////////////
;//	Name	BCDUUmov
;//	Desc	Move (copy) an un-packed BCD value.
;//
;//
;//	Entry	Passed args
;//	Exit	Destination = source. Acc undefined.

BCDUUmov proc
arg	dstBCD	:dataptr, \	; Addr of dest. BCD (size = srcsz)
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of source


;//////////////////////////////////////////////////////////////////////
;//	Name	BCDUUadd
;//	Desc	Add two unpacked unsigned BCD numbers (dst += src).
;//
;//
;//	Entry	Passed args
;//	Exit	Sum of dest. and source returned to destination.
;//		Accumulator (and cf flag) determined:
;//		Acc = 0: No carry
;//		Acc = 1: Carry (overflow)
;//
;//	Note	Destination and source may be the same.

BCDUUadd proc
arg	dstBCD	:dataptr, \	; Addr of dest. BCD (size = srcsz)
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of source


;//////////////////////////////////////////////////////////////////////
;//	Name	BCDUUsub
;//	Desc	Subtract two unpacked unsigned BCD numbers (dst -= src)
;//
;//
;//	Entry	Passed args
;//	Exit	Difference (dest - source) returned to destination.
;//		Accumulator (and cf flag) determined:
;//		Acc = 0: No borrow
;//		Acc = 1: Borrow (underflow)
;//
;//	Note	Destination and source may be the same.

BCDUUsub proc
arg	dstBCD	:dataptr, \	; Addr of dest. BCD (size = srcsz)
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of source


;//////////////////////////////////////////////////////////////////////
;//	Name	BCDUUu2p
;//	Desc	Convert un-packed unsigned BCD to packed unsigned BCD.
;//
;//
;//	Entry	Passed args
;//	Exit	Packed BCD returned to destination.
;//		Acc > 0: No error.
;//		Acc = 0: High word of source contains information
;//			 that cannot be converted.
;//
;//	Note	Assumes source size is twice that of destination.

BCDUUu2p proc
arg	dstBCD	:dataptr, \	; Addr of dest. BCD (size = srcsz/2)
	srcBCD	:dataptr, \	; Addr of unpacked source BCD
	srcsz	:@uint		; Byte size of source


;//////////////////////////////////////////////////////////////////////
;//	Name	BCDUUu2a
;//	Desc	Convert unpacked unsigned BCD to decimal Ascii.
;//		Outputs at least one character.
;//
;//
;//	Entry	Passed args
;//	Exit	Zero-terminated Ascii string returned to destination.
;//		Acc = length of destination string (less trailing 0).
;//
;//	Note	Maximum output to the destination string equals the
;//		BCD's byte size plus 1.

BCDUUu2a proc
arg	pStr	:dataptr, \	; Addr of AsciiZ dest.
	srcBCD	:dataptr, \	; Addr of source BCD
	srcsz	:@uint		; Byte size of source BCD


;//////////////////////////////////////////////////////////////////////
;//	Name	BCDUUmul
;//	Desc	Multiply two unpacked unsigned BCDs (dst *= src).
;//
;//
;//	Entry	Passed args
;//	Exit	Double-size unpacked unsigned BCD product returned to
;//		destination _replacing_ the multiplicand.
;//		Acc undefined.
;//
;//	Note	Both BCD operands must be defined as double-size,
;//		where the high-order is undefined (because the result
;//		is returned as double-precision, and the multiplier
;//		provides temporary work space for this procedure).
;//
;//		See bcdImul for details on algorithm.

BCDUUmul proc
arg	dstBCD	:dataptr, \	; Addr of BCD multiplicand
	srcBCD	:dataptr, \	; Addr of BCD multiplier
	srcsz	:@uint		; Byte size of each BCD (double-size)


------------------
FILE : BIN2ASC.ASM
------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	bin2asc
;//	Desc	Convert signed binary number to decimal Asciiz string.
;//
;//
;//	Entry	Passed args
;//	Exit	Left-justified Asciiz string returned to destination.
;//		Acc = string length (0 if bad srcsz).
;//
;//	Note	Destination storage must hold sufficient space.
;//		Insignificant leading zeros are not output.
;//
;//		Uses a shift-and-subtract algorithm whose primary 
;//		virtue is its ability to handle very large numbers.

	MAX_SIZEOF_BIN = 20h
        DIVISOR = 10d           ; Decimal conversion

bin2asc proc
arg	dstStr	:dataptr, \	; Addr of Asciiz destination
	srcBIN	:dataptr, \	; Addr of signed binary source
	srcsz	:@uint		; Byte size of source (even, min. 2)


;//////////////////////////////////////////////////////////////////////
;//	Name	HexN
;//	Desc	Convert unsigned binary word/dword to hexadecimal
;//		Asciiz string.
;//
;//
;//	Entry	Passed args
;//	Exit	Acc = string length.

HexN	proc
arg	pStr	:dataptr, \	; Addr of destination Asciiz string
	mval	:@uint		; 16-bit: word; 32-bit: dword value


-------------------
FILE : CONSOLIO.ASM
-------------------

;//////////////////////////////////////////////////////////////////////
;//	Name	IsDevRedir					  (DOS)
;//	Desc	Test redirection of standard input or standard output.
;//
;//
;//	Entry	Passed arg
;//	Exit	Acc > 0: Is redirected.
;//		Acc = 0: Not redirected.
;//		Acc =-1: Error on DOS call.

IsDevRedir proc
arg	hDev	:@uint		; Device handle (STDIN or STDOUT)


;//////////////////////////////////////////////////////////////////////
;//	Name	GetKey 						  (DOS)
;//	Desc	(Wait for and) Read character from the standard input
;//		device (usually the keyboard).
;//
;//
;//	Entry	N/A
;//	Exit	Acc = keyboard code (al zero if extended key).
;//
;//	Note	Checks for Ctrl-C and Ctrl-Break.

GetKey	proc


;//////////////////////////////////////////////////////////////////////
;//	Name	WriteZStr					  (DOS)
;//	Desc	Write zero-terminated Ascii string to standard output.
;//
;//
;//	Entry	Passed arg
;//	Exit	Acc = No. of bytes written.

WriteZStr proc
arg	pStr	:dataptr	; Addr of AsciiZ string


;//////////////////////////////////////////////////////////////////////
;//	Name	WriteNL 					  (DOS)
;//	Desc	Write new-line (one CR/LF pair) to standard output.
;//
;//
;//	Entry	N/A
;//	Exit	Acc = No. of bytes written.

WriteNL	proc


;//////////////////////////////////////////////////////////////////////
;//	Name	IsDevRedir					(Win32)
;//	Desc	Test redirection of standard input or standard output.
;//
;//
;//	Entry	Passed arg
;//	Exit	Acc > 0: Is redirected.
;//		Acc = 0: Not redirected.
;//		Acc =-1: Error on Win32 API call.
;//
;//	Note	Returns 0 if stdout redirected to LPTn (COMn?)
;//		or if a DOS box is running under Win95 v4.00.950a.
;//
;//	ToDo	Make this work as the DOS version!

IsDevRedir proc
arg	hDev	:@uint		; STD_INPUT_HANDLE or STD_OUTPUT_HANDLE


;//////////////////////////////////////////////////////////////////////
;//	Name	GetKey 						(Win32)
;//	Desc	(Wait for and) Read character from the standard input
;//		device (usually the keyboard).
;//
;//
;//	Entry	N/A
;//	Exit	Acc = keyboard code.
;//
;//	Note	Doesn't read extended keys (function or arrow keys).
;//		Returns Ctrl-C as 03h (but Ctrl-Break is handled by
;//		Windows).

GetKey	proc


;//////////////////////////////////////////////////////////////////////
;//	Name	WriteZStr					(Win32)
;//	Desc	Write zero-terminated Ansi string to standard output.
;//
;//
;//	Entry	Passed arg
;//	Exit	Acc = No. of bytes written.

WriteZStr proc
arg	pzStr	:dataptr	; Addr of AnsiZ string


;//////////////////////////////////////////////////////////////////////
;//	Name	WriteNL 					(Win32)
;//	Desc	Write new-line (one CR/LF pair) to standard output.
;//
;//
;//	Entry	N/A
;//	Exit	As for WriteZStr
;//     Calls   WriteZStr

WriteNL proc


;.