crt.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by Florian Klaempfl,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit crt;
  13. interface
  14. {$I os.inc}
  15. {$I386_ATT}
  16. const
  17. { CRT modes }
  18. BW40 = 0; { 40x25 B/W on Color Adapter }
  19. CO40 = 1; { 40x25 Color on Color Adapter }
  20. BW80 = 2; { 80x25 B/W on Color Adapter }
  21. CO80 = 3; { 80x25 Color on Color Adapter }
  22. Mono = 7; { 80x25 on Monochrome Adapter }
  23. Font8x8 = 256; { Add-in for ROM font }
  24. { Mode constants for 3.0 compatibility }
  25. C40 = CO40;
  26. C80 = CO80;
  27. { Foreground and background color constants }
  28. Black = 0;
  29. Blue = 1;
  30. Green = 2;
  31. Cyan = 3;
  32. Red = 4;
  33. Magenta = 5;
  34. Brown = 6;
  35. LightGray = 7;
  36. { Foreground color constants }
  37. DarkGray = 8;
  38. LightBlue = 9;
  39. LightGreen = 10;
  40. LightCyan = 11;
  41. LightRed = 12;
  42. LightMagenta = 13;
  43. Yellow = 14;
  44. White = 15;
  45. { Add-in for blinking }
  46. Blink = 128;
  47. var
  48. { Interface variables }
  49. CheckBreak: Boolean; { Enable Ctrl-Break }
  50. CheckEOF: Boolean; { Enable Ctrl-Z }
  51. DirectVideo: Boolean; { Enable direct video addressing }
  52. CheckSnow: Boolean; { Enable snow filtering }
  53. LastMode: Word; { Current text mode }
  54. TextAttr: Byte; { Current text attribute }
  55. WindMin: Word; { Window upper left coordinates }
  56. WindMax: Word; { Window lower right coordinates }
  57. { Interface procedures }
  58. procedure AssignCrt(var F: Text);
  59. function KeyPressed: Boolean;
  60. function ReadKey: Char;
  61. procedure TextMode(Mode: Integer);
  62. procedure Window(X1,Y1,X2,Y2: Byte);
  63. procedure GotoXY(X,Y: Byte);
  64. function WhereX: Byte;
  65. function WhereY: Byte;
  66. procedure ClrScr;
  67. procedure ClrEol;
  68. procedure InsLine;
  69. procedure DelLine;
  70. procedure TextColor(Color: Byte);
  71. procedure TextBackground(Color: Byte);
  72. procedure LowVideo;
  73. procedure HighVideo;
  74. procedure NormVideo;
  75. procedure Delay(MS: Word);
  76. procedure Sound(Hz: Word);
  77. procedure NoSound;
  78. {Extra Functions}
  79. procedure cursoron;
  80. procedure cursoroff;
  81. procedure cursorbig;
  82. implementation
  83. uses
  84. go32;
  85. var
  86. startattrib : byte;
  87. col,row,
  88. maxcols,maxrows : longint;
  89. {
  90. definition of textrec is in textrec.inc
  91. }
  92. {$i textrec.inc}
  93. {****************************************************************************
  94. Low level Routines
  95. ****************************************************************************}
  96. procedure setscreenmode(mode : byte);
  97. var regs : trealregs;
  98. begin
  99. {$ifdef GO32V2}
  100. regs.realeax:=mode;
  101. realintr($10,regs);
  102. {$else GO32V2}
  103. asm
  104. movb 8(%ebp),%al
  105. xorb %ah,%ah
  106. pushl %ebp
  107. int $0x10
  108. popl %ebp
  109. end;
  110. {$endif GO32V2}
  111. end;
  112. function screenrows : byte;
  113. begin
  114. dosmemget($40,$84,screenrows,1);
  115. inc(screenrows);
  116. end;
  117. function screencols : byte;
  118. begin
  119. dosmemget($40,$4a,screencols,1);
  120. end;
  121. function get_addr(row,col : byte) : word;
  122. begin
  123. get_addr:=((row-1)*maxcols+(col-1))*2;
  124. end;
  125. procedure screensetcursor(row,col : longint);
  126. {$ifdef GO32V2}
  127. var
  128. regs : trealregs;
  129. {$endif GO32V2}
  130. begin
  131. {$ifndef GO32V2}
  132. asm
  133. movb $0x02,%ah
  134. movb $0,%bh
  135. movb row,%dh
  136. movb col,%dl
  137. subw $0x0101,%dx
  138. pushl %ebp
  139. int $0x10
  140. popl %ebp
  141. end;
  142. {$else GO32V2}
  143. regs.realeax:=$0200;
  144. regs.realebx:=0;
  145. regs.realedx:=(row-1)*$100+(col-1);
  146. realintr($10,regs);
  147. {$endif GO32V2}
  148. end;
  149. procedure screengetcursor(var row,col : longint);
  150. begin
  151. col:=0;
  152. row:=0;
  153. dosmemget($40,$50,col,1);
  154. dosmemget($40,$51,row,1);
  155. inc(col);
  156. inc(row);
  157. end;
  158. { exported routines }
  159. procedure cursoron;
  160. {$ifdef GO32V2}
  161. var regs : trealregs;
  162. {$endif GO32V2}
  163. begin
  164. {$ifndef GO32V2}
  165. asm
  166. movb $1,%ah
  167. movb $10,%cl
  168. movb $9,%ch
  169. pushl %ebp
  170. int $0x10
  171. popl %ebp
  172. end;
  173. {$else GO32V2}
  174. regs.realeax:=$0100;
  175. regs.realecx:=$90A;
  176. realintr($10,regs);
  177. {$endif GO32V2}
  178. end;
  179. procedure cursoroff;
  180. {$ifdef GO32V2}
  181. var regs : trealregs;
  182. {$endif GO32V2}
  183. begin
  184. {$ifndef GO32V2}
  185. asm
  186. movb $1,%ah
  187. movb $-1,%cl
  188. movb $-1,%ch
  189. pushl %ebp
  190. int $0x10
  191. popl %ebp
  192. end;
  193. {$else GO32V2}
  194. regs.realeax:=$0100;
  195. regs.realecx:=$ffff;
  196. realintr($10,regs);
  197. {$endif GO32V2}
  198. end;
  199. procedure cursorbig;
  200. {$ifdef GO32V2}
  201. var
  202. regs : trealregs;
  203. {$endif GO32V2}
  204. begin
  205. {$ifdef GO32V2}
  206. regs.realeax:=$0100;
  207. regs.realecx:=$10A;
  208. realintr($10,regs);
  209. {$else GO32V2}
  210. asm
  211. movb $1,%ah
  212. movb $10,%cl
  213. movb $1,%ch
  214. pushl %ebp
  215. int $0x10
  216. popl %ebp
  217. end;
  218. {$endif GO32V2}
  219. end;
  220. var
  221. is_last : boolean;
  222. last : char;
  223. function readkey : char;
  224. var
  225. char2 : char;
  226. char1 : char;
  227. {$ifdef GO32V2}
  228. regs : trealregs;
  229. {$endif GO32V2}
  230. begin
  231. if is_last then
  232. begin
  233. is_last:=false;
  234. readkey:=last;
  235. end
  236. else
  237. begin
  238. {$ifdef GO32V2}
  239. regs.realeax:=$0000;
  240. realintr($16,regs);
  241. byte(char1):=regs.realeax and $ff;
  242. byte(char2):=(regs.realeax and $ff00) shr 8;
  243. {$else GO32V2}
  244. asm
  245. movb $0,%ah
  246. pushl %ebp
  247. int $0x16
  248. popl %ebp
  249. movb %al,char1
  250. movb %ah,char2
  251. end;
  252. {$endif GO32V2}
  253. if char1=#0 then
  254. begin
  255. is_last:=true;
  256. last:=char2;
  257. end;
  258. readkey:=char1;
  259. end;
  260. end;
  261. function keypressed : boolean;
  262. {$ifdef GO32V2}
  263. var regs : trealregs;
  264. {$endif GO32V2}
  265. begin
  266. if is_last then
  267. begin
  268. keypressed:=true;
  269. exit;
  270. end
  271. else
  272. {$ifdef GO32V2}
  273. begin
  274. regs.realeax:=$0100;
  275. realintr($16,regs);
  276. if (regs.realflags and zeroflag) = 0 then
  277. keypressed:=true
  278. else keypressed:=false;
  279. end;
  280. {$else GO32V2}
  281. asm
  282. movb $1,%ah
  283. pushl %ebp
  284. int $0x16
  285. popl %ebp
  286. setnz %al
  287. movb %al,__RESULT
  288. end;
  289. {$endif GO32V2}
  290. end;
  291. procedure gotoxy(x,y : byte);
  292. begin
  293. if (x<1) then
  294. x:=1;
  295. if (y<1) then
  296. y:=1;
  297. if y+hi(windmin)-2>=hi(windmax) then
  298. y:=hi(windmax)-hi(windmin)+1;
  299. if x+lo(windmin)-2>=lo(windmax) then
  300. x:=lo(windmax)-lo(windmin)+1;
  301. screensetcursor(y+hi(windmin),x+lo(windmin));
  302. end;
  303. function wherex : byte;
  304. var
  305. row,col : longint;
  306. begin
  307. screengetcursor(row,col);
  308. wherex:=col-lo(windmin);
  309. end;
  310. function wherey : byte;
  311. var
  312. row,col : longint;
  313. begin
  314. screengetcursor(row,col);
  315. wherey:=row-hi(windmin);
  316. end;
  317. procedure Window(X1,Y1,X2,Y2: Byte);
  318. begin
  319. if (x1<1) or (x2>screencols) or (y2>screenrows) or
  320. (x1>x2) or (y1>y2) then
  321. exit;
  322. windmin:=(x1-1) or ((x1-1) shl 8);
  323. windmax:=(x2-1) or ((y2-1) shl 8);
  324. gotoxy(1,1);
  325. end;
  326. procedure clrscr;
  327. var
  328. fil : word;
  329. row : longint;
  330. begin
  331. fil:=32 or (textattr shl 8);
  332. for row:=hi(windmin) to hi(windmax) do
  333. dosmemfillword($b800,get_addr(row+1,lo(windmin)+1),lo(windmax)-lo(windmin)+1,fil);
  334. gotoxy(1,1);
  335. end;
  336. procedure textcolor(color : Byte);
  337. begin
  338. textattr:=(textattr and $70) or color;
  339. end;
  340. procedure lowvideo;
  341. begin
  342. textattr:=textattr and $f7;
  343. end;
  344. procedure highvideo;
  345. begin
  346. textattr:=textattr or $08;
  347. end;
  348. procedure textbackground(color : Byte);
  349. begin
  350. textattr:=(textattr and $8f) or ((color and $7) shl 4);
  351. end;
  352. procedure normvideo;
  353. begin
  354. textattr:=startattrib;
  355. end;
  356. procedure removeline(line : byte);
  357. var
  358. row,left,right,bot : longint;
  359. fil : word;
  360. begin
  361. row:=line+hi(windmin);
  362. left:=lo(windmin)+1;
  363. right:=lo(windmax)+1;
  364. bot:=hi(windmax)+1;
  365. fil:=32 or (textattr shl 8);
  366. while (row<bot) do
  367. begin
  368. dosmemmove($b800,get_addr(row+1,left),$b800,get_addr(row,left),(right-left+1)*2);
  369. inc(row);
  370. end;
  371. dosmemfillword($b800,get_addr(bot,left),right-left+1,fil);
  372. end;
  373. procedure delline;
  374. begin
  375. removeline(wherey);
  376. end;
  377. procedure insline;
  378. var
  379. row,col,left,right,bot : longint;
  380. fil : word;
  381. begin
  382. screengetcursor(row,col);
  383. inc(row);
  384. left:=lo(windmin)+1;
  385. right:=lo(windmax)+1;
  386. bot:=hi(windmax);
  387. fil:=32 or (textattr shl 8);
  388. while (bot>row) do
  389. begin
  390. dosmemmove($b800,get_addr(bot-1,left),$b800,get_addr(bot,left),(right-left+1)*2);
  391. dec(bot);
  392. end;
  393. dosmemfillword($b800,get_addr(row,left),right-left+1,fil);
  394. end;
  395. procedure clreol;
  396. var
  397. row,col : longint;
  398. fil : word;
  399. begin
  400. screengetcursor(row,col);
  401. fil:=32 or (textattr shl 8);
  402. dosmemfillword($b800,get_addr(row,col),lo(windmax)-col+2,fil);
  403. end;
  404. procedure sound(hz : word);
  405. begin
  406. if hz=0 then
  407. begin
  408. nosound;
  409. exit;
  410. end;
  411. asm
  412. movzwl hz,%ecx
  413. movl $1193046,%eax
  414. cdq
  415. divl %ecx
  416. movl %eax,%ecx
  417. movb $0xb6,%al
  418. outb %al,$0x43
  419. movb %cl,%al
  420. outb %al,$0x42
  421. movb %ch,%al
  422. outb %al,$0x42
  423. inb $0x61,%al
  424. orb $0x3,%al
  425. outb %al,$0x61
  426. end ['EAX','ECX','EDX'];
  427. end;
  428. procedure nosound;
  429. begin
  430. asm
  431. inb $0x61,%al
  432. andb $0xfc,%al
  433. outb %al,$0x61
  434. end ['EAX'];
  435. end;
  436. var
  437. calibration : longint;
  438. function get_ticks:longint;
  439. begin
  440. dosmemget($40,$6c,get_ticks,4);
  441. end;
  442. procedure Delay(MS: Word);
  443. var
  444. i,j : longint;
  445. begin
  446. for i:=1 to ms do
  447. for j:=1 to calibration do;
  448. end;
  449. procedure initdelay;
  450. { From the mailling list,
  451. by Jonathan Anderson ([email protected]) }
  452. const
  453. threshold=7;
  454. { Raise this to increase speed but decrease accuracy }
  455. { currently the calibration will be no more than 7 off }
  456. { and shave a few ticks off the most accurate setting of 0 }
  457. { The best values to pick are powers of 2-1 (0,1,3,7,15...) }
  458. { but any non-negative value will work. }
  459. var
  460. too_small : boolean;
  461. first,
  462. incval : longint;
  463. begin
  464. calibration:=0;
  465. { wait for new tick }
  466. first:=get_ticks;
  467. while get_ticks=first do
  468. begin
  469. end;
  470. first:=get_ticks;
  471. { this estimates calibration }
  472. while get_ticks=first do
  473. inc(calibration);
  474. {$ifdef GO32V2}
  475. calibration:=calibration div 55;
  476. {$else}
  477. calibration:=calibration div 3;
  478. {$endif}
  479. { The ideal guess value is about half of the real value }
  480. { although a value lower than that take a large performance }
  481. { hit compared to a value higher than that because it has to }
  482. { go through the loop a few times. }
  483. if calibration<(threshold+1)*2 then
  484. calibration:=(threshold+1)*2;
  485. { If calibration is not at least this value, an }
  486. { infinite loop will result. }
  487. repeat
  488. incval:=calibration div 4;
  489. if calibration<0 then
  490. begin
  491. calibration:=$7FFFFFFF;
  492. exit;
  493. end;
  494. { If calibration becomes less than 0, then }
  495. { the maximum value was not long enough, so }
  496. { assign it the maximum value and exit. }
  497. { Without this code, an infinite loop would }
  498. { result on superfast computers about 315800 }
  499. { times faster (oh yeah!) than my Pentium 75. }
  500. { If you don't think that will happen, take }
  501. { out the if and save a few clock cycles. }
  502. too_small:=true; { Assumed true at beginning }
  503. while incval>threshold do
  504. begin
  505. incval:=incval div 2;
  506. first:=get_ticks;
  507. while get_ticks=first do
  508. begin
  509. end;
  510. first:=get_ticks;
  511. delay(55);
  512. if first=get_ticks then
  513. calibration:=calibration+incval
  514. else
  515. begin
  516. calibration:=calibration-incval;
  517. too_small:=false;
  518. { If you have to decrement calibration, }
  519. { the initial value was not too small to }
  520. { result in an accurate measurement. }
  521. end;
  522. end;
  523. until not too_small;
  524. end;
  525. procedure textmode(mode : integer);
  526. var
  527. set_font8x8 : boolean;
  528. begin
  529. lastmode:=mode;
  530. set_font8x8:=(mode and font8x8)<>0;
  531. mode:=mode and $ff;
  532. setscreenmode(mode);
  533. windmin:=0;
  534. windmax:=(screencols-1) or ((screenrows-1) shl 8);
  535. maxcols:=screencols;
  536. maxrows:=screenrows;
  537. end;
  538. {*****************************************************************************
  539. Read and Write routines
  540. *****************************************************************************}
  541. Procedure WriteChar(c:char);
  542. var
  543. regs : trealregs;
  544. chattr : word;
  545. begin
  546. case c of
  547. #10 : inc(row);
  548. #13 : col:=lo(windmin)+1;
  549. #8 : begin
  550. if col>lo(windmin)+1 then
  551. dec(col);
  552. end;
  553. #7 : begin { beep }
  554. {$ifdef GO32V2}
  555. regs.dl:=7;
  556. regs.ah:=2;
  557. realintr($21,regs);
  558. {$endif}
  559. end;
  560. else
  561. begin
  562. chattr:=(textattr shl 8) or byte(c);
  563. dosmemput($b800,get_addr(row,col),chattr,2);
  564. inc(col);
  565. end;
  566. end;
  567. if col>lo(windmax)+1 then
  568. begin
  569. col:=lo(windmin)+1;
  570. inc(row);
  571. end;
  572. while row>hi(windmax)+1 do
  573. begin
  574. removeline(1);
  575. dec(row);
  576. end;
  577. end;
  578. Function CrtWrite(var f : textrec):integer;
  579. var
  580. i : longint;
  581. begin
  582. screengetcursor(row,col);
  583. for i:=0 to f.bufpos-1 do
  584. WriteChar(f.buffer[i]);
  585. f.bufpos:=0;
  586. screensetcursor(row,col);
  587. CrtWrite:=0;
  588. end;
  589. Function CrtRead(Var F: TextRec): Integer;
  590. procedure BackSpace;
  591. begin
  592. if (f.bufpos>0) and (f.bufpos=f.bufend) then
  593. begin
  594. WriteChar(#8);
  595. WriteChar(' ');
  596. WriteChar(#8);
  597. dec(f.bufpos);
  598. dec(f.bufend);
  599. end;
  600. end;
  601. var
  602. ch : Char;
  603. Begin
  604. f.bufpos:=0;
  605. f.bufend:=0;
  606. repeat
  607. if f.bufpos>f.bufend then
  608. f.bufend:=f.bufpos;
  609. screensetcursor(row,col);
  610. ch:=readkey;
  611. case ch of
  612. #0 : case readkey of
  613. #71 : while f.bufpos>0 do
  614. begin
  615. dec(f.bufpos);
  616. WriteChar(#8);
  617. end;
  618. #75 : if f.bufpos>0 then
  619. begin
  620. dec(f.bufpos);
  621. WriteChar(#8);
  622. end;
  623. #77 : if f.bufpos<f.bufend then
  624. begin
  625. WriteChar(f.bufptr^[f.bufpos]);
  626. inc(f.bufpos);
  627. end;
  628. #79 : while f.bufpos<f.bufend do
  629. begin
  630. WriteChar(f.bufptr^[f.bufpos]);
  631. inc(f.bufpos);
  632. end;
  633. end;
  634. ^S,
  635. #8 : BackSpace;
  636. ^Y,
  637. #27 : begin
  638. f.bufpos:=f.bufend;
  639. while f.bufend>0 do
  640. BackSpace;
  641. end;
  642. #13 : begin
  643. WriteChar(#13);
  644. WriteChar(#10);
  645. f.bufptr^[f.bufend]:=#13;
  646. f.bufptr^[f.bufend+1]:=#10;
  647. inc(f.bufend,2);
  648. break;
  649. end;
  650. #26 : if CheckEOF then
  651. begin
  652. f.bufptr^[f.bufend]:=#26;
  653. inc(f.bufend);
  654. break;
  655. end;
  656. else
  657. begin
  658. if f.bufpos<f.bufsize-2 then
  659. begin
  660. f.buffer[f.bufpos]:=ch;
  661. inc(f.bufpos);
  662. WriteChar(ch);
  663. end;
  664. end;
  665. end;
  666. until false;
  667. f.bufpos:=0;
  668. screensetcursor(row,col);
  669. CrtRead:=0;
  670. End;
  671. Function CrtReturn:Integer;
  672. Begin
  673. CrtReturn:=0;
  674. end;
  675. Function CrtClose(Var F: TextRec): Integer;
  676. Begin
  677. F.Mode:=fmClosed;
  678. CrtClose:=0;
  679. End;
  680. Function CrtOpen(Var F: TextRec): Integer;
  681. Begin
  682. If F.Mode=fmOutput Then
  683. begin
  684. TextRec(F).InOutFunc:=@CrtWrite;
  685. TextRec(F).FlushFunc:=@CrtWrite;
  686. end
  687. Else
  688. begin
  689. F.Mode:=fmInput;
  690. TextRec(F).InOutFunc:=@CrtRead;
  691. TextRec(F).FlushFunc:=@CrtReturn;
  692. end;
  693. TextRec(F).CloseFunc:=@CrtClose;
  694. CrtOpen:=0;
  695. End;
  696. procedure AssignCrt(var F: Text);
  697. begin
  698. Assign(F,'');
  699. TextRec(F).OpenFunc:=@CrtOpen;
  700. end;
  701. begin
  702. is_last:=false;
  703. { load system variables to temporary variables to save time }
  704. maxcols:=screencols;
  705. maxrows:=screenrows;
  706. { set output window }
  707. windmax:=(maxcols-1) or ((maxrows-1) shl 8);
  708. { save the current settings to restore the old state after the exit }
  709. screengetcursor(row,col);
  710. dosmemget($b800,get_addr(row,col)+1,startattrib,1);
  711. dosmemget($40,$49,lastmode,1);
  712. textattr:=startattrib;
  713. { redirect the standard output }
  714. assigncrt(Output);
  715. Rewrite(Output);
  716. TextRec(Output).Handle:=StdOutputHandle;
  717. assigncrt(Input);
  718. Reset(Input);
  719. TextRec(Input).Handle:=StdInputHandle;
  720. { calculates delay calibration }
  721. initdelay;
  722. end.
  723. {
  724. $Log$
  725. Revision 1.6 1998-07-07 12:26:42 carl
  726. * now compiles under fpc v0.99.5, so don't modify!!!!
  727. Revision 1.5 1998/05/31 14:18:12 peter
  728. * force att or direct assembling
  729. * cleanup of some files
  730. Revision 1.4 1998/05/28 10:21:38 pierre
  731. * Handles of input and output restored
  732. Revision 1.3 1998/05/27 00:19:16 peter
  733. * fixed crt input
  734. Revision 1.2 1998/05/21 19:30:46 peter
  735. * objects compiles for linux
  736. + assign(pchar), assign(char), rename(pchar), rename(char)
  737. * fixed read_text_as_array
  738. + read_text_as_pchar which was not yet in the rtl
  739. }