rs.mod 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. IMPLEMENTATION MODULE rs;
  2. IMPORT SYSTEM, Lib, IO;
  3. CONST Com1 = 3F8H;
  4. Com1INr = 4;
  5. Com2 = 2F8H;
  6. Com2INr = 3;
  7. IntEnable = 1;
  8. DivisorMsb = 1;
  9. IntId = 2;
  10. LineCont = 3;
  11. ModemCont = 4;
  12. LineStatus = 5;
  13. ModemStatus = 6;
  14. TYPE b = SET OF SHORTCARD[0..7];
  15. VAR IOBase,ComINr : CARDINAL;
  16. CONST
  17. TXBuffer ::= IOBase;
  18. RXBuffer ::= IOBase;
  19. DivisorLsb ::= IOBase;
  20. BufferSize = 256;
  21. TRMax = BufferSize-16;
  22. Noise = FALSE;
  23. VAR WorkSpace : ARRAY[0..7FFH] OF CHAR;
  24. MainProc : ADDRESS;
  25. IP : ADDRESS;
  26. OldC : PROC;
  27. Term : PROC;
  28. (*$W+*)
  29. TXReady,CTS,CTSH : BOOLEAN;
  30. RTS : BOOLEAN;
  31. TXCount,TXI,TXO : CARDINAL;
  32. RXCount,RXI,RXO : CARDINAL;
  33. (*$W-*)
  34. IBuf,OBuf : ARRAY[0..BufferSize-1] OF SHORTCARD;
  35. PROCEDURE TX;
  36. BEGIN
  37. IF CTS OR NOT CTSH THEN
  38. TXReady := FALSE;
  39. DEC(TXCount);
  40. SYSTEM.Out( TXBuffer,OBuf[TXO] );
  41. TXO := (TXO+1) MOD BufferSize;
  42. END;
  43. END TX;
  44. PROCEDURE RX;
  45. BEGIN
  46. IF RXCount >= TRMax THEN
  47. SYSTEM.Out( IOBase+ModemCont, SHORTCARD( b{0,3} ) );
  48. RTS := FALSE;
  49. END;
  50. IBuf[RXI] := SYSTEM.In( RXBuffer );
  51. IF Noise AND (Lib.RANDOM(500)=0) THEN
  52. IBuf[RXI] := SHORTCARD(Lib.RANDOM(256));
  53. END;
  54. RXI := (RXI+1) MOD BufferSize;
  55. INC(RXCount);
  56. END RX;
  57. VAR GotBreak : BOOLEAN;
  58. (*$C FF,J+*)
  59. PROCEDURE Int;
  60. VAR i : SHORTCARD;
  61. s : b;
  62. BEGIN
  63. LOOP
  64. i := SYSTEM.In( IOBase+IntId );
  65. IF i=1 THEN EXIT; END;
  66. CASE i DIV 2 OF
  67. | 0 : (* Modem status *)
  68. s := b(SYSTEM.In( IOBase+ModemStatus ));
  69. CTS :=4 IN s;
  70. IF CTS AND (TXCount >0) AND TXReady THEN TX END;
  71. | 1 : (* TXEmpty *)
  72. TXReady := TRUE;
  73. IF TXCount > 0 THEN TX; END;
  74. | 2 : (* RXReady *)
  75. RX;
  76. | 3 : (* LineStatus *)
  77. s := b(SYSTEM.In( IOBase+LineStatus ));
  78. (*
  79. IF 1 IN s THEN IO.WrStr('OR-Error'); END;
  80. IF 2 IN s THEN IO.WrStr('PE-Error'); END;
  81. IF 4 IN s THEN IO.WrStr('Break');
  82. ELSIF 3 IN s THEN IO.WrStr('FE-Error'); END;
  83. SYSTEM.Out(20H,20H);
  84. HALT;*)
  85. ELSE (*IO.WrStr('Unknown Int'); HALT; *)
  86. END;
  87. END;
  88. SYSTEM.Out(20H,20H);
  89. END Int;
  90. (*$C F0,J-*)
  91. PROCEDURE RxCount():CARDINAL;
  92. BEGIN
  93. RETURN RXCount;
  94. END RxCount;
  95. PROCEDURE TxCount():CARDINAL;
  96. BEGIN
  97. RETURN TXCount;
  98. END TxCount;
  99. PROCEDURE TxFree ():CARDINAL;
  100. BEGIN
  101. RETURN TRMax-TXCount;
  102. END TxFree;
  103. VAR lc : SHORTCARD;
  104. PROCEDURE Break( Time : CARDINAL );
  105. BEGIN
  106. SYSTEM.Out( IOBase+LineCont,SHORTCARD( b(SYSTEM.In(IOBase+LineCont))+b{6})) ;
  107. Lib.Delay( Time );
  108. SYSTEM.Out( IOBase+LineCont,SHORTCARD( b(SYSTEM.In(IOBase+LineCont))-b{6}));
  109. END Break;
  110. PROCEDURE Init( Baud : CARDINAL;
  111. WordLength : wl;
  112. Parity : pt;
  113. OneStopBit : BOOLEAN;
  114. HandShake : BOOLEAN);
  115. VAR d : CARDINAL; i : SHORTCARD;
  116. BEGIN
  117. SYSTEM.DI;
  118. TXI := 0;
  119. TXO := 0;
  120. RXI := 0;
  121. RXO := 0;
  122. RXCount := 0;
  123. TXCount := 0;
  124. SYSTEM.EI;
  125. CTSH := HandShake;
  126. lc := (WordLength-5) MOD 4;
  127. IF NOT OneStopBit THEN lc := lc+4; END;
  128. CASE Parity OF
  129. | None :;
  130. | Even : lc := lc+18H;
  131. | Odd : lc := lc+ 8H;
  132. | Mark : lc := lc+38H;
  133. | Space : lc := lc+28H;
  134. END;
  135. SYSTEM.Out( IOBase+LineCont,80H );
  136. d := CARDINAL( 115200 DIV LONGCARD( Baud ) );
  137. SYSTEM.Out( DivisorLsb, SHORTCARD(d));
  138. SYSTEM.Out( IOBase+DivisorMsb, SHORTCARD(d DIV 100H));
  139. SYSTEM.Out( IOBase+LineCont,lc );
  140. TXReady := TRUE;
  141. SYSTEM.Out( IOBase+ModemCont,SHORTCARD(b{0,1,3}));
  142. CTS := 4 IN b(SYSTEM.In( IOBase+ModemStatus ));
  143. LOOP
  144. i := SYSTEM.In( IOBase+IntId );
  145. IF i=1 THEN EXIT; END;
  146. CASE i DIV 2 OF
  147. | 0 : (* Modem status *)
  148. i := SYSTEM.In( IOBase+ModemStatus );
  149. | 1 : (* TXEmpty *)
  150. | 2 : (* RXReady *)
  151. | 3 : (* LineStatus *)
  152. i := SYSTEM.In( IOBase+LineStatus );
  153. END;
  154. END;
  155. END Init;
  156. (*$V-*)
  157. PROCEDURE Receive(VAR Buf : ARRAY OF BYTE; Len : CARDINAL );
  158. VAR i : CARDINAL;
  159. BEGIN
  160. FOR i := 0 TO Len-1 DO
  161. WHILE RXCount = 0 DO END;
  162. Buf[i] := IBuf[RXO];
  163. DEC( RXCount );
  164. RXO := (RXO+1) MOD BufferSize;
  165. END;
  166. IF NOT RTS AND (RXCount < TRMax-16) THEN
  167. SYSTEM.Out( IOBase+ModemCont, SHORTCARD( b{0,1,3} ) );
  168. RTS := TRUE;
  169. END;
  170. END Receive;
  171. PROCEDURE Send( Buf : ARRAY OF BYTE; Len : CARDINAL );
  172. VAR i : CARDINAL;
  173. BEGIN
  174. FOR i := 0 TO Len-1 DO
  175. OBuf[TXI] := Buf[i];
  176. INC(TXCount);
  177. TXI := (TXI+1) MOD BufferSize;
  178. SYSTEM.DI();
  179. IF TXReady THEN TX; END;
  180. SYSTEM.EI();
  181. END;
  182. END Send;
  183. TYPE dp=POINTER TO PROC;
  184. PROCEDURE CloseDown;
  185. BEGIN
  186. [0:4*(8+ComINr) dp]^ := OldC;
  187. SYSTEM.Out( IOBase+IntEnable,00H );
  188. SYSTEM.Out( IOBase+ModemCont,SHORTCARD(b{}));
  189. Term;
  190. END CloseDown;
  191. PROCEDURE Install( Port : CARDINAL );
  192. BEGIN
  193. IF Port= 1 THEN
  194. Install2( Com1,Com1INr );
  195. ELSE
  196. Install2( Com2,Com2INr );
  197. END;
  198. END Install;
  199. PROCEDURE Install2( Port,Intr : CARDINAL);
  200. TYPE bs = SET OF SHORTCARD[0..7];
  201. BEGIN
  202. IOBase := Port;
  203. ComINr := Intr;
  204. SYSTEM.Out( IOBase+IntEnable,00H );
  205. SYSTEM.Out( IOBase+LineStatus,0 );
  206. TXI := 0;
  207. TXO := 0;
  208. RXI := 0;
  209. RXO := 0;
  210. RXCount := 0;
  211. TXCount := 0;
  212. OldC := [0:4*(8+ComINr) dp]^;
  213. [0:4*(8+ComINr) dp]^ := PROC(ADR(Int));
  214. Lib.Terminate( CloseDown,Term );
  215. SYSTEM.NewPriority( CARDINAL(BITSET( SYSTEM.CurrentPriority() )-{ComINr} ) );
  216. TXReady := TRUE;
  217. RTS := TRUE;
  218. SYSTEM.Out( IOBase+IntEnable,0BH );
  219. SYSTEM.Out( IOBase+ModemCont,SHORTCARD(b{0,1,3}));
  220. END Install2;
  221. PROCEDURE BreakTest():BOOLEAN;
  222. BEGIN
  223. RETURN 4 IN b(SYSTEM.In( IOBase+LineStatus ));
  224. END BreakTest;
  225. BEGIN
  226. lc := SYSTEM.In( IOBase+LineCont );
  227. END rs.
  228.