1 /**
2 ** u_vesa.c ---- interface utility functions to VESA BIOS inquiry calls
3 **
4 ** Copyright (c) 1995 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
5 ** [e-mail: csaba@vuse.vanderbilt.edu]
6 **
7 ** This file is part of the GRX graphics library.
8 **
9 ** The GRX graphics library is free software; you can redistribute it
10 ** and/or modify it under some conditions; see the "copying.grx" file
11 ** for details.
12 **
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 **
17 ** Contributions by: (See "doc/credits.doc" for details)
18 ** Hartmut Schirmer (hsc@xaphod.techfak.uni-kiel.d400.de)
19 **/
20
21 #include "libgrx.h"
22 #include "allocate.h"
23 #include "vesa.h"
24 #include "mempeek.h"
25 #include "memfill.h"
26 #include "int86.h"
27
28 #ifndef IREG_AX
29
_GrViDrvVESAgetVGAinfo(VESAvgaInfoBlock * ib)30 int _GrViDrvVESAgetVGAinfo(VESAvgaInfoBlock *ib)
31 {
32 return(FALSE);
33 }
_GrViDrvVESAgetModeInfo(int mode,VESAmodeInfoBlock * ib)34 int _GrViDrvVESAgetModeInfo(int mode,VESAmodeInfoBlock *ib)
35 {
36 return(FALSE);
37 }
38
_GrViDrvVESAgetPMinfo(void)39 VESApmInfoBlock * _GrViDrvVESAgetPMinfo(void)
40 {
41 return(NULL);
42 }
43
44 #else
45
46 #if defined(__WATCOMC__) && defined(__386__)
47 #define FAR _far
48 #else
49 #define FAR far
50 #endif /* __WATCOMC__ && __386__*/
51
_GrViDrvVESAgetVGAinfo(VESAvgaInfoBlock * ib)52 int _GrViDrvVESAgetVGAinfo(VESAvgaInfoBlock *ib)
53 {
54 static char *nmcopy = NULL;
55 static short *mdcopy = NULL;
56 Int86Regs regs;
57 short FAR *mp;
58 short *modes;
59 char FAR *p1;
60 char *p2;
61 int ii;
62 DECLARE_XFER_BUFFER(1000);
63 /*
64 * copy VBE 2.0 tag into XFER buffer
65 */
66 setup_far_selector(LINP_SEL(XFER_BUFFER));
67 p1 = (char FAR *)LINP_PTR(XFER_BUFFER);
68 poke_b_f(p1,'V'); ++p1;
69 poke_b_f(p1,'B'); ++p1;
70 poke_b_f(p1,'E'); ++p1;
71 poke_b_f(p1,'2'); ++p1;
72 /*
73 * set up registers and call interrupt
74 */
75 sttzero(®s);
76 IREG_AX(regs) = VESA_FUNC + VESA_VGA_INFO;
77 IREG_ES(regs) = FP_SEG(XFER_BUFFER);
78 IREG_DI(regs) = FP_OFF(XFER_BUFFER);
79 int10x(®s);
80 if(IREG_AX(regs) != VESA_SUCCESS) {
81 DELETE_XFER_BUFFER;
82 return(FALSE);
83 }
84 /*
85 * copy VESA info block into accessible memory
86 */
87 setup_far_selector(LINP_SEL(XFER_BUFFER));
88 p1 = (char FAR *)LINP_PTR(XFER_BUFFER);
89 p2 = (char *)ib;
90 for(ii = sizeof(*ib); --ii >= 0; p1++,p2++) *p2 = peek_b_f(p1);
91
92 if ( ib->VESAsignature[0] != 'V' ||
93 ib->VESAsignature[1] != 'E' ||
94 ib->VESAsignature[2] != 'S' ||
95 ib->VESAsignature[3] != 'A' ) {
96 DELETE_XFER_BUFFER;
97 return(FALSE);
98 }
99 /*
100 * allocate space and copy mode list into accessible memory
101 */
102 mp = LINP_PTR(MK_FP(FP86_SEG(ib->VideoModePtr),FP86_OFF(ib->VideoModePtr)));
103 p1 = (char FAR *)mp;
104 for(ii = 1; (short)peek_w_f(mp) != (short)(-1); mp++,ii++);
105 modes = mdcopy = realloc(mdcopy,ii * sizeof(short));
106 if(!modes) { DELETE_XFER_BUFFER; return(FALSE); }
107 ib->VideoModePtr = modes;
108 mp = (short far *)p1;
109 for( ; --ii >= 0; mp++,modes++) *modes = peek_w_f(mp);
110 /*
111 * allocate space and copy ID string into accessible memory
112 */
113 p1 = LINP_PTR(MK_FP(FP86_SEG(ib->OEMstringPtr),FP86_OFF(ib->OEMstringPtr)));
114 mp = (short FAR *)p1;
115 for(ii = 1; (char)peek_b_f(p1) != (char)(0); p1++,ii++);
116 p2 = nmcopy = realloc(nmcopy,ii * sizeof(char));
117 if(!p2) { DELETE_XFER_BUFFER; return(FALSE); }
118 ib->OEMstringPtr = p2;
119 p1 = (char FAR *)mp;
120 for( ; --ii >= 0; p1++,p2++) *p2 = peek_b_f(p1);
121 DELETE_XFER_BUFFER;
122 return(TRUE);
123 }
124
_GrViDrvVESAgetPMinfo(void)125 VESApmInfoBlock * _GrViDrvVESAgetPMinfo(void) {
126 Int86Regs r;
127 static VESApmInfoBlock *ib = NULL;
128 unsigned Length, ii;
129 char FAR *p1;
130 char *p2;
131
132 sttzero(&r);
133 IREG_AX(r) = VESA_FUNC + VESA_PM_INTERF;
134 IREG_BX(r) = 0x0000;
135 DBGPRINTF(DBG_DRIVER,("Getting protected mode interface\n"));
136 int10x(&r);
137 if(IREG_AX(r) != VESA_SUCCESS)
138 return(NULL);
139 /* Now we have : CX = length of table and routines (bytes)
140 ES:DI = pointer to table
141 ES_DI+00: offset PM set window routine
142 +02: offset PM set display start
143 +04: offset PM set primary palette
144 +06: offset PM description table */
145 Length = (unsigned)IREG_CX(r);
146 if( Length == 0) return(NULL);
147 ib = realloc(ib, Length + VESApmInfoBlock_BASEOFF);
148 if (ib == NULL) return(NULL);
149
150 ib->RealMode_SEG = IREG_ES(r);
151 ib->RealMode_OFF = IREG_DI(r);
152 ib->PhysicalLength = IREG_CX(r);
153
154 setup_far_selector(LINP_SEL(MK_FP( IREG_ES(r),IREG_DI(r))));
155 p1 = LINP_PTR( MK_FP( IREG_ES(r),IREG_DI(r) ) );
156 p2 = (char *) &(ib->SetWindow_off);
157 for(ii = 0; ii < Length; p1++,ii++) *(p2++) = peek_b_f(p1);
158 DBGPRINTF(DBG_DRIVER,("Protected Mode Interface :-\n" ));
159 DBGPRINTF(DBG_DRIVER,(" Real mode address = 0x%04x:0x%04x\n",ib->RealMode_SEG,ib->RealMode_OFF));
160 DBGPRINTF(DBG_DRIVER,(" Length = 0x%08x\n",ib->PhysicalLength));
161 DBGPRINTF(DBG_DRIVER,(" SetWindow function offset = 0x%08x\n",ib->SetWindow_off));
162 DBGPRINTF(DBG_DRIVER,(" SetDisplayStart function offset = 0x%08x\n",ib->DisplStart_off));
163 DBGPRINTF(DBG_DRIVER,(" Primary Palette function offset = 0x%08x\n",ib->PPalette_off));
164 DBGPRINTF(DBG_DRIVER,(" Resource Sub-Table offset = 0x%08x\n",ib->SubTable_off));
165 #ifdef DUMP_PM_TABLE
166 {
167 static int once = 0;
168 if (!once) {
169 int len;
170 FILE *dump = fopen("vesapm.s", "wt");
171 once = 1;
172 if (dump) {
173 p2 = (char *) &(ib->SetWindow_off);
174 fprintf(dump, ".text\n_vesa_pm_table:\n");
175 for (len=0; len < Length; ++len) {
176 fprintf(dump, "\t.byte %u\n", *(unsigned char *)p2);
177 ++p2;
178 }
179 fclose(dump);
180 }
181 dump = fopen("vesapm.dmp", "wb");
182 if (dump) {
183 p2 = (char *) &(ib->SetWindow_off);
184 fwrite(p2,Length,1,dump);
185 fclose(dump);
186 }
187 }
188 }
189 #endif
190 return(ib);
191 }
192
_GrViDrvVESAgetModeInfo(int mode,VESAmodeInfoBlock * ib)193 int _GrViDrvVESAgetModeInfo(int mode,VESAmodeInfoBlock *ib)
194 {
195 Int86Regs regs;
196 char FAR *p1;
197 char *p2;
198 int ii;
199 DECLARE_XFER_BUFFER(1000);
200 /*
201 * set up registers and call interrupt
202 */
203 sttzero(®s);
204 IREG_AX(regs) = VESA_FUNC + VESA_MODE_INFO;
205 IREG_CX(regs) = mode;
206 IREG_ES(regs) = FP_SEG(XFER_BUFFER);
207 IREG_DI(regs) = FP_OFF(XFER_BUFFER);
208 int10x(®s);
209 if(IREG_AX(regs) != VESA_SUCCESS) {
210 DELETE_XFER_BUFFER;
211 return(FALSE);
212 }
213 /*
214 * copy VESA info block into accessible memory
215 */
216 setup_far_selector(LINP_SEL(XFER_BUFFER));
217 p1 = (char FAR *)LINP_PTR(XFER_BUFFER);
218 p2 = (char *)ib;
219 for(ii = sizeof(*ib); --ii >= 0; p1++,p2++) *p2 = peek_b_f(p1);
220 DELETE_XFER_BUFFER;
221 return((ib->ModeAttributes & MODE_SUPPORTED) ? TRUE : FALSE);
222 }
223
224 #endif
225
226