	include	ed.inc

	.code

	Entry	GetNewPage
	push	ds:PageSize
	SetTurboDS
	Invoke	GetVMem
	mov	bx,ax
	or	bx,dx
	jz	@@2
	push	di
	mov	es,dx
	mov	di,ax
	mov	bx,es:[di]
	cmp	bx,VMemLimit
	ja	@@1
	push	dx ax
	push	dx ax
	Invoke	UseHandle
	pop	ax dx
	mov	es,dx
	mov	di,ax
	mov	bx,es:[di]
	cmp	bx,VMemLimit
	jbe	@@2
@@1:	xor	di,di
	mov	es,bx
	mov	es:[di].CurLineNum,-1
	pop	di
	clc
	jmp	@@3
@@2:	Invoke	SetEditDS
	mov	ax,erNoVirtMem
	mov	ds:ReturnCode,ax
	or	ds:Errors,al
	sub	ax,ax
	sub	dx,dx
	stc
@@3:	Exit	GetNewPage

	Entry	GoTopPage
	mov	ds:CurPage,offset PageTbl
	mov	ds:CPFirstLine,1
	Exit	GoTopPage

	Entry	InsertPageToEnd
	push	ds:CurPage
	mov	ax,ds:LastPage
	mov	ds:CurPage,ax
	Invoke	InsertPage
	Invoke	SetEditDS
	pop	ds:CurPage
	Exit	InsertPageToEnd

	Entry	ExpandPageTable
	add	ax,ds:LastPage
	jc	@@2
	cmp	ax,ds:PageTblSize
	jbe	@@1
	cmp	ax,VMemPageSize
	ja	@@2
	push	ax
	les	bx,ds:Handle
	push	es bx ax
	SetTurboDS
	Invoke	ReallocVMem
	Invoke	SetEditDS
	pop	ds:PageTblSize
@@1:	clc
	jmp	@@3
@@2:	mov	ax,erFileTooLarge
	or	ds:Errors,al
	mov	ds:ReturnCode,ax
	stc
@@3:	Exit	ExpandPageTable

	Entry	InsertPage
	push	si di es
	mov	ax,ds:PageTblSize
	sub	ax,size PageInfo
	sub	ax,ds:LastPage
	jae	@@3
	mov	ax,ds:PageTblSize
	add	ax,16
	jc	@@1
	cmp	ax,VMemPageSize
	jbe	@@2
@@1:	mov	ax,erFileTooLarge
	or	ds:Errors,al
	mov	ds:ReturnCode,ax
	jmp	@@4
@@2:	les	bx,ds:Handle
	push	es bx ax
	SetTurboDS
	Invoke	ReallocVMem
	Invoke	SetEditDS
	add	ds:PageTblSize,16
@@3:	Invoke	GetNewPage
	Invoke	SetEditDS
	mov	bx,ax
	or	bx,dx
	jnz	@@5
@@4:	sub	ax,ax
	sub	dx,dx
	stc
	jmp	@@7
@@5:	push	dx ax
	push	ds
	pop	es
	mov	si,ds:LastPage
	lea	di,[si+size PageInfo]
	mov	ds:LastPage,di
	std
	mov	cx,si
	sub	cx,ds:CurPage
	jz	@@6
	sub	cx,size PageInfo
	shr	cx,1
@@6:	dec	si
	dec	si
	dec	di
	dec	di
	rep	movsw
	cld
	pop	ax dx
	inc	si
	inc	si
	mov	[si].PageHandle.Offs,ax
	mov	[si].PageHandle.Segm,dx
	sub	di,di
	mov	[si].LinesInPage,di
	mov	[si].FirstLineNumber,di
	mov	[si].PageLength,size PageHeader
	or	ds:RedrawFlags,rfPageChanged
	clc
@@7:	pop	es di si
	Exit	InsertPage

	Entry	GoNextPage
	mov	ax,ds:CurPage
	mov	bx,ax
	add	ax,size PageInfo
	cmp	ax,ds:LastPage
	jae	@@1
	mov	ax,[bx].LinesInPage
	add	ds:CPFirstLine,ax
	add	ds:CurPage,size PageInfo
	clc
	jmp	@@2
