include	clib.inc
include	ctype.inc
include	conio.inc
include	tinfo.inc
include	string.inc
include	dos.inc
include	keyb.inc
include	mouse.inc
include	iost.inc

  ifdef __CLIP__
	extrn	tiselected:	NEAR
	extrn	ticlipevent:	NEAR
  endif
	public	ticurcp
	public	tievent
	public	timodal
	public	tiputs
	public	tiputc
	public	tiseto
	public	tiretevent
	public	ticontinue
	public	tihome
	public	titoend
	public	tidelete
	public	tisetcursor
	public	tiinitcursor
  ifdef __TE__
	public	tiflushl
	public	tiremline
	public	tialignx
	public	tialigny
	extrn	tistyle:near
  endif

_DATA	SEGMENT

ti_keytable label word
	dw	_TI_CONTINUE
	dw      KEY_CTRLRIGHT
	dw      KEY_CTRLLEFT
	dw      KEY_DEL
	dw      KEY_ESC
	dw      MOUSECMD
	dw      KEY_LEFT
	dw      KEY_RIGHT
	dw      KEY_HOME
	dw      KEY_END
	dw      KEY_BKSP
	dw	KEY_TAB
	dw      KEY_ENTER
	dw      KEY_KPENTER
	dw	KEY_UP
	dw	KEY_DOWN
ifdef __TE__
	dw	KEY_PGUP
	dw	KEY_PGDN
	dw	KEY_CTRLPGUP
	dw	KEY_CTRLPGDN
	dw	KEY_CTRLHOME
	dw	KEY_CTRLEND
	dw	KEY_CTRLUP	; Scroll up one line
	dw	KEY_CTRLDN	; Scroll down one line

cp_linetolong	db 'Line too long, was truncated',0

	public	cp_linetolong

endif

ti_proctab label word
	dw	ticontinue
	dw      tinextword
	dw      tiprevword
	dw      tidelete
	dw      tiesc
	dw      timouse
	dw      tileft

	dw      tiright
	dw      tihome
	dw      titoend
	dw      tibacksp
	dw      titab
  ifdef __TE__
	dw	tienter
	dw	tienter
	dw	tiup
	dw	tidown
	dw	tipgup
	dw	tipgdn
	dw      tictrlhome
	dw      tictrlend
	dw      tictrlpgup
	dw      tictrlpgdn
	dw	tiscrollup
	dw	tiscrolldn
  else
	dw      tiesc
	dw      tiesc
	dw      tiesc
	dw      tiesc
  endif

ti_key_count =	(($ - offset ti_proctab) / 2)

_DATA	ENDS

_TEXT	SEGMENT

ticurlp	PROC
	mov	bx,tinfo
  ifdef __TE__
	mov	ax,[bx.ti_loff]		; this return ZF set if	NULL
	add	ax,[bx.ti_yoff]
	call	tigetline
	jz	@F
	call	tistrlen
	test	dx,dx
    @@:
  else
	lodm	[bx.ti_bp]
  endif
	ret
ticurlp	ENDP

ticurcp	PROC
	call	ticurlp
	add	ax,[bx.ti_boff]		; no ZF flag if	__TE__
	add	ax,[bx.ti_xoff]
	ret
ticurcp	ENDP

nocando	PROC
	push	9
	push	1
	call	beep
	mov	ax,_TI_CMFAILED		; end of line/buffer
	ret
nocando	ENDP

ifdef __TE__
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;
	; Increase AX or DX
	;  ZF set if end of line
	;  CF set if DX increased
	;
inc_value proc pascal uses si di dx boff:dword, soff:dword,
	bmax:word, smax:word
	mov si,word ptr boff
	mov di,word ptr soff
	mov ax,[si]
	add ax,[di]
	inc ax
	.if ax >= bmax
	    sub ax,ax
	.else
	    mov dx,[si]
	    mov ax,[di]
	    inc ax
	    .if ax >= smax
		mov ax,smax
		dec ax
		inc dx
	    .endif
;	    test ax,ax
;	    stc
	    mov [di],ax
	    mov [si],dx
	.endif
	ret
inc_value endp

dec_value proc pascal uses si di dx boff:dword, soff:dword,
	bmax:word, smax:word
	mov si,word ptr boff
	mov di,word ptr soff
	mov ax,[si]
	add ax,[di]
	.if ax
	    mov dx,[si]
	    mov ax,[di]
	    .if ax
		dec ax
		and si,si
		stc
	    .else
		dec dx
		and si,si
		clc
	    .endif
	    mov [di],ax
	    mov [si],dx
	.endif
	ret
dec_value endp

tiincx:
	push	ax
	invoke	inc_value,addr ds:[bx.ti_boff],addr ds:[bx.ti_xoff],
		[bx.ti_bcol],[bx.ti_cols]
	pop	ax
	ret
tidecx:
	push	ax
	invoke	dec_value,addr ds:[bx.ti_boff],addr ds:[bx.ti_xoff],
		[bx.ti_bcol],[bx.ti_cols]
	pop	ax
	ret

tiincy:
	push ax
	push si
	mov si,[bx].ti_rows
	.if [bx].ti_flag & _T_USEMENUS
	    dec si
	.endif
	invoke inc_value, addr ds:[bx.ti_loff], addr ds:[bx.ti_yoff],
		[bx.ti_brow], si
	pop si
	pop ax
	ret

tidecy:
	push	ax
	invoke	dec_value,addr ds:[bx.ti_loff],addr ds:[bx.ti_yoff],
		[bx.ti_brow],[bx.ti_rows]
	pop	ax
	ret

tialignx PROC		; Align xoff and boff to AX
	push	bx
	push	cx
	mov	bx,tinfo
	mov	cx,[bx.ti_xoff]
	add	cx,[bx.ti_boff]
	cmp	cx,ax
	jb	tialignx_inc
	je	tialignx_end
    tialignx_dec:
	call	tidecx
	jz	tialignx_end
	dec	cx
	cmp	ax,cx
	jne	tialignx_dec
	jmp	tialignx_ok
    tialignx_inc:
	call	tiincx
	jz	tialignx_end
	inc	cx
	cmp	ax,cx
	jne	tialignx_inc
    tialignx_ok:
	inc	cx
    tialignx_end:
	pop	cx
	pop	bx
	ret
tialignx ENDP

tialigny PROC
	push	cx
	mov	bx,tinfo	; Align yoff and loff to AX
	mov	cx,[bx.ti_yoff]
	add	cx,[bx.ti_loff]
	cmp	cx,ax
	jb	tialigny_inc
	je	tialigny_end
    @@:
	call	tidecy
	jz	tialigny_end
	dec	cx
	cmp	ax,cx
	jne	@B
	jmp	tialigny_ok
    tialigny_inc:
	call	tiincy
	jz	tialigny_end
	inc	cx
	cmp	ax,cx
	jne	tialigny_inc
    tialigny_ok:
	inc	cx
    tialigny_end:
	pop	cx
	ret
