2
0

BIOS.Oberon.Centronics.Mod 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
  2. MODULE Centronics IN Oberon; (** non-portable *) (* pjm 07.08.95 *)
  3. (* Aos version *)
  4. IMPORT SYSTEM, Kernel IN A2, Machine IN A2;
  5. CONST
  6. LPT1* = 0;
  7. LPT2* = 1;
  8. LPT3* = 2;
  9. Timeout = 0; (* in seconds *)
  10. VAR
  11. adr: ARRAY 3 OF INTEGER;
  12. num: INTEGER;
  13. PROCEDURE Halt(msg: ARRAY OF CHAR);
  14. VAR error: ARRAY 32 OF CHAR;
  15. BEGIN
  16. COPY(msg, error);
  17. HALT(99)
  18. END Halt;
  19. PROCEDURE Wait;
  20. VAR t: Kernel.MilliTimer;
  21. BEGIN
  22. Kernel.SetTimer(t, 1); (* assume one GetTimer tick > 50us *)
  23. REPEAT UNTIL Kernel.Expired(t)
  24. END Wait;
  25. (** Start - Open parallel port. *)
  26. PROCEDURE Start*(port: INTEGER);
  27. BEGIN
  28. IF (port < 0) OR (port >= num) THEN Halt("Invalid parallel port") END
  29. END Start;
  30. (** Reset - Reset parallel port. *)
  31. PROCEDURE Reset*(port: INTEGER);
  32. VAR p: INTEGER;
  33. BEGIN
  34. IF port >= num THEN HALT(99) END;
  35. p := adr[port];
  36. INC(p, 2); Machine.Portout8(p, 8X);
  37. Wait; Machine.Portout8(p, 0CX)
  38. END Reset;
  39. (** Stop - Close parallel port. *)
  40. PROCEDURE Stop*(port: INTEGER);
  41. (* nop in current implementation *)
  42. END Stop;
  43. (** Send - Send byte to parallel port, waiting until it is ready. *)
  44. PROCEDURE Send*(port: INTEGER; x: CHAR);
  45. VAR p: INTEGER; s: SET; t: Kernel.MilliTimer;
  46. BEGIN
  47. IF port >= num THEN Halt("Invalid parallel port") END;
  48. p := adr[port]+1;
  49. IF Timeout = 0 THEN
  50. REPEAT
  51. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  52. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  53. UNTIL 7 IN s
  54. ELSE
  55. Kernel.SetTimer(t, Timeout*1000);
  56. REPEAT
  57. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  58. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  59. IF 5 IN s THEN (* out of paper *)
  60. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  61. IF 5 IN s THEN (* still out of paper *)
  62. Halt("Out of paper")
  63. END
  64. END;
  65. IF ~(3 IN s) THEN (* error *)
  66. Halt("Printer error")
  67. END
  68. UNTIL (7 IN s) OR Kernel.Expired(t)
  69. END;
  70. IF 7 IN s THEN
  71. p := adr[port]; Machine.Portout8(p, x);
  72. INC(p, 2); Machine.Portout8(p, 0DX);
  73. Machine.Portout8(p, 0DX); Machine.Portout8(p, 0CX)
  74. ELSE
  75. Halt("Printer timeout")
  76. END
  77. END Send;
  78. (** SendPoll - Send byte to parallel port. done indicates success or failure. *)
  79. PROCEDURE SendPoll*(port: INTEGER; x: CHAR; VAR done: BOOLEAN);
  80. VAR p: INTEGER; s: SET;
  81. BEGIN
  82. IF port >= num THEN Halt("Invalid parallel port") END;
  83. p := adr[port]+1;
  84. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  85. Machine.Portin8(p, SYSTEM.VAL(CHAR, s));
  86. IF 7 IN s THEN
  87. p := adr[port]; Machine.Portout8(p, x);
  88. INC(p, 2); Machine.Portout8(p, 0DX);
  89. Machine.Portout8(p, 0DX); Machine.Portout8(p, 0CX);
  90. done := TRUE
  91. ELSE
  92. done := FALSE
  93. END
  94. END SendPoll;
  95. (** Available - Returns number of bytes available for reading (implementation optional). *)
  96. PROCEDURE Available*(port: INTEGER): LONGINT;
  97. BEGIN
  98. Halt("Not implemented");
  99. RETURN 0
  100. END Available;
  101. (** Receive - Read a byte from the parallel port (implementation optional). *)
  102. PROCEDURE Receive*(port: INTEGER; VAR x: CHAR);
  103. BEGIN
  104. Halt("Not implemented")
  105. END Receive;
  106. PROCEDURE Detected(adr: INTEGER): BOOLEAN;
  107. VAR p: INTEGER; ch: CHAR;
  108. BEGIN
  109. p := adr+2; Machine.Portout8(p, 0CX);
  110. p := adr; Machine.Portout8(p, 55X);
  111. Wait; Machine.Portin8(p, ch);
  112. IF ch = 55X THEN
  113. Machine.Portout8(p, 0AAX);
  114. Wait; Machine.Portin8(p, ch);
  115. IF ch = 0AAX THEN RETURN TRUE END
  116. END;
  117. RETURN FALSE
  118. END Detected;
  119. PROCEDURE Init;
  120. VAR i: SHORTINT; p: INTEGER;
  121. BEGIN
  122. num := 0;
  123. FOR i := 0 TO 2 DO
  124. CASE i OF
  125. 0: p := 3BCH
  126. |1: p := 378H
  127. |2: p := 278H
  128. END;
  129. IF Detected(p) THEN adr[num] := p; INC(num) END
  130. END
  131. END Init;
  132. BEGIN
  133. Init
  134. END Centronics.