Chameleon

Chameleon Svn Source Tree

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

Source at commit 429 created 13 years 9 months ago.
By meklort, Updated module system. Hooks can now be used within modules when cetaion functions are called in chameleon. Note that onle two hooks currently exist, more need to be added. I also updated the HelloWorld module to use a hook instead of print out right away.
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 * Various inline routines for video I/O
34 */
35static inline void
36outi (int port, int index, int val)
37{
38 outw (port, (val << 8) | index);
39}
40
41static inline void
42outib (int port, int index, int val)
43{
44 outb (port, index);
45 outb (port + 1, val);
46}
47
48static inline int
49ini (int port, int index)
50{
51 outb (port, index);
52 return inb (port + 1);
53}
54
55static inline void
56rmwi (int port, int index, int clear, int set)
57{
58 outb (port, index);
59 outb (port + 1, (inb (port + 1) & ~clear) | set);
60}
61
62/*
63 * Globals
64 */
65static biosBuf_t bb;
66
67int getVBEInfo( void * infoBlock )
68{
69 bb.intno = 0x10;
70 bb.eax.rr = funcGetControllerInfo;
71 bb.es = SEG( infoBlock );
72 bb.edi.rr = OFF( infoBlock );
73 bios( &bb );
74 return(bb.eax.r.h);
75}
76
77int getVBEModeInfo( int mode, void * minfo_p )
78{
79 bb.intno = 0x10;
80 bb.eax.rr = funcGetModeInfo;
81 bb.ecx.rr = mode;
82 bb.es = SEG(minfo_p);
83 bb.edi.rr = OFF(minfo_p);
84 bios(&bb);
85 return(bb.eax.r.h);
86}
87
88int getVBEDACFormat(unsigned char *format)
89{
90 bb.intno = 0x10;
91 bb.eax.rr = funcGetSetPaletteFormat;
92 bb.ebx.r.l = subfuncGet;
93 bios(&bb);
94 *format = bb.ebx.r.h;
95 return(bb.eax.r.h);
96}
97
98int setVBEDACFormat(unsigned char format)
99{
100 bb.intno = 0x10;
101 bb.eax.rr = funcGetSetPaletteFormat;
102 bb.ebx.r.l = subfuncSet;
103 bb.ebx.r.h = format;
104 bios(&bb);
105 return(bb.eax.r.h);
106}
107
108int getEDID( void * edidBlock, UInt8 block)
109{
110bzero(&bb, sizeof(bb));
111 bb.intno = 0x10;
112 bb.eax.rr = funcGetEDID;
113bb.ebx.r.l= 0x01;
114bb.edx.rr = block;
115
116 bb.es = SEG( edidBlock );
117 bb.edi.rr = OFF( edidBlock );
118
119 bios( &bb );
120 return(bb.eax.r.h);
121}
122
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: 429