include	clib.inc

ifdef __TE__

include	fblk.inc
include	wsub.inc
include	string.inc
include	dos.inc
include	keyb.inc
include	stdio.inc
include	stdlib.inc
include	conio.inc
include	mouse.inc
include	tinfo.inc
include	iost.inc
include	malloc.inc
include	syserrls.inc
ifdef __DLL__
include	plugins/plugins.inc
endif
ifdef __DZ__
include	io.inc
endif


  ifdef DEBUG
    ifdef __DZ__
	extrn	cmdebug:	dist
    endif
  endif
	extrn	tiseto:		near
	extrn	tiputs:		near
  ifdef __CLIP__
	extrn	ticlipevent:	near
  endif
	extrn	ticurcp:	near
	extrn	titoend:	near
	extrn	tievent:	near
	extrn	tiread:		near
	extrn	ticontinue:	near
	extrn	tireadstyle:	near
	extrn	tiretevent:	near
	extrn	tiselectall:	near
	extrn	tisave:		near
	extrn	tiflush:	near
	extrn	tiftime:	near
	extrn	teoption:	dist
	extrn	tialignx:	near
	extrn	tialigny:	near
	extrn	tiputc:		near
	extrn	ticlipset:	near
	extrn	ticlipdel:	near
	extrn	tiofread:	near
	extrn	tihome:		near
	extrn	fsflag:		byte
	extrn	searchstring:	byte
	extrn	replacestring:	byte
	extrn	format_u:	byte
	extrn	IDD_TEHelp:	dword
	extrn	IDD_TESave:	dword
	extrn	IDD_TEReload:	dword
	extrn	IDD_TEReload2:	dword
	extrn	IDD_Replace:	dword
	extrn	IDD_ReplacePrompt: dword
	extrn	IDD_TESeek:	dword

	public	tedit
  ifdef __DZ__
	public	wedit
  endif
	public	topen
	public	tclose
	public	tcloseall
	public	tmodal
	public	tigetline
	public	tigetfile

_DATA	segment
;
; Editor commands
;
te_keytable label word
	dw      KEY_ESC		; Exit - leave files open
	dw      KEY_ALTX	; Exit - Close all files
	dw      KEY_CTRLX	; Close current file - exit if last file
	dw      KEY_F1		; Help			F1
	dw      KEY_F2		; Save file		F2
	dw	KEY_CTRLF2	; Save as		Ctrl-F2
	dw      KEY_F3		; Search		F3
	dw	KEY_F4		; Replace		F4
	dw	KEY_ALTS	; Word search		Alt-S
	dw	KEY_CTRLL	; Search again		Ctrl-L
	dw	KEY_CTRLA	; Select All		Ctrl-A
	dw	KEY_CTRLS	; Toggle style on/off	Ctrl-S
	dw	KEY_CTRLM	; Toggle menus on/off	Ctrl-M
	dw	KEY_F11		; Zoom (Ctrl-M)		F11
	dw	KEY_CTRLT	; Tabs mode on/off	Ctrl-T
	dw	KEY_CTRLF	; Optimal fill on/off	Ctrl-F
	dw	KEY_CTRLI	; Autoindent on/off	Ctrl-I
	dw	KEY_CTRLB	; User screen		Ctrl-B, Alt-F5
	dw	KEY_CTRLO
	dw	KEY_ALTF5
	dw	KEY_CTRLG
	dw	KEY_ALTL
	dw	KEY_CTRLR
	dw	KEY_F9
	dw	KEY_F6
ifdef __DZ__
	dw	KEY_F7
	dw	KEY_F8
endif
ifdef __DLL__
	dw	KEY_SHIFTF1	; [Compile]
	dw	KEY_SHIFTF2
	dw	KEY_SHIFTF3
	dw	KEY_SHIFTF4
	dw	KEY_SHIFTF5
	dw	KEY_SHIFTF6
	dw	KEY_SHIFTF7
	dw	KEY_SHIFTF8
	dw	KEY_SHIFTF9
	dw	KEY_ALTF1
	dw	KEY_ALTF2
	dw	KEY_ALTF3
	dw	KEY_ALTF4
	dw	KEY_ALTF5
	dw	KEY_ALTF6
	dw	KEY_ALTF7	; Previous error
	dw	KEY_ALTF8	; Next error
	dw	KEY_ALTF9	; [Compile]
endif

tekeycount =	(($ - offset te_keytable) / 2)

te_proctable label word
  ifdef __DZ__
	dw	cmexit
	dw	cmcloseall
	dw	cmclose
  else
	dw	cmcloseall
	dw	cmcloseall
	dw	cmcloseall
  endif
	dw	cmhelp
	dw	cmdsave
	dw	cmsaveas
	dw	cmsearch
	dw	cmreplace
	dw	cmsearchxy
	dw	cmcontinuesearch
	dw	cmdselectall
	dw	cmtogglestyle
	dw	cmtogglemenus
	dw	cmtogglemenus
	dw	cmtoggletabs
	dw	cmtogglefill
	dw	cmtoggleindent
	dw	cmuserscreen
	dw	cmuserscreen
	dw	cmuserscreen
	dw	cmlseek
	dw	cmlseek
	dw	cmreload
  ifdef __DZ__
	dw	cmexit
  else
	dw	cmcloseall
  endif
	dw	cmtogglefile
  ifdef __DZ__
	dw	cmloadfiles
	dw	cmsavefiles
  endif
ifdef __DLL__
	dw	cmShiftF1
	dw	cmShiftF2
	dw	cmShiftF3
	dw	cmShiftF4
	dw	cmShiftF5
	dw	cmShiftF6
	dw	cmShiftF7
	dw	cmShiftF8
	dw	cmShiftF9
	dw	cmAltF1
	dw	cmAltF2
	dw	cmAltF3
	dw	cmAltF4
	dw	cmAltF5
	dw	cmAltF6
	dw	cmAltF7
	dw	cmAltF8
	dw	cmAltF9
endif

ifdef __DZ__
cp_te		db '*.te',0
cp_pipe		db 'pipe'
cp_errorext	db '.err',0
error_count	dw ?
error_id	dw ?
endif

cp_noname	db 'nomame.asm',0
cp_defaultext	db '*.asm',0
cp_defaultsub	db '.',0
cp_AltFX	db 'AltF'
cp_AltX		db '1',0
cp_ShiftFX	db 'ShiftF'
cp_ShiftX	db '1',0

cp_tionfo	db ' col %-3u ln %-5u',0
tiupdate_line	dw -1
tiupdate_offs	dw -1

; These are characters used as valid identifiers (Alt-S)

idchars db	'0123456789_?@abcdefghijklmnopqrstuvwxyz',0

emmp	dd 0	; Allocated page
curh	dw -1	; Current owners handle
curp	dw -1	; Current page for this handle

