	include	ed.inc

	.code

StoreColumn	proc	near
	Invoke	CalcColumn
	Invoke	SetEditDS
	mov	ds:CursorPos.X,ax
	Invoke	FixScreen
	Invoke	SetEditDS
	ret
StoreColumn	endp

CharLeft	proc	near
	test	di,di
	jz	@@2
	Invoke	UseCurPage
	cmp	di,bx
	je	@@1
	lea	ax,[di+size LineHeader]
	cmp	bx,ax
	jbe	@@1
	dec	bx
	cmp	bx,ax
	mov	al,0
	jne	@@3
	inc	al
	jmp	@@3
@@1:	cmp	ds:CursorPos.Y,1
	jbe	@@2
	Invoke	PackLine
	Invoke	SetEditDS
	dec	ds:CursorPos.Y
	mov	ax,ds:CursorPos.Y
	mov	ds:RedrawLine,ax
	mov	ds:CursorPos.X,-1
	Invoke	GoCurPos
	Invoke	UseCurPage
	sub	ds:CursorPos.X,ax
	mov	al,-1
	clc
	jmp	@@3
@@2:	stc
@@3:	ret
CharLeft	endp

CharRight	proc	near
	test	di,di
	jz	@@2
	cmp	di,bx
	je	@@2
	Invoke	UseCurPage
	mov	ax,es:[di].LineLength
	add	ax,size LineHeader
	add	ax,di
	cmp	bx,ax
	jae	@@1
	inc	bx
	cmp	bx,ax
	mov	al,-1
	adc	al,0
	clc
	jmp	@@3
@@1:	Invoke	CheckForLastLine
	jc	@@2
	Invoke	PackLine
	Invoke	SetEditDS
	inc	ds:CursorPos.Y
	mov	ds:CursorPos.X,1
	mov	ax,ds:CursorPos.Y
	mov	ds:RedrawLine,ax
	Invoke	GoCurPos
	Invoke	UseCurPage
	mov	al,1
	clc
	jmp	@@3
@@2:	stc
@@3:	ret
CharRight	endp

	Entry	WordLeft
	Invoke	GoCurPos
@@1:	call	CharLeft
	jc	@@4
	cmp	al,-1
	je	@@4
	Invoke	CheckDelim
	jz	@@1
@@2:	call	CharLeft
	jc	@@4
	cmp	al,-1
	je	@@3
	Invoke	CheckDelim
	jnz	@@2
@@3:	call	CharRight
@@4:	call	StoreColumn
	Exit	WordLeft

	Entry	WordRight
	Invoke	GoCurPos
	jmp	@@2
@@1:	call	CharRight
	jc	@@4
	cmp	al,-1
	je	@@4
@@2:	Invoke	CheckDelim
	jnz	@@1
@@3:	call	CharRight
	jc	@@4
	cmp	al,-1
	je	@@4
	Invoke	CheckDelim
	jz	@@3
@@4:	call	StoreColumn
	Exit	WordRight

	Entry	RightOfWord
	Invoke	GoCurPos
	jmp	@@2
@@1:	call	CharRight
	jc	@@4
@@2:	Invoke	CheckDelim
	jz	@@1
@@3:	call	CharRight
	jc	@@4
	cmp	al,-1
	je	@@4
	Invoke	CheckDelim
	jnz	@@3
@@4:	call	StoreColumn
	Exit	RightOfWord

	Entry	CursorCharRight
	Invoke	GoCurPos
	call	CharRight
	call	StoreColumn
	Exit	CursorCharRight

	Entry	CursorCharLeft
	Invoke	GoCurPos
	call	CharLeft
	call	StoreColumn
	Exit	CursorCharLeft

	Entry	CheckForLastLine
	push	di bx
	mov	ax,ds:CursorPos.Y
	inc	ax
	Invoke	FindPage
	Invoke	SetEditDS
	jc	@@1
	cmp	cx,[bx].LinesInPage
	stc
	je	@@1
	clc
@@1:	pop	bx di
	Exit	CheckForLastLine

	Entry	CheckDelim,X
	test	di,di
	jz	@@2
	cmp	di,bx
	je	@@2
	Invoke	UseCurPage
	mov	ax,es:[di].LineLength
	add	ax,size LineHeader
	add	ax,di
	cmp	bx,ax
	mov	al,es:[bx]
	jb	@@1
	mov	al,0dh
