crt.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. {****************************************************************************
  2. Standard CRT unit.
  3. FPK-Pascal runtime library for OS/2.
  4. Copyright (c) 1997 Dani‰l Mantione.
  5. This file may be reproduced and modified under the same conditions
  6. as all other FPK-Pascal source code.
  7. ****************************************************************************}
  8. unit crt;
  9. interface
  10. uses dos;
  11. const _40cols=0;
  12. _80cols=1;
  13. _132cols=2;
  14. _25rows=0;
  15. _28rows=16;
  16. _43rows=32;
  17. _50rows=48;
  18. font8x8=_50rows;
  19. black =0;
  20. blue =1;
  21. green =2;
  22. cyan =3;
  23. red =4;
  24. magenta =5;
  25. brown =6;
  26. lightgray =7;
  27. darkgray =8;
  28. lightblue =9;
  29. lightgreen =10;
  30. lightcyan =11;
  31. lightred =12;
  32. lightmagenta =13;
  33. yellow =14;
  34. white =15;
  35. blink =128;
  36. {cemodeset means that the procedure textmode has failed to set up a mode.}
  37. type cexxxx=(cenoerror,cemodeset);
  38. var textattr:byte; {Text attribute. RW}
  39. windmin,windmax:word; {Window coordinates. R-}
  40. lastmode:word; {Last videomode. R-}
  41. crt_error:cexxxx; {Crt-status. RW}
  42. function keypressed:boolean;
  43. function readkey:char;
  44. procedure clrscr;
  45. procedure clreol;
  46. function whereX:byte;
  47. function whereY:byte;
  48. procedure gotoXY(x,y:byte);
  49. procedure window(left,top,right,bottom : byte);
  50. procedure textmode(mode:integer);
  51. procedure textcolor(colour:byte);
  52. procedure textbackground(colour:byte);
  53. procedure insline;
  54. procedure delline;
  55. procedure lowvideo;
  56. procedure normvideo;
  57. procedure highvideo;
  58. procedure assigncrt(var f:text);
  59. procedure delay(ms:word);
  60. procedure sound(hz:word);
  61. procedure nosound;
  62. {***************************************************************************}
  63. {***************************************************************************}
  64. implementation
  65. const extkeycode:char=#0;
  66. var maxrows,maxcols:word;
  67. calibration:longint;
  68. type Tkbdkeyinfo=record
  69. charcode,scancode:char;
  70. fbstatus,bnlsshift:byte;
  71. fsstate:word;
  72. time:longint;
  73. end;
  74. {if you have information on the folowing datastructure, please
  75. send them to me at [email protected]}
  76. {This datastructure is needed when we ask in what video mode we are,
  77. or we want to set up a new mode.}
  78. viomodeinfo=record
  79. cb:word; { length of the entire data
  80. structure }
  81. fbtype, { bit mask of mode being set}
  82. color: byte; { number of colors (power of 2) }
  83. col, { number of text columns }
  84. row, { number of text rows }
  85. hres, { horizontal resolution }
  86. vres: word; { vertical resolution }
  87. fmt_ID, { attribute format
  88. ! more info wanted !}
  89. attrib: byte; { number of attributes }
  90. buf_addr, { physical address of
  91. videobuffer, e.g. $0b800}
  92. buf_length, { length of a videopage (bytes)}
  93. full_length, { total video-memory on video-
  94. card (bytes)}
  95. partial_length:longint; { ????? info wanted !}
  96. ext_data_addr:pointer; { ????? info wanted !}
  97. end;
  98. Pviomodeinfo=^viomodeinfo;
  99. {EMXWRAP.DLL has strange calling conventions: All parameters must have
  100. a 4 byte size.}
  101. function kbdcharin(var Akeyrec:Tkbdkeyinfo;wait,kbdhandle:longint):word;
  102. external 'EMXWRAP' index 204;
  103. function kbdpeek(var Akeyrec:TkbdkeyInfo;kbdhandle:word):word;
  104. external 'EMXWRAP' index 222;
  105. function dossleep(time:longint):word;
  106. external 'DOSCALLS' index 229;
  107. function vioscrollup(top,left,bottom,right,lines:longint;
  108. var screl:word;viohandle:longint):word;
  109. external 'EMXWRAP' index 107;
  110. function vioscrolldn(top,left,bottom,right,lines:longint;
  111. var screl:word;viohandle:longint):word;
  112. external 'EMXWRAP' index 147;
  113. function viogetcurpos(var row,column:word;viohandle:longint):word;
  114. external 'EMXWRAP' index 109;
  115. function viosetcurpos(row,column,viohandle:longint):word;
  116. external 'EMXWRAP' index 115;
  117. function viowrtTTY(s:Pchar;len,viohandle:longint):word;
  118. external 'EMXWRAP' index 119;
  119. function viowrtcharstratt(s:Pchar;len,row,col:longint;var attr:byte;
  120. viohandle:longint):word;
  121. external 'EMXWRAP' index 148;
  122. function viogetmode(var Amodeinfo:viomodeinfo;viohandle:longint):word;
  123. external 'EMXWRAP' index 121;
  124. function viosetmode(var Amodeinfo:viomodeinfo;viohandle:longint):word;
  125. external 'EMXWRAP' index 122;
  126. procedure setscreenmode(mode:word);
  127. { This procedure sets a new videomode. Note that the constants passes to
  128. this procedure are different than in the dos mode.}
  129. const modecols:array[0..2] of word=(40,80,132);
  130. moderows:array[0..3] of word=(25,28,43,50);
  131. var newmode:viomodeinfo;
  132. begin
  133. if os_mode=osOS2 then
  134. begin
  135. newmode.cb:=8;
  136. newmode.fbtype:=1; {Non graphics colour mode.}
  137. newmode.color:=4; {We want 16 colours, 2^4=16.}
  138. newmode.col:=modecols[mode and 15];
  139. newmode.row:=moderows[mode shr 4];
  140. if viosetmode(newmode,0)=0 then
  141. crt_error:=cenoerror
  142. else
  143. crt_error:=cemodeset;
  144. maxcols:=newmode.col;
  145. maxrows:=newmode.row;
  146. end
  147. else
  148. begin
  149. maxcols:=modecols[mode and 15];
  150. maxrows:=moderows[mode shr 4];
  151. crt_error:=cenoerror;
  152. {Set correct vertical resolution.}
  153. asm
  154. movw $0x1202,%ax
  155. movw 8(%ebp),%bx
  156. shrw $4,%bx
  157. cmpb $2,%bl
  158. jne crtsetmode_a1
  159. decw %ax
  160. crtsetmode_a1:
  161. mov $0x30,%bl
  162. int $0x10
  163. end;
  164. {132 column mode in DOS is videocard dependend.}
  165. if mode and 15=2 then
  166. begin
  167. crt_error:=cemodeset;
  168. exit;
  169. end;
  170. {Switch to correct mode.}
  171. asm
  172. mov 8(%ebp),%bx
  173. and $15,%bl
  174. mov $1,%ax
  175. cmp $1,%bl
  176. jne crtsetmode_b1
  177. mov $3,%al
  178. crtsetmode_b1:
  179. int $0x10
  180. {Use alternate print-screen function.}
  181. mov $0x12,%ah
  182. mov $0x20,%bl
  183. int $0x10
  184. end;
  185. {Set correct font.}
  186. case mode shr 4 of
  187. 1:
  188. {Set 8x14 font.}
  189. asm
  190. mov $0x1111,%ax
  191. mov $0,%bl
  192. int $0x10
  193. end;
  194. 2,3:
  195. {Set 8x8 font.}
  196. asm
  197. mov $0x1112,%ax
  198. mov $0,%bl
  199. int $0x10
  200. end;
  201. end;
  202. end;
  203. end;
  204. procedure getcursor(var y,x:word);
  205. {Get the cursor position.}
  206. begin
  207. if os_mode=osOS2 then
  208. viogetcurpos(y,x,0)
  209. else
  210. asm
  211. movb $3,%ah
  212. movb $0,%bh
  213. int $0x10
  214. movl y,%eax
  215. movl x,%ebx
  216. movb %dh,(%eax)
  217. movb %dl,(%ebx)
  218. end;
  219. end;
  220. procedure setcursor(y,x:word);
  221. {Set the cursor position.}
  222. begin
  223. if os_mode=osOS2 then
  224. viosetcurpos(y,x,0)
  225. else
  226. asm
  227. movb $2,%ah
  228. movb $0,%bh
  229. movb y,%dh
  230. movb x,%dl
  231. int $0x10
  232. end;
  233. end;
  234. procedure scroll_up(top,left,bottom,right,lines:word;var screl:word);
  235. begin
  236. if os_mode=osOS2 then
  237. vioscrollup(top,left,bottom,right,lines,screl,0)
  238. else
  239. asm
  240. movb $6,%ah
  241. movb lines,%al
  242. movl screl,%edi
  243. movb 1(%edi),%bh
  244. movb top,%ch
  245. movb left,%cl
  246. movb bottom,%dh
  247. movb right,%dl
  248. int $0x10
  249. end;
  250. end;
  251. procedure scroll_dn(top,left,bottom,right,lines:word;var screl:word);
  252. begin
  253. if os_mode=osOS2 then
  254. vioscrolldn(top,left,bottom,right,lines,screl,0)
  255. else
  256. asm
  257. movb $7,%ah
  258. movb lines,%al
  259. movl screl,%edi
  260. movb 1(%edi),%bh
  261. movb top,%ch
  262. movb left,%cl
  263. movb bottom,%dh
  264. movb right,%dl
  265. int $0x10
  266. end;
  267. end;
  268. function keypressed:boolean;
  269. {Checks if a key is pressed.}
  270. var Akeyrec:Tkbdkeyinfo;
  271. begin
  272. if os_mode=osOS2 then
  273. begin
  274. kbdpeek(Akeyrec,0);
  275. keypressed:=(extkeycode<>#0) or ((Akeyrec.fbstatus and $40)<>0);
  276. end
  277. else
  278. begin
  279. if extkeycode<>#0 then
  280. begin
  281. keypressed:=true;
  282. exit
  283. end
  284. else
  285. asm
  286. movb $1,%ah
  287. int $0x16
  288. setnz %al
  289. movb %al,__RESULT
  290. end;
  291. end;
  292. end;
  293. function readkey:char;
  294. {Reads the next character from the keyboard.}
  295. var Akeyrec:Tkbdkeyinfo;
  296. c,s:char;
  297. begin
  298. if extkeycode<>#0 then
  299. begin
  300. readkey:=extkeycode;
  301. extkeycode:=#0
  302. end
  303. else
  304. begin
  305. if os_mode=osOS2 then
  306. begin
  307. kbdcharin(Akeyrec,0,0);
  308. c:=Akeyrec.charcode;
  309. s:=Akeyrec.scancode;
  310. if (c=#224) and (s<>#0) then
  311. c:=#0;
  312. end
  313. else
  314. begin
  315. asm
  316. movb $0,%ah
  317. int $0x16
  318. movb %al,c
  319. movb %ah,s
  320. end;
  321. end;
  322. if c=#0 then
  323. extkeycode:=s;
  324. readkey:=c;
  325. end;
  326. end;
  327. procedure clrscr;
  328. {Clears the current window.}
  329. var screl:word;
  330. begin
  331. screl:=$20+textattr shl 8;
  332. scroll_up(hi(windmin),lo(windmin),
  333. hi(windmax),lo(windmax),
  334. hi(windmax)-hi(windmin)+1,
  335. screl);
  336. gotoXY(1,1);
  337. end;
  338. procedure gotoXY(x,y:byte);
  339. {Positions the cursor on (x,y) relative to the window origin.}
  340. begin
  341. if x<1 then
  342. x:=1;
  343. if y<1 then
  344. y:=1;
  345. if y+hi(windmin)-2>=hi(windmax) then
  346. y:=hi(windmax)-hi(windmin)+1;
  347. if x+lo(windmin)-2>=lo(windmax) then
  348. x:=lo(windmax)-lo(windmin)+1;
  349. setcursor(y+hi(windmin)-1,x+lo(windmin)-1);
  350. end;
  351. function whereX:byte;
  352. {Returns the x position of the cursor.}
  353. var x,y:word;
  354. begin
  355. getcursor(y,x);
  356. whereX:=x-lo(windmin)+1;
  357. end;
  358. function whereY:byte;
  359. {Returns the y position of the cursor.}
  360. var x,y:word;
  361. begin
  362. getcursor(y,x);
  363. whereY:=y-hi(windmin)+1;
  364. end;
  365. procedure clreol;
  366. {Clear from current position to end of line.
  367. Contributed by Michail A. Baikov}
  368. var i:byte;
  369. begin
  370. {not fastest, but compatible}
  371. for i:=wherex to lo(windmax) do write(' ');
  372. gotoxy(1,wherey); {may be not}
  373. end;
  374. procedure delline;
  375. {Deletes the line at the cursor.}
  376. var row,left,right,bot:longint;
  377. fil:word;
  378. begin
  379. row:=whereY;
  380. left:=lo(windmin)+1;
  381. right:=lo(windmax)+1;
  382. bot:=hi(windmax)+1;
  383. fil:=$20 or (textattr shl 8);
  384. scroll_up(row+1,left,bot,right,1,fil);
  385. end;
  386. procedure insline;
  387. {Inserts a line at the cursor position.}
  388. var row,left,right,bot:longint;
  389. fil:word;
  390. begin
  391. row:=whereY;
  392. left:=lo(windmin)+1;
  393. right:=lo(windmax)+1;
  394. bot:=hi(windmax);
  395. fil:=$20 or (textattr shl 8);
  396. scroll_dn(row,left,bot-1,right,1,fil);
  397. end;
  398. procedure textmode(mode:integer);
  399. { Use this procedure to set-up a specific text-mode.}
  400. begin
  401. textattr:=$07;
  402. lastmode:=mode;
  403. mode:=mode and $ff;
  404. setscreenmode(mode);
  405. windmin:=0;
  406. windmax:=(maxcols-1) or ((maxrows-1) shl 8);
  407. clrscr;
  408. end;
  409. procedure textcolor(colour:byte);
  410. {All text written after calling this will have color as foreground colour.}
  411. begin
  412. textattr:=(textattr and $70) or (colour and $f)+colour and 128;
  413. end;
  414. procedure textbackground(colour:byte);
  415. {All text written after calling this will have colour as background colour.}
  416. begin
  417. textattr:=(textattr and $8f) or ((colour and $7) shl 4);
  418. end;
  419. procedure normvideo;
  420. {Changes the text-background to black and the foreground to white.}
  421. begin
  422. textattr:=$7;
  423. end;
  424. procedure lowvideo;
  425. {All text written after this will have low intensity.}
  426. begin
  427. textattr:=textattr and $f7;
  428. end;
  429. procedure highvideo;
  430. {All text written after this will have high intensity.}
  431. begin
  432. textattr:=textattr or $8;
  433. end;
  434. procedure delay(ms:word);
  435. var i,j:longint;
  436. {Waits ms microseconds. The DOS code is copied from the DOS rtl.}
  437. begin
  438. {Under OS/2 we could also calibrate like under DOS. But this is
  439. unreliable, because OS/2 can hold our programs while calibrating,
  440. if it needs the processor for other things.}
  441. if os_mode=osOS2 then
  442. dossleep(ms)
  443. else
  444. begin
  445. for i:=1 to ms do
  446. for j:=1 to calibration do
  447. begin
  448. end;
  449. end;
  450. end;
  451. procedure window(left,top,right,bottom:byte);
  452. {Change the write window to the given coordinates.}
  453. begin
  454. if (left<1) or
  455. (top<1) or
  456. (right>maxcols) or
  457. (bottom>maxrows) or
  458. (left>right) or
  459. (top>bottom) then
  460. exit;
  461. windmin:=(left-1) or ((top-1) shl 8);
  462. windmax:=(right-1) or ((bottom-1) shl 8);
  463. gotoXY(1,1);
  464. end;
  465. procedure writePchar(s:Pchar;len:word);
  466. {Write a series of characters to the screen.
  467. Not very fast, but is just text-mode isn't it?}
  468. var x,y:word;
  469. c:char;
  470. i,n:integer;
  471. screl:word;
  472. ca:Pchar;
  473. begin
  474. i:=0;
  475. getcursor(y,x);
  476. while i<=len-1 do
  477. begin
  478. case s[i] of
  479. #8:
  480. x:=x-1;
  481. #9:
  482. x:=(x-lo(windmin)) and $fff8+8+lo(windmin);
  483. #10:
  484. ;
  485. #13:
  486. begin
  487. x:=lo(windmin);
  488. inc(y);
  489. end;
  490. else
  491. begin
  492. ca:=@s[i];
  493. n:=1;
  494. while not(s[i+1] in [#8,#9,#10,#13]) and
  495. (x+n<=lo(windmax)+1) and (i<len-1) do
  496. begin
  497. inc(n);
  498. inc(i);
  499. end;
  500. if os_mode=osOS2 then
  501. viowrtcharstratt(ca,n,y,x,textattr,0)
  502. else
  503. asm
  504. movw $0x1300,%ax
  505. movb $0,%bh
  506. movb U_CRT_TEXTATTR,%bl
  507. movb y,%dh
  508. movb x,%dl
  509. movw n,%cx
  510. pushl %ebp
  511. movl ca,%ebp
  512. int $0x10
  513. popl %ebp
  514. end;
  515. x:=x+n;
  516. end;
  517. end;
  518. if x>lo(windmax) then
  519. begin
  520. x:=lo(windmin);
  521. inc(y);
  522. end;
  523. if y>hi(windmax) then
  524. begin
  525. screl:=$20+textattr shl 8;
  526. scroll_up(hi(windmin),lo(windmin),
  527. hi(windmax),lo(windmax),
  528. 1,screl);
  529. y:=hi(windmax);
  530. end;
  531. { writeln(stderr,x,' ',y);}
  532. inc(i);
  533. end;
  534. setcursor(y,x);
  535. end;
  536. function crtread(var f:textrec):word;
  537. {Read a series of characters from the console.}
  538. var max,curpos,i:integer;
  539. c:char;
  540. clist:array[0..2] of char;
  541. begin
  542. max:=f.bufsize-2;
  543. curpos:=0;
  544. repeat
  545. c:=readkey;
  546. case c of
  547. #0:
  548. readkey;
  549. #8:
  550. if curpos>0 then
  551. begin
  552. clist:=#8' '#8;
  553. writePchar(@clist,3);
  554. dec(curpos);
  555. end;
  556. #13:
  557. begin
  558. f.bufptr^[curpos]:=#13;
  559. inc(curpos);
  560. f.bufptr^[curpos]:=#10;
  561. inc(curpos);
  562. f.bufpos:=0;
  563. f.bufend:=curpos;
  564. clist[0]:=#13;
  565. writePchar(@clist,1);
  566. break;
  567. end;
  568. #32..#255:
  569. if curpos<max then
  570. begin
  571. f.bufptr^[curpos]:=c;
  572. inc(curpos);
  573. writePchar(@c,1);
  574. end;
  575. end;
  576. until false;
  577. crtread:=0;
  578. end;
  579. function crtwrite(var f:textrec):word;
  580. {Write a series of characters to the console.}
  581. begin
  582. writePchar(Pchar(f.bufptr),f.bufpos);
  583. f.bufpos:=0;
  584. crtwrite:=0;
  585. end;
  586. function crtopen(var f:textrec):integer;
  587. begin
  588. if f.mode=fmoutput then
  589. crtopen:=0
  590. else
  591. crtopen:=5;
  592. end;
  593. function crtinout(var f:textrec):integer;
  594. begin
  595. case f.mode of
  596. fminput:
  597. crtinout:=crtread(f);
  598. fmoutput:
  599. crtinout:=crtwrite(f);
  600. end;
  601. end;
  602. function crtclose(var f:textrec):integer;
  603. begin
  604. f.mode:=fmclosed;
  605. crtclose:=0;
  606. end;
  607. procedure assigncrt(var f:text);
  608. {Assigns a file to the crt console.}
  609. begin
  610. textrec(f).mode:=fmclosed;
  611. textrec(f).bufsize:=128;
  612. textrec(f).bufptr:=@textrec(f).buffer;
  613. textrec(f).bufpos:=0;
  614. textrec(f).openfunc:=@crtopen;
  615. textrec(f).inoutfunc:=@crtinout;
  616. textrec(f).flushfunc:=@crtinout;
  617. textrec(f).closefunc:=@crtclose;
  618. textrec(f).name[0]:='.';
  619. textrec(f).name[0]:=#0;
  620. end;
  621. procedure sound(hz:word);
  622. {sound and nosound are not implemented because the OS/2 API supports a freq/
  623. duration procedure instead of start/stop procedures.}
  624. begin
  625. end;
  626. procedure nosound;
  627. begin
  628. end;
  629. function get_ticks:word;
  630. type Pword=^word;
  631. begin
  632. get_ticks:=Pword(longint(first_meg)+$46c)^;
  633. end;
  634. procedure initdelay;
  635. {Calibrate the delay procedure. Copied from DOS rtl.}
  636. var first:word;
  637. begin
  638. calibration:=0;
  639. { wait for new tick }
  640. first:=get_ticks;
  641. while get_ticks=first do
  642. begin
  643. end;
  644. first:=get_ticks;
  645. { this estimates calibration }
  646. while get_ticks=first do
  647. inc(calibration);
  648. { calculate this to ms }
  649. calibration:=calibration div 70;
  650. while true do
  651. begin
  652. first:=get_ticks;
  653. while get_ticks=first do
  654. begin
  655. end;
  656. first:=get_ticks;
  657. delay(55);
  658. if first=get_ticks then
  659. exit
  660. else
  661. begin
  662. { decrement calibration two percent }
  663. calibration:=calibration-calibration div 50;
  664. dec(calibration);
  665. end;
  666. end;
  667. end;
  668. {Initialization.}
  669. type Pbyte=^byte;
  670. var curmode:viomodeinfo;
  671. mode:byte;
  672. begin
  673. textattr:=lightgray;
  674. if os_mode=osOS2 then
  675. begin
  676. curmode.cb:=sizeof(curmode);
  677. viogetmode(curmode,0);
  678. maxcols:=curmode.col;
  679. maxrows:=curmode.row;
  680. lastmode:=0;
  681. case maxcols of
  682. 40:
  683. lastmode:=0;
  684. 80:
  685. lastmode:=1;
  686. 132:
  687. lastmode:=2;
  688. end;
  689. case maxrows of
  690. 25:;
  691. 28:
  692. lastmode:=lastmode+16;
  693. 43:
  694. lastmode:=lastmode+32;
  695. 50:
  696. lastmode:=lastmode+48;
  697. end
  698. end
  699. else
  700. begin
  701. {Request video mode to determine columns.}
  702. asm
  703. mov $0x0f,%ah
  704. int $0x10
  705. mov %al,_MODE
  706. end;
  707. case mode of
  708. 0,1:
  709. begin
  710. lastmode:=0;
  711. maxcols:=40;
  712. end;
  713. else
  714. begin
  715. lastmode:=1;
  716. maxcols:=80;
  717. end;
  718. end;
  719. {Get number of rows from realmode $0040:$0084.}
  720. maxrows:=Pbyte(longint(first_meg)+$484)^;
  721. case maxrows of
  722. 25:;
  723. 28:
  724. lastmode:=lastmode+16;
  725. 43:
  726. lastmode:=lastmode+32;
  727. 50:
  728. lastmode:=lastmode+48;
  729. end
  730. end;
  731. windmin:=0;
  732. windmax:=((maxrows-1) shl 8) or (maxcols-1);
  733. if os_mode=osDOS then
  734. initdelay;
  735. crt_error:=cenoerror;
  736. assigncrt(input);
  737. textrec(input).mode:=fminput;
  738. assigncrt(output);
  739. textrec(output).mode:=fmoutput;
  740. end.