_DATA	ENDS

_TEXT	segment

;-----------------------------------------------------------------------------
; Validate tinfo
;-----------------------------------------------------------------------------

tistate proc
	push	bx
	mov	bx,ax
	test	ax,ax
	jz	@F
	sub	ax,ax
	mov	cx,[bx].S_TINFO.ti_flag
	les	bx,[bx].ti_dialog
	mov	dx,es:[bx].S_DOBJ.dl_flag
	test	bx,bx
	jz	@F
	test	cx,_T_MALLOC
	jz	@F
	test	cx,_T_LINEBUF
	jz	@F
	test	dx,_D_DOPEN
	jz	@F
	mov	ax,bx
      @@:
	pop	bx
	ret
tistate endp

;-----------------------------------------------------------------------------
; Allocate buffer
;-----------------------------------------------------------------------------

timemzero proc	; Clear buffer
	push	si
	push	di
	mov	bx,ax
	xor	si,si
	cld
      @@:
	mov	ax,si
	mov	dx,bx
	call	timemline
	jz	@F
	mov	es,dx
	mov	di,ax
	xor	ax,ax
	mov	cx,[bx].S_TINFO.ti_bcol
	shr	cx,1
	rep	stosw
	inc	si
	jmp	@B
      @@:
	pop	di
	pop	si
	ret
timemzero endp
;
; Allocates <tepages> to TINFO if possible, else low memory is used.
;
tialloc	proc
	push	si
	push	di
	xor	di,di
	mov	si,ax
	ASSUME	si:ptr S_TINFO
	;
	; validate <ti_flag>, <tepages>, and EMM
	;
	DMOV	ax,[si].ti_flag
	assertt	ax,<_T_MALLOC or _T_EMMBUF>,jz,"tialloc"
	cmp	tepages,EMSMINPAGES
	jb	tialloc_lokal
	call	emminit
	jz	tialloc_lokal
	call	emmcoreleft
	jz	tialloc_lokal
	mov	ax,bx
	cmp	ax,EMSMINPAGES
	jb	tialloc_lokal
	cmp	ax,tepages
	jb	@F
	mov	ax,tepages
      @@:
	mov	di,ax
	;
	; Allocate frame page
	;
	lodm	emmp
	test	dx,dx		; same page for all files..
	jnz	@F
	mov	ax,0402h
	call	palloc
	jz	tialloc_fail
	inc	dx		; + 16
	xor	ax,ax		; zero offset
	stom	emmp
      @@:
	stom	[si].ti_bp	; base pointer to page
	or	[si].ti_flag,_T_MALLOC
	;
	; Allocate 16K pages
	;
	invoke	emmalloc,di
	inc	ax
	jz	tialloc_emmfail
	mov	[si].ti_emmh,dx
	mov	[si].ti_emmp,0
	or	[si].ti_flag,_T_EMMBUF
	jmp	tialloc_style
    tialloc_fail?:
	mov	ax,si
	call	tifree
    tialloc_fail:
	mov	ax,offset CP_ENOMEM
	call	@ermsg
	jmp	tialloc_end
    tialloc_emmfail:
	mov	ax,si
	call	tifree
    tialloc_lokal:
    	;
	; if EMM alloc fail and files are open, exit..
	;
	mov	ax,tinfo
	call	tistate
	jnz	tialloc_fail
	;
	; Allocate 256K (16*16K pages) local
	;
	mov	ax,4004h
	call	palloc
	jz	tialloc_fail
	inc	dx
	xor	ax,ax
	or	[si].ti_flag,_T_MALLOC
	stom	[si].ti_bp
	mov	di,16
    tialloc_style:
    	;
	; Allocate <ti_style> and <ti_file>
	;
	mov	ax,((STYLESIZE + WMAXPATH) / 16) + 1
	call	palloc
	jz	tialloc_fail?
	invoke	strcpy,dx::ax,addr cp_noname
	stom	[si].ti_file
	add	ax,WMAXPATH
	stom	[si].ti_style
	invoke	memzero,dx::ax,STYLESIZE
	mov	ax,telsize
	mov     [si].ti_bcol,ax
	mov	bx,ax
	xor	ax,ax
	cwd
	inc	dx
	div	bx
	shr	di,2
	mul	di
	mov	[si].ti_brow,ax
	mov	ax,si
	call	timemzero
	inc	ax
    tialloc_end:
	pop	di
	pop	si
	ASSUME	si:nothing
	ret
tialloc	endp

tifree	proc
	push	si
	mov	si,ax
	ASSUME	si:ptr S_TINFO
	mov	ax,[si].ti_flag
	test	ax,_T_MALLOC or _T_EMMBUF
	jz	tifree_end
	test	ax,_T_EMMBUF
	jz	@F
	mov	dx,[si].ti_emmh	 	; DX EMM handle
	mov	ah,45h			; RELEASE HANDLE AND MEMORY
	int	67h
	mov	ax,-1
	mov	curh,ax			; Force a reread of the page
	mov	curp,ax
	jmp	tifree_name
      @@:
	mov	ax,[si].ti_flag
	test	ax,_T_MALLOC
	jz	tifree_end
	mov	ax,word ptr [si].ti_bp[2] ; free seg - 1
    tifree_page:
	dec	ax
	invoke	free,ax::ax		; free() only use segment..
    tifree_name:
	invoke	free,[si].ti_file
    tifree_end:
	and	[si].ti_flag,not (_T_MALLOC or _T_EMMBUF)
	pop	si
	ASSUME	si:nothing
	ret
tifree	endp

;-----------------------------------------------------------------------------
; Get line from buffer
;-----------------------------------------------------------------------------

tipushh	proc
	ASSUME	si:ptr S_TINFO
	mov	ax,curh
	cmp	ax,-1
	je	@F
	cmp	ax,[si].ti_emmh
	je	tipushh_end
	invoke	emmwrite,emmp,curh,curp
      @@:
	mov	ax,[si].ti_emmh
	mov	curh,ax
	mov	ax,[si].ti_emmp
	mov	curp,ax
	invoke	emmread,emmp,curh,curp
    tipushh_end:
	ASSUME	si:nothing
	ret
tipushh	endp

tigetline proc		; Get line from <tinfo> - tigetline(AX) --> DX:AX
	mov	dx,tinfo
ifdef DEBUG
	call timemline
	ret
endif
tigetline endp

