;      /*****************************************************************/
;      /*                                                               */
;      /*           Copyright (c) IBM Corporation  1987, 1992           */
;      /*                     All Rights Reserved                       */
;      /*                                                               */
;      /*****************************************************************/
;      /******************* START OF SPECIFICATIONS *********************/
;      /*                                                               */
;      /*  SOURCE FILE NAME: IDC.ASM                                    */
;      /*                                                               */
;      /*  DESCRIPTIVE NAME: Inter-driver communication routines        */
;      /*                                                               */
;      /*  COPYRIGHT:  IBM Corp. 1992                                   */
;      /*                                                               */
;      /*  STATUS:  Version 1.0                                         */
;      /*                                                               */
;      /*  NOTES: IDC routines are provided. The entry point that the   */
;      /*         pen device driver services calls, as defined by the   */
;      /*         Devhlp_RegisterDeviceClass, is defined here. The      */
;      /*         IDC entry point in the device header is available     */
;      /*         for device dependent use.                             */
;      /*                                                               */
;      /*         The configuration and binding protocol is implemented */
;      /*         here.                                                 */
;      /*                                                               */
;      /*         Routines to call the device driver services are       */
;      /*         provided here.                                        */
;      /*                                                               */
;      /*  ENTRY POINTS:                                                */
;      /*      See public statements                                    */
;      /*  EXTERNAL REFERENCES:                                         */
;      /*      See extrn statements                                     */
;      /*                                                               */
;      /******************* END  OF  SPECIFICATIONS *********************/
.xlist
  include pensegs.inc
  include pen.inc
  include penidc.inc
  include penei.inc
  include struc.inc
.list

.286p

;------------------------------------------------------------------------------
;  external data references
;------------------------------------------------------------------------------

extrn Device_Help  : dword
extrn dcb0         : byte
extrn RegCaps0     : byte

;------------------------------------------------------------------------------
;  external routines
;------------------------------------------------------------------------------

extrn Vmc_ReadEnable  : near

;------------------------------------------------------------------------------
; local data declarations
;------------------------------------------------------------------------------

DSEG segment

DevStatus     db     0                 ; idc controls

; bits for DevStatus
RPTENABLED    equ    0001h    ; reporting is enabled
DEVICEENABLED equ    0002h    ; events are enabled

; Inter Driver Communication table for driver entry point
public pen_idc
pen_idc       dw     Idc_invalid         ; by unit commands
              dw     Idc_QueryCaps       ; 1
              dw     Idc_QueryDevConfig  ; 2
              dw     Idc_StartDevice     ; 3
              dw     Idc_invalid         ; 4
              dw     Idc_invalid         ; 5
PENBYUNIT     equ    ($-pen_idc)/2

              dw     Idc_ReadEnable      ; 6
              dw     Idc_ReadDisable     ; 7
              dw     Idc_EnableDevice    ; 8
              dw     Idc_DisableDevice   ; 9
              dw     Idc_ActCallBack     ; 10
              dw     Idc_VMChange        ; 11
PENIDCMAX     equ    ($-pen_idc)/2


DSEG ends

CSEG SEGMENT
     ASSUME    CS:CSEG, SS:nothing, ES:nothing, DS:DGROUP


;---- OS/2 IDC ENTRY POINT ----------------------------------------------------
; Handle OS/2 device driver interface commands for pen PM device services
;  ax    = idc command number
; returns
;  cy & ax != 0 for error
;  nc & ax == 0 for success
;------------------------------------------------------------------------------
public Idc_DriverEntryPoint
Idc_DriverEntryPoint proc far

  .if <ax b  PENBYUNIT>      ; If it a call that passes unit
     mov  si, ax
     shl  si, 1
     CALL_UNIT pen_idc[si],bl
  .elseif <ax b  PENIDCMAX>  ; global call
     lea  bx, dcb0
     mov  si, ax
     shl  si, 1
     call pen_idc[si]
  .else                      ; out of range
     stc
     mov  ax, 1
  .endif

  ret                        ; return
Idc_DriverEntryPoint endp

