;*DDK*************************************************************************/
;
; 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.;
;*****************************************************************************/
PAGE    ,132
NAME    ASPISTUB
TITLE   ASPI stub device driver
;
;***    ASPISTUB
;
;       Title:  ASPI VDD V86 box stub driver
;
;       Description: small V86 ASPI stub device driver
;
;       Design/Implementation Notes:
;
;       The ASPI stub driver serves two purposes.
;
;       (1) To supply a device driver header which a DOS application
;           can find to determine whether ASPI is installed.
;
;
;       (2) To act as the intermediary between real mode and protected
;           mode.  The ASPI interface involves making a far call to
;           a location in conventional memory.  Hence, we need a way
;           to get from there to protected mode, where our VDD lives.
;
;       The driver itself responds to all requests by signalling done.
;
;       This stub code will be copied to the VDM address space and
;       installed by the VDD, not the loader.  It will be installed on
;       a paragraph boundary.
;
;       DOS Boot support was added summer of 1991 to provide ASPI
;       to Native DOS under OS/2 2.0.  It is much like the normal
;       stub, but does more checking and uses the private interface
;       to the VASPI VDD.  The special code is IFDEF STUBDD for building
;       the OS/2 version of a dos device driver, ASPI.SYS.  The reason
;       it is so small is that all of the code is in the 32-bit VDD.
;


        .xlist
        include devhdr.inc
        .list

;   MRI messages included by telling which messages in comments
;   MSGPROF is what scans for it.
;
; /* MSG_VMBOOT_ASPI_BANNER */
; /* MSG_STUBDD_NEEDS_VASPI */
; /* MSG_STUBDD_NEEDS_OS2 */


        .8086           ; This is run in real mode

;***LD+ ASPI DOS STUB DD data structures
;
;         DD header indicates character device, open allowed,
;         and IOCTL supported.  pNext stores the address to
;         chain to at interrupt time.  NOTE: The header must
;         be at the start of the segment.
;

DONE            equ     0100h   ; How a DD says "Okay"
ASPI_FUNCTION   equ     043h    ; the ASPI function code
VDDINTERFACE    equ     02Fh    ; Int vector for VDD interface

;STUBDD          equ     01

req_hdr   struc
    rq_reglen      db      ?                 ; offset 0
    rq_unit        db      ?                 ;        1
    rq_command     db      ?                 ;        2
    rq_status      dw      ?                 ;        3
    rq_rs2         db      8 dup (?)         ;        5
req_hdr  ends


req_init   struc
    rqi_rs3         db      13 dup (?)        ;        0
    rqi_units       db      ?                 ;       13
    rqi_addr        dd      ?                 ;       14
    rqi_count       dw      ?                 ;       18
    rqi_rs4         dw      ?                 ;       20
req_init ends

req_read   struc
    rqr_rs5         db      13 dup (?)        ;        0
    rqr_media       db      ?                 ;       13
    rqr_trans_addr  dd      ?                 ;       14
    rqr_count       dw      ?                 ;       18
    rqr_rs6         dw      10 dup (?)        ;       20
req_read ends



CODE    SEGMENT BYTE PUBLIC 'CODE'

        assume cs:CODE,ds:CODE,es:CODE

        org 0

;
; CAREFUL!  The positions of all the goodies in this file is crucial.
;  (or is it?)
;
; When this is run through the makefile, ASPIStubStart will be the
; start of the data block, and ASPIStubLength its length.
;
; The next few lines are used by an awk script.
;
; #### HEADERFILE=vastub.h
; #### ENTRYPOINT=ASPIStubStart
; #### LENGTH=ASPIStubLength
;
; #### BEGIN EXTRACTION
;  It is used by n awk script to convert the listing file into an .ASM file.

; Standard Device Driver Header follows

Header      dd  -1              ; link to nxet driver; -1 = end of list
Attrib      dw  DEV_CHAR_DEV OR DEV_IOCTL ; device attributes
            dw  Strategy        ; "Strategy" entry point
            dw  ASPIIntr         ; "Interrupt" entry point
            db  'SCSIMGR$'      ; Device name

; Global variables go here
pReqHdr     dd  ?               ; address of Request Header
VDDEntry    dw  ?,?             ; VASPI service EP



;***LP  Strategy - ASPI DOS STUB DD strategy handler
;
;       This function is called by DOS whenever the driver is
;       accessed.
;
;       ENTRY   ES:BX = Address of Request Header
;
;       EXIT    None
;
;       GLOBAL EFFECTS
;
;       pReqHdr points to the request header
;
;       METHOD
;
;       Squirrel away the address into pReqHdr.
;
        Public Strategy
