;*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    SSPCICIN
                page    60, 132
                title   'SSPCICIN'
;******************************************************************************
;*
;*                            File SSPCICIN.ASM
;*
;*                        Socket Services PCIC File
;*
;*                              Initialisation
;*
;*
;*
;******************************************************************************

                include ssmac.inc           ; Macros
                include ssdefs.inc          ; Sockets Services definitions
                include ss_segm.inc         ; Segment definitions
                include ssPCIC.inc          ; PCIC module defs
                include ssmsg.inc           ; Messages


;*****************************************************************************
;*                         --- Segment InitData ---
;*****************************************************************************
sBegin          InitData

;-------------------------------- Adapter Info --------------------------------

PCIC_Bases      dw      3E0h, 3E2h, 0
sEnd            InitData

;*****************************************************************************
;*                  --- Segment InitCode ---
;*****************************************************************************
sBegin          InitCode
                nop                         ; Just for avoid warning info

COMMENT ~*********************************************************************
        Procedure:      coiInitAdapter
        Revision:       1
        Date:           05/25/1993
        Purpose:        Initialize Adapter Hardware
        Entry:          [AL] = Adapter Number (Absolute)
        Exit:           none
        Side Effects:   All Registers Preserved
*****************************************************************************~
coiInitAdapter  PROC    NEAR
                assumes ds, Nothing
                assumes es, Nothing
                assumes ss, Nothing

                pushx   <ax, bx, dx, di>

                mov     ah, SET_ADAPTER
                mov     dh, 0               ; Nothing special
                mov     di, PCIC_DEF_SCIRQ
                call    codCommon16

                popx    <di, dx, bx, ax>
                ret
coiInitAdapter  ENDP

COMMENT ~*********************************************************************
        Procedure:      coiInitSocket
        Revision:       1
        Date:           05/25/1993
        Purpose:        Initialize Socket Hardware and Data Structures
        Entry:          [AL] = Adapter
                        [BL] = Socket Number (0 based)
        Exit:           none
        Side Effects:   All Registers Preserved
*****************************************************************************~
coiInitSocket   PROC    NEAR
                assumes ds, Nothing
                assumes es, Nothing
                assumes ss, Nothing

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

                mov     ch, IF_MEMORY
                mov     cl, PCIC_DEF_IRQ    ; Note, this value will be ignored.
                mov     di, cx
                mov     ah, SET_SOCKET
                mov     bh, 0               ; Disable all SC reports

                xor     cx, cx              ; Vcc = Vpp1 = Vpp2 = 0V

                mov     dh, 0FFh            ; Clear all saved states
                mov     dl, PCIC_DEF_CTLIND
                call    codCommon16
                popx    <di, dx, cx, bx, ax>
                ret
coiInitSocket   ENDP

COMMENT ~*********************************************************************
        Procedure:      coiInitWindow
        Revision:       2
        Date:           09/21/1993
        Purpose:        Initialize Window Hardware and Data Structures
        Entry:          [AL] = Adapter Number (Absolute)
                        [BH] = Window Number  (0 based)
        Exit:           All Registers Preserved
*****************************************************************************~
coiInitWindow   PROC    NEAR
                assumes ds, Nothing
                assumes es, Nothing
                assumes ss, Nothing

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

;----------------------------- Get type of window -----------------------------

                MOV     ah, GET_WINDOW
                call    codCommon16

                test    dh, WS_IO           ; Memory Window?
                jnz     iwIOWnd             ; No, do I/O setup

;------------------------ Set memory window parameters ------------------------

                mov     cx, 1               ; Default size:  4KB
                mov     di, 10H             ; Default Base:  10000h = 64K
                mov     dl, DSPEED_250NS    ; Default Speed: 250 ns
                jmp     short iwSet

;-------------------------- Set I/O window parameters -------------------------

iwIOWnd:        mov     cx, 1               ; Default Size: 1
                mov     di, 100H            ; Default Base: 100h

;-------------------------------- Set-up window -------------------------------

iwSet:          and     dh, NOT WS_ENABLED  ; Common Default State
                mov     ah, SET_WINDOW
                call    codCommon16

                test    dh, WS_IO           ; if MemWindow Set Page Too.
                jnz     iwExit

;------------------------ For memory window set-up page -----------------------

                mov     bl, 0               ; Default Page: 0
                mov     dx, 0               ; Default State (common memory,
                                            ; disabled, not write-protected)
                mov     di, 0               ; Default Card Offset: 0
                mov     ah, SET_PAGE        ; Function Code
                call    codCommon16


iwExit:         popx    <di, dx, cx, bx, ax>
                ret

coiInitWindow   ENDP

