Metropoli BBS
VIEWER: xprt.asm MODE: TEXT (ASCII)
 name XPRT
 page 62,128
 title XPRT -- Print a File

;XPRT -- 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.
;That is, unless the /X (Translate) option is specified, then the
;special characters (>128) are translated to GEMINI STAR compatable
;format.  This should be generalized but it will do what I want.
;This translate is intended to convert files formatted for the screen
;or IBM graphics to Gemini compatability ... should work for most cases.
;Embeded form feeds codes are recognized, and tabs are expanded.
;Unknown control codes (such as the ^B and ^U codes found in WordStar
;documents) are discarded.
;
;XPRT has been designed to work with the Gemini Start 10X printer.
;Some functions should also work on EPSON printers.  Specifically,
;the basic XPRT operation is OK and the /C and /N options should
;work (but not /I, /E, /8).  Full compatability with EPSON
;will require modification of this program.
;
;This program is desinged to operate as a COM file under PC-DOS.
;It has been tested with PC-DOS 3.1 on an IBM XT.


;Used in the form:
;      A>XPRT path\filename.ext  [/S] [/8] [/f=3] [/I] [/N] ["title text"]
;	      (items in brackets are optional)
;		/T -- output set to terminal (the console or screen)
;		/C -- set COPY option
;		/6 -- set 6 lines/inch spacing
;		/8 -- set 8 lines/inch spacing
;		/f=1 -- 10cpi
;		/f=2 -- 12cpi
;		/f=3 -- 15cpi
;		/f=4 -- 17cpi
;		/f=5 -- 20cpi
;		/S -- strip high order bits from input.
;		/X -- set Gemini Translate of special characters
;		/I -- set indent
;		/N -- add sequence numbers
;		/z -- suppress eof (1ah) check -- read until len=0
;		/d=1 -- Epson
;		/d=2 -- Gemini Star 10x
;		/d=3 -- NEC P6/p7
;		/d=4 -- IBM ProPrinter

;NOTE ---
;    1. This program requires PC-DOS 2.0 or later.
;    2. The following applies to the original LIST program:
;	Version 1.0 February 28, 1984
;	Copyright (c) 1984 by Ray Duncan
;	May be freely reproduced for noncommercial use.


;STATUS --
;      Updated and extensively modified by Gene Czarcinski
;      ... This is based on Ray Duncan's LIST program.
;
;      Version 2.3, Gene Czarcinski,  October 10, 1984 - created
;      Version 2.4, Gene Czarcinski,  December 3, 1984 - updated
;	 ... add help ('?') facility
;	 ... default title is the filename
;	 ... suppress leading formfeed
;      Version 2.5, Gene Czarcinski, May 24, 1986 - updated
;	 ... add /X option
;	 ... fix read_block to handle file with no ^Z correctly
;	 ... no final ff if output to terminal
;      Version 2.6, Gene Czarcinski, June 8, 1986 - updated
;	 ... support PICA, ELITE and COMPRESSED char sets
;	 ... no RESET .. init printer each time
;      Version 2.7, Gene Czarcinski, June 9, 1986 - updated
;	 ... finish /N support
;	 ... misc. cleanup
;      Version 3.0, Gene Czarcinski, February 15, 1987 -
;	 ... renamed from LIST to XPRT
;	 ... add /S to strip high order bits from input.
;	 ... add translate (/X) option
;      Version 4.0, Gene Czarcinski, September 28, 1987 - updated
;	 ... add multi printer type support (especially NEC p6)
;	 ... add capability to just copy input (with printer control)
;	 ... change parm analysis: can be option groups and allow
;	     anywhere in command-line input string ... the slash (/) is
;	     still the only option specifier
;	 ... fixup specifying command -- MASM 5.0
;	 ... optionally suppress EOF (1ah) check


cr	equ	0dh		;ASCII CR
lf	equ	0ah		;ASCII LF
ff	equ	0ch		;ASCII FormFeed
eof	equ	01ah		;end-of-file marker
tab	equ	09h		;ASCII tab char

