VESALIB.C 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/2d/rcs/vesalib.c $
  15. * $Revision: 1.3 $
  16. * $Author: john $
  17. * $Date: 1994/11/07 12:07:42 $
  18. *
  19. * Routines to access VESA video modes.
  20. *
  21. * $Log: vesalib.c $
  22. * Revision 1.3 1994/11/07 12:07:42 john
  23. * Made save/restore cursor work a bit better.
  24. *
  25. * Revision 1.2 1994/09/29 10:09:26 john
  26. * Initial version, but not used.
  27. *
  28. * Revision 1.1 1994/09/19 11:54:45 john
  29. * Initial revision
  30. *
  31. *
  32. */
  33. #pragma off (unreferenced)
  34. static char rcsid[] = "$Id: vesalib.c 1.3 1994/11/07 12:07:42 john Exp $";
  35. #pragma on (unreferenced)
  36. #include "dpmi.h"
  37. typedef struct VgaInfoBlock {
  38. char VESASignature[4]; // 4 signature bytes
  39. ushort VESAVersion; // VESA version number
  40. ushort OEMStringPtrOffset; // Pointer to OEM string
  41. ushort OEMStringPtrSegment; // Pointer to OEM string
  42. uint Capabilities; // Capabilities of the video environment
  43. ushort VideoModePtrOffset; // Pointer to supported Super VGA modes
  44. ushort VideoModePtrSegment; // Pointer to supported Super VGA modes
  45. ushort TotalMemory; // Number of 64K memory blocks on board
  46. ubyte Reserved[242]; // Reserved for future use.
  47. } VgaInfoBlock;
  48. typedef struct ModeInfoBlock {
  49. ushort ModeAttributes;
  50. ubyte WinAAttributes;
  51. ubyte WinBAttributes;
  52. ushort WinGranularity;
  53. ushort WinSize;
  54. ushort WinASegment;
  55. ushort WinBSegment;
  56. ushort WinFuncPtrOffset;
  57. ushort WinFuncPtrSegment;
  58. ushort BytesPerScanLine;
  59. ushort Xresolution;
  60. ushort Yresolution;
  61. ubyte Xcharsize;
  62. ubyte Ycharsize;
  63. ubyte NumberOfPlanes;
  64. ubyte BitsPerPixel;
  65. ubyte NumberOfBanks;
  66. ubyte MemoryModel;
  67. ubyte BankSize;
  68. ubyte dummy[227];
  69. } ModeInfoBlock;
  70. // 0=Mode set OK
  71. // 1=No VGA adapter installed
  72. // 2=Program doesn't support this VESA granularity
  73. // 3=Monitor doesn't support that VESA mode.:
  74. // 4=Video card doesn't support that VESA mode.
  75. // 5=No VESA driver found.
  76. // 6=Bad Status after VESA call/
  77. // 7=Not enough DOS memory to call VESA functions.
  78. // 8=Error using DPMI.
  79. // 9=Error setting logical line width.
  80. // 10=Error allocating selector for A0000h
  81. // 11=Not a valid mode support by gr.lib
  82. // Returns one of the above without setting mode
  83. void *pDosBuffer=NULL;
  84. VgaInfoBlock vesa_info_block;
  85. ModeInfoBlock vesa_mode_info_block;
  86. ushort RealSelector;
  87. ushort * SupportedModes=NULL;
  88. short gr_vesa_check_mode(short mode)
  89. {
  90. dpmi_real_regs rr;
  91. if(pDosBuffer==NULL) {
  92. pDosBuffer = dpmi_real_malloc( 256, &RealSelector );
  93. if (!pDosBuffer)
  94. Error( "Error allocating DOS buffer" );
  95. }
  96. memset( &rr, 0, sizeof(dpmi_real_regs); // Clear real registers...
  97. rr.eax = 0x4f00; // Return SuperVGA information
  98. rr.es = DPMI_real_segment(pDosBuffer);
  99. rr.edi = DPMI_real_offset(pDosBuffer);
  100. dpmi_real_int386( 0x10, &rr );
  101. if ((rr.eax & 0xffff) != 0x4f ) {
  102. return 5; // No VESA driver found
  103. }
  104. memcpy( &vesa_info_block, pDosBuffer, sizeof(VgaInfoBlock) );
  105. // Make sure there is a VESA signature
  106. if (!memcmp( vesa_info_block.VESASignature, "VESA" ))
  107. return 5; // No VESA driver found
  108. // We now have a valid VESA driver loaded, so search through the
  109. // list of supported modes, searching for the mode we want.
  110. SupportedModes = (ushort *)((vesa_info_block.VideoModePtrSegment*16)+vesa_info_block.VideoModePtrOffset);
  111. while( *SupportedModes != 0xffff ) {
  112. if (*SupportedModes==mode) {
  113. break;
  114. }
  115. SupportedModes++;
  116. }
  117. if (*SupportedModes!=mode) {
  118. return 4; // Video card doesn't support that VESA mode.
  119. }
  120. memset( &rr, 0, sizeof(dpmi_real_regs); // Clear real registers...
  121. rr.eax = 0x4f01; // Return SuperVGA mode information
  122. rr.ecx = mode; // Super VGA video mode
  123. rr.es = DPMI_real_segment(pDosBuffer);
  124. rr.edi = DPMI_real_offset(pDosBuffer);
  125. dpmi_real_int386x( 0x10, &rr );
  126. if ((rr.eax & 0xffff) != 0x4f ) {
  127. return 5; // No VESA driver found
  128. }
  129. memcpy( &vesa_mode_info_block, pDosBuffer, sizeof(ModeInfoBlock) );
  130. if (!(vesa_mode_info_block.ModeAttributes&1) ) {
  131. return 3; // Monitor doesn't support this mode.
  132. }
  133. switch( vesa_mode_info_block.WinGranularity ) {
  134. case 64: PageSizeShift = 0; break;
  135. case 32: PageSizeShift = 1; break;
  136. case 16: PageSizeShift = 2; break;
  137. case 8: PageSizeShift = 3; break;
  138. case 4: PageSizeShift = 4; break;
  139. case 2: PageSizeShift = 5; break;
  140. case 1: PageSizeShift = 6; break;
  141. default:
  142. return 2; // Granularity not supported.
  143. }
  144. return 0;
  145. }
  146. typedef struct VgaInfoBlock {
  147. char VESASignature[4]; // 4 signature bytes
  148. ushort VESAVersion; // VESA version number
  149. ushort OEMStringPtrOffset; // Pointer to OEM string
  150. ushort OEMStringPtrSegment; // Pointer to OEM string
  151. uint Capabilities; // Capabilities of the video environment
  152. ushort VideoModePtrOffset; // Pointer to supported Super VGA modes
  153. ushort VideoModePtrSegment; // Pointer to supported Super VGA modes
  154. ushort TotalMemory; // Number of 64K memory blocks on board
  155. ubyte Reserved[242]; // Reserved for future use.
  156. } VgaInfoBlock;
  157. void * gr_save_mode_vesa()
  158. {
  159. void * pDosBuffer;
  160. ushort DosSelector;
  161. dpmi_real_regs rr;
  162. VgaInfoBlock vesa_info_block;
  163. int save_size;
  164. pDosBuffer = dpmi_real_malloc(sizeof(VgaInfoBlock), &DosSelector);
  165. if (!pDosBuffer)
  166. return NULL;
  167. memset( &rr, 0, sizeof(dpmi_real_regs)); // Clear real registers...
  168. rr.eax = 0x4f00; // Return SuperVGA information
  169. rr.es = DPMI_real_segment(pDosBuffer);
  170. rr.edi = DPMI_real_offset(pDosBuffer);
  171. dpmi_real_int386x( 0x10, &rr );
  172. memcpy( &vesa_info_block, pDosBuffer, sizeof(VgaInfoBlock) );
  173. dpmi_real_free(DosSelector);
  174. if ((rr.eax & 0xffff) != 0x4f ) {
  175. return NULL; // No VESA driver found
  176. }
  177. // Make sure there is a VESA signature
  178. if (!memcmp( vesa_info_block.VESASignature, "VESA", 4 ))
  179. return NULL; // No VESA driver found
  180. memset( &rr, 0, sizeof(dpmi_real_regs)); // Clear real registers...
  181. rr.eax = 0x4f04; // Save/Restore SuperVGA video state
  182. rr.edx = 00; // Return save/restore buffer size
  183. rr.ecx = 0xf; // Save all states
  184. dpmi_real_int386x( 0x10, &rr );
  185. if ((rr.eax & 0xffff) != 0x4f ) {
  186. return NULL; // No VESA driver found
  187. }
  188. save_size = (rr.ebx & 0xffff)*64; // How many bytes save buffer requires...
  189. pDosBuffer = dpmi_real_malloc(save_size, &DosSelector);
  190. if (!pDosBuffer)
  191. return NULL;
  192. memset( &rr, 0, sizeof(dpmi_real_regs)); // Clear real registers...
  193. rr.eax = 0x4f04; // Save/Restore SuperVGA video state
  194. rr.edx = 1; // Save video state
  195. rr.ecx = 0xf; // Save all states
  196. rr.es = DPMI_real_segment(pDosBuffer);
  197. rr.ebx = DPMI_real_offset(pDosBuffer);
  198. dpmi_real_int386x( 0x10, &rr );
  199. if ((rr.eax & 0xffff) != 0x4f ) {
  200. dpmi_real_free(DosSelector);
  201. return NULL; // No VESA driver found
  202. }
  203. gr_restore_mode_vesa( pDosBuffer );
  204. return pDosBuffer;
  205. }
  206. void gr_restore_mode_vesa(void * buffer)
  207. {
  208. void * pDosBuffer;
  209. ushort DosSelector;
  210. dpmi_real_regs rr;
  211. VgaInfoBlock vesa_info_block;
  212. pDosBuffer = dpmi_real_malloc(sizeof(VgaInfoBlock), &DosSelector);
  213. if (!pDosBuffer)
  214. return;
  215. memset( &rr, 0, sizeof(dpmi_real_regs)); // Clear real registers...
  216. rr.eax = 0x4f00; // Return SuperVGA information
  217. rr.es = DPMI_real_segment(pDosBuffer);
  218. rr.edi = DPMI_real_offset(pDosBuffer);
  219. dpmi_real_int386x( 0x10, &rr );
  220. memcpy( &vesa_info_block, pDosBuffer, sizeof(VgaInfoBlock) );
  221. dpmi_real_free(DosSelector);
  222. if ((rr.eax & 0xffff) != 0x4f ) {
  223. return; // No VESA driver found
  224. }
  225. // Make sure there is a VESA signature
  226. if (!memcmp( vesa_info_block.VESASignature, "VESA", 4 ))
  227. return; // No VESA driver found
  228. memset( &rr, 0, sizeof(dpmi_real_regs)); // Clear real registers...
  229. rr.eax = 0x4f04; // Save/Restore SuperVGA video state
  230. rr.edx = 2; // Restore video state
  231. rr.ecx = 0xf; // Save all states
  232. rr.es = DPMI_real_segment(buffer);
  233. rr.ebx = DPMI_real_offset(buffer);
  234. dpmi_real_int386x( 0x10, &rr );
  235. if ((rr.eax & 0xffff) != 0x4f ) {
  236. return; // No VESA driver found
  237. }
  238. return;
  239. }
  240.