123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
- MODULE Centronics IN Oberon; (** non-portable *) (* pjm 07.08.95 *)
- (* Aos version *)
- IMPORT SYSTEM, Kernel IN A2, Machine IN A2;
- CONST
- LPT1* = 0;
- LPT2* = 1;
- LPT3* = 2;
- Timeout = 0; (* in seconds *)
- VAR
- adr: ARRAY 3 OF INTEGER;
- num: INTEGER;
- PROCEDURE Halt(msg: ARRAY OF CHAR);
- VAR error: ARRAY 32 OF CHAR;
- BEGIN
- COPY(msg, error);
- HALT(99)
- END Halt;
- PROCEDURE Wait;
- VAR t: Kernel.MilliTimer;
- BEGIN
- Kernel.SetTimer(t, 1); (* assume one GetTimer tick > 50us *)
- REPEAT UNTIL Kernel.Expired(t)
- END Wait;
- (** Start - Open parallel port. *)
- PROCEDURE Start*(port: INTEGER);
- BEGIN
- IF (port < 0) OR (port >= num) THEN Halt("Invalid parallel port") END
- END Start;
- (** Reset - Reset parallel port. *)
- PROCEDURE Reset*(port: INTEGER);
- VAR p: INTEGER;
- BEGIN
- IF port >= num THEN HALT(99) END;
- p := adr[port];
- INC(p, 2); Machine.Portout8(p, 8X);
- Wait; Machine.Portout8(p, 0CX)
- END Reset;
- (** Stop - Close parallel port. *)
- PROCEDURE Stop*(port: INTEGER);
- (* nop in current implementation *)
- END Stop;
- (** Send - Send byte to parallel port, waiting until it is ready. *)
- PROCEDURE Send*(port: INTEGER; x: CHAR);
- VAR p: INTEGER; s: SET; t: Kernel.MilliTimer;
- BEGIN
- IF port >= num THEN Halt("Invalid parallel port") END;
- p := adr[port]+1;
- IF Timeout = 0 THEN
- REPEAT
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- UNTIL 7 IN s
- ELSE
- Kernel.SetTimer(t, Timeout*1000);
- REPEAT
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- IF 5 IN s THEN (* out of paper *)
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- IF 5 IN s THEN (* still out of paper *)
- Halt("Out of paper")
- END
- END;
- IF ~(3 IN s) THEN (* error *)
- Halt("Printer error")
- END
- UNTIL (7 IN s) OR Kernel.Expired(t)
- END;
- IF 7 IN s THEN
- p := adr[port]; Machine.Portout8(p, x);
- INC(p, 2); Machine.Portout8(p, 0DX);
- Machine.Portout8(p, 0DX); Machine.Portout8(p, 0CX)
- ELSE
- Halt("Printer timeout")
- END
- END Send;
- (** SendPoll - Send byte to parallel port. done indicates success or failure. *)
- PROCEDURE SendPoll*(port: INTEGER; x: CHAR; VAR done: BOOLEAN);
- VAR p: INTEGER; s: SET;
- BEGIN
- IF port >= num THEN Halt("Invalid parallel port") END;
- p := adr[port]+1;
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
- IF 7 IN s THEN
- p := adr[port]; Machine.Portout8(p, x);
- INC(p, 2); Machine.Portout8(p, 0DX);
- Machine.Portout8(p, 0DX); Machine.Portout8(p, 0CX);
- done := TRUE
- ELSE
- done := FALSE
- END
- END SendPoll;
- (** Available - Returns number of bytes available for reading (implementation optional). *)
- PROCEDURE Available*(port: INTEGER): LONGINT;
- BEGIN
- Halt("Not implemented");
- RETURN 0
- END Available;
- (** Receive - Read a byte from the parallel port (implementation optional). *)
- PROCEDURE Receive*(port: INTEGER; VAR x: CHAR);
- BEGIN
- Halt("Not implemented")
- END Receive;
- PROCEDURE Detected(adr: INTEGER): BOOLEAN;
- VAR p: INTEGER; ch: CHAR;
- BEGIN
- p := adr+2; Machine.Portout8(p, 0CX);
- p := adr; Machine.Portout8(p, 55X);
- Wait; Machine.Portin8(p, ch);
- IF ch = 55X THEN
- Machine.Portout8(p, 0AAX);
- Wait; Machine.Portin8(p, ch);
- IF ch = 0AAX THEN RETURN TRUE END
- END;
- RETURN FALSE
- END Detected;
- PROCEDURE Init;
- VAR i: SHORTINT; p: INTEGER;
- BEGIN
- num := 0;
- FOR i := 0 TO 2 DO
- CASE i OF
- 0: p := 3BCH
- |1: p := 378H
- |2: p := 278H
- END;
- IF Detected(p) THEN adr[num] := p; INC(num) END
- END
- END Init;
- BEGIN
- Init
- END Centronics.
|