@@1:	stc
@@2:	Exit	GoNextPage

	Entry	DeleteNextPage
	mov	bx,ds:CurPage
	add	bx,size PageInfo
	cmp	bx,ds:LastPage
	jae	@@1
	mov	dx,[bx].PageHandle.Segm
	mov	bx,[bx].PageHandle.Offs
	Invoke	FreePage
	Invoke	SetEditDS
	push	ds
	pop	es
	mov	di,ds:CurPage
	add	di,size PageInfo
	lea	si,[di+size PageInfo]
	mov	cx,ds:LastPage
	sub	cx,si
	jb	@@1
	shr	cx,1
	cld
	rep	movsw
	mov	ds:LastPage,di
	jmp	@@1
@@1:	Exit	DeleteNextPage

	Entry	QuickCompactPages
	test	ds:RedrawFlags,rfPageChanged
	jz	@@5
	lea	bx,ds:PageTbl
@@1:	lea	si,[bx+size PageInfo]
	cmp	si,ds:LastPage
	jae	@@3
	mov	ax,[bx].PageLength
	add	ax,[si].PageLength
	jc	@@2
	sub	ax,size PageHeader
	cmp	ax,ds:PageSize
	jbe	@@6
@@2:	add	bx,size PageInfo
	jmp	@@1
@@3:	cmp	ds:CPFirstLine,0
	jne	@@4
	Invoke	GoTopPage
	Invoke	UnlockPage
	Invoke	SetEditDS
@@4:	and	ds:RedrawFlags,not rfPageChanged
@@5:	jmp	@@7
@@6:	mov	ds:CPFirstLine,0
	mov	ds:CurPage,bx
	Invoke	GetCurPage
	Invoke	UseCurPage
	jc	@@3
	push	dx ax
	Invoke	StoreLinesInfo
	call	UseTwoPages
	jc	@@3
	add	bx,size PageInfo
	mov	es,dx
	mov	si,ax
	mov	es,es:[si]
	push	dx ax
	Invoke	StoreLinesInfo
	Invoke	SetEditDS
	mov	bx,ds:CurPage
	mov	ax,[bx+size PageInfo].LinesInPage
	add	[bx].LinesInPage,ax
	mov	di,[bx].PageLength
	mov	si,size PageHeader
	mov	cx,[bx+size PageInfo].PageLength
	sub	cx,si
	add	[bx].PageLength,cx
	pop	bx ds
	mov	ds,[bx]
	pop	bx es
	mov	es,es:[bx]
	cld
	shr	cx,1
	rep	movsw
	Invoke	DeleteNextPage
	Invoke	SetEditDS
	mov	bx,ds:CurPage
	jmp	@@1
@@7:	Exit	QuickCompactPages

_CompactPages	proc	near
	push	si di
	sub	ax,ax
	push	ax
	Invoke	GoTopPage
	Invoke	SetEditDS
@@1:	mov	bx,ds:CurPage
	cmp	bx,ds:LastPage
	jae	@@3
	cmp	[bx].PageLength,size PageHeader
	ja	@@2
	Invoke	DeletePage
	Invoke	SetEditDS
	jmp	@@1
@@2:	call	UseTwoPages
	jnc	@@4
@@3:	pop	ax
	pop	di si
	jmp	@@10
@@4:	mov	es,dx
	mov	bx,ax
	mov	es,es:[bx]
	mov	ax,es
	les	bx,ds:LockedPage
	mov	es,es:[bx]
	mov	bx,ds:CurPage
	mov	di,[bx].PageLength
	mov	bx,[bx+size PageInfo].PageLength
	mov	dx,ds:PageSize
	push	ds
	mov	ds,ax
	mov	si,size PageHeader
	sub	ax,ax
