crt.pas 22 KB

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