SW9511 MACRO ;; ;; LAST MODIFICATION MADE 24-DEC-79 ;; LOCAL TRUE,FALSE FALSE EQU 0 TRUE EQU NOT FALSE ;; ;; USED FOR SOFTWARE FLOATING POINT FOR PASCAL/MT RUN-TIME ;; ;; ;; ;; ;; ;; ;; ;; JUMP TABLE LOCATED AT START FOR CONVIENENCE ;; ;; SWRADD: JMP FPRADD ;;FLOATING ADD ;; SWRSUB: JMP FPRSUB ;;FLOATING SUBTRACT ;; SWRMUL: JMP FPRMUL ;;FLOATING MULTIPLY ;; SWRDIV: JMP FPRDIV ;;FLOATING DIVIDE ;; SWRSQRT: JMP FPRSQR ;;SQUARE ROOT ;; ;; RFIX: JMP FPFIX ;;GO DIRECTLY TO MATH PAK ROUTINE ;; RFLT: JMP FLOAT2 ;; DITTO ;; ;; ;; ;; FPRADD: CALL FPSETP CALL FLOATADD CALL FPCLNP RET ;; ;; FPRSUB: CALL FPSETP CALL FPSUB CALL FPCLNP RET ;; ;; FPRMUL: CALL FPSETP CALL FLOATMULT CALL FPCLNP RET ;; ;; FPRDIV: CALL FPSETP CALL FLOATDIV CALL FPCLNP RET ;; ;; ;; SUBR TO SET UP DATA FOR MATH PAK ROUTINES ;; FPSETP: POP D ;;DE=RTN ADR TO CALLERR OF FPSETP SUBR POP B ;;BC=RTN ADR OF CALLER OF RXXX SUBR POP H ;;L=EXP OF TOS H=MANT(HIGH) OF TOS SHLD TOS ;;PLACE ARGU ON SIMULATED 9511 WORK STACK POP H ;;HL=REST OF 1ST ARGU SHLD TOS2 POP H ;;HL=1ST 2 BYTES OF 2ND ARGU SHLD NOS POP H SHLD NOS2 ;;SIMULATED 9511 STACK IS NOW LOADED ;; PUSH B ;;TOP OF SYS STACK=RTN ADR OF RXXX CALLER ;; XCHG PCHL ;;RTN TO CALL OF THIS SUBR ;; ;; ;; ;; SUBR TO PUT RESULT IN FORM FOR CALLING ROUTINES ;; FPCLNP: POP D ;;DE=RTN ADR TO CALL OF FPCLNP SUBR POP B ;;BC=RRTN ADR TO CALLER OF RXXX SUUBR ;; LHLD TOS2 ;;GET MIDDLE AND LOWER OF MANT OF RESULT PUSH H ;;PUT ON SYS STACK FOR RXXX CALLER LHLD TOS PUSH H ;;TOP 4 BYTES OF SYS STACK NOW HAVE FLPT RRESULT ;; PUSH B ;;TOP OF SYSSTACK = RTN ADR OF RXXX CALLER ;; XCHG PCHL ;;RTN TO CALL OF THIS SUBR ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; FPNSUB: EQU 14 ;;NUMBER OF NESTING LEVELS FOR INTERP SUBRS ;; ;; FPMSTK: EQU FALSE ;;INDICATOR FOR USE OF INTERNAL STACK FOR ;;FP ARITH OPERATIONS. IF TRUE AN INTERNAL STACK ;;WILL BE ALLOCATED IN RAM. IF FALSE THE SYSTEM ;;STACK WILL BE USED. ;; FPTRNF: EQU FALSE ;;TRANSCENDENTAL FLAG IF TRUE ;; THESE FUNCTIONS ARE INCLUDED ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; THESE SUBROUTINES PERFORM FLOATING POINT ADD AND SUBTRACT IN ;; AMD-9511 FORMAT. ;; ;; ;; ;; CSEG ;; ;; ;; ;; PUBLIC FLOATADD,FPSUB,FPSUBS ;; ;; ;; FPSUBS: STC ;;SET SPECIAL MODE FLAG = TRUE JMP FPSUB1 ;; ;; FPSUB: XRA A ;; SET SPECIAL MODE FLAG (CARRY BIT) = FALSE FPSUB1: PUSH PSW ;;SAVE CALL FPEQZR ;;ON RET HL=TOS JZ FLOATADD1 ;;JMP IF TOS =0 DONT COMPL IT MOV A,M XRI 80H MOV M,A ;;COMPL SIGN OF TOS JMP FLOATADD1 ;;THEN DO AN ADD ;; ;; ;; FLOATADD: XRA A ;;SET SPECIAL MODE FLAG FALSE PUSH PSW FLOATADD1: LHLD NOS MOV A,L ORA H ;;A=BITS OF EXP+HIGH BITS OF MANT JNZ ADD20 ;;JMP IF NOS NOT ZERO ;; IF NOS=0 DONT DO ACTUAL ARITHMETIC POP PSW ;;GET SPECIAL MODE FLAG JNC FPPOP ;;JMP IF NOT SPECIAL MODE AND RET FROM THAT SUBR ;; TOS IS ANSWER LXI H,TOS ADD21: MOV B,M ;;GET EXP INTO B FOR FPCMP OPCODE PROCESSOR INX H MOV C,M ;;GET HIGH BITS OF MANT FOR SAME REASON RET ;;ALL DONE ADD20: CALL FPEQZR JNZ ADD00 ;;JMP IF TOS NOT ZERO ;; IF TOS=0 DONT DO ACTUAL ARITHMETIC POP PSW ;;GET SPECIAL MODE FLAG JNC FPPOPP ;;JMP IF NOT SPECIAL MOD AND RETURN FROM THAT SUBR ;; NOS IS ANSWER LXI H,NOS JMP ADD21 ;;DO STUFF FOR SPECIAL MODE ADD00: CALL EXPS2 ;;ON RETURN A=EXP OF NOS B=EXP OF TOS SUB B ;;A HAS DIFFERENCE OF EXP'S . THISWILL BE THE SHIFT CNT PUSH PSW ;;SAVE LXI H,TOS JM ADD01 ;;JMP IF TOS>NOS LXI H,NOS ADD01: MOV A,M ;;HL HAS ADR OF LARGER VALUE SAVE IT POP B PUSH PSW PUSH B ;;SAVE EXP DIFFERENCE IN RIGHT ORDER ON STACK CALL ADDS1 ;;ON RET BCDE = MANT IN 2' COMPL FORM OF LARGER VALUE POP PSW ;;GET EXP DIFFERENCE PUSH B PUSH D ;;SAVE SO CAN ADD IT TO OTHER MANTISSA PUSH PSW ;;SAVE EXP DIFFERENCE AGAIN LXI H,NOS JM ADD02 ;;JMP IF TOS>NOS LXI H,TOS ADD02: CALL ADDS1 ;;ON RETURN BCDE = MANT IN 2'S COMPL FORM OF SMALLER POP PSW ;;GET EXP DIFFERENCE I.E. SHIFT COUNT JP ADD12 ;;JMP IF DIFF IS NEG CMA ;;* MAKE DIFF POS INR A ;;* ADD12: MOV L,A ;;L WILL BE SHIFT COUNT CPI 24D JP ADD06 ;;JMP IF SMALLER IS TOO SMALL TO HAVE EFFECT ON LARGER ORA A JZ ADD03 ;;JMP IF EXP'S ARE EQUAL NO SHIFT REQUIRED ;; ADD04: MOV A,B ;;* ORA A ;;* JP ADD05 ;;* PERFORM 32 BIT RIGHT SHIFT WITH SIGN EXTENSION STC ;;* ADD05: CALL ADSHRC ;;* DCR L JNZ ADD04 ;; ADD03: XCHG ;;HL HAS LOWER 16 BITS POP D ;;DE HAS LOWER 16 BITS OF OTHER VALUE DAD D XCHG ;;DE HAS LOWER 16 BITS OF SUM MOV H,B MOV L,C ;;HL HAS UPPER 16 BITS POP B ;;GETUPPER 16 BITS OF TOHER VALUE JNC ADD07 ;;JMP IF NO CARRY OUT OF LOWER 16 BITS OF SUM INX B ;;CARRY OUT OF LOW BITS ADD INTO HIGH BITS ADD07: DAD B ;;HLDE HAVE 32 BIT SUM MOV B,H MOV C,L ;;BCDE NOW HAVE 32 BIT SUM ;; MOV A,B ANI 80H ;;LEAVE SIGN BIT OF SUM MOV H,A ;;SAVE CM ADDCMP ;;MAKE SUM POS IF CAME OUT NEGATIVE XRA A MOV L,A ;;SET EXP INCR COUNT FOR 24 BIT RESULT ORA B ;;SEE IF ANY BITS IN B JZ ADD09 ;;JMP IF RESULT CONTAINED IN ONLY 24 BITS CALL ADSHRC ;;RESULT IS 25 BITS MAKE INTO 24 BITS SIZE INR L ;;EXP INCR VALUE ADD09: MOV B,C MOV A,C ORA D ORA E JZ ADD13 ;;JMP IF RESULT ENTIRELY ZERO ;; MOV A,C ADD11: ANI 80H ;;CHECK FOR NORMALIZED RESULT JNZ ADD10 ;;JMP IF NORMALIZED DCR L ;;NOT NORMALIZED YET DECR EXP COUNT MOV A,E ;;* RAL ;;* MOV E,A ;;* MOV A,D ;;* RAL ;;* 24 BIT LEFT SHIFT MOV D,A ;;* MOV A,C ;;* RAL ;;* MOV C,A ;;* JMP ADD11 ;; ADD10: POP PSW ;;GET EXP OF LARGER VALUE INTO A ADD L ;;ADD IN EXP INCR VALUE ANI 7FH ;;LEAVE EXP PORTION ORA H ;;PUT IN SIGN BIT OF RESULT MOV B,A ;;BCDE CONTAIL RESULT IN FLPT FORMAT ;; ;; ADD08: IF FPMSTK LHLD FPUSTK SPHL ;;RESTORE STACK PT OF CALLER THIS WAS SET UP BY ;; EXPS2 SUBR ENDIF ;; POP PSW ;;GET SPECIAL MODE FLAG RC ;;ALL DONE NOW IF CALLED IN SPECIAL MODE ;; LXI H,TOS MOV M,B INX H MOV M,C INX H MOV M,D INX H MOV M,E ;;SAVE RESULT CALL FPPOP ;;POP UP REST OF FLPT WORK STACK RET ;;ALL DONE ;; ;; ADD06: POP D ;;LARGER VAL WAS TOO MUCH LARGER - JUST USE ;; LARGER VAL AS RESULT POP B ;;BCDE = MANT IN 2'S COMPL FORM (32 BIT) MOV A,B ORA A CM ADDCMP ;; MAK POS IF NEG ( THE MANT SIGN BIT IS STILL IN THE ;; EXP BYTE WHICH IS POP'ED NEXT ) POP PSW MOV B,A ;;MOVE ORIGINAL EXP BYTE INTO RESULT AREA JMP ADD08 ;; ;; ADD13: POP PSW ;;ADJUST STACK SO CAN JOIN OTHER CODE JMP ADD08 ;; ;; ;; ;; ADDS1: MOV A,M ;;THIS SUBR RETURN THE MANTISSA OF THE FLPT VALUE ;; POINTED AT BY HL IN REG'S BCDE (B=HIGH BITS, E=LOW BITS) ;; THE 32 BIT MANT VALUE IS IN 2'S COMLP FROM. ;; INX H MOV C,M INX H MOV D,M INX H MOV E,M ;;CDE HAVE MANT MVI B,0 ;;B HAS UPPER BITS ORA A CM ADDCMP ;;MAKE 2'S COMPL NEG VALUE IF MANT IS NEG RET ;; ;; ;; ADDCMP: MOV A,E ;;THIS SUBR FORMS THE 32 BIT 2'S COMPL OF BCDE CMA ADI 1 MOV E,A MOV A,D CMA ACI 0 MOV D,A MOV A,C CMA ACI 0 MOV C,A MOV A,B CMA ACI 0 MOV B,A RET ;; ;; ;; ADSHRC: MOV A,B ;; THIS SUBR PERFORMS A RIGHT SHIFT OF THE 32 BIT ;; QUANTITY IN BCDE. THE CARRY BIT FROM THE CALLER IS ;; SHIFTED INTO THE HIGH END OF B. RAR MOV B,A MOV A,C RAR MOV C,A MOV A,D RAR MOV D,A MOV A,E RAR MOV E,A RET ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; THIS SUBROUTINE PERFORMS A FLOATING POINT (AMD-9511 FORMAT) ;; MULTIPLY. TOS IS MULTIPLIED BY NOS,THE RESULT IS PALCED IN NOS, AND ;; THE FLOATING POINT WORK STACK IS POP'ED. ;; ;; ;; THE MANTISSA OF THE MULTIPLIER IS PLACED ONE BIT AT A TIME IN ;; THE STACK AS THE CARRY BIT OF THE PSW. THE MULTIPLICAND MANTISSA IS ;; IN REG'S D, B, AND C (HIGH, MIDDLE, LOW ORDER). ;; THE PRODUCT IS ACCUMULATED IN REG'S E, H, AND L. ;; ;; ;; ;; ;; ;; CSEG ;; ;; ;; PUBLIC FLOATMULT,EXPS2,EXPS1,MUL15 ;; ;; ;; FLOATMULT: CALL EXPS2 ;;GET BOTH EXPONENTS AND PLAY WITH THEM A BIT ADD B ;;B HAS 8 BIT 2'S COMPL EXP OF PRODUCT PUSH PSW ;;SAVE PARTIAL EXP BYTE ;; ;; ;; ALL DONE WITH EXP NOW PUT MULTIPLIER ONTO STACK ONE BIT AT A TIME ;; MVI C,8D ;;LOOP COUNTER MOV B,C LDA NOS3 ;;GET LOW BITS OF MULPITLIER MANTISSA MUL01: RAR ;;SHIFT BIT OF MANT INTO CARRY BIT PUSH PSW ;;SAVE BIT OF MANT AS CARRY BIT IN PSW DCR B JNZ MUL01 ;;DO ALL 8 LOW BITS OF MANT MOV B,C LDA NOS2 ;;GET MIDDLE BITS OF MULTIPLIER MANT MUL02: RAR PUSH PSW DCR B JNZ MUL02 ;;DO ALL 8 MIDDLE BITS OF MANT DCR C ;;SET LOOP COUNTER TO 7 (SEVEN) LDA NOS1 ;;GET UPPER BITS OF MULTIPLIER MANT MUL03: RAR PUSH PSW DCR C JNZ MUL03 ;;DO LOWER 7 BIT OF UPPER 8 BITS OF MANT ;; THE HIGHEST BIT MUST BE A 1 (ONE) ANI 1 ;;THIS SHOULD BE HIGHEST BIT OF MANT JZ XMUL16 ;;JMP IF MULTIPLIER ZERO OR NOT NORMALIZED ;; MVI A,0FFH ;;MINUS ONE STA FPTEMP ;;SET CARRY OUT OF 24TH BIT PLACE FLAG TO FALSE ;; ;; BITS OF MULTIPLIER ARE NOW ON STACK AS CARRY BITS ;; NOW LOAD UP REGS WITH MULTIPLICAND MANT AND PRODUCT ACCUM ;; LXI H,TOS1 MOV D,M ;;D HAS UPPER BITS OF MULTIPLICAND MANTISSA XRA D ;;A HAD ALL ONE'S JM XMUL16 ;;JMP IF MULTIPLICAND ZERO OR NOT NORMALIZED INX H MOV B,M ;;B HAS MIDDLE BITS OF MULTIPLICAND MANT INX H MOV C,M ;;C HAS LOWER BITS OF MULTIPLICAND MANT ;; MOV E,D ;;* MOV H,B ;;* PRODUCT ACCUM = MULTIPLICAND MANT MOV L,C ;;* ;; ;; MUL05: XRA A ;;CLEAR CARRY BIT MOV A,D ;;* RAR ;;* MOV D,A ;;* MOV A,B ;;* RAR ;;* MULTIPLICAND=MULTIPLICAND/2 MOV B,A ;;* MOV A,C ;;* RAR ;;* MOV C,A ;;* ORA B ORA D JZ MUL08 ;;JMP IF DONE I.E. MULTIPLICAND HAS BEEN SHIFTED ;; 24 TIMES ;; POP PSW ;;GET A BIT FROM MULTIPLIER JNC MUL05 ;;JMP IF BIT WAS ZER0 DAD B ;;* MOV A,D ;;* ADD CURRENT VALUE OF MULTIPLICAND INTO ADC E ;;* PRODUCT ACCUMULATOR REGS MOV E,A ;;* JNC MUL05 ;;JMP IF NO CARRY OUT OF 24 TH BIT PLACE XRA A STA FPTEMP ;;SET CARRY OUT OF 24TH BIT PLACE FLAG TO TRUE JMP MUL05 ;; AGAIN ;; ;; ;; PRODUCT MANTISSA IS IN E, H, L AND MAGICALLY IS NORMALIZED ALREADY ;; MUL08: MOV C,L MOV D,H ;;E, D, AND C NOW HAVE MANTISSA OF PRODUCT LXI H,FPTEMP ORA M ;;CHECK CARRY OUT FLAG (NOTE - A MUST BE ZERO ) JNZ MUL09 ;;JMP IF FLAG=FALSE I.E. PROD MANT IS OKAY AS IS STC MOV A,E ;;* RAR ;;* MOV E,A ;;* MOV A,D ;;* RAR ;;* PUT CARRIED OUT BIT BACK INTO HIGH BIT OF PROD MOV D,A ;;* MOV A,C ;;* RAR ;;* MOV C,A ;;* MUL09: POP PSW ;; GET PARTIAL EXP BYTE INTO A ADD M ;;ADJUST EXP IF NECESSARY ANI 7FH ;;MAKE EXP INTI 7 BIT 2'S COMPL MOV B,A ;;SAVE LDA NOS ;;GET EXP OF MULTIPLIER INR L ;;HL NOW POINTS AT 1ST BYTE OF TOS XRA M ;;HIGH BIT OF A IS SIGN OF MANTISSA OF PRODUCT ANI 80H ORA B ;;A NOW HAS COMPLETED EXPONENT OF THE PRODUCT MUL10: MOV M,A ;;SAVE IN FINAL RESTING PLACE INR L MOV M,E INR L MOV M,D INR L MOV M,C ;;COMPLETE PRODUCT IS NOW SAVED IN FINAL RESTING PLACE CALL FPPOP ;; ;; IF FPMSTK LHLD FPUSTK SPHL ;;RESTORE CALLER'S STACK POINTER ENDIF ;; RET ;;THAT'S ALL FOLKS ;; XMUL16: MVI C,23D ;;COME HERE IF MULTILPIER OR ;; MULTILPICAND IS ZERO MUL17: POP PSW ;;REMOVE STUF PUT ON STACK DCR C JNZ MUL17 ;;JMP TIL CLEAN UP STACK ;; MUL15: POP PSW ;;ONE LAST STACK CLEAN UP - ALSO COME HERE FROM FLOATDIV XRA A ;;* MOV E,A ;;* MOV D,A ;;* MOV C,A ;;* SET PRODUCT (OR DIVIDEND) =0 LXI H,TOS ;;PLACE TO PUT IT JMP MUL10 ;; EXPS2: IF FPMSTK POP D ;;THIS SUBR SAVES THE CALLER'S SP AND SETS UP ;; SP FOR THE SPECIAL STACK USED BY FLOATMULT AND FLOATDIV ;; IT THE GETS BOTH EXPONENTS ;; ;; DE=RET ADR OF CALL TO EXPS2. THE USER SP NOW POINTS ;; AT THE RET ADR OF THE CALLER OF FLOATMULT OR FLOATDIV. ;; LXI H,0 DI DAD SP ;;HL=CALLER'S SP SHLD FPUSTK ;;SAVE LXI SP,FPMDST ;;SET UP SP FOR OWN USE EI ENDIF ;; LDA TOS CALL EXPS1 MOV B,A LDA NOS CALL EXPS1 ;; IF FPMSTK XCHG ;;HL HAS RET ADR OF CALL TO EXPS2 SUBR PCHL ENDIF ;; IF FPMSTK XOR 1 RET ENDIF ;; ;; ;; EXPS1: ANI 7FH ;;SIGN EXTEND 7 BIT 2'S COMPL VALUE TO AN 8 BIT 2'S COMPL MOV C,A ANI 40H MOV A,C RZ ORI 80H RET ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; THIS SUBROUTINE PERFORMS A FLOATING POINT (AMD9511 FORMAT) DIVIDE. ;; NOS IS DIVIDED BY TOS, THE RESULT IS PLACED IN NOS, AND THE ;; FLOATING POINT WORK STACK IS POP'ED. APPROXIMATELY 52D BYTES OF ;; SYSTEM STACK SPACE ARE USED. ;; ;; NOS / TOS BCD / EHL ;; ;; ;; ;; BCD REG'S HOLD THE DIVIDEND ;; EHL REG'S HOLD THE DIVISOR ;; ;; ;; ;; ;; ;; CSEG ;; ;; PUBLIC FLOATDIV ;; ;; ;; FLOATDIV: CALL EXPS2 ;;BUILD NEW EXP WITHOUT MANT SIGN BIT SUB B ;;EXP OF DIVIDEND-EXP OF DIVISOR PUSH PSW ;;SAVE PARTIAL EXP ON STACK LXI H,NOS3 ;;GET MANTISSAS FROM NOS AND TOS ;; MOV D,M DCX H MOV C,M DCX H MOV B,M LHLD TOS2 ;;HL=MIDDLE AND UPPER BITS BUT IN WRONG REG'S FOR ME MOV A,H MOV H,L MOV L,A ;;HL ARE IN CORRECT ORDER LDA TOS1 ;;A=UPPER BITS OF TOS MANT MOV E,A ;;BCD= MANT OF NOS EHL=MANTISSA OF TOS ORA A JP DIV99 ;;JMP IF ZERO DIVISOR OR NOT NORMALIZED MOV A,B ORA A JP MUL15 ;;JMP IF DIVIDEND ZERO OR NOT NORMALIZED ;; DIV09: MOV A,B SUB E ;;COMPARE UPPER BITS OF MANT JC DIV01 ;;JMP IF DIVIDENDDIVISOR MOV A,C SUB H ;;COMPARE MIDDLE BITS OF MANT JC DIV01 ;;JMP IF DIVIDENDDIVISOR MOV A,D SUB L ;;COMPARE LOWER BITS OF MANT JC DIV01 ;;JMP IF DIVIDEND