;$Author:   BCRANE  $
;$Date:   15 Jun 1992 09:45:32  $
;$Header:   W:/sccs/video/video.asv   1.0   15 Jun 1992 09:45:32   BCRANE  $
;$Log:   W:/sccs/video/video.asv  $
;  
;     Rev 1.0   15 Jun 1992 09:45:32   BCRANE
;  Initial revision.
;$Logfile:   W:/sccs/video/video.asv  $
;$Modtimes$
;$Revision:   1.0  $
;$Workfile:   video.asm  $ 

	Title	Video.asm  -- Media Vision simple video routines
	page	64,131

;   /*\
;   |*|
;   |*|----=====< Video.asm >====-----
;   |*|
;   |*| This module provides video bios services for the caller.
;   |*|
;   \*/

        .xlist
	include model.inc
	include masm.inc
	.list

;
;   /*\
;   |*|----====< _ttyout ( char *, char *,...0 ) >====----
;   |*|
;   |*|  This routine writes the text strings out via TTY
;   |*|
;   |*|  On Entry:
;   |*| 	int1 is the AND mask
;   |*| 	int2 is the XOR mask
;   |*| 	rect * is rectangle to pop
;   |*|
;   |*|  On Exit:
;   |*| 	Nothing
;   |*|
;   |*|----====< _videoattr (int1, int2, rect * ) >====----
;   |*|
;   |*|  This routine will AND/XOR the contents of the rectangle
;   |*|
;   |*|  On Entry:
;   |*| 	int1 is the AND mask
;   |*| 	int2 is the XOR mask
;   |*| 	rect * is rectangle to pop
;   |*|
;   |*|  On Exit:
;   |*| 	Nothing
;   |*|
;   |*|----====< int _videocard () >====----
;   |*|
;   |*|  This routine returns the active adapter type
;   |*|
;   |*|  On Entry:
;   |*|         Nothing
;   |*|
;   |*|  On Exit:
;   |*| 	ax = 1=hgc/mono,2=cga,4=ega,8=vga, 0=error
;   |*|
;   |*|----====< _videofill (int1, int2, rect * ) >====----
;   |*|
;   |*|  This routine will FILL the contents of the rectangle
;   |*|
;   |*|  On Entry:
;   |*| 	int1 is the character
;   |*| 	int2 is the attribute
;   |*| 	rect * is rectangle to pop
;   |*|
;   |*|  On Exit:
;   |*| 	Nothing
;   |*|
;   |*|
;   |*|----=====< long _videogetcurs () >====-----
;   |*|
;   |*| This function returns the cursor position
;   |*|
;   |*|   On Exit:
;   |*|
;   |*| 	DX holds the column position
;   |*| 	AX holds the row    position
;   |*|
;   |*|
;   |*|----=====< void _videosetcurs ( int1, int2 ) >====-----
;   |*|
;   |*| This function sets the cursor position
;   |*|
;   |*|   On Entry:
;   |*|
;   |*| 	int1 is the row
;   |*| 	int2 is the column
;   |*|
;   |*|
;   |*|----=====< void _videopage ( int1 ) >====-----
;   |*|
;   |*| This function sets the current video page
;   |*|
;   |*|   On Entry:
;   |*|
;   |*| 	int1 is the page #
;   |*|
;   |*|
;   |*|----=====< void _videocshape  ( int1, int2 ) >====-----
;   |*|
;   |*| This function sets the cursor shape
;   |*|
;   |*|   On Entry:
;   |*|
;   |*| 	int1 is the starting cursor scan line
;   |*| 	int2 is the ending   cursor scan line
;   |*|
;   |*|
;   |*|----=====< void _videoint     ( &int1, &int2, &int3, &int4 ) >====-----
;   |*|
;   |*| This module provides any video bios services for the caller.
;   |*|
;   |*|   On Entry:
;   |*|
;   |*| 	&int1-int4 are pointers to integers for registers AX,BX,CX,DX
;   |*|
;   |*|   On Exit:
;   |*|
;   |*| 	AX,BX,CX,DX returned in &int1-int4 respectively
;   |*|
;   |*|----=====< void _zipout ( char * ) >====-----
;   |*|
;   |*| This routine writes an ASCIIZ string to the screen at the
;   |*| current cursor position.
;   |*|
;   |*|   On Entry:
;   |*|
;   |*| 	char * is a pointer to the string
;   |*|
;   |*|   On Exit:
;   |*|
;   |*| 	AX,BX,CX,DX returned in &int1-int4 respectively
;   |*|
;   \*/

        .data