tialigny ENDP

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

simove	PROC			; move string to &string[1]
	lodsb
	cmp	si,cx		; CX max offset
	jae	simove_eof
	mov     [si-1],ah
	mov	ah,al
	or	al,al
	jnz	simove
	or	cx,cx
    simove_end:
	mov     [si],al		; terminate string
	ret
    simove_eof:
	xor	ax,ax
	jmp	simove_end
simove	ENDP

tistr0B	PROC			; convert a tab before put()
	push	di
	push	ax
	push	bx
	mov	di,ax
	mov	bx,ax
	mov	ax,2000h+TITABCHAR
	cmp	es:[di],al
	jne	tistr0B_end
	mov	es:[di],ah
	cmp	es:[di+1],al
	jne	@F
	mov	byte ptr es:[di],9
    @@:
	or	di,di
	jz	tistr0B_end
    @@:
	dec	di
	cmp	es:[di],al
	jne	@F
	mov	es:[di],ah
	or	di,di
	jnz	@B
    @@:
	cmp	byte ptr es:[di],9
	jne	tistr0B_end
	mov	es:[di],ah
    tistr0B_end:
	pop	bx
	pop	ax
	pop	di
	ret
tistr0B	ENDP

tistrip	PROC		; remove tab-spaces (0B - vertical tab)
	push	ds
	push	si
	push	di
	push	ax
	mov	es,dx
	mov	ds,dx
	mov	si,ax
	mov	di,ax
	cld
    @@:
	lodsb
	cmp	al,TITABCHAR
	je	@B
	dec	si
    tistrip_lod:
	lodsb
	or	al,al
	jz	tistrip_eof
	cmp	al,9
	je      tistrip_09h
    tistrip_sto:
	stosb
	jmp	tistrip_lod
    tistrip_09h:
	stosb
	test	si,7
	jz	tistrip_lod
	mov	ah,8
    @@:
	lodsb
	or	al,al
	jz	tistrip_eof
	cmp	al,9
	je	tistrip_09h
	cmp	al,TITABCHAR
	jne	tistrip_sto
	dec	ah
	jz	tistrip_sto
	jmp	@B
    tistrip_eof:
	stosb
    tistrip_end:
	pop	ax
	pop	di
	pop	si
	pop	ds
	ret
tistrip	ENDP

tiexpand PROC		; Expand Tabs with "tab-spaces" (0B)
	push	ds		; DX:AX string
	push	si
	push	di
	push	bp
	push	ax
	mov	bp,ss:tinfo
	mov	es,dx
	mov	ds,dx
	mov	si,ax
	mov	di,ax
	cld
	mov	cx,[bp.ti_bcol]
	dec	cx
    tiexpand_next:
	lodsb
	or	al,al
	jz	tiexpand_eos
	cmp	al,9
	je	tiexpand_09h
	cmp	di,cx
	je	tiexpand_end
	stosb
	jmp	tiexpand_next
    tiexpand_end:
	mov	al,0
	stosb
    tiexpand_ret:
	pop	ax
	pop	bp
	pop	di
	pop	si
	pop	ds
	ret
    tiexpand_eos:
	or	cx,cx
	jmp	tiexpand_end
    tiexpand_09h:		; insert TAB char
	stosb
	cmp	di,cx
	jae	tiexpand_end
    @@:		; insert "spaces" to next Tab offset
	mov	ah,TITABCHAR
	test	si,7
	jz	tiexpand_next
	push	si
	call	simove
	pop	si
	jz	tiexpand_ret
	inc	si
	mov	di,si
	jmp	@B
tiexpand ENDP

tistrlen PROC		; set byte count in line to .ti_bcnt
	push	es		; set line[size-1]=0
	push	si		; return CX strlen(DX:AX)
	push	di		; assume BX tinfo
	mov	es,dx
	mov	si,ax
	mov	di,ax
	xor	ax,ax
	add	di,[bx.ti_bcol]
	dec	di
	mov	es:[di],al
	mov	di,si
	mov	cx,ax
	dec	cx
	cld
	repnz	scasb
	not	cx
	dec	cx
	mov	[bx.ti_bcnt],cx
	mov	ax,si
	pop	di
	pop	si
	pop	es
	ret
tistrlen ENDP

tistripl PROC		; strip space and tabs from end of line (DX:AX)
	push	bp
	push	es		; uses CX,BX, tinfo.ti_bcnt
	push	si		; return CX strlen(line), BX tinfo
	push	di		;
	mov	si,ax
	invoke	strlen, dx::ax
	mov	di,si
	add	di,ax
	mov	cx,ax
	mov	bp,tinfo
	mov	ax,[bp.ti_flag]
	test	ax,_T_LINEBUF
	jz	tistripl_end
	and	ax,_T_USECONTROL
	jnz	tistripl_end
    tistripl_len:
	dec	di
	cmp	di,si
	jl      tistripl_end
	mov	al,es:[di]
	cmp	al,bl
	je	@F
	cmp	al,bh
	je	@F
	cmp	al,' '
	jne	tistripl_end
    @@:
	mov	es:[di],ah
	dec	cx
	jnz	tistripl_len
    tistripl_end:
	or	cx,cx
	mov	bx,bp
	mov	[bx.ti_bcnt],cx
	mov	ax,si
	pop	di
	pop	si
	pop	es
	pop	bp
	ret
tistripl ENDP

tistripline PROC
	call	ticurlp
	mov	bl,9
	mov	bh,TITABCHAR
	call	tistripl
	ret
tistripline ENDP

optimalfill PROC
	push	bx
	push	cx
	mov	bl,9
	mov	bh,TITABCHAR
	call	tistripl
	test	[si.ti_flag],_T_LINEBUF
	jz	optimalfill_end
	test	[si.ti_flag],_T_OPTIMALFILL
	jz	optimalfill_end
	cmp	cx,8
	jb	optimalfill_end
	push	ds
	push	si
	push	ax
	mov	si,ax
	mov	ds,dx
	mov	es,dx
    optimalfill_load:
	test	si,7
	jnz	optimalfill_skip
	mov	bx,si
	lodsb
	cmp	al,' '
	jne	optimalfill_test
    @@:
	lodsb
	cmp	al,' '
	je	@B
	mov	cx,si
	sub	cx,bx
	mov	si,bx
	lodsb
	cmp	cx,9
	jb	optimalfill_test
	xchg	bx,di
	mov	al,9
	stosb
	mov	al,TITABCHAR
	mov	cx,7
	rep	stosb
	mov	si,di
	mov	di,bx
	dec	si
    optimalfill_skip:
	lodsb
    optimalfill_test:
	or	al,al
	jnz	optimalfill_load
    optimalfill_eos:
	pop	ax
	pop	si
	pop	ds
    optimalfill_end:
	pop	cx
	pop	bx
	ret
optimalfill ENDP
	;
	; Produce output to clipboard or file
	;
	; args:	AX start line	?, 0
	;	DX start offset	?, 0
	;	CX end line	?, line count - 1 ?
	;	BX end offset	?, -1
	;	SI tinfo
	;