timemline proc  	; Get line from <[dx]> - timemline(AX,DX) --> DX:AX
	push	si
	push	di
	mov	di,ax
	mov	si,dx
	ASSUME	si:ptr S_TINFO
	mov	ax,[si].ti_flag
	test	ax,_T_LINEBUF
	jz	timemline_nol
	cmp	di,[si].ti_brow
	jnb	timemline_null
	test	ax,_T_EMMBUF
	mov	ax,[si].ti_bcol
	jz	timemline_malloc
	mov	ax,[si].ti_emmh		; Init current EMM handle
	cmp	curh,ax			; same handle ?
	je	@F
	call	tipushh
      @@:
	mov	ax,[si].ti_bcol
	shl	ax,2			; align segment
	mul	di   			; DX to page
	cmp	dx,[si].ti_emmp
	je	timemline_pageok
	push	dx
	push	ax
	pushm	[si].ti_bp
	push	[si].ti_emmh
	push	dx
	invoke	emmwrite,[si].ti_bp,[si].ti_emmh,[si].ti_emmp
	call	emmread
	test	ax,ax
	pop	ax
	pop	dx
	jnz	timemline_null
    timemline_pageok:
	mov	[si].ti_emmp,dx		; save page offset
	mov	curp,dx
	shr	ax,6
    timemline_ok:
	add	ax,word ptr [si].ti_bp+2 ; + segment
	mov	dx,ax
	xor	ax,ax
	cmp	di,[si].ti_lcnt
	jnb	timemline_new
	or	dx,dx
	clc
    timemline_end:
	pop	di			; Carry set if new line
	pop	si
	ret
    timemline_null:			; ZF and CF set on error
	xor	ax,ax
	cwd
	jmp	timemline_new
    timemline_nol:
	lodm	[si].ti_bp
    timemline_new:
	or	dx,dx
	stc
	jmp	timemline_end
    timemline_malloc:
	shr	ax,4			; line size in para
	mul	di			; * line offset
	jmp	timemline_ok
	ASSUME	si:nothing
timemline endp

;-----------------------------------------------------------------------------
; File buffer
;
; File info struct is allocated on the stack. A linked list is used
; to find open files.
;
;-----------------------------------------------------------------------------

	ASSUME	bx:ptr S_TINFO

tigetfile proc	dist
	sub ax,ax	; AX first file
	cwd		; DX last file
	mov bx,tinfo
	.if bx
	    .if [bx].ti_flag & _T_FILE
		mov dx,bx
		.repeat
		    mov ax,bx
		    mov bx,[bx].ti_prev
		    .break .if !bx
		.until bx == dx
		mov bx,dx
		.repeat
		    mov dx,bx
		    mov bx,[bx].ti_next
		    .break .if !bx
		.until bx == ax
		inc bx
	    .endif
	.endif
	ret
tigetfile endp

	ASSUME	bx:nothing

tiopen	proc
	push	si
	push	di
	mov	di,ax
	invoke	nalloc,SIZE S_TEDIT
	jz	tiopen_end
	push	ax
	DMOV	dx,sp
	DSUB	dx,SIZE S_TINFO
	assert	dx,ax,ja,"tiopen: SP < tinfo"
	invoke	memzero,ss::ax,SIZE S_TEDIT
	pop	si
	ASSUME	si:ptr S_TINFO
	mov	al,at_background[B_Desktop]
	or	al,at_foreground[F_Desktop]
	mov	[si].ti_clat,al
	mov	[si].ti_stat,al
	mov	dl,al
	invoke	dlscreen,addr [si].ti_DOBJ,dx
	stom	[si].ti_dialog
	jz	tiopen_nomem
	xor	ax,ax
	mov	[si].ti_xpos,ax
	mov	[si].ti_ypos,ax
	mov     [si].ti_cursor.cr_xy,ax
	mov     [si].ti_cursor.cr_type,CURSOR_NORMAL
	mov	al,[si].ti_DOBJ.dl_rect.rc_col
	mov	[si].ti_cols,ax
	mov	al,[si].ti_DOBJ.dl_rect.rc_row
	mov	[si].ti_rows,ax
	mov	al,' '
	mov	[si].ti_clch,al
	mov	[si].ti_stch,al
	mov	ax,si
	call	tialloc
	jz	tiopen_dlclose
	call	tigetfile
	jz	@F
	mov	bx,dx
	mov	[si].ti_prev,bx		; Link to last file
	mov	[bx].ti_next,si
      @@:
	mov	ax,teflag
	and	ax,_T_TESAVEMASK
	or	[si].ti_flag,ax
	mov	ax,si
	or	ax,ax
    tiopen_end:
	pop	di
	pop	si
	ret
    tiopen_dlclose:
	invoke	dlclose,[si].ti_dialog
    tiopen_nomem:
	invoke	nfree,si
	xor	ax,ax
	jmp	tiopen_end
	ASSUME	si:nothing
tiopen	endp

	ASSUME	si:ptr S_TINFO

ticlose proc
	push si
	push di
	mov si,ax
	sub di,di
	.if [si].ti_flag & _T_MALLOC or _T_EMMBUF
	    call tifree
	    invoke dlclose,[si].ti_dialog
	    mov ax,[si].ti_flag
	    and ax,_T_TESAVEMASK
	    or teflag,ax
	.endif
	.if func(tigetfile)
	    mov di,[si].ti_prev		; Unlink file
	    mov bx,[si].ti_next
	    mov [si].ti_prev,0
	    mov [si].ti_next,0
	    .if bx
		.if [bx].ti_prev == si
		    mov [bx].ti_prev,di
		.endif
	    .endif
	    .if di
		.if [di].ti_next == si
		    mov [di].ti_next,bx
		.endif
	    .else
		mov di,bx
	    .endif
	.endif
	mov tinfo,di
	xor ax,ax
	invoke nfree,si
	pop di
	pop si
	ret
ticlose endp

	ASSUME	si:nothing

;-----------------------------------------------------------------------------
; Window functions
;-----------------------------------------------------------------------------

tionscr proc
	call	tistate
	jz	@F
	test	dx,_D_ONSCR
      @@:
	ret
tionscr endp

timenus proc
	push	si
	mov	si,tinfo
	ASSUME	si:ptr S_TINFO
	mov	ax,si
	call	tionscr
	jz	timenus_end
	test	cx,_T_USEMENUS
	jz	timenus_end
	mov	bx,ax
	mov	ax,[si].ti_loff
	add	ax,[si].ti_yoff
	inc	ax
	push	ax
	mov	ax,[si].ti_xoff
	add	ax,[si].ti_boff
	push	ax
	xor	cx,cx
	mov	ax,es:[bx+4]
	add	al,es:[bx].dl_rect.rc_col
	sub	al,18
	mov	bx,ax
	mov	ax,offset cp_tionfo
	call	@scputf
	add	sp,4
	mov	bl,0
	inc	cx
	mov	ax,' '
	test    [si].ti_flag,_T_MODIFIED
	jz	timenus_put
	mov	al,'*'
    timenus_put:
	call    @scputw
    timenus_end:
	pop	si
	ASSUME	si:nothing
	xor	ax,ax
	ret
timenus endp

