LPTIDC - How to share Parallel port with the OS/2 printer device drivers

From EDM2
Jump to: navigation, search

By Joseph Nord

Example OS/2 PDD code demonstrating how to negociate access to PC parallel port via IDC.

License

You can use this IDC demonstrating code for what ever you want including commercial products with no restriction on use or royalty. If you find it useful, I would appreciate it if you give me a plug in the source and drop me a note to let me know where you are using the code.

IDC

The basic game is inter-device driver communciation between your device driver and the OS/2 shipped parallel port device driver. You may only touch the parallel port hardware after the PRINT0X.sys device driver says "okay".

The IDC support in the OS/2 parallel port device driver has been part of the OS since OS/2 2.11. It was not present in OS/2 2.1. This was a big concren when I coded what follows, but 10 years later, the code below should be "enhanced" to actually watch the return code as running on OS/2 2.1 isn't a big requirement anymore. The example code "pushes on" in cases where no communication can be established with the parallel port device driver.

Example source:

The "inc" file - LPTIDC.INC The "asm" file - LPTIDC.ASM (This is the code that does the real work)

The important parts:

The strategy open logic -

   push    LPTIDC_REQUEST_ACCESS   ; Ask OS/2 printer DD for
   call    LPTIDC_IDCAccess        ; permission to use the
   or      ax, ax                  ; parallel port.
   jnz     IDCFailed

The strategy close logic

   push    LPTIDC_RELEASE_ACCESS   ; Return ownership to OS/2
   call    LPTIDC_IDCAccess        ; Ignore errors

global data

   LPTIDC_DD_INFO  IDC_DD_INFOTYPE <>      ; For AttachDD, IDC communication

init data

szLPTn    db   "LPTn   ", 0    ; Name of OS/2 printer PDD ( "n" should be filled in at init )

init code

   mov     al, '1'                ; Perhaps - could be 2 or 3
   mov     szLPTn+3, al    ; Fill in "n" of parallel port device driver name LPTn

   mov     bx, offset szLPTn
   mov     di, offset LPTIDC_DD_INFO
   mov     dl, DevHlp_AttachDD
   call    [Device_Help]

   ; Regardless of success/fail, return success
   ; to our caller.  If the OS/2 printer PDD doesn't
   ; support IDC, we will do our best to get along.

   mov     bx, LPTIDC_DD_INFO.ProtModeOfs
   mov     ax, LPTIDC_DD_INFO.ProtModeSel
   mov     word ptr pLPTIDCEntry+0, bx     ; Offset
   mov     word ptr pLPTIDCEntry+2, ax     ; Selector 

   ; ...

End

LPTIDC.INC

;------------------------------------------------------------------------------
;- (c) Copyleft Joseph H. Nord 1993.  You may use this code what ever you want.
;- If you find it useful, please give me a plug in the commentary.
;------------------------------------------------------------------------------
;- Name:    baseidc.inc                                 Date Created: 01/26/93
;- Author:  Joseph H. Nord                              Last Update : 05/11/94
;------------------------------------------------------------------------------
;- Extern definitions for routines in baseidc.asm
;-----------------------------------------------------------------------------

LPTIDC_REQUEST_ACCESS   EQU     0
LPTIDC_RELEASE_ACCESS   EQU     1
EXTERNDEF LPTIDC_IDCAccess : NEAR

LPTIDC.ASM

;------------------------------------------------------------------------------
;- (c) Copyleft Joseph H. Nord 1993.  You may use this code what ever you want.
;- If you find it useful, please give me a plug in the commentary.
;------------------------------------------------------------------------------
;- Name:    lptidc.asm                                  Date Created: 01/26/93
;- Author:  Joseph H. Nord                              Last Update : 05/11/94
;------------------------------------------------------------------------------
;- IDC Communication with base OS/2 parallel port device driver
;-----------------------------------------------------------------------------

                .NOLIST
                INCLUDE DEVSYM6.INC             ; OS/2 toolkit include file
                INCLUDE DEVHLP.INC
                INCLUDE TYPES.INC
                INCLUDE DATA.INC
                INCLUDE LPTIDC.INC
                INCLUDE DEVICE.INC
                .LIST

                                        ;------------------------------- DATA -
DSEG    SEGMENT PUBLIC 'DATA'
DSEG    ENDS

                                        ;------------------------------- CODE -
CSEG            SEGMENT PUBLIC 'CODE'
                ASSUME CS:CSEG,DS:DSEG

                                        ;------------------- LPTIDC_IDCAccess -
; Routine calls the OS/2 printer device driver to negociate
; access to the parallel port.
; Based on the parameter, access is either requested
; or released.  The return code indicates success/failure.
;
; Parameters:
;    [bp+4] - <IDC_REQUEST_ACCESS, IDC_RELEASE_ACCESS>
; Returns(AX)
;    zero - success, or error code from OS/2 printer PDD

LPTIDC_IDCAccess PROC NEAR
                .386p
                push    bp                      ; Establish stack frame
                mov     bp, sp
                push    ebx                     ; Preserve registers
                push    cx
                push    dx
                push    ds
                push    es

                mov     ebx, pLPTIDCEntry       ; Insure IDC is possible
                or      ebx, ebx                ; If not possible, return
                jz      NoIDC                   ; success - access granted

                mov     ax, word ptr [bp+4]     ; Request/release access
                xor     bx, bx                  ; Do not block
                mov     cx, word ptr ulLPTNumber ; Port number 0..2
                push    ds                      ; es := ds
                pop     es                      ; ds := other PDDs DS
                mov     ds, es:LPTIDC_DD_INFO.ProtModeDS
                call    es:pLPTIDCEntry         ; Call other PDD

                ; If carry, then OS/2 printer PDD failed the request,
                ; error code is in ax
                ; OS/2 2.1 GA driver doesn't support IDC.  It always returns
                ; carry set with AX == 0.  To support hot cable swapping
                ; with this level of driver, we ignore this error condition
                ; and do our best to get along without trapping the machine.
                ; With this special case, we can ignore the carry/error flag
                ; and use only the RC - which is directly propagated to caller.

                jmp     Done

NoIDC:          xor     ax, ax                  ; Indicate success

Done:           pop     es                      ; Restore registers
                pop     ds
                pop     dx
                pop     cx
                pop     ebx                     ; Propagate RC in AX
                leave
                ret     2
                .286p
LPTIDC_IDCAccess ENDP

CSEG            ENDS
                END