video.pp 6.6 KB

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