home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / zsys / simtel20 / zcpr3 / print.mac < prev    next >
Encoding:
Text File  |  1994-07-13  |  27.4 KB  |  1,404 lines

  1. ;
  2. ;  PROGRAM:  PRINT III (PRINT)
  3. ;  VERSION:  2.0
  4. ;  DATE:  18 May 84
  5. ;  AUTHOR:  RICHARD CONN
  6. ;  PREVIOUS VERSIONS:  1.3 (17 May 83)
  7. ;  PREVIOUS VERSIONS:  1.2 (26 Apr 83), 1.1 (26 Apr 83), 1.0 (22 Apr 83)
  8. ;
  9. VERS    equ    20
  10. z3env    SET    0f400h
  11.  
  12. FALSE    equ    0
  13. TRUE    equ    NOT FALSE
  14.  
  15. timeok    equ    FALSE    ;TRUE to enable TIME feature, FALSE to disable
  16.  
  17. ;
  18. ;    PRINT is THE file print utility for ZCPR3.  Installable by Z3INS,
  19. ; PRINT provides a wide range of options for the user.  First, PRINT allows
  20. ; the user to employ wild cards and file name lists (lists of files separated
  21. ; by commas, like: file1,file2,file3,...).  Second, PRINT provides the
  22. ; following options:
  23. ;        E    Exact Mode
  24. ;                No heading appears, no line numbering,
  25. ;                no page numbering, tab expansion, form
  26. ;                feeds
  27. ;        F    File Name Toggle
  28. ;                The Heading Line can optionally contain
  29. ;                the name of the file
  30. ;        H@head@    Heading Text
  31. ;                The user may specify the text of the heading
  32. ;                to appear at the top of every page
  33. ;        I    Inspect Files
  34. ;                The user approves each file to be printed
  35. ;                before the printing process begins
  36. ;        L    Toggle Line Numbering
  37. ;                Each line may or may not begin with a line
  38. ;                number
  39. ;        M    Multiple Runs Toggle
  40. ;                The user may or may not be prompted to set
  41. ;                the Top of Form on his printer; Multiple Runs
  42. ;                ON means that he will not be prompted
  43. ;        N    Toggle Page Numbering
  44. ;                The numbering of each page is turned on or
  45. ;                off
  46. ;        Onn    Offset Each Line
  47. ;                Move each line in the indicated number of
  48. ;                characters from the left
  49. ;        Snnnn    Skip to Specified Page
  50. ;                Printing begins on the indicated page
  51. ;        T    Toggle Time Display
  52. ;                Time/Date information is optionally included
  53. ;                in the page header
  54. ;
  55.  
  56. ;
  57. ;  BASIC SYSLIB ROUTINES NEEDED BY PRINT
  58. ;
  59. ESIZE    EQU    16    ; SIZE OF DIR ENTRY (FROM SYSLIB DIRF ROUTINE)
  60.  
  61.     EXT    DIRQS    ; DIRECTORY PROCESSOR
  62.     EXT    DIRPACK    ; PACK DIRECTORY
  63.  
  64.     EXT    Z3INIT    ; INIT BUFFERS
  65.     EXT    ZFNAME    ; FILE NAME PROCESSOR
  66.     EXT    Z3LOG    ; LOG INTO DIR
  67.     EXT    GETPRT    ; GET PRINTER DATA
  68.  
  69.     EXT    INITFCB    ; INIT FCB
  70.     EXT    RETUD    ; RETURN CURRENT USER/DISK
  71.     EXT    PUTUD    ; SAVE CURRENT USER/DISK
  72.     EXT    GETUD    ; RESTORE CURRENT USER/DISK
  73.     EXT    EPRINT    ; PRINT STRING PTED TO BY RET ADR
  74.     EXT    PADC    ; PRINT A IN DEC
  75.     EXT    COUT    ; CONSOLE OUTPUT ROUTINE
  76.     EXT    CONDIN    ; CONDITIONAL INPUT ROUTINE
  77.     EXT    CIN    ; CONSOLE INPUT ROUTINE
  78.     EXT    CAPS    ; CAPITALIZE ROUTINE
  79.     EXT    CRLF    ; NEW LINE ROUTINE
  80.     EXT    CLINE    ; COMMAND LINE STRING SAVE ROUTINE
  81.     EXT    CODEND    ; CODE END COMPUTATION ROUTINE
  82.  
  83.     EXT    F$OPEN    ; FILE OPEN
  84.     EXT    F$READ    ; BLOCK READ
  85.     EXT    F$CLOSE    ; FILE CLOSE
  86.  
  87.     EXT    EVAL10    ; STRING TO BINARY CONVERSION
  88.     EXT    LHLDC    ; LST: HL AS DEC OUTPUT
  89.     EXT    LPSTR    ; LST: (HL) STRING OUTPUT
  90.     EXT    LPRINT    ; LST: STRING OUTPUT
  91.     EXT    LCRLF    ; LST: NEW LINE
  92.     EXT    LOUT    ; LST: OUTPUT
  93.     EXT    MOVEB    ; MOVEB ROUTINE
  94.  
  95.     if    timeok
  96.     EXT    TIME    ; TIME Library Module Routine
  97.     endif
  98.  
  99. ;
  100. ;  CP/M EQUATES
  101. ;
  102. CPM    EQU    0    ; WARM BOOT
  103. BDOSE    EQU    CPM+5    ; BDOS ENTRY
  104. FCB    EQU    CPM+5CH    ; FCB
  105. TBUFF    EQU    CPM+80H    ; INPUT LINE BUFFER
  106. DEL    EQU    7FH    ; <DEL>
  107. CR    EQU    13    ; <CR>
  108. FF    EQU    12    ; <FF>
  109. LF    EQU    10    ; <LF>
  110. CTRLC    EQU    'C'-'@'    ; ^C
  111. CTRLG    EQU    'G'-'@'
  112. CTRLH    EQU    'H'-'@'
  113. CTRLI    EQU    'I'-'@'
  114. CTRLX    EQU    'X'-'@'
  115. CTRLZ    EQU    'Z'-'@'
  116.  
  117. ;
  118. ;  OTHER EQUATES
  119. ;
  120. EOLD    EQU    0FFH    ; END OF LOAD DELIMITER
  121.  
  122. ;
  123. ; Environment Definition
  124. ;
  125.     if    z3env ne 0
  126. ;
  127. ; External ZCPR3 Environment Descriptor
  128. ;
  129.     jmp    start
  130.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  131.     db    1    ;External Environment Descriptor
  132. z3eadr:
  133.     dw    z3env
  134. start:
  135.     lhld    z3eadr    ;pt to ZCPR3 environment
  136. ;
  137.     else
  138. ;
  139. ; Internal ZCPR3 Environment Descriptor
  140. ;
  141.     MACLIB    Z3BASE.LIB
  142.     MACLIB    SYSENV.LIB
  143. z3eadr:
  144.     jmp    start
  145.     SYSENV
  146. start:
  147.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  148.     endif
  149.  
  150. ;
  151. ; Start of Program -- Initialize ZCPR3 Environment
  152. ;
  153.     call    z3init    ;initialize the ZCPR3 Env and the VLIB Env
  154.     jmp    startp
  155. ;
  156. ; Special Buffer Area
  157. ;
  158. LWIDTH:
  159.     DB    0    ; WIDTH OF LINE
  160. LTPP:
  161.     DB    0    ; LINES OF TEXT PER PAGE
  162. LSPP:
  163.     DB    0    ; LINES TO SKIP PER PAGE
  164. LFF:
  165.     DB    0    ; FORM FEED FLAG (0=NO)
  166. ;
  167. ;  NOTE:  LTPP + LSPP + 2 (HEADER SIZE) = TOTAL LINES PER PAGE ON PRINTER
  168. ;
  169. DLNUMFL:
  170.     DB    0    ; LINE NUMBER FLAG (DEFAULT TO NO)
  171. DPNUMFL:
  172.     DB    0FFH    ; PAGE NUMBER FLAG (DEFAULT TO YES)
  173. DEXACT:
  174.     DB    0    ; EXACT PRINT FLAG (DEFAULT TO NO)
  175. DFNPFL:
  176.     DB    0FFH    ; FILE NAME PRINT FLAG (DEFAULT TO YES)
  177. DTIMEPFL:
  178.     DB    0FFH    ; TIME PRINT FLAG (DEFAULT TO YES)
  179. DMULTFL:
  180.     DB    0FFH    ; MULTIPLE RUN FLAG (DEFAULT TO YES)
  181. DINSPECT:
  182.     DB    0    ; INSPECT FILES (DEFAULT TO NO)
  183. DOFFSET:
  184.     DB    0    ; INITIAL COLUMN OFFSET (DEFAULT TO NO COLUMNS)
  185. ;
  186. ;  OTHER BUFFERS
  187. ;
  188. SKIPFL:
  189.     DB    0    ; SKIP FLAG (DEFAULT TO NO)
  190. SKIPNUM:
  191.     DS    2    ; PAGE NUMBER TO SKIP TO
  192. LNUM:
  193.     DS    2    ; CURRENT LINE NUMBER
  194. PNUM:
  195.     DS    2    ; CURRENT PAGE NUMBER
  196. HBUF:
  197.     DS    2    ; PTR TO BUFFER FOR HEADING
  198. ;
  199.     if    timeok
  200. TIMEBF:
  201.     DS    2    ; PTR TO BUFFER FOR TIME STAMP
  202.     endif
  203. ;
  204. LNUMFL:
  205.     DB    0    ; LINE NUMBER FLAG (DEFAULT TO NO)
  206. PNUMFL:
  207.     DB    0FFH    ; PAGE NUMBER FLAG (DEFAULT TO YES)
  208. EXACT:
  209.     DB    0    ; EXACT PRINT FLAG (DEFAULT TO NO)
  210. FNPFL:
  211.     DB    0FFH    ; FILE NAME PRINT FLAG (DEFAULT TO YES)
  212. TIMEPFL:
  213.     DB    0FFH    ; TIME PRINT FLAG (DEFAULT TO YES)
  214. MULTFL:
  215.     DB    0FFH    ; MULTIPLE RUN FLAG (DEFAULT TO YES)
  216. INSPECT:
  217.     DB    0    ; INSPECT FILES (DEFAULT TO NO)
  218. OFFSET:
  219.     DB    0    ; OFFSET ON PAGE
  220.  
  221. ;
  222. ;  Start of Program
  223. ;
  224. STARTP:
  225.     LXI    H,0    ; GET STACK PTR
  226.     DAD    SP
  227.     SHLD    STACK    ; SAVE IT
  228.     CALL    CODEND    ; DETERMINE FREE SPACE
  229.     SHLD    CMDLNE    ; SAVE PTR TO COMMAND LINE
  230.     LXI    D,100H    ; BUFFER SIZE
  231.     DAD    D
  232.     SHLD    HBUF    ; BUFFER FOR HEADING
  233. ;
  234.     IF    TIMEOK
  235.     DAD    D
  236.     SHLD    TIMEBF    ; BUFFER FOR TIME DATA
  237.     ENDIF
  238. ;
  239.     DAD    D
  240.     SHLD    DIRBUF    ; PTR TO DIR BUFFER
  241.     SPHL        ; SET TOP OF STACK
  242.  
  243.     CALL    PUTUD    ; SAVE CURRENT USER/DISK AWAY
  244.  
  245.     CALL    GETPRT    ; GET PRINTER DATA
  246.     MOV    A,M    ; GET PRINTER WIDTH
  247.     STA    LWIDTH
  248.     INX    H
  249.     INX    H
  250.     MOV    A,M    ; GET NUMBER OF LINES OF TEXT
  251.     STA    LTPP
  252.     MOV    B,A    ; ... IN B
  253.     DCX    H
  254.     MOV    A,M    ; GET NUMBER OF LINES ON PAGE
  255.     SUI    2
  256.     SUB    B    ; ADJUST FOR PAGING DATA
  257.     STA    LSPP    ; NUMBER OF LINES TO SKIP PER PAGE
  258.     INX    H
  259.     INX    H
  260.     MOV    A,M    ; GET FORM FEED FLAG
  261.     STA    LFF
  262.  
  263.     LHLD    CMDLNE    ; PT TO COMMAND LINE SAVE AREA
  264.     LXI    D,TBUFF+1    ; SAVE COMMAND LINE
  265.     XCHG
  266.     MVI    B,80H    ; SIZE OF BUFFER
  267.     CALL    MOVEB
  268.  
  269. ;
  270. ;  **** Banner of Program
  271. ;
  272.     CALL    EPRINT
  273.     DB    'PRINT III,  Version '
  274.     DB    VERS/10+'0','.',(VERS MOD 10)+'0',0
  275.  
  276. ;
  277. ;  Check for Help Request
  278. ;
  279.     LDA    FCB+1    ; GET FIRST CHAR OF FILE NAME
  280.     CPI    ' '    ; NO FILE SPEC?
  281.     JZ    HELP
  282.     CPI    '/'    ; OPTION CAUGHT?
  283.     JNZ    ECONT
  284.  
  285. ;
  286. ;  **** Print Help Information
  287. ;
  288. HELP:
  289.     CALL    EPRINT
  290.     db    cr,lf,'   PRINT file1,file2,...,filen o...'
  291.     DB    cr,lf,'Options:'
  292.     db    cr,lf,' E       Exact Print (expand tabs, form feed, no line'
  293.     db    cr,lf,'           or page numbers, no heading)'
  294.     db    cr,lf,' F       Toggle File Name Display'
  295.     db    cr,lf,' H@head@ Specify Page Heading (@ is any printing char)'
  296.     db    cr,lf,' I       Inspect and Select Files First'
  297.     db    cr,lf,' L       Toggle Numbering of Each Line'
  298.     db    cr,lf,' M       Toggle Multiple Runs (MR=No TOF Msg)'
  299.     db    cr,lf,' N       Toggle Numbering of Each Page'
  300.     db    cr,lf,' Onn     Offset Printout by nn Characters from Left'
  301.     db    cr,lf,' Snnnn   Skip to Specified Page before Printing'
  302. ;
  303.     if    timeok
  304.     db    cr,lf,' T       Toggle Time Display in header'
  305.     endif
  306. ;
  307.     db    cr,lf,'Examples:'
  308.     db    cr,lf,'   PRINT MYFILE.TXT,*.MAC LH''SAMPLE'''
  309.     db    cr,lf,'        -- Number Lines, SAMPLE is Heading'
  310.     db    cr,lf,'   PRINT MYFILE.* S25E'
  311.     db    cr,lf,'     -- Skip to Page 25, Exact Print'
  312.     db    cr,lf,'At any time, ^C aborts PRINT and ^X skips to next '
  313.     db    'file'
  314.     DB    0
  315.  
  316. ;
  317. ;  RETURN TO OS
  318. ;
  319. RETURN:
  320.     LHLD    STACK    ; GET OLD STACK
  321.     SPHL        ; SET IT
  322.     RET
  323.  
  324. ;
  325. ;  PROGRAM'S INIT ROUTINE
  326. ;
  327. ECONT:
  328.     CALL    INIT    ; PROG INIT ROUTINE
  329. ;
  330. ;  EXTRACT FLAGS IF PRESENT
  331. ;
  332.     LHLD    CMDLNE    ; PT TO BUFFER
  333. ;
  334. ;  SKIP TO FILE NAME STRING
  335. ;
  336.     CALL    SBLANK    ; SKIP OVER BLANKS
  337. ;
  338. ;  SKIP TO END OF FILE NAME STRING
  339. ;
  340.     CALL    SNBLANK    ; SKIP OVER NON-BLANKS
  341. ;
  342. ;  SKIP TO OPTION CHAR
  343. ;
  344.     CALL    SBLANK
  345. ;
  346. ;  CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO
  347. ;
  348. OPT:
  349.     CPI    '/'    ; OPTION CHAR?
  350.     JNZ    OPTION
  351.     INX    H    ; SKIP SLASH
  352. ;
  353. ;  PROCESS LIST OF OPTIONS
  354. ;
  355. OPTION:
  356.     MOV    A,M    ; GET BYTE
  357.     ORA    A    ; DONE?
  358.     JZ    DSPEC
  359.     INX    H    ; PT TO NEXT CHAR
  360.     CPI    ' '    ; SKIP OVER SPACES
  361.     JZ    OPTION
  362.     MOV    C,A    ; COMMAND IN C
  363.     LXI    D,OPTAB    ; PT TO OPTION TABLE
  364. OPTL:
  365.     LDAX    D    ; GET OPTION LETTER
  366.     ORA    A    ; END OF TABLE?
  367.     JZ    HELP    ; HELP IF SO
  368.     CMP    C    ; MATCH?
  369.     JZ    OPTM    ; PROCESS IF SO
  370.     INX    D    ; PT TO NEXT ENTRY
  371.     INX    D
  372.     INX    D
  373.     JMP    OPTL
  374. ;
  375. ;  PROCESS OPTION
  376. ;
  377. OPTM:
  378.     PUSH    H    ; SAVE HL ON STACK
  379.     LXI    H,OPTION    ; GET RETURN ADDRESS
  380.     XTHL        ; ... ON STACK AND RESTORE HL
  381.     INX    D    ; PT TO ADDRESS
  382.     LDAX    D    ; GET ADDRESS LOW
  383.     MOV    B,A    ; ... IN B
  384.     INX    D
  385.     LDAX    D    ; GET ADDRESS HIGH
  386.     MOV    D,A    ; ... IN D
  387.     MOV    E,B    ; LOW IN E
  388.     PUSH    D    ; PUT ADDRESS ON STACK
  389.     MOV    A,C    ; COMMAND IN A
  390.     RET        ; "CALL" OPTION ROUTINE
  391.  
  392. ;
  393. ;  **** PROGRAM INIT ROUTINE
  394. ;    THIS ROUTINE IS USED BY THE PROGRAM TO PERFORM ANY INITS
  395. ;
  396. INIT:
  397.     lxi    h,dlnumfl    ;copy defaults into buffers
  398.     lxi    d,lnumfl
  399.     mvi    b,8        ;8 bytes
  400.     call    moveb        ;do copy
  401.     xra    a    ;A=0
  402.     sta    skipfl    ;set no skip
  403.     push    h
  404.     lhld    hbuf    ;pt to heading
  405.     mov    m,a    ;set no heading
  406.     pop    h
  407. ;
  408.     if    timeok
  409.     call    time    ;get time string
  410.     xchg
  411.     lhld    timebf    ;store in buffer
  412.     xchg
  413. initt:
  414.     mov    a,m    ;get byte
  415.     stax    d    ;put byte
  416.     inx    h    ;pt to next
  417.     inx    d
  418.     ora    a    ;done?
  419.     jnz    initt
  420.     endif
  421. ;
  422.     RET
  423.  
  424. ;
  425. ;  **** OPTION TABLE
  426. ;    EACH OPTION IS A CAPITAL LETTER OR SPECIAL CHAR FOLLOWED BY
  427. ;        AN ADDRESS; THE TABLE IS TERMINATED BY A BINARY ZERO
  428. ;
  429. OPTAB:
  430.     db    'E'
  431.     dw    optexact
  432.     db    'F'
  433.     dw    optfn
  434.     db    'H'
  435.     dw    opthd
  436.     db    'I'
  437.     dw    optinsp
  438.     db    'L'
  439.     dw    optln
  440.     db    'M'
  441.     dw    optmult
  442.     db    'N'
  443.     dw    optpn
  444.     db    'O'
  445.     dw    optoffs
  446.     db    'S'
  447.     dw    optskip
  448. ;
  449.     if    timeok
  450.     db    'T'
  451.     dw    opttime
  452.     endif
  453. ;
  454.     DB    0    ; END OF TABLE
  455. ;
  456. ;  Option:  E (Toggle exact mode)
  457. ;
  458. optexact:
  459.     lda    exact    ;get flag
  460.     cma        ;flip it
  461.     sta    exact    ;put flag
  462.     ret
  463. ;
  464. ;  Option:  F (Toggle file name display)
  465. ;
  466. optfn:
  467.     lda    fnpfl    ;get flag
  468.     cma        ;flip it
  469.     sta    fnpfl    ;put flag
  470.     ret
  471. ;
  472. ;  Option:  H (Set Heading)
  473. ;
  474. opthd:
  475.     xchg
  476.     lhld    hbuf    ;pt to heading buffer
  477.     xchg
  478.     mov    a,m    ;get delim
  479.     ora    a    ;none?
  480.     rz
  481.     mov    b,a    ;delim in B
  482.     inx    h    ;pt to next char
  483. opthd1:
  484.     mov    a,m    ;get next char
  485.     ora    a    ;done?
  486.     jz    opthd3
  487.     cmp    b    ;done by trailing delim?
  488.     jz    opthd2
  489.     stax    d    ;save char
  490.     inx    h    ;pt to next
  491.     inx    d
  492.     jmp    opthd1
  493. opthd2:
  494.     inx    h    ;skip over delim
  495. opthd3:
  496.     xra    a    ;store ending 0
  497.     stax    d
  498.     ret
  499. ;
  500. ;  Toggle Inspect Option
  501. ;
  502. optinsp:
  503.     lda    inspect    ;flip flag
  504.     cma
  505.     sta    inspect
  506.     ret
  507. ;
  508. ;  Set Line Number Flag
  509. ;
  510. optln:
  511.     lda    lnumfl    ;flip flag
  512.     cma
  513.     sta    lnumfl
  514.     ret
  515. ;
  516. ;  Set Multiple Run Flag
  517. ;
  518. optmult:
  519.     lda    multfl    ;flip flag
  520.     cma
  521.     sta    multfl
  522.     ret
  523. ;
  524. ;  Set Page Numbering Flag
  525. ;
  526. optpn:
  527.     lda    pnumfl    ;flip flag
  528.     cma
  529.     sta    pnumfl
  530.     ret
  531. ;
  532. ;  Set Page Offset
  533. ;
  534. optoffs:
  535.     call    eval10    ;get number
  536.     mov    a,e    ;get low-order byte
  537.     sta    offset    ;set offset
  538.     ret
  539. ;
  540. ;  Set Skip Flag and get number
  541. ;
  542. optskip:
  543.     mvi    a,0ffh    ;set flag
  544.     sta    skipfl
  545.     call    eval10    ;get number
  546.     xchg
  547.     shld    skipnum    ;set page number to skip to
  548.     xchg        ;HL pts to next char
  549.     mov    a,d    ;see if page number was zero
  550.     ora    e
  551.     rnz
  552.     xra    a    ;if zero, just turn off skip flag
  553.     sta    skipfl
  554.     ret
  555. ;
  556.     if    timeok
  557. ;
  558. ;  Set Time Flag
  559. ;
  560. opttime:
  561.     lda    timepfl    ;flip flag
  562.     cma
  563.     sta    timepfl
  564.     ret
  565. ;
  566.     endif
  567. ;
  568. ;  BEGIN MOVING THROUGH FILE NAMES, SEPARATED BY COMMAS
  569. ;
  570. DSPEC:
  571.     LHLD    CMDLNE    ; PT TO FIRST BYTE
  572.     CALL    SBLANK    ; SKIP TO NON-BLANK
  573. ;
  574. ;  MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS
  575. ;    HL PTS TO FIRST BYTE OF NEXT FILE SPEC
  576. ;
  577. DSPEC1:
  578.     SHLD    NEXTCH    ; SAVE PTR TO NEXT CHAR
  579.     LHLD    DIRBUF    ; RESET STACK
  580.     SPHL
  581.     CALL    GETUD    ; RESET USER IF NECESSARY
  582.     LXI    D,FCB    ; PT TO FCB IN DE, PT TO FIRST CHAR OF FILE NAME IN HL
  583.     MVI    A,0    ; SELECT DIR BEFORE DU
  584.     LHLD    NEXTCH    ; GET PTR TO NEXT CHAR
  585.     CALL    ZFNAME    ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER
  586.     SHLD    NEXTCH    ; SAVE PTR TO DELIMITER WHICH ENDED SCAN
  587.  
  588. ;
  589. ;  LOAD DIRECTORY AND PERFORM FUNCTION
  590. ;
  591. FCT:
  592.     LXI    D,FCB    ; PT TO FCB
  593.     CALL    Z3LOG    ; LOG INTO IT
  594.     LXI    D,FCB    ; PT TO FCB
  595.     CALL    INITFCB    ; INIT THE FCB
  596.     LHLD    DIRBUF    ; PT TO DIR BUFFER AREA
  597.     MVI    A,11000000B    ; SELECT SYS AND NON-SYS FILES
  598.     CALL    DIRQS    ; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE
  599. ;
  600. ;  DETERMINE BEGINNING OF SCRATCH AREA (SCRATCH) AND SIZE IN PAGES (BCNT)
  601. ;
  602.     PUSH    H    ; SAVE PTR AND COUNT
  603.     PUSH    B
  604.     LXI    D,ESIZE    ; SET PTR TO NEXT FREE BLOCK
  605. FCTFRE:
  606.     MOV    A,B    ; DONE?
  607.     ORA    C
  608.     JZ    FCTFR1
  609.     DAD    D    ; PT TO NEXT
  610.     DCX    B    ; COUNT DOWN
  611.     JMP    FCTFRE
  612. FCTFR1:
  613.     INR    H    ; NEXT PAGE
  614.     MVI    L,0
  615.     SHLD    SCRATCH    ; SET PTR TO SCRATCH AREA
  616.     XCHG        ; PTR IN DE
  617.     LHLD    BDOSE+1    ; COMPUTE BLOCK BUFFER SIZE
  618.     MOV    A,H    ; ADJUST FOR ZCPR3
  619.     SUI    10
  620.     SUB    D    ; A=SIZE IN BLOCKS
  621.     STA    BCNT    ; SET BLOCK COUNT
  622.     POP    B    ; RESTORE AND SAVE REGS
  623.     POP    H
  624. ;
  625. ;  ALLOW USER TO INSPECT FILES
  626. ;
  627.     PUSH    H
  628.     PUSH    B
  629.     CALL    ICHECK    ; CHECK FOR INSPECT OPTION AND INSPECT IF SET
  630.     POP    B    ; RESTORE COUNT AND PTR
  631.     POP    H
  632.  
  633. ;
  634. ;  PERFORM FUNCTION; HL PTS TO FILE AND BC CONTAINS NUMBER OF FILES
  635. ;
  636. FCTL:
  637.     MOV    A,B        ; CHECK FOR COMPLETION (COUNT = 0)
  638.     ORA    C
  639.     JZ    FCTL1
  640.     DCX    B        ; COUNT DOWN
  641.     SHLD    NFPTR
  642.     MOV    H,B
  643.     MOV    L,C
  644.     SHLD    NFCNT
  645.     LHLD    NFPTR        ; PT TO FILE
  646.     CALL    FUNCTION    ; PERFORM FUNCTION
  647. FCTLNXT:
  648.     LHLD    DIRBUF        ; RESET STACK
  649.     SPHL
  650.     LHLD    NFCNT        ; RESET FILE COUNT
  651.     MOV    B,H
  652.     MOV    C,L
  653.     LHLD    NFPTR        ; RESET FILE PTR
  654.     LXI    D,ESIZE        ; PT TO NEXT ENTRY
  655.     DAD    D
  656.     JMP    FCTL
  657.  
  658. ;
  659. ;  CHECK FOR NEXT FILE SPEC
  660. ;
  661. FCTL1:
  662.     CALL    GETUD    ; RETURN TO HOME USER/DISK
  663.     LHLD    NEXTCH    ; GET PTR
  664.     MOV    A,M    ; GET DELIM
  665.     CPI    ','    ; ANOTHER FILE?
  666.     JNZ    DRETURN
  667.     INX    H    ; PT TO CHAR AFTER COMMA
  668.     JMP    DSPEC1    ; CONTINUE PROCESSING
  669.  
  670. ;
  671. ;  **** EMERGENCY ABORT
  672. ;
  673. ABORT:
  674.     CALL    EPRINT
  675.     DB    CR,LF,'** PRINT Abort **',CR,LF,0
  676.     CALL    GETUD    ; RETURN HOME AND FALL THRU TO DRETURN
  677. ;
  678. ;  **** FUNCTION COMPLETE -- CLEANUP AND EXIT
  679. ;    FILL THIS IN WITH CLEANUP CODE FOR EXIT
  680. ;
  681. DRETURN:
  682.     JMP    RETURN
  683.  
  684. ;
  685. ;  **** INSPECT FILES -- THIS ROUTINE IS TO PERFORM A FILE INSPECTION
  686. ;    ON INPUT, HL PTS TO FIRST 16-BYTE ENTRY AND BC=NUMBER OF ENTRIES
  687. ;
  688. ICHECK:
  689.     mov    a,b    ;any files?
  690.     ora    c
  691.     rz
  692.     push    h    ;save ptrs
  693.     push    b
  694.     lxi    d,esize    ;size of entry
  695. ichk1:
  696.     mvi    m,0    ;clear MSBytes
  697.     dad    d    ;pt to next
  698.     dcx    b    ;count down
  699.     mov    a,b    ;done?
  700.     ora    c
  701.     jnz    ichk1
  702.     pop    b    ;restore ptrs
  703.     pop    h
  704.     lda    inspect    ;inspect?
  705.     ora    a    ;0=no
  706.     rz
  707.     call    eprint
  708.     db    cr,lf,'--- PRINT File Inspect Mode ---'
  709.     db    cr,lf,'  Option  Function'
  710.     db    cr,lf,'  Y (def) Select File'
  711.     db    cr,lf,'     N    Don''t Select File'
  712.     db    cr,lf,'     Q    Select Rest of Files'
  713.     db    cr,lf,'     S    Skip Rest of Files'
  714.     db    cr,lf,0
  715. ichk2:
  716.     call    eprint
  717.     db    cr,lf,'Select ',0
  718.     call    prfn    ;print file name
  719.     call    eprint
  720.     db    ' -- (Y/N/Q/S)? ',0
  721.     call    cin    ;get response
  722.     call    caps    ;capitalize
  723.     call    cout    ;echo
  724.     cpi    'Q'    ;select rest?
  725.     jz    ichkyr
  726.     cpi    'S'    ;skip rest
  727.     jz    ichknr
  728.     cpi    'N'    ;no to this one?
  729.     jnz    ichk3
  730.     mvi    m,0ffh    ;set NO flag in file FCB
  731. ichk3:
  732.     dad    d    ;pt to next one
  733.     dcx    b    ;count down
  734.     mov    a,b    ;done?
  735.     ora    c
  736.     jnz    ichk2
  737.     RET
  738. ;  Check Rest of Files as Selected
  739. ichkyr:
  740.     call    eprint
  741.     db    cr,lf,' Rest of Files Selected',0
  742.     ret
  743. ;  Check Rest of Files as NOT Selected
  744. ichknr:
  745.     mvi    m,0ffh    ;set NO flag
  746.     dad    d    ;pt to next
  747.     dcx    b    ;count down
  748.     mov    a,b    ;done?
  749.     ora    c
  750.     jnz    ichknr
  751.     call    eprint
  752.     db    cr,lf,' Rest of Files NOT Selected',0
  753.     ret
  754. ;
  755. ;  **** FUNCTION -- MAIN FUNCTION OF TEMPLATE
  756. ;    ON ENTRY, HL PTS TO NAME OF FILE (16 BYTES) AND USER IS LOGGED INTO
  757. ;        DIRECTORY CONTAINING INDICATED FILE
  758. ;
  759. FUNCTION:
  760. ;
  761. ;  FILE PRINT Routine -- Print the File Whose Name is Pointed to by
  762. ;    HL; we are already logged into the correct directory
  763. ;
  764.     mov    a,m    ;file selected?
  765.     ora    a    ;0=yes
  766.     rnz
  767.     lda    multfl    ;multiple runs?
  768.     ora    a    ;0=no
  769.     jnz    fprint    ;go right into function
  770.     call    eprint
  771.     db    cr,lf,'File: ',0
  772.     call    prfn    ;print file name
  773.     call    eprint
  774.     db    ' -- Set Top of Form ',0
  775.     call    cin    ;get response
  776.     cpi    ctrlc    ;abort?
  777.     jz    abort
  778.     cpi    ctrlx
  779.     rz
  780. fprint:
  781.     call    prinit    ;init print buffers
  782.     call    fload    ;load buffer initially
  783.     call    prhead    ;print heading line
  784.     lhld    scratch    ;pt to first char in file
  785.     shld    nxtln    ;set pointer to next line
  786. fprloop:
  787.     call    prline    ;print line of file
  788.     jnz    fprloop    ;done if EOF
  789.     lda    ltpp    ;check for new page
  790.     mov    b,a
  791.     lda    lcount    ;LTPP and Line Count are Equal if New Page
  792.     cmp    b    ;equal?
  793.     jnz    fprlp1
  794.     call    lcrlf    ;advance 2 lines
  795.     call    lcrlf
  796. fprlp1:
  797.     call    page    ;advance to top of next page
  798.     ret
  799. ;
  800. ;  Init Print Buffers and Print File Name
  801. ;
  802. prinit:
  803.     lxi    d,tfcb    ;set up FCB
  804.     mvi    b,12    ;12 bytes
  805.     call    moveb
  806.     lxi    h,0    ;HL=0
  807.     shld    lnum    ;set line number
  808.     inx    h    ;HL=1
  809.     shld    pnum    ;set page number
  810.     lda    ltpp    ;set line count
  811.     sta    lcount
  812.     call    eprint
  813.     db    cr,lf,'Printing File ',0
  814.     lxi    h,tfcb    ;pt to FCB
  815.     call    prfn    ;print file name
  816.     ret
  817. ;
  818. ;  FILE LOAD (FLOAD) Routine -- Initial Load of memory buffer
  819. ;
  820. fload:
  821.     lxi    d,tfcb    ;pt to file fcb
  822.     call    initfcb    ;init file's fcb
  823.     call    f$open    ;open file for input
  824.     jz    fload1    ;open was OK
  825.     call    eprint
  826.     db    cr,lf,'File ',0
  827.     xchg        ;HL pts to FCB
  828.     call    prfn    ;print file name
  829.     call    eprint
  830.     db    ' NOT Found',0
  831.     pop    d    ;clear return address
  832.     ret        ;abort printout of this file
  833. ;
  834. ;  This is an entry point for further memory loads of the file
  835. ;
  836. fload1:
  837.     lda    bcnt    ;get number of blocks to load
  838.     mov    c,a    ;... in C
  839.     lhld    scratch    ;get address of first block to load into
  840.     shld    nxtblk    ;set pointer to next block to load
  841. fload2:
  842.     call    rdblk    ;read a block (128 bytes)
  843.     jnz    eof    ;eof encountered?
  844.     call    rdblk    ;read another block (128 bytes)
  845.     jnz    eof    ;eof encountered?
  846.     dcr    c    ;count down
  847.     jnz    fload2
  848.     lhld    nxtblk    ;pt to next byte to load
  849.     mvi    m,eold    ;mark end of load
  850.     ret
  851. eof:
  852.     lxi    d,tfcb    ;close file
  853.     call    f$close
  854.     lhld    nxtblk    ;ensure ^Z
  855.     mvi    m,ctrlz
  856.     ret
  857. rdblk:
  858.     lxi    d,tfcb    ;pt to FCB
  859.     call    f$read    ;read next block
  860.     ora    a    ;error?
  861.     rnz
  862.     lhld    nxtblk    ;get ptr to next block
  863.     xchg        ; as dest
  864.     lxi    h,tbuff    ;ptr to DMA address
  865.     mvi    b,128    ;copy 128 bytes
  866. rdblk1:
  867.     mov    a,m    ;get byte
  868.     ani    7fh    ;mask out msb
  869.     stax    d    ;put byte
  870.     inx    h    ;pt to next
  871.     inx    d
  872.     dcr    b    ;count down
  873.     jnz    rdblk1
  874.     xchg        ;new nxtblock
  875.     shld    nxtblk
  876.     ret
  877.  
  878. ;
  879. ;  Line Print Routine
  880. ;    Print Next Line with Optional Disk Load
  881. ;    Input Parameter is NXTLN, which is the address of the first char
  882. ; on the next line
  883. ;    Output Parameter is Zero Flag, with Z meaning done with print, NZ
  884. ; meaning more yet to print
  885. ;
  886. prline:
  887.     call    proffs    ;print offset
  888.     lhld    lnum    ;increment line number
  889.     inx    h
  890.     shld    lnum
  891.     lhld    nxtln    ;pt to first char of next line
  892.     mvi    c,0    ;init char count
  893.     mov    a,m    ;get first char of line
  894.     cpi    ctrlz    ;EOF?
  895.     cnz    prlnum    ;print line number (optional)
  896. prl1:
  897.     mov    a,m    ;get char
  898.     cpi    eold    ;end of load?
  899.     jz    prload
  900.     cpi    ctrlz    ;eof?
  901.     jz    prexit
  902.     inx    h    ;pt to next char
  903.     cpi    ctrli    ;tab?
  904.     jz    prtab
  905.     cpi    cr    ;<CR>?
  906.     jz    prcr
  907.     cpi    ff    ;form feed?
  908.     jz    prff
  909.     cpi    lf    ;end of line?
  910.     jz    prldn
  911.     cpi    ctrlh    ;back space?
  912.     jz    prbs
  913.     cpi    ctrlg    ;ring bell?
  914.     jz    prbell
  915.     cpi    del    ;delete char?
  916.     jz    prl1    ;skip it
  917.     cpi    ' '    ;other control char?
  918.     jc    prl1    ;skip if other control char
  919.     call    prout    ;print char
  920.     inr    c    ;increment char count
  921.     call    eoltest    ;check to see if at end of line and newline if so
  922.     jmp    prl1
  923. ;
  924. ;  End of Load Reached -- Load More of File from Disk
  925. ;
  926. prload:
  927.     push    b    ;save char count
  928.     call    fload1    ;use load routine
  929.     pop    b    ;get char count
  930.     lhld    scratch    ;next byte is here
  931.     jmp    prl1    ;continue processing
  932. ;
  933. ;  Tabulate
  934. ;
  935. prtab:
  936.     mvi    a,' '    ;space
  937.     call    prout
  938.     inr    c    ;new char
  939.     call    eoltest    ;process EOL
  940.     mov    a,c    ;done?
  941.     ani    7
  942.     jnz    prtab    ;continue tabulation
  943.     jmp    prl1    ;continue processing
  944. ;
  945. ;  Exit with Zero Flag Set if Done
  946. ;
  947. prexit:
  948.     xra    a    ;set zero flag
  949.     ret
  950. ;
  951. ;  Carriage Return -- Reset Character Count and Continue
  952. ;
  953. prcr:
  954.     call    prout    ;send CR to printer
  955.     mvi    c,0    ;reset char count
  956.     jmp    prl1    ;continue processing
  957. ;
  958. ;  Form Feed -- Advance to Top of Next Page
  959. ;
  960. prff:
  961.     call    page    ;page eject with heading
  962.     mvi    c,0    ;reset char count
  963.     jmp    prl1    ;continue processing
  964. ;
  965. ;  Line Feed -- End of Routine
  966. ;
  967. prldn:
  968.     call    prout    ;echo LF to printer
  969.     shld    nxtln    ;set ptr to first char of next line
  970.     mvi    a,0ffh    ;set not done
  971.     ora    a    ;set flags
  972.     ret
  973. ;
  974. ;  Backspace on Printer
  975. ;
  976. prbs:
  977.     mov    a,c    ;check for beginning of line
  978.     ora    a
  979.     jz    prl1    ;continue if at BOL
  980.     mvi    a,ctrlh    ;backspace
  981.     call    prout
  982.     dcr    c    ;back up char position
  983.     jmp    prl1    ;continue
  984. ;
  985. ;  Ring Bell on Printer
  986. ;
  987. prbell:
  988.     call    prout    ;ring the bell
  989.     jmp    prl1    ;continue without advancing char position
  990. ;
  991. ;  Test for End of Line and Process if so
  992. ;
  993. eoltest:
  994.     lda    offset    ;get offset
  995.     mov    b,a    ;... in B
  996.     lda    lwidth    ;get line width
  997.     sub    b    ;compute remaining width
  998.     sui    4    ;4 chars less for continuation mark
  999.     mov    b,a    ;result in B
  1000.     lda    lnumfl    ;line numbering (lines are 7 chars shorter if so)
  1001.     ora    a    ;0=no
  1002.     jz    eolt1
  1003.     mov    a,b    ;reduce by 7 for line numbers
  1004.     sui    7
  1005.     mov    b,a
  1006. eolt1:
  1007.     mov    a,b    ;get line width
  1008.     cmp    c    ;there?
  1009.     rnz        ;continue if not
  1010.     mov    a,m    ;get next char
  1011.     cpi    cr    ;new line next?
  1012.     rz        ;continue if so
  1013.     mvi    b,3    ;see if CR is one of next 3 chars
  1014.     push    h
  1015. eolt2:
  1016.     inx    h    ;pt to next
  1017.     mov    a,m    ;get char
  1018.     cpi    cr
  1019.     jz    eolt2a    ;yes, it is
  1020.     dcr    b    ;count down
  1021.     jnz    eolt2
  1022.     pop    h    ;restore HL
  1023.     jmp    eolt3
  1024. eolt2a:
  1025.     pop    h    ;restore HL
  1026.     ret        ;allow to continue
  1027. eolt3:
  1028.     cpi    ctrlh    ;backspace next?
  1029.     rz        ;continue if so
  1030.     mvi    a,' '    ;print continuation chars
  1031.     call    prout
  1032.     mvi    a,'<'
  1033.     call    prout
  1034.     mvi    a,'<'
  1035.     call    prout
  1036.     mvi    a,cr    ;new line
  1037.     call    prout
  1038.     mvi    a,lf
  1039.     call    prout
  1040.     mvi    c,0    ;reset char position
  1041.     lda    skipfl    ;skipping?
  1042.     ora    a    ;0=no
  1043.     rnz
  1044.     call    proffs    ;print offset if any
  1045.     lda    lnumfl    ;printing line numbers?
  1046.     ora    a    ;0=no
  1047.     rz
  1048.     call    lprint    ;print blank for line number
  1049.     db    '     : ',0
  1050.     ret
  1051. ;
  1052. ;  Output a character to the printer
  1053. ;    A = Character
  1054. ;
  1055. prout:
  1056.     mov    b,a    ;char in B
  1057.     call    condin    ;check for abort
  1058.     jz    prout1
  1059.     cpi    ctrlc    ;abort?
  1060.     jz    abort
  1061.     cpi    ctrlx    ;abort this one file?
  1062.     jz    cxabort
  1063. prout1:
  1064.     lda    skipfl    ;skipping?
  1065.     ora    a    ;set flags (Z=no skip=print char)
  1066.     mov    a,b    ;restore char
  1067.     cz    lout    ;send character to printer
  1068.     cpi    lf    ;special tests if it is a line feed
  1069.     rnz        ;done if non-LF char
  1070.     lda    lcount    ;decrement line counter
  1071.     dcr    a
  1072.     sta    lcount
  1073.     rnz
  1074. ;
  1075. ;  Paging Required
  1076. ;    Skip to top of next page; reset LCOUNT (Lines Left on Page Count);
  1077. ;    print header
  1078. ;
  1079. prout0:
  1080.     lda    ltpp    ;get number of text lines per page
  1081.     sta    lcount    ;set as new line count
  1082.     push    h    ;save ptr
  1083.     lhld    pnum    ;increment page number
  1084.     inx    h
  1085.     shld    pnum
  1086.     lda    lspp    ;get number of lines to skip per page
  1087.     call    lineskp    ;skip lines
  1088.     pop    h    ;restore ptr
  1089.     mov    a,m    ;check next character
  1090.     cpi    ctrlz    ;EOF?
  1091.     jnz    prhead    ;print 2-line heading if NOT EOF
  1092.     ret
  1093. ;
  1094. ;  Abort current file with final page eject
  1095. ;
  1096. cxabort:
  1097.     lda    lcount    ;get count of remaining lines
  1098.     call    lineskp    ;skip lines
  1099.     lda    lff    ;form feed done?
  1100.     ora    a    ;0=no
  1101.     lda    lspp    ;number of lines to skip per page
  1102.     cz    lineskp    ;skip lines if no previous FF
  1103.     jmp    fctlnxt    ;continue with next file
  1104. ;
  1105. ;  Skip out rest of page
  1106. ;    Form Feed Function
  1107. ;
  1108. page:
  1109.     lda    lff    ;form feed in use
  1110.     ora    a    ;0=no
  1111.     jnz    prout0    ;process top of new page if form feed in use
  1112.     lda    lcount    ;get count of remaining lines
  1113.     call    lineskp    ;skip lines
  1114.     jmp    prout0    ;process top of new page
  1115. ;
  1116. ;  Skip out lines on page
  1117. ;    A = number of lines to skip
  1118. ;
  1119. lineskp:
  1120.     mov    b,a    ;line count in B
  1121.     ora    a    ;any?
  1122.     rz
  1123.     lda    skipfl    ;skipping?
  1124.     ora    a
  1125.     rnz
  1126.     lda    lff    ;form feed available?
  1127.     ora    a    ;0=no
  1128.     jnz    lines2
  1129. lines1:
  1130.     call    lcrlf    ;new line
  1131.     dcr    b    ;count down
  1132.     jnz    lines1
  1133.     ret
  1134. lines2:
  1135.     call    lcrlf    ;new line
  1136.     mvi    a,ff    ;output form feed to printer
  1137.     jmp    lout
  1138. ;
  1139. ;  Print Line Number (optional)
  1140. ;
  1141. prlnum:
  1142.     lda    skipfl    ;skipping?
  1143.     ora    a    ;0=no
  1144.     rnz
  1145.     lda    lnumfl    ;get flag
  1146.     ora    a    ;0=don't number lines
  1147.     rz
  1148.     push    h    ;save ptr
  1149.     lhld    lnum    ;get line number
  1150.     call    lhldc    ;print line number
  1151.     call    lprint    ;print separator
  1152.     db    ': ',0
  1153.     pop    h    ;restore ptr
  1154.     ret
  1155. ;
  1156. ;  Print 2-line heading and control skipping
  1157. ;
  1158. prhead:
  1159.     push    h    ;save ptr
  1160.     lda    skipfl    ;currently skipping?
  1161.     ora    a    ;0=no
  1162.     cnz    skiptst    ;test for shut off
  1163.     lda    exact    ;exact says no heading
  1164.     ora    a    ;0FFH=yes
  1165.     jnz    prhead1
  1166.     call    proffs    ;print offset
  1167.     lda    pnumfl    ;number pages?
  1168.     ora    a    ;0=no
  1169.     cnz    prpnum    ;print page heading and number
  1170.     lda    fnpfl    ;print file name?
  1171.     ora    a    ;0=no
  1172.     cnz    prfname    ;print file name
  1173. ;
  1174.     if    timeok    ;time available?
  1175.     lda    timepfl    ;print time?
  1176.     ora    a    ;0=no
  1177.     cnz    prtime    ;print time
  1178.     endif
  1179. ;
  1180.     push    h
  1181.     lhld    hbuf    ;pt to heading buffer
  1182.     mov    a,m    ;print heading?
  1183.     pop    h
  1184.     ora    a    ;0=no
  1185.     cnz    prhdg    ;print heading
  1186. prhead1:
  1187.     pop    h    ;restore ptr
  1188. prhead2:
  1189.     lda    skipfl    ;skipping?
  1190.     ora    a
  1191.     rnz
  1192.     call    lcrlf    ;new line
  1193.     jmp    lcrlf
  1194. ;
  1195. ;  Test for completion of skipping
  1196. ;
  1197. skiptst:
  1198.     lhld    pnum    ;get page number
  1199.     xchg        ;... in DE
  1200.     lhld    skipnum    ;get page to skip to
  1201.     mov    a,h    ;compare them
  1202.     cmp    d
  1203.     rnz
  1204.     mov    a,l
  1205.     cmp    e
  1206.     rnz
  1207.     xra    a    ;A=0 to stop skipping
  1208.     sta    skipfl    ;set flag
  1209.     ret
  1210. ;
  1211. ;  Print Line Offset
  1212. ;
  1213. proffs:
  1214.     lda    skipfl    ;skipping?
  1215.     ora    a
  1216.     rnz
  1217.     push    b    ;save BC
  1218.     lda    offset    ;get offset
  1219.     ora    a    ;any?
  1220.     jz    proff2
  1221.     mov    c,a    ;offset in B
  1222. proff1:
  1223.     mvi    a,' '    ;space over
  1224.     call    prout
  1225.     dcr    c    ;count down
  1226.     jnz    proff1
  1227. proff2:
  1228.     pop    b
  1229.     ret
  1230. ;
  1231. ;  Print Page Number
  1232. ;
  1233. prpnum:
  1234.     lda    skipfl    ;skipping?
  1235.     ora    a
  1236.     rnz
  1237.     call    lprint    ;print header
  1238.     db    'Page ',0
  1239.     lhld    pnum    ;print current page number
  1240.     call    lhldc    ;print as decimal
  1241.     ret
  1242. ;
  1243. ;  Print File Name
  1244. ;
  1245. prfname:
  1246.     lda    skipfl    ;skipping?
  1247.     ora    a
  1248.     rnz
  1249.     call    prdash    ;print separator
  1250.     lxi    h,tfcb+1    ;pt to first char
  1251.     mvi    b,8    ;8 chars
  1252.     call    lfn1
  1253.     mvi    a,'.'
  1254.     call    lout
  1255.     mvi    b,3    ;3 chars
  1256.     call    lfn1
  1257.     ret
  1258. lfn1:
  1259.     mov    a,m    ;get char
  1260.     ani    7fh    ;mask
  1261.     call    lout    ;send to printer
  1262.     inx    h    ;pt to next
  1263.     dcr    b    ;count down
  1264.     jnz    lfn1
  1265.     ret
  1266. ;
  1267. ;  Print Separator
  1268. ;
  1269. prdash:
  1270.     call    lprint
  1271.     db    ' -- ',0
  1272.     ret
  1273. ;
  1274.     if    timeok
  1275. ;
  1276. ;  Print Time
  1277. ;
  1278. prtime:
  1279.     lda    skipfl    ;skipping?
  1280.     ora    a
  1281.     rnz
  1282.     call    prdash    ;print separator
  1283.     lhld    timebf    ;pt to time stamp
  1284.     call    lpstr    ;print
  1285.     ret
  1286. ;
  1287.     endif
  1288. ;
  1289. ;  Print Header
  1290. ;
  1291. prhdg:
  1292.     lda    skipfl    ;skipping?
  1293.     ora    a
  1294.     rnz
  1295.     call    prdash    ;print separator
  1296.     lhld    hbuf    ;pt to heading
  1297.     call    lpstr    ;print
  1298.     ret
  1299. ;
  1300. ;  UTILITIES
  1301. ;    SBLANK  -- SKIP BLANKS PTED TO BY HL UNTIL NON-BLANK ENCOUNTERED; HL
  1302. ;    SNBLANK -- SKIP NON-BLANKS PTED TO BY HL UNTIL BLANK OR EOL; HL
  1303. ;    PRFN    -- PRINT FILE NAME PTED TO BY HL; AFFECT NOTHING
  1304. ;
  1305.  
  1306. ;
  1307. ;  SKIP UNTIL NON-BLANK
  1308. ;
  1309. SBLANK:
  1310.     MOV    A,M    ; LOOK FOR BLANK
  1311.     INX    H    ; PT TO NEXT
  1312.     CPI    ' '    ; BLANK?
  1313.     JZ    SBLANK
  1314.     DCX    H    ; BACK UP
  1315.     RET
  1316.  
  1317. ;
  1318. ;  SKIP UNTIL BLANK OR EOL
  1319. ;
  1320. SNBLANK:
  1321.     MOV    A,M    ; GET CHAR
  1322.     INX    H    ; PT TO NEXT
  1323.     CPI    ' '    ; BLANK?
  1324.     JZ    SNB1
  1325.     ORA    A    ; EOL?
  1326.     JNZ    SNBLANK
  1327. SNB1:
  1328.     DCX    H    ; BACK UP
  1329.     RET
  1330.  
  1331. ;
  1332. ;  PRINT FILE NAME PTED TO BY HL
  1333. ;    OUTPUT TO CON:
  1334. ;
  1335. PRFN:
  1336.     PUSH    H    ; SAVE REGS
  1337.     PUSH    B
  1338.     CALL    RETUD    ; GET CURRENT USER/DISK
  1339.     MOV    A,B    ; PRINT DISK
  1340.     ADI    'A'    ; LETTER
  1341.     CALL    COUT
  1342.     MOV    A,C    ; PRINT USER
  1343.     CALL    PADC
  1344.     CALL    EPRINT
  1345.     DB    ': ',0
  1346.     INX    H    ; PT TO FILE NAME
  1347.     MVI    B,8    ; PRINT NAME
  1348.     CALL    PRNT
  1349.     MVI    A,'.'    ; DECIMAL
  1350.     CALL    COUT
  1351.     MVI    B,3    ; PRINT TYPE
  1352.     CALL    PRNT
  1353.     POP    B    ; GET REGS
  1354.     POP    H
  1355.     RET
  1356.  
  1357. ;
  1358. ;  PRINT CHARS PTED TO BY HL FOR B BYTES
  1359. ;    OUTPUT TO CON:
  1360. ;
  1361. PRNT:
  1362.     MOV    A,M    ; GET CHAR
  1363.     CALL    COUT
  1364.     INX    H    ; PT TO NEXT
  1365.     DCR    B    ; COUNT DOWN
  1366.     JNZ    PRNT
  1367.     RET
  1368.  
  1369. ;
  1370. ;  BUFFERS
  1371. ;
  1372. CMDLNE:
  1373.     DS    2    ; PTR TO COMMAND LINE STRING
  1374. DIRBUF:
  1375.     DS    2    ; PTR TO DIRECTORY BUFFER
  1376. NFPTR:
  1377.     DS    2    ; PTR TO NEXT FILE
  1378. NFCNT:
  1379.     DS    2    ; NEXT FILE COUNT
  1380. NEXTCH:
  1381.     DS    2    ; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE
  1382. SCRATCH:
  1383.     DS    2    ; ADDRESS OF FIRST FREE BYTE
  1384. BCNT:
  1385.     DS    1    ; NUMBER OF PAGES IN SCRATCH AREA
  1386. ;
  1387. ;  PRINT3 Buffers
  1388. ;
  1389. tfcb:
  1390.     ds    36    ; FCB for current file
  1391. nxtblk:
  1392.     ds    2    ; pointer to next block to load
  1393. nxtln:
  1394.     ds    2    ; pointer to next line to read
  1395. lcount:
  1396.     ds    1    ; count of text lines left on page
  1397. ;
  1398. ;  Stack
  1399. ;
  1400. STACK:
  1401.     DS    2    ; OLD STACK PTR
  1402.  
  1403.     END
  1404.