Metropoli BBS
VIEWER: up&down.asm MODE: TEXT (ASCII)
; UP&DOWN.ASM for E32 - Copyright (C) 1994 Douglas Herr
;  all rights reserved

include	model.inc

public	up, down, screen_dn, screen_up
extrn	find_cr:near
extrn	find_start:near
extrn	shift_right:near
extrn	find_previous:near
extrn	find_next:near

include	dataseg.inc
extrn	undo_length:dword, cur_posn:word, cursor:dword
extrn	top_of_screen:dword, dirty_bits:byte, rows:byte
extrn	filesiz:dword, mark_mode:byte
extrn	file_row:dword, saved_pos:word, first_row:byte
extrn	display_mode:byte

page_proc	dd 0			; for PGUP, PGDN

up_proc		dd offset up_ascii
		dd offset up_hex
down_proc	dd offset down_ascii
		dd offset down_hex

@curseg	ends

include	codeseg.inc

up	proc	near

;
;   this moves the cursor up one row.  If the cursor is at the first
;   row, the screen is scrolled down.
;

	mov	dx,cur_posn
	movzx	esi,display_mode
	jmp	up_proc[esi]

up_hex:
	mov	esi,cursor
	sub	esi,10h
	jnc	short save_cursor_hex
	clc
	ret

save_cursor_hex:
	mov	cursor,esi
	dec	dh
	cmp	dh,first_row
	jae	short exit_up_hex
	inc	dh
	mov	eax,top_of_screen
	sub	eax,10h
	jnc	short save_screen_top
	xor	eax,eax
save_screen_top:
	mov	top_of_screen,eax
exit_up_hex:
	mov	cur_posn,dx
	or	dirty_bits,1
	ret

up_ascii:
	push	es
	mov	undo_length,0
	push	fs
	pop	es
	mov	esi,cursor
	dec	dh			; move cursor up one row
	cmp	dh,first_row
	jb	short screen_dn		; if at top row then scroll down
	dec	file_row
	call	find_cr			; find the beginning of this row
	mov	cursor,esi
	call	find_start		; find start of this row
	mov	cursor,esi
	call	shift_right		; skip over to current column
at_top:	clc
	pop	es
	ret

screen_dn:
	mov	esi,top_of_screen
	or	esi,esi		; at start of file?
	jz	at_top		; if at top then do nothing
	mov	saved_pos,-1	; refresh row, col on top line
	push	fs
	pop	es
	call	find_previous	; find the preceeding line
	mov	top_of_screen,esi
	dec	file_row
	mov	esi,cursor
	call	find_previous	; find the preceeding line
	mov	cursor,esi	; this is the new cursor
shift_ret:
	or	dirty_bits,1	; need to redraw screen
	mov	esi,cursor
	mov	dx,cur_posn
	call	shift_right	; move cursor to current column
exit:	clc
	pop	es
	ret
up	endp

down	proc	near

;
; This moves the cursor down one row.  When the last
; row is reached, the screen is shifted up one row.
;
	push	es
	push	fs
	pop	es
	mov	dx,cur_posn
	movzx	esi,display_mode
	jmp	down_proc[esi]

down_hex:
	mov	esi,cursor
	add	esi,10h
	cmp	esi,filesiz
	jae	down_ret

	mov	cursor,esi
	inc	dh
	cmp	dh,rows
	jbe	short down_hex1
	add	top_of_screen,10h
	jmp	short down_hex2

down_hex1:
	mov	cur_posn,dx

down_hex2:
	or	dirty_bits,1
	pop	es
	ret

;
; file displayed in ASCII mode
;
down_ascii:
	mov	undo_length,0
	cmp	dh,rows		; at bottom row already?
	mov	esi,cursor	; get position in file
	jae	short screen_up	; if at bottom, scroll up
	call	find_next	; find the start of the next line
	jc	short down_ret	; if no more lines, then return
	mov	cursor,esi
	inc	dh		; advance cursor to next row
	inc	file_row
	call	shift_right	; move cursor to next column
down_ret:
	clc
	pop	es
	ret

screen_up:
	mov	esi,cursor	; get position in file
	cmp	esi,filesiz	; get cursor offset
	je	down_ret
	mov	saved_pos,-1	; refresh row, col on top line
	push	fs
	pop	es
	call	find_start	; find the start of this line
	mov	cursor,esi	; this is the new cursor
	call	find_next	; find the offset of next line
	jc	shift_ret	; if no more lines the return
	inc	file_row
	mov	cursor,esi	; this is the new cursor
	mov	esi,top_of_screen	; get the start of the top row
	call	find_next	; and find the next line
	mov	top_of_screen,esi	; store the new top of screen
	jmp	shift_ret
down	endp

@curseg	ends


; PGUP, PGDN
;
; These two routines move the screen one page at
; a time by calling the UP and DOWN procedures.

public	pgdn, pgup

include	codeseg.inc
pgdn	proc	near
	mov	page_proc,offset down
page_up_dn:
	movzx	ecx,rows	; get the length of the screen
	sub	cl,4		; don't page a full screen
	sub	cl,first_row
page_loop:
	push	ecx
	call	page_proc	; move the cursor down
	pop	ecx
	loop	page_loop
	clc
	ret
pgdn	endp

pgup	proc	near
	mov	page_proc,offset up
	jmp	page_up_dn
pgup	endp

@curseg	ends
	end
[ RETURN TO DIRECTORY ]