Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazileon/i386/libsaio/vbe.c

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#include "edid.h"//Azi:autoresolution
32#include "autoresolution.h" //||
33
34/*
35 * Various inline routines for video I/O
36 */
37static inline void
38outi (int port, int index, int val)
39{
40 outw (port, (val << 8) | index);
41}
42
43static inline void
44outib (int port, int index, int val)
45{
46 outb (port, index);
47 outb (port + 1, val);
48}
49
50static inline int
51ini (int port, int index)
52{
53 outb (port, index);
54 return inb (port + 1);
55}
56
57static inline void
58rmwi (int port, int index, int clear, int set)
59{
60 outb (port, index);
61 outb (port + 1, (inb (port + 1) & ~clear) | set);
62}
63
64/*
65 * Globals
66 */
67static biosBuf_t bb;
68
69int getVBEInfo( void * infoBlock )
70{
71 bb.intno = 0x10;
72 bb.eax.rr = funcGetControllerInfo;
73 bb.es = SEG( infoBlock );
74 bb.edi.rr = OFF( infoBlock );
75 bios( &bb );
76 return(bb.eax.r.h);
77}
78
79int getVBEModeInfo( int mode, void * minfo_p )
80{
81 bb.intno = 0x10;
82 bb.eax.rr = funcGetModeInfo;
83 bb.ecx.rr = mode;
84 bb.es = SEG(minfo_p);
85 bb.edi.rr = OFF(minfo_p);
86 bios(&bb);
87 return(bb.eax.r.h);
88}
89
90int getVBEDACFormat(unsigned char *format)
91{
92 bb.intno = 0x10;
93 bb.eax.rr = funcGetSetPaletteFormat;
94 bb.ebx.r.l = subfuncGet;
95 bios(&bb);
96 *format = bb.ebx.r.h;
97 return(bb.eax.r.h);
98}
99
100int setVBEDACFormat(unsigned char format)
101{
102 bb.intno = 0x10;
103 bb.eax.rr = funcGetSetPaletteFormat;
104 bb.ebx.r.l = subfuncSet;
105 bb.ebx.r.h = format;
106 bios(&bb);
107 return(bb.eax.r.h);
108}
109
110/*
111 *EDID/DDC Readings
112 */
113int getEDID( void *ddcblock, uint8_t blocksleft )
114{
115bb.intno = 0x10;
116bb.eax.rr = FUNC_GET_EDID;
117bb.ebx.r.l = SERVICE_READ_EDID;
118bb.es = SEG( ddcblock );
119bb.edi.rr = OFF( ddcblock );
120bb.edx.rr = blocksleft;
121bios( &bb );
122return( bb.eax.r.h );
123}
124
125/*
126 * Default GTF parameter values.
127 */
128#define kCellGranularity 8.0 // character cell granularity
129#define kMinVSyncPlusBP 550.0 // min VSync + BP interval (us)
130#define kMinFrontPorch 1.0 // minimum front porch in lines(V)/cells(H)
131#define kVSyncLines 3.0 // width of VSync in lines
132#define kHSyncWidth 8.0 // HSync as a percent of total line width
133#define kC 30.0 // C = (C'-J) * (K/256) + J
134#define kM 300.0 // M = K/256 * M'
135
136int Round(double f)
137{
138return (int)(f + 0.5);
139}
140
141/*
142 * from http://www.azillionmonkeys.com/qed/sqroot.html
143 */
144
145double Sqrt( double y )
146{
147double x, z, tempf;
148unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
149
150tempf = y;
151*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
152x = tempf;
153z = y*0.5; /* hoist out the “/2” */
154x = (1.5*x) - (x*x)*(x*z); /* iteration formula */
155x = (1.5*x) - (x*x)*(x*z);
156x = (1.5*x) - (x*x)*(x*z);
157x = (1.5*x) - (x*x)*(x*z);
158x = (1.5*x) - (x*x)*(x*z);
159return x*y;
160}
161
162int generateCRTCTiming( unsigned short width,
163 unsigned short height,
164 unsigned long paramValue,
165 int paramType,
166 VBECRTCInfoBlock * timing )
167{
168 double h_period_est, h_freq, h_period, h_total_pixels, h_sync_pixels;
169 double h_active_pixels, h_ideal_duty_cycle, h_blank_pixels, pixel_freq = 0;
170 double v_sync_plus_bp = 0, v_total_lines = 0, v_field_rate_est, v_frame_rate = 0;
171 const double h_pixels = (double) width;
172 const double v_lines = (double) height;
173
174 enum {
175 left_margin_pixels = 0,
176 right_margin_pixels = 0,
177 top_margin_lines = 0,
178 bot_margin_lines = 0,
179 interlace = 0
180 };
181
182 // Total number of active pixels in image and both margins
183 h_active_pixels = h_pixels + left_margin_pixels + right_margin_pixels;
184
185 if (paramType == kCRTCParamPixelClock)
186 {
187 // Pixel clock provided in MHz
188 pixel_freq = (double) paramValue / 1000000;
189
190 // Ideal horizontal period from the blanking duty cycle equation
191 h_period = ((kC - 100) + (Sqrt(((100 - kC) * (100 - kC)) + (0.4 * kM *
192 (h_active_pixels + right_margin_pixels + left_margin_pixels) /
193 pixel_freq)))) / 2.0 / kM * 1000;
194 }
195 else /* kCRTCParamRefreshRate */
196 {
197 double v_field_rate_in = (double) paramValue;
198
199 // Estimate the horizontal period
200 h_period_est = ((1 / v_field_rate_in) - kMinVSyncPlusBP / 1000000) /
201 (v_lines + (2 * top_margin_lines) + kMinFrontPorch + interlace) *
202 1000000;
203
204 // Number of lines in Vsync + back porch
205 v_sync_plus_bp = Round(kMinVSyncPlusBP / h_period_est);
206
207 // Total number of lines in Vetical field period
208 v_total_lines = v_lines + top_margin_lines + bot_margin_lines +
209 v_sync_plus_bp + interlace + kMinFrontPorch;
210
211 // Estimate the vertical field frequency
212 v_field_rate_est = 1 / h_period_est / v_total_lines * 1000000;
213
214 // Find the actual horizontal period
215 h_period = h_period_est / (v_field_rate_in / v_field_rate_est);
216
217 // Find the vertical frame rate (no interlace)
218 v_frame_rate = 1 / h_period / v_total_lines * 1000000;
219 }
220
221 // Ideal blanking duty cycle from the blanking duty cycle equation
222 h_ideal_duty_cycle = kC - (kM * h_period / 1000);
223
224 // Number of pixels in the blanking time to the nearest double character cell
225 h_blank_pixels = Round(h_active_pixels * h_ideal_duty_cycle /
226 (100 - h_ideal_duty_cycle) / (2 * kCellGranularity)) *
227 (2 * kCellGranularity);
228
229 // Total number of horizontal pixels
230 h_total_pixels = h_active_pixels + h_blank_pixels;
231
232 if (paramType == kCRTCParamPixelClock)
233 {
234 // Horizontal frequency
235 h_freq = pixel_freq / h_total_pixels * 1000;
236
237 // Number of lines in V sync + back porch
238 v_sync_plus_bp = Round(kMinVSyncPlusBP * h_freq / 1000);
239
240 // Total number of lines in vertical field period
241 v_total_lines = v_lines + top_margin_lines + bot_margin_lines +
242 interlace + v_sync_plus_bp + kMinFrontPorch;
243
244 // Vertical frame frequency
245 v_frame_rate = Round(h_freq / v_total_lines * 1000);
246 }
247 else
248 {
249 // Find pixel clock frequency
250 pixel_freq = Round(h_total_pixels / h_period);
251 }
252
253 h_sync_pixels = Round(h_total_pixels * kHSyncWidth / 100 / kCellGranularity) *
254 kCellGranularity;
255
256 timing->HTotal = h_total_pixels;
257 timing->HSyncStart = h_active_pixels + (h_blank_pixels / 2) - h_sync_pixels;
258 timing->HSyncEnd = timing->HSyncStart + h_sync_pixels;
259 timing->VTotal = v_total_lines;
260 timing->VSyncStart = v_total_lines - v_sync_plus_bp;
261 timing->VSyncEnd = timing->VSyncStart + kVSyncLines;
262 timing->Flags = kCRTCNegativeHorizontalSync;
263 timing->PixelClock = pixel_freq * 1000000;
264 timing->RefreshRate = v_frame_rate * 100;
265
266 return 0;
267}
268
269int setVBEMode(unsigned short mode, const VBECRTCInfoBlock * timing)
270{
271 bb.intno = 0x10;
272 bb.eax.rr = funcSetMode;
273 bb.ebx.rr = mode;
274 if (timing) {
275 bb.es = SEG(timing);
276 bb.edi.rr = OFF(timing);
277 }
278 bios(&bb);
279 return(bb.eax.r.h);
280}
281
282int setVBEPalette(void *palette)
283{
284 bb.intno = 0x10;
285 bb.eax.rr = funcGetSetPaletteData;
286 bb.ebx.r.l = subfuncSet;
287 bb.ecx.rr = 256;
288 bb.edx.rr = 0;
289 bb.es = SEG(palette);
290 bb.edi.rr = OFF(palette);
291 bios(&bb);
292 return(bb.eax.r.h);
293}
294
295int getVBEPalette(void *palette)
296{
297 bb.intno = 0x10;
298 bb.eax.rr = funcGetSetPaletteData;
299 bb.ebx.r.l = subfuncGet;
300 bb.ecx.rr = 256;
301 bb.edx.rr = 0;
302 bb.es = SEG(palette);
303 bb.edi.rr = OFF(palette);
304 bios(&bb);
305 return(bb.eax.r.h);
306}
307
308int getVBECurrentMode(unsigned short *mode)
309{
310 bb.intno = 0x10;
311 bb.eax.rr = funcGetCurrentMode;
312 bios(&bb);
313 *mode = bb.ebx.rr;
314 return(bb.eax.r.h);
315}
316
317int getVBEPixelClock(unsigned short mode, unsigned long * pixelClock)
318{
319 bb.intno = 0x10;
320 bb.eax.rr = funcGetSetPixelClock;
321 bb.ebx.r.l = 0;
322 bb.ecx.rx = *pixelClock;
323 bb.edx.rr = mode;
324 bios(&bb);
325 *pixelClock = bb.ecx.rx;
326 return(bb.eax.r.h);
327}
328

Archive Download this file

Revision: 399