home *** CD-ROM | disk | FTP | other *** search
- {$S-,I-,V-,E-}
- UNIT LPT123;
- {
- MODULE: LPT123.PAS
- AUTHOR: L. Christopher Luther, ProLogic Consultants
- DATE: December 1, 1988
-
- PURPOSE: The purpose of this Unit is to provide a generic printer
- interface for all Turbo Pascal 5.0 (and 4.0 if you remove the
- E- compiler directive) programs. I feel that it fills a few
- gaps that Borland forgot to include in their Printer Unit.
-
- Two of the routines, Eject_A_Page and PrinterStatus, were
- obtained from the last issue of the Turbo User's Group Magazine,
- "TUG Lines." Eject_A_Page is sooooo simple that I could not
- improve it. However, PrinterStatus did not load the number of
- the printer into register DX. As a result, the routine was not
- consistent in its operation. I modified it around the other
- functions that I wrote so that it will report the status of
- whichever printer port is currently open.
-
- I hope that this routine is the first step to others sharing
- their code. I welcome comments and improvements. Maybe someone
- could write a set BIOS routines to make the LST output faster.
-
- }
-
- {=============================================================================}
- INTERFACE
-
- CONST
- PrtNoError = 0; { No printer error detected }
- PrtInUse = 1; { Printer busy error }
- PrtNotSelected = 2; { Printer not on line error }
- PrtNoPaper = 3; { Printer out of paper error }
- PrtNoPower = 4; { Printer no power error }
- PrtMiscError = 5; { Unknown printer error }
-
- VAR
- Lst : TEXT;
-
- PROCEDURE SetLstMode (Raw : BOOLEAN); { Toggle Cooked/Raw mode for Lst }
- PROCEDURE AssignLst (LstPort : BYTE); { Open LPT1: through LPT3: }
- PROCEDURE Eject_a_Page; { Send a form feed to Lst }
- FUNCTION PrinterStatus : INTEGER; { Attempt to determine Lst status }
-
- {=============================================================================}
- IMPLEMENTATION
-
- USES
- DOS;
-
- CONST
- FirstTime : BOOLEAN = TRUE; { A simple switch (see AssignLst). }
-
- VAR
- Regs : REGISTERS; { We need these registers. }
- ExitSave : POINTER; { Pointer to old Exit Proc. }
- OldLstMode : BOOLEAN; { Old status of Lst Raw or Cooked. }
- LstFileHandle : WORD Absolute Lst; { The file handle for the LST Text }
- { Device Driver. }
-
-
- {*****************************************************************************}
- FUNCTION GetLstMode : BOOLEAN;
- BEGIN
- WITH Regs DO
- BEGIN
- AX := $4400; { Get device status }
- BX := LstFileHandle; { Lst device handle }
- MSDOS (Regs); { Call INT 21 Function }
- GetLstMode := Odd(DX Shr 5); { Get the current status }
- END; { of the Raw Bit }
- END;
-
-
- {*****************************************************************************}
- PROCEDURE SetLstMode (Raw : BOOLEAN);
- BEGIN
- WITH Regs DO
- BEGIN
- AX := $4400; { Get device status }
- BX := LstFileHandle; { Lst device handle }
- MSDOS (Regs); { Call INT 21 Function }
- AX := $4401; { Set device status }
- DX := DX AND $00DF; { Clear the Raw Bit }
- IF Raw THEN
- Inc (DX, 32);
- MSDOS (Regs); { Call INT 21 Function }
- END;
- END;
-
-
- {*****************************************************************************}
- {$F+}
- PROCEDURE ExitHandler;
- BEGIN
- ExitProc := ExitSave; { Restore old Exit Proc Pointer. }
- SetLstMode (OldLstMode); { Restore Lst to its old status. }
- Close (Lst); { Close the LST Text Device Driver. }
- END;
- {$F-}
-
-
- {*****************************************************************************}
- PROCEDURE AssignLst (LstPort : BYTE);
-
- VAR
- LptName : STRING[4];
- DummyErr : WORD;
-
- BEGIN
- IF NOT FirstTime THEN { If this is not the first time that }
- BEGIN { the routine is executed, then }
- SetLstMode (OldLstMode); { restore the Raw/Cooked status of }
- Close (Lst); { LPT? and close the device. }
- DummyErr := IOResult; { We do not care if any IO Errors }
- END { occur. }
- ELSE
- FirstTime := FALSE;
-
- CASE LstPort OF
- 1 : LptName := 'LPT1';
- 2 : LptName := 'LPT2';
- 3 : LptName := 'LPT3';
- ELSE
- LptName := 'LPT1'; { Default to LPT1 if invalid port }
- END;
-
- Assign (Lst, LptName);
- WITH TextRec(Lst) DO
- BEGIN
- CASE LstPort OF
- 1 : UserData[1] := 0; { Store the LPT port in UserData[1] }
- { DOS uses 0 for LPT1: }
- 2 : UserData[1] := 1; { Store the LPT port in UserData[1] }
- { DOS uses 1 for LPT2: }
- 3 : UserData[1] := 2; { Store the LPT port in UserData[1] }
- { DOS uses 2 for LPT3: }
- ELSE
- UserData[1] := 0; { Store the LPT port in UserData[1] }
- { DOS uses 0 for LPT1: }
- END;
- END;
-
- ReWrite (Lst); { Open the LST Text Device Driver. }
- DummyErr := IOResult; { We do not care what errors occur. }
- OldLstMode := GetLstMode; { Save the Raw/Cooked Status of LST. }
- END;
-
-
- {*****************************************************************************}
- PROCEDURE Eject_a_Page;
-
- CONST
- FormFeed = #12;
-
- BEGIN
- Write (Lst, FormFeed); { Real simple, Eject one page }
- END;
-
-
- {*****************************************************************************}
- FUNCTION PrinterStatus : INTEGER;
-
- { See the DOS technical Reference for the values of the Bits that are set
- in register AH by this function. }
-
- BEGIN
- WITH Regs DO
- BEGIN
- AH := $02; { Printer status function code. }
- DX := TextRec(Lst).UserData[1];
- Intr ($17, Regs); { Printer service interrupt. }
- CASE AH OF
- $90 : PrinterStatus := PrtNoError;
- $A1 : PrinterStatus := PrtInUse;
- $08 : PrinterStatus := PrtNotSelected;
- $28 : PrinterStatus := PrtNoPaper;
- $48 : PrinterStatus := PrtNoPower; { for IBM XT }
- ELSE
- PrinterStatus := PrtMiscError;
- END;
- END;
- END;
-
-
- {=============================================================================}
- { Unit INITIALIZATION }
-
- BEGIN
- AssignLst (1); { Open LST as LPT1: }
- ExitSave := ExitProc; { Save the current Exit Proc.}
- ExitProc := @ExitHandler { Install our own Exit Proc. }
- END.