io.mod 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. (* Copyright (C) 1987 Jensen & Partners International *)
  2. (*$S-,R-,I-*)
  3. IMPLEMENTATION MODULE IO;
  4. FROM Str IMPORT Length,Compare,IntToStr,CardToStr,RealToStr,StrToInt,
  5. StrToCard,StrToReal;
  6. FROM SYSTEM IMPORT Registers,Seg,Ofs;
  7. IMPORT Lib,Str;
  8. CONST
  9. TrueStr = 'TRUE';
  10. VAR
  11. LWW : BOOLEAN;
  12. Buffer : ARRAY[0..MaxRdLength-1] OF CHAR;
  13. s,e : CARDINAL;
  14. (*$V-*)
  15. PROCEDURE KeyPressed (): BOOLEAN;
  16. VAR R : Registers;
  17. BEGIN
  18. WITH R DO
  19. AH := 0BH;
  20. Lib.Dos(R);
  21. RETURN AL=0FFH;
  22. END;
  23. END KeyPressed;
  24. PROCEDURE TerminalRdStr(VAR string: ARRAY OF CHAR);
  25. VAR
  26. R : Registers;
  27. H : CARDINAL;
  28. I : CARDINAL;
  29. InputBuffer : RECORD
  30. LenBuf : CHAR;
  31. Len : CHAR;
  32. Buf : ARRAY[0..81] OF CHAR;
  33. END;
  34. BEGIN
  35. IF Prompt AND NOT LWW THEN WrStr('?'); END;
  36. LWW := FALSE;
  37. H := HIGH(string);
  38. IF H > 80 THEN
  39. InputBuffer.LenBuf := CHR(82);
  40. ELSE
  41. InputBuffer.LenBuf := CHR(H+2);
  42. END;
  43. InputBuffer.Len := CHR(0);
  44. WITH R DO
  45. DS := Seg(InputBuffer);
  46. DX := Ofs(InputBuffer);
  47. AH := 0AH;
  48. Lib.Dos(R);
  49. END;
  50. I := ORD(InputBuffer.Len);
  51. IF I <= H THEN
  52. string[I] := CHR(0);
  53. END;
  54. WHILE (I>0) DO
  55. DEC(I);
  56. string[I] := InputBuffer.Buf[I];
  57. END;
  58. WrLn;
  59. END TerminalRdStr;
  60. PROCEDURE WrStr(s: ARRAY OF CHAR);
  61. BEGIN
  62. WrStrRedirect(s);
  63. END WrStr;
  64. PROCEDURE RdStr ( VAR s : ARRAY OF CHAR );
  65. BEGIN
  66. RdStrRedirect(s);
  67. END RdStr;
  68. PROCEDURE RdBuff;
  69. VAR
  70. p,h : CARDINAL;
  71. BEGIN
  72. RdStrRedirect(Buffer);
  73. p := Length(Buffer);
  74. h := SIZE(Buffer)-1;
  75. IF p>h-1 THEN p := h-1; END;
  76. Buffer[p] := CHR(13); INC(p);
  77. Buffer[p] := CHR(10); INC(p);
  78. IF p<=h THEN Buffer[p] := CHR(0) END;
  79. e := p; s := 0;
  80. END RdBuff;
  81. PROCEDURE TerminalWrStr(string: ARRAY OF CHAR);
  82. VAR R : Registers;
  83. BEGIN
  84. LWW := TRUE;
  85. WITH R DO
  86. BX := 1;
  87. AH := 40H;
  88. DS := Seg( string );
  89. DX := Ofs( string );
  90. CX := Str.Length(string);
  91. Lib.Dos( R );
  92. END;
  93. END TerminalWrStr;
  94. PROCEDURE RdKey() : CHAR;
  95. VAR R : Registers;
  96. BEGIN
  97. WITH R DO
  98. AH := 8;
  99. Lib.Dos(R);
  100. RETURN CHR(AL);
  101. END;
  102. END RdKey;
  103. (*$V+*)
  104. PROCEDURE WrStrAdj( S : ARRAY OF CHAR; Length : INTEGER );
  105. VAR
  106. L : CARDINAL;
  107. a : INTEGER;
  108. BEGIN
  109. OK := TRUE;
  110. IF RdLnOnWr THEN RdLn; END;
  111. L := Str.Length( S );
  112. a := ABS( Length ) - INTEGER( L );
  113. IF (a < 0) AND ChopOff THEN
  114. L := CARDINAL(ABS(Length));
  115. IF L<=HIGH(S) THEN S[L] := CHR(0); END;
  116. WHILE (L>0) DO DEC(L); S[L] := '?'; END;
  117. OK := FALSE;
  118. a := 0;
  119. END;
  120. IF (Length > 0) AND (a > 0) THEN WrCharRep( ' ',a ); END;
  121. WrStr( S );
  122. IF (Length < 0) AND (a > 0) THEN WrCharRep( ' ',a ); END;
  123. END WrStrAdj;
  124. (*$V+*)
  125. PROCEDURE WrChar( V: CHAR );
  126. BEGIN
  127. IF RdLnOnWr THEN RdLn; END;
  128. WrStr( V );
  129. END WrChar;
  130. PROCEDURE WrCharRep(V: CHAR; count: CARDINAL);
  131. VAR
  132. s : ARRAY[0..80] OF CHAR;
  133. i,j : CARDINAL;
  134. BEGIN
  135. IF RdLnOnWr THEN RdLn; END;
  136. WHILE count>0 DO
  137. i := SIZE(s)-2;
  138. IF i>count THEN i := count END;
  139. DEC(count,i);
  140. j := 0;
  141. WHILE (j<i) DO s[j] := V; INC(j) END;
  142. s[j] := CHR(0);
  143. WrStr(s);
  144. END;
  145. END WrCharRep;
  146. PROCEDURE WrBool(V: BOOLEAN; Length: INTEGER);
  147. BEGIN
  148. IF V THEN
  149. WrStrAdj(TrueStr,Length);
  150. ELSE
  151. WrStrAdj('FALSE',Length);
  152. END;
  153. END WrBool;
  154. PROCEDURE WrShtInt(V: SHORTINT; Length: INTEGER);
  155. VAR s : ARRAY[0..80] OF CHAR;
  156. BEGIN
  157. IntToStr( VAL( LONGINT,V ),s,10,OK );
  158. IF OK THEN WrStrAdj( s,Length ); END;
  159. END WrShtInt;
  160. PROCEDURE WrInt(V: INTEGER; Length: INTEGER);
  161. VAR s : ARRAY[0..80] OF CHAR;
  162. BEGIN
  163. IntToStr( VAL( LONGINT,V ),s,10,OK );
  164. IF OK THEN WrStrAdj( s,Length ); END;
  165. END WrInt;
  166. PROCEDURE WrLngInt(V: LONGINT; Length: INTEGER);
  167. VAR s : ARRAY[0..80] OF CHAR;
  168. BEGIN
  169. IntToStr( V,s,10,OK );
  170. IF OK THEN WrStrAdj( s,Length ); END;
  171. END WrLngInt;
  172. PROCEDURE WrShtCard(V: SHORTCARD; Length: INTEGER);
  173. VAR s : ARRAY[0..80] OF CHAR;
  174. BEGIN
  175. CardToStr( VAL( LONGCARD,V ),s,10,OK );
  176. IF OK THEN WrStrAdj( s,Length ); END;
  177. END WrShtCard;
  178. PROCEDURE WrCard(V: CARDINAL; Length: INTEGER);
  179. VAR s : ARRAY[0..80] OF CHAR;
  180. BEGIN
  181. CardToStr( VAL( LONGCARD,V ),s,10,OK );
  182. IF OK THEN WrStrAdj( s,Length ); END;
  183. END WrCard;
  184. PROCEDURE WrLngCard(V: LONGCARD; Length: INTEGER);
  185. VAR s : ARRAY[0..80] OF CHAR;
  186. BEGIN
  187. CardToStr( V,s,10,OK );
  188. IF OK THEN WrStrAdj( s,Length ); END;
  189. END WrLngCard;
  190. PROCEDURE WrShtHex(V: SHORTCARD; Length: INTEGER);
  191. VAR s : ARRAY[0..80] OF CHAR;
  192. BEGIN
  193. CardToStr( VAL( LONGCARD,V ),s,16,OK );
  194. IF OK THEN WrStrAdj( s,Length ); END;
  195. END WrShtHex;
  196. PROCEDURE WrHex(V: CARDINAL; Length: INTEGER);
  197. VAR s : ARRAY[0..80] OF CHAR;
  198. BEGIN
  199. CardToStr( VAL( LONGCARD,V ),s,16,OK );
  200. IF OK THEN WrStrAdj( s,Length ); END;
  201. END WrHex;
  202. PROCEDURE WrLngHex(V: LONGCARD; Length: INTEGER);
  203. VAR s : ARRAY[0..80] OF CHAR;
  204. BEGIN
  205. CardToStr( V,s,16,OK );
  206. IF OK THEN WrStrAdj( s,Length ); END;
  207. END WrLngHex;
  208. PROCEDURE WrReal(V: REAL; Precision: CARDINAL; Length: INTEGER);
  209. VAR s : ARRAY[0..80] OF CHAR;
  210. BEGIN
  211. RealToStr( VAL( LONGREAL,V ),Precision,Eng,s,OK );
  212. IF OK THEN WrStrAdj( s,Length ); END;
  213. END WrReal;
  214. PROCEDURE WrLngReal(V : LONGREAL; Precision: CARDINAL; Length: INTEGER);
  215. VAR s : ARRAY[0..80] OF CHAR;
  216. BEGIN
  217. RealToStr( V,Precision,Eng,s,OK );
  218. IF OK THEN WrStrAdj( s,Length ); END;
  219. END WrLngReal;
  220. PROCEDURE WrLn;
  221. TYPE
  222. a3 = ARRAY [0..1] OF CHAR;
  223. CONST
  224. crlf = a3(CHR(13),CHR(10));
  225. BEGIN
  226. IF RdLnOnWr THEN RdLn; END;
  227. WrStr( crlf );
  228. LWW := FALSE;
  229. END WrLn;
  230. PROCEDURE RdBool() : BOOLEAN;
  231. VAR s : ARRAY[0..80] OF CHAR;
  232. BEGIN
  233. RdItem( s );
  234. RETURN Compare( s,TrueStr )=0;
  235. END RdBool;
  236. PROCEDURE RdShtInt() : SHORTINT;
  237. VAR
  238. s : ARRAY[0..80] OF CHAR;
  239. i : LONGINT;
  240. BEGIN
  241. RdItem( s );
  242. i := StrToInt( s,10,OK );
  243. OK := OK AND (i >= -80H) AND (i <= 7FH);
  244. RETURN SHORTINT( i );
  245. END RdShtInt;
  246. PROCEDURE RdInt() : INTEGER;
  247. VAR
  248. s : ARRAY[0..80] OF CHAR;
  249. i : LONGINT;
  250. BEGIN
  251. RdItem( s );
  252. i := StrToInt( s,10,OK );
  253. OK := OK AND (i >= -8000H) AND (i <= 7FFFH);
  254. RETURN INTEGER(i);
  255. END RdInt;
  256. PROCEDURE RdLngInt() : LONGINT;
  257. VAR s : ARRAY[0..80] OF CHAR;
  258. BEGIN
  259. RdItem( s );
  260. RETURN StrToInt( s,10,OK );
  261. END RdLngInt;
  262. PROCEDURE RdShtCard() : SHORTCARD;
  263. VAR
  264. s : ARRAY[0..80] OF CHAR;
  265. i : LONGCARD;
  266. BEGIN
  267. RdItem( s );
  268. i := StrToCard( s,10,OK );
  269. OK := OK AND (i < 0FFH);
  270. RETURN SHORTINT( i );
  271. END RdShtCard;
  272. PROCEDURE RdShtHex() : SHORTCARD;
  273. VAR
  274. s : ARRAY[0..80] OF CHAR;
  275. i : LONGCARD;
  276. BEGIN
  277. RdItem( s );
  278. i := StrToCard( s,16,OK );
  279. OK := OK AND (i < 0FFH);
  280. RETURN SHORTINT( i );
  281. END RdShtHex;
  282. PROCEDURE RdCard() : CARDINAL;
  283. VAR
  284. s : ARRAY[0..80] OF CHAR;
  285. i : LONGCARD;
  286. BEGIN
  287. RdItem( s );
  288. i := StrToCard( s,10,OK );
  289. OK := OK AND (i < 10000H);
  290. RETURN INTEGER( i );
  291. END RdCard;
  292. PROCEDURE RdHex() : CARDINAL;
  293. VAR
  294. s : ARRAY[0..80] OF CHAR;
  295. i : LONGCARD;
  296. BEGIN
  297. RdItem( s );
  298. i := StrToCard( s,16,OK );
  299. OK := OK AND (i < 10000H);
  300. RETURN INTEGER( i );
  301. END RdHex;
  302. PROCEDURE RdLngCard() : LONGCARD;
  303. VAR s : ARRAY[0..80] OF CHAR;
  304. BEGIN
  305. RdItem( s );
  306. RETURN StrToCard( s,10,OK );
  307. END RdLngCard;
  308. PROCEDURE RdLngHex() : LONGCARD;
  309. VAR s : ARRAY[0..80] OF CHAR;
  310. BEGIN
  311. RdItem( s );
  312. RETURN StrToCard( s,16,OK );
  313. END RdLngHex;
  314. PROCEDURE RdReal() : REAL;
  315. VAR
  316. s : ARRAY[0..80] OF CHAR;
  317. r,a : LONGREAL;
  318. BEGIN
  319. RdItem( s );
  320. r := StrToReal( s,OK );
  321. a := ABS( r );
  322. OK := OK AND (a >= 1.2E-38 ) AND (a <= 3.4E38 );
  323. RETURN VAL( REAL,r );
  324. END RdReal;
  325. PROCEDURE RdLngReal() : LONGREAL;
  326. VAR s : ARRAY[0..80] OF CHAR;
  327. BEGIN
  328. RdItem( s );
  329. RETURN StrToReal( s,OK );
  330. END RdLngReal;
  331. PROCEDURE RdLn;
  332. BEGIN
  333. s:=e;
  334. END RdLn;
  335. PROCEDURE EndOfRd(Skip: BOOLEAN) : BOOLEAN;
  336. BEGIN
  337. IF Skip THEN
  338. WHILE (s < e) AND (Buffer[s] IN Separators) DO INC(s) END;
  339. END;
  340. RETURN s = e;
  341. END EndOfRd;
  342. PROCEDURE RdItem(VAR V: ARRAY OF CHAR);
  343. VAR L,i : CARDINAL;
  344. BEGIN
  345. OK := TRUE;
  346. L := HIGH(V);
  347. REPEAT
  348. IF s=e THEN RdBuff(); END;
  349. WHILE (s<e) AND ( Buffer[s] IN Separators ) DO INC(s); END;
  350. i := 0;
  351. WHILE (s<e) AND (i<=L) AND NOT ( Buffer[s] IN Separators ) DO
  352. V[i] := Buffer[s];
  353. INC(s);
  354. INC(i);
  355. END;
  356. IF i <= L THEN V[i] := CHR(0); END;
  357. UNTIL V[0] # CHR(0);
  358. END RdItem;
  359. PROCEDURE RdChar() : CHAR;
  360. VAR
  361. c : CHAR;
  362. t : BOOLEAN;
  363. BEGIN
  364. IF s >= e THEN RdBuff; END;
  365. INC (s);
  366. RETURN Buffer[s-1];
  367. END RdChar;
  368. PROCEDURE RedirectInput(FileName: ARRAY OF CHAR);
  369. VAR c : CARDINAL;
  370. r : Registers;
  371. BEGIN
  372. WITH r DO
  373. BX := 0;
  374. AH := 3EH; (* close file *)
  375. Lib.Dos(r);
  376. DS := Seg(FileName);
  377. DX := Ofs(FileName);
  378. CX := 0;
  379. AX := 3D00H; (* open for read *)
  380. Lib.Dos(r);
  381. END;
  382. END RedirectInput;
  383. PROCEDURE RedirectOutput(FileName: ARRAY OF CHAR);
  384. VAR c : CARDINAL;
  385. r : Registers;
  386. BEGIN
  387. WITH r DO
  388. BX := 1;
  389. AH := 3EH; (* close file *)
  390. Lib.Dos(r);
  391. DS := Seg(FileName);
  392. DX := Ofs(FileName);
  393. CX := 0;
  394. AX := 3C00H; (* Create *)
  395. Lib.Dos(r);
  396. END ;
  397. END RedirectOutput;
  398. BEGIN
  399. Prompt := TRUE;
  400. RdLnOnWr := FALSE;
  401. WrStrRedirect := TerminalWrStr;
  402. RdStrRedirect := TerminalRdStr;
  403. s := e;
  404. OK := TRUE;
  405. ChopOff := FALSE;
  406. Separators := CHARSET{CHR(9),CHR(10),CHR(13),CHR(26),' '};
  407. Eng := FALSE;
  408. LWW := FALSE;
  409. END IO.
  410.