VESALIB.C 8.3 KB

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