home *** CD-ROM | disk | FTP | other *** search
- NAME FPCNV
- CSEG
-
- PUBLIC FFLOAT,FFIX,FINP,FOUT
- EXTRN FSTOR,FZERO,FABS,FTEST,FLOAD,FMUL
- EXTRN FDIV,FADD,ADD10,LSH,RSH,FCOMP
- EXTRN OVER,ACCE,ACCS,ACC1,ACC2,ACC3,SF
- EXTRN FTEN,RND0
- EXTRN ADRL,ADRH,TMP1,TMP2,TMP3,VALE,VAL1,VAL2,VAL3,TMP4
- ; 8080 BINARY FLOATING POINT SYSTEM
- ; FORMAT CONVERSION PACKAGE
- ; PROGRAMMER CAL OHME
- ; DATE 26 DECEMBER 1973
-
-
- ; SUBROUTINE TO CONVERT FROM FIXED
- ; POINT TO FLOATING POINT FORMAT.
- FFLOAT: MOV L,E; INPUT EXPONENT
- MOV E,D; 4TH INPUT FRACTION
- MOV D,C; 3RD INPUT FRACTION
- MOV C,B; 2ND INPUT FRACTION
- MOV B,A; 1ST INPUT FRACTION
- MOV A,L; INPUT EXPONENT
- XRI 80H; APPLY EXPONENT BIAS
- LXI H,ACCE; TO ADDR ACCUM EXPONENT
- MOV M,A; ACCUMULATOR EXPONENT
- INR L; TO ADDRESS ACCUM SIGN
- MVI M,80H; SET ACCUM SIGN POSITIVE
- INR L; TO ADDR ACCUM 1ST FRCTN
- MOV A,B; 1ST INPUT FRACTION
- ANA A ; SET SIGN BIT
- RAL ; INPUT SIGN TO CARRY
- JMP ADD10; COMPLETE CONVERSION
- ; SUBROUTINE TO CONVERT FROM FLOATING
- ; POINT TO FIXED POINT FORMAT.
- FFIX: LXI H,ACCE; TO ADDRESS SCRATCH BANK
- MOV A,M; ACCUMULATOR EXPONENT
- ANA A ; SET CONTROL BITS
- JZ FIX1; IF ACCUMULATOR IS ZERO
- MOV A,E; INPUT EXPONENT
- ADI 7FH; APPLY BIAS - 1
- SUB M; SHIFT COUNT - 1
- RC ; RETURN IF ACCUM TOO LARGE
- CPI 1FH; COMPARE TO LARGE SHIFT
- JNC FIX1; IF ACCUMULATOR TOO SMALL
- ADI 1; SHIFT COUNT
- MVI L,LOW(ACC1); TO ADDR ACCUM 1ST FRCTN
- MOV B,M; ACCUMULATOR 1ST FRACTION
- INR L; TO ADDR ACCUM 2ND FRCTN
- MOV C,M; ACCUMULATOR 2ND FRCTN
- INR L; TO ADDR ACCUM 3RD FRCTN
- MOV D,M; ACCUMULATOR 3RD FRCTN
- CALL RSH; POSITION THE FRACTION
- MVI L,LOW(ACCS); TO ADDR ACCUM SIGN
- MOV A,M; ACCUMULATOR SIGN
- ANA A ; SET CONTROL BITS
- CP FCOMP; COMPLEMENT FRCTN IF NEG
- MVI A,1; NON-ZERO
- ORA B; SET CONTROL BITS FOR EXIT
- MOV A,B; 1ST RESULT
- MOV B,C; 2ND RESULT
- MOV C,D; 3RD RESULT
- MOV D,E; 4TH RESULT
- RET ; RETURN TO CALLER
- FIX1: XRA A; ZERO
- MOV B,A; ZERO
- MOV C,A; ZERO
- MOV D,A; ZERO
- RET ; RETURN TO CALLER
- DB 0; CHECKSUM WORD
- ; INP SUBROUTINE ENTRY POINT.
- ; INITIALIZE TEMPORARY STORAGE.
- FINP: MOV E,M; FIRST CHARACTER OF STRING
- CALL SVAD; SET CHAR ADDR, PNT FLG, EXP
- INR L; TO ADDRESS VALUE SIGN
- MVI M,80H; SET VALUE SIGN POSITIVE
- LXI H,ACCE; TO ADDR ACCUM EXPONENT
- MOV M,D; SET ACCUM TO ZERO
- MOV A,E; FIRST CHARACTER
- CPI 0F0H; COMPARE TO SPACE
- JZ INP1; IF SPACE CHARACTER
- CPI 0FBH; COMPARE CHAR TO PLUS
- JZ INP1; IF PLUS SIGN
- CPI 0FDH; COMPARE TO MINUS
- JNZ INP2; IF NOT MINUS SIGN
- LXI H,TMP3; TO ADDR VALUE SIGN
- MOV M,D; SET VALUE SIGN NEGATIVE
- ; ANALYZE NEXT CHARACTER IN STRING.
- INP1: CALL CHAD; CALL CHAR ADDR SBRTN
- MOV A,M; NEXT CHARACTER
- INP2: MVI B,0; DIGIT 2ND WD OR DEC EXP
- CPI 0FEH; COMPARE TO DECIMAL POINT
- JZ INP3; IF DECIMAL POINT
- CPI 15H; COMPARE TO EXPONENT SIGN
- JZ INP4; IF EXPONENT SIGN
- CPI 0AH; SET CARRY IF CHAR IS DIGIT
- JNC INP8; IF CHAR IS NOT A DIGIT
- LXI H,TMP4; TO ADDR CURRENT DIGIT
- MOV M,A; SAVE CURRENT DIGIT
- LXI H,FTEN; TO ADDR FLOATING TEN
- CALL FMUL; MULTIPLY BY TEN
- MVI L,LOW(VALE); TO ADDR VALUE
- CALL FSTOR; STORE OLD VALUE TIMES TEN
- INR L; TO ADDR CURRENT DIGIT
- MOV A,M; CURRENT DIGIT
- MVI B,0; CLEAR 2ND WORD OF DIGIT
- MOV C,B; CLEAR 3RD WORD OF DIGIT
- MOV D,B; CLEAR 4TH WORD OF DIGIT
- MVI E,8; INDICATE DIGIT IS IN REG A
- CALL FFLOAT; CONVERT DIGIT TO FLOATING PNT
- MVI L,LOW(VALE); TO ADDR VALUE
- CALL FADD ; ADD OLD VALUE TIMES TEN
- MVI L,LOW(TMP2); TO ADDR DEC PNT FLAG
- MOV A,M; DECIMAL POINT FLAG
- ANA A ; SET CONTROL BITS
- JZ INP1; IF NO DEC PNT ENCOUNTERED
- DCR L; TO ADDR INPUT EXPONENT
- MOV B,M; INPUT EXPONENT
- DCR B; DECREMENT INPUT EXPONENT
- MOV M,B; UPDATE INPUT EXPONENT
- JMP INP1; TO GET NEXT CHARACTER
- INP3: LXI H,TMP2; TO ADDR DEC PNT FLAG
- XRA M; ZERO IF FLAG SET
- MOV M,A; SET DEC PNT FLAG
- JNZ INP1; IF FLAG NOT ALREADY SET
- JMP INP8; IF 2ND DEC PNT
- ; PROCESS DECIMAL EXPONENT.
- INP4: CALL CHAD; CALL CHAR ADDR SBRTN
- MOV A,M; NEXT CHARACTER OF STRING
- MOV B,A; CURRENT CHARACTER
- SUI 0FDH; COMPARE TO MINUS CHAR
- MOV E,A; CHAR - MINUS SIGN
- JZ INP5; IF MINUS SIGN
- ADI 2; COMPARE TO PLUS CHAR
- MOV A,B; CURRENT CHARACTER
- JNZ INP6; IF NOT PLUS SIGN
- INP5: INR L; TO ADDRESS NEXT CHAR
- MOV A,M; NEXT CHARACTER OF STRING
- INP6: MVI B,0; POSSIBLE DEC EXPONENT
- CPI 0AH; SET CARRY IF CHAR IS DIGIT
- JNC INP8; IF CHAR IS NOT A DIGIT
- MOV B,A; DEC EXP EQUAL DIGIT
- INR L; TO ADDRESS NEXT CHAR
- MOV A,M; NEXT CHARACTER OF STRING
- CPI 0AH; SET CARRY IF CHAR IS DIGIT
- JNC INP7; IF CHAR IS NOT A DIGIT
- ; FORM COMPLETE DECIMAL EXPONENT.
- MOV C,A; LS DIGIT OF DEC EXP
- MOV A,B; MS DIGIT OF DEC EXP
- ADD A; 2 * MS DIGIT
- ADD A; 4 * MS DIGIT
- ADD B; 5 * MS DIGIT
- ADD A; 10 * MS DIGIT
- ADD C; 10 * MS + LS DIGIT
- MOV B,A; DECIMAL EXPONENT
- INP7: MOV A,E; SIGN OF DEC EXPONENT
- ANA A ; SET CONTROL BITS
- JNZ INP8; IF SIGN PLUS
- SUB B; COMPLEMENT DEC EXP
- MOV B,A; DECIMAL EXPONENT
- INP8: LXI H,TMP3; TO ADDRESS SCRATCH BANK
- MOV C,M; INPUT SIGN
- LXI H,ACCS; TO ADDRESS ACCUM SIGN
- MOV M,C; ACCUMULATOR SIGN
- MOV A,B; DECIMAL EXPONENT
- ; CONVERT DECIMAL EXPONENT TO BINARY.
- INP9: LXI H,TMP1; TO ADDRESS DEC EXPONENT
- ADD M; ADJUST DECIMAL EXPONENT
- JZ FTEST; IN DEC EXP IS ZERO
- MOV M,A; CURRENT DECIMAL EXPONENT
- LXI H,FTEN; TO ADDR FLOATING TEN
- JP INP10; IF MULTIPLY REQUIRED
- CALL FDIV; DIVIDE BY TEN
- MVI A,1; TO INCREMENT DEC EXP
- JMP INP9; TO TEST FOR COMPLETION
- INP10: CALL FMUL; MULTIPLY BY TEN
- RC ; RETURN IF OVERFLOW
- MVI A,0FFH; TO DECREMENT DEC EXP
- JMP INP9; TO TEST FOR COMPLETION
- ; OUT SUBROUTINE ENTRY POINT.
- ; SAVE CHARACTER ADDRESS AND ACCUMULATOR.
- FOUT: DCR L; DECREMENT CHARACTER ADDRESS
- CALL SVAD; SET CHAR ADDR, DIG CNT, DEC EXP
- CALL FTEST; LOAD ACCUM TO REGISTERS
- LXI H,VALE; TO ADDR ACCUM SAVE AREA
- CALL FSTOR; CALL REG STR SUBROUTINE
- ; OUTPUT SIGN CHARACTER.
- CALL CHAD; CALL CHAR ADDR SBRTN
- MVI M,0F0H; STORE SPACE CHARACTER
- ANA A ; SET CONTROL BITS
- JZ OUT3; IF ACCUMULATOR IS ZERO
- MOV E,A; ACCUMULATOR EXPONENT
- MOV A,B; ACCUM SIGN AND 1ST FRCTN
- ANA A ; SET CONTROL BITS
- MOV A,E; ACCUMULATOR EXPONENT
- JP OUT1; IF ACCUM IS POSITIVE
- MVI M,0FDH; CHANGE SIGN TO MINUS
- ; SCALE ACCUMULATOR TO .1 - 1. RANGE.
- OUT1: CPI 7EH; COMPARE TO SMALL EXPONENT
- OUT2: LXI H,FTEN; TO ADDR FLOATING TEN
- JC OUT4; IF EXPONENT TOO SMALL
- CPI 81H; COMPARE TO LARGE EXP
- JC OUT5; IF EXP SMALL ENOUGH
- CALL FDIV; DIVIDE BY TEN
- OUT3: LXI H,TMP2; TO ADDRESS SCRATCH BANK
- MOV E,M; DECIMAL EXPONENT
- INR E; INCREMENT DECIMAL EXPONENT
- MOV M,E; DECIMAL EXPONENT
- JMP OUT2; TO TEST FOR SCALING COMPLETE
- OUT4: CALL FMUL; MULTIPLY BY TEN
- LXI H,TMP2; TO ADDR DECIMAL EXPONENT
- MOV E,M; DECIMAL EXPONENT
- DCR E; DECREMENT DECIMAL EXPONENT
- MOV M,E; DECIMAL EXPONENT
- JMP OUT1; TO TEST FOR SCALING COMPLETE
- ; ROUND THE VALUE BY ADDING .00000005.
- OUT5: CALL FABS; SET ACCUM POSITIVE
- LXI H,RND0; TO ADDRESS ROUNDER
- CALL FADD; ADD THE ROUNDER
- CPI 81H; CHECK FOR OVERFLOW
- JNC OUT2; IF EXP TOO LARGE
- ; SET DIGIT COUNTS.
- LXI H,TMP2; TO ADDR DECIMAL EXPONENT
- MOV A,M; DECIMAL EXPONENT
- MOV E,A; DIGITS BEFORE DEC POINT
- CPI 8; COMPARE TO LARGE EXP
- JC OUT6; IF EXPONENT IN RANGE
- MVI E,1; DIGITS BEFORE DEC POINT
- OUT6: SUB E; ADJUST DEC EXPONENT
- MOV M,A; DECIMAL EXPONENT
- MVI A,7; TOTAL NUMBER OF DIGITS
- SUB E; DIGITS AFTER DECIMAL PNT
- INR L; TO ADDR 2ND DIGIT CNT
- MOV M,A; DIGITS AFTER DECIMAL POINT
- DCR E; DECREMENT DIGIT COUNT
- MOV A,E; DIGITS BEFORE DEC PNT
- ; OUTPUT SIGNIFICANT DIGITS.
- OUT7: LXI H,TMP1; TO ADDR DIGIT COUNT
- ADD M; ADJUST DIGIT COUNT
- MOV M,A; NEW DIGIT COUNT
- JM OUT8; IF COUNT RUN OUT
- LXI H,FTEN; TO ADDR FLOATING TEN
- CALL FMUL; MULTIPLY BY TEN
- MVI E,8; TO PLACE DIGIT IN REG A
- CALL FFIX; CONVERT TO FIXED FORMAT
- CALL CHAD; CALL CHAR ADDR SBRTN
- MOV M,A; OUTPUT DECIMAL DIGIT
- XRA A; CLEAR CURRENT DIGIT
- MVI E,8; BINARY SCALING FACTOR
- CALL FFLOAT; RESTORE VALUE MINUS DIGIT
- MVI A,0FFH; TO ADJUST DIGIT CNT
- JMP OUT7; LOOP FOR NEXT DIGIT
- OUT8: LXI H,TMP3; TO ADDR 2ND DIGIT CNT
- MOV A,M; DIGITS AFTER DECIMAL PNT
- MVI M,0FFH; SET 2ND COUNT NEG
- ANA A ; SET CONTROL BITS
- JM OUT9; IF 2ND COUNT RAN OUT
- CALL CHAD; CALL CHAR ADDR SBRTN
- MVI M,0FEH; STORE DECIMAL POINT
- JMP OUT7; LOOP FOR NEXT DIGIT
- OUT9: DCR L; TO ADDR DECIMAL EXP
- ANA M ; DECIMAL EXPONENT
- JZ OUT13; IF DECIMAL EXPONENT IS ZERO
- ; OUTPUT DECIMAL EXPONENT.
- MVI B,0FBH; PLUS CHARACTER
- JP OUT10; IF EXPONENT IS POSITIVE
- MVI B,0FDH; CHANGE SIGN TO MINUS
- MOV C,A; NEGATIVE EXPONENT
- XRA A; ZERO
- SUB C; COMPLEMENT EXPONENT
- OUT10: MVI C,0FFH; EMBRYO TENS DIGIT
- OUT11: MOV D,A; UNITS DIGIT
- INR C; INCREMENT TENS DIGIT
- SUI 0AH; REDUCE REMAINDER
- JNC OUT11; IF MORE TENS
- MVI A,15H; EXPONENT SIGN
- OUT12: CALL CHAD; CALL CHAR ADDR SBRTN
- CALL FSTOR; STORE LAST 4 CHARACTERS
- LXI H,VALE; TO ADDRESS ACCUM SAVE AREA
- JMP FLOAD; RESTORE ACCUM AND EXIT
- ; OUTPUT 4 SPACES IF EXPONENT IS ZERO.
- OUT13: MVI A,0F0H; SPACE CHARACTER
- MOV B,A; SPACE CHARACTER
- MOV C,A; SPACE CHARACTER
- MOV D,A; SPACE CHARACTER
- JMP OUT12; TO STORE CHARACTERS
- ; SUBROUTINE TO SAVE CHARACTER STRING ADDR.
- SVAD: MOV A,L; CHARACTER STRING WORD
- MOV B,H; CHARACTER STRING BANK
- MVI C,0; INPUT EXP OR DIGIT CNT
- MOV D,C; DEC PNT FLAG OR DEC EXP
- LXI H,ADRL; TO ADDR CHAR STRING WORD
- CALL FSTOR; STORE A, B, C, AND D
- RET ; RETURN TO CALLER
- ; SUBROUTINE TO OBTAIN NEXT CHARACTER ADDR.
- CHAD: LXI H,ADRL; TO ADDRESS SCRATCH BANK
- MOV E,M; CHARACTER STRING WORD
- INR E; TO ADDR NEXT CHARACTER
- MOV M,E; UPDATE CHAR STRING WORD
- INR L; TO ADDR CHAR STRING BANK
- MOV H,M; CHARACTER STRING BANK
- MOV L,E; CHARACTER STRING WORD
- RET ; RETURN TO CALLER
- END
-