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 >
Text File  |  1984-04-29  |  29KB  |  649 lines

  1.     NAME    FLPT
  2.     CSEG
  3.  
  4.     PUBLIC    OVERF,FLOAD,FSTOR,FADD,FSUB,FMUL,FDIV,FTEST
  5.     PUBLIC    FCHS,FABS,RSH,LSH,ADD10,FZERO,FCOMP,FSTR0
  6.     EXTRN    OVER,PREX,ACCE,ACCS,ACC1,ACC2,ACC3,SF
  7.  
  8.  ;     8008 BINARY FLOATING POINT SYSTEM
  9.  ;     ARITHMETIC AND UTILITY PACKAGE
  10.  ;     PROGRAMMER  CAL OHME
  11.  ;     DATE  26 DECEMBER 1973
  12.  
  13.  
  14.  ;     FSTOR SUBROUTINE ENTRY POINT.
  15.  FSTR0:  MOV     M,E;       STORE ZEROETH WORD
  16.         INR     L;       TO ADDRESS FIRST WORD
  17.  FSTOR:   MOV     M,A;       STORE FIRST WORD
  18.  STR1:  INR     L;       TO ADDRESS SECOND WORD
  19.         MOV     M,B;       STORE SECOND WORD
  20.         INR     L;       TO ADDRESS THIRD WORD
  21.         MOV     M,C;       STORE THIRD WORD
  22.         INR     L;       TO ADDRESS FOURTH WORD
  23.         MOV     M,D;       STORE FOURTH WORD
  24.         RET     ;       RETURN TO CALLER
  25.  ;     FLOATING POINT ZERO SUBROUTINE ENT. PNT.
  26.  FZERO:    LXI    H,ACCE;    TO ADDRESS ACCUM EXPONENT
  27.         XRA     A;       ZERO
  28.         MOV     M,A;       CLEAR ACCUMULATOR EXPONENT
  29.         RET     ;       RETURN TO CALLER
  30.  ;     FLOATING POINT CHS SUBROUTINE ENT. PNT.
  31.  FCHS:   MVI     A,80H;  MASK FOR SIGN BIT
  32.         DB      00EH;  LBI INST TO SKIP NEXT WD
  33.  ;     FLOATING POINT ABS SUBROUTINE ENT. PNT.
  34.  FABS:   XRA     A;       ZERO
  35.         LXI     H,ACCS;  TO ADDRESS ACCUM SIGN
  36.         ANA     M       ;       COMPLEMENT OF SIGN
  37.         XRI     80H;  COMPLEMENT THE SIGN BIT
  38.         MOV     M,A;       ACCUMULATOR SIGN
  39.  ;     FLOATING POINT TEST ENTRY POINT.
  40.  FTEST: LXI    H,ACCE;  TO ADDR ACCUM EXPONENT
  41.         MOV     A,M;       ACCUMULATOR EXPONENT
  42.         ANA     A       ;       SET CONTROL BITS
  43.         JZ      FZERO;   IF ACCUMULATOR IS ZERO
  44.         MOV     E,A;       ACCUMULATOR EXPONENT
  45.         INR     L;       TO ADDR ACCUMULATOR SIGN
  46.         MOV     A,M;       ACCUMULATOR SIGN
  47.         INR     L;       TO ADDR ACCUM 1ST FRCTN
  48.         XRA     M;       ACCUM SIGN AND 1ST FRCTN
  49.         INR     L;       TO ADDR ACCUM 2ND FRCTN
  50.         MOV     C,M;       ACCUMULATOR 2ND FRACTION
  51.         INR     L;       TO ADDR ACCUM 3RD FRCTN
  52.         MOV     D,M;       ACCUMULATOR 3RD FRCTN
  53.         JMP     ADD12; TO SET EXIT CONDITIONS
  54.  ;     FLOATING POINT LOAD ENTRY POINT.
  55.  FLOAD:   MOV     A,M;       OPERAND EXPONENT
  56.         ANA     A       ;       SET CONTROL BITS
  57.         JZ      FZERO;   IF OPERAND IS ZERO
  58.         MOV     E,A;       OPERAND EXPONENT
  59.         INR     L;       TO ADDR OP SIGN AND 1ST
  60.         MOV     A,M;       OPERAND SIGN AND 1ST FRCTN
  61.         INR     L;       TO ADDRESS OPERAND 2ND FRACTION
  62.         MOV     C,M;       OPERAND 2ND FRACTION
  63.         INR     L;       TO ADDRESS OPERAND 3RD FRACTION
  64.         MOV     D,M;       OPERAND 3RD FRACTION
  65.  ;     STORE THE OPERAND IN THE ACCUMULATOR.
  66.         MOV     L,A;       OPERAND SIGN AND 1ST FRCTN
  67.  FLOAD1:  ORI     80H;  ACCUMULATOR 1ST FRACTION
  68.         MOV     B,A;       ACCUMULATOR 1ST FRACTION
  69.         XRA     L;       ACCUMULATOR SIGN
  70.         LXI     H,ACCE;  TO ADDR ACCUM EXPONENT
  71.         CALL    FSTR0;  SET THE ACCUMULATOR
  72.         XRA     B;       ACCUM SIGN AND 1ST FRCTN
  73.  ;     SET CONTROL BITS AND EXIT
  74.         MOV     B,A;       ACCUM SIGN AND 1ST FRACTION
  75.         ORI     1;     SET SIGN BIT FOR EXIT
  76.         MOV     A,E;       ACCUMULATOR EXPONENT
  77.         RET     ;       RETURN TO CALLER
  78.  ;     FLOATING POINT MUL SUBROUTINE ENT. PNT.
  79.  FMUL:   MOV     A,M;       OPERAND EXPONENT
  80.         ANA     A       ;       SET CONTROL BITS
  81.         CNZ     MDEX;  READ OPERAND IF NOT ZERO
  82.         JZ      FZERO;   IF ZERO OR UNDERFLOW
  83.         JC      OVERF; IF OVERFLOW
  84.         CALL    MULX;  CALL FIXED MULT SUBRTN
  85.  ;     NORMALIZE IF NECESSARY.
  86.         MOV     A,B;       1ST PRODUCT
  87.         ANA     A       ;       SET CONTROL BITS
  88.         JM      RNDA;  IF NO NORMALIZATION REQUIRED
  89.         LXI     H,ACCE;  TO ADDR ACCUM EXPONENT
  90.         MOV     A,M;       ACCUMULATOR EXPONENT
  91.         SBI     1;     DECREMENT ACCUMULATOR EXPONENT
  92.         MOV     M,A;       ACCUMULATOR EXPONENT
  93.         RZ      ;       RETURN TO CALLER IF UNDERFLOW
  94.         CALL    LSH;   CALL LEFT SHIFT SUBROUTINE
  95.  ;     ROUND IF NECESSARY.
  96.  RNDA:  CALL    ROND;  CALL ROUNDING SUBROUTINE
  97.         JC      OVERF; IF OVERFLOW
  98.         MOV     B,A;       ACCUM SIGN AND 1ST FRACTION
  99.         ORI     1;     SET SIGN BIT
  100.         MOV     A,E;       ACCUMULATOR EXPONENT
  101.         RET     ;       RETURN TO CALLER
  102.  ;     FLOATING POINT DIV SUBROUTINE ENT. PNT.
  103.  FDIV:   XRA     A;       ZERO
  104.         SUB     M;       COMPLEMENT OF DIVISOR EXPONENT
  105.         CPI     1;     SET CARRY IF DIVISION BY ZERO
  106.         CNC     MDEX;  READ OPERAND IF NOT ZERO
  107.         JC      OVERF; IF OVERFLOW OR DIVISION BY ZERO
  108.         JZ      FZERO;  IF UNDERFLOW OR ZERO
  109.         MOV     C,A;       DIVISOR 1ST FRACTION
  110.         CALL    DIVX;  CALL FIXED DIV SUBRTN
  111.         JC      RNDA;  IF NO OVERFLOW
  112.  ;     SET OVERFLOW FLAG.
  113.  OVERF:    LXI    H,OVER;    TO ADDR OVERFLOW FLAG
  114.         MVI     A,0FFH;  OVERFLOW FLAG
  115.         MOV     M,A;       OVERFLOW FLAG
  116.         RLC     ;       SET CARRY BIT FOR EXIT
  117.         RET     ;       RETURN TO CALLER
  118.         DB      0;     CHECK SUM WORD
  119.  ;     FLOATING POINT SUB SUBROUTINE ENT. PNT.
  120.  FSUB:    MVI     A,80H;  MASK TO CHANGE OP SIGN
  121.         DB      0EH;  LBI INST TO SKIP NEXT WD
  122.  ;     FLOATING POINT ADD SUBROUTINE ENT. PNT.
  123.  FADD:    XRA     A;       ZERO
  124.  ;     LOAD THE OPERAND.
  125.         MOV     E,M;       OPERAND EXPONENT
  126.         INR     L;       TO ADDR OP SIGN, 1ST FRCTN
  127.         XRA     M;       OPERAND SIGN AND 1ST FRCTN
  128.         MOV     B,A;       OPERAND SIGN AND 1ST FRCTN
  129.         INR     L;       TO ADDR OPERAND 2ND
  130.         MOV     C,M;       OPERAND 2ND FRACTION
  131.         INR     L;       TO ADDR OPERAND 3RD FRCTN
  132.         MOV     D,M;       OPERAND 3RD FRACTION
  133.  ;     SAVE INITIAL EXPONENT.
  134.     LXI    H,ACCE;    TO ADDR ACCUM EXPONENT
  135.         MOV     A,M;       ACCUMULATOR EXPONENT
  136.         DCR     L;       TO ADDR INITIAL EXPONENT
  137.         MOV     M,A;       INITIAL EXPONENT
  138.  ;     CHECK FOR ZERO OPERAND.
  139.         MOV     A,E;       OPERAND EXPONENT
  140.         ANA     A       ;       SET CONTROL BITS
  141.         JZ      FTEST;  IF OPERAND IS ZERO
  142.  ;     GENERATE SUBTRACTION FLAG, RESTORE
  143.  ;     SUPPRESSED FRACTION BIT.
  144.         MOV     L,B;       OPERAND SIGN AND 1ST FRCTN
  145.         MOV     A,B;       OPERAND SIGN AND 1ST FRACTION
  146.         ORI     80H;  OPERAND 1ST FRACTION
  147.         MOV     B,A;       OPERAND 1ST FRACTION
  148.         XRA     L;       OPERAND SIGN
  149.         MVI     L,LOW(ACCS);  TO ADDRESS ACCUMULATOR SIGN
  150.         XRA     M;       SUBTRACTION FLAG
  151.         MVI     L,LOW(SF);    TO ADDRESS SUBTRACTION FLAG
  152.         MOV     M,A;       SUBTRACTION FLAG
  153.  ;     DETERMINE RELATIVE MAGNITUDES OF
  154.  ;     OPERAND AND ACCUMULATOR.
  155.         MVI     L,LOW(ACCE);  TO ADDRESS ACCUMULATOR EXPONENT
  156.         MOV     A,M;       ACCUMULATOR EXPONENT
  157.         ANA     A       ;       SET CONTROL BITS
  158.         JZ      ADD17; IF ACCUMULATOR IS ZERO
  159.         SUB     E;       DIFFERENCE IN EXPONENTS
  160.         JC      ADD2;  IF ACCUM SMALLER THAN OP
  161.  ;     CHECK FOR INSIGNIFICANT OPERAND.
  162.         JM      FTEST;  IF THE OPERAND IS INSIGNIFICANT
  163.         CPI     25;  COMPARE SHIFT COUNT TO 25
  164.         JC      ADD3;  JOIN EXCH PATH IF OP SIGNIF
  165.         JMP     FTEST;  OPERAND IS INSIGNIFICANT
  166.  ;     CHECK FOR INSIGNIFICANT ACCUMULATOR
  167.  ADD2:  JP      ADD17; IF ACCUM IS INSIGNIFICANT
  168.         CPI     0E7H;  COMPARE SHIFT COUNT TO MINUS 25
  169.         JC      ADD17; IF ACCUM IS INSIGNIFICANT
  170.         MOV     M,E;       OPERAND EXPONENT
  171.         MOV     E,A;       SHIFT COUNT
  172.         LXI     H,SF;    TO ADDRESS THE SUBTRACTION FLAG
  173.         MOV     A,M;       SUBTRACTION FLAG
  174.         MVI     L,LOW(ACCS);  TO ADDRESS THE ACCUMULATOR SIGN
  175.         XRA     M;       OPERAND SIGN
  176.         MOV     M,A;       ACCUMULATOR SIGN
  177.         XRA     A;       ZERO
  178.         SUB     E;       COMPLEMENT SHIFT COUNT
  179.  ;     EXCHANGE ACCUMULATOR AND OPERAND.
  180.         INR     L;       TO ADDR ACCUM 1ST FRACTION
  181.         MOV     E,M;       ACCUMULATOR 1ST FRACTION
  182.         MOV     M,B;       OPERAND 1ST FRACTION
  183.         MOV     B,E;       ACCUMULATOR 1ST FRACTION
  184.         INR     L;       TO ADDR ACCUM 2ND FRACTION
  185.         MOV     E,M;       ACCUMULATOR 2ND FRACTION
  186.         MOV     M,C;       OPERAND 2ND FRACTION
  187.         MOV     C,E;       ACCUMULATOR 2ND FRACTION
  188.         INR     L;       TO ADDR ACCUM 3RD FRACTION
  189.         MOV     E,M;       ACCUMULATOR 3RD FRACTION
  190.         MOV     M,D;       OPERAND 3RD FRACTION
  191.         MOV     D,E;       ACCUMULATOR 3RD FRACTION
  192.  ;     POSITION THE OPERAND.
  193.  ADD3:  CALL    RSH;   POSITION THE OPERAND
  194.         LXI     H,SF;    TO ADDRESS SUBTRACTION FLAG
  195.         MOV     A,M;       SUBTRACTION FLAG
  196.         ANA     A       ;       SET CONTROL BITS
  197.         MVI     L,LOW(ACC3);  TO ADDR ACCUM 3RD FRCTN
  198.         JM      ADD9;  IF SUBTRACTION REQUIRED
  199.  ;     ADD ADDEND TO AUGEND.
  200.         MOV     A,M;       AUGEND 3RD FRACTION
  201.         ADD     D;       ADDEND 3RD FRACTION
  202.         MOV     D,A;       SUM 3RD FRACTION
  203.         DCR     L;       TO ADDRESS AUGEND 2ND FRACTION
  204.         MOV     A,M;       AUGEND 2ND FRACTION
  205.         ADC     C;       ADDEND 2ND FRACTION
  206.         MOV     C,A;       SUM 2ND FRACTION
  207.         DCR     L;       TO ADDRESS AUGEND 1ST FRACTION
  208.         MOV     A,M;       AUGEND 1ST FRACTION
  209.         ADC     B;       ADDEND 1ST FRACTION
  210.         MOV     B,A;       SUM 1ST FRACTION
  211.         JNC     ADD11; IF NO CARRY FROM 1ST FRCTN
  212.  ;     RIGHT SHIFT SUM TO NORMALIZED POSITION.
  213.         RAR     ;       RIGHT SHIFT SUM 1ST FRACTION
  214.         MOV     B,A;       SUM 1ST FRACTION
  215.         MOV     A,C;       SUM 2ND FRACTION
  216.         RAR     ;       RIGHT SHIFT SUM 2ND FRACTION
  217.         MOV     C,A;       SUM 2ND FRACTION
  218.         MOV     A,D;       SUM 3RD FRACTION
  219.         RAR     ;       RIGHT SHIFT SUM 3RD FRACTION
  220.         MOV     D,A;       SUM 3RD FRACTION
  221.         RAR     ;       4TH FRCTN = LOW BIT OF 3RD
  222.         MOV     E,A;       SUM 4TH FRACTION
  223.         MVI     L,LOW(ACCE);  TO ADDRESS ACCUMULATOR EXPONENT
  224.         MOV     A,M;       ACCUMULATOR EXPONENT
  225.         ADI     1;     INCREMENT ACCUMULATOR EXPONENT
  226.         JC      OVERF; IF OVERFLOW
  227.         MOV     M,A;       ACCUMULATOR EXPONENT
  228.         JMP     ADD11; TO ROUND FRACTION
  229.  ;     SUBTRACT SUBTRAHEND FROM MINUEND.
  230.  ADD9:  XRA     A;       MINUEND 4TH FRCTN IS ZERO
  231.         SUB     E;       SUBTRAHEND 4TH FRACTION
  232.         MOV     E,A;       DIFFERENCE 4TH FRACTION
  233.         MOV     A,M;       MINUEND 3RD FRACTION
  234.         SBB     D;       SUBTRAHEND 3RD FRACTION
  235.         MOV     D,A;       DIFFERENCE 3RD FRACTION
  236.         DCR     L;       TO ADDRESS MINUEND 2ND FRACTION
  237.         MOV     A,M;       MINUEND 2ND FRACTION
  238.         SBB     C;       SUBTRAHEND 2ND FRACTION
  239.         MOV     C,A;       DIFFERENCE 2ND FRACTION
  240.         DCR     L;       TO ADDRESS MINUEND 1ST FRACTION
  241.         MOV     A,M;       MINUEND 1ST FRACTION
  242.         SBB     B;       SUBTRAHEND 1ST FRACTION
  243.         MOV     B,A;       DIFFERENCE 1ST FRACTION
  244.  ADD10: CC      FCOMP;  COMPLEMENT IF NEGATIVE
  245.         CP      NORM;  NORMALIZE IF NECESSARY
  246.         JP      FZERO;  IF UNDERFLOW OR ZERO
  247.  ADD11: CALL    ROND;  CALL ROUNDING SUBROUTINE
  248.         JC      OVERF; IF OVERFLOW
  249.  ADD12: MOV     B,A;       ACCUM SIGN AND 1ST FRCTN
  250.         LXI     H,PREX;  TO ADDRESS PREV EXPONENT
  251.         MOV     A,E;       ACCUMULATOR EXPONENT
  252.         SUB     M;       DIFFERENCE IN EXPONENTS
  253.         MOV     L,A;       DIFFERENCE IN EXPONENTS
  254.         MOV     A,B;       ACCUM SIGN AND 1ST FRCTN
  255.         ORI     1;     SET SIGN BIT FOR EXIT
  256.         MOV     A,E;       ACCUMULATOR EXPONENT
  257.         MOV     E,L;       SIGNIFICANCE INDEX
  258.         RET     ;       RETURN TO CALLER
  259.  ;     LOAD THE ACCUMULATOR WITH THE OPERAND.
  260.  ADD17: LXI     H,SF;    TO ADDR SUBTRACTION FLAG
  261.         MOV     A,M;       SUBTRACTION FLAG
  262.         MVI     L,LOW(ACCS);  TO ADDR ACCUMULATOR SIGN
  263.         XRA     M;       OPERAND SIGN
  264.         DCR     L;       TO ADDR ACCUM EXPONENT
  265.         CALL    FSTR0;  SET THE ACCUMULATOR
  266.         XRA     B;       ACCUM SIGN AND 1ST FRCTN
  267.         JMP     ADD12; JOIN EXIT CODE
  268.         DB      0;     CHECK SUM WORD
  269.  ;     SUBROUTINE TO READ THE OPERAND AND
  270.  ;     CHECK THE ACCUMULATOR EXPONENT.
  271.  MDEX:  MOV     B,A;       EXPONENT MODIFIER
  272.         INR     L;       TO ADDR OP SIGN, 1ST FRCTN
  273.         MOV     C,M;       OPERAND SIGN AND 1ST FRACTION
  274.         INR     L;       TO ADDRESS OPERAND 2ND FRACTION
  275.         MOV     D,M;       OPERAND 2ND FRACTION
  276.         INR     L;       TO ADDRESS OPERAND 3RD FRACTION
  277.         MOV     E,M;       OPERAND 3RD FRACTION
  278.         LXI     H,ACCE;  TO ADDRESS ACCUMULATOR EXPONENT
  279.         MOV     A,M;       ACCUMULATOR EXPONENT
  280.         ANA     A       ;       SET CONTROL BITS
  281.         RZ      ;       RETURN IF ACCUM IS ZERO
  282.         ADD     B;       RESULT EXPONENT PLUS BIAS
  283.         MOV     B,A;       RESULT EXPONENT PLUS BIAS
  284.         RAR     ;       CARRY TO SIGN
  285.         XRA     B;       CARRY AND SIGN MUST DIFFER
  286.         MOV     A,B;       RESULT EXPONENT PLUS BIAS
  287.         MVI     B,80H;  EXP BIAS, SIGN MASK, MS BIT
  288.         JP      OVUN;  IF OVERFLOW OR UNDERFLOW
  289.         SUB     B;       REMOVE EXCESS EXP BIAS
  290.         RZ      ;       RETURN IF UNDERFLOW
  291.         MOV     M,A;       RESULT EXPONENT
  292.         INR     L;       TO ADDRESS ACCUMULATOR SIGN
  293.         MOV     A,M;       ACCUMULATOR SIGN
  294.         XRA     C;       RESULT SIGN IN SIGN BIT
  295.         ANA     B       ;       RESULT SIGN
  296.         MOV     M,A;       RESULT SIGN
  297.         MOV     A,C;       OPERAND SIGN AND 1ST FRCTN
  298.         ORA     B;       OPERAND 1ST FRACTION
  299.         RET     ;       RETURN TO CALLER
  300.  OVUN:  RLC     ;       SET CARRY BIT IF OVERFLOW
  301.         RC      ;       RETURN IF OVERFLOW
  302.         XRA     A;       ZERO
  303.         RET     ;       RETURN IF UNDERFLOW
  304.  ;     SUBROUTINE TO LEFT SHIFT THE B, C,
  305.  ;     D, AND E REGISTERS ONE BIT.
  306.  LSH:   MOV     A,E;       ORIGINAL CONTENTS OF E
  307.         RAL     ;       LEFT SHIFT E
  308.         MOV     E,A;       RESTORE CONTENTS OF E REGISTER
  309.  LSH1:  MOV     A,D;       ORIGINAL CONTENTS OF D REGISTER
  310.         RAL     ;       LEFT SHIFT D
  311.         MOV     D,A;       RESTORE CONTENTS OF D REGISTER
  312.         MOV     A,C;       ORIGINAL CONTENTS OF C REGISTER
  313.         RAL     ;       LEFT SHIFT C
  314.         MOV     C,A;       RESTORE CONTENTS OF C REGISTER
  315.         MOV     A,B;       ORIGINAL CONTENTS OF B REGISTER
  316.         ADC     A;       LEFT SHIFT B
  317.         MOV     B,A;       RESTORE CONTENTS OF B REGISTER
  318.         RET     ;       RETURN TO CALLER
  319.  ;     RIGHT SHIFT THE B, C, D AND E REGISTERS
  320.  ;     BY THE SHIFT COUNT IN THE A REGISTER
  321.  ;     SHIFT OPERAND TO REGISTER INDICATED BY
  322.  ;     SHIFT COUNT
  323.  RSH:   MVI     E,0;     OPERAND 4TH FRCTN IS ZERO
  324.  RSH0:  MVI     L,8;  EACH REG IS 8 BITS OF SHIFT
  325.  RSH1:  CMP     L;       COMPARE SHIFT COUNT TO 8
  326.         JM      RSH2;  IF REQ SHIFT LESS THAN 8
  327.         MOV     E,D;       OPERAND 4TH FRACTION
  328.         MOV     D,C;       OPERAND 3RD FRACTION
  329.         MOV     C,B;       OPERAND 2ND FRACTION
  330.         MVI     B,0;     OPERAND 1ST FRACTION IS ZERO
  331.         SUB     L;       REDUCE SHIFT COUNT BY 1 REG
  332.         JNZ     RSH1;  IF MORE SHIFTS REQUIRED
  333.  ;     SHIFT OPERAND RIGHT BY -SHIFT COUNT-
  334.  ;     BITS.
  335.  RSH2:  ANA     A       ;       SET CONTROL BITS
  336.         RZ      ;       RETURN IF SHIFT COMPLETE
  337.         MOV     L,A;       SHIFT COUNT
  338.  RSH3:  ANA     A       ;       CLEAR CARRY BIT
  339.         MOV     A,B;       OPERAND 1ST FRACTION
  340.         RAR     ;       RIGHT SHIFT OP 1ST FRCTN
  341.         MOV     B,A;       OPERAND 1ST FRACTION
  342.         MOV     A,C;       OPERAND 2ND FRACTION
  343.         RAR     ;       RIGHT SHIFT OP 2ND FRCTN
  344.         MOV     C,A;       OPERAND 2ND FRACTION
  345.         MOV     A,D;       OPERAND 3RD FRACTION
  346.         RAR     ;       RIGHT SHIFT OP 3RD FRCTN
  347.         MOV     D,A;       OPERAND 3RD FRACTION
  348.         MOV     A,E;       OPERAND 4TH FRACTION
  349.         RAR     ;       RIGHT SHIFT OP 4TH FRCTN
  350.         MOV     E,A;       OPERAND 4TH FRACTION
  351.         DCR     L;       DECREMENT SHIFT COUNT
  352.         JNZ     RSH3;  IF MORE SHIFTS REQUIRED
  353.         RET     ;       RETURN TO CALLER
  354.  ;     COMPLEMENT THE B, C, D, AND E REGISTERS.
  355.  FCOMP:  DCR     L;       TO ADDR ACCUM SIGN
  356.         MOV     A,M;       ACCUMULATOR SIGN
  357.         XRI     80H;  CHANGE SIGN
  358.         MOV     M,A;       ACCUMULATOR SIGN
  359.  COMP1: XRA     A;       ZERO
  360.         MOV     L,A;       ZERO
  361.         SUB     E;       COMPLEMENT 4TH FRCTN
  362.         MOV     E,A;       4TH FRACTION
  363.         MOV     A,L;       ZERO
  364.         SBB     D;       COMPLEMENT 3RD FRCTN
  365.         MOV     D,A;       3RD FRACTION
  366.         MOV     A,L;       ZERO
  367.         SBB     C;       COMPLEMENT 2ND FRCTN
  368.         MOV     C,A;       2ND FRACTION
  369.         MOV     A,L;       ZERO
  370.         SBB     B;       COMPLEMENT 1ST FRCTN
  371.         MOV     B,A;       1ST FRACTION
  372.         RET     ;       RETURN TO CALLER
  373.  ;     NORMALIZE THE REGISTERS.
  374.  NORM:  MVI     L,20H;  MAX NORMALIZING SHIFT
  375.  NORM1: MOV     A,B;       1ST FRACTION
  376.         ANA     A       ;       SET CONTROL BITS
  377.         JNZ     NORM3; IF 1ST FRACTION NONZERO
  378.         MOV     B,C;       1ST FRACTION
  379.         MOV     C,D;       2ND FRACTION
  380.         MOV     D,E;       3RD FRACTION
  381.         MOV     E,A;       ZERO 4TH FRACTION
  382.         MOV     A,L;       NORMALIZING SHIFT COUNT
  383.         SUI     8;  REDUCE SHIFT COUNT
  384.         MOV     L,A;       NORMALIZING SHIFT COUNT
  385.         JNZ     NORM1; IF FRACTION NONZERO
  386.         RET     ;       IF FRACTION IS ZERO
  387.  NORM2: DCR     L;       DECREMENT SHIFT COUNT
  388.         MOV     A,E;       ORIGINAL CONTENTS OF E
  389.         RAL     ;       LEFT SHIFT E
  390.         MOV     E,A;       RESTORE CONTENTS OF E REGISTER
  391.         MOV     A,D;       ORIGINAL CONTENTS OF D REGISTER
  392.         RAL     ;       LEFT SHIFT D
  393.         MOV     D,A;       RESTORE CONTENTS OF D REGISTER
  394.         MOV     A,C;       ORIGINAL CONTENTS OF C REGISTER
  395.         RAL     ;       LEFT SHIFT C
  396.         MOV     C,A;       RESTORE CONTENTS OF C REGISTER
  397.         MOV     A,B;       ORIGINAL CONTENTS OF B REGISTER
  398.         ADC     A;       LEFT SHIFT B
  399.         MOV     B,A;       RESTORE CONTENTS OF B REGISTER
  400.  NORM3: JP      NORM2; IF NOT NORMALIZED
  401.         MOV     A,L;       NORMALIZING SHIFT COUNT
  402.         SUI     20H;  REMOVE BIAS
  403.         LXI     H,ACCE;  TO ADDR ACCUM EXPONENT
  404.         ADD     M;       ADJUST ACCUM EXPONENT
  405.         MOV     M,A;       NEW ACCUM EXPONENT
  406.         RZ      ;       RETURN IF ZERO EXP
  407.         RAR     ;       BORROW BIT TO SIGN
  408.         ANA     A       ;       SET SIGN TO IND. UNDERFLOW
  409.         RET     ;       RETURN TO CALLER
  410.  ;     SUBROUTINE TO ROUND THE B, C, D REGISTERS.
  411.  ROND:  LXI     H,ACCE;  TO ADDR ACCUM EXPONENT
  412.         MOV     A,E;       4TH FRACTION
  413.         ANA     A       ;       SET CONTROL BITS
  414.         MOV     E,M;       ACCUMULATOR EXPONENT
  415.         CM      RNDR;  CALL 2ND LEVEL ROUNDER
  416.         RC      ;       IF OVERFLOW
  417.         MOV     A,B;       1ST FRACTION
  418.         INR     L;       TO ADDR ACCUM SIGN
  419.         XRA     M;       ACCUM SIGN AND 1ST FRCTN
  420.         JMP     STR1;  RETURN THRU STORE SUBR.
  421.  ;     SECOND LEVEL ROUNDING SUBROUTINE.
  422.  RNDR:  INR     D;       ROUND 3RD FRACTION
  423.         RNZ     ;       RETURN IF NO CARRY
  424.         INR     C;       CARRY TO 2ND FRACTION
  425.         RNZ     ;       RETURN IF NO CARRY
  426.         INR     B;       CARRY TO 1ST FRACTION
  427.         RNZ     ;       RETURN IF NO CARRY
  428.         MOV     A,E;       ACCUMULATOR EXPONENT
  429.         ADI     1;     INCREMENT ACCUM EXPONENT
  430.         MOV     E,A;       NEW ACCUM EXPONENT
  431.         MVI     B,80H;  NEW 1ST FRACTION
  432.         MOV     M,A;       NEW ACCUM EXPONENT
  433.         RET     ;       RETURN TO ROND SUBROUTINE
  434.  ;     FIXED POINT MULTIPLY SUBROUTINE.
  435.  MULX:  LXI     H,MULP1+1; TO ADDR 1ST MULTIPLICAND
  436.         MOV     M,A;       1ST MULTIPLICAND
  437.         LXI     H,MULP2+1; TO ADDR 2ND MULTIPLICAND
  438.         MOV     M,D;       2ND MULTIPLICAND
  439.         LXI     H,MULP3+1; TO ADDR 3RD MULTIPLICAND
  440.         MOV     M,E;       3RD MULTIPLICAND
  441.         XRA     A;       CLEAR 6TH PRODUCT
  442.         MOV     E,A;       CLEAR 5TH PRODUCT
  443.         MOV     D,A;       CLEAR 4TH PRODUCT
  444.  ;     MULTIPLY BY EACH ACCUMULATOR
  445.  ;     FRACTION IN TURN.
  446.         LXI     H,ACC3;  TO ADDRESS 3RD FRCTN
  447.         CALL    MULX2; MULTIPLY BY ACCUM 3RD FRCTN
  448.         MVI     L,LOW(ACC2);  TO ADDRESS 2ND FRCTN
  449.         CALL    MULX1; MULTIPLY BY ACCUM 2ND FRCTN
  450.         MVI     L,LOW(ACC1);  TO ADDRESS 1ST FRCTN
  451.  ;     MULTIPLY BY ONE ACCUMULATOR WORD.
  452.  MULX1: MOV     A,D;       5TH PARTIAL PRODUCT
  453.         MOV     E,C;       4TH PARTIAL PRODUCT
  454.         MOV     D,B;       3RD PARTIAL PRODUCT
  455.  MULX2: MOV     B,M;       MULTIPLIER
  456.         MOV     L,A;       5TH PARTIAL PRODUCT
  457.         XRA     A;       ZERO
  458.         MOV     C,A;       2ND PARTIAL PRODUCT
  459.         SUB     B;       SET CARRY BIT FOR EXIT FLAG
  460.         JC      MULX3; IF MULTIPLIER IS NOT ZERO
  461.         MOV     C,D;       2ND PARTIAL PRODUCT
  462.         MOV     D,E;       3RD PARTIAL PRODUCT
  463.         RET     ;       MULT BY ZERO COMPLETE
  464.  ;     COMPLETE ADDITION OF MULTIPLICAND.
  465.  MULX5: MOV     C,A;       2ND PARTIAL PRODUCT
  466.         JNC     MULX3; IF NO CARRY TO 1ST PRODUCT
  467.         INR     B;       ADD CARRY TO 1ST PRODUCT
  468.         ANA     A       ;       CLEAR CARRY BIT
  469.  ;     LOOP FOR EACH BIT OF MULTIPLIER WORD.
  470.  MULX3: MOV     A,L;       5TH PART PRODUCT, EXIT FLAG
  471.         ADC     A;       SHIFT EXIT FLAG OUT IF DONE
  472.         RZ      ;       EXIT IF MULTIPLICATION DONE
  473.         MOV     L,A;       5TH PART PRODUCT, EXIT FLAG
  474.         MOV     A,E;       4TH PARTIAL PRODUCT
  475.         RAL     ;       SHIFT 4TH PARTIAL PRODUCT
  476.         MOV     E,A;       4TH PARTIAL PRODUCT
  477.         MOV     A,D;       3RD PARTIAL PRODUCT
  478.         RAL     ;       SHIFT 3RD PARTIAL PRODUCT
  479.         MOV     D,A;       3RD PARTIAL PRODUCT
  480.         MOV     A,C;       2ND PARTIAL PRODUCT
  481.         RAL     ;       SHIFT 2ND PARTIAL PRODUCT
  482.         MOV     C,A;       2ND PARTIAL PRODUCT
  483.         MOV     A,B;       1ST PART PROD AND MULTPLIER
  484.         RAL     ;       SHIFT 1ST PROD AND MULTIPLIER
  485.         MOV     B,A;       1ST PART PROD AND MULTIPLIER
  486.         JNC     MULX3; IF NO ADDITION REQUIRED
  487.  ;     ADD THE MULTIPLICAND TO THE PRODUCT
  488.  ;     IF THE MULTIPLIER BIT IS ONE.
  489.         MOV     A,E;       4TH PARTIAL PRODUCT
  490.  
  491. ;  THE FOLLOWING CODE WAS MOVED FROM THE BEGINNING
  492. ;  OF THE PROGRAM TO THIS LOCATION TO MAKE THINGS
  493. ;  A LITTLE EASIER...
  494.  
  495. MULX4:
  496. MULP3:
  497.     ADI    0;    ADD OPERAND 3RD FRACTION
  498.     MOV    E,A;    4TH PARTIAL PRODUCT
  499.     MOV    A,D;    3RD PARTIAL PRODUCT
  500. MULP2:
  501.     ACI    0;    ADD OPERAND 2ND FRACTION
  502.     MOV    D,A;    3RD PARTIAL PRODUCT
  503.     MOV    A,C;    2ND PARTIAL PRODUCT
  504. MULP1:
  505.     ACI    0;    ADD OPERAND 1ST FRACTION
  506.  
  507.     JMP    MULX5
  508.  ;     FIXED POINT DIVIDE SUBROUTINE.
  509.  ;     SUBTRACT DIVISOR FROM ACCUMULATOR TO
  510.  ;     OBTAIN 1ST REMAINDER.
  511.  DIVX:  LXI     H,ACC3;  TO ADDRESS ACCUM 3RD FRCTN
  512.         MOV     A,M;       ACCUMULATOR 3RD FRACTION
  513.         SUB     E;       DIVISOR 3RD FRACTION
  514.         MOV     M,A;       REMAINDER 3RD FRACTION
  515.         DCR     L;       TO ADDRESS ACCUM 2ND FRCTN
  516.         MOV     A,M;       ACCUMULATOR 2ND FRACTION
  517.         SBB     D;       DIVISOR 2ND FRACTION
  518.         MOV     M,A;       REMAINDER 2ND FRACTION
  519.         DCR     L;       TO ADDRESS ACCUM 1ST FRCTN
  520.         MOV     A,M;       ACCUMULATOR 1ST FRACTION
  521.         SBB     C;       DIVISOR 1ST FRACTION
  522.         MOV     M,A;       REMAINDER 1ST FRACTION
  523.  ;     HALVE THE DIVISOR AND STORE FOR
  524.  ;     ADDITION OR SUBTRACTION.
  525.         MOV     A,C;       DIVISOR 1ST FRACTION
  526.         RAL     ;       SET CARRY BIT
  527.         MOV     A,C;       DIVISOR 1ST FRACTION
  528.         RAR     ;       HALF OF DIVISOR 1ST FRCTN
  529.  ;               + 80H TO CORRECT QUOTIENT
  530.         LXI     H,OP1S+1;  TO ADDRESS 1ST SUBTRACT DIVISOR
  531.         MOV     M,A;       1ST SUBTRACT DIVISOR
  532.         LXI     H,OP1A+1;  TO ADDRESS 1ST ADD DIVISOR
  533.         MOV     M,A;       1ST ADD DIVISOR
  534.         MOV     A,D;       DIVISOR 2ND FRACTION
  535.         RAR     ;       HALF OF DIVISOR 2ND FRACTION
  536.         LXI     H,OP2S+1;  TO ADDRESS 2ND SUBTRACT DIVISOR
  537.         MOV     M,A;       2ND SUBTRACT DIVISOR
  538.         LXI     H,OP2A+1;  TO ADDRESS 2ND ADD DIVISOR
  539.         MOV     M,A;       2ND ADD DIVISOR
  540.         MOV     A,E;       DIVISOR 3RD FRACTION
  541.         RAR     ;       HALF OF DIVISOR 3RD FRACTION
  542.         LXI     H,OP3S+1;  TO ADDRESS 3RD SUBTRACT DIVISOR
  543.         MOV     M,A;       3RD SUBTRACT DIVISOR
  544.         LXI     H,OP3A+1;  TO ADDRESS 3RD ADD DIVISOR
  545.         MOV     M,A;       3RD ADD DIVISOR
  546.         MVI     B,0;     INIT QUOTIENT 1ST FRCTN
  547.         MOV     A,B;       DIVISOR FOURTH FRACTION IS ZERO
  548.         RAR     ;       LOW BIT OF DIVISOR 3RD FRACTION
  549.         LXI     H,OP4S+1;  TO ADDRESS 4TH SUBTRACT DIVISOR
  550.         MOV     M,A;       4TH SUBTRACT DIVISOR
  551.         LXI     H,OP4A+1;  TO ADDRESS 4TH ADD DIVISOR
  552.         MOV     M,A;       4TH ADD DIVISOR
  553.         LXI     H,OP4X+1;  TO ADDRESS 4TH ADD DIVISOR
  554.         MOV     M,A;       4TH ADD DIVISOR
  555.  ;     LOAD 1ST REMAINDER, CHECK SIGN.
  556.         LXI     H,ACC1;  TO ADDR REMAINDER 1ST FRCTN
  557.         MOV     A,M;       REMAINDER 1ST FRACTION
  558.         INR     L;       TO ADDR REMAINDER 2ND FRCTN
  559.         MOV     D,M;       REMAINDER 2ND FRACTION
  560.         INR     L;       TO ADDR REMAINDER 3RD FRCTN
  561.         MOV     E,M;       REMAINDER 3RD FRACTION
  562.         ANA     A       ;       SET CONTROL BITS
  563.         JM      DIVX4; IF REMAINDER IS NEGATIVE
  564.  ;     ADJUST EXPONENT,POSITION REMAINDER
  565.  ;     AND INITIALIZE THE QUOTIENT.
  566.         MVI     L,LOW(ACCE);  TO ADDRESS ACCUMULATOR EXPONENT
  567.         MOV     C,M;       QUOTIENT EXPONENT
  568.         INR     C;       INCREMENT QUOTIENT EXPONENT
  569.         RZ      ;       RETURN IF OVERFLOW
  570.         MOV     M,C;       QUOTIENT EXPONENT
  571.         MOV     L,E;       REMAINDER 3RD FRACTION
  572.         MOV     H,D;       REMAINDER 2ND FRACTION
  573.         MOV     E,A;       REMAINDER 1ST FRACTION
  574.         MVI     D,1;     INITIALIZE QUOT 3RD FRCTN
  575.         MOV     C,B;       INITIALIZE QUOT 2ND FRCTN
  576.  ;     SUBTRACT THE DIVISOR FROM THE REMAINDER
  577.  ;     IF IT IS POSITIVE
  578.  DIVX1: XRA     A;       REMAINDER 4TH FRCTN IS ZERO
  579.         CALL    DIVX5;
  580.  DIVX2: RLC     ;       SHFT REM 4TH FRCTN TO CY
  581.  ;     SHIFT THE REMAINDER LEFT ONE BIT.
  582.         MOV     A,B;       QUOTIENT 1ST FRACTION
  583.         RAL     ;       MS BIT OF QUOTIENT TO CY
  584.         RC      ;       IF DIVISION COMPLETE
  585.         RAR     ;       REMAINDER 4TH FRCTN TO CY
  586.         MOV     A,L;       REMAINDER 3RD FRACTION
  587.         RAL     ;       LEFT SHIFT REM 3RD FRCTN
  588.         MOV     L,A;       REMAINDER 3RD FRACTION
  589.         MOV     A,H;       REMAINDER 2ND FRACTION
  590.         RAL     ;       LEFT SHIFT REM 2ND FRCTN
  591.         MOV     H,A;       REMAINDER 2ND FRACTION
  592.         CALL    LSH;   CALL LEFT SHIFT SUBROUTINE
  593.  ;     BRANCH IF SUBTRACTION IS REQUIRED
  594.         MOV     A,D;       QUOTIENT 3RD FRACTION
  595.         RRC     ;       REM SIGN INDIC TO CARRY BIT
  596.         JC      DIVX1; TO SUB DIVISOR IF REM POS
  597.  ;     ADD THE DIVISOR IF THE REMAINDER
  598.  ;     IS NEGATIVE.
  599.  DIVX3: MOV     A,L;       REMAINDER 3RD FRACTION
  600.         JMP     DIVX6;
  601.  ;     POSITION THE REMAINDER AND INITIALIZE
  602.  ;     THE QUOTIENT.
  603.  DIVX4: MOV     L,E;       REMAINDER 3RD FRACTION
  604.         MOV     H,D;       REMAINDER 2ND FRACTION
  605.         MOV     E,A;       REMAINDER 1ST FRACTION
  606.         MOV     D,B;       INITIALIZE QUOT 3RD FRCTN
  607.         MOV     C,B;       INITIALIZE QUOT 2ND FRCTN
  608.         JMP     DIVX3; ADD DIVISOR IF REM IS NEG
  609. ;  ORIGINALLY, THIS CODE WAS AT THE BEGINNING
  610. ;  OF THE PROGRAM...
  611.  
  612. DIVX5:
  613. OP4S:
  614.     SUI    0;    SUB DIVISOR 4TH FRACTION
  615.     MOV    A,L;    REM 3RD FRACTION
  616. OP3S:
  617.     SBI    0;    SUB DIVISOR 3RD FRACTION
  618.     MOV    L,A;    REM 3RD FRACTION
  619.     MOV    A,H;    REM 2ND FRACTION
  620. OP2S:
  621.     SBI    0;    SUB DIVISOR 2ND FRACTION
  622.     MOV    H,A;    REM 2ND FRACTION
  623.     MOV    A,E;    REM 1ST FRACTION
  624. OP1S:
  625.     SBI    0;    SUB DIVISOR 1ST FRACTION
  626.     MOV    E,A;    REM 1ST FRACTION
  627. OP4A:
  628.     MVI    A,0;    REM 4TH FRACTION
  629.     RET
  630.  
  631. DIVX6:
  632. OP3A:
  633.     ADI    0;    ADD DIVISOR 3RD FRACTION
  634.     MOV    L,A;    REM 3RD FRACTION
  635.     MOV    A,H;    REM 2ND FRACTION
  636. OP2A:
  637.     ACI    0;    ADD DIVISOR 2ND FRACTION
  638.     MOV    H,A;    REM 2ND FRACTION
  639.     MOV    A,E;    REM 1ST FRACTION
  640. OP1A:
  641.     ACI    0;    ADD DIVISOR 1ST FRACTION
  642.     MOV    E,A;    REM 1ST FRACTION
  643. OP4X:
  644.     MVI    A,0;    REM 4TH FRACTION
  645.  
  646.     JMP    DIVX2
  647.  
  648.         END     
  649.