tiflushl PROC
	push	si
	push	di
	push	bp
	mov	bp,ax
	mov	di,dx
	call	tigetline
	jz	tiflushl_eoi
	jnc	@F		; CF set if string buffer
	test	[si.ti_flag],_T_LINEBUF
	jnz	tiflushl_eoi	; else CF is EOF
    @@:
	call	optimalfill
	add	di,ax
	add	bx,ax
    tiflushl_loop:
	mov	es,dx
	inc	di
	mov	ax,[si.ti_bcol]
	cmp	bp,cx
	jne	@F
	mov	ax,bx
    @@:
	cmp	di,ax
	ja	tiflushl_eob
	mov	al,es:[di-1]
	or	al,al
	jz	tiflushl_eol
	cmp	al,9
	je	tiflushl_tab
    tiflushl_put:
	assert	al,0,jne,"tiflushl: al=0"
	call	oputc
	jnz	tiflushl_loop	; out of space..
    tiflushl_eof:
	xor	ax,ax
	stc
	jmp	tiflushl_end
    tiflushl_tab:
	mov	ax,di
	and	ax,7
	jz 	tiflushl_putt
    @@:
	mov	ah,es:[di]
	cmp	ah,TITABCHAR
	jne	tiflushl_putt
	inc	di
	inc	al
	cmp	al,8
	jb	@B
    tiflushl_putt:
	mov	al,9
	jmp	tiflushl_put
    tiflushl_eob:		; end of selection buffer
	cmp	bp,cx		; break if last line
	je	tiflushl_eok
    tiflushl_eol:		; end of line
	inc	bp
	cmp	bp,cx
	ja	tiflushl_last	; break if last line (BP==CX)
	mov	ax,bp
	call	tigetline
	jbe	tiflushl_eoi	; break if last line (EOF)
	call	optimalfill
	mov	di,ax
	test	[si.ti_flag],_T_USECRLF
	jz	@F		; insert line: 0D0A or 0A
	mov	al,0Dh
	call	oputc
    @@:
	mov	al,0Ah
	call	oputc
	jz	tiflushl_eof
	mov	ax,di
	jmp	tiflushl_loop
    tiflushl_eoi:		; end of input (CF)
	xor	ax,ax
	inc	ax
	stc
	jmp	tiflushl_end
    tiflushl_last:
	dec	bp
    tiflushl_eok:
	xor	ax,ax
	inc	ax
	clc
    tiflushl_end:
	mov	bx,di		; out:	AX result
	mov	dx,bp		;	DX line index
	pop	bp		;	BX line offset
	pop	di
	pop	si
	ret
tiflushl ENDP

tixchgl	PROC		; xchange line [AX] <--> [BP]
	push	si		; size of line: [BP-2]
    tixchgl_get:		; uses DI
	push	ax		; while (getline(AX++))
	call	tigetline	;     xchange(AX, BP);
	mov	cx,[bp-2]	; return AX + 1 or -1
	mov	es,dx		;
	mov	di,ax
	mov	si,bp
	jc	tixchgl_eof
	shr	cx,1
    @@:
	mov	ax,es:[di]
	movsw
	mov	[si-2],ax
	dec	cx
	jnz	@B
	pop	ax
	inc	ax
	jmp	tixchgl_get
    tixchgl_eof:
	jz	tixchgl_end
	shr	cx,1
    @@:
	mov	ax,es:[di]
	movsw
	mov	[si-2],ax
	dec	cx
	jnz	@B
	inc	cx
    tixchgl_end:
	pop	ax
	pop	si
	ret
tixchgl ENDP

tinsline PROC		; Insert a line below line[AX]
	push	si
	push	di
	push	bp
	mov	bx,ax		; BX to line index
	mov	si,tinfo	; create a line buffer on the stack
	mov	ax,[si.ti_bcol]
	sub	sp,ax
	mov	bp,sp		; buffer to BP
	push	ax
	push	ss
	push	bp		; blank line
	push	ax
	call	memzero
	mov	ax,[si.ti_lcnt]	; room for one more line ?
	cmp	ax,[si.ti_brow]
	jae	tinsline_eof
	mov	ax,bx		; insert the blank line
	inc	ax
	call	tixchgl		; return index to last line
	cmp	ax,[si.ti_lcnt]
	jne	tinsline_eof
	inc	[si.ti_lcnt]
    tinsline_end:
	add	sp,[bp-2]	; free buffer
	pop	cx		; line size
	or	ax,ax		; line count
	pop	bp
	pop	di
	pop	si
	ret
    tinsline_eof:
	xor	ax,ax
	jmp     tinsline_end
tinsline ENDP

tiremline PROC		; remove_line(AX, DX)
	push	si
	push	di      	; AX index of line to remove
	push	bp      	; DX number of lines to remove
	mov	bx,ax
	mov	bp,tinfo
	mov	cx,[bp.ti_lcnt]
	mov	ax,[bp.ti_bcol]
	sub	sp,ax
	mov	bp,sp
	push	ax		; [bp-2] line size
	mov	ax,dx
	sub	cx,bx
	push	cx		; [bp-4] max lines
	add	dx,bx
	push	dx		; [bp-6] last line
	push	ax		; [bp-8] count
    @@:
	mov	ax,[bp-6]
	call	tigetline
	jc	@F
	mov	ds,dx
	mov	si,ax
	mov	cx,[bp-2]
	shr	cx,1
	push	ss
	pop	es
	mov	di,bp
	rep	movsw
	push	ss
	pop	ds
	mov	ax,bx
	call	tigetline
	jc	tiremlines_err
	mov	es,dx
	mov	di,ax
	mov	cx,[bp-2]
	shr	cx,1
	mov	si,bp
	rep	movsw
	inc	bx
	inc	word ptr [bp-6]
	dec	word ptr [bp-4]
	jnz	@B
    @@:
	mov	bx,[bp-8]
	mov	si,tinfo
    @@:
	mov	ax,[si.ti_lcnt]
	dec	ax
	call	tigetline
	jz	tiremlines_end
	mov	es,dx
	mov	di,ax
	xor	ax,ax
	mov	cx,[bp-2]
	shr	cx,1
	rep	stosw
	dec	[si.ti_lcnt]
	dec	bx
	jnz	@B
	inc	ax
    tiremlines_end:
	add	sp,[bp-2]
	add	sp,8
	or	ax,ax
	pop	bp
	pop	di
	pop	si
	ret
    tiremlines_err:
	xor	ax,ax
	jmp	tiremlines_end
tiremline ENDP

do_if_lines PROC
	mov	bx,tinfo
	test	[bx.ti_flag],_T_LINEBUF
	jnz	@F
	pop	ax
	jmp	tiretevent
    @@:
  ifdef __TE__
	call	tistripline
  endif
	ret
do_if_lines ENDP

	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;
