crt.pas 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. {****************************************************************************
  2. Standard CRT unit.
  3. Free Pascal runtime library for OS/2.
  4. Copyright (c) 1997 Daniel Mantione.
  5. This file may be reproduced and modified under the same conditions
  6. as all other Free Pascal source code.
  7. ****************************************************************************}
  8. unit crt;
  9. interface
  10. {$i crth.inc}
  11. procedure Window32 (X1, Y1, X2, Y2: dword);
  12. procedure GotoXY32 (X, Y: dword);
  13. function WhereX32: dword;
  14. function WhereY32: dword;
  15. var
  16. ScreenHeight, ScreenWidth: dword;
  17. (* API *)
  18. implementation
  19. {uses keyboard, video;}
  20. {$i textrec.inc}
  21. const
  22. VioHandle: word = 0;
  23. type
  24. TKbdKeyInfo = record
  25. CharCode, ScanCode: char;
  26. fbStatus, bNlsShift: byte;
  27. fsState: word;
  28. Time: longint;
  29. end;
  30. VioModeInfo = record
  31. cb: word; { length of the entire data
  32. structure }
  33. fbType, { bit mask of mode being set}
  34. Color: byte; { number of colors (power of 2) }
  35. Col, { number of text columns }
  36. Row, { number of text rows }
  37. HRes, { horizontal resolution }
  38. VRes: word; { vertical resolution }
  39. fmt_ID, { attribute format }
  40. Attrib: byte; { number of attributes }
  41. Buf_Addr, { physical address of
  42. videobuffer, e.g. $0b800}
  43. Buf_Length, { length of a videopage (bytes)}
  44. Full_Length, { total video-memory on video-
  45. card (bytes)}
  46. Partial_Length: longint; { ????? info wanted !}
  47. Ext_Data_Addr: pointer; { ????? info wanted !}
  48. end;
  49. TVioCursorInfo=record
  50. case boolean of
  51. false: (
  52. yStart: word; {Cursor start (top) scan line (0-based)}
  53. cEnd: word; {Cursor end (bottom) scan line}
  54. cx: word; {Cursor width (0=default width)}
  55. Attr: word); {Cursor colour attribute (-1=hidden)}
  56. true:(
  57. yStartInt: integer; {integer variants can be used to specify negative}
  58. cEndInt: integer; {negative values (interpreted as percentage by OS/2)}
  59. cxInt: integer;
  60. AttrInt: integer);
  61. end;
  62. PVioCursorInfo = ^TVioCursorInfo;
  63. function KbdCharIn (var AKeyRec: TKbdKeyInfo; Wait, KbdHandle: longint):
  64. word; cdecl;
  65. external 'EMXWRAP' index 204;
  66. function KbdPeek (var AKeyRec: TKbdKeyInfo; KbdHandle: longint): word; cdecl;
  67. external 'EMXWRAP' index 222;
  68. function DosSleep (Time: cardinal): word; cdecl;
  69. external 'DOSCALLS' index 229;
  70. function VioScrollUp (Top, Left, Bottom, Right, Lines: longint;
  71. var ScrEl: word; VioHandle: word): word; cdecl;
  72. external 'EMXWRAP' index 107;
  73. {$WARNING ScrEl as word not DBCS safe!}
  74. function VioScrollDn (Top, Left, Bottom, Right, Lines: longint;
  75. var ScrEl: word; VioHandle: word): word; cdecl;
  76. external 'EMXWRAP' index 147;
  77. function VioScrollRight (Top, Left, Bottom, Right, Columns: word;
  78. var ScrEl: word; VioHandle: word): word; cdecl;
  79. external 'EMXWRAP' index 112;
  80. {external 'VIOCALLS' index 12;}
  81. function VioGetCurPos (var Row, Column: word; VioHandle: word): word; cdecl;
  82. external 'EMXWRAP' index 109;
  83. function VioSetCurPos (Row, Column, VioHandle: word): word; cdecl;
  84. external 'EMXWRAP' index 115;
  85. function VioWrtCharStrAtt (S: PChar; Len, Row, Col: longint; var Attr: byte;
  86. VioHandle: word): word; cdecl;
  87. external 'EMXWRAP' index 148;
  88. function VioGetMode (var AModeInfo: VioModeInfo; VioHandle: word): word; cdecl;
  89. external 'EMXWRAP' index 121;
  90. function VioSetMode (var AModeInfo: VioModeInfo; VioHandle: word): word; cdecl;
  91. external 'EMXWRAP' index 122;
  92. function VioSetCurType (var CurData: TVioCursorInfo; VioHandle: word): word;
  93. cdecl;
  94. external 'EMXWRAP' index 132;
  95. {external 'VIOCALLS' index 32;}
  96. function VioGetCurType (var CurData: TVioCursorInfo; VioHandle: word): word;
  97. cdecl;
  98. external 'EMXWRAP' index 127;
  99. {external 'VIOCALLS' index 27;}
  100. function VioCreatePS (var VPS: word; Depth, Width, Format, Attrs: integer;
  101. Reserved: word): word; cdecl;
  102. external 'EMXWRAP' index 156;
  103. {external 'VIOCALLS' index 56;}
  104. function DosBeep (Freq, MS: cardinal): cardinal; cdecl;
  105. external 'DOSCALLS' index 286;
  106. {$ifdef HASTHREADVAR}
  107. threadvar
  108. {$else HASTHREADVAR}
  109. var
  110. {$endif HASTHREADVAR}
  111. ExtKeyCode: char;
  112. function KeyPressed: boolean;
  113. {Checks if a key is pressed.}
  114. var
  115. AKeyRec: TKbdKeyinfo;
  116. begin
  117. if ExtKeyCode <> #0 then
  118. KeyPressed := true
  119. else
  120. KeyPressed := (KbdPeek (AKeyRec, 0) = 0)
  121. and ((AKeyRec.fbStatus and $40) <> 0);
  122. end;
  123. function ReadKey: char;
  124. {Reads the next character from the keyboard.}
  125. var
  126. AKeyRec: TKbdKeyInfo;
  127. C, S: char;
  128. begin
  129. if ExtKeyCode <> #0 then
  130. begin
  131. ReadKey := ExtKeyCode;
  132. ExtKeyCode := #0
  133. end
  134. else
  135. begin
  136. KbdCharIn (AKeyRec, 0, 0);
  137. C := AKeyRec.CharCode;
  138. S := AKeyRec.ScanCode;
  139. if (C = #224) and (S <> #0) then
  140. C := #0;
  141. if C = #0 then
  142. ExtKeyCode := S;
  143. ReadKey := C;
  144. end;
  145. end;
  146. procedure GetScreenCursor (var X, Y: dword);inline;
  147. (* Return current cursor postion - 0-based. *)
  148. var
  149. X0, Y0: word;
  150. begin
  151. X := 0;
  152. Y := 0;
  153. if VioGetCurPos (Y0, X0, VioHandle) = 0 then
  154. begin
  155. X := X0;
  156. Y := Y0;
  157. end;
  158. end;
  159. procedure SetScreenCursor (X, Y: dword); inline;
  160. (* Set current cursor postion - 0-based. *)
  161. begin
  162. VioSetCurPos (Y, X, VioHandle);
  163. end;
  164. procedure RemoveLines (Row: dword; Cnt: dword); inline;
  165. (* Remove Cnt lines from screen starting with (0-based) Row. *)
  166. var
  167. ScrEl: word;
  168. begin
  169. ScrEl := $20 or (TextAttr shl 8);
  170. VioScrollUp (Row + WindMinY, WindMinX, WindMaxY, WindMaxX, Cnt, ScrEl,
  171. VioHandle);
  172. end;
  173. procedure ClearCells (X, Y, Cnt: dword); inline;
  174. (* Clear Cnt cells in line Y (0-based) starting with position X (0-based). *)
  175. var
  176. ScrEl: word;
  177. begin
  178. ScrEl := $20 or (TextAttr shl 8);
  179. VioScrollRight (Y, X, Y, X + Pred (Cnt), Cnt, ScrEl, VioHandle);
  180. end;
  181. procedure InsLine;
  182. (* Inserts a line at cursor position. *)
  183. var
  184. ScrEl: word;
  185. begin
  186. ScrEl := $20 or (TextAttr shl 8);
  187. VioScrollDn (Pred (WhereY32) + WindMinY, WindMinX, WindMaxY, WindMaxX, 1,
  188. ScrEl, VioHandle);
  189. end;
  190. procedure SetScreenMode (Mode: word);
  191. var
  192. NewMode: VioModeInfo;
  193. begin
  194. NewMode.cb := 8;
  195. VioGetMode (NewMode, VioHandle);
  196. NewMode.fbType := 1; {Non graphics colour mode.}
  197. NewMode.Color := 4; {We want 16 colours, 2^4=16 - requests for BW ignored.}
  198. case Mode and $FF of
  199. BW40, CO40: NewMode.Col := 40;
  200. BW80, CO80: NewMode.Col := 80;
  201. else
  202. begin
  203. (* Keep current amount of columns! *)
  204. end;
  205. end;
  206. case Mode and $100 of
  207. 0: NewMode.Row := 25;
  208. $100: NewMode.Row := 50
  209. else
  210. begin
  211. (* Keep current amount of rows! *)
  212. end;
  213. end;
  214. VioSetMode (NewMode, VioHandle);
  215. ScreenWidth := NewMode.Col;
  216. ScreenHeight := NewMode.Row;
  217. end;
  218. procedure Delay (Ms: word);
  219. {Waits ms milliseconds.}
  220. begin
  221. DosSleep (Ms)
  222. end;
  223. procedure WriteNormal (C: char; X, Y: dword); inline;
  224. (* Write C to console at X, Y (0-based). *)
  225. begin
  226. VioWrtCharStrAtt (@C, 1, Y, X, TextAttr, VioHandle);
  227. end;
  228. procedure WriteBell; inline;
  229. (* Write character #7 - beep. *)
  230. begin
  231. DosBeep (800, 250);
  232. end;
  233. {****************************************************************************
  234. Extra Crt Functions
  235. ****************************************************************************}
  236. procedure CursorOn;
  237. var
  238. I: TVioCursorInfo;
  239. begin
  240. VioGetCurType (I, VioHandle);
  241. with I do
  242. begin
  243. yStartInt := -90;
  244. cEndInt := -100;
  245. Attr := 15;
  246. end;
  247. VioSetCurType (I, VioHandle);
  248. end;
  249. procedure CursorOff;
  250. var
  251. I: TVioCursorInfo;
  252. begin
  253. VioGetCurType (I, VioHandle);
  254. I.AttrInt := -1;
  255. VioSetCurType (I, VioHandle);
  256. end;
  257. procedure CursorBig;
  258. var
  259. I: TVioCursorInfo;
  260. begin
  261. VioGetCurType (I, VioHandle);
  262. with I do
  263. begin
  264. yStart := 0;
  265. cEndInt := -100;
  266. Attr := 15;
  267. end;
  268. VioSetCurType (I, VioHandle);
  269. end;
  270. (* Include common, platform independent part. *)
  271. {$I crt.inc}
  272. {Initialization.}
  273. var
  274. CurMode: VioModeInfo;
  275. begin
  276. if not (IsConsole) then
  277. VioCreatePS (VioHandle, 25, 80, 1, 1, 0);
  278. { InitVideo;}
  279. CurMode.cb := SizeOf (CurMode);
  280. VioGetMode (CurMode, VioHandle);
  281. ScreenWidth := CurMode.Col;
  282. ScreenHeight := CurMode.Row;
  283. LastMode := 0;
  284. case ScreenWidth of
  285. 40: LastMode := CO40;
  286. 80: LastMode := CO80
  287. else
  288. LastMode := 255
  289. end;
  290. case ScreenHeight of
  291. 50: LastMode := LastMode + $100
  292. else
  293. LastMode := LastMode + $FF00;
  294. end;
  295. CrtInit;
  296. end.