You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.7 KiB
NASM
136 lines
3.7 KiB
NASM
;
|
|
; This program reads text from the standard input device and writes
|
|
; filtered and transformed text to the standard output device.
|
|
;
|
|
; 1. High bit of all characters is stripped off.
|
|
; 2. Tabs are expanded.
|
|
; 3. Removes all control codes except for line
|
|
; feeds, carriage returns, and form feeds.
|
|
; 4. Appends an end-of-file mark to the text, if
|
|
; none was present in the input stream.
|
|
;
|
|
; Can be used to make a WordStar file acceptable for
|
|
; other screen or line editors, and vice versa.
|
|
;
|
|
;
|
|
cr equ 0dh ; ASCII carriage return
|
|
lf equ 0ah ; ASCII line feed
|
|
ff equ 0ch ; ASCII form feed
|
|
eof equ 01ah ; End-of-file marker
|
|
tab equ 09h ; ASCII tab code
|
|
|
|
command equ 80h ; buffer for command tail
|
|
|
|
; DOS 2.0 Pre-Defined Handles
|
|
|
|
stdin equ 0000 ; standard input file
|
|
stdout equ 0001 ; standard output file
|
|
stderr equ 0002 ; standard error file
|
|
stdaux equ 0003 ; standard auxilliary file
|
|
stdprn equ 0004 ; standard printer file
|
|
|
|
cseg segment para public 'CODE'
|
|
|
|
assume cs:cseg,ds:cseg
|
|
|
|
org 100H ; start .COM at 100H
|
|
|
|
clean proc far ; entry point from PC-DOS.
|
|
push ds ; push a long return back
|
|
xor ax,ax ; to DOS onto the stack.
|
|
push ax
|
|
|
|
clean3: call get_char ; get a character from input.
|
|
and al,7fh ; turn off the high bit.
|
|
cmp al,20h ; is it a control char?
|
|
jae clean4 ; no. write it to output.
|
|
cmp al,eof ; is it end of file?
|
|
je clean6 ; yes, go write EOF mark and exit.
|
|
cmp al,tab ; is it a tab?
|
|
je clean5 ; yes, go expand it to spaces.
|
|
cmp al,cr ; is it a carriage return?
|
|
je clean35 ; yes, go process it.
|
|
cmp al,lf ; is it a line feed?
|
|
je clean35 ; yes, go process it.
|
|
cmp al,ff ; is it a form feed?
|
|
jne clean3 ; no. discard it.
|
|
clean35:
|
|
mov column,0 ; if it's a legit ctrl char,
|
|
jmp clean45 ; we should be back at column 0.
|
|
|
|
clean4: inc column ; if it's a non-ctrl char,
|
|
clean45: ; col = col + 1.
|
|
call put_char ; write the char to output.
|
|
jnc clean3 ; if OK, go back for another char.
|
|
|
|
mov bx,stderr ; not OK. Set up to show error.
|
|
mov dx,offset err_msg
|
|
mov cx,err_msg_len ; error = Disk full.
|
|
mov ah,40h ; write the error message
|
|
int 21h ; to the standard error device. (CON:)
|
|
ret ; back to DOS.
|
|
|
|
clean5: mov ax,column ; tab code detected, must expand
|
|
cwd ; expand tabs to spaces.
|
|
mov cx,8 ; divide the current column counter
|
|
idiv cx ; by eight...
|
|
sub cx,dx ; eight minus the remainder is the
|
|
add column,cx ; number of spaces to send out to
|
|
clean55: ; move to the next tab position.
|
|
push cx
|
|
mov al,20h
|
|
call put_char ; send an ASCII blank
|
|
pop cx
|
|
loop clean55
|
|
jmp clean3
|
|
|
|
clean6: call put_char ; write out the EOF mark,
|
|
ret ; and return to DOS.
|
|
|
|
clean endp
|
|
|
|
|
|
get_char proc near
|
|
mov bx,stdin ; get chars from std. input
|
|
mov cx,1 ; # of chars to get = 1
|
|
mov dx,offset input_buffer ; location = input_buffer
|
|
mov ah,3fh
|
|
int 21h ; do the function call
|
|
or ax,ax ; test # of chars returned
|
|
jz get_char1 ; if none, return EOF
|
|
mov al,input_buffer ; else, return the char in AL
|
|
ret
|
|
get_char1:
|
|
mov al,eof ; no chars read, return
|
|
ret ; an End-of-File (EOF) mark.
|
|
get_char endp
|
|
|
|
put_char proc near
|
|
mov output_buffer,al ; put char to write in buffer.
|
|
mov bx,stdout ; write to std. output
|
|
mov cx,1 ; # of chars = 1
|
|
mov dx,offset output_buffer ; location = output_buffer
|
|
mov ah,40h
|
|
int 21h ; do the function call
|
|
cmp ax,1 ; check to see it was really done.
|
|
jne put_char1
|
|
clc ; really done. return carry = 0
|
|
ret ; as success signal.
|
|
put_char1:
|
|
stc ; not really done. return carry = 1
|
|
ret ; as error signal (device is full).
|
|
put_char endp
|
|
|
|
input_buffer db 0
|
|
output_buffer db 0
|
|
|
|
column dw 0
|
|
|
|
err_msg db cr,lf
|
|
db 'clean: Disk is full.'
|
|
db cr,lf
|
|
err_msg_len equ (this byte)-(offset err_msg)
|
|
|
|
cseg ends
|
|
|
|
end clean |