;---- IDC ROUTINES ------------------------------------------------------------
;
;------------------------------------------------------------------------------

Idc_invalid proc
  PANIC PANIC_INVALID_IDC
  stc
  ret
Idc_invalid endp

;------------------------------------------------------------------------------
;  Query the capibilities for the logical device
;    bx = unit
;    es: di = area to copy registration packet
;  returns
;    nc, ax == 0 for success
;    cy, ax 1= 0 for error
;------------------------------------------------------------------------------
public Idc_QueryCaps
Idc_QueryCaps proc near     ; request unit registration
  xor  ax,ax
  mov  si,[bx].dcb_@RegCaps        ; si -> registration packet
  mov  cx,[si]                     ; get size
  .if <cx a es:[di]>               ; truncate copy
    mov  cx, es:[di]
    mov  ax,DRV_ERR_BUFF_TRUNC     ; return error, but copy part
  .endif
  rep movsb
  clc
  ret
Idc_QueryCaps endp

;------------------------------------------------------------------------------
; Get device configuration parameters
;  bx = dcb
;  es:di = pointer to buffer to return parameters
;------------------------------------------------------------------------------
public Idc_QueryDevConfig
Idc_QueryDevConfig  Proc
  mov  si, [bx].dcb_@DeviceData        ; get addr of device data
  .if  <zero si>
     mov  word ptr es:[di],0
  .else
     mov  cx, es:[di].DevData_CfgDataLen ; get length of data requested
     .if <cx gt [si].DevData_CfgDataLen> ; if more than we got
        mov  cx, [si].DevData_CfgDataLen ; limit to what we have
     .endif
     cld                               ; go forward
     rep  movsb                        ; move data to callers data area
  .endif
  xor  ax,ax                           ; clear carry for no error
  ret                                  ; return to IDC router
Idc_QueryDevConfig  EndP

;------------------------------------------------------------------------------
; Enable reporting of interrupt data to locator driver service
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_StartDevice
Idc_StartDevice Proc

   UNPANIC  PANIC_DDS     ; we have been contacted

; do level check

  .if  <es:[di].sinfo_idc_major lt PEN_DDS_LEV_MAJOR> OR
  .if  <es:[di].sinfo_idc_minor lt PEN_DDS_LEV_MINOR> OR
  .if  <es:[di].sinfo_eif_major lt PEN_EI_LEV_MAJOR> OR
  .if  <es:[di].sinfo_eif_minor lt PEN_EI_LEV_MINOR>
     PANIC PANIC_LEVELS
     mov  ax,DRV_ERR_LEVEL
     stc
     ret
  .endif

; hold stuff from SINFO structure needed to call

  mov  ax, es:[di].sinfo_service_ds
  mov  [bx].dcb_service_ds, ax
  mov  ax, word ptr es:[di].sinfo_service_rtn
  mov  word ptr [bx].dcb_service_rtn, ax
  mov  ax, word ptr es:[di].sinfo_service_rtn+2
  mov  word ptr [bx].dcb_service_rtn+2, ax

; register with device service

  call Idc_RegisterDevice

; save returned information

  .if c
     PANIC PANIC_REG_ERR
     stc
  .else
     mov  di, [bx].dcb_@RegCaps
     mov  al, [di].ccap_device_id
     mov  di, [bx].dcb_@EiEvent
     .if  <nonzero di>
        mov  [di].cev_device_id, al
     .endif

; start up the device

     CALL_NZ_OK [bx].dcb_@Dev_Start ; start up the device
  .endif
  ret
Idc_StartDevice EndP

;------------------------------------------------------------------------------
; Enable reporting of interrupt data to driver services
; cx:dx = Style/Capabilites bits
;------------------------------------------------------------------------------
public Idc_ReadEnable
Idc_ReadEnable  Proc
  or   DevStatus, RPTENABLED ; Set flag to enable intrpt reporting
  CALL_NZ_OK [bx].dcb_@Dev_ReadEnable ; Change default Style
  call Vmc_ReadEnable        ; check for video mode overrides
  ret
