home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
xprt.asm
< prev
next >
Wrap
Assembly Source File
|
1987-09-27
|
26KB
|
1,007 lines
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