video.pp 6.4 KB

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