;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;       SCCSID = @(#)screen01.asm	6.1 90/11/17
;SCCSID = @(#)screen01.asm	1.9 90/02/05
;	SCCSID = @(#)screen01.asm	1.9 90/02/05
; ****************************************************************************
; *									     *
; *									     *
; *									     *
; ****************************************************************************
	PAGE	58,132
	TITLE	Screen Device Driver - (Screen01.Asm)
	.286p								;@T30

;/***********************************************************************/
;/*									*/
;/* SOURCE FILE NAME: Screen01.Asm	STATUS: Version 1.1		*/
;/*									*/
;/* DESCRIPTIVE NAME:  Base Video Subsystem Screen Device Driver	*/
;/*									*/
;/* FUNCTION:	Processes the Init, DeInstall, and Screen IOCtl 	*/
;/*		functions listed below.  All other device commands	*/
;/*		return an error.					*/
;/*									*/
;/* NOTES:  Executes on Level 0 					*/
;/*									*/
;/* ENTRY POINT:  Screen_Strategy					*/
;/*   LINKAGE: Far Call 						*/
;/*									*/
;/* INPUT:  ES = Selector of Request Packet				*/
;/*	    BX = Offset of Request Packet				*/
;/*									*/
;/*   Category 3 Functions:						*/
;/*									*/
;/*	65h	Get 3xBox CodePage (Not supported in 2.0)  @T51 @C13	*/
;/*	70h	Allocate a Selector					*/
;/*	71h	Deallocate a Selector					*/
;/*	74h	Allocate a Selector:Offset			@T30	*/
;/*	75h	Allocate a Selector:Offset				*/
;/*	76h	Allocate a Selector:Offset with requested attr	@B01	*/
;/*									*/
;/*             						        */
;/*   Category 80 Functions added					*/
;/*									*/
;/* EXIT-NORMAL:  Request Block Status Field set to good return code	*/
;/*									*/
;/* EXIT-ERROR:  Request Block Status Field set to error:		*/
;/*									*/
;/*		 Error Code		Cause				*/
;/*		 ------------------------------------------		*/
;/*		 ERROR_I24_BAD_COMMAND	Invalid Request 		*/
;/*									*/
;/* EFFECTS:  None							*/
;/*									*/
;/* INTERNAL REFERENCES:  None						*/
;/*   ROUTINES:  Init, IOCtl						*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES:  Device_Help (DevHlp_PhysToUVirt)			*/
;/*									*/
;/************************ END OF SPECIFICATIONS ************************/

;Bgnsub Screen_Strategy
;: If Function = INIT
;: : Call Init to initialize the device driver
;: Else
;: : Preset return code for INVALID_CATEGORY
;: : If Category = 3
;: : : Preset return code for BAD_COMMAND
;: : : If Function = DEINSTALL
;: : : : Set good return code
;: : : Elseif Funtion = GENERIC IOCtl
;: : : : Call IOCtl to process Screen IOCtl requests
;: : : Endif
;: : Endif
;: : If Category = 80H                                            
;: : : Preset return code for BAD_COMMAND
;: : : Elseif Funtion = GENERIC IOCtl
;: : : : Call SVGA_IOCtl to process SVGA IOCtl requests
;: : : Endif                                                      
;: : If Function = 4,8 or 9  (Read or Write or Write/Verify)  @@5
;: : : Set byte count = 0				      @@5
;: Endif
;Endsub

;Bgnsub IOCtl
;: Preset return code for BAD_COMMAND
;: If Function = Deallocate selector (71h)
;: : Call Device_Help (DevHlp_PhysToUVirt) to deallocate a selector
;: Elseif Function = Allocate selector (70h)
;: : Check for valid range for physical address
;: : If invalid physical address
;: : : Set return code for     address
;: : Else
;: : : Call Device_Help (DevHlp_PhysToUVirt) to allocate a selector
;: : Endif
;: Endif
;Endsub

;Bgnsub SVGA_IOCtl                                        
;: Preset return code for BAD_COMMAND
;: If function supported, Dispatch to it
;: Endif
;Endsub                                                   

;Bgnsub Init
;: Set up end of data and code addresses
;: Set good return code
;Endsub

.xlist
	INCLUDE devhlp.inc		; Define DevHlp functions
	INCLUDE devsym.inc		; Define DOS equates
	INCLUDE basemaca.inc		;;;;;; 2.0 unique (dosmac replacement)
	INCLUDE error.inc		; Define Error Messages
	INCLUDE ioctl.inc		; Define IOCTL equates ;@@B
	INCLUDE struc.inc		; Define STRUC macros
.list

;***************************************
;
;  PVB Address Function Return Structure
;
;***************************************

pvbdata STRUC
pvb_off DW	?			; PVB address offset
pvb_sel DW	?			; PVB address segment/selector
pvb_len DW	?			; Length of the PVB
acc_bit DW	?			; Access bits for function 76H	;@B01
pvbdata ENDS

;                       start of SVGA support
;SVGA category, functions and parameter packet structures
;All SVGA functions in SVGAROUT.ASM

    EXTRN   SVGA_IOCTL          : NEAR  ;           moved to svgarout.asm
    EXTRN   Init                : NEAR  ;           moved to svgarout.asm

SVGA_CATEGORY  EQU  80h     ; SVGA SCREENDD category

BioData SEGMENT WORD PUBLIC 'DATA'    ;           changed alignment
	ASSUME	DS:BioData

; Define I/O packet offsets for useful values.
;
; SEE ALSO
;	CP/DOS Technical Reference manual section on Installable Device Drivers

dev_attribute EQU DEV_CHAR_DEV+DEVLEV_1+DEV_COUT;SCRDD Attribute Word Value           

;**	Device Table Record
;		   *
;	Devices are described by a chain of these records
;
;  Copied from devhdr.inc in dos subdirectory.
;    Note:  Required since Device Name field was not defined as a String!

	Assume	CS:BiosSeg,DS:BioData,ES:NOTHING,SS:NOTHING
	public	Screen$ 		;@SZL
Screen$ DD	-1			; Pointer to next device header ;@SZL
	DW	dev_attribute		; Attributes of the device
	DW	offset BiosSeg:Screen_Strategy ; Strategy entry point
	DW	JustReturn              ; Interrupt entry point
	DB	'SCREEN$ '              ; Dev Name (only 1st byte used for blk)
	DW	0			; Prot-mode CS sel of strat entry pt
	DW	0			; Prot-mode DS sel
	DW	0			; Real-mode CS seg of strat entry pt
	DW	0			; Real-mode DS seg

Public	DevHelp
DevHelp DD	0			; DevHelp Function Router Address

BioData ends

BiosSeg SEGMENT WORD Public 'CODE'
	ASSUME	CS:BiosSeg

PUBLIC	Screen_Strategy
Screen_Strategy PROC FAR
	push	ds			;@@1
	push	es			;@@
	push	bx			;@@
	mov	dh,es:[bx].ReqFunc	; Command code ;1
	.IF	<dh eq CMDInitBase>	;if a base request ;1;@@8;@@B
	    CALL    Init		;process the init ;1
	.ELSE				;1
	    mov     ax,STERR+ERROR_I24_BAD_COMMAND ;Preset error ;1;@@;@@8;@@B
	    .IF     <dh eq CMDDeInstall> ;if a deinstall request ;@@
		sub	ax,ax		;NOERROR ;1
	    .ELSE
		.IF	<dh eq CMDGenIOCtl> ;if a generic IOCtl request ;@@
		    .if     <es:[bx].GIOCategory eq IOC_SC> ;@@;@@B
			CALL	IOCtl	        ;process the IOCtl
		    .else			;           start
		      .if     <es:[bx].GIOCategory eq SVGA_CATEGORY> 
			CALL	SVGA_IOCtl      ;process the IOCtl
                      .endif                    ;           end
                    .endif
		.ELSE			;@@7
		    .IF     <dh eq CMDINPUT> OR ;@@5
		    .IF     <dh eq CMDOUTPUT> OR ;@@5
		    .IF     <dh eq CMDOUTPUTV> ;@@5
		    	sub	ax,ax	;NOERROR ;@@7
		    	mov	es:[bx].IOcount,ax ;Byte Count ;@@5;@@7
		    .ENDIF		;@@5
	        .ENDIF
	    .ENDIF
	.ENDIF
	pop	bx			;@@
	pop	es			;@@
	pop	ds			;@@1
	or	ax,STDON		; Set the done bit
	mov	es:[bx].ReqStat,ax	; Set return status
JustReturn LABEL FAR			;@@
	ret				; restore regs and return
Screen_Strategy ENDP

PUBLIC	IOCtl
IOCtl	PROC	NEAR
	enter	2,0			;Reserve a word for size	;@T30
	DataSize equ <word ptr [bp-2]>	;				;@T30
	mov	dh,es:[bx].GIOFunction	;Get IOCtl function ;@@
	.if	<dh eq 71H>		;Deallocate selector ;@@
	    mov     di,word ptr es:[bx].GIOParaPack ;@@2
	    mov     ax,word ptr es:[bx].GIOParaPack+2 ;Parm ptr ;@@2
	    mov     cx,2		;2-byte buffer ;@@2
	    mov     dh,0		;Read Access ;@@2
	    Call    Verify		;Verify access ;@@2
	    .if     nc			;@@2
		mov	es,word ptr es:[bx].GIOParaPack+2 ;Parm ptr ;@@2
		mov	ax,es:[di]	; selector to free
		mov	dh,2		; UnMap      BUGBUG
		mov	dl,DevHlp_PhysToUVirt
		call	DevHelp
		xor	ax,ax
	    .endif			;@@2
	.else	near
	    mov     DataSize,2		;Return selector only		;@T30
	    sub     si,si		;Default is read access 	;@B01
	    .if     <dh ne 70H> near	;Allocate selector:offset	;@B01
		mov	DataSize,4	;Return selector:offset 	;@T30
	    .endif							;@T30
	    mov     dl,dh		;Save IOCTL function		;@B01
	    .if     <dh eq 70H> or near ;Allocate selector		;@B01
	    .if     <dh ae 75H> near					;@B01

		push	es
		push	bx

		mov	di,word ptr es:[bx].GIOParaPack ;@@2
		mov	ax,word ptr es:[bx].GIOParaPack+2 ;Parm ptr ;@@2
		mov	cx,6		;6-byte buffer ;@@2
		push	dx						;@B01
		mov	dh,0		;Read Access ;@@2
		Call	Verify		;@@2
		pop	dx						;@B01
		.if	nc near 	;@@2

		    mov     es,word ptr es:[bx].GIOParaPack+2 ;Parm ptr ;@@2
		    mov     bx,es:[di].pvb_off ; 32-bit physical address
		    mov     ax,es:[di].pvb_sel ; 32-bit physical address

		    sub     si,si					;@B01
		    mov     cx,es:[di].pvb_len ;Length of PVB ;@@3
		    .if     <dl eq 76H> near				;@B01
			mov	si,es:[di].acc_bit			;@B01
			.if	<si a 5> or	;Invalid access bits	;@B01
			.if	<si eq 2>	;Invalid access bits	;@B01
			    mov     ax,STERR+ERROR_I24_INVALID_PARAMETER;@B01
			    jmp     bad_bits	;			;@B01
			.endif
			or	si,8000h				;@B01
		    .endif						;@B01
		    dec     cx		;@@3
		    sub     dx,dx	;@@3
		    add     cx,bx	;@@3
		    adc     dx,ax	;DX:CX = Addr32 of final byte ;@@3
		    mov     bx,si	;Access bits			;@B01

		    .if     <ax a 000Fh> or ;Above FFFFFh (Prot Mode) or ;@@3
		    .if     <dx a 000Fh> ;Above FFFFFh (Prot Mode) ;@@3;DCR0226
			mov	ax,STERR+ERROR_I24_INVALID_PARAMETER ;@@3
		    .else		;@@3
			mov	cx,es:[di].pvb_len ;Length of PVB
			mov	dh,bl	    ;Access bits		;@B01
			.if	<al ae 000Ah> and ;@@C
			.if	<dl b 000Ch> ;@@3
			    .if     <bh ne 80H> near			;@B01
				mov	dh,5 ;Read/Write Segment ;DCR0216
			    .endif					;@B01
			    sub     si,si ;DCR0216
			.elseif <bl ne 0> and ;Invalid access bits	;@B01
			.if	<bl ne 3>     ;Invalid access bits	;@B01
			    mov     ax,STERR+ERROR_I24_INVALID_PARAMETER;@B01
			    jmp     bad_bits				;@B01
			.endif		;Else dh=0=Read Only ;@@3
			mov	bx,es:[di].pvb_off ; 32-bit phys addr	;@B01
			mov	dl,DevHlp_PhysToUVirt
			call	DevHelp

			mov	si,es	;SI=Selector			;@T30
			mov	dx,bx	;save offset in DX		;@T30
			pop	bx
			pop	es	;Restore Request Block Addressibility
			push	es	;@@2
			push	bx	;Save it again ;@@2

			mov	ax,STERR+ERROR_I24_BAD_COMMAND ; Set error ;1
			.if	nc
			    mov     di,word ptr es:[bx].GIODataPack ;@@2
			    mov     ax,word ptr es:[bx].GIODataPack+2 ;Data ptr ;@@2
			    mov     cx,DataSize ;2 or 4-byte buffer ;@@2;@T30
			    push    dx					;@T30
			    mov     dh,1 ;Read/Write Access ;@@2
			    Call    Verify ;@@2
			    pop     dx					;@T30
			    .if     nc	;@@2
				mov	ds,word ptr es:[bx].GIODataPack+2 ;Data ptr ;@@2t
				.if <DataSize eq 2>			;@T30
				    mov     [di],si   ;Return sel. only ;@T30
				.else					;@T30
				    mov     [di],dx   ;Return sel:off	;@T30
				    mov     [di+2],si			;@T30
				.endif					;@T30
				sub	ax,ax
			    .endif	;@@2
			.endif
		    .endif		;@@3
		.endif			;@@2
bad_bits:	pop	bx		;@@2				;@B01
		pop	es		;Restore Request Block Addr ;@@2
;@T51	    .else							;@C13
;@T51		.if	<dh eq 65H>	    ;Get 3xBox CodePage 	 @C13
;@T51		    Call    Get3xBoxCP					;@C13
;@T51		.endif							;@C13
	    .endif
	.endif
	leave								;@T30
	ret
IOCtl	ENDP

Verify	PROC	NEAR			;@@2
	mov	dl,DevHlp_VerifyAccess	;@@2
	Call	DS:DevHelp		;Verify access ;@@2
	mov	ax,STERR+error_invalid_access ;@@2
	ret				;@@2
Verify	ENDP				;@@2

;@T51 Get3xBoxCP PROC NEAR						;@C13
;@T51	PUBLIC	Get3xBoxCP						;@C13
;@T51	les	di,dword ptr es:[bx].GIODataPack ;Data ptr		 @C13
;@T51	mov	ax,es			;Data ptr			 @C13
;@T51	mov	cx,2			;2-byte buffer = Length 	 @C13
;@T51	mov	dh,0			;Read Access			 @C13
;@T51	Call	Verify			;Verify access			 @C13
;@T51	.if	nc							;@C13
;@T51	    mov     cx,es:[di]		;Get size of output buffer	 @C13
;@T51	    mov     ax,es		;Data ptr			 @C13
;@T51	    mov     dh,1		;Read/Write Access		 @C13
;@T51	    Call    Verify						;@C13
;@T51	    .if     nc							;@C13

;@T51		.if	<cx ae 4>	;Enough room for CodePage	 @C13
;@T51		    push    bx						;@C13
;@T51		    mov     al,11	;Dos CodePage Segment		 @C13
;@T51		    mov     dl,DevHlp_GetDosVar 			;@C13
;@T51		    call    DevHelp	;Get Dos Variable table 	 @C13
;@T51		    mov     ds,ax					;@C13
;@T51		    mov     cx,[bx]	;Get current 3xBox CodePage	 @C13
;@T51		    pop     bx						;@C13

;@T51		    mov     es:[di+2],cx ;Return the CodePage		 @C13
;@T51		    sub     ax,ax					;@C13
;@T51		.endif							;@C13
;@T51	    .endif							;@C13
;@T51	.endif								;@C13
;@T51	RET								;@C13
;@T51 Get3xBoxCP ENDP							;@C13

BiosSeg ends
	end

;1 = 08/15/86 STJ, Add check for invalid category
;@@ = 11/19/86 STJ, Make the device driver loadable
;@@1 = 03/04/87 STJ, 64h = Get data segment addr and shadow PalRegs
;@@2 = 05/04/87 STJ, Start shadowing at DD Init time and change IOCTL
;@@3 = 05/05/87 STJ, Limit selector allocation to 400h-500h and A0000h-FFFFFh
;@@4 = 06/25/87 STJ, Set device and data size to limit, not length
;@@5 = 07/31/87 JMP, Set length to 0 for illegal read/write function calls
;@@6 = 07/31/87 JMP, Get pallete register data address from BIOS data area
;@@7 = 11/30/87 STJ, Add a new IOCTL to get the 3xBox CodePage and do cleanup
;@@A = 12/11/87 STJ, Use a new Init command for base device drivers
;@@B = 03/09/87 STJ, Correctly check for Category IOC_SC (3)
;@@C = 10/02/88 STJ, Changes to support DCR71
;DCR0216 = 02/10/89 STJ, Use new PhysToUVirt request type for video validation
;DCR0226 = 02/17/89 STJ, Remove unused IOCTLs and expand valid selector range
;@C13 = 03/29/89 CJJ, Add back IOCTL to get the 3xBox CodePage, B700817
;@SZL = 04/24/89 STJ, Allow combining of all base DDs
;@T30 = 05/10/89 TPL, DCR 511 changes
;@T51 = 08/26/89 TPL, Removal of 3xbox code in 2.0, DCR 432.10
;@B01 = 01/24/90 WKB, Add IOCTL function 76H in 2.0, DCR 702
;           = 12/28/92 Senja, SVGA support expansion.
