home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug017.ark / PROCCALC.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  24.3 KB  |  1,619 lines

  1. ; THIS IS A FOUR FUNCTION FLOATING POINT MATH PACKAGE
  2. ; EACH FUNCTION MAY BE EXPRESSED AS <BC> = <DE> # <HL> WHERE
  3. ;    <BC> = ADDRESS OF RESULT
  4. ;    <DE> = ADDRESS OF FIRST ARGUMENT
  5. ;    <HL> = ADDRESS OF SECOND ARGUMENT
  6. ;    AND # IS ONE OF THE FUNCTIONS +, -, *, /
  7. ; ON ENTRY TO EACH FUNCTION, BC,DE, & HL SHOULD BE SET AS INDICATED 
  8. ; ABOVE.    ALL ADDRESSES ON ENTRY POINT TO THE EXPONENT PART OF THE 
  9. ; FLOATING POINT NUMBER.    EACH FLOATING POINT NUMBER CONSISTS OF 12 PACKED
  10. ; DECIMAL DIGITS, A SIGN, AND A BIASED BINARY EXPONENT
  11. ; THE EXPONENT RANGE IS    -127 TO +127
  12. ; THE NUMBER ZERO IS REPRESENTED BY ALL DIGITS ZERO AND THE EXPONENT ZERO
  13. ; THE NUMBERS ARE STORED IN MEMORY STARTING AT THE LOW ORDER ADDRESS AS
  14. ; 6 BYTES OF DECIMAL DIGITS FOLLOWED BY THE SIGN FOLLOWED BY THE EXPONENT
  15. ; THE NUMBERS ARE ASSUMED TO BE NORMALIZED.    THAT IS, EACH NUMBER
  16. ; CAN BE REPRESENTED AS    F**E    WHERE .1 <= F <1.0    AND E IS THE EXPONENT
  17. PROCT    EQU    0
  18. INTEL    EQU    1
  19. CI    EQU    3803H
  20. CO    EQU    3809H
  21. CSTS    EQU    3812H
  22. DIGIT    EQU    15
  23. ASCR    EQU    0DH
  24. MAXI    EQU    72    ;MAXIMUM INPUT LINE LENGTH
  25. STAT    EQU    0
  26. DATA    EQU    1
  27. DAV    EQU    40H
  28. TBE    EQU    80H
  29.     ORG    100H
  30. CALC:    LXI    H,0    ;ENTRY POINT FOR THE CALCULATOR
  31.     DAD    SP
  32.     SHLD    USRST    ;SAVE USER'S STACK POINTER
  33. CALC2:    LXI    SP,STACK
  34. INIT:    LXI    H,INFES
  35.     MVI    M,18H    ;INITIALIZE FORMAT (FD12)
  36.     INX    H
  37.     MVI    M,60    ;INITIALIZE TERMINAL WIDTH TO 60
  38.     LXI    H,INMES    ;PRINT HEADER
  39.     JMP    OMESS
  40. INMES:    DB    'PROCESSOR TECHNOLOGY CORP.'
  41.     DW    0A0DH
  42.     DW    77577Q
  43.     DB    'FLOATING POINT CALCULATOR'
  44.     DB    0
  45.     CALL    CRLF
  46. ; THIS ROUTINE CLEARS ALL RAM STORAGE SPACE AND
  47. ; PRINTS "CLEAR" MESSAGE
  48. FRESH:    LXI    H,OPST
  49.     MVI    C,MAXCL
  50.     CALL    CLEAR
  51.     LXI    H,CLMES
  52.     CALL    OMESS
  53.     JMP    READ
  54. ; ALL ERRORS COME HERE FOR MESSAGE PRINTOUT
  55. ERCHK:    CALL    MSG
  56.     JMP    READ
  57. MSG:    LXI    H,OMESS
  58.     PUSH    H    ;OMESS ADDR
  59.     JP    OVER
  60.     LXI    H,UNMES
  61.     RET
  62. OVER:    RAR
  63.     JNC    DIVZM
  64.     LXI    H,OVMES
  65.     RET
  66. DIVZM:    LXI    H,DZMES
  67.     RET
  68. ERROR:    LXI    H,ERMES
  69.     CALL    OMESS
  70.     JMP    READ
  71. ; THIS ROUTINE WILL OUTPUT AN ASCII MESSAGE..H&L 
  72. ; POINT TO THE BEGINNING AND THE ROUTINE TERMINATES
  73. ; WHEN IT FINDS A BINARY ZERO.    THE PROGRAM COUNTER IS 
  74. ; SET ONE BYTE PAST THE ZERO.
  75. OMESS:    CALL    CRLF
  76.     MOV    B,M
  77.     CALL    OUTB
  78.     INX    H
  79.     ORA    A
  80.     JNZ    OMESS+3
  81.     PCHL
  82. ; ERROR MESSAGES USED BY OMESS
  83. ERMES:    DB    'THAT DOES NOT COMPUTE'
  84.     DB    0
  85.     RET
  86. DZMES:    DB    'D/ZERO'
  87.     DB    0
  88.     RET
  89. UNMES:    DB    'UNDERFLOW'
  90.     DB    0
  91.     RET
  92. OVMES:    DB    'OVERFLOW'
  93.     DB    0
  94.     RET
  95. CLMES:    DB    'CLEAR'
  96.     DB    0
  97.     RET
  98. ; THIS ROUTINE READS DATA INTO AN INPUT BUFFER (IBUF)
  99. ; THE INPUT IS TERMINATED BY A CARRIAGE RETURN
  100. READ:    LXI    SP,STACK
  101.     LXI    H,IBUF-1
  102.     SHLD    ADDS
  103.     INX    H
  104.     CALL    CRLF
  105.     MVI    E,MAXI
  106. READ2:    CALL    INB
  107.     CPI    18H    ;CHECK FOR CONTROL X
  108.     JNZ    DEL
  109.     MVI    B,'\'
  110.     CALL    OUTB
  111.     JMP    READ
  112. DEL:    CPI    7FH    ;CHECK FOR RUBOUT
  113.     JNZ    CHR
  114.     MVI    A,MAXI
  115.     CMP    E
  116.     JZ    READ
  117.     DCX    H
  118. DEL2:    MVI    B,'_'    
  119.     CALL    OUTB
  120.     INR    E
  121.     JMP    READ2
  122. CHR:    XRA    A
  123.     ORA    E
  124.     JZ    DEL2
  125.     MOV    M,B    ;STORE CHARACTER
  126.     INX    H
  127.     DCR    E
  128.     MVI    A,ASCR
  129.     CMP    B    ;CHECK FOR CARRIAGE RETURN
  130.     JZ    SCAN
  131.     CALL    OUTB    ;ECHO CHAR
  132.     JMP    READ2    ;GET MORE
  133. ; THIS ROUTINE GETS CHARACTERS FROM THE INPUT BUFFER
  134. ; AND SCANS PAST BLANKS
  135. IBSCN:    LHLD    ADDS
  136.     INX    H
  137.     MOV    A,M
  138.     CPI    ' '
  139.     JZ    IBSCN+3
  140.     SHLD    ADDS
  141. ; THIS ROUTINE CHECKS FOR ASCII NUMBERS (0-9)
  142. NMCHK:    CPI    '9'+1
  143.     RNC
  144.     CPI    '0'
  145.     CMC
  146.     RET
  147. ; THIS ROUTINE SCANS THE INPUT LINE, BRANCHES TO 
  148. ; NECESSARY SUBROUTINES, AND CONVERTS ASCII NUMBERS
  149. ; TO BINARY AND BCD PACKS THEM INTO REGISTER 'BC'
  150. ; OF THE SOFTWARE PUSH-DOWN STACK FOR LATER USE
  151. SCAN:    CALL    CRLF
  152.     LXI    H,TEMP    ;CLEAR TEMPORARY STORAGE AREAS
  153.     MVI    C,7
  154.     CALL    CLEAR
  155.     STA    ERRI    ;CLEAR ERROR FLAG BYTE
  156. SCANC:    LXI    D,0
  157.     LXI    H,BC
  158. SCAN0:    SHLD    BCADD
  159. SCANP:    LXI    H,SCANP
  160.     PUSH    H
  161.     XRA    A
  162.     STA    XSIGN
  163.     LDA    TEMP
  164.     ORA    A    ;ANY TEMPORARY CHARS?
  165.     JZ    SCANG
  166.     CALL    NMCHK    ;CHECK IF NUMBER
  167.     JMP    SCANG+3
  168. SCANG:    CALL    IBSCN
  169.     JC    SCANX
  170.     CPI    '.'    ;RADIX?
  171.     JZ    SCAN5
  172.     CPI    'E'    ;EXPONENT?
  173.     JZ    EXCON
  174.     LXI    H,OPST
  175.     STA    TEMP
  176.     MOV    C,A
  177.     MVI    A,10H    ;ANY NUMBERS IN BC YET?
  178.     ANA    M
  179.     JNZ    ENTR2    ;YES-PUSH SOFTWARE STACK
  180.     STA    TEMP
  181.     MVI    B,80H
  182.     MOV    A,C
  183.     CPI    'S'    ;SUBTOTAL?
  184.     JNZ    PCHK
  185.     MOV    A,B
  186. PUT:    ORA    M
  187.     MOV    M,A
  188.     RET
  189. PCHK:    CPI    'P'    ;PRINT?
  190.     JNZ    SCNQ
  191.     MOV    A,B
  192.     RLC
  193.     JMP    PUT
  194. SCNQ:    CPI    'Q'    ;SQUARE ROOT?
  195.     JNZ    SCN
  196.     MVI    A,1
  197.     STA    SQR
  198.     RET
  199. SCN:    CPI    '##'    ;FLAG FOR LEADING UNARY SIGN
  200.     JZ    SCAN3-4
  201.     CALL    CHKOP
  202.     JNZ    SCAN3
  203.     MOV    B,A
  204.     LDA    OPSTR
  205.     ORA    A
  206.     JZ    SCAN2    ;IT'S AN OPERATOR
  207.     MOV    A,C
  208.     CPI    2
  209.     JNC    SCAN2
  210. SQN:    STA    SIGN    ;IT'S A SIGN
  211.     RET
  212. SCAN2:    LDA    SQR
  213.     ORA    A
  214.     JNZ    SQN
  215.     MOV    A,B
  216.     STA    OPSTR
  217.     RET
  218. SCAN3:    CALL    FINDR    ;CHECK IF REGISTER (A,B,C,D)
  219.     JM    DLMT    ;NO GO-CHECK FOR DELIMITERS
  220.     PUSH    H
  221.     CALL    IBSCN
  222.     CPI    '='    ;FIND REG AND SET DESTINATION
  223.     JZ    SCAN4
  224.     DCX    H    ;MOVE DATA IN REG (N) TO BC
  225.     SHLD    ADDS
  226.     LXI    D,HL-1
  227.     POP    H
  228.     MVI    C,DIGIT+2
  229.     CALL    UP
  230.     JMP    ENT1    ;SKIP FILE AND MOVE REG TO STACK
  231. SCAN4:    MVI    A,3
  232.     DCR    A
  233.     CMP    C
  234.     JNZ    SCAN4+2
  235.     LXI    H,OPST
  236.     INR    A
  237.     RLC    ;A=8,B=6,C=4,D=2
  238.     ORA    M
  239.     MOV    M,A
  240.     POP    H
  241.     SHLD    DEST
  242.     RET
  243. SCAN5:    XRA    A    ;FOUND RADIX
  244.     ORA    D    ;ANY DIGITS YET?
  245.     JNZ    SCAN6
  246.     ADI    0C0H    ;SET ECNT - & STOP COUNTING DIGITS
  247.     ORA    E
  248.     MOV    E,A
  249.     RET
  250. SCAN6:    MVI    A,80H    ;SET ECNT TO COUNT DIGITS
  251.     ORA    E
  252.     MOV    E,A
  253.     RET
  254. SCANX:    ANI    0FH    ;FOUND NUMBER-REMOVE ASCII BIAS
  255.     MOV    B,A
  256.     LXI    H,OPST    ;SET FIRST CHARACTER FLAG
  257.     MVI    A,30H
  258.     ORA    M
  259.     MOV    M,A
  260.     XRA    A
  261.     ORA    B    ;IS CHARACTER ZERO
  262.     JNZ    PACK
  263.     ORA    D    ;LEADING ZERO?
  264.     JNZ    PACK
  265.     ORA    E
  266.     MOV    E,A
  267.     RZ
  268.     INR    E    ;ECNT+1
  269.     RET
  270. ; THIS SUBROUTINE BCD PACKS DIGITS INTO REG BC
  271. PACK:    MOV    A,E
  272.     RAL
  273.     JC    $+4
  274.     INR    E
  275.     MOV    A,E
  276.     STA    ECNT
  277.     INR    D
  278.     MOV    A,D
  279.     ANI    7FH    ;REMOVE TOP/BOTTOM FLAG
  280.     CPI    DIGIT*2    ;LIMIT INPUT DIGITS
  281.     RNC
  282.     XRA    A
  283.     ORA    D
  284.     JM    BOTM
  285. TOP:    ORI    80H    ;SET MSB FOR TOP FLAG
  286.     MOV    D,A
  287.     MOV    A,B
  288.     LHLD    BCADD    ;GET BC ADDRESS
  289.     RLC
  290.     RLC
  291.     RLC
  292.     RLC
  293.     MOV    M,A    ;SAVE CHR IN BC
  294.     RET
  295. BOTM:    ANI    7FH    ;STRIP MSB (BOTTOM FLAG)
  296.     MOV    D,A
  297.     MOV    A,B
  298.     LHLD    BCADD
  299.     ORA    M    ;OR IN TOP NUMBER
  300.     MOV    M,A    ;PUT NUMBER BACK IN BC
  301.     INX    H
  302.     POP    B
  303.     JMP    SCAN0
  304. ; THIS ROUTINE CHECKS FOR STATEMENT DELIMITERS
  305. ;    ( : \ , \ ; \ <CR> )
  306. DLMT:    LXI    H,TEMP
  307.     MOV    M,A
  308.     INX    H    ;TO OPST
  309.     MOV    A,M
  310.     MOV    B,A
  311.     PUSH    PSW
  312.     ANI    0EH    ;ANY REGISTER NAMES TO PRINT?
  313.     JZ    DL2
  314.     MOV    L,A
  315.     MOV    A,B
  316.     ANI    100Q
  317.     JZ    DL1
  318.     MVI    A,12Q
  319.     MVI    B,'A'-1
  320. ALPH:    INR    B    ;FIND REGISTER NAME
  321.     DCR    A
  322.     DCR    A
  323.     CMP    L
  324.     JNZ    ALPH
  325. DOUT:    CALL    OUTB    ;PRINT NAME
  326.     MVI    B,'='
  327.     CALL    OUTB
  328. DL1:    LHLD    DEST
  329.     XCHG
  330.     LXI    H,DE-1    ;MOVE SOFTWARE STACK REG HL TO MEMORY REG
  331.     MVI    C,DIGIT+2    ;(A,B,C,D)
  332.     CALL    UP
  333. DL2:    POP    B    ;PRINT RESULTS IF ANY
  334.     MVI    A,40H
  335.     ANA    B
  336.     JZ    DL3
  337.     XRA    B
  338.     STA    OPST
  339.     CALL    OUTPUT
  340.     CALL    SPACE
  341. DL3:    LXI    H,OPSTR
  342.     MOV    A,M
  343.     ORA    A
  344.     JNZ    ENTR5    ;CONTINUE IF MORE DATA
  345.     DCX    H    ;CHECK FOR DELIMITERS
  346.     DCX    H
  347.     MOV    A,M    ;GET DATA FROM TEMPORARY
  348.     MVI    M,DIGIT-DIGIT
  349.     CPI    ASCR    ;CARRIAGE RETURN?
  350.     JZ    READ    ;NEXT LINE IN
  351.     CPI    ':'    ;COLON?
  352.     JNZ    DL4
  353.     POP    H
  354.     JMP    SCAN
  355. DL4:    CPI    ','    ;COMMA?
  356.     JNZ    DL5
  357.     MVI    C,5    ;PRINT FIVE SPACES
  358. DL40:    CALL    SPACE
  359.     DCR    C
  360.     JNZ    DL40
  361.     POP    H
  362.     JMP    SCAN+3
  363. DL5:    MVI    C,1    ;PRINT ONE SPACE
  364.     CPI    ';'    ;SEMICOLON?
  365.     JZ    DL40
  366. ; THIS ROUTINE CHECKS FOR COMMAND CHARACTERS
  367. ; AND JUMPS TO THE APPROPRIATE ROUTINES
  368. ; IF CHR IS NOT FOUND HERE, IT IS ILLEGAL
  369. CMD:    CPI    'X'
  370.     JZ    EXIT
  371.     CPI    'R'
  372.     JZ    FRESH
  373.     CPI    'F'
  374.     JZ    FIXS
  375.     CPI    'K'
  376.     JZ    POPST
  377.     CPI    'Q'
  378.     JZ    ROOT
  379.     CPI    'W'
  380.     JZ    WIDE
  381.     JMP    ERROR
  382.     DS    40    ;LEAVE ROOM FOR MORE COMMANDS!!!
  383. ; THIS ROUTINE SETS THE TERMINAL WIDTH
  384. WIDE:    CALL    IBSCN
  385.     RNC
  386.     CALL    ASCDC
  387.     MOV    A,E
  388.     CPI    4    ;MINIMUM WIDTH
  389.     JC    ERROR
  390.     STA    WIDTH
  391.     RET
  392. ; THIS ROUTINE IS USED TO ADJUST A NUMBER IN BC
  393. ; FOR INPUT TO THE SOFTWARE STACK.    IT THEN CALLS
  394. ; ROUTINES TO PUSH THE NUMBER ON THE STACK, AND CHECKS
  395. ; IF IMMEDIATE PRINTING OF A NUMBER IS WANTED
  396. ENTR2:    LXI    D,0
  397.     CALL    FIXE    ;NORMALIZE FLOATING POINT NUMBER
  398. ENT1:    LXI    H,SCANC
  399.     XTHL    ;CHANGE RETURN ADDRESS ON STACK
  400.     LDA    SIGN    ;SET UNARY SIGN OF NUMBER
  401.     ORA    A
  402.     JZ    ENT2
  403.     XRA    A
  404.     STA    SIGN
  405.     LDA    BC+DIGIT
  406.     CMA
  407.     STA    BC+DIGIT
  408. ENT2:    CALL    ENTR    ;PUSH SOFTWARE STACK
  409. ENTR3:    LXI    H,OPST    ;CHECK FOR IMMEDIATE 'PRINT' (P)
  410.     MVI    A,1
  411.     ANA    M
  412.     JZ    ENTR4
  413.     PUSH    H
  414.     CALL    OUTPUT
  415.     CALL    SPACE
  416.     POP    H
  417. ENTR4:    LDA    SQR
  418.     ORA    A
  419.     JNZ    ROOT    
  420. QRET:    XRA    A
  421.     STA    SQR
  422.     MVI    A,356Q    ;CLEAR PRINT AND 'OPERATION-OCCURRED' FLAGS
  423.     ANA    M
  424.     MOV    M,A
  425.     INX    H
  426.     MOV    A,M
  427.     ORA    A
  428.     RZ    ;TO SCANC
  429.     CPI    '##'    ;CHECK IF LEADING UNARY
  430.     JNZ    ENTR5
  431.     MVI    M,DIGIT-DIGIT
  432.     RET    ;TO SCANC
  433. ENTR5:    CALL    CHKOP    ;CHECK FOR LEGAL OPERATOR
  434.     JNZ    ERROR
  435. ; THIS ROUTINE SETS UP ALL REGISTERS AND CALLS
  436. ; THE FLOATING POINT ROUTINES
  437. FPC:    MVI    A,-1    ;FIND TYPE OF OPERATION
  438.     LXI    H,FPCAL-2
  439. FPC2:    INX    H
  440.     INX    H
  441.     INR    A
  442.     CMP    C
  443.     JNZ    FPC2
  444.     MOV    E,M    ;MOVE FLOATING POINT ROUTINE ADDR INTO D&E
  445.     INX    H
  446.     MOV    D,M
  447. FPC3:    LXI    B,FPR
  448.     PUSH    B    ;SET UP RETURN FOR FLOATING POINT ROUTINES
  449.     PUSH    D    ;SET UP FLOATING POINT ADDRESS
  450.     LXI    B,BC+DIGIT+1    ;SET REGISTERS
  451.     LXI    H,HL+DIGIT+1
  452.     LXI    D,DE+DIGIT+1
  453.     RET    ;GO TO FLOATING POINT!
  454. ; FLOATING POINT ROUTINE ADDRESSES
  455. FPCAL:    DW    FADD    
  456.     DW    FSUB
  457.     DW    FMULT
  458.     DW    FDIV
  459. ; THE FLOATING POINT ROUTINES RETURN HERE
  460. FPR:    LDA    ERRI    ;CHECK FOR OVER-UNDER-D/ZERO ERRORS
  461.     ORA    A
  462.     JNZ    ERCHK    ;PRINT MESSAGE IF ERROR
  463.     CALL    POP    ;FIX SOFTWARE STACK
  464.     LXI    H,BC
  465.     LXI    D,HL
  466.     LXI    B,DIGIT+2
  467.     CALL    DOWN
  468.     XRA    A    ;CHECK HERE IF SUBTOTAL PRINTOUT IS WANTED
  469.     STA    OPSTR
  470.     LXI    H,OPST
  471.     MVI    A,100Q
  472.     ORA    M
  473.     MOV    M,A
  474.     RAL
  475.     RNC    ;NO-RETURN TO SCANC
  476.     ANI    7FH
  477.     STC
  478.     RAR
  479.     MOV    M,A
  480.     CALL    OUTPUT
  481.     CALL    SPACE
  482.     RET    ;SCANC
  483. ; THIS IS THE EXIT ROUTINE.    IT IS SET NOW TO RETURN
  484. ; TO THE BEGINNING OF THIS FLOATING POINT CALCULATOR
  485. ; PACKAGE.    IT MAY BE SET TO JUMP OR RETURN TO OTHER
  486. ; ROUTINES OR PROGRAMS.    IT WILL RESET THE STACK
  487. ; WITH THE VALUE IT HAD WHEN THE FLOATING POINT
  488. ; CALCULATOR WAS ENTERED.
  489. EXIT:    LHLD    USRST    ;GET USER STACK ADDRESS
  490.     SPHL    ;RESET USER'S STACK
  491.     JMP    CALC    ;ENTER A RETURN OR JUMP HERE IF NEEDED
  492. ; THIS ROUTINE IS USED TO CALCULATE THE SQUARE ROOT
  493. ; THE FORMULA IS B=(A/B+2)/2 WHERE A IS THE NUMBER TO BE
  494. ; ROOTED, AND B IS THE ESTIMATED SQUARE ROOT.
  495. ROOT:    INX    H    ;SAVE OPERATION IF ANY
  496.     MOV    A,M
  497.     STA    ECNT
  498.     LXI    D,BC+DIGIT+1
  499.     LXI    H,HL+DIGIT
  500.     XRA    A
  501.     ORA    M
  502.     JNZ    ERROR    ;ERROR IF NEGATIVE ARG
  503.     INX    H    
  504.     ORA    M
  505.     JZ    QRET    ;Q=0 - MOVE ON
  506.     SUI    128    ;SUBTRACT EXPONENT BIAS
  507.     JNC    ROOT2
  508.     CMA
  509.     INR    A    ;MAKE NEGATIVE EXPONENT POSITIVE
  510. ROOT2:    STC
  511.     RAR    
  512.     STAX    D    ;PUT ESTIMATE EXPONENT IN BC
  513.     MVI    A,80H
  514.     ANA    M    ;CHECK IF NEGATIVE EXPONENT
  515.     JNZ    RTPOS
  516.     LDAX    D    ;SWITCH IF NEGATIVE
  517.     CMA
  518.     INR    A
  519.     STAX    D    ;NEGATIVE EXPONENT ESTIMATE TO BC
  520. RTPOS:    DCX    H
  521.     DCX    D
  522.     MVI    C,DIGIT+1
  523.     CALL    UP    ;MOVE ESTIMATE TO BC
  524.     LXI    H,DE    ;MOVE DATA IN SOFTWARE STACK TO TEMPORARY
  525.     LXI    D,REGE
  526.     LXI    B,DIGIT+2
  527.     CALL    DOWN
  528.     CALL    ENTR    ;PUSH SOFTWARE STACK
  529.     MVI    A,(DIGIT/3)*4    ;ITERATION COUNT
  530. ROOT3:    PUSH    PSW
  531.     CALL    SETST
  532.     LXI    D,FDIV    ;DIVIDE A/B
  533.     CALL    FPC3
  534.     LXI    D,FADD
  535.     CALL    FPC3    ;ADD (A/B)+B
  536.     MVI    A,20H
  537.     STA    BC
  538.     MVI    A,81H
  539.     STA    BC+DIGIT+1    ;MOVE IN A '2' FOR DIVIDE
  540.     CALL    ENTR
  541.     LXI    D,FDIV    ;DIVIDE (A/B+B)/2
  542.     CALL    FPC3
  543.     POP    PSW
  544.     DCR    A
  545.     JNZ    ROOT3    ;DO IT 8 TIMES
  546.     LXI    H,REGE
  547.     LXI    D,DE    ;MOVE DATA FROM THE TEMPORARY TO DE IN STACK
  548.     LXI    B,DIGIT+2
  549.     CALL    DOWN
  550.     LDA    ECNT    ;GET PREVIOUS OPERATORS IF ANY
  551.     LXI    H,OPSTR
  552.     MOV    M,A
  553.     XRA    A
  554.     STA    ECNT
  555.     DCX    H
  556.     JMP    QRET    ;DONE-BACK TO NORMAL
  557. SETST:    LXI    H,DE+DIGIT+1    ;SET UP SOFTWARE STACK FOR SQR ROOT
  558.     LXI    D,S4+DIGIT+1
  559.     MVI    C,(DIGIT+2)*2
  560.     JMP    UP
  561. ; THIS ROUTINE IS USED TO SET REGISTER ADDRESSES 
  562. ; FOR MEMORY REGISTERS A,B,C,D
  563. FINDR:    LXI    H,REGB-1
  564.     PUSH    D
  565.     LXI    D,DIGIT+2
  566.     LXI    B,4103H
  567. FIND2:    CMP    B
  568.     JZ    FEND
  569.     DCR    C
  570.     JM    FEND
  571.     DAD    D    ;GO TO NEXT REG
  572.     INR    B
  573.     JMP    FIND2
  574. FEND:    POP    D
  575.     RET
  576. ; THESE ROUTINES ARE USED TO MANIPULATE THE 
  577. ; SOFTWARE STACK
  578. ; POP STACK
  579. POPST:    LXI    H,HL
  580.     LXI    D,BC
  581.     MVI    C,DIGIT*5+2
  582.     CALL    DOWN
  583.     LXI    B,DIGIT+2
  584.     LXI    H,BC
  585.     LXI    D,S4
  586.     CALL    DOWN
  587.     JMP    ENTR3
  588. ; RESET STACK AFTER OPERATION
  589. POP:    LXI    H,S3
  590.     LXI    D,DE
  591.     LXI    B,DIGIT*2+4
  592.     CALL    DOWN
  593.     RET
  594. ; MOVE DATA FROM ADDRESS POINTED TO BY HL
  595. ; TO ADDRESS POINTED TO BY DE
  596. DOWN:    MOV    A,M
  597.     STAX    D
  598.     MOV    M,B    ;PULL A ZERO
  599.     INX    H
  600.     INX    D
  601.     DCR    C
  602.     JNZ    DOWN
  603.     RET
  604. ; ENTER (PUSH) DATA ONTO STACK
  605. ENTR:    LXI    H,S3+DIGIT+1
  606.     LXI    D,S4+DIGIT+1
  607.     MVI    C,DIGIT*5+3
  608.     CALL    UP
  609.     LXI    H,BC
  610.     MVI    C,DIGIT+2
  611.     CALL    CLEAR    ;CLEAR BC
  612.     RET
  613. ; MOVE DATA
  614. UP:    MOV    A,M
  615.     STAX    D
  616.     DCX    D
  617.     DCX    H
  618.     DCR    C
  619.     JNZ    UP
  620.     RET
  621. ; THIS ROUTINE IS USED TO SET THE OUTPUT FORMAT
  622. FIXS:    CALL    FIXS2    ;GET FORMAT SYMBOL
  623.     JNZ    ERROR    ;NO FORMAT?
  624.     CALL    IBSCN
  625.     JC    FIXS3
  626.     CPI    '$'    ;PRINT TRAILING ZEROS?
  627.     JNZ    FIXS3
  628.     MVI    A,200Q
  629.     ORA    C
  630.     MOV    C,A
  631.     CALL    IBSCN
  632. FIXS3:    PUSH    B    ;SAVE OLD DECIMAL PLACE COUNT
  633.     JC    FIXS4
  634.     LDA    INFES
  635.     RRC
  636.     ANI    0FH
  637.     JMP    FIXS5
  638. FIXS4:    CALL    ASCDC    ;CONVERT DECIMAL PLACE COUNT
  639.     MOV    A,E
  640. FIXS5:    CPI    DIGIT*2+1
  641.     JC    FIXS6
  642.     MVI    A,DIGIT*2
  643. FIXS6:    RLC
  644.     POP    B
  645.     ORA    C
  646.     STA    INFES    ;STORE NEW FORMAT
  647.     XRA    A
  648.     STA    TEMP    ;CLEAR TEMPORARY STORAGE REGISTERS
  649.     RET    ;TO SCANC
  650. FIXS2:    CALL    IBSCN    ;GET FORMAT SYMBOL
  651.     MVI    C,0
  652.     CPI    'D'    ;DECIMAL PLACES
  653.     RZ
  654.     INR    C
  655.     CPI    'E'    ;EXPONENTIAL
  656.     RZ
  657.     MVI    C,40H
  658.     CPI    'F'    ;FLOAT-MANDATORY DECIMAL PLACE
  659.     RET
  660. ; THIS ROUTINE CHECKS OR OPERATORS (+,-,*,/)
  661. CHKOP:    MVI    C,0
  662.     CPI    '+'
  663.     RZ
  664.     INR    C
  665.     CPI    '-'
  666.     RZ
  667.     INR    C
  668.     CPI    '*'
  669.     RZ
  670.     INR    C
  671.     CPI    '/'
  672.     RET
  673. ; THIS ROUTINE IS USED TO CLEAR STORAGE AREAS
  674. ; THE STARTING ADDRESS IS IN H&L AND THE COUNT
  675. ; IS IN REG C
  676. CLEAR:    XRA    A
  677.     MOV    M,A
  678.     INX    H
  679.     DCR    C
  680.     JNZ    CLEAR+1
  681.     RET
  682. ; THIS ROUTINE CONVERTS THE ASCII EXPONENT O
  683. ; THE NUMBER IN THE INPUT BUFFER TO BINARY, AND
  684. ; NORMALIZES EXPONENT ACCORDING TO THE INPUT
  685. ; FORMAT OF THE NUMBER
  686. EXCON:    CALL    IBSCN    ;GET CHAR
  687.     JC    EXC3
  688.     CPI    '+'    ;CHECK FOR UNARY OPERATOR
  689.     JZ    EXC2+3    ;*************************?????????
  690.     CPI    '-'
  691.     JNZ    ERROR    ;NO SIGN OR NUMBER?
  692.     MVI    A,1
  693. EXC2:    STA    XSIGN    ;SAVE SIGN
  694.     CALL    IBSCN
  695.     JNC    ERROR    ;NO NUMBER?
  696. EXC3:    CALL    ASCDC    ;CONVERT ASCII TO BINARY
  697.     CALL    FIXE    ;NORMALIZE EXPONENT
  698.     JMP    ENT1    ;GO ENTER NUMBER NOW
  699. ; THIS ROUTINE CONVERTS ASCII TO BINARY
  700. ; THREE CONSECUTIVE NUMBERS < 128 MAY BE CONVERTED
  701. ASCDC:    XCHG
  702.     LXI    H,0
  703. ASC1:    LDAX    D
  704.     CALL    NMCHK    ;CHECK NUMERIC
  705.     JNC    ASC2
  706.     SUI    '0'    ;REMOVE ASCII BIAS
  707.     MOV    B,H
  708.     MOV    C,L
  709.     DAD    H
  710.     DAD    H
  711.     DAD    B
  712.     DAD    H
  713.     MOV    C,A
  714.     MVI    B,0
  715.     DAD    B
  716.     INX    D
  717.     JMP    ASC1
  718. ASC2:    XCHG
  719.     DCX    H
  720.     SHLD    ADDS    ;SAVE IBUF ADDRESS
  721.     MOV    A,D
  722.     ORA    A
  723.     JNZ    ERROR    ;TOO BIG >255
  724.     MOV    A,E
  725.     RAL
  726.     JC    ERROR    ;TOO BIG >127
  727.     RAR    
  728.     RET
  729. ; THIS ROUTINE NORMALIZES THE INPUT NUMBER
  730. FIXE:    XCHG
  731.     LDA    BC
  732.     ORA    A    ;IS IT ZERO?
  733.     JZ    ZZ2
  734.     CALL    CHKPN
  735.     ADI    80H    ;ADD EXPONENT BIAS
  736. ZZ2:    STA    BC+DIGIT+1
  737.     RET
  738. CHKPN:    LDA    ECNT    ;GET DIGIT COUNT
  739.     MOV    E,A
  740.     ANI    3FH    ;STRIP BITS 7&8
  741.     MOV    B,A
  742.     LDA    XSIGN
  743.     ORA    A
  744.     JZ    LPOS    ;EXPONENT IS POSITIVE
  745.     INR    H    ;SET SIGN IN H
  746.     MVI    A,40H    ;L IS NEGATIVE
  747.     ANA    E    ;CHECK IF E IS NEGATIVE
  748.     JZ    EPOS
  749.     MOV    A,L    ;BOTH E&L NEGATIVE
  750.     MOV    L,B
  751.     CALL    EPOS+1
  752.     CMA
  753.     INR    A
  754.     RET    ;BACK TO FIXE
  755. EPOS:    MOV    A,L    ;E&L NEGATIVE
  756.     CMA
  757.     INR    A
  758.     ADD    B
  759.     RET    ;TO FIXE
  760. LPOS:    MVI    A,40H    ;EXPONENT POSITIVE
  761.     ANA    E    ;IS E NEGATIVE?
  762.     JZ    BPOS
  763.     MOV    A,B
  764.     MOV    B,L
  765.     JMP    EPOS+1
  766. BPOS:    MOV    A,B    ;E&L POSITIVE
  767.     ADD    L
  768.     JM    ERSET
  769.     RET
  770. ERSET:    XRA    A    ;EXPONENT ERROR
  771.     ORA    H    ;GET EXPONENT SIGN
  772.     JZ    ERSE2    ;UNDERFLOW
  773.     CMA
  774. ERSE2:    INR    A    ;OVERFLOW
  775.     STA    ERRI    ;STORE ERROR NUMBER
  776.     JMP    ERCHK    ;GO OUTPUT ERROR MESSAGE
  777. ;    THIS ROUTINE TAKES THE BCD NUMBER IN HL AND 
  778. ; CONVERTS IT FOR OUTPUT ACCORDING TO THE OUTPUT
  779. ; FORMAT
  780. OUTPUT: LXI    H,ABUF
  781.     LDA    INFES    ;GET OUTPUT FORMAT
  782.     STA    FES    ;STORE IT IN WORKING BUFFER
  783.     LXI    B,HL
  784.     MVI    E,DIGIT
  785.     MVI    M,0    ;CLEAR ROUND-OFF OVERFLOW BUFFER
  786.     INX    H
  787. NEXT:    LDAX    B    ;GET DIGIT AND UNPACK
  788.     MOV    D,A
  789.     RAR    
  790.     RAR
  791.     RAR
  792.     RAR
  793.     ANI    0FH    ;REMOVE BOTTOM DIGIT
  794.     MOV    M,A    ;STORE TOP DIGIT IN OUTPUT BUFFER(ABUF)
  795.     INX    H
  796.     MOV    A,D    ;NOW GET BOTTOM DIGIT
  797.     ANI    0FH
  798.     MOV    M,A    ;STORE IT
  799.     INX    H
  800.     INX    B
  801.     DCR    E
  802.     JNZ    NEXT
  803.     XRA    A
  804.     MOV    M,A
  805.     INX    H
  806.     MOV    M,A
  807. FIX:    INX    B
  808.     LDAX    B
  809.     ORA    A    ;EXPONENT ZERO?
  810.     JZ    ZRO
  811.     SBI    128    ;REMOVE NORMALIZING BIAS
  812.     JNZ    FIX2
  813.     INR    M
  814. FIX2:    JP    CHK13
  815.     CMA    ;IT'S A NEGATIVE EXPONENT
  816.     INR    M
  817. ZRO:    INR    A
  818. CHK13:    INX    H    ;CHECK IF EXPONENT > 12
  819.     MOV    M,A
  820.     MOV    E,A
  821.     CPI    DIGIT*2
  822.     INX    H
  823.     JC    CHKX0
  824. CHK40:    MVI    A,1    ;FORCE EXPONENTIAL PRINTOUT
  825.     ORA    M
  826.     MOV    M,A
  827. CHKX0:    MOV    A,M    ;CHECK IF EXPONENTIAL PRINTOUT
  828.     RAR
  829.     JNC    CHKX3
  830.     ANI    1FH
  831.     CPI    DIGIT*2
  832.     JC    CHKX2
  833.     MVI    A,DIGIT*2-1
  834. CHKX2:    MOV    D,A
  835.     INR    A
  836.     JMP    ROUND
  837. CHKX3:    ANI    1FH    ;ADD EXPONENT AND DECIMAL PLACES
  838.     MOV    D,A
  839.     ADD    E
  840.     CPI    DIGIT*2+1
  841.     MOV    B,A
  842.     JC    CHKXN
  843.     MOV    A,M
  844.     CPI    100Q
  845.     JNZ    CHK40
  846. CHKXN:    LDA    XSIGN    ;CHECK EXPONENT SIGN
  847.     ORA    A
  848.     JNZ    XNEG    ;IT'S NEGATIVE
  849.     MOV    A,B
  850.     JMP    ROUND
  851. XNEG:    MOV    A,D    ;SUBTRACT EXPONENT AND DECIMAL PLACE COUNT
  852.     SUB    E
  853.     JNC    XN2
  854. XN1:    LDA    INFES
  855.     ORA    A
  856.     JP    ZERO
  857.     ANI    0EH
  858.     JZ    ZERO
  859.     RRC
  860.     MOV    E,A
  861.     DCR    E
  862.     MVI    C,1
  863.     LXI    H,ABUF-1
  864.     JMP    NRND
  865. XN2:    JZ    XN1
  866.     JMP    ROUND
  867. CLEAN:    MVI    B,1FH    ;CLEAR FLAGS
  868.     ANA    B
  869.     CPI    DIGIT*2+1
  870.     RC
  871.     MVI    A,DIGIT*2+1
  872.     RET
  873. ; THIS ROUTINE IS USED TO ROUND DATA TO THE 
  874. ; SPECIFIED PRECISION
  875. ROUND:    CALL    CLEAN
  876.     MOV    C,A
  877.     MVI    B,0
  878.     LXI    H,ABUF+1
  879.     DAD    B    ;GET ROUND ADDRESS
  880.     SHLD    ADD
  881.     MOV    A,M
  882.     CPI    5    ;ROUND IF >= 5
  883.     JC    TRL2-1
  884. LESS1:    DCX    H
  885.     INR    M    ;ROUND UP
  886.     MOV    A,M
  887.     ORA    A
  888.     JZ    TRL2
  889.     CPI    10    ;CHECK IF ROUNDED NUMBER >9
  890.     JNZ    TRAIL
  891.     MVI    M,0
  892.     JMP    LESS1
  893. ; THIS ROUTINE IS USED TO ELIMINATE TRAILING ZEROS
  894. TRAIL:    LHLD    ADD
  895.     DCX    H
  896. TRL2:    LDA    FES    ;CHECK IF TRAILING ZEROS ARE WANTED
  897.     RAL
  898.     JC    PRINT    ;YES-GO PRINT DATA
  899. TRL3:    MOV    A,M    
  900.     ORA    A    ;IS IT A ZERO?
  901.     JNZ    PRINT    ;NO - GO PRINT
  902.     DCX    H
  903.     DCR    C    ;YES-FIX OUTPUT DIGIT COUNT
  904.     JM    ZERO
  905.     JMP    TRL3
  906. ; HERE START THE PRINT FORMAT ROUTINES
  907. PRINT:    LXI    H,ABUF
  908.     MOV    A,M    ;CHECK IF ROUNDED UP TO 1
  909.     ORA    A
  910.     JZ    NRND    ;JUMP IF NOT
  911.     MVI    B,1
  912.     LDA    XSIGN    ;IS EXPONENT NEGATIVE
  913.     ORA    A
  914.     JZ    POSR
  915.     MVI    B,-1
  916. POSR:    LDA    EXPO    ;GET EXPONENT
  917.     ORA    A
  918.     JNZ    PO2    ;IS IT ZERO? (E+0)
  919.     STA    XSIGN
  920.     MVI    B,1
  921. PO2:    ADD    B    ;FIX EXPONENT COUNT
  922.     STA    EXPO
  923.     INR    E
  924.     INR    C
  925.     DCX    H
  926. NRND:    INX    H
  927.     MOV    A,C
  928.     CPI    DIGIT*2+1    ;CHECK FOR MAXIMUM DIGITS OUT
  929.     JNZ    $+4
  930.     DCR    C
  931.     LDA    HL+DIGIT
  932.     RAR
  933.     JNC    PRIN2
  934.     CALL    NEG
  935.     JMP    PRIN2+3
  936. PRIN2:    CALL    SPACE
  937.     LDA    FES    ;GET OUTPUT FORMAT
  938.     RAR
  939.     JC    XPRIN
  940.     LDA    XSIGN    ;GET EXPONENT SIGN
  941.     ORA    A
  942.     JZ    POSIT
  943. PRIN3:    MOV    A,C    ;CHECK IF FRACTIONAL NUMBER
  944.     ORA    A
  945.     RZ
  946.     RM
  947. PRIN4:    CALL    RADIX    ;PRINT DECIMAL POINT
  948.     XRA    A
  949.     ORA    E
  950.     JZ    PRIN5    ;JUMP IF NO ZEROS TO PRINT
  951.     CALL    ZERO    ;FORCE PRINT A ZERO
  952.     DCR    E
  953.     JNZ    PRIN4+3
  954. PRIN5:    CALL    NOUT    ;PRINT ASCII DIGIT
  955.     JNZ    PRIN5
  956.     RET
  957. POSIT:    CALL    NOUT
  958.     DCR    E    ;BUMP EXPONENT COUNT
  959.     JNZ    POSIT
  960.     JMP    PRIN3    ;NOW PRINT DECIMAL POINT
  961. ; GET HERE FOR EXPONENTIAL OUTPUT FORMAT
  962. XPRIN:    CALL    NOUT    
  963.     JZ    NDEC    ;INTEGER?
  964.     CALL    RADIX    ;NO...PRINT DECIMAL POINT
  965. XPRI2:    CALL    NOUT
  966.     JNZ    XPRI2
  967. NDEC:    CALL    SPACE
  968.     MVI    B,'E'
  969.     CALL    OUTB
  970.     LDA    XSIGN
  971.     ORA    A
  972.     JZ    XPRI3
  973.     CALL    NEG    ;PRINT EXPONENT SIGN (-)
  974.     LDA    EXPO
  975.     INR    A
  976.     JMP    XOUT2
  977. XPRI3:    MVI    B,'+'    ;EXPONENT (+)
  978.     CALL    OUTB
  979. ; THIS ROUTINE IS USED TO CONVERT THE EXPONENT
  980. ; FROM BINARY TO ASCII AND PRINT THE RESULT
  981. XOUT:    LDA    EXPO
  982.     DCR    A
  983. XOUT2:    MVI    C,100
  984.     MVI    D,0
  985.     CALL    CONV
  986.     CPI    '0'    ;SKIP LEADING ZEROS
  987.     JZ    $+7
  988.     INR    D
  989.     CALL    OUTB
  990.     MOV    A,E
  991.     MVI    C,10
  992.     CALL    CONV
  993.     CPI    '0'
  994.     JNZ    $+7
  995.     DCR    D
  996.     JNZ    $+6
  997.     CALL    OUTB
  998.     MOV    A,E
  999.     ADI    '0'    ;ADD ASCII BIAS
  1000.     MOV    B,A
  1001.     CALL    OUTB
  1002.     RET
  1003. CONV:    MVI    B,'0'-1
  1004.     INR    B
  1005.     SUB    C
  1006.     JNC    CONV+2
  1007.     ADD    C
  1008.     MOV    E,A
  1009.     MOV    A,B
  1010.     RET
  1011. ; THIS ROUTINE ADDS ASCII BIAS TO A BCD DIGIT
  1012. ;    AND CALLS THE OUTPUT ROUTINE
  1013. NOUT:    MOV    A,M
  1014.     ADI    '0'
  1015.     MOV    B,A
  1016.     CALL    OUTB
  1017.     INX    H    
  1018.     DCR    C
  1019.     RET
  1020. ; COMMON SYMBOL LOADING ROUTINES
  1021. NEG:    MVI    B,'-'
  1022.     JMP    OUTB
  1023. ZERO:    MVI    B,'0'
  1024.     JMP    OUTB
  1025. SPACE:    MVI    B,' '
  1026.     JMP    OUTB
  1027. RADIX:    MVI    B,'.'
  1028.     JMP    OUTB
  1029. ; OUTPUT DRIVER
  1030. OUTB:    PUSH    B
  1031.     IF    PROCT
  1032.     IN    STAT    ;STATUS PORT
  1033.     ANI    TBE+DAV    ;CHECK FOR "ESCAPE"
  1034.     JP    OUTB+1
  1035.     ANI    DAV
  1036.     JZ    OUTB2
  1037.     IN    DATA
  1038.     ANI    7FH
  1039.     CPI    1BH    ; ESCAPE
  1040.     JZ    READ    ;STOP OUTPUT
  1041. OUTB2:    MOV    A,B
  1042.     CALL    9060H
  1043.     ENDIF
  1044.     IF    INTEL
  1045.     CALL    CSTS
  1046.     ORA    A
  1047.     JZ    OUTB2
  1048.     CALL    CI
  1049.     ANI    7FH
  1050.     CPI    1BH
  1051.     JZ    READ
  1052. OUTB2:    MOV    C,B
  1053.     CALL    CO
  1054.     ENDIF
  1055.     CPI    0DH    ;CHECK IF CARRIAGE RETURN FOR TERM WIDTH
  1056.     JZ    OUTR
  1057.     LDA    WIDTH
  1058.     MOV    C,A
  1059.     LDA    WIDEC
  1060.     INR    A    ;UPDATE CHAR COUNT
  1061.     CMP    C
  1062.     JNZ    OUTR+1
  1063.     CALL    CRLF    ;NEW LINE
  1064. OUTR:    XRA    A
  1065.     STA    WIDEC
  1066.     POP    B
  1067.     MOV    A,B
  1068.     RET
  1069. ; OUTPUT A CARRIAGE RETURN, LINE FEED
  1070. ; FOLLOWED BY TWO DELETES
  1071. CRLF:    MVI    B,0DH
  1072.     CALL    OUTB
  1073.     MVI    B,0AH
  1074.     CALL    OUTB
  1075.     MVI    B,7FH
  1076.     CALL    OUTB
  1077.     JMP    OUTB
  1078. ; INPUT DATA ROUTINE
  1079. INB:
  1080.     IF    PROCT
  1081.     IN    STAT
  1082.     ANI    DAV
  1083.     JZ    INB
  1084.     IN    DATA
  1085.     ENDIF
  1086.     IF    INTEL
  1087.     CALL    CI
  1088.     ENDIF
  1089.     ANI    7FH
  1090.     MOV    B,A
  1091.     RET
  1092. ; GLOBAL PARAMETERS
  1093. INFES:    DS    1
  1094. WIDTH:    DS    1
  1095. USRST:    DS    2
  1096. ADDS:    DS    2
  1097. ADD:    DS    2
  1098. BCADD:    DS    2
  1099. WIDEC:    DS    1
  1100. TEMP:    DS    1
  1101. OPST:    DS    1
  1102. OPSTR:    DS    1
  1103. ECNT:    DS    1
  1104. SIGN:    DS    1
  1105. DEST:    DS    2
  1106. IBUF:    DS    73
  1107. ABUF:    DS    DIGIT*2+2
  1108. XSIGN:    DS    1
  1109. EXPO:    DS    1
  1110. FES:    DS    1
  1111. SQR:    DS    1
  1112. REGA:    DS    DIGIT+2
  1113. REGB:    DS    DIGIT+2
  1114. REGC:    DS    DIGIT+2
  1115. REGD:    DS    DIGIT+2
  1116. REGE:    DS    DIGIT+2
  1117. BC:    DS    DIGIT+2
  1118. HL:    DS    DIGIT+2
  1119. DE:    DS    DIGIT+2
  1120. S3:    DS    DIGIT+2
  1121. S4:    DS    DIGIT+2
  1122. MAXCL    EQU    $-OPST
  1123.     DS    (DIGIT+2)*10
  1124.     DS    50
  1125. STACK:    DW    0
  1126. FADD:    PUSH    B
  1127.     CALL    L0F77
  1128.     MVI    C,000H
  1129. L0DB8:    DCX    D
  1130.     XCHG    
  1131.     LDA    L0FFE
  1132.     XRA    M
  1133.     MOV    B,A
  1134.     XCHG    
  1135.     LDAX    D
  1136.     DCX    D
  1137.     XRA    C
  1138.     STA    L0FFE
  1139.     MOV    A,B
  1140.     ANI    001H
  1141.     JNZ    L0E05
  1142.     CALL    L0DE3
  1143.     JNC    L0DDE
  1144.     MVI    B,004H
  1145.     CALL    L0FBE
  1146.     LXI    H,EXP
  1147.     INR    M
  1148.     JZ    L0FE4
  1149. L0DDE:    POP    B
  1150.     CALL    L0FB0
  1151.     RET    
  1152. L0DE3:    LXI    H,BUF+DIGIT-1
  1153.     MVI    B,DIGIT
  1154.     ORA    A
  1155. L0DE9:    LDAX    D
  1156.     ADC    M
  1157.     DAA    
  1158.     MOV    M,A
  1159.     DCX    H
  1160.     DCX    D
  1161.     DCR    B
  1162.     JNZ    L0DE9
  1163.     RNC    
  1164.     INR    M
  1165.     RET    
  1166. FSUB:    PUSH    B
  1167.     CALL    L0F77
  1168.     LDA    L0FFE
  1169.     XRI    001H
  1170.     STA    L0FFE
  1171.     JMP    L0DB8
  1172. L0E05:    CALL    L0E51
  1173.     LXI    H,L0FFE
  1174.     JNC    L0E15
  1175.     MOV    A,M
  1176.     XRI    001H
  1177.     MOV    M,A
  1178.     JMP    L0E25
  1179. L0E15:    DCX    H
  1180.     MVI    B,DIGIT
  1181. L0E18:    MVI    A,09AH
  1182.     SBB    M
  1183.     ADI    000H
  1184.     DAA    
  1185.     MOV    M,A
  1186.     DCX    H
  1187.     DCR    B
  1188.     CMC    
  1189.     JNZ    L0E18
  1190. L0E25:    LXI    H,BUF
  1191.     XRA    A
  1192.     MVI    C,DIGIT
  1193. L0E2B:    CMP    M
  1194.     JNZ    L0E3A
  1195.     INX    H
  1196.     DCR    C
  1197.     JNZ    L0E2B
  1198.     STA    EXP
  1199.     JMP    L0DDE
  1200. L0E3A:    LDA    BUF
  1201.     ANI    0F0H
  1202.     JNZ    L0DDE
  1203.     LXI    H,EXP
  1204.     DCR    M
  1205.     JZ    L0FEC
  1206.     MVI    B,004H
  1207.     CALL    L0FD1
  1208.     JMP    L0E3A
  1209. L0E51:    LXI    H,BUF+DIGIT-1
  1210.     MVI    B,DIGIT
  1211.     STC    
  1212. L0E57:    MVI    A,099H
  1213.     ACI    000H
  1214.     XCHG    
  1215.     SUB    M
  1216.     XCHG    
  1217.     ADD    M
  1218.     DAA    
  1219.     MOV    M,A
  1220.     DCX    H
  1221.     DCX    D
  1222.     DCR    B
  1223.     JNZ    L0E57
  1224.     RET    
  1225. FMULT:    PUSH    B
  1226.     MOV    A,M
  1227.     ORA    A
  1228.     JZ    L0E82
  1229.     LDAX    D
  1230.     ORA    A
  1231.     JZ    L0E82
  1232.     ADD    M
  1233.     JC    L0E7D
  1234.     JP    L0FEC
  1235.     JMP    L0E80
  1236. L0E7D:    JM    L0FE4
  1237. L0E80:    SUI    080H
  1238. L0E82:    STA    EXP
  1239.     DCX    D
  1240.     DCX    H
  1241.     LDAX    D
  1242.     XRA    M
  1243.     STA    L0FFE
  1244.     DCX    H
  1245.     DCX    D
  1246.     MOV    C,L
  1247.     MOV    B,H
  1248.     MVI    A,DIGIT+1
  1249.     LXI    H,L0FF7
  1250. L0E95:    MVI    M,0
  1251.     INX    H
  1252.     DCR    A
  1253.     JNZ    L0E95
  1254.     LXI    H,DIGIT+DIGIT
  1255. L0E9F:    LDAX    B
  1256. L0EA0:    PUSH    H
  1257.     ANI    0FH
  1258.     PUSH    B
  1259.     MOV    C,A
  1260.     JZ    L0EB5
  1261. L0EA8:    CALL    L0DE3
  1262.     XCHG    
  1263.     LXI    D,DIGIT
  1264.     DAD    D
  1265.     XCHG    
  1266.     DCR    C
  1267.     JNZ    L0EA8
  1268. L0EB5:    MVI    B,4
  1269.     CALL    L0FBE
  1270.     POP    B
  1271.     POP    H
  1272.     DCR    L
  1273.     JZ    L0ECF
  1274.     DCR    H
  1275.     JP    L0E9F
  1276.     INR    H
  1277.     INR    H
  1278.     LDAX    B
  1279.     RAR    
  1280.     RAR    
  1281.     RAR    
  1282.     RAR    
  1283.     DCX    B
  1284.     JMP    L0EA0
  1285. L0ECF:    LDA    BUF
  1286.     ANI    0F0H
  1287.     JNZ    L0DDE
  1288.     MVI    B,004H
  1289.     LXI    H,EXP
  1290.     DCR    M
  1291.     JZ    L0FEC
  1292.     CALL    L0FD1
  1293.     JMP    L0DDE
  1294. FDIV:    PUSH    B
  1295.     MOV    A,M
  1296.     ORA    A
  1297.     JZ    L0FF1
  1298.     LDAX    D
  1299.     ORA    A
  1300.     JZ    L0FE9
  1301.     SUB    M
  1302.     JC    L0EFB
  1303.     JM    L0FE4
  1304.     JMP    L0EFE
  1305. L0EFB:    JP    L0FEC
  1306. L0EFE:    ADI    081H
  1307.     STA    EXP
  1308.     XCHG    
  1309.     CALL    L0F9B
  1310.     POP    B
  1311.     XCHG    
  1312.     LDA    L0FFE
  1313.     DCX    H
  1314.     XRA    M
  1315.     STA    L0FFE
  1316.     XCHG    
  1317.     DCX    D
  1318.     LXI    H,-DIGIT-1
  1319.     DAD    B
  1320.     MOV    B,H
  1321.     MOV    C,L
  1322. L0F19:    MVI    L,DIGIT+DIGIT
  1323. L0F1B:    PUSH    B
  1324.     PUSH    H
  1325.     MVI    C,0
  1326. L0F1F:    CALL    L0E51
  1327.     MOV    A,M
  1328.     CMC    
  1329.     SBI    0
  1330.     MOV    M,A
  1331.     RAR    
  1332.     LXI    H,DIGIT
  1333.     DAD    D
  1334.     XCHG    
  1335.     INR    C
  1336.     RAL    
  1337.     JNC    L0F1F
  1338.     CALL    L0DE3
  1339.     LXI    H,DIGIT
  1340.     DAD    D
  1341.     XCHG    
  1342.     PUSH    B
  1343.     MVI    B,4
  1344.     CALL    L0FD1
  1345.     POP    B
  1346.     DCR    C
  1347.     POP    H
  1348.     MOV    H,C
  1349.     POP    B
  1350.     MOV    A,L
  1351.     JNZ    L0F58
  1352.     CPI    DIGIT+DIGIT
  1353.     JNZ    L0F58
  1354.     LXI    H,EXP
  1355.     DCR    M
  1356.     CZ    L0FEC
  1357.     JMP    L0F19
  1358. L0F58:    RAR    
  1359.     MOV    A,H
  1360.     JNC    L0F68
  1361.     LDAX    B
  1362.     RLC    
  1363.     RLC    
  1364.     RLC    
  1365.     RLC    
  1366.     ADD    H
  1367.     STAX    B
  1368.     INX    B
  1369.     JMP    L0F69
  1370. L0F68:    STAX    B
  1371. L0F69:    DCR    L
  1372.     JNZ    L0F1B
  1373.     LDA    L0FFE
  1374.     STAX    B
  1375.     LDA    EXP
  1376.     INX    B
  1377.     STAX    B
  1378.     RET    
  1379. L0F77:    LDAX    D
  1380.     SUB    M
  1381.     MVI    C,000H
  1382.     JNC    L0F82
  1383.     INR    C
  1384.     XCHG    
  1385.     CMA    
  1386.     INR    A
  1387. L0F82:    MOV    B,A
  1388.     LDAX    D
  1389.     STA    EXP
  1390.     MOV    A,B
  1391.     CPI    DIGIT+DIGIT
  1392.     JC    L0F8F
  1393.     MVI    A,DIGIT+DIGIT
  1394. L0F8F:    RLC    
  1395.     RLC    
  1396.     MOV    B,A
  1397.     PUSH    B
  1398.     CALL    L0F9B
  1399.     CALL    L0FBE
  1400.     POP    B
  1401.     RET    
  1402. L0F9B:    PUSH    D
  1403.     LXI    D,L0FFE
  1404.     MVI    C,DIGIT+1
  1405.     DCX    H
  1406. L0FA2:    MOV    A,M
  1407.     STAX    D
  1408.     DCX    H
  1409.     DCX    D
  1410.     DCR    C
  1411.     JNZ    L0FA2
  1412.     XRA    A
  1413.     STAX    D
  1414.     DCX    D
  1415.     STAX    D
  1416.     POP    D
  1417.     RET    
  1418. L0FB0:    LXI    H,EXP
  1419.     MVI    E,DIGIT+2
  1420. L0FB5:    MOV    A,M
  1421.     STAX    B
  1422.     DCX    B
  1423.     DCX    H
  1424.     DCR    E
  1425.     JNZ    L0FB5
  1426.     RET    
  1427. L0FBE:    LXI    H,BUF-1
  1428.     DCR    B
  1429.     RM    
  1430.     ORA    A
  1431.     MVI    C,DIGIT+1
  1432. L0FC6:    MOV    A,M
  1433.     RAR    
  1434.     MOV    M,A
  1435.     INX    H
  1436.     DCR    C
  1437.     JNZ    L0FC6
  1438.     JMP    L0FBE
  1439. L0FD1:    LXI    H,BUF+DIGIT-1
  1440.     DCR    B
  1441.     RM    
  1442.     ORA    A
  1443.     MVI    C,DIGIT+1
  1444. L0FD9:    MOV    A,M
  1445.     RAL    
  1446.     MOV    M,A
  1447.     DCX    H
  1448.     DCR    C
  1449.     JNZ    L0FD9
  1450.     JMP    L0FD1
  1451. L0FE4:    MVI    A,001H
  1452. L0FE6:    STA    ERRI
  1453. L0FE9:    INX    SP
  1454.     INX    SP
  1455.     RET    
  1456. L0FEC:    MVI    A,-1
  1457.     JMP    L0FE6
  1458. L0FF1:    MVI    A,2
  1459.     JMP    L0FE6
  1460. ERRI:    DB    0    
  1461. L0FF7:    DB    0    
  1462. BUF:    DS    DIGIT
  1463. L0FFE:    DB    0
  1464. EXP:    DB    84H
  1465.     END
  1466.