rect    struc
 xmin	dw	0
 ymin	dw	0
 xmax	dw	0
 ymax	dw	0
rect	ends

video	struc
 wndr	dw	4 dup (0)	; screen X,Y
 row	dw	0		; current cursor row
 col	dw	0		; current cursor column
 attr	db	0		; attribute
 wrap	db	0		; wrap flag
 soff	dw	0		; current screen offset
 sseg	dw	0		; current screen segment
video	ends

VideoPage	db	 0	; save a copy for speed!
OrigCursShape	dw	-1	; cursor shape

if @datasize
	Extrn	CurWnd:dword	; pointer to window block
else
	Extrn	CurWnd:word	; pointer to window block
endif

BLACK_bk	equ	000h
BLUE_bk 	equ	010h
GREEN_bk	equ	020h
CYAN_bk 	equ	030h
RED_bk		equ	040h
PURPLE_bk	equ	050h
BROWN_bk	equ	060h
GREY_bk 	equ	070h

BLACK_fg	equ	000h
BLUE_fg 	equ	001h
GREEN_fg	equ	002h
CYAN_fg 	equ	003h
RED_fg		equ	004h
PURPLE_fg	equ	005h
BROWN_fg	equ	006h
GREY_fg 	equ	007h
IBLACK_fg	equ	008h
IBLUE_fg	equ	009h
IGREEN_fg	equ	00Ah
ICYAN_fg	equ	00Bh
IRED_fg 	equ	00Ch
IPURPLE_fg	equ	00Dh
IBROWN_fg	equ	00Eh
WHITE_fg	equ	00Fh