tiup	PROC
	call	do_if_lines
	xor	ax,ax
	cmp	ax,[bx.ti_yoff]
	je	@F
	dec	[bx.ti_yoff]
	ret
    @@:
	cmp	ax,[bx.ti_loff]
	je	@F
	dec	[bx.ti_loff]
    @@:
	ret
tiup	ENDP

tiscrollup PROC
	call	do_if_lines
	xor	ax,ax
	cmp	ax,[bx.ti_loff]
	je	@F
	dec	[bx.ti_loff]
    @@:
	ret
tiscrollup ENDP

tidown	PROC
	call	do_if_lines
	mov	dx,[bx.ti_loff]
	mov	cx,[bx.ti_yoff]
	mov	ax,dx
	add	ax,cx
	inc	ax
	cmp	ax,[bx.ti_brow]
	jae	tidown_end
	cmp	ax,[bx.ti_lcnt]
	jb	@F
	jmp	ticontinue
    @@:
	mov	ax,[bx.ti_rows]
	dec	ax
	cmp	cx,ax
	jae	@F
	inc	[bx.ti_yoff]
	jmp	ticontinue
    @@:
	mov	ax,[bx.ti_brow]
	sub	ax,dx
	sub	ax,cx
	jz	tidown_end
	dec	ax
	jz	tidown_end
	inc	[bx.ti_loff]
	jmp	ticontinue
    tidown_end:
	jmp	tiretevent
tidown	ENDP

tiscrolldn PROC
	call	do_if_lines
	mov	ax,[bx.ti_loff]
	add	ax,[bx.ti_yoff]
	inc	ax
	cmp	ax,[bx.ti_lcnt]
	jae	@F
	inc	[bx.ti_loff]
    @@:
	jmp	ticontinue
tiscrolldn ENDP

tictrlpgdn PROC
	call	do_if_lines
	mov	ax,[bx.ti_rows]
	assert	ax,0,jne,"Ctrl-PgDn"
	dec	ax
	mov	[bx.ti_yoff],ax
	add	ax,[bx.ti_loff]
	cmp	ax,[bx.ti_lcnt]
	jae	tictrlend
	ret
tictrlpgdn ENDP

tictrlend PROC
	call	do_if_lines
	mov	ax,[bx.ti_lcnt]
	assert	ax,0,jne,"Ctrl-End"
	dec	ax
	call	tialigny
	jmp	ticontinue
tictrlend ENDP

tictrlpgup PROC
	call	do_if_lines
	xor	ax,ax
	mov	[bx.ti_yoff],ax
	ret
tictrlpgup ENDP

tictrlhome PROC
	call	tictrlpgup
	mov	[bx.ti_loff],ax
	ret
tictrlhome ENDP

tipgup	PROC
	call	do_if_lines
	mov	ax,[bx.ti_loff]
	or	ax,ax
	jz	@F
	cmp	ax,[bx.ti_rows]
	jb	@F
	sub	ax,[bx.ti_rows]
	mov	[bx.ti_loff],ax
	jmp	ticontinue
    @@:
	jmp	tictrlhome
tipgup	ENDP

tipgdn	PROC
	call	do_if_lines
	mov	ax,[bx.ti_rows]
	add	ax,ax
	add	ax,[bx.ti_loff]
	cmp	ax,[bx.ti_lcnt]
	jnb	@F
	mov	ax,[bx.ti_loff]
	add	ax,[bx.ti_rows]
	mov	[bx.ti_loff],ax
	jmp	ticontinue
    @@:
	jmp	tictrlend
tipgdn	ENDP

tienterni PROC
	push	si
	push	di
	push	bp
	mov	si,tinfo
	mov	bx,[si.ti_brow]
	mov	ax,[si.ti_loff]
	add	ax,[si.ti_yoff]
	mov	di,ax
	inc	ax
	cmp	ax,bx
	mov	ax,_TI_RETEVENT
	jb	tienterni_do
	dec	bx
	jz	tienterni_end
    tienterni_nocando:
	call	nocando
	jmp	tienterni_end
    tienterni_CONTINUE:
	mov	ax,_TI_CONTINUE
    tienterni_end:
	pop	bp
	pop	di
	pop	si
	ret
    tienterni_do:
	mov	ax,di
	call	tinsline
	jz	tienterni_nocando
	mov	cx,[si.ti_bcol]
	or	[si.ti_flag],_T_MODIFIED
	sub	sp,cx
	mov	bp,sp
	call	ticurcp
	push	dx
	push	ax
	invoke	strcpy, ss::bp, dx::ax
	pop	bx
	pop	es
	xor	ax,ax
	mov	es:[bx],al
	;
	; need to get indent if line above if stripped..
	;
	call	ticurlp
	mov	bx,ax
	xor	cx,cx
    @@:
    	mov	al,es:[bx]
	inc	cx
	inc	bx
	call	isspace
	jnz	@B
	mov	bl,al		; add indent if last char is zero
	mov	bh,0
	mov	ax,di
	inc	ax
	call	tigetline
	jz	tienterni_home
	mov	di,ax
	dec	cx
	jz	tienterni_home
	or	bl,bl
	jnz	tienterni_home
	mov	al,' '
	mov	es,dx
	mov	bx,cx
	rep	stosb
    tienterni_push:
	push	dx
	push	di
	push	ss
	mov	al,TITABCHAR
    @@:
	cmp	ss:[bp],al
	jne	tienterni_cpy
	inc	bp
	jmp	@B
    tienterni_home:
	xor	bx,bx
	jmp	tienterni_push
    tienterni_cpy:
	push	bp
	call	strcpy
	call	tistrip
	call	tiexpand
    tienterni_done:
	add	sp,[si.ti_bcol]
	or	bx,bx		; just move down if indent
	jz	@F
	call	tidown
	call	tiprevword
	call	tinextword
	jmp	tienterni_end
    @@:
    	call	tihome
	call	tidown
	jmp	tienterni_end
tienterni ENDP

tienter_putc PROC
	mov	ax,[si.ti_xoff]
	add	ax,[si.ti_boff]
	push	ax
	mov	al,dl
	call	tiputc
	cmp	ax,_TI_CONTINUE
	pop	dx
	mov	ax,0
	jne	@F
	mov	ax,[si.ti_xoff]
	add	ax,[si.ti_boff]
	sub	ax,dx
    @@:
	or	ax,ax
	ret
tienter_putc ENDP

