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

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
 * - Author: Joseph H. Nord                              Last Update : 05/11/94
 * - Extern definitions for routines in baseidc.asm
 * - 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
 * - Author: Joseph H. Nord                              Last Update : 05/11/94
 * - IDC Communication with base OS/2 parallel port device driver
 * - 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] - 
 * Returns(AX)
 * zero - success, or error code from OS/2 printer PDD
 * 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 