                name    SSPCICUT
                page    60, 132
                title   'SSPCICUT'
;******************************************************************************
;*
;*                            File SSPCICUT.ASM
;*
;*                     Socket Services PCIC Utilities
;*
;*            Copyright (c) Award Software International Inc., 1994
;*
;*
;******************************************************************************

                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 ResData ---
;*****************************************************************************
sBegin          ResData
DevExtSpeed     db      10, 12, 13, 15, 20, 25, 30      ; PCMCIA mantissa
                db      35, 40, 45, 50, 55, 60, 70, 80
DevSpeed        db      25, 20, 15, 10                  ; Divided by 10
sEnd            ResData


;*****************************************************************************
;*                         --- Segment ResCode ---
;*****************************************************************************
sBegin          ResCode


;*****************************************************************************
;*                            --- couDelay ---
;*
;*     Purpose: Delay execution
;*       Input: AX - Milliseconds to delay
;*      Output: none
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
couDelay        PROC    NEAR
                assume  ds:@data, es:Nothing

                pushx   <ax, bx, cx, dx>

                mov     cx, ax                  ; Save Interval (mS) CX

DL1:            xor     al, al                  ; Zero AL
                out     TIM_CTL, al             ; Latch Timer Count
                in      al, TIMER0              ; Read LS Byte
                mov     ah, al
                in      al, TIMER0              ; Read MS Byte
                xchg    ah, al                  ; Put Bytes in order
                mov     dx, ax                  ; Save First Count in DX

@@:             mov     bx, dx                  ; Restore First Count in BX
                xor     al, al                  ; Zero AL
                out     TIM_CTL, al             ; Latch Timer Count
                in      al, TIMER0              ; Read LS Byte
                mov     ah, al
                in      al, TIMER0              ; Read MS Byte
                xchg    ah, al                  ; Put Bytes in Order
                sub     bx, ax                  ; Compute Interval (downcount)
                cmp     bx, 1193                ; > One Ms ?
                jb      @b                      ; No, go again.
                loop    DL1                     ; Yes, next interation

                popx    <dx, cx, bx, ax>
                ret
couDelay        ENDP

;*****************************************************************************
;*                         --- couIsValidSpeed ---
;*
;*     Purpose: Return carry, if speed is invalid
;*       Input: AH - speed
;*      Output: CY, if speed isn't valid
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 06.05.94
;*****************************************************************************
couIsValidSpeed PROC    NEAR
                assume  ds:@data, es:Nothing

                push    ax
                test    ah, EXT_BIT
                jnz     ivs_fail

                test    ah, MANTISSA_BITS   ; Extended speed?
                jnz     @f                  ; Yes, continue

                cmp     ah, DSPEED_100NS
                ja      ivs_fail
                jmp     short ivs_check0

@@:             shr     ah, 1               ; Get rid of exponents
                shr     ah, 1
                shr     ah, 1

ivs_check0:     cmp     ah, 1
                jae     ivs_done            ; Carry is cleared

ivs_fail:       stc
ivs_done:       pop     ax
                ret
couIsValidSpeed ENDP


;*****************************************************************************
;*                        --- couGetSpeedComp ---
;*
;*     Purpose: Convert speed to mantissa and exponenta
;*       Input: AL - Speed
;*      Output: AL - Mantissa
;*              AH - exponenta
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 06.05.94
;*****************************************************************************
couGetSpeedComp PROC    NEAR
                assume  ds:@data, es:Nothing

                push    bx

                mov     ah, 2               ; Assume hundreds of ns
                mov     bx, offset DevSpeed

                test    al, MANTISSA_BITS
                jz      @f

                mov     ah, al
                and     ah, EXPONENT_BITS
                mov     bx, offset DevExtSpeed
                shr     al, 1               ; Get rid of exponent
                shr     al, 1
                shr     al, 1

@@:             dec     al                  ; 0 is reserved value
                push    ax
                xor     ah, ah
                add     bx, ax
                pop     ax
                mov     al, [bx]

                pop     bx

                ret
couGetSpeedComp ENDP

;*****************************************************************************
;*                          --- couCompSpeed ---
;*
;*     Purpose: Compare two speed in device speed form
;*       Input: AH - Speed 1, AL - Speed 2
;*      Output: ZR, if AH = AL
;*              CY, if AH < AL
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 06.05.94
;*        Note: Speed have to be valid and w/o EXT bit
;*****************************************************************************
couCompSpeed    PROC    NEAR
                assume  ds:@data, es:Nothing

                pushx   <ax, bx>

                push    ax
                call    couGetSpeedComp

                mov     bx, ax              ; bx - speed 2

                pop     ax
                mov     al, ah
                call    couGetSpeedComp     ; ax - speed 1

                cmp     ah, bh              ; Compare exponents
                jne     @f

                cmp     al, bl              ; Compare mantissa

@@:             popx    <bx, ax>
                ret
couCompSpeed    ENDP

;*****************************************************************************
;*                           --- couCopyInfo ---
;*
;*     Purpose: Copy info to client buffer
;*       Input: CX    - size of info to copy
;*              DS:SI - source of information
;*              ES:DI - client buffer with lengths
;*      Output: none
;* Scratch reg: none
;*****************************************************************************
couCopyInfo     PROC    NEAR
                assume  ds:@data, es:Nothing

                pushx   <cx, si, di>

                mov     es:[di + 2], cx     ; Save in client's data buffer
                cmp     cx, es:[di]         ; Room in buffer for data
                jbe     @f                  ; Yes, continue
                mov     cx, es:[di]         ; No, use length from buffer

