video.pp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Video unit for DOS
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit Video;
  14. interface
  15. {$i videoh.inc}
  16. var
  17. VideoSeg : word;
  18. implementation
  19. uses
  20. mouse,
  21. go32;
  22. {$i video.inc}
  23. {$ASMMODE ATT}
  24. { used to know if LastCursorType is valid }
  25. const
  26. LastCursorType : word = crUnderline;
  27. { allways set blink state again }
  28. procedure SetHighBitBlink;
  29. var
  30. regs : trealregs;
  31. begin
  32. regs.ax:=$1003;
  33. regs.bx:=$0001;
  34. realintr($10,regs);
  35. end;
  36. function BIOSGetScreenMode(var Cols,Rows: word; var Color: boolean): boolean;
  37. var r: trealregs;
  38. L: longint;
  39. LSel,LSeg: word;
  40. B: array[0..63] of byte;
  41. type
  42. TWord = word;
  43. PWord = ^TWord;
  44. var
  45. OK: boolean;
  46. begin
  47. L:=global_dos_alloc(64);
  48. LSeg:=(L shr 16);
  49. LSel:=(L and $ffff);
  50. r.ah:=$1b; r.bx:=0;
  51. r.es:=LSeg; r.di:=0;
  52. realintr($10,r);
  53. OK:=(r.al=$1b);
  54. if OK then
  55. begin
  56. dpmi_dosmemget(LSeg,0,B,64);
  57. Cols:=PWord(@B[5])^; Rows:=B[$22];
  58. Color:=PWord(@B[$27])^<>0;
  59. end;
  60. global_dos_free(LSel);
  61. BIOSGetScreenMode:=OK;
  62. end;
  63. procedure SysInitVideo;
  64. var
  65. regs : trealregs;
  66. begin
  67. VideoSeg:=$b800;
  68. if (ScreenWidth=$ffff) or (ScreenHeight=$ffff) or
  69. (ScreenWidth=0) or (ScreenHeight=0) then
  70. begin
  71. ScreenColor:=true;
  72. regs.ah:=$0f;
  73. realintr($10,regs);
  74. if (regs.al and 1)=0 then
  75. ScreenColor:=false;
  76. if regs.al=7 then
  77. begin
  78. ScreenColor:=false;
  79. VideoSeg:=$b000;
  80. end
  81. else
  82. VideoSeg:=$b800;
  83. ScreenWidth:=regs.ah;
  84. regs.ax:=$1130;
  85. regs.bx:=0;
  86. realintr($10,regs);
  87. ScreenHeight:=regs.dl+1;
  88. BIOSGetScreenMode(ScreenWidth,ScreenHeight,ScreenColor);
  89. end;
  90. regs.ah:=$03;
  91. regs.bh:=0;
  92. realintr($10,regs);
  93. CursorLines:=regs.cl;
  94. CursorX:=regs.dl;
  95. CursorY:=regs.dh;
  96. SetHighBitBlink;
  97. SetCursorType(LastCursorType);
  98. end;
  99. procedure SysDoneVideo;
  100. begin
  101. LastCursorType:=GetCursorType;
  102. ClearScreen;
  103. SetCursorType(crUnderLine);
  104. SetCursorPos(0,0);
  105. end;
  106. function SysGetCapabilities: Word;
  107. begin
  108. SysGetCapabilities := $3F;
  109. end;
  110. procedure SysSetCursorPos(NewCursorX, NewCursorY: Word);
  111. var
  112. regs : trealregs;
  113. begin
  114. regs.ah:=$02;
  115. regs.bh:=0;
  116. regs.dh:=NewCursorY;
  117. regs.dl:=NewCursorX;
  118. realintr($10,regs);
  119. CursorY:=regs.dh;
  120. CursorX:=regs.dl;
  121. end;
  122. { I don't know the maximum value for the scan line
  123. probably 7 or 15 depending on resolution !!
  124. }
  125. function SysGetCursorType: Word;
  126. var
  127. regs : trealregs;
  128. begin
  129. regs.ah:=$03;
  130. regs.bh:=0;
  131. realintr($10,regs);
  132. SysGetCursorType:=crHidden;
  133. if (regs.ch and $60)=0 then
  134. begin
  135. SysGetCursorType:=crBlock;
  136. if (regs.ch and $1f)<>0 then
  137. begin
  138. SysGetCursorType:=crHalfBlock;
  139. if regs.cl-1=(regs.ch and $1F) then
  140. SysGetCursorType:=crUnderline;
  141. end;
  142. end;
  143. end;
  144. procedure SysSetCursorType(NewType: Word);
  145. var
  146. regs : trealregs;
  147. const
  148. MaxCursorLines = 7;
  149. begin
  150. regs.ah:=$01;
  151. regs.bx:=NewType;
  152. case NewType of
  153. crHidden : regs.cx:=$2000;
  154. crHalfBlock : begin
  155. regs.ch:=MaxCursorLines shr 1;
  156. regs.cl:=MaxCursorLines;
  157. end;
  158. crBlock : begin
  159. regs.ch:=0;
  160. regs.cl:=MaxCursorLines;
  161. end;
  162. else begin
  163. regs.ch:=MaxCursorLines-1;
  164. regs.cl:=MaxCursorLines;
  165. end;
  166. end;
  167. realintr($10,regs);
  168. end;
  169. procedure SysUpdateScreen(Force: Boolean);
  170. begin
  171. if not force then
  172. begin
  173. asm
  174. movl VideoBuf,%esi
  175. movl OldVideoBuf,%edi
  176. movl VideoBufSize,%ecx
  177. shrl $2,%ecx
  178. repe
  179. cmpsl
  180. setne force
  181. end;
  182. end;
  183. if Force then
  184. begin
  185. dosmemput(videoseg,0,videobuf^,VideoBufSize);
  186. move(videobuf^,oldvideobuf^,VideoBufSize);
  187. end;
  188. end;
  189. Procedure DoSetVideoMode(Params: Longint);
  190. type
  191. wordrec=packed record
  192. lo,hi : word;
  193. end;
  194. var
  195. regs : trealregs;
  196. begin
  197. regs.ax:=wordrec(Params).lo;
  198. regs.bx:=wordrec(Params).hi;
  199. realintr($10,regs);
  200. end;
  201. Procedure SetVideo8x8;
  202. type
  203. wordrec=packed record
  204. lo,hi : word;
  205. end;
  206. var
  207. regs : trealregs;
  208. begin
  209. regs.ax:=3;
  210. regs.bx:=0;
  211. realintr($10,regs);
  212. regs.ax:=$1112;
  213. regs.bx:=$0;
  214. realintr($10,regs);
  215. end;
  216. Const
  217. SysVideoModeCount = 5;
  218. SysVMD : Array[0..SysVideoModeCount-1] of TVideoMode = (
  219. (Col: 40; Row : 25; Color : False),
  220. (Col: 40; Row : 25; Color : True),
  221. (Col: 80; Row : 25; Color : False),
  222. (Col: 80; Row : 25; Color : True),
  223. (Col: 80; Row : 50; Color : True)
  224. );
  225. Function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
  226. Var
  227. I : Integer;
  228. begin
  229. I:=SysVideoModeCount-1;
  230. SysSetVideoMode:=False;
  231. While (I>=0) and Not SysSetVideoMode do
  232. If (Mode.col=SysVMD[i].col) and
  233. (Mode.Row=SysVMD[i].Row) and
  234. (Mode.Color=SysVMD[i].Color) then
  235. SysSetVideoMode:=True
  236. else
  237. Dec(I);
  238. If SysSetVideoMode then
  239. begin
  240. If (I<SysVideoModeCount-1) then
  241. DoSetVideoMode(I)
  242. else
  243. SetVideo8x8;
  244. ScreenWidth:=SysVMD[I].Col;
  245. ScreenHeight:=SysVMD[I].Row;
  246. ScreenColor:=SysVMD[I].Color;
  247. DoCustomMouse(false);
  248. end;
  249. end;
  250. Function SysGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
  251. begin
  252. SysGetVideoModeData:=(Index<=SysVideoModeCount);
  253. If SysGetVideoModeData then
  254. Data:=SysVMD[Index];
  255. end;
  256. Function SysGetVideoModeCount : Word;
  257. begin
  258. SysGetVideoModeCount:=SysVideoModeCount;
  259. end;
  260. Const
  261. SysVideoDriver : TVideoDriver = (
  262. InitDriver : @SysInitVideo;
  263. DoneDriver : @SysDoneVideo;
  264. UpdateScreen : @SysUpdateScreen;
  265. ClearScreen : Nil;
  266. SetVideoMode : @SysSetVideoMode;
  267. GetVideoModeCount : @SysGetVideoModeCount;
  268. GetVideoModeData : @SysGetVideoModedata;
  269. SetCursorPos : @SysSetCursorPos;
  270. GetCursorType : @SysGetCursorType;
  271. SetCursorType : @SysSetCursorType;
  272. GetCapabilities : @SysGetCapabilities
  273. );
  274. initialization
  275. SetVideoDriver(SysVideoDriver);
  276. end.
  277. {
  278. $Log$
  279. Revision 1.5 2001-10-12 16:04:45 peter
  280. * video fixes (merged)
  281. Revision 1.4 2001/10/06 22:28:24 michael
  282. + Merged video mode selection/setting system
  283. Revision 1.3 2001/09/21 19:50:18 michael
  284. + Merged driver support from fixbranch
  285. Revision 1.2 2001/05/09 19:53:28 peter
  286. * removed asm for copy, use dosmemput (merged)
  287. Revision 1.1.2.5 2001/10/06 22:23:40 michael
  288. + Better video mode selection/setting system
  289. Revision 1.1.2.4 2001/09/21 18:42:08 michael
  290. + Implemented support for custom video drivers.
  291. Revision 1.1.2.3 2001/05/06 21:54:23 carl
  292. * bugfix of Windows NT double exception crash
  293. Revision 1.1.2.2 2001/04/16 10:56:13 peter
  294. * fixes for stricter compiler
  295. Revision 1.1.2.1 2001/01/30 21:52:01 peter
  296. * moved api utils to rtl
  297. Revision 1.1 2001/01/13 11:03:58 peter
  298. * API 2 RTL commit
  299. }