;       SCCSID = @(#)bvfwrite.asm	6.1 90/11/16
;SCCSID = @(#)bvfwrite.asm	6.3 90/01/23
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
	PAGE	58,132
	TITLE	BvsWrite.Asm -- Base Video Subsystem Write Routines

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SOURCE FILE NAME:	BvsWrite.Asm					*/
;/*									*/
;/* DESCRIPTIVE NAME:	BVS Write Routines				*/
;/*									*/
;/* COPYRIGHT:	na							*/
;/*									*/
;/* STATUS:	na							*/
;/*									*/
;/* NOTES:	Executes on level 3 - Protect Mode ONLY 		*/
;/*									*/
;/*    DEPENDENCIES:	None						*/
;/*									*/
;/*    RESTRICTIONS:	None						*/
;/*									*/
;/*    PATCH LABEL:	na						*/
;/*									*/
;/* ENTRY POINTS: BvsWrtNAttr, BvsWrtNChar, BvsWrtNCell,		*/
;/*		  BvsWrtCharStr, BvsWrtCellStr, BvsWrtCharStrAtt	*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/************************ END OF SPECIFICATIONS ************************/

	.xlist
	INCLUDE bvfcb.inc		;BVS Data Structures
	INCLUDE error2.inc		;Error Equates
	INCLUDE struc.inc		;Structured Macros
	.list

BVSNSEG SEGMENT PARA PUBLIC 'DATA'
BVSNSEG ENDS

	EXTRN	BufferUpdate:NEAR	;Retrace Buffer Routines	;P1118
	extrn	BVSROUT:NEAR

BVS3SEG SEGMENT BYTE PUBLIC 'CODE'
	ASSUME	CS:BVS3SEG

VIOWRTNCHAR proc far
	public	VIOWRTNCHAR
	pushi	<offset CS:BvsWrtNChar>
	call	BVSROUT
	ret	12			;5 words + VioHandle
VIOWRTNCHAR endp

VIOWRTNATTR proc far
	public	VIOWRTNATTR
	pushi	<offset CS:BvsWrtNAttr>
	call	BVSROUT
	ret	12			;5 words + VioHandle
VIOWRTNATTR endp

VIOWRTNCELL proc far
	public	VIOWRTNCELL
	pushi	<offset CS:BvsWrtNCell>
	call	BVSROUT
	ret	12			;5 words + VioHandle
VIOWRTNCELL endp

VIOWRTCHARSTR proc far
	public	VIOWRTCHARSTR
	pushi	<offset CS:BvsWrtCharStr>
	call	BVSROUT
	ret	12			;5 words + VioHandle
VIOWRTCHARSTR endp

VIOWRTCHARSTRATT proc far
	public	VIOWRTCHARSTRATT
	pushi	<offset CS:BvsWrtCharStrAtt>
	call	BVSROUT
	ret	16			;7 words + VioHandle
VIOWRTCHARSTRATT endp

VIOWRTCELLSTR proc far
	public	VIOWRTCELLSTR
	pushi	<offset CS:BvsWrtCellStr>
	call	BVSROUT
	ret	12			;5 words + VioHandle
VIOWRTCELLSTR endp

;Stack equates for BvsWrite routines

w_attr	EQU	parmn-4 		;Attribute (unadjusted)
w_attroff EQU	parmn-4 		;Offset of Attribute (unadjusted)
w_attrsel EQU	parmn-2 		;Selector of Attribute (unadjusted)
w_column EQU	parmn			;Starting column
w_row	EQU	parmnm1 		;Starting row
w_times EQU	parmnm2 		;Number of times to write
w_length EQU	parmnm2 		;Number of bytes to write
w_stroff EQU	parmnm3 		;Offset of Item
w_strsel EQU	parmnm4 		;Selector of Item
	PAGE
;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	BvsWrtNAttr					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Write N attributes				*/
;/*									*/
;/* FUNCTION:	N attributes are written to the screen			*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen. 						*/
;/*									*/
;/* NOTES:	Executes on level 3, protect mode only			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtNAttr						*/
;/*   LINKAGE:	Call BvsWrtNAttr from BVSMAIN				*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_times	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of Attribute			*/
;/*	parmnm4 = w_strsel	Selector of Attribute			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute 		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;Call CheckWriteParms
;move n attributes to destination (Call StoreBCSD)
;move zero to the AX register
;return

BvsWrtNAttr PROC NEAR
;	PUBLIC	BvsWrtNAttr

	Call	CheckWriteParms
	.if	z

	    .if     <BIT [bx].bvs_flags AND bvs_f_reqint10h> ;@S2

		mov	dh,byte ptr [bp].w_row ;P1118
		mov	dl,byte ptr [bp].w_column ;P1118

		mov	ax,40h
		mov	ds,ax
		mov	di,cx
		push	[bx].real_cursorposn ;Get current curpos

		mov	bl,byte ptr es:[si] ;Attribute

		.repeat
		    mov     ds:real_cursorposn,dx ;Set requested curpos

		    mov     ah,8
		    int     10h 	;Read cell at curpos

		    mov     cx,1
		    mov     ah,9
		    int     10h 	;Write cell at curpos

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr ds:real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     di
		.until	z

		sub	bx,bx
		pop	[bx].real_cursorposn ;Restore curpos

	    .else			;@S2
		inc	di		;point to the attribute 		;P1118
		mov	al,es:[si]	;P1118
		mov	si,ax		;Get attribute in SI			;P1118
		mov	al,StBCSD	;put them on the screen 		;P1118
		Call	BufferUpdate	;put them on the screen 		;P1118
	    .endif			;@S2

	    sub     ax,ax		;Set good return code
	.endif
	RET				;exit
BvsWrtNAttr ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	BvsWrtNChar					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Write N characters				*/
;/*									*/
;/* FUNCTION:	N characters are written to the screen			*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen. 						*/
;/*									*/
;/* NOTES:	Executes on level 3, protect mode ONLY			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtNChar						*/
;/*   LINKAGE:	Call BvsWrtNChar from BVSMAIN				*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_times	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of Character			*/
;/*	parmnm4 = w_strsel	Selector of Character			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute 		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;Call CheckWriteParms
;move n chars to destination (Call StoreBCSD)
;move zero to the AX register
;return

BvsWrtNChar PROC NEAR
;	PUBLIC	BvsWrtNChar

	Call	CheckWriteParms
	.if	z

	    .if     <BIT [bx].bvs_flags AND bvs_f_reqint10h> ;@S2

		mov	dh,byte ptr [bp].w_row ;P1118
		mov	dl,byte ptr [bp].w_column ;P1118

		mov	al,es:[si]	;Character
		mov	ah,10
		.if	<BIT [bx].bvs_type AND mode_f_graphics> ;@S2
		    mov     ah,9	;Alternate graphics routine ;@S2
		.endif			;@S2

		mov	si,40h		;@S2
		mov	ds,si		;@S2
		push	[bx].real_cursorposn ;Get current curpos
		mov	[bx].real_cursorposn,dx ;Set requested curpos

		int	10h		;Write chars at curpos

		pop	[bx].real_cursorposn ;Restore curpos

	    .else			;@S2
		mov	al,es:[si]	;P1118
		mov	si,ax		;Get character in SI			;P1118
		mov	al,StBCSD	;P1118
		Call	BufferUpdate	;put them on the screen 		;P1118
	    .endif			;@S2
	    sub     ax,ax		;Set good return code
	.endif
	RET				;exit
BvsWrtNChar ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	BvsWrtNCell					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Write N cells					*/
;/*									*/
;/* FUNCTION:	N cells are written to the screen			*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen. 						*/
;/*									*/
;/* NOTES:	Executes on level 3, protect mode ONLY			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtNCell						*/
;/*   LINKAGE:	Call BvsWrtNCell from BVSMAIN				*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_times	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of Cell				*/
;/*	parmnm4 = w_strsel	Selector of Cell			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute 		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;Call CheckWriteParms
;move n cells to destination (Call StoreWCSD)
;move zero to the AX register
;return

BvsWrtNCell PROC NEAR
;	PUBLIC	BvsWrtNCell

	Call	CheckWriteParms
	.if	z
	    .if     <BIT [bx].bvs_flags AND bvs_f_reqint10h> ;@S2

		mov	dh,byte ptr [bp].w_row ;P1118
		mov	dl,byte ptr [bp].w_column ;P1118

		mov	ax,40h
		mov	ds,ax
		push	[bx].real_cursorposn ;Get current curpos

		mov	[bx].real_cursorposn,dx ;Set requested curpos

		mov	ax,es:[si]	;Char/Attr
		mov	bl,ah		;Attribute
		mov	ah,9
		int	10h		;Write cells at curpos

		sub	bx,bx
		pop	ds:real_cursorposn ;Restore curpos

	    .else			;@S2
		mov	si,es:[si]	;put the cell in SI			;P1118
		mov	al,StWCSD	;P1118
		Call	BufferUpdate	;put them on the screen 		;P1118
	    .endif			;@S2
	    sub     ax,ax
	.endif
	RET				;exit
BvsWrtNCell ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:	BvsWrtCharStr					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Write Char String				*/
;/*									*/
;/* FUNCTION:	The chars are read from the string buffer and put	*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen. 						*/
;/*									*/
;/* NOTES:	Executes on level 3, Protect mode only			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtCharStr 					*/
;/*   LINKAGE:	Call BvsWrtCharStr from BVSMAIN 			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_length	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of String			*/
;/*	parmnm4 = w_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute 		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;Call CheckWriteParms
;move character string to destination (Call MoveBSDA)
;move zero to the AX register
;return

BvsWrtCharStr PROC NEAR
;	PUBLIC	BvsWrtCharStr

	Call	CheckWriteParms
	.if	z
	    .if     <BIT [bx].bvs_flags AND bvs_f_reqint10h> ;@S2
		mov	dh,byte ptr [bp].w_row ;P1118
		mov	dl,byte ptr [bp].w_column ;P1118

		mov	ah,10
		.if	<BIT [bx].bvs_type AND mode_f_graphics> ;@S2
		    mov     ah,9	;Alternate graphics routine ;@S2
		.endif			;@S2
		push	bp		;@S2
		mov	bp,ax		;@S2

		push	es
		pop	ds
		mov	di,cx		;Get length in di

		mov	ax,40h
		mov	es,ax
		push	es:[bx].real_cursorposn ;Get current curpos

		.repeat
		    mov     es:[bx].real_cursorposn,dx ;Set requested curpos
		    mov     cx,1
		    mov     ax,bp	;@S2
		    lodsb		;Get next Character
		    int     10h 	;Write char at curpos

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr es:[bx].real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     di
		.until	z

		pop	es:[bx].real_cursorposn ;Restore curpos
		pop	bp		;@S2
	    .else			;@S2
		mov	al,MvBSDA	;P1118
		Call	BufferUpdate	;move the chars, skip DI attrs		;P1118
	    .endif			;@S2
	    sub     ax,ax		;Set good return code
	.endif
	RET				;exit
BvsWrtCharStr ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	BvsWrtCellStr					*/
;/*									*/
;/* DESCRIPTIVE NAME:	Write Cell String				*/
;/*									*/
;/* FUNCTION:	The cells are read from the cell string buffer and put	*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen. 						*/
;/*									*/
;/* NOTES:	Executes on level 3, protect mode only			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtCellStr 					*/
;/*   LINKAGE:	Call BvsWrtCellStr from BVSMAIN 			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_length	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of String			*/
;/*	parmnm4 = w_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute 		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;Call CheckWriteParms
;move cell string to destination (Call MoveWCSD)
;move zero to the AX register
;return

BvsWrtCellStr PROC NEAR
;	PUBLIC	BvsWrtCellStr

	mov	ax,[bp].w_length
	shr	ax,1
	mov	[bp].w_length,ax	;Use of half length
	Call	CheckWriteParms
	.if	z
	    .if     <BIT [bx].bvs_flags AND bvs_f_reqint10h> ;@S2

		mov	dh,byte ptr [bp].w_row ;P1118
		mov	dl,byte ptr [bp].w_column ;P1118

		mov	di,cx
		push	es
		pop	ds

		mov	ax,40h
		mov	es,ax
		push	es:[bx].real_cursorposn ;Get current curpos

		.repeat
		    mov     es:real_cursorposn,dx ;Set requested curpos
		    lodsw		;Get next Cell
		    mov     bl,ah
		    mov     cx,1
		    mov     ah,9
		    int     10h 	;Write cell at curpos

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr es:real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     di
		.until	z

		sub	bx,bx
		pop	es:[bx].real_cursorposn ;Restore curpos

	    .else			;@S2
		mov	al,MvWCSDW	;P1118
		Call	BufferUpdate	;put it to the screen			;P1118
	    .endif			;@S2
	    sub     ax,ax		;Set good return code
	.endif
	RET				;exit
BvsWrtCellStr ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	BvsWrtCharStrAtt				*/
;/*									*/
;/* DESCRIPTIVE NAME:	Write Char String with an attribute		*/
;/*									*/
;/* FUNCTION:	The chars are read from the string buffer and put	*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen.  The specified attribute is			*/
;/*		written at the attribute positions.			*/
;/*									*/
;/* NOTES:	Executes on level 3, Protect mode ONLY			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtCharStrAtt					*/
;/*   LINKAGE:	Call BvsWrtCharStrAtt from BVSMAIN			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) after BP adjustment: */
;/*	userip	= w_attroff	Offset of Attribute			*/
;/*	usercs	= w_attrsel	Selector of Attribute			*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_length	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of String			*/
;/*	parmnm4 = w_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute 		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCB						*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

;Call CheckWriteParms (Check all the other parms.)
;move character string with specified attribute to destination (Call MoveBWAA)
;move zero to the AX register
;return

BvsWrtCharStrAtt PROC NEAR
;	PUBLIC	BvsWrtCharStrAtt

	add	bp,4			;Adjust for Attr ptr
	les	di,dword ptr [bp].w_attroff
	mov	al,es:[di]
	mov	[bp].w_attr,ax		;Save the attribute
	Call	CheckWriteParms
	.if	z
	    .if     <BIT [bx].bvs_flags AND bvs_f_reqint10h> ;@S2

		mov	dh,byte ptr [bp].w_row ;P1118
		mov	dl,byte ptr [bp].w_column ;P1118

		push	es
		pop	ds
		mov	di,cx		;Number of characters

		mov	ax,40h
		mov	es,ax
		push	es:[bx].real_cursorposn ;Get current curpos
		mov	bl,byte ptr [bp].w_attr ;Get attr for update

		.repeat
		    mov     es:real_cursorposn,dx ;Set requested curpos
		    lodsb		;Get next Character
		    mov     cx,1
		    mov     ah,9
		    int     10h 	;Write cell at curpos

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr es:real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     di
		.until	z

		sub	bx,bx
		pop	es:[bx].real_cursorposn ;Restore curpos

	    .else			;@S2
		mov	ah,byte ptr [bp].w_attr ;Get attr for update ;P1118
		mov	al,MvBWCA	;P1118
		Call	BufferUpdate	;move the chars with constant attr ;P1118
	    .endif			;@S2
	    sub     ax,ax		;Set good return code
	.endif
	sub	bp,4			;Restore BP to normal stackfram
	RET				;exit
BvsWrtCharStrAtt ENDP

;/********************** START OF SPECIFICATIONS ************************/
;/*									*/
;/* SUBROUTINE NAME:	CheckWriteParms 				*/
;/*									*/
;/* DESCRIPTIVE NAME:	Validate Common Write Parameters		*/
;/*									*/
;/* FUNCTION:	The chars are read from the string buffer and put	*/
;/*		starting at the specified row/column location.		*/
;/*		Line wrap occurs if the end of a line is reached.	*/
;/*		The write is terminated if it comes to the end of the	*/
;/*		screen.  The specified attribute is			*/
;/*		written at the attribute positions.			*/
;/*									*/
;/* NOTES:	Executes on level 3, Protect mode ONLY			*/
;/*									*/
;/* ENTRY POINT:  BvsWrtCharStrAtt					*/
;/*   LINKAGE:	Call BvsWrtCharStrAtt from BVSMAIN			*/
;/*									*/
;/* INPUT:  StackFrame and Registers (see BVSMAIN) with:		*/
;/*	parmn	= w_column	Starting column 			*/
;/*	parmnm1 = w_row 	Starting row				*/
;/*	parmnm2 = w_length	Number of times to write		*/
;/*	parmnm3 = w_stroff	Offset of String			*/
;/*	parmnm4 = w_strsel	Selector of String			*/
;/*									*/
;/* EXIT-NORMAL:  AX	= 0						*/
;/*		  ES:DI = Valid pointer passed to routine		*/
;/*		  SI	= Offset computed from Row and Column		*/
;/*		  CX	= Adjusted Length of Write			*/
;/*									*/
;/* EXIT-ERROR: Invalid ptr to Cell/Character/Attribute/String		*/
;/*		Invalid Row value					*/
;/*		Invalid Column value					*/
;/*									*/
;/* EFFECTS:	None							*/
;/*									*/
;/* INTERNAL REFERENCES: BVSCBsg					*/
;/*   ROUTINES:  None							*/
;/*									*/
;/* EXTERNAL REFERENCES: None						*/
;/*   ROUTINES:  None							*/
;/************************ END OF SPECIFICATIONS ************************/

CheckWriteParms PROC NEAR

	Call	CheckInt10h		;@S2

	mov	cx,[bp].w_column
	.if	<cx ae [bx].bvs_cols>
	    mov     ax,error_vio_col	;Set bad column return code
	.else
	    mov     ax,[bp].w_row
	    .if     <ax ae [bx].bvs_rows>
		mov	ax,error_vio_row ;Set bad row return code
	    .else
		mul	[bx].bvs_cols	;Calculate the row offset
		add	ax,cx		;Add the column offset
		add	ax,ax		;Adjust for attributes		;P1118

		mov	di,ax		;Save the buffer index in DI
		mov	ax,[bx].bvs_rows
		mul	[bx].bvs_cols
		add	ax,ax		;P1118
		sub	ax,di
		shr	ax,1		;Calculate max len for write	;P1118

		mov	cx,[bp].w_length
		.if	<cx a ax>
		    mov     cx,ax	;Limit write to maximum length
		.endif
		sub	ax,ax		;Set good return code for routine
	    .endif
	.endif
	les	si,dword ptr [bp].w_stroff ;Get ptr to string

	.if	<zero ax>		;Set the zero flag for testing ;@S2
	    .if     <cxz>		;@S2
		inc	cx		;Reset zero flag if CX was 0 ;@S2
	    .endif			;@S2
	.endif				;@S2

	RET
CheckWriteParms ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:  CheckInt10h					*/
;/*									*/
;/* DESCRIPTIVE NAME:  setup to call INT 10H or BVS routines		*/
;/*									*/
;/* FUNCTION:  Decides whether to call INT 10h routine or not and,	*/
;/*	       based on that decision, may change the worker routine	*/
;/*	       offset at [bp].viofunc.					*/
;/*									*/
;/* NOTES:  Executes on Level 3 					*/
;/*									*/
;/* ENTRY POINT:  CheckInt10h						*/
;/*   LINKAGE:	Call CheckInt10h from BvsMain				*/
;/*									*/
;/* INPUT:  DS = BVSCB selector 					*/
;/*									*/
;/* EXIT-NORMAL:  [bp].viofunc possibly changed to call the BVS 	*/
;/*		  worker routine instead of the INT 10h routine 	*/
;/*									*/
;/* EXIT-ERROR:  N/A							*/
;/*									*/
;/* EFFECTS:  None.							*/
;/*									*/
;/* INTERNAL REFERENCES:  BVSCBsg, PPBVSCB, Common data area		*/
;/*   ROUTINES: None							*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES: Int 10h (Read cell), BufferUpdate			*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

CheckInt10h PROC NEAR			;@S2

	.if	<BIT [bx].bvs_type AND mode_f_graphics>
	    or	    [bx].bvs_flags,bvs_f_reqint10h ;Set flag
	    or	    [bx].bvs_oldmode,mode_f_graphics ;Mark old mode graphics
	.else

;-----------------------------------------------------------------------
; Check to see if mode data has changed, then save current mode data
;-----------------------------------------------------------------------

	    push    ds
	    pop     es			;ES = DS = BVSCB selector

	    mov     si,bvs_type
	    mov     di,bvs_oldmode
	    mov     cx,(size bvs_oldmode)/2
	    repe    cmpsw
	    .if     <ne>		;Mode has changed
		mov	si,bvs_type
		mov	di,bvs_oldmode
		mov	cx,(size bvs_oldmode)/2
		rep	movsw		;Update old mode data

;-----------------------------------------------------------------------
; Read first 8 bytes of video buffer using BufferUpdate
;-----------------------------------------------------------------------

		mov	cx,bvs_readbufsize
		sub	si,si		;source offset = 0
		push	ds
		pop	es		;dest selector
		mov	di,bvs_readbuf1 ;dest. offset

		mov	al,MvWCSDR	;readcellstr
		call	BufferUpdate

;-----------------------------------------------------------------------
; Read first 8 bytes of video buffer using INT 10H (read cell)
;-----------------------------------------------------------------------

		push	ds		;Save BVSCB selector

		mov	si,bvs_readbufsize/2
		mov	ax,40h
		mov	ds,ax
		push	[bx].real_cursorposn ;Get current curpos
		xor	dx,dx
		mov	di,bvs_readbuf2 ;dest. offset

		.repeat
		    mov     [bx].real_cursorposn,dx ;Set requested curpos
		    mov     ah,8
		    int     10h 	;Read cell at curpos
		    stosw		;Save the Cell

		    inc     dl		;Go to next curpos
		    .if     <dl ae <byte ptr [bx].real_crtcols>> ;End of line
			sub	dl,dl
			inc	dh	;Go to next line
		    .endif
		    dec     si
		.until	z

		pop	[bx].real_cursorposn ;Restore curpos

;-----------------------------------------------------------------------
; Compare the read buffers and set the Required Int 10h flag
;-----------------------------------------------------------------------

		pop	ds		;Restore BVSCB selector
		and	[bx].bvs_flags,NOT bvs_f_reqint10h ;Reset flag

		mov	cx,bvs_readbufsize/2
		mov	si,bvs_readbuf1
		mov	di,bvs_readbuf2
		repe	cmpsw

		.if	<ne>		;Different results
		    or	    [bx].bvs_flags,bvs_f_reqint10h ;Mark Int 10h req
		.endif
	    .endif
	.endif

	RET
CheckInt10h ENDP			;@S2

BVS3SEG ENDS
	END

;P1118 = 08/28/88 THG, Don't call INT 10h routines if IBM compatibile
;@S2   = 04/13/89 STJ, Check Int10h usage only before writes, B701002
