LPTIDC - How to share Parallel port with the OS/2 printer device drivers
By Joseph Nord
Example OS/2 PDD code demonstrating how to negotiate 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 communication 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 concern 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