blksize equ	1024		;size of block reads from input file
linesize equ	250		;max length of output line
heading_lines equ 3		;number of lines in page heading

console_handle equ 1		;handle of standard console device
error_handle   equ 2		;not re-directable...std error output
list_handle    equ 4		;handle of standard list device

;----------------------------------------------------------------------------

xprt	segment para public 'CODE'

	assume cs:xprt,ds:xprt,es:xprt

	org	0080h		; location of command tail
command LABEL	BYTE		;buffer for command tail

	org	0100h

main	proc	far		;entry point from PC-DOS
	jmp	starts
;----------------------------------------------------------------------------

printer_type	db	3	;0=none (screen)
				;1=Epson FX
				;2=Gemini Star 10x
				;3=NEC p6/p7
				;4=IBM Proprinter

flg_font	db	1	;font type:
				; 1=10cpi, 2=12cpi, 3=15cpi, 4=17cpi, 5=20cpi
flg_lpi 	db	6	;lines per inch
flg_indent	db	0	;indenting flag
flg_copy	db	0	; Copy Option
flg_no_eof	db	0	; eof skip check

input_name	db	64 dup (0)	;buffer for input filespec
input_handle	dw	0		;token from PC-DOS for input file
output_handle	dw	list_handle	;the handle of the output file
input_ptr	dw	0		;pntr to input	buffer
output_ptr	dw	0		;pntr to output buffer
column		dw	0		;column count for tab processing
pagesize	dw	60		;lines/page
linenumber	dw	0		;for /N
linecount	dw	99		;line counter for current page ...
					;init to pagesize to force eject
pagecount	dw	0		;current page number
titlecount	db	0		;count for scanning title
term_switch	dw	0		;set to -1 if /T
xlate_switch	dw	0		;set to -1 if /X
strip_switch	dw	0		;set to -1 if /S
num_switch	dw	0		;set to -1 if /N
ttl_flag	dw	0		;set to -1 if title from command line

init_printer	db	32 dup (0)	;set by set_option
init_printer_length dw 0

msg1		db	cr,lf,'Cannot find INPUT file.',cr,lf,'$'
msg2		db	cr,lf,'Missing filename.',cr,lf,'$'
helpmsg db	cr,lf,'---XPRT Version 4.0, September 28, 1987---'
 db cr,lf,cr,lf
 db 'XPRT <path\filename.ext> [/t] [/n] [/i] ... "..title.."'
 db cr,lf
 db cr,lf,'  /c - plain COPY option .. no pagination'
 db cr,lf,'  /t - set output to terminal/screen'
 db cr,lf,'  /f=n font select .. n selects cpi value'
 db cr,lf,'     n=1 -- 10cpi (default)   n=4 -- 17cpi'
 db cr,lf,'     n=2 -- 12cpi             n=5 -- 20cpi'
 db cr,lf,'     n=3 -- 15cpi'
 db cr,lf,'  /6 - set 6 lines/inch'
 db cr,lf,'  /8 - set 8 lines/inch'
 db cr,lf,'  /i - set printer indent mode'
 db cr,lf,'  /s - strip input'
 db cr,lf,'  /z - skip eof check'
 db cr,lf,'  /x - set translate mode'
 db cr,lf,'  /n - sequence number the output lines'
 db cr,lf,'  /d=n - set output printer type'
 db cr,lf,'     n=1 Epson              n=3 NEC P6/P7'
 db cr,lf,'     n=2 Gemini Star 10x    n=4 IBM Proprinter'
 db cr,lf
helplen equ	$-helpmsg

help_pt db cr,lf,'Printer Type: '
help_ptl equ $-help_pt
help_pt0 db 'None'
help_pt0l equ $-help_pt0
help_pt1 db 'Epson FX'
help_pt1l equ $-help_pt1
help_pt2 db 'Gemini Star 10x'
help_pt2l equ $-help_pt2
help_pt3 db 'NEC P6/P7'
help_pt3l equ $-help_pt3
help_pt4 db 'IBM Proprinter'
help_pt4l equ $-help_pt4
help_ptx db cr,lf
help_ptxl equ $-help_ptx