COMMENT ~*********************************************************************
        Procedure:      coiInitAll
        Revision:       1
        Date:           05/25/1993
        Purpose:        Initialize all Adapters, Sockets, and Windows
        Entry:          none
        Exit:           All Registers Preserved
*****************************************************************************~
coiInitAll      PROC    FAR
                assumes ds, ResData
                assumes es, InitData
                assumes ss, Nothing

                pushx   <ax, bx, cx>

                mov     al, bFirstAdapter
                mov     cl, bNumAdapters
                xor     ch, ch
                mov     bx, offset Adapters

;-------------------------------- Adapter loop --------------------------------

ia_NextAdapter: call    coiInitAdapter
                push    cx                  ; Save adapter count

                ; Initialise all sockets


                mov     cl, (ADP_DATA PTR [bx]).bNumSockets
                xor     ch, ch
                push    bx                  ; Save adapter data pointer
                xor     bl, bl              ; Start from socket 0

@@:             call    coiInitSocket
                inc     bl
                loop    @b

                pop     bx                  ; Restore pointer to adapter data

                ; Window loop

                mov     cl, (ADP_DATA PTR [bx]).bNumWindows
                xor     ch, ch
                push    bx                  ; Save adapter data pointer
                xor     bh, bh              ; Start from window 0

@@:             call    coiInitWindow
                inc     bh
                loop    @b

                pop     bx                  ; Restore pointer to adapter data
                add     bx, SIZEOF ADP_DATA
                pop     cx
                loop    ia_NextAdapter

GIExit:         popx    <cx, bx, ax>
                ret

coiInitAll      ENDP

sEnd            InitCode

;*****************************************************************************
;*                         --- Segment InitCode ---
;*****************************************************************************
sBegin          InitCode

;*****************************************************************************
;*                        --- coiScanCommand ---
;*
;*     Purpose: Scan command line
;*       Input: ES:BX - point the command line string
;*      Output: In case of error: CY and DX - offset of message to print
;*              else NC.
;* Scratch reg: AX
;*     Written: by Alexis A.Piatetsky 23.07.94
;*****************************************************************************
coiScanCommand  PROC    NEAR
                assumes ds, ResData
                assumes es, Nothing
                assumes ss, Nothing
                assume  ds:@data, es:Nothing

                push    dx

;------------------------- Get lenth of command string ------------------------

                push    bx

scan_end:       mov     al, es:[bx]
                cmp     al, ' '
                jb      @f
                cmp     al, ';'
                je      @f
                inc     bx
                jmp     short scan_end

@@:             mov     cx, bx
                pop     bx
                sub     cx, bx

;--------------------- Now cx - length of parameter string --------------------


GetNext:        push    bx
                push    cx
                call    couGetToken
                jc      ScanFail

                cmp     al, 0
                je      ScanDone


; Give the help --------------------------------------

                cmp     al, 'H'
                je      @f
                cmp     al, '?'
                jne     @f

sc_givehelp:    mov     dx, offset HelpMsg
                add     sp, 6               ; Kill everything in stack

                jmp     short sc_error

; Screen Output

@@:             cmp     al, 'E'             ; Enable messages?
                jne     @f

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

                mov     es:osMsgFlag, MSG_ON
                pop     es
                jmp     short ScanNext

@@:             cmp     al, 'A'             ; Adapter address?
                jne     @f

                call    couGetHex           ; Get Adapter address
                jc      ScanFail

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

                mov     PCIC_Bases,   ax
                mov     PCIC_Bases+2, 0
                pop     es

ScanNext:       add     sp, 4               ; Kill bx, cx in the stack
                jmp     short GetNext

ScanDone:       clc
                add     sp, 4               ; Kill bx, cx in the stack
                pop     dx
                ret

;----------------------------- Report Syntax error ----------------------------

ScanFail:       mov     dx, offset SyntaxMsg
@@:             pop     cx                  ; Restore address of Token
                pop     bx                  ; that causes problems

                push    es                  ; Address of Tocken
                mov     ax, InitDataBASE
                mov     es, ax
        assumes es, InitData
                cCall   _osPrintString, <dx>

                jcxz    @f

                mov     dx, 39              ; Quote
                cCall   _osPrintChar, <dx>

                pop     es
        assumes es, Nothing

                push    ds                  ; Print rest of command line
                push    es
                pop     ds
        assumes ds, Nothing
                cCall   _osPrintString, <bx>
                pop     ds
        assumes ds, @data
                push    es
                mov     ax, InitDataBASE
                mov     es, ax
        assumes es, InitData

@@:             mov     dx, offset EndOfMsg
                cCall   _osPrintString, <dx>

                pop     es
        assumes es, Nothing

                mov     dx, offset SyntaxHelpMsg
                add     sp, 2               ; Kill dx in the stack
