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