;	0   1	2   3	4   5	6   7	8   9	A   B	C   D	E   F
Xtbl db 000,001,002,003,004,005,006,007,008,009,010,011,012,013,014,015 ;00
     db 016,017,018,019,020,021,022,023,024,025,026,027,028,029,030,031 ;10
     db 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;20
     db 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;30
     db 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;40
     db 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;50
     db 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;60
     db 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;70
     db 239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239 ;80*
     db 239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239 ;90*
     db 239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239 ;A0*
     db 20h,20h,20h,245,249,249,249,242,242,249,245,242,247,247,247,242 ;B0*
     db 246,248,243,244,241,250,244,244,246,240,248,243,244,241,250,248 ;C0*
     db 248,243,243,246,246,240,240,250,250,247,240,239,231,233,234,232 ;D0*
     db 20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h ;E0*
     db 20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,174,20h ;F0*


input_buffer_len dw	0		;length read
input_buffer	db	blksize dup (?) ;deblocking buffer for input file
output_number	db	'nnnnn>'
output_buffer	db	linesize dup (?); output buffer for list device

heading_buffer	db	00		;initial=null, then formfeed
heading_month	db	'00/'
heading_day	db	'00/'
heading_year	db	'00  '
heading_hh	db	'00.'
heading_mm	db	'00  '
heading1	db	40 dup (' ')    ;filled in with user's title
max_title	equ	$-heading1
		db	'  '
		db	'       Page '
heading2	db	'_____',cr
		db	heading_lines dup (lf)
heading_length	equ	$-heading_buffer

;-------Main Line Code-------------------------------------------------------

starts: push	ds		;save DS:0000 for final
	xor	ax,ax		;return to PC-DOS
	push	ax

	call	get_date	;insert formatted date/time into title
	call	get_title	;get maining title from command line tail
	call	get_option	;process (switch) options
	call	get_filename	;get path anbd file spec. for input file
				;from the command line tail.
	mov	ax,es		;set DS=ES for remainder of pgm
	mov	ds,ax

	jnc	main15		;jump, got accesptable name
	mov	dx,offset msg2	;missing or illegal filespec
	jmp	main9		;print error msg and exit

main15: mov	al,input_name	;check if help wanted
	cmp	al,'?'
	jne	main19		;continue
	call	display_info
	ret			;return to DOS

main19: call	open_input	;now try to open the inpuyt file
	jnc	main2		;jump if opened OK
	mov	dx,offset msg1	;open failed for input file
	jmp	main9		;print error msg and exit

main2:	call	set_option

	cmp	term_switch,0	;console (/s) or printer ?
	je	main22		;printer

	mov	ax,console_handle ; init for console
	mov	output_handle,ax
	mov	al,0		;if console, set formfeed to null
	mov	heading_buffer,al
	jmp	main25		;skip printer init code

main22: mov	dx,offset init_printer
	mov	cx,init_printer_length
	mov	bx,output_handle
	mov	ah,40h
	int	21h

main25: 			;initialize input deblocking buffer
	call	read_block	;get first block
	mov	output_ptr,0	;set output to null
	mov	linenumber,0
	cmp	input_buffer_len,0
	jne	main3
	jmp	main8

main3:				;file successfully opened.
				;now print it.
	call	get_char	;read 1 char from input
	cmp	al,20h		;is it a control code?
	jae	main4		;no, write it to main device.
				;yes, it is a control code
	cmp	al,eof		;is it e-o-f marker?
	je	main8		;yes, go close files
	cmp	al,tab		;is it a tab char?
	je	main5		;yes, go to special processing.
	cmp	al,ff		;us it a FormFeed?
	je	main54		;yes, goto special processing
	cmp	al,cr		;if it is an illegal control code,
	jne	main3		;discard it and get next char.
	mov	al,lf		;insert a line feed
	call	put_char

	mov	al,cr		;restore reg
	call	put_char

	mov	column,0	;if C/R, store it into output
	jmp	main53		;string and initialize column output.

