;###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 ; ; ;###S ; EQUATES FOR RELOCATED PACKAGES ORG 10DDH INTERP: EQU 0100H FPTBL: EQU 1774H IOJUMP: EQU 1900H CONIN: EQU IOJUMP+4 STATUS: EQU IOJUMP+0AH INP: EQU FPTBL+33H OUTR: EQU FPTBL+36H OUTL: EQU INTERP+7D9H INL: EQU INTERP+996H ; ORG 110000Q ; ; CPM: EQU 5 ;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 ;###E 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 ;###S ORG 1774H FPTBL: ; ORG 113707Q ;###E 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