tienter	PROC
	call	do_if_lines
	push	si
	push	di
	call	tienterni
	cmp	ax,_TI_CONTINUE
	je	@F
	cmp	ax,_TI_RETEVENT
	je	tienter_ret
	jmp	tienter_end
    @@:
	mov	si,tinfo
	mov	ax,[si.ti_flag]
	and	ax,_T_USEINDENT
	jz	tienter_end
	mov	ax,[si.ti_loff]
	add	ax,[si.ti_yoff]
	dec	ax
	call	tigetline
	jz	tienter_end
	mov	es,dx
	mov	di,ax
	add	ax,[si.ti_bcol]
	mov	dx,ax
	xor	cx,cx
    @@:
	mov	al,es:[di]
	call	isspace
	jz	@F
	inc	cx
	inc	di
	cmp	di,dx
	jb	@B
    @@:
	or	cx,cx
	jz	tienter_end
	mov	di,cx
	test	[si.ti_flag],_T_OPTIMALFILL
	jz	tienter_space
    @@:
	cmp	di,8
	jb	tienter_space
	mov	dl,9
	call	tienter_putc
	jz	tienter_end
	cmp	di,ax
	jbe	tienter_end
	sub	di,ax
	jmp	@B
    tienter_space:
	mov	dl,' '
	call	tienter_putc
	jz	tienter_end
	dec	di
	jnz	tienter_space
    tienter_end:
	pop	di
	pop	si
	jmp	ticontinue
    tienter_ret:
	pop	di
	pop	si
	jmp	tiretevent
tienter	ENDP

endif ; __TE__

tiputc	PROC
	mov	bx,tinfo
	mov	cx,ax
	call	getctype
	test	ah,_CONTROL
	jz	tiputc_add
	jmp	tiputc_CONTROL
    tiputc_add:
	mov	ax,[bx.ti_bcnt]
	inc	ax
	cmp	ax,[bx.ti_bcol]
	jae	tiputc_eof
  ifdef __TE__
	call	tiincx
	jz	tiputc_eof
	inc	[bx.ti_bcnt]
	push	cx
	call	ticurlp
	pop	cx
	jz	tiputc_eof
	or	[bx.ti_flag],_T_MODIFIED
	mov	es,dx
	add	ax,[bx.ti_xoff]
	add	ax,[bx.ti_boff]
	test	[bx.ti_flag],_T_LINEBUF
	jnz	tiputc_lbuf
    tiputc_insert:
	dec	ax
	mov	bx,ax
	mov	ah,cl
    tiputc_addcl:
	mov	al,es:[bx]
	mov     es:[bx],ah
	mov	ah,al
	inc	bx
	or	al,al
	jnz	tiputc_addcl
	mov     es:[bx],al
	jmp	tiputc_CONTINUE
    tiputc_lbuf:
	dec	ax
	push	ax
	call	tistr0B
	call	tistrip
	inc	ax
	call	tiputc_insert
	pop	ax
	push	cx
	call	tiexpand
	push	ax
	call	ticurlp
	pop	cx
	mov	bx,ax
	mov	ah,' '
    @@:
	cmp	bx,cx
	je	@F
	mov	al,es:[bx]
	inc	bx
	or	al,al
	jnz	@B
	mov	es:[bx-1],ah
	jmp	@B
    @@:
	pop	cx
	mov	bx,tinfo
	cmp	cl,9
	jne	tiputc_CONTINUE
	mov	ax,[bx.ti_xoff]		; Align xoff and boff to next TAB
	add	ax,[bx.ti_boff]
	mov	cx,ax
	test	al,7
	jz	tiputc_CONTINUE
	and	al,0F8h
	add	al,8
	cmp	cx,ax			; Align xoff and boff to AX
	jb	tiputc_inc
	je	tiputc_CONTINUE
    tiputc_dec:
	call	tidecx
	jz	tiputc_CONTINUE
	dec	cx
	cmp	ax,cx
	jne	tiputc_dec
	jmp	tiputc_CONTINUE
    tiputc_inc:
	call	tiincx
	jz	tiputc_CONTINUE
	inc	cx
	cmp	ax,cx
	jne	tiputc_inc
  else
	push	cx
	call	ticurcp
	push	si
	push	di
	mov	cx,[bx.ti_bcol]
	sub	cx,[bx.ti_xoff]
	sub	cx,[bx.ti_boff]
	dec	cx
	mov	ds,dx
	mov	es,dx
	mov	di,ax
	mov	si,ax
	inc	di
	dec	cx
	mov	ax,si
	add	si,cx
	add	di,cx
	inc	cx
	std
	rep	movsb
	cld
	mov	bx,ax
	pop	di
	pop	si
	pop	ax
	mov	[bx],al
	mov	ax,ss
	mov	ds,ax
	mov	bx,tinfo
	inc	[bx.ti_bcnt]
	inc	[bx.ti_xoff]
	mov	ax,[bx.ti_cols]
	cmp	[bx.ti_xoff],ax
	jl	tiputc_CONTINUE
	dec	ax
	mov	[bx.ti_xoff],ax
	add	ax,[bx.ti_boff]
	cmp	[bx.ti_bcnt],ax
	jbe	tiputc_CONTINUE
	inc	[bx.ti_boff]
  endif
    tiputc_CONTINUE:
	mov	ax,_TI_CONTINUE
	ret
  ifdef __TE__
    tiputc_strbuf:
  else
    tiputc_CONTROL:
  endif
	or	al,al
	jz	tiputc_ret
	test	[bx.ti_flag],_T_USECONTROL
	jnz	tiputc_add
    tiputc_ret:
	mov	ax,_TI_RETEVENT
	ret
    tiputc_eof:
  ifdef __TE__
	mov	ax,[bx.ti_bcol]
	dec	ax
	mov	[bx.ti_bcnt],ax
	mov	ax,offset cp_linetolong
	call	@ermsg
	mov	bx,tinfo
    tiputc_nocando:
  endif
	jmp	nocando
  ifdef __TE__
    tiputc_ENTER:
	jmp	tienterni
    tiputc_CONTROL:
	test	[bx.ti_flag],_T_LINEBUF
	jz	tiputc_strbuf
	cmp	al,9
	je	tiputc_TAB
	cmp	al,0Ah
	je	tiputc_ENTER
	cmp	al,0Dh
	je	tiputc_CONTINUE
	or	al,al
	jz	tiputc_ret
	cmp	al,TITABCHAR
	jne	@F
	mov	cx,' '
      @@:
	jmp	tiputc_add
    tiputc_TAB:
	call	tiputc_add
	cmp	ax,_TI_CONTINUE
	jne	tiputc_nocando
	jmp	tiputc_CONTINUE
  endif
tiputc	ENDP