attributetable	label	byte
	db	GREY_fg 	;  0	CYAN_bk +
	db	IGREEN_fg	;  1	CYAN_bk +
	db	GREY_fg 	;  2	CYAN_bk +
	db	GREY_fg 	;  3	CYAN_bk +
	db	GREY_fg 	;  4	CYAN_bk +
	db	GREY_fg 	;  5	CYAN_bk +
	db	GREY_fg 	;  6	CYAN_bk +
	db	IGREEN_fg	;  7	CYAN_bk +
	db	GREY_fg 	;  8	CYAN_bk +
	db	GREY_fg 	;  9	CYAN_bk +
	db	GREY_fg 	;  a	CYAN_bk +
	db	GREY_fg 	;  b	CYAN_bk +
	db	GREY_fg 	;  c	CYAN_bk +
	db	GREY_fg 	;  d	CYAN_bk +
	db	GREY_fg 	;  e	CYAN_bk +
	db	GREY_fg 	;  f	CYAN_bk +

	db	IGREEN_fg	; 10	CYAN_bk +
	db	IGREEN_fg	; 11	CYAN_bk +
	db	GREY_fg 	; 12	CYAN_bk +
	db	GREY_fg 	; 13	CYAN_bk +
	db	GREY_fg 	; 14	CYAN_bk +
	db	GREY_fg 	; 15	CYAN_bk +
	db	GREY_fg 	; 16	CYAN_bk +
	db	GREY_fg 	; 17	CYAN_bk +
	db	GREY_fg 	; 18	CYAN_bk +
	db	GREY_fg 	; 19	CYAN_bk +
	db	0		; 1a	0
	db	0		; 1b	0
	db	GREY_fg 	; 1c	CYAN_bk +
	db	GREY_fg 	; 1d	CYAN_bk +
	db	GREY_fg 	; 1e	CYAN_bk +
	db	GREY_fg 	; 1f	CYAN_bk +

	db	0		; 20
	db	BLACK_fg	; 21	CYAN_bk +
	db	BLACK_fg	; 22	CYAN_bk +
	db	BLACK_fg	; 23	CYAN_bk +
	db	BLACK_fg	; 24	CYAN_bk +
	db	BLACK_fg	; 25	CYAN_bk +
	db	BLACK_fg	; 26	CYAN_bk +
	db	BLACK_fg	; 27	CYAN_bk +
	db	BLACK_fg	; 28	CYAN_bk +
	db	BLACK_fg	; 29	CYAN_bk +
	db	BLACK_fg	; 2a	CYAN_bk +
	db	BLACK_fg	; 2b	CYAN_bk +
	db	BLACK_fg	; 2c	CYAN_bk +
	db	BLACK_fg	; 2d	CYAN_bk +
	db	BLACK_fg	; 2e	CYAN_bk +
	db	BLACK_fg	; 2f	CYAN_bk +

	db	BLACK_fg	; 30	CYAN_bk +
	db	BLACK_fg	; 31	CYAN_bk +
	db	BLACK_fg	; 32	CYAN_bk +
	db	BLACK_fg	; 33	CYAN_bk +
	db	BLACK_fg	; 34	CYAN_bk +
	db	BLACK_fg	; 35	CYAN_bk +
	db	BLACK_fg	; 36	CYAN_bk +
	db	BLACK_fg	; 37	CYAN_bk +
	db	BLACK_fg	; 38	CYAN_bk +
	db	BLACK_fg	; 39	CYAN_bk +
	db	BLACK_fg	; 3a	CYAN_bk +
	db	BLACK_fg	; 3b	CYAN_bk +
	db	BLACK_fg	; 3c	CYAN_bk +
	db	BLACK_fg	; 3d	CYAN_bk +
	db	BLACK_fg	; 3e	CYAN_bk +
	db	BLACK_fg	; 3f	CYAN_bk +

	db	BLACK_fg	; 40	CYAN_bk +
	db	BLACK_fg	; 41	CYAN_bk +
	db	BLACK_fg	; 42	CYAN_bk +
	db	BLACK_fg	; 43	CYAN_bk +
	db	BLACK_fg	; 44	CYAN_bk +
	db	BLACK_fg	; 45	CYAN_bk +
	db	BLACK_fg	; 46	CYAN_bk +
	db	BLACK_fg	; 47	CYAN_bk +
	db	BLACK_fg	; 48	CYAN_bk +
	db	BLACK_fg	; 49	CYAN_bk +
	db	BLACK_fg	; 4a	CYAN_bk +
	db	BLACK_fg	; 4b	CYAN_bk +
	db	BLACK_fg	; 4c	CYAN_bk +
	db	BLACK_fg	; 4d	CYAN_bk +
	db	BLACK_fg	; 4e	CYAN_bk +
	db	BLACK_fg	; 4f	CYAN_bk +

	db	BLACK_fg	; 50	CYAN_bk +
	db	BLACK_fg	; 51	CYAN_bk +
	db	BLACK_fg	; 52	CYAN_bk +
	db	BLACK_fg	; 53	CYAN_bk +
	db	BLACK_fg	; 54	CYAN_bk +
	db	BLACK_fg	; 55	CYAN_bk +
	db	BLACK_fg	; 56	CYAN_bk +
	db	BLACK_fg	; 57	CYAN_bk +
	db	BLACK_fg	; 58	CYAN_bk +
	db	BLACK_fg	; 59	CYAN_bk +
	db	BLACK_fg	; 5a	CYAN_bk +
	db	BLACK_fg	; 5b	CYAN_bk +
	db	BLACK_fg	; 5c	CYAN_bk +
	db	BLACK_fg	; 5d	CYAN_bk +
	db	BLACK_fg	; 5e	CYAN_bk +
	db	BLACK_fg	; 5f	CYAN_bk +

	db	BLACK_fg	; 60	CYAN_bk +
	db	BLACK_fg	; 61	CYAN_bk +
	db	BLACK_fg	; 62	CYAN_bk +
	db	BLACK_fg	; 63	CYAN_bk +
	db	BLACK_fg	; 64	CYAN_bk +
	db	BLACK_fg	; 65	CYAN_bk +
	db	BLACK_fg	; 66	CYAN_bk +
	db	BLACK_fg	; 67	CYAN_bk +
	db	BLACK_fg	; 68	CYAN_bk +
	db	BLACK_fg	; 69	CYAN_bk +
	db	BLACK_fg	; 6a	CYAN_bk +
	db	BLACK_fg	; 6b	CYAN_bk +
	db	BLACK_fg	; 6c	CYAN_bk +
	db	BLACK_fg	; 6d	CYAN_bk +
	db	BLACK_fg	; 6e	CYAN_bk +
	db	BLACK_fg	; 6f	CYAN_bk +

	db	BLACK_fg	; 70	CYAN_bk +
	db	BLACK_fg	; 71	CYAN_bk +
	db	BLACK_fg	; 72	CYAN_bk +
	db	BLACK_fg	; 73	CYAN_bk +
	db	BLACK_fg	; 74	CYAN_bk +
	db	BLACK_fg	; 75	CYAN_bk +
	db	BLACK_fg	; 76	CYAN_bk +
	db	BLACK_fg	; 77	CYAN_bk +
	db	BLACK_fg	; 78	CYAN_bk +
	db	BLACK_fg	; 79	CYAN_bk +
	db	BLACK_fg	; 7a	CYAN_bk +
	db	BLACK_fg	; 7b	CYAN_bk +
	db	BLACK_fg	; 7c	CYAN_bk +
	db	BLACK_fg	; 7d	CYAN_bk +
	db	BLACK_fg	; 7e	CYAN_bk +
	db	BLACK_fg	; 7f	CYAN_bk +

        .code

