home *** CD-ROM | disk | FTP | other *** search
- ;###S
- ;MODIFIED BY TONY GOLD FOR NON-MACR0 ASSEMBLER
- ;CHANGES WITHIN ;###S AND ;###E LINES
- ;ALL ORIGINAL CODE RETAINED AS COMMENTS
- ;###E
- ;
- ; ////FLOATING POINT PACKAGE FOR THE MCS8
- ; ////BY DAVID MEAD
- ; ////MODIFIED BY HAL BRAND 9/6/74
- ; ////MODIFIED FOR 24 BIT MANTISSAS***********
- ; ////PLUS ADDED I/O CONVERSION ROUTINES
- ; ////NEW ROUTINE COMMENTS
- ; ////ARE PRECEEDED BY /
- ; ////OTHER CHANGES ARE NOTED BY **
- ; ////MODIFIED BY FRANK OLKEN 6/28/75
- ;
- ;
- ORG 110000Q
- ;
- ;
- CONIN EQU 404Q ; JMP TABLE LOCATION OF CONSOLE INP.
- STATUS EQU 412Q ; JMP TABLE LOC. FOR STATUS PORT INPUT
- OUTR EQU 113775Q ;LINK TO BASIC
- OUTL EQU 103726Q
- INL EQU 104623Q
- INP EQU 113772Q ;LINK TO BASIC
- MINCH EQU 300Q ;MINIMUM CHARACTERISTIC WITH SIGN EXTENDED
- MAXCH EQU 077Q ;MAXIMUM CHARACTERISTIC WITH SIGN EXTENDED
- ;
- ;
- ;******************************************************
- ; //// DIVIDE SUBROUTINE
- ;******************************************************
- ;
- ;
- LDIV: CALL CSIGN ;COMPUTE SIGN OF RESULT
- CALL ZCHK ;CHECK IF DIVIDEND = ZERO
- JNZ DTST2 ;IF DIVIDEND .NE. 0 CHECK DIVISOR
- CALL BCHK ;CHECK FOR ZERO/ZERO
- JZ INDFC ;ZERO/ZERO = INDEFINITE
- JMP WZERC ;ZERO/NONZERO = ZERO
- DTST2: CALL BCHK ;COME HERE IF DIVIDEND .NE. 0
- JZ OFLWC ;NONZERO/ZERO = OVERFLOW
- ;IF WE GET HERE, THINGS LOOK OKAY
- MOV E,L ;SAVE BASE IN E
- MOV L,C ;BASE\6 TO L
- CALL DCLR ;CLEAR QUOTIENT MANTISSA SLOT
- MOV L,E ;RESTORE BASE IN L
- CALL ENT1 ;DO FIRST CYCLE
- MOV L,C ;BASE \6 TO L
- CALL DLST ;MOVE QUOTIENT OVER ONE PLACE
- MVI D,23 ;NUMBER OF ITERATIONS TO D
- REP3: MOV L,E
- CALL ENT2
- DCR D ;DEC D
- JZ GOON
- MOV A,L
- MOV L,C ;BASE\6 TO L
- MOV C,A
- CALL DLST ;MOVE QUOTIENT MANT OVER
- MOV A,L ;CPTR TO A
- MOV E,C ;LPTR TO E
- MOV C,A ;CPTR TO C
- JMP REP3
- ;
- GOON: CALL AORS ;CHECK IF RESULT IS NORMALIZED
- JM CRIN
- MOV A,L ;LPTR TO A
- MOV L,C ;CPTR TO L
- MOV C,A ;LPTR TO C
- CALL DLST ;SHIFT QUOTIENT LEFT
- MOV C,L
- MOV L,E
- CALL LDCP ;COMPUTE THE CHARACTERISTIC OF RESULT
- RET
- ;
- CRIN: CALL CFCHE ;GET A=CHAR(H,L), E=CHAR(H,B)
- SUB E ;NEW CHAR = CHAR(DIVIDEND) - CHAR(DVISIOR)
- CPI 177Q ;CHECK MAX POSITIVE NUMBER
- JZ OFLWC ;JUMP ON OVERFLOW
- ADI 1 ;ADD 1 SINCE WE DID NOT LEFTSHIFT
- CALL CCHK ;CHECK AND STORE CHARACTERISTIC
- RET ;RETURN
- ;
- ;
- ;
- ;******************************************************
- ; //// ADDITION SUBROUTINE
- ;******************************************************
- ;
- ;
- LADD: XRA A ;/***SET UP TO ADD
- JMP LADS ;/NOW DO IT
- ;
- ;
- ;******************************************************
- ; //// SUBTRACTION SUBROUTINE
- ;******************************************************
- ;
- ;
- LSUB: MVI A,200Q ;/****SET UP TO SUBTRACT
- ; SUBROUTINE LADS
- ; FLOATING POINT ADD OR SUB
- ; A[128 ON ENTRY[SUB
- ; A[0 ON ENTRY[ADD
- ; F-S[F,FIRST OPER DESTROYED
- ; BASE \11 USED FOR SCRATCH
- LADS: CALL ACPR ;SAVE ENTRY PNT AT BASE \6
- CALL BCHK ;CHECK ADDEND/SUBTRAHEND = ZERO
- RZ ;IF SO, RESULT=ARG SO RETURN
- ;THIS WILL PREVENT UNDERFLOW INDICATION ON
- ;ZERO + OR - ZERO
- CALL CCMP
- JZ EQ02 ;IF EQUAL, GO ON
- MOV D,A ;SAVE LPTR CHAR IN D
- JC LLTB
- SUB E ;L.GT.B IF HERE
- ANI 127
- MOV D,A ;DIFFERENCE TO D
- MOV E,L ;SAVE BASE IN E
- MOV L,C ;C PTR TO L
- INR L ;C PTR\1 TO L
- MOV M,E ;SAVE BASE IN C PTR\1
- MOV L,B ;B PTR TO L
- JMP NCHK
- LLTB: MOV A,E ;L.LT.B IF HERE,BPTR TO A
- SUB D ;SUBTRACT LPTR CHAR FROM BPTR CHAR
- ANI 127
- MOV D,A ;DIFFERENCE TO D
- NCHK: MVI A,24
- CMP D
- JNC SH10
- MVI D,24
- SH10: ORA A
- CALL DRST
- DCR D
- JNZ SH10
- EQUL: MOV A,L
- CMP B
- JNZ EQ02 ;F.GT.S IF L.NE.B
- MOV L,C ;C PTR TO L
- INR L ;C PTR\1 TO L
- MOV L,M ;RESTORE L
- EQ02: CALL LASD ;CHECK WHAT TO
- CALL ACPR ;SAVE ANSWER
- CPI 2 ;TEST FOR ZERO ANSWER
- JNZ NOT0
- JMP WZER ;WRITE FLOATING ZERO AND RETURN
- ;
- NOT0: MVI D,1 ;WILL TEST FOR SUB
- ANA D
- JZ ADDZ ;LSB[1 INPLIES SUB
- CALL TSTR ;CHECK NORMAL/REVERSE
- JZ SUBZ ;IF NORMAL,GO SUBZ
- MOV A,L ;OTHERWISE REVERSE
- MOV L,B ;ROLES
- MOV B,A ;OF L AND B
- ;
- SUBZ: CALL DSUB ;SUBTRACT SMALLER FROM BIGGER
- CALL MANT ;SET UP SIGN OF RESULT
- CALL TSTR ;SEE IF WE NEED TO INTERCHANGE
- ;BPTR AND LPTR
- JZ NORM ;NO INTERCHANGE NECESSARY, SO NORMALIZE
- ;AND RETURN
- MOV A,L ;INTERCHANGE
- MOV L,B ;L
- MOV B,A ;AND B
- MOV A,C ;CPTR TO A
- MOV C,B ;BPTR TO C
- MOV E,L ;LPTR TO E
- MOV B,A ;CPTR TO B
- CALL LXFR ;MOVE_BPTR> TO _LPTR>
- MOV A,B
- MOV B,C
- MOV C,A
- MOV L,E
- JMP NORM ;NORMALIZE RESULT AND RETURN
- ;
- ; COPY THE LARGER CHARACTERISTIC TO THE RESULT
- ;
- ADDZ: CALL CCMP ;COMPARE THE CHARACTERISTICS
- JNC ADD2 ;IF CHAR(H,L) .GE. CHAR(H,B) CONTINUE
- CALL BCTL ;IF CHAR(H,L) .LT. CHAR(H,B) THE COPY
- ;CHAR(H,B) TO CHAR(H,L)
- ADD2: CALL MANT ;COMPUTE SIGN OF RESULT
- CALL DADD ;ADD MANTISSAS
- JNC SCCFG ;IF THERE IS NO OVFLW - DONE
- CALL DRST ;IF OVERFLOW SHIFT RIGHT
- CALL INCR ;AND INCREMENT CHARACTERISTIC
- RET ;ALL DONE, SO RETURN
- ;
- ; THIS ROUTINE STORES THE MANTISSA SIGN IN THE RESULT
- ; THE SIGN HAS PREVIOUSLY BEEN COMPUTED BY LASD.
- ;
- MANT: MOV E,L ;SAVE L PTR
- MOV L,C ;C PTR TO L
- MOV A,M ;LOAD INDEX WORD
- ANI 128 ;SCARF SIGN
- MOV L,E ;RESTORE L PTR
- INR L ;L PTR\2
- INR L
- INR L ;TO L
- MOV E,A ;SAVE SIGN IN E
- MOV A,M
- ANI 127 ;SCARF CHAR
- ADD E ;ADD SIGN
- MOV M,A ;STORE IT
- DCR L ;RESTORE
- DCR L
- DCR L ;L PTR
- RET
- ;
- ;
- ; SUBROUTINE LASD
- ; UTILITY ROUTINE FOR LADS
- ; CALCULATES TRUE OPER AND SGN
- ; RETURNS ANSWER IN
- LASD: CALL MSFH ;FETCH MANT SIGNS, F IN A,D
- CMP E ;COMPARE SIGNS
- JC ABCH ;F\,S- MEANS GO TO A BRANCH
- JNZ BBCH ;F- S\ MEANS GO TO B BRANCH
- ADD E ;SAME SIGN IF HERE, ADD SIGNS
- JC BMIN ;IF BOTH MINUS, WILL OVERFLOW
- CALL AORS ;BOTH POS IF HERE
- JP L000 ;IF AN ADD, LOAD 0
- COM1: CALL DCMP ;COMPARE F WITH S
- JC L131 ;S.GT.F,SO LOAD 131
- JNZ L001 ;F.GT.S,SO LOAD 1
- L002: MVI A,2 ;ERROR CONDITION, ZERO ANSWER
- RET
- BMIN: CALL AORS ;CHECK FOR ADD OR SUB
- JP L128 ;ADD, SO LOAD 128
- COM2: CALL DCMP ;COMPARE F WITH S
- JC L003 ;S.GT.F,SO LOAD 3
- JNZ L129 ;FGT.S.SO LOAD 129
- JMP L002 ;ERROR
- ABCH: CALL AORS ;FT,S- SO TEST FOR A/S
- JM L000 ;SUBTRACT, SO LOAD 0
- JMP COM1 ;ADD, SO GO TO DCMP
- BBCH: CALL AORS ;F-,S\,SO TEST FOR A/S
- JM L128 ;SUB
- JMP COM2 ;ADD
- L000: XRA A
- RET
- L001: MVI A,1
- RET
- L003: MVI A,3
- RET
- L128: MVI A,128
- RET
- L129: MVI A,129
- RET
- L131: MVI A,131
- RET
- ;
- ; SUBROUTINE LMCM
- ; COMPARES THE MAGNITUDE OF
- ; TWO FLOATING PNT NUMBERS
- ; Z[1 IF [,C[1 IF F.LT.S.
- LMCM: CALL CCMP ;CHECK CHARS
- RNZ ;RETURN IF NOT EQUAL
- CALL DCMP ;IF EQUAL, CHECK MANTS
- RET
- ;
- ;
- ;
- ;***************************************************
- ; //// MULTIPLY SUBROUTINE
- ;***************************************************
- ;
- ; SUBROUTINE LMUL
- ; FLOATING POINT MULTIPLY
- ; L PTR X B PTR TO C PTR
- ;
- LMUL: CALL CSIGN ;COMPUTE SIGN OF RESULT AND STORE IT
- CALL ZCHK ;CHECK FIRST OPERAND FOR ZERO
- JZ WZERC ;ZERO * ANYTHING = ZERO
- CALL BCHK ;CHECK SECOND OPERAND FOR ZERO
- JZ WZERC ;ANYTHING * ZERO = ZERO
- MOV E,L ;SAVE L PTR
- MOV L,C ;C PTR TO L
- CALL DCLR ;CLR PRODUCT MANT LOCS
- MOV L,E ;L PTR TO L
- MVI D,24 ;LOAD NUMBER ITERATIONS
- KPGO: CALL DRST ;SHIFT L PTR RIGHT
- JC MADD ;WILL ADD B PTR IF C[1
- MOV A,L ;INTERCHANGE
- MOV L,C ;L AND
- MOV C,A ;C PTRS
- INTR: CALL DRST ;SHIFT PRODUCT OVER
- MOV A,L ;INTERCHANGE
- MOV L,C ;L AND C PTRS_BACK TO
- MOV C,A ;ORIGINAL>
- DCR D
- JNZ KPGO ;MORE CYCLES IF Z[0
- CALL AORS ;TEST IF RESULT IS NORMALIZED
- JM LMCP ;IF NORMALIZED GO COMPUTE CHAR
- MOV E,L ;SAVE LPTR IN E
- MOV L,C ;SET L=CPTR
- CALL DLST ;LEFT SHIFT RESULT TO NORMALIZE
- MOV L,E ;RESTORE LPTR
- CALL CFCHE ;OTHERWISE SET A=CHAR(H,L), E=CHAR(H,B)
- ADD E ;CHAR(RESULT) = CHAR(H,L) + CHAR(H,B)
- CPI 200Q ;CHECK FOR SMALLEST NEGATIVE NUMBER
- JZ UFLWC ;IF SO THEN UNDERFLOW
- SUI 1 ;SUBTRACT 1 TO COMPENSATE FOR NORMALIZE
- CALL CCHK ;CHECK CHARACTERISTIC AND STORE IT
- RET ;RETURN
- ;
- MADD: MOV A,L ;INTERCHANGE
- MOV L,C ;L AND
- MOV C,A ;C PTRS
- CALL DADD ;ACCUMULATE PRODUCT
- JMP INTR
- ;
- ; SUBROUTINE NORM
- ;
- ; THIS SUBROUTINE WILL NORMALIZE A FLOATING POINT
- ; NUMBER, PRESERVING ITS ORIGINAL SIGN.
- ; WE CHECK FOR UNDERFLOW AND SET THE CONDITION
- ; FLAG APPROPRIATELY. (SEE ERROR RETURNS).
- ; THER IS AN ENTRY POINT TO FLOAT A SIGNED INTEGER
- ; (FLOAT) AND AN ENTRY POINT TO FLOAT AN UNSIGNED
- ; INTEGER.
- ;
- ; ENTRY POINTS:
- ;
- ; NORM - NORMALIZE FLOATING PT NUMBER AT (H,L)
- ; FLOAT - FLOAT TRIPLE PRECISION INTEGER AT (H,L)
- ; PRESERVING SIGN BIT IN (H,L)+3
- ; DFXL - FLOAT UNSIGNED (POSITIVE) TRIPLE PRECISION
- ; AT (H,L)
- ;
- ;REGISTERS ON EXIT:
- ;
- ; A = CONDITION FLAG (SEE ERROR RETURNS)
- ; D,E = GARBAGE
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- NORM: MOV E,L ;SAVE L IN E
- NORM1: CALL GCHAR ;GET CHAR(H,L) IN A WITH SIGN EXTENDED
- MOV D,A ;SAVE CHAR IN D
- FXL1: MOV L,E ;RESTORE L
- FXL2: CALL ZMCHK ;CHECK FOR ZERO MANTISSA
- JZ WZER ;IF ZERO MANTISSA THEN ZERO RESULT
- REP6: MOV A,M ;GET MOST SIGNIFICANT BYTE OF
- ;MANTISSA
- ORA A ;SET FLAGS
- JM SCHAR ;IF MOST SIGNFICANT BIT = 1 THEN
- ;NUMBER IS NORMALIZED AND WE GO TO
- ;STORE THE CHARACTERISTIC
- MOV A,D ;OTHERWISE CHECK FOR UNDERFLOW
- CPI MINCH ;COMPARE WITH MINIMUM CHAR
- JZ WUND ;IF EQUAL THEN UNDERFLOW
- CALL DLST ;SHIFT MANTISSA LEFT
- DCR D ;DECREMENT CHARACTERSTIC
- JMP REP6 ;LOOP AN TEST NEXT BIT
- SCHAR: JMP INCR3 ;STORE THE CHARACTERISTIC USING
- ;THE SAME CODE AS THE INCREMENT
- ;
- DFXL: MOV E,L ;ENTER HERE TO FLOAT UNSIGNED
- ;INTEGER
- ;FIRT SAVE L IN E
- INR L ;MAKE (H,L) POINT TO CHAR
- INR L ;MAKE (H,L) POINT TO CHAR
- INR L ;MAKE (H,L) POINT TO CHAR
- XRA A ;ZERO ACCUMULATOR
- MOV M,A ;STORE A PLUS (+) SIGN
- MOV L,E ;RESTORE L
- FLOAT: MVI D,24 ;ENTER HERE TO FLOAT INTEGER
- ;PRESERVING ORIGINAL SIGN IN (H,L)+3
- ;SET UP CHARACTERISTIC
- JMP FXL2 ;GO FLOAT THE NUMBER
- ;
- ;
- ;
- ;
- ; SUBROUTINE ZCHK
- ;
- ; THIS ROUTINE SETS THE ZERO FLAG IF IT DETECTS
- ; A FLOATING ZERO AT (H,L).
- ;
- ; SUBROUTINE ZMCHK
- ;
- ; THIS ROUTINE SETS THE ZERO FLAG IF IT DETECTS A
- ; ZERO MANTISSA AT (H,L)
- ;
- ZCHK:
- ZMCHK: INR L ;SET L TO POINT LAST BYTE OF MANTISSA
- INR L ;SET L TO POINT TO LAST BYTE OF MANTISSA
- MOV A,M ;LOAD LEAST SIGNIFICANT BYTE
- DCR L ;L POINTS TO MIDDLE BYTE
- ORA M ;OR WITH LEAST SIGNFICANT BYTE
- DCR L ;L POINTS TO MOST SIGNFICANT BYTE
- ;OF MANTISSA (ORIGINAL VALUE)
- ORA M ;OR IN MOST SIGNFICANT BYTE
- RET ;RETURNS WITH ZERO FLAG SET APPROPRIATELY
- ;
- ; SUBROUTINE BCHK
- ;
- ; THIS ROUTINE CHECKS (H,B) FOR FLOATING PT ZERO
- ;
- BCHK: MOV E,L ;SAVE LPTR IN E
- MOV L,B ;SET L=BPTR
- CALL ZCHK ;CHECK FOR ZERO
- MOV L,E ;RESTORE L=LPTR
- RET ;RETURN
- ;
- ;
- ; SUBROUTINE DLST
- ; SHIFTS DBL WORD ONE PLACE LF
- DLST: INR L
- INR L ;/***TP
- MOV A,M ;LOAD IT
- ORA A ;KILL CARRY
- RAL ;SHIFT IT LEFT
- MOV M,A ;STORE IT
- DCR L
- MOV A,M ;LOAD IT
- RAL ;SHIFT IT LEFT
- ; IF CARRY SET BY FIRST SHIFT
- ; IT WILL BE IN LSB OF SECOND
- MOV M,A
- DCR L ;/***TP EXTENSION
- MOV A,M
- RAL
- MOV M,A ;/***ALL DONE TP
- RET
- ; SUBROUTINE DRST
- ; SHIFTS DOUBLE WORD ONE PLACE
- ; TO THE RIGHT
- ; DOES NOT AFFECT D
- DRST: MOV E,L ;/***TP MODIFIED RIGHT SHIFT TP
- MOV A,M ;LOAD FIRST WORD
- RAR ;ROTATE IT RIGHT
- MOV M,A ;STORE IT
- INR L ;/*** TP
- MOV A,M ;LOAD SECOND WORD
- RAR ;SHIFT IT RIGHT
- MOV M,A ;STORE IT
- INR L ;/*** TP EXTENSION
- MOV A,M
- RAR
- MOV M,A
- MOV L,E ;/***TP - ALL DONE TP
- RET
- ; SUBROUTINE DADD
- ; ADDS TWO DOUBLE PRECISION
- ; WORDS, C[1 IF THERE IS OVRFLW
- DADD: MOV E,L ;SAVE BASE IN E
- MOV L,B ;BASE \3 TO L
- INR L ;BASE \4 TO L
- INR L ;/***TP
- MOV A,M ;LOAD S MANTB
- MOV L,E ;BASE TO L
- INR L ;BASE \1 TO L
- INR L ;/***TP
- ADD M ;ADD TWO MANTB]S
- MOV M,A ;STORE ANSWER
- MOV L,B ;/***TP EXTENSION
- INR L
- MOV A,M
- MOV L,E
- INR L
- ADC M
- MOV M,A ;/***TP - ALL DONE
- MOV L,B ;BASE \3 TO L
- MOV A,M ;MANTA OF S TO A
- MOV L,E ;BASE TO L
- ADC M ;ADD WITH CARRY
- MOV M,A ;STORE ANSWER
- RET
- ; SUBROUTINE DCLR
- ; CLEARS TWO SUCCESSIVE
- ; LOCATIONS OF MEMORY
- DCLR: XRA A
- MOV M,A
- INR L
- MOV M,A
- INR L ;/***TP EXTENSION
- MOV M,A ;/***TP ZERO 3
- DCR L ;/***TP - ALL DONE
- DCR L
- RET
- ; /*****ALL NEW DSUB - SHORTER***
- ; SUBROUTINE DSUB
- ; DOUBLE PRECISION SUBTRACT
- DSUB: MOV E,L ;SAVE BASE IN E
- INR L ;/***TP EXTENSION
- INR L ;/START WITH LOWS
- MOV A,M ;/GET ARG
- MOV L,B ;/NOW SET UP TO SUB
- INR L
- INR L
- SUB M ;/NOW DO IT
- MOV L,E ;/NOW MUST PUT IT BACK
- INR L
- INR L
- MOV M,A ;/PUT BACK
- DCR L ;/***TP - ALL DONE
- MOV A,M ;/GET LOW OF LOP
- MOV L,B ;/SET TO BOP
- INR L ;/SET TO BOP LOW
- SBB M ;/GET DIFF. OF LOWS
- MOV L,E ;/SAVE IN LOP LOW
- INR L ;/TO LOP LOW
- MOV M,A ;/INTO RAM
- DCR L ;/BACK UP TO LOP HIGH
- MOV A,M ;/GET LOP HIGH
- MOV L,B ;/SET TO BOP HIGH
- SBB M ;/SUB. WITH CARRY
- MOV L,E ;/SAVE IN LOP HIGH
- MOV M,A ;/INTO RAM
- RET ;/ALL DONE - MUCH SHORTER
- ;
- ; SUBROUTINE GCHAR
- ;
- ; THIS SUBROUTINE RETURNS THE CHARACTERISTIC OF
- ; THE FLOATING POINT NUMBER POINTED TO BY (H,L)
- ; IN THE A REGISTER WITH ITS SIGN EXTENDED INTO THE
- ; LEFTMOST BIT.
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CHARACTERISTIC OF (H,L) WITH SIGN EXTENDED
- ; L = (ORIGINAL L) + 3
- ; B,C,D,E,H = SAME AS ON ENTRY
- ;
- GCHAR: INR L ;MAKE (H,L) POINT TO CHAR
- INR L ;MAKE (H,L) POINT TO CHAR
- INR L ;MAKE (H,L) POINT TO CHAR
- MOV A,M ;SET A=CHAR + MANTISSA SIGN
- ANI 177Q ;GET RID OF MANTISSA SIGN BIT
- ADI 100Q ;PROPAGATE CHAR SIGN INTO LEFTMOST BIT
- XRI 100Q ;RESTORE ORIGINAL CHAR SIGN BIT
- RET ;RETURN WITH (H,L) POINTING TO THE
- ;CHAR = ORIGINAL (H,L)+3
- ;SOMEONE ELSE WILL CLEAN UP
- ;
- ;
- ; SUBROUTINE CFCHE
- ;
- ; THIS SUBROUTINE RETURNS THE CHARACTERISTICS OF THE
- ; FLOATING POINT NUMBERS POINTED TO BY (H,L) AND
- ; (H,B) IN THE A AND E REGISTERS RESPECTIVELY,
- ; WITH THEIR SIGNS EXTENDED INTO THE LEFTMOST BIT.
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CHARACTERISTIC OF (H,L) WITH SIGN EXTENDED
- ; E = CHARACTERISTIC OF (H,B) WITH SIGN EXTENDED
- ; B,C,H,L = SAME AS ON ENTRY
- ; D = A
- ;
- CFCHE: MOV E,L ;SAVE LPTR IN E
- MOV L,B ;SET L = BPTR
- CALL GCHAR ;GET CHAR(H,B) WITH SIGN EXTENDED IN A
- MOV L,E ;RESTORE L = LPTR
- MOV E,A ;SET E=CHAR(H,B) WITH SIGN EXTENDED
- CALL GCHAR ;SET A=CHAR(H,L) WITH SIGN EXTENDED
- DCR L ;RESTORE L = LPTR
- DCR L ;RESTORE L = LPTR
- DCR L ;RESTORE L = LPTR
- MOV D,A ;SET D=A=CHAR(H,L) WITH SIGN EXTENDED
- RET
- ;
- ;
- ; SUBROUTINE CCMP
- ;
- ; THIS SUBROUTINE COMPARES THE CHARACTERISTICS OF
- ; FLOATING POINT NUMBERS POINTED TO BY (H,L) AND (H,B).
- ; THE ZERO FLIP-FLOP IS SET IF CHAR(H,L) EQUALS
- ; CHAR(H,B). IF CHAR(H,L) IS LESS THAN CHAR(H,B) THEN
- ; THE CARRY BIT WILL BE SET.
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CHARACTERISTIC OF (H,L) WITH SIGN EXTENDED
- ; E = CHARACTERISTIC OF (H,B) WITH SIGN EXTENDED
- ; D = A
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- CCMP: CALL CFCHE ;FETCH CHARACTERTISTICS WITH SIGN EXTENDED
- ;INTO A (CHAR(H,L)) AND E (CHAR(H,B)) REGISTERS
- MOV D,A ;SAVE CHAR (H,L)
- SUB E ;SUBTRACT E (CHAR(H,B))
- RAL ;ROTATE SIGN BIT INTO CARRY BIT
- MOV A,D ;RESTORE A=CHAR(H,L)
- RET ;RETURN
- ;
- ; ERROR RETURNS
- ;
- ; THE FOLLOWING CODE IS USED TO RETURN VARIOUS
- ; ERROR CONDITIONS. IN EACH CASE A FLOATING POINT
- ; NUMBER IS STORED IN THE 4 WORDS POINTED TO BY (H,L)
- ; AND A FLAG IS STORED IN THE ACCUMULATOR.
- ;
- ; CONDITION FLAG RESULT (+) RESULT (-)
- ;
- ; UNDERFLOW 377 000 000 000 100 000 000 000 300
- ; OVERFLOW 177 377 377 377 077 377 377 377 277
- ; INDEFINITE 077 377 377 377 077 377 377 377 277
- ; NORMAL 000 XXX XXX XXX XXX XXX XXX XXX XXX
- ; NORMAL ZERO 000 000 000 000 100 (ALWAYS RETURNS +0)
- ;
- ; ENTRY POINTS:
- ;
- ; WUND - WRITE UNDERFLOW
- ; WOVR - WRITE OVERFLOW
- ; WIND - WRITE INDEFINITE
- ; WZER - WRITE NORMAL ZERO
- ;
- ;###S
- ;WFLT MACRO VMANT,VCHAR,VFLAG,LABEL ;WRITE FLOATING NUMBER
- ;
- ; MVI D,VCHAR ;LOAD CHARACTERISTIC INTO D REGISTER
- ; CALL WCHAR ;WRITE CHARACTERISTIC
- ;LABEL:: MVI A,VMANT ;LOAD MANTISSA VALUE
- ; ;WE ASSUME HERE THAT ALL BYTES OF MANTISSA
- ; ;ARE THE SAME
- ; CALL WMANT ;WRITE THE MANTISSA
- ; MVI A,VFLAG ;SET ACCUMULATOR TO FLAG
- ; ORA A ;SET FLAGS PROPERLY
- ; RET ;RETURN (WMANT RESTORED (H,L))
- ; ENDM
- ;
- ;WUND: WFLT 0,100Q,377Q,UFLW1 ;WRITE UNDERFLOW
- WUND: MVI D,100Q ;LOAD CHARACTERISTIC INTO D REGISTER
- CALL WCHAR ;WRITE CHARACTERISTIC
- UFLW1: MVI A,0 ;LOAD MANTISSA VALUE
- ;WE ASSUME HERE THAT ALL BYTES OF MANTISSA
- ;ARE THE SAME
- CALL WMANT ;WRITE THE MANTISSA
- MVI A,377Q ;SET ACCUMULATOR TO FLAG
- ORA A ;SET FLAGS PROPERLY
- RET ;RETURN (WMANT RESTORED (H,L))
- ;WOVR: WFLT 377Q,77Q,177Q,OFLW1 ;WRITE OVERFLOW
- WOVR: MVI D,77Q ;LOAD CHARACTERISTIC INTO D REGISTER
- CALL WCHAR ;WRITE CHARACTERISTIC
- OFLW1: MVI A,377Q ;LOAD MANTISSA VALUE
- ;WE ASSUME HERE THAT ALL BYTES OF MANTISSA
- ;ARE THE SAME
- CALL WMANT ;WRITE THE MANTISSA
- MVI A,177Q ;SET ACCUMULATOR TO FLAG
- ORA A ;SET FLAGS PROPERLY
- RET ;RETURN (WMANT RESTORED (H,L))
- ;WIND: WFLT 377Q,77Q,77Q,INDF1 ;WRITE INDEFINITE
- WIND: MVI D,77Q ;LOAD CHARACTERISTIC INTO D REGISTER
- CALL WCHAR ;WRITE CHARACTERISTIC
- INDF1: MVI A,377Q ;LOAD MANTISSA VALUE
- ;WE ASSUME HERE THAT ALL BYTES OF MANTISSA
- ;ARE THE SAME
- CALL WMANT ;WRITE THE MANTISSA
- MVI A,77Q ;SET ACCUMULATOR TO FLAG
- ORA A ;SET FLAGS PROPERLY
- RET ;RETURN (WMANT RESTORED (H,L))
- ;###E
- ;
- WZER: INR L ;WRITE NORMAL ZERO
- INR L ;
- INR L ;
- MVI M,100Q ;STORE CHARACTERISTIC FOR ZERO
- XRA A ;ZERO ACCUMULATOR
- CALL WMANT ;STORE ZERO MANTISSA
- ORA A ;SET FLAGS PROPERLY
- RET ;RETURN
- ;
- ; ROUTINE TO WRITE MANTISSA FOR ERROR RETURNS
- ;
- WMANT: DCR L ;POINT LEAST SIGNIFICANT BYTE
- ;OF MANTISSA
- MOV M,A ;STORE LSBYTE OF MANTISSA
- DCR L ;POINT TO NEXT LEAST SIGNIFICANT BYTE
- ;OF MANTISSA
- MOV M,A ;STORE NLSBYTE OF MANTISSA
- DCR L ;POINT TO MOST SIGNIFICANT BYTE
- ;OF MANTISSA
- MOV M,A ;STORE MSBYTE OF MANTISSA
- RET ;RETURN (H,L) POINTS TO BEGINNING OF
- ;FLOATING POINT RESULT
- ;
- ; ROUTINE TO WRITE CHARACTERTIC FOR ERROR RETURNS
- ; NOTE: WE PRESERVE ORIGINAL MANTISSA SIGN
- ; ON ENTRY D CONTAINS NEW CHARACTERTISTIC TO BE STORED.
- ;
- WCHAR: INR L ;SET (H,L) TO POINT TO CHARACTERISTIC
- INR L ;PART OF ABOVE
- INR L ;PART OF ABOVE
- MOV A,M ;LOAD CHARACTERISTIC A
- ;AND MANTISSA SIGN
- ANI 200Q ;JUST KEEP MANTISSA SIGN
- ORA D ;OR IN NEW CHARACTERISTIC
- MOV M,A ;STORE IT BACK
- RET ;RETURN WITH (H,L) POINT TO CHARACTERISTIC
- ;OF RESULT
- ;SOMEONE ELSE WILL FIX UP (H,L)
- ;
- ; SUBROUTINE INDFC
- ;
- ; THIS ROUTINE WRITES A FLOATING INDEFINITE, SETS
- ; THIS WRITES WRITES A FLOATING POINT INDEFINITE
- ; AT (H,C), SETS THE CONDITION FLAG AND RETURNS
- ;
- ;
- INDFC: MOV E,L ;SAVE LPTR IN E
- MOV L,C ;SET L=CPTR SO (H,L)-ADDR OF RESULT
- CALL WIND ;WRITE INDEFINITE
- MOV L,E ;RESTORE L=LPTR
- RET ;RETURN
- ;
- ;
- ; SUBROUTINE WZERC
- ;
- ; THIS ROUTINE WRITES A NORMAL FLAOTING POINT ZERO
- ; AT (H,C), SETS THE CONDITION FLAG AND RETURNS
- ;
- WZERC: MOV E,L ;SAVE LPTR IN E
- MOV L,C ;SETL=CPTR SO (H,L)=ADDR OF RESULT
- CALL WZER ;WRITE NORMAL ZERO
- MOV L,E ;RESTORE L=LPTR
- RET ;RETURN
- ;
- ; SUBROUTINE INCR
- ;
- ; THIS SUBROUTINE INCREMENTS THE CHARACTERISTIC
- ; OF THE FLOATING POINT NUMBER POINTED TO BY (H,L).
- ; WE TEST FOR OVERFLOW AND SET APPROPRIATE FLAG.
- ; (SEE ERRROR RETURNS).
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CONDITION FLAG (SEE ERROR RETURNS)
- ; D = CLOBBERED
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- INCR: CALL GCHAR ;GET CHAR WITH SIGN EXTENDED
- CPI MAXCH ;COMPARE WITH MAX CHAR PERMITTED
- JZ OFLW1 ;INCREMENT WOULD CAUSE OVERFLOW
- MOV D,A ;/SAVE IT IN D
- INR D ;/INCREMENT IT
- JMP INCR2 ;JUMP AROUND ALTERNATE ENTRY POINT
- INCR3: INR L ;COME HERE TO STORE CHARACTERISTIC
- INR L ;POINT (H,L) TO CHAR
- INR L ;POINT (H,L) TO CHAR
- INCR2: MVI A,177Q
- ANA D ;/KILL SIGN BIT
- MOV D,A ;/BACK TO D
- MOV A,M ;/NOW SIGN IT
- ANI 200Q ;/GET MANTISSA SIGN
- ORA D ;/PUT TOGETHER
- MOV M,A ;/STORE IT BACK
- DCR L ;/NOW BACK TO BASE
- DCR L ;/***TP
- DCR L
- SCCFG: XRA A ;SET SUCCESS FLAG
- RET
- ;
- ; SUBROUTINE DECR
- ;
- ; THIS SUBROUTINE DECREMENTS THE CHARACTERISTIC
- ; OF THE FLOATING POINT NUMBER POINTED TO BY (H,L).
- ; WE TEST FOR UNDERFLOW AND SET APPROPRIATE FLAG.
- ; (SEE ERRROR RETURNS).
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CONDITION FLAG (SEE ERROR RETURNS)
- ; D = CLOBBERED
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- DECR: CALL GCHAR ;GET CHAR WITH SIGN EXTENDED
- CPI MINCH ;COMPARE WITH MIN CHAR PERMITTED
- JZ UFLW1 ;DECREMENT WOULD CAUSE UNDERFLOW
- MOV D,A ;SAVE CHARACTERSTIC IN D
- DCR D ;DECREMENT CHARACTERISTIC
- JMP INCR2 ;GO STORE IT BACK
- ;
- ; SUBROUTINE AORS
- ; RETURN S[1 IF BASE \6
- ; HAS A 1 IN MSB
- AORS: MOV E,L ;SAVE BASE
- MOV L,C ;BASE \6 TO L
- MOV A,M ;LOAD IT
- ORA A ;SET FLAGS
- MOV L,E ;RESTORE BASE
- RET
- ; SUBROUTINE TSTR
- ; CHECKS C PTR TO SEE IF
- ; NLSB[1
- ; RETURNS Z[1 IF NOT
- ; DESTROYS E,D
- TSTR: MOV E,L ;SAVE BASE
- MOV L,C ;C PTR TO L
- MVI D,2 ;MASK TO D
- MOV A,M ;LOAD VALUE
- MOV L,E ;RESTORE BASE
- ANA D ;AND VALUE WITH MASK
- RET
- ; SUBROUTINE ACPR
- ; STORES A IN LOCATION OF CPTR
- ; LPTR IN E
- ACPR: MOV E,L ;SAVE LPTR
- MOV L,C ;CPTR TO L
- MOV M,A ;STORE A
- MOV L,E ;RESTORE BASE
- RET
- ; SUBROUTINE DCMP
- ; COMPARES TWO DOUBLE LENGTH
- ; WORDS
- DCMP: MOV A,M ;NUM MANTA TO A
- MOV E,L ;SAVE BASE IN E
- MOV L,B ;BASE\3 TO L
- CMP M ;COMPARE WITH DEN MANTA
- MOV L,E ;RETURN BASE TO L
- RNZ ;RETURN IF NOT THE SAME
- INR L ;L TO NUM MANTB
- MOV A,M ;LOAD IT
- MOV L,B ;DEN MANTB ADD TO L
- INR L ;BASE\ 4 TO L
- CMP M
- MOV L,E
- RNZ ;/***TP EXTENSION
- INR L ;/NOW CHECK BYTE 3
- INR L
- MOV A,M ;/GET FOR COMPARE
- MOV L,B
- INR L
- INR L ;/BYTE 3 NOW
- CMP M ;/COMPARE
- MOV L,E ;/***TP - ALL DONE
- RET
- ; SUBROUTINE DIVC
- ; PERFORMS ONE CYCLE OF DOUBLE
- ; PRECISION FLOATING PT DIVIDE
- ; ENTER AT ENT1 ON FIRST CYCLE
- ; ENTER AT ENT2 ALL THEREAFTER
- ENT2: CALL DLST ;SHIFT MOVING DIVIDEND
- JC OVER ;IF CARRY[1,NUM.GT.D
- ENT1: CALL DCMP ;COMPARE NUM WITH DEN
- JNC OVER ;IF CARRY NOT SET,NUM.GE.DEN
- RET
- OVER: CALL DSUB ;CALL DOUBLE SUBTRACT
- MOV E,L ;SAVE BASE IN E
- MOV L,C ;BASE \6 TO L
- INR L ;BASE \7 TO L
- INR L ;/***TP
- MOV A,M
- ADI 1 ;ADD 1
- MOV M,A ;PUT IT BACK
- MOV L,E ;RESTORE BASE TO L
- RET
- ; SUBROUTINE LXFR
- ; MOVES CPTR TO EPTR
- ; MOVES 3 WORDS IF ENTER AT LXFR
- LXFR: MVI D,4 ;/MOVE 4 WORDS
- REP5: MOV L,C ;CPTR TO L
- MOV A,M ;_CPTR> TO A
- MOV L,E ;EPTR TO L
- MOV M,A
- INR C ;/INCREMENT C
- INR E ;/INCREMENT E TO NEXT
- DCR D ;/TEST FOR DONE
- JNZ REP5 ;/GO FOR FOR TILL D=0
- MOV A,E ;/NOW RESET C AND E
- SUI 4 ;/RESET BACK BY 4
- MOV E,A ;/PUT BACK IN E
- MOV A,C ;/NOW RESET C
- SUI 4 ;/BY 4
- MOV C,A ;/BACK TO C
- RET ;/DONE
- ;
- ; SUBROUTINE LDCP
- ;
- ; THIS SUBROUTINE COMPUTES THE CHARACTERISTIC
- ; FOR THE FLOATING DIVIDE ROUTINE
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CONDITION FLAG (SEE ERROR RETURNS)
- ; D,E = GARBAGE
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- ; REGISTERS ON ENTRY:
- ;
- ; (H,B) = ADDRESS OFF DIVISOR
- ; (H,C) = ADDRESS OF QUOTIENT
- ; (H,L) = ADDRESS OF DIVIDEND
- ;
- LDCP: CALL CFCHE ;SET E=CHAR(H,B), A=CHAR(H,L)
- SUB E ;SUBTRACT TO GET NEW CHARACTERISTIC
- JMP CCHK ;GO CHECK FOR OVER/UNDERFLOW
- ;AND STORE CHARACTERTISTIC
- ;
- ;
- ; SUBROUTINE LMCP
- ;
- ; THIS SUBROUTINE COMPUTES THE CHARACTERISTIC
- ; FOR THE FLOATING MULTIPLY ROUTINE.
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CONDITION FLAG (SEE ERROR RETURNS)
- ; D,E = GARBAGE
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- ; REGISTERS ON ENTRY:
- ;
- ; (H,B) = ADDRESS OFF MULTIPLICAND
- ; (H,C) = ADDRESS OF PRODUCT
- ; (H,L) = ADDRESS OF MULTIPLIER
- ;
- LMCP: CALL CFCHE ;SET E=CHAR(H,B), A=CHAR(H,L)
- ADD E ;ADD TO GET NEW CHARACTERISTIC
- ;NOW FALL INTO THE ROUTINE
- ;WHICH CHECKS FOR OVER/UNDERFLOW
- ;AND STORE CHARACTERTISTIC
- ;
- ;
- ; SBUROUTINE CCHK
- ;
- ; THIS SUBROUTINE CHECKS A CHARACTERISTIC IN
- ; THE ACCUMULATOR FOR OVERFLOW OR UNDERFLOW.
- ; IT THEN STORES THE CHARACTERISTIC, PRESERVING
- ; THE PREVIOUSLY COMPUTED MANTISSA SIGN.
- ;
- ; REGISTERS ON ENTRY:
- ;
- ; (H,L) = ADDRESS OF ONE OPERAND
- ; (H,B) = ADDRESS OF OTHER OPERAND
- ; (H,C) = ADDRESS OF RESULT
- ; A = NEW CHARACTERISTIC OF RESULT
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = CONDITION FLAG (SEE ERROR RETURNS)
- ; D,E = GARBAGE
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- CCHK: ;ENTER HERE TO CHECK CHARACTERISTIC
- CPI 100Q ;CHECK FOR 0 TO +63
- JC STORC ;JUMP IF OKAY
- CPI 200Q ;CHECK FOR +64 TO +127
- JC OFLWC ;JUMP IF OVERFLOW
- CPI 300Q ;CHECK FOR -128 TO -65
- JC UFLWC ;JUMP IF UNDERFLOW
- STORC: MOV E,L ;SAVE L IN E
- MOV L,C ;LET L POINT TO RESULT
- MOV D,A ;SAVE CHARACTERISTIC IN D
- CALL INCR3 ;STORE CHARACTERISTIC
- MOV L,E ;RESTORE L
- RET ;RETURN
- ;
- ; SUBROUTINE OFLWC
- ;
- ; THIS ROUTINE WRITES A FLOATING POINT OVERFLOW AT (H,C)
- ; SETS THE CONDITION FLAG, AND RETURNS.
- ;
- OFLWC: MOV E,L ;SAVE L IN E
- MOV L,C ;SET L=CPTR, SO (H,L)=ADDR OF RESULT
- CALL WOVR ;WRITE OUT OVERFLOW
- MOV L,E ;RESTORE L
- RET ;RETURN
- ;
- ; SUBROUTINE UFLWC
- ;
- ; THIS ROUTINE WRITES A FLOATING POINT UNDERFLOW AT (H,C)
- ; SETS THE CONDITION FLAG, AND RETURNS.
- ;
- UFLWC: MOV E,L ;SAVE L IN E
- MOV L,C ;SET L=CPTR, SO (H,L)=ADDR OF RESULT
- CALL WUND ;WRITE OUT UNDEFLOW
- MOV L,E ;RESTORE L
- RET ;RETURN
- ;
- ;
- ; SUBROUTINE CSIGN
- ;
- ; THIS SUBROUTINE COMPUTES AND STORE THE MANTISSA
- ; SIGN FOR THE FLOATING MULTIPLY AND DIVIDE ROUTINES
- ;
- ; REGISTERS ON ENTRY:
- ;
- ; (H,L) = ADDRESS OF ONE OPERAND
- ; (H,B) = ADDRESS OF OTHER OPERAND
- ; (H,C) = ADDRESS OF RESULT
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A,D,E = GARBAGE
- ; B,C,H,L = SAME AS ON ENTRY
- ;
- ;
- CSIGN: CALL MSFH ;SET A=SIGN(H,L), E=SIGN(H,B)
- XRA E ;EXCLUSIVE OR SIGNS TO GET NEW SIGN
- CALL CSTR ;STORE SIGN INTO RESULT
- RET ;RETURN
- ;
- ;
- ; SUBROUTINE CSTR
- ; STORES VALUE IN A IN
- ; CPTR\2
- ; PUTS LPTR IN E
- CSTR: MOV E,L ;SAVE LPTR IN E
- MOV L,C ;CPTR TO L
- INR L ;CPTR\2
- INR L ;TO L
- INR L ;/***TP
- MOV M,A ;STORE ANSWER
- MOV L,E ;LPTR BACK TO L
- RET
- ;
- ; SUBROUTINE MSFH
- ;
- ; THIS SUBROUTINE FETCHES THE SIGNS OF THE MANTISSAS
- ; OF THE FLOATING POINT NUMBERS POINTED TO BY (H,L)
- ; AND (H,B) INTO THE A AND E REGISTERS RESPECTIVELY.
- ;
- ; REGISTERS ON EXIT:
- ;
- ; A = SIGN OF MANTISSA OF (H,L)
- ; E = SIGN OF MANTISSA OF (H,B)
- ; B,C,D,H,L = SAME AS ON ENTRY
- ;
- MSFH: MOV E,L ;SAVE LPTR
- MOV L,B ;BPTR TO L
- INR L ;BPTR\2
- INR L ;/***TP
- INR L ;TO L
- MOV A,M ;_BPTR\2>TO A
- ANI 128 ;SAVE MANT SIGN
- MOV L,E ;LPTR BACK TO L
- MOV E,A ;STORE BPTR MANT SIGN
- INR L ;LPTR\2
- INR L ;/***TP
- INR L ;TO L
- MOV A,M ;_LPTR\2>TO A
- ANI 128 ;SAVE LPTR MANT SIGN
- DCR L ;LPTR BACK
- DCR L ;TO L
- DCR L ;/***TP
- RET
- ; SUBROUTINE BCTL
- ; MOVES BPTR CHAR TO LPTR CHAR
- ; DESTROYSE
- BCTL: MOV E,L ;LPTR TO E
- MOV L,B ;BPTR TO L
- INR L ;BPTR \2
- INR L ;/***TP
- INR L ;TO L
- MOV A,M ;BPTR CHAR TO A
- MOV L,E ;LPTR TO L
- INR L ;LPTR \2
- INR L ;TO L
- INR L ;/***TP
- MOV M,A ;STORE BPTR CHAR IN LPTR CHAR
- MOV L,E ;LPTR TO L
- RET
- ;
- ;
- ;******************************************************
- ; //// 5 DIGIT FLOATING PT. OUTPUT
- ;******************************************************
- ;
- ;
- ;
- ;
- ; *******ROUTINE TO CONVERT FLOATING PT.
- ; ***NUMBERS TO ASCII AND OUTPUT THEM VIA A SUBROUTINE
- ; ***CALLED OUTR - NOTE: THIS IS CURRENTLY SET
- ; ***TO ODT'S OUTPUT ROUTINE
- ;
- ;
- CVRT: CALL ZCHK ;CHECK FOR NEW ZERO
- JNZ NNZRO ;NOT ZERO
- INR C ;IT WAS, OFFSET C BY 2
- INR C
- MOV L,C
- CALL WZER ;WRITE ZERO
- INR L ;PNT TO DECIMAL EXPONENT
- INR L
- INR L
- INR L
- XRA A ;SET IT TO ZERO
- MOV M,A
- JMP MDSKP ;OUTPUT IT
- NNZRO: MOV D,M ;/GET THE NUMBER TO CONVERT
- INR L
- MOV B,M
- INR L
- MOV E,M
- INR L ;/4 WORD***TP
- MOV A,M ;/***TP
- INR C ;/OFFSET SCRATCH POINTER BY 2
- INR C
- MOV L,C ;/L NOT NEEDED ANY MORE
- MOV M,D ;/SAVE NUMBER IN SCRATCH
- INR L
- MOV M,B
- INR L
- MOV M,E ;/***TP
- INR L ;/***TP
- MOV B,A ;/SAVE COPY OF CHAR & SIGN
- ANI 177Q ;GET ONLY CHAR.
- MOV M,A ;/SAVE ABS(NUMBER)
- CPI 100Q ;CK FOR ZERO
- JZ NZRO
- SUI 1 ;/GET SIGN OF DEC. EXP
- ANI 100Q ;/GET SIGN OF CHAR.
- NZRO: RLC ;MOVE IT TO SIGN POSITION
- INR L ;/MOVE TO DECIMAL EXP.
- MOV M,A ;/SAVE SIGN OF EXP.
- MOV A,B ;/GET MANT. SIGH BACK
- CALL SIGN ;/OUTPUT SIGN
- MVI L,(TEN5 AND 377Q) ;/TRY MULT. OR DIV. BY 100000 FIRST
- CALL COPT ;/MAKE A COPY IN RAM
- TST8: CALL GCHR ;/GET CHAR. OF NUMBER
- MOV B,A ;/SAVE A COPY
- ANI 100Q ;/GET ABSOLUTE VALUE OF CHAR
- MOV A,B ;/INCASE PLUS
- JZ GOTV ;/ALREADY PLUS
- MVI A,200Q ;/MAKE MINUS INTO PLUS
- SUB B ;/PLUS=200B-CHAR
- GOTV: CPI 22Q ;/TEST FOR USE OF 100000
- JM TRY1 ;/WONT GO
- CALL MORD ;/WILL GO SO DO IT
- ADI 5 ;/INCREMENT DEC. EXPONENT BY 5
- MOV M,A ;/UPDATE MEM
- JMP TST8 ;/GO TRY AGAIN
- TRY1: MVI L,(TEN AND 377Q) ;/NOW USE JUST TEN
- CALL COPT ;/PUT IT IN RAM
- TST1: CALL GCHR ;/GET CHARACTERISTIC
- CPI 1 ;/MUST GET IN RANGE 1 TO 6
- JP OK1 ;/ATLEAST ITS 1 OR BIGGER
- MDGN: CALL MORD ;/MUST MUL OF DIV BY 10
- ADI 1 ;/INCREMENT DECIMAL EXP.
- MOV M,A ;/UPDATE MEM
- JMP TST1 ;/NOW TRY AGAIN
- OK1: CPI 7 ;/TEST FOR LESS THAN 7
- JP MDGN ;/NOPE - 7 OR GREATER
- MDSKP: MOV L,C ;/SET UP DIGIT COUNT
- DCR L
- DCR L ;/IN 1ST WORD OF SCRATCH
- MVI M,5 ;/5 DIGITS
- MOV E,A ;/SAVE CHAR. AS LEFT SHIFT COUNT
- CALL LSFT ;/SHIFT LEFT PROPER NUMBER
- CPI 12Q ;/TEST FOR 2 DIGITS HERE
- JP TWOD ;/JMP IF 2 DIGITS TO OUTPUT
- CALL DIGO ;/OUTPUT FIRST DIGIT
- POPD: CALL MULTT ;/MULTIPLY THE NUMBER BY 10
- INPOP: CALL DIGO ;/PRINT DIGIT IN A
- JNZ POPD ;/MORE DIGITS?
- MVI A,305Q ;/NO SO PRINT E
- CALL OUTR ;/BASIC CALL TO OUTPUT
- CALL GETEX ;/GET DECIMAL EXP
- MOV B,A ;/SAVE A COPY
- CALL SIGN ;/OUTPUT SIGN
- MOV A,B ;/GET EXP BACK
- ANI 77Q ;/GET GOOD BITS
- CALL CTWO ;/GO CONVERT 2 DIGITS
- DIGO: ADI 260Q ;/MAKE A INTO ASCII
- CALL OUTR ;/OUTPUT DIGIT
- MOV L,C ;/GET DIGIT COUNT
- DCR L ;/BACK UP TO DIGIT COUNT
- DCR L
- MOV A,M ;/TEST FOR DECIMAL PT
- CPI 5 ;/PRINT . AFTER 1ST DIGIT
- MVI A,256Q ;/JUST IN CASE
- CZ OUTR ;/OUTPUT . IF 1ST DIGIT
- MOV D,M ;/NOW DECREMENT DIGIT COUNT
- DCR D
- MOV M,D ;/UPDATE MEM AND LEAVE FLOPS SET
- RET ;/SERVES AS TERM FOR DIGO & CVRT
- MULTT: MVI E,1 ;/MULT. BY 10 (START WITH X2)
- CALL LSFT ;/LEFT SHIFT 1 = X2
- MOV L,C ;/SAVE X2 IN "RESULT"
- DCR L ;/SET TO TOP OF NUMBER
- MOV A,C ;/SET C TO RESULT
- ADI 11Q
- MOV C,A ;/NOW C SET RIGHT
- MOV A,H ;/SHOW RAM TO RAM TRANSFER
- CALL COPY ;/SAVE X2 FINALLY
- MOV A,C ;/MUST RESET C
- SUI 11Q ;/BACK TO NORMAL
- MOV C,A
- MVI E,2 ;/NOW GET (X2)X4=X8
- MOV L,C ;/BUT MUST SAVE OVERFLOW
- DCR L
- CALL TLP2 ;/GET X8
- MOV L,C ;/SET UP TO CALL DADD
- MOV A,C ;/SET B TO X2
- ADI 12Q ;/TO X2
- MOV B,A
- CALL DADD ;/ADD TWO LOW WORDS
- DCR L ;/BACK UP TO OVERFLOW
- MOV A,M ;/GET IT
- MOV L,B ;/NOW SET TO X2 OVERFLOW
- DCR L ;/ITS AT B-1
- ADC M ;/ADD WITH CARRY - CARRY WAS PRESERVED
- RET ;/ALL DONE, RETURN OVERFLOW IN A
- LSFT: MOV L,C ;/SET PTR FOR LEFT SHIFT OF NUMBER
- DCR L ;/BACK UP TO OVERFLOW
- XRA A ;/OVERFLOW=0 1ST TIME
- TLOOP: MOV M,A ;/SAVE OVERFLOW
- TLP2: DCR E ;/TEST FOR DONE
- RM ;/DONE WHEN E MINUS
- INR L ;/MOVE TO LOW
- INR L
- INR L ;/***TP EXTENSION
- MOV A,M ;/SHIFT LEFT 4 BYTES
- RAL
- MOV M,A ;/PUT BACK
- DCR L ;/***TP - ALL DONE
- MOV A,M ;/GET LOW
- RAL ;/SHIFT LEFT 1
- MOV M,A ;/RESTORE IT
- DCR L ;/BACK UP TO HIGH
- MOV A,M ;/GET HIGH
- RAL ;/SHIFT IT LEFT WITH CARRY
- MOV M,A ;/PUT IT BACK
- DCR L ;/BACK UP TO OVERFLOW
- MOV A,M ;/GET OVERFLOW
- RAL ;/SHIFT IT LEFT
- JMP TLOOP ;/GO FOR MORE
- SIGN: ANI 200Q ;/GET SIGN BIT
- MVI A,240Q ;/SPACE INSTEAD OF PLUS
- JZ PLSV ;/TEST FOR +
- MVI A,255Q ;/NEGATIVE
- PLSV: CALL OUTR ;/OUTPUT SIGN
- RET
- GCHR: MOV L,C ;/GET CHARCTERISTIC
- GETA: INR L ;/MOVE TO IT
- INR L
- INR L ;/***TP
- MOV A,M ;/FETCH INTO A
- RET ;/DONE
- MORD: CALL GETEX ;/MUL OR DIV DEPENDING ON EXP
- MOV E,A ;/SAVE DECIMAL EXP
- MOV B,L ;/SET UP TO MULT OR DIV
- INR B ;/NOW BOP POINTER SET
- MOV L,C ;/L POINTS TO NUMBER TO CONVERT
- MOV A,C ;/POINT C AT "RESULT" AREA
- ADI 11Q ;/IN SCRATCH
- MOV C,A ;/NOW C SET RIGHT
- MOV A,E ;/NOW TEST FOR MUL
- ANI 200Q ;/TEST NEGATIVE DEC. EXP.
- JZ DIVIT ;/IF EXP IS + THEN DIVIDE
- CALL LMUL ;/MULT.
- FINUP: MOV A,C ;/SAVE LOC. OF RESULT
- MOV C,L ;/C=LOC OF NUMBER (IT WAS DESTROYED)
- MOV L,A ;/SET L TO LOC. OF RESUTL
- MOV A,H ;/SHOW RAM TO RAM TRANSFER
- CALL COPY ;/MOVE RESULT TO NUMBER
- GETEX: MOV L,C ;/NOW GET DECIMAL EXP
- INR L
- JMP GETA ;/USE PART OF GCHR
- DIVIT: CALL LDIV ;/DIVIDE
- JMP FINUP
- TWOD: CALL CTWO ;/CONVERT TO 2 DIGITS
- MOV B,A ;/SAVE ONES DIGIT
- CALL GETEX ;/GET DECIMAL EXP
- MOV E,A ;/SAVE A COPY
- ANI 200Q ;/TEST FOR NEGATIVE
- JZ ADD1 ;/BUMP EXP BY 1 SINCE 2 DIGITS
- DCR E ;/DECREMENT NEGATIVE EXP SINCE 2 DIGITS
- FINIT: MOV M,E ;/RESTORE EXP WITH NEW VALUE
- MOV A,B ;/NOW DO 2ND DIGIT
- JMP INPOP ;/GO OUT 2ND AND REST FO DIGITS
- ADD1: INR E ;/COMPENSATE FOR 2 DIGITS
- JMP FINIT
- CTWO: MVI E,377Q ;/CONVERT 2 DIGIT BIN TO BCD
- LOOP: INR E ;/ADD UP TENS DIGIT
- SUI 12Q ;/SUBTRACT 10
- JP LOOP ;/TIIL NEGATIVE RESULT
- ADI 12Q ;/RESTORE ONES DIGIT
- MOV B,A ;/SAVE ONES DIGIT
- MOV A,E ;/GET TENS DIGIT
- CALL DIGO ;/OUTPUT IT
- MOV A,B ;/SET A TO 2ND DIGIT
- RET
- COPT: MOV A,C ;/COPY FROM 10N TO RAM
- ADI 5
- MOV C,A ;/SET C TO PLACE TO PUT
- MVI A,(TEN5/256)
- CALL COPY ;/COPY IT
- MOV A,C ;/NOW RESET C
- SUI 5
- MOV C,A ;/ITS RESET
- RET
- COPY: MOV B,H ;/SAVE RAM H
- MOV H,A ;/SET TO SOURCE H
- MOV A,M ;/GET 4 WORDS INTO THE REGS.
- INR L
- MOV D,M
- INR L
- MOV E,M
- INR L
- MOV L,M ;/LAST ONE ERASES L
- MOV H,B ;/SET TO DESTINATION RAM
- MOV B,L ;/SAVE 4TH WORD IN B
- MOV L,C ;/SET TO DESTINATION
- MOV M,A ;/SAVE FIRST WORD
- INR L
- MOV A,M ;/SAVE THIS WORD IN A (INPUT SAVES C HERE
- MOV M,D ;/NOW PUT 2ND WORD
- INR L
- MOV M,E
- INR L
- MOV M,B ;/ALL 4 COPIED NOW
- RET ;/ALL DONE
- ;
- ;
- TEN5: DB 303Q,120Q,0Q,21Q ;/303240(8) = 100000.
- TEN: DB 240Q,0Q,0Q,4Q ;/12(8) = 10
- ;
- ; SCRATCH MAP FOR I/O CONVERSION ROUTINES
- ;
- ; RELATIVE TO (C+2)USE
- ; C-2 DIGIT COUNT
- ; C-1 OVERFLOW
- ; C HIGH NUMBER - MANTISSA
- ; C+1 LOW NUMBER
- ; C+2 CHARACTERISTIC
- ; C+3 DECIMAL EXPONEXT (SIGN & MAG.)
- ; C+4 TEN**N
- ; C+5 TEN**N
- ; C+6 TEN**N
- ; C+7 RESULT OF MULT & DIV
- ; C+8 AND TEMP FOR X2
- ; C+9 " "
- ; C+10 L FOR NUMBER TO GO INTO (INPUT ONLY)
- ; C+11 DIGIT JUST INPUT (INPUT ONLY)
- ;
- ;
- ; /*****BEGIN INPUT*************
- ;
- ;
- ERR: STC ;ERROR FLAG
- RET ;AND RETURN
- ;
- ;********************************************************
- ; //// 4 1/2 DIGIT INPUT ROUTINE
- ;*******************************************************
- ;
- ;
- ; /L POINTS TO WHERE TO PUT INPUT NUMBER
- ; /C POINTS TO 13(10) WORDS OF SCRATCH
- ;
- INPUT: MOV B,L ;/SAVE ADDRESS WHERE DATA IS TO GO
- MOV A,C ;/IN SCRATCH
- ADI 17Q ;/COMPUTE LOC. IN SCRATCH
- MOV L,A
- MOV M,B ;/PUT IT
- INR C ;/OFFSET SCRATCH POINTER
- INR C ;/BY 2
- CALL ZROIT ;/ZERO NUMBER
- INR L ;/AND ZERO
- MOV M,A ;/DECIMAL EXPONENT
- CALL GNUM ;/GET INTEGER PART OF NUM
- CPI 376Q ;/TERM=.?
- JZ DECPT ;/YES
- TSTEX: CPI 25Q ;/TEST FOR E
- JZ INEXP ;/YES - HANDLE EXP
- CPI 360Q ;/TEST FOR SPACE TERM (240B-260B)
- JNZ ERR ;/NOT LEGAL TERM
- CALL FLTSGN ;/FLOAT # AND SIGN IT
- SCALE: CALL GETEX ;/GET DECIMAL EXP
- ANI 177Q ;/GET GOOD BITS
- MOV E,A ;/SAVE COPY
- ANI 100Q ;/GET SIGN OF EXP
- RLC ;/INTO SIGN BIT
- ORA A ;/SET FLOPS
- MOV B,A ;/SAVE SIGN
- MOV A,E ;/GET EXP BACK
- JZ APLS ;/JMP IS +
- MVI A,200Q ;/MAKE MINUS +
- SUB E ;/NOW ITS +
- APLS: ADD B ;/SIGN NUMBER
- MOV M,A ;/SAVE EXP (SIGN & MAG.)
- MVI L,(TEN5 AND 377Q) ;/TRY MORD WITH 10**5 FIRST
- CALL COPT ;/TRANSFER TO RAM
- CALL GETEX ;/GET DECIMAL EXP
- INT5: ANI 77Q ;/GET MAG. OF EXP
- CPI 5Q ;/TEST FOR USE OF 10**5
- JM TRYTN ;/WONT GO - TRY 10
- CALL MORD ;/WILL GO SO DO IT
- SUI 5Q ;/MAG = MAG -5
- MOV M,A ;/UPDATE DEC. EXP IN MEM
- JMP INT5 ;/GO TRY AGAIN
- TRYTN: MVI L,(TEN AND 377Q) ;/PUT TEN IN RAM
- CALL COPT
- CALL GETEX ;/SET UP FOR LOOP
- INT1: ANI 77Q ;/GET MAGNITUDE
- ORA A ;/TEST FOR 0
- JZ SAVEN ;/DONE, MOVE NUM OUT AND GET OUT
- CALL MORD ;/NOT DONE - DO 10
- SUI 1Q ;/EXP = EXP -1
- MOV M,A ;/UPDATE MEM
- JMP INT1 ;/TRY AGAIN
- DECPT: MOV L,C ;/ZERO DIGIT COUNT
- DCR L ;/SINCE ITS NECESSARY
- DCR L ;/TO COMPUTE EXP.
- MVI M,0 ;/ZEROED
- CALL EP1 ;/GNUM IN MIDDLE
- MOV E,A ;/SAVE TERMINATOR
- MOV L,C ;/MOVE DIGIT COUNT TO EXP
- DCR L ;/BACK UP TO DIGIT COUNT
- DCR L
- MOV B,M ;/GOT DIGIT COUNT
- CALL GETEX ;/SET L TO DEC. EXP
- MOV M,B ;/PUT EXP
- MOV A,E ;/TERM BACK TO A
- JMP TSTEX ;/TEST FOR E+OR-XX
- INEXP: CALL FLTSGN ;/FLOAT AND SIGN NUMBER
- CALL SAVEN ;/SAVE NUMBER IN (L) TEMP
- CALL ZROIT ;/ZERO OUT NUM. FOR INPUTTING EXP
- CALL GNUM ;/NOW INPUT EXPONENT
- CPI 360Q ;/TEST FOR SPACE TERM.
- JNZ ERR ;/NOT LEGAL - TRY AGAIN
- MOV L,C ;/GET EXP OUT OF MEM
- INR L ;/***TP
- INR L ;/EXP LIMITED TO 5 BITS
- MOV A,M ;/GET LOWEST 8 BITS
- ANI 37Q ;/GET GOOD BITS
- MOV B,A ;/SAVE THEM
- INR L ;/GET SIGN OF EXP
- MOV A,M ;/INTO A
- ORA A ;/SET FLOPS
- MOV A,B ;/INCASE NOTHING TO DO
- JM USEIT ;/IF NEG. USE AS +
- MVI A,0Q ;/IF + MAKE -
- SUB B ;/0-X = -X
- USEIT: INR L ;/POINT AT EXP
- ADD M ;/GET REAL DEC. EXP
- MOV M,A ;/PUT IN MEM
- MOV A,C ;/NOW GET NUMBER BACK
- ADI 15Q ;/GET ADD OF L
- MOV L,A ;/L POINTS TO L OF NUMBER
- MOV L,M ;/NOW L POINTS TO NUMBER
- MOV A,H ;/RAM TO RAM COPY
- CALL COPY ;/COPY IT BACK
- JMP SCALE ;/NOW ADJUST FOR EXP
- GNUM: CALL INP ;/GET A CHAR
- CPI 240Q ;/IGNORE LEADING SPACES
- JZ GNUM
- CPI 255Q ;/TEST FOR -
- JNZ TRYP ;/NOT MINUS
- MOV L,C ;/MINUS SO SET SIGN
- INR L ;/IN CHAR LOC.
- INR L ;/***TP
- INR L
- MVI M,200Q ;/SET - SIGN
- JMP GNUM
- TRYP: CPI 253Q ;/IGNORE +
- JZ GNUM
- TSTN: SUI 260Q ;/STRIP ASCII
- RM ;/RETURN IF TERM
- CPI 12Q ;/TEST FOR NUMBER
- RP ;/ILLEGAL
- MOV E,A ;/SAVE DIGIT
- CALL GETN ;/LOC. OF DIGIT STORAGE TO L
- MOV M,E ;/SAVE DIGIT
- CALL MULTT ;/MULT NUMBER BY 10
- ORA A ;/TEST FOR TOO MANY DIGITS
- RNZ ;/TOO MANY DIGITS
- CALL GETN ;/GET DIGIT
- MOV L,C ;/SET L TO NUMBER
- INR L
- INR L ;/***TP
- ADD M ;/ADD IN THE DIGIT
- MOV M,A ;/PUT RESULT BACK
- DCR L ;/NOW DO HIGH
- MOV A,M ;/GET HIGH TO ADD IN CARRY
- ACI 0Q ;/ADD IN CARRY
- MOV M,A ;/UPDATE HIGH
- DCR L ;/***TP EXTENSION
- MOV A,M
- ACI 0Q ;/ADD IN CARRY
- MOV M,A ;/***TP ALL DONE
- RC ;/OVERFLOW ERROR
- DCR L ;/BUMP DIGIT COUNT NOW
- DCR L
- MOV B,M ;/GET DIGIT COUNT
- INR B ;/BUMP DIGIT COUNT
- MOV M,B ;/UPDATE DIGIT COUNT
- EP1: CALL INP ;/GET NEXT CHAR
- JMP TSTN ;/MUST BE NUM. OR TERM
- FLTSGN: MOV L,C ;POINT L AT NUMBER TO FLOAT
- JMP FLOAT ;GO FLOAT IT
- SAVEN: MOV A,C ;/PUT NUMBER IN (L)
- ADI 15Q ;/GET ADD OF L
- MOV L,A
- MOV E,M ;/GET L OF RESULT
- MOV L,E ;/POINT L AT (L)
- INR L ;/SET TO 2ND WORD TO SAVE C
- MOV M,C ;/SAVE C IN (L) +1 SINCE IT WILL BE DESTROYED
- MOV L,C ;/SET UP TO CALL COPY
- MOV C,E ;/NOW L&C SET
- MOV A,H ;/RAM TO RAM COPY
- CALL COPY ;/COPY TO L
- MOV C,A ;/(L)+1 RETURNED HERE SO SET AS C
- ORA A ;MAKE SURE CY=0 (NO ERROR)
- RET ;/NOW EVERYTHING HUNKY-DORRY
- GETN: MOV A,C ;/GET DIGIT
- ADI 16Q ;/LAST LOC. IN SCRATCH
- MOV L,A ;/PUT IN L
- MOV A,M ;/GET DIGIT
- RET
- ZROIT: MOV L,C ;/ZERO NUMBER
- XRA A
- MOV M,A ;/***TP
- INR L ;/***TP
- MOV M,A
- INR L
- MOV M,A
- INR L ;/NOW SET SIGN TO +
- MOV M,A
- RET ;/DONE
- ; CONTAIN LOW BYTE OF TWO BYTE VALUE. RETURNS CY=1 IF
- ; BC>DE, CY=0 IF BC<DE: Z=1 IF BC=DE.
- DCOMP: MOV A,E
- CMP C
- RNZ
- MOV A,D
- CMP B
- RET
- ; ROUTINE TO INPUT CHAR FROM TTY
- CHAR2: PUSH B
- CALL CONIN ;INPUT FROM ODT
- MOV A,B ;GET CHAR TO A REG.
- POP B ;RESTORE B,C
- RET
- ; ROUTINE TO ADJUST VALUES OF BIN, FORWARD PNT. AND
- ; LINE LENGTH OF SOURCE LINE. PASSED ADD OF TEMP VARIABLE
- ; CONTAINING ADD OF SOURCE LINE.
- PTVAL: PUSH PSW
- PUSH D
- PUSH H
- MVI A,002
- MOV E,M
- INR L
- MOV D,M
- INR L
- PUSH D
- N1: XTHL
- MOV E,M
- INX H
- MOV D,M
- INX H
- XTHL
- MOV M,E
- INR L
- MOV M,D
- INR L
- DCR A
- JNZ N1
- XTHL
- MOV D,M
- POP H
- MOV M,D
- POP H
- POP D
- POP PSW
- RET
- ; ROUTINE TO CHK FLAGS ON INPUT AND OUTPUT.
- ; PASSED FLAG VALUE IN REG B.
- MCHK: PUSH PSW
- MCHK1: CALL STATUS
- ANA B
- JZ MCHK1
- POP PSW
- RET
- ; MULTIPLICATION ROUTINE (ADD. VALUES)
- MULT: MOV E,M
- DCX H
- MOV D,M
- MVI M,11H
- MVI B,0
- MOV C,B
- TOP: MOV A,E
- RAR
- MOV E,A
- MOV A,D
- RAR
- DCR M
- MOV D,A
- RZ
- JNC SHIFT
- DCX H
- DCX H
- MOV A,B
- ADD M
- MOV B,A
- INX H
- MOV A,C
- ADC M
- MOV C,A
- INX H
- SHIFT: MOV A,C
- RAR
- MOV C,A
- MOV A,B
- RAR
- MOV B,A
- JMP TOP
- ;LINKAGES TO FLOATING POINT ROUTINES
- ORG 113707Q
- JMP NORM
- JMP FLOAT
- JMP WZER
- JMP LADD
- JMP LMUL
- JMP LDIV
- JMP LSUB
- JMP DFXL
- JMP LMCM
- JMP COPY
- JMP CVRT
- JMP INPUT
- JMP MULT
- JMP PTVAL
- JMP DCOMP
- JMP MCHK
- JMP CHAR2
- JMP INL
- JMP OUTL
- END
-