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
/
FPPKG.SRC
< prev
next >
Wrap
Text File
|
1984-04-29
|
29KB
|
649 lines
NAME FLPT
CSEG
PUBLIC OVERF,FLOAD,FSTOR,FADD,FSUB,FMUL,FDIV,FTEST
PUBLIC FCHS,FABS,RSH,LSH,ADD10,FZERO,FCOMP,FSTR0
EXTRN OVER,PREX,ACCE,ACCS,ACC1,ACC2,ACC3,SF
; 8008 BINARY FLOATING POINT SYSTEM
; ARITHMETIC AND UTILITY PACKAGE
; PROGRAMMER CAL OHME
; DATE 26 DECEMBER 1973
; FSTOR SUBROUTINE ENTRY POINT.
FSTR0: MOV M,E; STORE ZEROETH WORD
INR L; TO ADDRESS FIRST WORD
FSTOR: MOV M,A; STORE FIRST WORD
STR1: INR L; TO ADDRESS SECOND WORD
MOV M,B; STORE SECOND WORD
INR L; TO ADDRESS THIRD WORD
MOV M,C; STORE THIRD WORD
INR L; TO ADDRESS FOURTH WORD
MOV M,D; STORE FOURTH WORD
RET ; RETURN TO CALLER
; FLOATING POINT ZERO SUBROUTINE ENT. PNT.
FZERO: LXI H,ACCE; TO ADDRESS ACCUM EXPONENT
XRA A; ZERO
MOV M,A; CLEAR ACCUMULATOR EXPONENT
RET ; RETURN TO CALLER
; FLOATING POINT CHS SUBROUTINE ENT. PNT.
FCHS: MVI A,80H; MASK FOR SIGN BIT
DB 00EH; LBI INST TO SKIP NEXT WD
; FLOATING POINT ABS SUBROUTINE ENT. PNT.
FABS: XRA A; ZERO
LXI H,ACCS; TO ADDRESS ACCUM SIGN
ANA M ; COMPLEMENT OF SIGN
XRI 80H; COMPLEMENT THE SIGN BIT
MOV M,A; ACCUMULATOR SIGN
; FLOATING POINT TEST ENTRY POINT.
FTEST: LXI H,ACCE; TO ADDR ACCUM EXPONENT
MOV A,M; ACCUMULATOR EXPONENT
ANA A ; SET CONTROL BITS
JZ FZERO; IF ACCUMULATOR IS ZERO
MOV E,A; ACCUMULATOR EXPONENT
INR L; TO ADDR ACCUMULATOR SIGN
MOV A,M; ACCUMULATOR SIGN
INR L; TO ADDR ACCUM 1ST FRCTN
XRA M; ACCUM SIGN AND 1ST FRCTN
INR L; TO ADDR ACCUM 2ND FRCTN
MOV C,M; ACCUMULATOR 2ND FRACTION
INR L; TO ADDR ACCUM 3RD FRCTN
MOV D,M; ACCUMULATOR 3RD FRCTN
JMP ADD12; TO SET EXIT CONDITIONS
; FLOATING POINT LOAD ENTRY POINT.
FLOAD: MOV A,M; OPERAND EXPONENT
ANA A ; SET CONTROL BITS
JZ FZERO; IF OPERAND IS ZERO
MOV E,A; OPERAND EXPONENT
INR L; TO ADDR OP SIGN AND 1ST
MOV A,M; OPERAND SIGN AND 1ST FRCTN
INR L; TO ADDRESS OPERAND 2ND FRACTION
MOV C,M; OPERAND 2ND FRACTION
INR L; TO ADDRESS OPERAND 3RD FRACTION
MOV D,M; OPERAND 3RD FRACTION
; STORE THE OPERAND IN THE ACCUMULATOR.
MOV L,A; OPERAND SIGN AND 1ST FRCTN
FLOAD1: ORI 80H; ACCUMULATOR 1ST FRACTION
MOV B,A; ACCUMULATOR 1ST FRACTION
XRA L; ACCUMULATOR SIGN
LXI H,ACCE; TO ADDR ACCUM EXPONENT
CALL FSTR0; SET THE ACCUMULATOR
XRA B; ACCUM SIGN AND 1ST FRCTN
; SET CONTROL BITS AND EXIT
MOV B,A; ACCUM SIGN AND 1ST FRACTION
ORI 1; SET SIGN BIT FOR EXIT
MOV A,E; ACCUMULATOR EXPONENT
RET ; RETURN TO CALLER
; FLOATING POINT MUL SUBROUTINE ENT. PNT.
FMUL: MOV A,M; OPERAND EXPONENT
ANA A ; SET CONTROL BITS
CNZ MDEX; READ OPERAND IF NOT ZERO
JZ FZERO; IF ZERO OR UNDERFLOW
JC OVERF; IF OVERFLOW
CALL MULX; CALL FIXED MULT SUBRTN
; NORMALIZE IF NECESSARY.
MOV A,B; 1ST PRODUCT
ANA A ; SET CONTROL BITS
JM RNDA; IF NO NORMALIZATION REQUIRED
LXI H,ACCE; TO ADDR ACCUM EXPONENT
MOV A,M; ACCUMULATOR EXPONENT
SBI 1; DECREMENT ACCUMULATOR EXPONENT
MOV M,A; ACCUMULATOR EXPONENT
RZ ; RETURN TO CALLER IF UNDERFLOW
CALL LSH; CALL LEFT SHIFT SUBROUTINE
; ROUND IF NECESSARY.
RNDA: CALL ROND; CALL ROUNDING SUBROUTINE
JC OVERF; IF OVERFLOW
MOV B,A; ACCUM SIGN AND 1ST FRACTION
ORI 1; SET SIGN BIT
MOV A,E; ACCUMULATOR EXPONENT
RET ; RETURN TO CALLER
; FLOATING POINT DIV SUBROUTINE ENT. PNT.
FDIV: XRA A; ZERO
SUB M; COMPLEMENT OF DIVISOR EXPONENT
CPI 1; SET CARRY IF DIVISION BY ZERO
CNC MDEX; READ OPERAND IF NOT ZERO
JC OVERF; IF OVERFLOW OR DIVISION BY ZERO
JZ FZERO; IF UNDERFLOW OR ZERO
MOV C,A; DIVISOR 1ST FRACTION
CALL DIVX; CALL FIXED DIV SUBRTN
JC RNDA; IF NO OVERFLOW
; SET OVERFLOW FLAG.
OVERF: LXI H,OVER; TO ADDR OVERFLOW FLAG
MVI A,0FFH; OVERFLOW FLAG
MOV M,A; OVERFLOW FLAG
RLC ; SET CARRY BIT FOR EXIT
RET ; RETURN TO CALLER
DB 0; CHECK SUM WORD
; FLOATING POINT SUB SUBROUTINE ENT. PNT.
FSUB: MVI A,80H; MASK TO CHANGE OP SIGN
DB 0EH; LBI INST TO SKIP NEXT WD
; FLOATING POINT ADD SUBROUTINE ENT. PNT.
FADD: XRA A; ZERO
; LOAD THE OPERAND.
MOV E,M; OPERAND EXPONENT
INR L; TO ADDR OP SIGN, 1ST FRCTN
XRA M; OPERAND SIGN AND 1ST FRCTN
MOV B,A; OPERAND SIGN AND 1ST FRCTN
INR L; TO ADDR OPERAND 2ND
MOV C,M; OPERAND 2ND FRACTION
INR L; TO ADDR OPERAND 3RD FRCTN
MOV D,M; OPERAND 3RD FRACTION
; SAVE INITIAL EXPONENT.
LXI H,ACCE; TO ADDR ACCUM EXPONENT
MOV A,M; ACCUMULATOR EXPONENT
DCR L; TO ADDR INITIAL EXPONENT
MOV M,A; INITIAL EXPONENT
; CHECK FOR ZERO OPERAND.
MOV A,E; OPERAND EXPONENT
ANA A ; SET CONTROL BITS
JZ FTEST; IF OPERAND IS ZERO
; GENERATE SUBTRACTION FLAG, RESTORE
; SUPPRESSED FRACTION BIT.
MOV L,B; OPERAND SIGN AND 1ST FRCTN
MOV A,B; OPERAND SIGN AND 1ST FRACTION
ORI 80H; OPERAND 1ST FRACTION
MOV B,A; OPERAND 1ST FRACTION
XRA L; OPERAND SIGN
MVI L,LOW(ACCS); TO ADDRESS ACCUMULATOR SIGN
XRA M; SUBTRACTION FLAG
MVI L,LOW(SF); TO ADDRESS SUBTRACTION FLAG
MOV M,A; SUBTRACTION FLAG
; DETERMINE RELATIVE MAGNITUDES OF
; OPERAND AND ACCUMULATOR.
MVI L,LOW(ACCE); TO ADDRESS ACCUMULATOR EXPONENT
MOV A,M; ACCUMULATOR EXPONENT
ANA A ; SET CONTROL BITS
JZ ADD17; IF ACCUMULATOR IS ZERO
SUB E; DIFFERENCE IN EXPONENTS
JC ADD2; IF ACCUM SMALLER THAN OP
; CHECK FOR INSIGNIFICANT OPERAND.
JM FTEST; IF THE OPERAND IS INSIGNIFICANT
CPI 25; COMPARE SHIFT COUNT TO 25
JC ADD3; JOIN EXCH PATH IF OP SIGNIF
JMP FTEST; OPERAND IS INSIGNIFICANT
; CHECK FOR INSIGNIFICANT ACCUMULATOR
ADD2: JP ADD17; IF ACCUM IS INSIGNIFICANT
CPI 0E7H; COMPARE SHIFT COUNT TO MINUS 25
JC ADD17; IF ACCUM IS INSIGNIFICANT
MOV M,E; OPERAND EXPONENT
MOV E,A; SHIFT COUNT
LXI H,SF; TO ADDRESS THE SUBTRACTION FLAG
MOV A,M; SUBTRACTION FLAG
MVI L,LOW(ACCS); TO ADDRESS THE ACCUMULATOR SIGN
XRA M; OPERAND SIGN
MOV M,A; ACCUMULATOR SIGN
XRA A; ZERO
SUB E; COMPLEMENT SHIFT COUNT
; EXCHANGE ACCUMULATOR AND OPERAND.
INR L; TO ADDR ACCUM 1ST FRACTION
MOV E,M; ACCUMULATOR 1ST FRACTION
MOV M,B; OPERAND 1ST FRACTION
MOV B,E; ACCUMULATOR 1ST FRACTION
INR L; TO ADDR ACCUM 2ND FRACTION
MOV E,M; ACCUMULATOR 2ND FRACTION
MOV M,C; OPERAND 2ND FRACTION
MOV C,E; ACCUMULATOR 2ND FRACTION
INR L; TO ADDR ACCUM 3RD FRACTION
MOV E,M; ACCUMULATOR 3RD FRACTION
MOV M,D; OPERAND 3RD FRACTION
MOV D,E; ACCUMULATOR 3RD FRACTION
; POSITION THE OPERAND.
ADD3: CALL RSH; POSITION THE OPERAND
LXI H,SF; TO ADDRESS SUBTRACTION FLAG
MOV A,M; SUBTRACTION FLAG
ANA A ; SET CONTROL BITS
MVI L,LOW(ACC3); TO ADDR ACCUM 3RD FRCTN
JM ADD9; IF SUBTRACTION REQUIRED
; ADD ADDEND TO AUGEND.
MOV A,M; AUGEND 3RD FRACTION
ADD D; ADDEND 3RD FRACTION
MOV D,A; SUM 3RD FRACTION
DCR L; TO ADDRESS AUGEND 2ND FRACTION
MOV A,M; AUGEND 2ND FRACTION
ADC C; ADDEND 2ND FRACTION
MOV C,A; SUM 2ND FRACTION
DCR L; TO ADDRESS AUGEND 1ST FRACTION
MOV A,M; AUGEND 1ST FRACTION
ADC B; ADDEND 1ST FRACTION
MOV B,A; SUM 1ST FRACTION
JNC ADD11; IF NO CARRY FROM 1ST FRCTN
; RIGHT SHIFT SUM TO NORMALIZED POSITION.
RAR ; RIGHT SHIFT SUM 1ST FRACTION
MOV B,A; SUM 1ST FRACTION
MOV A,C; SUM 2ND FRACTION
RAR ; RIGHT SHIFT SUM 2ND FRACTION
MOV C,A; SUM 2ND FRACTION
MOV A,D; SUM 3RD FRACTION
RAR ; RIGHT SHIFT SUM 3RD FRACTION
MOV D,A; SUM 3RD FRACTION
RAR ; 4TH FRCTN = LOW BIT OF 3RD
MOV E,A; SUM 4TH FRACTION
MVI L,LOW(ACCE); TO ADDRESS ACCUMULATOR EXPONENT
MOV A,M; ACCUMULATOR EXPONENT
ADI 1; INCREMENT ACCUMULATOR EXPONENT
JC OVERF; IF OVERFLOW
MOV M,A; ACCUMULATOR EXPONENT
JMP ADD11; TO ROUND FRACTION
; SUBTRACT SUBTRAHEND FROM MINUEND.
ADD9: XRA A; MINUEND 4TH FRCTN IS ZERO
SUB E; SUBTRAHEND 4TH FRACTION
MOV E,A; DIFFERENCE 4TH FRACTION
MOV A,M; MINUEND 3RD FRACTION
SBB D; SUBTRAHEND 3RD FRACTION
MOV D,A; DIFFERENCE 3RD FRACTION
DCR L; TO ADDRESS MINUEND 2ND FRACTION
MOV A,M; MINUEND 2ND FRACTION
SBB C; SUBTRAHEND 2ND FRACTION
MOV C,A; DIFFERENCE 2ND FRACTION
DCR L; TO ADDRESS MINUEND 1ST FRACTION
MOV A,M; MINUEND 1ST FRACTION
SBB B; SUBTRAHEND 1ST FRACTION
MOV B,A; DIFFERENCE 1ST FRACTION
ADD10: CC FCOMP; COMPLEMENT IF NEGATIVE
CP NORM; NORMALIZE IF NECESSARY
JP FZERO; IF UNDERFLOW OR ZERO
ADD11: CALL ROND; CALL ROUNDING SUBROUTINE
JC OVERF; IF OVERFLOW
ADD12: MOV B,A; ACCUM SIGN AND 1ST FRCTN
LXI H,PREX; TO ADDRESS PREV EXPONENT
MOV A,E; ACCUMULATOR EXPONENT
SUB M; DIFFERENCE IN EXPONENTS
MOV L,A; DIFFERENCE IN EXPONENTS
MOV A,B; ACCUM SIGN AND 1ST FRCTN
ORI 1; SET SIGN BIT FOR EXIT
MOV A,E; ACCUMULATOR EXPONENT
MOV E,L; SIGNIFICANCE INDEX
RET ; RETURN TO CALLER
; LOAD THE ACCUMULATOR WITH THE OPERAND.
ADD17: LXI H,SF; TO ADDR SUBTRACTION FLAG
MOV A,M; SUBTRACTION FLAG
MVI L,LOW(ACCS); TO ADDR ACCUMULATOR SIGN
XRA M; OPERAND SIGN
DCR L; TO ADDR ACCUM EXPONENT
CALL FSTR0; SET THE ACCUMULATOR
XRA B; ACCUM SIGN AND 1ST FRCTN
JMP ADD12; JOIN EXIT CODE
DB 0; CHECK SUM WORD
; SUBROUTINE TO READ THE OPERAND AND
; CHECK THE ACCUMULATOR EXPONENT.
MDEX: MOV B,A; EXPONENT MODIFIER
INR L; TO ADDR OP SIGN, 1ST FRCTN
MOV C,M; OPERAND SIGN AND 1ST FRACTION
INR L; TO ADDRESS OPERAND 2ND FRACTION
MOV D,M; OPERAND 2ND FRACTION
INR L; TO ADDRESS OPERAND 3RD FRACTION
MOV E,M; OPERAND 3RD FRACTION
LXI H,ACCE; TO ADDRESS ACCUMULATOR EXPONENT
MOV A,M; ACCUMULATOR EXPONENT
ANA A ; SET CONTROL BITS
RZ ; RETURN IF ACCUM IS ZERO
ADD B; RESULT EXPONENT PLUS BIAS
MOV B,A; RESULT EXPONENT PLUS BIAS
RAR ; CARRY TO SIGN
XRA B; CARRY AND SIGN MUST DIFFER
MOV A,B; RESULT EXPONENT PLUS BIAS
MVI B,80H; EXP BIAS, SIGN MASK, MS BIT
JP OVUN; IF OVERFLOW OR UNDERFLOW
SUB B; REMOVE EXCESS EXP BIAS
RZ ; RETURN IF UNDERFLOW
MOV M,A; RESULT EXPONENT
INR L; TO ADDRESS ACCUMULATOR SIGN
MOV A,M; ACCUMULATOR SIGN
XRA C; RESULT SIGN IN SIGN BIT
ANA B ; RESULT SIGN
MOV M,A; RESULT SIGN
MOV A,C; OPERAND SIGN AND 1ST FRCTN
ORA B; OPERAND 1ST FRACTION
RET ; RETURN TO CALLER
OVUN: RLC ; SET CARRY BIT IF OVERFLOW
RC ; RETURN IF OVERFLOW
XRA A; ZERO
RET ; RETURN IF UNDERFLOW
; SUBROUTINE TO LEFT SHIFT THE B, C,
; D, AND E REGISTERS ONE BIT.
LSH: MOV A,E; ORIGINAL CONTENTS OF E
RAL ; LEFT SHIFT E
MOV E,A; RESTORE CONTENTS OF E REGISTER
LSH1: MOV A,D; ORIGINAL CONTENTS OF D REGISTER
RAL ; LEFT SHIFT D
MOV D,A; RESTORE CONTENTS OF D REGISTER
MOV A,C; ORIGINAL CONTENTS OF C REGISTER
RAL ; LEFT SHIFT C
MOV C,A; RESTORE CONTENTS OF C REGISTER
MOV A,B; ORIGINAL CONTENTS OF B REGISTER
ADC A; LEFT SHIFT B
MOV B,A; RESTORE CONTENTS OF B REGISTER
RET ; RETURN TO CALLER
; RIGHT SHIFT THE B, C, D AND E REGISTERS
; BY THE SHIFT COUNT IN THE A REGISTER
; SHIFT OPERAND TO REGISTER INDICATED BY
; SHIFT COUNT
RSH: MVI E,0; OPERAND 4TH FRCTN IS ZERO
RSH0: MVI L,8; EACH REG IS 8 BITS OF SHIFT
RSH1: CMP L; COMPARE SHIFT COUNT TO 8
JM RSH2; IF REQ SHIFT LESS THAN 8
MOV E,D; OPERAND 4TH FRACTION
MOV D,C; OPERAND 3RD FRACTION
MOV C,B; OPERAND 2ND FRACTION
MVI B,0; OPERAND 1ST FRACTION IS ZERO
SUB L; REDUCE SHIFT COUNT BY 1 REG
JNZ RSH1; IF MORE SHIFTS REQUIRED
; SHIFT OPERAND RIGHT BY -SHIFT COUNT-
; BITS.
RSH2: ANA A ; SET CONTROL BITS
RZ ; RETURN IF SHIFT COMPLETE
MOV L,A; SHIFT COUNT
RSH3: ANA A ; CLEAR CARRY BIT
MOV A,B; OPERAND 1ST FRACTION
RAR ; RIGHT SHIFT OP 1ST FRCTN
MOV B,A; OPERAND 1ST FRACTION
MOV A,C; OPERAND 2ND FRACTION
RAR ; RIGHT SHIFT OP 2ND FRCTN
MOV C,A; OPERAND 2ND FRACTION
MOV A,D; OPERAND 3RD FRACTION
RAR ; RIGHT SHIFT OP 3RD FRCTN
MOV D,A; OPERAND 3RD FRACTION
MOV A,E; OPERAND 4TH FRACTION
RAR ; RIGHT SHIFT OP 4TH FRCTN
MOV E,A; OPERAND 4TH FRACTION
DCR L; DECREMENT SHIFT COUNT
JNZ RSH3; IF MORE SHIFTS REQUIRED
RET ; RETURN TO CALLER
; COMPLEMENT THE B, C, D, AND E REGISTERS.
FCOMP: DCR L; TO ADDR ACCUM SIGN
MOV A,M; ACCUMULATOR SIGN
XRI 80H; CHANGE SIGN
MOV M,A; ACCUMULATOR SIGN
COMP1: XRA A; ZERO
MOV L,A; ZERO
SUB E; COMPLEMENT 4TH FRCTN
MOV E,A; 4TH FRACTION
MOV A,L; ZERO
SBB D; COMPLEMENT 3RD FRCTN
MOV D,A; 3RD FRACTION
MOV A,L; ZERO
SBB C; COMPLEMENT 2ND FRCTN
MOV C,A; 2ND FRACTION
MOV A,L; ZERO
SBB B; COMPLEMENT 1ST FRCTN
MOV B,A; 1ST FRACTION
RET ; RETURN TO CALLER
; NORMALIZE THE REGISTERS.
NORM: MVI L,20H; MAX NORMALIZING SHIFT
NORM1: MOV A,B; 1ST FRACTION
ANA A ; SET CONTROL BITS
JNZ NORM3; IF 1ST FRACTION NONZERO
MOV B,C; 1ST FRACTION
MOV C,D; 2ND FRACTION
MOV D,E; 3RD FRACTION
MOV E,A; ZERO 4TH FRACTION
MOV A,L; NORMALIZING SHIFT COUNT
SUI 8; REDUCE SHIFT COUNT
MOV L,A; NORMALIZING SHIFT COUNT
JNZ NORM1; IF FRACTION NONZERO
RET ; IF FRACTION IS ZERO
NORM2: DCR L; DECREMENT SHIFT COUNT
MOV A,E; ORIGINAL CONTENTS OF E
RAL ; LEFT SHIFT E
MOV E,A; RESTORE CONTENTS OF E REGISTER
MOV A,D; ORIGINAL CONTENTS OF D REGISTER
RAL ; LEFT SHIFT D
MOV D,A; RESTORE CONTENTS OF D REGISTER
MOV A,C; ORIGINAL CONTENTS OF C REGISTER
RAL ; LEFT SHIFT C
MOV C,A; RESTORE CONTENTS OF C REGISTER
MOV A,B; ORIGINAL CONTENTS OF B REGISTER
ADC A; LEFT SHIFT B
MOV B,A; RESTORE CONTENTS OF B REGISTER
NORM3: JP NORM2; IF NOT NORMALIZED
MOV A,L; NORMALIZING SHIFT COUNT
SUI 20H; REMOVE BIAS
LXI H,ACCE; TO ADDR ACCUM EXPONENT
ADD M; ADJUST ACCUM EXPONENT
MOV M,A; NEW ACCUM EXPONENT
RZ ; RETURN IF ZERO EXP
RAR ; BORROW BIT TO SIGN
ANA A ; SET SIGN TO IND. UNDERFLOW
RET ; RETURN TO CALLER
; SUBROUTINE TO ROUND THE B, C, D REGISTERS.
ROND: LXI H,ACCE; TO ADDR ACCUM EXPONENT
MOV A,E; 4TH FRACTION
ANA A ; SET CONTROL BITS
MOV E,M; ACCUMULATOR EXPONENT
CM RNDR; CALL 2ND LEVEL ROUNDER
RC ; IF OVERFLOW
MOV A,B; 1ST FRACTION
INR L; TO ADDR ACCUM SIGN
XRA M; ACCUM SIGN AND 1ST FRCTN
JMP STR1; RETURN THRU STORE SUBR.
; SECOND LEVEL ROUNDING SUBROUTINE.
RNDR: INR D; ROUND 3RD FRACTION
RNZ ; RETURN IF NO CARRY
INR C; CARRY TO 2ND FRACTION
RNZ ; RETURN IF NO CARRY
INR B; CARRY TO 1ST FRACTION
RNZ ; RETURN IF NO CARRY
MOV A,E; ACCUMULATOR EXPONENT
ADI 1; INCREMENT ACCUM EXPONENT
MOV E,A; NEW ACCUM EXPONENT
MVI B,80H; NEW 1ST FRACTION
MOV M,A; NEW ACCUM EXPONENT
RET ; RETURN TO ROND SUBROUTINE
; FIXED POINT MULTIPLY SUBROUTINE.
MULX: LXI H,MULP1+1; TO ADDR 1ST MULTIPLICAND
MOV M,A; 1ST MULTIPLICAND
LXI H,MULP2+1; TO ADDR 2ND MULTIPLICAND
MOV M,D; 2ND MULTIPLICAND
LXI H,MULP3+1; TO ADDR 3RD MULTIPLICAND
MOV M,E; 3RD MULTIPLICAND
XRA A; CLEAR 6TH PRODUCT
MOV E,A; CLEAR 5TH PRODUCT
MOV D,A; CLEAR 4TH PRODUCT
; MULTIPLY BY EACH ACCUMULATOR
; FRACTION IN TURN.
LXI H,ACC3; TO ADDRESS 3RD FRCTN
CALL MULX2; MULTIPLY BY ACCUM 3RD FRCTN
MVI L,LOW(ACC2); TO ADDRESS 2ND FRCTN
CALL MULX1; MULTIPLY BY ACCUM 2ND FRCTN
MVI L,LOW(ACC1); TO ADDRESS 1ST FRCTN
; MULTIPLY BY ONE ACCUMULATOR WORD.
MULX1: MOV A,D; 5TH PARTIAL PRODUCT
MOV E,C; 4TH PARTIAL PRODUCT
MOV D,B; 3RD PARTIAL PRODUCT
MULX2: MOV B,M; MULTIPLIER
MOV L,A; 5TH PARTIAL PRODUCT
XRA A; ZERO
MOV C,A; 2ND PARTIAL PRODUCT
SUB B; SET CARRY BIT FOR EXIT FLAG
JC MULX3; IF MULTIPLIER IS NOT ZERO
MOV C,D; 2ND PARTIAL PRODUCT
MOV D,E; 3RD PARTIAL PRODUCT
RET ; MULT BY ZERO COMPLETE
; COMPLETE ADDITION OF MULTIPLICAND.
MULX5: MOV C,A; 2ND PARTIAL PRODUCT
JNC MULX3; IF NO CARRY TO 1ST PRODUCT
INR B; ADD CARRY TO 1ST PRODUCT
ANA A ; CLEAR CARRY BIT
; LOOP FOR EACH BIT OF MULTIPLIER WORD.
MULX3: MOV A,L; 5TH PART PRODUCT, EXIT FLAG
ADC A; SHIFT EXIT FLAG OUT IF DONE
RZ ; EXIT IF MULTIPLICATION DONE
MOV L,A; 5TH PART PRODUCT, EXIT FLAG
MOV A,E; 4TH PARTIAL PRODUCT
RAL ; SHIFT 4TH PARTIAL PRODUCT
MOV E,A; 4TH PARTIAL PRODUCT
MOV A,D; 3RD PARTIAL PRODUCT
RAL ; SHIFT 3RD PARTIAL PRODUCT
MOV D,A; 3RD PARTIAL PRODUCT
MOV A,C; 2ND PARTIAL PRODUCT
RAL ; SHIFT 2ND PARTIAL PRODUCT
MOV C,A; 2ND PARTIAL PRODUCT
MOV A,B; 1ST PART PROD AND MULTPLIER
RAL ; SHIFT 1ST PROD AND MULTIPLIER
MOV B,A; 1ST PART PROD AND MULTIPLIER
JNC MULX3; IF NO ADDITION REQUIRED
; ADD THE MULTIPLICAND TO THE PRODUCT
; IF THE MULTIPLIER BIT IS ONE.
MOV A,E; 4TH PARTIAL PRODUCT
; THE FOLLOWING CODE WAS MOVED FROM THE BEGINNING
; OF THE PROGRAM TO THIS LOCATION TO MAKE THINGS
; A LITTLE EASIER...
MULX4:
MULP3:
ADI 0; ADD OPERAND 3RD FRACTION
MOV E,A; 4TH PARTIAL PRODUCT
MOV A,D; 3RD PARTIAL PRODUCT
MULP2:
ACI 0; ADD OPERAND 2ND FRACTION
MOV D,A; 3RD PARTIAL PRODUCT
MOV A,C; 2ND PARTIAL PRODUCT
MULP1:
ACI 0; ADD OPERAND 1ST FRACTION
JMP MULX5
; FIXED POINT DIVIDE SUBROUTINE.
; SUBTRACT DIVISOR FROM ACCUMULATOR TO
; OBTAIN 1ST REMAINDER.
DIVX: LXI H,ACC3; TO ADDRESS ACCUM 3RD FRCTN
MOV A,M; ACCUMULATOR 3RD FRACTION
SUB E; DIVISOR 3RD FRACTION
MOV M,A; REMAINDER 3RD FRACTION
DCR L; TO ADDRESS ACCUM 2ND FRCTN
MOV A,M; ACCUMULATOR 2ND FRACTION
SBB D; DIVISOR 2ND FRACTION
MOV M,A; REMAINDER 2ND FRACTION
DCR L; TO ADDRESS ACCUM 1ST FRCTN
MOV A,M; ACCUMULATOR 1ST FRACTION
SBB C; DIVISOR 1ST FRACTION
MOV M,A; REMAINDER 1ST FRACTION
; HALVE THE DIVISOR AND STORE FOR
; ADDITION OR SUBTRACTION.
MOV A,C; DIVISOR 1ST FRACTION
RAL ; SET CARRY BIT
MOV A,C; DIVISOR 1ST FRACTION
RAR ; HALF OF DIVISOR 1ST FRCTN
; + 80H TO CORRECT QUOTIENT
LXI H,OP1S+1; TO ADDRESS 1ST SUBTRACT DIVISOR
MOV M,A; 1ST SUBTRACT DIVISOR
LXI H,OP1A+1; TO ADDRESS 1ST ADD DIVISOR
MOV M,A; 1ST ADD DIVISOR
MOV A,D; DIVISOR 2ND FRACTION
RAR ; HALF OF DIVISOR 2ND FRACTION
LXI H,OP2S+1; TO ADDRESS 2ND SUBTRACT DIVISOR
MOV M,A; 2ND SUBTRACT DIVISOR
LXI H,OP2A+1; TO ADDRESS 2ND ADD DIVISOR
MOV M,A; 2ND ADD DIVISOR
MOV A,E; DIVISOR 3RD FRACTION
RAR ; HALF OF DIVISOR 3RD FRACTION
LXI H,OP3S+1; TO ADDRESS 3RD SUBTRACT DIVISOR
MOV M,A; 3RD SUBTRACT DIVISOR
LXI H,OP3A+1; TO ADDRESS 3RD ADD DIVISOR
MOV M,A; 3RD ADD DIVISOR
MVI B,0; INIT QUOTIENT 1ST FRCTN
MOV A,B; DIVISOR FOURTH FRACTION IS ZERO
RAR ; LOW BIT OF DIVISOR 3RD FRACTION
LXI H,OP4S+1; TO ADDRESS 4TH SUBTRACT DIVISOR
MOV M,A; 4TH SUBTRACT DIVISOR
LXI H,OP4A+1; TO ADDRESS 4TH ADD DIVISOR
MOV M,A; 4TH ADD DIVISOR
LXI H,OP4X+1; TO ADDRESS 4TH ADD DIVISOR
MOV M,A; 4TH ADD DIVISOR
; LOAD 1ST REMAINDER, CHECK SIGN.
LXI H,ACC1; TO ADDR REMAINDER 1ST FRCTN
MOV A,M; REMAINDER 1ST FRACTION
INR L; TO ADDR REMAINDER 2ND FRCTN
MOV D,M; REMAINDER 2ND FRACTION
INR L; TO ADDR REMAINDER 3RD FRCTN
MOV E,M; REMAINDER 3RD FRACTION
ANA A ; SET CONTROL BITS
JM DIVX4; IF REMAINDER IS NEGATIVE
; ADJUST EXPONENT,POSITION REMAINDER
; AND INITIALIZE THE QUOTIENT.
MVI L,LOW(ACCE); TO ADDRESS ACCUMULATOR EXPONENT
MOV C,M; QUOTIENT EXPONENT
INR C; INCREMENT QUOTIENT EXPONENT
RZ ; RETURN IF OVERFLOW
MOV M,C; QUOTIENT EXPONENT
MOV L,E; REMAINDER 3RD FRACTION
MOV H,D; REMAINDER 2ND FRACTION
MOV E,A; REMAINDER 1ST FRACTION
MVI D,1; INITIALIZE QUOT 3RD FRCTN
MOV C,B; INITIALIZE QUOT 2ND FRCTN
; SUBTRACT THE DIVISOR FROM THE REMAINDER
; IF IT IS POSITIVE
DIVX1: XRA A; REMAINDER 4TH FRCTN IS ZERO
CALL DIVX5;
DIVX2: RLC ; SHFT REM 4TH FRCTN TO CY
; SHIFT THE REMAINDER LEFT ONE BIT.
MOV A,B; QUOTIENT 1ST FRACTION
RAL ; MS BIT OF QUOTIENT TO CY
RC ; IF DIVISION COMPLETE
RAR ; REMAINDER 4TH FRCTN TO CY
MOV A,L; REMAINDER 3RD FRACTION
RAL ; LEFT SHIFT REM 3RD FRCTN
MOV L,A; REMAINDER 3RD FRACTION
MOV A,H; REMAINDER 2ND FRACTION
RAL ; LEFT SHIFT REM 2ND FRCTN
MOV H,A; REMAINDER 2ND FRACTION
CALL LSH; CALL LEFT SHIFT SUBROUTINE
; BRANCH IF SUBTRACTION IS REQUIRED
MOV A,D; QUOTIENT 3RD FRACTION
RRC ; REM SIGN INDIC TO CARRY BIT
JC DIVX1; TO SUB DIVISOR IF REM POS
; ADD THE DIVISOR IF THE REMAINDER
; IS NEGATIVE.
DIVX3: MOV A,L; REMAINDER 3RD FRACTION
JMP DIVX6;
; POSITION THE REMAINDER AND INITIALIZE
; THE QUOTIENT.
DIVX4: MOV L,E; REMAINDER 3RD FRACTION
MOV H,D; REMAINDER 2ND FRACTION
MOV E,A; REMAINDER 1ST FRACTION
MOV D,B; INITIALIZE QUOT 3RD FRCTN
MOV C,B; INITIALIZE QUOT 2ND FRCTN
JMP DIVX3; ADD DIVISOR IF REM IS NEG
; ORIGINALLY, THIS CODE WAS AT THE BEGINNING
; OF THE PROGRAM...
DIVX5:
OP4S:
SUI 0; SUB DIVISOR 4TH FRACTION
MOV A,L; REM 3RD FRACTION
OP3S:
SBI 0; SUB DIVISOR 3RD FRACTION
MOV L,A; REM 3RD FRACTION
MOV A,H; REM 2ND FRACTION
OP2S:
SBI 0; SUB DIVISOR 2ND FRACTION
MOV H,A; REM 2ND FRACTION
MOV A,E; REM 1ST FRACTION
OP1S:
SBI 0; SUB DIVISOR 1ST FRACTION
MOV E,A; REM 1ST FRACTION
OP4A:
MVI A,0; REM 4TH FRACTION
RET
DIVX6:
OP3A:
ADI 0; ADD DIVISOR 3RD FRACTION
MOV L,A; REM 3RD FRACTION
MOV A,H; REM 2ND FRACTION
OP2A:
ACI 0; ADD DIVISOR 2ND FRACTION
MOV H,A; REM 2ND FRACTION
MOV A,E; REM 1ST FRACTION
OP1A:
ACI 0; ADD DIVISOR 1ST FRACTION
MOV E,A; REM 1ST FRACTION
OP4X:
MVI A,0; REM 4TH FRACTION
JMP DIVX2
END