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

include	model.inc

public	left, right
extrn	sh_left:near
extrn	sh_right:near
extrn	cursor_col:near
extrn	up:near
extrn	down:near

CR	equ	13

include	dataseg.inc
extrn	cursor:dword
extrn	left_margin:word, dirty_bits:byte
extrn	save_column:byte, undo_length:byte
extrn	filesiz:dword, cur_posn:word, display_mode:byte

home_proc	dd offset home_ascii
		dd offset home_hex
endd_proc	dd offset end_ascii
		dd offset end_hex
left_proc	dd offset left_ascii
		dd offset left_hex
right_proc	dd offset right_ascii
		dd offset right_hex

@curseg	ends

include	codeseg.inc
;----------------------------------------------------------------------
;   These routines move the cursor left and right
;----------------------------------------------------------------------
left	proc	near
	movzx	edx,display_mode
	jmp	left_proc[edx]

;
; file is displayed in hex mode
;
left_hex:
	mov	esi,cursor
	mov	dx,cur_posn
	sub	esi,1
	jc	short lr_no_change

	sub	dl,3
	cmp	dl,10
	jb	short move_up
	mov	cur_posn,dx
	mov	cursor,esi
	ret

;
; file is displayed in ASCII mode
;
left_ascii:
	cmp	cursor,0		; at start of file?
	jz	short lr_no_change	; can't move left
	mov	dx,cur_posn

left2:	test	dl,dl			; at first screen column?
	jne	short move_cursor_left
	cmp	left_margin,0
	jz	short move_up		; if yes, move up one
	call	sh_left			; move window to show cursor
	jmp	left2

move_cursor_left:
	dec	cursor			; shift the cursor offset
lr_return:
	call	cursor_col		; compute column for cursor
	mov	save_column,dl		; save the cursor column
lr_no_change:
	mov	undo_length,0
	clc
	ret

move_up:
	call	up			; move up to next row
	call	endd			; and move to end of line
	ret
left	endp

;
; advance cursor one byte in file
;
right	proc	near
	mov	esi,cursor
	cmp	esi,filesiz		; at the end of file?
	je	short lr_no_change	; if yes, can't move
	movzx	eax,display_mode
	jmp	right_proc[eax]

;
; file displayed in hex mode
;
right_hex:
	inc	esi
	cmp	esi,filesiz
	jae	short lr_no_change
	test	esi,0Fh			; ZF = 1 if next line
	jz	short move_down
	mov	cursor,esi
	and	esi,0Fh
	mov	edx,esi
	shl	edx,1
	add	edx,esi
	add	dl,10
	mov	byte ptr cur_posn,dl
	ret

;
; file displayed in ASCII mode
;
right_ascii:
	push	es
	push	fs
	pop	es
	cmp	byte ptr es:[esi],cr	; at end of line?
	pop	es
	je	short move_down		; if yes, then move down
	inc	cursor			; advance the cursor
	jmp	lr_return

move_down:
	call	home			; move to start of line
	call	down			;    and move down one row
	ret
right	endp

@curseg	ends


; HOME
;
;  move the cursor to the start of the current line
;
public	home
extrn	find_start:near
extrn	find_eol:near

include	codeseg.inc

home	proc	near

	movzx	esi,display_mode
	jmp	home_proc[esi]

home_hex:
	and	cursor,0ffffFFF0h
	mov	byte ptr cur_posn,10
	ret

home_ascii:
	push	es
	call	find_start		; find start of line
	mov	cursor,esi		; save the new cursor
	mov	save_column,0		; save the cursor column
	mov	byte ptr cur_posn,0	; store column number
	cmp	left_margin,0
	je	short home_ret
	mov	left_margin,0
	or	dirty_bits,1		; redraw screen if shift needed

home_ret:
	clc
	pop	es
	ret
home	endp


; ENDD
;
;  move the cursor to the end of the current line
;

public	endd

endd	proc	near
	movzx	esi,display_mode
	jmp	endd_proc[esi]

end_hex:
	mov	esi,cursor
	mov	dx,cur_posn
	or	esi,0Fh			; move to end of line
	cmp	esi,filesiz		; past end of file?
	jb	short end_hex_cursor	;  no, continue

; limit offset to last character in file
	mov	esi,filesiz
	dec	esi

; save offset & calculate cursor position
end_hex_cursor:
	mov	cursor,esi
	and	esi,0Fh
	mov	edx,esi
	shl	esi,1
	add	edx,esi
	add	dl,10
	mov	byte ptr cur_posn,dl
	ret

end_ascii:
	mov	esi,cursor
	call	find_eol		; find the end of this line
	mov	cursor,esi		; store the new cursor
	call	cursor_col		; compute the correct column
	mov	save_column,dl		; save the cursor column
	ret
endd	endp

@curseg	ends



; SHIFT_RIGHT
;
;  This subroutine adjusts the cursor position ahead to
;  the saved cursor column.  On entry DH has the cursor row.
;

public	shift_right

include	codeseg.inc
shift_right	proc	near
	movzx	cx,save_column
	mov	bp,cx
	add	cx,left_margin
	xor	dl,dl
	mov	cur_posn,dx	; get cursor row/col
	jcxz	no_change
	push	fs
	pop	es
right_again:
	push	ecx
	cmp	esi,filesiz
	jae	short dont_move
	cmp	byte ptr es:[esi],CR	; at end of line?
	je	short dont_move
	call	right
dont_move:
	pop	ecx
	movzx	ax,save_column
	cmp	ax,cx		; is cursor still in margin?
	jl	short in_margin	; yup, keep moving
	mov	dx,cur_posn
	xor	dh,dh
	cmp	dx,bp			; at saved cursor position?
	je	short right_done	; if yes, we're done
	ja	short right_too_far	; did we go too far?
in_margin:
	loop	right_again
right_done:
	mov	cx,bp
	mov	save_column,cl	; get back saved cursor position
no_change:
	ret

right_too_far:
	call	left		; move back left one place
	jmp	right_done

shift_right	endp

@curseg	ends
	end
[ RETURN TO DIRECTORY ]