Strategy    proc far
        mov word ptr cs:[pReqHdr],bx
        mov word ptr cs:[pReqHdr+2],es
        ret

Strategy    endp

;
;***LP  ASPIIntr - ASPI DOS DD Stub interrupt routine
;
;
;
ASPIIntr proc far
        push    ax              ; Standard operating procedure
        push    bx
        push    si
        push    di
        push    ds
        push    es

        les     si,cs:[pReqHdr] ; look at our request header
        mov     word ptr es:[si.rq_status], DONE
                                ; we always say "okay, sure, no problem"

        mov     al, es:[si.rq_command]  ; What are we being asked to do?
        cmp     al, 0           ; "Init" command?
        je      IInit           ; Yes, go do initialization
        cmp     al, 3
        jne     IExit
;
;       Call the ASPI VDD to get the appropriate BP address
;       for the ASPI request. An appropriate BP address will be
;       returned if the user program has entered DPMI mode.
;

IRead:
;
;
;       VDD service returns ax:di for breakpoint
;                           cx = 0 - V86 BP, cx = 1 - DPMI BP
;
        mov     ax, 0
        call    dword ptr [VDDEntry]


        les     si,es:[si.rqr_trans_addr]
;
        mov     word ptr es:[si],   di   ; 
        mov     word ptr es:[si+2], ax

IExit:  pop     es              ; Clean up behind you
        pop     ds
        pop     di
        pop     si
        pop     bx
        pop     ax
        ret



IInit:
;
;       Set post-init code end
;
        mov     word ptr es:[si.rqi_addr],   offset IInit
        mov     word ptr es:[si.rqi_addr+2], cs


ifdef STUBDD
;
;
;       For VASPI Stub make sure we're running under a booted
;       VDM. Could be running under real DOS!
;

        mov     ax,4010h
        int     VDDINTERFACE         ; verify interface is present

        cmp     ax,4010h
        jne     OS2Present

NoOS2:
        push    si
        mov     si,offset TXT_MSG_STUBDD_NEEDS_OS2
        call    msgprint
        pop     si
        jmp     die

endif

;
;
;       Get initial ASPI VDM Service Entry Point.
;
;       This EP will be called when the client tries to read the
;       when the user program attempts to read the ASPI entry
;       point from the character device (SCSIMGR$). The VASPI
;       VDD will supply an appropriate BreakPoint Address to
;       be returned to the user program.
;


OS2Present:
        mov     si,offset ASPINAME
        xor     di,di
        push    es
        mov     es,di
        mov     ax,04011h
        int     VDDINTERFACE
        mov     ax,es
        or      ax,di
        mov     ax,es                ; AX:DI = ASPI VDD Entry Point
        pop     es
        jnz     VDDPresent           ; if no error, continue

ifdef   STUBDD

NoVDD:
        push    si
        mov     si,offset TXT_MSG_STUBDD_NEEDS_VASPI
        call    msgprint
        pop     si
        jmp     die

endif

VDDPresent:
       mov      VDDEntry[0],di
       mov      VDDEntry[2],ax
       jmp      IInitExit


die:
        xor     ax, ax
        mov     es:[si.rqi_units], al
        mov     word ptr es:[si.rqi_addr][0], ax

IInitExit:
        jmp     IExit

ASPIIntr endp

ifdef STUBDD

;
; msgprint - small msgretriever print routine
;
;   INPUT - (DS:SI) message (length message)
;
msgprint   proc   near
        mov     ax,word ptr ds:[si]                 ; get the length
        inc     si                                  ; move DX to text area
        inc     si                                  ; 
        mov     dx,si
        add     si,ax                               ; point SI to end of text
        mov     byte ptr ds:[si],'$'                ; add string terminate
        mov     ah,09h
        int     21h
        ret
msgprint   endp



; messages unique to STUBDD.SYS for Booted DOS

; include file generated on the fly by MSGPROF, MKMSGF
;
include STUBDD.inc

endif

;define the Virtual Device driver name for VDD-VDM communication
ASPINAME db      'VASPI',0

ASPIEnd  label    byte              ; This line is a dummy to keep
                                    ; the AWK happy with the byte length count
                                    ; PUT ALL DATA/CODE ABOVE THIS LABEL
;
; #### END EXTRACTION
;

CODE    ends

        end