tiupdate proc dist
	push	si
	mov	si,tinfo
	ASSUME	si:ptr S_TINFO
	mov	ax,si
	call	tionscr
	jz	tiupdate_end
	test	cx,_T_USEMENUS
	jz	tiupdate_end
	mov	ax,[si].ti_loff
	add	ax,[si].ti_yoff
	mov	dx,[si].ti_xoff
	add	dx,[si].ti_boff
	cmp	ax,tiupdate_line
	jne	tiupdate_do
	cmp	dx,tiupdate_offs
	je	tiupdate_end
    tiupdate_do:
	mov	tiupdate_offs,dx
	mov	tiupdate_line,ax
	call	timenus
    tiupdate_end:
	pop	si
	ASSUME	si:nothing
	xor	ax,ax
	ret
tiupdate endp

;-----------------------------------------------------------------------------
; Edit command
;-----------------------------------------------------------------------------
;
; Close window and exit -- leave files open
;
ifdef __DZ__

cmexit proc
	mov	bx,tinfo
	test	[bx].S_TINFO.ti_flag,_T_EMMBUF ;or _T_MALLOC
	jz	cmclose
	invoke	dlhide,[bx].S_TINFO.ti_dialog
	mov	ax,_TI_RETEVENT
	ret
cmexit endp
;
; Close current file -- exit if last file
;
cmclose proc
	call	tclose
	mov	ax,_TI_RETEVENT
	jz	@F
	mov	bx,tinfo
	ASSUME	bx:ptr S_TINFO
	invoke	dlshow,[bx].ti_dialog
	mov	bx,tinfo
	xor	[bx].ti_flag,_T_USEMENUS
	invoke	setcursor,[bx].ti_cursor
	call	cmtogglemenus
	mov	ax,_TI_CONTINUE
      @@:
	ASSUME	bx:nothing
	ret
cmclose endp

endif

;
; Close all open files -- exit
;
cmcloseall proc
	call	tcloseall
	mov	ax,_TI_RETEVENT
	ret
cmcloseall endp

cmlseek	proc
	invoke	rsopen, IDD_TESeek
	jz	cmlseek_end
	push	dx
	push	ax
	pushm	IDD_TESeek
	push	dx
	push	ax
	push	dx
	push	ax
	mov	cx,es:[bx+24]
	mov	bx,tinfo
	mov	ax,[bx].S_TINFO.ti_loff
	add	ax,[bx].S_TINFO.ti_yoff
	push	ax
	mov	ax,offset format_u
	call	@sprintf
	pop	ax
	call	dlinit
	call	rsevent
	or	ax,ax
	jz	cmlseek_close
	push	es:[bx+26]
	push	es:[bx+24]
	call	strtol
	call	tialigny
    cmlseek_close:
	call	dlclose
	call	tiputs
    cmlseek_end:
	jmp	ticontinue
cmlseek	endp

cmreload proc
	mov	bx,tinfo
	test	[bx].S_TINFO.ti_flag,_T_MODIFIED
	jz	@F
	invoke	rsmodal, IDD_TEReload2
	jnz	@F
	jmp	ticontinue
      @@:
	mov	ax,tinfo
	call	timemzero
	mov	ax,tinfo
	call	tiread
	jz	@F
	call	tiseto
	call	tiputs
	jmp	ticontinue
      @@:
    	mov	di,KEY_ESC
	dec	ax
	ret
cmreload endp

cmtogglefile proc
	call	tigetfile
	jnz	@F
	ret
      @@:
	mov	bx,tinfo
	cmp	[bx].S_TINFO.ti_next,0
	jz	titogglefile
	mov	ax,[bx].S_TINFO.ti_next
cmtogglefile endp

titogglefile proc
	push	si
	push	di
	mov	di,ax
	mov	si,tinfo
	cmp	di,si
	je	titogglefile_end
	test	[di].S_TINFO.ti_flag,_T_MALLOC or _T_EMMBUF
	jz	titogglefile_end
	invoke	dlhide,[si].S_TINFO.ti_dialog
	invoke	dlshow,[di].S_TINFO.ti_dialog
	mov	tinfo,di
	xor	[di].S_TINFO.ti_flag,_T_USEMENUS
	call	cmtogglemenus
	invoke	setcursor,[di].S_TINFO.ti_cursor
    titogglefile_end:
	pop	di
	pop	si
	jmp	ticontinue
titogglefile endp

ifdef __DLL__
inicommand  proto dist pascal :dword, :dword, :dword

Message	struc
m_file	db WMAXPATH dup(?)
m_info	db 256 dup(?)
m_line	dd ?
Message	ends

GetMessageId proc pascal uses si di M:dword, id:word
    sub si,si
    .if func(filexist,addr cp_pipe) == 1
	.if func(osopen,addr cp_pipe,0,M_RDONLY,A_OPEN) != -1
	    mov di,ax
	    mov ax,SIZE Message
	    mul id
	    invoke lseek,di,dx::ax,SEEK_SET
	    invoke osread,di,M,SIZE Message
	    xchg ax,di
	    invoke close,ax
	    .if di == SIZE Message
		inc si
	    .endif
	.endif
    .endif
    mov ax,si
    ret
GetMessageId endp

LoadMessageFile proc pascal uses si di M:dword
    mov si,tinfo
    mov di,word ptr M
    invoke strfn,addr [di].m_file
    push dx
    push ax
    invoke strfn,[si].ti_file
    push dx
    push ax
    call stricmp
    .if ax
	.if func(topen,addr [di].m_file)
	    mov ax,tinfo
	    mov tinfo,si
	    call titogglefile
	    mov si,tinfo
	.else
	    jmp @F
	.endif
    .endif
    mov ax,word ptr [di].m_line
    .if ax
	dec ax
    .endif
    call tialigny
    call tiseto
    call tiputs
    mov dx,ss
    lea ax,[di].m_info
    mov bl,0
    mov bh,byte ptr [si].ti_yoff
    .if bh <= 1
	add bh,2
    .endif
    .if !([si].ti_flag & _T_USEMENUS)
	dec bh
    .endif
    mov cx,[si].ti_cols
    mov ch,4Fh
    call @scputs
    mov ax,1
  @@:
    ret
LoadMessageFile endp

cmAltF7	proc pascal	; Previous Error
    local M:Message
    .if error_count
	.if func(GetMessageId, addr M, error_id)
	    invoke LoadMessageFile, addr M
	    .if error_id
		dec error_id
	    .else
		mov ax,error_count
		dec ax
		mov error_id,ax
	    .endif
	.endif
    .endif
    mov ax,_TI_CONTINUE
    ret
cmAltF7 endp