;
;   /*\
;---|*|----====< BackupVideo ( rect *, char far *, int, int ) >====----
;---|*|
;---|*| Back up a rectangle in the current window
;---|*|
;---|*| void BackupVideo (rect *r, char far *b, int morex, int morey);
;---|*| Save the screen contents of rectangle X, plus some...
;---|*|
;---|*| Entry Conditions.
;---|*|     parm1 is a pointer to the rectangle
;---|*|     parm2 is a far pointer to the target buffer
;---|*|     parm3 is an int requesting x more rows to be save
;---|*|     parm4 is an int requesting x more colums to be save
;---|*|
;---|*| Exit Conditions:
;---|*|     nothing
;---|*|
;   \*/
	public	BackupVideo
BackupVideo	proc	near
	push	bp
	mov	bp,sp
	push	si
	push	di
	push	ds
	push	es
;
; calculate the screen area
;
	call	calcarea
;
a00:
	push	cx
	mov	cx,bx
	rep	movsw
	add	si,dx
	pop	cx
	loop	a00

	pop	es
	pop	ds
	pop	di
	pop	si
	pop	bp
        ret

BackupVideo	endp

;
;   /*\
;---|*|----====< calcarea >====----
;---|*|
;---|*| calculate the area to be moved
;---|*| the stack frame is pointed to by bp, as it entered into
;---|*| the caller's routine.
;---|*|
;---|*| Entry Conditions.
;---|*|     BP points to:
;---|*|       parm1 is a pointer to the rectangle
;---|*|       parm2 is a far pointer to the target buffer
;---|*|       parm3 is an int requesting xxx more rows to be save
;---|*|       parm4 is an int requesting xxx more colums to be save
;---|*|
;---|*| Exit Conditions:
;---|*|     ES:DI point to the char far * buffer
;---|*|     DS:SI point to the video screen
;---|*|     CX holds the # of rows to move
;---|*|     BX holds the # of columns to save (word count)
;---|*|     DX holds the # of columns to skip (byte count)
;---|*|     direction flag is set
;---|*|
;   \*/

calcarea        proc    near

	mov	si,wParm1		; get the rect *
;
; get the number of rows to be saved into cx
;
	mov	cx,[si.xmax]		; calculate the # of rows
	mov	ax,[si.xmin]
	sub	cx,ax
	inc	cx

	mov	ah,80*2 		; ax holds the offset to the
	mul	ah			; start of the video buffer

	add	cx,wParm4		; add in any more lines
;
; get the number of columns to save in bx, columns to skip in dx
;
	mov	bx,[si.ymax]		; calculate the number of colums
	sub	bx,[si.ymin]
	add	ax,[si.ymin]
        add     ax,[si.ymin]
	inc	bx

	add	bx,wParm5		; add in any more columns

	mov	dx,80			; calc the # of columns to skip
	sub	dx,bx			; bx holds the # of ints to move
	shl	dx,1			; dx holds the # of characters to skip
;
; load the screen segment:offset into ds:si
;
if @datasize
	les	di,CurWnd		; get the segment of the window pointer
	mov	ds,es:[di.sseg]
