Metropoli BBS
VIEWER: lst13-14.asm MODE: TEXT (ASCII)
;
; *** Listing 13-14 ***
;
; Copies a zero-terminated string to another string,
; optionally converting characters to uppercase. The
; decision as to whether to convert to uppercase is made
; once at the beginning of the subroutine; if conversion
; is not desired, the register containing the value of the
; start of the lowercase range is simply set to cause all
; tests for lowercase to fail. This avoids one test in the
; case where conversion to uppercase is desired, since the
; single test for the start of the lowercase range is able
; to perform both that test and the test for whether
; conversion is desired.
;
	jmp	Skip
;
SourceString	label	byte
	db	'This is a sample string, consisting of '
	db	'both uppercase and lowercase characters.'
	db	0
DestinationString	label	byte
	db	100 dup (?)
;
; Copies a zero-terminated string to another string,
; optionally converting characters to uppercase.
;
; Input:
;	DL = 1 if conversion to uppercase during copying is
;		desired, 0 otherwise
;	DS:SI = source string
;	ES:DI = destination string
;
; Output: none
;
; Registers altered: AX, SI, DI
;
; Direction flag cleared
;
; Note: Does not handle strings that are longer than 64K
;	bytes or cross segment boundaries.
;
CopyAndConvert:
	cld
	mov	ah,0ffh	;assume conversion to uppercase is
			; not desired. In that case, this
			; value will cause the initial
			; lowercase test to fail (except
			; when the character is 0FFh, but
			; that's rare and will be rejected
			; by the second lowercase test
	and	dl,dl	;is conversion to uppercase desired?
	jz	CopyAndConvertLoop	;no, AH is all set
	mov	ah,'a'	;set the proper lower limit of the
			; lowercase range
CopyAndConvertLoop:
	lodsb				;get the next byte
					; to check
	cmp	al,ah			;less than 'a'?
					; (If conversion
					; isn't desired,
					; AH is 0FFh, and
					; this fails)
	jb	CopyAndConvertUC	;yes, not lowercase
	cmp	al,'z'			;greater than 'z'?
	ja	CopyAndConvertUC	;yes, not lowercase
	and	al,not 20h		;make it uppercase
CopyAndConvertUC:
	stosb				;put the byte in the
					; destination string
	and	al,al			;was that the
					; terminating zero?
	jnz	CopyAndConvertLoop	;no, do next byte
	ret
;
Skip:
	call	ZTimerOn
;
; First, copy without converting to uppercase.
;
	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
	sub	dl,dl	;don't convert to uppercase
	call	CopyAndConvert	;copy without converting
				; to uppercase
;
; Now copy and convert to uppercase.
;
	mov	di,offset DestinationString
			;ES:DI points to the destination
	mov	si,offset SourceString
			;DS:SI points to the source
	mov	dl,1	;convert to uppercase this time
	call	CopyAndConvert	;copy and convert to
				; uppercase
	call	ZTimerOff

[ RETURN TO DIRECTORY ]