sc_error:       stc
                ret
coiScanCommand  ENDP

;*****************************************************************************
;*                          --- DetectAdapter ---
;*
;*     Purpose: Perform detection of installed adapters
;*       Input: none
;*      Output: bNumAdapters, ADP_DATA wBasePort, bNumWindows, bNumSockets are set.
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 02.08.94
;*        Note: If base address is specified on command line, use this address
;*              only. Otherwise, start at 3e0 and scan for adapters.
;*              If command line specifies number of sockets less than actual,
;*              use only those sockets.
;*****************************************************************************
asDetectAdapter PROC    NEAR
                assumes ds, ResData
                assumes es, InitData
                assumes ss, Nothing

                pushx   <ax, dx, si>

;----------------- Establish pointer to the adapter structure -----------------

                mov     al, bFirstAdapter   ; previous SS?
                xor     ah, ah
                mov     cl, SIZEOF ADP_DATA ; if so, we adjust pointer
                                            ; to next adapter structure,
                mul     cl                  ; since adapter number indexes
                                            ; into the array
                mov     bx, offset Adapters
                add     bx, ax

                mov     si, offset PCIC_Bases

;----------------------------- Adapter search loop ----------------------------


adCheckAddr:    mov     dx, es:[si]         ; Get next address
                add     si, 2               ; Advance pointer
                or      dx, dx              ; end of list?
                je      adDone              ; Yes, terminate

                xor     al, al              ; Ident register
                out     dx, al
                jmp     $+2

                inc     dx
                in      al, dx
                jmp     $+2
                dec     dx

                cmp     al, 83h             ; Intel PCIC step B?
                jne     adCheckAddr

; Load Adapter parameters to the data structure

                mov     (ADP_DATA PTR [bx]).wBasePort, dx ; Save adapter
                                                          ; address
                mov     (ADP_DATA PTR [bx]).bNumSockets, 1

                inc     bNumAdapters        ; number of adapters on this SS

; Get number of sockets

                mov     ah, PCIC_SOCKET1

gns_getsock:    mov     al, ah
                out     dx, al
                jmp     $+2

                inc     dx
                in      al, dx
                jmp     $+2
                dec     dx

                cmp     al, 83h             ; Socket present?
                jne     gns_done

; On some adapters sockets 0, 1 are mirrored to 2 and 3

                cmp     ah, PCIC_SOCKET2
                jne     gns_con

                ; Set power register of socket 0 to 0

                mov     al, PCIC_SOCKET0 + PCIC_POWER
                out     dx, al                  ; Output to index register
                jmp     $+2

                inc     dx                      ; Point to data register

                xor     al, al
                out     dx, al
                jmp     $+2

                dec     dx

                ; Check power register of socket 2

                mov     al, PCIC_SOCKET2 + PCIC_POWER

                out     dx, al                  ; Output to index register
                jmp     $+2

                inc     dx                      ; Point to data register

                ; If we have mirror, this register contains 0, because we
                ; init this value for socket 0

                in      al, dx
                jmp     $+2
                dec     dx                      ; Back to Index register
                or      al, al
                jnz     gns_con

                ; Try to increase power register value for socket 2

                inc     dx                      ; Point to data register
                inc     al                      ; Vpp(1)=5V, but Card Power
                                                ; Disabled
                out     dx, al                  ; Output to data register
                jmp     $+2

                dec     dx                      ; Back to Index register

                ; Check, if value changed also for socket 0

                mov     al, PCIC_SOCKET0 + PCIC_POWER
                out     dx, al                  ; Output to index register
                jmp     $+2

                inc     dx                      ; Point to data register
                in      al, dx
                dec     dx                      ; Back to Index register
                or      al, al
                jnz     gns_done

gns_con:        inc     (ADP_DATA PTR [bx]).bNumSockets
                add     ah, PCIC_SKTINC
                jnz     gns_getsock

gns_done:       mov     al, (ADP_DATA PTR [bx]).bNumSockets
                mov     cl, PCIC_WIN_PER_SKT
                mul     cl
                mov     (ADP_DATA PTR [bx]).bNumWindows, al

                add     bx, SIZEOF ADP_DATA ; Point the next entry
                jmp     adCheckAddr

adDone:
                popx    <si, dx, ax>
                ret
asDetectAdapter ENDP

;*****************************************************************************
;*                             --- ResetHardware ---
;*
;*     Purpose: Initialize all sockets (registers zeroed)
;*       Input: none (uses ADP_DATA data)
;*      Output: none
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 29.07.94
;*       Notes: any device-specific init should go here
;*****************************************************************************
asResetHardware PROC    NEAR
                assumes ds, ResData
                assumes es, Nothing
                assumes ss, Nothing

