Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/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
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
79#if UNUSED
80
81int getEDID( void * edidBlock, UInt8 block)
82{
83bzero(&bb, sizeof(biosBuf_t));
84 bb.intno = 0x10;
85 bb.eax.rr = funcGetEDID;
86bb.ebx.r.l= 0x01;
87bb.edx.rr = block;
88
89 bb.es = SEG( edidBlock );
90 bb.edi.rr = OFF( edidBlock );
91
92 bios( &bb );
93 return(bb.eax.r.h);
94}
95
96
97
98/*
99 * Default GTF parameter values.
100 */
101#define kCellGranularity 8.0 // character cell granularity
102#define kMinVSyncPlusBP 550.0 // min VSync + BP interval (us)
103#define kMinFrontPorch 1.0 // minimum front porch in lines(V)/cells(H)
104#define kVSyncLines 3.0 // width of VSync in lines
105#define kHSyncWidth 8.0 // HSync as a percent of total line width
106#define kC 30.0 // C = (C'-J) * (K/256) + J
107#define kM 300.0 // M = K/256 * M'
108
109static int Round(double f)
110{
111return (int)(f + 0.5);
112}
113
114/*
115 * from http://www.azillionmonkeys.com/qed/sqroot.html
116 */
117double Sqrt( double y )
118{
119double x, z, tempf;
120unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
121
122tempf = y;
123*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
124x = tempf;
125z = y*0.5; /* hoist out the “/2” */
126x = (1.5*x) - (x*x)*(x*z); /* iteration formula */
127x = (1.5*x) - (x*x)*(x*z);
128x = (1.5*x) - (x*x)*(x*z);
129x = (1.5*x) - (x*x)*(x*z);
130x = (1.5*x) - (x*x)*(x*z);
131return x*y;
132}
133
134int generateCRTCTiming( unsigned short width,
135 unsigned short height,
136 unsigned long paramValue,
137 int paramType,
138 VBECRTCInfoBlock * timing )
139{
140 double h_period_est, h_freq, h_period, h_total_pixels, h_sync_pixels;
141 double h_active_pixels, h_ideal_duty_cycle, h_blank_pixels, pixel_freq = 0;
142 double v_sync_plus_bp = 0, v_total_lines = 0, v_field_rate_est, v_frame_rate = 0;
143 const double h_pixels = (double) width;
144 const double v_lines = (double) height;
145
146 enum {
147 left_margin_pixels = 0,
148 right_margin_pixels = 0,
149 top_margin_lines = 0,
150 bot_margin_lines = 0,
151 interlace = 0
152 };
153
154 // Total number of active pixels in image and both margins
155 h_active_pixels = h_pixels + left_margin_pixels + right_margin_pixels;
156
157 if (paramType == kCRTCParamPixelClock)
158 {
159 // Pixel clock provided in MHz
160 pixel_freq = (double) paramValue / 1000000;
161
162 // Ideal horizontal period from the blanking duty cycle equation
163 h_period = ((kC - 100) + (Sqrt(((100 - kC) * (100 - kC)) + (0.4 * kM *
164 (h_active_pixels + right_margin_pixels + left_margin_pixels) /
165 pixel_freq)))) / 2.0 / kM * 1000;
166 }
167 else /* kCRTCParamRefreshRate */
168 {
169 double v_field_rate_in = (double) paramValue;
170
171 // Estimate the horizontal period
172 h_period_est = ((1 / v_field_rate_in) - kMinVSyncPlusBP / 1000000) /
173 (v_lines + (2 * top_margin_lines) + kMinFrontPorch + interlace) *
174 1000000;
175
176 // Number of lines in Vsync + back porch
177 v_sync_plus_bp = Round(kMinVSyncPlusBP / h_period_est);
178
179 // Total number of lines in Vetical field period
180 v_total_lines = v_lines + top_margin_lines + bot_margin_lines +
181 v_sync_plus_bp + interlace + kMinFrontPorch;
182
183 // Estimate the vertical field frequency
184 v_field_rate_est = 1 / h_period_est / v_total_lines * 1000000;
185
186 // Find the actual horizontal period
187 h_period = h_period_est / (v_field_rate_in / v_field_rate_est);
188
189 // Find the vertical frame rate (no interlace)
190 v_frame_rate = 1 / h_period / v_total_lines * 1000000;
191 }
192
193 // Ideal blanking duty cycle from the blanking duty cycle equation
194 h_ideal_duty_cycle = kC - (kM * h_period / 1000);
195
196 // Number of pixels in the blanking time to the nearest double character cell
197 h_blank_pixels = Round(h_active_pixels * h_ideal_duty_cycle /
198 (100 - h_ideal_duty_cycle) / (2 * kCellGranularity)) *
199 (2 * kCellGranularity);
200
201 // Total number of horizontal pixels
202 h_total_pixels = h_active_pixels + h_blank_pixels;
203
204 if (paramType == kCRTCParamPixelClock)
205 {
206 // Horizontal frequency
207 h_freq = pixel_freq / h_total_pixels * 1000;
208
209 // Number of lines in V sync + back porch
210 v_sync_plus_bp = Round(kMinVSyncPlusBP * h_freq / 1000);
211
212 // Total number of lines in vertical field period
213 v_total_lines = v_lines + top_margin_lines + bot_margin_lines +
214 interlace + v_sync_plus_bp + kMinFrontPorch;
215
216 // Vertical frame frequency
217 v_frame_rate = Round(h_freq / v_total_lines * 1000);
218 }
219 else
220 {
221 // Find pixel clock frequency
222 pixel_freq = Round(h_total_pixels / h_period);
223 }
224
225 h_sync_pixels = Round(h_total_pixels * kHSyncWidth / 100 / kCellGranularity) *
226 kCellGranularity;
227
228 timing->HTotal = h_total_pixels;
229 timing->HSyncStart = h_active_pixels + (h_blank_pixels / 2) - h_sync_pixels;
230 timing->HSyncEnd = timing->HSyncStart + h_sync_pixels;
231 timing->VTotal = v_total_lines;
232 timing->VSyncStart = v_total_lines - v_sync_plus_bp;
233 timing->VSyncEnd = timing->VSyncStart + kVSyncLines;
234 timing->Flags = kCRTCNegativeHorizontalSync;
235 timing->PixelClock = pixel_freq * 1000000;
236 timing->RefreshRate = v_frame_rate * 100;
237
238 return 0;
239}
240
241#endif
242
243int setVBEMode(unsigned short mode, const VBECRTCInfoBlock * timing)
244{
245 bb.intno = 0x10;
246 bb.eax.rr = funcSetMode;
247 bb.ebx.rr = mode;
248 if (timing) {
249 bb.es = SEG(timing);
250 bb.edi.rr = OFF(timing);
251 }
252 bios(&bb);
253 return(bb.eax.r.h);
254}
255
256
257int setVBEPalette(void *palette)
258{
259 bb.intno = 0x10;
260 bb.eax.rr = funcGetSetPaletteData;
261 bb.ebx.r.l = subfuncSet;
262 bb.ecx.rr = 256;
263 bb.edx.rr = 0;
264 bb.es = SEG(palette);
265 bb.edi.rr = OFF(palette);
266 bios(&bb);
267 return(bb.eax.r.h);
268}
269
270#if UNUSED
271
272int getVBEPalette(void *palette)
273{
274 bb.intno = 0x10;
275 bb.eax.rr = funcGetSetPaletteData;
276 bb.ebx.r.l = subfuncGet;
277 bb.ecx.rr = 256;
278 bb.edx.rr = 0;
279 bb.es = SEG(palette);
280 bb.edi.rr = OFF(palette);
281 bios(&bb);
282 return(bb.eax.r.h);
283}
284
285int getVBECurrentMode(unsigned short *mode)
286{
287 bb.intno = 0x10;
288 bb.eax.rr = funcGetCurrentMode;
289 bios(&bb);
290 *mode = bb.ebx.rr;
291 return(bb.eax.r.h);
292}
293
294int getVBEPixelClock(unsigned short mode, unsigned long * pixelClock)
295{
296 bb.intno = 0x10;
297 bb.eax.rr = funcGetSetPixelClock;
298 bb.ebx.r.l = 0;
299 bb.ecx.rx = *pixelClock;
300 bb.edx.rr = mode;
301 bios(&bb);
302 *pixelClock = bb.ecx.rx;
303 return(bb.eax.r.h);
304}
305#endif
306

Archive Download this file

Revision: 1972