;*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 = @(#)screen02.asm	6.1 90/11/17
;SCCSID = @(#)screen02.asm	1.7 90/02/05
;	SCCSID = @(#)screen02.asm	1.7 90/02/05
; ****************************************************************************
; *									     *
; *									     *
; *									     *
; ****************************************************************************
	PAGE	58,132
	TITLE	Screen Device Driver - (Screen02.Asm)
	.286p								;@T30

;/***********************************************************************/
;/*									*/
;/* SOURCE FILE NAME: Screen02.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				@C13	*/
;/*	70h	Allocate a Selector					*/
;/*	71h	Deallocate a Selector					*/
;/*	74h	Passthru to Video ABIOS 				*/
;/*	75h	Allocate a Selector:Offset			@T30	*/
;/*	76h	Allocate a Selector:Offset with requested attr	@B01	*/
;/*									*/
;/* 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, GetVideo, SetVideo			*/
;/*									*/
;/* EXTERNAL REFERENCES:  None						*/
;/*   ROUTINES:  Device_Help (DevHlp_PhysToUVirt, DevHlp_GetLIDEntry,	*/
;/*		     DevHlp_ABIOSCall)					*/
;/*									*/
;/************************ 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
;: : : : Free the LID
;: : : : Set good return code
;: : : Elseif Funtion = GENERIC IOCtl
;: : : : Call IOCtl to process Screen IOCtl requests
;: : : Endif
;: : Elseif Function = 4,8 or 9  (Read or Write or Write/Verify)
;: : : Set byte count = 0
;: : Endif
;: 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
;: Elseif Function = Passthru to Video ABIOS (74h)
;: : Call Device_Help (DevHlp_ABIOSCall)
;: Endif
;Endsub

;Bgnsub Init
;: Set up end of data and code addresses
;: Call Device_Help (DevHlp_GetLIDEntry) to get ABIOS information
;: Call Device_Help (DevHlp_ABIOSCall) to get control block sizes
;: Set good return code
;Endsub

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

;STJFMT,,24

ABIOS_Request_Block	STRUC

ABIOS_RB_Len		dw	0	;+00h
ABIOS_DevId		dw	0	;+02h
ABIOS_Unit		dw	0	;+04h
ABIOS_Func		dw	0	;+06h
ABIOS_RBFlags		dw	0	;+08h
ABIOS_ELOff		dw	0	;+0Ah
ABIOS_RetCode		dw	0	;+0Ch
ABIOS_TimeOut		dw	0	;+0Eh
ABIOS_DataPtr1x 	dw	0	;+10h
ABIOS_DataPtr1l 	dw	0	;+12h
ABIOS_DataPtr1h 	dw	0	;+14h
			dw	0
ABIOS_Count		dw	0	;+18h
ABIOS_DevCntlFlag	dw	0	;+1Ah
ABIOS_ScanLines 	db	0	;+1Ch
ABIOS_CharGenType	db	0	;+1Dh
ABIOS_VideoMode 	dw	0	;+1Eh
ABIOS_MonitorType	dw	0	;+20h
ABIOS_CharHeight	dw	0	;+22h
ABIOS_Map2Block 	dw	0	;+24h
ABIOS_UpdateFontFlag	dw	0	;+26h
ABIOS_CharOffset	dw	0	;+28h
ABIOS_FontDataSize	dw	0	;+2Ah
ABIOS_Environment	dw	0	;+2Ch
ABIOS_SR_Header_Size	dw	0	;+2Eh
ABIOS_SR_Hdw_Size	dw	0	;+30h
ABIOS_PaletteReg	dw	0	;+32h
ABIOS_PaletteValue	dw	0	;+34h
			dw	0	;+36h
			dw	0	;+38h
			dw	0	;+3Ah
			dw	0	;+3Ch
			dw	0	;+3Eh = Padding for future use

ABIOS_Request_Block	ENDS

ABIOS_SR_DB_Size	equ	ABIOS_PaletteReg ;+32h
ABIOS_SR_DAC_Size	equ	ABIOS_PaletteValue ;+34h

;STJFMT,

;***************************************
;
;  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 class name 

; 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	offset BiosSeg: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

Public	LID                             ;          
LID	dw	0			;Logical Id
ABIOS_RB ABIOS_Request_Block <> 	;ABIOS Request Block

DATA_END LABEL	BYTE

BioData ends

BiosSeg SEGMENT Byte Public 'CODE'
	ASSUME	CS:BiosSeg

Screen_Strategy PROC FAR
	push	es
	push	bx
	push	bp
	sub	bp,bp
	mov	dh,es:[bx].ReqFunc	; Command code
	.IF	<dh eq CMDInitBase>	;if a base init request
	    CALL    Init		;process the init
	.ELSE
	    mov     ax,STERR+ERROR_I24_BAD_COMMAND ;Preset error
	    .IF     <dh eq CMDDeInstall> ;if a deinstall request
		mov	ax,LID
		mov	dl,DevHlp_FreeLIDEntry
		Call	DevHelp 	;Free the LID Entry
		sti
		sub	ax,ax		;NOERROR
	    .ELSE
		.IF	<dh eq CMDGenIOCtl> ;if a generic IOCtl request
		    .if     <es:[bx].GIOCategory eq IOC_SC>
			CALL	IOCtl	;process the IOCtl
		    .else			;           start
		      .if     <es:[bx].GIOCategory eq SVGA_CATEGORY> 
			CALL	SVGA_IOCtl      ;process the IOCtl
                      .endif                    ;           end
		    .endif
		.else
		    .IF     <dh eq CMDINPUT> OR
		    .IF     <dh eq CMDOUTPUT> OR
		    .IF     <dh eq CMDOUTPUTV>
			sub	ax,ax	;NOERROR
			mov	es:[bx].IOcount,ax ;Byte Count
		    .ENDIF
		.ENDIF
	    .ENDIF
	.ENDIF
	pop	bp
	pop	bx
	pop	es
	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

IOCtl	PROC	NEAR
	public	IOCtl

	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
	    mov     ax,word ptr es:[bx].GIOParaPack+2 ;Parm ptr
	    mov     cx,2		;2-byte buffer
	    mov     dh,0		;Read Access
	    Call    Verify		;Verify access
	    .if     nc
		mov	es,word ptr es:[bx].GIOParaPack+2 ;Parm ptr
		mov	ax,es:[di]	; selector to free
		mov	dh,2		; UnMap      BUGBUG
		mov	dl,DevHlp_PhysToUVirt
		call	DevHelp
		xor	ax,ax
	    .endif
	.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
		mov	ax,word ptr es:[bx].GIOParaPack+2 ;Parm ptr
		mov	cx,6		;6-byte buffer
		push	dx						;@B01
		mov	dh,0		;Read Access
		Call	Verify
		pop	dx						;@B01
		.if	nc near 					;@B01

		    mov     es,word ptr es:[bx].GIOParaPack+2 ;Parm ptr
		    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
		    .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
		    sub     dx,dx
		    add     cx,bx
		    adc     dx,ax	;DX:CX = Addr32 of final byte
		    mov     bx,si	;Access bits			;@B01

		    .if     <ax a 000Fh> or ;Above FFFFFh (Prot Mode) or
		    .if     <dx a 000Fh>    ;Above FFFFFh (Prot Mode)
			mov	ax,STERR+ERROR_I24_INVALID_PARAMETER
		    .else
			mov	cx,es:[di].pvb_len ;Length of PVB
			mov	dh,bl	    ;Access bits		;@B01
			.if	<al ae 000Ah> and
			.if	<dl b 000Ch>
			    .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
			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
			push	bx	;Save it again

			mov	ax,STERR+ERROR_I24_BAD_COMMAND ; Set error
			.if	nc
			    mov     di,word ptr es:[bx].GIODataPack
			    mov     ax,word ptr es:[bx].GIODataPack+2 ;Data ptr
			    mov     cx,DataSize ;2 or 4-byte buffer ;@@2;@T30
			    push    dx					;@T30
			    mov     dh,1 ;Read/Write Access
			    Call    Verify
			    pop     dx					;@T30
			    .if     nc
				mov	ds,word ptr es:[bx].GIODataPack+2 ;Data ptr t
				.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
			.endif
		    .endif
		.endif
bad_bits:	pop	bx						;@B01
		pop	es		;Restore Request Block Addr

	    .else
		.if	<dh eq 74H>	;Passthru to ABIOS ;DCR0226
		    mov     DataSize,2		;Return selector only	;@B02	;@T30
		    mov     di,word ptr es:[bx].GIOParaPack
		    mov     ax,word ptr es:[bx].GIOParaPack+2 ;Parm ptr
		    mov     cx,2	;2-byte buffer
		    mov     dh,0	;Read Access
		    Call    Verify	;Verify access
		    .if     nc
			push	ds
			mov	ax,word ptr es:[bx].GIOParaPack+2 ;Parm ptr
			mov	ds,ax
			mov	cx,[di].ABIOS_RB_Len
			pop	ds

			mov	di,word ptr es:[bx].GIOParaPack
			mov	ax,word ptr es:[bx].GIOParaPack+2 ;Data ptr
			mov	dh,1	;Read/Write Access
			Call	Verify
			.if	nc and
			mov	ax,STERR+ERROR_I24_INVALID_PARAMETER
			.if	<cx be <size ABIOS_Request_Block>> and
			.if	<ncxz>	;Valid length
			    push    ds
			    push    es

			    push    ds
			    lds     si,es:[bx].GIOParaPack ;ABIOS request block
			    pop     es
			    mov     di,offset ABIOS_RB
			    push    di
			    push    cx
			    rep     movsb ;Copy user's RB to local RB
			    pop     cx
			    pop     si	;Offset of ABIOS Request Block

			    pop     es
			    pop     ds

			    mov     ax,LID ;Get Video device id for DevHelp
			    mov     [si].ABIOS_DevId,ax ;Set Video device id
			    mov     [si].ABIOS_Unit,0 ;Set Video unit number
			    mov     dx,DevHlp_ABIOSCall+256*0 ;Start command
			    Call    DevHelp ;Invoke ABIOS

			    mov     ax,STERR+ERROR_I24_BAD_COMMAND ;Preset error
			    .if     nc
				les	di,es:[bx].GIOParaPack ;ABIOS Req Blk
				mov	si,offset ABIOS_RB
				rep	movsb ;Copy local RB to user's RB
				sub	ax,ax ;Good return code
			    .endif
			    sti 	;Guarantee interrupts enabled
			.endif
		    .endif
;@T51		.else							;@C13
;@T51		    .if     <dh eq 65H> 	;Get 3xBox CodePage	 @C13
;@T51			Call	Get3xBoxCP				;@C13
;@T51		    .endif						;@C13
		.endif
	    .endif
	.endif
	leave								;@T30
	ret
IOCtl	ENDP

Verify	PROC	NEAR
	public	Verify

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

;@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

; The following label defines the end of the Screen resident code.

;DEVICE_END LABEL BYTE


;**	INIT - Device Driver Initialization routine
;
;	ENTRY
;		ES:BX = Request Packet
;		DS    = ?
;	EXIT
;		Terminating Code Address Set
;		Terminating Data Address Set
;		Status = OK
;		DevHelp Address Saved
;

;Init	PROC	NEAR
;
;; Save DevHelp Function Router Address
;
;	mov	ax,word ptr ES:[bx.InitpEnd]
;	mov	word ptr DevHelp,ax
;	mov	ax,word ptr ES:[bx.InitpEnd+2]
;	mov	word ptr DevHelp+2,ax
;
;	mov	word ptr es:[bx.InitpEnd],offset DEVICE_END-1
;	mov	word ptr es:[bx.InitpEnd+2],offset DATA_END-1
;
;	mov	al,3			;Video Device Id ???
;	mov	bl,0			;First available LID
;	mov	dh,0			;Device State = 0 (Reserved)
;	mov	dl,DevHlp_GetLIDEntry
;	Call	DevHelp
;	sti
;	.if	nc
;	    mov     LID,ax		;Save the LID number
;	.endif
;	sub	ax,ax			;DCR0226
;	ret
;Init	ENDP

BiosSeg ends
	end

;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.
