| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /****************************************************************************
- *
- * 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
- *
- *----------------------------------------------------------------------------
- *
- * FILE
- * vesavid.c
- *
- * DESCRIPTION
- * VESA video manager. (32-Bit protected mode)
- *
- * PROGRAMMER
- * Denzil E. Long, Jr.
- *
- * DATE
- * January 26, 1995
- *
- *----------------------------------------------------------------------------
- *
- * PUBLIC
- * InitVESA - Initialize the VESA video manager.
- * UninitVESA - Uninitialize the VESA video manager.
- * SetVESAMode - Set the display to the specified VESA video mode.
- * ReadVESAModeInfo - Read the VESA mode information from the video card.
- * SetVESAWindow - Set VESA window A's start address.
- *
- ****************************************************************************/
- #include <stdio.h>
- #include <mem.h>
- #include <dos.h>
- #ifndef __WATCOMC__
- #include <pldos32.h>
- #include <pharlap.h>
- #else
- #include "realmode.h"
- #endif
- #include "vesavid.h"
- /*---------------------------------------------------------------------------
- * PRIVATE DECLARATIONS
- *-------------------------------------------------------------------------*/
- #ifdef __WATCOMC__
- static short _VInfoSel = NULL;
- static short _VInfoSeg = NULL;
- static short _ModeInfoSel = NULL;
- static short _ModeInfoSeg = NULL;
- #else /* __WATCOMC__ */
- /* _regs - Registers used for calling software interrupts.
- * _rpVInfo - Real pointer to VInfo structure in conventional memory.
- * _rpModeInfo - Real pointer to ModeInfo structure in conventional memory.
- * _VInfo - Protected mode copy of VInfo structure.
- * _ModeInfo - Protected mode copy of ModeInfo structure.
- */
- static SWI_REGS _regs;
- static REALPTR _rpVInfo = NULL;
- static REALPTR _rpModeInfo = NULL;
- static VESAInfo _VInfo;
- static VESAModeInfo _ModeInfo;
- #endif /* __WATCOMC__ */
- /****************************************************************************
- *
- * NAME
- * InitVESA - Initialize the VESA video manager.
- *
- * SYNOPSIS
- * Error = InitVESA()
- *
- * long InitVESA(void);
- *
- * FUNCTION
- * Initialize the VESA video system. Get the VESA information from the
- * VESA video bios.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * Error - 0 if successful, or -1 error/VESA not supported.
- *
- ****************************************************************************/
- long InitVESA(void)
- {
- #ifdef __WATCOMC__
- union REGS r;
- struct SREGS sr;
- RMInfo rmi;
- long error = -1;
- /* Allocate real-mode memory for VESA structure. */
- r.x.eax = 0x0100;
- r.x.ebx = (sizeof(VESAInfo) + 15) >> 4;
- int386(0x31, &r, &r);
- if (r.x.cflag == 0) {
- _VInfoSel = r.w.dx;
- _VInfoSeg = r.w.ax;
- /* Allocate real-mode memory for VESAModeInfo structure. */
- r.x.eax = 0x0100;
- r.x.ebx = (sizeof(VESAModeInfo) + 15) >> 4;
- int386(0x31, &r, &r);
- if (r.x.cflag == 0) {
- _ModeInfoSel = r.w.dx;
- _ModeInfoSeg = r.w.ax;
- /* Clear VESAInfo structure. */
- memset(MK_PTR(0, _VInfoSeg), 0, sizeof(VESAInfo));
- /* Get VESA information. */
- memset(&rmi, 0, sizeof(RMInfo));
- rmi.eax = 0x4F00;
- rmi.edi = 0;
- rmi.es = _VInfoSeg;
- segread(&sr);
- r.w.ax = 0x0300;
- r.h.bl = 0x10;
- r.h.bh = 0;
- r.w.cx = 0;
- sr.es = FP_SEG(&rmi);
- r.x.edi = FP_OFF(&rmi);
- int386x(0x31, &r, &r, &sr);
- if ((r.x.cflag == 0) && (rmi.eax == 0x004F)) {
- error = 0;
- }
- }
- }
- if (error != 0) {
- UninitVESA();
- }
- return (error);
- #else /* __WATCOMC__ */
- unsigned short rseg;
- long paras;
- long error = -1;
- /* Calculate size of VESAInfo structure in paragraphs */
- paras = (sizeof(VESAInfo) + 15) >> 4;
-
- /* Allocate real-mode memory for VESA structure. */
- if (_dx_real_alloc(paras, (unsigned short *)&rseg,
- (unsigned short *)¶s) == 0) {
- RP_SET(_rpVInfo, 0, rseg);
- /* Calculate size of VESAModeInfo structure in paragraphs */
- paras = (sizeof(VESAModeInfo) + 15) >> 4;
- /* Allocate real-mode memory for VESAModeInfo structure. */
- if (_dx_real_alloc(paras, (unsigned short *)&rseg,
- (unsigned short *)¶s) == 0) {
- RP_SET(_rpModeInfo, 0, rseg);
- /* Clear the input buffer */
- FillRealMem(_rpVInfo, 0, sizeof(VESAInfo));
- /* Set up function call */
- _regs.eax = 0x4F00;
- _regs.edi = RP_OFF(_rpVInfo);
- _regs.es = RP_SEG(_rpVInfo);
- _dx_real_int(0x10, &_regs);
- if (_regs.eax == 0x004F) {
- ReadRealMem(&_VInfo, _rpVInfo, sizeof(VESAInfo));
- error = 0;
- }
- }
- }
- if (error != 0) {
- UninitVESA();
- }
- return (error);
- #endif /* __WATCOMC__ */
- }
- /****************************************************************************
- *
- * NAME
- * UninitVESA - Uninitialize the VESA video manager.
- *
- * SYNOPSIS
- * UninitVESA()
- *
- * void UninitVESA(void);
- *
- * FUNCTION
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ****************************************************************************/
- void UninitVESA(void)
- {
- #ifdef __WATCOMC__
- union REGS r;
- /* Free VESAInfo structure */
- if (_VInfoSeg != NULL) {
- r.x.eax = 0x0101;
- r.x.edx = _VInfoSel;
- int386(0x31, &r, &r);
- _VInfoSeg = NULL;
- _VInfoSel = NULL;
- }
- /* Free VESAModeInfo structure */
- if (_ModeInfoSeg != NULL) {
- r.x.eax = 0x0101;
- r.x.edx = _VInfoSel;
- int386(0x31, &r, &r);
- _ModeInfoSeg = NULL;
- _ModeInfoSel = NULL;
- }
- #else /* __WATCOMC__ */
- /* Free VESAInfo structure */
- if (_rpVInfo != NULL) {
- _dx_real_free(RP_SEG(_rpVInfo));
- _rpVInfo = NULL;
- }
- /* Free VESAModeInfo structure */
- if (_rpModeInfo != NULL) {
- _dx_real_free(RP_SEG(_rpModeInfo));
- _rpModeInfo = NULL;
- }
- #endif /* __WATCOMC__ */
- }
- /****************************************************************************
- *
- * NAME
- * SetVESAMode - Set the display adapter to the given VESA video mode.
- *
- * SYNOPSIS
- * VESAModeInfo = SetVESAMode(Mode)
- *
- * VESAModeInfo *SetVESAMode(long);
- *
- * FUNCTION
- * Set the display adapter to the specified VESA video mode.
- *
- * INPUTS
- * Mode - VESA video mode to set the display to.
- *
- * RESULT
- * VESAModeInfo - Pointer to VESA mode information structure or NULL if
- * error.
- *
- ****************************************************************************/
- VESAModeInfo *SetVESAMode(long mode)
- {
- VESAModeInfo *vminfo;
- /* Get mode info */
- if ((vminfo = ReadVESAModeInfo(mode)) != NULL) {
- /* If the mode is supported, set it. */
- if ((vminfo->Attributes & 0x01) != 0) {
- #ifdef __WATCOMC__
- {
- union REGS r;
-
- r.x.eax = 0x4F02;
- r.x.ebx = mode;
- int386(0x10, &r, &r);
- if (r.x.eax != 0x004F)
- vminfo = NULL;
- }
- #else /* __WATCOMC__ */
- /* Set up function call */
- _regs.eax = 0x4F02;
- _regs.ebx = mode;
- _dx_real_int(0x10, &_regs);
- if (_regs.eax != 0x004F) {
- vminfo = NULL;
- }
- #endif /* __WATCOMC__ */
- }
- }
- return (vminfo);
- }
- /****************************************************************************
- *
- * NAME
- * ReadVESAModeInfo - Read the VESA mode information from the video card.
- *
- * SYNOPSIS
- * VESAModeInfo = ReadVESAModeInfo(Mode)
- *
- * VESAModeInfo *ReadVESAModeInfo(long);
- *
- * FUNCTION
- * Read information about the specified mode from the VESA video BIOS.
- *
- * INPUTS
- * Mode - Mode ID to get information about.
- *
- * RESULT
- * VESAModeInfo - Pointer to VESA mode information structure or NULL if
- * error.
- *
- ****************************************************************************/
- VESAModeInfo *ReadVESAModeInfo(long mode)
- {
- VESAModeInfo *vminfo = NULL;
- #ifdef __WATCOMC__
- union REGS r;
- struct SREGS sr;
- RMInfo rmi;
- /* Make sure we have real-mode memory. */
- if (_ModeInfoSeg != NULL) {
- memset(MK_PTR(0, _ModeInfoSeg), 0, sizeof(VESAModeInfo));
- /* Get mode information. */
- memset(&rmi, 0, sizeof(RMInfo));
- rmi.eax = 0x4F01;
- rmi.ecx = mode;
- rmi.edi = 0;
- rmi.es = _ModeInfoSeg;
- segread(&sr);
- r.w.ax = 0x0300;
- r.w.bx = 0x0010;
- r.w.cx = 0;
- sr.es = FP_SEG(&rmi);
- r.x.edi = FP_OFF(&rmi);
- int386x(0x31, &r, &r, &sr);
- if ((r.x.cflag == 0) && (rmi.eax == 0x004F)) {
- vminfo = (VESAModeInfo *)MK_PTR(0, _ModeInfoSeg);
- }
- }
- #else /* __WATCOMC__ */
- /* Make sure we have real-mode memory. */
- if (_rpModeInfo != NULL) {
- /* Clear the input buffer */
- FillRealMem(_rpModeInfo, 0, sizeof(VESAModeInfo));
- /* Set up function call */
- _regs.eax = 0x4F01;
- _regs.ecx = mode;
- _regs.edi = RP_OFF(_rpModeInfo);
- _regs.es = RP_SEG(_rpModeInfo);
- _dx_real_int(0x10, &_regs);
- if (_regs.eax == 0x004F) {
- ReadRealMem(&_ModeInfo, _rpModeInfo, sizeof(VESAModeInfo));
- vminfo = &_ModeInfo;
- }
- }
- #endif /* __WATCOMC__ */
- return (vminfo);
- }
- /****************************************************************************
- *
- * NAME
- * SetVESAWindow - Set VESA window A's start address.
- *
- * SYNOPSIS
- * Error = SetVESAWindow(GrainNum)
- *
- * long SetVESAWindow(long);
- *
- * FUNCTION
- * This function invokes the Window Function, whose address is provided
- * in the VESAModeInfo structure. The 'GrainNum' must be in granularity
- * units as specified in the ModeInfo structure.
- *
- * INPUTS
- * GrainNum - Granularity number to set window to.
- *
- * RESULT
- * NONE
- *
- ****************************************************************************/
- void SetVESAWindow(long grain)
- {
- #ifdef __WATCOMC__
- #else /* __WATCOMC__ */
- RMC_BLK regp;
-
- regp.eax = 0x4F05;
- regp.ebx = 0x00;
- regp.edx = grain;
- _dx_call_real(_ModeInfo.WinFunc, ®p, 0);
- #endif /* __WATCOMC__ */
- }
|