@@5:	cmp	si,bx
	jae	@@9
	mov	cx,[si].LineLength
	add	cx,size LineHeader+1
	and	cl,0feh
	add	cx,di
	cmp	cx,dx
	ja	@@6
	sub	cx,di
	shr	cx,1
	rep	movsw
	inc	ax
	jmp	@@5
@@6:	mov	cx,ds
	pop	ds
	test	ax,ax
	jz	@@8
	push	bx
	mov	bx,ds:CurPage
	mov	[bx].PageLength,di
	add	[bx].LinesInPage,ax
	sub	[bx+size PageInfo].LinesInPage,ax
	pop	bx
	mov	di,size PageHeader
	push	ds
	mov	ds,cx
	mov	es,cx
	mov	ds:CurLineNum,-1
	mov	cx,bx
	sub	cx,si
	jae	@@7
	sub	cx,cx
@@7:	shr	cx,1
	rep	movsw
	pop	ds
	mov	bx,ds:CurPage
	mov	[bx+size PageInfo].PageLength,di
	pop	ax
	mov	al,1
	push	ax
@@8:	Invoke	GoNextPage
	Invoke	SetEditDS
	jmp	@@1
@@9:	pop	ds
	mov	bx,ds:CurPage
	mov	[bx].PageLength,di
	add	[bx].LinesInPage,ax
	pop	ax
	mov	al,1
	push	ax
	Invoke	DeleteNextPage
	Invoke	SetEditDS
	jmp	@@1
@@10:	ret
_CompactPages	endp

	Entry	CompactPages
	call	_CompactPages
	Exit	CompactPages

	Entry	Compact
	call	_CompactPages
	Exit	Compact

	Entry	DeletePage
	mov	bx,ds:CurPage
	cmp	bx,ds:LastPage
	jae	@@1
	les	bx,[bx].PageHandle
	mov	dx,es
	Invoke	FreePage
	Invoke	SetEditDS
	push	ds
	pop	es
	mov	di,ds:CurPage
	lea	si,[di+size PageInfo]
	mov	cx,ds:LastPage
	sub	cx,si
	shr	cx,1
	cld
	rep	movsw
	mov	ds:LastPage,di
	clc
	jmp	@@2
@@1:	stc
@@2:	Exit	DeletePage

	public	DeleteEmptyPages
DeleteEmptyPages	proc	near
	Invoke	SetEditDS
@@1:	mov	bx,ds:CurPage
	add	bx,size PageInfo
	cmp	bx,ds:LastPage
	jae	@@3
	cmp	[bx].PageLength,size PageHeader
	ja	@@2
	Invoke	DeleteNextPage
	Invoke	SetEditDS
	jmp	@@1
@@2:	call	UseTwoPages
	jmp	@@4
@@3:	stc
@@4:	ret
DeleteEmptyPages	endp

	public	SetEditDS
SetEditDS	proc	far
	push	bx
	mov	bx,_Data
	mov	ds,bx
	lds	bx,EdHandle
	mov	ds,[bx]
	pop	bx
	ret
SetEditDS	endp

	public	ErrorExit
ErrorExit	proc	far
	SetTurboDS
	mov	sp,SaveBP
	pop	bp
	ret
ErrorExit	endp

	public	UseCurPage
UseCurPage	proc	far
	pushf
	push	ax bx
	mov	bx,_Data
	mov	ds,bx
	lds	bx,EdHandle
	mov	ds,[bx]
	mov	bx,ds:CurPage
	cmp	bx,ds:LastPage
	jae	@@2
	les	bx,[bx].PageHandle
	mov	ax,es
	or	ax,bx
	jz	@@2
	mov	ax,es:[bx]
	cmp	ax,VMemLimit
	jbe	@@1
	mov	es,ax
	jmp	@@2
@@1:	push	si di dx cx
	SetTurboDS
	push	es bx
	push	es bx
	Invoke	UseHandle
	lds	bx,EdHandle
	mov	ds,[bx]
	pop	bx es
	mov	es,es:[bx]
	pop	cx dx di si
@@2:	pop	bx ax
	popf
	ret