tidelete PROC
	call	ticurcp
	mov	es,dx
	or	[bx.ti_flag],_T_MODIFIED
	xchg	ax,bx
	cmp	byte ptr es:[bx],0
	xchg	ax,bx
  ifdef __TE__
	je	tidelete_line
	test	[bx.ti_flag],_T_LINEBUF
	jz	tidelete_nol
	call	tistrip
	mov	bx,ax
	test	al,7
	jz	tidelete_do
	mov	ax,es:[bx-1]
	cmp	al,TITABCHAR
	je	tidelete_tabc
	cmp	al,9
	jne	tidelete_do
    tidelete_tab:
	mov	byte ptr es:[bx-1],' '
	jmp	tidelete_endx
    tidelete_tabc:		; convert TITABCHAR to ' ' in front
	push	di
	mov	di,bx
	mov	ah,' '
	assert  di,0,jne,"TITABCHAR[0]"
    tidelete_tcl:
	dec	di
	cmp	es:[di],al
	jne     tidelete_09h
	mov     es:[di],ah
	or	di,di
	jnz	tidelete_tcl
    tidelete_09h:
	assert  <byte ptr es:[di]>,9,je,"[?]TITABCHAR"
	mov     es:[di],ah
	pop	di
	jmp	tidelete_endx
    tidelete_do:
	mov	ax,bx
	push	dx
	push	ax
	inc	ax
	push	dx
	push	ax
	call	strcpy
	cmp	byte ptr es:[bx],TITABCHAR
	je	tidelete_do
    tidelete_endx:
	mov	ax,bx
	call	tiexpand
	mov	bx,tinfo
	or	[bx.ti_flag],_T_MODIFIED
	jmp	ticontinue
    tidelete_nol:
  else
	je	tidelete_end
  endif
	dec	[bx.ti_bcnt]
	push	dx
	push	ax
	inc	ax
	push	dx
	push	ax
	call	strcpy
    tidelete_end:
	jmp	ticontinue
  ifdef __TE__
    tidelete_eof:
	jmp	nocando
    tidelete_line:
	test	[bx.ti_flag],_T_LINEBUF
	jz	tidelete_end
	mov	ax,[bx.ti_loff]
	add	ax,[bx.ti_yoff]
	inc	ax
	cmp	ax,[bx.ti_brow]
	jae	tidelete_end
	cmp	ax,[bx.ti_lcnt]
	jae	tidelete_end
	call	tigetline
	jc	tidelete_end
	push	ax
	push	dx
	push	ax
	call	strlen
	add	ax,[bx.ti_bcnt]
	cmp	ax,[bx.ti_bcol]
	pop	ax
	jae	tidelete_end
	push	si
	push	di
	push	bp
	sub	sp,[bx.ti_bcol]		; add next line to this line
	mov	bp,sp
	push	ss
	push	bp
	push	dx
	push	ax
	call	strcpy
	mov	ax,[bx.ti_loff]
	add	ax,[bx.ti_yoff]
	mov	si,ax
	call	tigetline
	jc	tidelete_pop
	push	dx
	push	ax
	push	ss
	push	bp
	call	strcat
	add	sp,[bx.ti_bcol]
	inc	si
	mov	ax,si
	mov	dx,1
	call	tiremline
    tidelete_pop:
	pop	bp
	pop	di
	pop	si
	jmp	ticontinue
  endif
tidelete ENDP

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

ticontinue PROC
	xor	ax,ax
	ret
ticontinue ENDP

tiretevent PROC
	mov	ax,_TI_RETEVENT
	ret
tiretevent ENDP

titab	PROC
	mov	bx,tinfo
	test	[bx.ti_flag],_T_LINEBUF
	jz	tiretevent
	call	tiputc
	jmp	ticontinue
titab	ENDP

tiesc	PROC
	jmp	tiretevent
tiesc	ENDP

tihome	PROC
  ifdef __TE__
	call	tistripline
  else
	mov	bx,tinfo
  endif
	xor	ax,ax
	mov	[bx.ti_xoff],ax
	mov	[bx.ti_boff],ax
	ret
tihome	ENDP

titoend	PROC
  ifdef __TE__
	call	tistripline
  else
	mov	bx,tinfo
  endif
	mov	dx,[bx.ti_cols]
	dec	dx
	mov	ax,[bx.ti_bcnt]
	cmp	ax,dx
	jle	@F
	mov	ax,dx
    @@:
	mov	[bx.ti_xoff],ax
	mov	dx,[bx.ti_bcnt]
	sub	dx,[bx.ti_cols]
	inc	dx
	xor	ax,ax
	cmp	ax,dx
	jg	@F
	mov	ax,dx
    @@:
	mov	[bx.ti_boff],ax
	add	ax,[bx.ti_xoff]
	cmp	ax,[bx.ti_bcnt]
	jbe	@F
	dec	[bx.ti_boff]
    @@:
	jmp	ticontinue
titoend	ENDP

tiright	PROC
  ifdef __TE__
	mov	bx,tinfo
	test	[bx.ti_flag],_T_LINEBUF
	jz	@F
	call	tiincx
	jmp	ticontinue
    @@:
  endif
	push	di
	call	ticurcp
	mov	es,dx
	mov	di,ax
	mov	al,es:[di]
	sub	di,[bx.ti_xoff]
	or	al,al
	jz	tiright_00
	mov	ax,[bx.ti_cols]
	dec	ax
	cmp	ax,[bx.ti_xoff]
	jbe	tiright_00
	inc	[bx.ti_xoff]
    tiright_ok:
	pop	di
	jmp	ticontinue
    tiright_00:
	invoke	strlen, dx::di
	cmp	ax,[bx.ti_cols]
	jb	tiright_eof
	inc	[bx.ti_boff]
	jmp	tiright_ok
    tiright_eof:
	pop	di
	jmp	nocando
tiright	ENDP

tileft	PROC
	xor	cx,cx
tileft	ENDP

tiback	PROC
	mov bx,tinfo
	xor ax,ax
	.if cx == [bx.ti_xoff]
	    .if cx == [bx.ti_boff]
		mov ax,_TI_CMFAILED
	    .else
		dec [bx.ti_boff]
	    .endif
	.else
	    dec [bx.ti_xoff]
	.endif
	ret
tiback	ENDP

if 0
tigetindent proc
	xor cx,cx
	call tigetline
	.if !ZERO?
	    mov bx,ax
	    .while !ZERO?
		mov al,es:[bx]
		inc cx
		inc bx
		call isspace
	    .endw
	    dec cx
	.endif
	ret
tigetindent endp
endif

tibacksp PROC
	mov bx,tinfo
	xor cx,cx
	mov ax,[bx.ti_boff]
	add ax,[bx.ti_xoff]
	.if ax
	  ifdef __TE__
	  endif
	    call tiback
	    jmp tidelete
	.else
	  ifdef __TE__
	    .if [bx.ti_flag] & _T_LINEBUF
		mov ax,[bx.ti_loff]
		add ax,[bx.ti_yoff]
		.if ax
		    .if [bx.ti_yoff] != cx
			dec [bx.ti_yoff]
		    .else
			dec [bx.ti_loff]
		    .endif
		    jmp @F
		.endif
	    .endif
	  endif
	    jmp	nocando
	.endif
    @@:
	call	tiseto
	call	titoend
	jmp	tidelete
tibacksp ENDP

isword	PROC
	call	getctype
	and	ah,_UPPER or _LOWER or _DIGIT
	jnz	@F
	cmp	al,'_'
	jne	isword_nul
	or	al,al
    @@:
	ret
    isword_nul:
	cmp	al,al
	ret
isword	ENDP

