home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / calculat / calc32.lbr / CALC.ZZ0 / CALC.Z80
Text File  |  1988-03-24  |  14KB  |  921 lines

  1. ;32 bit calculator 88-02-02
  2. ;
  3. ;******* NOTES ON LABELS *******
  4. ;
  5. ;HATOR and LATOR are used for
  6. ;the high 16 and low 16 bytes
  7. ;of the operator.  Similarly
  8. ;for HAND and LAND.  The result
  9. ;is placed by most functions in
  10. ;MOST and LEAST.  For
  11. ;exponentiation, these values
  12. ;are moved back to the operator
  13. ;for subsequent passes.  In
  14. ;the addition and subtraction
  15. ;routines, certain parts are
  16. ;shared by other routines ...
  17. ;this is why they jump around.
  18. ;
  19.     ORG    100H
  20.     LD    (OLDSP),SP
  21.     LD    SP,STACK
  22.     LD    DE,HELLO
  23.     CALL    PRTSTR
  24. ;
  25. ;GET OPERATOR, OPERATION, AND OPERAND
  26. ;
  27. START
  28.     LD    SP,STACK    ;Clean up the garbage caused by error traps
  29.     LD    HL,0
  30.     LD    (MOST),HL
  31.     LD    (LEAST),HL    ;Clear result
  32.     CALL    GETINPUT
  33.     LD    BC,BUFFER+2
  34.     CALL    DECODE
  35.     LD    (LATOR),DE
  36.     LD    (HATOR),HL
  37.     LD    A,(FUNCTION)
  38.     OR    A
  39.     JR    Z,CONVERT
  40. ;
  41. ;factorial is rather useless
  42. ;it overflows at 13
  43. ;
  44.     CP    '!'
  45.     JP    Z,FACTORIAL
  46.     PUSH    AF        ;Save it
  47.     INC    BC        ;Skip the null
  48.     CALL    DECODE        ;Get second number
  49.     LD    (LAND),DE
  50.     LD    (HAND),HL    ;Save number
  51.     POP    AF
  52.     CP    '&'
  53.     JR    Z,IAND
  54.     CP    '%'
  55.     JR    Z,IOR
  56.     CP    '#'
  57.     JR    Z,IXOR
  58.     CP    '('
  59.     JR    Z,RLEFT
  60.     CP    ')'
  61.     JR    Z,RRIGHT
  62.     CP    '<'
  63.     JR    Z,SLEFT
  64.     CP    '>'
  65.     JP    Z,SRIGHT
  66.     CP    '+'
  67.     JP    Z,ADD
  68.     CP    '-'
  69.     JP    Z,SUBTRACT
  70.     CP    '*'
  71.     JP    Z,MULTIPLY
  72.     CP    '/'
  73.     JP    Z,DIVIDE
  74.     CP    '^'
  75.     JP    Z,EXPONENT
  76. ;
  77. ;BAD OPERATION
  78. ;
  79. BADOP
  80.     LD    DE,BADOPER
  81.     JP    ER1
  82. ;
  83. ;*****HEX<->DEC CONVERSION*****
  84. ;
  85. CONVERT
  86.     LD    HL,(HATOR)
  87.     LD    (MOST),HL
  88.     LD    HL,(LATOR)
  89.     LD    (LEAST),HL
  90.     JP    DISPLAY
  91. ;
  92. ;*****AND FUNCTION*****
  93. ;
  94. IAND
  95.     LD    HL,LATOR
  96.     LD    A,(LAND)
  97.     AND    (HL)
  98. IAND1
  99.     LD    (LEAST),A
  100.     JP    DISPLAY
  101. ;
  102. ;*****OR FUNCTION
  103. ;
  104. IOR
  105.     LD    HL,LATOR
  106.     LD    A,(LAND)
  107.     OR    (HL)
  108.     JR    IAND1
  109. ;
  110. ;*****XOR FUNCTION*****
  111. ;
  112. IXOR
  113.     LD    HL,LATOR
  114.     LD    A,(LAND)
  115.     XOR    (HL)
  116.     JR    IAND1
  117. ;
  118. ;*****ROTATE LEFT FUNCTION*****
  119. ;
  120. RLEFT
  121.     LD    A,(LAND)
  122.     LD    B,A
  123.     LD    A,(LATOR)
  124. RLEFT1
  125.     RLCA
  126.     DJNZ    RLEFT1
  127.     JR    IAND1
  128. ;
  129. ;*****ROTATE RIGHT FUNCTION*****
  130. ;
  131. RRIGHT
  132.     LD    A,(LAND)
  133.     LD    B,A
  134.     LD    A,(LATOR)
  135. RR1
  136.     RRCA
  137.     DJNZ    RR1
  138.     JR    IAND1
  139. ;
  140. ;*****SHIFT LEFT FUNCTION*****
  141. ;
  142. SLEFT
  143.     LD    DE,(LATOR)
  144.     LD    HL,(HATOR)
  145.     LD    A,(LAND)
  146.     LD    B,A
  147. SLEFT1
  148.     SLA    E
  149.     RL    D
  150.     RL    L
  151.     RL    H
  152.     DJNZ    SLEFT1
  153. SLEFT2
  154.     LD    (LEAST),DE
  155.     LD    (MOST),HL
  156.     JP    DISPLAY
  157. ;
  158. ;*****SHIFT RIGHT FUNCTION*****
  159. ;
  160. SRIGHT
  161.     LD    DE,(LATOR)
  162.     LD    HL,(HATOR)
  163.     LD    A,(LAND)
  164.     LD    B,A
  165. SR1
  166.     OR    A
  167.     RR    H
  168.     RR    L
  169.     RR    D
  170.     RR    E
  171.     DJNZ    SR1
  172.     JR    SLEFT2
  173. ;
  174. ;*****ADD FUNCTION*****
  175. ;
  176. ADD:
  177.     CALL    ADD1
  178.     LD    (LEAST),HL
  179.     LD    HL,(HATOR)
  180.     LD    DE,(HAND)
  181.     ADC    HL,DE
  182.     JP    C,OVER1        ;Too big
  183.     LD    (MOST),HL
  184.     JP    DISPLAY
  185. ADD1
  186.     LD    HL,(LATOR)
  187.     LD    DE,(LAND)
  188.     ADD    HL,DE
  189.     RET
  190. ;
  191. ;*****SUBTRACT FUNCTION*****
  192. ;
  193. SUBTRACT
  194.     CALL    SUB1
  195.     LD    (LEAST),HL
  196.     CALL    SUB2
  197.     JP    C,OVER1
  198.     LD    (MOST),HL
  199.     JP    DISPLAY
  200. SUB1
  201.     LD    HL,(LATOR)
  202.     LD    DE,(LAND)
  203.     XOR    A
  204.     SBC    HL,DE
  205.     RET
  206. SUB2
  207.     LD    HL,(HATOR)
  208.     LD    DE,(HAND)
  209.     SBC    HL,DE
  210.     RET
  211. ;
  212. ;*****MULTIPLICATION FUNCTION*****
  213. ;
  214. MULTIPLY
  215.     CALL    MULT0
  216.     JP    DISPLAY
  217. ;
  218. ;SHARED WITH EXPONENT
  219. ;
  220. MULTX
  221.     PUSH    BC
  222.     CALL    MULT0        ;Do one power
  223.     POP    BC
  224.     DEC    BC
  225.     LD    A,B
  226.     OR    C
  227.     RET    NZ
  228.     POP    BC        ;Clean up stack
  229.     JP    DISPLAY
  230. MULT0    
  231.     XOR    A
  232.     LD    HL,0
  233.     LD    (LEAST),HL
  234.     LD    (MOST),HL
  235.     LD    (CARRY),A    ;No carry in operator yet
  236.     LD    B,32        ;Number of bits to test
  237. ;
  238. ;SHIFT OPERAND
  239. ;
  240. MULT1
  241.     LD    HL,(HAND)
  242.     LD    DE,(LAND)
  243.     SRL    H        ;Move a zero in
  244.     RR    L
  245.     RR    D
  246.     RR    E
  247.     LD    (HAND),HL
  248.     LD    (LAND),DE    ;Save it
  249.     JR    NC,MULT2    ;Nothing to multiply
  250. ;
  251. ;CHECK OVERFLOW CONDITION
  252. ;
  253.     LD    A,(CARRY)
  254.     OR    A
  255.     JP    NZ,OVERFLOW
  256.     LD    HL,(LEAST)
  257.     LD    DE,(LATOR)
  258.     ADD    HL,DE
  259.     LD    (LEAST),HL
  260.     LD    HL,(MOST)
  261.     LD    DE,(HATOR)
  262.     ADC    HL,DE
  263.     JP    C,OVERFLOW
  264.     LD    (MOST),HL
  265. ;
  266. ;SHIFT OPERATOR AND SET OVERFLOW
  267. ;
  268. MULT2
  269.     LD    HL,(HATOR)
  270.     LD    DE,(LATOR)
  271.     XOR    A        ;Clear carry
  272.     RL    E
  273.     RL    D
  274.     RL    L
  275.     RL    H
  276.     LD    (LATOR),DE
  277.     LD    (HATOR),HL
  278.     JR    NC,MULT3
  279. ;
  280. ;WE HAVE A CARRY
  281. ;SET TO ABORT IF ANOTHER ADDITION IS TRIED
  282. ;
  283.     INC    A        ;Becomes non-zero
  284.     LD    (CARRY),A    ;Remember
  285. MULT3
  286.     DJNZ    MULT1        ;Do 32 times
  287.     RET
  288. ;
  289. ;*****DIVISION FUNCTION*****
  290. ;
  291. DIVIDE
  292.     LD    HL,(HAND)
  293.     LD    A,H
  294.     OR    L
  295.     LD    HL,(LAND)
  296.     OR    H
  297.     OR    L
  298.     LD    DE,DIVZERO
  299.     JP    Z,ER1
  300. ;
  301. ;NO DIVIDE BY ZERO
  302. ;LET'S GO FOR IT
  303. ;
  304.     LD    B,32
  305.     LD    HL,(HATOR)
  306.     LD    (EXPH),HL
  307.     LD    HL,(LATOR)
  308.     LD    (EXPL),HL
  309.     LD    HL,0
  310.     LD    (HATOR),HL
  311.     LD    (LATOR),HL
  312.     LD    (LEAST),HL
  313.     LD    (MOST),HL
  314. ;
  315. ;DOUBLE OPERATOR
  316. ;
  317. DIV1
  318.     LD    HL,(EXPL)
  319.     RL    L
  320.     RL    H
  321.     LD    (EXPL),HL
  322.     LD    HL,(EXPH)
  323.     RL    L
  324.     RL    H
  325.     LD    (EXPH),HL
  326.     LD    HL,(LATOR)
  327.     RL    L
  328.     RL    H
  329.     LD    (LATOR),HL
  330.     LD    HL,(HATOR)
  331.     RL    L
  332.     RL    H
  333.     LD    (HATOR),HL
  334. ;
  335. ;TRY A SUBTRACT
  336. ;
  337.     CALL    SUB1
  338.     PUSH    HL
  339.     CALL    SUB2
  340.     POP    DE
  341.     JR    C,DIV2
  342. ;
  343. ;GOOD DIVISION SAVE RESULT
  344. ;
  345.     LD    (LATOR),DE
  346.     LD    (HATOR),HL
  347.     XOR    A
  348. DIV2
  349.     PUSH    AF
  350.     LD    HL,(LEAST)
  351.     ADD    HL,HL
  352.     LD    (LEAST),HL
  353.     LD    HL,(MOST)
  354.     ADC    HL,HL
  355.     LD    (MOST),HL
  356.     LD    HL,(LEAST)
  357.     POP    AF
  358.     JR    C,DIV3
  359.     INC    HL
  360.     LD    (LEAST),HL
  361. DIV3
  362.     DJNZ    DIV1
  363. ;
  364. ;
  365. ;DISPLAY REMAINDER IN DECIMAL ONLY
  366. ;
  367.     LD    DE,REMAIN
  368.     CALL    PRTSTR
  369.     LD    HL,(MOST)
  370.     PUSH    HL
  371.     LD    HL,(LEAST)
  372.     PUSH    HL
  373.     LD    HL,(HATOR)
  374.     LD    (MOST),HL
  375.     LD    HL,(LATOR)
  376.     LD    (LEAST),HL
  377.     CALL    DPHEX
  378.     LD    DE,UP        ;Reverse line feed
  379.     CALL    PRTSTR
  380.     POP    HL
  381.     LD    (LEAST),HL
  382.     POP    HL
  383.     LD    (MOST),HL    
  384.     JP    DISPLAY
  385. ;
  386. ;*****EXPONENTIATION FUNCTION*****
  387. ;
  388. EXPONENT
  389.     LD    HL,(HATOR)
  390.     LD    (EXPH),HL    ;Save multiplier
  391.     LD    HL,(LATOR)
  392.     LD    (EXPL),HL
  393.     LD    HL,(HAND)
  394.     LD    A,H
  395.     OR    L
  396.     JP    NZ,OVER1    ;Are you crazy?
  397.     LD    HL,1
  398.     LD    (LEAST),HL
  399.     LD    BC,(LAND)
  400.     LD    A,B
  401.     OR    C
  402.     JP    Z,DISPLAY    ;The answer is 1
  403.     LD    HL,1
  404.     LD    (LAND),HL    ;First cycle with a 1
  405.     DEC    HL
  406.     LD    (HAND),HL
  407. ;
  408. ;HERE WE GO
  409. ;
  410. EXP1
  411.     CALL    MULTX
  412. ;
  413. ;MOVE ORIGINAL MULTIPLIER BACK
  414. ;
  415.     LD    HL,(EXPH)
  416.     LD    (HAND),HL
  417.     LD    HL,(EXPL)
  418.     LD    (LAND),HL    ;Move original back
  419. ;
  420. ;MOVE RESULT BACK INTO OPERAND
  421. ;
  422.     LD    HL,(MOST)
  423.     LD    (HATOR),HL
  424.     LD    HL,(LEAST)
  425.     LD    (LATOR),HL
  426.     JR    EXP1        ;More more more
  427. ;
  428. ;*****FACTORIAL FUNCTION*****
  429. ;
  430. FACTORIAL
  431.     LD    HL,1
  432.     LD    (LEAST),HL
  433.     LD    BC,(LATOR)
  434.     LD    A,C
  435.     OR    A
  436.     JP    Z,DISPLAY    ;0!=1
  437.     LD    (LEAST),BC
  438.     DEC    A
  439.     JP    Z,DISPLAY    ;1!=1
  440.     DEC    BC        ;Do X*(X-1) on first pass    
  441. FACT1
  442.     LD    (LAND),BC
  443.     CALL    MULTX
  444.     LD    HL,0
  445.     LD    (HAND),HL
  446.     LD    HL,(MOST)
  447.     LD    (HATOR),HL
  448.     LD    HL,(LEAST)
  449.     LD    (LATOR),HL
  450.     JR    FACT1
  451. ;
  452. ;*****SUBROUTINES*****
  453. ;
  454. ;
  455. ;EXIT TO CCP
  456. ;
  457. EXIT:
  458.     LD    SP,(OLDSP)
  459.     LD    E,10
  460.     JP    PRT
  461. ;
  462. ;GET A NUMBER
  463. ;
  464. GETINPUT
  465.     LD    DE,BUFFER
  466.     LD    C,10
  467.     CALL    5
  468.     LD    HL,BUFFER+1
  469.     LD    A,(HL)        ;Used length
  470.     OR    A
  471.     JR    Z,EXIT
  472.     LD    B,A
  473.     XOR    A
  474.     LD    (FUNCTION),A
  475. PARSE
  476.     INC    HL
  477.     LD    A,(HL)
  478.     CP    ''''        ;ASCII prefix
  479.     JR    NZ,PARSE1
  480.     INC    HL        ;Pass byte as is
  481.     DEC    B        ;Skip the '
  482.     RET    Z
  483.     JR    PARSE6        ;Skip the character    
  484. PARSE1
  485.     CP    'a'
  486.     JR    C,PARSE2
  487.     CP    'z'+1
  488.     JR    NC,PARSE2
  489.     AND    5FH        ;Upper case
  490. PARSE2
  491.     CP    'H'
  492.     JR    Z,PARSE5    ;Intro for HEX value
  493.     CP    'I'
  494.     JR    Z,PARSE5    ;Intro for binary (INDIVIDUAL)
  495.     CP    'M'
  496.     JR    Z,PARSE5    ;Memory flag
  497.     CP    ','
  498.     JR    Z,PARSE5    ;Ignore separator
  499.     CP    '^'
  500.     JR    Z,PARSE3    ;The following are functions
  501.     CP    '>'
  502.     JR    Z,PARSE3
  503.     CP    '<'
  504.     JR    Z,PARSE3
  505.     SUB    '0'
  506.     JR    NC,PARSE4
  507.     ADD    A,'0'        ;Oops it was a function, maybe
  508. PARSE3
  509.     LD    (FUNCTION),A
  510.     LD    A,255        ;End marker
  511.     JR    PARSE5
  512. PARSE4
  513.     CP    10
  514.     JR    C,PARSE5
  515.     SUB    7        ;Offset for A-F
  516. PARSE5
  517.     LD    (HL),A
  518. PARSE6
  519.     DJNZ    PARSE
  520.     INC    HL
  521.     LD    (HL),255    ;End marker
  522.     RET
  523. ;
  524. ;DECODE HEX, DECIMAL, OR ASCII VALUE
  525. ;
  526. DECODE
  527.     LD    HL,0
  528.     LD    DE,0        ;Start with nothing
  529.     LD    A,(BC)
  530.     CP    'H'
  531.     JR    Z,GETHEX
  532.     CP    'I'        ;Binary prefix
  533.     JR    Z,GETBINARY
  534.     CP    'M'
  535.     JR    Z,GETMEMORY
  536.     CP    ''''        ;ASCII prefix
  537.     JR    NZ,GETDECIMAL    ;Default
  538.     INC    BC
  539.     LD    A,(BC)
  540.     LD    E,A        ;Pass ASCII byte to E
  541.     INC    BC
  542.     RET
  543. ;
  544. ;GET LAST RESULT
  545. ;
  546. GETMEMORY
  547.     LD    DE,(LMEM)
  548.     LD    HL,(HMEM)
  549.     INC    BC
  550.     RET
  551. ;
  552. ;GET A HEX NUMBER
  553. ;
  554. GETHEX
  555.     INC    BC        ;Skip the 'H' first time around
  556.     LD    A,(BC)
  557.     CP    255
  558.     RET    Z
  559.     CP    ','
  560.     JR    Z,GETHEX    ;Ignore comma separators
  561.     CP    16
  562.     JR    NC,ERROR
  563.     PUSH    BC        ;Save position
  564. ;
  565. ;SLIDE BITS ONE AT A TIME
  566. ;TO MULTIPLY 'HLDE' BY 0FH AND ADD NUMBER IN 'A'
  567. ;
  568.     RLCA
  569.     RLCA
  570.     RLCA
  571.     RLCA            ;Move number to high nibble of A
  572.     LD    B,4        ;4 rotates will do the trick
  573. ROTATE
  574.     RL    A
  575.     RL    E
  576.     RL    D
  577.     RL    L
  578.     RL    H
  579.     JR    C,OVERFLOW    ;If top bit of 'H' non-zero
  580.     DJNZ    ROTATE
  581.     POP    BC        ;Get pointer back
  582.     JR    GETHEX
  583. ;
  584. ;GET A BINARY NUMBER
  585. ;
  586. GETBINARY
  587.     INC    BC        ;Skip the 'I' first time around
  588.     LD    A,(BC)
  589.     CP    255
  590.     RET    Z
  591.     CP    ','
  592.     JR    Z,GETBINARY    ;Ignore comma separators
  593.     CP    2
  594.     JR    NC,ERROR
  595.     RRA            ;Get bit into carry
  596.     RL    E        ;Bring it into E
  597.     RL    D
  598.     JR    GETBINARY
  599. ;
  600. ;BAD DIGIT ENCOUNTERED
  601. ;
  602. ERROR
  603.     LD    DE,ERMES
  604.     JR    ER1
  605. ;
  606. ;OVERFLOW CONDITIONS
  607. ;
  608. OVERFLOW
  609.     POP    BC        ;Clean up stack
  610. OVER1
  611.     LD    DE,OVER
  612. ER1
  613.     CALL    PRTSTR
  614.     JP    START
  615. ;
  616. ;GET A DECIMAL NUMBER
  617. ;
  618. GETDECIMAL
  619.     DEC    BC        ;Don't ignore first digit
  620. GETD2
  621.     INC    BC
  622.     LD    A,(BC)
  623.     CP    255        ;End of buffer?
  624.     RET    Z
  625.     CP    ','
  626.     JR    Z,GETD2        ;Ignore commas
  627.     CP    10
  628.     JR    NC,ERROR    ;No hex digits allowed here
  629.     PUSH    BC        ;Save pointer
  630. ;
  631. ;DE AND HL *10
  632. ;
  633.     EX    DE,HL
  634.     ADD    HL,HL        ;DE*2
  635.     PUSH    HL
  636.     POP    BC        ;Save DE*2 in BC
  637.     EX    DE,HL    
  638.     ADC    HL,HL        ;HL*2 + overflow
  639.     JR    C,OVERFLOW    ;High bytes not allowed to overflow
  640.     PUSH    HL        ;Save *2
  641.     EX    DE,HL
  642.     ADD    HL,HL        ;DE*4
  643.     EX    DE,HL
  644.     ADC    HL,HL        ;HL*4
  645.     JR    C,OVERFLOW
  646.     EX    DE,HL
  647.     ADD    HL,HL        ;DE*8
  648.     EX    DE,HL
  649.     ADC    HL,HL        ;HL*8
  650.     JR    C,OVERFLOW
  651.     EX    DE,HL
  652.     ADD    HL,BC        ;DE*10
  653.     POP    BC        ;HL*2
  654.     EX    DE,HL
  655.     ADC    HL,BC        ;HL*10
  656.     JR    C,OVERFLOW
  657.     LD    B,0
  658.     LD    C,A
  659.     EX    DE,HL
  660.     ADD    HL,BC        ;Add incoming digit
  661.     EX    DE,HL
  662.     LD    C,0
  663.     ADC    HL,BC        ;Add carry to HL
  664.     JR    C,OVERFLOW
  665.     POP    BC        ;Get pointer back
  666.     JR    GETD2        ;Whew! get another one
  667. ;
  668. ;*****OUTPUT ROUTINES
  669. ;
  670. ;
  671. ;DISPLAY LEAST SIGNIFICANT BYTE IN BINARY
  672. ;
  673. DISPLAY
  674.     LD    HL,(MOST)
  675.     LD    (HMEM),HL    ;Save for memory operation
  676.     LD    HL,(LEAST)
  677.     LD    (LMEM),HL
  678.     LD    DE,CRLF
  679.     CALL    PRTSTR
  680.     LD    A,(LEAST)
  681.     LD    B,8
  682. BITS
  683.     RLCA
  684.     LD    E,'0'
  685.     JR    NC,BIT1
  686.     LD    E,'1'
  687. BIT1
  688.     PUSH    AF
  689.     PUSH    BC
  690.     CALL    PRT
  691.     POP    BC
  692.     POP    AF
  693.     DJNZ    BITS
  694. ;
  695. ;DISPLAY IN ASCII TO HELP FOR LOGICALS
  696. ;
  697.     LD    E,' '
  698.     CALL    PRT
  699.     LD    A,(LEAST)
  700.     AND    7FH        ;Strip high bit
  701.     CP    ' '        ;Control chr?
  702.     JR    NC,ASC1
  703.     PUSH    AF        ;Save for now
  704.     LD    E,'^'
  705.     CALL    PRT
  706.     POP    AF
  707.     ADD    A,64        ;ASCII offset
  708. ASC1
  709.     LD    E,A
  710.     CALL    PRT
  711. ;
  712. ;DISPLAY RESULT IN HEX
  713. ;
  714. DHEX
  715.     LD    DE,CRLF
  716.     CALL    PRTSTR
  717.     XOR    A
  718.     LD    (LEAD),A    ;Ignore leading zeros
  719.     LD    HL,(MOST)
  720.     CALL    DUMPH        ;Hexdump high bytes
  721.     CALL    COMMA
  722.     LD    HL,(LEAST)
  723.     CALL    DUMPH        ;Hexdump low bytes
  724.     LD    DE,EQUAL
  725.     CALL    PRTSTR
  726. ;
  727. ;DISPLAY IN DECIMAL
  728. ;
  729.     CALL    DPHEX
  730.     JP    START
  731. ;
  732. ;DECIMAL CONVERSION ROUTINE
  733. ;
  734. DPHEX
  735.     XOR    A
  736.     LD    (LEAD),A    ;Set leading zero flag
  737.     LD    BC,3B9AH
  738.     LD    DE,0CA00H    ;1,000,000,000
  739.     CALL    SDIV
  740.     CALL    COMMA
  741.     LD    BC,5F5H
  742.     LD    DE,0E100H    ;100,000,000
  743.     CALL    SDIV
  744.     LD    BC,98H
  745.     LD    DE,9680H    ;10,000,000
  746.     CALL    SDIV
  747.     LD    BC,0FH
  748.     LD    DE,4240H    ;1,000,000
  749.     CALL    SDIV
  750.     CALL    COMMA
  751.     LD    BC,1
  752.     LD    DE,86A0H    ;100,000
  753.     CALL    SDIV
  754.     LD    BC,0        ;Will be zero from here on in
  755.     PUSH    BC
  756.     LD    DE,10000
  757.     CALL    SDIV        ;It will do the trick
  758.     POP    BC
  759.     PUSH    BC
  760.     LD    DE,1000
  761.     CALL    SDIV
  762.     CALL    COMMA
  763.     POP    BC
  764.     PUSH    BC
  765.     LD    DE,100
  766.     CALL    SDIV
  767.     POP    BC
  768.     LD    DE,10
  769.     CALL    SDIV
  770.     LD    A,(LEAST)
  771.     ADD    A,'0'
  772.     LD    E,A
  773.     CALL    PRT
  774.     LD    DE,CRLFF
  775.     CALL    PRTSTR
  776.     RET        
  777. ;
  778. ;FIND ONE DIGIT
  779. ;SUBTRACT BCDE FROM MOSTLEAST
  780. ;KEEP COUNT IN A
  781. ;
  782. SDIV
  783.     LD    A,'0'        ;ASCII offset for count
  784. SDIV2
  785.     OR    A        ;And clear carry
  786.     LD    HL,(MOST)
  787.     SBC    HL,BC
  788.     JR    C,PRINT        ;No more of this digit
  789.     LD    (MOST),HL
  790.     LD    HL,(LEAST)
  791.     SBC    HL,DE        ;Subtract rest of number
  792.     LD    (LEAST),HL
  793.     JR    NC,SDIV3    ;No borrow needed
  794.     LD    HL,(MOST)
  795.     EX    AF,AF'        ;Save counter
  796.     LD    A,H
  797.     OR    L
  798.     JR    Z,SDIV4        ;Sorry can't borrow
  799.     EX    AF,AF'        ;Get counter back
  800.     DEC    HL        ;Get a borrow
  801.     LD    (MOST),HL        
  802. SDIV3
  803.     INC    A        ;Clear carry and increment counter
  804.     JR    SDIV2        ;Do another round
  805. ;
  806. ;WE HAVE OVERFLOW -- UNDO IT
  807. ;
  808. SDIV4
  809.     EX    AF,AF'        ;Get counter back first
  810.     ADD    HL,BC
  811.     LD    (MOST),HL
  812.     LD    HL,(LEAST)
  813.     ADD    HL,DE
  814.     LD    (LEAST),HL
  815. PRINT
  816.     LD    E,A
  817.     CP    '0'
  818.     JR    Z,CHECK
  819.     LD    (LEAD),A    ;Yes we've printed a non-zero
  820. CHECK
  821.     LD    A,(LEAD)    ;Have we printed a number?
  822.     OR    A
  823.     RET    Z        ;Not yet
  824. PRT
  825.     LD    C,2
  826.     CALL    5
  827.     RET
  828. ;
  829. ;PRINT A COMMA IF NON-ZERO DIGIT PRINTED
  830. ;
  831. COMMA
  832.     LD    E,','
  833.     JR    CHECK        ;Print the comma, maybe
  834. ;
  835. ;DUMP HL IN HEX
  836. ;
  837. DUMPH
  838.     LD    A,H        ;Get high byte
  839.     PUSH    HL
  840.     CALL    DUMPA
  841.     POP    HL
  842.     LD    A,L        ;Get low byte
  843. DUMPA
  844.     PUSH    AF
  845.     RRCA            ;Get high nibble
  846.     RRCA
  847.     RRCA
  848.     RRCA
  849.     CALL    DUMP
  850.     POP    AF        ;Get low nibble
  851. DUMP
  852.     AND    0FH
  853.     ADD    A,'0'        ;ASCII offest
  854.     CP    '9'+1
  855.     JR    C,PRINT        ;Not a HEX digit
  856.     ADD    A,7        ;Offset for A-F
  857.     JR    PRINT        ;And return
  858. ;
  859. ;PRINT STRING IN (DE)
  860. ;
  861. PRTSTR
  862.     LD    C,9
  863.     CALL    5
  864.     RET
  865. ;
  866. ;DATA NEEDED BY ROUTINE
  867. ;
  868. LEAST    DS    2
  869. MOST    DS    2
  870. LEAD    DS    1
  871. ;
  872. ;OTHER DATA
  873. ;
  874. ;
  875. HELLO    DB    13,10,10,'32-BIT CALCULATOR'
  876.     DB    13,10,9,'  Guy Cousineau',10
  877.     DB    13,10,9,'< SHL    > SHR    ( RL    ) RR' 
  878.     DB    13,10,'& AND    % OR     # XOR'
  879.     DB    13,10,9,'+  -  *  /  ^  !',10
  880.     DB    13,10,'SYNTAX num[OPnum]<CR>',10
  881.     DB    13,10,'use ''M'' to use last result'
  882.     DB    13,10,'precede HEX numbers with H'
  883.     DB    13,10,'precede ASC values  with '''
  884.     DB    13,10,'precede BIN values  with I',10
  885.     DB    13,10,'Empty <CR> exits'
  886. CRLFF    DB    10
  887. CRLF    DB    13,10,'$'
  888. ERMES    DB    10,7,9,'*BAD DIGIT*',13,10,'$'
  889. OVER    DB    10,7,9,'*OVERFLOW*',13,10,'$'
  890. BADOPER    DB    10,7,9,'*BAD FUNCTION*',13,10,'$'
  891. DIVZERO    DB    10,7,9,'*DIVIDE BY ZERO*',13,10,'$'
  892. EQUAL    DB    ' <-> $'
  893. REMAIN    DB    10,9,'     REMAINDER $'
  894. UP    DB    6,6,6,'$'
  895. LATOR    DS    2
  896. HATOR    DS    2        ;OPERATOR
  897. LAND    DS    2
  898. HAND    DS    2        ;OPEARND    
  899. CARRY    DS    1
  900. QUOTIENT DS    2
  901. EXPON    DS    2
  902. EXPH    DS    2
  903. EXPL    DS    2
  904. LMEM    DS    2
  905. HMEM    DS    2
  906. FUNCTION DS    1
  907. OLDSP    DS    2
  908. BUFFER    DB    28
  909.     DS    30        ;INPUT BUFFER
  910.     DS    10H
  911. STACK
  912. ;
  913. ;THIS IS ALL THE STACK WE NEED FOR THIS ROUTINE
  914. ;KEEP THAT IN MIND WHEN ADDING AS A SUBROUTINE
  915. ;
  916. BUFFER
  917.     DS    10H
  918. STACK
  919. ;
  920. ;THIS IS ALL THE STACK WE NEED FOR THIS ROUTINE
  921. ;KEEP THAT IN M