else
	mov	di,CurWnd		; get the segment of the window pointer
	mov	ds,[di.sseg]
endif
        mov     si,ax                   ; si points to the start
;
; get the buffer pointer into es:di
;
	les	di,wParm2		; get the buffer pointer

	cld				; make sure we move forward
	ret

calcarea	endp

;
;   /*\
;---|*|----====< ChangeAttributes ( int, int, int, int ) >====----
;---|*|
;---|*| Change some attributes in the rectangle
;---|*|
;   \*/
	public	ChangeAttributes
ChangeAttributes proc
	push	bp
	mov	bp,sp
	push	es
	push	di

if @datasize
	les	di,[CurWnd]
	mov	es,es:[di.sseg]
else
	mov	di,[CurWnd]
	mov	es,[di.sseg]
endif
;
chat00:
	mov	cx,wParm4		; get the ending column
	mov	bx,wParm2		; get the starting column
	sub	cx,bx			; cx holds the length
	jb	chat20			; skip if inverted

	inc	cx			; include the starting columm

	mov	di,wParm1		; get the row #
	cmp	di,wParm3		; skip out if past the end
	ja	chatdone		; exit now

	mov	ax,80*2
	mul	di
	xchg	ax,di
	add	di,bx
	add	di,bx			; di points to the end

	lea	bx,attributetable	; get the attribute xlate table
    ;
    chat05:
        mov     al,es:[di]
	test	al,80h
	jnz	chat07
	xlat
	or	al,al
	jz	chat10
	and	bptr es:[di+1],070h
	or	es:[di+1],al
	jmp	short chat10
    ;
    chat07:
	and	bptr es:[di+1],77h
	or	bptr es:[di+1],0Fh
    ;
    chat10:
	inc	di
        inc     di
	loop	chat05			; go for more
;
chat20:
	inc	wptr wParm1		; move down the screen
	jmp	short chat00
;
chatdone:
	pop	di
	pop	es
	pop	bp
	ret

ChangeAttributes endp

;
;   /*\
;---|*|----====< RestoreVideo ( rect *, char far *, int, int ) >====----
;---|*|
;---|*| void RestoreVideo (rect *r, char far *b, int morex, int morey);
;---|*|
;---|*| restore the screen contents of rectangle X, plus some...
;---|*|
;---|*| Entry Conditions.
;---|*|     parm1 is a pointer to the rectangle
;---|*|     parm2 is a far pointer to the source buffer
;---|*|     parm3 is an int requesting x more rows to be save
;---|*|     parm4 is an int requesting x more colums to be save
;---|*|
;---|*| Exit Conditions:
;---|*|     nothing
;---|*|
;   \*/
	public	RestoreVideo
RestoreVideo	proc	near
        push    bp
	mov	bp,sp
	push	si
	push	di
	push	ds
	push	es
;
; calculate the screen area
;
	call	calcarea
;
; swap the pointers
;
	push	es
	push	ds
	pop	es
	pop	ds
	xchg	si,di
;
vr00:
;
; move the data back into the video buffer
;
        push    cx
	mov	cx,bx
	rep	movsw
	add	di,dx
	pop	cx
	loop	vr00
;
; all done, return home
;
	pop	es
	pop	ds
	pop	di
	pop	si
	pop	bp
        ret

RestoreVideo	endp

;
;   /*\
;---|*|----====< _ttyout ( char *, char *,...0 );
;---|*|
;---|*|  This routine writes the text strings out via TTY
;---|*|
;---|*|  On Entry:
;---|*| 	int1 is the AND mask
;---|*| 	int2 is the XOR mask
;---|*| 	rect * is rectangle to pop
;---|*|
;---|*|  On Exit:
;---|*| 	Nothing
;---|*|
;   \*/
	public	_ttyout
_ttyout proc
	push	bp
	mov	bp,sp
	push	ds
	push	si

	lea	bp,wParm1		; bp points to the next string
	mov	bh,VideoPage		; get the current page
	cld
;
to_05:
if @datasize
	lds	si,[bp] 		; get the next string
	add	bp,4
	mov	ax,ds
	or	ax,si
else
	mov	si,[bp] 		; get the next string
	add	bp,2
	or	si,si