tinextword PROC
	push	ds
	push	si
	call	ticurcp
	mov	ds,dx
	mov	si,ax
	mov	dx,ax
	xchg	bp,bx
	cld
    @@:
	lodsb
	call	isword
	jnz	@B
	or	al,al
	jz      tinextword_eof
    @@:
	lodsb
	or	al,al
	jz      tinextword_eof
	call	isword
	jz	@B
	dec	si
	sub	si,dx
	mov	ax,[bp.ti_boff]
	add	ax,[bp.ti_xoff]
	add	ax,si
	cmp	ax,[bp.ti_bcnt]
	ja	tinextword_eof
	mov	ax,si
	add	ax,[bp.ti_xoff]
	mov	dx,[bp.ti_cols]
	pop	si
	pop	ds
	cmp	ax,dx
	jb	@F
	dec	dx
	sub	ax,dx
	add	[bp.ti_boff],ax
	mov	ax,dx
    @@:
	mov	[bp.ti_xoff],ax
	xchg	bp,bx
	jmp	ticontinue
    tinextword_eof:
	; next line..
	xchg	bp,bx
	pop	si
	pop	ds
	jmp	titoend
tinextword ENDP

tiprevword PROC
	push	ds
	push	si
	mov	bx,tinfo
	mov	ax,[bx.ti_boff]
	add	ax,[bx.ti_xoff]
	or	ax,ax
	jz	tiprevword_eof
	mov	si,ax
	mov	cx,ax
	call	ticurlp
	mov	ds,dx
	mov	dx,ax
	add	si,ax
	std
	lodsb
	inc	si
	call	isword
	jnz	tiprevword_start
	or	al,al
	jnz	tiprevword_l1
	dec	si
    tiprevword_l1:
	call	tiprevword_lodsb
	jz	tiprevword_l1
    tiprevword_l2:
	call	tiprevword_lodsb
	jnz	tiprevword_l2
	mov	ax,si
	cld
	pop	si
	pop	ds
	sub	ax,dx
	add	ax,2
	cmp	ax,[bx.ti_xoff]
	ja	tiprevword_boff
	mov	[bx.ti_xoff],ax
	jmp	ticontinue
    tiprevword_start:
	mov	al,[si-1]
	call	isword
	jnz	tiprevword_l2
	dec	si
	jmp	tiprevword_l1
    tiprevword_boff:
	sub	ax,[bx.ti_xoff]
	mov	[bx.ti_xoff],0
	sub	[bx.ti_boff],ax
	jmp	ticontinue
    tiprevword_eof:
	cld
	pop	si
	pop	ds
	jmp	tihome
    tiprevword_lodsb:
	lodsb
	cmp	si,dx
	jbe	@F
	or	al,al
	jz	@F
	call	isword
	ret
    @@:
	pop	ax
	jmp	tiprevword_eof
tiprevword ENDP

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

timouse	PROC
  ifdef __MOUSE__
	mov	bx,tinfo
	call	mousey
   ifdef __TE__
	mov	bx,tinfo
	call	mousey
	mov	dx,ax
	call	mousex
	mov	cx,ax
	mov	ax,[bx.ti_xpos]
	cmp	cx,ax
	jb	timouse_end
	add	ax,[bx.ti_cols]
	cmp	cx,ax
	jae	timouse_end
	mov	ax,[bx.ti_ypos]
	cmp	dx,ax
	jb	timouse_end
	add	ax,[bx.ti_rows]
	cmp	dx,ax
	jae	timouse_end
	sub	dx,[bx.ti_ypos]
	mov	[bx.ti_yoff],dx
	push	cx
	call	ticurlp
	jz	@F
	invoke	strlen, dx::ax
   @@:
	pop	cx
	sub	cx,[bx.ti_xpos]
	cmp	cx,ax
	jg	@F
	mov	ax,cx
   @@:
	mov	[bx.ti_xoff],ax
	call	tisetcursor
	call	msloop
   else
	cmp	ax,[bx.ti_ypos]
	jne	timouse_end
	call	mousex
	mov	dx,[bx.ti_xpos]
	cmp	al,dl
	jb	timouse_end
	add	dx,[bx.ti_cols]
	cmp	ax,dx
	jnb	timouse_end
	sub	ax,[bx.ti_xpos]
	mov	[bx.ti_xoff],ax
	mov	ax,word ptr [bx.ti_bp]
	add	ax,[bx.ti_boff]
	push	word ptr [bx.ti_bp+2]
	push	ax
	call	strlen
	cmp	ax,[bx.ti_xoff]
	jnb	@F
	mov	[bx.ti_xoff],ax
    @@:
	mov	ax,[bx.ti_xpos]
	add	ax,[bx.ti_xoff]
	invoke	gotoxy, ax, [bx.ti_ypos]
	call	msloop
   endif ; __TE__
	jmp	ticontinue
    timouse_end:
	jmp	tiesc
  else
	jmp	ticontinue
  endif ; __MOUSE__
timouse	ENDP

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

tiseto	PROC
	push	di
	call	ticurlp
	mov	di,ax
  ifdef __TE__
	jz	tiseto_00
	mov	bx,2020h
	call	tistripl
	mov	ax,[bx.ti_boff]		; test if char is visible
	add	ax,[bx.ti_xoff]
	cmp	ax,cx
	jbe	tiseto_00
	test	[bx.ti_flag],_T_LINEBUF
	jz	tiseto_01
	add	di,cx			; length of line
	mov	es,dx			; ES to segment
	mov	cx,ax
	sub	cx,[bx.ti_bcnt]		; CX to pad count
   ifdef _PADD_WITH_TABS
	test	[bx.ti_flag],_T_OPTIMALFILL
	jz	tiseto_space
    tiseto_tab:
	mov	dx,di			; insert '\t' if possible
	add	dx,cx
	mov	ax,di
	and	ax,not 7
	add	ax,8
	cmp	ax,dx
	ja	tiseto_space
	sub	ax,di
	mov	ah,al
	mov	al,9
    @@:
	stosb
	mov	al,TITABCHAR
	dec	cx
	dec	ah
	jnz	@B
	jmp	tiseto_tab
    tiseto_space:			; padd the rest with ' '
   endif
	mov	ax,' '
	cld
	rep	stosb
	mov	al,ah
	stosb
	jmp	tiseto_01
  else
	push	dx
	push	ax
	add	ax,[bx.ti_bcol]
	dec	ax
	mov	es,dx
	mov	bx,ax
	xor	ax,ax
	mov	es:[bx],al
	call	strlen
	mov	dx,ax
	mov	bx,tinfo
	mov	[bx.ti_bcnt],ax
	mov	ax,[bx.ti_boff]		; test if char is visible
	add	ax,[bx.ti_xoff]
	cmp	ax,dx
	jb	tiseto_00
  endif
    tiseto_toend:
	call	titoend			; if not --> to end of line
    tiseto_01:
	mov	ax,1
    tiseto_end:
	pop	di
	ret
    tiseto_00:
	xor	ax,ax
	jmp	tiseto_end
tiseto	ENDP

