RS.LST 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. Listing:
  2. 1 (*========================================================
  3. 2 == JPI-TopSpeed Modula-2 V2 ==
  4. 3 == demo program: ==
  5. 4 == ==
  6. 5 == Example RS232 module ==
  7. 6 == ==
  8. 7 ========================================================*)
  9. 8
  10. 9 (*# call(o_a_copy=>off) *)
  11. 10 (*# check(stack=>off,index=>off,range=>off,overflow=>off,nil_ptr=>off) *)
  12. 11
  13. 12 IMPLEMENTATION MODULE rs;
  14. 13 (*==*)
  15. 14 IMPORT SYSTEM, Lib;
  16. 15
  17. 16 CONST Com1 = 3F8H;
  18. 17 Com1INr = 4;
  19. 18 Com2 = 2F8H;
  20. 19 Com2INr = 3;
  21. 20
  22. 21 IntEnable = 1;
  23. 22 DivisorMsb = 1;
  24. 23 IntId = 2;
  25. 24 LineCont = 3;
  26. 25 ModemCont = 4;
  27. 26 LineStatus = 5;
  28. 27 ModemStatus = 6;
  29. 28 Debug = TRUE;
  30. 29
  31. 30 TYPE b = SET OF SHORTCARD[0..7];
  32. ***** ^ not supported yet
  33. 31 VAR IOBase,ComINr : CARDINAL;
  34. 32
  35. 33 CONST
  36. 34 TXBuffer ::= IOBase;
  37. 35 RXBuffer ::= IOBase;
  38. 36 DivisorLsb ::= IOBase;
  39. 37
  40. 38
  41. 39 BufferSize = 256;
  42. 40 TRMax = BufferSize-16;
  43. 41 Noise = FALSE;
  44. 42
  45. 43 VAR
  46. 44 OldC : FarADDRESS;
  47. 45 Term : PROC;
  48. 46 (*# save, data(volatile=>on) *)
  49. 47 TXReady,CTS,CTSH : BOOLEAN;
  50. 48 RTS : BOOLEAN;
  51. 49 TXCount,TXI,TXO : CARDINAL;
  52. 50 RXCount,RXI,RXO : CARDINAL;
  53. 51 (*# restore *)
  54. 52 IBuf,OBuf : ARRAY[0..BufferSize-1] OF SHORTCARD;
  55. 53
  56. 54 PROCEDURE WrStr(string: ARRAY OF CHAR);
  57. 55 VAR R : SYSTEM.Registers;
  58. 56 i : CARDINAL;
  59. 57 BEGIN
  60. 58 IF Debug THEN
  61. 59 i := 0;
  62. 60 WHILE (i<SIZE(string))AND(string[i]<>CHR(0)) DO
  63. 61 R.AL := SHORTCARD(string[i]);
  64. 62 R.AH := 14;
  65. 63 R.BL := 0;
  66. 64 Lib.Intr( R ,10H );
  67. 65 INC(i);
  68. 66 END;
  69. 67 END;
  70. 68 END WrStr;
  71. 69
  72. 70 PROCEDURE WrLn;
  73. 71 TYPE
  74. 72 a3 = ARRAY [0..1] OF CHAR;
  75. 73 CONST
  76. 74 crlf = a3(CHR(13),CHR(10));
  77. 75 BEGIN
  78. 76 WrStr( crlf );
  79. 77 END WrLn;
  80. 78
  81. 79
  82. 80 PROCEDURE TX;
  83. 81 BEGIN
  84. 82 IF CTS OR NOT CTSH THEN
  85. 83 TXReady := FALSE;
  86. 84 DEC(TXCount);
  87. 85 SYSTEM.Out( TXBuffer,OBuf[TXO] );
  88. 86 TXO := (TXO+1) MOD BufferSize;
  89. 87 END;
  90. 88 END TX;
  91. 89
  92. 90 PROCEDURE RX;
  93. 91 BEGIN
  94. 92 IF RXCount >= TRMax THEN
  95. 93 SYSTEM.Out( IOBase+ModemCont, SHORTCARD( b{0,3} ) );
  96. 94 RTS := FALSE;
  97. 95 END;
  98. 96 IBuf[RXI] := SYSTEM.In( RXBuffer );
  99. 97 IF Noise AND (Lib.RANDOM(500)=0) THEN
  100. 98 IBuf[RXI] := SHORTCARD(Lib.RANDOM(256));
  101. 99 END;
  102. 100 RXI := (RXI+1) MOD BufferSize;
  103. 101 INC(RXCount);
  104. 102 END RX;
  105. 103
  106. 104 VAR GotBreak : BOOLEAN;
  107. 105
  108. 106 (* pragmas for interrupt handler *)
  109. 107 (*# save,
  110. 108 call(interrupt => on,
  111. 109 reg_param => (),
  112. 110 same_ds => off
  113. 111 )
  114. 112 *)
  115. 113 PROCEDURE Int;
  116. 114 VAR i : SHORTCARD;
  117. 115 s : b;
  118. 116 BEGIN
  119. 117 LOOP
  120. 118 i := SYSTEM.In( IOBase+IntId );
  121. 119 IF i=1 THEN EXIT; END;
  122. 120 CASE i DIV 2 OF
  123. 121 | 0 : (* Modem status *)
  124. 122 s := b(SYSTEM.In( IOBase+ModemStatus ));
  125. 123 CTS :=4 IN s;
  126. 124 IF CTS AND (TXCount >0) AND TXReady THEN TX END;
  127. 125
  128. 126 | 1 : (* TXEmpty *)
  129. 127 TXReady := TRUE;
  130. 128 IF TXCount > 0 THEN TX; END;
  131. 129
  132. 130 | 2 : (* RXReady *)
  133. 131
  134. 132 RX;
  135. 133
  136. 134 | 3 : (* LineStatus *)
  137. 135
  138. 136 s := b(SYSTEM.In( IOBase+LineStatus ));
  139. 137
  140. 138 IF 1 IN s THEN WrStr('OR-Error'); WrLn; END;
  141. 139 IF 2 IN s THEN WrStr('PE-Error'); WrLn; END;
  142. 140 IF 4 IN s THEN WrStr('Break'); WrLn;
  143. 141 ELSIF 3 IN s THEN WrStr('FE-Error'); WrLn;
  144. 142 END;
  145. 143 ELSE
  146. 144 WrStr('Unknown Int'); WrLn;
  147. 145 END;
  148. 146 END;
  149. 147 SYSTEM.Out(20H,20H);
  150. 148 END Int;
  151. 149
  152. 150 (*# restore *)
  153. 151
  154. 152 PROCEDURE RxCount():CARDINAL;
  155. 153 BEGIN
  156. 154 RETURN RXCount;
  157. 155 END RxCount;
  158. 156
  159. 157 PROCEDURE TxCount():CARDINAL;
  160. 158 BEGIN
  161. 159 RETURN TXCount;
  162. 160 END TxCount;
  163. 161
  164. 162 PROCEDURE TxFree ():CARDINAL;
  165. 163 BEGIN
  166. 164 RETURN TRMax-TXCount;
  167. 165 END TxFree;
  168. 166
  169. 167 VAR lc : SHORTCARD;
  170. 168
  171. 169 PROCEDURE Break( Time : CARDINAL );
  172. 170 BEGIN
  173. 171 SYSTEM.Out( IOBase+LineCont,SHORTCARD( b(SYSTEM.In(IOBase+LineCont))+b{6})) ;
  174. 172 Lib.Delay( Time );
  175. 173 SYSTEM.Out( IOBase+LineCont,SHORTCARD( b(SYSTEM.In(IOBase+LineCont))-b{6}));
  176. 174 END Break;
  177. 175
  178. 176 PROCEDURE Init( Baud : CARDINAL;
  179. 177 WordLength : wl;
  180. 178 Parity : pt;
  181. 179 OneStopBit : BOOLEAN;
  182. 180 HandShake : BOOLEAN);
  183. 181
  184. 182 VAR d : CARDINAL; i : SHORTCARD;
  185. 183 BEGIN
  186. 184 SYSTEM.DI;
  187. 185 TXI := 0;
  188. 186 TXO := 0;
  189. 187 RXI := 0;
  190. 188 RXO := 0;
  191. 189 RXCount := 0;
  192. 190 TXCount := 0;
  193. 191 SYSTEM.EI;
  194. 192 CTSH := HandShake;
  195. 193 lc := (WordLength-5) MOD 4;
  196. 194 IF NOT OneStopBit THEN lc := lc+4; END;
  197. 195 CASE Parity OF
  198. 196 | None :;
  199. 197 | Even : lc := lc+18H;
  200. 198 | Odd : lc := lc+ 8H;
  201. 199 | Mark : lc := lc+38H;
  202. 200 | Space : lc := lc+28H;
  203. 201 END;
  204. 202 SYSTEM.Out( IOBase+LineCont,80H );
  205. 203 d := CARDINAL( 115200 DIV LONGCARD( Baud ) );
  206. 204 SYSTEM.Out( DivisorLsb, SHORTCARD(d));
  207. 205 SYSTEM.Out( IOBase+DivisorMsb, SHORTCARD(d DIV 100H));
  208. 206 SYSTEM.Out( IOBase+LineCont,lc );
  209. 207 TXReady := TRUE;
  210. 208 SYSTEM.Out( IOBase+ModemCont,SHORTCARD(b{0,1,3}));
  211. 209 CTS := 4 IN b(SYSTEM.In( IOBase+ModemStatus ));
  212. 210 LOOP
  213. 211 i := SYSTEM.In( IOBase+IntId );
  214. 212 IF i=1 THEN EXIT; END;
  215. 213 CASE i DIV 2 OF
  216. 214 | 0 : (* Modem status *)
  217. 215 i := SYSTEM.In( IOBase+ModemStatus );
  218. 216 | 1 : (* TXEmpty *)
  219. 217 | 2 : (* RXReady *)
  220. 218 | 3 : (* LineStatus *)
  221. 219 i := SYSTEM.In( IOBase+LineStatus );
  222. 220 END;
  223. 221 END;
  224. 222 END Init;
  225. 223
  226. 224
  227. 225 PROCEDURE Receive(VAR Buf : ARRAY OF BYTE; Len : CARDINAL );
  228. 226 VAR i : CARDINAL;
  229. 227 BEGIN
  230. 228 FOR i := 0 TO Len-1 DO
  231. 229 WHILE RXCount = 0 DO END;
  232. 230 Buf[i] := IBuf[RXO];
  233. 231 DEC( RXCount );
  234. 232 RXO := (RXO+1) MOD BufferSize;
  235. 233 END;
  236. 234 IF NOT RTS AND (RXCount < TRMax-16) THEN
  237. 235 SYSTEM.Out( IOBase+ModemCont, SHORTCARD( b{0,1,3} ) );
  238. 236 RTS := TRUE;
  239. 237 END;
  240. 238 END Receive;
  241. 239
  242. 240 (*# call(o_a_copy=>off) *)
  243. 241 PROCEDURE Send( Buf : ARRAY OF BYTE; Len : CARDINAL );
  244. 242 VAR i : CARDINAL;
  245. 243 BEGIN
  246. 244 FOR i := 0 TO Len-1 DO
  247. 245 OBuf[TXI] := Buf[i];
  248. 246 INC(TXCount);
  249. 247 WHILE TXCount=BufferSize DO END;
  250. 248 TXI := (TXI+1) MOD BufferSize;
  251. 249 IF TXReady THEN TX; END;
  252. 250 END;
  253. 251 END Send;
  254. 252
  255. 253 VAR
  256. 254 IntTab[0:0] : ARRAY[0..255] OF FarADDRESS;
  257. 255
  258. 256
  259. 257 PROCEDURE CloseDown;
  260. 258 BEGIN
  261. 259 SYSTEM.Out( IOBase+IntEnable,00H );
  262. 260 SYSTEM.Out( IOBase+ModemCont,SHORTCARD(b{}));
  263. 261 Lib.Delay(100);
  264. 262 SYSTEM.DI;
  265. 263 IntTab[8+ComINr] := OldC;
  266. 264 SYSTEM.EI;
  267. 265 Term;
  268. 266 END CloseDown;
  269. 267
  270. 268 PROCEDURE Install( Port : CARDINAL );
  271. 269 BEGIN
  272. 270 IF Port= 1 THEN
  273. 271 Install2( Com1,Com1INr );
  274. 272 ELSE
  275. 273 Install2( Com2,Com2INr );
  276. 274 END;
  277. 275 END Install;
  278. 276
  279. 277 PROCEDURE Install2( Port,Intr : CARDINAL);
  280. 278 TYPE bs = SET OF SHORTCARD[0..7];
  281. 279 VAR s : SHORTCARD; i : CARDINAL;
  282. 280 fa : FarADDRESS;
  283. 281 BEGIN
  284. 282 SYSTEM.DI;
  285. 283 IOBase := Port;
  286. 284 ComINr := Intr;
  287. 285 SYSTEM.Out( IOBase+IntEnable,00H );
  288. 286 SYSTEM.Out( IOBase+LineStatus,0 );
  289. 287 TXI := 0;
  290. 288 TXO := 0;
  291. 289 RXI := 0;
  292. 290 RXO := 0;
  293. 291 RXCount := 0;
  294. 292 TXCount := 0;
  295. 293 OldC := IntTab[8+ComINr];
  296. 294 IntTab[8+ComINr] := FarADR(Int);
  297. 295 Lib.Terminate( CloseDown,Term );
  298. 296 SYSTEM.NewPriority( CARDINAL(BITSET( SYSTEM.CurrentPriority() )-{ComINr} ) );
  299. 297 TXReady := TRUE;
  300. 298 RTS := TRUE;
  301. 299 SYSTEM.Out( IOBase+IntEnable,0BH );
  302. 300 SYSTEM.Out( IOBase+ModemCont,SHORTCARD(b{0,1,3}));
  303. 301 SYSTEM.EI;
  304. 302 END Install2;
  305. 303
  306. 304
  307. 305 PROCEDURE BreakTest():BOOLEAN;
  308. 306 BEGIN
  309. 307 RETURN 4 IN b(SYSTEM.In( IOBase+LineStatus ));
  310. 308 END BreakTest;
  311. 309
  312. 310 BEGIN
  313. 311 lc := SYSTEM.In( IOBase+LineCont );
  314. 312 END rs.
  315. 1 error