Idc_ReadEnable  EndP

;------------------------------------------------------------------------------
; Disable reporting of interrupt data
;------------------------------------------------------------------------------
public Idc_ReadDisable
Idc_ReadDisable  Proc  Near
  and  DevStatus, NOT RPTENABLED ; set flag to disable data reporting
  CALL_NZ_OK dcb0.dcb_@Dev_ReadDisable
  ret
Idc_ReadDisable  EndP

;------------------------------------------------------------------------------
;  Disable reporting device interrupts
;------------------------------------------------------------------------------
public Idc_DisableDevice
Idc_DisableDevice  Proc  Near
  and  DevStatus, NOT DEVICEENABLED
  CALL_NZ_OK dcb0.dcb_@Dev_Disable
  ret
Idc_DisableDevice  EndP

;------------------------------------------------------------------------------
; Enable reporting device interrupts
;------------------------------------------------------------------------------
public Idc_EnableDevice
Idc_EnableDevice  Proc  Near
  or   DevStatus, DEVICEENABLED
  CALL_NZ_OK dcb0.dcb_@Dev_Enable
  ret
Idc_EnableDevice  EndP

;------------------------------------------------------------------------------
; activity call back stub
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_ActCallBack
Idc_ActCallBack Proc
  CALL_NZ_OK dcb0.dcb_@Dev_CallBack
  ret                            ; return to IDC router
Idc_ActCallBack EndP

;------------------------------------------------------------------------------
; Video Mode Notification
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_VMChange
Idc_VMChange proc
  CALL_NZ_OK dcb0.dcb_@Dev_VMChange
  ret
Idc_VMChange endp

;------------------------------------------------------------------------------
; Advance Power Management notification
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_APM
Idc_APM proc
  CALL_NZ_OK dcb0.dcb_@Dev_APM
  ret
Idc_APM endp

;-- IDC SUPPORT ROUTINES ------------------------------------------------------
;
;------------------------------------------------------------------------------

idc_common proc

;------------------------------------------------------------------------------
; register device
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_RegisterDevice
Idc_RegisterDevice:
  mov  ax, REGISTER_DEVICE
  mov  di, [bx].dcb_@RegCaps
  jmp  short common2

;------------------------------------------------------------------------------
; report event
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_ReportEvent
Idc_ReportEvent:
  mov  di, [bx].dcb_@EiEvent   ; Addr of event packet
  mov  ax, REPORT_EVENT
  jmp  short common

;------------------------------------------------------------------------------
; update capabilities
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_UpdateCaps
Idc_UpdateCaps:
  mov  di, [bx].dcb_@RegCaps   ; Addr of caps packet
  mov  ax, UPDATE_CAPS
  jmp  short common

;------------------------------------------------------------------------------
; request a callback
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_RequestCallback
Idc_RequestCallback:
  mov  cl, RegCaps0.ccap_device_id
  mov  ax, REQUEST_CALLBACK
  jmp  short common

;------------------------------------------------------------------------------
; cancel a callback
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_CancelCallback
Idc_CancelCallback:
  mov  cl, RegCaps0.ccap_device_id
  mov  ax, CANCEL_CALLBACK
  jmp  short common

;------------------------------------------------------------------------------
; suppress stroke
;  bx = dcb
;------------------------------------------------------------------------------
public Idc_SuppressStroke
Idc_SuppressStroke:
  mov  cl, RegCaps0.ccap_device_id
  mov  ax, SUPPRESS_STROKE
  jmp  short common

;------------------------------------------------------------------------------
; request the activity count
;  bx = dcb
; returns
;  edx = activity count
;------------------------------------------------------------------------------
public Idc_QueryActivity
Idc_QueryActivity:
  mov  ax, QUERY_ACTIVITY

common:
  .if <bit DevStatus nz RPTENABLED>
common2:
     push ds
     push bx

     push ds
     pop  es
     mov  ds,[bx].dcb_service_ds
     call es:[bx].dcb_service_rtn
     pop  bx
     pop  ds
  .endif
  ret
Idc_Common endp

CSEG ends
END
