;*DDK*************************************************************************/
;
; COPYRIGHT (C) Award Software International Inc., 1994
; 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.;
;*****************************************************************************/
                name    SSOS2DRV
                page    60, 132
                title   'SSOS2DRV'
;******************************************************************************
;*
;*                            File SSOS2DRV.ASM
;*
;*                            OS2 Device Driver
;*
;*    The code in this file is relative to the OS2 Device Driver conception
;*    and OS2 memory structure. The file contains OS2 Device Driver header,
;*    strategy and interrupt routine, command line processing helpers and
;*    interrupt handlers for SS interrupt and keyboard interrupt.
;*
;*
;*
;******************************************************************************

                .xlist
                include ssmac.inc           ; Macros
                include ssdefs.inc          ; Sockets Services definitions
                include ss_segm.inc         ; Segments definitions
                include ssos2.inc           ; OS2 specific definitions
                include ssPCIC.inc          ; PCIC datatypes and prototypes
                include ssmsg.inc           ; Message defs
                .list


;*****************************************************************************
;*                         --- Segment ResData ---
;*****************************************************************************
sBegin          ResData

                org     0
DevHdr__       SysDev  {-1, DATTR_SS, offset Strategy, codRM_Entry, OS2DRVNAME, 0, 0, 0, 0}
sDevCaps        dd      0                   ; Device capabilities
staticFP        Request                     ; Device driver request header
staticFP        DevHelp                     ; DevHelp Entry point
staticFP        PriorHandler                ; Prior handler

pCardServices   dd      ?                   ; Card Services entry point
wCS_DS          dw      ?                   ; Card Services data segment

sEnd            ResData

;*****************************************************************************
;*                         --- Segment InitData ---
;*****************************************************************************
sBegin          InitData

;-------------------------------- Screen Output -------------------------------

osMsgFlag       db      MSG_OFF             ; Default: No messages

PrintCharBuff   db      0, 0                ; Print character buffer
MessageTable    label   byte                ; Save_Message structure
Msg_ID          dw      MSG_REPLACEMENT_STRING
Msg_nMsgs       dw      1                   ; Only one message supported
Msg_BufferOff   dw      InitDataOFFSET MsgBuffer
Msg_BufferSeg   dw      InitDataBASE

MsgBuffer       db      MAX_MSG dup (0)     ; Message Buffer

;-------------------------------- CS Interface --------------------------------

PCMCIA_Dev_Name db      "PCMCIA$  ", 00h    ; OS/2 CS Device
PCMCIA_Data     AttachDD_Data {0, 0, 0, 0, 0, 0}

AddSSData       AddSS_Data {RSSE_PROT_1616, ResDataBASE}
                                            ; Attribute One indicates, the
                                            ; SSEntry and DataPointer arguments
                                            ; are far 16-bit selector:offset
                                            ; pointers
sEnd            InitData

;*****************************************************************************
;*                         --- Segment ResCode ---
;*****************************************************************************
sBegin          ResCode

;*****************************************************************************
;*                             --- Strategy ---
;*
;*     Purpose: Strategy procedure
;*       Input: es:bx - Request header
;*      Output: none
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 22.07.94
;*****************************************************************************
cProc           Strategy, <FAR>, <ax, bx, cx, dx, si, di, ds, es>
cBegin          Strategy
                assumes ds, Nothing
                assumes es, Nothing
                assumes ss, Nothing

                pushf                       ; Preserve All Regiseters

                mov     ax, ResDataBASE     ; Use our data segment
                mov     ds, ax
        assumes ds, ResData

                mov     Off_Request, bx
                mov     Seg_Request, es

                mov     Off_PriorHandler, 0 ; Initialise
                mov     Seg_PriorHandler, 0

;---------------------- Device Driver supports ONLY Init ----------------------

                mov     ax, STERR OR UNKNOWN_CMD    ; Default Error Code
                cmp     (InitPacket PTR es:[bx]).Pkt_Cmd, CMDInitBase
                jne     short opdone

                mov     eax, (InitPacket PTR es:[bx]).PktInitpEnd
                mov     DevHelp, eax