endif
	jz	to_exit 		; all done, exit home
	mov	ah,0eh
;
to_10:
	lodsb				; get the character
	or	al,al
	jz	to_05			; go get the next string
	int	10h
	jmp	short to_10
;
to_exit:
	pop	si
	pop	ds
	pop	bp
	ret

_ttyout endp

;
;   /*\
;---|*|----====< _videoattr (int1, int2, rect * );
;---|*|
;---|*|  This routine will AND/XOR the contents of the rectangle
;---|*|
;---|*|  On Entry:
;---|*| 	int1 is the AND mask
;---|*| 	int2 is the XOR mask
;---|*| 	rect * is rectangle to pop
;---|*|
;---|*|  On Exit:
;---|*| 	Nothing
;   \*/

	public	_videoattr
_videoattr      proc
	push	bp
	mov	bp,sp
	push	ds
        push    es
	push	di
	push	si

@psh	equ	(4*2)+2 		; 4 more words stored

lRows		equ    wptr [bp-@psh-0] ; # of rows to hit
lCols		equ    wptr [bp-@psh-2] ; # of columns to hit
lPtr		equ    wptr [bp-@psh-4] ; starting address
lNext		equ    wptr [bp-@psh-6] ; offset to next address
	sub	sp,8			; save some more space

if @datasize
	lds	si,wParm3		; get the rectangle pointer
else
	mov	si,wParm3		; get the rectangle pointer
endif

        mov     ax,[si.xmin]
	mov	dx,[si.xmax]
	sub	dx,ax
	inc	dx			; bx has max rows
	mov	lRows,dx

	mov	bl,80*2
	mul	bl

	mov	cx,[si.ymin]
	add	ax,cx
	add	ax,cx			; ax holds offset to video
	mov	bx,[si.ymax]
	sub	bx,cx
	inc	bx			; bx has max rows

	mov	lCols,bx

	cmp	dx,0			; no rows, bomb out...
	jbe	ViAt_exit
	cmp	bx,0			; no colums, bomb out...
	jbe	ViAt_exit

	sub	bx,80			; get next ptr count
        neg     bx
	add	bx,bx			; double

	mov	lNext,bx

if @datasize
	les	di,[CurWnd]
	mov	es,es:[di.sseg]
else
	mov	di,[CurWnd]
	mov	es,[di.sseg]
endif

	mov	di,ax
	inc	di			; point to attributes

	mov	al,bptr wParm1		; AND mask
	mov	ah,wParm2		; XOR mask
;
ViAt_05:
	mov	cx,lCols		; refresh the column count
;
ViAt_10:
	and	es:[di],al
	xor	es:[di],ah
	add	di,2
	loop	ViAt_10
	add	di,lNext
	dec	lRows
	jnz	ViAt_05
;
; all done, exit home...
;
ViAt_exit:
	add	sp,8			; toss out the local storage
        pop     si
        pop     di
	pop	es
	pop	ds
	pop	bp
	ret

_videoattr	endp

;
;   /*\
;---|*|----====< int _videocard () >====----
;---|*|
;---|*|  This routine returns the active adapter type
;---|*|
;---|*|  On Entry:
;---|*| 	Nothing
;---|*|
;---|*|  On Exit:
;---|*| 	ax = 1=hgc/mono,2=cga,3=ega,4=vga
;   \*/
	public	_videocard
_videocard	proc			; was a near here kdn
	mov	ah,0fh			; check for MONO card being active now
	int	10h
	cmp	al,07h			; current mono mode?
	mov	ax,1			; (set just in case)
	jz	vc_exit 		; yes, return it...

	mov	ax,1c00h
	mov	cx,7
	int	10h
	cmp	al,1ch			; VGA?
	mov	al,08			; (setup just in case)
	jz	vc_exit 		; yes, exit now.

	mov	ah,12h			; check EGA
	mov	bl,10h
	int	10h
	cmp	bl,10h			; changed? (EGA card?)
	mov	al,04
	jnz	vc_exit 		; yes, exit now

	mov	al,02			; return CGA
;
vc_exit:
	cbw
	ret

_videocard     endp

