·汇编源码--BRK
·汇编源码--CLOCK
·汇编源码--BURNOUT
·汇编源码--DOSSYM
·汇编源码--circle
·汇编源码--DEV
·汇编源码--getspace
·汇编源码--CLEAR
·汇编源码--col
·汇编源码--gameport
nameclean
page55,132
title'CLEAN --- Filter text file'
;
; CLEAN --- a utility to filter text files.
; This program removes all control codes except
; for line feeds, carriage returns, and form
; feeds, strips off the high bit of all characters,
; and expands tabs. Can be used to make a Wordstar
; file acceptable for other screen or line editors,
; and vice versa.
;
; version 1.1 10 Dec 83 Blocking/deblocking
; version 1.0 25 Nov 83
;
; Copyright (c) 1983 by Ray Duncan
crequ0dh;ASCII carriage return
lfequ0ah;ASCII line feed
ffequ0ch;ASCII form feed
eofequ01ah;End of file marker
tabequ09h;ASCII tab character
commandequ80h;buffer for command tail
blksizeequ1024;blocking/deblocking size
csegsegmentpara public 'CODE'
assumecs:cseg,ds:data,es:data,ss:stack
cleanprocfar;entry point from PC-DOS
pushds;save DS:0000 for final
xorax,ax;return to PC-DOS
pushax
movax,data;make our data segment
moves,ax;addressable via ES register
callinfile;get path and file spec.
;for input file
movax,es;set DS=ES for remainder
movds,ax;of program
jncclean1;jump, got acceptable name
movdx,offset msg4;missing or illegal filespec,
jmpclean9;print error message and exit.
clean1:calloutfile;set up output file name
callopen_input;now try to open input file
jncclean2;jump,opened input ok
movdx,offset msg1;open of input file failed,
jmpclean9;print error msg and exit.
clean2:
callopen_output;try to open output file.
jncclean25;jump,opened ok
movdx,offset msg2;open of output file failed,
jmpclean9;print error message and exit.
clean25:;set up buffers
callinit_buffs
callsign_on;print ident and file names
;files successfully opened,
clean3:;now filter the file.
callget_char;read 1 character from input.
andal,07fh;strip off the high bit
cmpal,20h;is it a control code?
jaeclean4;no,write it to new file
;yes it is control code,
cmpal,eof;is it end of file marker?
jeclean6;yes,jump to close files.
cmpal,tab;is it a tab command?
jzclean5;yes,jump to special processing.
cmpal,cr;if control code other than
jeclean35;tab or end-of-file mark, throw
cmpal,ff;it away unless it is a
jeclean35;form feed, carriage return,
cmpal,lf;or line feed.
jneclean3
clean35:;If it is one of those three,
movcolumn,0;incidentally initialize
jmpclean45;column count for tab processor.
clean4:;count alphanumeric chars. sent.
inccolumn
clean45:;write this character to
callput_char;output file,
jncclean3;if CY not set, write was
;ok so go get next char.
clean47:
callclose_input;if CY set, disk is full
callclose_output;so close files and exit
movdx,offset msg5 ;with error message.
jmpclean9
clean5:;process tab character
movax,column;let DX:AX=column count
cwd
movcx,8;divide it by eight...
idivcx
subcx,dx;remainder is in DX.
addcolumn,cx;update column pointer.
clean55:;8 minus the remainder
pushcx;gives us the number of
moval,20h;spaces to send out to
callput_char;move to the next tab position
popcx;restore space count
jcclean47;jump if disk is full
loopclean55
jmpshort clean3;get next character
clean6:;end of file detected,
callput_char;write end-of-file marker,
jcclean47;jump if disk was full
callflush_buffs;write remaining data to disk
jcclean47;if CY set,disk was full
;otherwise file was written ok
callclose_input;close input and output
callclose_output;files.
movdx,offset msg3;addr of success message,
clean9:;print message and return
movah,9;control to PC-DOS
int21h
ret
cleanendp
infileprocnear;process name of input file
;DS:SI <- addr command line
movsi,offset command
;ES:DI <- addr filespec buffer
movdi,offset input_name
cld
lodsb;any command line present?
oral,al;return error status if not.
jzinfile4
infile1: ;scan over leading blanks
lodsb;to file name
cmpal,cr;if we hit carriage return
jzinfile4 ;filename is missing.
cmpal,20h;is this a blank?
jzinfile1;if so keep scanning.
infile2: ;found first char of name,
stosb;move last char. to output
;file name buffer.
lodsb;check next character, found
cmpal,cr;carriage return yet?
jeinfile3;yes,exit with success code
cmpal,20h;is this a blank?
jne infile2;if not keep moving chars.
infile3: ;exit with carry =0
clc;for success flag
ret
infile4: ;exit with carry =1
stc;for error flag
ret
infile endp
outfileprocnear;set up path and file
cld;name for output file.
movcx,64;length to move
movsi,offset input_name ;source addr
movdi,offset output_name ;dest addr
rep movsb;transfer the string
movdi,offset output_name
outfile1:;scan string looking for
moval,[di] ;"." marking start of extension
oral,al;or zero byte marking name end.
jzoutfile2;if either is found,jump.
cmpal,'.'
jeoutfile2;bump string pointer, loop
incdi;if neither '.' or zero found.
jmpoutfile1
outfile2:;found zero or '.',force the
;extension of the output file
;to '.CLN'
movsi,offset outfile_ext
movcx,5
rep movsb
ret;back to caller
outfile endp
open_input proc near;open input file
;DS:DX=addr filename
movdx,offset input_name
moval,0;AL=0 for read only
movah,3dh;function 3dh=open
int 21h;handle returned in AX,
movinput_handle,ax ;save it for later.
ret;CY is set if error
open_input endp
open_output proc near;open output file
;DS:DX=addr filename
movdx,offset output_name
moval,1;AL=1 for writeonly
movah,3ch;function 3ch=MAKE or
int21h;truncate existing file
;handle returned in AX
movoutput_handle,ax;save it for later.
ret;return CY=true if error
open_output endp
close_input proc near;close input file
movbx,input_handle ;BX=handle
movah,3eh
int21h
ret
close_input endp
close_output proc near;close output file
movbx,output_handle;BX=handle
movah,3eh
int21h
ret
close_output endp
get_char proc near;get one character from input buffer
movbx,input_ptr
cmpbx,blksize
jneget_char1
callread_block
movbx,0
get_char1:
moval,[input_buffer+bx]
incbx
movinput_ptr,bx
ret
get_char endp
put_char procnear;put one character into output buffer
movbx,output_ptr
mov[output_buffer+bx],al
incbx
movoutput_ptr,bx
cmpbx,blksize;buffer full yet?
jneput_char1;no,jump
callwrite_block;yes,write the block
ret;return CY as status code
put_char1:
clc;return CY clear for OK status
ret
put_char endp
read_block proc near
movbx,input_handle ;read first block of input
movcx,blksize
movdx,offset input_buffer
movah,3fh
int21h
jncread_block1;jump if no error status
movax,0;simulate a zero length read if error
read_block1:
cmpax,blksize;was full buffer read in?
jeread_block2;yes,jump
movbx,ax;no, store End-of-File mark
movbyte ptr [input_buffer+bx],eof
read_block2:
xorax,ax;initialize input buffer pointer
movinput_ptr,ax
ret
read_block endp
write_block proc near;write blocked output (blksize bytes)
movdx,offset output_buffer
movcx,blksize
movbx,output_handle
movah,40h
int21h
xorbx,bx;initialize pointer to blocking buffer
movoutput_ptr,bx
cmpax,blksize;was correct length written?
jnewrite_block1;no,disk must be full
clc;yes,return CY=0 indicating all OK
ret
write_block1:;disk is full, return CY =1
stc;as error code
ret
write_block endp
init_buffs proc near
callread_block;read 1st block of input
xorax,ax;initialize pointer to output
movoutput_ptr,ax;output blocking buffer
ret
init_buffs endp
flush_buffs proc near;write any data in output buffer to disk
movcx,output_ptr
orcx,cx
jzflush_buffs1;jump,buffer is empty
movbx,output_handle
movdx,offset output_buffer
movah,40h
int21h
cmpax,output_ptr;was write successful?
jnzflush_buffs2;no,jump
flush_buffs1:
clc;yes,return CY=0 for
ret;success flag
flush_buffs2:;disk was full so write failed,
stc;return CY=1 as error flag
ret
flush_buffs endp
sign_on procnear;print sign-on message
movdx,offset msg6;title...
movah,9
int21h
movdx,offset msg7;input file:
movah,9
int21h
movdx,offset input_name
callpasciiz
movdx,offset msg8;output file:
movah,9
int21h
movdx,offset output_name
callpasciiz
movdx,offset msg9
movah,9
int21h
ret
sign_onendp
pasciizprocnear;call DX=offset of ASCIIZ string
movbx,dx;which will be printed on standard output
pasciiz1:
movdl,[bx]
ordl,dl
jzpasciiz9
cmpdl,'A'
jbpasciiz2
cmpdl,'Z'
japasciiz2
ordl,20h
pasciiz2:
movah,2
int21h
incbx
jmppasciiz1
pasciiz9:
ret
pasciiz endp
csegends
datasegmentpara public 'DATA'
input_namedb64 dup (0);buffer for input filespec
output_namedb64 dup (0);buffer for output filespec
input_handledw0;token returned by PCDOS
output_handledw0;token returned by PCDOS
input_ptrdw0;pointer to input blocking buffer
output_ptrdw0;pointer to output blocking buffer
outfile_extdb '.CLN',0;extension for filtered file
columndw0;column count for tab processing
msg1dbcr,lf
db'Cannot find input file.'
dbcr,lf,'$'
msg2dbcr,lf
db'Failed to open output file.'
dbcr,lf,'$'
msg3dbcr,lf
db'File processing completed'
dbcr,lf,'$'
msg4dbcr,lf
db'Missing file name.'
dbcr,lf,'$'
msg5dbcr,lf
db'Disk is full.'
dbcr,lf,'$'
msg6dbcr,lf
db'Clean Word Processing File'
dbcr,lf
db'Copyright (c) 1983 Laboratory Microsystems Inc.'
dbcr,lf,'$'
msg7dbcr,lf,'Input file: $'
msg8dbcr,lf,'Output file: $'
msg9dbcr,lf,'$'
input_bufferdbblksize dup (?);buffer for deblocking of data
;from input file
output_bufferdbblksize dup (?);buffer for blocking of data
;sent to output file
data ends
stacksegmentpara stack 'STACK'
db64 dup (?)
stackends
endclean
进入讨论组讨论。