@@1:	mov	ah,0
	mov	cl,al
	and	cl,7
	shr	ax,1
	shr	ax,1
	shr	ax,1
	xchg	ax,si
	mov	ch,80h
	shr	ch,cl
	push	es bx
	les	bx,ds:CommandTable
	and	ch,es:[si].Delimiters
	pop	bx es
	xchg	ax,si
@@2:	Exit	CheckDelim

	Entry	CheckWS,X
	test	di,di
	jz	@@3
	cmp	di,bx
	je	@@3
	Invoke	UseCurPage
	mov	ax,es:[di].LineLength
	add	ax,size LineHeader
	add	ax,di
	cmp	bx,ax
	mov	al,es:[bx]
	jb	@@1
	or	al,1
	stc
	jmp	@@4
@@1:	cmp	al,' '
	je	@@2
	cmp	al,9
@@2:	clc
	jmp	@@4
@@3:	or	al,1
@@4:	Exit	CheckWS

	Entry	CursorRight
	mov	ax,ds:CursorPos.X
	inc	ax
	cmp	ax,16384
	jae	@@1
	mov	ds:CursorPos.X,ax
	Invoke	FixScreen
@@1:	Exit	CursorRight

	Entry	CursorLeft
	mov	ax,ds:CursorPos.X
	dec	ax
	jbe	@@1
	mov	ds:CursorPos.X,ax
	Invoke	FixScreen
@@1:	Exit	CursorLeft

	Entry	CursorSwitchedLeft
	test	ds:Options,eoRoamingCursor
	jz	@@1
	mov	ax,ds:CursorPos.X
	dec	ax
	jbe	@@3
	mov	ds:CursorPos.X,ax
	jmp	@@2
@@1:	cmp	ds:CursorPos.X,1
	jle	@@2
	dec	ds:CursorPos.X
	Invoke	GoCurPos
	Invoke	UseCurPage
	test	di,di
	jz	@@2
	cmp	di,bx
	je	@@2
	test	ax,ax
	jz	@@2
	mov	cx,es:[di].LineLength
	mov	dx,bx
	sub	dx,di
	sub	dx,size LineHeader
	cmp	dx,cx
	jae	@@2
	sub	ds:CursorPos.X,ax
@@2:	Invoke	FixScreen
@@3:	Exit	CursorSwitchedLeft

_ROfLine	proc	near
	Invoke	GoLine
	Invoke	SetEditDS
	inc	ax
	mov	ds:CursorPos.X,ax
	test	ds:Options,eoNoTruncate
	jnz	@@3
	push	ax
	Invoke	GoCurPos
	pop	cx
@@1:	dec	cx
	jz	@@2
	call	CharLeft
	jc	@@2
	Invoke	CheckWS
	jz	@@1
	call	CharRight
@@2:	Invoke	CalcColumn
	Invoke	SetEditDS
	mov	ds:CursorPos.X,ax
@@3:	Invoke	FixScreen
	ret
_ROfLine	endp

	Entry	ROfLine
	call	_ROfLine
	Exit	ROfLine

	Entry	RightOfLine
	call	_ROfLine
	Exit	RightOfLine

_LOfLine	proc	near
	mov	ds:CursorPos.X,1
	Invoke	FixScreen
	ret
_LOfLine	endp

	Entry	LOfLine
	call	_LOfLine
	Exit	LOfLine

	Entry	LeftOfLine
	call	_LOfLine
	Exit	LeftOfLine

_FixScreen	proc	near
	test	ds:Options,eoRoamingCursor
	jnz	@@3
	Invoke	GoCurPos
	Invoke	UseCurPage
	test	ax,ax
	jz	@@3
	mov	cx,es:[di].LineLength
	mov	dx,bx
	sub	dx,di
	sub	dx,size LineHeader
	cmp	dx,cx
	jae	@@3
	mov	ax,ds:CursorPos.X
	mov	cx,ds:TabSize
	cmp	cx,1
	jg	@@1
	inc	ax
	jmp	@@2
@@1:	add	ax,cx
	push	ax
	dec	ax
	sub	dx,dx
	div	cx
	pop	ax
	sub	ax,dx
@@2:	mov	ds:CursorPos.X,ax
@@3:	mov	ax,ds:CursorPos.X
	cmp	ax,1
	adc	ax,0
	mov	ds:CursorPos.X,ax
	sub	ax,ds:ScreenPos.X
	jb	@@4
	sub	ax,ds:WindowWidth
	jb	@@5
	inc	ax
@@4:	add	ds:ScreenPos.X,ax
@@5:	Invoke	CheckLine
	Invoke	SetEditDS
	mov	ax,ds:CursorPos.Y
	sub	ax,ds:ScreenPos.Y
	jb	@@6
	sub	ax,ds:WindowHeight
	jb	@@7
	inc	ax
