crt.pas 9.2 KB

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