cmAltF8	proc pascal	; Next Error
    local M:Message
    .if error_count
	.if func(GetMessageId,addr M,error_id)
	    invoke LoadMessageFile, addr M
	    mov ax,error_id
	    inc ax
	    .if ax >= error_count
		sub ax,ax
	    .endif
	    mov error_id,ax
	.endif
    .endif
    mov ax,_TI_CONTINUE
    ret
cmAltF8 endp

cmspawnini proc pascal IniSection:dword
	.if func(filexist,addr cp_pipe)
	    invoke remove,addr cp_pipe
	.endif
	sub ax,ax
	mov bx,tinfo
	.if [bx].S_TINFO.ti_flag & _T_EMMBUF
	    .if [bx].S_TINFO.ti_flag & _T_MODIFIED
		call cmdsave
		mov bx,tinfo
	    .endif
	    invoke dlhide,[bx].S_TINFO.ti_dialog
	    mov bx,tinfo
	    .if func(inicommand,addr __srcfile,[bx].S_TINFO.ti_file,IniSection)
		mov dx,ds
		mov bx,offset __srcfile
		mov ah,_DZ_command
		mov al,SPAWN_HIDE
		int DZ
		mov ax,1
		.if CARRY?
		    sub ax,ax
		.endif
	    .endif
	.endif
	ret
cmspawnini endp

cmAltF1:
	mov al,'1'
	jmp cmAltFX
cmAltF2:
	mov al,'2'
	jmp cmAltFX
cmAltF3:
	mov al,'3'
	jmp cmAltFX
cmAltF4:
	mov al,'4'
	jmp cmAltFX
cmAltF5:
	mov al,'5'
	jmp cmAltFX
cmAltF6:
	mov al,'6'
	jmp cmAltFX
cmAltF9:
	mov al,'7'
cmAltFX:
	mov cp_AltX,al
	mov dx,offset cp_AltFX
	jmp ExecuteINI

cmShiftF1:
	mov al,'1'
	jmp cmShiftFX
cmShiftF2:
	mov al,'2'
	jmp cmShiftFX
cmShiftF3:
	mov al,'3'
	jmp cmShiftFX
cmShiftF4:
	mov al,'4'
	jmp cmShiftFX
cmShiftF5:
	mov al,'5'
	jmp cmShiftFX
cmShiftF6:
	mov al,'6'
	jmp cmShiftFX
cmShiftF7:
	mov al,'7'
	jmp cmShiftFX
cmShiftF8:
	mov al,'8'
	jmp cmShiftFX
cmShiftF9:
	mov al,'9'
cmShiftFX:
	mov cp_ShiftX,al
	mov dx,offset cp_ShiftFX

ExecuteINI proc pascal uses si di
	mov error_count,0
	mov si,tinfo
	invoke cmspawnini,ds::dx
	push ax
	invoke dlshow,[si].ti_dialog
	call cmreload
	pop ax
	.if ax
	    .if func(filexist,addr cp_pipe) == 1
		.if func(osopen,addr cp_pipe,0,M_RDONLY,A_OPEN) != -1
		    mov di,ax
		    invoke lseek,di,0,SEEK_END
		    mov cx,SIZE Message
		    div cx
		    mov error_id,0
		    mov error_count,ax
		    invoke close,di
		.endif
		.if error_count
		    call cmAltF8
		.endif
	    .endif
	.endif
	sub ax,ax
	ret
ExecuteINI endp

endif

cmdselectall proc
	call	tiselectall
	call	tiseto
	jmp	cmdtoggleupdate
cmdselectall endp

cmdsave proc
	mov	ax,tinfo
	call	tisave
	jmp	ticontinue
cmdsave endp

tisavechanges proc
	push si
	.if func(rsopen,IDD_TESave)
	    push dx
	    push ax
	    pushm IDD_TESave
	    push dx
	    push ax
	    invoke dlshow,dx::ax
	    mov ch,0
	    mov cl,es:[bx+6]
	    sub cl,10
	    mov bx,es:[bx+4]
	    add bx,0205h
	    mov si,tinfo
	    lodm [si].ti_file
	    call @scpath
	    call rsevent
	    call dlclose
	    mov ax,dx
	.endif
	pop si
	ret
tisavechanges endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; ios_l		= line
; ios_bp	= &tigetline(ios_l)
; ios_bb	= line:offset
; ios_offset	= line:offset (seek?)

titostdi proc
	push	ds
	push	OSTDI
	push	SIZE S_IOST
	call	memzero
	mov	al,fsflag
	and	al,IO_SEARCHMASK
	or	ax,IO_LINEBUF
	mov	STDI.ios_flag,ax
	call	ticurcp
	mov	es,dx
	mov	bx,ax
	cmp	byte ptr es:[bx],0
	jne	@F
	call	titoend
      @@:
	mov	bx,tinfo
	mov	ax,[bx].S_TINFO.ti_boff
	add	ax,[bx].S_TINFO.ti_xoff
	mov	word ptr STDI.ios_bb,ax
	mov	ax,[bx].S_TINFO.ti_loff
	add	ax,[bx].S_TINFO.ti_yoff
	mov	STDI.ios_l,ax
	mov	word ptr STDI.ios_bb+2,ax
	call	tiofread
	mov	ax,word ptr STDI.ios_bb
	mov	STDI.ios_i,ax
	ret
titostdi endp

ticontinuesearch proc
	call	titostdi
	and	STDI.ios_flag,not (IO_SEARCHSET or IO_SEARCHCUR)
	call	continuesearch
	or	ax,ax
	jnz	cmsearchfound
	inc	ax
	ret
ticontinuesearch endp

cmsearchfound proc
	mov	ax,STDI.ios_l
	call	tialigny
	invoke	strlen,addr searchstring
	mov	dx,STDI.ios_i
	sub	dx,ax
	push	ax
	mov	ax,dx
	dec	ax
	call	tialignx
	call	ticlipset
	pop	ax
	push	ax
	add	[bx].ti_cleo,ax
	call	tiputs
	call	ticlipset
	pop	cx
	jmp	ticontinue
cmsearchfound endp

cmcontinuesearch proc
	call	ticontinuesearch
	jmp	ticontinue
cmcontinuesearch endp

cmsearch proc
	call	titostdi
	call	ogetc
	push	1
	push	0
	call	cmdsearch
	push	ax
	and	fsflag,not IO_SEARCHMASK
	mov	ax,STDI.ios_flag
	and	al,IO_SEARCHMASK
	or	fsflag,al
	pop	ax
	or	ax,ax
	jnz	cmsearchfound
	jmp	ticontinue
cmsearch endp

; Replace prompt
; 0 1 &Yes
; 1 2 Change &All
; 2 3 &No
; 3 0 &Cancel

ID_YES	equ	1
ID_ALL	equ	2
ID_NO	equ	3

