crt.pp 9.6 KB

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