;----------- ## AAP ## 19.04.94 16:56 Scan command line. Skip filename --------

                les     bx, (InitPacket PTR es:[bx]).PktInitParms
                                                ; ASCII string from CONFIG.SYS
@@:             mov     al, es:[bx]
                or      al, al
                jz      @f
                cmp     al, ' '
                jbe     @f
                inc     bx
                jmp     short @b
@@:
;----------------------------------- ## AAP End -------------------------------

                call    coiInitSS
        assume  es:Nothing
                jc      @f                  ; Initialisation failed

                mov     ax, InitDataBASE
                mov     es, ax
        assumes es, InitData
                call    osAddSS

@@:             les     bx, Request         ; Restore Request Header Ptr
        assume  es:Nothing
                jc      @f

                mov     ax, cs              ; Get Size of code
                call    GetSegmPars
                jc      @f
                mov     word ptr (InitPacket PTR es:[bx]).PktInitpEnd, dx

                mov     ax, ds              ; Get size of data
                call    GetSegmPars
                jc      @f
                mov     word ptr (InitPacket PTR es:[bx+2]).PktInitpEnd, dx

                mov     ax, 0               ; Init successful
                jmp     short opdone

@@:             mov     (InitPacket PTR es:[bx]).PktInitpEnd, 0
                mov     ax, STERR OR osGENERAL_FAILURE

opdone:         or      ax, STDON
                mov     (InitPacket PTR es:[bx]).Pkt_Status, ax     ; Set return status
                mov     (InitPacket PTR es:[bx]).PktInitcUnit, 0

;----------------------------- Print all messages -----------------------------

                push    ds
                pop     es
        assumes es, ResData
                mov     ax, InitDataBASE
                mov     ds, ax
        assumes ds, InitData

                cmp     osMsgFlag, MSG_ON
                jne     @f

                mov     si, InitDataOFFSET MessageTable
                xor     bx, bx
                mov     dl, DevHlp_Save_Message
                call    es:[DevHelp]
@@:
                popf

cEnd            Strategy

;*****************************************************************************
;*                            --- GetSegmPars ---
;*
;*     Purpose: Return Segment base address and size
;*       Input: ax - Selector of segment of interest
;*      Output: CY, if failed, else NC and
;*              dx - Segment size (Not LIMIT!!!)
;*              cx - Segment linear base address
;* Scratch reg: cx, dx
;*     Written: by Alexis A.Piatetsky 09.08.94
;*        Note: This routine works for both LDT and GDT, even if comment was
;*              initially writen for GDT only
;*****************************************************************************
GetSegmPars     PROC    NEAR
        assumes ds, ResData
        assumes es, Nothing
        assumes ss, Nothing
                push    ax
                mov     dl, DevHlp_GetDescInfo
                call    [DevHelp]
gsm_Done:       pop     ax
                ret
GetSegmPars     ENDP

COMMENT ~*********************************************************************

        Procedure:      GetSetSSAddr

        Purpose:        Get or Set SS addresses for call interface

        Entry:          [BP] = Pointer to entry args on stack
                        [BX] = Pointer to adapter entry in Adapters array
                        Args.BHReg = Desired processor mode
                           00 = Real mode       02 = 16:32 Protect
                           01 = 16:16 Protect   03 = 00:32 Protect
                        Args.BLReg = Subfunction
                           00 = Get Cod and Main Data segment descriptions
                           01 = Get descriptions of additional data segments
                           02 = Set mode-specific pointers for additional data segments
                        If Args.BLReg = 0
                           [ES]:[(E)DI] = Pointer to buffer for segment descriptions
                        If Args.BLReg = 1
                           Args.CXReg = Number of additional data segments
                           [ES]:[(E)DI] = Pointer to buffer for add data seg descrips
                        If Args.BLReg = 2
                           Args.CXReg = Number of additional data segments
                           [ES]:[(E)DI] = Pointer to buffer of mode-specific pointers

        Exit:           Args.AHReg = Return code
                        If Args.AHReg = SUCCESS and Args.BLReg = 0
                           Args.CXReg = Number of additional data segments
                           Client-supplied buffer filled with main seg descriptions
                        If Args.AHReg = SUCCESS and Args.BLReg = 1
                           Client-supplied buffer with add data seg descrips

        WARNING:        This procedure assumes the code and data segments are
                        the same during execution and uses just the code segment
                        to compute return values.  If the code and data segments
                        are not the same, this procedure MUST be modified.

