home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpmug
/
cpmug018.ark
/
FLTARITH.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
39KB
|
1,313 lines
; 8008 BINARY FLOATING POINT SYSTEM
;
; THE 8008 BINARY FLOATING POINT SYSTEM CONSISTS OF A
; SET OF SUBROUTINES DESIGNED TO PERFORM ARITHMETIC
; OPERATIONS ON NUMERIC QUANTITIES REPRESENTED IN
; MEMORY.
;
; EACH NUMERIC QUANTITY OCCUPIES FOUR CONSECUTIVE WORDS
; (32 BITS) OF MEMORY. THE LARGEST MAGNITUDE THAT CAN
; BE REPRESENTED IS APPROXIMATELY 3.6 TIMES TEN TO THE
; 38TH POWER. THE SMALLEST NON-ZERO MAGNITUDE THAT
; CAN BE REPRESENTED IS APPROXIMATELY 2.7 TIMES TEN TO
; THE MINUS 39TH POWER. EACH NUMERIC QUANTITY IS
; REPRESENTED WITH A PRECISION OF ONE PART IN
; APPROXIMATELY 16,00Q,00Q.
;
; THE SOFTWARE CONSTITUTING THE FLOATING POINT SYSTEM
; IS DIVIDED INTO TWO SECTIONS, EACH OF WHICH OCCUPIES
; 3 BANKS OF ROM OR RAM. SECTION 1 IS INDEPENDENT OF
; OTHER SOFTWARE. SECTION 2 IS OPERABLE ONLY WHEN
; SECTION 1 IS AVAILABLE IN MEMORY. IN ADDITION TO
; MEMORY FOR PROGRAM, 63 WORDS OF RAM ARE USED AS SCRATCHPAD.
;
; SOFTWARE SECTION 1 CONTAINS THE FOLLOWING SUBROUTINES:
; LOD - LOAD SPECIFIED DATA INTO THE FLOATING POINT
; ACCUMULATOR.
; ADD - ADD SPECIFIED DATA TO THE FLOATING POINT
; ACCUMULATOR.
; SUB - SUBTRACT SPECIFIED DATA FROM THE FLOATING
; POINT ACCUMULATOR.
; MUL - MULTIPLY THE FLOATING POINT ACCUMULATOR
; BY THE SPECIFIED DATA.
; DIV - DIVIDE THE FLOATING POINT ACCUMULATOR
; BY THE SPECIFIED DATA
; TST - SET CONTROL BITS TO INDICATE ATTRIBUTES
; OF THE CONTENTS OF THE FLOATING POINT ACCUMULATOR
; CHS - CHANGE THE SIGN OF THE FLOATING POINT ACCUMULATOR.
; ABS - SET THE SIGN OF THE FLOATING POINT ACCUMULATOR
; POSITIVE.
; STR - STORE IN SPECIFIED MEMORY THE VALUE IN THE
; REGISTERS AS RETURNED BY OTHER SUBROUTINES.
; INIT - MOVE CODE FROM ROM TO RAM IN PREPARATION
; FOR EXECUTION OF THE MUL AND DIV SUBROUTINES.
;
; SOFTWARE SECTION 2 CONTAINS SUBROUTINES WHICH ARE
; USED TO CONVERT DATA BETWEEN THE BINARY FLOATING
; POINT FORMAT AND A DECIMAL FORMAT SUITABLE FOR
; ENTRY OR DISPLAY IN INPUT/OUTPUT EQUIPMENT. THE
; DECIMAL FORMAT IS STORED IN MEMORY AS A SERIES
; OF CHARACTERS. RELATIVELY SIMPLE INPUT/OUTPUT
; ROUTINES MAY BE USED TO INTERFACE THE MEMORY-
; RESIDENT CHARACTER STRINGS WITH ANY TYPE OF PHYSICAL
; I/O DEVICE. THE CONVERSION ROUTINES ARE MORE FULLY
; EXPLAINED IN TEXT IMMEDIATELY PRECEEDING THE ROUTINES.
;
; THE 8008 BINARY FLOATING POINT SYSTEM CONSISTS OF A SET
; OF SUBROUTINES DESIGNED TO PERFORM OPERATIONS ON NUMERIC
; QUANTITIES REPRESENTED IN A SPECIFIC NOTATION. SUBROUTINES
; ARE PROVIDED TO PERFORM A VARIETY OF ARITHMETIC AND RELATED
; OPERATIONS.
;
; THE SUBROUTINES ARE DESIGNED TO BE STORED AND EXECUTED IN
; READ-ONLY-MEMORY (ROM) AND REQUIRE THE FIRST PORTION OF A
; BANK OF READ-WRITE MEMORY (RAM, FROM 'RANDOM ACCESS MEMORY')
; FOR SCRATCHPAD MEMORY. THE SUBROUTINES ARE SEPARATED INTO
; A NUMBER OF PACKAGES, EACH CONTAINING SUBROUTINES FOR A GROUP
; OF RELATED OPERATIONS. THE AMOUNT OF MEMORY (ROM AND RAM)
; REQUIRED FOR INSTALLATION OF THE SYSTEM IS DEPENDENT UPON
; THE COMBINATION OF PACKAGES TO BE USED. SCRATCHPAD MEMORY
; IS INITIALIZED BY A UTILITY SUBROUTINE WHICH MUST BE EXECUTED
; BEFORE OTHER SUBROUTINES ARE EXECUTED THE FIRST TIME.
;
; IN GENERAL, THE SUBROUTINES HAVE SIMILAR ENTRY AND EXIT
; CONDITIONS. UNLESS SPECIFIED DIFFERENTLY IN THE DESCRIPTION
; OF A SUBROUTINE, THE SUBROUTINES HAVE THE FOLLOWING CHARACTERISTICS.
;
; SUBROUTINES REQUIRING ONE OPERAND TAKE IT FROM AN INTERNAL
; FLOATING POINT ACCUMULATOR. SUBROUTINES REQUIRING TWO OPERANDS
; TAKE ONE FROM THE ACCUMULATOR AND THE OTHER FROM THE MEMORY
; LOCATION INDICATED BY THE CONTENTS OF THE H AND L REGISTERS
; UPON ENTRY. THE NUMERIC RESULT OF EACH OPERATION IS STORED
; IN THE ACCUMULATOR AND IS RETURNED TO THE CALLING ROUTINE
; IN THE A, B, C, AND D REGISTERS.
;
; UPON EXIT FROM THE ARITHMETIC SUBROUTINES, THE PROPERTIES
; OF THE RESULT ARE INDICATED BY THE SETTINGS OF THE CONTROL
; BITS.
; CARRY BIT = 1 THE RESULT EXCEEDS THE CAPACITY OF THE
; ACCUMULATOR. THE OTHER CONTROL BITS, THE
; CONTENTS OF THE HARDWARE REGISTERS, AND
; THE CONTENTS OF THE ACCUMULATOR ARE
; MEANINGLESS. THIS SITUATION IS ALSO
; INDICATED BY A NON-ZERO QUANTITY BEING
; STORED IN A FLAG WORD.
; CARRY BIT = 0 THE RESULT IS IN RANGE. THE ZERO AND
; SIGN BITS ARE PROPERLY SET, AND THE A, B,
; C, AND D REGISTERS CONTAIN THE FOUR PARTS
; OF THE ACCUMULATOR.
; ZERO BIT = 1 THE RESULT OF THE OPERATION IS ZERO OR
; A QUANTITY TOO SMALL TO BE REPRESENTED.
; ZERO BIT = 0 THE RESULT IS NON-ZERO.
; SIGN BIT = 1 THE RESULT IS NEGATIVE.
; SIGN BIT = 0 THE RESULT IS POSITIVE.
; DATA ARE REPRESENTED IN A NOTATION WHICH RECORDS EIGHT BITS
; OF EXPONENT, ONE BIT OF SIGN, AND TWENTY-FOUR BITS OF FRACTION.
; THE LARGEST MAGNITUDE THAT CAN BE REPRESENTED IS APPROXIMATELY
; 3.6 * 10 ** 38. THE SMALLEST NON-ZERO MAGNITUDE IS
; APPROXIMATELY 2.7 * 10 ** -39. THE RESOLUTION OF THE NOTATION
; IS APPROXIMATELY 6.2 * 10 ** -8; I.E., BETTER THAN SEVEN
; DECIMAL DIGIT PRECISION.
;
; DATA VALUES ARE REPRESENTED IN FOUR CONSECUTIVE MEMORY WORDS
; WHICH MUST BE IN THE SAME BANK OF MEMORY. THE INTERPRETATION
; OF THESE WORDS IS SHOWN BELOW.
; WORD 1 IF NON-ZERO, THIS WORD CONTAINS THE
; EXPONENT PLUS A BIAS OF 200 OCTAL. THE
; EXPONENT INDICATES THE POWER OF 2 BY
; WHICH THE FRACTION IS TO BE MULTIPLIED TO
; OBTAIN THE REPRESENTED VALUE. IF THIS
; WORD IS ZERO, THE REPRESENTED VALUE IS ZERO
; AND WORDS 2, 3, AND 4 ARE MEANINGLESS.
; WORD 2, BIT 7 THIS BIT INDICATES THE SIGN OF THE VALUE:
; 0 IF POSITIVE, 1 IF NEGATIVE.
; WORD 2, BITS 6-0 THESE BITS PLUS AN ASSUMED 1 IN BIT 7 POSITION
; ARE THE MOST SIGNIFICANT BITS OF THE FRACTION.
; THE FRACTION IS STORED IN ABSOLUTE FORM
; (UNSIGNED) WITH THE RADIX POINT POSITIONED TO
; THE LEFT OF BIT 7. THE VALUE OF THE FRACTION
; IS THUS LESS 1.0 AND EQUAL TO OR GREATER THAN
; THAN 0.5.
; WORD 3 THIS WORD CONTAINS THE SECOND MOST SIGNIFICANT
; EIGHT BITS OF THE FRACTION.
; WORD 4 THIS WORD CONTAINS THE EIGHT LEAST SIGNIFICANT
; BITS OF THE FRACTION.
;
; EXAMPLES OF DATA NOTATION
; VALUE WORD1 WORD2 WORD3 WORD4
; 0.0 00Q XXX XXX XXX X = DON'T CARE
; +1.0 201 00Q 00Q 00Q
; -1.0 201 200 00Q 00Q
; +0.1 175 114 314 314
; -100.0 207 310 63Q 63Q
;
;
; FLOATING POINT ACCUMULATOR.
;
; THE FLOATING POINT ACCUMULATOR CONSISTS OF 5 SCRATCHPAD WORDS
; CONTAINING RESPECTIVELY THE ACCUMULATOR EXPONENT, THE
; ACCUMULATOR SIGN, AND THREE WORDS OF ACCUMULATOR FRACTION.
; THE EXPONENT IS RECORDED WITH A BIAL OF 200 OCTAL. AN
; EXPONENT WORD OF ZERO INDICATES THAT THE VALUE IN THE
; ACCUMULATOR IS ZERO AND THE REMAINING WORDS OF THE ACCUMULATOR
; ARE MEANINGLESS. THE SIGN WORD HOLDS 00Q IF THE ACCUMULATOR
; IS NEGATIVE, 200 OCTAL IF POSITIVE. THE FRACTION IS RECORDED
; AS A NORMALIZED POSITIVE VALUE WITH THE RADIX POINT TO THE
; LEFT OF THE MOST SIGNIFICANT BIT OF THE FIRST FRACTION WORD.
; OVERFLOW FLAG
;
; THE OVERFLOW FLAG WORD IS PROVIDED AS A CONVENIENCE TO THE
; USER OF THE FLOATING POINT SYSTEM. THE WORD IS INITIALLY SET
; TO ZERO AND MAY BE RESET TO ZERO BY THE USER AT ANY TIME.
; WHEN ANY OF THE SYSTEM ROUTINES DETECTS AN OVERFLOW CONDITION,
; THE OVERFLOW FLAG IS SET NON-ZERO. THUS THE USER MAY CLEAR
; THE FLAG, PERFORM A SEQUENCE OF FLOATING POINT OPERATIONS, AND
; CHECK THE FLAG TO DETERMINE IF AN OVERFLOW OCCURRED DURING THE
; SEQUENCE.
;
; SIGNIFICANCE INDEX.
;
; THE FLOATING POINT ADD AND SUBTRACT SUBROUTINES RETURN A
; SIGNIFICANCE INDEX TO THE USER WHEN THE RESULT OF THE
; OPERATION IS NOT ZERO. THIS INDEX GIVES AN INDICATION OF THE
; CHANGE IN THE VALUE OF THE ACCUMULATOR EXPONENT AS A RESULT
; OF THE ARITHMETIC OPERATION PERFORMED. IT IS USED PRIMARILY
; FOR COMPARISON OF TWO VALUES WHICH ARE EXPECTED TO BE EQUAL,
; BUT WHICH MAY DIFFER BY A SMALL AMOUNT DUE TO MEASUREMENT OR
; ROUND-OFF ERRORS. AS AN EXAMPLE, A SIGNIFICANCE INDEX OF
; 354 OCTAL (-20 DECIMAL) INDICATES THAT THE RESULT OF THE
; OPERATION IS SMALLER THAN THE OPERANDS BY A FACTOR OF
; APPROXIMATELY ONE MILLION (2 ** 20).
; THE FLOATING POINT TEST, COMPLEMENT AND ABSOLUTE SUBROUTINES
; RETURN THE SIGNIFICANCE INDEX FROM AN IMMEDIATELY PRECEEDING
; ADD OR SUBTRACT OPERATION.
;
;
; ARITHMETIC AND UTILITY PACKAGE
;
; THE ARITHMETIC AND UTILITY SUBROUTINE PACKAGE OF THE 8008
; BINARY FLOATING POINT SYSTEM CONTAINS SUBROUTINES FOR
; PERFORMING THE BASIC ARITHMETIC AND UTILITY OPERATIONS
; AVAILABLE IN THE SYSTEM.
;
; THE ARITHMETIC AND UTILITY PACKAGE IS CONTAINED IN 768
; CONSECUTIVE WORDS OF MEMORY (3 BANKS OF ROM) AND DOES NOT
; REQUIRE THAT ANY OTHER SOFTWARE BE PRESENT IN MEMORY. THIS
; PACKAGE USES THE FIRST 54 WORDS OF A BANK OF RAM AS
; SCRATCHPAD MEMORY.
;
; THE INDIVIDUAL SUBROUTINES INCLUDED IN THE ARITHMETIC AND
; UTILITY PACKAGE ARE DESCRIBED BELOW.
;
; FLOATING POINT INITIALIZE SUBROUTINE
;
; THE FLOATING POINT INITIALIZE SUBROUTINE MOVES A SECTION OF
; CODE FROM ROM MEMORY TO SCRATCHPAD RAM MEMORY IN PREPARATION
; FOR EXECUTION OF THE FLOATING POINT MULTIPLY AND DIVIDE
; SUBROUTINES. THE OVERFLOW FLAG IS ALSO SET TO ZERO.
;
; ENTRY POINT
; INIT
;
; ENTRY CONDITIONS
; NONE
;
; EXIT CONDITIONS
; SCRATCHPAD RAM INITIALIZED
;
; REGISTERS ALTERED
; E, H, L
;
; MAXIMUM SUBROUTINE LEVELS USED
; 0
;
;
; STORE REGISTERS SUBROUTINE
;
; THE STORE REGISTERS SUBROUTINE STORES THE CONTENTS OF THE
; A,B,C,AND D REGISTERS IN FOUR CONSECUTIVE MEMORY LOCATIONS
; (IN THE SAME BANK OF RAM). THE ADDRESS WHERE THE FIRST WORD
; WILL BE STORED IS INDICATED BY THE CONTENTS OF THE H AND L
; REGISTERS.
;
; ENTRY POINT
; STR
;
; ENTRY CONDITIONS
; A REGISTER = 1ST WORD TO BE STORED
; B REGISTER = 2ND WORD TO BE STORED
; C REGISTER = 3RD WORD TO BE STORED
; D REGISTER = 4TH WORD TO BE STORED
; H REGISTER = MS 6 BITS OF MEMORY ADDRESS
; L REGISTER = LS 8 BITS OF MEMORY ADDRESS
;
; EXIT CONDITIONS
; THE CONTENTS OF THE REGISTERS ARE STORED IN THE SPECIFIED
; MEMORY LOCATION
;
; REGISTERS ALTERED
; L
;
; MAXIMUM SUBROUTINE LEVELS USED
; 0
;
;
; FLOATING POINT LOAD ROUTINE
;
; THE FLOATING POINT LOAD SUBROUTINE PLACES THE SPECIFIED
; FLOATING POINT OPERAND IN THE FLOATING POINT ACCUMULATOR
;
; ENTRY POINT
; LOD
;
; ENTRY CONDITIONS
; H REGISTER = MS 6 BITS OF OPERAND ADDRESS
; L REGISTER = LS 8 BITS OF OPERAND ADDRESS
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 1
;
;
; FLOATING POINT ADD SUBROUTINE
;
; THE FLOATING POINT ADD SUBROUTINE ADDS THE SPECIFIED
; FLOATING POINT OPERAND TO THE VALUE IN THE FLOATING POINT
; ACCUMULATOR AND PLACES THE SUM IN THE FLOATING POINT
; ACCUMULATOR.
;
; ENTRY POINT
; ADD
;
; ENTRY CONDITIONS
; H REGISTER = MS 6 BITS OF OPERAND ADDRESS
; L REGISTER = LS 8 BITS OF OPERAND ADDRESS
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; IF OVERFLOW:
; LOCATION <OVER> SET NON-ZERO
; IF NO OVERFLOW:
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
; E REGISTER = SIGNIFICANCE INDEX
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 2
;
;
;
; FLOATING POINT SUBTRACT SUBROUTINE
;
; THE FLOATING POINT SUBTRACT SUBROUTINE SUBTRACTS THE SPECIFIED
; FLOATING POINT OPERAND FROM THE VALUE IN THE FLOATING POINT
; ACCUMULATOR AND PLACES THE DIFFERENCE IN THE FLOATING POINT
; ACCUMULATOR.
;
; ENTRY POINT
; SUB
;
; ENTRY CONDITIONS
; H REGISTER = MS 6 BITS OF OPERAND ADDRESS
; L REGISTER = LS 8 BITS OF OPERAND ADDRESS
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; IF OVERFLOW:
; LOCATION <OVER> SET NON-ZERO
; IF NO OVERFLOW:
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
; E REGISTER = SIGNIFICANCE INDEX
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 2
;
;
;
; FLOATING POINT ABSOLUTE SUBROUTINE
;
; THE FLOATING POINT ABSOLUTE SUBROUTINE SETS THE SIGN OF THE
; VALUE IN THE FLOATING POINT ACCUMULATOR POSITIVE.
;
; ENTRY POINT
; ABS
;
; ENTRY CONDITIONS
; NONE
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
; E REGISTER = SIGNIFICANCE INDEX, IF THE PREVIOUS
; OPERATION WAS AN ADD OR SUBTRACT
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 0
;
;
;
; FLOATING POINT ZERO SUBROUTINE
;
; THE FLOATING POINT ZERO SUBROUTINE PLACES THE VALUE ZERO IN
; THE FLOATING POINT ACCUMULATOR.
;
; ENTRY POINT
; ZRO
;
; ENTRY CONDITIONS
; NONE
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 0
;
;
;
; FLOATING POINT TEST SUBROUTINE
;
; THE FLOATING POINT TEST SUBROUTINE LOADS THE VALUE IN THE
; FLOATING POINT ACCUMULATOR INTO THE REGISTERS AND SETS THE
; ZERO AND SIGN CONTROL BITS TO INDICATE THE CORRESPONDING
; ATTRIBUTES OF THE VALUE.
;
; ENTRY POINT
; TST
;
; ENTRY CONDITIONS
; NONE
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
; E REGISTER = SIGNIFICANCE INDEX, IF THE PREVIOUS
; OPERATION WAS AN ADD OR SUBTRACT
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 0
;
;
;
; FLOATING POINT COMPLEMENT SUBROUTINE
;
; THE FLOATING POINT COMPLEMENT SUBROUTINE CHANGES THE
; ARITHMETIC SIGN OF THE VALUE IN THE FLOATING POINT
; ACCUMULATOR
;
; ENTRY POINT
; CHS
;
; ENTRY CONDITIONS
; NONE
;
; EXIT CONDITIONS
; CONTROL BITS SET AS DEFINED FOR THE SYSTEM
; A REGISTER = ACCUMULATOR EXPONENT
; B REGISTER = ACCUMULATOR SIGN AND 1ST FRACTION
; C REGISTER = ACCUMULATOR 2ND FRACTION
; D REGISTER = ACCUMULATOR 3RD FRACTION
; E REGISTER = SIGNIFICANCE INDEX, IF THE PREVIOUS
; OPERATION WAS AN ADD OF SUBTRACT
;
; REGISTERS ALTERED
; ALL
;
; MAXIMUM SUBROUTINE LEVELS USED
; 0
;
;
; SAMPLE PROGRAM USING THE 8008 FLOATING POINT SYSTEM
;
; INVESTIGATE THE RIGHT TRIANGLE
;
; INITIALIZE THE FLOATING POINT SYSTEM SCRATCHPAD
;
ORG 1000Q
BEGIN: CALL INIT ;INITIALIZE THE SCRATCHPAD
;
; SQUARE THE BASE AND STORE THE RESULT
;
LXI H,BASE ;ADDRESS OF THE BASE LEG
CALL LOD ;LOAD THE BASE LEG INTO THE ACCUM
LXI H,BASE ;ADDRESS OF THE BASE LEG
CALL MUL ;SQUARE THE BASE LEG
LXI H,TEMP ;ADDRESS OF TEMPORARY STORAGE
CALL STR
;
; SQUARE THE HEIGHT, ADD THE SQUARE OF THE BASE AND STORE
;
LXI H,HEIGHT ;ADDRESS OF THE HEIGHT LEG
CALL LOD ;LOAD THE HEIGHT LEG INTO THE ACCUM
LXI H,HEIGHT
CALL MUL ;SQUARE THE HEIGHT LEG
LXI H,TEMP ;TEMPORARY STORAGE
CALL ADD ;SUM THE BASE AND HEIGHT SQUARES
LXI H,TEMP ;TEMP STORAGE
CALL STR ;SAVE THE SUM OF THE SQUARES
;
; SQUARE THE HYPOTENUSE, SUBTRACT THE SUM OF THE SQUARES OF THE LEGS
;
LXI H,HYPOT ;ADDRESS OF THE HYPOTENUSE
CALL LOD ;LOAD THE HYPOTENUSE INTO THE ACCUM
LXI H,HYPOT
CALL MUL ;SQUARE THE HYPOT
LXI H,TEMP ;TEMP STORAGE
CALL SUB ;SUBTRACT THE SUM OF THE SQUARES OF THE LEGS
;
; CHECK FOR AN OVERFLOW DURING THE ABOVE OPERATIONS
;
MVI H,SCRB ;ADDRESS THE SCRATCH BANK
MVI L,OVER ;ADDRESS THE OVERFLOW FLAG
MOV A,M ;GET THE FLAG
ANA A ;SET THE CONTROL BITS
JNZ ERR3 ;JUMP IF AN OVERFLOW OCCURRED
CALL TST ;TEST THE ACCUMULATOR
JZ OK ;IF THE ACCUM IS ZERO
;
; CHECK FOR ROUND OFF ERROR
;
MOV A,E
ADI 22
JP ERR2
;
; PYTHAGORAS WAS ALL WET
;
ERR1: HLT
;
; HE WAS PRETTY CLOSE
;
ERR2: HLT
;
; THAT IS A BIG TRIANGLE
;
ERR3: HLT
;
; RIGHT ON
; (THE PROGRAM STOPS HERE IF IT HAS BEEN KEYED IN WITHOUT ERROR,
; AND IF THE CPU IS FUNCTIONING PROPERLY)
;
OK: HLT
;
; DATA STORAGE
;
BASE: DB 202Q,300Q,0,0 ;-3
HEIGHT: DB 203Q,0,0,0 ;4
HYPOT: DB 203Q,40Q,0,0 ;5
TEMP: DB 0,0,0,0 ;TEMPORARY STORAGE
; FLOATING POINT ARITHMETIC PACKAGE
;
ORG 1400Q ;SET ORIGIN TO 1400 OCTAL
ARTHB EQU 3 ;BANK NO. OF ARITH PKG
ARITH EQU $
SCR EQU 5400Q
SCRB EQU 13Q ;BANK NO. OF SCRATCHPAD
; 8008 BINARY FLOATING POINT SYSTEM
; ARITHMETIC AND UTILITY PACKAGE
; PROGRAMMER: CAL OHME
; DATE: 26 DECEMBER 1973
; ARITH IS THE BEGINNING ADDRESS OF THE
; ARITHMETIC AND UTILITY PACKAGE OF THE FLOATING
; POINT SYSTEM.
; SCR IS THE BEGINNING ADDRESS OF THE RAM USED AS
; SCRATCHPAD FOR THE SYSTEM.
; THE RAM MULTIPLY AND DIVIDE SUBROUTINES
; ARE MOVED FROM ROM TO RAM BY SUBROUTINE
; INIT AND ARE EXECUTED IN RAM ONLY.
; RAM MULTIPLY SUBROUTINE.
;
MULX4 EQU $-ARITH+SCR
ADI 0 ;ADD OPERAND 3RD FRACTION
MULP3 EQU $-1-ARITH
MOV E,A ;4TH PARTIAL PROD
MOV A,D ;3RD PARTIAL PROD
ACI 0 ;ADD OPERAND 2ND FRACTION
MULP2 EQU $-1-ARITH
MOV D,A ;3RD PARTIAL PROD
MOV A,C ;2ND PARTIAL PROD
ACI 0 ;ADD OPERAND 1ST FRACTION
MULP1 EQU $-1-ARITH
JMP MULX5 ;TO ROM CODE
;
; RAM DIVIDE SUBTROUTINE
;
DIVX5 EQU $-ARITH+SCR
SUI 0 ;SUB DIVISOR 4TH FRACTION
OP4S EQU $-1-ARITH
MOV A,L ;REMAINDER 3RD FRACTION
SBI 0 ;SUBDIVISOR 3RD FRACTION
OP3S EQU $-1-ARITH
MOV L,A ;REMAINDER 3RD FRACTION
MOV A,H ;REMAINDER 2ND FRACTION
SBI 0 ;SUB DIVISOR 2ND FRACTION
OP2S EQU $-1-ARITH
MOV H,A ;REMAINDER 2ND FRACTION
MOV A,E ;REMAINDER 1ST FRACTION
SBI 0 ;SUB DIVISOR 1ST FRACTION
OP1S EQU $-1-ARITH
MOV E,A ;REMAINDER 1ST FRACTION
MVI A,0 ;REMAINDER 4TH FRACTION
OP4A EQU $-1-ARITH
RET ;RETURN TO ROM
DIVX6 EQU $-ARITH+SCR
ADI 0 ;ADD DIVISOR 3RD FRACTION
OP3A EQU $-1-ARITH
MOV L,A ;REMAINDER 3RD FRACTION
MOV A,H ;REMAINDER 2ND FRACTION
ACI 0 ;ADD DIVISOR 2ND FRACTION
OP2A EQU $-1-ARITH
MOV H,A ;REMAINDER 2ND FRACTION
MOV A,E ;REMAINDER 1ST FRACTION
ACI 0 ;ADD DIVISOR 1ST FRACTION
OP1A EQU $-1-ARITH
MOV E,A ;REMAINDER 1ST FRACTION
MVI A,0 ;REMAINDER 4TH FRACTION
OP4X EQU $-1-ARITH
JMP DIVX2 ;TO ROM CODE
;
; RAM LOCATIONS USED BY THE BINARY FLOATING POINT SYSTEM
;
OVER EQU $-ARITH
DB 0 ;INITIALLY CLEAR
PREX EQU OVER+1 ;PREVIOUS EXPONENT
ACCE EQU PREX+1 ;ACCUMULATOR EXPONENT
ACCS EQU ACCE+1 ;ACCUMULATOR SIGN
ACC1 EQU ACCS+1 ;ACCUMULATOR 1ST FRACTION
ACC2 EQU ACC1+1 ;ACCUMULATOR 2ND FRACTION
ACC3 EQU ACC2+1 ;ACCUMULATOR 3RD FRACTION
SF EQU ACC3+1 ;SUBTRACTION FLAG
;
; INIT SUBROUTINE ENTRY POINT
;
INIT: MVI L,PREX ;ADDRESS LAST WORD TO MOVE
INIT1: MVI H,ARTHB ;ADDRESS ROM COPY
MOV E,M ;CURRENT WORD OF ROM COPY
MVI H,SCRB ;ADDRESS RAM COPY
MOV M,E ;WRITE CURRENT WORD TO RAM
DCR L ;DECREMENT WORD ADDRESS
JP INIT1 ;IF MORE TO MOVE
RET ;RETURN TO CALLER
;
; STR SUBROUTINE ENTRY POINT
;
STR0: MOV M,E ;STORE ZEROETH WORD
INR L ;ADDRESS FIRST WORD
STR: MOV M,A ;STORE FIRST WORD
STR1: INR L ;ADDRESS SECOND WORD
MOV M,B ;STORE SECOND WORD
INR L
MOV M,C ;STORE THIRD WORD
INR L
MOV M,D ;STORE FOURTH WORD
RET ;RETURN TO CALLER
;
; FLOATING POINT ZRO SUBROUTINE ENTRY POINT
;
ZRO: MVI H,SCRB ;ADDRESS SCRATCH BANK
ZRO1: MVI L,ACCE ;ADDRESS ACCUM EXPONENT
XRA A ;CLEAR THE A REGISTER
MOV M,A ;CLEAR THE ACCUM EXPONENT
RET ;RETURN TO CALLER
;
; FLOATING POINT CHS SUBROUTINE ENTRY POINT
;
CHS: MVI A,200Q ;MASK FOR SIGN BIT
MVI B,0 ;MVI INST TO SKIP NEXT WORD
ORG $-1
;
; FLOATING POINT ABS SUBROUTINE ENTRY POINT
;
ABS: XRA A ;CLEAR THE A REGISTER
MVI H,SCRB ;ADDRESS THE SCRATCH BANK
MVI L,ACCS ;ADDRESS ACCUM SIGN
ANA M
XRI 200Q ;COMPLEMENT THE SIGN BIT
MOV M,A ;PUT THE ACCUM SIGN BACK
;
; FLOATING POINT TEST ENTRY POINT
;
TST: MVI H,SCRB ;ADDRESS SCRATCH BANK
TST1: MVI L,ACCE ;ACCUM EXPONENT
MOV A,M ;GET THE EXPONENT
ANA A ;SET CONTROL BITS
JZ ZRO ;IF ACCUM IS ZERO
MOV E,A ;ACCUM EXPONENT
INR L ;ADDRESS THE ACCUM SIGN
MOV A,M
INR L ;ADDRESS ACCUM 1ST FRACTION
XRA M ;XOR ACCUM SIGN AND 1ST FRACTION
INR L ;ADDRESS ACCUM 2ND FRACTION
MOV C,M
INR L ;ADDRESS ACCUM 3RD FRACTION
MOV D,M
JMP ADD12 ;TO SET EXIT CONDITIONS
;
; FLOATING POINT LOAD ENTRY POINT
;
LOD: MOV A,M ;OPERAND EXPONENT
ANA A ;SET CONTROL BITS
JZ ZRO ;IF OPERAND IS ZERO
MOV E,A ;OPERAND EXPONENT
INR L ;ADDRESS OPERAND SIGN AND 1ST FRACTION
MOV A,M
INR L ;ADDRESS OPERAND 2ND FRACTION
MOV C,M
INR L ;ADDRESS OPERAND 3RD FRACTION
MOV D,M
;
; STORE THE OPERAND IN THE ACCUM
;
MOV L,A ;OPERAND SIGN AND 1ST FRACTION
LOD1: ORI 200Q ;SET THE ASSUMED MSB IN THE FIRST FRACTION
; TO A 1
MOV B,A ;ACCUM 1ST FRACTION
XRA L ;ACCUMULATOR SIGN
MVI H,SCRB ;ADDRESS SCRATCH BANK
MVI L,ACCE ;ADDRESS ACCUM EXPONENT
CALL STR0 ;SET THE ACCUMULATOR
XRA B ;ACCUM SIGN AND 1ST FRACTION
;
; 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 ENTRY POINT
;
MUL: MOV A,M ;OPERAND EXPONENT
ANA A ;SET CONTROL BITS
CNZ MDEX ;READ OPERAND IN NOT ZERO
JZ ZRO ;IF ZERO OR UNDERFLOW
JC OVERF ;IF OVERFLOW
CALL MULX ;CALL FIXED MULT SUBROUTINE
;
; NORMALIZE IF NECESSARY
;
MOV A,B ;1ST PRODUCT
ANA A ;SET CONTROL BITS
JM RNDA ;IF NO NORMALIZATION NECESSARY
MVI L,ACCE ;ADDRESS ACCUM EXP
MOV A,M
SBI 1 ;DECR ACCUM EXP
MOV M,A
RZ ;RETURN TO CALLER IF UNDERFLOW
CALL LSH ;CALL LEFT SHIFT ROUTINE
;
; ROUND IF NECESSARY
;
RNDA: CALL ROND ;CALL ROUNDING SUBROUTINE
JC OVERF ;IF OVERFLOW
MOV B,A ;ACCUM SIGN AND 1ST FRACTION
ORI 1 ;GET SIGN BIT
MOV A,E ;ACCUM EXP
RET
;
; FLOATING POINT DIV SUBROUTINE ENTRY POINT
;
DIV: XRA A ;CLEAR A REGISTER
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 ZRO1 ;IF UNDERFLOW OF ZERO
MOV C,A ;DIVISOR 1ST FRACTION
CALL DIVX ;CALL FIXED DIVISION SUBROUTINE
MVI H,SCRB ;ADDRESS SCRATCH BANK
JC RNDA ;IF NO OVERFLOW
;
; SET OVERFLOW FLAG
;
OVERF: MVI H,SCRB ;ADDR SCRATCH BANK
MVI L,OVER ;ADDRESS OVERFLOW FLAG
MVI A,-1 ;OVERFLOW FLAG
MOV M,A ;STORE OVERFLOW FLAG
RLC ;SET CARRY BIT FOR EXIT
RET
DB 0 ;CHECK SUM WORD
;
; FLOATING POINT SUB SUBROUTINE ENTRY POINT
;
SUB: MVI A,200Q ;MASK TO CHANGE OPERAND SIGN
MVI B,0 ;MVI INST TO SKIP NEXT WORD
ORG $-1
;
; FLOATING POINT ADD SUBROUTINE ENTRY POINT
;
ADD: XRA A ;CLEAR THE A REGISTER
;
; LOAD THE OPERAND
;
MOV E,M ;OPERAND EXPONENT
INR L ;ADDRESS OPERAND SIGN, 1ST FRACTION
XRA M
MOV B,A ;OPERAND SIGN AND 1ST FRACTION
INR L ;ADDRESS OPERAND 2ND FRACTION
MOV C,M
INR L ;ADDRESS OPERAND 3RD FRACTION
MOV D,M
;
; SAVE INITIAL EXPONENT
;
MVI H,SCRB ;ADDRESS SCRATCH BANK
MVI L,ACCE ;ADDRESS ACCUM EXPONENT
MOV A,M
DCR L ;ADDRESS INITIAL EXPONENT
MOV M,A ;SAVE INITIAL EXPONENT
;
; CHECK FOR ZERO OPERAND
;
MOV A,E ;OPERAND EXP
ANA A ;SET CONTROL BITS
JZ TST1 ;IF OPERAND IS ZERO
;
; GENERATE SUBTRACTION FLAG, RESTORE SUPPRESSED FRACTION BIT
;
MOV L,B ;OPERAND SIGN AND 1ST FRACTION
MOV A,B
ORI 200Q ;SET ASSUMED MSB
MOV B,A ;OPERAND 1ST FRACTION
XRA L ;OPERAND SIGN
MVI L,ACCS ;ADDRESS ACCUM SIGN
XRA M ;SUBTRACTION FLAG
MVI L,SF ;ADDRESS SUBTRACTION FLAG
MOV M,A ;STORE IT
;
; DETERMINE RELATIVE MAGNITUDES OF OPERAND AND ACCUM
;
MVI L,ACCE ;ADDRESS ACCUM EXP
MOV A,M
ANA A ;SET CONTROL BITS
JZ ADD17 ;IF ACCUM IS ZERO
SUB E ;DIFFERENCE OF EXPONENTS
JC ADD2 ;IF ACCUM SMALLER THAN OPERAND
;
; CHECK FOR INSIGNIFICANT OPERAND
;
JM TST1 ;IF OPERAND IS INSIG
CPI 25 ;COMPARE SHIFT COUNT TO 25
JC ADD3 ;JOIN EXCHANGE PATH IF OP IS SIGNIFICANT
JMP TST1 ;OPERAND IS INSIGNIFICANT
;
; CHECK FOR INSIGNIFICANT ACCUM
;
ADD2: JP ADD17 ;IF ACCUM IS INSIGNIFICANT
CPI -25 ;COMPARE SHIFT COUNT TO MINUS 25
JC ADD17 ;IF ACCUM IS INSIG
MOV M,E ;OPERAND EXP
MOV E,A ;SHIFT COUNT
MVI L,SF ;ADDRESS THE SUBTRACTION FLAG
MOV A,M
MVI L,ACCS ;ADDRESS THE ACCUM SIGN
XRA M ;OPERAND SIGN
MOV M,A ;ACCUM SIGN
XRA A ;ZERO THE A REGISTER
SUB E ;COMPLEMENT SHIFT COUNT
;
; EXCHANGE ACCUM AND OPERAND
;
INR L ;ADDRESS ACCUM 1ST FRACTION
MOV E,M
MOV M,B ;OPERAND 1ST FRACTION
MOV B,E ;ACCUM 1ST FRACTION
INR L ;ADDRESS ACCUM 2ND FRACTION
MOV E,M
MOV M,C ;OPERAND 2ND FRACTION
MOV C,E ;ACCUM 2ND FRACTION
INR L ;ADDRESS ACCUM 3RD FRACTION
MOV E,M
MOV M,D ;OPERAND 3RD FRACTION
MOV D,E ;ACCUM 3RD FRACTION
;
; POSITION THE OPERAND
;
ADD3: CALL RSH ;CALL RIGHT SHIFT
MVI L,SF ;ADDRESS THE SUBTRACTION FLAG
MOV A,M
ANA A ;SET CONTROL BITS
MVI L,ACC3 ;ADDRESS ACCUM 3RD FRACTION
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 ;ADDRESS AUGEND 2ND FRACTION
MOV A,M
ADC C ;ADDEND 2ND FRACTION
MOV C,A ;SUM 2ND FRACTION
DCR L ;ADDRESS AUGEND 1ST FRACTION
MOV A,M
ADC B ;ADDEND 1ST FRACTION
MOV B,A ;SUM 1ST FRACTION
JNC ADD11 ;IF NO CARRY FROM 1ST FRACTION
;
; 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 FRACTION = LOW BIT OF 3RD
MOV E,A ;SUM 4TH FRACTION
MVI L,ACCE ;ADDRESS ACCUM EXP
MOV A,M
ADI 1 ;INCREMENT ACCUMULATOR EXP
JC OVERF ;IF OVERFLOW
MOV M,A ;STORE ACCUM EXP
JMP ADD11 ;TO ROUND FRACTION
;
; SUBTRACT SUBTRAHEND FROM MINUEND
;
ADD9: XRA A ;MINUEND 4TH FRACTION IS ZERO
SUB E ;SUBTRAHEND 4TH FRACTION
MOV E,A ;DIFFERENCE 4TH FRACTION
MOV A,M ;MINUEND 3RD FRACTION
SBB D ;SUBTRA 3RD FRACTION
MOV D,A ;DIFF 3RD FRACTION
DCR L ;ADDRESS MINUEND 2ND FRACTION
MOV A,M
SBB C ;SUBTRA 2ND FRACTION
MOV C,A ;DIFF 2ND FRACTION
DCR L ;ADDRESS MINUEND 1ST FRACTION
MOV A,M
SBB B ;SUBTRA 1ST FRACTION
MOV B,A ;DIFF 1ST FRACTION
ADD10: CC COMP ;COMPLEMENT IF NECESSARY
CP NORM ;NORMALIZE IF NECESSARY
JP ZRO1 ;IF UNDERFLOW OR ZERO
ADD11: CALL ROND ;CALL ROUNDING SUBROUTINE
JC OVERF ;IF OVERFLOW
ADD12: MOV B,A ;ACCUM SIGN AND 1ST FRACTION
MVI L,PREX ;ADDRESS PREVIOUS EXP
MOV A,E ;ACCUM EXP
SUB M ;DIFFERENCE IN EXPONENTS
MOV L,A
MOV A,B ;ACCUM SIGN AND 1ST FRACTION
ORI 1 ;SET SIGN BIT FOR EXIT
MOV A,E ;ACCUM EXP
MOV E,L ;SIGNIFICANCE INDEX
RET
;
; LOAD THE ACCUM WITH THE OPERAND
;
ADD17: MVI L,SF ;ADDRESS THE SUBTRACTION FLAG
MOV A,M
MVI L,ACCS ;ADDRESS THE ACCUM SIGN
XRA M ;OPERAND SIGN
DCR L ;ADDRESS ACCUM EXP
CALL STR0 ;SET THE ACCUM
XRA B ;ACCUM SIGN AND 1ST FRACTION
JMP ADD12 ;JOIN EXIT CODE
DB 0 ;CHECH SUM WORD
;
; SUBROUTINE TO READ THE OPERAND AND
; CHECK THE ACCUMULATOR EXPONENT
;
MDEX: MOV B,A ;EXPONENT MODIFIER
INR L ;ADDRESS OPERAND SIGN, 1ST FRACTION
MOV C,M
INR L ;ADDRESS OPERAND 2ND FRACTION
MOV D,M
INR L ;ADDRESS OPERAND 3RD FRACTION
MOV E,M
MVI H,SCRB ;ADDRESS SCRATCH BANK
MVI L,ACCE ;ADDRESS ACCUM EXP
MOV A,M
ANA A ;SET CONTROL BITS
RZ ;RETURN IF ACCUM IS ZERO
ADD B ;RESULT EXP PLUS BIAS
MOV B,A
RAR ;CARRY TO SIGN
XRA B ;CARRY AND SIGN MUST DIFFER
MOV A,B ;RESULT EXP PLUS BIAS
MVI B,200Q ;EXP BIAS, SIGN MASK, MOST SIG BIT
JP OVUN ;IF OVER OR UNDERFLOW
SUB B ;REMOVE EXCESS EXP BIAS
RZ ;RETURN IF UNDERFLOW
MOV M,A ;RESULT EXP
INR L ;ADDRESS ACCUM SIGN
MOV A,M
XRA C ;RESULT SIGN IN SIGN BIT
ANA B ;RESULT SIGN
MOV M,A ;STORE IT
MOV A,C ;OPERAND SIGN AND 1ST FRACTION
ORA B ;OPERAND FIRST FRACTION
RET
OVUN: RLC ;SET CARRY BIT IF OVERFLOW
RC ;RETURN IF OVERFLOW
XRA A ;CLEAR A REGISTER
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
LSH1: MOV A,D ;ORIGINAL CONTENTS OF D
RAL ;LEFT SHIFT D
MOV D,A ;RESTORE D
MOV A,C ;ORIGINAL CONTENTS OF C
RAL ;LEFT SHIFT C
MOV C,A ;RESTORE C
MOV A,B ;ORIGINAL CONTENTS OF B
ADC A ;LEFT SHIFT B
MOV B,A ;RESTORE B
RET
;
; 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 FRACTION IS ZERO
RSH0: MVI L,8 ;EACH REG IS 8 BITS OF SHIFT
RSH1: CMP L ;COMPARE SHIFT COUNT TO 8
JM RSH2 ;IF REQUIRED 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 OPERAND 1ST FRACTION
MOV B,A ;OP 1ST FRACTION
MOV A,C ;OP 2ND FRACTION
RAR
MOV C,A ;OP 2ND FRACTION
MOV A,D ;OP 3RD FRACTION
RAR
MOV D,A ;OP 3RD FRACTION
MOV A,E ;OP 4TH FRACTION
RAR
MOV E,A ;OP 4TH FRACTION
DCR L ;DECREMENT SHIFT COUNT
JNZ RSH3 ;IF MORE SHIFTS REQUIRED
RET
;
; COMPLEMENT THE B,C,D,AND E REGISTERS
;
COMP: DCR L ;ADDRESS ACCUM SIGN
MOV A,M
XRI 200Q ;CHANGE SIGN
MOV M,A ;PUT IT BACK
COMP1: XRA A ;ZERO THE A REGISTER
MOV L,A ;ZERO L REG
SUB E ;COMPLEMENT 4TH FRACTION
MOV E,A ;4TH FRACTION
MOV A,L ;ZERO A REG
SBB D ;COMPLEMENT 3RD FRACTION
MOV D,A ;3RD FRACTION
MOV A,L ;ZERO A REG
SBB C ;COMPLEMENT 2ND FRACTION
MOV C,A ;2ND FRACTION
MOV A,L ;ZERO A REG
SBB B ;COMPLEMENT 1ST FRACTION
MOV B,A ;1ST FRACTION
RET
;
; NORMALIZE THE REGISTERS
;
NORM: MVI L,32 ;MAXIMUM 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 ZERO
NORM2: DCR L ;DECREMENT SHIFT COUNT
MOV A,E ;ORIGINAL CONTENTS OF E
RAL ;LEFT SHIFT E
MOV E,A ;PUT E BACK
MOV A,D
RAL
MOV D,A
MOV A,C
RAL
MOV C,A
MOV A,B
ADC A ;LEFT SHIFT B
MOV B,A ;PUT B BACK
NORM3: JP NORM2 ;IF NOT NORMALIZED
MOV A,L ;NORMALIZING SHIFT COUNT
SUI 32 ;REMOVE BIAS
MVI L,ACCE ;ADDRESS ACCUM EXP
ADD M ;ADJUST ACCUM EXP
MOV M,A ;NEW ACCUM EXP
RZ ;RETURN IF ZERO EXP
RAR ;MOVE BORROW BIT TO SIGN
ANA A ;SET SIGN TO INDICATE UNDERFLOW
RET
;
; SUBROUTINE TO ROUND THE B,C,D REGISTERS
;
ROND: MVI L,ACCE ;ADDRESS THE ACCUM EXP
MOV A,E ;4TH FRACTION
ANA A ;SET CONTROL BITS
MOV E,M ;ACCUM EXP
CM RNDR ;CALL 2ND LEVEL ROUNDER
RC ;IF OVERFLOW
MOV A,B ;1ST FRACTION
INR L ;ADDRESS ACCUM SIGN
XRA M ;ACCUM SIGN AND 1ST FRACTION
JMP STR1 ;RETURN THROUGH STORE SUBROUTINE
;
; SECOND LEVEL ROUNDING ROUTINE
;
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 ;ACCUM EXP
ADI 1 ;INCREMENT ACCUM EXP
MOV E,A ;NEW ACCUM EXP
MVI B,200Q ;NEW 1ST FRACTION
MOV M,A ;NEW ACCUM EXP
RET
;
; FIXED POINT MULTIPLY SUBROUTINE
;
MULX: MVI L,MULP1 ;ADDRESS 1ST MULTIPLICAND
MOV M,A ;1ST MULT
MVI L,MULP2 ;ADDRESS 2ND MULTIPLICAND
MOV M,D ;2ND MULT
MVI L,MULP3 ;ADDRESS 3RD MULTIPLICAND
MOV M,E ;3RD MULT
XRA A ;CLEAR 6TH PRODUCT
MOV E,A ;CLEAR 5TH PRODUCT
MOV D,A ;CLEAR 4TH PRODUCT
;
; MULTIPLY BY EACH ACCUMULATOR FRACTION IN TURN
;
MVI L,ACC3 ;ADDRESS 3RD FRACTION
CALL MULX2 ;MULTIPLY BY ACCUM 3RD FRACTION
MVI L,ACC2 ;ADDRESS 2ND FRACTION
CALL MULX1 ;MULTIPLY BY ACCUM 2ND FRACTION
MVI L,ACC1 ;ADDRESS 1ST FRACTION
;
; MULTIPLY BY ONE ACCUMULATOR WORD
;
MULX1: MOV A,D ;5TH PARTIAL PRODUCT
MOV E,C ;4TH PARTIAL PROD
MOV D,B ;3RD PARTIAL PROD
MULX2: MOV B,M ;MULTIPLIER
MOV L,A ;5TH PARTIAL PROD
XRA A ;ZERO A REGISTER
MOV C,A ;2ND PARTIAL PROD
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 PROD
RET ;MULT BY ZERO COMPLETE
;
; COMPLETE ADDITION OF MULTIPLICAND
;
MULX5: MOV C,A ;2ND PARTIAL PROD
JNC MULX3 ;IF NO CARRY TO 1ST PROD
INR B ;ADD CARRY TO 1ST PROD
ANA A ;CLEAR CARRY BIT
;
; LOOP FOR EACH BIT OF MULTIPLIER WORD
;
MULX3: MOV A,L ;5TH PARTIAL PRODUCT, EXIT FLAG
ADC A ;SHIFT EXIT FLAG OUT IF DONE
RZ ;EXIT IF MULTIPLICATION DONE
MOV L,A ;5TH PARTIAL PROD, EXIT FLAG
MOV A,E ;4TH PARTIAL PROD
RAL ;SHIFT 4TH PARTIAL PROD
MOV E,A ;4TH PARTIAL PROD
MOV A,D ;3RD PARTIAL PROD
RAL
MOV D,A
MOV A,C ;2ND PARTIAL PROD
RAL
MOV C,A
MOV A,B ;1ST PARTIAL PROD AND MULTIPLIER
RAL
MOV B,A
JNC MULX3 ;IF NO ADDITION REQUIRED
;
; ADD THE MULTIPLICAND TO THE PRODUCT
; IF THE MULTIPLIER BIT IS ONE
;
MOV A,E ;4TH PARTIAL PROD
JMP MULX4 ;TO RAM CODE
;
; FIXED POINT DIVIDE SUBROUTINE .
; SUBTRACT DIVISOR FROM ACCUM TO OBTAIN 1ST REMAINDER
;
DIVX: MVI L,ACC3 ;ADDRESS ACCUM 3RD FRACTION
MOV A,M
SUB E ;DIVISOR 3RD FRACTION
MOV M,A ;REMAINDER 3RD FRACTION
DCR L ;ADDRESS ACCUM 2ND FRACTION
MOV A,M
SBB D ;DIVISOR 2ND FRACTION
MOV M,A ;REMAINDER 2ND FRACTION
DCR L ;ADDRESS ACCUM 1ST FRACTION
MOV A,M
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 FRACTION
; + 200 OCTAL TO CORRECT QUOTIENT
MVI L,OP1S ;ADDRESS 1ST SUBTRACT DIVISOR
MOV M,A
MVI L,OP1A ;ADDRESS 1ST ADD DIVISOR
MOV M,A
MOV A,D ;DIVISOR 2ND FRACTION
RAR ;HALF OF DIVISOR 2ND FRACTION
MVI L,OP2S ;ADDRESS 2ND SUBTRACT DIVISOR
MOV M,A
MVI L,OP2A ;ADDRESS 2ND ADD DIVISOR
MOV M,A
MOV A,E ;DIVISOR 3RD FRACTION
RAR ;HALF OF DIVISOR 3RD FRACTION
MVI L,OP3S ;ADDRESS 3RD SUBTRACT DIVISOR
MOV M,A
MVI L,OP3A ;ADDRESS 3RD ADD DIVISOR
MOV M,A
MVI B,0 ;INITIALIZE QUOTIENT 1ST FRACTION
MOV A,B ;DIVISOR 4TH FRACTION IS ZERO
RAR ;LOW BIT OF DIVISOR 3RD FRACTION
MVI L,OP4S ;ADDRESS 4TH SUBTRACT DIVISOR
MOV M,A ;4TH SUBTRACT DIVISOR
MVI L,OP4A ;ADDRESS 4TH ADD DIVISOR
MOV M,A
MVI L,OP4X ;ADDRESS 4TH ADD DIVISOR
MOV M,A
;
; LOAD 1ST REMAINDER, CHECK SIGN
;
MVI L,ACC1 ;ADDRESS REMAINDER 1ST FRACTION
MOV A,M
INR L ;ADDRESS 2ND FRACTION
MOV D,M
INR L ;ADDRESS 3RD FRACTION
MOV E,M
ANA A ;SET CONTROL BITS
JM DIVX4 ;IF REMAINDER IS NEGATIVE
;
; ADJUST EXPONENT, POSITION REMAINDER
; AND INITIALIZE THE QUOTIENT
;
MVI L,ACCE ;ADDRESS ACCUM EXP
MOV C,M ;QUOTIENT EXP
INR C ;INCREMENT QUOTIENT EXP
RZ ;RETURN IF OVERFLOW
MOV M,C ;QUOTIENT EXP
MOV L,E ;REMAINDER 3RD FRACTION
MOV H,D ;REMAINDER 2ND FRACTION
MOV E,A ;REMAINDER 1ST FRACTION
MVI D,1 ;INITIALIZE QUOTIENT 3RD FRACTION
MOV C,B ;INITIALIZE QUOTIENT 2ND FRACTION
;
; SUBTRACT THE DIVISOR FROM THE REMAINDER
; IF IT IS POSITIVE
;
DIVX1: XRA A ;REMAINDER 4TH FRACTION IS ZERO
CALL DIVX5 ;CALL RAM SECTION
DIVX2: RLC ;SHIFT REMAINDER 4TH FRACTION TO CARRY
;
; SHIFT THE REMAINDER LEFT ONE BIT
;
MOV A,B ;QUOTIENT 1ST FRACTION
RAL ;MSB OF QUOTIENT TO CARRY
RC ;IF DIVISION COMPLETE
RAR ;REMAINDER 4TH FRACTION TO CARRY
MOV A,L ;REMAINDER 3RD FRACTION
RAL
MOV L,A
MOV A,H ;REMAINDER 2ND FRACTION
RAL
MOV H,A
CALL LSH ;CALL LEFT SHIFT ROUTINE
;
; BRANCH IF SUBTRACTION IS REQUIRED
;
MOV A,D ;QUOTIENT 3RD FRACTION
RRC ;REMAINDER SIGN INDIC TO CARRY BIT
JC DIVX1 ;TO SUB DIVISOR IF REMAINDER POSITIVE
;
; ADD THE DIVISOR IF THE REMAINDER IS NEGATIVE
;
DIVX3: MOV A,L ;REMAINDER 3RD FRACTION
JMP DIVX6 ;TO RAM CODE
;
; 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 QUOTIENT 3RD FRACTION
MOV C,B ;INITIALIZE QUOTIENT 2ND FRACTION
JMP DIVX3 ;ADD DIVISOR IF REMAINDER IS NEGATIVE
DB 0 ;CHECKSUM WORD
END