crt.pas 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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. 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. procedure GetScreenCursor (var X, Y: dword);inline;
  107. (* Return current cursor postion - 0-based. *)
  108. var
  109. X0, Y0: word;
  110. begin
  111. X := 0;
  112. Y := 0;
  113. if VioGetCurPos (Y0, X0, VioHandle) = 0 then
  114. begin
  115. X := X0;
  116. Y := Y0;
  117. end;
  118. end;
  119. procedure SetScreenCursor (X, Y: dword); inline;
  120. (* Set current cursor postion - 0-based. *)
  121. begin
  122. VioSetCurPos (Y, X, VioHandle);
  123. end;
  124. procedure RemoveLines (Row: dword; Cnt: dword); inline;
  125. (* Remove Cnt lines from screen starting with (0-based) Row. *)
  126. var
  127. ScrEl: word;
  128. begin
  129. ScrEl := $20 or (TextAttr shl 8);
  130. VioScrollUp (Row + WindMinY, WindMinX, WindMaxY, WindMaxX, Cnt, ScrEl,
  131. VioHandle);
  132. end;
  133. procedure ClearCells (X, Y, Cnt: dword); inline;
  134. (* Clear Cnt cells in line Y (0-based) starting with position X (0-based). *)
  135. var
  136. ScrEl: word;
  137. begin
  138. ScrEl := $20 or (TextAttr shl 8);
  139. VioScrollRight (Y, X, Y, X + Pred (Cnt), Cnt, ScrEl, VioHandle);
  140. end;
  141. procedure InsLine;
  142. (* Inserts a line at cursor position. *)
  143. var
  144. ScrEl: word;
  145. begin
  146. ScrEl := $20 or (TextAttr shl 8);
  147. VioScrollDn (Pred (WhereY32) + WindMinY, WindMinX, WindMaxY, WindMaxX, 1,
  148. ScrEl, VioHandle);
  149. end;
  150. procedure SetScreenMode (Mode: word);
  151. var
  152. NewMode: VioModeInfo;
  153. begin
  154. NewMode.cb := 8;
  155. VioGetMode (NewMode, VioHandle);
  156. NewMode.fbType := 1; {Non graphics colour mode.}
  157. NewMode.Color := 4; {We want 16 colours, 2^4=16 - requests for BW ignored.}
  158. case Mode and $FF of
  159. BW40, CO40: NewMode.Col := 40;
  160. BW80, CO80: NewMode.Col := 80;
  161. else
  162. begin
  163. (* Keep current amount of columns! *)
  164. end;
  165. end;
  166. case Mode and $100 of
  167. 0: NewMode.Row := 25;
  168. $100: NewMode.Row := 50
  169. else
  170. begin
  171. (* Keep current amount of rows! *)
  172. end;
  173. end;
  174. VioSetMode (NewMode, VioHandle);
  175. ScreenWidth := NewMode.Col;
  176. ScreenHeight := NewMode.Row;
  177. end;
  178. procedure Delay (Ms: word);
  179. {Waits ms milliseconds.}
  180. begin
  181. DosSleep (Ms)
  182. end;
  183. procedure WriteNormal (C: char; X, Y: dword); inline;
  184. (* Write C to console at X, Y (0-based). *)
  185. begin
  186. VioWrtCharStrAtt (@C, 1, Y, X, TextAttr, VioHandle);
  187. end;
  188. procedure WriteBell; inline;
  189. (* Write character #7 - beep. *)
  190. begin
  191. DosBeep (800, 250);
  192. end;
  193. {****************************************************************************
  194. Extra Crt Functions
  195. ****************************************************************************}
  196. procedure CursorOn;
  197. var
  198. I: TVioCursorInfo;
  199. begin
  200. VioGetCurType (I, VioHandle);
  201. with I do
  202. begin
  203. yStartInt := -90;
  204. cEndInt := -100;
  205. Attr := 15;
  206. end;
  207. VioSetCurType (I, VioHandle);
  208. end;
  209. procedure CursorOff;
  210. var
  211. I: TVioCursorInfo;
  212. begin
  213. VioGetCurType (I, VioHandle);
  214. I.AttrInt := -1;
  215. VioSetCurType (I, VioHandle);
  216. end;
  217. procedure CursorBig;
  218. var
  219. I: TVioCursorInfo;
  220. begin
  221. VioGetCurType (I, VioHandle);
  222. with I do
  223. begin
  224. yStart := 0;
  225. cEndInt := -100;
  226. Attr := 15;
  227. end;
  228. VioSetCurType (I, VioHandle);
  229. end;
  230. (* Include common, platform independent part. *)
  231. {$I crt.inc}
  232. function KeyPressed: boolean;
  233. {Checks if a key is pressed.}
  234. var
  235. AKeyRec: TKbdKeyinfo;
  236. begin
  237. if SpecialKey or (ScanCode <> 0) then
  238. KeyPressed := true
  239. else
  240. KeyPressed := (KbdPeek (AKeyRec, 0) = 0)
  241. and ((AKeyRec.fbStatus and $40) <> 0);
  242. end;
  243. function ReadKey: char;
  244. {Reads the next character from the keyboard.}
  245. var
  246. AKeyRec: TKbdKeyInfo;
  247. C, S: char;
  248. begin
  249. if SpecialKey then
  250. begin
  251. SpecialKey := false;
  252. ReadKey := char (ScanCode);
  253. ScanCode := 0;
  254. end
  255. else
  256. if ScanCode <> 0 then
  257. begin
  258. ReadKey := char (ScanCode);
  259. ScanCode := 0;
  260. end
  261. else
  262. begin
  263. while ((KbdCharIn (AKeyRec, 1, 0) <> 0)
  264. or (AKeyRec.fbStatus and $41 <> $40)) and (ScanCode = 0) do
  265. DosSleep (5);
  266. if ScanCode = 0 then
  267. begin
  268. C := AKeyRec.CharCode;
  269. S := AKeyRec.ScanCode;
  270. if (C = #224) and (S <> #0) then
  271. C := #0;
  272. if C = #0 then
  273. begin
  274. SpecialKey := true;
  275. ScanCode := byte (S);
  276. end;
  277. ReadKey := C;
  278. end
  279. else
  280. begin
  281. ReadKey := char (ScanCode);
  282. ScanCode := 0;
  283. end;
  284. end;
  285. end;
  286. {Initialization.}
  287. var
  288. CurMode: VioModeInfo;
  289. begin
  290. if not (IsConsole) then
  291. VioCreatePS (VioHandle, 25, 80, 1, 1, 0);
  292. { InitVideo;}
  293. CurMode.cb := SizeOf (CurMode);
  294. VioGetMode (CurMode, VioHandle);
  295. ScreenWidth := CurMode.Col;
  296. ScreenHeight := CurMode.Row;
  297. LastMode := 0;
  298. case ScreenWidth of
  299. 40: LastMode := CO40;
  300. 80: LastMode := CO80
  301. else
  302. LastMode := 255
  303. end;
  304. case ScreenHeight of
  305. 50: LastMode := LastMode + $100
  306. else
  307. LastMode := LastMode + $FF00;
  308. end;
  309. CrtInit;
  310. end.