iddreplaceprompt proc
	mov ax,1
	mov bx,tinfo
	.if [bx].S_TINFO.ti_flag & _T_PROMPTONREP
	    .if func(rsmodal,IDD_ReplacePrompt)
		mov dx,ax
		.if ax
		    dec dx
		.endif
		mov bx,word ptr IDD_ReplacePrompt
		mov [bx].S_ROBJ.rs_index,dl
		mov bx,tinfo
		.if ax == ID_ALL
		    xor [bx].S_TINFO.ti_flag,_T_PROMPTONREP
		.endif
	    .endif
	.endif
	test ax,ax
	ret
iddreplaceprompt endp

; Replace text
; 0 1 &Text to find
; 1 2 &New text
; 2 3 [ ] Ca&se sensitive
; 3 4 [ ] &Prompt on replace
; 4 5 ( ) &From cursor
; 5 6 ( ) &Entire scope
; 6 7 &OK
; 7 8 Change &All
; 9 0 &Cancel

ID_OLDSTRING	equ	1
ID_NEWSTRING    equ	2
ID_USECASE	equ	3
ID_PROMPT	equ	4
ID_CURSOR	equ	5
ID_GLOBAL	equ	6
ID_OK		equ	7
ID_CHANGEALL	equ	8

iddreplace proc pascal, sflag:word
	push	si
	push	di
	invoke	rsopen,IDD_Replace
	jz	iddreplace_nul
	push	dx
	push	ax
	pushm	IDD_Replace
	push	dx
	push	ax
	push	dx
	push	ax
	ASSUME	bx:ptr S_TOBJ
	mov	es:[bx].to_count[ID_OLDSTRING*16],128 shr 4
	mov	word ptr es:[bx].to_data[ID_OLDSTRING*16],offset searchstring
	mov	word ptr es:[bx].to_data[ID_OLDSTRING*16+2],ds
	mov	es:[bx].to_count[ID_NEWSTRING*16],128 shr 4
	mov	word ptr es:[bx].to_data[ID_NEWSTRING*16],offset replacestring
	mov	word ptr es:[bx].to_data[ID_NEWSTRING*16+2],ds
	mov	ax,sflag
	mov	dl,_O_FLAGB
	test	ax,IO_SEARCHCASE
	jz	@F
	or	es:[bx+ID_USECASE*16],dl
      @@:
	test	ax,_T_PROMPTONREP
	jz	@F
	or	es:[bx+ID_PROMPT*16],dl
      @@:
	mov	dl,_O_RADIO
	test	ax,IO_SEARCHCUR
	jz	iddreplace_cursor
	or	es:[bx+ID_CURSOR*16],dl
	jmp	iddreplace_event
    iddreplace_nul:
	xor	ax,ax
	jmp	iddreplace_end
    iddreplace_cursor:
	or	es:[bx+ID_GLOBAL*16],dl
    iddreplace_event:
	call	dlinit
	call	rsevent
	or	ax,ax
	jz	iddreplace_nul
	mov	ax,sflag
	and	ax,not (IO_SEARCHMASK or _T_PROMPTONREP)
	mov	dl,_O_FLAGB
	test	es:[bx+ID_USECASE*16],dl
	jz	@F
	or	ax,IO_SEARCHCASE
      @@:
	test	es:[bx+ID_PROMPT*16],dl
	jz	@F
	or	ax,_T_PROMPTONREP
      @@:
	test	byte ptr es:[bx+ID_CURSOR*16],_O_RADIO
	jz	@F
	or	ax,IO_SEARCHCUR
	jmp	iddreplace_toend
      @@:
	or	ax,IO_SEARCHSET
    iddreplace_toend:
	ASSUME	bx:nothing
	mov	dx,ax
	xor	ax,ax
	cmp	searchstring,al
	je	iddreplace_end
	cmp	replacestring,al
	je	iddreplace_end
	inc	ax
    iddreplace_end:
	mov	si,dx
	call	dlclose
	mov	ax,dx
	mov	dx,si
	or	ax,ax
	pop	di
	pop	si
	ret
iddreplace endp

cmreplace proc
	push	si
	push	di
	mov	si,tinfo
	ASSUME	si:ptr S_TINFO
	mov	ax,_T_PROMPTONREP
	or	[si].ti_flag,ax
	mov	al,fsflag
	and	al,IO_SEARCHMASK
	invoke	iddreplace,ax
	jz	cmreplace_end
	and	fsflag,not IO_SEARCHMASK
	or	fsflag,dl
	cmp	ax,ID_CHANGEALL
	je	@F
	test	dx,_T_PROMPTONREP
	jnz	cmreplace_do
      @@:
	and	[si].ti_flag,not _T_PROMPTONREP
    cmreplace_do:
	call	ticontinuesearch
	jnz	cmreplace_end
	jmp	cmreplace_first
    cmreplace_loop:
	call	continuesearch
	or	ax,ax
	jz	cmreplace_end
	call	cmsearchfound
    cmreplace_first:
	mov	di,cx
	call	iddreplaceprompt
	jz	cmreplace_end		; 3 0 [ Cancel ]
	cmp	ax,ID_NO
	je	cmreplace_skip		; --> find next
	add	[si].ti_cleo,di		; select text
	call	ticlipdel		; delete text
	mov	di,offset replacestring	; add new text
    cmreplace_putc:
	mov	al,[di]
	inc	di
	or	al,al
	jz	cmreplace_loop
	call	tiputc
	jmp	cmreplace_putc
    cmreplace_skip:
	call	ticontinuesearch
	jmp	cmreplace_loop
    cmreplace_end:
	call	tiputs
	xor	ax,ax
	pop	di
	pop	si
	ASSUME	si:nothing
	ret
cmreplace endp

idtestal proc
	push	es
	push	di
	push	cx
	push	ax
	cmp	al,'A'
	jb	idtestal_start
	cmp	al,'Z'
	ja	idtestal_start
	or	al,20h
    idtestal_start:
	push	ds
	pop	es
	mov	di,offset idchars
	mov	cx,sizeof idchars
	cld
	repne	scasb
	cmp	byte ptr [di-1],0
	pop	ax
	pop	cx
	pop	di
	pop	es
	ret
idtestal endp

