crt.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1997 by Nils Sjoholm
  5. member of the Amiga RTL 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. const
  15. { screen modes }
  16. bw40 = 0;
  17. co40 = 1;
  18. bw80 = 2;
  19. co80 = 3;
  20. mono = 7;
  21. font8x8 = 256;
  22. { screen color, fore- and background }
  23. black = 0;
  24. blue = 1;
  25. green = 2;
  26. cyan = 3;
  27. red = 4;
  28. magenta = 5;
  29. brown = 6;
  30. lightgray = 7;
  31. { only foreground }
  32. darkgray = 8;
  33. lightblue = 9;
  34. lightgreen = 10;
  35. lightcyan = 11;
  36. lightred = 12;
  37. lightmagenta = 13;
  38. yellow = 14;
  39. white = 15;
  40. { blink flag }
  41. blink = $80;
  42. var
  43. { for compatibility }
  44. checkbreak,checkeof,checksnow : boolean;
  45. { works in another way than in TP }
  46. { true: cursor is set with direct port access }
  47. { false: cursor is set with a bios call }
  48. directvideo : boolean;
  49. lastmode : word; { screen mode}
  50. textattr : byte; { current text attribute }
  51. windmin : word; { upper right corner of the CRT window }
  52. windmax : word; { lower left corner of the CRT window }
  53. function keypressed : boolean;
  54. function readkey : char;
  55. procedure gotoxy(x,y : integer);
  56. procedure window(left,top,right,bottom : byte);
  57. procedure clrscr;
  58. procedure textcolor(color : byte);
  59. procedure textbackground(color : byte);
  60. procedure assigncrt(var f : text);
  61. function wherex : integer;
  62. function wherey : integer;
  63. procedure delline;
  64. procedure delline(line : byte);
  65. procedure clreol;
  66. procedure insline;
  67. procedure cursoron;
  68. procedure cursoroff;
  69. procedure cursorbig;
  70. procedure lowvideo;
  71. procedure highvideo;
  72. procedure nosound;
  73. procedure sound(hz : word);
  74. procedure delay(ms : longint);
  75. procedure textmode(mode : integer);
  76. procedure normvideo;
  77. implementation
  78. Type
  79. {$PACKRECORDS 4}
  80. { returned by Info(), must be on a 4 byte boundary }
  81. pInfoData = ^tInfoData;
  82. tInfoData = record
  83. id_NumSoftErrors : Longint; { number of soft errors on disk }
  84. id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
  85. id_DiskState : Longint; { See defines below }
  86. id_NumBlocks : Longint; { Number of blocks on disk }
  87. id_NumBlocksUsed : Longint; { Number of block in use }
  88. id_BytesPerBlock : Longint;
  89. id_DiskType : Longint; { Disk Type code }
  90. id_VolumeNode : Longint; { BCPL pointer to volume node }
  91. id_InUse : Longint; { Flag, zero if not in use }
  92. end;
  93. { * List Node Structure. Each member in a list starts with a Node * }
  94. pNode = ^tNode;
  95. tNode = Record
  96. ln_Succ, { * Pointer to next (successor) * }
  97. ln_Pred : pNode; { * Pointer to previous (predecessor) * }
  98. ln_Type : Byte;
  99. ln_Pri : Shortint; { * Priority, for sorting * }
  100. ln_Name : PChar; { * ID string, null terminated * }
  101. End; { * Note: Integer aligned * }
  102. {$PACKRECORDS NORMAL}
  103. { normal, full featured list }
  104. pList = ^tList;
  105. tList = record
  106. lh_Head : pNode;
  107. lh_Tail : pNode;
  108. lh_TailPred : pNode;
  109. lh_Type : Byte;
  110. l_pad : Byte;
  111. end;
  112. pMsgPort = ^tMsgPort;
  113. tMsgPort = record
  114. mp_Node : tNode;
  115. mp_Flags : Byte;
  116. mp_SigBit : Byte; { signal bit number }
  117. mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
  118. mp_MsgList : tList; { message linked list }
  119. end;
  120. pMessage = ^tMessage;
  121. tMessage = record
  122. mn_Node : tNode;
  123. mn_ReplyPort : pMsgPort; { message reply port }
  124. mn_Length : Word; { message len in bytes }
  125. end;
  126. pIOStdReq = ^tIOStdReq;
  127. tIOStdReq = record
  128. io_Message : tMessage;
  129. io_Device : Pointer; { device node pointer }
  130. io_Unit : Pointer; { unit (driver private)}
  131. io_Command : Word; { device command }
  132. io_Flags : Byte;
  133. io_Error : Shortint; { error or warning num }
  134. io_Actual : Longint; { actual number of bytes transferred }
  135. io_Length : Longint; { requested number bytes transferred}
  136. io_Data : Pointer; { points to data area }
  137. io_Offset : Longint; { offset for block structured devices }
  138. end;
  139. pIntuiMessage = ^tIntuiMessage;
  140. tIntuiMessage = record
  141. ExecMessage : tMessage;
  142. Class_ : Longint;
  143. Code : Word;
  144. Qualifier : Word;
  145. IAddress : Pointer;
  146. MouseX,
  147. MouseY : Word;
  148. Seconds,
  149. Micros : Longint;
  150. IDCMPWindow : Pointer;
  151. SpecialLink : pIntuiMessage;
  152. end;
  153. pWindow = ^tWindow;
  154. tWindow = record
  155. NextWindow : pWindow; { for the linked list in a screen }
  156. LeftEdge,
  157. TopEdge : Integer; { screen dimensions of window }
  158. Width,
  159. Height : Integer; { screen dimensions of window }
  160. MouseY,
  161. MouseX : Integer; { relative to upper-left of window }
  162. MinWidth,
  163. MinHeight : Integer; { minimum sizes }
  164. MaxWidth,
  165. MaxHeight : Word; { maximum sizes }
  166. Flags : Longint; { see below for defines }
  167. MenuStrip : Pointer; { the strip of Menu headers }
  168. Title : PChar; { the title text for this window }
  169. FirstRequest : Pointer; { all active Requesters }
  170. DMRequest : Pointer; { double-click Requester }
  171. ReqCount : Integer; { count of reqs blocking Window }
  172. WScreen : Pointer; { this Window's Screen }
  173. RPort : Pointer; { this Window's very own RastPort }
  174. BorderLeft,
  175. BorderTop,
  176. BorderRight,
  177. BorderBottom : Shortint;
  178. BorderRPort : Pointer;
  179. FirstGadget : Pointer;
  180. Parent,
  181. Descendant : pWindow;
  182. Pointer_ : Pointer; { sprite data }
  183. PtrHeight : Shortint; { sprite height (not including sprite padding) }
  184. PtrWidth : Shortint; { sprite width (must be less than or equal to 16) }
  185. XOffset,
  186. YOffset : Shortint; { sprite offsets }
  187. IDCMPFlags : Longint; { User-selected flags }
  188. UserPort,
  189. WindowPort : pMsgPort;
  190. MessageKey : pIntuiMessage;
  191. DetailPen,
  192. BlockPen : Byte; { for bar/border/gadget rendering }
  193. CheckMark : Pointer;
  194. ScreenTitle : PChar; { if non-null, Screen title when Window is active }
  195. GZZMouseX : Integer;
  196. GZZMouseY : Integer;
  197. GZZWidth : Integer;
  198. GZZHeight : Word;
  199. ExtData : Pointer;
  200. UserData : Pointer; { general-purpose pointer to User data extension }
  201. WLayer : Pointer;
  202. IFont : Pointer;
  203. MoreFlags : Longint;
  204. end;
  205. pConUnit = ^tConUnit;
  206. tConUnit = record
  207. cu_MP : tMsgPort;
  208. cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
  209. cu_XCP : Integer; { character position }
  210. cu_YCP : Integer;
  211. cu_XMax : Integer; { max character position }
  212. cu_YMax : Integer;
  213. cu_XRSize : Integer; { character raster size }
  214. cu_YRSize : Integer;
  215. cu_XROrigin : Integer; { raster origin }
  216. cu_YROrigin : Integer;
  217. cu_XRExtant : Integer; { raster maxima }
  218. cu_YRExtant : Integer;
  219. cu_XMinShrink : Integer; { smallest area intact from resize process }
  220. cu_YMinShrink : Integer;
  221. cu_XCCP : Integer; { cursor position }
  222. cu_YCCP : Integer;
  223. cu_KeyMapStruct : Pointer;
  224. cu_TabStops : Array [0..80-1] of Word;
  225. cu_Mask : Shortint;
  226. cu_FgPen : Shortint;
  227. cu_BgPen : Shortint;
  228. cu_AOLPen : Shortint;
  229. cu_DrawMode : Shortint;
  230. cu_AreaPtSz : Shortint;
  231. cu_AreaPtrn : Pointer; { cursor area pattern }
  232. cu_Minterms : Array [0..7] of Byte; { console minterms }
  233. cu_Font : Pointer; { (TextFontPtr) }
  234. cu_AlgoStyle : Byte;
  235. cu_TxFlags : Byte;
  236. cu_TxHeight : Word;
  237. cu_TxWidth : Word;
  238. cu_TxBaseline : Word;
  239. cu_TxSpacing : Word;
  240. cu_Modes : Array [0..(22+7) div 8 - 1] of Byte;
  241. cu_RawEvents : Array [0..($15+7) div 8 - 1] of Byte;
  242. end;
  243. const
  244. CD_CURRX = 1;
  245. CD_CURRY = 2;
  246. CD_MAXX = 3;
  247. CD_MAXY = 4;
  248. function AllocVec( size, reqm : Longint ): Pointer; Assembler;
  249. asm
  250. MOVE.L A6,-(A7)
  251. MOVE.L _ExecBase,A6
  252. MOVE.L size,d0
  253. MOVE.L reqm,d1
  254. JSR -684(A6)
  255. MOVE.L (A7)+,A6
  256. end;
  257. function DoPkt(ID : pMsgPort;
  258. Action, Param1, Param2,
  259. Param3, Param4, Param5 : Longint) : Longint; Assembler;
  260. asm
  261. MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
  262. MOVE.L _DOSBase,A6
  263. MOVE.L ID,d1
  264. MOVE.L Action,d2
  265. MOVE.L Param1,d3
  266. MOVE.L Param2,d4
  267. MOVE.L Param3,d5
  268. MOVE.L Param4,d6
  269. MOVE.L Param5,d7
  270. JSR -240(A6)
  271. MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
  272. end;
  273. procedure FreeVec( memory : Pointer ); Assembler;
  274. asm
  275. MOVE.L A6,-(A7)
  276. MOVE.L _ExecBase,A6
  277. MOVE.L memory,a1
  278. JSR -690(A6)
  279. MOVE.L (A7)+,A6
  280. end;
  281. function GetConsoleTask : pMsgPort; Assembler;
  282. asm
  283. MOVE.L A6,-(A7)
  284. MOVE.L _DOSBase,A6
  285. JSR -510(A6)
  286. MOVE.L (A7)+,A6
  287. end;
  288. function GetMsg(port : pMsgPort): pMessage; Assembler;
  289. asm
  290. MOVE.L A6,-(A7)
  291. MOVE.L _ExecBase,A6
  292. MOVE.L port,a0
  293. JSR -372(A6)
  294. MOVE.L (A7)+,A6
  295. end;
  296. function ModifyIDCMP(window : pWindow;
  297. IDCMPFlags : Longint) : Boolean; Assembler;
  298. asm
  299. MOVE.L A6,-(A7)
  300. MOVE.L _IntuitionBase,A6
  301. MOVE.L window,a0
  302. MOVE.L IDCMPFlags,d0
  303. JSR -150(A6)
  304. MOVE.L (A7)+,A6
  305. TST.L d0
  306. SNE d0
  307. end;
  308. procedure ReplyMsg(mess : pMessage); Assembler;
  309. asm
  310. MOVE.L A6,-(A7)
  311. MOVE.L _ExecBase,A6
  312. MOVE.L mess,a1
  313. JSR -378(A6)
  314. MOVE.L (A7)+,A6
  315. end;
  316. function WaitPort(port : pMsgPort): pMessage; Assembler;
  317. asm
  318. MOVE.L A6,-(A7)
  319. MOVE.L _ExecBase,A6
  320. MOVE.L port,a0
  321. JSR -384(A6)
  322. MOVE.L (A7)+,A6
  323. end;
  324. procedure Delay_(ticks : Integer); Assembler;
  325. asm
  326. MOVE.L A6,-(A7)
  327. MOVE.L _DOSBase,A6
  328. MOVE.L ticks,d1
  329. JSR -198(A6)
  330. MOVE.L (A7)+,A6
  331. end;
  332. function OpenInfo : pInfoData;
  333. var
  334. port : pMsgPort;
  335. info : pInfoData;
  336. bptr, d4, d5, d6, d7 : Longint;
  337. begin
  338. info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
  339. if info <> nil then begin
  340. port := GetConsoleTask;
  341. bptr := Longint(info) shr 2;
  342. if port <> nil then begin
  343. if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
  344. else port := nil;
  345. end;
  346. if port = nil then begin
  347. FreeVec(info);
  348. info := nil;
  349. end;
  350. end;
  351. OpenInfo := info;
  352. end;
  353. procedure CloseInfo(var info : pInfoData);
  354. begin
  355. if info <> nil then begin
  356. FreeVec(info);
  357. info := nil;
  358. end;
  359. end;
  360. function ConData(modus : byte) : integer;
  361. var
  362. info : pInfoData;
  363. theunit : pConUnit;
  364. pos : Longint;
  365. begin
  366. pos := 1;
  367. info := OpenInfo;
  368. if info <> nil then begin
  369. theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
  370. case modus of
  371. CD_CURRX : pos := theunit^.cu_XCP;
  372. CD_CURRY : pos := theunit^.cu_YCP;
  373. CD_MAXX : pos := theunit^.cu_XMax;
  374. CD_MAXY : pos := theunit^.cu_YMax;
  375. end;
  376. CloseInfo(info);
  377. end;
  378. ConData := pos + 1;
  379. end;
  380. function wherex : integer;
  381. begin
  382. wherex := ConData(CD_CURRX);
  383. end;
  384. function wherey : integer;
  385. begin
  386. wherey := ConData(CD_CURRY);
  387. end;
  388. function maxx : integer;
  389. begin
  390. maxx := ConData(CD_MAXX);
  391. end;
  392. function maxy : integer;
  393. begin
  394. maxy := ConData(CD_MAXY);
  395. end;
  396. procedure gotoxy(x, y : integer);
  397. var
  398. mx, my : integer;
  399. begin
  400. mx := maxx;
  401. my := maxy;
  402. if x < 1 then x := wherex
  403. else if x > mx then x := mx;
  404. if y < 1 then y := wherey
  405. else if y > my then y := my;
  406. Write($9b, y, ';', x, 'H');
  407. end;
  408. procedure cursoroff;
  409. begin
  410. Write($9b,'0 p');
  411. end;
  412. procedure cursoron;
  413. begin
  414. Write($9b,'1 p');
  415. end;
  416. procedure clrscr;
  417. begin
  418. Write(Chr($0c));
  419. end;
  420. function ReadKey : char;
  421. const
  422. IDCMP_VANILLAKEY = $00200000;
  423. IDCMP_RAWKEY = $00000400;
  424. var
  425. info : pInfoData;
  426. win : pWindow;
  427. imsg : pIntuiMessage;
  428. msg : pMessage;
  429. key : char;
  430. idcmp, vanil : longint;
  431. begin
  432. key := #0;
  433. info := OpenInfo;
  434. if info <> nil then begin
  435. win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
  436. idcmp := win^.IDCMPFlags;
  437. vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
  438. ModifyIDCMP(win, (idcmp or vanil));
  439. repeat
  440. msg := WaitPort(win^.UserPort);
  441. imsg := pIntuiMessage(GetMsg(win^.UserPort));
  442. if (imsg^.Class_ = IDCMP_VANILLAKEY) or (imsg^.Class_ = IDCMP_RAWKEY) then key := char(imsg^.Code);
  443. ReplyMsg(pMessage(imsg));
  444. until key <> char(0);
  445. repeat
  446. msg := GetMsg(win^.UserPort);
  447. if msg <> nil then ReplyMsg(msg);
  448. until msg = nil;
  449. ModifyIDCMP(win, idcmp);
  450. CloseInfo(info);
  451. end;
  452. ReadKey := key;
  453. end;
  454. procedure textcolor(fgpen : byte);
  455. begin
  456. Write($9b, '3', fgpen, 'm');
  457. end;
  458. procedure textbackground(bgpen : byte);
  459. begin
  460. Write($9b, '4', bgpen, 'm');
  461. end;
  462. function keypressed : boolean;
  463. begin
  464. keypressed := true;
  465. end;
  466. procedure window(left,top,right,bottom : byte);
  467. begin
  468. end;
  469. procedure assigncrt(var f : text);
  470. begin
  471. end;
  472. procedure delline;
  473. begin
  474. Write($9b,'X');
  475. end;
  476. procedure delline(line : byte);
  477. begin
  478. Write($9b,'X');
  479. end;
  480. procedure clreol;
  481. begin
  482. Write($9b,'K');
  483. end;
  484. procedure insline;
  485. begin
  486. Write($9b,'1 L');
  487. end;
  488. procedure cursorbig;
  489. begin
  490. end;
  491. procedure lowvideo;
  492. begin
  493. end;
  494. procedure highvideo;
  495. begin
  496. end;
  497. procedure nosound;
  498. begin
  499. end;
  500. procedure sound(hz : word);
  501. begin
  502. end;
  503. { MsDos have 1000 ticks per second
  504. and Amiga only 50, so we have to
  505. do some calcs here.
  506. The min value this procedure will
  507. handle is 20, (less you will get 0)
  508. this will be 1 tick in Amiga. If
  509. you want to use amigados delay just
  510. use Delay_. }
  511. procedure delay(ms : longint);
  512. var
  513. dummy : integer;
  514. begin
  515. dummy := trunc((real(ms) / 1000.0) * 50.0);
  516. Delay_(dummy);
  517. end;
  518. procedure textmode(mode : integer);
  519. begin
  520. end;
  521. procedure normvideo;
  522. begin
  523. end;
  524. end.