home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / z3util / dprog12.lbr / DPROG12.MZC / DPROG12.MAC
Encoding:
Text File  |  1993-06-07  |  20.3 KB  |  1,200 lines

  1. ;
  2. ; PROGRAM: DPROG
  3. ; AUTHOR: Richard Conn
  4. ; VERSION: 1.2
  5. ; DATE: 13 Apr 85
  6. ; PREVIOUS VERSIONS: 1.1 (22 Oct 84), 1.0 (28 July 84)
  7. ; REVISION HISTORY:
  8. ;    1.2 - Howard Goldstein - Fixed error messages and word and format
  9. ;        dumps to always print on console. Fixed 2- and 3-digit
  10. ;        decimal routines so original value would not be trashed.
  11. ;    Fixed %D and %X to output on selected device.
  12. ;
  13. ;    1.1 - Rick Conn - Added Word References from Command Line
  14. ;
  15. vers    equ    12
  16. z3env    equ    0f400h
  17.  
  18. ;
  19. ;    DPROG is used to program the user's terminal, printer, or punch
  20. ; with data from the file specified in the command line.  DPROG will
  21. ; automatically search for the file along the path starting at the
  22. ; indicated (or implied) DU.
  23. ;
  24.  
  25. ;
  26. ;  Basic Equates
  27. ;
  28. opsys    equ    0
  29. fcb    equ    5ch
  30. tbuff    equ    80h
  31. cr    equ    0dh
  32. ff    equ    0ch
  33. lf    equ    0ah
  34. ctrlc    equ    'C'-'@'
  35. ctrls    equ    'S'-'@'
  36. ctrlz    equ    'Z'-'@'
  37. bel    equ    7
  38. bs    equ    8
  39. tab    equ    9
  40.  
  41. ;
  42. ;  DPROG Constants
  43. ;
  44. COMMENT    equ    ';'    ;denotes a comment line
  45. WORD    equ    '-'    ;denotes a word definition
  46. SYM    equ    '='    ;symbol table dump command
  47. DEV    equ    '>'    ;device assignment
  48. INP    equ    '<'    ;input forms (pause, string, delay)
  49. wordl    equ    16    ;length of word
  50. fmt    equ    '('    ;begin format definition
  51. fmtch    equ    '%'    ;format escape char
  52. endfmt    equ    ')'    ;end format definition
  53. quote    equ    '"'    ;quote string
  54. literal    equ    '\'    ;literal interpretation follows
  55. control    equ    '^'    ;control char follows
  56.  
  57. ;
  58. ;  SYSLIB Routines
  59. ;
  60.     ext    condin,cin,cout,lout,pout
  61.     ext    z3init,pfind,z3log
  62.     ext    moveb,hmovb,logud,pfn1,caps
  63.     ext    f$open,f$read,f$close
  64.     ext    eval
  65.     ext    sknsp
  66.     ext    codend
  67.  
  68. ;
  69. ; Environment Definition
  70. ;
  71.     if    z3env ne 0
  72. ;
  73. ; External ZCPR3 Environment Descriptor
  74. ;
  75.     jmp    start
  76.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  77.     db    1    ;External Environment Descriptor
  78. z3eadr:
  79.     dw    z3env
  80. start:
  81.     lhld    z3eadr    ;pt to ZCPR3 environment
  82. ;
  83.     else
  84. ;
  85. ; Internal ZCPR3 Environment Descriptor
  86. ;
  87.     MACLIB    Z3BASE.LIB
  88.     MACLIB    SYSENV.LIB
  89. z3eadr:
  90.     jmp    start
  91.     SYSENV
  92. start:
  93.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  94.     endif
  95.  
  96. ;
  97. ; Start of Program -- Initialize ZCPR3 Environment
  98. ;
  99.     call    z3init    ;initialize the ZCPR3 Env
  100. ;
  101. ; Initial Routines
  102. ;
  103.     call    helpck    ;check for help
  104.     call    bufinit    ;initialize buffers
  105.     call    savecmd    ;save ending command
  106. ;
  107. ; Load File
  108. ;
  109.     call    locfile    ;locate file
  110.     call    logud    ;enter directory of file
  111.     call    load    ;load file
  112. ;
  113. ; Perform Program
  114. ;
  115.     call    program    ;program the user's terminal
  116.     lhld    endcmd    ;execute words from ending command
  117.     call    prog1    ;subroutine of PROGRAM
  118.     ret
  119.  
  120. ;
  121. ; Save Ending Command
  122. ;
  123. savecmd:
  124.     lhld    endcmd        ;set empty end command
  125.     mvi    m,ctrlz
  126.     xchg            ;DE pts to end command
  127.     lxi    h,tbuff+1    ;pt to first char of tail
  128.     call    sksp        ;skip to non-space
  129.     mov    a,m        ;any left?
  130.     ora    a        ;none?
  131.     rz
  132.     call    sknsp        ;skip to space
  133.     mov    a,m        ;any left?
  134.     ora    a        ;none?
  135.     rz
  136. savec1:
  137.     mov    a,m        ;get next char
  138.     ora    a        ;done?
  139.     jz    savec2
  140.     stax    d        ;store next char
  141.     inx    h        ;pt to next
  142.     inx    d
  143.     jmp    savec1
  144. savec2:
  145.     mvi    a,ctrlz        ;store EOL
  146.     stax    d
  147.     ret
  148.  
  149. ;
  150. ; Initialize Buffers
  151. ;
  152. bufinit:
  153.     call    codend    ;address of free space
  154.     shld    endcmd    ;set ptr to ending commands
  155.     lxi    d,100H
  156.     dad    d    ;reserve 100H bytes
  157.     shld    format    ;format string
  158.     xchg
  159.     lxi    h,deffmt    ;set default format (char)
  160.     mvi    b,40    ;allow 40 chars
  161.     call    moveb
  162.     xchg        ;HL pts to format buffer
  163.     inr    h    ;next page
  164.     shld    locstk    ;set location stack
  165.     shld    tos    ;set top of stack
  166.     mvi    m,0
  167.     inx    h
  168.     mvi    m,0    ;zero stack
  169.     dcx    h
  170.     inr    h    ;next page
  171.     shld    free    ;free area
  172.     mvi    a,'C'    ;assign console as output device
  173.     sta    outdev
  174.     ret
  175.  
  176. ;
  177. ; Check for Help
  178. ;
  179. helpck:
  180.     lxi    h,fcb+1    ;pt to fcb name
  181.     mov    a,m    ;get it
  182.     cpi    '/'    ;help if slash
  183.     rnz
  184.     pop    psw    ;clear stack
  185.     call    eprint
  186.     db    'DPROG, Version '
  187.     db    (vers/10)+'0','.',(vers mod 10)+'0'
  188.     db    cr,lf,' Syntax:'
  189.     db    cr,lf,'  DPROG              <-- STD.DPG'
  190.     db    cr,lf,'  DPROG filename     <-- filename.DPG'
  191.     db    cr,lf,'  DPROG filename.typ <-- filename.typ'
  192.     db    0
  193.     ret
  194.  
  195. ;
  196. ; Find File
  197. ;   If found, return BC=DU and NZ
  198. ;
  199. locfile:
  200.     lxi    d,fcb    ;pt to FCB
  201.     call    z3log
  202.     lxi    d,fcb+1    ;pt to file name
  203.     lxi    h,defname    ;pt to default file name
  204.     mvi    b,8    ;8 chars
  205.     ldax    d    ;any type?
  206.     cpi    ' '    ;none if space
  207.     cz    moveb
  208.     lxi    d,fcb+9    ;pt to file type
  209.     lxi    h,deftype    ;pt to default file type
  210.     mvi    b,3    ;3 chars
  211.     ldax    d    ;any type?
  212.     cpi    ' '    ;none if space
  213.     cz    moveb
  214.     lxi    d,fcb    ;pt to FCB
  215.     mvi    a,0ffh    ;search current
  216.     call    pfind    ;search for file
  217.     rnz        ;get file if found
  218. ;
  219. ; Abort Attempt to Load File
  220. ;
  221. abort:
  222.     pop    psw    ;clear stack
  223.     call    eprint
  224.     db    cr,lf,' File ',0
  225.     lxi    d,fcb+1    ;pt to file name
  226.     call    pfn1
  227.     call    eprint
  228.     db    ' NOT Found',0
  229.     ret
  230.  
  231. ;
  232. ; Load File
  233. ;
  234. load:
  235.     lxi    d,fcb    ;pt to fcb
  236.     call    f$open    ;open file for input
  237.     jnz    abort    ;abort attempt
  238.     lhld    free    ;buffer area
  239. load1:
  240.     lxi    d,fcb    ;pt to fcb
  241.     call    f$read    ;read next block
  242.     jnz    load2    ;done, so mark and close
  243.     lxi    d,tbuff    ;copy into buffer
  244.     xchg        ;copy into buffer at DE from TBUFF at HL
  245.     mvi    b,128    ;128 bytes
  246.     call    moveb
  247.     lxi    h,80h    ;pt to next buffer
  248.     dad    d
  249.     jmp    load1
  250. load2:
  251.     mvi    m,ctrlz    ;mark EOF
  252.     inr    h    ;next page
  253.     mvi    l,0
  254.     shld    words    ;mark beginning of word definition area
  255.     shld    nxtword    ;mark next word
  256.     mvi    m,0    ;mark no words
  257.     jmp    f$close    ;close input file
  258.  
  259. ;
  260. ; Program the User's Terminal
  261. ;
  262. program:
  263.     lhld    free    ;pt to first char
  264. prog1:
  265.     call    capa    ;capitalize
  266.     cpi    ctrlz    ;done?
  267.     rz
  268.     cpi    CR    ;eol?
  269.     jz    skipl
  270.     cpi    WORD    ;word definition?
  271.     jz    defword
  272.     cpi    SYM    ;symbol table or format definition dump?
  273.     jz    dump
  274.     cpi    DEV    ;assign device?
  275.     jz    device
  276.     cpi    INP    ;input form?
  277.     jz    input
  278.     push    h    ;save HL
  279. prog2:
  280.     call    output    ;output line at HL
  281.     call    locpop    ;pop stack if any
  282.     jnz    prog2    ;continue if any element on stack
  283.     pop    h    ;restore HL
  284. ;
  285. ; Skip to next line
  286. ;
  287. skipl:
  288.     mov    a,m    ;get char
  289.     call    capa    ;capitalize
  290.     cpi    CR    ;new line?
  291.     jz    skipl1
  292.     cpi    LF    ;new line?
  293.     jz    skipl1
  294.     cpi    CTRLZ    ;EOF?
  295.     rz
  296.     inx    h    ;pt to next
  297.     jmp    skipl
  298. skipl1:
  299.     mov    a,m    ;get it
  300.     inx    h    ;pt to next
  301.     ani    7fh    ;mask
  302.     cpi    CR    ;continue?
  303.     jz    skipl1
  304.     cpi    LF    ;continue?
  305.     jz    skipl1
  306.     dcx    h    ;pt to non-eol char
  307.     jmp    prog1    ;continue with next line
  308. ;
  309. ; Input Form
  310. ;
  311. input:
  312.     inx    h    ;pt to next char
  313.     call    cin    ;get any char
  314.     ani    7fh    ;mask
  315.     cpi    ctrlc    ;abort?
  316.     jz    opsys
  317.     jmp    skipl    ;continue
  318. ;
  319. ; Assign Device
  320. ;
  321. device:
  322.     inx    h    ;pt to char
  323.     call    capa    ;capitalize
  324.     cpi    'C'    ;console?
  325.     jz    setdev
  326.     cpi    'L'    ;list?
  327.     jz    setdev
  328.     cpi    'P'    ;punch?
  329.     jz    setdev
  330.     push    psw
  331.     call    eprint
  332.     db    cr,lf,bel,' Invalid Device Assignment: ',0
  333.     pop    psw
  334.     call    cout    ;print char
  335.     dcx    h    ;back up
  336.     jmp    skipl    ;continue
  337. ;
  338. ; Perform assignment
  339. ;
  340. setdev:
  341.     sta    outdev    ;assign
  342.     jmp    skipl    ;continue
  343. ;
  344. ; Define Word
  345. ;
  346. defword:
  347.     inx    h    ;pt to first char of word
  348.     call    bufword    ;store word in buffer
  349.     shld    nextch    ;save ptr to next char
  350.     call    wscan    ;scan for word
  351.     jz    defnew    ;new word defined
  352.     xchg        ;ptr to high-order in DE
  353.     lhld    nextch    ;get ptr to word definition
  354.     xchg        ;word defn in DE, word adr high in HL
  355.     mov    m,d    ;store new address
  356.     dcx    h
  357.     mov    m,e
  358.     xchg        ;HL pts to word
  359.     jmp    skipl    ;skip out line
  360. ;
  361. ; New Word
  362. ;
  363. defnew:
  364.     lhld    nxtword        ;pt to next word
  365.     xchg
  366.     lxi    h,wordbf    ;pt to buffer
  367.     mvi    b,wordl        ;number of chars max
  368.     call    hmovb        ;copy into buffer and advance HL
  369.     lhld    nextch        ;get address
  370.     xchg
  371.     mov    m,e        ;put low
  372.     inx    h
  373.     mov    m,d        ;put high
  374.     inx    h        ;set ptr to next word
  375.     mvi    m,0        ;store zero
  376.     shld    nxtword        ;set ptr
  377.     xchg            ;HL pts to word definition
  378.     jmp    skipl        ;skip to next line
  379.  
  380. ;
  381. ; Dump Format String or Word Table
  382. ;
  383. dump:
  384.     inx    h    ;pt to option
  385.     call    capa    ;check for format display option
  386.     cpi    'F'    ;format?
  387.     jz    dfmt    ;dump format if so
  388.     cpi    'S'    ;symbols?
  389.     jz    dsym
  390.     dcx    h    ;pt to current
  391.     call    dumpsym    ;dump symbols
  392.     call    dumpfmt    ;dump format
  393.     jmp    skipl    ;continue
  394. ;
  395. ; Dump Format
  396. ;
  397. dfmt:
  398.     call    dumpfmt    ;do dump
  399.     jmp    skipl    ;continue
  400. ;
  401. ; Dump Words
  402. ;
  403. dsym:
  404.     call    dumpsym    ;do dump
  405.     jmp    skipl    ;continue
  406. ;
  407. ; Dump Words in Symbol Table
  408. ;
  409. dumpsym:
  410.     push    h    ;save HL
  411.     call    eprint
  412.     db    cr,lf,' >> Word Definitions <<',0
  413.     lhld    words    ;dump word table
  414. sym1:
  415.     mov    a,m    ;get next
  416.     ora    a
  417.     jz    symexit
  418.     call    eprint
  419.     db    cr,lf,'  ',0
  420.     call    prword    ;print word
  421.     mov    e,m    ;get low
  422.     inx    h
  423.     mov    d,m    ;get high
  424.     inx    h    ;pt to next word
  425.     push    h    ;save ptr
  426.     call    eprint
  427.     db    '  >',0
  428.     xchg        ;HL pts to word
  429. sym2:
  430.     mov    a,m    ;get next char
  431.     cpi    CR    ;done?
  432.     jz    sym3
  433.     cpi    TAB    ;translate tab to space
  434.     jnz    sym2out
  435.     mvi    a,' '    ;space instead of tab
  436. sym2out:
  437.     call    cout
  438.     inx    h
  439.     jmp    sym2
  440. sym3:
  441.     call    eprint
  442.     db    '<',0
  443.     pop    h    ;pt to next word
  444.     jmp    sym1
  445. symexit:
  446.     pop    h    ;pt to char
  447.     ret
  448. ;
  449. ; Output Format String
  450. ;
  451. dumpfmt:
  452.     push    h    ;save ptr
  453.     call    eprint
  454.     db    cr,lf,' Format: (',0
  455.     lhld    format    ;pt to string
  456.     call    epstr    ;print it
  457.     call    eprint
  458.     db    ')',cr,lf,0
  459.     pop    h    ;get ptr
  460.     ret
  461.  
  462. ;
  463. ; Print Word at HL (advance HL)
  464. ;
  465. prword:
  466.     mvi    b,wordl    ;number of chars
  467. prw1:
  468.     mov    a,m    ;get char
  469.     call    cout
  470.     inx    h
  471.     dcr    b
  472.     jnz    prw1
  473.     ret
  474. ;
  475. ; Routine to Output a Line
  476. ;
  477. output:
  478.     call    sksp    ;skip spaces
  479.     cpi    COMMENT    ;done?
  480.     rz
  481.     cpi    CR    ;done?
  482.     rz
  483.     cpi    LF    ;done?
  484.     rz
  485.     cpi    CTRLZ    ;done?
  486.     rz
  487.     cpi    fmt    ;format definition?
  488.     jz    outfmt
  489.     cpi    quote    ;chars?
  490.     jz    outch
  491.     call    bufword    ;store word in buffer
  492.     shld    nextch    ;save ptr to next char after word
  493.     call    wscan    ;scan for word in table
  494.     jz    badword    ;word not defined
  495.     call    locpush    ;push location onto stack
  496.     xchg        ;HL pts to continuation location
  497.     jmp    output    ;continue
  498. ;
  499. ; Output Quoted String
  500. ;
  501. outch:
  502.     inx    h    ;pt to next char
  503. outch1:
  504.     mov    a,m    ;get it
  505.     ani    7fh    ;mask
  506.     cpi    CR    ;done?
  507.     jz    outcherr
  508.     cpi    LF    ;done?
  509.     jz    outcherr
  510.     cpi    CTRLZ    ;done?
  511.     jz    outcherr
  512.     cpi    quote    ;end of quote?
  513.     jz    outch2
  514.     call    charout    ;output char in whatever form
  515.     jmp    outch1    ;continue
  516. outcherr:
  517.     call    eprint
  518.     db    cr,lf,bel,' Premature End of Quote',cr,lf,0
  519.     jmp    output
  520. outch2:
  521.     inx    h    ;pt to after quote
  522.     jmp    output    ;continue
  523. ;
  524. ; Output char in A and set HL to next char on exit
  525. ;
  526. charout:
  527.     cpi    control    ;control char follows?
  528.     jz    charo0
  529.     cpi    literal    ;literal follows?
  530.     jz    charo1
  531. ;
  532. ; Normal Char in A
  533. ;
  534. charnxt:
  535.     inx    h        ;pt to next char
  536.     jmp    formatout    ;output with format
  537. ;
  538. ; Output control char
  539. ;
  540. charo0:
  541.     inx    h    ;pt to char
  542.     call    capa    ;get char
  543.     sui    '@'    ;convert to control
  544.     jc    ctrlerr
  545.     cpi    20h
  546.     jnc    ctrlerr
  547.     inx    h    ;pt to next
  548.     jmp    formatout
  549. ctrlerr:
  550.     call    eprint
  551.     db    cr,lf,bel,' Invalid Control Character',cr,lf,0
  552.     ret
  553. ;
  554. ; Output Literal Format
  555. ;
  556. charo1:
  557.     inx    h    ;pt to char
  558.     call    capa    ;get char
  559.     cpi    'B'    ;BS?
  560.     jz    c1bs
  561.     cpi    'D'    ;DEL?
  562.     jz    c1del
  563.     cpi    'E'    ;ESCAPE?
  564.     jz    c1esc
  565.     cpi    'L'    ;CRLF?
  566.     jz    c1nl
  567.     cpi    'N'    ;LF?
  568.     jz    c1lf
  569.     cpi    'R'    ;CR?
  570.     jz    c1cr
  571.     cpi    'T'    ;TAB?
  572.     jz    c1tab
  573.     cpi    '0'    ;digit?
  574.     jc    charol    ;literal if not
  575.     cpi    '9'+1    ;range?
  576.     jc    numout
  577.     cpi    ' '    ;less than space?
  578.     jnc    charol
  579.     call    eprint
  580.     db    cr,lf,bel,' Invalid Literal Argument',cr,lf,0
  581.     ret
  582.  
  583. ;
  584. ; Output Char in A literally
  585. ;
  586. charol:
  587.     mov    a,m    ;get char
  588.     ani    7fh    ;don't cap this way
  589.     inx    h    ;pt to next
  590.     jmp    formatout
  591. ;
  592. ; Output Number
  593. ;
  594. numout:
  595.     call    eval    ;convert to binary in DE
  596.     mov    a,e    ;char binary value
  597.     jmp    formatout    ;output with format
  598. ;
  599. ; Output BS
  600. ;
  601. c1bs:
  602.     mvi    a,bs
  603.     jmp    charnxt
  604. ;
  605. ; Output TAB
  606. ;
  607. c1tab:
  608.     mvi    a,tab
  609.     jmp    charnxt
  610. ;
  611. ; Output CR
  612. ;
  613. c1cr:
  614.     mvi    a,cr
  615.     jmp    charnxt
  616. ;
  617. ; Output DEL
  618. ;
  619. c1del:
  620.     mvi    a,7fh
  621.     jmp    charnxt
  622. ;
  623. ; Output ESCAPE
  624. ;
  625. c1esc:
  626.     mvi    a,1bh
  627.     jmp    charnxt
  628. ;
  629. ; Output LF
  630. ;
  631. c1lf:
  632.     mvi    a,lf
  633.     jmp    charnxt
  634. ;
  635. ; Output CRLF
  636. ;
  637. c1nl:
  638.     mvi    a,cr
  639.     call    formatout    ;output CR
  640.     mvi    a,lf
  641.     jmp    charnxt
  642.  
  643. ;
  644. ; Output Char in A According to Format
  645. ;
  646. formatout:
  647.     push    h    ;save ptr to next char
  648.     push    b    ;save BC
  649.     mov    b,a    ;char in B
  650.     lhld    format    ;pt to format string
  651. fout1:
  652.     mov    a,m    ;get next char
  653.     ani    7fh    ;mask
  654.     jz    foutx    ;exit if end of string
  655.     cpi    fmtch    ;expression form?
  656.     jz    fout2
  657.     cpi    literal    ;literal?
  658.     jz    flit
  659. ;
  660. ; Output char in A and advance
  661. ;
  662. fch:
  663.     call    chout    ;output char
  664.     inx    h    ;pt to next
  665.     jmp    fout1
  666. ;
  667. ; Output Value in B according to format
  668. ;
  669. fout2:
  670.     inx    h    ;pt to format type
  671.     mov    a,m    ;get char
  672.     inx    h    ;pt to next
  673.     ani    7fh    ;mask
  674.     call    caps
  675.     ora    a    ;none?
  676.     jz    fout1    ;error condition - % at end of string
  677.     cpi    'C'    ;char?
  678.     jz    foch
  679.     push    b
  680.     cpi    'D'    ;floating decimal chars
  681.     jz    fod
  682.     cpi    '2'    ;2 decimal chars
  683.     jz    fo2
  684.     cpi    '3'    ;3 decimal chars
  685.     jz    fo3
  686.     pop    b
  687.     cpi    'X'    ;2 hex chars
  688.     jz    fox
  689.     push    psw
  690.     call    eprint
  691.     db    cr,lf,bel,' Invalid Format Char: ',0
  692.     pop    psw
  693.     call    cout
  694.     call    crlf
  695.     jmp    fout1    ;continue
  696.  
  697. ;
  698. ; Output value in B as char
  699. ;
  700. foch:
  701.     mov    a,b    ;get value
  702.     call    chout    ;output it
  703.     jmp    fout1    ;continue
  704. ;
  705. ; Output value in B as floating decimal
  706. ;
  707. fod:
  708.     mvi    a,0ffh
  709.     sta    supzero    ;set zero suppress
  710.     jmp    fo3    ;output value
  711. ;
  712. ; Output value in B as hex
  713. ;
  714. fox:
  715.     mov    a,b    ;get value
  716.     rlc        ;shift out right nyble
  717.     rlc
  718.     rlc
  719.     rlc
  720.     call    outhex    ;output left nyble
  721.     mov    a,b    ;get value again
  722.     call    outhex    ;output right nyble
  723.     jmp    fout1    ;continue
  724. ;
  725. ; Output value in A as a hex digit
  726. ;
  727. outhex:    ani    0fh    ;clear left half of byte
  728.     cpi    0ah
  729.     jnc    outaf
  730.     adi    30h    ;convert to 0-9
  731.     jmp    chout    ;output
  732. outaf:    adi    37h    ;convert to digit A-F
  733.     jmp    chout    ;output
  734. ;
  735. ; Output value in B as 3 decimal chars
  736. ;
  737. fo3:
  738.     mvi    c,100    ;100's
  739.     call    dec    ;output and fall thru to FO2
  740. ;
  741. ; Output value in B as 2 decimal chars
  742. ;
  743. fo2:
  744.     mvi    c,10    ;10's
  745.     call    dec
  746.     mov    a,b    ;get value
  747.     adi    '0'    ;convert
  748.     call    chout
  749.     xra    a
  750.     sta    supzero    ;indicate no zero suppress
  751.     pop    b
  752.     jmp    fout1    ;continue
  753. ;
  754. ; Subtracting Output
  755. ;   Output value in B as 100's or 10's digit
  756. ;   (leading 0 conditionally allowed)
  757. ;
  758. dec:
  759.     push    d    ;save DE
  760.     xra    a
  761.     mov    d,a    ;set digit
  762.     mov    a,b    ;get value
  763. dec1:
  764.     sub    c    ;subtract
  765.     jc    dec2
  766.     inr    d    ;increment digit
  767.     jmp    dec1
  768. dec2:
  769.     add    c    ;add back in
  770.     mov    b,a
  771.     mov    a,d    
  772.     ora    a    ;is digit zero?
  773.     jnz    dec3    ;no, go print it
  774.     lda    supzero    ;are we suppressing zero?
  775.     jnz    dec4
  776. dec3:    adi    '0'    ;convert to printable form
  777.     call    chout
  778. dec4:    pop    d    ;restore DE
  779.     ret
  780. ;
  781. ; Exit Format String Output
  782. ;
  783. foutx:
  784.     pop    b    ;restore BC
  785.     pop    h    ;restore ptr to next char
  786.     ret
  787. ;
  788. ; Literal Format Output
  789. ;
  790. flit:
  791.     inx    h    ;pt to char
  792.     call    capa    ;get char
  793.     cpi    'B'    ;BS?
  794.     jz    f1bs
  795.     cpi    'D'    ;DEL?
  796.     jz    f1del
  797.     cpi    'E'    ;ESCAPE?
  798.     jz    f1esc
  799.     cpi    'L'    ;CRLF?
  800.     jz    f1nl
  801.     cpi    'N'    ;LF?
  802.     jz    f1lf
  803.     cpi    'R'    ;CR?
  804.     jz    f1cr
  805.     cpi    'T'    ;TAB?
  806.     jz    f1tab
  807.     cpi    '0'    ;digit?
  808.     jc    fchck    ;literal if not
  809.     cpi    '9'+1    ;range?
  810.     jnc    fchck
  811. ;
  812. ; Output Number
  813. ;
  814.     call    eval    ;convert to binary in DE
  815.     mov    a,e    ;char binary value
  816.     jmp    fch    ;output
  817. ;
  818. ; Check for Valid Literal
  819. ;
  820. fchck:
  821.     cpi    ' '    ;not valid if less than space
  822.     jnc    fch
  823.     call    eprint
  824.     db    cr,lf,bel,' Invalid Literal Argument',cr,lf,0
  825.     jmp    fout1
  826. ;
  827. ; Output BS
  828. ;
  829. f1bs:
  830.     mvi    a,bs
  831.     jmp    fch
  832. ;
  833. ; Output TAB
  834. ;
  835. f1tab:
  836.     mvi    a,tab
  837.     jmp    fch
  838. ;
  839. ; Output CR
  840. ;
  841. f1cr:
  842.     mvi    a,cr
  843.     jmp    fch
  844. ;
  845. ; Output DEL
  846. ;
  847. f1del:
  848.     mvi    a,7fh
  849.     jmp    fch
  850. ;
  851. ; Output ESCAPE
  852. ;
  853. f1esc:
  854.     mvi    a,1bh
  855.     jmp    fch
  856. ;
  857. ; Output LF
  858. ;
  859. f1lf:
  860.     mvi    a,lf
  861.     jmp    fch
  862. ;
  863. ; Output CRLF
  864. ;
  865. f1nl:
  866.     mvi    a,cr
  867.     call    chout    ;output CR
  868.     mvi    a,lf
  869.     jmp    fch
  870.  
  871. ;
  872. ; Define New Output Format
  873. ;
  874. outfmt:
  875.     inx    h    ;pt to format char
  876.     xchg
  877.     lhld    format    ;pt to format area
  878.     xchg
  879. ;
  880. ; Get next char for format string
  881. ;
  882. outf1:
  883.     mov    a,m    ;get next char
  884.     ani    7fh    ;mask
  885.     cpi    endfmt    ;end of format?
  886.     jz    outf2
  887.     cpi    CR    ;end of line?
  888.     jz    outf3
  889.     cpi    LF    ;end of line?
  890.     jz    outf3
  891.     cpi    CTRLZ    ;end of file?
  892.     jz    outf3
  893.     stax    d    ;store char
  894.     inx    h    ;pt to next
  895.     inx    d
  896.     cpi    literal    ;literal denotation?
  897.     jnz    outf1    ;continue if not
  898. ;
  899. ; Literal flag, so store next char exactly as-is without interpretation
  900. ;
  901.     mov    a,m    ;get next char
  902.     ani    7fh    ;mask
  903.     stax    d    ;store it literally
  904.     inx    h    ;pt to next
  905.     inx    d
  906.     jmp    outf1
  907. ;
  908. ; Format String Stored - Terminate it
  909. ;
  910. outf2:
  911.     inx    h    ;pt to next char
  912. outf3:
  913.     xra    a    ;terminate format string
  914.     stax    d
  915.     jmp    output
  916.  
  917. ;
  918. ; Invalid Word - So State
  919. ;
  920. badword:
  921.     call    eprint
  922.     db    cr,lf,bel,' Invalid Word Reference: ',0
  923.     lxi    h,wordbf    ;pt to buffer
  924.     call    prword        ;print word
  925.     lhld    nextch        ;continue
  926.     jmp    output
  927. ;
  928. ; Element must be a word - resolve it
  929. ;
  930. bufword:
  931.     lxi    d,wordbf    ;buffer to store word in
  932.     mvi    b,wordl        ;length
  933. ;
  934. ; Build Word into WORDBF
  935. ;
  936. bword1:
  937.     call    capa        ;get char
  938.     cpi    ' '+1        ;end?
  939.     jc    bword3
  940.     stax    d        ;store char
  941.     inx    h        ;pt to next
  942.     inx    d
  943.     dcr    b        ;count down
  944.     jnz    bword1
  945. ;
  946. ; Word is longer than WORDL - skip trailing chars
  947. ;
  948. bword2:
  949.     mov    a,m        ;skip chars to delimiter
  950.     ani    7fh        ;mask
  951.     cpi    ' '+1
  952.     jc    bword4
  953.     inx    h        ;pt to next
  954.     jmp    bword2
  955. ;
  956. ; Word is built into WORDBF - space fill it
  957. ;
  958. bword3:
  959.     mvi    a,' '        ;space
  960.     stax    d        ;store char
  961.     inx    d        ;pt to next
  962.     dcr    b        ;count down
  963.     jnz    bword3
  964. ;
  965. ; Word is Stored
  966. ;   HL pts to next char after the Word
  967. ;
  968. bword4:
  969.     ret
  970. ;
  971. ; Scan for Word in Table
  972. ;   Return with Zero Set if Not Resolved
  973. ;   If Resolved, DE=address of word
  974. ;
  975. wscan:
  976.     lhld    words        ;pt to first word in table
  977. wscan1:
  978.     mov    a,m        ;abort if empty table
  979.     ora    a
  980.     rz
  981.     lxi    d,wordbf    ;pt to buffer
  982.     mvi    b,wordl        ;size of buffer
  983.     push    h        ;save HL
  984. wscan2:
  985.     ldax    d        ;get char
  986.     cmp    m        ;compare
  987.     jnz    wscan3
  988.     inx    h        ;pt to next
  989.     inx    d
  990.     dcr    b        ;count down
  991.     jnz    wscan2
  992.     mov    e,m        ;get address in DE
  993.     inx    h
  994.     mov    d,m
  995.     pop    psw        ;clear stack
  996.     xra    a        ;return NZ
  997.     dcr    a
  998.     ret
  999. wscan3:
  1000.     pop    h        ;get address of current word in table
  1001.     lxi    d,wordl+2    ;advance to next word
  1002.     dad    d
  1003.     jmp    wscan1
  1004.  
  1005. ;
  1006. ; Push Address in NEXTCH onto Location Stack
  1007. ;
  1008. locpush:
  1009.     push    h    ;save regs
  1010.     push    d
  1011.     lhld    nextch    ;get address
  1012.     xchg        ;... in DE
  1013.     lhld    tos    ;get top of stack
  1014.     mov    m,e    ;store address
  1015.     inx    h
  1016.     mov    m,d
  1017.     inx    h
  1018.     shld    tos    ;new top of stack
  1019.     pop    d    ;restore regs
  1020.     pop    h
  1021.     ret
  1022. ;
  1023. ; Pop Address from Top of Stack
  1024. ;
  1025. locpop:
  1026.     lhld    locstk    ;local stack
  1027.     xchg
  1028.     lhld    tos    ;check to see if nothing on stack
  1029.     mov    a,e    ;if lows are same, nothing on stack
  1030.     cmp    l
  1031.     rz
  1032.     dcx    h    ;pt to top element
  1033.     mov    d,m    ;get high
  1034.     dcx    h
  1035.     mov    e,m    ;get low
  1036.     shld    tos    ;new top of stack
  1037.     xchg        ;address in HL
  1038.     xra    a    ;return with NZ
  1039.     dcr    a
  1040.     ret
  1041. ;
  1042. ; Skip to Non-Space
  1043. ;
  1044. sksp:
  1045.     mov    a,m    ;get char
  1046.     ani    7fh    ;mask
  1047.     call    issp    ;test for space
  1048.     rnz        ;not space, so return
  1049.     inx    h    ;pt to next
  1050.     jmp    sksp
  1051. ;
  1052. ; Test char in A for space char
  1053. ;   Ret with Z if yes
  1054. ;
  1055. issp:
  1056.     push    h    ;save HL
  1057.     push    b    ;save BC
  1058.     lxi    h,sptab    ;pt to table
  1059.     mov    b,a    ;char in B
  1060. issp1:
  1061.     mov    a,m    ;get next char
  1062.     ora    a    ;end of table?
  1063.     jz    issp3
  1064.     cmp    b    ;match?
  1065.     jz    issp2
  1066.     inx    h    ;pt to next
  1067.     jmp    issp1
  1068. issp2:
  1069.     mov    a,b    ;restore char
  1070.     pop    b    ;restore regs
  1071.     pop    h
  1072.     ret        ;Z flag is set
  1073. issp3:
  1074.     xra    a    ;set NZ
  1075.     dcr    a
  1076.     jmp    issp2
  1077. ;
  1078. ; Output New Line
  1079. ;
  1080. crlf:
  1081.     push    psw    ;save A
  1082.     mvi    a,cr    ;CR
  1083.     call    cout
  1084.     mvi    a,lf    ;LF
  1085.     call    cout
  1086.     pop    psw    ;get A
  1087.     ret
  1088. ;
  1089. ; Output Char in A with XON/XOFF Flow Control
  1090. ;
  1091. chout:
  1092.     push    psw    ;save char
  1093.     call    condin    ;conditional input
  1094.     jz    chout1
  1095.     cpi    ctrls    ;pause?
  1096.     jnz    chout1
  1097.     call    cin    ;wait for following char
  1098. chout1:
  1099.     pop    psw    ;get char
  1100.     push    b    ;save BC
  1101.     mov    c,a    ;char in C
  1102.     lda    outdev    ;get output device
  1103.     cpi    'C'    ;console?
  1104.     jz    chcon
  1105.     cpi    'L'    ;printer?
  1106.     jz    chlst
  1107.     cpi    'P'    ;punch?
  1108.     jz    chpun
  1109. ;
  1110. ; Output to Console
  1111. ;
  1112. chcon:
  1113.     mov    a,c    ;get char
  1114.     call    cout
  1115.     pop    b
  1116.     ret
  1117. ;
  1118. ; Output to List
  1119. ;
  1120. chlst:
  1121.     mov    a,c    ;get char
  1122.     call    lout
  1123.     pop    b
  1124.     ret
  1125. ;
  1126. ; Output to Punch
  1127. ;
  1128. chpun:
  1129.     mov    a,c    ;get char
  1130.     call    pout
  1131.     pop    b
  1132.     ret
  1133. ;
  1134. ; Print String Pted to by HL
  1135. ;
  1136. epstr:
  1137.     mov    a,m    ;get char
  1138.     inx    h    ;pt to next
  1139.     ani    7fh    ;mask MSB
  1140.     rz        ;done
  1141.     call    cout    ;print char
  1142.     jmp    epstr
  1143. ;
  1144. ; Print String at Return Address
  1145. ;
  1146. eprint:
  1147.     xthl        ;save HL and pt to string
  1148.     call    epstr    ;print string
  1149.     xthl        ;restore HL and new exec adr
  1150.     ret
  1151. ;
  1152. ; Input Char, Mask, and Capitalize
  1153. ;
  1154. capa:
  1155.     mov    a,m    ;get char
  1156.     ani    7fh    ;mask
  1157.     jmp    caps    ;capitalize
  1158.  
  1159. ;
  1160. ; Space Table
  1161. ;
  1162. sptab:
  1163.     db    ' ',tab,bs,ff,',','.',0    ;space chars
  1164.  
  1165. ;
  1166. ; Data Area
  1167. ;
  1168. defname:
  1169.     db    'STD     '    ;default file name
  1170. deftype:
  1171.     db    'DPG'        ;default file type
  1172. deffmt:
  1173.     db    '%C',0    ;default format string
  1174. supzero:
  1175.     db    0    ;zero suppress flag (set off)
  1176. outdev:
  1177.     ds    1    ;output device (C=console, L=list, P=punch)
  1178. outdev1:
  1179.     ds    1    ;save area for output device
  1180. wordbf:
  1181.     ds    wordl    ;current word buffer
  1182. endcmd:
  1183.     ds    2    ;address of end command line
  1184. format:
  1185.     ds    2    ;address of format string
  1186. free:
  1187.     ds    2    ;address of free area
  1188. words:
  1189.     ds    2    ;address of scratch area
  1190. nxtword:
  1191.     ds    2    ;pointer to next word
  1192. nextch:
  1193.     ds    2    ;pointer to next char
  1194. locstk:
  1195.     ds    2    ;pointer to location stack
  1196. tos:
  1197.     ds    2    ;pointer to top of stack
  1198.  
  1199.     end
  1200.