cmsearchxy proc pascal
local	linebuf[128]:byte
	push	si
	push	di
	mov	ah,3		; get cursor x,y pos
	mov	bh,0
	int	10h
	mov	bx,dx		; DH y, DL x
	mov	di,bx
	call	@getxyp		; ES:BX to screen(x,y)
	and	di,00FFh	; x ?
	jz	cmsearchxy_start
	inc	di		; not start of line..
    cmsearchxy_back:		; moving left seeking a valid character
	dec	di
	jz	cmsearchxy_start
	mov	al,es:[bx]
	call	idtestal
	jz	cmsearchxy_next
	mov	al,es:[bx-2]
	call	idtestal
	jz	cmsearchxy_start
    cmsearchxy_next:
	sub	bx,2
	jmp	cmsearchxy_back
    cmsearchxy_start:
	lea	si,linebuf
	mov	cx,32
	xor	ax,ax
    cmsearchxy_loop:
	mov	al,es:[bx]
	add	bx,2
	call	idtestal
	jz	cmsearchxy_break
	mov	[si],al
	inc	si
	dec	cx
	jnz	cmsearchxy_loop
    cmsearchxy_break:
	mov	[si],ah
	mov	al,linebuf
	or	al,al
	jz	cmsearchxy_end
	invoke	strcpy,addr searchstring,addr linebuf
	call	cmsearch
    cmsearchxy_end:
	pop	di
	pop	si
	ret
cmsearchxy endp

cmsaveas proc
	mov	bx,tinfo
	invoke	strcpy,addr _bufin,[bx].ti_file
	push	dx
	push	ax
	invoke	strfn,dx::ax
	cmp	ax,offset _bufin
	je	cmsaveas_?
	mov	bx,ax
	mov	byte ptr [bx-1],0
    cmsaveas_?:
	push	dx
	push	ax
	push	0
	call	wdlgopen
	jz	cmsaveas_end
	mov	bx,tinfo
	invoke	strcpy,[bx].S_TINFO.ti_file,dx::ax
	mov	ax,tinfo
	call	tiflush
	mov	bx,tinfo
	xor	[bx].S_TINFO.ti_flag,_T_USEMENUS
	jmp	cmtogglemenus
    cmsaveas_end:
	jmp	ticontinue
cmsaveas endp

cmtoggletabs proc
	mov	bx,tinfo
	ASSUME	bx:ptr S_TINFO
	xor	[bx].ti_flag,_T_SHOWTABS
	jmp	cmdtoggleupdate
cmtoggletabs endp

cmtogglefill proc
	mov	bx,tinfo
	xor	[bx].ti_flag,_T_OPTIMALFILL
	jmp	cmdtoggleupdate
cmtogglefill endp

cmtoggleindent proc
	mov	bx,tinfo
	xor	[bx].ti_flag,_T_USEINDENT
	jmp	cmdtoggleupdate
cmtoggleindent endp

cmtogglestyle proc
	mov	bx,tinfo
	xor	[bx].ti_flag,_T_USESTYLE
	jmp	cmdtoggleupdate
cmtogglestyle endp

cmtogglemenus proc
	mov	bx,tinfo
	les	bx,[bx].ti_dialog
	mov	dx,es:[bx+4]
	mov	cx,es:[bx+6]
	mov	bx,tinfo
	mov	ax,[bx].ti_flag
	xor	ax,_T_USEMENUS
	mov	[bx].ti_flag,ax
	and	ax,_T_USEMENUS
	jz	ticlosemenus
	mov	al,dh
	inc	al
	mov	[bx].ti_ypos,ax
	mov	al,ch
	dec	al
	mov	[bx].ti_rows,ax
	mov	cx,[bx].ti_cols
	mov	bx,dx
	mov	ah,at_background[B_Menus]
	mov	al,' '
	call	@scputw
	inc	bl
	sub	cx,19
	push	bx
	mov	bx,tinfo
	lodm	[bx].ti_file
	pop	bx
	call	@scpath
	jmp	cmdtoggleupdate
    ticlosemenus:
	mov	al,dh
	mov	[bx].ti_ypos,ax
	mov	al,ch
	mov	[bx].ti_rows,ax
	mov	cx,[bx].ti_cols
	mov	ah,[bx].ti_clat
	mov	al,[bx].ti_clch
	test	[bx].ti_flag,_T_USESTYLE
	jz	cmtogglemenus_nostyle
	mov	ah,[bx].ti_stat
	mov	al,[bx].ti_stch
    cmtogglemenus_nostyle:
	mov	bx,dx
	call	@scputw
cmtogglemenus endp

cmdtoggleupdate proc
	call	tiputs
	jmp	ticontinue
cmdtoggleupdate endp

tioption proc dist
	mov	bx,tinfo
	mov	ax,[bx].ti_flag
	and	ax,_T_TESAVEMASK
	mov	teflag,ax
	call	teoption
	mov	bx,tinfo
	mov	ax,[bx].ti_flag
	and	ax,not _T_TESAVEMASK
	or	ax,teflag
	mov	[bx].ti_flag,ax
	ret
tioption endp

	ASSUME	bx:nothing

cmhelp	proc
	.if func(rsopen, IDD_TEHelp)
	    fpmov es:[bx].S_TOBJ.to_proc[2*16],tioption
	    invoke rsevent, IDD_TEHelp, dx::ax
	    invoke dlclose, es::bx
	.endif
	jmp ticontinue
cmhelp	endp

cmuserscreen proc
	call consuser
	ret
cmuserscreen endp

;-----------------------------------------------------------------------------
; Event handler
;-----------------------------------------------------------------------------

teevent proc
	push si
	push di
	call tiseto
	call tiputs
	.repeat
	    mov ax,tinfo
	    mov si,ax
	    call tiftime
	    .if ax
		.if ax != [si].S_TINFO.ti_time
		    .if func(rsmodal,IDD_TEReload)
			mov ax,si
			call timemzero
			mov ax,si
			call tiread
			mov di,KEY_ESC
			.break .if ZERO?
			call tiseto
			call tiputs
		    .endif
		.endif
    	    .endif
	    call timenus
	    call tgetevent
	    mov di,ax
	  ifdef DEBUG
	    ifdef __DZ__
		cmp ax,5400h	; Shift-F1
		jne @F
		call cmdebug
		.continue
	      @@:
	    endif
	  endif
	    xor bx,bx
	    mov cx,tekeycount
	  @@:
	    .if ax == te_keytable[bx]
		call te_proctable[bx]
		.if ax == _TI_CONTINUE
		    .continue
		.endif
		.break
	    .endif
	    add bx,2
	    dec cx
	    jnz @B
	  ifdef __CLIP__
	    call ticlipevent
	  endif
	    call tievent
	    mov si,ax
	    call tiseto
	    call tiputs
	.until 0
	mov ax,di
	pop di
	pop si
	ret
teevent endp

;-----------------------------------------------------------------------------
; Load file
;-----------------------------------------------------------------------------

tiinitfile proc
	mov bx,tinfo
	.if !dx
	    inc [bx].S_TINFO.ti_lcnt ; set line count to 1
	    mov dx,ds
	    mov ax,offset cp_noname
	.else
	    invoke wlongpath,dx::ax, 0
	.endif
	mov bx,tinfo
	assert word ptr [bx].S_TINFO.ti_file,0,jne,"ti_file NULL!"
	invoke strcpy,[bx].S_TINFO.ti_file,dx::ax
	cmp ax,offset cp_noname
	ret
