This is the past DOS era of the compilation of source code, although has passed, but for the study of the assembly is still helpful, assembly language is just a basic programmer language, most people can grasp, not necessarily in-depth research.
Name cleanf
Page 55,132
Title ' Cleanf-filter text file '
;
; Cleanf-a DOS 2.0 filter for word processing document files.
;
; Clean. ASM originally written by Ray Duncan
; Converted to DOS 2.0 filter cleanf. ASM by Bob Taylor.
;
; This is reads text from the standard input device and writes
; Filtered and transformed text to the standard output device.
;
; 1. The high bit of the all characters are stripped off.
; 2. Tabs are expanded.
; 3. Removes all control codes except
; Feeds, carriage returns, and form feeds.
; 4. Appends an end-of-file mark to the text, if
; The none is present in the input stream.
;
; Can is used to make a WordStar file acceptable for
; Other screens 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 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 are should to 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; Does the function call
or Ax,ax; Test # of Chars returned
JZ get_char1; If none, return EOF
MOV al,input_buffer; else, return to 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 the 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; Does the function call
CMP ax,1; Check to the it is 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