;
;   /*\
;---|*|----====< _videofill (int1, int2, rect * );
;---|*|
;---|*|  This routine will fill the contents of the rectangle
;---|*|
;---|*|  On Entry:
;---|*| 	int1 is the CHARACTER
;---|*| 	int2 is the ATTRIBUTE
;---|*| 	rect * is rectangle to pop
;---|*|
;---|*|  On Exit:
;---|*| 	Nothing
;   \*/

	public	_videofill
_videofill      proc
	push	bp
	mov	bp,sp
	push	ds
        push    es
	push	di
	push	si

@psh	equ	(4*2)+2 		; 4 registers stored

vfRows		equ    wptr [bp-@psh-0] ; # of rows to hit
vfCols		equ    wptr [bp-@psh-2] ; # of columns to hit
vfPtr		equ    wptr [bp-@psh-4] ; starting address
vfNext		equ    wptr [bp-@psh-6] ; offset to next address
        sub     sp,8                    ; save some more space

if @datasize
	lds	si,wParm3		; get the rectangle pointer
else
	mov	si,wParm3		; get the rectangle pointer
endif

        mov     ax,[si.xmin]
	mov	dx,[si.xmax]
	sub	dx,ax
	inc	dx			; bx has max rows
	mov	vfRows,dx

	mov	bl,80*2
	mul	bl

	mov	cx,[si.ymin]
	add	ax,cx
	add	ax,cx			; ax holds offset to video
	mov	bx,[si.ymax]
	sub	bx,cx
	inc	bx			; bx has max rows

	mov	vfCols,bx

	cmp	dx,0			; no rows, bomb out...
	jbe	ViFi_exit
	cmp	bx,0			; no colums, bomb out...
	jbe	ViFi_exit

	sub	bx,80			; get next ptr count
	neg	bx
	add	bx,bx			; double

	mov	vfNext,bx


if @datasize
	les	di,dptr [CurWnd]
	mov	es,es:[di.sseg]
else
	mov	di,[CurWnd]
	mov	es,[di.sseg]
endif
	mov	di,ax

	mov	al,wParm1		; character
	mov	ah,wParm2		; attribute
	cld
;
ViFi_05:
	mov	cx,vfCols		; refresh the column count
	rep	stosw
	add	di,vfNext
	dec	vfRows
	jnz	ViFi_05
;
ViFi_exit:
;
; all done, exit home...
;
	add	sp,8			; toss out the local storage
        pop     si
        pop     di
	pop	es
	pop	ds
	pop	bp
	ret

_videofill	endp

;
;   /*\
;---|*|
;---|*|----=====< long _videogetcurs () >====-----
;---|*|
;---|*| This function returns the cursor position
;---|*|
;---|*|   On Exit:
;---|*|
;---|*| 	DX holds the column position
;---|*| 	AX holds the row    position
;---|*|
;---|*|
;   \*/
	public	_videogetcurs
_videogetcurs	proc
	push	bp
	mov	bp,sp

	mov	ah,03h
	mov	bh,VideoPage
	int	10h

	sub	ax,ax
	xchg	al,dh

	pop	bp
	ret

_videogetcurs	endp

;
;   /*\
;---|*|
;---|*|----=====< void _videosetcurs ( int1, int2 ) >====-----
;---|*|
;---|*| This function sets the cursor position
;---|*|
;---|*|   On Entry:
;---|*|
;---|*| 	int1 is the row
;---|*| 	int2 is the column
;---|*|
;   \*/
	public	_videosetcurs
_videosetcurs	proc
	push	bp
	mov	bp,sp

	mov	ah,02h
        mov     bh,VideoPage
	mov	dl,byte ptr wParm2
	mov	dh,byte ptr wParm1
	int	10h

	pop	bp
	ret

_videosetcurs	endp

;
;   /*\
;---|*|
;---|*|----=====< void _videopage ( int1 ) >====-----
;---|*|
;---|*| This function sets the current video page
;---|*|
;---|*|   On Entry:
;---|*|
;---|*| 	int1 is the page #
;---|*|
;---|*|
;   \*/

	public	_videopage
_videopage      proc
	push	bp
	mov	bp,sp

	mov	ah,05h
	mov	al,byte ptr wParm1
	mov	VideoPage,al
        int     10h

	pop	bp
	ret

_videopage      endp

