Chameleon

Chameleon Svn Source Tree

Root/branches/meklortOld/i386/libsaio/vbe.c

Source at commit 1146 created 12 years 10 months ago.
By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing).
1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1993 NeXT, Inc.
26 * All rights reserved.
27 */
28
29#include "libsaio.h"
30#include "vbe.h"
31
32/*
33 * Globals
34 */
35static biosBuf_t bb;
36
37int getVBEInfo( void * infoBlock )
38{
39 bb.intno = 0x10;
40 bb.eax.rr = funcGetControllerInfo;
41 bb.es = SEG( infoBlock );
42 bb.edi.rr = OFF( infoBlock );
43 bios( &bb );
44 return(bb.eax.r.h);
45}
46
47int getVBEModeInfo( int mode, void * minfo_p )
48{
49 bb.intno = 0x10;
50 bb.eax.rr = funcGetModeInfo;
51 bb.ecx.rr = mode;
52 bb.es = SEG(minfo_p);
53 bb.edi.rr = OFF(minfo_p);
54 bios(&bb);
55 return(bb.eax.r.h);
56}
57#if UNUSED
58int getVBEDACFormat(unsigned char *format)
59{
60 bb.intno = 0x10;
61 bb.eax.rr = funcGetSetPaletteFormat;
62 bb.ebx.r.l = subfuncGet;
63 bios(&bb);
64 *format = bb.ebx.r.h;
65 return(bb.eax.r.h);
66}
67
68int setVBEDACFormat(unsigned char format)
69{
70 bb.intno = 0x10;
71 bb.eax.rr = funcGetSetPaletteFormat;
72 bb.ebx.r.l = subfuncSet;
73 bb.ebx.r.h = format;
74 bios(&bb);
75 return(bb.eax.r.h);
76}
77#endif
78
79int getEDID( void * edidBlock, UInt8 block)
80{
81bzero(&bb, sizeof(bb));
82 bb.intno = 0x10;
83 bb.eax.rr = funcGetEDID;
84bb.ebx.r.l= 0x01;
85bb.edx.rr = block;
86
87 bb.es = SEG( edidBlock );
88 bb.edi.rr = OFF( edidBlock );
89
90 bios( &bb );
91 return(bb.eax.r.h);
92}
93
94
95
96/*
97 * Default GTF parameter values.
98 */
99#define kCellGranularity 8.0 // character cell granularity
100#define kMinVSyncPlusBP 550.0 // min VSync + BP interval (us)
101#define kMinFrontPorch 1.0 // minimum front porch in lines(V)/cells(H)
102#define kVSyncLines 3.0 // width of VSync in lines
103#define kHSyncWidth 8.0 // HSync as a percent of total line width
104#define kC 30.0 // C = (C'-J) * (K/256) + J
105#define kM 300.0 // M = K/256 * M'
106
107int Round(double f)
108{
109return (int)(f + 0.5);
110}
111
112/*
113 * from http://www.azillionmonkeys.com/qed/sqroot.html
114 */
115#if UNUSED
116double Sqrt( double y )
117{
118double x, z, tempf;
119unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
120
121tempf = y;
122*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
123x = tempf;
124z = y*0.5; /* hoist out the “/2” */
125x = (1.5*x) - (x*x)*(x*z); /* iteration formula */
126x = (1.5*x) - (x*x)*(x*z);
127x = (1.5*x) - (x*x)*(x*z);
128x = (1.5*x) - (x*x)*(x*z);
129x = (1.5*x) - (x*x)*(x*z);
130return x*y;
131}
132
133int generateCRTCTiming( unsigned short width,
134 unsigned short height,
135 unsigned long paramValue,
136 int paramType,
137 VBECRTCInfoBlock * timing )
138{
139 double h_period_est, h_freq, h_period, h_total_pixels, h_sync_pixels;
140 double h_active_pixels, h_ideal_duty_cycle, h_blank_pixels, pixel_freq = 0;
141 double v_sync_plus_bp = 0, v_total_lines = 0, v_field_rate_est, v_frame_rate = 0;
142 const double h_pixels = (double) width;
143 const double v_lines = (double) height;
144
145 enum {
146 left_margin_pixels = 0,
147 right_margin_pixels = 0,
148 top_margin_lines = 0,
149 bot_margin_lines = 0,
150 interlace = 0
151 };
152
153 // Total number of active pixels in image and both margins
154 h_active_pixels = h_pixels + left_margin_pixels + right_margin_pixels;
155
156 if (paramType == kCRTCParamPixelClock)
157 {
158 // Pixel clock provided in MHz
159 pixel_freq = (double) paramValue / 1000000;
160
161 // Ideal horizontal period from the blanking duty cycle equation
162 h_period = ((kC - 100) + (Sqrt(((100 - kC) * (100 - kC)) + (0.4 * kM *
163 (h_active_pixels + right_margin_pixels + left_margin_pixels) /
164 pixel_freq)))) / 2.0 / kM * 1000;
165 }
166 else /* kCRTCParamRefreshRate */
167 {
168 double v_field_rate_in = (double) paramValue;
169
170 // Estimate the horizontal period
171 h_period_est = ((1 / v_field_rate_in) - kMinVSyncPlusBP / 1000000) /
172 (v_lines + (2 * top_margin_lines) + kMinFrontPorch + interlace) *
173 1000000;
174
175 // Number of lines in Vsync + back porch
176 v_sync_plus_bp = Round(kMinVSyncPlusBP / h_period_est);
177
178 // Total number of lines in Vetical field period
179 v_total_lines = v_lines + top_margin_lines + bot_margin_lines +
180 v_sync_plus_bp + interlace + kMinFrontPorch;
181
182 // Estimate the vertical field frequency
183 v_field_rate_est = 1 / h_period_est / v_total_lines * 1000000;
184
185 // Find the actual horizontal period
186 h_period = h_period_est / (v_field_rate_in / v_field_rate_est);
187
188 // Find the vertical frame rate (no interlace)
189 v_frame_rate = 1 / h_period / v_total_lines * 1000000;
190 }
191
192 // Ideal blanking duty cycle from the blanking duty cycle equation
193 h_ideal_duty_cycle = kC - (kM * h_period / 1000);
194
195 // Number of pixels in the blanking time to the nearest double character cell
196 h_blank_pixels = Round(h_active_pixels * h_ideal_duty_cycle /
197 (100 - h_ideal_duty_cycle) / (2 * kCellGranularity)) *
198 (2 * kCellGranularity);
199
200 // Total number of horizontal pixels
201 h_total_pixels = h_active_pixels + h_blank_pixels;
202
203 if (paramType == kCRTCParamPixelClock)
204 {
205 // Horizontal frequency
206 h_freq = pixel_freq / h_total_pixels * 1000;
207
208 // Number of lines in V sync + back porch
209 v_sync_plus_bp = Round(kMinVSyncPlusBP * h_freq / 1000);
210
211 // Total number of lines in vertical field period
212 v_total_lines = v_lines + top_margin_lines + bot_margin_lines +
213 interlace + v_sync_plus_bp + kMinFrontPorch;
214
215 // Vertical frame frequency
216 v_frame_rate = Round(h_freq / v_total_lines * 1000);
217 }
218 else
219 {
220 // Find pixel clock frequency
221 pixel_freq = Round(h_total_pixels / h_period);
222 }
223
224 h_sync_pixels = Round(h_total_pixels * kHSyncWidth / 100 / kCellGranularity) *
225 kCellGranularity;
226
227 timing->HTotal = h_total_pixels;
228 timing->HSyncStart = h_active_pixels + (h_blank_pixels / 2) - h_sync_pixels;
229 timing->HSyncEnd = timing->HSyncStart + h_sync_pixels;
230 timing->VTotal = v_total_lines;
231 timing->VSyncStart = v_total_lines - v_sync_plus_bp;
232 timing->VSyncEnd = timing->VSyncStart + kVSyncLines;
233 timing->Flags = kCRTCNegativeHorizontalSync;
234 timing->PixelClock = pixel_freq * 1000000;
235 timing->RefreshRate = v_frame_rate * 100;
236
237 return 0;
238}
239
240#endif
241
242int setVBEMode(unsigned short mode, const VBECRTCInfoBlock * timing)
243{
244 bb.intno = 0x10;
245 bb.eax.rr = funcSetMode;
246 bb.ebx.rr = mode;
247 if (timing) {
248 bb.es = SEG(timing);
249 bb.edi.rr = OFF(timing);
250 }
251 bios(&bb);
252 return(bb.eax.r.h);
253}
254
255
256int setVBEPalette(void *palette)
257{
258 bb.intno = 0x10;
259 bb.eax.rr = funcGetSetPaletteData;
260 bb.ebx.r.l = subfuncSet;
261 bb.ecx.rr = 256;
262 bb.edx.rr = 0;
263 bb.es = SEG(palette);
264 bb.edi.rr = OFF(palette);
265 bios(&bb);
266 return(bb.eax.r.h);
267}
268
269#if UNUSED
270
271int getVBEPalette(void *palette)
272{
273 bb.intno = 0x10;
274 bb.eax.rr = funcGetSetPaletteData;
275 bb.ebx.r.l = subfuncGet;
276 bb.ecx.rr = 256;
277 bb.edx.rr = 0;
278 bb.es = SEG(palette);
279 bb.edi.rr = OFF(palette);
280 bios(&bb);
281 return(bb.eax.r.h);
282}
283
284int getVBECurrentMode(unsigned short *mode)
285{
286 bb.intno = 0x10;
287 bb.eax.rr = funcGetCurrentMode;
288 bios(&bb);
289 *mode = bb.ebx.rr;
290 return(bb.eax.r.h);
291}
292
293int getVBEPixelClock(unsigned short mode, unsigned long * pixelClock)
294{
295 bb.intno = 0x10;
296 bb.eax.rr = funcGetSetPixelClock;
297 bb.ebx.r.l = 0;
298 bb.ecx.rx = *pixelClock;
299 bb.edx.rr = mode;
300 bios(&bb);
301 *pixelClock = bb.ecx.rx;
302 return(bb.eax.r.h);
303}
304#endif
305

Archive Download this file

Revision: 1146