Chameleon Applications

Chameleon Applications Svn Source Tree

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

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

Archive Download this file

Revision: 214