VESAVID.CPP 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /****************************************************************************
  19. *
  20. * C O N F I D E N T I A L -- W E S T W O O D S T U D I O S
  21. *
  22. *----------------------------------------------------------------------------
  23. *
  24. * FILE
  25. * vesavid.c
  26. *
  27. * DESCRIPTION
  28. * VESA video manager. (32-Bit protected mode)
  29. *
  30. * PROGRAMMER
  31. * Denzil E. Long, Jr.
  32. *
  33. * DATE
  34. * January 26, 1995
  35. *
  36. *----------------------------------------------------------------------------
  37. *
  38. * PUBLIC
  39. * InitVESA - Initialize the VESA video manager.
  40. * UninitVESA - Uninitialize the VESA video manager.
  41. * SetVESAMode - Set the display to the specified VESA video mode.
  42. * ReadVESAModeInfo - Read the VESA mode information from the video card.
  43. * SetVESAWindow - Set VESA window A's start address.
  44. *
  45. ****************************************************************************/
  46. #include <stdio.h>
  47. #include <mem.h>
  48. #include <dos.h>
  49. #ifndef __WATCOMC__
  50. #include <pldos32.h>
  51. #include <pharlap.h>
  52. #else
  53. #include "realmode.h"
  54. #endif
  55. #include "vesavid.h"
  56. /*---------------------------------------------------------------------------
  57. * PRIVATE DECLARATIONS
  58. *-------------------------------------------------------------------------*/
  59. #ifdef __WATCOMC__
  60. static short _VInfoSel = NULL;
  61. static short _VInfoSeg = NULL;
  62. static short _ModeInfoSel = NULL;
  63. static short _ModeInfoSeg = NULL;
  64. #else /* __WATCOMC__ */
  65. /* _regs - Registers used for calling software interrupts.
  66. * _rpVInfo - Real pointer to VInfo structure in conventional memory.
  67. * _rpModeInfo - Real pointer to ModeInfo structure in conventional memory.
  68. * _VInfo - Protected mode copy of VInfo structure.
  69. * _ModeInfo - Protected mode copy of ModeInfo structure.
  70. */
  71. static SWI_REGS _regs;
  72. static REALPTR _rpVInfo = NULL;
  73. static REALPTR _rpModeInfo = NULL;
  74. static VESAInfo _VInfo;
  75. static VESAModeInfo _ModeInfo;
  76. #endif /* __WATCOMC__ */
  77. /****************************************************************************
  78. *
  79. * NAME
  80. * InitVESA - Initialize the VESA video manager.
  81. *
  82. * SYNOPSIS
  83. * Error = InitVESA()
  84. *
  85. * long InitVESA(void);
  86. *
  87. * FUNCTION
  88. * Initialize the VESA video system. Get the VESA information from the
  89. * VESA video bios.
  90. *
  91. * INPUTS
  92. * NONE
  93. *
  94. * RESULT
  95. * Error - 0 if successful, or -1 error/VESA not supported.
  96. *
  97. ****************************************************************************/
  98. long InitVESA(void)
  99. {
  100. #ifdef __WATCOMC__
  101. union REGS r;
  102. struct SREGS sr;
  103. RMInfo rmi;
  104. long error = -1;
  105. /* Allocate real-mode memory for VESA structure. */
  106. r.x.eax = 0x0100;
  107. r.x.ebx = (sizeof(VESAInfo) + 15) >> 4;
  108. int386(0x31, &r, &r);
  109. if (r.x.cflag == 0) {
  110. _VInfoSel = r.w.dx;
  111. _VInfoSeg = r.w.ax;
  112. /* Allocate real-mode memory for VESAModeInfo structure. */
  113. r.x.eax = 0x0100;
  114. r.x.ebx = (sizeof(VESAModeInfo) + 15) >> 4;
  115. int386(0x31, &r, &r);
  116. if (r.x.cflag == 0) {
  117. _ModeInfoSel = r.w.dx;
  118. _ModeInfoSeg = r.w.ax;
  119. /* Clear VESAInfo structure. */
  120. memset(MK_PTR(0, _VInfoSeg), 0, sizeof(VESAInfo));
  121. /* Get VESA information. */
  122. memset(&rmi, 0, sizeof(RMInfo));
  123. rmi.eax = 0x4F00;
  124. rmi.edi = 0;
  125. rmi.es = _VInfoSeg;
  126. segread(&sr);
  127. r.w.ax = 0x0300;
  128. r.h.bl = 0x10;
  129. r.h.bh = 0;
  130. r.w.cx = 0;
  131. sr.es = FP_SEG(&rmi);
  132. r.x.edi = FP_OFF(&rmi);
  133. int386x(0x31, &r, &r, &sr);
  134. if ((r.x.cflag == 0) && (rmi.eax == 0x004F)) {
  135. error = 0;
  136. }
  137. }
  138. }
  139. if (error != 0) {
  140. UninitVESA();
  141. }
  142. return (error);
  143. #else /* __WATCOMC__ */
  144. unsigned short rseg;
  145. long paras;
  146. long error = -1;
  147. /* Calculate size of VESAInfo structure in paragraphs */
  148. paras = (sizeof(VESAInfo) + 15) >> 4;
  149. /* Allocate real-mode memory for VESA structure. */
  150. if (_dx_real_alloc(paras, (unsigned short *)&rseg,
  151. (unsigned short *)&paras) == 0) {
  152. RP_SET(_rpVInfo, 0, rseg);
  153. /* Calculate size of VESAModeInfo structure in paragraphs */
  154. paras = (sizeof(VESAModeInfo) + 15) >> 4;
  155. /* Allocate real-mode memory for VESAModeInfo structure. */
  156. if (_dx_real_alloc(paras, (unsigned short *)&rseg,
  157. (unsigned short *)&paras) == 0) {
  158. RP_SET(_rpModeInfo, 0, rseg);
  159. /* Clear the input buffer */
  160. FillRealMem(_rpVInfo, 0, sizeof(VESAInfo));
  161. /* Set up function call */
  162. _regs.eax = 0x4F00;
  163. _regs.edi = RP_OFF(_rpVInfo);
  164. _regs.es = RP_SEG(_rpVInfo);
  165. _dx_real_int(0x10, &_regs);
  166. if (_regs.eax == 0x004F) {
  167. ReadRealMem(&_VInfo, _rpVInfo, sizeof(VESAInfo));
  168. error = 0;
  169. }
  170. }
  171. }
  172. if (error != 0) {
  173. UninitVESA();
  174. }
  175. return (error);
  176. #endif /* __WATCOMC__ */
  177. }
  178. /****************************************************************************
  179. *
  180. * NAME
  181. * UninitVESA - Uninitialize the VESA video manager.
  182. *
  183. * SYNOPSIS
  184. * UninitVESA()
  185. *
  186. * void UninitVESA(void);
  187. *
  188. * FUNCTION
  189. *
  190. * INPUTS
  191. * NONE
  192. *
  193. * RESULT
  194. * NONE
  195. *
  196. ****************************************************************************/
  197. void UninitVESA(void)
  198. {
  199. #ifdef __WATCOMC__
  200. union REGS r;
  201. /* Free VESAInfo structure */
  202. if (_VInfoSeg != NULL) {
  203. r.x.eax = 0x0101;
  204. r.x.edx = _VInfoSel;
  205. int386(0x31, &r, &r);
  206. _VInfoSeg = NULL;
  207. _VInfoSel = NULL;
  208. }
  209. /* Free VESAModeInfo structure */
  210. if (_ModeInfoSeg != NULL) {
  211. r.x.eax = 0x0101;
  212. r.x.edx = _VInfoSel;
  213. int386(0x31, &r, &r);
  214. _ModeInfoSeg = NULL;
  215. _ModeInfoSel = NULL;
  216. }
  217. #else /* __WATCOMC__ */
  218. /* Free VESAInfo structure */
  219. if (_rpVInfo != NULL) {
  220. _dx_real_free(RP_SEG(_rpVInfo));
  221. _rpVInfo = NULL;
  222. }
  223. /* Free VESAModeInfo structure */
  224. if (_rpModeInfo != NULL) {
  225. _dx_real_free(RP_SEG(_rpModeInfo));
  226. _rpModeInfo = NULL;
  227. }
  228. #endif /* __WATCOMC__ */
  229. }
  230. /****************************************************************************
  231. *
  232. * NAME
  233. * SetVESAMode - Set the display adapter to the given VESA video mode.
  234. *
  235. * SYNOPSIS
  236. * VESAModeInfo = SetVESAMode(Mode)
  237. *
  238. * VESAModeInfo *SetVESAMode(long);
  239. *
  240. * FUNCTION
  241. * Set the display adapter to the specified VESA video mode.
  242. *
  243. * INPUTS
  244. * Mode - VESA video mode to set the display to.
  245. *
  246. * RESULT
  247. * VESAModeInfo - Pointer to VESA mode information structure or NULL if
  248. * error.
  249. *
  250. ****************************************************************************/
  251. VESAModeInfo *SetVESAMode(long mode)
  252. {
  253. VESAModeInfo *vminfo;
  254. /* Get mode info */
  255. if ((vminfo = ReadVESAModeInfo(mode)) != NULL) {
  256. /* If the mode is supported, set it. */
  257. if ((vminfo->Attributes & 0x01) != 0) {
  258. #ifdef __WATCOMC__
  259. {
  260. union REGS r;
  261. r.x.eax = 0x4F02;
  262. r.x.ebx = mode;
  263. int386(0x10, &r, &r);
  264. if (r.x.eax != 0x004F)
  265. vminfo = NULL;
  266. }
  267. #else /* __WATCOMC__ */
  268. /* Set up function call */
  269. _regs.eax = 0x4F02;
  270. _regs.ebx = mode;
  271. _dx_real_int(0x10, &_regs);
  272. if (_regs.eax != 0x004F) {
  273. vminfo = NULL;
  274. }
  275. #endif /* __WATCOMC__ */
  276. }
  277. }
  278. return (vminfo);
  279. }
  280. /****************************************************************************
  281. *
  282. * NAME
  283. * ReadVESAModeInfo - Read the VESA mode information from the video card.
  284. *
  285. * SYNOPSIS
  286. * VESAModeInfo = ReadVESAModeInfo(Mode)
  287. *
  288. * VESAModeInfo *ReadVESAModeInfo(long);
  289. *
  290. * FUNCTION
  291. * Read information about the specified mode from the VESA video BIOS.
  292. *
  293. * INPUTS
  294. * Mode - Mode ID to get information about.
  295. *
  296. * RESULT
  297. * VESAModeInfo - Pointer to VESA mode information structure or NULL if
  298. * error.
  299. *
  300. ****************************************************************************/
  301. VESAModeInfo *ReadVESAModeInfo(long mode)
  302. {
  303. VESAModeInfo *vminfo = NULL;
  304. #ifdef __WATCOMC__
  305. union REGS r;
  306. struct SREGS sr;
  307. RMInfo rmi;
  308. /* Make sure we have real-mode memory. */
  309. if (_ModeInfoSeg != NULL) {
  310. memset(MK_PTR(0, _ModeInfoSeg), 0, sizeof(VESAModeInfo));
  311. /* Get mode information. */
  312. memset(&rmi, 0, sizeof(RMInfo));
  313. rmi.eax = 0x4F01;
  314. rmi.ecx = mode;
  315. rmi.edi = 0;
  316. rmi.es = _ModeInfoSeg;
  317. segread(&sr);
  318. r.w.ax = 0x0300;
  319. r.w.bx = 0x0010;
  320. r.w.cx = 0;
  321. sr.es = FP_SEG(&rmi);
  322. r.x.edi = FP_OFF(&rmi);
  323. int386x(0x31, &r, &r, &sr);
  324. if ((r.x.cflag == 0) && (rmi.eax == 0x004F)) {
  325. vminfo = (VESAModeInfo *)MK_PTR(0, _ModeInfoSeg);
  326. }
  327. }
  328. #else /* __WATCOMC__ */
  329. /* Make sure we have real-mode memory. */
  330. if (_rpModeInfo != NULL) {
  331. /* Clear the input buffer */
  332. FillRealMem(_rpModeInfo, 0, sizeof(VESAModeInfo));
  333. /* Set up function call */
  334. _regs.eax = 0x4F01;
  335. _regs.ecx = mode;
  336. _regs.edi = RP_OFF(_rpModeInfo);
  337. _regs.es = RP_SEG(_rpModeInfo);
  338. _dx_real_int(0x10, &_regs);
  339. if (_regs.eax == 0x004F) {
  340. ReadRealMem(&_ModeInfo, _rpModeInfo, sizeof(VESAModeInfo));
  341. vminfo = &_ModeInfo;
  342. }
  343. }
  344. #endif /* __WATCOMC__ */
  345. return (vminfo);
  346. }
  347. /****************************************************************************
  348. *
  349. * NAME
  350. * SetVESAWindow - Set VESA window A's start address.
  351. *
  352. * SYNOPSIS
  353. * Error = SetVESAWindow(GrainNum)
  354. *
  355. * long SetVESAWindow(long);
  356. *
  357. * FUNCTION
  358. * This function invokes the Window Function, whose address is provided
  359. * in the VESAModeInfo structure. The 'GrainNum' must be in granularity
  360. * units as specified in the ModeInfo structure.
  361. *
  362. * INPUTS
  363. * GrainNum - Granularity number to set window to.
  364. *
  365. * RESULT
  366. * NONE
  367. *
  368. ****************************************************************************/
  369. void SetVESAWindow(long grain)
  370. {
  371. #ifdef __WATCOMC__
  372. #else /* __WATCOMC__ */
  373. RMC_BLK regp;
  374. regp.eax = 0x4F05;
  375. regp.ebx = 0x00;
  376. regp.edx = grain;
  377. _dx_call_real(_ModeInfo.WinFunc, &regp, 0);
  378. #endif /* __WATCOMC__ */
  379. }