]> git.saurik.com Git - apple/boot.git/blob - i386/boot2/graphics.c
db91fe503e44178941b30c2a7f663459be560b60
[apple/boot.git] / i386 / boot2 / graphics.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 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 1.1 (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 "boot.h"
31 #include "vbe.h"
32 #include "kernBootStruct.h"
33
34 #define CHAR_W 8
35 #define CHAR_W_SHIFT 3
36 #define CHAR_H 16
37 #define CHAR_H_SHIFT 4
38 #define BYTE_SHIFT 3
39 #define NCOLS (screen_width / CHAR_W)
40 #define NROWS (screen_height / CHAR_H)
41 #define SCREEN_W (screen_width)
42 #define SCREEN_H (screen_height)
43
44 /*
45 * Forward declarations.
46 */
47 static int convert_vbe_mode(char * mode_name, int * mode);
48 BOOL gSilentBoot;
49
50 //==========================================================================
51 // Display a (optionally centered) text message.
52
53 void
54 message(char * str, int centered)
55 {
56 register int x;
57
58 x = (NCOLS - strlen(str)) >> 1;
59
60 if ( currentMode() == TEXT_MODE )
61 {
62 if (centered)
63 {
64 while(x--) printf(" ");
65 }
66 printf("%s\n", str);
67 }
68 }
69
70 /*
71 * for spinning disk
72 */
73 static int currentIndicator = 0;
74
75 //==========================================================================
76 // Set the screen mode: TEXT_MODE or GRAPHICS_MODE
77
78 void
79 setMode(int mode)
80 {
81 unsigned int vmode;
82 char * vmode_name;
83 int err = errSuccess;
84
85 if ( currentMode() == mode ) return;
86
87 if ( mode == GRAPHICS_MODE &&
88 (vmode_name = newStringForKey(kGraphicsModeKey)) != 0)
89 {
90 // Set to the graphics mode specified in the config table file,
91 // enable linear frame buffer mode, and update kernBootStruct.
92
93 if ( convert_vbe_mode(vmode_name, &vmode) == 0 )
94 vmode = mode1024x768x256; /* default mode */
95
96 err = set_linear_video_mode(vmode);
97
98 if ( err == errSuccess )
99 {
100 kernBootStruct->graphicsMode = GRAPHICS_MODE;
101 kernBootStruct->video.v_display = gSilentBoot;
102 kernBootStruct->video.v_baseAddr = (unsigned long) frame_buffer;
103 kernBootStruct->video.v_width = SCREEN_W;
104 kernBootStruct->video.v_height = SCREEN_H;
105 kernBootStruct->video.v_depth = bits_per_pixel;
106 kernBootStruct->video.v_rowBytes = (screen_rowbytes == 0) ?
107 (SCREEN_W * bits_per_pixel) >> BYTE_SHIFT : screen_rowbytes;
108 }
109
110 free(vmode_name);
111 }
112
113 if ( (mode == TEXT_MODE) || (err != errSuccess) )
114 {
115 video_mode(2); // 80x25 text mode
116
117 kernBootStruct->graphicsMode = TEXT_MODE;
118 kernBootStruct->video.v_display = 0;
119 kernBootStruct->video.v_baseAddr = (unsigned long) 0xb8000;
120 kernBootStruct->video.v_width = 80;
121 kernBootStruct->video.v_height = 25;
122 kernBootStruct->video.v_depth = 8;
123 kernBootStruct->video.v_rowBytes = 0x8000;
124 }
125
126 currentIndicator = 0;
127 }
128
129 //==========================================================================
130 // Return the current screen mode, TEXT_MODE or GRAPHICS_MODE.
131
132 int currentMode(void)
133 {
134 return kernBootStruct->graphicsMode;
135 }
136
137 //==========================================================================
138 // Convert from a string describing a graphics mode, to a VGA mode number.
139
140 typedef struct {
141 char mode_name[15];
142 int mode_val;
143 } mode_table_t;
144
145 mode_table_t mode_table[] = {
146 { "640x400x256", mode640x400x256 },
147 { "640x480x256", mode640x480x256 },
148 { "800x600x16", mode800x600x16 },
149 { "800x600x256", mode800x600x256 },
150 { "1024x768x16", mode1024x768x16 },
151 { "1024x768x256", mode1024x768x256 },
152 { "1280x1024x16", mode1280x1024x16 },
153 { "1280x1024x256", mode1280x1024x256 },
154 { "640x480x555", mode640x480x555 },
155 { "640x480x888", mode640x480x888 },
156 { "800x600x555", mode800x600x555 },
157 { "800x600x888", mode800x600x888 },
158 { "1024x768x555", mode1024x768x555 },
159 { "1024x768x888", mode1024x768x888 },
160 { "1280x1024x555", mode1280x1024x555 },
161 { "1280x1024x888", mode1280x1024x888 },
162 { "", 0 }
163 };
164
165 int convert_vbe_mode(char * mode_name, int * mode)
166 {
167 mode_table_t * mtp = mode_table;
168
169 if (mode_name == 0 || *mode_name == 0)
170 return 0;
171
172 while ( *mtp->mode_name )
173 {
174 if (strcmp(mtp->mode_name, mode_name) == 0)
175 {
176 *mode = mtp->mode_val;
177 return 1;
178 }
179 mtp++;
180 }
181 return 0;
182 }
183
184 //==========================================================================
185 // Display and clear the activity indicator.
186
187 static char indicator[] = {'-', '\\', '|', '/', '-', '\\', '|', '/', '\0'};
188
189 // To prevent a ridiculously fast-spinning indicator,
190 // ensure a minimum of 1/9 sec between animation frames.
191 #define MIN_TICKS 2
192
193 void
194 spinActivityIndicator( void )
195 {
196 static unsigned long lastTickTime = 0;
197 unsigned long currentTickTime = time18();
198 static char string[3] = {'\0', '\b', '\0'};
199
200 if (currentTickTime < lastTickTime + MIN_TICKS)
201 return;
202 else
203 lastTickTime = currentTickTime;
204
205 if ( currentMode() == TEXT_MODE )
206 {
207 string[0] = indicator[currentIndicator];
208 printf(string);
209 if (indicator[++currentIndicator] == 0)
210 currentIndicator = 0;
211 }
212 }
213
214 void
215 clearActivityIndicator( void )
216 {
217 if ( currentMode() == TEXT_MODE )
218 {
219 printf(" \b");
220 }
221 }