main4:	inc	column		;count chars sent on this line.

main45: call	put_char	;write this char into forming output string.

	cmp	output_ptr,linesize-1  ;about to overflow?
	je	main53		;yes,force print to buffer.
	jmp	main3		;no,get next char

main5:	mov	ax,column	;process tab char .. let DX:AX=column count
	cwd
	mov	cx,8		;divide by 8
	idiv	cx
	sub	cx,dx		;remainder is in DX
	add	column,cx	;update column pntr
main51: 			;8 minus the remainder.
	push	cx		;gives the number of spaces
	mov	al,20h		;to send out to move to
	call	put_char	;the next tyab position.
	pop	cx		;restore space count
	loop	main51
	jmp	short main3	;get next char


main53: 		;line-feed detected, interprete as print command.
	call	heading_maybe	;print heading if needed.
	call	write_line	;print output buffer
	jmp	main3		;continue

main54: 			;handle a form-feed
	call	write_maybe	;FormFeed detected ..
				;if anything waiting in output buffer,
				;print it first.
	call	print_heading	;new page and print title
	jmp	main3		;continue

main8:				;end-of-file detected
	call	write_maybe	;print if anything waiting ...

main81: cmp	term_switch,0	;Console output?
	jne	main83		;yes, skip ff
	mov	al,ff		;send FormFeed to finish maining
	call	put_char
	call	write_line
main83: mov	bx,input_handle ;BX=handle --- close the input file
	mov	ah,3eh		;close
	int	21h
main85: ret			;return to PC-DOS

main9:			;come here to print error message
	mov	ah,9		;and return to dos
	int	21h
	ret

main	endp

display_info proc near		;display some help info
	mov	dx,offset helpmsg
	mov	cx,helplen
	mov	bx,console_handle
	mov	ah,40h
	int	21h
	mov	dx,offset help_pt
	mov	cx,help_ptl
	mov	bx,console_handle
	mov	ah,40h
	int	21h
	mov	dx,offset help_pt1
	mov	cx,help_pt1l
	cmp	printer_type,1
	je	info_9
	mov	dx,offset help_pt2
	mov	cx,help_pt2l
	cmp	printer_type,2
	je	info_9
	mov	dx,offset help_pt3
	mov	cx,help_pt3l
	cmp	printer_type,3
	je	info_9
	mov	dx,offset help_pt4
	mov	cx,help_pt4l
	cmp	printer_type,4
	je	info_9
	mov	dx,offset help_pt0
	mov	cx,help_pt0l
info_9: mov	bx,console_handle
	mov	ah,40h
	int	21h
	mov	dx,offset help_ptx
	mov	cx,help_ptxl
	mov	bx,console_handle
	mov	ah,40h
	int	21h
	ret
display_info endp


get_filename proc near		;process name of the 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_filename9
get_filename1:	lodsb		;scan over leading blanks to file name
	cmp	al,20h		;blank?
	je	get_filename1	;yes, keep scanning.
	cmp	al,cr		;C/R?
	jne	get_filename1a
get_filename1x:
	jmp	get_filename9
get_filename1a:
	cmp	al,'/'          ;or switch?
	jne	get_filename1b
get_filename1aL:
	lodsb
	cmp	al,cr
	je	get_filename1x
	cmp	al,' '
	jne	get_filename1aL
	jmp	get_filename1
get_filename1b:
	cmp	al,'"'          ;or quote mark (filename missing)
	jne	get_filename2	;no, found filename
get_filename1bL:
	lodsb
	cmp	al,cr
	je	get_filename1x
	cmp	al,'"'
	jne	get_filename1bL
	jmp	get_filename1

get_filename2:
	push	si		;save for title
	push	ax