UseCurPage	endp

	Entry	FreePage,X
	push	dx bx
	SetTurboDS
	Invoke	FreeVMem
	Exit	FreePage

	Entry	ClearText
	Invoke	InvalidateUndo
	Invoke	SetEditDS
	sub	ax,ax
	mov	ds:LockedPage.Offs,ax
	mov	ds:LockedPage.Segm,ax
	lea	bx,ds:PageTbl
	mov	ds:CurPage,bx
	inc	ax
	mov	ds:CPFirstLine,ax
	mov	ds:CursorPos.Y,ax
	mov	ds:CursorPos.X,ax
	mov	ds:ScreenPos.Y,ax
	mov	ds:ScreenPos.X,ax
@@1:	cmp	bx,ds:LastPage
	jae	@@2
	push	bx
	mov	dx,[bx].PageHandle.Segm
	mov	bx,[bx].PageHandle.Offs
	Invoke	FreePage
	Invoke	SetEditDS
	pop	bx
	add	bx,size PageInfo
	jmp	@@1
@@2:	mov	ds:LastPage,offset PageTbl
	Exit	ClearText

	Entry	GetCurPage
	mov	bx,ds:CurPage
	cmp	bx,ds:LastPage
	jae	@@1
	les	ax,[bx].PageHandle
	mov	dx,es
	mov	bx,ds:CurPage
	clc
	jmp	@@2
@@1:	sub	ax,ax
	stc
@@2:	Exit	GetCurPage

_LockPage	proc	near
	push	dx ax
	push	dx ax
	Invoke	UnlockPage
	SetTurboDS
	Invoke	LockHandle
	Invoke	SetEditDS
	pop	bx es
	mov	ds:LockedPage.Offs,bx
	mov	ds:LockedPage.Segm,es
	mov	ax,es:[bx]
	cmp	ax,VMemLimit
	ja	@@1
	InvokeJ	ErrorExit
@@1:	clc
	ret
_LockPage	endp

	Entry	LockCurPage
	mov	bx,ds:CurPage
	cmp	bx,ds:LastPage
	jb	@@1
	stc
	jmp	@@2
@@1:	les	bx,[bx].PageHandle
	mov	dx,es
	mov	ax,bx
	call	_LockPage
@@2:	Exit	LockCurPage

	Entry	LockPage
	call	_LockPage
	Exit	LockPage

	Entry	UnlockPage
	mov	bx,ds:CurPage
	cmp	bx,ds:LastPage
	jae	@@1
	les	bx,ds:LockedPage
	mov	ax,es
	or	ax,bx
	jz	@@2
	push	es bx
	SetTurboDS
	Invoke	UnlockHandle
	Invoke	SetEditDS
@@1:	sub	ax,ax
	mov	ds:LockedPage.Offs,ax
	mov	ds:LockedPage.Segm,ax
@@2:	Exit	UnlockPage

	public 	UseTwoPages
UseTwoPages	proc	near
	Invoke	SetEditDS
	mov	bx,ds:CurPage
	add	bx,size PageInfo
	cmp	bx,ds:LastPage
	jae	@@2
	Invoke	LockCurPage
	Invoke	SetEditDS
	jc	@@2
	mov	bx,ds:CurPage
	les	bx,[bx+size PageInfo].PageHandle
	mov	dx,es
	mov	ax,es:[bx]
	cmp	ax,VMemLimit
	ja	@@1
	push	es bx
	push	es bx
	SetTurboDS
	Invoke	UseHandle
	Invoke	SetEditDS
	pop	bx es
	mov	dx,es
	mov	ax,es:[bx]
	cmp	ax,VMemLimit
	ja	@@1
	InvokeJ	ErrorExit
@@1:	mov	ax,bx
	mov	bx,ds:CurPage
	clc
	jmp	@@3
@@2:	sub	ax,ax
	mov	dx,ax
	mov	bx,ax
	stc
@@3:	ret
UseTwoPages	endp

	.data

	extrn	EdHandle:dword,SaveBP:word

	end