*****************************************************************************~

GetSetSSAddr    PROC    NEAR
                assume  ds:@data, es:Nothing

                cmp     (ARGS PTR [BP]).BLReg, 0 ; SubFunc zero (0) ?
                je      short @f                 ; Yes, continue

                mov     AH, BAD_FUNCTION         ; No, indicate error
                jmp     short GSSSAddrExit       ;  and exit
@@:
                cmp     (ARGS PTR [BP]).BHReg, RSSE_PROT_1616 ; 16:16 PM?
                je      short @f                 ; Yes, continue

                mov     ah, BAD_MODE             ; No, indicate error
                jmp     short GSSSAddrExit       ;  and exit
@@:

;---------------------------- Resident code segment ---------------------------

                mov     ax, cs
                call    GetSegmPars
                mov     ah, GENERAL_FAILURE      ; Assume, failure
                jc      GSSSAddrExit

                dec     edx                      ; We must return Limit
                mov     dword ptr es:(SS_ADDR_MAIN PTR [di]).wCodeBaseLo, ecx
                mov     dword ptr es:(SS_ADDR_MAIN PTR [di]).wCodeSizeLo, edx

;---------------------------- Resident data segment ---------------------------

                mov     ax, ds
                call    GetSegmPars
                mov     ah, GENERAL_FAILURE      ; Assume, failure
                jc      GSSSAddrExit

                dec     edx                      ; We must return Limit
                mov     dword ptr es:(SS_ADDR_MAIN PTR [di]).wDataBaseLo, ecx
                mov     dword ptr es:(SS_ADDR_MAIN PTR [di]).wDataSizeLo, edx

;----------------------------- Entry point offset  ----------------------------


                mov     es:(SS_ADDR_MAIN PTR [di]).wCodeEntryLo,  OFFSET codRM_Entry
                mov     es:(SS_ADDR_MAIN PTR [di]).wCodeEntryHi,  0

;-------------------------------- Data offset  --------------------------------


                mov     dword ptr es:(SS_ADDR_MAIN PTR [di]).wDataOffsetLo, 0

                mov     (ARGS PTR [BP]).CXReg, 0 ; No Additional Data Segments

                mov     ah, SUCCESS
GSSSAddrExit:   ret

GetSetSSAddr    ENDP

sEnd            ResCode

;*****************************************************************************
;*                         --- Segment InitCode ---
;*****************************************************************************
sBegin          InitCode

;*****************************************************************************
;*                             --- osAddSS ---
;*
;*     Purpose: Add SS to card services
;*       Input: none
;*      Output: none
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 11.08.94
;*****************************************************************************
osAddSS         PROC    FAR
                assumes ds, ResData
                assumes es, InitData
                assumes ss, Nothing

                pushx   <ax, bx, cx, dx, di, si>

;--------------------- Make call to CS in order to Add SS ---------------------

                pushx   <ds, es>
                push    cs
                push    InitCodeOFFSET csRet ; Return point
                pushd   [pCardServices]      ; Card Services entry point

                mov     bx, InitDataOFFSET AddSSData
                mov     cx, SIZEOF AddSS_Data
                mov     di, ResCodeBASE
                mov     si, ResCodeOFFSET codRM_Entry
                mov     dx, 0

                mov     ax, wCS_DS
                mov     ds, ax
        assumes ds, Nothing
                mov     ah, CARD_SERVICES
                mov     al, AddSS

                retf                        ; call pCardServices