@@6:	add	ds:ScreenPos.Y,ax
@@7:	clc
	ret
_FixScreen	endp

	Entry	FixScreen
	call	_FixScreen
	Exit	FixScreen

	Entry	FixScreenPos
	call	_FixScreen
	Exit	FixScreenPos

SetLine	proc	near
	push	ax
	Invoke	PackLine
	Invoke	SetEditDS
	pop	ax
	cmp	ax,1
	adc	ax,0
	mov	ds:CursorPos.Y,ax
	mov	ds:RedrawLine,ax
	Invoke	FixScreen
	Invoke	SetEditDS
	ret
SetLine	endp

	Entry	TopOfScreenRaw
	mov	ax,ds:ScreenPos.Y
	call	SetLine
	Exit	TopOfScreenRaw

	Entry	BottomOfScreenRaw
	mov	ax,ds:ScreenPos.Y
	add	ax,ds:WindowHeight
	dec	ax
	call	SetLine
	Exit	BottomOfScreenRaw

	Entry	HomeCursorRaw
	Invoke	GoTopPage
	Invoke	SetEditDS
	mov	ax,1
	mov	ds:CursorPos.X,ax
	call	SetLine
	Exit	HomeCursorRaw

	Entry	EndCursorRaw
	mov	ax,-1
	call	SetLine
	Invoke	RightOfLine
	Exit	EndCursorRaw

_Up	proc	near
	mov	ax,ds:CursorPos.Y
	cmp	ax,1
	je	@@1
	dec	ax
@@1:	call	SetLine
	ret
_Up	endp

	Entry	Up
	call	_Up
	Exit	Up

	Entry	CursorUp
	call	_Up
	Exit	CursorUp

_Down	proc	near
	mov	ax,ds:CursorPos.Y
	cmp	ax,32767
	jae	@@1
	inc	ax
@@1:	call	SetLine
	ret
_Down	endp

	Entry	Down
	call	_Down
	Exit	Down

	Entry	CursorDown
	call	_Down
	Exit	CursorDown

AdjustScroll	proc	near
	cmp	ax,1
	adc	ax,0
	push	ax
	Invoke	FindPage
	Invoke	SetEditDS
	pop	ax
	mov	cx,ds:CPFirstLine
	add	cx,[bx].LinesInPage
	cmp	ax,cx
	jae	@@1
	mov	cx,ax
	mov	ds:ScreenPos.Y,ax
@@1:	mov	ax,ds:CursorPos.Y
	mov	ds:RedrawLine,ax
	ret
AdjustScroll	endp

	Entry	ScrollScreenDown
	mov	ax,ds:ScreenPos.Y
	test	ax,ax
	jz	@@1
	dec	ax
@@1:	call	AdjustScroll
	Exit	ScrollScreenDown

	Entry	ScrollScreenUp
	mov	ax,ds:ScreenPos.Y
	cmp	ax,32767
	jae	@@1
	inc	ax
@@1:	call	AdjustScroll
	Exit	ScrollScreenUp

	Entry	PageScreenUp
	mov	ax,ds:ScreenPos.Y
	sub	ax,ds:WindowHeight
	jae	@@1
	sub	ax,ax
@@1:	inc	ax
	call	AdjustScroll
	Exit	PageScreenUp

	Entry	PageScreenDown
	mov	ax,ds:ScreenPos.Y
	dec	ax
	add	ax,ds:WindowHeight
	cmp	ax,32767
	jbe	@@1
	mov	ax,32767
@@1:	call	AdjustScroll
	Exit	PageScreenDown

	Entry	PageUpRaw
	Invoke	PackLine
	Invoke	SetEditDS
	mov	bx,ds:WindowHeight
	dec	bx
	mov	ax,ds:ScreenPos.Y
	sub	ax,bx
	ja	@@1
	mov	ax,1
@@1:	mov	bx,ax
	sub	bx,ds:ScreenPos.Y
	add	ds:CursorPos.Y,bx
	jc	@@2
	mov	ds:CursorPos.Y,1
@@2:	cmp	ds:CursorPos.Y,1
	jae	@@3
	inc	ds:CursorPos.Y
@@3:	call	AdjustScroll
	Exit	PageUpRaw

	Entry	PageDownRaw
	Invoke	PackLine
	Invoke	SetEditDS
	mov	bx,ds:WindowHeight
	dec	bx
	mov	ax,ds:ScreenPos.Y
	add	ax,bx
	jnc	@@1
	mov	ax,-1
