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

        extrn   MemoryIoctl : near                                      ;J-TS920924

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 ;@@
                    call    MemoryIoctl                                 ;J-TS920924
                    .if     <ax ne 0>                                   ;J-TS920924
                        .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
                    .endif                                              ;J-TS920924
                .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.
