home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / plist.asm < prev    next >
Assembly Source File  |  1986-06-27  |  29KB  |  963 lines

  1.      name    plist
  2.     page    78,132
  3.     title    PLIST12 --- Print text file (version 1.2A)
  4.  
  5. ;    Zider Brothers,    San Francisco
  6. ;
  7. ;    Based on LIST.ASM by Ray Duncan
  8. ;
  9. ;6.27    Fixed output buffer bug.
  10. ;    Added version id on help screen.
  11. ;    Added PLIST id to error messages.
  12. ;    Fixed automatic computation of remaining available space 
  13. ;      (courtesy Chris Dunford via Vern Buerg).
  14. ;
  15. ;6.5.86    Fixed title buffer init to conform to page offset, line
  16. ;      width parms.
  17. ;    Fixed end-of-input processing (now does not pump out extra
  18. ;      line with pg_offset pad plus line feed)
  19. ;
  20. ;6.4.86    Add /7 option to strip hi-bit (make ok 8-bit the default now)
  21. ;    Enlarged I/O buffers to max space available (64K assumed - may 
  22. ;      blow system if full 64KB not available for code).
  23. ;    DEL char (07Fh or 127 decimal) is now treated as low-order control
  24. ;      character. 
  25. ;    Add /b option for blanks substituted for low-order control chars 
  26. ;      (Default is that non-special treatment control chars are discarded 
  27. ;      from the output listing stream to keep output devices from
  28. ;      interpreting WordStar embedded print control chars).
  29. ;    Change default output file to zz.spl (from zz.lst).
  30. ;    Speed on AT 6/1 around 90-100K bps, and about 11-17,000 lines per minute.
  31. ;
  32. ;5.8.85    Add std    error out for error messages
  33. ;    Disable    code that toggles lpi, cpi on exit if parm was exercised
  34. ;    Change to COM file format
  35. ;    Input buffer moved to end, fill    above program
  36. ;    Change input block size    to 4096    bytes (for DOS 2.0 hard    disk)
  37. ;    Conversion speed from 14K bps to 19K bps, depending on tabs expansion
  38. ;    Make ZZ.LST the default (file) output--21K-24K bps (bits per second)
  39. ;
  40. ;5.7.85    Make compressed, 8 lpi the default (using IBM PC Graphics printer)
  41. ;    Add /N option to get uncompressed print    ("normal" print)
  42. ;    Exit print without changing settings if    none set, toggle back if set
  43. ;    Disable    FF bracketing, make no FF's at begin/end the default
  44. ;    Add /F switch to enable    lead-in    FF (tail end still disabled)
  45. ;    Add /S switch to print to std output device (so    can redirect to    file)
  46. ;    Change name to PLIST to    avoid confusion    with LIST545, etc by Vern Buerg
  47. ;    Add syntax, options help when null command line    tail
  48. ;    Add page offset    of 8 spaces
  49. ;    Added clarifying comments, code section identification breaks.
  50. ;
  51. ;5.6.85    Hack to    add 8 Lines Per    Inch option (/8)
  52. ;
  53. ;-----original documentation:
  54. ;
  55. ; LIST --- a utility to    print out text files with titles and page
  56. ; numbers on  the current list device.    The high bit of    all
  57. ; characters is     stripped [this option now must be specified on the command
  58. ; line with the /7 option], so that raw Wordstar or other word
  59. ; processing files can    be listed.  Embedded form feed codes are
  60. ; recognized, and tabs are  expanded.  Unknown control codes (such
  61. ; as the ^B and    ^U codes found in Wordstar documents) are discarded.
  62. ; If using an Epson printer, compressed    mode can be turned on with
  63. ; /C switch in command so that lines up    to 128 characters long will
  64. ; fit on a normal page.     Requires PC-DOS 2.0 or    MS-DOS 2.0.
  65.  
  66. ; Used in the form:
  67. ; A>LIST path\filename.ext  ["title text"]  [/C]
  68. ; (items in square brackets are    optional)
  69.  
  70. ; version 1.0    February 28, 1984
  71. ; Copyright (c)    1984 by    Ray Duncan
  72. ; May be freely    reproduced for non-commercial use.
  73.  
  74. cr    equ    0dh        ;ASCII carriage    return
  75. lf    equ    0ah        ;ASCII line feed
  76. ff    equ    0ch        ;ASCII form feed
  77. eof    equ    01ah        ;End of    file marker
  78. tab    equ    09h        ;ASCII tab character
  79. blank    equ    20h        ;space character
  80.  
  81. command        equ    80h    ;buffer    for command tail
  82.  
  83. prog_size    =    offset end_code        ; s/b about 09f6h
  84. end_segment    equ    0ffffh
  85. stack_space    equ    100h
  86. avail        =    end_segment-(offset end_code - cseg) - stack_space
  87. ;avail2        =    end_segment-prog_size-stack_space    ;gives error
  88.         public    buf_size
  89. ;buf_size    equ    1024
  90. buf_size    equ    avail/2
  91.         public    output_buffer
  92. output_buffer    equ    prog_size+buf_size
  93. chk_stack    equ    output_buffer+buf_size+1
  94. stack_start    equ    end_segment-stack_space+1
  95.  
  96. inblksize    equ    buf_size
  97. outblksize    equ    buf_size
  98. ;inblksize    equ    8192    ;size of block reads from input    file
  99. ;outblksize    equ    8192    ;size of block writes to output file
  100. pg_offset    equ    8    ;set page offset to 8 spaces
  101. linesize equ    132-pg_offset    ;maximum length    of output line
  102. page6lpi    equ    58    ;58 out of 66 lines
  103. page8lpi    equ    80    ;80 of of 88 lines
  104. heading_lines    equ    3    ;number    of lines in page heading
  105.  
  106. std_out        equ    1    ;standard output
  107. std_error    equ    2    ;standard error--not redirectable
  108. std_printer    equ    4    ;standard printer
  109.     page
  110. cseg    segment    para public 'CODE'
  111.  
  112. ;old assume:
  113. ;    assume    cs:cseg,ds:data,es:data,ss:stack
  114.     assume    cs:cseg,ds:cseg,es:cseg,ss:cseg
  115.     org    100H
  116. ENTRY:    jmp    start
  117. ;
  118. ;DATA area at end of the program.
  119. ;
  120. who_am_i    db    'PLIST12: Zider Brothers, San Francisco'
  121. start:
  122. list    proc    far        ;entry point from PC-DOS
  123.  
  124.     push    ds        ;save DS:0000 for final
  125.     xor    ax,ax        ;return    to PC-DOS
  126.     push    ax
  127.  
  128. list13:                ;make sure we're running under DOS 2.0.
  129.     mov    ah,30h
  130.     int    21h
  131.     cmp    al,2
  132.     jae    list01        ;proceed, DOS 2.0 or greater
  133.     mov    dx,offset msg3    ;DOS 1.x --- print error message
  134.     mov    cx,msg3_len
  135.     jmp    list9
  136.  
  137.  
  138. ;----------------------------------------------------------
  139. ;        Process command line
  140.  
  141. list01:    call    get_title    ;get listing title from
  142.                 ;command line tail.
  143.     call    get_switch    ;look for /C, /N, /6, /8, etc switches,    if any
  144.     call    get_filename    ;get path and file spec. for
  145.                 ;input file from command line tail.
  146.  
  147.     jnc    list15        ;jump, got acceptable name.
  148.     mov    dx,offset msg2    ;missing or illegal filespec,
  149.     mov    cx,msg2_len
  150.     jmp    list9        ;print error message and exit.
  151.  
  152. ;----------------------------------------------------------
  153. ;        Open input file
  154.  
  155. list15:    call    open_input    ;now try to open input file
  156.     jnc    list2        ;jump,opened input ok
  157.     mov    dx,offset msg1    ;open of input file failed,
  158.     mov    cx,msg1_len
  159.     jmp    list9        ;print error msg and exit.
  160.  
  161. ;----------------------------------------------------------
  162. ;        Open output file
  163.  
  164. list2:
  165.     cmp    s_switch,0    ;output    to std out?
  166.     jne    list25        ;jump if DOS std output    selected
  167.     call    open_zzlst    ;open default output file
  168.     jnc    list25        ;skip if ok open
  169.     mov    dx,offset zzmsg    ;opening default file error
  170.     mov    cx,zzmsg_len
  171.     jmp    list9        ;print error msg and xit.
  172.  
  173. ;----------------------------------------------------------
  174. ;        Initialization
  175.  
  176. list25:    call    init_buff    ;initialize input deblocking buffer
  177.  
  178. ;----------------------------------------------------------
  179. ;        Set page, printer configuration
  180.  
  181. list20:    test    compress_switch,-1 ;was    /C switch found?
  182.     jz    list21
  183.     call    compress_on    ;yes,turn on compressed    print mode
  184. list21:    test    ate_lpi,-1    ;/8 switch found?
  185.     jz    list22
  186.     call    ate_on
  187. list22:    test    six_lpi,-1    ;/6 switch found?
  188.     jz    list23
  189.     call    six_on
  190. list23:    test    norm_switch,-1    ;was /N    switch found?
  191.     jz    list3
  192.     call    compress_off
  193.  
  194. ;===============================================================;
  195. ;        Main program control loop            ;
  196. ;                                ;
  197.  
  198. ;----------------------------------------------------------
  199. ;        Process character input stream
  200.  
  201. list3:                
  202.     call    get_char    ;read 1    character from input.
  203.     cmp    al,20h        ;is it a low-order control code?
  204.     jb    short list30    ;yes, go check out what kind.
  205.     cmp    al,07fh        ;not low-order, pivot on DEL char (127 decimal)
  206.     jb    list4        ;ok char, write to list device.
  207.     je    short list30    ;treat it like low-order control char.
  208.  
  209. mod1    label    word
  210.     nop            ;high bit is set on char = upper 128 chars.
  211.     nop            ;..two bytes here may be modified to 
  212.                 ;  'and  al,07h' by /7 option to strip hi-bit.
  213.                 ;  Otherwise code falls through to jmp:
  214.     jmp    list4        ;now write to list device.
  215.  
  216. list30:    cmp    al,tab        ;is it a tab command?
  217.     je    list5        ;yes,jump to special processing.
  218.     cmp    al,cr        ;carriage return?
  219.     jne    list31        ;
  220.     mov    column,0    ;carriage return, store it into output
  221.     jmp    list45        ;  string and initialize column count.
  222. list31:    cmp    al,lf        ;is it a line feed?
  223.     je    list7        ;yes,jump to special processing. (force print)
  224.     cmp    al,ff        ;is it a form feed?
  225.     je    list6        ;yes, jump to special processing.
  226.     cmp    al,eof        ;is it end of file marker?
  227.     je    list8        ;yes,jump to close files.
  228.     test    blank_sub,-1    ;substitute blank char for control char?    
  229.     jz    list32        ;no
  230.     mov    al,blank    ;yes, replace ctl char with blank
  231.     jmp    list4        ;now write to list device
  232. list32:    jmp    list3        ;none of the above--ignore it and get another
  233.  
  234. ;----------------------------------------------------------
  235. ;        Special tab expansion
  236.  
  237. list5:                ;process tab character
  238.     mov    ax,column    ;let DX:AX=column count
  239.     cwd
  240.     mov    cx,8        ;divide    it by eight...
  241.     idiv    cx
  242.     sub    cx,dx        ;remainder is in DX.
  243.     add    column,cx    ;update    column pointer.
  244. list55:                ;8 minus the remainder
  245.     push    cx        ;gives us the number of
  246.     mov    al,20h        ;spaces    to send    out to
  247.     call    put_char    ;move to the next tab position
  248.     pop    cx        ;restore space count
  249.     loop    list55
  250.     jmp    short list3    ;get next character
  251.  
  252. ;----------------------------------------------------------
  253. ;        Form feed processing
  254.  
  255. list6:                ;form feed detected
  256.     call    write_maybe    ;if anything waiting in    output
  257.                 ;buffer, print it first
  258.     call    print_heading    ;new page and print title
  259.     jmp    list3        ;get next character from input
  260.  
  261. ;----------------------------------------------------------
  262. ;        Put character into output line buffer
  263.  
  264. list4:                
  265.     inc    column        ;bump line char count
  266.  
  267. list45:                ;write this character into
  268.     call    put_char    ;forming output    string.
  269.                 ;is output buffer about    to overflow?
  270.     cmp    linput_ptr,linesize-1
  271.     je    list7        ;yes, force print of buffer.
  272.     jmp    list3        ;no, get next char. from input file.
  273.  
  274. ;----------------------------------------------------------
  275. ;        Line feed  char or line full, flush line buffer
  276.  
  277. list7:                ;line feed detected, interpreted
  278.                 ;as print command.
  279.     call    heading_maybe    ;print heading if needed
  280.     call    write_line    ;print contents    of text    buffer
  281.     jmp    list3        ;get more from input file
  282.  
  283. ;----------------------------------------------------------
  284. ;        End of file processing
  285.  
  286. list8:                ;end of    file detected  (^Z, 1AH)
  287.     call    close_input    ;close input file
  288.     call    write_maybe    ;print anything    that's waiting
  289.                 ;in output buffer.
  290.  
  291. ;disable end of    job form feed check and form feed output:
  292. ;    cmp    ff_switch,0    ;see if    FF's have been specified
  293. ;    je    list81        ;skip it if /F not set
  294. ;    mov    al,ff        ;send form feed    to finish listing.
  295. ;list81:    
  296. ;    call    put_char
  297.  
  298. ;     call    write_line    ;why need? already called write_maybe
  299.     call    flush_out    ;flush output buffer
  300.     call    close_output    ;close output file
  301.     jmp    list85        ;skip following    code
  302.  
  303. ;disable this exit code--leave printer in mode(s) selected by cmd line parms:
  304. ;                ;turn off compressed print mode,
  305. ;                ;if it was enabled.
  306. ;    test    compress_switch,-1
  307. ;    jz    list82
  308. ;    call    compress_off
  309. ;list82:    cmp    norm_switch,0
  310. ;    je    list83
  311. ;    call    compress_on
  312. ;list83:    cmp    ate_lpi,0
  313. ;    je    list84
  314. ;    call    six_on
  315. ;list84:    cmp    six_lpi,0
  316. ;    je    list85
  317. ;    call    ate_on
  318.  
  319. list85:    
  320.     ret            ;now return to PC-DOS.
  321.  
  322. ;----------------------------------------------------------
  323. ;        Error: program termination
  324. ;
  325. ;DX    offset to error message
  326. ;CX    length of error message
  327.  
  328. error_out:
  329. list9:                ;come here to print error message
  330.     mov    bx,std_error
  331.     mov    ah,40H        
  332.     int    21H
  333.     mov    bx,std_error
  334.     mov    cx,hlpmsg_len
  335.     mov    dx,offset hlpmsg    ;help with syntax added    here
  336.     mov    ah,40H
  337.     int    21H
  338.     ret            ;return to DOS
  339.  
  340. list    endp
  341.  
  342. ;                                ;
  343. ;        End of main program control loop           ;
  344. ;===============================================================;
  345.  
  346. page
  347.  
  348. ;----------------------------------------------------------
  349. ;        Get filename
  350.  
  351. get_filename proc near        ;process name of input file
  352.                 ;DS:SI <- addr command line
  353.     mov    si,offset command
  354.                 ;ES:DI <- addr filespec    buffer
  355.     mov    di,offset input_name
  356.     cld
  357.     lodsb            ;any command line present?
  358.     or    al,al        ;return    error status if    not.
  359.     jz    get_filename4
  360. get_filename1:            ;scan over leading blanks
  361.     lodsb            ;to file name
  362.     cmp    al,cr        ;if we hit carriage return
  363.     je    get_filename4
  364.     cmp    al,'/'        ;or switch,
  365.     je    get_filename4
  366.     cmp    al,'"'          ;or quote mark, filename missing.
  367.     je    get_filename4    ;so go return error flag.
  368.     cmp    al,20h        ;is this a blank?
  369.     jz    get_filename1    ;if so keep scanning.
  370. get_filename2:            ;found first char of name,
  371.     stosb            ;move last char. to output
  372.                 ;file name buffer.
  373.     lodsb            ;check next character, found
  374.     cmp    al,cr        ;carriage return yet?
  375.     je    get_filename3    ;yes,exit with success code.
  376.     cmp    al,'"'          ;same if quote encountered.
  377.     je    get_filename3
  378.     cmp    al,20h        ;is this a blank?
  379.     jne    get_filename2    ;if not    keep moving chars.
  380. get_filename3:            ;exit with carry =0
  381.     clc            ;for success flag
  382.     ret
  383. get_filename4:            ;exit with carry =1
  384.     stc            ;for error flag
  385.     ret
  386. get_filename endp
  387.  
  388. ;----------------------------------------------------------
  389. ;        Get title
  390.  
  391. get_title proc near        ;process title for listing
  392.                 ;DS:SI <- addr command line
  393.     mov    si,offset command
  394.                 ;ES:DI <- addr page heading buffer
  395.     mov    di,offset heading1
  396.     add    di,pg_offset    ;mov pointer into buf by page offset amt
  397.     cld
  398.     lodsb            ;any command line present?
  399.     or    al,al        ;no,exit
  400.     jz    get_title3
  401. get_title1:            ;scan for leading <"> to find title.
  402.     lodsb
  403.     cmp    al,cr        ;if we hit carriage return,
  404.     je    get_title3    ;title text is missing.
  405.     cmp    al,'"'          ;found delimiter?
  406.     jne    get_title1    ;if so keep scanning.
  407. get_title2:            ;get next char.    of title.
  408.     lodsb
  409.     cmp    al,'"'          ;terminate if 2nd <"> delimiter
  410.     je    get_title3    ;or carriage return found
  411.     cmp    al,cr
  412.     je    get_title3
  413.     stosb            ;store this char. into page heading buffer
  414.     jmp    get_title2    ;examine next char.
  415. get_title3:
  416.     ret
  417. get_title endp
  418.  
  419. ;----------------------------------------------------------
  420. ;        Get switch
  421.  
  422. get_switch proc    near        ;Scan the input    line for a "/"
  423.                 ;delimiting a switch, then make
  424.                 ;sure it is legal "/C" or "/c".
  425.                 ;If legal switch found,    set
  426.                 ;variable COMPRESS_SWITCH true.
  427.                 ;Also check for    /8 for 8 lines per inch
  428.                 ;        /6 for 6 lines per inch
  429.                 ;        /N for normal (uncompressed)
  430.                 ;        /S for std out
  431.     mov    ax,std_printer    ;set default output device to printer
  432.     mov    output_handle,ax
  433.     mov    si,offset command+1  ; DS:SI = addr of command line
  434. get_switch1:            ;look for "/" character
  435.     lodsb
  436.     cmp    al,cr        ;if we run into    a carriage return,
  437.     jnz    gsw1        ;not cr
  438.     jmp    get_switch2    ;is cr,switch missing so take normal exit.
  439. gsw1:    cmp    al,'/'
  440.     jne    get_switch1    ;not '/' yet, keep looking.
  441.     lodsb            ;found '/', pick up next char.
  442. chk_8:    cmp    al,'8'        ;8 lines per inch?
  443.     jne    chk_6
  444.     mov    es:ate_lpi,-1    ;set 8 lines per inch switch
  445.     jmp    get_switch1    ;check for more    options
  446. chk_6:    cmp    al,'6'        ;6 lines per inch?
  447.     jne    chk_7
  448.     mov    es:six_lpi,-1    ;set 6 lines per inch switch
  449.     jmp    get_switch1    ;check for more    options
  450. chk_7:    cmp    al,'7'        ;7-bits only? (strip high bit)
  451.     jne    chk_b
  452.     mov    es:sept_bits,-1    ;set for 7-bit output only (flag not used..
  453.                 ;  ..used self-modifying code instead:
  454.     mov    ax,cs:and_w    ;move op to in-line code location
  455.     mov    cs:mod1,ax    ;                    )
  456.     jmp    get_switch1    ;check for more options
  457. and_w    label    word        ;and-operator
  458. and_op:    and    al,07fh        ;strip hi-bit op code bytes
  459.  
  460. chk_b:    cmp    al,'b'        ;b=blank sub for low control chars
  461.     jne    chk_c
  462.     mov    es:blank_sub,-1    ;set for blank
  463.     jmp    get_switch1    ;check for more options
  464. chk_c:    or    al,20h        ;and fold to lower case.
  465.     cmp    al,'c'        ;c=compress
  466.     jne    chk_n        ;not /C, check for /N
  467.                 ;set compress switch
  468.     mov    es:compress_switch,-1
  469.     jmp    get_switch1    ;check for more    options
  470. chk_n:    cmp    al,'n'        ;n=normal
  471.     jne    chk_f        ;not n,    check for /F
  472.     mov    es:norm_switch,-1
  473.     jmp    get_switch1    ;check for more    options
  474. chk_f:    cmp    al,'f'        ;f=bracket print with FF's
  475.     jne    chk_s
  476.     mov    es:ff_switch,-1
  477.     jmp    get_switch1    ;check for more    options
  478. chk_s:    cmp    al,'s'        ;/S
  479.     jne    get_switch2    ;not f,    jump to    return
  480.     mov    es:output_handle,std_out    ;set output to std out
  481.     mov    es:s_switch,-1
  482.     jmp    get_switch1    ;check for more    options
  483.  
  484. get_switch2:
  485.     ret            ;exit
  486. get_switch endp
  487.  
  488. ;----------------------------------------------------------
  489. ;        Open input file
  490.  
  491. open_input proc    near        ;open input file
  492.                 ;DS:DX=addr filename
  493.     mov    dx,offset input_name
  494.     mov    al,0        ;AL=0 for read only
  495.     mov    ah,3dh        ;function 3dh=open
  496.     int    21h        ;handle    returned in AX,
  497.     mov    input_handle,ax    ;save it for later.
  498.     ret            ;CY is set if error
  499. open_input endp
  500.  
  501. ;----------------------------------------------------------
  502. ;        Open default output file
  503.  
  504. open_zzlst    proc    near    ;open default output file
  505. ;This will open    an existing file if it exists
  506.     mov    dx,offset zzlst    ;ASCIIZ    string of default output file name
  507.     mov    al,1        ;open file for writing
  508.     mov    ah,3dh        ;open a    file
  509.     int    21h
  510.     jc    ozz1        ;if CY, check if not found
  511. savozz:    mov    output_handle,ax
  512.     mov    zzlst_handle,ax    ;in case we need it
  513. ;move to the end of the file for default file append
  514.     mov    bx,ax        ;handle to BX for LSEEK
  515.     mov    cx,0        
  516.     mov    dx,0
  517.     mov    al,2        ;to end of file plus offset of zero (CX:DX)
  518.     mov    ah,42h        ;LSEEK call (what's an LSEEK???)
  519.     int    21h        ;CY may be set here if invalid handle or function
  520.  
  521. ozzxit:    ret            ;carry will be set if error
  522.  
  523.     public ozz1
  524. ozz1:    cmp    ax,2        ;if =2, then file not found and must be created
  525.     jne    ozz9
  526.     mov    dx,offset zzlst    ;in case trashed by DOS
  527.     mov    cx,20h        ;creating normal file
  528.     mov    ah,3ch        ;create file call
  529.     int    21h
  530.     jnc    savozz        ;ok create if no CY
  531.  
  532. ozz9:    stc            ;other error (too many handles or access denied)
  533.     ret
  534. open_zzlst    endp
  535.  
  536. ;----------------------------------------------------------
  537. ;        Initialize buffers
  538.  
  539. init_buff proc near        ;initialize input buffer
  540.     call    read_block    ;read 1st block    of input file
  541.     mov    linput_ptr,pg_offset    ;initialize pointer to output string
  542.     ret
  543. init_buff endp
  544.  
  545. ;----------------------------------------------------------
  546. ;        Read input block
  547.  
  548. read_block proc    near        ;read block of data from input file.
  549.     mov    bx,input_handle
  550.     mov    cx,inblksize
  551.     mov    dx,offset input_buffer
  552.     mov    ah,3fh
  553.     int    21h
  554.     jnc    read_block1    ;jump if no error status
  555.     mov    ax,0        ;simulate a zero length    read if    error
  556. read_block1:
  557.     cmp    ax,inblksize    ;was full buffer read in?
  558.     je    read_block2    ;yes,jump
  559.     mov    bx,ax        ;no, store End-of-File mark
  560.     mov    byte ptr [input_buffer+bx],eof
  561. read_block2:
  562.     mov    input_ptr,0    ;initialize pointer to input buffer.
  563.     ret
  564. read_block endp
  565.  
  566. ;----------------------------------------------------------
  567. ;        Set page, printer configuration
  568.  
  569. compress_on proc near        ;turn on compressed printing mode
  570.                 ;by sending command string.
  571.     mov    cx,comp_command_length
  572.     mov    bx,output_handle
  573.     mov    dx,offset comp_command
  574.     mov    ah,40h
  575.     int    21h
  576.     ret
  577. compress_on endp
  578.  
  579. compress_off proc near            ;turn off compressed printing mode
  580.                     ;by sending command string.
  581.     mov    cx,norm_command_length
  582.     mov    bx,output_handle
  583.     mov    dx,offset norm_command
  584.     mov    ah,40h
  585.     int    21h
  586.     ret
  587. compress_off endp
  588.  
  589. ate_on    proc    near            ;turn on 8 lpi
  590.     mov    ax,page8lpi
  591.     mov    pagesize,ax
  592.     mov    linecount,ax
  593.     mov    cx,ate_lpi_cmd_len
  594.     mov    bx,output_handle
  595.     mov    dx,offset ate_lpi_cmd
  596.     mov    ah,40H
  597.     int    21H
  598.     ret
  599. ate_on    endp
  600.  
  601. six_on    proc    near            ;turn on 6 lpi
  602.     mov    ax,page6lpi
  603.     mov    pagesize,ax
  604.     mov    linecount,ax
  605.     mov    cx,six_lpi_cmd_len
  606.     mov    bx,output_handle
  607.     mov    dx,offset six_lpi_cmd
  608.     mov    ah,40H
  609.     int    21H
  610.     ret
  611. six_on    endp
  612.  
  613.  
  614. ;----------------------------------------------------------
  615. ;        Get one character from input buffer
  616.  
  617. get_char proc    near        ;get one character from    input buffer
  618.     mov    bx,input_ptr    ;is pointer at end of buffer?
  619.     cmp    bx,inblksize
  620.     jne    get_char1    ;no,jump
  621.                 ;yes, buffer is    exhausted,
  622.     call    read_block    ;new block must    be read    from disk.
  623.     mov    bx,0        ;initialize buffer pointer.
  624. get_char1:
  625.     mov    al,byte    ptr [input_buffer+bx]
  626.     inc    bx        ;bump input buffer pointer
  627.     mov    input_ptr,bx
  628.     ret
  629. get_char endp
  630.  
  631. ;----------------------------------------------------------
  632. ;        Put char into output line buffer
  633.  
  634.     public    put_char
  635. put_char proc    near        ;put one character into    output buffer
  636.     mov    bx,linput_ptr
  637.     mov    [line_buffer+bx],al
  638.     inc    linput_ptr    ;bump pointer to output    string
  639.     ret
  640. put_char endp
  641.  
  642. ;----------------------------------------------------------
  643. ;        Heading maybe--if end of the page
  644.  
  645.     public    heading_maybe
  646. heading_maybe proc near        ;print heading if the line
  647.                 ;count justifies it
  648.     mov    ax,pagesize
  649.     cmp    linecount,ax
  650.     jl    heading_maybe2    ;jump,page not full yet
  651.     call    print_heading    ;form feed (maybe) and print title
  652. heading_maybe2:
  653.     ret
  654. heading_maybe endp
  655.  
  656. ;----------------------------------------------------------
  657. ;        Print heading
  658.  
  659.     public print_heading
  660. print_heading proc near        ;print form feed, title, and page no.
  661.     inc    pagecount    ;bump page number,
  662.     mov    ax,pagecount    ;load it,
  663.     aam            ;and turn it into ASCII,
  664.     add    ax,'00'
  665.     mov    heading2,ah    ;then store into heading string.
  666.     mov    heading2+1,al
  667.                 ;now print the heading string.
  668.     cmp    pagecount,1    ;check if first    page heading
  669.     je    chk_ff        ;see if    FF switch was specified
  670.     public    ph2
  671. ph2:    mov    dx,offset heading_buffer    ;header including lead FF
  672.     mov    cx,heading_length
  673.     public    ph3
  674. ph3:    
  675. ;put these lines  into output buffer now instead:
  676. ;    mov    bx,output_handle
  677. ;    mov    ah,40h
  678. ;    int    21h
  679.  
  680.     call    put_line
  681.  
  682.                 ;initialize line count
  683.     mov    linecount,heading_lines
  684.     mov    column,0    ;and column counter
  685.     ret
  686.  
  687.     public chk_ff
  688. chk_ff:    cmp    ff_switch,-1    ;see if    set
  689.     je    ph2        ;if set, jump back
  690.     mov    dx,offset heading_buffer+1    ;not set, skip lead FF on page 1
  691.     mov    cx,heading_length-1
  692.     jmp    ph3
  693.  
  694. print_heading endp
  695.  
  696.  
  697. ;----------------------------------------------------------
  698. ;        Write maybe--if chars in the output line buffer
  699.  
  700. write_maybe proc near        ;transmit line to list device, if
  701.                 ;output    buffer contains    anything.
  702.     mov    ax,linput_ptr    ;pointer is more than pg_offset if 
  703.     cmp    ax,pg_offset    ;characters are waiting in buffer.
  704. ;    or    ax,ax        ;
  705.     jz    write_maybe1    ;nothing, jump to exit
  706.     call    write_line    ;something there, send it to printer
  707. write_maybe1:
  708.     ret
  709. write_maybe endp
  710.  
  711. ;----------------------------------------------------------
  712. ;        Write line buffer -- put line in output
  713.  
  714. write_line proc    near        ;transmit contents of output
  715.                 ;buffer    to the standard    list device.
  716.     mov    al,lf        ;append    line feed to string.
  717. ;    call    put_char    ;insert code directly instead of call
  718.     mov    bx,linput_ptr    
  719.     mov    [line_buffer+bx],al
  720.     inc    linput_ptr    ;bump pointer into output line buffer
  721.     mov    cx,linput_ptr    ;CX contains length of string
  722.                 ;DX:DX=buffer address
  723.     mov    dx,offset line_buffer
  724.  
  725.     call    put_line    ;put line into output buffer
  726. ;    mov    bx,output_handle;BX=handle for standard    list device is default
  727. ;    mov    ah,40h        ;function 40h=write to device.
  728. ;    int    21h        ;request service from DOS.
  729.  
  730.  
  731.     inc    linecount    ;count lines printed this page.
  732.     mov    linput_ptr,pg_offset    ;reset pointer to list device buffer
  733.     ret
  734. write_line endp
  735.  
  736. ;----------------------------------------------------------
  737. ;        Put line into output buffer
  738. ;
  739. ;DX    ptr to line buffer
  740. ;CX    cnt of chars in line to be put
  741.  
  742.     public    put_line
  743. put_line    proc    near
  744.     
  745.     cmp    cx,0        ;anything to send?
  746.     je    xit_putlin
  747. put1:    mov    ax,output_ptr    ;get current ptr into output block
  748.     mov    bx,ax        ;set index for destination
  749.     add    ax,cx        ;add the line size to be added
  750.     cmp    ax,outblksize    ;see if we can take it
  751.     jbe    putl2        ;if not, flush the block first
  752.     call    flush_out
  753.     jc    xit_putlin    ;exit if carry (error writing block)
  754.     jmp    put1        ;recycle
  755.     
  756. putl2:    mov    output_ptr,ax    ;save new ptr (a bit out of order, but available)
  757.     mov    si,dx        ;source into si
  758.     mov    di,offset output_buffer
  759.     add    di,bx        ;dest into di
  760.     cld            ;increment pointers (clear direction flag: fwd)
  761.     rep    movsb        ;do your thing
  762.     clc            ;clear carry to indicate ok return
  763.  
  764. xit_putlin:    
  765.     ret
  766.  
  767.     public    flush_out
  768. flush_out    proc    near
  769.     push    cx
  770.     push    dx
  771.     mov    cx,output_ptr        ;bytes to write
  772.     mov    dx,offset output_buffer    ;source of bytes
  773.     mov    bx,output_handle    ;file to write them to
  774.     mov    ah,40h            ;DOS Write to File call
  775.     int    21H            ;the old 21H maneuver
  776.     cmp    ax,cx            ;written should equal requested
  777.     jne    error_putlin
  778.     mov    output_ptr,0        ;zero the buffer counter
  779.     clc
  780. flush_xit:
  781.     pop    dx            ;restore registers
  782.     pop    cx
  783.     ret
  784.  
  785.     public    error_putlin
  786. error_putlin    equ    $        ;here if file write error
  787.     mov    dx,offset msg4
  788.     mov    cx,msg4_len
  789.     mov    bx,std_error
  790.     mov    ah,40h
  791.     int    21h
  792.     stc
  793.     jmp    flush_xit
  794.  
  795. flush_out    endp
  796.  
  797. put_line    endp
  798.  
  799. ;----------------------------------------------------------
  800. ;        Close input file
  801.  
  802. close_input proc near        ;close input file
  803.     mov    bx,input_handle    ;BX=handle
  804.     mov    ah,3eh
  805.     int    21h
  806.     ret
  807. close_input endp
  808.  
  809. ;----------------------------------------------------------
  810. ;        Close output file
  811.  
  812. close_output    proc    near    ;close output file
  813.     mov    bx,output_handle
  814.     mov    ah,3eh
  815.     int    21h
  816.     ret
  817. close_output    endp
  818.  
  819. ;Move this to the end:
  820. ;cseg    ends
  821.  
  822. page
  823. ;===============================================================;
  824. ;        Data area                    ;
  825.  
  826. ;disable data segment setup:
  827. ;data    segment    para public 'DATA'
  828.  
  829.         public    input_name
  830. input_name    db    64 dup (0)    ;buffer    for input filespec
  831.  
  832.         public    input_handle
  833. input_handle    dw    0        ;token from PCDOS for input file.
  834.         public    output_handle
  835. output_handle    dw    std_printer    ;for printer or    std out
  836. zzlst        db    'ZZ.SPL',0    ;ASCIIZ    string for default output
  837. zzlst_handle    dw    1        ;std file output name, later reset
  838.  
  839.         public    input_ptr
  840. input_ptr    dw    0        ;pointer into input blocking buffer
  841.         public    linput_ptr
  842. linput_ptr    dw    pg_offset    ;pointer into line blocking buffer
  843.         public    output_ptr
  844. output_ptr    dw    0        ;ptr into output blocking buffer
  845.  
  846. column        dw    0        ;column    count for tab processing
  847.         public    linecount
  848. linecount    dw    page8lpi    ;line counter, current page.
  849.                     ;(set to "pagesize" initially to
  850.                     ;force first heading on    listing)
  851. pagesize    dw    page8lpi    ;initially at 8    lpi size
  852.         public    pagecount
  853. pagecount    dw    0        ;current page number
  854.  
  855. compress_switch    dw    0        ;set to    -1 if /C switch
  856.                     ;found in command line tail.
  857.  
  858. comp_command    db    0fh        ;command string    for compressed mode
  859. comp_command_length equ    $-comp_command
  860.  
  861. norm_switch    dw    0        ;set to    -1 if /N switch
  862. norm_command    db    12h        ;command string    for normal print
  863.                     ;(actually: turn off compressed)
  864. norm_command_length equ    $-norm_command
  865.  
  866. ate_lpi        dw    0        ;set to    -1 if /8 switch
  867. ate_lpi_cmd    db    1BH,'0'        ;ESC 0
  868. ate_lpi_cmd_len    equ    $-ate_lpi_cmd
  869.  
  870. sept_bits    dw    0        ;set to -1 if /7 switch        
  871.  
  872. blank_sub    dw    0        ;set to -1 if /b switch
  873.  
  874. six_lpi        dw    0        ;set to    -1 if /6 switch
  875. six_lpi_cmd    db    1BH,'2'        ;ESC 2
  876. six_lpi_cmd_len    equ    $-six_lpi_cmd
  877.  
  878. ff_switch    dw    0        ;set to    -1 if /F switch    (lead FF)
  879. s_switch    dw    0        ;set to    -1 if /S switch    (std out)
  880.  
  881. msg1        db    cr,lf
  882.         db    'PLIST: cannot find input file.'
  883.         db    cr,lf,'$'
  884. msg1_len    equ    $-msg1-1    ;net of    trailing '$'
  885.  
  886. msg2        db    cr,lf
  887.         db    'PLIST: missing file name.'
  888.         db    cr,lf,'$'
  889. msg2_len    equ    $-msg2-1
  890.  
  891. msg3        db    cr,lf
  892.         db    'PLIST: requires PC-DOS version 2.0 or greater.'
  893.         db    cr,lf,'$'
  894. msg3_len    equ    $-msg3-1
  895.  
  896. msg4        db    cr,lf
  897.         db    'PLIST: error writing output block.'
  898.         db    cr,lf,'$'
  899. msg4_len    equ    $-msg4-1
  900.  
  901. zzmsg        db    cr,lf
  902.         db    'PLIST: error opening default file ZZ.SPL.'
  903.         db    cr,lf,'$'
  904. zzmsg_len    equ    $-zzmsg-1
  905.  
  906.  
  907. hlpmsg        db    cr,lf
  908.         db    'Syntax:  [d\p\]filename.ext ["title text"] [/8/6/b/7/n/c/f/s]',cr,lf
  909.         db    cr,lf
  910.         db    '       /8      print 8 lpi (default)',cr,lf
  911.         db    '       /6      print 6 lpi (66 lines per page)',cr,lf
  912.         db    '       /b      blank substitution for low ctrl chars (default: discard)',cr,lf
  913.         db    '       /7      7-bits print (strip high bit)',cr,lf
  914.         db    '       /c      compressed print (default)',cr,lf
  915.         db    '       /n      non-compressed print (10 cpi)',cr,lf
  916.         db    '       /f      leading Form Feeds added (no trailing in any case)',cr,lf
  917.         db    '       /s      output to std out (screen), else file zz.spl default',cr,lf
  918.         db    cr,lf
  919.         db    'Notes:  no wildcards (*.*)  - use FOR expansion ',cr,lf
  920.         db    '        output dumped into zz.spl on current path - 15,000 lpm on AT',cr,lf
  921.         db    '        Version 1.2A 6.27.86',cr,lf
  922.         db    cr,lf
  923.         db    'Usage:  ',cr,lf,cr,lf
  924.         db    '  C>for %1 in (*.sno) do plist %1 "6.4.86 Snobol4+ source        %1       "',cr,lf
  925.         db    '  C>plist d:t.dta /s >tt',cr,lf
  926.         db    '$'
  927.         
  928.  
  929. hlpmsg_len    equ    $-hlpmsg-1    ;not including the '$'
  930.  
  931.  
  932.         public    line_buffer
  933. line_buffer    db    pg_offset dup(' ')    ;page offset blank pad
  934.         db    linesize-pg_offset dup (?);buffer used to build    output
  935.                     ;lines for list    device
  936.  
  937.         public        heading_buffer
  938. heading_buffer    db    ff        ;form feed control code
  939. heading1    db    linesize-pg_offset-7 dup (' ')    ;filled    in with    title from user
  940.         db    'Page '                ;7 chars in Page ##
  941. heading2    db    '00',cr
  942.         db    heading_lines dup (lf)
  943. heading_length    equ    $-heading_buffer
  944.  
  945. ;input_buffer    db    inblksize    dup ('x');deblocking buffer for    input file
  946.         public    input_buffer
  947.         even
  948. end_code    equ    $        ;end of code label
  949. input_buffer    equ    $        ;filled    above program, no cseg
  950.                     ;space required    in .COM    file
  951. ;output_buffer    equ    $+inblksize    ;output buffer space
  952. ;data segment disabled:
  953. ;data    ends
  954.  
  955. ;disable code for stack    segment:
  956. ;stack    segment    para stack 'STACK'
  957. ;    db    64 dup (?)
  958. ;stack    ends
  959.  
  960. cseg    ends
  961.  
  962.     end    entry
  963.