video.pp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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. var
  25. OldVideoBuf : PVideoBuf;
  26. { used to know if LastCursorType is valid }
  27. const
  28. InitVideoCalled : boolean = false;
  29. LastCursorType : word = crUnderline;
  30. { allways set blink state again }
  31. procedure SetHighBitBlink;
  32. var
  33. regs : trealregs;
  34. begin
  35. regs.ax:=$1003;
  36. regs.bx:=$0001;
  37. realintr($10,regs);
  38. end;
  39. function BIOSGetScreenMode(var Cols,Rows: word; var Color: boolean): boolean;
  40. var r: trealregs;
  41. L: longint;
  42. LSel,LSeg: word;
  43. B: array[0..63] of byte;
  44. type
  45. TWord = word;
  46. PWord = ^TWord;
  47. var
  48. OK: boolean;
  49. begin
  50. L:=global_dos_alloc(64);
  51. LSeg:=(L shr 16);
  52. LSel:=(L and $ffff);
  53. r.ah:=$1b; r.bx:=0;
  54. r.es:=LSeg; r.di:=0;
  55. realintr($10,r);
  56. OK:=(r.al=$1b);
  57. if OK then
  58. begin
  59. dpmi_dosmemget(LSeg,0,B,64);
  60. Cols:=PWord(@B[5])^; Rows:=B[$22];
  61. Color:=PWord(@B[$27])^<>0;
  62. end;
  63. global_dos_free(LSel);
  64. BIOSGetScreenMode:=OK;
  65. end;
  66. procedure SysInitVideo;
  67. var
  68. regs : trealregs;
  69. begin
  70. VideoSeg:=$b800;
  71. if (ScreenWidth=$ffff) or (ScreenHeight=$ffff) or
  72. (ScreenWidth=0) or (ScreenHeight=0) then
  73. begin
  74. ScreenColor:=true;
  75. regs.ah:=$0f;
  76. realintr($10,regs);
  77. if (regs.al and 1)=0 then
  78. ScreenColor:=false;
  79. if regs.al=7 then
  80. begin
  81. ScreenColor:=false;
  82. VideoSeg:=$b000;
  83. end
  84. else
  85. VideoSeg:=$b800;
  86. ScreenWidth:=regs.ah;
  87. regs.ax:=$1130;
  88. regs.bx:=0;
  89. realintr($10,regs);
  90. ScreenHeight:=regs.dl+1;
  91. BIOSGetScreenMode(ScreenWidth,ScreenHeight,ScreenColor);
  92. end;
  93. regs.ah:=$03;
  94. regs.bh:=0;
  95. realintr($10,regs);
  96. CursorLines:=regs.cl;
  97. CursorX:=regs.dl;
  98. CursorY:=regs.dh;
  99. If InitVideoCalled then
  100. Begin
  101. FreeMem(VideoBuf,VideoBufSize);
  102. FreeMem(OldVideoBuf,VideoBufSize);
  103. End;
  104. { allocate pmode memory buffer }
  105. VideoBufSize:=ScreenWidth*ScreenHeight*2;
  106. GetMem(VideoBuf,VideoBufSize);
  107. GetMem(OldVideoBuf,VideoBufSize);
  108. SetHighBitBlink;
  109. SetCursorType(LastCursorType);
  110. { ClearScreen; removed here
  111. to be able to catch the content of the monitor }
  112. end;
  113. procedure SysDoneVideo;
  114. begin
  115. LastCursorType:=GetCursorType;
  116. ClearScreen;
  117. SetCursorType(crUnderLine);
  118. SetCursorPos(0,0);
  119. FreeMem(VideoBuf,VideoBufSize);
  120. VideoBuf:=nil;
  121. FreeMem(OldVideoBuf,VideoBufSize);
  122. OldVideoBuf:=nil;
  123. VideoBufSize:=0;
  124. end;
  125. function SysGetCapabilities: Word;
  126. begin
  127. SysGetCapabilities := $3F;
  128. end;
  129. procedure SysSetCursorPos(NewCursorX, NewCursorY: Word);
  130. var
  131. regs : trealregs;
  132. begin
  133. regs.ah:=$02;
  134. regs.bh:=0;
  135. regs.dh:=NewCursorY;
  136. regs.dl:=NewCursorX;
  137. realintr($10,regs);
  138. CursorY:=regs.dh;
  139. CursorX:=regs.dl;
  140. end;
  141. { I don't know the maximum value for the scan line
  142. probably 7 or 15 depending on resolution !!
  143. }
  144. function SysGetCursorType: Word;
  145. var
  146. regs : trealregs;
  147. begin
  148. regs.ah:=$03;
  149. regs.bh:=0;
  150. realintr($10,regs);
  151. SysGetCursorType:=crHidden;
  152. if (regs.ch and $60)=0 then
  153. begin
  154. SysGetCursorType:=crBlock;
  155. if (regs.ch and $1f)<>0 then
  156. begin
  157. SysGetCursorType:=crHalfBlock;
  158. if regs.cl+1=(regs.ch and $1F) then
  159. SysGetCursorType:=crUnderline;
  160. end;
  161. end;
  162. end;
  163. procedure SysSetCursorType(NewType: Word);
  164. var
  165. regs : trealregs;
  166. const
  167. MaxCursorLines = 7;
  168. begin
  169. regs.ah:=$01;
  170. regs.bx:=NewType;
  171. case NewType of
  172. crHidden : regs.cx:=$2000;
  173. crHalfBlock : begin
  174. regs.ch:=MaxCursorLines shr 1;
  175. regs.cl:=MaxCursorLines;
  176. end;
  177. crBlock : begin
  178. regs.ch:=0;
  179. regs.cl:=MaxCursorLines;
  180. end;
  181. else begin
  182. regs.ch:=MaxCursorLines-1;
  183. regs.cl:=MaxCursorLines;
  184. end;
  185. end;
  186. realintr($10,regs);
  187. end;
  188. function DefaultVideoModeSelector(const VideoMode: TVideoMode; Params: Longint): Boolean;
  189. type
  190. wordrec=packed record
  191. lo,hi : word;
  192. end;
  193. var
  194. regs : trealregs;
  195. begin
  196. regs.ax:=wordrec(Params).lo;
  197. regs.bx:=wordrec(Params).hi;
  198. realintr($10,regs);
  199. defaultvideomodeselector:=true;
  200. DoCustomMouse(false);
  201. end;
  202. function VideoModeSelector8x8(const VideoMode: TVideoMode; Params: Longint): Boolean;
  203. type
  204. wordrec=packed record
  205. lo,hi : word;
  206. end;
  207. var
  208. regs : trealregs;
  209. begin
  210. regs.ax:=3;
  211. regs.bx:=0;
  212. realintr($10,regs);
  213. regs.ax:=$1112;
  214. regs.bx:=$0;
  215. realintr($10,regs);
  216. videomodeselector8x8:=true;
  217. ScreenColor:=true;
  218. ScreenWidth:=80;
  219. ScreenHeight:=50;
  220. DoCustomMouse(false);
  221. end;
  222. procedure SysClearScreen;
  223. begin
  224. FillWord(VideoBuf^,VideoBufSize shr 1,$0720);
  225. UpdateScreen(true);
  226. end;
  227. procedure SysUpdateScreen(Force: Boolean);
  228. begin
  229. if LockUpdateScreen<>0 then
  230. exit;
  231. if not force then
  232. begin
  233. asm
  234. movl VideoBuf,%esi
  235. movl OldVideoBuf,%edi
  236. movl VideoBufSize,%ecx
  237. shrl $2,%ecx
  238. repe
  239. cmpsl
  240. setne force
  241. end;
  242. end;
  243. if Force then
  244. begin
  245. dosmemput(videoseg,0,videobuf^,VideoBufSize);
  246. move(videobuf^,oldvideobuf^,VideoBufSize);
  247. end;
  248. end;
  249. procedure RegisterVideoModes;
  250. begin
  251. RegisterVideoMode(40, 25, False,@DefaultVideoModeSelector, $00000000);
  252. RegisterVideoMode(40, 25, True, @DefaultVideoModeSelector, $00000001);
  253. RegisterVideoMode(80, 25, False,@DefaultVideoModeSelector, $00000002);
  254. RegisterVideoMode(80, 25, True, @DefaultVideoModeSelector, $00000003);
  255. RegisterVideoMode(80, 50, True, @VideoModeSelector8x8, 0);
  256. end;
  257. Const
  258. SysVideoDriver : TVideoDriver = (
  259. InitDriver : @SysInitVideo;
  260. DoneDriver : @SysDoneVideo;
  261. UpdateScreen : @SysUpdateScreen;
  262. ClearScreen : @SysClearScreen;
  263. SetVideoMode : Nil;
  264. HasVideoMode : Nil;
  265. SetCursorPos : @SysSetCursorPos;
  266. GetCursorType : @SysGetCursorType;
  267. SetCursorType : @SysSetCursorType;
  268. GetCapabilities : @SysGetCapabilities
  269. );
  270. initialization
  271. SetVideoDriver(SysVideoDriver);
  272. RegisterVideoModes;
  273. finalization
  274. UnRegisterVideoModes;
  275. end.
  276. {
  277. $Log$
  278. Revision 1.3 2001-09-21 19:50:18 michael
  279. + Merged driver support from fixbranch
  280. Revision 1.2 2001/05/09 19:53:28 peter
  281. * removed asm for copy, use dosmemput (merged)
  282. Revision 1.1.2.4 2001/09/21 18:42:08 michael
  283. + Implemented support for custom video drivers.
  284. Revision 1.1.2.3 2001/05/06 21:54:23 carl
  285. * bugfix of Windows NT double exception crash
  286. Revision 1.1.2.2 2001/04/16 10:56:13 peter
  287. * fixes for stricter compiler
  288. Revision 1.1.2.1 2001/01/30 21:52:01 peter
  289. * moved api utils to rtl
  290. Revision 1.1 2001/01/13 11:03:58 peter
  291. * API 2 RTL commit
  292. }