csRet:          popx    <es, ds>
                assumes ds, ResData
                assumes es, InitData

                jnc     @f

                mov     dx, InitDataOFFSET FailAddMsg
                cCall   osPrintString, <dx>
                stc

@@:             popx    <si, di, dx, cx, bx, ax>
                ret
osAddSS         ENDP


;*****************************************************************************
;*                            --- osOKtoLoad ---
;*
;*     Purpose: Check, if SS could be loaded
;*       Input: none
;*      Output: NC, if yes
;*              CY and DX - offset of message, if not
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 09.08.94
;*****************************************************************************
osOKtoLoad      PROC    NEAR
                assumes ds, ResData
                assumes es, InitData
                assumes ss, Nothing

                pushx   <ax, bx, di>

                push    dx

;----------------------- Try to attach to Card Services -----------------------

                pushx   <ds, es>            ; xchg ds, es
                popx    <ds, es>
        assumes es, ResData
        assumes ds, InitData

                mov     bx, InitDataOFFSET PCMCIA_Dev_Name
                mov     di, InitDataOFFSET PCMCIA_Data
                mov     dl,DevHlp_AttachDD
                call    es:[DevHelp]

                pushx   <ds, es>            ; xchg ds, es
                popx    <ds, es>
        assumes ds, ResData
        assumes es, InitData
                jc      @f                  ; Attachement to CS failed


;------------------- Copy returned values to resident data  -------------------

                mov     eax, dword ptr es:PCMCIA_Data.ADDD_IDCOff
                mov     pCardServices, eax
                mov     ax, es:PCMCIA_Data.ADDD_IDCDS
                mov     wCS_DS, ax

                pop     dx
                clc                         ; We can load SS
                jmp     short otl_Done

@@:             mov     dx, offset CSPresentMsg
                add     sp, 2               ; Discard dx in the stack
                stc                         ; Do not load CS

otl_Done:       popx    <di, bx, ax>
                ret
osOKtoLoad      ENDP

;*****************************************************************************
;*                           --- PrintString ---
;*
;*     Purpose: Print NULL terminated string via OS/2 interface
;*   Prototype: void PrintString(PSTR pString);
;*       Input: Offset of string to print. String must be located in InitData
;*              segment
;*      Output: none
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 02.05.94
;*****************************************************************************
cProc           osPrintString, <NEAR, PUBLIC>, <di, cx, ax>
                parmW   pString             ; String Offset
cBegin          PrintString
                assumes ds, ResData
                assumes es, InitData

                pushx   <si, ds>
                mov     di, pString
                mov     si, di
                call    couStrLen           ; String length

                mov     ax, cx

                mov     di, InitDataOFFSET MsgBuffer
                call    couStrLen           ; Buffer length

                push    ax                  ; Message length
                add     ax, cx
                cmp     ax, MAX_MSG         ; Do we have space?
                pop     ax                  ; Message length
                jae     @f                  ; Buffer full, abort print

                xchg    ax, cx              ; ax - Buffer length, cx - Message
                                            ; length
                add     di, ax              ; es:di - Point end of the buffer

                push    es
                pop     ds
        assumes ds, InitData

            rep movsb                       ; Copy message to the buffer

@@:             popx    <ds, si>
        assumes ds, ResData

cEnd            osPrintString

;*****************************************************************************
;*                           --- osPrintChar ---
;*
;*     Purpose: Print character via OS/2 interface
;*   Prototype: void PrintChar(WORD wChar);
;*       Input: Character to print
;*      Output: none
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 02.05.94
;*****************************************************************************
cProc           osPrintChar, <NEAR, PUBLIC>, <ax>
                parmW   wChar
cBegin          PrintChar
                assumes ds, ResData
                assumes es, InitData

                mov     ax, wChar
                mov     es:PrintCharBuff, al
                mov     ax, offset PrintCharBuff
                cCall   osPrintString, <ax>

cEnd            osPrintChar


sEnd            InitCode
                END