@@:             jcxz    @f                  ; If no room in buffer, skip move
                add     di, 4               ; Point past length information
        rep     movsb                       ; Copy to client's buffer

@@:             popx    <di, si, cx>
                ret
couCopyInfo     ENDP
sEnd            ResCode

;*****************************************************************************
;*                         --- Segment InitCode ---
;*****************************************************************************
sBegin          InitCode

;*****************************************************************************
;*                            --- couGetHex ---
;*
;*     Purpose: Return Hex number from command line parameter to AX
;*       Input: ES:BX - Pointer to the command line string with Hex
;*              CX    - String length
;*      Output: CY, if error occurs (es:bx unchanged in this case)
;*              CX    - modified
;*              AL    - Number
;*        Note: We expect parameter Hex as XXXX
;* Scratch reg: CX, BX
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
couGetHex       PROC    NEAR
                assume  ds:@data, es:Nothing

                push    dx
                push    bx
                push    cx

                jcxz    GetHexFail

;------------------- Parameter should start from '/' or '-' -------------------

                xor     ax, ax
NextDigit:      mov     dl, es:[bx]

                cmp     dl, ' '
                jbe     GetHexSuccess

                cmp     dl, ';'
                je      GetHexSuccess

                sub     dl, '0'
                jc      GetHexFail

                cmp     dl, 9
                jbe     AddDigit

                cmp     dl, 'a' - '0'
                jb      @f
                sub     dl, 'a' - 'A'

@@:             sub     dl, 'A' - '0'
                jc      GetHexFail

                add     dl, 10
                cmp     dl, 15
                ja      GetHexFail

AddDigit:       xor     dh, dh
                shl     ax, 1
                shl     ax, 1
                shl     ax, 1
                shl     ax, 1
                or      ax, dx

                inc     bx
                dec     cx
                jcxz    GetHexSuccess
                jmp     short NextDigit


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

GetHexFail:     pop     bx
                pop     cx
                stc
                jmp     short @b

couGetHex       ENDP

;*****************************************************************************
;*                           --- couGetToken ---
;*
;*     Purpose: Separate command line token
;*       Input: ES:BX - Pointer to the command line string with Hex
;*              CX    - String length
;*      Output: CY, if error occurs (es:bx unchanged in this case)
;*              CX    - modified
;*              AL    - Parameter uppercase letter
;*        Note: We expect parameter Token as '/c:xxxx', where c is parameter
;* Scratch reg: cx, bx
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
couGetToken     PROC    NEAR
                assume  ds:@data, es:Nothing

                push    bx
                push    cx

                xor     al, al
                jcxz    GetTokenSuccess

;-------------------------- Kill leading white spaces -------------------------

@@:             mov     al, es:[bx]
                cmp     al, ';'
                je      break_l
                cmp     al, ' '
                ja      @f
                inc     bx
                loop    @b

break_l:        xor     ax, ax                  ; Only white spaces in Token
                jmp     short GetTokenSuccess

;------------------- Parameter should start from '/' or '-' -------------------

@@:             cmp     al, '-'
                je      @f
                cmp     al, '/'
                jne     GetTokenFail

;----------------------------- Load command letter ----------------------------

@@:             inc     bx
                dec     cx
                jcxz    GetTokenFail

                mov     al, es:[bx]
                cmp     al, 'a'
                jb      @f
                cmp     al, 'z'
                jz      @f

                and     al, 05Fh                ; Uppercase it if required

;----------------- Letter after command have to be ':' or '=' -----------------

@@:             inc     bx
                dec     cx
                jcxz    GetTokenSuccess         ; Just switch w/o parameter

                cmp     byte ptr es:[bx], ':'
                je      @f
                cmp     byte ptr es:[bx], '='
                je      @f

                cmp     byte ptr es:[bx], ';'   ; Just switch w/o parameter ?
                je      GetTokenSuccess         ; Yes report it
                cmp     byte ptr es:[bx], ' '   ; Just switch w/o parameter ?
                ja      GetTokenFail            ; No, something wrong
                jmp     short GetTokenSuccess   ; Yes report it

;----------- We will return es:bx as pointer to first char in params ----------

@@:             inc     bx
                dec     cx

GetTokenSuccess:
                add     sp, 4                   ; Kill bx and cx in the stack
                clc
                ret

GetTokenFail:   pop     bx
                pop     cx
                stc
                ret

couGetToken     ENDP

;*****************************************************************************
;*                            --- couStrLen ---
;*
;*     Purpose: Calculate string length
;*       Input: es:di - String address
;*      Output: cx    - String length
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 11.08.94
;*****************************************************************************
couStrLen       PROC    NEAR
                pushx   <ax, di>

                push    di
                mov     al, 0
                mov     cx, -1
         repne  scasb
                xchg    cx, di
                dec     cx
                pop     di
                sub     cx, di

                popx    <di, ax>
                ret
couStrLen       ENDP

sEnd            InitCode
                end
