mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 07:54:25 +00:00
649 lines
28 KiB
Plaintext
649 lines
28 KiB
Plaintext
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
|