@@1:	cmp	ax,1
	adc	ax,0
	mov	bx,ax
	sub	bx,ds:ScreenPos.Y
	add	ds:CursorPos.Y,bx
	jnc	@@2
	mov	ds:CursorPos.Y,-1
@@2:	push	ax
	Invoke	CheckLine
	pop	ax
	call	AdjustScroll
	Exit	PageDownRaw

	Entry	FixCursorPos
	mov	ax,ds:CursorPos.X
	cmp	ax,1
	adc	ax,0
	mov	ds:CursorPos.X,ax
	sub	ax,ds:ScreenPos.X
	jb	@@1
	sub	ax,ds:WindowWidth
	jb	@@2
	inc	ax
@@1:	sub	ds:CursorPos.X,ax
@@2:	Invoke	CheckLine
	Invoke	SetEditDS
	mov	ax,ds:CursorPos.Y
	sub	ax,ds:ScreenPos.Y
	jb	@@3
	sub	ax,ds:WindowHeight
	jb	@@4
	inc	ax
@@3:	jz	@@4
	push	ax
	Invoke	PackLine
	Invoke	SetEditDS
	pop	ax
	sub	ds:CursorPos.Y,ax
	sub	ds:RedrawLine,ax
@@4:	Exit	FixCursorPos

_CenterFix	proc	near
	Invoke	CheckLine
	Invoke	SetEditDS
	mov	ax,ds:CursorPos.Y
	sub	ax,ds:ScreenPos.Y
	jb	@@1
	sub	ax,ds:WindowHeight
	jb	@@3
@@1:	mov	ax,ds:WindowHeight
	cmp	ax,1
	adc	ax,0
	dec	ax
	shr	ax,1
	neg	ax
	add	ax,ds:CursorPos.Y
	jc	@@2
	mov	ax,1
@@2:	cmp	ax,1
	adc	ax,0
	mov	ds:ScreenPos.Y,ax
	jmp	@@4
@@3:	mov	ax,ds:CursorPos.X
	cmp	ax,1
	adc	ax,0
	mov	ds:CursorPos.X,ax
	sub	ax,ds:ScreenPos.X
	jb	@@4
	sub	ax,ds:WindowWidth
	jb	@@5
@@4:	mov	ds:ScreenPos.X,1
	mov	ax,ds:WindowWidth
	cmp	ds:CursorPos.X,ax
	jb	@@5
	shr	ax,1
	mov	cx,ax
	shr	ax,1
	add	ax,cx
	neg	ax
	add	ax,ds:CursorPos.X
	mov	ds:ScreenPos.X,ax
@@5:	ret
_CenterFix	endp

	Entry	CenterFixScreen
	call	_CenterFix
	Exit	CenterFixScreen

	Entry	CenterFixScreenPos
	call	_CenterFix
	Exit	CenterFixScreenPos

	Entry	CheckLine
	cmp	ds:CursorPos.X,0
	jne	@@1
	mov	ds:CursorPos.X,1
@@1:	mov	ax,ds:CursorPos.Y
	test	ax,ax
	jz	@@2
	Invoke	FindPage
	Invoke	SetEditDS
	jc	@@2
	mov	ax,ds:CPFirstLine
	add	ax,[bx].LinesInPage
	dec	ax
	jz	@@2
	cmp	ax,ds:CursorPos.Y
	jae	@@4
	jmp	@@3
@@2:	mov	ax,1
@@3:	mov	ds:CursorPos.Y,ax
	mov	ds:RedrawLine,ax
	mov	ds:CursorPos.X,1
@@4:	Exit	CheckLine

	Entry	PackLine
	test	ds:Modified,emShow+emUpdate
	jz	@@1
	mov	ax,ds:CursorPos.Y
	cmp	ax,ds:UndoBeg.Y
	jb	@@1
	cmp	ax,ds:UndoEnd.Y
	ja	@@1
	Invoke	OptimalFill
	Invoke	TruncateWS
	Invoke	SetEditDS
	test	ds:RedrawFlags,rfAny
	jz	@@1
	and	ds:RedrawFlags,not rfAny
	or	ds:RedrawFlags,rfFullScreen
@@1:	Exit	PackLine

	Entry	GetPosOffset
	Invoke	CheckLine
	Invoke	GoCurPos
	Invoke	SetEditDS
	mov	ax,bx
	sub	ax,di
	sub	ax,size LineHeader-1
	jg	@@1
	mov	ax,1
@@1:	mov	ds:ReturnCode,ax
	Exit	GetPosOffset

	end
