crt.pp 19 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by the Free Pascal development team.
  5. Borland Pascal 7 Compatible CRT Unit for Go32V1 and Go32V2
  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. const
  16. { CRT modes }
  17. BW40 = 0; { 40x25 B/W on Color Adapter }
  18. CO40 = 1; { 40x25 Color on Color Adapter }
  19. BW80 = 2; { 80x25 B/W on Color Adapter }
  20. CO80 = 3; { 80x25 Color on Color Adapter }
  21. Mono = 7; { 80x25 on Monochrome Adapter }
  22. Font8x8 = 256; { Add-in for ROM font }
  23. { Mode constants for 3.0 compatibility }
  24. C40 = CO40;
  25. C80 = CO80;
  26. { Foreground and background color constants }
  27. Black = 0;
  28. Blue = 1;
  29. Green = 2;
  30. Cyan = 3;
  31. Red = 4;
  32. Magenta = 5;
  33. Brown = 6;
  34. LightGray = 7;
  35. { Foreground color constants }
  36. DarkGray = 8;
  37. LightBlue = 9;
  38. LightGreen = 10;
  39. LightCyan = 11;
  40. LightRed = 12;
  41. LightMagenta = 13;
  42. Yellow = 14;
  43. White = 15;
  44. { Add-in for blinking }
  45. Blink = 128;
  46. var
  47. { Interface variables }
  48. CheckBreak: Boolean; { Enable Ctrl-Break }
  49. CheckEOF: Boolean; { Enable Ctrl-Z }
  50. DirectVideo: Boolean; { Enable direct video addressing }
  51. CheckSnow: Boolean; { Enable snow filtering }
  52. LastMode: Word; { Current text mode }
  53. TextAttr: Byte; { Current text attribute }
  54. WindMin: Word; { Window upper left coordinates }
  55. WindMax: Word; { Window lower right coordinates }
  56. { Interface procedures }
  57. procedure AssignCrt(var F: Text);
  58. function KeyPressed: Boolean;
  59. function ReadKey: Char;
  60. procedure TextMode(Mode: Integer);
  61. procedure Window(X1,Y1,X2,Y2: Byte);
  62. procedure GotoXY(X,Y: Byte);
  63. function WhereX: Byte;
  64. function WhereY: Byte;
  65. procedure ClrScr;
  66. procedure ClrEol;
  67. procedure InsLine;
  68. procedure DelLine;
  69. procedure TextColor(Color: Byte);
  70. procedure TextBackground(Color: Byte);
  71. procedure LowVideo;
  72. procedure HighVideo;
  73. procedure NormVideo;
  74. procedure Delay(MS: Word);
  75. procedure Sound(Hz: Word);
  76. procedure NoSound;
  77. {Extra Functions}
  78. procedure cursoron;
  79. procedure cursoroff;
  80. procedure cursorbig;
  81. implementation
  82. uses
  83. go32;
  84. {$ifdef VER0_99_5}
  85. {$I386_DIRECT} {due to a bug in the assembler reader using a }
  86. { call to a symbol will crash under FPC 0.99.5 }
  87. {$endif}
  88. {$ASMMODE ATT}
  89. var
  90. DelayCnt, { don't modify this var name, as it is hard coded }
  91. ScreenWidth,
  92. ScreenHeight : longint;
  93. {
  94. definition of textrec is in textrec.inc
  95. }
  96. {$i textrec.inc}
  97. {****************************************************************************
  98. Low level Routines
  99. ****************************************************************************}
  100. procedure setscreenmode(mode : byte);
  101. {$ifdef GO32V2}
  102. var
  103. regs : trealregs;
  104. {$endif GO32V2}
  105. begin
  106. {$ifdef GO32V2}
  107. regs.realeax:=mode;
  108. realintr($10,regs);
  109. {$else GO32V2}
  110. asm
  111. movb 8(%ebp),%al
  112. xorb %ah,%ah
  113. pushl %ebp
  114. int $0x10
  115. popl %ebp
  116. end;
  117. {$endif GO32V2}
  118. end;
  119. function GetScreenHeight : longint;
  120. begin
  121. {$ifdef GO32V2}
  122. getscreenheight:=mem[$40:$84]+1;
  123. {$else}
  124. dosmemget($40,$84,getscreenheight,1);
  125. inc(getscreenheight);
  126. {$endif}
  127. end;
  128. function GetScreenWidth : longint;
  129. begin
  130. {$ifdef GO32V2}
  131. getscreenwidth:=mem[$40:$4a];
  132. {$else}
  133. dosmemget($40,$4a,getscreenwidth,1);
  134. {$endif}
  135. end;
  136. procedure SetScreenCursor(x,y : longint);
  137. {$ifdef GO32V2}
  138. var
  139. regs : trealregs;
  140. {$endif GO32V2}
  141. begin
  142. {$ifdef GO32V2}
  143. regs.realeax:=$0200;
  144. regs.realebx:=0;
  145. regs.realedx:=(y-1) shl 8+(x-1);
  146. realintr($10,regs);
  147. {$else GO32V2}
  148. asm
  149. movb $0x02,%ah
  150. movb $0,%bh
  151. movb y,%dh
  152. movb x,%dl
  153. subw $0x0101,%dx
  154. pushl %ebp
  155. int $0x10
  156. popl %ebp
  157. end;
  158. {$endif GO32V2}
  159. end;
  160. procedure GetScreenCursor(var x,y : longint);
  161. begin
  162. {$ifdef Go32V2}
  163. x:=mem[$40:$50]+1;
  164. y:=mem[$40:$51]+1;
  165. {$else Go32V2}
  166. x:=0;
  167. y:=0;
  168. dosmemget($40,$50,x,1);
  169. dosmemget($40,$51,y,1);
  170. inc(x);
  171. inc(y);
  172. {$endif GO32V2}
  173. end;
  174. {****************************************************************************
  175. Helper Routines
  176. ****************************************************************************}
  177. Function WinMinX: Byte;
  178. {
  179. Current Minimum X coordinate
  180. }
  181. Begin
  182. WinMinX:=(WindMin and $ff)+1;
  183. End;
  184. Function WinMinY: Byte;
  185. {
  186. Current Minimum Y Coordinate
  187. }
  188. Begin
  189. WinMinY:=(WindMin shr 8)+1;
  190. End;
  191. Function WinMaxX: Byte;
  192. {
  193. Current Maximum X coordinate
  194. }
  195. Begin
  196. WinMaxX:=(WindMax and $ff)+1;
  197. End;
  198. Function WinMaxY: Byte;
  199. {
  200. Current Maximum Y coordinate;
  201. }
  202. Begin
  203. WinMaxY:=(WindMax shr 8) + 1;
  204. End;
  205. Function FullWin:boolean;
  206. {
  207. Full Screen 80x25? Window(1,1,80,25) is used, allows faster routines
  208. }
  209. begin
  210. FullWin:=(WindMax-WindMin=$184f);
  211. end;
  212. {****************************************************************************
  213. Public Crt Functions
  214. ****************************************************************************}
  215. procedure textmode(mode : integer);
  216. begin
  217. lastmode:=mode;
  218. mode:=mode and $ff;
  219. setscreenmode(mode);
  220. screenwidth:=getscreenwidth;
  221. screenheight:=getscreenheight;
  222. windmin:=0;
  223. windmax:=(screenwidth-1) or ((screenheight-1) shl 8);
  224. end;
  225. Procedure TextColor(Color: Byte);
  226. {
  227. Switch foregroundcolor
  228. }
  229. Begin
  230. TextAttr:=(Color and $8f) or (TextAttr and $70);
  231. End;
  232. Procedure TextBackground(Color: Byte);
  233. {
  234. Switch backgroundcolor
  235. }
  236. Begin
  237. TextAttr:=(Color shl 4) or (TextAttr and $0f);
  238. End;
  239. Procedure HighVideo;
  240. {
  241. Set highlighted output.
  242. }
  243. Begin
  244. TextColor(TextAttr Or $08);
  245. End;
  246. Procedure LowVideo;
  247. {
  248. Set normal output
  249. }
  250. Begin
  251. TextColor(TextAttr And $77);
  252. End;
  253. Procedure NormVideo;
  254. {
  255. Set normal back and foregroundcolors.
  256. }
  257. Begin
  258. TextColor(7);
  259. TextBackGround(0);
  260. End;
  261. Procedure GotoXy(X: Byte; Y: Byte);
  262. {
  263. Go to coordinates X,Y in the current window.
  264. }
  265. Begin
  266. If (X>0) and (X<=WinMaxX- WinMinX+1) and
  267. (Y>0) and (Y<=WinMaxY-WinMinY+1) Then
  268. Begin
  269. Inc(X,WinMinX-1);
  270. Inc(Y,WinMinY-1);
  271. SetScreenCursor(x,y);
  272. End;
  273. End;
  274. Procedure Window(X1, Y1, X2, Y2: Byte);
  275. {
  276. Set screen window to the specified coordinates.
  277. }
  278. Begin
  279. if (X1>X2) or (X2>ScreenWidth) or
  280. (Y1>Y2) or (Y2>ScreenHeight) then
  281. exit;
  282. WindMin:=((Y1-1) Shl 8)+(X1-1);
  283. WindMax:=((Y2-1) Shl 8)+(X2-1);
  284. GoToXY(1,1);
  285. End;
  286. Procedure ClrScr;
  287. {
  288. Clear the current window, and set the cursor on 1,1
  289. }
  290. var
  291. fil : word;
  292. y : longint;
  293. begin
  294. fil:=32 or (textattr shl 8);
  295. if FullWin then
  296. DosmemFillWord($b800,0,ScreenHeight*ScreenWidth,fil)
  297. else
  298. begin
  299. for y:=WinMinY to WinMaxY do
  300. DosmemFillWord($b800,((y-1)*ScreenWidth+(WinMinX-1))*2,WinMaxX-WinMinX+1,fil);
  301. end;
  302. Gotoxy(1,1);
  303. end;
  304. Procedure ClrEol;
  305. {
  306. Clear from current position to end of line.
  307. }
  308. var
  309. x,y : longint;
  310. fil : word;
  311. Begin
  312. GetScreenCursor(x,y);
  313. fil:=32 or (textattr shl 8);
  314. if x<WinMaxX then
  315. DosmemFillword($b800,((y-1)*ScreenWidth+(x-1))*2,WinMaxX-x+1,fil);
  316. End;
  317. Function WhereX: Byte;
  318. {
  319. Return current X-position of cursor.
  320. }
  321. var
  322. x,y : longint;
  323. Begin
  324. GetScreenCursor(x,y);
  325. WhereX:=x-WinMinX+1;
  326. End;
  327. Function WhereY: Byte;
  328. {
  329. Return current Y-position of cursor.
  330. }
  331. var
  332. x,y : longint;
  333. Begin
  334. GetScreenCursor(x,y);
  335. WhereY:=y-WinMinY+1;
  336. End;
  337. {*************************************************************************
  338. KeyBoard
  339. *************************************************************************}
  340. var
  341. is_last : boolean;
  342. last : char;
  343. function readkey : char;
  344. var
  345. char2 : char;
  346. char1 : char;
  347. {$ifdef GO32V2}
  348. regs : trealregs;
  349. {$endif GO32V2}
  350. begin
  351. if is_last then
  352. begin
  353. is_last:=false;
  354. readkey:=last;
  355. end
  356. else
  357. begin
  358. {$ifdef GO32V2}
  359. regs.realeax:=$0000;
  360. realintr($16,regs);
  361. char1:=chr(regs.realeax and $ff);
  362. char2:=chr((regs.realeax and $ff00) shr 8);
  363. {$else GO32V2}
  364. asm
  365. movb $0,%ah
  366. pushl %ebp
  367. int $0x16
  368. popl %ebp
  369. movb %al,char1
  370. movb %ah,char2
  371. end;
  372. {$endif GO32V2}
  373. if char1=#0 then
  374. begin
  375. is_last:=true;
  376. last:=char2;
  377. end;
  378. readkey:=char1;
  379. end;
  380. end;
  381. function keypressed : boolean;
  382. {$ifdef GO32V2}
  383. var
  384. regs : trealregs;
  385. {$endif GO32V2}
  386. begin
  387. if is_last then
  388. begin
  389. keypressed:=true;
  390. exit;
  391. end
  392. else
  393. begin
  394. {$ifdef GO32V2}
  395. regs.realeax:=$0100;
  396. realintr($16,regs);
  397. keypressed:=((regs.realflags and zeroflag) = 0);
  398. {$else GO32V2}
  399. asm
  400. movb $1,%ah
  401. pushl %ebp
  402. int $0x16
  403. popl %ebp
  404. setnz %al
  405. movb %al,__RESULT
  406. end;
  407. {$endif GO32V2}
  408. end;
  409. end;
  410. {*************************************************************************
  411. Delay
  412. *************************************************************************}
  413. {$ifdef VER0_99_5}
  414. { Workaround for ATT reader with CALL }
  415. procedure Delayloop;
  416. begin
  417. asm
  418. .LDelayLoop1:
  419. subl $1,%eax
  420. jc .LDelayLoop2
  421. cmpl %fs:(%edi),%ebx
  422. je .LDelayLoop1
  423. .LDelayLoop2:
  424. end;
  425. end;
  426. procedure initdelay;
  427. begin
  428. asm
  429. movl $0x46c,%edi
  430. movl $-28,%edx
  431. movl %fs:(%edi),%ebx
  432. .LInitDel1:
  433. cmpl %fs:(%edi),%ebx
  434. je .LInitDel1
  435. movl %fs:(%edi),%ebx
  436. movl %edx,%eax
  437. call _CRT$$_DELAYLOOP
  438. notl %eax
  439. xorl %edx,%edx
  440. movl $55,%ecx
  441. divl %ecx
  442. movl %eax,_DELAYCNT
  443. end;
  444. end;
  445. procedure Delay(MS: Word);
  446. begin
  447. asm
  448. movzwl MS,%ecx
  449. jecxz .LDelay2
  450. movl $0x400,%edi
  451. movl _DELAYCNT,%edx
  452. movl %fs:(%edi),%ebx
  453. .LDelay1:
  454. movl %edx,%eax
  455. call _CRT$$_DELAYLOOP
  456. loop .LDelay1
  457. .LDelay2:
  458. end;
  459. end;
  460. {$else}
  461. procedure Delayloop;
  462. begin
  463. asm
  464. .LDelayLoop1:
  465. subl $1,%eax
  466. jc .LDelayLoop2
  467. cmpl %fs:(%edi),%ebx
  468. je .LDelayLoop1
  469. .LDelayLoop2:
  470. end;
  471. end;
  472. procedure initdelay;
  473. begin
  474. asm
  475. movl $0x46c,%edi
  476. movl $-28,%edx
  477. movl %fs:(%edi),%ebx
  478. .LInitDel1:
  479. cmpl %fs:(%edi),%ebx
  480. je .LInitDel1
  481. movl %fs:(%edi),%ebx
  482. movl %edx,%eax
  483. call DelayLoop
  484. notl %eax
  485. xorl %edx,%edx
  486. movl $55,%ecx
  487. divl %ecx
  488. movl %eax,DelayCnt
  489. end;
  490. end;
  491. procedure Delay(MS: Word);
  492. begin
  493. asm
  494. movzwl MS,%ecx
  495. jecxz .LDelay2
  496. movl $0x400,%edi
  497. movl DelayCnt,%edx
  498. movl %fs:(%edi),%ebx
  499. .LDelay1:
  500. movl %edx,%eax
  501. call DelayLoop
  502. loop .LDelay1
  503. .LDelay2:
  504. end;
  505. end;
  506. {$endif VER0_99_5}
  507. procedure sound(hz : word);
  508. begin
  509. if hz=0 then
  510. begin
  511. nosound;
  512. exit;
  513. end;
  514. asm
  515. movzwl hz,%ecx
  516. movl $1193046,%eax
  517. cdq
  518. divl %ecx
  519. movl %eax,%ecx
  520. movb $0xb6,%al
  521. outb %al,$0x43
  522. movb %cl,%al
  523. outb %al,$0x42
  524. movb %ch,%al
  525. outb %al,$0x42
  526. inb $0x61,%al
  527. orb $0x3,%al
  528. outb %al,$0x61
  529. end ['EAX','ECX','EDX'];
  530. end;
  531. procedure nosound;
  532. begin
  533. asm
  534. inb $0x61,%al
  535. andb $0xfc,%al
  536. outb %al,$0x61
  537. end ['EAX'];
  538. end;
  539. {****************************************************************************
  540. HighLevel Crt Functions
  541. ****************************************************************************}
  542. procedure removeline(y : longint);
  543. var
  544. fil : word;
  545. begin
  546. fil:=32 or (textattr shl 8);
  547. y:=WinMinY+y-1;
  548. While (y<WinMaxY) do
  549. begin
  550. dosmemmove($b800,(y*ScreenWidth+(WinMinX-1))*2,
  551. $b800,((y-1)*ScreenWidth+(WinMinX-1))*2,(WinMaxX-WinMinX+1)*2);
  552. inc(y);
  553. end;
  554. dosmemfillword($b800,((WinMaxY-1)*ScreenWidth+(WinMinX-1))*2,(WinMaxX-WinMinX+1),fil);
  555. end;
  556. procedure delline;
  557. begin
  558. removeline(wherey);
  559. end;
  560. procedure insline;
  561. var
  562. my,y : longint;
  563. fil : word;
  564. begin
  565. fil:=32 or (textattr shl 8);
  566. y:=WhereY;
  567. my:=WinMaxY-1;
  568. while (my>=y) do
  569. begin
  570. dosmemmove($b800,(((WinMinY+my-1)-1)*ScreenWidth+(WinMinX-1))*2,
  571. $b800,(((WinMinY+my)-1)*ScreenWidth+(WinMinX-1))*2,(WinMaxX-WinMinX+1)*2);
  572. dec(my);
  573. end;
  574. dosmemfillword($b800,(((WinMinY+y-1)-1)*ScreenWidth+(WinMinX-1))*2,(WinMaxX-WinMinX+1),fil);
  575. end;
  576. {****************************************************************************
  577. Extra Crt Functions
  578. ****************************************************************************}
  579. procedure cursoron;
  580. {$ifdef GO32V2}
  581. var
  582. regs : trealregs;
  583. {$endif GO32V2}
  584. begin
  585. {$ifndef GO32V2}
  586. asm
  587. movb $1,%ah
  588. movb $10,%cl
  589. movb $9,%ch
  590. pushl %ebp
  591. int $0x10
  592. popl %ebp
  593. end;
  594. {$else GO32V2}
  595. regs.realeax:=$0100;
  596. regs.realecx:=$90A;
  597. realintr($10,regs);
  598. {$endif GO32V2}
  599. end;
  600. procedure cursoroff;
  601. {$ifdef GO32V2}
  602. var
  603. regs : trealregs;
  604. {$endif GO32V2}
  605. begin
  606. {$ifdef GO32V2}
  607. regs.realeax:=$0100;
  608. regs.realecx:=$ffff;
  609. realintr($10,regs);
  610. {$else GO32V2}
  611. asm
  612. movb $1,%ah
  613. movb $-1,%cl
  614. movb $-1,%ch
  615. pushl %ebp
  616. int $0x10
  617. popl %ebp
  618. end;
  619. {$endif GO32V2}
  620. end;
  621. procedure cursorbig;
  622. {$ifdef GO32V2}
  623. var
  624. regs : trealregs;
  625. {$endif GO32V2}
  626. begin
  627. {$ifdef GO32V2}
  628. regs.realeax:=$0100;
  629. regs.realecx:=$10A;
  630. realintr($10,regs);
  631. {$else GO32V2}
  632. asm
  633. movb $1,%ah
  634. movw $110,%cx
  635. pushl %ebp
  636. int $0x10
  637. popl %ebp
  638. end;
  639. {$endif GO32V2}
  640. end;
  641. {*****************************************************************************
  642. Read and Write routines
  643. *****************************************************************************}
  644. var
  645. CurrX,CurrY : longint;
  646. Procedure WriteChar(c:char);
  647. var
  648. {$ifdef GO32V2}
  649. regs : trealregs;
  650. {$else}
  651. chattr : word;
  652. {$endif}
  653. begin
  654. case c of
  655. #10 : inc(CurrY);
  656. #13 : CurrX:=WinMinX;
  657. #8 : begin
  658. if CurrX>WinMinX then
  659. dec(CurrX);
  660. end;
  661. #7 : begin { beep }
  662. {$ifdef GO32V2}
  663. regs.dl:=7;
  664. regs.ah:=2;
  665. realintr($21,regs);
  666. {$endif}
  667. end;
  668. else
  669. begin
  670. {$ifdef GO32V2}
  671. memw[$b800:((CurrY-1)*ScreenWidth+(CurrX-1))*2]:=(textattr shl 8) or byte(c);
  672. {$else}
  673. chattr:=(textattr shl 8) or byte(c);
  674. dosmemput($b800,((CurrY-1)*ScreenWidth+(CurrX-1))*2,chattr,2);
  675. {$endif}
  676. inc(CurrX);
  677. end;
  678. end;
  679. if CurrX>WinMaxX then
  680. begin
  681. CurrX:=WinMinX;
  682. inc(CurrY);
  683. end;
  684. while CurrY>WinMaxY do
  685. begin
  686. removeline(1);
  687. dec(CurrY);
  688. end;
  689. end;
  690. Function CrtWrite(var f : textrec):integer;
  691. var
  692. i : longint;
  693. begin
  694. GetScreenCursor(CurrX,CurrY);
  695. for i:=0 to f.bufpos-1 do
  696. WriteChar(f.buffer[i]);
  697. SetScreenCursor(CurrX,CurrY);
  698. f.bufpos:=0;
  699. CrtWrite:=0;
  700. end;
  701. Function CrtRead(Var F: TextRec): Integer;
  702. procedure BackSpace;
  703. begin
  704. if (f.bufpos>0) and (f.bufpos=f.bufend) then
  705. begin
  706. WriteChar(#8);
  707. WriteChar(' ');
  708. WriteChar(#8);
  709. dec(f.bufpos);
  710. dec(f.bufend);
  711. end;
  712. end;
  713. var
  714. ch : Char;
  715. Begin
  716. GetScreenCursor(CurrX,CurrY);
  717. f.bufpos:=0;
  718. f.bufend:=0;
  719. repeat
  720. if f.bufpos>f.bufend then
  721. f.bufend:=f.bufpos;
  722. SetScreenCursor(CurrX,CurrY);
  723. ch:=readkey;
  724. case ch of
  725. #0 : case readkey of
  726. #71 : while f.bufpos>0 do
  727. begin
  728. dec(f.bufpos);
  729. WriteChar(#8);
  730. end;
  731. #75 : if f.bufpos>0 then
  732. begin
  733. dec(f.bufpos);
  734. WriteChar(#8);
  735. end;
  736. #77 : if f.bufpos<f.bufend then
  737. begin
  738. WriteChar(f.bufptr^[f.bufpos]);
  739. inc(f.bufpos);
  740. end;
  741. #79 : while f.bufpos<f.bufend do
  742. begin
  743. WriteChar(f.bufptr^[f.bufpos]);
  744. inc(f.bufpos);
  745. end;
  746. end;
  747. ^S,
  748. #8 : BackSpace;
  749. ^Y,
  750. #27 : begin
  751. f.bufpos:=f.bufend;
  752. while f.bufend>0 do
  753. BackSpace;
  754. end;
  755. #13 : begin
  756. WriteChar(#13);
  757. WriteChar(#10);
  758. f.bufptr^[f.bufend]:=#13;
  759. f.bufptr^[f.bufend+1]:=#10;
  760. inc(f.bufend,2);
  761. break;
  762. end;
  763. #26 : if CheckEOF then
  764. begin
  765. f.bufptr^[f.bufend]:=#26;
  766. inc(f.bufend);
  767. break;
  768. end;
  769. else
  770. begin
  771. if f.bufpos<f.bufsize-2 then
  772. begin
  773. f.buffer[f.bufpos]:=ch;
  774. inc(f.bufpos);
  775. WriteChar(ch);
  776. end;
  777. end;
  778. end;
  779. until false;
  780. f.bufpos:=0;
  781. SetScreenCursor(CurrX,CurrY);
  782. CrtRead:=0;
  783. End;
  784. Function CrtReturn:Integer;
  785. Begin
  786. CrtReturn:=0;
  787. end;
  788. Function CrtClose(Var F: TextRec): Integer;
  789. Begin
  790. F.Mode:=fmClosed;
  791. CrtClose:=0;
  792. End;
  793. Function CrtOpen(Var F: TextRec): Integer;
  794. Begin
  795. If F.Mode=fmOutput Then
  796. begin
  797. TextRec(F).InOutFunc:=@CrtWrite;
  798. TextRec(F).FlushFunc:=@CrtWrite;
  799. end
  800. Else
  801. begin
  802. F.Mode:=fmInput;
  803. TextRec(F).InOutFunc:=@CrtRead;
  804. TextRec(F).FlushFunc:=@CrtReturn;
  805. end;
  806. TextRec(F).CloseFunc:=@CrtClose;
  807. CrtOpen:=0;
  808. End;
  809. procedure AssignCrt(var F: Text);
  810. begin
  811. Assign(F,'');
  812. TextRec(F).OpenFunc:=@CrtOpen;
  813. end;
  814. var
  815. x,y : longint;
  816. begin
  817. { Load startup values }
  818. ScreenWidth:=GetScreenWidth;
  819. ScreenHeight:=GetScreenHeight;
  820. WindMax:=(ScreenWidth-1) or ((ScreenHeight-1) shl 8);
  821. { Load TextAttr }
  822. GetScreenCursor(x,y);
  823. {$ifdef GO32V2}
  824. TextAttr:=mem[$b800:((y-1)*ScreenWidth+(x-1))*2+1];
  825. lastmode:=mem[$40:$49];
  826. {$else Go32V2}
  827. dosmemget($b800,((y-1)*ScreenWidth+(x-1))*2+1,TextAttr,1);
  828. dosmemget($40,$49,lastmode,1);
  829. {$endif Go32V2}
  830. { Redirect the standard output }
  831. assigncrt(Output);
  832. Rewrite(Output);
  833. TextRec(Output).Handle:=StdOutputHandle;
  834. assigncrt(Input);
  835. Reset(Input);
  836. TextRec(Input).Handle:=StdInputHandle;
  837. { Calculates delay calibration }
  838. initdelay;
  839. end.
  840. {
  841. $Log$
  842. Revision 1.13 1998-08-26 10:01:54 peter
  843. * fixed readln cursor position
  844. Revision 1.12 1998/08/19 17:57:55 peter
  845. * fixed crtread with wrong cursor position
  846. Revision 1.11 1998/08/19 14:55:44 peter
  847. * fixed removeline which scrolled too much lines
  848. Revision 1.10 1998/08/18 13:32:46 carl
  849. * bugfix to make it work with FPC 0.99.5 (Delayloop is not correctly
  850. converted by ATT parser)
  851. Revision 1.9 1998/08/15 17:00:10 peter
  852. * moved delaycnt from interface to implementation
  853. Revision 1.8 1998/08/08 21:56:45 peter
  854. * updated crt with new delay, almost like bp7 routine
  855. Revision 1.5 1998/05/31 14:18:12 peter
  856. * force att or direct assembling
  857. * cleanup of some files
  858. Revision 1.4 1998/05/28 10:21:38 pierre
  859. * Handles of input and output restored
  860. Revision 1.3 1998/05/27 00:19:16 peter
  861. * fixed crt input
  862. Revision 1.2 1998/05/21 19:30:46 peter
  863. * objects compiles for linux
  864. + assign(pchar), assign(char), rename(pchar), rename(char)
  865. * fixed read_text_as_array
  866. + read_text_as_pchar which was not yet in the rtl
  867. }