Metropoli BBS
VIEWER: findchr.asm MODE: TEXT (ASCII)
; FINDCHR.ASM for E32 - Copyright (C) 1994 Douglas Herr
;  all rights reserved

; call with FS = file selector

include	model.inc

public	find_start, find_CR
public	find_next, find_eol
public	find_previous

CR	equ	0Dh
LF	equ	0Ah

include	dataseg.inc

extrn	cursor:dword
extrn	filesiz:dword

@curseg	ends

include	codeseg.inc

;
; This subroutine finds the beginning of the previous line
;
find_previous	proc
	push	fs
	pop	es
	push	cursor
	call	find_CR		; find start of this line
	mov	cursor,esi
	call	find_start	; find the start of this line
	pop	cursor
	ret
find_previous	endp

;
; This searches for the previous CR, starting at ESI
;
find_CR	proc	near
	push	ecx
	push	fs
	pop	es
	mov	al,cr
	mov	edi,esi
	mov	ecx,esi
	jecxz	short at_beginning
	dec	edi
	std
	repne	scasb
	cld
	inc	edi
	mov	esi,edi
at_beginning:
	pop	ecx
	ret
find_CR	endp

;-------------------------------------------------------------------------;
;   This subroutine computes the location of the start of current line.   ;
;   Returns ESI pointing to the first character of the current line.      ;
;-------------------------------------------------------------------------;
find_start	proc	near
	mov	esi,cursor
	test	esi,esi		; at start of file?
	jz	short at_start
	call	find_CR
	call	skipCRLF
at_start:
	ret
find_start	endp

;-------------------------------------------------------------------------;
;   This finds the offset of the start of the next line.  The search is   ;
;   started at location ES:SI.  On return CF = 1 if no CR was found.      ;
;-------------------------------------------------------------------------;
find_next	proc
	push	ecx
	call	find_eol
	jc	short at_next
	call	skipCRLF
	clc
at_next:pop	ecx
	ret
find_next	endp

;----------------------------------------------------;
;   This searches for the next CR in the file.       ;
;   The search starts at the offset in register SI.  ;
;----------------------------------------------------;
find_eol	proc near
	mov	al,CR		; look for CR
	push	fs
	pop	es
	mov	ecx,filesiz	; last letter in file
	sub	ecx,esi		; count for the search
	mov	edi,esi
	jecxz	short at_end
	repne	scasb
	mov	esi,edi
	jecxz	short at_end
	dec	esi
	clc
	ret
at_end:	stc
	ret
find_eol	endp


; skipCRLF
;
; This subroutine skips past the CR and LF at ESI
; ESI returns new offset.
;
; call with: ESI = position in file
;            FS = file selector
; uses: ES, ESI

skipCRLF:
	push	es
	push	fs
	pop	es
	cmp	esi,filesiz		; at last character in file?
	jae	short no_skip		; if so, no skip
	cmp	byte ptr es:[esi],CR	; at CR?
	jne	short no_skip
	inc	esi			; look at next char
	cmp	esi,filesiz		; at last char in file?
	jae	short no_skip
	cmp	byte ptr es:[esi],LF	; at LF?
	jne	short no_skip
	inc	esi
no_skip:
	pop	es
	ret

@curseg	ends
	end
[ RETURN TO DIRECTORY ]