[Back to PRINTING SWAG index]  [Back to Main SWAG index]  [Original]

{ The following Program, LPRINT, illustrates how to do control a    }
{ Printer directly without using the BIOS (Printers connected to    }
{ the parallel port, not serial Printers connected to an RS-232     }
{ port).                                                            }
{ LPRINT checks to see if you want to print a line from the command }
{ prompt, as in:                                                    }
{        LPRINT Hello, World!                                       }
{ If there's no command input, LPRINT checks For Characters at the  }
{ "standard input," so you can print Files or directories using     }
{ redirection or piping:    LPRINT < myFile.pas                     }
{                           DIR | LPRINT                            }
{ LPT1 is used. You can modify LPRINT to use another, or be able to }
{ specify which Printer via the command line (eg. /2 For LPT2,etc.) }
{ This source code is a bit cramped, to fit into one message.       }
{                                                                   }

Program LPRINT;
Uses
  Dos;
Const
  BusyB   =$80;                   { status port 'busy' bit    }
  AckB    =$40;                   { status port 'ack' bit     }
Var
  DataP,
  Strobe,
  Status,                         { assigned lpt i/o ports    }
  MaxWait : Word;                 { seconds before timing out }
  Done    : Boolean;              { sanity clause             }
  Reg     : Registers;            { For Dos i/o               }
  txtptr  : Byte;                 { counter Byte              }

Procedure VerifyPrinter( Var Printer, Status, Strobe : Word );
{ check For presence of specified Printer - returning ports         }
begin
  if Printer in [1..3] then         { must be known     }
  begin
    DEC( Printer );                 { For 0..2          }
    Printer := MemW[$40 : (Printer + 8 + Printer * 2)];
    if ((Port[Printer + 1] and AckB) = 0) then
      Printer := 0           { to say it's not there }
    else
    begin
      Status := Printer + 1;
      Strobe := Printer + 2;
    end
  end
end; {VerifyPrinter}

Procedure Print( DataP : Word; chout : Byte; Var Done : Boolean);
{ send Character to Printer port, With busy timeout and feedback    }
Var
  WaitTime : LongInt;
  Timer    : LongInt Absolute 0:$046c;
  BusyWait : Word;
begin
  BusyWait := 0;
  WaitTime := Timer;
  While ((Port[Status] and BusyB) = 0) and (BusyWait < MaxWait * 19) do
  { wait up to MaxWait seconds For non-busy state             }
    BusyWait := Word( Timer - WaitTime );
  if BusyWait >= (MaxWait * 19) then { Printer "busy" For too long? }
    Done := False              { failed            }
  else
  begin
    Port[DataP]  := chout;     { send the Char data}
    Port[Strobe] := $0c;       { strobe it in      }
    Port[Strobe] := $0d;       { reset strobe      }
    Done := True;              { success           }
  end {else}
end; {Print}

begin   {LPRINT}
  WriteLn(#10, 'LPRINT v1.0 G.S.Vigneault', #10);
  DataP := 1;     { LPT1 }
  VerifyPrinter( DataP, Status, Strobe );
  { DataP will be 0 now if requested Printer didn't respond   }
  if DataP = 0 then
  begin
    WriteLn('Printer not detected!',#10,#7);
    Halt(1);
  end;
  MaxWait := 10;  { max wait 10sec before timing out lpt      }
  if ParamCount = 0 then  { no command-line input?            }
  { handle redirected and piped }
  Repeat
    Reg.AH := $b;   { to see if a Char is available     }
    MsDos( Reg );
    if Reg.AL <> 0 then
    begin
      Reg.AH := 8;            { get the Char      }
      MsDos( Reg );           { via Dos           }
      Print( DataP, Reg.AL, Done );{ lprint it    }
    end; {if}
  Until (Reg.AL = 0) or not Done
  else    { print the command line Text }
  begin
    txtptr := $82;
    Repeat
      Print( DataP, Mem[PrefixSeg:txtptr], Done );
      INC( txtptr );
    Until (Mem[PrefixSeg:txtptr] = 13) or not Done;
  if Done then
    Print( DataP, 10, Done);       { lf    }
  end;
end {LPRINT}.
(********************************************************************)

[Back to PRINTING SWAG index]  [Back to Main SWAG index]  [Original]