home *** CD-ROM | disk | FTP | other *** search
- name list
- page 55,132
- title 'LIST --- Print text file'
-
- ; Revisions:
- ; 8/23/87 - Added Prism 16cpi control code.
- ; - Revised non-arg msg to show pgm usage.
- ; OPR.
-
- ; LIST --- a utility to print out text files with titles and page
- ; numbers on the current list device. The high bit of all
- ; characters is stripped, so that raw Wordstar or other word
- ; processing files can be listed. Embedded form feed codes are
- ; recognized, and tabs are expanded. Unknown control codes (such
- ; as the ^B and ^U codes found in Wordstar documents) are discarded.
- ; If using an Epson printer, compressed mode can be turned on with
- ; /C switch in command so that lines up to 128 characters long will
- ; fit on a normal page. Requires PC-DOS 2.0 or MS-DOS 2.0.
- ;
- ; version 1.0 February 28, 1984
- ; Copyright (c) 1984 by Ray Duncan
- ;
- ; Used in the form:
- ;
- ; A>LIST path\filename.ext ["title text"] [/C]
- ;
- ; (items in square brackets are optional)
- ;
- ; To assemble, link, and convert this program into
- ; an EXE file, follow these steps:
- ;
- ; C>MASM LIST;
- ; C>LINK LIST;
- ;
- PRISM equ 1 ;Prism printer control code request if non-zero
- cr equ 0dh ;ASCII carriage return
- lf equ 0ah ;ASCII line feed
- ff equ 0ch ;ASCII form feed
- eof equ 01ah ;End of file marker
- tab equ 09h ;ASCII tab character
-
- command equ 80h ;buffer for command tail
-
- blksize equ 1024 ;size of block reads from input file
- linesize equ 132 ;maximum length of output line
- pagesize equ 58 ;number of lines per page
- heading_lines equ 3 ;number of lines in page heading
-
- output_handle equ 4 ;handle of standard list device
-
- cseg segment para public 'CODE'
-
- assume cs:cseg,ds:data,es:data,ss:stack
-
-
- list proc far ;entry point from PC-DOS
-
- push ds ;save DS:0000 for final
- xor ax,ax ;return to PC-DOS
- push ax
- mov ax,data ;make our data segment
- mov es,ax ;addressable via ES register.
- call get_title ;get listing title from
- ;command line tail.
- call get_switch ;look for /C switch if any
- call get_filename ;get path and file spec. for
- ;input file from command line tail.
- mov ax,es ;set DS=ES for remainder
- mov ds,ax ;of program.
- jnc list13 ;jump, got acceptable name.
- mov dx,offset msg2 ;missing or illegal filespec,
- jmp list9 ;print error message and exit.
-
- list13: ;make sure we're running under DOS 2.0.
- mov ah,30h
- int 21h
- cmp al,2
- jae list15 ;proceed, DOS 2.0 or greater
- mov dx,offset msg3 ;DOS 1.x --- print error message
- jmp list9
-
- list15: call open_input ;now try to open input file
- jnc list2 ;jump,opened input ok
- mov dx,offset msg1 ;open of input file failed,
- jmp list9 ;print error msg and exit.
-
- list2:
- test compress_switch,-1 ;was /C switch found?
- jz list25 ;no,jump
- call compress_on ;yes,turn on compressed print mode
-
- list25: call init_buff ;initialize input deblocking buffer
-
- ;file successfully opened,
- list3: ;now print it!
- call get_char ;read 1 character from input.
- and al,07fh ;strip off the high bit
- cmp al,20h ;is it a control code?
- jae list4 ;no,write it to list device.
- ;yes it is control code,
- cmp al,eof ;is it end of file marker?
- je list8 ;yes,jump to close files.
- cmp al,tab ;is it a tab command?
- je list5 ;yes,jump to special processing.
- cmp al,ff ;is it a form feed?
- je list6 ;yes, jump to special processing.
- cmp al,lf ;is it a line feed?
- je list7 ;yes,jump to special processing.
- cmp al,cr ;if illegal control code,
- jne list3 ;discard it and get next char.
- mov column,0 ;if carriage return, store it into output
- jmp list45 ;string and initialize column count.
-
- list4: ;count chars. sent on this line.
- inc column
-
- list45: ;write this character into
- call put_char ;forming output string.
- ;is output buffer about to overflow?
- cmp output_ptr,linesize-1
- je list7 ;yes, force print of buffer.
- jmp list3 ;no, get next char. from input file.
-
- list5: ;process tab character
- mov ax,column ;let DX:AX=column count
- cwd
- mov cx,8 ;divide it by eight...
- idiv cx
- sub cx,dx ;remainder is in DX.
- add column,cx ;update column pointer.
- list55: ;8 minus the remainder
- push cx ;gives us the number of
- mov al,20h ;spaces to send out to
- call put_char ;move to the next tab position
- pop cx ;restore space count
- loop list55
- jmp short list3 ;get next character
-
- list6: ;form feed detected
- call write_maybe ;if anything waiting in output
- ;buffer, print it first
- call print_heading ;new page and print title
- jmp list3 ;get next character from input
-
- list7: ;line feed detected, interpreted
- ;as print command.
- call heading_maybe ;print heading if needed
- call write_line ;print contents of text buffer
- jmp list3 ;get more from input file
-
- list8: ;end of file detected,
- call write_maybe ;print anything that's waiting
- ;in output buffer.
- mov al,ff ;send form feed to finish listing.
- call put_char
- call write_line
- call close_input ;close input file.
- ;turn off compressed print mode,
- ;if it was enabled.
- test compress_switch,-1
- jz list85
- call compress_off
- list85: ret ;now return to PC-DOS.
-
- list9: ;come here to print error message
- mov ah,9 ;and return control to PC-DOS
- int 21h
- ret
-
- list endp
-
-
- get_filename proc near ;process name of input file
- ;DS:SI <- addr command line
- mov si,offset command
- ;ES:DI <- addr filespec buffer
- mov di,offset input_name
- cld
- lodsb ;any command line present?
- or al,al ;return error status if not.
- jz get_filename4
- get_filename1: ;scan over leading blanks
- lodsb ;to file name
- cmp al,cr ;if we hit carriage return
- je get_filename4
- cmp al,'/' ;or switch,
- je get_filename4
- cmp al,'"' ;or quote mark, filename missing.
- je get_filename4 ;so go return error flag.
- cmp al,20h ;is this a blank?
- jz get_filename1 ;if so keep scanning.
- get_filename2: ;found first char of name,
- stosb ;move last char. to output
- ;file name buffer.
- lodsb ;check next character, found
- cmp al,cr ;carriage return yet?
- je get_filename3 ;yes,exit with success code.
- cmp al,'"' ;same if quote encountered.
- je get_filename3
- cmp al,20h ;is this a blank?
- jne get_filename2 ;if not keep moving chars.
- get_filename3: ;exit with carry =0
- clc ;for success flag
- ret
- get_filename4: ;exit with carry =1
- stc ;for error flag
- ret
- get_filename endp
-
-
- get_title proc near ;process title for listing
- ;DS:SI <- addr command line
- mov si,offset command
- ;ES:DI <- addr page heading buffer
- mov di,offset heading1
- cld
- lodsb ;any command line present?
- or al,al ;no,exit
- jz get_title3
- get_title1: ;scan for leading <"> to find title.
- lodsb
- cmp al,cr ;if we hit carriage return,
- je get_title3 ;title text is missing.
- cmp al,'"' ;found delimiter?
- jne get_title1 ;if so keep scanning.
- get_title2: ;get next char. of title.
- lodsb
- cmp al,'"' ;terminate if 2nd <"> delimiter
- je get_title3 ;or carriage return found
- cmp al,cr
- je get_title3
- stosb ;store this char. into page heading buffer
- jmp get_title2 ;examine next char.
- get_title3:
- ret
- get_title endp
-
- get_switch proc near ;Scan the input line for a "/"
- ;delimiting a switch, then make
- ;sure it is legal "/C" or "/c".
- ;If legal switch found, set
- ;variable COMPRESS_SWITCH true.
- mov si,offset command+1 ; DS:SI = addr of command line
- get_switch1: ;look for "/" character
- lodsb
- cmp al,cr ;if we run into a carriage return,
- jz get_switch2 ;switch missing so take normal exit.
- cmp al,'/'
- jne get_switch1 ;not '/' yet, keep looking.
- lodsb ;found '/', pick up next char.
- or al,20h ;and fold to lower case.
- cmp al,'c' ;c=compress
- jne get_switch2 ;not c, jump
- ;set compress switch
- mov es:compress_switch,-1
- get_switch2:
- ret ;exit
- get_switch endp
-
- open_input proc near ;open input file
- ;DS:DX=addr filename
- mov dx,offset input_name
- mov al,0 ;AL=0 for read only
- mov ah,3dh ;function 3dh=open
- int 21h ;handle returned in AX,
- mov input_handle,ax ;save it for later.
- ret ;CY is set if error
- open_input endp
-
- close_input proc near ;close input file
- mov bx,input_handle ;BX=handle
- mov ah,3eh
- int 21h
- ret
- close_input endp
-
- get_char proc near ;get one character from input buffer
- mov bx,input_ptr ;is pointer at end of buffer?
- cmp bx,blksize
- jne get_char1 ;no,jump
- ;yes, buffer is exhausted,
- call read_block ;new block must be read from disk.
- mov bx,0 ;initialize buffer pointer.
- get_char1:
- mov al,[input_buffer+bx]
- inc bx ;bump input buffer pointer
- mov input_ptr,bx
- ret
- get_char endp
-
- put_char proc near ;put one character into output buffer
- mov bx,output_ptr
- mov [output_buffer+bx],al
- inc output_ptr ;bump pointer to output string
- ret
- put_char endp
-
- read_block proc near ;read block of data from input file.
- mov bx,input_handle
- mov cx,blksize
- mov dx,offset input_buffer
- mov ah,3fh
- int 21h
- jnc read_block1 ;jump if no error status
- mov ax,0 ;simulate a zero length read if error
- read_block1:
- cmp ax,blksize ;was full buffer read in?
- je read_block2 ;yes,jump
- mov bx,ax ;no, store End-of-File mark
- mov byte ptr [input_buffer+bx],eof
- read_block2:
- mov input_ptr,0 ;initialize pointer to input buffer.
- ret
- read_block endp
-
- write_maybe proc near ;transmit line to list device, if
- ;output buffer contains anything.
- mov ax,output_ptr ;pointer is non-zero if characters
- or ax,ax ;are waiting in buffer.
- jz write_maybe1 ;nothing, jump to exit
- call write_line ;something there, send it to printer
- write_maybe1:
- ret
- write_maybe endp
-
- write_line proc near ;transmit contents of output
- ;buffer to the standard list device.
- mov al,lf ;append line feed to string.
- call put_char
- mov cx,output_ptr ;CX contains length of string
- ;DX:DX=buffer address
- mov dx,offset output_buffer
- mov bx,output_handle;BX=handle for standard list device.
- mov ah,40h ;function 40h=write to device.
- int 21h ;request service from DOS.
- inc linecount ;count lines printed this page.
- mov output_ptr,0 ;reset pointer to list device buffer
- ret
- write_line endp
-
- heading_maybe proc near ;print heading if the line
- ;count justifies it
- cmp linecount,pagesize
- jl heading_maybe2 ;jump,page not full yet
- call print_heading ;form feed and print title
- heading_maybe2:
- ret
- heading_maybe endp
-
- print_heading proc near ;print form feed, title, and page no.
- inc pagecount ;bump page number,
- mov ax,pagecount ;load it,
- aam ;and turn it into ASCII,
- add ax,'00'
- mov heading2,ah ;then store into heading string.
- mov heading2+1,al
- ;now print the heading string.
- mov dx,offset heading_buffer
- mov cx,heading_length
- mov bx,output_handle
- mov ah,40h
- int 21h
- ;initialize line count
- mov linecount,heading_lines
- mov column,0 ;and column counter
- ret
- print_heading endp
-
- init_buff proc near ;initialize i/o buffers
- call read_block ;read 1st block of input file
- mov output_ptr,0 ;initialize pointer to output string
- ret
- init_buff endp
-
- compress_on proc near ;turn on compressed printing mode
- ;by sending command string.
- mov cx,comp_command_length
- mov bx,output_handle
- mov dx,offset comp_command
- mov ah,40h
- int 21h
- ret
- compress_on endp
-
- compress_off proc near ;turn off compressed printing mode
- ;by sending command string.
- mov cx,norm_command_length
- mov bx,output_handle
- mov dx,offset norm_command
- mov ah,40h
- int 21h
- ret
- compress_off endp
-
- cseg ends
-
-
- data segment para public 'DATA'
-
- input_name db 64 dup (0) ;buffer for input filespec
-
- input_handle dw 0 ;token from PCDOS for input file.
-
- input_ptr dw 0 ;pointer to input blocking buffer
- output_ptr dw 0 ;pointer to output blocking buffer
-
- column dw 0 ;column count for tab processing
- linecount dw pagesize ;line counter, current page.
- ;(set to "pagesize" initially to
- ;force first heading on listing)
- pagecount dw 0 ;current page number
-
- compress_switch dw 0 ;set to -1 if /C switch
- ;found in command line tail.
-
- ; Alternate Prism Compressed Mode command added - OPR 8/23/87
- IF PRISM
- comp_command db 1fh ;Prism command string for 16 cpi mode
- ELSE
- comp_command db 0fh ;Epson command string for 16 cpi mode
- ENDIF
- comp_command_length equ $-comp_command
-
- norm_command db 12h ;command string for normal print
- norm_command_length equ $-norm_command
-
- msg1 db cr,lf
- db 'Cannot find input file.'
- db cr,lf,'$'
-
- msg2 db cr,lf
- db 'Usage: LIST [path\]filename ["Title"] [/C]'
- db cr,lf
- db ' Items in brackets are optional.'
- db cr,lf
- db ' /C flag shifts printer to compact mode.'
- db cr,lf,'$'
-
- msg3 db cr,lf
- db 'Requires PC-DOS version 2 or greater.'
- db cr,lf,'$'
-
- input_buffer db blksize dup (?) ;deblocking buffer for input file
-
- output_buffer db linesize dup (?);buffer used to build output
- ;lines for list device
-
- heading_buffer db ff ;form feed control code
- heading1 db 60 dup (' ') ;filled in with title from user
- db 'Page '
- heading2 db '00',cr
- db heading_lines dup (lf)
- heading_length equ $-heading_buffer
-
-
- data ends
-
-
- stack segment para stack 'STACK'
- db 64 dup (?)
- stack ends
-
- end list