tievent	PROC
	mov cx,ti_key_count
	xor bx,bx
	.while cx
	    .if ax == [bx+ti_keytable]
		jmp [bx+ti_proctab]
	    .endif
	    add bx,2
	    dec cx
	.endw
	call tiputc
	ret
tievent	ENDP

tiinitcursor PROC
	mov	bx,tinfo
	mov     [bx.ti_cursor.cr_type],CURSOR_NORMAL
tiinitcursor ENDP

tisetcursor PROC
	mov	bx,tinfo
	mov	ax,[bx.ti_xpos]
	add	ax,[bx.ti_xoff]
	mov	dl,al
	mov	ah,byte ptr [bx.ti_ypos]
  ifdef __TE__
	test	[bx.ti_flag],_T_LINEBUF
	jz	@F
	add	ah,byte ptr [bx.ti_yoff]
    @@:
  endif
	mov	[bx.ti_cursor.cr_xy],ax
	invoke	setcursor, [bx.ti_cursor]
	ret
tisetcursor ENDP

tiputl	PROC PASCAL
local	lb[2+TIMAXSCRLINE]:BYTE
local	wc[2*TIMAXSCRLINE]:BYTE
local	line:WORD	; current line 0..max
local	loff:WORD	; adress of line
local	lseg:WORD
local	llen:WORD	; length of line
local	clst:WORD	; clip start
local	clen:WORD	; clip end
	push	si
	push	di
	mov	si,tinfo
  ifdef __TE__
	mov	line,ax
	mov	ah,[si.ti_clat]
	mov	al,[si.ti_clch]
	test	[si.ti_flag],_T_USESTYLE
	jz	@F
	;test	[si.ti_flag],_T_LINEBUF
	;jz	@F
	mov	ah,[si.ti_stat]
	mov	al,[si.ti_stch]
    @@:
  else
	mov	ah,[si.ti_clat]
	mov	al,[si.ti_clch]
  endif
	push	ss
	pop	es
	lea	dx,wc
	mov	di,dx
	mov	cx,TIMAXSCRLINE
	cld
	rep	stosw
	mov	di,dx
  ifdef __TE__
	mov	ax,line
	call	tigetline
	mov	loff,ax
	mov	lseg,dx
	jz	tiputl_screen
  else
	lodm	[si.ti_bp]
	mov	loff,ax
	mov	lseg,dx
  endif
	push	dx
	push	ax
	lea	bx,lb
	add	ax,[si.ti_boff]
	invoke	memcpy, ss::bx, dx::ax, TIMAXSCRLINE
	mov	[bx+TIMAXSCRLINE],cl
	call	strlen
	mov	es,dx
	mov	llen,ax
	cmp	ax,[si.ti_boff]
	jbe	tiputl_color
	xchg	si,bx
	mov	cx,TIMAXSCRLINE
    tiputl_cl:
	lodsb
	or	al,al
	jz	tiputl_break
	cmp	al,TITABCHAR
	jne	@F
	mov	al,' '
    @@:
	cmp	al,9
	jne	@F
	test	[bx.ti_flag],_T_SHOWTABS
	jnz	@F
	mov	al,' '
    @@:
	stosb
	inc	di
	dec	cx
	jnz	tiputl_cl
    tiputl_break:
	mov	si,bx
  ifdef __TE__
	test	[si.ti_flag],_T_USESTYLE
	jz	tiputl_color
	push	es
	mov	ax,loff
	mov	di,lseg
	lea	dx,wc
	mov	cx,llen
	mov	bx,line
	call	tistyle
	pop     es
  endif
    tiputl_color:
  ifdef __CLIP__
	xor	ax,ax
	mov	clen,ax		; clip end to   0000
	dec	ax		; clip start to FFFF
	mov	clst,ax
	call	tiselected
	jz	tiputl_screen
  ifdef __TE__
	xor	dx,dx
	cmp	word ptr [si.ti_bp],dx
	jne	tiputl_local
	mov	ax,line
	cmp	ax,[si.ti_clsl]
	jb	tiputl_screen
	je	tiputl_clst
	cmp	ax,[si.ti_clel]
	ja	tiputl_screen
	mov	clst,dx
	je      tiputl_clen
	dec	dx
	mov	clen,dx
	jmp	tiputl_clput
    tiputl_clen:
	mov	ax,[si.ti_cleo]
	mov	clen,ax
	jmp	tiputl_clput
    tiputl_clst:
	dec	dx
	mov	clen,dx
	cmp	ax,[si.ti_clel]
	mov	ax,[si.ti_clso]
	mov	clst,ax
	je	tiputl_clen
	jmp	tiputl_clput
    tiputl_local:
  endif
	mov	ax,[si.ti_clso]
	add	ax,word ptr [si.ti_bp]
	mov	clst,ax
	mov	ax,[si.ti_cleo]
	add	ax,word ptr [si.ti_bp]
	mov	clen,ax
    tiputl_clput:
	mov	cx,TIMAXSCRLINE
	lea	di,wc+1
	mov	al,at_background[B_DarkGray]
	mov	bx,loff
	add	bx,[si.ti_boff]
	mov	dx,clst
    tiputl_cloop:
	cmp	bx,dx
	jb	@F
	cmp	bx,clen
	jae	tiputl_screen
	stosb
	jmp	tiputl_inc
    @@:
	inc	di
    tiputl_inc:
	inc	bx
	inc	di
	dec	cx
	jnz	tiputl_cloop
  endif
    tiputl_screen:
	mov	bx,[si.ti_xpos]
	mov	ax,[si.ti_ypos]
	mov	bh,al
  ifdef __TE__
	mov	ax,line
	sub	ax,[si.ti_loff]
	add	bh,al
  endif
	call	@getxyp
	mov	di,bx
	mov	cx,[si.ti_cols]
	lea	si,wc
	assert	cx,TIMAXSCRLINE,jna,"tiputl"
	rep	movsw
  ifdef __MOUSE__
	call	mouseshow
  endif
	xor	ax,ax
	pop	di
	pop	si
	ret
tiputl	ENDP

tiputs	PROC
	call tisetcursor
  ifdef __TE__
	push si
	push di
	mov di,tinfo
	mov si,[di.ti_rows]
	mov di,[di.ti_loff]
	.if !si
	    inc si
	.endif
	.while si
	    mov ax,di
	    call tiputl
	    inc di
	    dec si
	.endw
	pop di
	pop si
  else
	xor ax,ax
	call tiputl
  endif
	ret
tiputs	ENDP

timodal	proc
	push si
	push di
	mov si,_TI_CONTINUE
	.while si != _TI_RETEVENT
	    call tiseto
	    call tiputs
	    call tgetevent
	  ifdef __CLIP__
	    call ticlipevent
	  endif
	    mov di,ax
	    call tievent
	    mov si,ax
	.endw
	call ticurlp
	invoke strlen, dx::ax
	mov [bx.ti_bcnt],ax
	mov ax,di
	pop di
	pop si
	ret
timodal	ENDP

_TEXT	ENDS

	END
