title VT101 module support routines
include mc.ash
.model small
;
;Some of the screen image support functions
;coded in assembly for speed. These all assume
;that char *'s fit into short ints.
;
;	T. Jennings 16 May 85
;
.data
extrn _lptr:dword	;table of line pointers
extrn _line:word	;current line number
extrn _column:word	;current column number

.code
;
;    Scroll the array of line pointers down
;one, between the two specified lines. This 
;rotates an array of pointers, putting the
;one rolled off the bottom at the top.
;
;image_dn(h,l)
;
func _image_dn
	push	bx
	push	cx
	push	si
	push	di
	mov	ax,arg1		;l
	add	ax,ax
	add	ax,ax		;(4 bytes ea.)
	add	di,ax		;;ES:DI= &lptr[l]

	mov	ax,es
	mov	ds,ax
	mov	si,di
	sub	si,4		;DS:SI= lptr[l - 1]

	mov	cx,arg1
	sub	cx,arg0		;line count,
	jbe	id1		;panic test
	add	cx,cx		;2 words ea.

	mov	ax,es:[di]	;save last,
	mov	bx,es:[di + 2]
	std			;backwards,
	rep	movsw		;scroll,
	stosw			;store last
	mov	ax,bx
	stosw
id1:
	pop	di
	pop	si
	pop	cx
	pop	bx
endf _image_dn
;
;image_up(h,l);
;
;    Scroll the screen pointer array up one
;line.
;
func _image_up
	push	bx
	push	cx
	push	si
	push	di
	mov	ax,arg0		;hi line
	add	ax,ax
	add	ax,ax		;(4 bytes ea.)
	les	di,_lptr
	add	di,ax		;ES:DI= &lptr[h]

	mov	ax,es
	mov	ds,ax
	mov	si,di
	add	si,4		;&lptr[h + 1]

	mov	cx,arg1
	sub	cx,arg0		;line count
	jbe	iu1
	add	cx,cx		;(2 words ea.)

	mov	ax,es:[di]	;save lo line
	mov	bx,es:[di + 2]
	cld
	rep	movsw		;scroll
	stosw			;store lo line
	mov	ax,bx
	stosw
iu1:
	pop	di
	pop	si
	pop	cx
	pop	bx
endf _image_up
;
;clrln(l,c,cols,c,a)
;
;Clear a line in the screen image, until end of
;line with the given char and attribute.
;
func _clrln
	push	bx
	push	cx
	push	di
	mov	ax,arg0		;l
	call	line_ptr	;ES:DI= lptr[l]
	add	di,arg1		; lptr[l] + col
	add	di,arg1		;(sizeof(struct _cell)

	mov	cx,arg2		;CX= cols
	sub	cx,arg1		;col count
	jbe	ic1		;eol check

	mov	al,arg3		;AL= char
	mov	ah,arg4		;AH= attr
	cld			;forward
	rep	stosw		;clear it
ic1:
	pop	di
	pop	cx
	pop	bx
endf _clrln

;
;Return ES:DI equal to lptr[AX]
;
line_ptr:
	les	bx,_lptr	;lptr
	add	ax,ax
	add	ax,ax		;4 bytes ea.
	add	bx,ax
	mov	di,es:[bx]
	mov	ax,es:[bx + 2]
	mov	es,ax
	ret
;
;backfill(c,a);
;
;  If the cursor is in the middle of a blank
;line (as when after a LF in the middle of a
;line) fill to the beginning of the line or
;until we hit text with spaces.
;
func _backfill
	push	si
	push	di
	mov	cx,_column	;col/count
	jcxz	bf2

	mov	ax,_line
	call	line_ptr	;ES:DI= lptr[line]
	add	di,cx		; + column
	add	di,cx		;(sizeof(struct _cell)

	mov	ax,es
	mov	ds,ax
	mov	si,di		;DS:SI= ES:DI

	mov	dl,arg0		;DL= char
	mov	dh,arg1		;DH= attr

	std			;backwards
bf1:	lodsb			;sample char
	or	al,al		;if not null
	jnz	bf2		;stop
	mov	ax,dx		;fill char & attr
	stosb			;
	loop	bf1
bf2:	pop	di
	pop	si
endf _backfill

	end