tiinitfile endp

;-----------------------------------------------------------------------------
; Global functions
;-----------------------------------------------------------------------------

topen	proc dist pascal fname:dword
	push	si
	xor	ax,ax
	call	tiopen
	jz	topen_nul
	mov	si,ax
	or	[si].S_TINFO.ti_flag,_T_FILE
	mov	tinfo,ax
	lodm	fname
	call	tiinitfile
	jz	@F
	call	tireadstyle
	mov	ax,si
	call	tiread
	jz	topen_fail
      @@:
	mov	ax,si
	or	ax,ax
    topen_end:
	pop	si
	ret
    topen_fail:
	mov	ax,si
	call	ticlose
    topen_nul:
	xor	ax,ax
	jmp	topen_end
topen	endp

tclose	proc dist
	mov bx,tinfo
	.if bx
	    .if [bx].S_TINFO.ti_flag & _T_MALLOC or _T_EMMBUF
		.if [bx].S_TINFO.ti_flag & _T_MODIFIED
		    .if func(tisavechanges) == 1
			mov ax,tinfo
			call tiflush
		    .endif
		.endif
		mov bx,tinfo
		mov ax,[bx].S_TINFO.ti_flag
		and ax,_T_TESAVEMASK
		mov teflag,ax
		mov ax,tinfo
		call ticlose
	    .endif
	.endif
	mov ax,tinfo
	test ax,ax
	ret
tclose	endp

tcloseall proc dist
	call	tclose
	jnz	tcloseall
	ret
tcloseall endp

tmodal	proc dist pascal
local	cursor:dword
local	update:dword
local	ftime:word
	push	si
	push	di
	@@:
	call	mousep
	jnz	@B
	xor	ax,ax
	mov	si,tinfo
	or	si,si
	jz	temodal_pop
	test	[si].S_TINFO.ti_flag,_T_MALLOC or _T_EMMBUF
	jz	temodal_pop
	movmx	update,tupdate
	mov	word ptr tupdate,offset tiupdate
	LMOV	word ptr tupdate+2,cs
	invoke	getcursor,addr cursor
	invoke	dlshow,[si].S_TINFO.ti_dialog
	xor	[si].S_TINFO.ti_flag,_T_USEMENUS
	call	cmtogglemenus
	invoke	setcursor,[si].S_TINFO.ti_cursor
	mov	ax,si
	call	tiftime
	mov	ftime,ax
	call	teevent
	mov	di,ax
	mov	ax,tinfo
	cmp	si,ax
	mov	si,0
	jne	temodal_end
	call	tiftime
	mov	si,ftime
	sub	si,ax
    temodal_end:
	movmw	tupdate,update
	LMOV	ax,word ptr update+2
	LMOV	word ptr tupdate+2,ax
	invoke	setcursor, cursor
	mov	dx,si		; zero if not modified
	mov	ax,di		; returned key value
	or	ax,ax
    temodal_pop:
	pop	di
	pop	si
	ret
tmodal	endp

tedit	proc dist pascal fname:dword, line:word
	.if func(topen,fname)
	    mov ax,line
	    call tialigny
	    call tmodal
	.endif
	ret
tedit	endp

ifdef __DZ__

tsaveh	proc dist pascal public uses si di handle:word
local	tf:S_TFILE
	call tigetfile
	mov si,ax
	.while si
	    invoke memzero,addr tf,SIZE S_TFILE
	    invoke strcpy,addr tf,[si].ti_file
	    mov ax,[si].ti_time
	    mov tf.tf_time,ax
	    mov ax,[si].ti_xoff
	    mov tf.tf_xoff,ax
	    mov ax,[si].ti_yoff
	    mov tf.tf_yoff,ax
	    mov ax,[si].ti_boff
	    mov tf.tf_boff,ax
	    mov ax,[si].ti_loff
	    mov tf.tf_loff,ax
	    invoke oswrite,handle,addr tf,SIZE S_TFILE
	    mov ax,[si].ti_next
	    .break .if si >= ax
	    mov si,ax
	.endw
	ret
tsaveh	endp

topenh	proc dist pascal public uses si di handle:word
local	tf:S_TFILE
	.repeat
	    invoke osread,handle,addr tf,SIZE S_TFILE
	    .break .if ax != SIZE S_TFILE
	    .if func(filexist,addr tf) != 1
	    	.continue
	    .endif
	    invoke topen,addr tf
	    .break .if ZERO?
	    mov si,tinfo
;	    mov ax,tf.tf_time
;	    mov [si].ti_time,ax
	    mov ax,tf.tf_xoff
	    mov [si].ti_xoff,ax
	    mov ax,tf.tf_yoff
	    mov [si].ti_yoff,ax
	    mov ax,tf.tf_boff
	    mov [si].ti_boff,ax
	    mov ax,tf.tf_loff
	    mov [si].ti_loff,ax
	.until 0
	ret
topenh	endp

cmloadfiles proc
	push si
	mov si,tinfo
	invoke wgetfile,addr cp_te,3
	jz cmloadfiles_end
	push ax
	push ax
	.if si && [si].S_TINFO.ti_flag & _T_MALLOC or _T_EMMBUF
	    invoke dlhide,[si].ti_dialog
	.endif
	call topenh
	call close
	mov si,tinfo
	.if si && [si].S_TINFO.ti_flag & _T_MALLOC or _T_EMMBUF
	    invoke dlshow,[si].ti_dialog
	    xor [si].ti_flag,_T_USEMENUS
	    pop si
	    jmp cmtogglemenus
	.endif
    cmloadfiles_end:
	mov ax,_TI_CONTINUE
	pop si
	ret
cmloadfiles endp

cmsavefiles proc
	push	si
	invoke	wgetfile,addr cp_te,2
	jz	cmsavefiles_end
	mov	si,ax
	invoke	tsaveh,si
	invoke	close,si
    cmsavefiles_end:
	mov	ax,_TI_CONTINUE
	pop	si
	ret
cmsavefiles endp

wedit	proc dist pascal uses si di fcb:dword, count:word
	.repeat
	    invoke fbffirst,fcb,count
	    .break .if ZERO?
	    mov si,dx
	    mov di,bx
	    .if !(cx & _A_ARCHIVE or _A_SUBDIR)
		invoke topen,dx::ax
		.break .if ZERO?
	    .endif
	    mov es,si
	    and es:[di.fb_flag],not _A_SELECTED
	.until 0
	sub ax,ax
	call tmodal
	ret
wedit	endp

topensession proc dist pascal public
local	cu:S_CURSOR
	invoke getcursor,addr cu
	call cmloadfiles
	sub ax,ax
	call tmodal
	invoke setcursor,cu
	ret
topensession endp

endif ; __DZ__

_TEXT	ENDS
endif
	end
