home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug011.ark / BASIC_5.ASM next >
Encoding:
Assembly Source File  |  1984-04-29  |  75.8 KB  |  4,627 lines

  1. ;  HAMPSHIRE COLLEGE 5K BASIC
  2. ;  ==========================
  3. ;
  4. ;
  5. ;  KEVIN JORDAN'S CP/M ADAPTATION OF PROCESSOR TECH
  6. ;  5K BASIC.
  7. ;
  8. ;  THIS IS VERSION Z1.0 FROM JEFF ZURKOW, WITH THE FOLLOWING
  9. ;  ADDITIONAL FEATURES:
  10. ;
  11. ;    1. THE BEAM AND DRAW STATEMENTS FOR TEKTRONIX TERMINALS.
  12. ;    2. LLIST COMMAND AND LPRINT STATEMENT FOR LINE PRINTER OUTPUT.
  13. ;    3. ARRAYS CLEARED ONLY WHEN DIMENSION STATEMENT EXECUTED,
  14. ;       ONLY USED SYMBOL TABLE SPACE CLEARED. (ORIGINAL VERSION
  15. ;       CLEARED ALL OF NON-PROGRAM MEMORY EACH TIME A STATEMENT
  16. ;       WAS TYPED IN).
  17. ;
  18. ;
  19. ;
  20. ;
  21. ;    SYSTEM GLOBAL EQUATES
  22. ;
  23.     ORG    100H
  24. SYSTEM    EQU    5    ;ENTRY TO CP/M
  25. TFCB    EQU    5CH    ;DEFAULT FCB ADDR
  26. TBUFF    EQU    80H    ;DEFAULT DMA ADDR
  27. NR    EQU    TFCB+32    ;NEXT RECORD INDEX
  28. FPSIZ    EQU    5
  29. LINLEN    EQU    80    ;# CHARS IN LEGAL INPUT LINE
  30. FP123    EQU    FPSIZ-2
  31. FPNIB    EQU    FP123*2
  32. DIGIT    EQU    FPNIB/2
  33. CR    EQU    15Q
  34. NULL    EQU    0
  35. LF    EQU    12Q
  36. ESC    EQU    3Q    ;CONTROL-C
  37. RUBOUT    EQU    7FH
  38. CNTRU    EQU    15H    ;CONTROL-U
  39. EOF    EQU    1    ;END OF FILE
  40. BELL    EQU    7    ;BELL CHARACTER
  41. STESIZ    EQU    2+FPSIZ    ;SYMBOL TABLE ELEMENT SIZE
  42. OPBASE    EQU    '('
  43. FTYPE    EQU    1    ;CONTROL STACK FOR ENTRY TYPE
  44. FORSZ    EQU    FPSIZ*2+2+2+1    ;'FOR' CONTROL STACK ENTRY SIZE
  45. GTYPE    EQU    2    ;CONTROL STACK GOSUB ENTRY TYPE
  46. ETYPE    EQU    0    ;CONTROL STACK UNDERFLOW TYPE
  47. UMINU    EQU    61Q    ;UNARY MINUS
  48. ;
  49. ;    STARTUP BASIC SYSTEM
  50. ;
  51. START:    LXI    SP,CMNDSP
  52.     XRA    A
  53.     STA    NULLCT    ;INITIALIZE NULL COUNT
  54.     STA    PFLAG    ;TURN OF LINE-PRINTER FLAG
  55.     INR    A
  56.     STA    DIRF    ;INITIALIZE DIRECT INPUT FLAG
  57.     LXI    H,MEMTOP+2 ;FIRST FREE BYTE AFTER INTERPRETTER
  58.     SHLD    BOFA    ;START OF USER ASSIGNED MEMORY
  59.     LHLD    SYSTEM+1 ;ADDRESS OF BDOS
  60.     DCX    H    ;SET LAST POSSIBLE FREE BYTE BEFORE BDOS
  61.     SHLD    MEMTOP    ;END OF ASSIGNED MEMORY POINTER
  62.     SHLD    STB    ;INITIALIZE END OF SYMBOL TABLE
  63.     CALL    CSCR    ;INITIALIZE FREE-SPACE
  64.     CALL    CRLF
  65.     LXI    H,HEAD    ;OUTPUT HEADER MESSAGE
  66.     CALL    PRNT
  67.     CALL    CRLF
  68.     CALL    CRLF2
  69.     LXI    H,TFCB+1;TEST FOR FILE NAME IN BASIC INVOCATION
  70.     MOV    A,M
  71.     CPI    ' '
  72.     JZ    ST0    ;IF NO FILE NAME
  73.     LXI    D,WSIDN
  74.     MVI    C,8
  75.     CALL    COPY
  76.     MOV    A,M    ;TEST FOR FILE TYPE SPECIFIED
  77.     CPI    ' '
  78.     JNZ    STRT1    ;IF TYPE SPECIFIED
  79.     LXI    H,WSIDD+8 ;DEFAULT TYPE
  80. STRT1:    LXI    D,WSIDT
  81.     MVI    C,3
  82.     CALL    COPY    ;SET FILE TYPE
  83.     JMP    COLD3    ;FETCH THE FILE
  84. ;
  85. ;    COPY - COPIES NUMBER OF BYTES IN C
  86. ;    FROM ADDRESS IN HL TO ADDR IN DE
  87. ;
  88. COPY:    MOV    A,M
  89.     STAX    D
  90.     INX    H
  91.     INX    D
  92.     DCR    C
  93.     JNZ    COPY
  94.     RET
  95. ;
  96. ST0:    LXI    H,PLS    ;'NEW OR OLD' MESSAGE
  97.     CALL    PRNT
  98. STAR1:    CALL    INLINE
  99.     LDA    IBUF
  100.     CPI    'N'    ;IS IT A 'NEW' COMMAND?
  101.     JZ    CNEW1    ;IF 'NEW' COMMAND
  102.     CPI    'O'
  103.     JZ    COLD1    ;IF 'OLD' COMMAND
  104.     JMP    ST0
  105. ;
  106. COLD:    CALL    CSCR    ;CLEAR WORK-SPACE
  107.     CALL    GC    ;FIND FIRST NON-BLANK
  108.     CPI    CR
  109.     JNZ    COLD2    ;IF FILE NAME IN-LINE
  110. COLD1:    LXI    H,OPN    ;PRINT 'OLD PROGRAM NAME: '
  111.     CALL    PRNT
  112.     CALL    INLINE    ;GET THE WSID
  113.     LXI    H,IBUF
  114.     SHLD    TXA
  115. COLD2:    CALL    WSID    ;GET THE WORK-SPACE ID
  116. COLD3:    CALL    FETCH    ;LOAD THE PROGRAM
  117.     JMP    ST4
  118. ;
  119. CNEW:    CALL    CSCR    ;CLEAR WORK-SPACE
  120.     CALL    GC
  121.     CPI    CR
  122.     JNZ    CNEW2    ;IF FILE NAME IN-LINE
  123. CNEW1:    LXI    H,NPN    ;PRINT 'NEW PROGRAM NAME: '
  124.     CALL    PRNT
  125.     CALL    INLINE    ;GET THE WSID
  126.     LXI    H,IBUF
  127.     SHLD    TXA
  128. CNEW2:    CALL    WSID    ;SAVE IT
  129. ST4:    MVI    A,2*FPNIB
  130.     STA    INFES
  131. ;
  132. ;    INITIALIZE RANDOM NUMBER
  133. ;
  134.     LXI    D,FRAND
  135.     LXI    H,RANDS
  136.     CALL    VCOPY    ;FRAND=RANDOM NUMBER SEED
  137. ;
  138. ;    COMMAND PROCESSOR
  139. ;
  140. CMND1:    CALL    CRLF2
  141.     LXI    H,RDYS    ;PRINT READY MESSAGE
  142.     CALL    PRNT
  143. CMNDR:    MVI    A,1    ;SET DIRECT INPUT FLAG
  144.     STA    DIRF
  145.     LXI    SP,CMNDSP
  146.     CALL    CRLF
  147. CMND2:    CALL    INLINE    ;GET INPUT FROM OPERATOR
  148.     CALL    PP    ;PRE-PROCESS IT
  149.     JC    CMND3
  150.     CALL    LINE    ;LINE NUMBER . . . GO EDIT
  151.     CALL    CCLEAR
  152.     JMP    CMND2
  153. ;
  154. CMND3:    CALL    CMND4
  155.     JMP    CMNDR
  156. ;
  157. CMND4:    LXI    H,IBUF    ;POINT TO COMMAND OR STATEMENT
  158.     SHLD    TXA
  159.     CALL    GC
  160.     ANI    240Q
  161.     CPI    240Q    ;CHECK FOR COMMAND
  162.     LXI    D,CMNDD
  163.     JZ    ISTA1    ;PROCESS COMMAND
  164.     CALL    ISTAT    ;PROCESS STATEMENT (IF ALLOWED)
  165.     CALL    GCI
  166.     CPI    CR
  167.     RZ
  168. E1:    LXI    H,SYNTX
  169.     JMP    ERROR
  170. ;
  171. ;    ERROR MESSAGE PRINTOUT
  172. ;
  173. E3:    LXI    H,ARGUM
  174.     JMP    ERROR
  175. ;
  176. E4:    LXI    H,CSTAK
  177.     JMP    ERROR
  178. ;
  179. E5:    LXI    H,BOUND
  180.     JMP    ERROR
  181. ;
  182. E6:    LXI    H,DIMEN
  183. ;
  184. ERROR:    PUSH    H
  185.     LDA    DIRF    ;CHECK INPUT MODE
  186.     ORA    A
  187.     JNZ    ERRO1    ;IF DIRECT INPUT MODE
  188.     LHLD    TRPSP    ;CHECK FOR TRAPS SET
  189.     LXI    B,-TRPSTK
  190.     DAD    B
  191.     MOV    A,H
  192.     ORA    L
  193.     JZ    ERRO1    ;IF TRAP STACK EMPTY
  194.     LHLD    TRPSP    ;POP LINE NUMBER
  195.     INX    H
  196.     MOV    E,M
  197.     INX    H
  198.     MOV    D,M
  199.     SHLD    TRPSP
  200.     CALL    FINDLN    ;FIND THE LINE
  201.     INX    H    ;ADVANCE POINTER BEYOND LINE # AND COUNT
  202.     INX    H
  203.     INX    H
  204.     SHLD    TXA    ;UPDATE TXA
  205.     LXI    SP,CMNDSP ;CLEAN UP
  206.     JMP    ILOOP    ;CONTINUE EXECUTION FROM TRAP LINE
  207. ;
  208. ERRO1:    CALL    CRLF
  209.     POP    H
  210.     CALL    PRNT
  211.     LXI    H,ERS
  212. ERM1:    CALL    PRNT
  213.     LDA    DIRF
  214.     ORA    A
  215.     JNZ    CMND1
  216.     LXI    H,INS
  217.     CALL    PRNT
  218. ;
  219. ;    FIND LINE NUMBER
  220. ;
  221.     LHLD    BOFA
  222. ERM2:    MOV    B,H
  223.     MOV    C,L
  224.     MOV    E,M
  225.     MVI    D,0
  226.     DAD    D
  227.     XCHG
  228.     LXI    H,TXA
  229.     CALL    DCMP
  230.     XCHG
  231.     JC    ERM2
  232.     INX    B
  233.     LDAX    B
  234.     MOV    L,A
  235.     INX    B
  236.     LDAX    B
  237.     MOV    H,A
  238.     LXI    D,IBUF    ;USE IBUF TO ACCUMULATE LINE NO. STRING
  239.     CALL    CNS
  240.     MVI    A,CR
  241.     STAX    D
  242.     LXI    H,IBUF
  243.     CALL    PRNTCR
  244.     JMP    CMND1
  245. ;
  246. ;    LINE EDITOR
  247. ;
  248. LINE:    LHLD    BOFA    ;CHECK FOR EMPTY FILE
  249. FIN:    MOV    A,M    ;CHECK IF APPENDING LINE AT END
  250.     DCR    A
  251.     JZ    APP
  252.     XCHG
  253.     INX    D
  254.     LHLD    IBLN    ;GET INPUT LINE NUMBER
  255.     XCHG
  256.     CALL    DCMP    ;COMPARE WITH FILE LINE NUMBER
  257.     DCX    H
  258.     JC    INSR    ;LESS THAN
  259.     JZ    INSR    ;EQUAL
  260.     MOV    A,M    ;LENGTH OF LINE
  261.     CALL    ADR    ;JUMP FORWARD
  262.     JMP    FIN
  263. ;
  264. ;    APPEND LINE AT END CASE
  265. ;
  266. APP:    LDA    IBCNT    ;DONT APPEND NULL LINE
  267.     CPI    4
  268.     RZ
  269.     CALL    FULL    ;CHECK FOR ROOM IN FILE
  270.     LHLD    EOFA    ;PLACE LINE IN FILE
  271.     CALL    IMOV
  272.     MVI    M,EOF
  273.     SHLD    EOFA
  274.     RET
  275. ;
  276. ;    INSERT LINE IN FILE CASE
  277. ;
  278. INSR:    MOV    B,M    ;OLD LINE COUNT
  279.     SHLD    INSA    ;INSERT LINE POINTER
  280.     LDA    IBCNT    ;NEW LINE COUNT
  281.     JC    LT    ;JMP IF NEW LINE #<>OLD LINE #
  282.     SUI    4
  283.     JZ    LT1    ;TEST IF SHOULD DELETE NULL LINE
  284.     ADI    4
  285. LT1:    SUB    B
  286.     JZ    LIN1    ;LINE LENGTHS EQUAL
  287.     JC    GT
  288. ;
  289. ;    EXPAND FILE FOR NEW OR LARGER LINE
  290. ;
  291. LT:    MOV    B,A
  292.     LDA    IBCNT
  293.     CPI    4    ;DON'T INSERT NULL LINE
  294.     RZ
  295.     MOV    A,B
  296.     CALL    FULL
  297.     LHLD    INSA
  298.     CALL    NMOV
  299.     LHLD    EOFA
  300.     XCHG
  301.     SHLD    EOFA
  302.     INX    B
  303.     CALL    RMOV
  304.     JMP    LIN1
  305. ;
  306. ;    CONTRACT FILE FOR SMALLER LINE
  307. ;
  308. GT:    CMA
  309.     INR    A
  310.     CALL    ADR
  311.     CALL    NMOV
  312.     XCHG
  313.     LHLD    INSA
  314.     CNZ    LMOV
  315.     MVI    M,EOF
  316.     SHLD    EOFA
  317. ;
  318. ;    INSERT CURRENT LINE INTO FILE
  319. ;
  320. LIN1:    LHLD    INSA
  321.     LDA    IBCNT
  322.     CPI    4
  323.     RZ
  324. ;
  325. ;    INSERT CURRENT LINE AT ADDR HL
  326. ;
  327. IMOV:    LXI    D,IBCNT
  328.     LDAX    D
  329.     MOV    C,A
  330.     MVI    B,0
  331. ;
  332. ;    COPY BLOCK FROM BEGINNING
  333. ;    HL IS DESTIN ADDR, DE IS SOURCE ADDR, BC IS COUNT
  334. ;
  335. LMOV:    LDAX    D
  336.     MOV    M,A
  337.     INX    D
  338.     INX    H
  339.     DCX    B
  340.     MOV    A,B
  341.     ORA    C
  342.     JNZ    LMOV
  343.     RET
  344. ;
  345. ;    COPY BLOCK STARTING AT END
  346. ;    HL IS DESTIN ADDR, DE IS SOURCE ADDR, BC IS COUNT
  347. ;
  348. RMOV:    LDAX    D
  349.     MOV    M,A
  350.     DCX    H
  351.     DCX    D
  352.     DCX    B
  353.     MOV    A,B
  354.     ORA    C
  355.     JNZ    RMOV
  356.     RET
  357. ;
  358. ;    COMPUTE FILE MOVE COUNT
  359. ;
  360. ;    BC GETS (EOFA)-(HL), RET Z SET MEANS ZERO COUNT
  361. ;
  362. NMOV:    LDA    EOFA
  363.     SUB    L
  364.     MOV    C,A
  365.     LDA    EOFA+1
  366.     SBB    H
  367.     MOV    B,A
  368.     ORA    C
  369.     RET
  370. ;
  371. ;    ADD A TO HL
  372. ;
  373. ADR:    ADD    L
  374.     MOV    L,A
  375.     RNC
  376.     INR    H
  377.     RET
  378. ;
  379. ;    CHECK FOR FILE OVERFLOW, LEAVES NEW EOFA IN DE
  380. ;    A HAS INCREASE IN SIZE
  381. ;
  382. FULL:    LHLD    EOFA
  383.     CALL    ADR
  384.     XCHG
  385.     LXI    H,MEMTOP
  386.     CALL    DCMP
  387.     JNC    E8
  388.     RET
  389. ;
  390. ;    COMMANDS
  391. ;
  392. CSCR:    LHLD    BOFA
  393.     MVI    M,EOF
  394.     SHLD    EOFA
  395. ;
  396. ;    'CLEAR'
  397. ;
  398. CCLEAR:    LHLD    EOFA    ;CLEAR FROM EOFA TO MEMTOP
  399.     INX    H
  400.     SHLD    MATA
  401.     LHLD    STB
  402.     XCHG
  403.     LXI    H,MEMTOP;END OF ASSIGNED MEMORY
  404. CCLR1:    XRA    A
  405.     STAX    D
  406.     CALL    DCMP
  407.     INX    D
  408.     JNZ    CCLR1
  409.     LHLD    MEMTOP
  410.     SHLD    STB
  411.     LXI    H,CSTKL+CSTKSZ-1
  412.     MVI    M,ETYPE
  413.     SHLD    CSTKA
  414.     LXI    H,ASTKL+ASTKSZ+FPSIZ-1
  415.     SHLD    ASTKA
  416.     RET
  417. ;
  418. ;    'NULL'
  419. ;
  420. CNULL:    CALL    INTGER
  421.     JC    E3    ;NO ARGUMENT SUPPLIED
  422.     MOV    A,L
  423.     STA    NULLCT
  424.     JMP    CMND1
  425. ;
  426. ;    'LIST'
  427. ;
  428. CLIST:    CALL    GC
  429.     CPI    CR
  430.     LXI    D,0
  431.     JZ    CL0    ;JUMP IF NO ARGUMENT SUPPLIED
  432.     CALL    INTGER    ;ERROR DEFAULT IS LIST
  433. CL0:    LHLD    BOFA
  434. CL1:    MOV    A,M
  435.     DCR    A
  436.     RZ
  437.     INX    H
  438.     CALL    DCMP
  439.     DCX    H    ;POINT TO COUNT CHAR AGAIN
  440.     JC    CL2
  441.     JZ    CL2
  442. ;
  443. ;    INCREMENT TO NEXT LINE
  444. ;
  445.     MOV    A,M
  446.     CALL    ADR
  447.     JMP    CL1
  448. CL2:    PUSH    D
  449.     LXI    D,IBUF    ;AREA TO UNPREPROCESS TO
  450.     CALL    UPPL
  451.     INX    H
  452.     PUSH    H
  453.     LXI    H,IBUF
  454.     CALL    PRNTCR
  455.     CALL    PCHECK
  456.     CALL    CRLF
  457.     POP    H
  458.     POP    D
  459.     JMP    CL1
  460. ;
  461. ;    'LLIST'
  462. ;
  463. LLIST:    MVI    A,1    ;SWITCH OUTPUT TO LINE PRINTER
  464.     STA    PFLAG
  465.     CALL    CRLF2
  466.     CALL    CLIST    ;CALL NORMAL LIST ROUTINE
  467.     CALL    CRLF2
  468.     XRA    A    ;SWITCH OUTPUT BACK TO CONSOLE
  469.     STA    PFLAG
  470.     RET
  471. ;
  472. ;    'RUN'
  473. ;
  474. CRUN:    CALL    CCLEAR
  475.     LHLD    BOFA
  476.     MOV    A,M
  477.     DCR    A    ;CHECK FOR NULL PROGRAM
  478.     JZ    CEND
  479.     INX    H
  480.     INX    H
  481.     INX    H
  482.     SHLD    TXA
  483.     SHLD    RTXA    ;POINTER FOR 'READ' STATEMENT
  484.     XRA    A
  485.     STA    DIRF    ;CALL DIRECT FLAG AND FALL THRU TO DRIVER
  486.     CALL    CRLF
  487. ;
  488. ;    INTERPRETTER DRIVER
  489. ;
  490. ILOOP:    CALL    PCHECK
  491.     CALL    ISTAT    ;INTERPRET CURRENT STATEMENT
  492.     CALL    JOE    ;TEST FOR JUNK ON END
  493.     JNC    ILOOP    ;CONTINUE IF NOT AT END OF PROGRAM
  494.     JMP    CEND    ;EXECUTE END STATEMENT
  495. ;
  496. ;    INTERPRET STATEMENNT LOCATED BY TXA
  497. ;
  498. ISTAT:    CALL    GC    ;GET FIRST NON BLANK
  499.     ORA    A
  500.     JM    ISTA0    ;IF RW
  501.     CPI    CR
  502.     JZ    CMND1    ;OUTPUT 'READY' IF BLANK LINE
  503.     JMP    LET    ;MUST BE 'LET' IF NOT RW OR CR
  504. ;
  505. ISTA0:    CPI    IRWLIM    ;IS IT AN INITIAL RW
  506.     JNC    E1
  507.     LXI    D,STATD    ;STATEMENT DISPATCH TABLE BASE
  508. ISTA1:    CALL    GCI    ;ADVANCE TEXT POINTER
  509.     ANI    37Q
  510.     RLC        ;MULTIPLY BY TWO PREPARING FOR TABLE LOOKUP
  511.     MOV    L,A
  512.     MVI    H,0
  513.     DAD    D
  514.     CALL    LHLI
  515.     PCHL        ;BRANCH TO STATEMENT OR COMMAND
  516. ;
  517. ;    STATEMENTS
  518. ;
  519. ;    'LET'
  520. ;
  521. LET:    CALL    VAR    ;CHECK FOR VARIABLE
  522.     JC    E1
  523.     PUSH    H    ;SAVE VALUE ADDRESS
  524.     MVI    B,EQRW
  525.     CALL    EATC
  526.     CALL    EXPRB
  527.     POP    D    ;DESTINATION ADDRESS
  528.     CALL    POPA1    ;COPY EXPRESSION VALUE TO VARIABLE
  529.     RET
  530. ;
  531. ;    'FOR'
  532. ;
  533. SFOR:    CALL    DIRT
  534.     CALL    VAR    ;CONTROL VARIABLE
  535.     JC    E1
  536.     PUSH    H    ;CONTROL VARIABLE VALUE ADDRESS
  537.     MVI    B,EQRW
  538.     CALL    EATC
  539.     CALL    EXPRB    ;INITIAL VALUE
  540.     POP    D    ;VARIABLE VALUE ADDRESS
  541.     PUSH    D    ;SAVE
  542.     CALL    POPA1    ;SET INITIAL VALUE
  543.     MVI    B,TORW    ;RW FOR 'TO'
  544.     CALL    EATC
  545.     CALL    EXPRB    ;LIMIT VALUE COMPUTATION
  546.     CALL    GC    ;CHECK NEXT CHARACTER FOR POSSIBLE STEP EXPRESSION
  547.     CPI    STEPRW
  548.     JZ    FOR1
  549. ;
  550. ;    USE STEP OF 1
  551. ;
  552.     LXI    D,FPONE
  553.     CALL    PSHA1
  554.     JMP    FOR2
  555. ;
  556. ;    COMPUTE STEP VALUE
  557. ;
  558. FOR1:    CALL    GCI    ;EAT THE STEP RW
  559.     CALL    EXPRB    ;THE STEP VALUE
  560. ;
  561. ;    HERE THE STEP AND LIMIT ARE ON ARG STACK
  562. ;
  563. FOR2:    LXI    D,-2    ;PREPARE TO ALLOCATE 2 BYTES ON CONTROL STACK
  564.     CALL    PSHCS    ;RETURNS ADDRESS OF THOSE 2 BYTES IN HL
  565.     XCHG
  566.     CALL    JOE    ;TEST FOR JUNK ON END
  567.     JC    E4    ;NO 'FOR' STATEMENT AT END OF PROGRAM
  568.     XCHG        ;DE HAS LOOP TEXT ADDR, HL HAS CONTROL STACK ADDR
  569.     MOV    M,D    ;HIGH ORDER TEXT ADDRESS BYTE
  570.     DCX    H
  571.     MOV    M,E    ;LOW ORDER TEXT ADDRESS BYTE
  572.     LXI    D,-FPSIZ;ALLOCATE SPACE FOR LIMIT ON CONTROL STACK
  573.     CALL    PSHCS
  574.     PUSH    H    ;ADDR ON CONTROL STACK FOR LIMIT
  575.     LXI    D,-FPSIZ;ALLOCATE SPACE FOR STEP ON CONTROL STACK
  576.     CALL    PSHCS
  577.     CALL    POPAS    ;COPY STEP VALUE TO CONTROL STACK
  578.     POP    D    ;CONTROL STACK ADDR FOR LIMIT VALUE
  579.     CALL    POPA1    ;LIMIT VALUE TO CONTROL STACK
  580.     LXI    D,-3    ;ALLOCATE SPACE FOR TEXT ADDR AND CS ENTRY
  581.     CALL    PSHCS
  582.     POP    D    ;CONTROL VARIABLE ADDR
  583.     MOV    M,D    ;HIGH ORDER BYTE OF CONTROL VARIABLE ADDR
  584.     DCX    H
  585.     MOV    M,E    ;LOW ORDER BYTE OF CONTROL VARIABLE ADDR
  586.     DCX    H
  587.     MVI    M,FTYPE    ;SET CONTROL STACK ENTRY TYPE FOR 'FOR'
  588.     JMP    NEXT5    ;GO FINISH OFF CAREFULLY
  589. ;
  590. ;    'NEXT'
  591. ;
  592. NEXT:    CALL    DIRT
  593.     LHLD    CSTKA    ;CONTROL STACK ADDR
  594.     MOV    A,M    ;STACK ENTRY TYPE BYTE
  595.     DCR    A    ;MUST BE FOR TYPE ELSE ERROR
  596.     JNZ    E4    ;IMPROPER NESTING ERROR
  597.     INX    H    ;CONTROL STACK POINTER TO CONTROL VARIABLE ADDR
  598.     PUSH    H
  599.     CALL    VAR    ;CHECK VARIABLE, IN CASE USER WANTS
  600.     JC    NEXT1    ;SKIP CHECK IF VAR NOT THERE
  601.     XCHG
  602.     POP    H    ;CONTROL VARIABLE ADDRESS
  603.     PUSH    H    ;SAVE IT AGAIN
  604.     CALL    DCMP
  605.     JNZ    E4    ;IMPROPER NESTING IF NOT THE SAME
  606. NEXT1:    POP    H    ;CONTROL VARIABLE ADDR
  607.     PUSH    H
  608.     PUSH    H
  609.     LXI    D,FPSIZ+2-1 ;COMPUTE ADDR TO STEP VALUE
  610.     DAD    D
  611.     XTHL        ;NOW ADDR TO VAR IN HL
  612.     CALL    LHLI    ;VARIABLE ADDR
  613.     MOV    B,H    ;COPY VAR ADDR TO BC
  614.     MOV    C,L
  615.     POP    D    ;STEP VALUE ADDR
  616.     PUSH    D
  617.     CALL    FADD    ;DO INCREMENT
  618.     POP    H    ;STEP VALUE
  619.     DCX    H    ;POINT TO SIGN OF STEP VALUE
  620.     MOV    A,M    ;SIGN 0=POS, 1=NEG
  621.     LXI    D,FPSIZ+1
  622.     DAD    D    ;PUTS LIMIT ADDR IN HL
  623.     XCHG
  624.     POP    H    ;VARIABLE ADDR
  625.     CALL    LHLI    ;GET ADDR
  626.     PUSH    D    ;SAVE CONTROL STACK POINTER TO GET TEXT ADDR
  627.     ORA    A    ;SET CONDITIONS BASED ON SIGN OF STEP VALUE
  628.     JZ    NEXT2    ;REVERSE TEST ON NEGATIVE STEP VALUE
  629.     XCHG
  630. NEXT2:    MOV    B,H    ;SET UP ARGS FOR COMPARE
  631.     MOV    C,L
  632.     CALL    RELOP    ;TEST <=
  633.     POP    D    ;TEXT ADDR
  634.     JM    NEXT3    ;STILL SMALLER?
  635.     JZ    NEXT3    ;JUMP IF WANT TO CONTINUE LOOP
  636. ;
  637. ;    TERMINATE LOOP
  638. ;
  639.     LXI    H,3    ;REMOVE CSTACK ENTRY
  640.     DAD    D
  641.     SHLD    CSTKA
  642.     RET
  643. ;
  644. NEXT3:    INX    D    ;TEXT ADDR
  645.     XCHG
  646.     CALL    LHLI    ;GET TEXT ADDR IN HL
  647. ;
  648. ;    ITERATE, SKIPPING NORMAL JUNK ON END TEST AT ILOOP
  649. ;
  650. NEXT4:    XCHG        ;SAVE NEW TEXT ADDR IN DE
  651.     CALL    JOE
  652.     XCHG
  653. NEXT6:    SHLD    TXA
  654. NEXT5:    LXI    H,ILOOP
  655.     XTHL
  656.     RET        ;TO DISPATCHER SKIPPING JOE CALL THERE
  657. ;
  658. ;    'IF'
  659. ;
  660. SIF:    MVI    B,1    ;SPECIFY PRINCIPAL OPERATOR IS RELATIONAL
  661.     CALL    EXPB1
  662.     LHLD    ASTKA    ;ADDR OF BOOLEAN VALUE ON ARG STACK
  663.     INR    M    ;SETS ZERO CONDITION IF RELATIONAL WAS TRUE
  664.     PUSH    PSW    ;SAVE CONDITIONS TO TEST LATER
  665.     CALL    POPAS    ;REMOVE VALUE FROM ARG STACK COPY TO SELF
  666.     POP    PSW
  667.     JNZ    REM    ;IF TEST FALSE TREAT REST OF STATEMENT AS REM
  668. ;
  669. ;    TEST SUCCEEDED
  670. ;
  671.     MVI    B,THENRW
  672.     CALL    EATC
  673.     CALL    INTGER    ;CHECK IF LINE NUMBER IS DESIRED ACTION
  674.     JC    ISTAT
  675.     JMP    GOTO1
  676. ;
  677. ;    'GOTO'
  678. ;
  679. SGOTO:    XRA    A
  680.     STA    DIRF    ;CLEAR DIRECT STATEMENT FLAG
  681.     CALL    INTGER    ;RETURNS INTEGER IN HL IF LINE NUMBER PRESENT
  682.     JC    E1    ;SYNTAX ERROR, NO LINE NUMBER
  683. GOTO1:    XCHG        ;LINE IN DE
  684.     CALL    FINDLN    ;RETURNS TEXT ADDR POINTS TO COUNT VALUE
  685. GOTO2:    INX    H
  686.     INX    H
  687.     INX    H    ;ADVANCE TEXT POINTER PAST LINE NUMBER AND COUNT
  688.     JMP    NEXT4
  689. ;
  690. ;    'GOSUB'
  691. ;
  692. GOSUB:    CALL    DIRT
  693.     LXI    D,-3    ;CREATE CONTROL STACK ENTRY
  694.     CALL    PSHCS
  695.     PUSH    H    ;SAVE STACK ADDRESS
  696.     CALL    INTGER
  697.     JC    E1
  698.     XCHG        ;LINE NUMBER TO DE
  699.     CALL    JOE
  700.     MOV    B,H
  701.     MOV    C,L
  702.     POP    H    ;STACK ADDR
  703.     MOV    M,B    ;STACK RETURN ADDR RETURNED BY JOE
  704.     DCX    H
  705.     MOV    M,C
  706.     DCX    H
  707.     MVI    M,GTYPE    ;MAKE CONTROL STACK ENTRY TYPE 'GOSUB'
  708.     CALL    FINDLN
  709.     INX    H
  710.     INX    H
  711.     INX    H
  712.     JMP    NEXT6
  713. ;
  714. ;    'RETURN'
  715. ;
  716. RETRN:    CALL    DIRT
  717.     STA    DIRF    ;CLEARS DIRF IF ACC IS CLEAR
  718.     LHLD    CSTKA
  719. RET1:    MOV    A,M
  720.     ORA    A    ;CHECK FOR STACK EMPTY
  721.     JZ    E4
  722.     CPI    GTYPE    ;CHECK FOR GOSUB TYPE
  723.     JZ    RET2
  724. ;
  725. ;    REMOVE FOR TYPE ENTRY FROM STACK
  726. ;
  727.     LXI    D,FORSZ
  728.     DAD    D
  729.     JMP    RET1
  730. ;
  731. ;    FOUND A GTYPE STACK ENTRY
  732. ;
  733. RET2:    INX    H
  734.     MOV    E,M    ;LOW ORDER TEXT ADDR
  735.     INX    H
  736.     MOV    D,M    ;HIGH ORDER TEXT ADDR
  737.     INX    H    ;ADDR OF PREVIOUS CONTROL STACK ENTRY
  738.     SHLD    CSTKA
  739.     XCHG        ;PUT TEXT ADDR IN HL
  740.     MOV    A,M    ;ADDR POINTS TO EOF IF GOSUB WAS LAST LINE
  741.     DCR    A    ;END OF FILE?
  742.     JNZ    NEXT4
  743.     JMP    CEND
  744. ;
  745. ;    'DATA' AND 'REM'
  746. ;
  747. DATA:    CALL DIRT    ;DATA STATEMENT ILLEGAL AS DIRECT
  748. REM:    CALL    GCI
  749.     CPI    CR
  750.     JNZ    REM
  751.     DCX    H    ;BACKUP POINTER SO NORMAL JOE WILL WORK
  752.     SHLD    TXA
  753.     RET
  754. ;
  755. ;    'DIMENSION'
  756. ;
  757. DIM:    CALL    NAME    ;LOOK FOR VARIABLE NAME
  758.     JC    E1
  759.     MOV    A,C    ;PREPARE TURN ON 200Q BIT TO SIGNIFY MATRIX
  760.     ORI    200Q
  761.     MOV    C,A
  762.     CALL    STLK
  763.     JNC    E6    ;ERROR IF NAME ALREADY EXISTS
  764.     PUSH    H    ;SYMBOL TABLE ADDR
  765.     MVI    B,LPARRW
  766.     CALL    EATC
  767.     CALL    EXPRB
  768.     MVI    B,')'
  769.     CALL    EATC
  770.     CALL    PFIX    ;RETURN INTEGER IN DE
  771.     LXI    H,MATUB    ;MAX SIZE FOR MATRIX
  772.     CALL    DCMP
  773.     JNC    E6
  774.     POP    H    ;SYMBOL TABLE ADDR
  775.     CALL    DIMS
  776.     CALL    GC    ;SEE IF MORE TO DO
  777.     CPI    ','
  778.     RNZ
  779.     CALL    GCI    ;EAT THE COMMA
  780.     JMP    DIM
  781. ;
  782. ;    'STOP'
  783. ;
  784. STOP:    CALL    DIRT
  785. STOP1:    CALL    CRLF2
  786.     LXI    H,STOPS
  787.     JMP    ERM1
  788. ;
  789. ;    'END'
  790. ;
  791. CEND    EQU    CMND1
  792. ;
  793. ;    'READ'
  794. ;
  795. READ:    CALL    DIRT
  796.     LHLD    TXA
  797.     PUSH    H    ;SAVE TXA TEMPORARILY
  798.     LHLD    RTXA    ;THE 'READ' TXA
  799. READ0:    SHLD    TXA
  800.     CALL    GCI
  801.     CPI    ','
  802.     JZ    READ2    ;PROCESS INPUT VALUE
  803.     CPI    DATARW
  804.     JZ    READ2
  805.     DCR    A
  806.     JZ    READ4
  807. ;
  808. ;    SKIP TO NEXT LINE
  809. ;
  810.     CALL    REM    ;LEAVES ADDR OF LAST CR IN HL
  811.     INX    H
  812.     MOV    A,M
  813.     DCR    A
  814.     JZ    READ4
  815.     INX    H
  816.     INX    H
  817.     INX    H    ;HL NOW POINTS TO FIRST BYTE OF NEXT LINE
  818.     JMP    READ0
  819. ;
  820. ;    PROCESS VALUE
  821. ;
  822. READ2:    CALL    EXPRB
  823.     CALL    GC
  824.     CPI    ','    ;SKIP JOE TEST IF COMMA
  825.     JZ    READ3
  826. ;
  827. ;    JUNK ON END TEST
  828. ;
  829.     CALL    JOE
  830. READ3:    LHLD    TXA
  831.     SHLD    RTXA    ;SAVE NEW 'READ' TEXT ADDR
  832.     POP    H
  833.     SHLD    TXA
  834.     CALL    VAR
  835.     JC    E1
  836.     CALL    POPAS    ;PUT READ VALUE INTO VARIABLE
  837.     CALL    GC
  838.     CPI    ','    ;CHECK FOR ANOTHER VARIABLE
  839.     RNZ
  840.     CALL    GCI    ;EAT THE COMMA
  841.     JMP    READ
  842. ;
  843. READ4:    POP    H    ;PROGRAM TXA
  844.     SHLD    TXA
  845.     LXI    H,RDERR
  846.     JMP    ERROR
  847. ;
  848. ;    'RESTORE'
  849. ;
  850. RESTOR:    LHLD    BOFA    ;BEGINNING OF FILE POINTER
  851.     INX    H
  852.     INX    H
  853.     INX    H
  854.     SHLD    RTXA
  855.     RET
  856. ;
  857. ;    'LPRINT'
  858. ;
  859. LPRINT:    MVI    A,1    ;SWITCH OUTPUT TO LINE PRINTER
  860.     STA    PFLAG
  861.     CALL    PRINT    ;CALL NORMAL PRINT ROUTINE
  862.     XRA    A    ;SWITCH OUTPUT BACK TO CONSOLE
  863.     STA    PFLAG
  864.     RET
  865. ;
  866. ;    'PRINT'
  867. ;
  868. PRINT:    CALL    GC
  869.     CPI    CR    ;CHECK FOR STAND ALONE PRINT
  870.     JZ    CRLF
  871. PRIN0:    CPI    '"'
  872.     JZ    PSTR    ;PRINT THE STRING
  873.     CPI    TABRW
  874.     JZ    PTAB    ;TABULATION
  875.     CPI    '%'
  876.     JZ    PFORM    ;SET FORMAT
  877.     CPI    CR
  878.     RZ
  879.     CPI    ';'
  880.     RZ
  881.     CALL    EXPRB    ;MUST BE EXPRESSION TO PRINT
  882.     LXI    D,FPSINK
  883.     CALL    POPA1    ;POP VALUE TO FPSINK
  884.     LDA    PHEAD
  885.     LXI    H,LWID
  886.     CMP    M
  887.     CNC    CRLF    ;IF PRINT HEAD PAST LINE WIDTH LIMIT
  888.     LXI    H,FPSINK
  889.     CALL    FPOUT
  890.     MVI    B,' '
  891.     CALL    CHOUT
  892. PR1:    CALL    GC    ;GET DELIMITER
  893.     CPI    ','
  894.     JNZ    CRLF
  895. PR0:    CALL    GCI
  896.     CALL    GC
  897.     JMP    PRIN0
  898. ;
  899. PSTR:    CALL    GCI    ;GOBBLE THE QUOTE
  900.     CALL    PRNT    ;PRINT UP TO DOUBLE QUOTE
  901.     INX    H
  902.     SHLD    TXA
  903.     JMP    PR1
  904. ;
  905. PFORM:    MVI    A,2*FPNIB
  906.     STA    INFES
  907.     CALL    GCI    ;GOBBLE PREVIOUS CHARACTER
  908. PFRM1:    CALL    GCI
  909.     LXI    H,INFES
  910.     CPI    '%'    ;DELIMITER
  911.     JZ    PR1
  912.     MVI    B,200Q
  913.     CPI    'Z'    ;TRAILING ZEROES?
  914.     JZ    PF1
  915.     MVI    B,1
  916.     CPI    'E'    ;SCIENTIFIC NOTATION?
  917.     JZ    PF1
  918.     CALL    NMCHK
  919.     JNC    E1
  920.     SUI    '0'    ;NUMBER OF DECIMAL PLACES
  921.     RLC
  922.     MOV    B,A
  923.     MOV    A,M
  924.     ANI    301Q
  925.     MOV    M,A
  926. PF1:    MOV    A,M
  927.     ORA    B
  928.     MOV    M,A
  929.     JMP    PFRM1
  930. ;
  931. PTAB:    CALL    GCI    ;GOBBLE TAB RW
  932.     MVI    B,LPARRW
  933.     CALL    EATC
  934.     CALL    EXPRB
  935.     MVI    B,')'
  936.     CALL    EATC
  937.     CALL    PFIX
  938. PTAB1:    LDA    PHEAD
  939.     CMP    E
  940.     JNC    PR1
  941.     MVI    B,' '
  942.     CALL    CHOUT
  943.     JMP    PTAB1
  944. ;
  945. ;    'INPUT'
  946. ;
  947. INPUT:    CALL    GC
  948.     CPI    '"'    ;CHECK FOR USER-DEFINED PROMPT
  949.     JNZ    INPU1    ;IF NO PROMPT
  950.     CALL    GCI
  951.     CALL    PRNT    ;OUTPUT PROMPT
  952.     INX    H    ;UPDATE TXA
  953.     SHLD    TXA
  954.     CALL    GC
  955. INPU1:    CPI    ','
  956.     JZ    NCRLF
  957.     CALL    CRLF
  958. INP0:    MVI    B,'?'
  959.     CALL    CHOUT
  960. LINP:    CALL    INLINE
  961.     LXI    D,IBUF
  962. IN1:    PUSH    D    ;SAVE FOR FPIN
  963.     CALL    VAR
  964.     JC    E1
  965.     POP    D
  966.     MVI    B,0
  967.     LDAX    D
  968.     CPI    '+'    ;LOOK FOR LEADING PLUS OR MINUS ON INPUT
  969.     JZ    IN2
  970.     CPI    '-'
  971.     JNZ    IN3
  972.     MVI    B,1
  973. IN2:    INX    D
  974. IN3:    PUSH    B
  975.     PUSH    H
  976.     CALL    FPIN    ;INPUT FP NUMBER
  977.     JC    INERR
  978.     POP    H
  979.     DCX    H
  980.     POP    PSW
  981.     MOV    M,A
  982.     CALL    GC
  983.     CPI    ','
  984.     RNZ        ;DONE IF NO MORE
  985.     CALL    GCI    ;EAT THE COMMA
  986.     MOV    A,B    ;GET THE TERMINATOR TO A
  987.     CPI    ','
  988.     JZ    IN1    ;GET THE NEXT INPUT VALUE FROM STRING
  989. ;
  990. ;    GET NEW LINE FROM USER
  991. ;
  992.     MVI    B,'?'
  993.     CALL    CHOUT
  994.     JMP    INP0
  995. ;
  996. NCRLF:    CALL    GCI
  997.     JMP    LINP    ;NOW GET LINE
  998. ;
  999. INERR:    LXI    H,INPER
  1000.     JMP    ERROR
  1001. ;
  1002. ;
  1003. ;    - TPUT -  ROUTINE TO OUTPUT CHARACTER FROM C TO TEKTRONIX
  1004. ;
  1005. TPUT:    IN    3
  1006.     ANI    1
  1007.     JZ    TPUT
  1008.     MOV    A,C
  1009.     OUT    2
  1010.     RET
  1011. ;
  1012. ;
  1013. ;    - TEKOUT -  ROUTINE TO OUTPUT X OR Y ADDRESS FROM DE TO
  1014. ;            TEKTRONIX.
  1015. ;
  1016. ;
  1017. TEKOUT:    MOV    A,D
  1018.     RLC
  1019.     RLC
  1020.     RLC
  1021.     ANI    18H
  1022.     ORI    20H
  1023.     MOV    D,A
  1024.     MOV    A,E
  1025.     RLC
  1026.     RLC
  1027.     RLC
  1028.     ANI    7H
  1029.     ORA    D
  1030.     MOV    D,A
  1031.     MOV    A,E
  1032.     ANI    1FH
  1033.     ORA    B
  1034.     MOV    E,A
  1035.     MOV    C,D
  1036.     CALL    TPUT
  1037.     MOV    C,E
  1038.     CALL    TPUT
  1039.     RET
  1040. ;
  1041. ;
  1042. BEAM:    MVI    C,29
  1043.     CALL    TPUT    ;PUT TEK IN GRAPH MODE
  1044. DRAW:    CALL    EXPRB
  1045.     CALL    PFIX
  1046.     PUSH    D    ;SAVE X VALUE
  1047.     MVI    B,','
  1048.     CALL    EATC
  1049.     CALL    EXPRB
  1050.     CALL    PFIX
  1051.     MVI    B,60H
  1052.     CALL    TEKOUT
  1053.     POP    D
  1054.     MVI    B,40H
  1055.     CALL    TEKOUT
  1056.     RET
  1057. ;
  1058. ;
  1059. ;
  1060. ;    - CPUSH - ROUTINE TO PUSH 16-BIT INTEGERS ON
  1061. ;        MACHINE LANGUAGE LINKAGE STACK
  1062. ;
  1063. CPUSH:    CALL    EXPRB    ;EVALUATE EXPRESSION
  1064.     CALL    PFIX    ;CONVERT RESULT TO INTEGER
  1065.     LHLD    MACSP    ;SET UP FOR BOUNDS CHECK
  1066.     LXI    B,-(MACSTK-MACSIZ)
  1067.     CALL    ARGPSH    ;PUSH INTEGER ON STACK (IF ROOM)
  1068.     SHLD    MACSP    ;UPDATE STACK POINTER
  1069.     CALL    EATCOM    ;CHECK FOR MORE
  1070.     JMP    CPUSH    ;IF MORE
  1071. ;
  1072. ;    - STRAP - ROUTINE TO PUSH LINE NUMBERS ON TRAP STACK
  1073. ;
  1074. STRAP:    CALL    INTGER    ;GET LINE NUMBER
  1075.     JC    E1    ;IF INVALID
  1076.     XCHG
  1077.     LHLD    TRPSP    ;SET UP BOUNDS CHECK
  1078.     LXI    B,-(TRPSTK-TRPSIZ)
  1079.     CALL    ARGPSH    ;PUSH LINE NUMBER (IF ROOM)
  1080.     SHLD    TRPSP    ;UPDATE STACK POINTER
  1081.     CALL    EATCOM    ;CHECK FOR MORE
  1082.     JMP    STRAP    ;IF MORE
  1083. ;
  1084. ;    - CPOKE - ROUTINE TO WRITE BYTES INTO MEMORY
  1085. ;
  1086. CPOKE:    CALL    EXPRB    ;EVALUATE ADDR EXPRESSION
  1087.     CALL    PFIX    ;CONVERT TO INTEGER
  1088.     PUSH    D    ;SAVE ADDR
  1089.     MVI    B,'['    ;FIND '['
  1090.     CALL    EATC
  1091. CPOK1:    CALL    BYTARG    ;CONVERT NEXT EXPRESSION TO BYTE
  1092.     POP    H    ;RETRIEVE ADDR
  1093.     MOV    M,E    ;WRITE BYTE
  1094.     INX    H
  1095.     PUSH    H    ;SAVE NEW ADDR
  1096.     LXI    H,CPOK2    ;SET UP RETURN ADDR IF NEXT NON-BLANK<>','
  1097.     PUSH    H
  1098.     CALL    EATCOM
  1099.     POP    H    ;CHAR=','
  1100.     JMP    CPOK1
  1101. ;
  1102. CPOK2:    MVI    B,']'    ;TEST FOR ']'
  1103.     CALL    EATC
  1104.     POP    H    ;CLEAN OUT STACK IN CASE DONE
  1105.     CALL    EATCOM
  1106.     PUSH    H
  1107.     JMP    CPOKE
  1108. ;
  1109. ;    - COUT - ROUTINE TO OUTPUT BYTES TO OUTPUT DEVICES
  1110. ;
  1111. COUT:    CALL    BYTARG    ;GET PORT NUMBER
  1112.     MOV    A,E
  1113.     STA    COUT3+1    ;SET UP OUTPUT INSTRUCTION
  1114.     MVI    B,'['    ;FIND '['
  1115.     CALL    EATC
  1116. COUT1:    CALL    BYTARG    ;GET OUTPUT BYTE
  1117.     MOV    A,E
  1118.     CALL    COUT3    ;OUTPUT IT
  1119.     LXI    H,COUT2    ;IN CASE NEXT NON-BLANK<>','
  1120.     PUSH    H
  1121.     CALL    EATCOM
  1122.     POP    H
  1123.     JMP    COUT1
  1124. ;
  1125. COUT2:    MVI    B,']'    ;TEST FOR ']'
  1126.     CALL    EATC
  1127.     CALL    EATCOM
  1128.     JMP    COUT
  1129. ;
  1130. COUT3:    OUT    0
  1131.     RET
  1132. ;
  1133. ;    - BYTARG - ROUTINE TO EVALUATE TEXT EXPRESSIONS, CONVERT
  1134. ;        RESULT TO INTEGER, AND MAKE SURE INTEGER IS A
  1135. ;        BYTE VALUE
  1136. ;
  1137. BYTARG:    CALL    EXPRB
  1138. BYTAR1:    CALL    PFIX
  1139.     XRA    A
  1140.     ORA    D
  1141.     RZ
  1142.     JMP    E3
  1143. ;
  1144. ;    - ARGPSH - ROUTINE TO PUSH 16-BIT VALUES ON STACKS
  1145. ;        AND DO BOUNDS CHECKING ON STACKS
  1146. ;    ENTRY - HL IS STACK POINTER, BC IS NEGATIVE OF UPPER LIMIT
  1147. ;        OF STACK
  1148. ;    EXIT - HL IS UPDATED STACK POINTER
  1149. ;
  1150. ARGPSH:    PUSH    H    ;SAVE SP
  1151.     DAD    B    ;DO BOUNDS CHECK
  1152.     MOV    A,H
  1153.     ORA    L
  1154.     JNZ    ARPS1    ;IF ROOM ON STACK
  1155.     LXI    H,ISTAK
  1156.     JMP    ERROR
  1157. ;
  1158. ARPS1:    POP    H    ;RETRIEVE SP
  1159.     MOV    M,D    ;PUSH WORD
  1160.     DCX    H
  1161.     MOV    M,E
  1162.     DCX    H
  1163.     RET
  1164. ;
  1165. ;    - EATCOM - ROUTINE TO CHECK NEXT NON-BLANK FOR ','
  1166. ;        IF ',' THEN EAT IT AND ADVANCE TO NEXT NON-BLANK
  1167. ;        RETURN TO CALLER
  1168. ;        IF NOT ',' THEN POP ONE WORD OFF STACK AND RETURN
  1169. ;        TO CALLER OF CALLER
  1170. ;
  1171. EATCOM:    CALL    GC
  1172.     CPI    ','
  1173.     JZ    ETCO1
  1174.     POP    H
  1175.     RET
  1176. ;
  1177. ETCO1:    CALL    GCI
  1178.     CALL    GC
  1179.     RET
  1180. ;
  1181. ;        EVALUATE AN EXPRESSION FROM TEXT
  1182. ;    HL TAKE OP TABLE ADDR OF PREVIOUS OPERATOR (NOT CHANGED)
  1183. ;    RESULT VALUE LEFT ON TOP OF ARG STACK, ARGF LEFT TRUE
  1184. ;
  1185. EXPRB:    MVI    B,0
  1186. EXPB1:    LXI    H,OPBOL
  1187.     XRA    A
  1188.     STA    RELTYP
  1189. ;
  1190. ;    ZERO IN B MEANS PRINCIPAL OPERATOR MAY NOT BE RELATIONAL
  1191. ;
  1192. EXPR:    PUSH    B
  1193.     PUSH    H    ;PUSH OPTBA
  1194.     XRA    A
  1195.     STA    ARGF
  1196. EXPR1:    LDA    ARGF
  1197.     ORA    A
  1198.     JNZ    EXPR2
  1199.     CALL    VAR    ;LOOK FOR VARIABLE PERHAPS SUBSCRIPTED
  1200.     CNC    PSHAS
  1201.     JNC    EXPR2
  1202.     CALL    CONST
  1203.     JNC    EXPR2
  1204.     CALL    GC
  1205.     CPI    LPARRW
  1206.     LXI    H,OPLPAR
  1207.     JZ    XLPAR
  1208. ;
  1209. ;    ISN'T OR SHOULDN'T BE AN ARGUMENT
  1210. ;
  1211. EXPR2:    CALL    GC
  1212.     CPI    340Q    ;CHECK FOR RESERVED WORD OPERATOR
  1213.     JNC    XOP
  1214.     CPI    300Q    ;CHECK FOR BUILT IN FUNCTION
  1215.     JNC    XBILT
  1216. ;
  1217. ;    ILLEGAL EXPRESSION CHARACTER
  1218. ;
  1219.     POP    H    ;GET OPTABA
  1220.     LDA    ARGF
  1221.     ORA    A
  1222.     JZ    E1
  1223. XDON1:    POP    PSW
  1224.     LXI    H,RELTYP;CHECK IF LEGAL PRINCIPAL OPERATOR
  1225.     CMP    M
  1226.     RZ
  1227.     JMP    E1
  1228. ;
  1229. XOP:    ANI    37Q    ;CLEANS OFF RW BITS
  1230.     LHLD    ARGF    ;TEST FOR ARGF TRUE
  1231.     DCR    L
  1232.     JZ    XOP1
  1233. ;
  1234. ;    ARGF WAS FALSE, UNARY OPS ONLY POSSIBILITY
  1235. ;
  1236.     CPI    '-'-OPBASE
  1237.     JZ    XOPM
  1238.     CPI    '+'-OPBASE
  1239.     JNZ    E1
  1240.     CALL    GCI    ;EAT THE '+'
  1241.     JMP    EXPR1
  1242. ;
  1243. XOPM:    MVI    A,UMINU-OPBASE
  1244. XOP1:    CALL    OPADR
  1245.     POP    D    ;PREVIOUS OPTBA
  1246.     LDAX    D
  1247.     CMP    M
  1248.     JNC    XDON1    ;NON-INCREASING PRECEDENCE
  1249. ;
  1250. ;    INCREASING PRECEDENCE CASE
  1251. ;
  1252.     PUSH    D    ;SAVE PREVIOUS OPTBA
  1253.     PUSH    H    ;SAVE CURRENT OPTBA
  1254.     CALL    GCI    ;TO GOBBLE OPERATOR
  1255.     POP    H
  1256.     PUSH    H
  1257.     MVI    B,0    ;SPECIFY NON-RELATIONAL
  1258.     CALL    EXPR
  1259.     POP    H
  1260. ;
  1261. ;    HL HAS OPTBA ADDR
  1262. ;    SET UP ARGS AND PERFORM OPERATION ACTION
  1263. ;
  1264. XOP2:    PUSH    H
  1265.     MOV    A,M
  1266.     LHLD    ASTKA
  1267.     MOV    B,H
  1268.     MOV    C,L
  1269.     ANI    1
  1270.     JNZ    XOP21
  1271. ;
  1272. ;    DECREMENT SP BY 1 VALUE BINARY CASE
  1273. ;
  1274.     LXI    D,FPSIZ
  1275.     DAD    D
  1276.     SHLD    ASTKA
  1277.     MOV    D,H
  1278.     MOV    E,L
  1279. XOP21:    LXI    H,EXPR1
  1280.     XTHL        ;CHANGE RETURN LINK
  1281.     INX    H    ;SKIP OVER PRECEDENCE
  1282.     CALL    LHLI    ;LOAD ACTION ADDR
  1283.     PCHL
  1284. ;
  1285. ;    ACTION ROUTINE CONVENTION
  1286. ;    DE LEFT ARG AND RESULT FOR BINARY
  1287. ;    BC RIGHT ARG FOR BINARY, ARG AND RESULT FOR UNARY
  1288. ;    BUILT IN FUNCTION PROCESSING
  1289. ;
  1290. XBILT:    CALL    GCI    ;EAT TOKEN
  1291.     ANI    77Q    ;CLEAN OFF RW BITS
  1292.     LHLD    ARGF    ;BUILT IN FUNCTION MUST COME AFTER OPERATOR
  1293.     DCR    L
  1294.     JZ    E1
  1295.     CALL    OPADR    ;OPTBA TO HL
  1296. XLPAR:    PUSH    H
  1297.     MVI    B,LPARRW
  1298.     CALL    EATC
  1299.     CALL    EXPRB
  1300.     MVI    B,')'
  1301.     CALL    EATC
  1302.     POP    H    ;CODE FOR BUILT IN FUNCTION
  1303.     JMP    XOP2
  1304. ;
  1305. ;    COMPUTE OP TABLE ADDR FOR OPERATOR IN ACC
  1306. ;
  1307. OPADR:    MOV    C,A
  1308.     MVI    B,0
  1309.     LXI    H,OPTAB
  1310.     DAD    B
  1311.     DAD    B
  1312.     DAD    B    ;OPTAB ENTRY ADDR IS 3*OP+BASE
  1313.     RET
  1314. ;
  1315. ;    PREPROCESSOR, UN-PREPROCESSOR
  1316. ;    PREPROCESS LINE IN IBUF BACK INTO IBUF
  1317. ;    SETS CARRY IF LINE HAS NO LINE NUMBER
  1318. ;    LEAVES CORRECT LENGTH OF LINE AFTER PREPROCESSING IN IBCN
  1319. ;    IF THERE IS A LINE NUMBER, IT IS LOCATED AT IBLN=IBUF-2
  1320. ;    TXA IS CLOBBERED
  1321. ;
  1322. PP:    LXI    H,IBUF    ;FIRST CHARACTER OF INPUT LINE
  1323.     SHLD    TXA    ;SO GCI WILL WORK
  1324.     CALL    INTGER    ;SETS CARRY IF NO LINE NUMBER
  1325.     SHLD    IBLN    ;STORE LINE NUMBER VALUE (EVEN IF NONE)
  1326.     PUSH    PSW    ;SAVE STATE OF CARRY BIT
  1327.     LHLD    TXA    ;ADDRESS OF NEXT CHARACTER IN IBUF
  1328.     MVI    C,4    ;SET UP INITIAL VALUE FOR COUNT
  1329.     LXI    D,IBUF    ;INITIALIZE WRITE POINTER
  1330. ;
  1331. ;    COME HERE TO CONTINUE PREPROCESSING LINE
  1332. ;
  1333. PPL:    PUSH    D
  1334.     LXI    D,RWT    ;BASE OF RWT
  1335. PPL1:    PUSH    H    ;SAVE TEXT ADDRESS
  1336.     LDAX    D    ;RW VALUE FOR THIS ENTRY IN RWT
  1337.     MOV    B,A    ;SAVE IN B IN CASE OF MATCH
  1338. PPL2:    INX    D    ;ADVANCE ENTRY POINTER TO NEXT BYTE
  1339.     LDAX    D    ;GET NEXT CHARACTER FROM ENTRY
  1340.     CMP    M    ;COMPARE WITH CHARACTER IN TEXT
  1341.     JNZ    PPL3
  1342.     INX    H    ;ADVANCE TEXT POINTER
  1343.     JMP    PPL2
  1344. ;
  1345. ;    COME HERE WHEN COMPARISON OF BYTE FAILED
  1346. ;
  1347. PPL3:    ORA    A
  1348.     JM    PPL6    ;JUMP IF FOUND MATCH
  1349. ;
  1350. ;    SCAN TO BEGINNING OF NEXT ENTRY
  1351. ;
  1352. PPL4:    INX    D    ;ADVANCE ENTRY POINTER
  1353.     LDAX    D    ;NEXT BYTE IS EITHER CHARACTER OR RW BYTE
  1354.     ORA    A
  1355.     JP    PPL4    ;KEEP SCANNING IF NOT RW BYTE
  1356. ;
  1357. ;    NOW SEE IF AT END OF TABLE, AND FAIL OR RETURN CONDITION
  1358. ;
  1359.     POP    H    ;RECOVER ORIGINAL TEXT POINTER
  1360.     XRI    377Q    ;CHECK FOR END OF TABLE BYTE
  1361.     JNZ    PPL1    ;CONTINUE SCAN OF TABLE
  1362. ;
  1363. ;    DIDN'T FIND AN ENTRY AT THE GIVEN TEXT ADDR
  1364. ;
  1365.     POP    D
  1366.     MOV    A,M    ;GET TEXT CHARACTER
  1367.     CPI    CR    ;CHECK FOR END OF LINE
  1368.     JZ    PPL8    ;GO CLEAN UP AND RETURN
  1369.     STAX    D
  1370.     INX    D
  1371.     INR    C
  1372.     INX    H    ;ADVANCE TEXT POINTER
  1373.     CPI    '"'    ;CHECK FOR QUOTED STRING POSSIBILITY
  1374.     JNZ    PPL    ;RESTART RWT SEARCH AT NEXT CHARACTER POSITION
  1375. ;
  1376. ;    HERE WE HAVE A QUOTED STRING, SO EAT TILL ENDQUOTE
  1377. ;
  1378. PPL5:    MOV    A,M    ;NEXT CHARACTER
  1379.     CPI    CR
  1380.     JZ    PPL8    ;NO STRING ENDQUOTE, LET INTERPRETTER WORRY
  1381.     STAX    D
  1382.     INX    D
  1383.     INR    C
  1384.     INX    H    ;ADVANCE TEXT POINTER
  1385.     CPI    '"'
  1386.     JZ    PPL    ;BEGIN RWT SCAN FROM NEW CHARACTER POSITION
  1387.     JMP    PPL5
  1388. ;
  1389. ;    FOUND MATCH SO PUT RW VALUE IN TEXT
  1390. ;
  1391. PPL6:    POP    PSW    ;REMOVE UNNEEDED TEST POINTER FROM STACK
  1392.     POP    D
  1393.     MOV    A,B
  1394.     STAX    D
  1395.     INX    D
  1396.     INR    C
  1397.     ANI    240Q    ;TEST FOR COMMAND RW
  1398.     CPI    240Q
  1399.     JNZ    PPL    ;IF NOT COMMAND
  1400.     MOV    A,B    ;TEST FOR BIT 6 SET
  1401.     ANI    100Q
  1402.     JNZ    PPL    ;IF SET
  1403.     JMP    PPL5    ;END PREPROCESSING OF COMMAND LINE
  1404. ;
  1405. ;    COME HERE WHEN DONE
  1406. ;
  1407. PPL8:    MVI    A,CR
  1408.     STAX    D
  1409.     LXI    H,IBCNT    ;SET UP COUNT IN CASE LINE OF LINE NUMBER
  1410.     MOV    M,C
  1411.     POP    PSW    ;RESTORE CARRY (LINE NUMBER FLAG)
  1412.     RET
  1413. ;
  1414. ;    UN-PREPROCESS LINE ADDRESSES IN HL TO DE BUFFER
  1415. ;    RETURN SOURCE ADDRESS OF CR IN HL ON RETURN
  1416. ;
  1417. UPPL:    INX    H    ;SKIP OVER COUNT BYTE
  1418.     PUSH    H    ;SAVE SOURCE TEXT POINTER
  1419.     CALL    LHLI    ;LOAD LINE NUMBER VALUE
  1420.     CALL    CNS    ;CONVERT LINE NUMBER
  1421.     MVI    A,' '
  1422.     STAX    D    ;PUT BLANK AFTER LINE NUMBER
  1423.     INX    D    ;INCREMENT DESTINATION POINTER
  1424.     POP    H
  1425.     INX    H    ;INCREMENT H PAST LINE NUMBER
  1426. UPP0:    INX    H
  1427.     MOV    A,M    ;NEXT TOKEN IN SOURCE
  1428.     ORA    A
  1429.     JM    UPP1    ;JUMP IF TOKEN IS RW
  1430.     STAX    D    ;PUT CHARACTER IN BUFFER
  1431.     CPI    CR    ;CHECK FOR DONE
  1432.     RZ
  1433.     INX    D    ;ADVANCE DESTINATION BUFFER ADDRESS
  1434.     JMP    UPP0
  1435. ;
  1436. ;    COME HERE WHEN RW BYTE DETECTED IN SOURCE
  1437. ;
  1438. UPP1:    PUSH    H    ;SAVE SOURCE POINTER
  1439.     LXI    H,RWT    ;BASE OF RWT
  1440. UPP2:    CMP    M    ;SEE IF RW MATCHED RWT ENTRY
  1441.     INX    H    ;ADVANCE RWT POINTER
  1442.     JNZ    UPP2    ;CONTINUE LOOKING IF NOT FOUND
  1443. ;
  1444. ;    FOUND MATCH, ENTRY POINTER LOCATES FIRST CHARACTER
  1445. ;
  1446. UPP3:    MOV    A,M    ;CHARACTER OF RW
  1447.     ORA    A    ;CHECK FOR DONE
  1448.     JM    UPP4
  1449.     STAX    D
  1450.     INX    D
  1451.     INX    H
  1452.     JMP    UPP3
  1453. ;
  1454. ;    COME HERE IF DONE WITH RW TRANSFER
  1455. ;
  1456. UPP4:    POP    H    ;SOURCE POINTER
  1457.     JMP    UPP0
  1458. ;
  1459. ;    CONSTANTS AND TABLES
  1460. ;
  1461. HEAD:    DB    'BASIC/5 INTERACTIVE INTERPRETER    V Z1.0  10/16/77"'
  1462. RDYS:    DB    'READY"'
  1463. RNING:    DB    'RUNNING"'
  1464. PLS:    DB    'NEW OR OLD? "'
  1465. ;
  1466. ;    TABLE OF ERROR MESSAGES
  1467. ;
  1468. ARGUM:    DB    'ARGUMENT "'
  1469. SYNTX:    DB    'SYNTAX "'
  1470. CSTAK:    DB    'CONTROL STACK "'
  1471. ISTAK:    DB    'INTERNAL STACK "'
  1472. DIRIN:    DB    'DIRECT INPUT "'
  1473. DIMEN:    DB    'DIMENSION "'
  1474. FLOAT:    DB    'FLOATING POINT "'
  1475. INPER:    DB    'INPUT "'
  1476. LENGT:    DB    'LINE OVERFLOW "'
  1477. LNUMB:    DB    'LINE NUMBER "'
  1478. NGSQR:    DB    'NEGATIVE SQUARE ROOT "'
  1479. BOUND:    DB    'BOUNDS "'
  1480. RDERR:    DB    'READ "'
  1481. STOVL:    DB    'STORAGE OVERFLOW "'
  1482. FSERR:    DB    'FILE SPACE "'
  1483. DSERR:    DB    'DIRECTORY SPACE "'
  1484. FSIZE:    DB    'FILE SIZE "'
  1485. FNAME:    DB    'FILE NAME "'
  1486. RNDER:    DB    'RANDOM ACCESS FILE "'
  1487. ;
  1488. ;
  1489. ERS:    DB    'ERROR"'
  1490. INS:    DB    ' IN LINE "'
  1491. STOPS:    DB    'STOP"'
  1492. OPN:    DB    'OLD PROGRAM NAME: "'
  1493. NPN:    DB    'NEW PROGRAM NAME: "'
  1494. ;
  1495.     DB    0FFH    ;FLAGS END OF SINE COEFFICIENT LIST
  1496.     DB    0
  1497.     DB    1*16
  1498.     DW    0
  1499.     DB    0
  1500. FPONE:    DB    129    ;EXPONENT
  1501. ;
  1502. ;    SINE COEFFICIENT LIST
  1503. ;    NOTE:  THE FLOATING PNT 1 ABOVE IS A PART OF THIS TABLE
  1504. ;
  1505.     DB    1*16+6
  1506.     DB    6*16+6
  1507.     DB    6*16+7
  1508.     DB    1
  1509.     DB    128    ;-.166667 E 0 (-1/3 FACTORIAL)
  1510.     DB    8*16+3
  1511.     DB    3*16+3
  1512.     DB    3*16+3
  1513.     DB    0
  1514.     DB    128-2    ;.833333 E-2 (1/5 FACT)
  1515.     DB    1*16+9
  1516.     DB    8*16+4
  1517.     DB    1*16+3
  1518.     DB    1
  1519.     DB    128-3    ;-.198413 E-3 (-1/7 FACT)
  1520.     DB    2*16+7
  1521.     DB    5*16+5
  1522.     DB    7*16+3
  1523.     DB    0
  1524.     DB    128-5    ;.275573 E-5 (1/9 FACT)
  1525.     DB    2*16+5
  1526.     DB    0*16+5
  1527.     DB    2*16+1
  1528.     DB    1
  1529. SINX:    DB    128-7    ;-.250521 E-7 (-1/11 FACT)
  1530. ;
  1531. ;    COSINE COEFFICIENT LIST
  1532. ;
  1533.     DB    0FFH    ;MARKS END OF LIST
  1534.     DB    0
  1535.     DB    1*16+0
  1536.     DB    0
  1537.     DB    0
  1538.     DB    0
  1539.     DB    128+1    ;.100000 E 1 (1/1 FACT)
  1540.     DB    5*16+0
  1541.     DB    0
  1542.     DB    0
  1543.     DB    1
  1544. MATUB:    DB    128    ;-.500000 E 0 (-1/2 FACT)
  1545.     DB    4*16+1
  1546.     DB    6*16+6
  1547.     DB    6*16+7
  1548.     DB    0
  1549. RANDS:    DB    128-1    ;.416667 E-1 (1/4 FACT)
  1550.     DB    1*16+3
  1551.     DB    8*16+8
  1552.     DB    8*16+9
  1553.     DB    1
  1554.     DB    128-2    ;.138889 E-2 (-1/6 FACT)
  1555.     DB    2*16+4
  1556.     DB    8*16+0
  1557.     DB    1*16+6
  1558.     DB    0
  1559.     DB    128-4    ;.248016 E-4 (1/8 FACT)
  1560.     DB    2*16+7
  1561.     DB    5*16+5
  1562.     DB    7*16+3
  1563.     DB    1
  1564. COSX:    DB    128-6    ;.275573 E-6 (-1/10 FACT)
  1565.     DB    2*16
  1566.     DW    0
  1567.     DB    0
  1568. FPTWO:    DB    129
  1569.     DB    1*16+5
  1570.     DB    7*16+0
  1571.     DB    8*16+0
  1572.     DB    0
  1573. PIC2:    DB    128+1    ;PI/2  .157080 E 1
  1574.     DB    6*16+3
  1575.     DB    6*16+6
  1576.     DB    2*16+0
  1577.     DB    0
  1578. PIC1:    DB    128    ;2/PI  .636620 E 0
  1579. LCSTKA:    DW    CSTKL
  1580. ;
  1581. ;    COMMAND TABLE
  1582. ;
  1583. CMNDD:    DW    CRUN    ;0
  1584.     DW    LLIST    ;1 LIST ON LINE PRINTER
  1585.  
  1586.     DW    CNULL    ;2
  1587.     DW    CSCR    ;3
  1588.     DW    CNEW    ;4 SET UP MEMORY BOUNDS
  1589.     DW    SAVE    ;5 DISK SAVE BASIC PROGRAM
  1590.     DW    COLD    ;6 LOAD BASIC PROGRAM FROM DISK
  1591.     DW    CSYS    ;7 RETURN TO CP/M SYSTEM
  1592.     DW    CNAME    ;8 RENAME OR OUTPUT NAME OF WS
  1593.     DW    ERA    ;9 ERASE FILE
  1594.     DW    CLIST    ;10 LIST
  1595. ;
  1596. ;    STATEMENT TABLE
  1597. ;
  1598. STATD:    DW    LET    ;0
  1599.     DW    NEXT    ;1
  1600.     DW    SIF    ;2
  1601.     DW    SGOTO    ;3
  1602.     DW    GOSUB    ;4
  1603.     DW    RETRN    ;5
  1604.     DW    READ    ;6
  1605.     DW    DATA    ;7
  1606.     DW    SFOR    ;8
  1607.     DW    LPRINT    ;9
  1608.     DW    INPUT    ;10
  1609.     DW    DIM    ;11
  1610.     DW    STOP    ;12
  1611.     DW    CEND    ;13
  1612.     DW    RESTOR    ;14
  1613.     DW    REM    ;15
  1614.     DW    CCLEAR    ;16
  1615.     DW    CPUSH    ;17
  1616.     DW    CPOKE    ;18
  1617.     DW    COUT    ;19
  1618.     DW    STRAP    ;20
  1619.     DW    BEAM    ;21
  1620.     DW    DRAW    ;22
  1621.     DW    PRINT    ;23
  1622. ;
  1623. ;    R/W WORD TABLE FORMAT IS RESERVED WORD FOLLOWED BY CHR
  1624. ;    OF RESERVED WORD.  LAST ENTRY IS FOLLOWED BY A 377Q
  1625. ;    RW'S THAT ARE SUBSTRINGS OF OTHER RW'S (E. G. >) MUST
  1626. ;    FOLLOW THE LARGER WORD.
  1627. ;
  1628. RWT:    DB    200Q
  1629.     DB    'LET'
  1630.     DB    201Q
  1631.     DB    'NEXT'
  1632.     DB    202Q
  1633.     DB    'IF'
  1634.     DB    203Q
  1635.     DB    'GOTO'
  1636.     DB    204Q
  1637.     DB    'GOSUB'
  1638.     DB    205Q
  1639.     DB    'RETURN'
  1640.     DB    206Q
  1641.     DB    'READ'
  1642.     DB    207Q
  1643.     DB    'DATA'
  1644. DATARW    EQU    207Q
  1645.     DB    210Q
  1646.     DB    'FOR'
  1647.     DB    211Q
  1648.     DB    'LPRINT'
  1649.     DB    211Q
  1650.     DB    ':'
  1651.     DB    212Q
  1652.     DB    'INPUT'
  1653.     DB    213Q
  1654.     DB    'DIM'
  1655.     DB    214Q
  1656.     DB    'STOP'
  1657.     DB    215Q
  1658.     DB    'END'
  1659.     DB    216Q
  1660.     DB    'RESTORE'
  1661.     DB    217Q
  1662.     DB    'REM'
  1663.     DB    220Q
  1664.     DB    'CLEAR'
  1665. CLRRW    EQU    220Q
  1666.     DB    221Q
  1667.     DB    'PUSH'
  1668.     DB    222Q
  1669.     DB    'POKE'
  1670.     DB    223Q
  1671.     DB    'OUT'
  1672.     DB    224Q
  1673.     DB    'TRAP'
  1674.     DB    225Q
  1675.     DB    'BEAM'
  1676.     DB    226Q
  1677.     DB    'DRAW'
  1678.     DB    227Q
  1679.     DB    'PRINT'
  1680. IRWLIM    EQU    230Q    ;LAST INITIAL RESERVED WORD VALUE+1
  1681. ;
  1682. ;
  1683.     DB    237Q
  1684.     DB    'STEP'
  1685. STEPRW    EQU    237Q
  1686.     DB    236Q
  1687.     DB    'TO'
  1688. TORW    EQU    236Q
  1689.     DB    235Q
  1690.     DB    'THEN'
  1691. THENRW    EQU    235Q
  1692.     DB    234Q
  1693.     DB    'TAB'
  1694. TABRW    EQU    234Q
  1695. ;
  1696. ;    COMMANDS
  1697. ;
  1698.     DB    240Q
  1699.     DB    'RUN'
  1700. RUNRW    EQU    240Q
  1701.     DB    241Q
  1702.     DB    'LLIST'
  1703.     DB    242Q
  1704.     DB    'NULL'
  1705. NULLRW    EQU    242Q
  1706.     DB    243Q
  1707.     DB    'SCR'
  1708. SCRRW    EQU    243Q
  1709.     DB    244Q
  1710.     DB    'NEW'
  1711. NEWRW    EQU    244Q
  1712.     DB    245Q
  1713.     DB    'SAVE'
  1714.     DB    246Q
  1715.     DB    'OLD'
  1716.     DB    247Q
  1717.     DB    'SYSTEM'
  1718.     DB    250Q
  1719.     DB    'NAME'
  1720.     DB    251Q
  1721.     DB    'ERA'
  1722.     DB    251Q
  1723.     DB    'UNSAVE'
  1724.     DB    252Q
  1725.     DB    'LIST'
  1726. LISTRW    EQU    252Q
  1727. ;
  1728. ;
  1729. LPARRW    EQU    '('-OPBASE+340Q
  1730.     DB    LPARRW
  1731.     DB    '('
  1732.     DB    '*'-OPBASE+340Q
  1733.     DB    '*'
  1734. PLSRW    EQU    '+'-OPBASE+340Q
  1735.     DB    PLSRW
  1736.     DB    '+'
  1737. MINRW    EQU    '-'-OPBASE+340Q
  1738.     DB    MINRW
  1739.     DB    '-'
  1740.     DB    '/'-OPBASE+340Q
  1741.     DB    '/'
  1742.     DB    67Q-OPBASE+340Q
  1743.     DB    '>='
  1744.     DB    70Q-OPBASE+340Q
  1745.     DB    '<='
  1746.     DB    71Q-OPBASE+340Q
  1747.     DB    '<>'
  1748.     DB    62Q-OPBASE+340Q
  1749.     DB    '=>'
  1750.     DB    63Q-OPBASE+340Q
  1751.     DB    '=<'
  1752.     DB    '<'-OPBASE+340Q
  1753.     DB    '<'
  1754. EQRW    EQU    '='-OPBASE+340Q
  1755.     DB    EQRW
  1756.     DB    '='
  1757.     DB    '>'-OPBASE+340Q
  1758.     DB    '>'
  1759.     DB    301Q
  1760.     DB    'ABS'
  1761.     DB    306Q
  1762.     DB    'INT'
  1763.     DB    314Q
  1764.     DB    'ARG'
  1765.     DB    315Q
  1766.     DB    'CALL'
  1767.     DB    316Q
  1768.     DB    'RND'
  1769.     DB    322Q
  1770.     DB    'SGN'
  1771.     DB    323Q
  1772.     DB    'SIN'
  1773.     DB    304Q
  1774.     DB    'SQR'
  1775.     DB    327Q
  1776.     DB    'TAN'
  1777.     DB    330Q
  1778.     DB    'COS'
  1779.     DB    331Q
  1780.     DB    'POP'
  1781.     DB    332Q
  1782.     DB    'PEEK'
  1783.     DB    333Q
  1784.     DB    'INP'
  1785.     DB    334Q
  1786.     DB    'UNTRAP'
  1787.     DB    377Q    ;END OF TABLE
  1788. ;
  1789. ;    OPERATION TABLE
  1790. ;
  1791. OPTAB:    DB    15
  1792. OPLPAR    EQU    OPTAB
  1793.     DW    ALPAR
  1794.     DB    15
  1795.     DW    AABS
  1796.     DB    10
  1797.     DW    AMUL
  1798.     DB    6
  1799.     DW    AADD
  1800.     DB    15
  1801.     DW    ASQR
  1802.     DB    6
  1803.     DW    ASUB
  1804.     DB    15
  1805.     DW    AINT
  1806.     DB    10
  1807.     DW    ADIV
  1808. OPBOL:    DB    1
  1809.     DW    0
  1810.     DB    13
  1811.     DW    ANEG
  1812.     DB    4
  1813.     DW    AGE
  1814.     DB    4
  1815.     DW    ALE
  1816.     DB    15
  1817.     DW    AARG
  1818.     DB    15
  1819.     DW    ACALL
  1820.     DB    15
  1821.     DW    ARND
  1822.     DB    4
  1823.     DW    AGE
  1824.     DB    4
  1825.     DW    ALE
  1826.     DB    4
  1827.     DW    ANE
  1828.     DB    15
  1829.     DW    ASGN
  1830.     DB    15
  1831.     DW    ASIN
  1832.     DB    4
  1833.     DW    ALT
  1834.     DB    4
  1835.     DW    AEQ
  1836.     DB    4
  1837.     DW    AGT
  1838.     DB    15
  1839.     DW    ATAN
  1840.     DB    15
  1841.     DW    ACOS
  1842.     DB    15
  1843.     DW    APOP
  1844.     DB    15
  1845.     DW    APEEK
  1846.     DB    15
  1847.     DW    AINP
  1848.     DB    15
  1849.     DW    AUNTRP
  1850. ;
  1851. ;    ACTION ROUTINES FOR RELATIONAL OPEATORS
  1852. ;
  1853. AGT:    CALL    RELOP
  1854.     JZ    RFALSE
  1855.     JM    RTRUE
  1856. RFALSE:    XRA    A
  1857.     STAX    D
  1858.     RET
  1859. ALT:    CALL    RELOP
  1860.     JZ    RFALSE
  1861.     JM    RFALSE
  1862. RTRUE:    MVI    A,377Q
  1863.     STAX    D
  1864.     RET
  1865. AEQ:    CALL    RELOP
  1866.     JZ    RTRUE
  1867.     JMP    RFALSE
  1868. ;
  1869. ANE:    CALL    RELOP
  1870.     JZ    RFALSE
  1871.     JMP    RTRUE
  1872. ;
  1873. AGE:    CALL    RELOP
  1874.     JZ    RTRUE
  1875.     JM    RTRUE
  1876.     JMP    RFALSE
  1877. ;
  1878. ALE:    CALL    RELOP
  1879.     JZ    RTRUE
  1880.     JM    RFALSE
  1881.     JMP    RTRUE
  1882. ;
  1883. ;    COMMON ROUTINE FOR RELATIONAL OPERATOR ACTION
  1884. ;
  1885. ;    LEFT ARG ADDR IN DE, SAVED
  1886. ;    RIGHT ARG ADDR IN BC
  1887. ;    ON RETURN, SIGN SET=GT, ZERO SET=EQUAL
  1888. ;
  1889. RELOP:    PUSH    D
  1890.     DCX    B
  1891.     DCX    D
  1892.     MOV    H,B
  1893.     MOV    L,C
  1894.     LDAX    D
  1895.     SUB    M
  1896.     INX    H
  1897.     INX    D
  1898.     JNZ    RLOP1    ;TEST SIGNS OF ARGS IF DIFFERENT THEN RET
  1899.     LXI    B,FPSINK
  1900.     CALL    FSUB
  1901.     LDA    FPSINK    ;CHECK FOR ZERO RESULT
  1902.     ORA    A
  1903.     JZ    RLOP1
  1904.     LDA    FPSINK-1;SIGN OF FPSINK
  1905.     RLC
  1906.     DCR    A
  1907. RLOP1:    MVI    A,1
  1908.     STA    RELTYP    ;SET RELTYPE TRUE
  1909.     POP    D
  1910.     RET
  1911. ;
  1912. ;    ACTION ROUTINES FOR ARITHMETIC OPERATORS
  1913. ;        (CODE WASTERS)
  1914. ;
  1915. AADD:    MOV    H,B
  1916.     MOV    L,C
  1917.     MOV    B,D
  1918.     MOV    C,E
  1919. AADD1:    CALL    FADD
  1920.     JMP    FPETST
  1921. ;
  1922. ASUB:    MOV    H,B
  1923.     MOV    L,C
  1924.     MOV    B,D
  1925.     MOV    C,E
  1926. ASUB1:    CALL    FSUB
  1927.     JMP    FPETST
  1928. ;
  1929. AMUL:    MOV    H,B
  1930.     MOV    L,C
  1931.     MOV    B,D
  1932.     MOV    C,E
  1933. AMUL1:    CALL    FMUL
  1934.     JMP    FPETST
  1935. ;
  1936. ADIV:    MOV    H,B
  1937.     MOV    L,C
  1938.     MOV    B,D
  1939.     MOV    C,E
  1940. ADIV1:    CALL    FDIV
  1941. FPETST:    XRA    A
  1942.     STA    RELTYP
  1943.     LDA    ERRI
  1944.     ORA    A
  1945.     RZ
  1946.     LHLD    ASTKA    ;ZERO RESULT ON UNDERFLOW
  1947. FPET1:    MVI    M,0
  1948. ALPAR:    RET
  1949. ;
  1950. ;    UNARY AND BUILT IN FUNCTION ACTION ROUTINES
  1951. ;
  1952. ANEG:    LDAX    B
  1953.     ORA    A
  1954.     JZ    ANEG1
  1955.     DCX    B
  1956.     LDAX    B
  1957.     XRI    1
  1958.     STAX    B
  1959. ANEG1:    XRA    A
  1960.     STA    RELTYP
  1961.     RET
  1962. ;
  1963. AABS:    DCX    B
  1964.     XRA    A
  1965.     STAX    B
  1966.     JMP    ANEG1
  1967. ;
  1968. ASGN:    CALL    ANEG1
  1969.     MOV    D,B
  1970.     MOV    E,C
  1971.     LDAX    B    ;GET EXPONENT
  1972.     ORA    A
  1973.     JNZ    ASGN1
  1974.     STAX    D    ;MAKE ARGUMENT ZERO
  1975.     RET
  1976. ;
  1977. ASGN1:    DCX    B
  1978.     LDAX    B
  1979.     ORA    A
  1980.     LXI    H,FPONE
  1981.     JZ    VCOPY
  1982.     LXI    H,FPNONE
  1983.     JMP    VCOPY
  1984. ;
  1985. ;    COMPUTE SINE(X) X=TOP OF ARG STACK
  1986. ;    RETURN RESULT IN PLACE OF X
  1987. ;
  1988. ASIN:    CALL    QUADC    ;COMPUTE QUADRANT
  1989.     LHLD    ASTKA
  1990.     MOV    D,H
  1991.     MOV    E,L
  1992.     LXI    B,FTEMP
  1993.     CALL    AMUL1    ;FTEMP = X*X
  1994.     POP    PSW
  1995.     PUSH    PSW    ;A=QUADRANT
  1996.     RAR
  1997.     JC    SIN10    ;QUAD ODD. COMPUTE COSINE
  1998. ;
  1999. ;    COMPUTE X*P(X*X) -- SINE
  2000. ;
  2001.     LXI    D,FTEM1
  2002.     LHLD    ASTKA
  2003.     CALL    VCOPY    ;FTEM1=X*X
  2004.     LXI    B,SINX
  2005.     CALL    POLY    ;P(X*X)
  2006.     CALL    PREPOP
  2007.     LXI    H,FTEM1
  2008.     CALL    AMUL1    ;X*P(X*X)
  2009. ;
  2010. ;    COMPUTE SIGN OF RESULT
  2011. ;    POSITIVE FOR QUADRANT 0,1.  NEGATIVE FOR 2,3
  2012. ;    NEGATE ABOVE FOR NEGATIVE ARGUMENTS
  2013. ;
  2014. SIN5:    POP    PSW    ;QUADRANT
  2015.     MOV    B,A
  2016.     POP    PSW    ;SIGN
  2017.     RLC        ;SIGN, 2 TO THE 1ST BIT
  2018.     XRA    B    ;QUADRANT, MAYBE MODIFIED FOR NEGATIVE ARG
  2019.     LHLD    ASTKA
  2020.     DCX    H    ;PTR TO SIGN
  2021.     SUI    2
  2022.     RM        ;QUADRANT 0 OR 1
  2023.     INR    M    ;ELSE SET RESULT NEGATIVE
  2024.     RET
  2025. ;
  2026. ;    COMPUTE P(X*X) -- COSINE
  2027. ;
  2028. SIN10:    LXI    B,COSX
  2029.     CALL    POLY    ;P(X*X)
  2030.     JMP    SIN5
  2031. ;
  2032. ;        COMPUTE COS(X)   X=TOP OF ARGUMENT STACK
  2033. ;    RETURN RESULT IN PLACE OF X
  2034. ;    COS(X)=SIN(X+PI/2)
  2035. ;
  2036. ACOS:    CALL    PREPOP
  2037.     LXI    H,PIC2    ;PI/2
  2038.     CALL    AADD1    ;TOS=TOS+PI/2
  2039.     JMP    ASIN
  2040. ;
  2041. ;    COMPUTE TAN(X) X=TOP OF ARGUMENT STACK
  2042. ;    RETURN RESULT IN PLACE OF X
  2043. ;    TAN(X)=SIN(X)/COS(X)
  2044. ;
  2045. ATAN:    LHLD    ASTKA
  2046.     CALL    PSHAS    ;PUSH COPY OF X ONTO ARG STACK
  2047.     CALL    ACOS    ;COS(X)
  2048.     LXI    D,FTEM2
  2049.     CALL     POPA1    ;FTEM2=COS(X)
  2050.     CALL    ASIN
  2051.     CALL     PREPOP
  2052.     LXI    H,FTEM2
  2053.     JMP    ADIV1    ;SIN(X)/COS(X)
  2054. ;
  2055. ;    COMPUTE SQR(X) X=TOP OF ARGUMENT STACK
  2056. ;    RETURN RESULT IN PLACE OF X
  2057. ;
  2058. ASQR:    LHLD     ASTKA
  2059.     LXI    D,FTEMP
  2060.     CALL    VCOPY    ;SAVE X IN FTEMP
  2061. ;
  2062. ;    COMPUTE EXPONENT OF FIRST GUESS AS EXPONENT OF X/2
  2063. ;
  2064.     LHLD    ASTKA
  2065.     MOV    A,M
  2066.     ORA    A
  2067.     RZ    ;    X=0
  2068.     SUI    128
  2069.     JM    SQR5    ;NEGATIVE EXPONENT
  2070.     RRC
  2071.     ANI    127
  2072.     JMP    SQR6
  2073. ;
  2074. SQR5:    CMA
  2075.     INR    A
  2076.     RRC
  2077.     ANI    127
  2078.     CMA
  2079.     INR    A
  2080. SQR6:    ADI    128
  2081.     MOV    M,A
  2082. ;
  2083. ;    TEST FOR NEGATIVE ARGUMENT
  2084.     DCX    H
  2085.     MOV    A,M
  2086.     LXI    H,NGSQR
  2087.     ORA    A
  2088.     JNZ    ERROR    ;NEG ARG
  2089. ;
  2090. ;    DO NEWTON ITERATIONS
  2091. ;    NEWGUESS=(X/OLDGUESS+OLDGUESS)/2
  2092. ;
  2093.     MVI    A,6    ;DO 6 ITERATIONS
  2094. SQR20:    PUSH    PSW    ;SET NEW ITERATION COUNT
  2095.     LXI    B,FTEM1
  2096.     LXI    D,FTEMP    ;FTEMP IS 'X'
  2097.     LHLD    ASTKA    ;GUESS
  2098.     CALL    ADIV1    ;FTEM1 = X/GUESS
  2099.     LXI    D,FTEM1
  2100.     LHLD    ASTKA
  2101.     MOV    B,H
  2102.     MOV    C,L
  2103.     CALL    AADD1    ;TOS=(X/GUESS)+GUESS
  2104.     CALL    PREPOP
  2105.     LXI    H,FPTWO
  2106.     CALL    ADIV1    ;TOS=(X/GUESS+GUESS)/2
  2107.     POP    PSW
  2108.     DCR    A    ;DECREMENT COUNT
  2109.     JNZ    SQR20    ;DO ANOTHER ITERATION
  2110.     RET
  2111. ;
  2112. ;    COMPUTE RND(X)  X=TOP OF ARG STACK
  2113. ;    FRAMD IS UPDATED TO NEW RANDOM VALUE
  2114. ;    A RANDOM NUMBER IN THE RANGE 0<RND<1 IS RETURNED IN PLACE
  2115. ;
  2116. ARND:    CALL    PREPOP
  2117.     LXI    D,FRAND
  2118.     LXI    H,FRAND
  2119.     CALL    AMUL1    ;TOS= FRAND*FRAND
  2120. ;
  2121. ;    SET EXPONENT = 0
  2122. ;
  2123.     LHLD    ASTKA
  2124.     MVI    M,128    ;EXPONENT=128  (0 IN EXTERNAL FORM)
  2125. ;
  2126. ;    PERMUTE DIGITS OF X AS
  2127. ;    123456 INTO 345612
  2128. ;
  2129.     LXI    B,-4
  2130.     DAD    B
  2131.     MOV    B,M    ;SAVE 12
  2132.     INX    H
  2133.     INX    H
  2134.     CALL    PERMU    ;56=12
  2135.     CALL    PERMU    ;34=56
  2136.     CALL    PERMU    ;12=34
  2137. ;
  2138. ;    NORMALIZE NUMBER
  2139. ;
  2140. RND5:    LHLD    ASTKA    ;TOS
  2141.     LXI    B,-FPSIZ+1
  2142.     DAD    B
  2143.     MOV    A,M    ;FIRST DIGIT PAIR
  2144.     ANI    15*16
  2145.     JNZ    RND10    ;NUMBER IS NORMALIZED
  2146. ;
  2147. ;    SHIFT LEFT 1 DIGIT
  2148. ;
  2149.     LHLD    ASTKA
  2150.     MOV    A,M    ;EXPONENT
  2151.     DCR    A
  2152.     STA    EXP
  2153.     CALL    LOAD    ;TOS INTO TEMP
  2154.     MVI    B,4
  2155.     CALL    LEFT    ;SHIFT LEFT
  2156.     CALL    PREPOP
  2157.     CALL    STORE
  2158.     JMP    RND5    ;TEST IF NORMALIZED
  2159. ;
  2160. ;    SAVE NEW RANDOM NUMBER FRAND CELL
  2161. ;
  2162. RND10:    LXI    D,FRAND
  2163.     LHLD    ASTKA
  2164.     CALL    VCOPY    ;FRAND=TOS
  2165.     RET
  2166. ;
  2167. ;    PERMUTE PAIR OF DIGIT PAIRS
  2168. ;
  2169. PERMU:    MOV    A,M
  2170.     MOV    M,B
  2171.     MOV    B,A
  2172.     DCX    H
  2173.     RET
  2174. ;
  2175. ;    EVALUATE P(X) USING HORNERS METHOD (X IS IN FTEMP)
  2176. ;    COEFFICIENT LIST POINTER IS IN BC
  2177. ;    RESULT REPLACES NUMBER ON TOP OF ARG STACK (Y)
  2178. ;
  2179. POLY:    LHLD    ASTKA
  2180.     XCHG    ;    DE=PTR TO Y
  2181.     MOV    H,B
  2182.     MOV    L,C    ;HL PTR TO COEFFICIENT LIST
  2183.     CALL    VCOPY    ;Y=FIRST COEFFICIENT
  2184. ;
  2185. ;    MULTIPLY BY X
  2186. ;
  2187. POLY1:    PUSH    H    ;SAVE COEFF. LIST POINTER
  2188.     CALL    PREPOP
  2189.     LXI    H,FTEMP
  2190.     CALL    AMUL1    ;Y=Y*X
  2191. ;
  2192. ;    ADD NEXT COEFFICIENT
  2193. ;
  2194.     CALL    PREPOP
  2195.     POP    H
  2196.     PUSH    H    ;HL=COEFF. LIST POINTER
  2197.     CALL    AADD1    ;Y=Y+COEFF
  2198. ;
  2199. ;BUMP POINTER TO NEXT COEFFICIENT
  2200. ;
  2201.     POP    H    ;COEFF POINTER
  2202.     LXI    B,-FPSIZ-1
  2203.     DAD    B    ;NEXT COEFF SIGN
  2204.     MOV    A,M
  2205.     INX    H    ;PTR TO EXPONENT
  2206.     ORA    A
  2207.     JP    POLY1    ;PROCESS NEXT COEFF
  2208.     RET    ;    NEGATIVE SIGN (-1) ENDS LIST
  2209. ;
  2210. ;    PREPARE FOR OPERATION
  2211. ;
  2212. PREPOP:    LHLD    ASTKA
  2213.     XCHG    ;    DE=ASTKA
  2214.     MOV    B,D
  2215.     MOV    C,E
  2216.     RET
  2217. ;
  2218. ;    QUADRANT COMPUTATION
  2219. ;    POPS TOP OF ARGUMENT STACK
  2220. ;    COMPUTE/GETS SIGN OF ARGUMENT,QUADRANT OF ARGUMENT
  2221. ;    AND INDEX INTO QUADRANT
  2222. ;
  2223. ;    EXITS WITH
  2224. ;    SP POINTING TO QUADRANT,MOD 4
  2225. ;    SP+2 POINTING TO SIGN OF ARGUMENT
  2226. ;    TOP OF ARGUMENT STACK HAS INDEX INTO QUADRANT
  2227. ;
  2228. QUADC:    LHLD    ASTKA
  2229.     DCX    H    ;POINT TO SIGN
  2230.     MOV    B,M
  2231.     XRA    A
  2232.     MOV    M,A    ;ARG SIGN=0
  2233.     MOV    H,B
  2234.     XTHL    ;    PUT SIGN ON STACK, POP RETURN
  2235.     PUSH    H    ;PUSH RETURN
  2236. ;
  2237. ;    COMPUTE QUADRANT OF ABS(X)
  2238. ;
  2239.     LHLD    ASTKA
  2240.     CALL    PSHAS    ;PUT COPY OF ARG ONTO STACK
  2241.     CALL    PREPOP
  2242.     LXI    H,PIC1    ;2/PI
  2243.     CALL    AMUL1    ;TOS=X*2/PI
  2244.     CALL    PREPOP
  2245.     CALL    AINT    ;TOS=INT(X*2/PI)
  2246.     LHLD    ASTKA
  2247.     CALL    PSHAS    ;ANOTHER COPY
  2248.     CALL    PFIX    ;POPS TOS TO DE
  2249.     MOV    A,E
  2250.     PUSH    PSW    ;QUADRANT
  2251.     CALL    PREPOP
  2252.     LXI    H,PIC2
  2253.     CALL    AMUL1    ;TOS=INT(X*2/PI)
  2254.     LXI    D,FTEMP
  2255.     CALL    POPA1    ;FTEMP=TOS
  2256.     CALL    PREPOP
  2257.     LXI    H,FTEMP
  2258.     CALL    ASUB1    ;TOS=TOS-FTEMP
  2259.     POP    PSW
  2260.     ANI    3    ;MOD 4
  2261.     POP    H
  2262.     PUSH    PSW    ;SAVE QUADRANT ON STACK
  2263.     PCHL    ;    RETURN
  2264. ;
  2265. ;    SET UP ARG FOR USER CALL
  2266. ;
  2267. AARG:    CALL    PFIX
  2268.     XCHG
  2269.     SHLD    CALLA
  2270.     LXI    D,FPSINK
  2271.     JMP    PSHA1    ;PUTS BACH THE ARG VALUE ON ARG STACK
  2272. ;
  2273. ;    USED TO CALL USER ROUTINE
  2274. ;
  2275. ACALL:    CALL    PFIX    ;GET THE ADDRESS
  2276.     LHLD    CALLA    ;GET THE USER ARGUMENT
  2277.     LXI    B,ACAL1    ;RETURN LINK FOR USER ROUTINE
  2278.     PUSH    B
  2279.     MOV    B,H    ;MOVE ARG TO BC (PL/M CONVENTION)
  2280.     MOV    C,L
  2281.     LHLD    MACSP    ;GET MACHINE LANGUAGE LINKAGE SP
  2282.     XCHG
  2283.     PCHL
  2284. ACAL1:    MOV    H,B    ;CONVERT FROM PL/M TO BASIC
  2285.     MOV    L,A    
  2286.     LXI    D,CALST
  2287.     CALL    CNS
  2288.     MVI    A,CR
  2289.     STAX    D
  2290.     LXI    D,CALST
  2291.     LXI    H,FPSINK
  2292.     CALL    FPIN
  2293.     LXI    D,FPSINK
  2294.     JMP    PSHA1    ;PUT THE RETURNED USER VALUE ON ARG STACK
  2295. ;
  2296. ;    - AUNTRP - FUNCTION TO POP LINE NUMBERS FROM TRAP STACK
  2297. ;
  2298. AUNTRP:    CALL    PFIX    ;GET POP COUNT
  2299.     LHLD    TRPSP    ;SET TRAP SP
  2300. AUNT1:    LXI    B,-TRPSTK ;SET UP BOUNDS CHECK
  2301.     CALL    ARGPOP    ;POP LINE NUMBER INTO BC
  2302.     SHLD    TRPSP    ;UPDATE TRAP SP
  2303.     CALL    ARGPA    ;PUSH LINE NUMBER ON ARG STACK IF COUNT=0
  2304.     JMP    AUNT1    ;LOOP TILL COUNT=0
  2305. ;
  2306. ;    - APOP - FUNCTION TO POP 16-BIT INTEGERS FROM MACHINE
  2307. ;        LANGUAGE LINKAGE STACK
  2308. ;
  2309. APOP:    CALL    PFIX    ;GET POP COUNT
  2310.     LHLD    MACSP    ;SET MACHINE LANGUAGE LINKAGE  SP
  2311. APOP1:    LXI    B,-MACSTK ;SET UP BOUNDS CHECK
  2312.     CALL    ARGPOP    ;POP A PARAMETER INTO BC
  2313.     SHLD    MACSP    ;UPDATE SP
  2314.     CALL    ARGPA    ;PUSH PARAM ONTO ARG STACK IF COUNT=0
  2315.     JMP    APOP1    ;LOOP TILL COUNT=0
  2316. ;
  2317. ;    - ARGPOP - SUBROUTINE TO POP 16-BIT WORDS FROM STACKS
  2318. ;        AND DO BOUNDS CHECKING ON STACKS
  2319. ;    ENTRY - HL IS STACK POINTER, BC IS NEGATIVE OF STACK BASE
  2320. ;    EXIT - BC IS POPPED WORD, HL IS UPDATED STACK POINTER
  2321. ;
  2322. ARGPOP:    PUSH    H    ;SAVE VALUE OF SP
  2323.     DAD    B    ;CHECK FOR STACK EMPTY
  2324.     XRA    A
  2325.     ORA    H
  2326.     JM    ARGP1    ;IF STACK NOT EMPTY
  2327.     LXI    H,ISTAK
  2328.     JMP    ERROR
  2329. ;
  2330. ARGP1:    POP    H    ;RETRIEVE SP
  2331.     INX    H    ;POP    WORD
  2332.     MOV    C,M
  2333.     INX    H
  2334.     MOV    B,M
  2335.     RET
  2336. ;
  2337. ;    - ARGPA - ARGPOP AUXILIARY SUBROUTINE
  2338. ;        DECREMENTS A COUNT IN DE
  2339. ;        JUMPS TO ACAL1 IF COUNT=0, RETURNS IF NOT
  2340. ;    ENTRY - BC CONTAINS WORD TO PASS TO ACAL1, DE IS COUNT
  2341. ;    EXIT - BA CONTAINS WORD
  2342. ;
  2343. ARGPA:    DCX    D
  2344.     MOV    A,D
  2345.     ORA    E
  2346.     RNZ
  2347.     MOV    A,C
  2348.     POP    H
  2349.     JMP    ACAL1
  2350. ;
  2351. ;    - APEEK - FUNCTION TO READ CONTENTS OF MEMORY
  2352. ;
  2353. APEEK:    CALL    PFIX    ;SET MEMORY ADDR
  2354.     LDAX    D    ;FETCH BYTE
  2355.     MVI    B,0
  2356.     JMP    ACAL1    ;PUT BYTE ON ARGUMENT STACK
  2357. ;
  2358. ;    - AINP - FUNCTION TO INPUT BYTE FROM PORT
  2359. ;
  2360. AINP:    CALL    BYTAR1    ;GET PORT ADDR
  2361.     MOV    A,E
  2362.     STA    AINP1+1    ;SET UP INPUT INSTRUCTION
  2363. AINP1:    IN    0
  2364.     MVI    B,0
  2365.     JMP    ACAL1    ;PUT BYTE ON ARG STACK
  2366. ;
  2367. ;    INT FUNCTION ACTION ROUTINE
  2368. ;
  2369. AINT:    LDAX    B
  2370.     SUI    129
  2371.     JP    AINT1
  2372. ;
  2373. ;    ZERO IF VALUE LESS THAN ONE
  2374. ;
  2375.     MVI    D,FPSIZ
  2376.     XRA    A
  2377. AINT0:    STAX    B
  2378.     DCX    B
  2379.     DCR    D
  2380.     JNZ    AINT0
  2381.     RET
  2382. ;
  2383. ;    EXP>0
  2384. ;
  2385. AINT1:    SUI    FPNIB-1
  2386.     RNC
  2387.     MOV    D,A    ;COUNT
  2388.     DCX    B
  2389. AINT2:    DCX    B
  2390.     LDAX    B
  2391.     ANI    360Q
  2392.     STAX    B
  2393.     INR    D
  2394.     RZ
  2395.     XRA    A
  2396.     STAX    B
  2397.     INR    D
  2398.     JNZ    AINT2
  2399.     RET
  2400. ;
  2401. ;        DIMENSION MATRIX
  2402. ;    SYMTAB ADDR IN HL, HL NOT CLOBBERED
  2403. ;    DE CONTAINS SIZE IN NUMBER OF ELEMENTS
  2404. ;
  2405. DIMS:    PUSH    H
  2406.     INX    D
  2407.     PUSH    D
  2408.     LXI    H,0
  2409.     MVI    C,FPSIZ
  2410.     CALL    RADD    ;MULTIPLY NELTS BY BYTES PER VALUE
  2411.     XCHG
  2412.     LHLD    MATA    ;HL = MATRIX BASE ADDRESS
  2413.     MOV    B,H    ;COPY HL TO BC
  2414.     MOV    C,L
  2415.     PUSH    H
  2416.     DAD    D    ;HL = ADDR. OF 1ST LOC. AFTER THIS MATRIX
  2417. MATCLR:    XRA    A    ;ZERO STORAGE FOR THIS MATRIX
  2418.     STAX    B
  2419.     INX    B
  2420.     MOV    A,C    ;END LOOP WHEN BC=HL
  2421.     SUB    L
  2422.     MOV    A,B
  2423.     SBB    H
  2424.     JNZ    MATCLR
  2425.     CALL    STOV    ;CHECK THAT STORAGE NOT EXHAUSTED
  2426.     SHLD    MATA    ;UPDATA MATRIX FREE POINTER
  2427.     POP    B    ;BASE ADDR
  2428.     POP    D    ;NELTS
  2429.     POP    H    ;SYMTAB ADDR
  2430.     PUSH    H
  2431.     MOV    M,D
  2432.     DCX    H
  2433.     MOV    M,E
  2434.     DCX    H
  2435.     MOV    M,B
  2436.     DCX    H
  2437.     MOV    M,C    ;SYMTAB ENTRY NOW SET UP
  2438.     POP    H
  2439.     RET
  2440. ;
  2441. ;        FIND VARIABLE OPTIONALLY SUBSCRIPTED IN TEXT
  2442. ;    SETS CARRY IF NOT FOUND
  2443. ;    RETURNS ADDR OF VARIABLE IN HL
  2444. ;    UPDATES TXA IF FOUND
  2445. ;
  2446. VAR:    CALL    ALPHA
  2447.     RC
  2448.     CALL    NAME2
  2449.     CALL    GC
  2450.     CPI    LPARRW
  2451.     JZ    VAR1    ;TEST IF SUBSCRIPTED
  2452. ;
  2453. ;    MUST BE SCALAR VARIABLE
  2454. ;
  2455.     CALL    STLK    ;RETURNS ENTRY ADDR IN HL
  2456.     ORA    A    ;CLEAR CARRY
  2457.     RET
  2458. ;
  2459. ;    MUST BE SUBSCRIPTED
  2460. ;
  2461. VAR1:    CALL    GCI    ;GOBBLE LEFT PAREN
  2462.     MVI    A,200Q
  2463.     ORA    C
  2464.     MOV    C,A    ;SET TYPE TO MATRIX
  2465.     CALL    STLK
  2466.     PUSH    H    ;SYMBOL TABLE
  2467.     LXI    D,10    ;DEFAULT MATRIX SIZE
  2468.     CC    DIMS    ;DEFAULT DIMENSION MATRIX
  2469.     CALL    EXPRB    ;EVALUATE SUBSCRIPT EXPRESSION
  2470.     CALL    PFIX    ;DE NOW HAS INTEGER
  2471.     MVI    B,')'
  2472.     CALL    EATC    ;GOBBLE RIGHT PAREN
  2473.     POP    H
  2474.     DCX    H
  2475.     CALL    DCMP    ;BOUNDS CHECK INDEX
  2476.     JNC    E5
  2477.     DCX    H
  2478.     DCX    H
  2479.     CALL    LHLI    ;GET BASE ADDR
  2480.     MVI    C,FPSIZ
  2481.     INX    D    ;BECAUSE BASE ADDR IS TO ELEMENT -1
  2482.     CALL    RADD    ;ADD INDEX, CLEAR CARRY
  2483.     RET
  2484. ;
  2485. ;    JUNK ON END OF STATEMENT, TEST IF AT END OF FILE
  2486. ;    DOES NOT CLOBBER DE
  2487. ;    EATS CHARACTER AND LINE COUNT AFTER CR
  2488. ;    LEAVES NEW TXA IN HL
  2489. ;    SETS CARRY IF END OF FILE
  2490. ;
  2491. JOE:    CALL    GCI
  2492.     CPI    ';'
  2493.     RZ
  2494.     CPI    CR
  2495.     JNZ    E1
  2496.     MOV    A,M
  2497.     DCR    A
  2498.     JZ    JOE2
  2499.     INX    H
  2500.     INX    H
  2501.     INX    H    ;SKIP OVER COUNT AND LINE NUMBER
  2502. JOE1:    SHLD    TXA
  2503.     RET
  2504. ;
  2505. JOE2:    STC
  2506.     JMP    JOE1
  2507. ;
  2508. ;        GET NAME FROM TEXT
  2509. ;    SETS CARRY IF NAME NOT FOUND
  2510. ;    IF SUCCEEDS RETURNS NAME IN BC, C=0 IF NO DIGIT IN NAME
  2511. ;
  2512. NAME:    CALL    ALPHA
  2513.     RC
  2514. NAME2:    MOV    B,A
  2515.     MVI    C,0
  2516.     CALL    DIG
  2517.     CMC
  2518.     RNC
  2519.     MOV    C,A
  2520.     ORA    A    ;CLEAR CARRY
  2521.     RET
  2522. ;
  2523. ;        SYMBOL TABLE LOOKUP
  2524. ;    BC CONTAIN NAME AND CLASS
  2525. ;    IF NOT FOUND THEN CREATE ZERO'ED ENTRY AND SET CARRY
  2526. ;    HL HAS ADDRESS ON RET
  2527. ;
  2528. STLK:    LHLD    MEMTOP
  2529.     LXI    D,-STESIZ;SET UP BASE AND INCREMENT FOR SEARCH LOOP
  2530. STLK0:    MOV    A,M
  2531.     ORA    A
  2532.     JZ    STLK2    ;TEST IF END OF TABLE
  2533.     CMP    B
  2534.     JNZ    STLK1    ;TEST IF ALPHA COMPARES
  2535.     DCX    H
  2536.     MOV    A,M    ;LOOK FOR DIGIT
  2537.     CMP    C
  2538.     DCX    H
  2539.     RZ        ;CARRY CLEAR SO RET
  2540.     INX    H
  2541.     INX    H
  2542. STLK1:    DAD    D    ;DIDN'T COMPARE, DECREMENT POINTER
  2543.     JMP    STLK0
  2544. ;
  2545. ;    ADD ENTRY TO SYMTAB
  2546. ;
  2547. STLK2:    MOV    M,B
  2548.     DCX    H
  2549.     MOV    M,C
  2550.     INX    H
  2551.     XCHG
  2552.     DAD    D
  2553.     SHLD    STB    ;STORE NEW END OF SYMTAB POINTER
  2554.     DCX    D
  2555.     DCX    D
  2556.     XCHG
  2557.     STC
  2558.     RET
  2559. ;
  2560. ;    GOBBLES NEXT CHARACTER IF ALPHABETIC
  2561. ;    SETS CARRY IF NOT
  2562. ;    NEXT CHAR IN ACC ON FAILURE
  2563. ;
  2564. ALPHA:    CALL    GC
  2565.     CPI    'A'
  2566.     RC
  2567.     CPI    'Z'+1
  2568.     CMC
  2569.     RC
  2570.     JMP    DIGT1
  2571. ;
  2572. ;    GOBBLES NEXT TEXT CHAR IF DIGIT
  2573. ;    SETS CARRY IF NOT
  2574. ;    NEXT CHAR IN ACC ON FAILURE
  2575. ;
  2576. DIG:    CALL    GC
  2577.     CPI    '0'
  2578.     RC
  2579.     CPI    '9'+1
  2580.     CMC
  2581.     RC
  2582. DIGT1:    INX    H
  2583.     SHLD    TXA
  2584.     RET
  2585. ;
  2586. ;    COPYS FPSIZ BYTES AT ADDR HL TO ADDR DE
  2587. ;    ON EXIT HL POINTS TO ADR-1 OF LAST BYTE COPIED
  2588. ;
  2589. VCOPY:    MVI    C,FPSIZ
  2590. VCOP1:    MOV    A,M
  2591.     STAX    D
  2592.     DCX    H
  2593.     DCX    D
  2594.     DCR    C
  2595.     JNZ    VCOP1
  2596.     RET
  2597. ;
  2598. ;    PUSH VALUE ADDRESSED BY HL ONTO ARG STACK
  2599. ;    SETS ARGF, CLEARS CARRY
  2600. ;
  2601. PSHAS:    XCHG
  2602. PSHA1:    LHLD    ASTKA
  2603.     LXI    B,-FPSIZ
  2604.     DAD    B
  2605.     SHLD    ASTKA    ;DECREMENT ARG STACK POINTER
  2606.     XCHG
  2607.     CALL    VCOPY
  2608.     MVI    A,1
  2609.     STA    ARGF    ;CLEAR ARGF
  2610.     ORA    A    ;CLEAR CARRY
  2611.     RET
  2612. ;
  2613. ;        POP ARG STACK
  2614. ;    HL CONTAINS ADDRESS TO PUT POPPED VALUE AT
  2615. ;
  2616. POPAS:    XCHG
  2617. POPA1:    LHLD    ASTKA
  2618.     PUSH    H
  2619.     LXI    B,FPSIZ
  2620.     DAD    B
  2621.     SHLD    ASTKA    ;INCREMENT STACK POINTER
  2622.     POP    H
  2623.     JMP    VCOPY
  2624. ;
  2625. ;        PUSH FRAME ONTO CONTROL STACK
  2626. ;    TAKES MINUS AMOUNT TO SUB FROM CSTKA IN DE
  2627. ;    DOES OVERFLOW TEST AND RETURNS OLD CSTKA-1
  2628. ;
  2629. PSHCS:    LHLD    CSTKA
  2630.     PUSH    H
  2631.     DAD    D
  2632.     SHLD    CSTKA
  2633.     XCHG
  2634.     LXI    H,LCSTKA;ADDR CONTAINS CSTKL
  2635.     CALL    DCMP
  2636.     JC    E4
  2637.     POP    H
  2638.     DCX    H
  2639.     RET
  2640. ;
  2641. ;        STORAGE OVERFLOW TEST
  2642. ;    TEST THAT VALUE IN HL IS BETWEEN MATA AND STB
  2643. ;    DOES NOT CLOBBER HL
  2644. ;
  2645. STOV:    XCHG
  2646.     LXI    H,MATA
  2647.     CALL    DCMP
  2648.     JC    E8
  2649.     LXI    H,STB
  2650.     CALL    DCMP
  2651.     XCHG
  2652.     RC
  2653. E8:    LXI    H,STOVL
  2654.     JMP    ERROR
  2655. ;
  2656. ;    INCREMENT TXA IF NEXT NON-BLANK CHAR IS EQUAL TO B
  2657. ;    ELSE SYNTAX ERROR
  2658. ;
  2659. EATC:    CALL    GCI
  2660.     CMP    B
  2661.     RZ
  2662.     JMP    E1
  2663. ;
  2664. ;    GET NEXT NON-BLANK CHAR INTO ACC
  2665. ;    INCREMENT PAST BLANKS ONLY
  2666. ;
  2667. GC:    CALL    GCI
  2668.     DCX    H
  2669.     SHLD    TXA
  2670.     RET
  2671. ;
  2672. ;        GET NEXT NON-BLANK TEXT CHAR AND INCREMENT TXA
  2673. ;    DOES NOT CLOBBER DE, BC
  2674. ;    RETURN CHAR IN ACC
  2675. ;
  2676. GCI:    LHLD    TXA
  2677. GCI0:    MOV    A,M
  2678.     INX    H
  2679.     CPI    ' '
  2680.     JZ    GCI0
  2681.     SHLD    TXA
  2682.     RET
  2683. ;
  2684. ;        REPEAT ADD
  2685. ;    ADDS DE TO HL C TIMES
  2686. ;
  2687. RADD:    DAD    D
  2688.     DCR    C
  2689.     JNZ    RADD
  2690.     RET
  2691. ;
  2692. ;        PRINT MESSAGE ADDRESSED BY HL
  2693. ;    ENDS WITH CHARACTER PROVIDED IN C
  2694. ;    RETURN IN HL ADDRESS OF TERMINATOR
  2695. ;
  2696. PRNTCR:    MVI    C,CR
  2697.     JMP    PRN1
  2698. ;
  2699. PRNT:    MVI    C,'"'
  2700. PRN1:    MOV    A,M    ;GET NEXT CHAR
  2701.     MOV    B,A    ;FOR CHOUT
  2702.     CMP    C    ;END OF MESSAGE TEST
  2703.     RZ
  2704.     CPI    CR
  2705.     JZ    E1    ;NEVER PRINT A CR IN THIS  ROUTINE
  2706.     CALL    CHOUT
  2707.     INX    H
  2708.     JMP    PRN1
  2709. ;
  2710. ;    16 BIT UNSIGNED COMPARE
  2711. ;    COMPARE DE AGAINST VALUE ADDRESSED BY HL
  2712. ;    CLOBBERS A ONLY
  2713. ;
  2714. DCMP:    MOV    A,E
  2715.     SUB    M
  2716.     INX    H
  2717.     MOV    A,D
  2718.     SBB    M
  2719.     DCX    H
  2720.     RNZ
  2721.     MOV    A,E
  2722.     SUB    M
  2723.     ORA    A    ;CLEAR CARRY
  2724.     RET
  2725. ;
  2726. ;    INDIRECT LOAD HL THRU HL
  2727. ;
  2728. LHLI:    PUSH    PSW
  2729.     MOV    A,M
  2730.     INX    H
  2731.     MOV    H,M
  2732.     MOV    L,A
  2733.     POP    PSW
  2734.     RET
  2735. ;
  2736. ;    GET FP CONSTANT FROM TEXT
  2737. ;    PUSHES VALUE ON ARG STACK AND SETS ARGF FLAG
  2738. ;    SETS CARRY IF NOT FOUND
  2739. ;
  2740. CONST:    LHLD    TXA    ;PREPARE CALL FPIN
  2741.     XCHG
  2742.     LXI    H,FPSINK
  2743.     CALL    FPIN
  2744.     RC
  2745.     DCX    D
  2746.     XCHG
  2747.     SHLD    TXA    ;NOW POINTS TO TERMINATOR
  2748.     LXI    D,FPSINK
  2749.     CALL    PSHA1
  2750.     XRA    A
  2751.     INR    A    ;SET A TO 1 AND CLEAR CARRY
  2752.     STA    ARGF
  2753.     RET
  2754. ;
  2755. ;    DIRECT STATEMENT CHECKING ROUTINE
  2756. ;
  2757. DIRT:    LDA    DIRF
  2758.     ORA    A
  2759.     RZ
  2760.     LXI    H,DIRIN
  2761.     JMP    ERROR
  2762. ;
  2763. ;    FIND TEXT LINE WITH LINE NUMBER GIVEN IN DE
  2764. ;    RETURNS TEXT ADDR COUNT BYTE IN HL
  2765. ;
  2766. FINDLN:    LHLD    BOFA
  2767.     MVI    B,0
  2768. FIND1:    MOV    C,M
  2769.     MOV    A,C
  2770.     CPI    EOF
  2771.     JZ    LERR
  2772.     INX    H
  2773.     CALL    DCMP
  2774.     DCX    H
  2775.     RZ
  2776.     DAD    B
  2777.     JMP    FIND1
  2778. ;
  2779. LERR:    LXI    H,LNUMB
  2780.     JMP    ERROR
  2781. ;
  2782. ;        FIX FLOATING TO POSITIVE INTEGER
  2783. ;    RETURN INTEGER VALUE IN DE
  2784. ;    FP VALUE FROM TOP OF ARG STACK, POP ARG STACK
  2785. ;
  2786. PFIX:    LHLD    ASTKA
  2787.     MOV    B,H
  2788.     MOV    C,L
  2789.     PUSH    H
  2790.     CALL    AINT
  2791.     LXI    H,FPSINK
  2792.     CALL    POPAS
  2793.     POP    H
  2794.     MOV    C,M    ;EXPONENT
  2795.     DCX    H
  2796.     MOV    A,M    ;SIGN
  2797.     ORA    A
  2798.     JNZ    E5    ;NEGATIVE NO GOOD
  2799.     LXI    D,-FPSIZ+1
  2800.     DAD    D
  2801.     LXI    D,0
  2802.     MOV    A,C
  2803.     ORA    A
  2804.     RZ
  2805.     DCR    C    ;SET UP FOR LOOP CLOSE TEST
  2806. PFIX1:    INX    H
  2807.     MOV    A,M
  2808.     RRC
  2809.     RRC
  2810.     RRC
  2811.     RRC
  2812.     CALL    MUL10
  2813.     JC    E5
  2814.     DCR    C
  2815.     RP
  2816.     MOV    A,M
  2817.     CALL    MUL10
  2818.     JC    E5
  2819.     DCR    C
  2820.     JM    PFIX1
  2821.     RET
  2822. ;
  2823. ;    TAKE NEXT  DIGIT IN A (MASK TO 17Q), ACCUMULATE TO DE
  2824. ;    PRESERVES ALL BUT A, DE
  2825. ;
  2826. MUL10:    PUSH    H
  2827.     INX    SP
  2828.     INX    SP
  2829.     MOV    H,D    ;GET ORIGINAL VALUE TO HL
  2830.     MOV    L,E
  2831.     DAD    H    ;DOUBLE IT
  2832.     RC
  2833.     DAD    H    ;AGAIN
  2834.     RC
  2835.     DAD    D    ;PLUS ORIGINAL MAKES 5 TIMES ORIG
  2836.     RC
  2837.     DAD    H    ;TIMES TWO MAKES TEN
  2838.     RC
  2839.     XCHG
  2840.     DCX    SP
  2841.     DCX    SP
  2842.     POP    H
  2843.     ANI    17Q
  2844.     ADD    E
  2845.     MOV    E,A
  2846.     MOV    A,D
  2847.     ACI    0    ;PROPOGATE THE CARRY
  2848.     MOV    D,A
  2849.     RET
  2850. ;
  2851. ;        GET INTEGER FROM TEXT
  2852. ;    SET CARRY IF NOT FOUND
  2853. ;    RETURN INTEGER VALUE IN HL
  2854. ;    RETURN TERMINATOR IN ACC
  2855. ;
  2856. INTGER:    CALL    DIG
  2857.     RC
  2858.     LXI    D,0
  2859.     JMP    INTG2
  2860. ;
  2861. INTG1:    CALL    DIG
  2862.     MOV    H,D
  2863.     MOV    L,E
  2864.     CMC
  2865.     RNC
  2866. INTG2:    SUI    '0'
  2867.     CALL    MUL10
  2868.     JNC    INTG1
  2869.     RET
  2870. ;
  2871. ;        CONVERT INTEGER TO STRING
  2872. ;    DE CONTAINS ADDR OF STRING, RETURN UPDATED VALUE IN DE
  2873. ;    HL CONTAINS VALUE TO CONVERT
  2874. ;
  2875. CNS:    XRA    A    ;SET FOR NO LEADING ZEROES
  2876.     LXI    B,-10000
  2877.     CALL    RSUB
  2878.     LXI    B,-1000
  2879.     CALL    RSUB
  2880.     LXI    B,-100
  2881.     CALL    RSUB
  2882.     LXI    B,-10
  2883.     CALL    RSUB
  2884.     LXI    B,-1
  2885.     CALL    RSUB
  2886.     RNZ
  2887.     MVI    A,'0'
  2888.     STAX    D
  2889.     INX    D
  2890.     RET
  2891. ;
  2892. ;    TAKE VALUE IN HL
  2893. ;    SUB MINUS NUMBER IN BE THE MOST POSSIBLE TIMES
  2894. ;    PUT VALUE ON STRING AT DE
  2895. ;    IF A=0 THEN DONT PUT ZERO ON STRING
  2896. ;    RETURN NON-ZERO IN A IF PUT ON STRING
  2897. ;
  2898. RSUB:    PUSH    D
  2899.     MVI    D,0FFH
  2900. RSUB1:    PUSH    H
  2901.     INX    SP
  2902.     INX    SP
  2903.     INR    D
  2904.     DAD    B
  2905.     JC    RSUB1
  2906.     DCX    SP
  2907.     DCX    SP
  2908.     POP    H
  2909.     MOV    B,D
  2910.     POP    D
  2911.     ORA    B    ;A GETS 0 IF A WAS 0 AND B IS 0
  2912.     RZ
  2913.     MVI    A,'0'
  2914.     ADD    B
  2915.     STAX    D
  2916.     INX    D
  2917.     RET
  2918. ;
  2919. ;    INPUT CHARACTER FROM TERMINAL
  2920. ;
  2921. INCHAR:    PUSH    B
  2922.     PUSH    H
  2923.     MVI    C,1
  2924.     CALL    SYSTEM
  2925.     POP    H
  2926.     POP    B
  2927.     CPI    ESC
  2928.     JZ    CMND1
  2929.     CPI    LF    ;IGNORE LINE FEEDS
  2930.     JZ    INCHAR
  2931.     CPI    NULL    ;IGNORE NULLS
  2932.     JZ    INCHAR
  2933.     MOV    B,A
  2934.     RET
  2935. ;
  2936. INL0:    CALL    CRLF
  2937. INLINE:    LXI    H,IBUF
  2938.     MVI    C,LINLEN
  2939. INL1:    CALL    INCHAR
  2940.     CPI    RUBOUT
  2941.     JZ    INL2    ;RUBOUT LAST CHAR
  2942.     MOV    M,A
  2943.     MOV    A,B
  2944.     CPI    CNTRU    ;LINE DELETION
  2945.     JZ    INL0
  2946.     MVI    B,LF    ;IN CASE WE ARE DONE
  2947.     CPI    CR
  2948.     JZ    CHOUT    ;DO LF THEN RETURN
  2949.     INX    H
  2950.     DCR    C
  2951.     JNZ    INL1
  2952.     LXI    H,LENGT
  2953.     JMP    ERROR
  2954. ;
  2955. INL2:    MOV    A,C
  2956.     MVI    B,BELL
  2957.     CPI    LINLEN
  2958.     JZ    INL3    ;IF DELETION BEFORE BEGINNING OF LINE
  2959.     DCX    H
  2960.     INR    C
  2961.     MOV    B,M
  2962. INL3:    PUSH    B
  2963.     PUSH    H
  2964.     CALL    CHOUT
  2965.     POP    H
  2966.     POP    B
  2967.     JMP    INL1
  2968. ;
  2969. ;        OUPUT ROUTINES
  2970. ;
  2971. CHOUT:    PUSH    B
  2972.     PUSH    D
  2973.     PUSH    H
  2974.     MVI    C,2
  2975.     MOV    E,B
  2976.     LDA    PFLAG    ;SELECT LINE PRINTER OR CONSOLE
  2977.     ORA    A
  2978.     JZ    CHO1    ;IF CONSOLE
  2979.     MVI    C,5
  2980. CHO1:    CALL    SYSTEM    ;OUTPUT CHARACTER THRU CP/M
  2981.     POP    H
  2982.     POP    D
  2983.     POP    B
  2984.     MOV    A,B
  2985. CHCHK:    CPI    CR
  2986.     JNZ    CHLF    ;NOT CR IS IT LF?
  2987.     XRA    A
  2988.     JMP    PSTOR    ;RETURN PHEAD TO ZERO
  2989. ;
  2990. CHLF:    CPI    LF
  2991.     JZ    NULCH    ;IF LINE FEED PROCESS THE NULLS
  2992.     CPI    40Q    ;NO PHEAD INC IF CONTROL CHAR
  2993.     RC
  2994.     LDA    PHEAD
  2995.     INR    A
  2996. PSTOR:    STA    PHEAD
  2997.     RET
  2998. ;
  2999. NULCH:    LDA    NULLCT    ;OUTPUT NULL CHARS
  3000.     ORA    A
  3001.     RZ
  3002.     PUSH    B
  3003.     MOV    C,A
  3004.     MVI    B,NULL
  3005. CH2:    CALL    CHOUT    ;OUTPUT COUNT 'C' NULLS
  3006.     DCR    C
  3007.     JNZ    CH2
  3008.     POP    B
  3009.     RET
  3010. ;
  3011. CRLF2:    CALL    CRLF
  3012. CRLF:    MVI    B,CR
  3013.     CALL    CHOUT
  3014.     MVI    B,LF
  3015.     JMP    CHOUT
  3016. ;
  3017. ;    CHECK IF PANIC CHARACTER HAS BEEN HIT
  3018. ;
  3019. PCHECK:    MVI    C,11
  3020.     CALL    SYSTEM    ;CHECK FOR A CHARACTER TYPED
  3021.     ORA    A
  3022.     RZ        ;IF NO CHARACTER TYPED
  3023.     MVI    C,1    ;GET THE CHARACTER
  3024.     CALL    SYSTEM
  3025.     CPI    ESC
  3026.     JZ    BREAK    ;IF OPERATOR INTERRUPT REQUEST
  3027.     CPI    CR
  3028.     RNZ        ;IF NOT PROGRAM STATUS REQUEST
  3029.     LDA    PFLAG    ;SAVE I/O FLAG AND SELECT CONSOLE
  3030.     PUSH    PSW
  3031.     XRA    A
  3032.     STA    PFLAG
  3033.     LXI    H,RNING    ;OUTPUT 'RUNNING' MESSAGE
  3034.     CALL    PRNT
  3035.     CALL    CRLF2
  3036.     POP    PSW    ;RESTORE I/O FLAG
  3037.     STA    PFLAG
  3038.     RET
  3039. ;
  3040. BREAK:    XRA    A    ;TURN OFF PFLAG INCASE LLIST OR LPRINT IN PROGRESS
  3041.     STA    PFLAG
  3042.     JMP    STOP1
  3043. ;
  3044. ;    OUTPUT FP NUMBER ADDRESSED BY HL
  3045. ;
  3046. FPOUT:    LXI    B,-DIGIT-1
  3047.     DAD    B
  3048.     MOV    B,H
  3049.     MOV    C,L
  3050.     LXI    H,ABUF    ;OUTPUT BUFFER
  3051.     LDA    INFES    ;OUTPUT FORMAT
  3052.     STA    FES    ;STORE IT
  3053.     MVI    E,DIGIT
  3054.     MVI    M,0    ;CLEAR ROUND OFF OVERFLOW BUFFER
  3055.     INX    H    ;ABUF+1
  3056. ;
  3057. NXT:    LDAX    B    ;GET DIGIT AND UNPACK
  3058.     MOV    D,A
  3059.     RAR
  3060.     RAR
  3061.     RAR
  3062.     RAR
  3063.     ANI    17Q    ;REMOVE BOTTOM DIGIT
  3064.     MOV    M,A    ;STORE TOP DIGIT IN OUTPUT BUFFER (ABUF)
  3065.     INX    H
  3066.     MOV    A,D    ;NOW GET BOTTOM DIGIT
  3067.     ANI    17Q
  3068.     MOV    M,A    ;STORE IT
  3069.     INX    H
  3070.     INX    B
  3071.     DCR    E
  3072.     JNZ    NXT
  3073.     LDAX    B
  3074.     STA    FSIGN    ;STORE SIGN OF NUMBER
  3075.     XRA    A
  3076.     MOV    M,A    ;CLEAR ROUND-OFF BUFFER (ABUF+13) 12 DIG NO RND
  3077.     LXI    H,XSIGN    ;EXPONENT SIGN STORE
  3078.     MOV    M,A    ;CLEAR XSIGN
  3079. ;
  3080. FIX:    INX    B    ;GET EXPONENT
  3081.     LDAX    B
  3082.     ORA    A    ;EXPONENT ZERO?
  3083.     JZ    ZRO
  3084.     SUI    128    ;REMOVE NORMALIZING BIAS
  3085.     JNZ    FIX2
  3086.     INR    M    ;INCREMENT XSIGN TO NEGATIVE FLAG (1) LATER ZERO
  3087. FIX2:    JP    CHK13
  3088.     CMA        ;ITS A NEGATIVE EXPONENT
  3089.     INR    M    ; INCREMENT XSIGN TO NEGATIVE (1)
  3090. ZRO:    INR    A
  3091. CHK13:    LXI    H,EXPO    ;EXPONENT TEMP STORE
  3092.     MOV    M,A
  3093.     MOV    E,A
  3094.     CPI    DIGIT*2
  3095.     LXI    H,FES    ;FORMAT TEMP BYTE
  3096.     JC    CHKXO
  3097. CHK40:    MVI    A,1    ;FORCE EXPONENTIAL PRINTOUT
  3098.     ORA    M    ;SET FORMAT FOR XOUT
  3099.     MOV    M,A
  3100. ;
  3101. CHKXO:    MOV    A,M    ;CHECK IF EXPONENTIAL PRINTOUT
  3102.     RAR
  3103.     JNC    CHKX3
  3104.     ANI    17Q
  3105.     CPI    DIGIT*2
  3106.     JC    CHKX2
  3107.     MVI    A,DIGIT*2-1 ;MAX DIGITS
  3108. CHKX2:    MOV    D,A
  3109.     INR    A
  3110.     JMP    ROUND
  3111. ;
  3112. CHKX3:    ANI    17Q    ;ADD EXPONENT AND DECIMAL PLACES
  3113.     MOV    D,A
  3114.     ADD    E
  3115.     CPI    DIGIT*2+1
  3116.     MOV    B,A
  3117.     JC    CHKXN
  3118.     MOV    A,M
  3119.     ANI    100Q
  3120.     JNZ    CHK40
  3121. ;
  3122. CHKXN:    LDA    XSIGN    ;CHECK EXPONENT SIGN
  3123.     ORA    A
  3124.     JNZ    XNEG    ;ITS NEGATIVE
  3125.     MOV    A,B
  3126.     JMP    ROUND
  3127. ;
  3128. XNEG:    MOV    A,D    ;SUBTRACT EXPONENT AND DECIMAL PLACE COUNT
  3129.     SUB    E
  3130.     JNC    XN2
  3131. XN1:    LDA    INFES
  3132.     ORA    A
  3133.     JP    ZERO
  3134.     ANI    16Q
  3135.     JZ    ZERO
  3136.     RRC
  3137.     MOV    E,A
  3138.     DCR    E
  3139.     MVI    C,1
  3140.     LXI    H,ABUF-1
  3141.     JMP    NRND
  3142. ;
  3143. XN2:    JZ    XN1
  3144.     JMP    ROUND
  3145. ;
  3146. ;
  3147. CLEAN:    MVI    B,37Q    ;CLEAR FLAGS
  3148.     ANA    B
  3149.     CPI    DIGIT*2+1
  3150.     RC
  3151.     MVI    A,DIGIT*2+1 ;MAX DIGITS OUT
  3152.     RET
  3153. ;
  3154. ;    THIS ROUTINE IS USED TO ROUND DATA TO THE
  3155. ;    SPECIFIED DECIMAL PLACE
  3156. ;
  3157. ROUND:    CALL    CLEAN
  3158.     MOV    C,A
  3159.     MVI    B,0
  3160.     LXI    H,ABUF+1
  3161.     DAD    B    ;GET ROUND-OFF ADDRESS
  3162.     SHLD    ADDT
  3163.     MOV    A,M
  3164.     CPI    5    ;ROUND IF >=5
  3165.     JC    TRL2-1
  3166. ;
  3167. LESS1:    DCX    H
  3168.     INR    M    ;ROUND UP
  3169.     MOV    A,M
  3170.     ORA    A
  3171.     JZ    TRL2
  3172.     CPI    10    ;CHECK IF ROUNDED NUMBER >9
  3173.     JNZ    TRAIL
  3174.     MVI    M,0
  3175.     JMP    LESS1
  3176. ;
  3177. ;    THIS ROUTINE IS USED TO ELIMINATE TRAILING ZERO'S
  3178. ;
  3179. TRAIL:    LHLD    ADDT
  3180.     DCX    H
  3181. TRL2:    LDA    FES    ;CHECK IF TRAILING ZERO'S ARE WANTED
  3182.     RAL
  3183.     JC    FPRNT    ;YES- GO PRINT DATA
  3184. TRL3:    MOV    A,M
  3185.     ORA    A    ;IS IT ZERO?
  3186.     JNZ    FPRNT    ;NO- GO PRINT
  3187.     DCX    H
  3188.     DCR    C    ;YES- FIX OUTPUT DIGIT COUNT
  3189.     JM    ZERO
  3190.     JMP    TRL3
  3191. ;
  3192. ;    HERE STARTS THE PRINT FORMAT ROUTINES
  3193. ;
  3194. FPRNT:    LXI    H,ABUF
  3195.     MOV    A,M    ;CHECK IF ROUNDED UP TO 1
  3196.     ORA    A
  3197.     JZ    NRND    ;JUMP IF NOT
  3198.     MVI    B,1
  3199.     LDA    XSIGN    ;IS EXPONENT NEGATIVE?
  3200.     ORA    A
  3201.     JZ    POSR
  3202.     MVI    B,0FFH
  3203. ;
  3204. POSR:    LDA    EXPO    ;GET EXONENT
  3205.     ORA    A
  3206.     JNZ    PO2    ;IS IT ZERO?    (E+0)
  3207.     STA    XSIGN
  3208.     MVI    B,1
  3209. PO2:    ADD    B    ;FIX EXPONENT COUNT
  3210.     STA    EXPO
  3211.     INR    E
  3212.     INR    C
  3213.     DCX    H
  3214. ;
  3215. NRND:    INX    H
  3216.     MOV    A,C
  3217.     CPI    DIGIT*2+1    ;CHECK FOR MAX DIGITS OUT
  3218.     JNZ    NRND1
  3219.     DCR    C
  3220. NRND1:    LDA    FSIGN    ;CHECK IF NEGATIVE NUMBER
  3221.     RAR
  3222.     JNC    PRIN2    ;GO OUTPUT RADIX AND NUMBER
  3223.     CALL    NEG    ;OUTPUT (-)
  3224.     JMP    PRI21
  3225. ;
  3226. ;
  3227. PRIN2:    CALL    SPACE    ;OUTPUT A SPACE
  3228. PRI21:    LDA    FES    ;GET OUTPUT FORMAT
  3229.     RAR        ;CHECK IF EXPONENTIAL OUTPUT FORMAT
  3230.     JC    XPRIN
  3231.     LDA    XSIGN    ;GET EXPONENT SIGN
  3232.     ORA    A    ;CHECK IF NEGATIVE EXPONENT
  3233.     JZ    POSIT
  3234.     MOV    A,C
  3235.     ORA    A
  3236.     JNZ    PRIN4    ;OUTPUT RADIX AND NUMBER
  3237.     CALL    ZERO    ;NO DIGITS AFTER RADIX, OUTPUT ZERO AND DONE
  3238.     RET
  3239. ;
  3240. PRIN4:    CALL    RADIX    ;PRINT DECIMAL POINT
  3241.     XRA    A
  3242.     ORA    E
  3243.     JZ    PRIN5    ;JUMP IF NO ZEROS TO PRINT
  3244.     CALL    ZERO    ;FORCE PRINT A ZERO
  3245.     DCR    E
  3246.     JNZ    PRIN4+3
  3247. ;
  3248. PRIN5:    CALL    NOUT    ;PRINT ASCII DIGIT
  3249.     JNZ    PRIN5
  3250.     RET
  3251. ;
  3252. POSIT:    CALL    NOUT
  3253.     DCR    E    ;BUMP EXPONENT COUNT
  3254.     JNZ    POSIT
  3255.     MOV    A,C    ;CHECK IF MORE DIGITS TO OUTPUT
  3256.     ORA    A
  3257.     RZ        ;NO, DONE
  3258.     RM
  3259.     JMP    PRIN4    ;NOW PRINT DECIMAL POINT
  3260. ;
  3261. ;    GET HERE FOR EXPONENTIAL OUTPUT FORMAT
  3262. ;
  3263. XPRIN:    CALL    NOUT
  3264.     JZ    NDEC    ;INTEGER?
  3265.     CALL    RADIX    ;NO.....PRINT DECIMAL POINT
  3266. XPRI2:    CALL    NOUT
  3267.     JNZ    XPRI2
  3268. ;
  3269. NDEC:    MVI    B,'E'    ;OUTPUT 'E'
  3270.     CALL    CHOUT
  3271.     LDA    XSIGN
  3272.     ORA    A
  3273.     JZ    XPRI3
  3274.     CALL    NEG    ;PRINT EXPONENT SIGN (-)
  3275.     LDA    EXPO
  3276.     INR    A
  3277.     JMP    XOUT2
  3278. ;
  3279. XPRI3:    MVI    B,'+'    ;EXPONENT (+)
  3280.     CALL    CHOUT
  3281. ;
  3282. ;    THIS ROUTINE IS USED TO CONVERT THE EXPONENT
  3283. ;    FROM BINARY TO ASCII AND PRINT THE RESULT
  3284. ;
  3285. XOUT:    LDA    EXPO
  3286.     DCR    A
  3287. XOUT2:    MVI    C,100
  3288.     MVI    D,0
  3289.     CALL    CONV
  3290.     CPI    '0'    ;SKIP LEADING ZEROES
  3291.     JZ    XO21
  3292.     INR    D
  3293.     CALL    CHOUT
  3294. XO21:    MOV    A,E
  3295.     MVI    C,10
  3296.     CALL    CONV
  3297.     CPI    '0'
  3298.     JNZ    XO3
  3299.     DCR    D
  3300.     JNZ    XO4
  3301. XO3:    CALL    CHOUT
  3302. XO4:    MOV    A,E
  3303.     ADI    '0'    ;ADD ASCII BIAS
  3304.     MOV    B,A
  3305.     CALL    CHOUT
  3306.     RET
  3307. ;
  3308. CONV:    MVI    B,'0'-1
  3309.     INR    B
  3310.     SUB    C
  3311.     JNC    CONV+2
  3312.     ADD    C
  3313.     MOV    E,A
  3314.     MOV    A,B
  3315.     RET
  3316. ;
  3317. ;    THIS ROUTINE ADDS ASCII BIAS TO A BCD DIGIT
  3318. ;    AND CALLS THE OUTPUT ROUTINE
  3319. ;
  3320. NOUT:    MOV    A,M
  3321.     ADI    '0'
  3322.     MOV    B,A
  3323.     CALL    CHOUT
  3324.     INX    H
  3325.     DCR    C    ;DECREMENT TOTAL DIGITS OUT COUNT
  3326.     RET
  3327. ;
  3328. ;    COMMON SYMBOL LOADING ROUTINES
  3329. ;
  3330. NEG:    MVI    B,'-'
  3331.     JMP    CHOUT
  3332. ZERO:    MVI    B,'0'
  3333.     JMP    CHOUT
  3334. SPACE:    MVI    B,' '
  3335.     JMP    CHOUT
  3336. RADIX:    MVI    B,'.'
  3337.     JMP    CHOUT
  3338. ;
  3339. ;    CONVERTS FP STRING AT DE, UPDATE DE PAST TERMINATOR
  3340. ;    PUTS TERMINATOR IN B, PUTS FP NUMBER AT ADDR IN HL
  3341. ;    SETS CARRY IF NOT FOUND
  3342. ;
  3343. FPIN:    PUSH    H
  3344.     PUSH    D
  3345.     XCHG
  3346.     DCX    H
  3347.     SHLD    ADDS
  3348.     LXI    H,OPST    ;CLEAR TEMP STORAGE AREAS AND BC BUFFER
  3349.     MVI    C,DIGIT+6
  3350.     CALL    CLEAR
  3351. ;
  3352. SCANC:    LXI    D,0
  3353.     LXI    H,BC    ;BC=PACK BUFFER
  3354. SCAN0:    SHLD    BCADD    ;PACK BUFFER POINTER
  3355. SCANP:    LXI    H,SCANP
  3356.     PUSH    H    ;USED FOR RETURN FROM OTHER ROUTINES
  3357.     XRA    A
  3358.     STA    XSIGN    ;CLEAR EXPONENT SIGN BYTE
  3359. ;
  3360. SCANG:    CALL    IBSCN
  3361.     JC    SCANX    ;FOUND A NUMBER, GO PACK IT
  3362.     CPI    '.'    ;RADIX?
  3363.     JZ    SCAN5    ;PROCESS RADIX POINTERS
  3364.     CPI    'E'    ;EXPONENT?
  3365.     JZ    EXCON    ;FOUND 'E', GO PROCESS EXPONENT NUMBER
  3366. ;
  3367. ;    NOT A CHARACTER LEGAL IN NUMBER
  3368. ;
  3369.     MOV    B,A    ;MOVE TERMINATOR TO B
  3370.     LDA    OPST    ;CHECK IF ANY DIGITS YET
  3371.     ANI    20Q
  3372.     JNZ    ENTR2
  3373. ;
  3374. ;    GET HERE IF LEGAL FP NUMBER NOT FOUND
  3375. ;
  3376. FPIN1:    POP    H    ;SCANP LINK
  3377.     POP    D    ;TEXT POINTER
  3378.     POP    H    ;FP # ADDR
  3379.     STC
  3380.     RET
  3381. ;
  3382. ;    FOUND DECIMAL POINT
  3383. ;
  3384. SCAN5:    XRA    A    ;FOUND RADIX PROCESS RADIX POINTERS FOR EXP
  3385.     ORA    D    ;ANY DIGITS YET?
  3386.     JNZ    SCAN6
  3387.     ADI    300Q    ;SET ECNT - STOP COUNTING DIGITS
  3388.     ORA    E    ;NO INT DIGITS, BIT 7 IS COUNT/DONT COUNT FLAG
  3389.     MOV    E,A    ;BIT 6 IS NEGATIVE EXPONENT FLAG
  3390.     RET
  3391. ;
  3392. SCAN6:    MVI    A,200Q    ;SET ECNT TO COUNT DIGITS
  3393.     ORA    E
  3394.     MOV    E,A
  3395.     RET
  3396. ;
  3397. SCANX:    ANI    17Q    ;FOUND NUMBER-REMOVE ASCII BIAS
  3398.     MOV    B,A
  3399.     LXI    H,OPST    ;SET FIRST CHARACTER FLAG
  3400.     MVI    A,60Q
  3401.     ORA    M
  3402.     MOV    M,A
  3403.     XRA    A
  3404.     ORA    B    ;IS CHAR ZERO?
  3405.     JNZ    PACK
  3406.     ORA    D    ;LEADING ZERO I. E. ANY INT DIGITS?
  3407.     JNZ    PACK
  3408.     ORA    E
  3409.     MOV    E,A
  3410.     RZ        ;IF COUNTING YET,
  3411.     INR    E    ;ECNT+1-COUNT ZEROS FOR EXPONENT COUNT
  3412.     RET
  3413. ;
  3414. ;    THIS SUBROUTINE BCD PACKS DIGITS INTO REG BC
  3415. ;
  3416. PACK:    MOV    A,E
  3417.     RAL
  3418.     JC    PACK1
  3419.     INR    E
  3420. PACK1:    MOV    A,E
  3421.     STA    ECNT    ;DIGIT COUNT FOR EXPONENT COUNT
  3422.     INR    D    ;TOTAL DIGIT COUNT (D ALSO HAS TOP/BOTM FLAG BIT 7
  3423.     MOV    A,D
  3424.     ANI    177Q    ;REMOVE TOP/BOTTOM FLAG
  3425.     CPI    DIGIT*2+1 ;LIMIT INPUT DIGITS
  3426.     RNC
  3427.     XRA    A
  3428.     ORA    D
  3429.     JM    BOTM
  3430. ;
  3431. TOP:    ORI    200Q    ;SET MSB FOR TOP FLAG
  3432.     MOV    D,A
  3433.     MOV    A,B
  3434.     LHLD    BCADD    ;GET BC ADDRESS
  3435.     RLC
  3436.     RLC
  3437.     RLC
  3438.     RLC
  3439.     MOV    M,A    ;SAVE CHR IN BC
  3440.     RET
  3441. ;
  3442. BOTM:    ANI    177Q    ;STRIP MSB (BOTTOM FLAG)
  3443.     MOV    D,A
  3444.     MOV    A,B
  3445.     LHLD    BCADD
  3446.     ORA    M    ;OR IN TOP NUMBER
  3447.     MOV    M,A    ;PUT NUMBER BACK IN BC
  3448.     INX    H
  3449.     POP    B
  3450.     JMP    SCAN0
  3451. ;
  3452. IBSCN:    LHLD    ADDS    ;INPUT BUFFER POINTER
  3453.     INX    H    ;GET NEXT BYTE
  3454.     MOV    A,M
  3455.     CPI    ' '
  3456.     JZ    IBSCN+3
  3457.     SHLD    ADDS    ;NOTE:  THIS ROUTINE FALLS THROUGH TO BELOW
  3458. ;
  3459. ;    THIS ROUTINE CHECKS FOR ASCII NUMBERS (0-9)
  3460. ;
  3461. NMCHK:    CPI    '9'+1
  3462.     RNC
  3463.     CPI    '0'
  3464.     CMC
  3465.     RET
  3466. ;
  3467. ;    THIS ROUTINE IS USED TO ADJUST A NUMBER IN BC BUFFER
  3468. ;    AND RETURNS VALUE
  3469. ;
  3470. ENTR2:    LXI    D,0
  3471. ENT1:    PUSH    B    ;TERMINATOR
  3472.     CALL    FIXE    ;NORMALIZE FLOATING POINT NUMBER
  3473.     POP    B    ;TERMINATOR
  3474.     POP    D    ;SCANP LINK
  3475.     POP    D    ;OLD TEXT ADDR
  3476.     POP    D    ;RETURN ADDR
  3477.     MVI    C,DIGIT+2
  3478.     LXI    H,BC+DIGIT+1
  3479.     CALL    VCOPY
  3480.     LHLD    ADDS
  3481.     XCHG
  3482.     INX    D
  3483.     ORA    A
  3484.     RET
  3485. ;
  3486. ;    THIS ROUTINE IS USED TO CLEAR STORAGE AREAS
  3487. ;    THE STARTING ADDRESS IS IN HL AND THE COUNT
  3488. ;    IS IN REG C
  3489. ;
  3490. CLEAR:    XRA    A
  3491.     MOV    M,A
  3492.     INX    H
  3493.     DCR    C
  3494.     JNZ    CLEAR+1
  3495.     RET
  3496. ;
  3497. ;    THIS ROUTINE CONVERTS THE ASCII EXPONENT OF
  3498. ;    NUMBER IN THE INPUT BUFFER TO BINARY, AND
  3499. ;    NORMALIZES EXPONENT ACCORDING TO THE INPUT
  3500. ;    FORMAT OF THE NUMBER
  3501. ;
  3502. EXCON:    CALL    IBSCN    ;GET CHARACTER
  3503.     JC    EXC3
  3504.     CPI    PLSRW    ;CHECK FOR UNARY SIGNS
  3505.     JZ    EXC4
  3506.     CPI    '+'
  3507.     JZ    EXC4
  3508.     CPI    '-'
  3509.     JZ    EXC2
  3510.     CPI    MINRW
  3511.     JNZ    FPERR    ;NO SIGN OR NUMBER?
  3512. EXC2:    MVI    A,1
  3513.     STA    XSIGN    ;SAVE SIGN
  3514. EXC4:    CALL    IBSCN
  3515.     JNC    FPERR    ;NO NUMBER?
  3516. EXC3:    CALL    ASCDC    ;CONVERT ASCII TO BINARY
  3517.     JMP    ENT1    ;NORMALIZE NUMBER AND RETURN
  3518. ;
  3519. ;    THIS ROUTINE CONVERTS ASCII TO BINARY
  3520. ;    THREE CONSECUTIVE NUMBERS <128 MAY BE CONVERTED
  3521. ;
  3522. ASCDC:    XCHG
  3523.     LXI    H,0
  3524. ASC1:    LDAX    D    ;GET CHR FROM INPUT BUFFER, NO SPACES ALLOWED
  3525.     CALL    NMCHK    ;CHECK IF NUMBER
  3526.     JNC    ASC2
  3527.     SUI    '0'    ;REMOVE ASCII BIAS
  3528.     MOV    B,H
  3529.     MOV    C,L
  3530.     DAD    H
  3531.     DAD    H
  3532.     DAD    B
  3533.     DAD    H
  3534.     MOV    C,A
  3535.     MVI    B,0
  3536.     DAD    B
  3537.     INX    D
  3538.     JMP    ASC1
  3539. ;
  3540. ASC2:    XCHG
  3541.     MOV    B,A    ;SAVE TERMINATOR
  3542.     SHLD    ADDS    ;SAVE IBUF ADDR
  3543.     MOV    A,D
  3544.     ORA    A
  3545.     JNZ    FPERR    ;TOO BIG >255
  3546.     MOV    A,E
  3547.     RAL
  3548.     JC    FPERR    ;TOO BIG >127
  3549.     RAR
  3550.     RET
  3551. ;
  3552. FPERR:    POP    B    ;ASCDC RET LINK
  3553.     JMP    FPIN1
  3554. ;
  3555. ;    THIS ROUTINE NORMALIZES THE INPUT NUMBER
  3556. ;
  3557. FIXE:    XCHG
  3558.     LDA    BC
  3559.     ORA    A    ;IS IT ZERO
  3560.     JZ    ZZ2
  3561.     CALL    CHKPN    ;SET EXPONENT POSITIVE/NEGATIVE
  3562.     ADI    200Q    ;ADD EXPONENT BIAS
  3563. ZZ2:    STA    BC+DIGIT+1 ;STORE NORMALIZED EXPONENT IN BC
  3564.     RET
  3565. ;
  3566. CHKPN:    LDA    ECNT    ;GET EXPONENT COUNT-SET IN 'SCAN' ROUTINE
  3567.     MOV    E,A
  3568.     ANI    77Q    ;STRIP BITS 7 AND 8
  3569.     MOV    B,A
  3570.     LDA    XSIGN
  3571.     ORA    A
  3572.     JZ    LPOS    ;EXPONENT IS POSITIVE
  3573.     INR    H    ;SET SIGN IN H **THIS SHOULD BE INR H NOT INX H
  3574.     MVI    A,100Q    ;L IS NEGATIVE
  3575.     ANA    E    ;CHECK IF E IS NEGATIVE
  3576.     JZ    EPOS
  3577.     MOV    A,L    ;BOTH E AND L NEGTIVE
  3578.     MOV    L,B
  3579.     CALL    BPOS+1
  3580.     CMA
  3581.     INR    A
  3582.     RET        ;BACK TO FIXE
  3583. ;
  3584. EPOS:    MOV    A,L    ;E AND L NEGATIVE
  3585.     CMA
  3586.     INR    A
  3587.     ADD    B
  3588.     RET        ;TO FIXE
  3589. ;
  3590. LPOS:    MVI    A,100Q    ;EXPONENT POSITIVE
  3591.     ANA    E
  3592.     JZ    BPOS    ;IF E POSITIVE
  3593.     MOV    A,B
  3594.     MOV    B,L
  3595.     JMP    EPOS+1
  3596. ;
  3597. BPOS:    MOV    A,B    ;E AND L POSITIVE
  3598.     ADD    L
  3599.     RP
  3600. ;
  3601.     POP    H
  3602.     JMP    FPERR
  3603.     DB    1*16
  3604.     DW    0
  3605.     DB    1
  3606. FPNONE:    DB    129
  3607. ;
  3608. ;    THIS PROGRAM IS A FOUR FUNCTION FLOATING POINT BCD
  3609. ;    MATH PACKAGE
  3610. ;    EACH FUNCTION MAY BE EXPRESSED AS:  BC=DE # HL
  3611. ;    <BC> = ADDR OF RESULT
  3612. ;    <DE> = ADDR OF 1ST ARGUMENT
  3613. ;    <HL> = ADDR OF 2ND ARGUMENT
  3614. ;    # IS ONE OF THE FUNCTIONS:  +, -, *, /
  3615. ;    ALL ADDRESSES ON ENTRY, POINT TO THE EXPONENT PART OF
  3616. ;    THE FLOATING POINT NUMBER
  3617. ;    EACH FLOATING POINT NUMBER CONSISTS OF (2*DIGIT) PACKED
  3618. ;    DECIMAL DIGITS, A SIGN AND A BIASED BINARY EXPONENT.  THE
  3619. ;    EXPONENT RANGE IS 10**-127 TO 10**127.
  3620. ;    THE NUMBER ZERO IS REPRESENTED BY THE EXPONENT 0.
  3621. ;    THE NUMBERS ARE STORED IN MEMORY AS (DIGIT) BYTES OF
  3622. ;    DECIMAL DIGITS.
  3623. ;    STARTING AT THE LOW ORDER ADDRESS
  3624. ;    ALL NUMBERS ARE ASSUMED TO BE NORMALIZED.  THAT IS EACH
  3625. ;    NUMBER CAN BE REPRESENTED AS F**E.
  3626. ;    WHERE .1<=F<=1.0 AND F IS THE EXPONENT.
  3627. ;
  3628. ;    FLOATING POINT ADDITION
  3629. ;
  3630. FADD:    PUSH    B
  3631.     CALL    EXPCK    ;FETCH ARGUMENTS
  3632.     MVI    C,0
  3633. ADSUM:    DCX    D
  3634.     XCHG
  3635.     LDA    SIGN
  3636.     XRA    M    ;FORM SIGN OF RESULT
  3637.     MOV    B,A
  3638.     XCHG
  3639.     LDAX    D
  3640.     DCX    D
  3641.     XRA    C
  3642.     STA    SIGN
  3643.     LXI    H,RCTRL    ;ROUNDING CONTROL FLAG
  3644.     MOV    A,M
  3645.     ORA    A
  3646.     INX    H
  3647.     MOV    A,M    ;GET ROUNDING DIGIT
  3648.     JZ    ADS8
  3649.     RLC
  3650.     RLC
  3651.     RLC
  3652.     RLC
  3653. ADS8:    ADI    0B0H    ;FORCE CARRY IF DIGIT > 5
  3654.     MOV    A,B
  3655.     RAR
  3656.     JC    ADS1    ;HAVE SUBTRACTION
  3657.     RAL        ;RESTORE CARRY
  3658.     CALL    ADDF    ;PERFORM ADDITION
  3659.     JNC    ADS2
  3660.     MVI    B,4
  3661.     CALL    RIGHT
  3662.     LXI    H,EXP
  3663.     INR    M    ;INCREMENT EXPONENT
  3664.     JZ    OVER
  3665. ADS2:    POP    B    ;GET RESULTS ADDRESS
  3666.     CALL    STORE    ;SAVE RESULTS
  3667.     RET
  3668. ;
  3669. ZEREX:    POP    H
  3670.     JMP    ADS2
  3671. ;
  3672. ADDF:    LXI    H,BUF+DIGIT-1
  3673.     MVI    B,DIGIT
  3674. ADD1:    LDAX    D
  3675.     ADC    M
  3676.     DAA
  3677.     MOV    M,A
  3678.     DCX    H
  3679.     DCX    D
  3680.     DCR    B
  3681.     JNZ    ADD1
  3682.     RNC
  3683.     INR    M
  3684.     RET
  3685. ;
  3686. ;    FLOATING POINT SUBTRACTION
  3687. ;
  3688. FSUB:    PUSH    B
  3689.     CALL    EXPCK    ;GET ARGUMENTS
  3690.     LDA    SIGN
  3691.     XRI    1    ;COMPLEMENT SIGN
  3692.     STA    SIGN
  3693.     JMP    ADSUM
  3694. ;
  3695. ADS1:    RAL        ;RESTORE CARRY
  3696.     CMC        ;COMPLEMENT FOR ROUNDING
  3697.     CALL    SUBF    ;SUBTRACT ARGUMENTS
  3698.     LXI    H,SIGN
  3699.     JC    ADS4
  3700.     MOV    A,M    ;GET SIGN
  3701.     XRI    1    ;COMPLEMENT
  3702.     MOV    M,A
  3703. ADS7:    DCX    H
  3704.     MVI    B,DIGIT
  3705. ADS3:    MVI    A,9AH
  3706.     SBB    M    ;COMPLEMENT RESULT
  3707.     ADI    0
  3708.     DAA
  3709.     MOV    M,A
  3710.     DCX    H
  3711.     DCR    B
  3712.     CMC
  3713.     JNZ    ADS3
  3714. ADS4:    LXI    H,BUF
  3715.     LXI    B,DIGIT
  3716. ADS5:    MOV    A,M
  3717.     ORA    A
  3718.     JNZ    ADS6
  3719.     INX    H
  3720.     INR    B
  3721.     INR    B
  3722.     DCR    C
  3723.     JNZ    ADS5
  3724.     XRA    A
  3725.     STA    EXP
  3726.     JMP    ADS2
  3727. ;
  3728. ADS6:    CPI    10H
  3729.     JNC    ADS9
  3730.     INR    B
  3731. ADS9:    LXI    H,EXP
  3732.     MOV    A,M
  3733.     SUB    B
  3734.     JZ    UNDER
  3735.     JC    UNDER
  3736.     MOV    M,A
  3737.     MOV    A,B
  3738.     RLC
  3739.     RLC
  3740.     MOV    B,A
  3741.     CALL    LEFT
  3742.     JMP    ADS2
  3743. ;
  3744. SUBF:    LXI    H,BUF+DIGIT-1
  3745.     MVI    B,DIGIT
  3746. SUB1:    MVI    A,99H
  3747.     ACI    0
  3748.     SUB    M
  3749.     XCHG
  3750.     ADD    M
  3751.     DAA
  3752.     XCHG
  3753.     MOV    M,A
  3754.     DCX    H
  3755.     DCX    D
  3756.     DCR    B
  3757.     JNZ    SUB1
  3758.     RET
  3759. ;
  3760. ;    FLOATING POINT MULTIPLY
  3761. ;
  3762. FMUL:    PUSH    B
  3763.     MOV    A,M
  3764.     ORA    A    ;ARGUMENT=0?
  3765.     JZ    FMUL1+2
  3766.     LDAX    D
  3767.     ORA    A    ;ARGUMENT=0?
  3768.     JZ    FMUL1+2
  3769.     ADD    M    ;FORM RESULT EXPONENT
  3770.     JC    FMOVR
  3771.     JP    UNDER
  3772.     JMP    FMUL1
  3773. ;
  3774. FMOVR:    JM    OVER
  3775. FMUL1:    SUI    128    ;REMOVE EXCESS BIAS
  3776.     STA    EXP    ;SAVE EXPONENT
  3777.     DCX    D
  3778.     DCX    H
  3779.     LDAX    D
  3780.     XRA    M    ;FORM RESULT SIGN
  3781.     DCX    H
  3782.     DCX    D
  3783.     PUSH    H
  3784.     LXI    H,SIGN    ;GET SIGN ADDRESS
  3785.     MOV    M,A
  3786.     DCX    H
  3787.     XRA    A
  3788.     MVI    B,DIGIT+2
  3789. FMUL2:    MOV    M,A    ;ZERO WORKING BUFFER
  3790.     DCX    H
  3791.     DCR    B
  3792.     JNZ    FMUL2
  3793.     LDA    EXP
  3794.     ORA    A
  3795.     JZ    ZEREX
  3796.     MVI    C,DIGIT
  3797.     LXI    H,HOLD1+DIGIT
  3798. ;
  3799. ;    GET MULTIPLIER INTO HOLDING REGISTER
  3800. ;
  3801. FMUL3:    LDAX    D
  3802.     MOV    M,A    ;PUT IN REGISTER
  3803.     DCX    H
  3804.     DCX    D
  3805.     DCR    C
  3806.     JNZ    FMUL3
  3807.     MOV    M,C
  3808.     DCX    H
  3809.     MVI    B,250    ;SET LOOP COUNT
  3810. FMUL4:    LXI    D,DIGIT+1
  3811.     MOV    C,E
  3812.     DAD    D
  3813.     XCHG
  3814.     DAD    D    ;HL=NEXT HOLDING REGISTER
  3815.     INR    B
  3816.     JP    FMUL8    ;FINISHED
  3817. FMUL5:    LDAX    D    ;GET DIGITS
  3818.     ADC    A    ;TIMES 2
  3819.     DAA
  3820.     MOV    M,A    ;PUT IN HOLDING REGISTER
  3821.     DCX    D
  3822.     DCX    H
  3823.     DCR    C
  3824.     JNZ    FMUL5
  3825.     INR    B    ;INCREMENT LOOP COUNT
  3826.     JNZ    FMUL4
  3827. ;
  3828. ;    FORM 10X BY ADDING 8X AND 2X
  3829. ;    FIRST GET 8X
  3830. ;
  3831.     INX    H
  3832.     LXI    D,HOLD5    ;NEXT HOLDING REGISTER
  3833.     MVI    C,DIGIT+1
  3834.     MOV    B,C
  3835. FMUL6:    MOV    A,M
  3836.     STAX    D
  3837.     INX    H
  3838.     INX    D
  3839.     DCR    C
  3840.     JNZ    FMUL6
  3841.     LXI    H,HOLD2+DIGIT ;GET 2X
  3842.     DCX    D
  3843. FMUL7:    LDAX    D
  3844.     ADC    M    ;FORM 10X
  3845.     DAA
  3846.     STAX    D
  3847.     DCX    D
  3848.     DCX    H
  3849.     DCR    B
  3850.     JNZ    FMUL7
  3851.     MVI    B,249
  3852.     XCHG
  3853.     JMP    FMUL4
  3854. ;
  3855. FMUL8:    XCHG
  3856.     INX    H
  3857.     MVI    M,DIGIT+1 ;SET NEXT LOOP COUNT
  3858. ;
  3859. ;    PERFORM ACCUMULATION OF PRODUCT
  3860. ;
  3861. FMUL9:    POP    B    ;GET MULTIPLIER
  3862.     LXI    H,HOLD8+DIGIT+1
  3863.     DCR    M    ;DECREMENT LOOP COUNT
  3864.     JZ    FMU14    ;FINISHED
  3865.     LDAX    B
  3866.     DCX    B
  3867.     PUSH    B
  3868.     DCX    H
  3869.     XCHG
  3870. FMU10:    ADD    A    ;CHECK FOR BIT IN CARRY
  3871.     JC    FMU11    ;FOUND A BIT
  3872.     JZ    FMU12    ;ZERO- FINISHED THIS DIGIT
  3873.     LXI    H,-DIGIT-1
  3874.     DAD    D    ;POINT TO NEXT HOLDING REGISTER
  3875.     XCHG
  3876.     JMP    FMU10
  3877. ;
  3878. FMU11:    MOV    C,A
  3879.     ORA    A    ;CLEAR CARRY
  3880.     CALL    ADDF    ;ACCUMULATE PRODUCT
  3881.     LDAX    D
  3882.     ADD    M
  3883.     DAA
  3884.     MOV    M,A
  3885.     MOV    A,C
  3886.     DCX    D
  3887.     JMP    FMU10
  3888. ;
  3889. ;    ROTATE RIGHT 1 BYTE
  3890. ;
  3891. FMU12:    MVI    B,8
  3892.     CALL    RIGHT
  3893.     JMP    FMUL9
  3894. ;
  3895. FMU14:    LDA    BUF
  3896.     ANI    0F0H    ;CHECK IF NORMALIZED
  3897.     JZ    FMU17
  3898.     MOV    A,D
  3899.     ANI    0F0H
  3900.     LXI    H,SIGN-1
  3901.     JMP    FMU18
  3902. ;
  3903. FMU17:    MVI    B,4
  3904.     LXI    H,EXP
  3905.     DCR    M
  3906.     JZ    UNDER
  3907.     CALL    LEFT    ;NORMALIZE
  3908.     MOV    A,D    ;GET DIGIT SHIFTED OFF
  3909. ;
  3910. ;    PERFORM ROUNDING
  3911. ;
  3912.     RRC
  3913.     RRC
  3914.     RRC
  3915.     RRC
  3916. FMU18:    CPI    50H
  3917.     JC    FMU16
  3918.     INR    A
  3919.     ANI    0FH
  3920.     MVI    C,DIGIT
  3921. FMU15:    ADC    M
  3922.     DAA
  3923.     MOV    M,A
  3924.     MVI    A,0
  3925.     DCX    H
  3926.     DCR    C
  3927.     JNZ    FMU15
  3928. ;
  3929. ;    CHECK FOR ROUNDING OVERFLOW
  3930. ;
  3931.     JNC    ADS2    ;NO OVERFLOW
  3932.     INX    H
  3933.     MVI    M,10H
  3934.     LXI    H,EXP
  3935.     INR    M
  3936.     JNZ    ADS2
  3937.     JMP    OVER
  3938. ;
  3939. ;    ROUNDING NOT NEEDED
  3940. ;
  3941. FMU16:    ANI    0FH
  3942.     ADD    M
  3943.     MOV    M,A
  3944.     JMP    ADS2
  3945. ;
  3946. ;    FLOATING POINT DIVISION
  3947. ;
  3948. FDIV:    PUSH    B
  3949.     MOV    A,M    ;FETCH DIVISOR EXP
  3950.     ORA    A    ;DIVIDE BY 0?
  3951.     JZ     DIVZ
  3952.     LDAX    D
  3953.     ORA    A    ;DIVIDEND=0?
  3954.     JZ    INSP
  3955.     SUB    M
  3956.     JC    DIVUN
  3957.     JM    OVER
  3958.     JMP    FDI1
  3959. ;
  3960. DIVUN:    JP    UNDER
  3961. FDI1:    ADI    129    ;FORM QUOTIENT EXP
  3962.     STA    EXPD
  3963.     XCHG
  3964.     PUSH    D
  3965.     CALL    LOAD    ;FETCH DIVIDEND
  3966.     POP    D
  3967.     XCHG
  3968.     LDA    SIGN
  3969.     DCX    H
  3970.     XRA    M    ;FORM QUOTIENT SIGN
  3971.     STA    SIGND
  3972.     XCHG
  3973.     DCX    D
  3974.     LXI    B,HOLD1
  3975. DIV0:    MVI    L,DIGIT+DIGIT
  3976. DIV1:    PUSH    B
  3977.     PUSH    H
  3978.     MVI    C,0    ;QUOTIENT DIGIT=0
  3979. DIV3:    STC        ;SET CARRY
  3980.     LXI    H,BUF+DIGIT-1
  3981.     MVI    B,DIGIT
  3982. DIV4:    MVI    A,99H
  3983.     ACI    0
  3984.     XCHG
  3985.     SUB    M
  3986.     XCHG
  3987.     ADD    M
  3988.     DAA
  3989.     MOV    M,A
  3990.     DCX    H
  3991.     DCX    D
  3992.     DCR    B
  3993.     JNZ    DIV4
  3994.     MOV    A,M
  3995.     CMC
  3996.     SBI    0
  3997.     MOV    M,A
  3998.     RAR
  3999.     LXI    H,DIGIT
  4000.     DAD    D
  4001.     XCHG
  4002.     INR    C    ;INCREMENT QUOTIENT
  4003.     RAL
  4004.     JNC    DIV3
  4005.     ORA    A    ;CLEAR CARRY
  4006.     CALL    ADDF    ;RESTORE DIVIDEND
  4007.     LXI    H,DIGIT
  4008.     DAD    D
  4009.     XCHG
  4010.     PUSH    B
  4011.     MVI    B,4
  4012.     CALL    LEFT    ;SHIFT DIVIDEND
  4013.     POP    B
  4014.     DCR    C
  4015.     POP    H
  4016.     MOV    H,C
  4017.     POP    B
  4018.     MOV    A,L
  4019.     JNZ    DIV5
  4020.     CPI    DIGIT+DIGIT
  4021.     JNZ    DIV5
  4022.     LXI    H,EXPD
  4023.     DCR    M
  4024.     CZ    UNDER
  4025.     JMP    DIV0
  4026. ;
  4027. DIV5:    RAR
  4028.     MOV    A,H
  4029.     JNC    DIV6
  4030.     LDAX    B
  4031.     RLC
  4032.     RLC
  4033.     RLC
  4034.     RLC
  4035.     ADD    H
  4036.     STAX    B    ;STORE QUOTIENT
  4037.     INX    B
  4038.     JMP    DIV7
  4039. ;
  4040. DIV6:    STAX    B    ;STORE QUOTIENT
  4041. DIV7:    DCR    L    ;DECREMENT DIGIT COUNT
  4042.     JNZ    DIV1
  4043.     LXI    H,EXPD
  4044.     POP    B
  4045.     CALL    STORO
  4046.     RET
  4047. ;
  4048. ;    FETCH AND ALIGN ARGUMENTS FOR
  4049. ;    ADDITION AND SUBTRACTION
  4050. ;
  4051. EXPCK:    LDAX    D
  4052.     SUB    M    ;DIFFERENCE OF EXPS
  4053.     MVI    C,0
  4054.     JNC    EXPC1
  4055.     INR    C
  4056.     XCHG
  4057.     CMA
  4058.     INR    A
  4059. EXPC1:    MOV    B,A
  4060.     LDAX    D
  4061.     STA    EXP
  4062.     MOV    A,B
  4063.     CPI    DIGIT+DIGIT
  4064.     JC    EXPC2
  4065.     MVI    A,DIGIT+DIGIT
  4066. EXPC2:    RLC
  4067.     RLC
  4068.     MOV    B,A
  4069.     ANI    4
  4070.     STA    RCTRL    ;SET ROUNDING CONTROL
  4071.     PUSH    B
  4072.     PUSH    D
  4073.     CALL    LOAD    ;LOAD SMALLER VALUE
  4074.     MVI    A,8*DIGIT+16
  4075.     SUB    B
  4076.     CPI    8*DIGIT+16
  4077.     JZ    EXPC3
  4078.     ANI    0F8H
  4079.     RAR
  4080.     RAR
  4081.     RAR
  4082.     ADD    E
  4083.     MOV    E,A
  4084.     MOV    A,D
  4085.     ACI    0
  4086.     MOV    D,A
  4087.     LDAX    D    ;GET ROUNDING DIGIT
  4088.     STA    RDIGI    ;SAVE
  4089. EXPC3:    CALL    RIGHT    ;ALIGN VALUES
  4090.     POP    D
  4091.     POP    B
  4092.     RET
  4093. ;
  4094. ;    LOAD ARGUMENT INTO BUFFER
  4095. ;
  4096. LOAD:    LXI    D,SIGN
  4097.     MVI    C,DIGIT+1
  4098.     DCX    H
  4099. LOAD1:    MOV    A,M
  4100.     STAX    D
  4101.     DCX    H
  4102.     DCX    D
  4103.     DCR    C
  4104.     JNZ    LOAD1
  4105.     XRA    A
  4106.     STAX    D
  4107.     DCX    D
  4108.     STAX    D
  4109.     STA    RDIGI    ;ZERO ROUNDING DIGIT
  4110.     RET
  4111. ;
  4112. ;    STORE RESULTS IN MEMORY
  4113. ;
  4114. STORE:    LXI    H,EXP
  4115. STORO:    MVI    E,DIGIT+2
  4116. STOR1:    MOV    A,M
  4117.     STAX    B
  4118.     DCX    B
  4119.     DCX    H
  4120.     DCR    E
  4121.     JNZ    STOR1
  4122.     RET
  4123. ;
  4124. ;    SHIFT RIGHT NUMBER OF DIGITS
  4125. ;    IN B/4
  4126. ;
  4127. RIGHT:    MVI    C,DIGIT+1
  4128. RIGH1:    LXI    H,BUF-1
  4129.     MOV    A,B
  4130.     SUI    8    ;CHECK IF BYTE CAN BE SHIFTED
  4131.     JNC    RIGH3
  4132.     DCR    B
  4133.     RM
  4134.     ORA    A
  4135. RIGH2:    MOV    A,M
  4136.     RAR
  4137.     MOV    M,A
  4138.     INX    H
  4139.     DCR    C
  4140.     JNZ    RIGH2
  4141.     JMP    RIGHT
  4142. ;
  4143. ;    SHIFT RIGHT ONE BYTE
  4144. ;
  4145. RIGH3:    MOV    B,A
  4146.     XRA    A
  4147. RIGH4:    MOV    D,M
  4148.     MOV    M,A
  4149.     MOV    A,D
  4150.     INX    H
  4151.     DCR    C
  4152.     JNZ    RIGH4
  4153.     JMP    RIGHT
  4154. ;
  4155. ;    SHIFT LEFT NUMBER OF DIGITS
  4156. ;    IN B/4
  4157. ;
  4158. LEFT:    MVI    C,DIGIT+1
  4159.     LXI    H,SIGN-1
  4160. LEF1:    MOV    A,B
  4161.     SUI    8
  4162.     JNC    LEF3
  4163.     DCR    B
  4164.     RM
  4165.     ORA    A
  4166. LEF2:    MOV    A,M
  4167.     RAL
  4168.     MOV    M,A
  4169.     DCX    H
  4170.     DCR    C
  4171.     JNZ    LEF2
  4172.     JMP    LEFT
  4173. ;
  4174. ;    SHIFT LEFT ONE BYTE
  4175. ;
  4176. LEF3:    MOV    B,A
  4177.     XRA    A
  4178. LEF4:    MOV    D,M
  4179.     MOV    M,A
  4180.     MOV    A,D
  4181.     DCX    H
  4182.     DCR    C
  4183.     JNZ    LEF4
  4184.     JMP    LEFT
  4185. ;
  4186. ;    SET FLAGS FOR OVERFLOW, UNDERFLOW,
  4187. ;    AND DIVIDE BY ZERO
  4188. ;
  4189. OVER:    LXI    H,FLOAT
  4190.     JMP    ERROR
  4191. UNDER:    MVI    A,0FFH
  4192.     STA    ERRI
  4193. INSP:    INX    SP
  4194.     INX    SP
  4195.     RET
  4196. ;
  4197. DIVZ    EQU    OVER
  4198. ;
  4199. ;    HAMPSHIRE ADDED COMMANDS
  4200. ;
  4201. CSYS:    JMP    0
  4202. ;
  4203. SAVE:    CALL    GC
  4204.     CPI    CR
  4205.     CNZ    WSID    ;RENAME THE WORK-SPACE
  4206.     CALL    SETFCB    ;SET UP FCB
  4207.     MVI    C,19    ;ERASE PREVIOUS FILE (IF ANY)
  4208.     LXI    D,TFCB
  4209.     CALL    SYSTEM
  4210.     MVI    C,22    ;CREATE A NEW FILE
  4211.     LXI    D,TFCB
  4212.     CALL    SYSTEM
  4213.     CPI    0FFH
  4214.     JZ    SAV6    ;IF NO DIRECTORY SPACE
  4215.     LHLD    BOFA    ;INITIALIZE DMA ADDR
  4216.     XCHG
  4217.     MOV    A,D
  4218.     CMA
  4219.     MOV    B,A
  4220.     MOV    A,E
  4221.     CMA
  4222.     MOV    C,A
  4223.     INX    B    ;NEGATE BOFA
  4224.     LHLD    EOFA    ;COUNT=EOFA-BOFA+1
  4225.     DAD    B
  4226.     INX    H
  4227. SAV1:    XRA    A    ;COUNT<256?
  4228.     ORA    H
  4229.     JNZ    SAV2    ;IF COUNT>255
  4230.     MOV    A,L
  4231.     CPI    128
  4232.     JM    SAV3    ;IF COUNT<128
  4233. SAV2:    PUSH    D    ;SAVE COUNT AND DMA ADDRESS
  4234.     PUSH    H
  4235.     MVI    C,26    ;SET DMA ADDR
  4236.     CALL    SYSTEM
  4237.     MVI    C,21    ;WRITE SECTOR
  4238.     LXI    D,TFCB
  4239.     CALL    SYSTEM
  4240.     ORA    A
  4241.     JNZ    SAV5    ;IF NO DISK SPACE
  4242.     POP    H    ;RETRIEVE COUNT AND DMA ADDR
  4243.     POP    D
  4244.     LXI    B,-128    ;COUNT=COUNT-128
  4245.     DAD    B
  4246.     XCHG
  4247.     LXI    B,128    ;DMA ADDR=DMA ADDR+128
  4248.     DAD    B
  4249.     XCHG
  4250.     JMP    SAV1
  4251. ;
  4252. SAV3:    ORA    A
  4253.     JNZ    SAV4    ;IF COUNT>0
  4254.     MVI    C,26    ;RESET DMA ADDRESS TO 80H
  4255.     LXI    D,TBUFF
  4256.     CALL    SYSTEM
  4257.     MVI    C,16    ;CLOSE FILE
  4258.     LXI    D,TFCB
  4259.     CALL    SYSTEM
  4260.     JMP    CMND1    ;RETURN TO TOP LEVEL OF INTERPRETTER
  4261. ;
  4262. SAV4:    XCHG        ;HL=DMA ADDR, E=COUNT
  4263.     LXI    B,TBUFF
  4264. SAV41:    MOV    A,M    ;MOVE BYTE TO TBUFF
  4265.     STAX    B
  4266.     INX    H
  4267.     INX    B
  4268.     DCR    E
  4269.     JNZ    SAV41    ;LOOP FOR ALL BYTES
  4270.     LXI    H,128    ;SO COUNT WILL BE 0 ON NEXT PASS
  4271.     LXI    D,TBUFF    ;DMA ADDR=TBUFF
  4272.     JMP    SAV2
  4273. ;
  4274. SAV5:    LXI    H,FSERR
  4275.     JMP    ERROR
  4276. ;
  4277. SAV6:    LXI    H,DSERR
  4278.     JMP    ERROR
  4279. ;
  4280. FETCH:    CALL    SETFCB    ;SET UP FCB
  4281.     MVI    C,15    ;OPEN FILE
  4282.     LXI    D,TFCB
  4283.     CALL    SYSTEM
  4284.     CPI    0FFH
  4285.     JZ    FET11    ;IF FILE NOT FOUND
  4286.     LXI    H,NR    ;INITIALIZE NEXT RECORD INDEX
  4287.     MVI    M,0
  4288.     LHLD    BOFA    ;INITIALIZE DMA ADDR
  4289.     XCHG
  4290.     MOV    A,D    ;NEGATE BOFA
  4291.     CMA
  4292.     MOV    B,A
  4293.     MOV    A,E
  4294.     CMA
  4295.     MOV    C,A
  4296.     INX    B
  4297.     LHLD    SYSTEM+1;FREE SPACE LENGTH=FL-BOFA
  4298.     DAD    B
  4299. FET1:    XRA    A    ;COUNT<=255?
  4300.     ORA    H
  4301.     JNZ    FET2    ;IF COUNT>255
  4302.     MOV    A,L
  4303.     CPI    128
  4304.     JM    FET4    ;IF COUNT<128
  4305.     JZ    FET4    ;IF COUNT=128
  4306. FET2:    PUSH    D    ;SAVE DMA ADDR AND LENGTH
  4307.     PUSH    H
  4308.     MVI    C,26    ;SET DMA ADDR
  4309.     CALL    SYSTEM
  4310.     MVI    C,20    ;READ SECTOR
  4311.     LXI    D,TFCB
  4312.     CALL    SYSTEM
  4313.     POP    H    ;RETRIEVE DMA ADDR AND COUNT
  4314.     POP    D
  4315.     ORA    A
  4316.     JZ    FET3    ;IF SUCCESSFUL READ
  4317.     RRC
  4318.     JC    FET9    ;IF EOF READ
  4319.     LXI    H,RNDER    ;RANDOM ACCESS FILE ERROR
  4320.     JMP    ERROR
  4321. ;
  4322. FET3:    LXI    B,-128    ;LENGTH=LENGTH-128
  4323.     DAD    B
  4324.     XCHG
  4325.     LXI    B,128    ;DMA ADDR=DMA ADDR+128
  4326.     DAD    B
  4327.     XCHG
  4328.     JMP    FET1
  4329. ;
  4330. FET4:    ORA    A
  4331.     JZ    FET5    ;IF LENGTH=0
  4332.     PUSH    D    ;SAVE DMA ADDR AND LENGTH
  4333.     PUSH    H
  4334.     LXI    H,128
  4335.     LXI    D,TBUFF    ;DMA ADDR=TBUFF
  4336.     JMP    FET2
  4337. ;
  4338. FET5:    LXI    H,TBUFF    ;FIND FIRST CR IN TBUFF
  4339.     LXI    D,TBUFF+127 ;SET UPPER LIMIT OF SEARCH
  4340.     MVI    C,128    ;SET MAXIMUM NUMBER OF BYTES TO SEARCH
  4341.     MOV    A,M
  4342.     CPI    EOF
  4343.     JZ    FET6    ;IF FIRST BYTE IS EOF
  4344. FET51:    CPI    CR
  4345.     INX    H
  4346.     JNZ    FET52    ;IF NOT CR
  4347.     DCR    C
  4348.     JZ    FET12    ;IF CR IS LAST BYTE IN TBUFF
  4349.     CALL    FET10    ;FIND EOF
  4350.     JMP    FET6
  4351. ;
  4352. FET52:    MOV    A,M
  4353.     DCR    C
  4354.     JNZ    FET51    ;IF MORE BYTES TO SEARCH
  4355.     JMP    FET12    ;FILE SIZE ERROR
  4356. ;
  4357. FET6:    LXI    B,-TBUFF-1 ;SET COUNT OF BYTES TO MOVE
  4358.     DAD    B
  4359.     POP    B    ;RETRIEVE LENGTH OF FREE SPACE
  4360.     MOV    A,B
  4361.     CMP    H
  4362.     JM    FET12    ;IF FILE TOO LONG
  4363.     JNZ    FET7    ;IF FILE NOT TOO LONG
  4364.     MOV    A,C
  4365.     CMP    L
  4366.     JM    FET12    ;IF FILE TOO LONG
  4367. FET7:    POP    B    ;SET FREE SPACE ADDR
  4368.     LXI    D,TBUFF
  4369. FET8:    LDAX    D    ;MOVE COUNT BYTES TO FREE SPACE
  4370.     STAX    B
  4371.     INX    D
  4372.     INX    B
  4373.     DCR    L
  4374.     JNZ    FET8    ;IF MORE BYTES TO MOVE
  4375. ;
  4376. FET9:    LHLD    SYSTEM+1    ;FIND EOF
  4377.     DCX    H
  4378.     XCHG
  4379.     LHLD    BOFA
  4380.     CALL    FET10
  4381.     SHLD    EOFA
  4382.     MVI    C,26
  4383.     LXI    D,TBUFF
  4384.     CALL    SYSTEM
  4385.     RET
  4386. ;
  4387. FET10:    MOV    A,M
  4388.     CPI    EOF
  4389.     RZ        ;IF EOF FOUND
  4390.     ORA    A
  4391.     JZ    FET11    ;IF ILLEGAL FILE
  4392.     CALL    ADR
  4393.     MOV    A,E
  4394.     SUB    L
  4395.     MOV    A,D
  4396.     SBB    H
  4397.     JC    FET12    ;IF FILE TOO LONG
  4398.     JMP    FET10
  4399. ;
  4400. FET11:    LXI    H,FNAME
  4401.     JMP    ERROR
  4402. ;
  4403. FET12:    LXI    H,FSIZE
  4404.     JMP    ERROR
  4405. ;
  4406. CNAME:    CALL    GC
  4407.     CPI    CR
  4408.     JZ    CNAM1    ;IF CURRENT WSID WANTED
  4409.     CALL    WSID    ;RENAME THE WORK-SPACE
  4410.     JMP    CMND1
  4411. ;
  4412. CNAM1:    LXI    D,IBUF    ;ASSEMBLE OUTPUT INTO IBUF
  4413.     LXI    H,WSIDN
  4414.     MVI    C,8
  4415.     CALL    COPY    ;COPY FILE NAME
  4416.     MVI    A,' '
  4417.     STAX    D
  4418.     INX    D
  4419.     MVI    C,3
  4420.     CALL    COPY    ;COPY FILE TYPE
  4421.     MVI    A,'"'
  4422.     STAX    D
  4423.     LXI    H,IBUF    ;OUTPUT WSID
  4424.     CALL    PRNT
  4425.     CALL    CRLF
  4426.     JMP    CMND1
  4427. ;
  4428. ERA:    CALL    SETFCB    ;INITIALIZE TFCB
  4429.     CALL    GC
  4430.     CPI    CR
  4431.     JZ    ERA1    ;IF FILE NAME=WSID
  4432.     LXI    D,TFCB+1;SET UP FILE NAME AND TYPE IN TFCB
  4433.     MVI    A,' '    ;PRESET NAME AND TYPE
  4434.     MVI    C,11
  4435. ERA0:    STAX    D
  4436.     INX    D
  4437.     DCR    C
  4438.     JNZ    ERA0
  4439.     LXI    D,TFCB+1;SET NAME AND TYPE
  4440.     LHLD    TXA
  4441.     MVI    C,9
  4442.     CALL    SETFN    ;SET NAME
  4443.     CPI    CR
  4444.     JZ    ERA1    ;IF DONE
  4445.     CPI    '.'
  4446.     JNZ    ERA2    ;IF FILE NAME ERROR
  4447.     INX    H
  4448.     LXI    D,TFCB+9
  4449.     MVI    C,4
  4450.     CALL    SETFN    ;SET TYPE
  4451.     CPI    CR
  4452.     JNZ    ERA2    ;IF FILE NAME ERROR
  4453. ERA1:    MVI    C,19    ;DELETE FILE
  4454.     LXI    D,TFCB
  4455.     CALL    SYSTEM
  4456.     JMP    CMND1
  4457. ;
  4458. ERA2:    LXI    H,FNAME
  4459.     JMP    ERROR
  4460. ;
  4461. WSID:    LXI    H,WSIDN    ;INITIALIZE NAME ADDR
  4462.     LXI    D,WSIDD    ;INITIALIZE DEFAULT WSID ADDR
  4463.     MVI    C,11
  4464. WSID1:    LDAX    D    ;INITIALIZE WSID
  4465.     MOV    M,A
  4466.     INX    H
  4467.     INX    D
  4468.     DCR    C
  4469.     JNZ    WSID1
  4470.     LHLD    TXA
  4471.     CALL    GC
  4472.     CPI    CR
  4473.     RZ        ;IF NO FILE NAME SPECIFIED
  4474.     MVI    A,' '    ;PREPARE NAME FIELD
  4475.     MVI    C,8
  4476.     LXI    D,WSIDN
  4477. WSD10:    STAX    D
  4478.     INX    D
  4479.     DCR    C
  4480.     JNZ    WSD10    ;IF MORE TO DO
  4481.     LXI    D,WSIDN
  4482.     MVI    C,9
  4483.     CALL    SETFN    ;SET FILE NAME
  4484.     CPI    CR
  4485.     RZ        ;IF DONE
  4486.     CPI    '.'
  4487.     JNZ    WSID3    ;IF FILE NAME ERROR
  4488.     MVI    A,' '    ;PREPARE TYPE FIELD
  4489.     MVI    C,3
  4490.     LXI    D,WSIDT
  4491. WSID2:    STAX    D
  4492.     INX    D
  4493.     DCR    C
  4494.     JNZ    WSID2
  4495.     MVI    C,4
  4496.     LXI    D,WSIDT
  4497.     INX    H
  4498.     CALL    SETFN
  4499.     CPI    CR
  4500.     RZ        ;IF DONE
  4501. WSID3:    LXI    H,FNAME
  4502.     JMP    ERROR
  4503. ;
  4504. SETFN:    MOV    A,M
  4505.     CPI    CR
  4506.     RZ
  4507.     CPI    '.'
  4508.     RZ
  4509.     STAX    D
  4510.     INX    H
  4511.     INX    D
  4512.     DCR    C
  4513.     RZ
  4514.     JMP    SETFN
  4515. ;
  4516. SETFCB:    LXI    H,TFCB    ;SET FCB ADDR
  4517.     MVI    M,0    ;CLEAR ET
  4518.     INX    H
  4519.     MVI    C,11
  4520.     LXI    D,WSIDN    ;SET ADDR OF WSID
  4521. SETF1:    LDAX    D    ;COPY WSID TO TFCB
  4522.     MOV    M,A
  4523.     INX    H
  4524.     INX    D
  4525.     DCR    C
  4526.     JNZ    SETF1    ;IF MORE CHARS
  4527.     MVI    C,21
  4528. SETF2:    MVI    M,0    ;CLEAR REST OF FCB
  4529.     INX    H
  4530.     DCR    C
  4531.     JNZ    SETF2
  4532.     RET
  4533. ;
  4534. ;    FLOATING POINT RAM
  4535. ;
  4536. HOLD1:    DS    DIGIT+1
  4537. HOLD2:    DS    DIGIT+1
  4538. HOLD3:    DS    DIGIT+1
  4539. HOLD4:    DS    DIGIT+1
  4540. HOLD5:    DS    DIGIT+1
  4541. HOLD6:    DS    DIGIT+1
  4542. HOLD7:    DS    DIGIT+1
  4543. HOLD8:    DS    DIGIT+1
  4544.     DS    1
  4545. ERRI:    DS    1    ;ERROR FLAG
  4546.     DS    1
  4547. BUF:    DS    DIGIT    ;WORKING BUFFER
  4548. SIGN:    DS    1    ;SIGN BIT
  4549. EXP:    DS    1    ;EXPONENT
  4550. RCTRL:    DS    1    ;ROUNDING CONTROL FLAG 1=MSD
  4551. RDIGI:    DS    1    ;ROUNDING DIGIT
  4552. SIGND    EQU    HOLD1+DIGIT
  4553. EXPD    EQU    HOLD1+DIGIT+1
  4554. ;
  4555. ;    SYSTEM RAM
  4556. ;
  4557. LWID:    DB    80    ;LINE WIDTH LIMIT
  4558. WSIDN:    DS    8    ;WORK-SPACE NAME FIELD
  4559. WSIDT:    DS    4    ;WORK-SPACE TYPE FIELD
  4560. WSIDD:    DB    'PROGRAM BSC' ;DEFAULT NAME AND TYPE
  4561. EROM:    DS    0
  4562.     DS    100
  4563. CMNDSP:    DB    0
  4564. MACSIZ    EQU    34
  4565. MACSP:    DW    MACSTK
  4566.     DS    MACSIZ-1
  4567. MACSTK:    DB    0    ;DB TO PREVENT MACSTK=TRPSP
  4568. TRPSIZ    EQU    20
  4569. TRPSP:    DW    TRPSTK
  4570.     DS    TRPSIZ-1
  4571. TRPSTK:    DB    0    ;DB TO PREVENT TRPSTK=PHEAD
  4572. PHEAD:    DS    1
  4573. RELTYP:    DS    1
  4574. NULLCT:    DS    1
  4575. PFLAG:    DB    0    ;I/O SWITCH- 1=PRINTER, 0=CONSOLE
  4576. ARGF:    DS    1
  4577. DIRF:    DS    1
  4578. TXA:    DS    2
  4579. CSTKSZ    EQU    100
  4580. ASTKSZ    EQU    FPSIZ*LINLEN/2
  4581. CSTKL:    DS    CSTKSZ
  4582. ASTKL:    DS    ASTKSZ
  4583. RTXA:    DS    2
  4584. STB:    DS    2
  4585. CSTKA:    DS    2
  4586. SINK:    DS    FPSIZ-1
  4587. FPSINK:    DS    1
  4588.     DS    FPSIZ-1
  4589. FTEMP:    DS    1
  4590.     DS    FPSIZ-1
  4591. FTEM1:    DS    1
  4592.     DS    FPSIZ-1
  4593. FTEM2:    DS    1
  4594.     DS    FPSIZ-1
  4595. FRAND:    DS    1
  4596. IBCNT:    DS    1
  4597. IBLN:    DS    2
  4598. IBUF:    DS    LINLEN
  4599. ASTKA:    DS    2
  4600. MATA:    DS    2
  4601. ADDS:    DS    2
  4602. ADDT:    DS    2
  4603. BCADD:    DS    2
  4604. OPST:    DS    1
  4605. OPSTR:    DS    1
  4606. ECNT:    DS    1
  4607. FSIGN:    DS    1
  4608. BC:    DS    DIGIT+2
  4609. ABUF:    DS    DIGIT*2+2
  4610. XSIGN:    DS    1
  4611. EXPO:    DS    1
  4612. FES:    DS    1
  4613. INFES:    DS    1
  4614. MAXL:    DS    2
  4615. INSA:    DS    2
  4616. ;
  4617. ;    SPECIAL INTERFACE GLOBAL
  4618. ;
  4619. CALST:    DS    6
  4620. CALLA:    DS    2
  4621. EOFA:    DS    2    ;END OF FILE ADDRESS
  4622. BOFA:    DS    2    ;START OF FILE ADDRESS
  4623. MEMTOP:    DS    2    ;STORAGE FOR LAST ASSIGNED MEMORY LOCATION
  4624. ;
  4625. ;
  4626.     END
  4627.