home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol201 / dprog.mqc / DPROG.MAC
Encoding:
Text File  |  1985-02-10  |  18.5 KB  |  1,125 lines

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