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

{
Here a nice unit to control the DOS Printer spooler (PRINT.COM/EXE).
It's a extended/modified/debugged version of some program I found
elsewere. By controlling the DEFINE the source changes from PROGRAM
to UNIT. Just load good PRINT, Compile the demo and try to print some.
Watch your paper supply !!

{---------------------------------------------------------}
{ Original by Brian Ebarb Power Software Company -        }
{             Houston, TX (713)781-9784                   }
{                                                         }
{ Modified by G.W. van der Vegt                           }
{---------------------------------------------------------}

{ DEFINE UNIT}
{$IFDEF  UNIT}

UNIT Spooler;

INTERFACE

{$ELSE}

USES
  crt,
  dos;

{$ENDIF}

CONST
  queue_max         = 10;
  queue_namlen      = 64;

TYPE
{----Queue types}
  queue_action      = 1..5;
  queue_printer     = 1..4;
  queue_name        = STRING[queue_namlen-1];
  queue_type        = ARRAY[1..queue_max] OF queue_name;

CONST
{----Queue actions}
  queue_submit      = 1;
  queue_kill        = 2;
  queue_purge       = 3;
  queue_hold        = 4;
  queue_continue    = 5;

{----Queue results}
  queue_ok          = $00;
  queue_invfie      = $01;
  queue_nofile      = $02;
  queue_nopath      = $03;
  queue_nohandles   = $04;
  queue_noaccess    = $05;
  queue_full        = $08;
  queue_busy        = $09;
  queue_missing     = $0a; {----self defined returncode,
                                returned IF called AND NOT
                                installed.}
  queue_longname    = $0c;
  queue_nowprinting = $9e;

VAR
  queue             : queue_type;

{$IFDEF UNIT}

FUNCTION Spool(filestring : queue_name;
               theprinter : queue_printer;
               action     : queue_action) : WORD;

{---------------------------------------------------------}

IMPLEMENTATION

USES
  crt,
  dos;

{---------------------------------------------------------}

{$ENDIF}

FUNCTION Spool(filestring : queue_name;
               theprinter : queue_printer;
               action     : queue_action) : WORD;

CONST
{----MPX interrupt const}
  queue_int         = $2f;
  queue_mpx         = $01;
  queue_check       = $00;
  queue_installed   = $ff;

TYPE
  fnames  = ARRAY[1..queue_namlen] OF CHAR;
  res     = ARRAY[1..32768 DIV Sizeof(fnames)] OF fnames;

VAR
  p       : ^res;
  regs    : registers;
  fname   : fnames;
  thefile : RECORD
              prn  : BYTE;
              loc  : ARRAY[1..2] OF WORD;
            END;
  i,j     : INTEGER;

BEGIN
  Fillchar(fname, Sizeof(fname), #0);
  Move(filestring[1],fname[1],Length(filestring));

  thefile.prn    := theprinter - 1;
  thefile.loc[2] := Seg(fname);
  thefile.loc[1] := Ofs(fname);

{----Check installation}
  regs.ah := queue_mpx;
  regs.al := queue_check;

  Intr(queue_int, regs);
  IF (regs.al<>queue_installed)
  {----on return, 10 = "not installed" }
    THEN Spool:=queue_missing
    ELSE
      CASE action OF
               {----Spool a FILE, return error OR
                                  00 IF no error
                                  01 IF added TO queue OR
                                  9e IF printing           }
  queue_submit : BEGIN
                   regs.ah:=queue_mpx;
                   regs.al:=queue_submit;
                   regs.ds:=Seg(thefile);
                   regs.dx:=Ofs(thefile);

                   Intr(queue_int, regs);

                   IF ((regs.flags AND fcarry) = fcarry)
                     THEN Spool:=regs.ax
                     ELSE Spool:=regs.al;
                 END;
               {----Dequeue a file, Returns Error or ok }
    queue_kill : BEGIN
                   regs.ah:=queue_mpx;
                   regs.al:=queue_kill;
                   regs.ds:=thefile.loc[2];
                   regs.dx:=thefile.loc[1];

                   Intr(queue_int, regs);

                   IF ((regs.flags AND fcarry) = fcarry)
                     THEN Spool := regs.ax
                     ELSE Spool := queue_ok;
                 END;

               {----Deque ALL files, Returns Error or ok }
   queue_purge : BEGIN
                   regs.ah := queue_mpx;
                   regs.al := queue_purge;

                   Intr(queue_int, regs);

                   IF ((regs.flags AND fcarry) = fcarry)
                     THEN Spool := regs.ax
                     ELSE Spool := queue_ok;
                 END;

               {----Hold queue, returns error OR
                                no. OF errors since last hold (dx) ?
                                (seems TO be no. OF looks at Printer port) &
                                queue RECORD WITH first queue_max filenames}
    queue_hold : BEGIN
                   regs.ah:=queue_mpx;
                   regs.al:=queue_hold;

                   Intr(queue_int, regs);

                   IF ((regs.flags AND fcarry) = fcarry)
                     THEN Spool := regs.ax
                     ELSE
                     {----Fill & return the queue record}
                       BEGIN
                         Spool:=queue_ok; {Regs.dx}
                         p:=Ptr(regs.ds,regs.si);

                         FOR i:=1 TO queue_max DO queue[i]:='';
                         i:=1;
                         WHILE (p^[i,1]<>#00) AND (i<=queue_max) DO
                           BEGIN
                             j:=1;
                             WHILE (p^[i,j]<>#00) DO
                               BEGIN
                                 queue[i]:=queue[i]+p^[i,j];
                                 Inc(j);
                               END;
                             Inc(i);
                           END;
                       END;
                 END;

            {----Restart queue after function 4, Returns error or ok }
queue_continue : BEGIN
                   regs.ah:=queue_mpx;
                   regs.al:=queue_continue;

                   Intr(queue_int, regs);

                   IF ((regs.flags AND fcarry) = fcarry)
                     THEN Spool := regs.ax
                     ELSE Spool := queue_ok;
                 END;
      END;

END; {of Spool}

{$IFNDEF UNIT}

{---------------------------------------------------------}
{----MAIN PROGRAM                                         }
{---------------------------------------------------------}

VAR
  i : INTEGER;

BEGIN
  FOR i:=1 TO queue_max DO queue[i]:='';

  REPEAT
    Writeln('Type cmd : 1 = submit, 2 = kill, 3 = purge, 4 = hold, 5 = continue

    CASE Readkey OF
      #27 : Halt;
      '1' : Writeln('Function 1, result = ',Spool('\AUTOEXEC.BAT',1,queue_submi
      '2' : Writeln('Function 2, result = ',Spool('\AUTOEXEC.BAT',1,queue_kill
      '3' : Writeln('Function 3, result = ',Spool('',1,queue_purge   ));
      '4' : BEGIN
              Writeln('Function 4, result = ',Spool('',1,queue_hold    ));
              Writeln('Queue : ');
              FOR i:=1 TO queue_max DO
                IF (queue[i]<>'')
                  THEN Writeln(i:2,' ',queue[i]);
            END;
      '5' : Writeln('Function 5, result = ',Spool('',1,queue_continue));
    END;
  UNTIL true=false;

{$ENDIF}

END.

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