Metropoli BBS
VIEWER: lst14-3.asm MODE: TEXT (ASCII)
;
; *** Listing 14-3 ***
;
; Copies a zero-terminated string to another string,
; filtering out non-printable characters by means of a
; subroutine that performs the test. The subroutine is
; invoked with a JMP and returns with a JMP through a
; register.
;
	jmp	Skip
;
SourceString	label	byte
	db	'This is a sample string, consisting of '
X=1
	rept	31
	db	X
X=X+1
	endm
	db	7fh
	db	'both printable and non-printable '
	db	'characters', 0
DestinationString	label	byte
	db	200 dup (?)
;
; Determines whether a character is printable (in the range
; 20h through 7Eh).
;
; Input:
;	AL = character to check
;	BP = return address
;
; Output:
;	Zero flag set to 1 if character is printable,
;		set to 0 otherwise
;
; Registers altered: none
;
IsPrintable:
	cmp	al,20h
	jb	IsPrintableDone	;not printable
	cmp	al,7eh
	ja	IsPrintableDone	;not printable
	cmp	al,al	;set the Zero flag to 1, since the
			; character is printable
IsPrintableDone:
	jmp	bp	;return to the address in BP
;
; Copies a zero-terminated string to another string,
; filtering out non-printable characters.
;
; Input:
;	DS:SI = source string
;	ES:DI = destination string
;
; Output: none
;
; Registers altered: AL, SI, DI, BP
;
; Direction flag cleared
;
; Note: Does not handle strings that are longer than 64K
;	bytes or cross segment boundaries.
;
CopyPrintable:
	cld
	mov	bp,offset IsPrintableReturn
				;set the return address for
				; IsPrintable. Note that
				; this is done outside the
				; loop for speed
CopyPrintableLoop:
	lodsb			;get the next byte to copy
	jmp	IsPrintable	;is it printable?
IsPrintableReturn:
	jnz	NotPrintable	;nope, don't copy it
	stosb			;put the byte in the
	     			; destination string
	jmp	CopyPrintableLoop ;the character was
				; printable, so it couldn't
				; possibly have been 0. No
				; need to check whether it
				; terminated the string
NotPrintable:
	and	al,al		;was that the
				; terminating zero?
	jnz	CopyPrintableLoop ;no, do next byte
	stosb			;copy the terminating zero
	ret			;done
;
Skip:
	call	ZTimerOn
	mov	di,seg DestinationString
	mov	es,di
	mov	di,offset DestinationString
			;ES:DI points to the destination
	mov	si,offset SourceString
			;DS:SI points to the source
	call	CopyPrintable	;copy the printable
				; characters
	call	ZTimerOff

[ RETURN TO DIRECTORY ]