; ----- Insure socket is initialized to zero

                pushx   <ax, bx, cx, dx>

;----------------- Establish pointer to the adapter structure ----------------


                mov     bx, offset Adapters
                mov     cl, bNumAdapters
                xor     ch, ch

rh_NextAdp:     push    cx
                mov     ah, PCIC_SOCKET0    ; start at 0
                mov     dx, (ADP_DATA PTR [bx]).wBasePort
                xor     ch, ch
                mov     cl, (ADP_DATA PTR [bx]).bNumSockets

rh_NextSock:    push    cx                  ; Save socket counter
                mov     cl, PCIC_POWER      ; Set starting register to zero

rh_NextReg:     mov     al, ah              ; Create proper index for register
                add     al, cl              ; by adding socket offset

                out     dx, al              ; Output to index register
                jmp     $+2
                inc     dx                  ; Point to data register

                xor     al, al              ; Output zero to data register
                cmp     cl, PCIC_WINDOW     ; Window enable is a special case
                jne     @f

                mov     al, PCIC_WINDOW_A23A12  ; enable full addr decode
@@:             out     dx, al              ; of MEMCS16

                dec     dx                  ; Point back to index register

                inc     cl                  ; Point to next PCIC register
                cmp     cl, PCIC_IOWIN_CTRL ; Have we done last one ?
                jbe     short rh_NextReg    ; No, go do another

                mov     al, PCIC_CDGCR
                out     dx, al
                jmp     $+2
                inc     dx

                mov     al, PCIC_CDGCR_16BITMDI

                out     dx, al
                jmp     $+2
                dec     dx

                mov     al, PCIC_GLOBL
                out     dx, al
                jmp     $+2
                inc     dx

                mov     al, 0

                out     dx, al
                jmp     $+2
                dec     dx

                add     ah, PCIC_SKTINC     ; Point to next socket
                pop     cx
                loop    rh_NextSock

                pop     cx
                add     bx, sizeof ADP_DATA
                loop    rh_NextAdp

                popx    <dx, cx, bx, ax>
                ret
asResetHardware ENDP

;*****************************************************************************
;*                            --- coiInitSS ---
;*
;*     Purpose: Initialise Socket Services
;*       Input: ES:BX - Pointer to the command line string
;*      Output: NC, if successful, CY otherwise
;* Scratch reg: all
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
coiInitSS       PROC    FAR
                assumes ds, ResData
                assumes es, Nothing
                assumes ss, Nothing

; ----- Display signon message

                push    es                  ; es:bx Pointer to command line
                mov     ax, InitDataBASE
                mov     es, ax
        assumes es, InitData

                lea     dx, SignonMsg
                cCall   _osPrintString, <dx>

                pop     es
        assumes es, Nothing

; ----- Check command line for arguments

                call    coiScanCommand
                mov     ax, InitDataBASE
                mov     es, ax
        assumes es, InitData
                jnc     @f
                jmp     initSSExit          ; Exit with error message

@@:             push    ds                  ; Establish [ES] register
                pop     es
        assume  es:@data

; ----- Initialize adapter structures

                mov     ax, SIZEOF ADP_DATA
                mov     cx, MAX_ADAPTERS
                mul     cl
                mov     cx, ax
                xor     ax, ax
                cld

                mov     di, OFFSET Adapters
        rep     stosb

                mov     ax, InitDataBASE
                mov     es, ax
        assumes es, InitData

                call    osOKtoLoad
                jc      initSSExit

; ----- Detect Adapter(s)

ISSInstall:     mov     al, bFirstAdapter
                push    ax                  ; bFirstAdapter in al
                mov     bFirstAdapter, 0

                call    asDetectAdapter

                pop     ax                  ; Restore bFirstAdapter in al

                cmp     bNumAdapters, 0     ; Any adapters found ?
                jne     short @f            ; Yes, continue

                mov     dx, offset NoAdapterMsg ; No, indicate error
                jmp     short initSSExit        ;  and exit

; ----- Adjust adapter values for adapter(s) located

@@:             mov     bFirstAdapter, al   ; Restore bFirstAdapter
                add     al, bNumAdapters
                mov     bTotAdapters, AL
                dec     al
                mov     bLastAdapter, AL

; ----- Perform hardware initialization

                call    asResetHardware
                call    coiInitAll

; ----- Create and display completion message

                mov     AL, bNumAdapters
                add     AL, '0'
                mov     es:chAdapters, AL

                mov     dx, offset SuccessMsg

initSSExit:     cCall   _osPrintString, <dx>

                cmp     bNumAdapters, 1         ; Set [CF] if bNumAdapters EQ zero (0)
                ret

coiInitSS       ENDP

sEnd            InitCode
                end
