home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 135_01 / math.csm < prev    next >
Text File  |  1985-03-10  |  21KB  |  1,458 lines

  1. ;
  2. ;    MATH.CSM---a high precision (2^2048) integer math package.
  3. ;    This version based on the package written by M. G. Dinneley,
  4. ;    published in the March 1977 issue of Dr Dobb's Journal.  It
  5. ;    has been adapted by Thomas Hill for m80 and CP/M.  Further
  6. ;    corrections, additions and adaptions for BDSc by Hugh S. Myers.
  7. ;
  8. ;    M. G. Dinneley
  9. ;    3/77
  10. ;
  11. ;    Thomas Hill
  12. ;    8/10/82
  13. ;
  14. ;    Hugh S. Myers
  15. ;    9/30/83
  16. ;    4/2/84
  17. ;
  18.  
  19.     INCLUDE    <BDS.LIB>
  20.  
  21. ;
  22. ; AD1---SIGNED ADDITION.
  23. ;
  24.     FUNCTION    AD1
  25.     EXTERNAL    GPAS1
  26.  
  27.     XRA    A    ;CLEAR CARRY
  28.     JMP    GPAS1
  29.  
  30.     ENDFUNC
  31. ;
  32. ; SB1---SIGNED SUBTRACTION.
  33. ;
  34.     FUNCTION    SB1
  35.     EXTERNAL    GPAS1
  36.  
  37.     STC        ;SET CARRY
  38.     JMP    GPAS1
  39.  
  40.     ENDFUNC
  41. ;
  42. ; GPAS1---GENERAL PURPOSE ADD & SUBTRACT (SIGNED).
  43. ;
  44.     FUNCTION    GPAS1
  45.     EXTERNAL    ADD1,SUB1
  46.  
  47.     PUSH    PSW    ;SAVE FLAGS
  48.     LDAX    D
  49.     XRA    M    ;DIFFERING SIGNS?
  50.     JM    GPAS3
  51.     POP    PSW    ;NO
  52.     JC    GPAS4    ;GO DO SUBTRACTION
  53. GPAS2:
  54.     CALL    ADD1    ;ELSE DO ADDITION.
  55.     RET
  56. GPAS3:
  57.     POP    PSW
  58.     JC    GPAS2    ;DIFFERING SIGNS, IF SUBTRACT (CARRY SET) THEN
  59.             ;DO ADDITION RATHER THAN SUBTRACTION.
  60. GPAS4:
  61.     CALL    SUB1
  62.     RET
  63.  
  64.     ENDFUNC
  65. ;
  66. ; ADD1---SIMPLE POSITIVE ADDITION, ADDS (HL) TO (DE) LEAVING
  67. ; RESULT AT (DE).
  68. ;
  69.     FUNCTION    ADD1
  70.     EXTERNAL    LDC2,LDB1,INRM
  71.  
  72.     CALL    LDC2    ;GET LENGTH OF (HL) TO C
  73.     PUSH    D
  74.     PUSH    H
  75.     CALL    LDB1    ;GET LENGTH OF (DE) TO B
  76.     SUB    C    ;COMPARE LENGTHS
  77.     XCHG
  78.     JNC    ADD2
  79.     CMA        ;INCREASE AUGEND LENGTH TO
  80.             ;EQUAL LENGTH OF ADDEND
  81.     ADC    M
  82.     MOV    M,A
  83.     XRA    A    ;CLEAR ACCUMULATOR
  84.     ADD    B    ;LENGTH OF (DE)
  85.     JZ    ADD5    ;AUGEND IS ZERO, DON'T ADD
  86. ADD2:
  87.     INX    H
  88.     INX    D
  89.     LDAX    D    ;GET AUGEND BYTE
  90.     ADC    M    ;AND ADD IT TO ADDEND PLUS CARRY IF ANY
  91.     MOV    M,A
  92.     DCR    B
  93.     JZ    ADD6    ;NO MORE AUGEND LEFT TO ADD
  94.     DCR    C
  95.     JNZ    ADD2    ;CONTINUE ADDITION
  96. ADD3:
  97.     INX    H    ;ADDEND EXHAUSTED
  98.     MOV    A,M
  99.     ADC    C
  100.     MOV    M,A
  101.     DCR    B    ;CONTINUE BY ADDING ZEROS TO AUGEND
  102.             ;UNTIL AUGEND EXHAUSTED
  103.     JNZ    ADD3
  104.     JNC    ADD7    ;FINISHED
  105. ADD4:
  106.     INX    H    ;OVERFLOW
  107.     MVI    M,1    ;EXTEND RESULT BY CARRY TO NEW DIGIT
  108.             ;POSITION
  109.     POP    D
  110.     POP    H
  111.     CALL    INRM    ;EXTEND LENGTH BYTE BY ONE
  112.     XCHG
  113.     RET
  114. ADD5:
  115.     INX    H
  116.     INX    D
  117.     LDAX    D
  118.     ADC    B
  119.     MOV    M,A
  120. ADD6:
  121.     DCR    C    ;ADD ZERO TO ADDEND
  122.     JNZ    ADD5
  123.     JC    ADD4    ;FINISHED, CHECK FOR OVERFLOWS
  124. ADD7:
  125.     POP    H
  126.     POP    D
  127.     RET
  128.  
  129.     ENDFUNC
  130. ;
  131. ; SUB1---SIMPLE UNSIGNED SUBTRACTION ROUTINE, SUB1 SUBTRACTS
  132. ; (HL) FROM (DE) LEAVING THE RESULT AT (DE).
  133. ;
  134.     FUNCTION    SUB1
  135.     EXTERNAL    LDC2,LDB1,DCRM
  136.  
  137.     CALL    LDC2
  138.     PUSH    H
  139.     PUSH    D
  140.     CALL    LDB1    ;GET LENGTHS
  141.     SUB    C    ;COMPARE THEM.
  142.     JNC    SUB2
  143.     XCHG
  144.     CMA
  145.     ADC    M    ;INCREASE MINUEND
  146.             ;LENGTH (PRESERVE SIGN)
  147.     MOV    M,A
  148.     XRA    A
  149.     ADD    B
  150.     XCHG
  151.     JZ    SUB3    ;MINUEND EQUALS ZERO
  152. SUB2:
  153.     INX    H
  154.     INX    D
  155.     LDAX    D
  156.     SBB    M    ;DO THE SUBTRACTION HERE
  157.     STAX    D
  158.     DCR    C
  159.     JZ    SUB7    ;JUMP IF SUBTRAHEND EXHAUSTED
  160.     DCR    B
  161.     JNZ    SUB2
  162. SUB3:
  163.     INX    H    ;IF HERE THEN MINUEND EXHAUSTED
  164.     INX    D
  165.     MOV    A,B
  166.     SBB    M    ;SUBTRACT ZEROS
  167.     STAX    D
  168.     DCR    C
  169.     JNZ    SUB3    ;CONTINUE UNTIL DONE
  170. SUB4:
  171.     POP    H
  172.     PUSH    H    ;IF RESULT IS NEGATIVE, FORM TWO'S
  173.             ;COMPLIMENT.
  174.     PUSH    D
  175.     MOV    A,M
  176.     RAL
  177.     CMC
  178.     RAR
  179.     MOV    M,A
  180.     ANI    7FH
  181.     MOV    C,A    ;LENGTH TO C
  182.     STC
  183. SUB5:
  184.     INX    H
  185.     MOV    A,M
  186.     CMA
  187.     ADC    B
  188.     MOV    M,A
  189.     DCR    C
  190.     JNZ    SUB5
  191.     POP    D
  192.     JMP    SUB8
  193. SUB6:
  194.     INX    D
  195.     LDAX    D
  196.     SBB    C
  197.     STAX    D
  198. SUB7:
  199.     DCR    B
  200.     JNZ    SUB6
  201.     JC    SUB4
  202. SUB8:
  203.     POP    H
  204. SUB9:
  205.     LDAX    D
  206.     CMP    C    ;ANY REDUCTION IN PRECISION?
  207.     JNZ    SUB11    ;NOPE.
  208.     DCX    D
  209. SUB10:
  210.     CALL    DCRM    ;REDUCE PRECISION
  211.     JNZ    SUB9
  212. SUB11:
  213.     XCHG
  214.     POP    H
  215.     RET
  216.  
  217.     ENDFUNC
  218. ;
  219. ; MULT---GENERAL PURPOSE MULTIPLY ROUTINE.  MULTIPLIES (DE) BY (HL)
  220. ; WITH RESULT STORED AT (DE).  THIS ROUTINE HANDLES BOTH NEGATIVE AND
  221. ; AND POSITIVE VALUES.  NOTE...THIS VERSION HAS BEEN PATCHED TO ALLOW
  222. ; (DE) AND (HL) TO POINT AT THE SAME INITIAL NUMBER.
  223. ;
  224.     FUNCTION    MULT
  225.     EXTERNAL    LDB2,MOOV,LEFT,RIGHT,ADD1
  226.  
  227.     CALL    LDB2
  228.     PUSH    H
  229.     LDAX    D
  230.     XRA    M    ;CHECK SIGNS
  231.     PUSH    PSW    ;SAVE RESULT
  232.     PUSH    D
  233.     PUSH    H
  234.     LXI    H,T1
  235.     CALL    MOOV    ;PUT MULTIPLICAND IN T1 WORK AREA
  236.     POP    D
  237.     LXI    H,T2
  238.     CALL    MOOV    ;PUT MULTIPLIER IN T2 WORK AREA
  239.     POP    D
  240.     XRA    A
  241.     STAX    D    ;SET RESULT TO ZERO FOR START
  242. MULT1:
  243.     LXI    H,T2
  244.     MOV    A,M    ;START MULTIPLICATION
  245.     ORA    A
  246.     JZ    MULT3    ;FINISHED
  247.     CALL    RIGHT
  248.     LXI    H,T1
  249.     JNC    MULT2    ;LEAST SIGNIFICANT BIT NOT SET, SO DON'T
  250.             ;ADD
  251.     CALL    ADD1
  252. MULT2:
  253.     CALL    LEFT    ;LEFT SHIFT MULTIPLICAND
  254.     JMP    MULT1
  255. MULT3:
  256.     POP    PSW
  257.     POP    H
  258.     RP        ;IF PLUS THEN NO SIGN DIFFERENCE
  259.     LDAX    D
  260.     XRI    80H    ;CHANGE SIGN
  261.     STAX    D
  262.     RET
  263.  
  264. T1:        DS    128
  265. T2:        DS    128
  266.  
  267.     ENDFUNC
  268. ;
  269. ; MODULUS---GENERAL PURPOSE MODULO ROUTINE.
  270. ; DIVIDES (DE) BY (HL) WITH REMAINDER TO (DE).
  271.     FUNCTION    MODULUS
  272.     EXTERNAL    DDIV
  273.  
  274.     XRA    A
  275.     ADI    80H    ;CLEAR CARRY AND SET SIGN BIT
  276.     JMP    DDIV
  277.  
  278.     ENDFUNC
  279. ;
  280. ; DIVR---DIVIDE AND ROUND.  DIVIDES (DE) BY (HL) WITH RESULT TO (DE)
  281. ; AFTER ROUNDING.
  282. ;
  283.     FUNCTION    DIVR
  284.     EXTERNAL    DDIV
  285.  
  286.     XRA    A
  287.     STC        ;SET CARRY AND CLEAR SIGN
  288.     JMP    DDIV
  289.  
  290.     ENDFUNC
  291. ;
  292. ; DIV---DIVIDE ROUTINE.  DIVIDES (DE) BY (HL) WITH RESULT TO (DE).
  293. ;
  294.     FUNCTION    DIV
  295.     EXTERNAL    DDIV
  296.  
  297.     XRA    A    ;CLEAR CARRY AND CLEAR SIGN
  298.     JMP    DDIV
  299.  
  300.     ENDFUNC
  301. ;
  302. ; DDIV---GENERAL PURPOSE WORKHORSE FOR DIV, MODULUS AND DIVR.
  303. ;
  304.     FUNCTION    DDIV
  305.     EXTERNAL    LDC1,LDB1,MOOV,PSHL,SUB1,INCR,RIGHT
  306.     EXTERNAL    LEFT,PARE
  307.  
  308.     PUSH    H
  309.     PUSH    PSW    ;SAVE VECTOR FLAGS
  310.     LDAX    D
  311.     XRA    M    ;SIGN DIFFERENCE?
  312.     RLC
  313.     JNC    DDIV2    ;NO SIGN DIFFERENCES
  314.     POP    PSW
  315.     INR    A    ;SIGN DIFFERENCE IN BIT 0
  316.     PUSH    PSW
  317. DDIV2:
  318.     CALL    LDC1    ;GET LENGTH OF DIVISOR
  319.     JZ    RETN    ;BAIL OUT IF DIVISOR IS ZERO
  320.     CALL    LDB1
  321.     SUB    C
  322.     JM    RETN    ;DIVISOR IS GREATER THAN DIVIDEND
  323.     PUSH    D
  324.     INR    A
  325.     MOV    B,A
  326.     MOV    C,A    ;SAVE LENGTH DIFFERENCE
  327.     PUSH    B
  328.     LDAX    D
  329.     ANI    7FH    ;CLEAR SIGN OF DIVIDEND
  330.     STAX    D
  331.     MOV    A,M
  332.     ANI    7FH    ;CLEAR SIGN OF PARTIAL DIVISOR
  333.     MOV    M,A
  334.     XCHG
  335.     LXI    H,T1    ;SET TO T1
  336.     CALL    MOOV    ;MOVE DIVISOR FROM (DE) TO T1 (HL)
  337.     XRA    A
  338.     STA    T2    ;ZERO OUT DIVIDEND (T2)
  339.     POP    D
  340. DDIV3:
  341.     CALL    PSHL
  342.     DCR    E
  343.     JNZ    DDIV3
  344.     MOV    C,A
  345.     MOV    B,D
  346. DDIV4:
  347.     POP    D
  348.     PUSH    D
  349.     PUSH    B
  350.     LXI    H,T1
  351.     CALL    PARE    ;PARTIAL DIVIDEND >= PARTIAL DIVISOR?
  352.     JC    DDIV5    ;NO
  353.     CALL    SUB1    ;YES, SUBTRACT
  354.     LXI    H,T2
  355.     CALL    INCR    ;INCREMENT QUOTIENT
  356. DDIV5:
  357.     LXI    H,T1
  358.     CALL    RIGHT    ;RIGHT SHIFT PARTIAL DIVISOR
  359.     POP    B
  360.     DCR    C    ;LOOP COUNT
  361.     JP    DDIV6
  362.     MVI    C,7
  363.     DCR    B
  364.     JM    DDIV7    ;END
  365. DDIV6:
  366.     PUSH    B
  367.     LXI    H,T2
  368.     CALL    LEFT    ;LEFT SHIFT PARTIAL RESULT
  369.     POP    B
  370.     JMP    DDIV4    ;CONTINUE DIVISION
  371. DDIV7:
  372.     POP    D
  373.     POP    PSW    ;(DE)-> REMAINDER
  374.     JM    DDIV11    ;MODULO FUNCTION
  375.     JNC    DDIV9    ;NO ROUNDING
  376.     PUSH    PSW
  377.     CALL    PARE    ;PARTIAL DIVISOR/2 < REMAINDER?
  378.     JC    DDIV8
  379.     JZ    DDIV8    ;NO
  380.     LXI    H,T2
  381.     CALL    INCR    ;YES, INCREMENT ANSWER FOR ROUNDING
  382. DDIV8:
  383.     POP    PSW
  384. DDIV9:
  385.     XCHG
  386.     LXI    D,T2
  387.     ANI    1
  388.     JZ    DDIV10    ;NO CHANGE OF SIGN
  389.     LDAX    D
  390.     ORI    80H    ;CHANGE SIGN
  391.     STAX    D
  392. DDIV10:
  393.     CALL    MOOV    ;MOVE RESULT TO (DE)
  394.     XCHG
  395. DDIV11:
  396.     XRA    A
  397.     POP    H
  398.     LXI    H,T2    ;(DE)-> MODULUS, (HL)->QUOTIENT
  399.     RET
  400. RETN:
  401.     POP    PSW
  402.     STC        ;CARRY SET INDICATES NO
  403.             ;DIVISION
  404.     POP    H
  405.     RET
  406.  
  407. T1:        DS    128
  408. T2:        DS    128
  409.  
  410.     ENDFUNC
  411. ;
  412. ; SQRTR---SQUARE ROOT ROUNDED OF (DE).
  413. ; RETURNS RESULT AT (DE).
  414. ;
  415.     FUNCTION    SQRTR
  416.     EXTERNAL    SQRT1
  417.  
  418.     ORA    A    ;CLEAR CARRY FOR ROUNDING
  419.     JMP    SQRT1
  420.  
  421.     ENDFUNC
  422. ;
  423. ; SQRT---SQUARE ROOT OF (DE) RETURNED AT (DE).
  424. ;
  425.     FUNCTION    SQRT
  426.     EXTERNAL    SQRT1
  427.  
  428.     STC        ;SET CARRY FOR NO ROUNDING
  429.     JMP    SQRT1
  430.  
  431.     ENDFUNC
  432. ;
  433. ; SQRT1---WORKHORSE FOR SQRT AND SQRTR.
  434. ;
  435.     FUNCTION    SQRT1
  436.     EXTERNAL    PSHL,ADD1,PARE,SUB1,RIGHT,INCR,MOOV
  437.  
  438.     PUSH    PSW    ;SAVE OPERATION TYPE
  439.     LDAX    D
  440.     ORA    A
  441.     STC
  442.     JP    SQRT2
  443.     POP    B
  444.     RET        ;RETURN NO OP IF NEGATIVE OR ZERO
  445. SQRT2:
  446.     MVI    C,1
  447.     LXI    H,T2
  448.     MOV    M,C
  449.     INX    H
  450.     MOV    M,C    ;INITIALIZE T2 TO 1
  451.     PUSH    D
  452.     MOV    D,A
  453.     MVI    A,0
  454.     DCX    H
  455. SQRT3:
  456.     CALL    PSHL
  457.     DCR    D    ;MAKE T2 >N (T2 MUST BE A SQUARE NUMBER)
  458.     JNZ    SQRT3
  459.     LXI    D,T1
  460.     STAX    D    ;CLEAR T1
  461. SQRT4:
  462.     CALL    ADD1    ;T1 = T1 + T2
  463.     XCHG
  464.     POP    D
  465.     CALL    PARE    ;N >= T1?
  466.     PUSH    PSW
  467.     CNC    SUB1    ;YES, N = N -T1
  468.     POP    PSW
  469.     PUSH    D
  470.     XCHG
  471.     LXI    H,T2
  472.     PUSH    PSW
  473.     CNC    ADD1    ;YES, T1 = T1 + T2
  474.     POP    PSW
  475.     CC    SUB1    ;NO, T1 = T1 - T2
  476.     XCHG
  477.     CALL    RIGHT    ;T1 = T1 / 2
  478.     XCHG
  479.     CALL    RIGHT
  480.     CALL    RIGHT    ;T2 = T2 / 4
  481.     MOV    A,M
  482.     ORA    A    ;T2 = ZERO?
  483.     JNZ    SQRT4    ;NO
  484.     POP    H
  485.     POP    PSW    ;WAS IT ROUND?
  486.     JC    SQRT5    ;NO
  487.     CALL    PARE    ;N > T1?
  488.     JNC    SQRT5
  489.     XCHG
  490.     CALL    INCR    ;YES SO T1 = T1 + 1
  491.     XCHG
  492. SQRT5:
  493.     CALL    MOOV    ;PUT RESULT BACK TO (DE)
  494.     XCHG
  495.     ORA    A    ;CLEAR CARRY FOR GOOD RESULT
  496.     RET
  497.  
  498. T1:        DS    128
  499. T2:        DS    128
  500.  
  501.     ENDFUNC
  502. ;
  503. ; FACT---COMPUTE THE FACTORIAL OF (HL) AND RETURN
  504. ; RESULT AT (HL).
  505. ;
  506.     FUNCTION    FACT
  507.     EXTERNAL    MOOV,DECR,MULT
  508.  
  509.     MOV    A,M
  510.     ANI    7FH    ;N=ABS(N).
  511.     MOV    M,A
  512.     ORA    A
  513.     RZ        ;F(0)=0 SO RETURN IF ZERO.
  514.     CPI    1    ;CHECK FOR SPECIAL CASE OF N=1
  515.             ;AND N=2.
  516.     JNZ    FAC1
  517.     INX    H
  518.     MOV    A,M
  519.     DCX    H
  520.     CPI    1
  521.     RZ        ;F(1)=1 SO RETURN ONE.
  522.     CPI    2
  523.     RZ        ;F(2)=2 SO RETURN TWO.
  524. FAC1:
  525.     PUSH    D    ;SAVE DE FOR RETURN.
  526.     XCHG
  527.     LXI    H,FVAR
  528.     CALL    MOOV    ;FVAR=N.
  529.     CALL    DECR    ;FVAR=FVAR-1.
  530. FAC2:
  531.     CALL    MULT    ;N=N*FVAR.
  532.     CALL    DECR    ;FVAR=FVAR-1.
  533.     MOV    A,M
  534.     CPI    1
  535.     JNZ    FAC2
  536.     INX    H
  537.     MOV    A,M
  538.     DCX    H
  539.     CPI    1    ;DECREASE FVAR TO 1 STEP -1.
  540.     JNZ    FAC2
  541.     XCHG        ;(HL)->N!, (DE)->FVAR.
  542.     POP    D    ;RESTORE D.
  543.     RET
  544.  
  545. FVAR:        DS    128
  546.  
  547.     ENDFUNC
  548. ;
  549. ; POW---GIVEN (HL)=X AND (DE)=N, RETURN P(X,N) AT (DE), WHERE
  550. ; N IS A POSITIVE INTEGER.  THIS ROUTINE USES ALGORITHM A, PAGE
  551. ; 442 OF SEMINUMERICAL ALGORITHMS, BY D. KNUTH.
  552. ;
  553.     FUNCTION    POW
  554.     EXTERNAL    MOOV,RIGHT,MULT
  555.  
  556.     PUSH    H    ;SAVE FOR ALL RETURNS.
  557.     PUSH    D    ;SAVE FOR ALL RETURNS.
  558.     XRA    A
  559.     STA    PNEG    ;CLEAR NEGATIVE RETURN FLAG.
  560.     MOV    A,M
  561.     ORA    A
  562.     JZ    RET0    ;P(0,N)=0.
  563.     ANI    80    ;IS X <0?
  564.     JZ    POW0    ;NO.
  565.     INX    D
  566.     LDAX    D    ;GET N.
  567.     DCX    D
  568.     ANI    1    ;IS N ODD OR EVEN?
  569.     JZ    POW0    ;N IS EVEN SO SKIP.
  570.     STA    PNEG    ;SET SIGN FOR RETURN.
  571. POW0:
  572.     MOV    A,M
  573.     ANI    7FH    ;IGNORE SIGN FOR NOW.
  574.     CPI    1
  575.     JNZ    POW1
  576.     INX    H
  577.     MOV    A,M
  578.     DCX    H
  579.     CPI    1
  580.     JZ    RET1    ;P(1,N)=1.
  581. POW1:
  582.     XCHG
  583.     MOV    A,M
  584.     ANI    7FH    ;N=ABS(N).
  585.     MOV    M,A
  586.     ORA    A
  587.     JZ    RET1    ;P(X,0)=1.
  588.     CPI    1
  589.     JNZ    POW2
  590.     INX    H
  591.     MOV    A,M
  592.     DCX    H
  593.     CPI    1
  594.     JZ    RETX    ;P(X,1)=X.
  595. POW2:
  596.     PUSH    H
  597.     LXI    H,Y
  598.     MVI    M,1
  599.     INX    H
  600.     MVI    M,1    ;Y=1.
  601.     LXI    H,Z
  602.     CALL    MOOV    ;Z=X.
  603.     POP    H
  604. POW3:
  605.     INX    H
  606.     MOV    A,M
  607.     DCX    H
  608.     ANI    1
  609.     PUSH    PSW    ;TEST FOR ODD/EVEN AND SAVE RESULT.
  610.     CALL    RIGHT    ;SHIFT RIGHT ONE BIT, N=N/2.
  611.     POP    PSW
  612.     JZ    POW4    ;SEE STEP A2...POW4 CORRESPONDS TO A5.
  613.     PUSH    H
  614.     PUSH    D
  615.     LXI    D,Y
  616.     LXI    H,Z
  617.     CALL    MULT
  618.     POP    D
  619.     POP    H
  620.     MOV    A,M
  621.     ORA    A
  622.     JZ    RETY
  623. POW4:
  624.     PUSH    H
  625.     PUSH    D
  626.     LXI    D,Z
  627.     LXI    H,Z
  628.     CALL    MULT
  629.     POP    D
  630.     POP    H
  631.     JMP    POW3
  632. RET0:
  633.     POP    D
  634.     POP    H
  635.     MVI    A,0
  636.     STAX    D
  637.     RET
  638. RET1:
  639.     POP    D
  640.     POP    H
  641.     MVI    A,1
  642.     STAX    D
  643.     INX    D
  644.     STAX    D
  645.     DCX    D
  646.     RET
  647. RETX:    
  648.     POP    D
  649.     POP    H
  650.     XCHG
  651.     CALL    MOOV
  652.     XCHG
  653.     RET
  654. RETY:
  655.     LDA    PNEG
  656.     ORA    A
  657.     JZ    RETY1
  658.     LDA    Y
  659.     XRI    80H
  660.     STA    Y
  661. RETY1:
  662.     POP    D
  663.     XCHG
  664.     LXI    D,Y
  665.     CALL    MOOV
  666.     POP    H
  667.     RET
  668.  
  669. PNEG:        DB    0
  670. Y:        DS    128
  671. Z:        DS    128
  672.  
  673.     ENDFUNC
  674. ;
  675. ; GCD---GIVEN (DE)=A AND (HL)=B, RETURN THE GREATEST COMMON
  676. ; DIVISOR AT (DE).
  677. ;
  678.     FUNCTION    GCD
  679.     EXTERNAL    MOOV,DIV,MULT,SB1
  680.  
  681.     MOV    B,M
  682.     LDAX    D
  683.     ORA    B
  684.     RZ        ;BOTH ARE ZERO.
  685.     MOV    A,M
  686.     ANI    7FH
  687.     MOV    M,A    ;B=ABS(B).
  688.     LDAX    D
  689.     ANI    7FH
  690.     STAX    D    ;A=ABS(A).
  691. GCD1:
  692.     PUSH    H
  693.     LXI    H,R
  694.     CALL    MOOV    ;R=A.
  695.     POP    H
  696.     PUSH    H    ;SAVE BECAUSE DIV RETURNS QUOTIENT IN HL
  697.     CALL    DIV    ;A=A\B.
  698.     POP    H
  699.     CALL    MULT    ;A=A*B.
  700.     XCHG        ;HL=A, DE=B.
  701.     PUSH    D
  702.     LXI    D,R
  703.     CALL    SB1    ;R=R-A.
  704.     POP    D
  705.     LDA    R
  706.     ORA    A
  707.     JZ    RETB    ;IF R=0 THEN RETURN B.
  708.     CALL    MOOV    ;A=B.
  709.     XCHG        ;HL=B, DE=A.
  710.     PUSH    D
  711.     LXI    D,R
  712.     CALL    MOOV    ;B=R.
  713.     POP    D
  714.     JMP    GCD1
  715. RETB:
  716.     CALL    MOOV    ;A=B.
  717.     XCHG        ;HL=B, DE=A.
  718.     RET
  719.  
  720. R:        DS    128
  721.  
  722.     ENDFUNC
  723. ;
  724. ; LCM---GIVEN (DE)=A AND (HL)=B, RETURN THE LEAST COMMON MULTIPLE
  725. ; OF A AND B AT (DE).  LCM(A,B)=A*B/GCD(A,B).
  726. ;
  727.     FUNCTION    LCM
  728.     EXTERNAL    MOOV,MULT,GCD,DIV
  729.  
  730.     MOV    B,M
  731.     LDAX    D
  732.     ORA    B
  733.     RZ        ;BOTH ARE ZERO.
  734.     MOV    A,M
  735.     ANI    7FH
  736.     MOV    M,A    ;B=ABS(B).
  737.     LDAX    D
  738.     ANI    7FH
  739.     STAX    D    ;A=ABS(A).
  740.     PUSH    H
  741.     LXI    H,LCMV
  742.     CALL    MOOV    ;LCMV=A.
  743.     POP    H
  744.     PUSH    D
  745.     LXI    D,LCMV
  746.     CALL    MULT    ;LCMV=LCMV*B.
  747.     POP    D
  748.     CALL    GCD    ;A=GCD(A,B)
  749.     PUSH    H
  750.     XCHG
  751.     LXI    D,LCMV
  752.     CALL    DIV
  753.     CALL    MOOV
  754.     XCHG
  755.     POP    H
  756.     RET    
  757.  
  758. LCMV:        DS    128
  759.  
  760.     ENDFUNC
  761. ;
  762. ; RAND---RANDOM NUMBER GENERATOR.  IF HL=0 THEN RETURN R(N) ELSE
  763. ; RETURN R(1).  NUMBER IS RETURNED AT (DE).
  764. ;
  765.     FUNCTION    RAND
  766.     EXTERNAL    AD1,MOOV,MULT,MODULUS
  767.  
  768.     MOV    A,H
  769.     ORA    L
  770.     JZ    RAND1
  771.     LXI    H,XN
  772.     MVI    M,1
  773.     INX    H
  774.     MVI    M,1
  775. RAND1:
  776.     PUSH    D
  777.     LXI    D,XN
  778.     LXI    H,RMULT
  779.     CALL    MULT
  780.     CALL    AD1
  781.     LXI    H,RMOD
  782.     PUSH    H
  783.     CALL    MODULUS
  784.     POP    H
  785.     POP    D
  786.     XCHG
  787.     LXI    D,XN
  788.     CALL    MOOV
  789.     XCHG
  790.     RET
  791.  
  792. XN:        DS    128
  793. RMULT:        DB    3,1,0,1
  794. RMOD:        DB    10H,0FFH,0FFH,0FFH,0FFH
  795.         DB    0FFH,0FFH,0FFH,0FFH
  796.         DB    0FFH,0FFH,0FFH,0FFH
  797.         DB    0FFH,0FFH,0FFH,7FH
  798.  
  799.     ENDFUNC
  800. ;
  801. ; AUXILLIARY ROUTINES
  802. ;
  803. ;
  804. ; LDB1---LOADS REGISTER B WITH LENGTH INDICATOR OF VALUE AT (DE).
  805. ;
  806.     FUNCTION    LDB1
  807.  
  808.     LDAX    D
  809.     RAL
  810.     ORA    A
  811.     RAR
  812.     MOV    B,A
  813.     ORA    A
  814.     RET
  815.  
  816.     ENDFUNC
  817. ;
  818. ; LDB2---AS LDB1, BUT RETURNS TO CALLER'S CALLER ON LENGTH ZERO.
  819. ;
  820.     FUNCTION    LDB2
  821.     EXTERNAL    LDB1,ABRT
  822.  
  823.     CALL    LDB1
  824.     JZ    ABRT
  825.     RET
  826.  
  827.     ENDFUNC
  828. ;
  829. ; LDC1---LOADS REGISTER C WITH LENGTH INDICATOR OF MULTI-VALUE AT (HL).
  830. ;
  831.     FUNCTION    LDC1
  832.  
  833.     MOV    A,M
  834.     RAL
  835.     ORA    A
  836.     RAR
  837.     MOV    C,A
  838.     ORA    A
  839.     RET
  840.  
  841.     ENDFUNC
  842. ;
  843. ; LDC2---AS LDC1, BUT RETURNS TO CALLER'S CALLER ON LENGTH ZERO.
  844. ;
  845.     FUNCTION    LDC2
  846.     EXTERNAL    LDC1,ABRT
  847.  
  848.     CALL    LDC1
  849.     JZ    ABRT
  850.     RET
  851.  
  852.     ENDFUNC
  853. ;
  854. ; ABRT---ABORT ROUTINE USED BY LDC2 AND LDB2.   ADJUSTS STACK TO RETURN TO
  855. ; CALLER'S CALLER.
  856. ;
  857.     FUNCTION    ABRT
  858.  
  859.     INX    SP
  860.     INX    SP
  861.     RET
  862.  
  863.     ENDFUNC
  864. ;
  865. ; OVFLW---OVERFLOW RECOVERY ROUTINE.  CURRENTLY THIS ROUTINE PERFORMS
  866. ; AN UNCONDITIONAL RETURN TO CP/M WITH A JUMP TO LOCATION ZERO.
  867. ;
  868.     FUNCTION    OVFLW
  869.  
  870.     LXI    D,OVER
  871.     MVI    C,PSTRNG
  872.     CALL    BDOS
  873.     JMP    BASE
  874.  
  875. OVER:        DB    'overflow error$'
  876.  
  877.     ENDFUNC
  878. ;
  879. ; UNFLW---UNDERFLOW RECOVERY ROUTINE.  CURRENTLY THIS ROUTINE PERFORMS
  880. ; AND UNCONDITIONAL RETURN TO CP/M WITH A JUMP TO LOCATION ZERO.
  881. ;
  882.     FUNCTION    UNFLW
  883.  
  884.     LXI    D,UNDER
  885.     MVI    C,PSTRNG
  886.     CALL    BDOS
  887.     JMP    BASE
  888.  
  889. UNDER:        DB    'underflow error$'
  890.  
  891.     ENDFUNC
  892. ;
  893. ; INRM---INCREMENT LENGTH INDICATOR OF VALUE AT (HL).
  894. ;
  895.     FUNCTION    INRM
  896.     EXTERNAL    OVFLW
  897.  
  898.     MOV    A,M
  899.     INR    M
  900.     XRA    M
  901.     RP        ;CHECK FOR SIGN CHANGE
  902.     JMP    OVFLW    ;IF NEGATIVE, THEN SIZE LIMIT EXCEEDED.
  903.  
  904.     ENDFUNC
  905. ;
  906. ; DCRM---DECREMENT LENGTH INDICATOR OF VALUE AT (DE).
  907. ;
  908.     FUNCTION    DCRM
  909.     EXTERNAL    UNFLW
  910.  
  911.     MOV    A,M
  912.     CPI    81H    ;IS IT ZERO PLUS ONE?
  913.     JZ    LABB
  914.     DCR    M
  915.     RZ        ;RETURN WITH ZERO SET FOR
  916.             ;ZERO
  917.     XRA    M    ;SIGN CHANGE?
  918.     RP        ;NO, ELSE
  919.     JMP    UNFLW    ;UNDERFLOW CONDITION HERE
  920. LABB:
  921.     MVI    M,0    ;SPECIAL CASE OF ZERO AS LENGTH AND
  922.     RET        ;VALUE.
  923.  
  924.     ENDFUNC
  925. ;
  926. ; INCR---ADD ONE TO (HL)
  927. ;
  928.     FUNCTION    INCR
  929.     EXTERNAL    LDC1,INCR2,INCR3
  930.  
  931.     PUSH    H
  932.     CALL    LDC1    ;GET LENGTH
  933.     JZ    INCR2
  934. INCR1:
  935.     INX    H
  936.     INR    M    ;INCREMENT DATA
  937.     JNZ    INCR3    ;OVERFLOW?
  938.     DCR    C
  939.     JNZ    INCR1    ;LOOP TILL DONE
  940.     JMP    INCR2
  941.  
  942.     ENDFUNC
  943. ;
  944. ; INCR2---PART OF INCR
  945. ;
  946.     FUNCTION    INCR2
  947.     EXTERNAL    INRM
  948.  
  949. INCR2:
  950.     INX    H
  951.     MVI    M,1    ;EXTEND PRECISION
  952.     POP    H
  953.     CALL    INRM    ;EXTEND LENGTH
  954.     RET
  955.     ENDFUNC
  956. ;
  957. ; INCR3---PART OF INCR
  958. ;
  959.     FUNCTION    INCR3
  960.  
  961.     POP    H
  962.     RET
  963.  
  964.     ENDFUNC
  965. ;
  966. ; DECR---SUBTRACT ONE FROM (HL).
  967. ;
  968.     FUNCTION    DECR
  969.     EXTERNAL    INCR,LDC2,MOOV,DCRM
  970.  
  971.     MOV    A,M
  972.     ORA    A
  973.     JZ    DECR3
  974.     ANI    80H
  975.     JNZ    INCR
  976.     PUSH    H
  977.     CALL    LDC2
  978.     INX    H
  979.     MOV    A,M
  980.     SBI    1
  981.     MOV    M,A
  982.     DCR    C
  983.     JZ    DECR2
  984. DECR1:
  985.     INX    H
  986.     MOV    A,M
  987.     SBI    0
  988.     MOV    M,A
  989.     DCR    C
  990.     JNZ    DECR1
  991. DECR2:
  992.     POP    H
  993.     ORA    A
  994.     RNZ
  995.     CALL    DCRM
  996.     RET
  997. DECR3:
  998.     MVI    M,81H
  999.     INX    H
  1000.     MVI    M,1
  1001.     DCX    H
  1002.     RET
  1003.  
  1004.     ENDFUNC
  1005. ;
  1006. ; LEFT---SHIFT (HL) LEFT ONE BIT, MULTIPLY BY 2.
  1007. ;
  1008.     FUNCTION    LEFT
  1009.     EXTERNAL    LDC2,INCR2
  1010.  
  1011.     CALL    LDC2
  1012.     PUSH    H
  1013. LEFT1:
  1014.     INX    H
  1015.     MOV    A,M    ;GET BYTE
  1016.     RAL
  1017.     MOV    M,A    ;RESTORE SHIFTED
  1018.     DCR    C    ;DECREMENT COUNTER
  1019.     JNZ    LEFT1
  1020.     JC    INCR2    ;EXTEND PRECISION IF OVERFLOW OFF END
  1021.     POP    H
  1022.     RET
  1023.  
  1024.     ENDFUNC
  1025. ;
  1026. ; RIGHT---SHIFT (HL) RIGHT ONE BIT, DIVIDE BY 2.
  1027. ;
  1028.     FUNCTION    RIGHT
  1029.     EXTERNAL    LDC2,DCRM
  1030.  
  1031.     CALL    LDC2
  1032.     MVI    B,0
  1033.     DAD    B    ;GO TO TO HIGH END
  1034.     MOV    A,M
  1035.     RAR
  1036.     MOV    M,A    ;ROTATE RIGHT
  1037.     MOV    B,A    ;SAVE NEW TOP BYTE
  1038. RIGHT1:
  1039.     DCX    H
  1040.     DCR    C
  1041.     JZ    RIGHT2
  1042.     MOV    A,M
  1043.     RAR
  1044.     MOV    M,A
  1045.     JMP    RIGHT1    ;HANDLE REST OF DATA
  1046. RIGHT2:
  1047.     DCR    B    ;WAS NEW TOP EQUAL TO ZERO?
  1048.     RP        ;NO.
  1049.     PUSH    PSW    ;IF YES, THEN SAVE CARRY (= LOST BIT)
  1050.     CALL    DCRM    ;CHANGE LENGTH
  1051.     POP    PSW
  1052.     RET
  1053.  
  1054.     ENDFUNC
  1055. ;
  1056. ; MOOV---MOVE VALUE FROM (DE) TO (HL)
  1057. ;
  1058.     FUNCTION    MOOV
  1059.     EXTERNAL    LDB1
  1060.  
  1061.     CALL    LDB1
  1062.     MOV    M,A
  1063.     RZ        ;WAS LENGTH EQUAL TO ZERO?
  1064.     LDAX    D    ;NO, THEN MOVE THINGS
  1065.     MOV    M,A    ;STORE PROPER LENGTH COUNT
  1066.     PUSH    D
  1067.     PUSH    H    ;SAVE POINTERS
  1068. MOOV1:
  1069.     INX    D
  1070.     INX    H
  1071.     LDAX    D
  1072.     MOV    M,A
  1073.     DCR    B
  1074.     JNZ    MOOV1
  1075.     POP    H
  1076.     POP    D
  1077.     RET
  1078.  
  1079.     ENDFUNC
  1080. ;
  1081. ; PARE---COMPARE TWO MULTI-BYTE VALUES (DE) TO (HL).
  1082. ; RETURNS ZERO SET IF EQUAL, CARRY SET IF (DE)<(HL).
  1083. ;
  1084.     FUNCTION    PARE
  1085.     EXTERNAL    LDC1
  1086.  
  1087.     MOV    A,M
  1088.     RAL        ;SIGN TO CARRY
  1089.     CMC        ;SET TO TRUE
  1090.     RAR        ;PUT IT BACK
  1091.     MOV    B,A
  1092.     LDAX    D
  1093.     RAL        ;SAME TO (DE)
  1094.     CMC
  1095.     RAR
  1096.     CMP    B    ;COMPARE LENGTHS
  1097.     RNZ        ;LENGTHS NOT EQUAL
  1098.     CALL    LDC1    ;GET LENGTH OF (HL)
  1099.     PUSH    H
  1100.     PUSH    D
  1101.     MVI    B,0
  1102.     DAD    B    ;POINT TO HIGH BYTE OF (HL)
  1103.     XCHG
  1104.     DAD    B    ;POINT TO HIGH BYTE OF (DE)
  1105.     XCHG
  1106. PARE1:
  1107.     LDAX    D
  1108.     CMP    M    ;COMPARE BYTES
  1109.     JNZ    PARE2    ;NOT EQUAL
  1110.     DCX    H
  1111.     DCX    D    ;TRY NEXT BYTE DOWN
  1112.     DCR    C
  1113.     JNZ    PARE1
  1114. PARE2:
  1115.     POP    D
  1116.     POP    H
  1117.     RET
  1118.  
  1119.     ENDFUNC
  1120. ;
  1121. ; PSHL---DEQUEUE UTILITY, PUSH VALUE TO BEGINING OF (HL).
  1122. ;
  1123.     FUNCTION    PSHL
  1124.     EXTERNAL    OVFLW
  1125.  
  1126.     PUSH    PSW    ;SAVE VALUE
  1127.     MVI    B,0
  1128.     MOV    A,M    ;GET LENGTH
  1129.     ORA    A
  1130.     MOV    C,A    ;MOVE LENGTH TO C AS A COUNTER
  1131.     JZ    PSHL2    ;IF ZERO, NO NEED TO SHUFFLE DATA AROUND
  1132.     DAD    B    ;GOTO HIGH END OF DATA
  1133. PSHL1:
  1134.     MOV    A,M
  1135.     INX    H
  1136.     MOV    M,A
  1137.     DCX    H
  1138.     DCX    H
  1139.     DCR    C
  1140.     JNZ    PSHL1
  1141. PSHL2:
  1142.     INR    M    ;ADVANCE LENGTH
  1143.     JZ    OVFLW    ;OVERFLOW CONDITION
  1144.     POP    PSW
  1145.     INX    H
  1146.     MOV    M,A    ;PUT NEW BYTE AWAY
  1147.     DCX    H
  1148.     RET
  1149.  
  1150.     ENDFUNC
  1151. ;
  1152. ; POPL---DEQUEUE UTILITY, POP FROM BEGINING OF (HL).
  1153. ;
  1154.     FUNCTION    POPL
  1155.  
  1156.     MOV    A,M    ;GET LENGTH
  1157.     ORA    A
  1158.     RZ        ;NOTHING TO GET
  1159.     MOV    C,A
  1160.     PUSH    H
  1161.     INX    H
  1162.     MOV    B,M    ;GET DATA BYTE
  1163. POPL1:
  1164.     INX    H
  1165.     MOV    A,M
  1166.     DCX    H
  1167.     MOV    M,A
  1168.     INX    H
  1169.     DCR    C
  1170.     JNZ    POPL1
  1171.     POP    H
  1172.     DCR    M    ;LENGTH EQUALS LENGTH MINUS ONE
  1173.     MOV    A,B    ;DATA REMOVED TO ACCUMULATOR
  1174.     RET
  1175.  
  1176.     ENDFUNC
  1177. ;
  1178. ; PSHH---DEQUEUE UTILITY, PUSH DATA ONTO END OF (HL).
  1179. ;
  1180.     FUNCTION    PSHH
  1181.     EXTERNAL    OVFLW
  1182.  
  1183.     PUSH    H
  1184.     PUSH    PSW    ;SAVE DATA BYTE AND LENGTH BYTE
  1185.     INR    M    ;EXTEND LENGTH
  1186.     JZ    OVFLW    ;OVERFLOW CONDITION
  1187.     MOV    C,M    ;LENGTH
  1188.     MVI    B,0
  1189.     DAD    B    ;GOTO HIGH END OF DATA
  1190.     POP    PSW
  1191.     MOV    M,A    ;PUT DATA IN POSITION
  1192.     POP    H
  1193.     RET
  1194.  
  1195.     ENDFUNC
  1196. ;
  1197. ; POPH---DEQUEUE UTILITY, POP DATA FROM END OF (HL).
  1198. ;
  1199.     FUNCTION    POPH
  1200.  
  1201.     MOV    A,M    ;LENGTH
  1202.     ORA    A
  1203.     RZ        ;NOTHING TO GET
  1204.     MOV    C,A
  1205.     PUSH    H
  1206.     MVI    B,0
  1207.     DAD    B    ;GOTO HIGH END OF DATA
  1208.     MOV    A,M    ;GET BYTE
  1209.     POP    H
  1210.     PUSH    PSW    ;SAVE IT
  1211.     DCR    M    ;LENGTH EQUALS LENGTH MINUS ONE
  1212.     POP    PSW
  1213.     RET
  1214.  
  1215.     ENDFUNC
  1216. ;
  1217. ; DECTOHEX---GIVEN A STRING AT (HL) IN STANDARD FORM,
  1218. ; N BYTES, FOLLOWED BY A NULL CHAR, CONVERT TO HEX NUMBER
  1219. ; IN VERY LONG INTEGER FORMAT AT (DE).
  1220. ;
  1221.     FUNCTION    DECTOHEX
  1222.     EXTERNAL    MULT,AD1
  1223.  
  1224.     XRA    A
  1225.     STAX    D
  1226.     STA    NFLAG
  1227.     MOV    A,M
  1228.     CPI    '-'
  1229.     JNZ    DTH11
  1230.     MVI    A,1
  1231.     STA    NFLAG
  1232.     INX    H
  1233. DTH1:
  1234.     MOV    A,M
  1235. DTH11:
  1236.     ANI    0FH
  1237.     ORA    A
  1238.     JZ    DTH2    ;SKIP IF DIGIT IS ZERO
  1239.     STA    DIGIT+1
  1240.     PUSH    H
  1241.     LXI    H,DIGIT
  1242.     CALL    AD1
  1243.     POP    H
  1244. DTH2:
  1245.     INX    H    ;GET NEXT DIGIT IF ANY
  1246.     MOV    A,M
  1247.     ORA    A    ;IS IT A NULL?
  1248.     JZ    DTH3    ;YES, THEN FINISHED
  1249.     PUSH    H
  1250.     LXI    H,TEN
  1251.     CALL    MULT    ;SHIFT TO NEXT DIGIT POSITION
  1252.     POP    H
  1253.     JMP    DTH1
  1254. DTH3:
  1255.     LDA    NFLAG
  1256.     ORA    A
  1257.     RZ
  1258.     LDAX    D
  1259.     ORI    80H
  1260.     STAX    D
  1261.     RET
  1262.  
  1263. TEN:        DB    1,10
  1264. DIGIT:        DB    1,0
  1265. NFLAG:        DB    0
  1266.  
  1267.     ENDFUNC
  1268. ;
  1269. ; HEXTODEC---CONVERT HEX NUMBER IN VERY LONG INTEGER FORMAT
  1270. ; AT (DE) TO A DECIMAL NUMBER (STRING), RETURN ADDRESS IN HL.
  1271. ; FOR MORE INFORMATION ON RADIX CONVERSION SEE KNUTH, VOL 2,
  1272. ; "SEMINUMERICAL ALGORITHMS" PP 302-310.
  1273. ;
  1274.     FUNCTION    HEXTODEC
  1275.     EXTERNAL    MODULUS,MOOV
  1276.  
  1277. EXP:    EQU    12    ;FOR RADIX 10^12 CONVERSION
  1278.  
  1279.     LDAX    D
  1280.     CPI    80H
  1281.     JZ    HTD0    ;HANDLE CASE OF "-0"
  1282.     ORA    A
  1283.     JNZ    HTD1    ;HANDLE CASE OF "0"
  1284. HTD0:
  1285.     LXI    H,ANSWER
  1286.     MVI    M,30H
  1287.     INX    H
  1288.     MVI    M,0
  1289.     DCX    H
  1290.     RET
  1291. HTD1:
  1292.     XRA    A
  1293.     STA    NFLAG
  1294.     LXI    H,INDEX
  1295.     SHLD    INDEXPTR
  1296.     LXI    H,TEMPARRAY
  1297.     SHLD    TEMPPTR
  1298.     LXI    H,ANSEND
  1299.     SHLD    ANSPTR
  1300.     LDAX    D
  1301.     ORA    A
  1302.     JP    HTD2
  1303.     MVI    A,'-'    ;NUMBER IS NEGATIVE
  1304.     STA    NFLAG
  1305. HTD2:
  1306.     LXI    H,RADIX
  1307.     CALL    MODULUS
  1308.     CALL    HTD14    ;MOVE RESULT TO T2
  1309.     JC    HTD3
  1310.     LHLD    TEMPPTR
  1311.     CALL    MOOV
  1312.     PUSH    D
  1313.     XCHG
  1314.     LHLD    INDEXPTR
  1315.     MOV    M,E
  1316.     INX    H
  1317.     MOV    M,D
  1318.     INX    H
  1319.     SHLD    INDEXPTR
  1320.     XCHG
  1321.     POP    D
  1322.     LDAX    D
  1323.     MOV    C,A
  1324.     MVI    B,0
  1325.     DAD    B
  1326.     INX    H
  1327.     SHLD    TEMPPTR
  1328.     XCHG
  1329.     LXI    D,T2
  1330.     CALL    MOOV
  1331.     XCHG
  1332.     JMP    HTD2
  1333. HTD3:
  1334.     LHLD    TEMPPTR
  1335.     CALL    MOOV
  1336.     XCHG
  1337.     LHLD    INDEXPTR
  1338.     MOV    M,E
  1339.     INX    H
  1340.     MOV    M,D
  1341.     INX    H
  1342.     MVI    M,0
  1343.     INX    H
  1344.     MVI    M,0
  1345. HTD4:
  1346.     LXI    H,INDEX
  1347.     SHLD    INDEXPTR
  1348. HTD5:
  1349.     LHLD    INDEXPTR
  1350.     MOV    E,M
  1351.     INX    H
  1352.     MOV    A,M
  1353.     ORA    E
  1354.     JZ    HTD9
  1355.     MOV    D,M
  1356.     INX    H
  1357.     SHLD    INDEXPTR
  1358.     LXI    H,TEMP
  1359.     CALL    MOOV
  1360.     LDA    TEMP
  1361.     ORA    A
  1362.     JZ    HTD7
  1363. HTD6:
  1364.     MVI    A,EXP
  1365.     STA    RCNT
  1366. HTD61:
  1367.     LXI    D,TEMP
  1368.     LXI    H,TEN
  1369.     LDAX    D
  1370.     ORA    A
  1371.     JZ    HTD62
  1372.     CALL    MODULUS
  1373.     CALL    HTD14    ;MOVE RESULT TO T2
  1374.     INX    D
  1375.     LDAX    D
  1376.     DCX    D
  1377.     CALL    HTD13
  1378.     LDA    RCNT
  1379.     DCR    A
  1380.     JZ    HTD5
  1381.     STA    RCNT
  1382.     XCHG
  1383.     LXI    D,T2
  1384.     CALL    MOOV
  1385.     XCHG
  1386.     JMP    HTD61
  1387. HTD62:
  1388.     LDA    RCNT
  1389.     ORA    A
  1390.     JZ    HTD5
  1391.     DCR    A
  1392.     STA    RCNT
  1393.     MVI    A,0
  1394.     CALL    HTD13
  1395.     JMP    HTD62
  1396. HTD7:
  1397.     MVI    B,EXP
  1398. HTD8:
  1399.     MVI    A,0
  1400.     CALL    HTD13
  1401.     DCR    B
  1402.     JNZ    HTD8
  1403.     JMP    HTD5
  1404. HTD9:
  1405.     LHLD    ANSPTR
  1406. HTD10:
  1407.     INX    H
  1408.     MOV    A,M
  1409.     CPI    30H
  1410.     JZ    HTD10
  1411.     LDA    NFLAG
  1412.     ORA    A
  1413.     RZ
  1414.     DCX    H
  1415.     MOV    M,A
  1416.     RET
  1417. HTD13:
  1418.     PUSH    H
  1419.     LHLD    ANSPTR
  1420.     ADI    30H
  1421.     MOV    M,A
  1422.     DCX    H
  1423.     SHLD    ANSPTR
  1424.     POP    H
  1425.     RET
  1426. HTD14:
  1427.     PUSH    PSW
  1428.     PUSH    H
  1429.     PUSH    D
  1430.     LXI    D,T2
  1431.     XCHG        ;MOVE QUOTIENT TO T2
  1432.     CALL    MOOV
  1433.     POP    D
  1434.     POP    H
  1435.     POP    PSW
  1436.     RET
  1437.  
  1438. RCNT:        DB    0
  1439. T2:        DS    128
  1440. NFLAG:        DB    0
  1441. DIGIT:        DB    1,0
  1442. TEN:        DB    1,10
  1443. RADIX:        DB    05,00
  1444.         DB    10H,0A5H,0D4H,0E8H
  1445. INDEXPTR:    DW    0
  1446. TEMPPTR:    DW    0
  1447. ANSPTR:        DW    0
  1448. INDEX:        DS    128
  1449. TEMP:        DS    128
  1450. TEMPARRAY:    DS    512
  1451. ANSWER:        DS    320
  1452. ANSEND:        DS    1
  1453.         DB    0    ;NULL TERMINATOR.
  1454.  
  1455.     ENDFUNC
  1456.     END
  1457.