get_filename4: stosb		;found first char of name
				;move last char to output filename buffer
	lodsb			;check next char found
	cmp	al,cr		;C/R yet?
	je	get_filename5	;yes,exit with success code
	cmp	al,'"'          ;quote encountered?
	je	get_filename5
	cmp	al,20h		;blank?
	jne	get_filename4	;no, keep moving chars
get_filename5:
	pop	ax		;get saved values (and restore stack)
	pop	si
	test	ttl_flag,-1	;was a title specified?
	jnz	get_filename8	;yes, exit.
	mov	di,offset heading1
	mov	bl,max_title+1
	mov	titlecount,bl
get_filename7: stosb
	lodsb
	dec	titlecount
	jz	get_filename8
	cmp	al,cr		;test for end
	je	get_filename8
	cmp	al,'"'
	je	get_filename8
	cmp	al,20h
	jne	get_filename7
get_filename8:
	clc			;for success flag
	ret
get_filename9:			;exit with carry=1 for error flag
	stc
	ret
get_filename endp


get_title proc near		;process title for listing
	mov	al,max_title+1
	mov	titlecount,al
	mov	si,offset command    ;DS:SI <- addr command line
	mov	di,offset heading1   ;ES:DI <- addr page heading buffer
	cld
	lodsb			;any command line present?
	or	al,al		;no, exit
	jz	get_title3
get_title1:	lodsb		;scan for leading <"> to find title.
	cmp	al,cr		;C/R?
	je	get_title3	;yes, title text missing.
	cmp	al,'"'          ;delimiter found?
	jne	get_title1	;no, continue scanning
	mov	ttl_flag,-1	;indicate title specified
get_title2:	lodsb		;get next char of title
	cmp	al,'"'          ;terminate if second <"> char
	je	get_title3	;or C/R found.
	cmp	al,cr
	je	get_title3
	stosb			;store char into page heading buffer
	dec	titlecount
	jnz	get_title2	;and continue scan
get_title3:  ret
get_title endp


get_date proc near		;get date/time, insert into title
	mov	ah,2Ch		;time-of-day
	int	21h
	xor	ax,ax
	mov	al,ch
	aam			;convert to decimal chars
	add	ax,'00'
	mov	heading_hh,ah
	mov	heading_hh+1,al
	xor	ax,ax
	mov	al,cl
	aam
	add	ax,'00'
	mov	heading_mm,ah
	mov	heading_mm+1,al
	mov	ah,2Ah		;get date
	int	21h
	xor	ax,ax		;clear
	mov	al,dl		;do day
	aam
	add	ax,'00'
	mov	heading_day,ah
	mov	heading_day+1,al
	xor	ax,ax		;clear
	mov	al,dh		;do month
	aam
	add	ax,'00'
	mov	heading_month,ah
	mov	heading_month+1,al
	mov	ax,cx		;do year
	sub	ax,1900
	aam
	add	ax,'00'
	mov	heading_year,ah
	mov	heading_year+1,al
	ret
get_date endp



get_option proc near		;Scan the input line and determine the
				;run-time options (parameters).
	mov	si,offset command+1  ;DS:SI=addr of command line
	cld
gopt00: lodsb			;look for "/"
gopt01: cmp	al,cr		;C/R?
	jne	gopt03		;not end, continue
gopt02: ret			;exit
gopt03: cmp	al,' '          ;blank?
	je	gopt00		;yes, try next
	cmp	al,'"'          ;title?
	jne	gopt08		;no, continue
gopt05: lodsb
	cmp	al,cr
	je	gopt02
	cmp	al,'"'
	je	gopt00
	jmp	gopt05
gopt08: cmp	al,'/'          ;is this and option?
	je	gopt10		;yes, process option
gopt09: lodsb			;find next parm
	cmp	al,cr
	je	gopt02		;exit	?
	cmp	al,'/'
	je	gopt10
	cmp	al,' '          ;end of this parm?
	jne	gopt09		;no, continue
	jmp	gopt00		;yes

