;       SCCSID = @(#)bvfmain.asm	6.1 90/11/16
;SCCSID = @(#)bvfmain.asm	6.4 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	BVSMAIN.Asm -- Base Video Subsystem

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SOURCE FILE NAME:  BVSMAIN.Asm					*/
;/*									*/
;/* DESCRIPTIVE NAME:  Base Video Subsystem				*/
;/*									*/
;/* COPYRIGHT:	na							*/
;/*									*/
;/* STATUS:	na							*/
;/*									*/
;/* NOTES:   Executes on level 3 - Protect Mode ONLY			*/
;/*									*/
;/*    DEPENDENCIES:  none						*/
;/*									*/
;/*    RESTRICTIONS:  none						*/
;/*									*/
;/*    PATCH LABEL:   na						*/
;/*									*/
;/* ENTRY POINT:    BVSMAIN						*/
;/*									*/
;/* EXTERNAL REFERENCES:  DOSDEVIOCTL, DOSOPEN				*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

	INCLUDE bvfcb.inc		;BVS Data Structures
	INCLUDE error2.inc		;CP/DOS Error Codes
	.xlist
	INCLUDE struc.inc		;Structured Macros
	.list

BVSDSEG SEGMENT PARA PUBLIC 'DATA'

commonmaster bvscommon <>		;Common data segment

BvfCnfg configdata <40,0,0,0,0,0,0,0,0,0,1,cf_emadapters,1,cf_emdisplays,0,0> ;@@A @@BB7
	public	BvfCnfg 		;@@A

BVSDSEG ENDS

BVSNSEG SEGMENT PARA PUBLIC 'DATA'      ;Instance data segment

ppbvscbmaster ppbvscb <>		;Per Process Base Video Subsystem CB

BVSNSEG ENDS

	EXTRN	BufferUpdate:NEAR	;Retrace Buffer Routines	;P1118
	EXTRN	BvsInit:NEAR
	EXTRN	BVSDINIT:NEAR

BVS3SEG SEGMENT BYTE PUBLIC 'CODE'
	ASSUME	CS:BVS3SEG,ES:BVSDSEG

;/*********************** START OF SPECIFICATIONS ***********************/
;/* SUBROUTINE NAME: BVSROUT						*/
;/*									*/
;/* DESCRIPTIVE NAME: VIO function call router. 			*/
;/*									*/
;/* FUNCTION: Route the VIO function call to the Base Video Subsystem.	*/
;/*									*/
;/* NOTES: None 							*/
;/*									*/
;/* ENTRY POINT: BVSROUT						*/
;/*	LINKAGE: NEAR CALL  (internal call from VIOxxx) 		*/
;/*									*/
;/* INPUT: "FC" - VIOxxx function code for BVS                          */
;/*									*/
;/* EXIT-NORMAL: AX = return code set by video subsystem		*/
;/*									*/
;/* EXIT-ERROR: AX = error code from the AKS or BKS			*/
;/*									*/
;/* EFFECTS: The contents of AX are destroyed.	Also, on exit the input */
;/*	     parameter (1 WORD) is removed from the stack.		*/
;/* INTERNAL								*/
;/* REFERENCES: None							*/
;/*   ROUTINES: None							*/
;/* EXTERNAL								*/
;/* REFERENCES: None.							*/
;/*   ROUTINES: BVSMAIN in BVSCALLS					*/
;/*********************** END OF SPECIFICATIONS *************************/

BVSROUT proc	near
	public	BVSROUT
	push	ds			;For compatibility with Prot Mode
	sub	ax,ax			;Mark as not replaced
	Call	far ptr BVSMAIN
	pop	ds
	ret	2			;return to VIOxxx and remove func code
BVSROUT endp

VIOSCRLOCK proc far
	public	VIOSCRLOCK
	push	es
	push	di
	push	bp
	sub	ax,ax			;Good return code
	mov	bp,sp
	les	di,dword ptr [bp+12]	;Get status return address
	stosb				;Return good status
	pop	bp
	pop	di
	pop	es
	ret	8
VIOSCRLOCK endp

VIOSCRUNLOCK proc far
	public	VIOSCRUNLOCK
	sub	ax,ax			;Good return code
	ret	2
VIOSCRUNLOCK endp

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:  BVSMAIN						*/
;/*									*/
;/* DESCRIPTIVE NAME:  Base Video Subsystem Main Program		*/
;/*									*/
;/* FUNCTION:  Routing of all device dependent functions for the Base	*/
;/*	       Video Subsystem.  It also contains common character	*/
;/*	       movement routines from the user to/from the video buffer */
;/*									*/
;/* NOTES:  Executes on Level 3 					*/
;/*	    BX=0 throughout BVS to optimize addresses and compares	*/
;/*									*/
;/* ENTRY POINT:  BVSMAIN						*/
;/*   LINKAGE:	Far Call to BVSMAIN from VIOROUT			*/
;/*									*/
;/* INPUT:  Stack Frame (Including interface to internal modules)	*/
;/*   BP for --> regfl		 dw	 Register FL save area		*/
;/*   BvsXXXX	 reges		 dw	 Register ES save area		*/
;/*		 regds		 dw	 Register DS save area		*/
;/*		 regdi		 dw	 Register DI save area		*/
;/*		 regsi		 dw	 Register SI save area		*/
;/*		 regbp		 dw	 Register BP save area		*/
;/*		 regspworkarea	 dw	 Work area for general use	*/
;/*		 regbx		 dw	 Register BX save area		*/
;/*		 regdx		 dw	 Register DX save area		*/
;/*		 regcx		 dw	 Register CX save area		*/
;/*		 regax		 dw	 Register AX save area		*/
;/*   SP at ---> vioroutip	 dw	 VIOROUT return offset		*/
;/*   Entry	 vioroutcs	 dw	 VIOROUT return selector	*/
;/*		 vioroutds	 dw	 VIOROUT data selector		*/
;/*		 vioip		 dw	 VIOxxx return offset		*/
;/*		 viofunc	 dw	 VIOxxx Function code		*/
;/*		 userip 	 dw	 User return offset		*/
;/*		 usercs 	 dw	 User return segment		*/
;/*		 parmn		 dw	 Nth parameter			*/
;/*		 parmnm1	 dw	 (N-1)st parameter		*/
;/*		 parmnm2	 dw	 (N-2)nd parameter		*/
;/*		 parmnm3	 dw	 (N-3)rd parameter		*/
;/*		 parmnm4	 dw	 (N-4)th parameter		*/
;/*		 parmnm5	 dw	 (N-5)th parameter		*/
;/*		 parmnm6	 dw	 (N-6)th parameter		*/
;/*		 parmnm7	 dw	 (N-7)th parameter		*/
;/*		 parmnm8	 dw	 (N-8)th parameter		*/
;/*		 parmnm9	 dw	 (N-9)th parameter		*/
;/*									*/
;/*   Registers to BvsXXXX:	 DS	 Selector of BVSCB		*/
;/*				 ES	 Selector of PPBVSCB		*/
;/*				 BP	 pointer to StackFrame above	*/
;/*									*/
;/* EXIT-NORMAL:  AX = 0						*/
;/*									*/
;/* EXIT-ERROR:  AX = VIOxxx return code				*/
;/*		      error_vio_invalid_handle				*/
;/*									*/
;/* EFFECTS:  None							*/
;/*									*/
;/* INTERNAL REFERENCES:  BVSsg = Base Video Subsystem Control Block	*/
;/*			PPBVSCB = Per Process BVSCB (Instance Data)	*/
;/*			  LVBsg = Logical Video Buffer per Screen Group */
;/*   ROUTINES:  BvsGetPhysBuf, BvsGetBuf, BvsShowBuf, BvsGetCurPos,	*/
;/*		 BvsGetCurType, BvsGetMode, BvsSetCurPos, BvsSetCurType,*/
;/*		 BvsSetMode, BvsReadCharStr, BvsReadCellStr,		*/
;/*		 BvsWrtNChar, BvsWrtNAttr, BvsWrtNCell, BvsWrtCharStr,	*/
;/*		 BvsWrtCharStrAtt, BvsWrtCellStr, BvsWrtTTY,		*/
;/*		 BvsScrollUp, BvsScrollDn, BvsScrollLf, BvsScrollRt,	*/
;/*		 BvsGetANSI, BvsSetANSI, BvsGetCP, BvsSetCP, BvsInit,	*/
;/*		 PVBSelector						*/
;/*									*/
;/*   ROUTINES:  None							*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

;Bgnsub BVSMAIN
;: If VioHandle<>0
;: : Set invalid handle return code
;: Else
;: : Call BvsInit to initialize the BVSCB, PPBVSCB, and LVB
;: : Set the background flag to reflect the state of the current process
;: : If the PVB selector not current
;: : : Call PVBSelector to correct the PVB selector
;: : Endif
;: : Call BvsXxx routine according to the function code from VIOROUT
;: : Decrement recursion level
;: Endif
;Endsub

BVSMAIN PROC	FAR

	pushall
	PUSH	DS
	PUSH	ES
	PUSHF
	MOV	BP,SP
	CLD
	sub	bx,bx			;Set dummy base reg

	mov	ah,0Bh
	int	21h			;Check for Control-Break

	mov	ax,bvsnseg
	mov	ds,ax			;DS = PPBVSCB selector

	mov	ax,bvsdseg
	mov	es,ax			;ES = Common data selector

	.if	<es:[bx].cmn_bvscbsize eq bx> ;DynLink Init not yet done
	    pushall
	    PUSH    DS
	    PUSH    ES

	    Call    BVSDINIT		;DynLink Initialization

	    POP     ES
	    POP     DS
	    popall
	.endif

	sub	ax,ax			;Preset good return code
	test	es:[bx].cmn_devtypes,NOT (aioflag+mouflag) ;@@Z
	.if	nz near 		;Some displays found

	    .if     <[bp].viohandle ne bx>
		mov	ax,error_vio_invalid_handle ;Invalid VIO handle
		jmp	finis		;error encountered, abort processing
	    .endif
	    call    BVSInit

	    mov     ax,bvsnseg
	    mov     es,ax		;ES = PPBVS selector

	    mov     ds,es:[bx].ppbvs_bvssel ;DS = BVSCB selector

	    mov     si,bvs_physaddrl
	    mov     di,ppbvs_physaddrl
	    mov     cx,4
	    repe    cmpsw
	    .if     ne
		mov	si,bvs_physaddrl
		mov	di,ppbvs_physaddrl
		mov	cx,4
		rep	movsw
		Call	PVBSelector	;Fix the PVB selector

		mov	ax,bvsnseg	;@@S1
		mov	es,ax		;ES = PPBVS selector  @@S1

		mov	ds,es:[bx].ppbvs_bvssel ;DS = BVSCB selector  @@S1
	    .endif

	    mov     ax,[bp].viofunc
	    mov     [bx].bvs_scratch,ax
	    Call    [bx].bvs_scratch	;Call the BVS routine
	.endif

finis	LABEL	NEAR
	PUBLIC	finis			;Error exit point for BvsInit
	mov	[bp].regax,ax		;Save return code for POPA

	MOV	SP,BP
	POPF
	POP	ES
	POP	DS
	popall
	RET
BVSMAIN ENDP

SetCurData PROC NEAR
	PUBLIC	SetCurData
	sub	dx,dx
	mov	ax,[bx].bvs_grows
	div	[bx].bvs_rows		;Compute PELS/CHAR
	dec	ax
	mov	[bx].bvs_cursorend,ax
	dec	ax
	mov	[bx].bvs_cursorstart,ax
	mov	[bx].bvs_cursorwidth,bx
	mov	[bx].bvs_cursorattr,bx	;Setup cursordata
	ret
SetCurData ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*									*/
;/* SUBROUTINE NAME:  PVBSelector					*/
;/*									*/
;/* DESCRIPTIVE NAME:  BVS PVB Selector (De)Allocation			*/
;/*									*/
;/* FUNCTION:  Deallocates any old PVB select and allocates a new one.	*/
;/*									*/
;/* NOTES:  Executes on Level 3 					*/
;/*									*/
;/* ENTRY POINT:  PVBSelector						*/
;/*   LINKAGE:	Call PVBSelector from BvsSetMode			*/
;/*									*/
;/* INPUT:  ES = PPBVSCB Selector					*/
;/*	    ppbvs_physaddrl,physaddrh,length,lenhigh and pvbsel 	*/
;/*									*/
;/* EXIT-NORMAL:  ppbvs_pvbsel with new selector			*/
;/*									*/
;/* EXIT-ERROR:  Errors from DosDevIoctl				*/
;/*									*/
;/* EFFECTS:  DX destroyed						*/
;/*									*/
;/* INTERNAL REFERENCES:  BVSCBsg, PPBVSCB, Common data area		*/
;/*   ROUTINES: None							*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES: DOSDEVIOCTL						*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

PVBSelector PROC NEAR
	PUBLIC	PVBSelector
	mov	ax,es:[bx].ppbvs_physaddrl
	mov	cl,4
	shr	ax,cl
	mov	dx,es:[bx].ppbvs_physaddrh
	mov	cl,12
	shl	dx,cl
	add	ax,dx
	mov	es:[bx].ppbvs_pvbsel,ax ;Get selector from address
	sub	ax,ax
	RET
PVBSelector ENDP

BVS3SEG ENDS
	END

;@@Z  = 07/17/88 STJ, Add flags for other VGA types, D143
;P1118= 08/28/88 THG, Don't call INT 10h routines if IBM compatibile
;@@A  = 12/14/88 STJ, Add config information to BVSDSEG, P3156
;@@S  = 03/17/89 STJ, Updates related to fix for PTR 3848
;@S2  = 04/11/89 STJ, Move Int10h check to BvsWrite, B701002
;@BB7 = 05/09/89 WKB, Restructure stack frame, B702184
