home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------------ *)
- (* SPOOLPRN.PAS *)
- (* Drucker-Spooler in Turbo-Pascal fuer MS-DOS *)
- (* ------------------------------------------------------------ *)
-
- PROGRAM SpoolPrinter;
-
- {$K-}
- {$U-}
- {$R-}
- {$V-}
- {$I-}
- {$C-}
-
- {$I REGS8088.INC}
- {$I CRITICAL.INC}
- {$I MAKEINT.INC}
- {$I FIFO.INC}
-
- TYPE
- PrinterStatus_ = SET OF (
- PrinterTimeOut,
- PrinterUnused2,
- PrinterUnused3,
- PrinterIOError,
- PrinterSelected,
- PrinterPaperOut,
- PrinterReadyForMore,
- PrinterNotBusy
- );
-
- PrinterControl_ = SET OF (
- PrinterStrobe,
- PrinterAutoLineFeed,
- PrinterNormalOperation,
- PrinterSelect,
- PrinterEnableInterrupt,
- PrinterUnused6,
- PrinterUnused7,
- PrinterUnused8
- );
-
- Printer_ = RECORD
- Status : PrinterStatus_;
- DataPort,
- StatusPort,
- ControlPort : INTEGER;
- Fifo : FifoAddr_;
- END;
-
-
- CONST
- PrinterSize = 32000;
- PrinterPortBase = $0378;
-
- VAR
- Printer : Printer_;
-
- (* ------------------------------------------------------------ *)
- (* Drucker-Spooler einrichten: *)
-
- PROCEDURE PrinterAllocate (VAR Printer: Printer_;
- PortBase, FifoSize: INTEGER);
-
- BEGIN
- WITH Printer DO
- BEGIN
- Status:= [];
- Fifo:= FifoAllocate (FifoSize);
- IF Fifo = NIL THEN
- WriteLn (' Kein Platz fuer Puffer')
- ELSE
- BEGIN
- DataPort := PortBase;
- StatusPort := DataPort + 1;
- ControlPort:= DataPort + 2;
- END;
- END;
- END;
-
- (* ------------------------------------------------------------ *)
- (* Drucker-Hardware-Status abfragen: *)
-
- PROCEDURE PrinterNativeStatus (VAR Printer: Printer_);
-
- VAR
- Stat : PrinterStatus_;
- StatByte : BYTE ABSOLUTE Stat;
-
- BEGIN
- WITH Printer DO
- BEGIN
- StatByte:= (Port [StatusPort] XOR $48) AND $F8;
- Status:= Stat;
- END;
- END;
-
- (* ------------------------------------------------------------ *)
- (* Drucker-Kontrollinformationen uebergeben: *)
-
- PROCEDURE PrinterWriteControl (VAR Printer: Printer_;
- Control: PrinterControl_);
-
- VAR ControlByte : BYTE ABSOLUTE Control;
-
- BEGIN
- Control:= Control + [PrinterEnableInterrupt, PrinterSelect];
- Port [Printer.ControlPort]:= ControlByte;
- END;
-
- (* ------------------------------------------------------------ *)
- (* Drucker-Status fuer BIOS erzeugen: *)
-
- PROCEDURE PrinterStatus (VAR Printer: Printer_);
-
- BEGIN
- WITH Printer DO
- BEGIN
- PrinterNativeStatus (Printer);
- IF (Status * [PrinterIOError, PrinterPaperOut]) = [] THEN
- Status:= [PrinterReadyForMore, PrinterNotBusy,
- PrinterSelected];
- END;
- END;
-
- (* ------------------------------------------------------------ *)
- (* Drucker initialisieren und FIFO loeschen: *)
-
- PROCEDURE PrinterInit (VAR Printer: Printer_);
-
- BEGIN
- WITH Printer DO
- BEGIN
- FifoReset (Fifo^);
- PrinterWriteControl (Printer, []);
- PrinterWriteControl (Printer, [PrinterNormalOperation]);
- PrinterStatus (Printer);
- END;
- END;
-
- (* ------------------------------------------------------------ *)
- (* ein Zeichen in den FIFO schreiben: *)
-
- PROCEDURE PrinterWrite (VAR Printer: Printer_; Character: BYTE);
-
- VAR
- FifoStatus : FifoStatus_;
- EndOfLoop : BOOLEAN;
-
- BEGIN
- WITH Printer DO
- BEGIN
- REPEAT
- EndOfLoop:= TRUE;
- FifoWrite (Fifo^, FifoStatus, Character);
- PrinterStatus (Printer);
- IF FifoStatus = FifoFull THEN
- IF (Status * [PrinterIOError, PrinterPaperOut]) = []
- THEN EndOfLoop:= FALSE;
- UNTIL EndOfLoop;
- END;
- END;
-
- (* ------------------------------------------------------------ *)
- (* die BIOS-Interrupt-Routine des Druckers: *)
-
- PROCEDURE PrinterInterrupt;
-
- {$I BEGININT.INC}
- WITH PgmRegs DO
- IF PgmDx = 0 THEN
- WITH Printer DO
- BEGIN
- IF Fifo <> NIL THEN
- CASE PgmAh OF
- 0: PrinterWrite (Printer, PgmAl);
- 1: PrinterInit (Printer);
- 2: PrinterStatus (Printer);
- ELSE ;
- END
- ELSE
- Status:= [PrinterIOError];
- PgmAh:= Mem [Seg (Status): Ofs (Status)];
- END;
- {$I ENDINT.INC}
-
- (* ------------------------------------------------------------ *)
- (* ein Zeichen aus dem FIFO an Drucker senden: *)
-
- PROCEDURE PrinterRestart (VAR Printer: Printer_);
-
- VAR
- Transaction : CriticalSection_;
- Character : BYTE;
- FifoStatus : FifoStatus_;
-
- BEGIN
- WITH Printer DO
- BEGIN
- CriticalBegin (Transaction);
- PrinterNativeStatus (Printer);
- IF (Status * [PrinterIOError, PrinterPaperOut]) = [] THEN
- IF PrinterNotBusy IN Status THEN
- BEGIN
- FifoRead (Fifo^, FifoStatus, Character);
- IF FifoStatus = FifoOk THEN
- BEGIN
- Port [DataPort]:= Character;
- PrinterWriteControl (Printer,
- [PrinterStrobe,
- PrinterNormalOperation]);
- PrinterWriteControl (Printer,
- [PrinterNormalOperation]);
- END;
- END;
- CriticalEnd (Transaction);
- END;
- END;
-
- (* ------------------------------------------------------------ *)
- (* Hardware-Interrupt-Routine fuer Drucker: *)
-
- PROCEDURE Printer1Interrupt;
-
- {$I BEGININT.INC}
- PrinterRestart (Printer);
- IntChipRestart;
- {$I ENDINT.INC}
-
- (* ------------------------------------------------------------ *)
- (* Drucker-Spooler instalieren: *)
-
- PROCEDURE PrinterInstall;
-
- BEGIN
- PrinterAllocate (Printer, PrinterPortBase, PrinterSize);
- IntSet (IntPrinter, Cseg, Ofs (PrinterInterrupt));
- IntSet (IntCentronics, Cseg, Ofs (Printer1Interrupt));
- IntChipEnable (IntChipPrinterMask);
- END;
-
- (* ------------------------------------------------------------ *)
- (* Das Hauptprogramm: Interrupt-Routinen installieren und *)
- (* resident machen: *)
- (* Die zwei Timer-Prozeduren dienen lediglich dazu, einen *)
- (* Kunstfehler des PCs in den Griff zu bekommen (s. Artikel) *)
-
- CONST TimerOldInterrupt : IntEntry_ = (Offset:0; Segment:0);
-
-
- PROCEDURE TimerInterrupt;
-
- {$I BEGININT.INC}
- PrinterRestart (Printer);
- {$I EXITINT.INC}
- TimerOldInterrupt);
- END;
-
-
- PROCEDURE TimerInstall;
-
- BEGIN
- WITH TimerOldInterrupt DO
- IntGet (IntTimer, Segment, Offset);
- IntSet (IntTimer, Cseg, Ofs (TimerInterrupt));
- END;
-
-
- BEGIN
- PrinterInstall;
- WriteLn; WriteLn;
- WriteLn('Drucker-Spooler installiert...');
- WriteLn('(C) 1987 W. Hofmeister-Dunkel / PASCAL Int.');
- TimerInstall;
- MakeResident;
- END.
-