gopt10: lodsb			;found, get next char
	or	al,20h		;fold to lower case

	cmp	al,'f'
	jne	gopt18
	lodsb
	cmp	al,'='
	jne	gopt01
	lodsb
	cmp	al,'1'
	jb	gopt01
	cmp	al,'5'
	ja	gopt01
	and	al,07h
	mov	flg_font,al
	jmp	gopt09
gopt18:
	cmp	al,'x'          ;x=translate
	jne	gopt20
	mov	xlate_switch,-1 ;set translate
	jmp	gopt09
gopt20: cmp	al,'s'          ;s=strip
	jne	gopt24
	mov	strip_switch,-1 ;set input-strip
	jmp	gopt09
gopt24: cmp	al,'t'          ;t=terminal (the console or screen)
	jne	gopt26
	mov	term_switch,-1 ;set print switch
	jmp	gopt09
gopt26: cmp	al,'i'          ;i=indent
	jne	gopt30
	mov	flg_indent,-1	;set indent switch
	jmp	gopt09
gopt30: cmp	al,'8'
	jne	gopt32
	mov	flg_lpi,8	;8 lpi
	jmp	gopt09
gopt32: cmp	al,'6'
	jne	gopt40
	mov	flg_lpi,6	;6 lpi
	jmp	gopt09
gopt40: cmp	al,'n'          ;n=number (sequence numbering)
	jne	gopt50
	mov	num_switch,-1	;set sequence numbering switch
	jmp	gopt09
gopt50: cmp	al,'c'          ;COPY
	jne	gopt60
	mov	flg_copy,-1
	jmp	gopt09
gopt60: cmp	al,'d'          ;Device spec
	jne	gopt70
	lodsb
	cmp	al,'='
	je	gopt62
gopt61: jmp	gopt01
gopt62: lodsb
	cmp	al,'1'
	jb	gopt61
	cmp	al,'4'
	ja	gopt61
	and	al,07h
	mov	printer_type,al
	jmp	gopt09
gopt70: cmp	al,'z'
	jne	gopt80
	mov	flg_no_eof,-1
	jmp	gopt09
gopt80: jmp	gopt09

get_option endp

set_option proc near		;set run-time options
	cld
	mov	di,offset init_printer
	mov	init_printer_length,0


sopt10: cmp	printer_type,1	;Epson
	jne	sopt20
	mov	al,012h
	stosb
	inc	init_printer_length
	cmp	flg_font,1	;10cpi?
	je	sopt11		;yes
	mov	al,0fh		;everything else
	stosb
	inc	init_printer_length
sopt11: mov	al,01bh 	; set lines/inch vertical
	stosb
	mov	pagesize,60	;assume 6 lpi
	mov	al,50
	cmp	flg_lpi,8
	jne	sopt14
	mov	pagesize,80	;set 8 lpi
	mov	al,48
sopt14: stosb
	add	init_printer_length,2
	jmp	sopt90

sopt20: cmp	printer_type,2	;Gemini Star 10x
	jne	sopt30
	mov	al,01bh 	; set font
	stosb
	mov	al,042h
	stosb
	mov	al,1		;10cpi
	mov	bl,3
	cmp	flg_font,1
	je	sopt21
	mov	al,2		;12cpi
	mov	bl,4
	cmp	flg_font,2
	je	sopt21
	mov	al,3		;15,17cpi -- and everything else
	mov	bl,5
sopt21: stosb
	mov	al,01bh 	;set indent
	stosb
	mov	al,04dh
	stosb
	mov	al,0
	cmp	flg_indent,0
	je	sopt22
	mov	al,bl
sopt22: stosb
	mov	al,01bh 	; set lines/inch vertical
	stosb
	mov	pagesize,60	;assume 6 lpi
	mov	al,50
	cmp	flg_lpi,8
	jne	sopt24
	mov	pagesize,80	;set 8 lpi
	mov	al,48
sopt24: stosb
	add	init_printer_length,8
	jmp	sopt90

sopt30: cmp	printer_type,3	;NEC p6/p7
	je	sopt31
	jmp	sopt40
