sys7.1-doc-wip/Toolbox/SANE/BinDec.a
2019-07-27 22:37:48 +08:00

266 lines
7.1 KiB
Plaintext

;
; File: BinDec.a
;
; Contains: Binary-To-Decimal conversion routines
;
; Written by: Larry Kenyon et al
;
; Copyright: © 1983-1990 by Apple Computer, Inc., all rights reserved.
;
; This file is used in these builds: Mac32
;
; Change History (most recent first):
;
; <3> 9/15/90 BG Removed <2>. 040s are behaving more reliably now.
; <2> 7/4/90 BG Added EclipseNOPs for flakey 040s.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <•1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <1.0> 2/12/88 BBM Adding file for the first time into EASE…
; File: BinDec.asm
;_______________________________________________________________________
;
; Package 7
;
; Contains LBIN2DEC and LDEC2BIN code from from original Pack7 and new
; code for _cstr2dec, _pstr2dec, and _dec2str (.include str2dec
; .include dec2str ).
;
; Calls:
; 0000: LBIN2DEC
; 0001: LDEC2BIN
; 0002: FOPSTR2DEC <19Aug85>
; 0003: FODEC2STR <19Aug85>
; 0004: FOCSTR2DEC <19Aug85>
;
; Change traps as follows:
;
; _LBin2Dec -> CLR.W -(SP)
; _Pack7
;
; _LDec2Bin -> MOVE.W #1,-(SP)
; _Pack7
;
; 13 Nov 83 LAK Created the package . . .
; 15 Jan 85 JTC convert to MDS.
; 14 Feb 85 JTC added res name.
; 19 Aug 85 KLH added _cstr2dec, _pstr2dec, and _dec2str.
; 16 Sep 85 JTC modified pathnames for ROM build. <16Sep85>
; <C206/09oct86> bbm Changed to mpw equates.
;_______________________________________________________________________
BLANKS ON
STRING ASIS
LOAD 'StandardEqu.d'
INCLUDE 'SANEMacs.a' ;<16Sep85>
fsymok EQU 0 ; debug flag from Lisa Workshop version ;<19Aug85>
Pkg7 PROC EXPORT
IMPORT _pstr2dec,_dec2str,_cstr2dec ;<19Aug85>
BRA.S @0 ; skip around header
DC.W 0 ; flags word
DC.B 'PACK' ; I am a PACK
DC.W 7 ; whose ID is 7:
DC.W 1 ; and version is 1. ;<19Aug85>
@0 SUBQ.W #1,4(SP) ; PACK SELECT 0 = LBin2Dec
Bpl.s select1 ; PACK SELECT >= 1, LDec2Bin, _pstr2dec, _dec2str, _cstr2dec or nothing.
;<19Aug85>
MOVE.L (SP),2(SP) ; RETURN ADDRESS (KILL PACK SELECT) ;<19Aug85>
ADDQ #2,SP ;<19Aug85>
;---------------------------------------------------
; Signed long integer binary-decimal conversion.
; Written by Jerome T. Coonen, 29 June 83.
;
; Takes long integer in D0, string pointer in A0.
; Converts D0 to decimal in Pascal string at A0.
; The sign is placed in the string only if D0 is
; negative. Leading zeros are suppressed, except
; that the value zero is printed as '0'.
; All registers are preserved, including D0 and A0.
;
; Modification History:
;
;---------------------------------------------------
LBIN2DEC
MOVEM.L D0-D6/A1,-(SP) ; SAVE WORKING REGISERS
MOVEQ #0,D1 ; 10-DIGIT VALUE HELD IN
MOVEQ #0,D2 ; D1.B THROUGH D5.B AT
MOVEQ #0,D3 ; TWO DIGITS PER BYTE.
MOVEQ #0,D4
MOVEQ #0,D5
MOVEQ #31,D6 ; LOOP COUNTER, FOR LATER
;
; First check for zero or negative value.
;
LEA 1(A0),A1 ; POINTER TO STRING CHARS
TST.L D0 ; CHECK INPUT OPERAND SIGN
BGT.S BDPOSVAL
BMI.S BDNEGVAL
MOVE.B #'0',(A1)+ ; VALUE IS ZERO
BRA.S BDFIN
BDNEGVAL
MOVE.B #'-',(A1)+ ; LEADING MINUS
NEG.L D0
BDPOSVAL
;
; Loop, finding successive bits from left to right. At
; each step, double the decimal buffer in D1.B to D5.B and add in
; the next digit.
;
BDLOOP
ADD.L D0,D0 ; NEXT BIT TO X BIT
ABCD D5,D5 ; DOUBLE, ADDING X BIT IN
ABCD D4,D4
ABCD D3,D3
ABCD D2,D2
ABCD D1,D1
DBRA D6,BDLOOP ; FINISH WITH D6.W = $FFFF
;
; The hard part is delivering the ascii digits, stripping leading
; zeros. Use D6 as a marker: if minus then skipping leading zeros; if
; plus print any digit.
;
BSR.S BD1OUT
MOVE.B D2,D1
BSR.S BD1OUT
MOVE.B D3,D1
BSR.S BD1OUT
MOVE.B D4,D1
BSR.S BD1OUT
MOVE.B D5,D1
BSR.S BD1OUT
;
; Finally, stuff the string length, restore the registers, and exit.
; A0 points to the length byte, A1 points to the next character after
; the string; so (A1 - A0 - 1) is the true length.
;
BDFIN
MOVE.W A1,D0
SUB.W A0,D0
SUBQ.B #1,D0
MOVE.B D0,(A0)
MOVEM.L (SP)+,D0-D6/A1
RTS ; exit package
;
; Utility routine to print two digits from nibbles in D1, skipping
; leading zeros, according to sign of D6. Recall that ascii digits
; have the hex form $3x.
;
BD1OUT
ROR.W #4,D1 ; ALIGN D1: $0000L00H
BSR.S BD1DIGOUT
ROL.W #4,D1 ; ALIGN D1: $0000000L
; FALL THROUGH AND RETURN
;
; Place a character from D1.B into the string (A1).
; Skip a leading 0 if D6.W is negative.
;
BD1DIGOUT
TST.W D6
BPL.S BDDOIT
TST.B D1 ; 0 NIBBLE?
BEQ.S BDSKIPIT
MOVEQ #0,D6 ; MARK NONZERO FOUND
BDDOIT
ORI.B #$30,D1 ; MAKE ASCII DIGIT
MOVE.B D1,(A1)+
SUB.B D1,D1 ; CLEAR FOR NEXT ROTATE
BDSKIPIT
RTS
select1 ;<19Aug85>
move.w 4(sp),d0 ;<19Aug85>
MOVE.L (SP),2(SP) ; RETURN ADDRESS (KILL PACK SELECT) ;<19Aug85>
ADDQ #2,SP ;<19Aug85>
SUBQ.W #1,d0 ; d0 = LDec2Bind(-1), _pstr2dec (0), _dec2str (1), _cstr2dec (2) or nothing (>1).
Bpl.s select2 ; PACK SELECT >= 2,_pstr2dec,_dec2str,_cstr2dec or nothing. ;<19Aug85>
;
; Convert decimal string to signed long integer. A0 points to
; a Pascal format string; D0 is assigned an integer value according
; to (A0). A0 is not changed. Overflow is not detected; the value
; produced is the true decimal value, modulo 2^32, with sign according
; to optional leading sign character ('+' or '-').
; A null string produces 0.
;
LDEC2BIN
MOVEM.L D1-D3/A0,-(SP)
MOVEQ #0,D0 ; RESULT SLOT
MOVEQ #0,D1 ; TEMP FOR MULT BY 10
MOVEQ #0,D3 ; D3.B IS 0 FOR +, 1 FOR -
MOVE.B (A0)+,D2 ; STRING LENGTH BYTE
BEQ.S DBFIN
CMPI.B #'+',(A0) ; SKIP LEADING +?
BEQ.S DBPOSSIGN
CMPI.B #'-',(A0) ; RECORD LEADING -?
BNE.S DBNOSIGN
MOVEQ #1,D3 ; MARK NEGATIVE
DBPOSSIGN
ADDQ.L #1,A0 ; SKIP OVER SIGN CHAR
SUBQ.B #1,D2 ; AND DELETE SIGN FROM STRING COUNT
BEQ.S DBFIN ; PERVERSE CASE OF SIGN ONLY
DBNOSIGN
;
; Loop through string, successively multiplying by 10 and adding
; in the low nibble of the character.
;
DBLOOP
MOVEQ #$0F,D1
AND.B (A0)+,D1 ; GET LOW NIBBLE
ADD.L D0,D0 ; LONG * 2
ADD.L D0,D1 ; (LONG * 2) + NIBBLE
LSL.L #2,D0 ; LONG * 8
ADD.L D1,D0 ; (LONG * 10) + NIBBLE
SUBQ.B #1,D2
BNE.S DBLOOP
;
; Finally, negate if necessary.
;
TST.B D3
BEQ.S DBFIN
NEG.L D0
DBFIN
MOVEM.L (SP)+,D1-D3/A0
RTS
select2 ;<19Aug85>
SUBQ.W #1,d0 ; d0 = _pstr2dec (-1), _dec2str (0), _cstr2dec (1) or nothing (>1).
bmi.s @2 ; PACK SELECT = 2 ;<19Aug85>
beq.s @3 ; PACK SELECT = 3 ;<19Aug85>
cmp.W #1,d0 ;<19Aug85>
beq.s @4 ; PACK SELECT = 4 ;<19Aug85>
rts ; PACK SELECT > 4 ;<19Aug85>
@2 jmp _pstr2dec ;<19Aug85>
@3 jmp _dec2str ;<19Aug85>
@4 jmp _cstr2dec ;<19Aug85>
INCLUDE 'Str2Dec.A' ;<16Sep85>
INCLUDE 'Dec2Str.A' ;<16Sep85>
END