home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG029.ARK
/
FPCONV.SRC
< prev
next >
Wrap
Text File
|
1984-04-29
|
14KB
|
305 lines
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