;
;   /*\
;---|*|
;---|*|----=====< void _videocshape  ( int1, int2 ) >====-----
;---|*|
;---|*| This function sets the cursor shape
;---|*|
;---|*|   On Entry:
;---|*|
;---|*| 	int1 is the starting cursor scan line
;---|*| 	int2 is the ending   cursor scan line
;---|*|
;   \*/

	public	_videocshape
_videocshape    proc
	push	bp
	mov	bp,sp

	cmp	OrigCursShape,-1	; is it -1?
	jnz	vish_found		; no, already fetched...
	mov	ah,3			; yes, get the original shape
	int	10h
	mov	OrigCursShape,cx	; save the new shape
;
vish_found:
	mov	cl,byte ptr wParm1	; get the new shape
	mov	ch,byte ptr wParm2
	cmp	cx,-1			; restoration request?
	jnz	vish_new
	mov	cx,OrigCursShape	; yes, use it!
	cmp	cx,-1			; oops it was never set
	jz	vish_done
;
vish_new:
	mov	ah,01h
        int     10h
;
vish_done:
	pop	bp
	ret

_videocshape	endp

;
;   /*\
;---|*|
;---|*|----=====< void _videoint     ( &int1, &int2, &int3, &int4 ) >====-----
;---|*|
;---|*| This module provides any video bios services for the caller.
;---|*|
;---|*|   On Entry:
;---|*|
;---|*| 	&int1-int4 are pointers to integers for registers AX,BX,CX,DX
;---|*|
;---|*|   On Exit:
;---|*|
;---|*| 	AX,BX,CX,DX returned in &int1-int4 respectively
;---|*|
;   \*/
;

	public	_videoint
_videoint       proc
	push	bp
	mov	bp,sp
if @datasize
	push	es
endif
        push    si

if @datasize
	les	si,dParm1
	mov	ax,es:[si]
else
	mov	si,wParm1
	mov	ax,[si]
endif

if @datasize
	les	si,dParm2
	mov	bx,es:[si]
else
	mov	si,wParm2
	mov	bx,[si]
endif

if @datasize
	les	si,dParm3
	mov	cx,es:[si]
else
	mov	si,wParm3
	mov	cx,[si]
endif

if @datasize
	les	si,dParm4
	mov	dx,es:[si]
else
	mov	si,wParm4
	mov	dx,[si]
endif

        int     10h

if @datasize
	mov	es:[si],dx
else
	mov	[si],dx
endif
if @datasize
	les	si,dParm3
	mov	es:[si],cx
else
	mov	si,wParm3
	mov	[si],cx
endif

if @datasize
	les	si,dParm2
	mov	es:[si],bx
else
	mov	si,wParm2
	mov	[si],bx
endif

if @datasize
	les	si,dParm1
	mov	es:[si],ax
else
	mov	si,wParm1
	mov	[si],ax
endif

	pop	si
if @datasize
        pop     es
endif
        pop     bp
	ret

_videoint	endp

;
;   /*\
;---|*|----====< _zipout ( char * ) >====----
;---|*|
;---|*| print the string at the current cursor position
;---|*|
;   \*/

	public	_zipout
_zipout proc				;was a near here kdn
	push	bp
	mov	bp,sp
	push	ds
        push    es
	push	di
	push	si
;
; calculate the starting position
;
	sub	bx,bx
	mov	es,bx
        mov     ah,0fh                  ; get the page number
	int	10h
	xchg	bh,bl			; bx holds the cursor index

	mov	bx,es:[0450h]		; get the x,y

	mov	di,0b000h		; mono segment
	cmp	al,7
	jz	@F
	mov	di,0b800h
   @@:	mov	es,di

	mov	al,80*2 		; get the column width
	mul	bh			; ax = row offset
	sub	bh,bh
	shl	bx,1			; add colume offset
	add	ax,bx

	mov	di,ax			; es:di point to the screen
;
; load other registers & rip!
;

if @datasize
	lds	si,wParm1		; get the next string
else
        mov     si,wParm1               ; get the string address
endif

	cld
;
_zi05:
	lodsb				; get the next character
	or	al,al
	jz	_zi10			; done...
	stosb
	inc	di
	jmp	short _zi05
;
_zi10:
	pop	si
	pop	di
	pop	es
	pop	ds
	pop	bp
	ret

_zipout endp

	end