sopt31: mov	al,012h 	;cancel condensed
	stosb
	inc	init_printer_length
	mov	bl,0
	cmp	flg_font,1	;10cpi
	jne	sopt32
	mov	al,01bh
	stosb
	mov	al,05dh
	stosb
	add	init_printer_length,2
	mov	bl,3
	jmp	sopt36
sopt32: cmp	flg_font,2	;12cpi
	jne	sopt33
	mov	al,01bh
	stosb
	mov	al,04dh
	stosb
	add	init_printer_length,2
	mov	bl,4
	jmp	sopt36
sopt33: cmp	flg_font,3	;15cpi
	jne	sopt34
	mov	al,01bh
	stosb
	mov	al,067h
	stosb
	add	init_printer_length,2
	mov	bl,5
	jmp	sopt36
sopt34: cmp	flg_font,4	;17cpi
	jne	sopt35
	mov	al,01bh
	stosb
	mov	al,05dh
	stosb
	mov	al,0fh
	stosb
	add	init_printer_length,3
	mov	bl,5
	jmp	sopt36
sopt35: cmp	flg_font,5	;20cpi
	jne	sopt36
	mov	al,01bh
	stosb
	mov	al,04dh
	stosb
	mov	al,0fh
	stosb
	add	init_printer_length,3
	mov	bl,6
	jmp	sopt36
sopt36: mov	al,01bh 	;set indent
	stosb
	mov	al,06ch
	stosb
	mov	al,0
	cmp	flg_indent,0
	je	sopt37
	mov	al,bl
sopt37: stosb
	add	init_printer_length,3
	mov	al,01bh 	; set lines/inch vertical
	stosb
	mov	pagesize,60	;assume 6 lpi
	mov	al,50
	cmp	flg_lpi,8
	jne	sopt39
	mov	pagesize,80	;set 8 lpi
	mov	al,48
sopt39: stosb
	add	init_printer_length,2
	jmp	sopt90

sopt40: cmp	printer_type,4	;IBM Proprinter
	jne	sopt50
	cmp	flg_font,1	;10cpi
	jne	sopt42
	mov	al,012h
	stosb
	inc	init_printer_length
	jmp	sopt46
sopt42: cmp	flg_font,2	;12cpi
	jne	sopt43
	mov	al,01bh
	stosb
	mov	al,03ah
	stosb
	add	init_printer_length,2
	jmp	sopt46
sopt43: 			;17cpi and everything else
	mov	al,0fh
	stosb
	inc	init_printer_length
	jmp	sopt46
sopt46:
	mov	al,01bh 	; set lines/inch vertical
	stosb
	mov	pagesize,60	;assume 6 lpi
	mov	al,50
	cmp	flg_lpi,8
	jne	sopt49
	mov	pagesize,80	;set 8 lpi
	mov	al,48
sopt49: stosb
	add	init_printer_length,2
	jmp	sopt90
sopt50:
	jmp	sopt90

sopt90:
	ret
set_option endp


open_input proc near		;open the input file
	mov	dx,offset input_name  ;DS:DX=addr filename
	mov	al,0		;read-only
	mov	ah,3dh		;function=3dh for open
	int	21h		;handle return in ax
	mov	input_handle,ax ;save it for later
	ret			;CY is set if error
open_input endp


get_char proc near		;get one char from input buffer
get_char0:
	mov	bx,input_ptr	;is pntr at end of buffer?
	cmp	bx,blksize
	jne	get_char1	;no
	call	read_block	;yes, new block must be read
	mov	bx,0		;init pntr
	mov	input_ptr,bx
	cmp	input_buffer_len,0  ;end?
	jne	get_char1	;no, continue
	mov	al,eof
	ret
get_char1: mov	al,[input_buffer+bx]
	inc	bx		;inc pntr
	mov	input_ptr,bx
	cmp	al,20h		;is it a control code?
	jae	get_char6	;no, continue.
	cmp	flg_no_eof,0
	je	get_char9	;not skiping eof's
	cmp	al,eof
	je	get_char0
	ret
