Metropoli BBS
VIEWER: locate.asm MODE: TEXT (ASCII)
; LOCATE.ASM for E32

include	model.inc

public	locate
extrn	find_start:near, find_cr:near
extrn	cursor_col:near

cr	equ	13

include	dataseg.inc
extrn	cursor:dword, top_of_screen:dword, cur_posn:word, save_column:byte
extrn	first_row:byte, window_row:byte, display_mode:byte, filesiz:dword

locate_proc	dd _ascii
		dd _hex

@curseg	ends

include	codeseg.inc
;-------------------------------------------------------------------------;
;   This subroutine positions the screen with the cursor at the row       ;
;   selected in register DH.  On entry, ESI holds the cursor offset.      ;
;-------------------------------------------------------------------------;
locate	proc	near
	mov	cursor,esi
	sub	dh,first_row
	movzx	eax,display_mode
	jmp	locate_proc[eax]

_hex:
; limit offset to file size
	mov	eax,filesiz
	dec	eax
	cmp	esi,eax
	jb	short _hex0
	mov	esi,eax
_hex0:
	mov	cursor,esi
	mov	eax,esi
	and	esi,0ffffFFF0h
	sub	eax,esi
	mov	dl,al		; column offset
	shl	al,1
	add	dl,al
	add	dl,10		; cursor pos
	mov	al,dh		; save row offset
	add	dh,first_row

	mov	bl,10h
	mul	bl
	movzx	eax,ax
	sub	esi,eax
	jnc	short _hex9
	neg	esi
	mov	eax,esi
	div	bl
	sub	dh,al
	xor	esi,esi
_hex9:
	mov	cur_posn,dx
	mov	top_of_screen,esi
	ret

_ascii:
	push	es
	movzx	ecx,dh
	xor	edx,edx		; start at the top of the window
	test	esi,esi		; at start of buffer?
	jz	short locate_first
	call	find_start	; get start of this row
	test	esi,esi		; is cursor at start of file?
	jz	short locate_first
	jecxz	locate_first	; if locating to top row, we're done
	push	fs
	pop	es
find_top:
	push	esi
	push	ecx
	call	find_CR
	pop	ecx
	pop	eax
	cmp	byte ptr es:[esi],CR
	jne	short locate_first
	cmp	esi,eax
	je	short locate_done
	inc	dh
	loop	find_top
locate_done:
	push	cursor
	mov	cursor,esi
	call	find_start
	pop	cursor
locate_first:
	mov	top_of_screen,esi
	add	dh,first_row
	mov	cur_posn,dx
	call	cursor_col
	mov	save_column,dl
	pop	es
	ret
locate	endp

@curseg	ends
	end
[ RETURN TO DIRECTORY ]