home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
txtutl
/
ascutils.arc
/
TABSPC.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-05-23
|
4KB
|
192 lines
PAGE 55,130
;
; TABSPC
;
bufspc equ 0400h
stkspc equ 0100h
midbuf equ 0200h
codeseg segment
assume cs:codeseg, ds:codeseg
org 100h
tabspc proc far
start: jmp init
errmsg1 db 0Dh, 0Ah, 'Read Error', 0Dh, 0Ah, '$'
errmsg2 db 0Dh, 0Ah, 'Could not get enough memory.', 0Dh, 0Ah, '$'
help_msg db 0Dh, 0Ah, 'TABSPC is a filter that converts all TABs'
db ' in the standard input to spaces in', 0Dh, 0Ah
db 'the standard output.', 0Dh, 0Ah, 0Dh, 0Ah
db 'Usage: TABSPC [<fname] [>fname]', 0Dh, 0Ah, '$'
errmsg3 db 0Dh, 0Ah, 'Write Error', 0Dh, 0Ah, '$'
; Note - space for the 1024 byte buffer and the 256 byte stack is allocated
; here, rather than being stored in the task image on disk.
;
init: mov bx,offset buffer + bufspc + stkspc ; req'd memory
add bx,010h
mov cl,4
shr bx,cl ; get it in paragraphs
mov ah,04Ah ; set it - cf=1 if error
int 021h
mov dx,offset errmsg2 ; setup err msg if needed
jc err_exit ; exit with error message.
mov ax,0
mov di,offset buffer ; else initialize buffer and
mov cx,bufspc + stkspc ; stack space to 0's
shr cx,1
cld
rep stosw
mov sp,offset buffer + bufspc + stkspc ; init sp
mov si,80h ; get cmd line char count
cmp byte ptr [si],0 ; into cx and incr by 1
je Main ; - char count 0, skip next
mov cl,[si]
inc cx
skpspc: inc si ; skip over blanks
cmp byte ptr [si],20h
loopz skpspc
jcxz Main ; skip to Main if out of chars
cmp byte ptr [si],3Fh ; '?' (for help)
jne Main ; no, ignore any others.
mov dx,offset help_msg ; output help msg to std error
jmp short err_exit
Main: call get_line ; get a line from std input
jc err_exit ; cf=1 if error
or ax,ax ; ax=0 if eof (not error)
jz norm_exit
call fix_line ; convert tabs to spaces
call put_line ; write to std output
jc err_exit ; cf=1 is error
jmp short Main ; continue.
err_exit: mov di,dx ; point di to error message
mov cx,0FFh ; set cx to 255 (arbitrary limit)
mov al,024h ; "$" line terminator
cld ; clear direction flag
repnz scasb ; scan message for char count
dec di ; decr by 1 to leave out "$"
mov cx,di ; arith. to get char count into cx
sub cx,dx
mov bx,2 ; std error handle
mov ah,040h ; output message.
int 021h
mov al,1 ; set exit status to 1 on error
norm_exit: mov ah,04Ch ; program terminate.
int 021h
tabspc endp
; SUBROUTINE
; gets a line from std input.
get_line proc near
mov si,offset buffer
get_1: mov dx,si ; point to input buffer
mov bx,0 ; std input handle
mov cx,1 ; char count = 1
mov ah,03Fh ; input a char
int 021h
jc get_err ; cf=1 if error
cmp byte ptr [si],0Ah ; eoln ?
je get_ok
or ax,ax ; ax=0 if kybd eof
jz get_ok
xor ax,ax ; make ax=0 on eof (disk)
cmp byte ptr [si],1Ah
je get_ok
inc si ; incr pointer to next loc.
jmp short get_1 ; and continue.
get_ok: clc
ret
get_err: mov dx,offset errmsg1 ; read error.
stc
ret
get_line endp
; SUBROUTINE
; This is where the transformation takes place.
; Have fun.
;
fix_line proc near
push ax
mov si,offset buffer
mov di,offset buffer + midbuf
mov dx,di
fixloop: lodsb
cmp al,9
je fix_1
stosb
cmp al,0Ah
je fix_2
jmp short fixloop
fix_1: mov cx,di
sub cx,dx
add cx,8
and cx,0FFF8h
add cx,dx
sub cx,di
mov al,20h
rep stosb
jmp short fixloop
fix_2: pop ax
mov cx,di
sub cx,dx
ret
fix_line endp
; SUBROUTINE
; Outputs a line to std output
;
put_line proc near
jcxz put_ok ; no chars? exit.
push cx ; save char count
mov dx,offset buffer + midbuf ; point to out buffer
mov bx,1 ; std out handle
mov ah,040h ; output cx chars
int 021h
pop cx ; restore cx
jc put_err ; cf=1 if error ocurred
sub cx,ax ; ax=cx if ok.
jnz put_err
put_ok: clc
ret
put_err: mov dx,offset errmsg3 ; write error
stc
ret
put_line endp
buffer db 0 ; marker to set up buffer and stack
; when program begins execution.
codeseg ends
end start