get_char6: cmp strip_switch,0	;stripping?
	je	get_char7	;no
	and	al,7fh		;yes
	ret
get_char7: cmp	xlate_switch,0	;translating?
	je	get_char9
	cmp	al,80h		;special char?
	jae	get_char8	;yes
	ret			;no
get_char8: mov	bx,0		;yes, do xlate
	mov	bl,al
	mov	al,[Xtbl+bx]
	ret
get_char9:
	ret
get_char endp


put_char proc near		;put one char into output buffer
	mov	bx,output_ptr
	mov	[output_buffer+bx],al  ;insert char in buffer
	inc	output_ptr	;and update pntr/counter
	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	;if no error
	mov	ax,0		;fake zero length if error
read_block1:
	mov	input_buffer_len,ax
	cmp	ax,blksize	;was a full buffer read?
	je	read_block2	;yes
	mov	bx,ax		;no, store e-o-f mark
	mov	byte ptr [input_buffer+bx],eof
read_block2: mov input_ptr,0	;init pntr to input buffer
	ret
read_block endp


write_maybe proc near		;output line if buffer contains anything
	mov	ax,output_ptr	;pntr is non-zero if data in buffer
	or	ax,ax
	jz	write_maybe1	;nothing, exit
	call	write_line	;something is there, output it.
write_maybe1: ret
write_maybe  endp


write_line	proc near	;transmit contents of output buffer to
				;the standard list device.

	cmp	num_switch,0
	je	write_line5
	inc	linenumber
	mov	ax,linenumber
	mov	bx,offset output_number
	call	Convert
write_line5:
	mov	cx,output_ptr	;CX contains length of string
	mov	dx,offset output_buffer ;DX:DX=buffer addr
	cmp	num_switch,0
	je	write_line7
	add	cx,6
	mov	dx,offset output_number
write_line7:
	mov	bx,output_handle;BX=handle for standard list device.
	mov	ah,40h		;function 40h = write to device
	int	21h
	inc	linecount	;for lines/page
	mov	output_ptr,0	;reset buffer pntr
	ret
write_line endp


heading_maybe proc near 	;print heading if linecount justifies it
	cmp	flg_copy,0
	jne	heading_maybe2	;skip ff if just on linecount
	mov	ax,linecount
	cmp	ax,pagesize
	jb	heading_maybe2	;page not full yet.
	call	print_heading	;FormFeed and print heading
heading_maybe2: ret
heading_maybe	endp


print_heading proc near 	;PRINT FormFeed, title and Page Number
	inc	pagecount	;update page number
	mov	ax,pagecount	;get it and convert to ascii
	mov	bx,offset heading2
	call	Convert
	mov	dx,offset heading_buffer ;now print the heading string
	mov	cx,heading_length
	cmp	flg_copy,0
	je	print_heading_3
	mov	cx,1
print_heading_3:
	mov	bx,output_handle
	mov	ah,40h
	int	21h
	test	term_switch,-1	;console output?
	jne	print_heading_5
	mov	al,ff		;printer, set formfeed after first one.
	mov	heading_buffer,al
print_heading_5:
	mov	linecount,heading_lines  ;init line count
	mov	column,0	;and column counter
	ret
print_heading endp

Convert proc near		;convert binary to ASCII
	push	dx
	push	si
	mov	cx,5
Conv1:	mov	byte ptr [bx],' '  ;clear buffer
	inc	bx
	loop	Conv1
	mov	si,10		   ;to get digits
	or	ax,ax		   ;force positive
	jns	conv5
	neg	ax
Conv5:	sub	dx,dx
	div	si		   ;divide by 10
	add	dx,'0'
	dec	bx
	mov	[bx],dl 	   ;insert digit into output
	or	ax,ax		   ;if zero, done
	jnz	Conv5
	pop	si
	pop	dx
	ret
Convert endp

xprt	ends

	end main


[ RETURN TO DIRECTORY ]