home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
txtutl
/
ascutils.arc
/
RMCOL.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-05-20
|
5KB
|
192 lines
PAGE 55,132
; RMCOL
; This program takes lines from std input and trims 'count' columns
; beginning with column 'start+1'. Syntax is:
; RMCOL n1<delim>n2 [<file1] [>[>file2]] where n1 is the start col-1
; (0 to 256), n2 is the # of cols to remove (may be 0), <delim> is any
; number of tabs or spaces with an optional single comma, and files
; are as usual for std in and std out.
codeseg segment
assume cs:codeseg, ds:codeseg
org 100h
rmcol proc far
start: jmp Main
errmsg db 0Dh, 0Ah, 'RMCOL: Invalid arguments', 0Dh, 0Ah, '$'
start_col dw 0
col_count dw 0
Main: mov si,81h ; point si to PSP
call skip_spc ; skip white space
call get_dec ; get first number
jc error ; cf=1 on error
mov start_col,cx ; save value
call skip_spc
call get_dec
jc error
mov col_count,cx ; save column count
Main_loop: call get_line ; get a line
jc Exit ; cf=1 on error or eof
call doit ; remove the columns
call put_line ; output the line
jmp short Main_loop ; continue until cf=1
error: mov dx,offset errmsg ; error message exit
mov ah,9
int 021h
Exit: int 020h ; program exit.
rmcol endp
; SUBROUTINE
; skips white space
skip_spc proc near
skip1: cmp byte ptr [si],020h
jne skip2
inc si
jmp short skip1
skip2: cmp byte ptr [si],9
jne skip_ret
inc si
jmp short skip1
skip_ret: ret
skip_spc endp
; SUBROUTINE
; converts ASCII decimal int to binary int
get_dec proc near
xor cx,cx ; start with cx=0
dec1: mov al,[si] ; get char
cmp al,020h ; space indicates end of numerals
je dec_ret
cmp al,9 ; so does tab
je dec_ret
inc si
cmp al,02Ch ; and comma
je dec_ret
dec si
cmp al,03Ah ; ascii range of char ok so far
jb dec2
stc ; ascii out of range - exit cf=1
jmp short dec_ret
dec2: sub al,030h ; if numeral, cvt to binary
jc dec_ret ; not a numeral, exit cf=1
shl cx,1 ; cx = cx * 2
mov dx,cx ; save cx * 2
shl cx,1 ; cx * 4
shl cx,1 ; cx * 8
add cx,dx ; cx * 8 + cx * 2 = cx * 10d
cbw ; convert al byte to word
add cx,ax ; add 1's to 10's
mov ax,0FFh ; 255d = max line length
cmp ax,cx ; if cx > 255 then error
jb dec_ret
inc si ; otherwise continue.
jmp short dec1
dec_ret: ret ; ret with cf=1 for error or cf=0 for success
get_dec endp
; SUBROUTINE
; gets line from std input
get_line proc near
mov si,offset buffer ; point to input line buffer
get_1: mov dx,si ; chars are input to ds:dx
mov cx,1 ; char count
mov bx,0 ; std input handle
mov ah,3Fh ; get char from std in
int 21h
jc get_line_ret ; error - exit cf=1
cmp byte ptr [si],0Ah
je get_line_ret
mov cx,ax ; get # input chars into cx
cmp byte ptr [si],1Ah ; check for eof
stc
jz get_line_ret ; eof - exit cf=1
jcxz get_line_ret ; 0 chars input - exit cf=1
inc si ; point to next char
cmp si,offset buffer+254 ; max line - 2
jae get_end ; truncate long lines.
jmp short get_1 ; else continue.
get_end: mov byte ptr [si],0Dh
mov byte ptr [si+1],0Ah
clc
get_line_ret: ret
get_line endp
; SUBROUTINE
; This is where the columns get removed
doit proc near
mov cx,start_col
mov si,offset buffer ; input buffer
mov di,offset buffer+256 ; copy buffer
start_loop: jcxz doit_1 ; start removing at col 1
lodsb ; otherwise, copy start_col chars
stosb ; to copy buffer
cmp al,0Dh ; (premature eoln)
je doit_2
loop start_loop ; loop cx to 0
doit_1: mov cx,col_count ; get count in cx
middle_loop: jcxz doit_2 ; col count 0 ? copy whole line.
lodsb ; else skip over cx chars.
cmp al,0Dh ; premature eoln, finish up now.
je end_loop
loop middle_loop
jmp short doit_2 ; if middle loop was executed, skip
; this next stosb instr.
end_loop: stosb
doit_2: lodsb
cmp byte ptr [si-2],0Ah ; now copy chars until eoln.
jne end_loop
ret
doit endp
; SUBROUTINE
; Output line to std output
put_line proc near
mov si,offset buffer+256 ; set up pointers to the
mov dx,si ; copy (output) buffer.
xor cx,cx
loc_6: inc cx
lodsb
cmp al,0Ah
jne loc_6 ; count chars to eoln into cx
mov bx,1 ; handle for std out
mov ah,40h
int 21h
ret ; cf=1 if error
put_line endp
buffer db 0 ; line input buffer - this makes the
; program look smaller, but it uses 512 bytes
; past the 'end' of the coded listing. This
; may be extended arbitrarily, but with risk.
codeseg ends
end start