/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
static unsigned long lookUpCLUTIndex( unsigned char index,
unsigned char depth );
-static void drawColorRectangle( unsigned short x,
+void drawColorRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char colorIndex );
-static void drawDataRectangle( unsigned short x,
+void drawDataRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
- unsigned char * data );
+ unsigned char * data );
-#define VIDEO(x) (bootArgs->video.v_ ## x)
+static void setBorderColor( unsigned char colorIndex );
+int
+convertImage( unsigned short width,
+ unsigned short height,
+ const unsigned char *imageData,
+ unsigned char **newImageData );
+
+#define VIDEO(x) (bootArgs->Video.v_ ## x)
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
//==========================================================================
// printVBEInfo
{
VBEInfoBlock vbeInfo;
int err;
+ int small;
// Fetch VBE Controller Info.
// Check presence of VESA signature.
- if ( strncmp( vbeInfo.VESASignature, "VESA", 4 ) )
+ if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) )
return;
// Announce controller properties.
- printf("VESA v%d.%d %dMB (%s)\n",
+ small = (vbeInfo.TotalMemory < 16);
+
+ printf("VESA v%d.%d %d%s (%s)\n",
vbeInfo.VESAVersion >> 8,
vbeInfo.VESAVersion & 0xf,
- vbeInfo.TotalMemory / 16,
+ small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16),
+ small ? "KB" : "MB",
VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
}
+//==========================================================================
+//
+
+void
+printVBEModeInfo()
+{
+ VBEInfoBlock vbeInfo;
+ unsigned short * modePtr;
+ VBEModeInfoBlock modeInfo;
+ int err;
+ int line;
+
+ err = getVBEInfo( &vbeInfo );
+ if ( err != errSuccess )
+ return;
+
+ line = 0;
+
+ // Activate and clear page 1
+ setActiveDisplayPage(1);
+ clearScreenRows(0, 24);
+ setCursorPosition( 0, 0, 1 );
+
+ printVBEInfo();
+ printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr));
+
+ // Loop through the mode list, and find the matching mode.
+
+ for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
+ *modePtr != modeEndOfList; modePtr++ )
+ {
+ // Get mode information.
+
+ bzero( &modeInfo, sizeof(modeInfo) );
+ err = getVBEModeInfo( *modePtr, &modeInfo );
+ if ( err != errSuccess )
+ {
+ continue;
+ }
+
+ printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
+ *modePtr, modeInfo.XResolution, modeInfo.YResolution,
+ modeInfo.BitsPerPixel, modeInfo.MemoryModel,
+ modeInfo.ModeAttributes);
+
+ if (line++ >= 20) {
+ printf("(Press a key to continue...)");
+ getc();
+ line = 0;
+ clearScreenRows(0, 24);
+ setCursorPosition( 0, 0, 1 );
+ }
+ }
+ if (line != 0) {
+ printf("(Press a key to continue...)");
+ getc();
+ }
+ setActiveDisplayPage(0);
+}
+
+
//==========================================================================
// getVESAModeWithProperties
//
continue;
}
-#if 0 // debug
+#if DEBUG
printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
}
if ( modeInfo.XResolution < outModeInfo->XResolution ||
modeInfo.YResolution < outModeInfo->YResolution ||
- modeBitsPerPixel < 16 )
+ modeBitsPerPixel < outModeInfo->BitsPerPixel )
{
continue; // Saved mode has more resolution.
}
//==========================================================================
// Simple decompressor for boot images encoded in RLE format.
-static char * decodeRLE( const void * rleData, int rleBlocks, int outBytes )
+char * decodeRLE( const void * rleData, int rleBlocks, int outBytes )
{
char *out, *cp;
// Update KernBootStruct using info provided by the selected
// VESA mode.
- bootArgs->graphicsMode = GRAPHICS_MODE;
- bootArgs->video.v_width = minfo.XResolution;
- bootArgs->video.v_height = minfo.YResolution;
- bootArgs->video.v_depth = minfo.BitsPerPixel;
- bootArgs->video.v_rowBytes = minfo.BytesPerScanline;
- bootArgs->video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr);
+ bootArgs->Video.v_display = GRAPHICS_MODE;
+ bootArgs->Video.v_width = minfo.XResolution;
+ bootArgs->Video.v_height = minfo.YResolution;
+ bootArgs->Video.v_depth = minfo.BitsPerPixel;
+ bootArgs->Video.v_rowBytes = minfo.BytesPerScanline;
+ bootArgs->Video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr);
+
}
while ( 0 );
return err;
}
+int
+convertImage( unsigned short width,
+ unsigned short height,
+ const unsigned char *imageData,
+ unsigned char **newImageData )
+{
+ int cnt;
+ unsigned char *img = 0;
+ unsigned short *img16;
+ unsigned long *img32;
+
+ switch ( VIDEO(depth) ) {
+ case 16 :
+ img16 = malloc(width * height * 2);
+ if ( !img16 ) break;
+ for (cnt = 0; cnt < (width * height); cnt++)
+ img16[cnt] = lookUpCLUTIndex(imageData[cnt], 16);
+ img = (unsigned char *)img16;
+ break;
+
+ case 32 :
+ img32 = malloc(width * height * 4);
+ if ( !img32 ) break;
+ for (cnt = 0; cnt < (width * height); cnt++)
+ img32[cnt] = lookUpCLUTIndex(imageData[cnt], 32);
+ img = (unsigned char *)img32;
+ break;
+
+ default :
+ img = malloc(width * height);
+ bcopy(imageData, img, width * height);
+ break;
+ }
+ *newImageData = img;
+ return 0;
+}
+
//==========================================================================
// drawBootGraphics
-static int
-drawBootGraphics( unsigned short width,
- unsigned short height,
- unsigned char bitsPerPixel,
- unsigned short refreshRate )
+void
+drawBootGraphics( void )
{
- VBEModeInfoBlock minfo;
- unsigned short mode;
- unsigned short vesaVersion;
- int err = errFuncNotSupported;
-
- char * appleBoot = 0;
- short * appleBoot16;
- long * appleBoot32;
- long cnt, x, y;
+ unsigned char * imageData = 0;
+ long x, y;
char * appleBootPict;
do {
- mode = getVESAModeWithProperties( width, height, bitsPerPixel,
- maColorModeBit |
- maModeIsSupportedBit |
- maGraphicsModeBit |
- maLinearFrameBufferAvailBit,
- 0,
- &minfo, &vesaVersion );
- if ( mode == modeEndOfList )
- {
- break;
- }
-
// Fill the background to 75% grey (same as BootX).
- drawColorRectangle( 0, 0, minfo.XResolution, minfo.YResolution,
+ drawColorRectangle( 0, 0, VIDEO(width), VIDEO(height),
0x01 /* color index */ );
+ setBorderColor( 0x01 /* color index */ );
+
appleBootPict = decodeRLE( gAppleBootPictRLE, kAppleBootRLEBlocks,
kAppleBootWidth * kAppleBootHeight );
if ( appleBootPict )
{
- switch ( VIDEO(depth) )
- {
- case 16 :
- appleBoot16 = malloc(kAppleBootWidth * kAppleBootHeight * 2);
- if ( !appleBoot16 ) break;
- for (cnt = 0; cnt < (kAppleBootWidth * kAppleBootHeight); cnt++)
- appleBoot16[cnt] = lookUpCLUTIndex(appleBootPict[cnt], 16);
- appleBoot = (char *) appleBoot16;
- break;
-
- case 32 :
- appleBoot32 = malloc(kAppleBootWidth * kAppleBootHeight * 4);
- if ( !appleBoot32 ) break;
- for (cnt = 0; cnt < (kAppleBootWidth * kAppleBootHeight); cnt++)
- appleBoot32[cnt] = lookUpCLUTIndex(appleBootPict[cnt], 32);
- appleBoot = (char *) appleBoot32;
- break;
-
- default :
- appleBoot = (char *) appleBootPict;
- break;
- }
+ convertImage(kAppleBootWidth, kAppleBootHeight,
+ (unsigned char *)appleBootPict, &imageData);
x = ( VIDEO(width) - kAppleBootWidth ) / 2;
y = ( VIDEO(height) - kAppleBootHeight ) / 2 + kAppleBootOffset;
// Draw the happy mac in the center of the display.
- if ( appleBoot )
+ if ( imageData )
{
drawDataRectangle( x, y, kAppleBootWidth, kAppleBootHeight,
- appleBoot );
+ imageData );
+ free( imageData );
}
-
free( appleBootPict );
}
- } while (0);
- return err;
+ } while (0);
}
//==========================================================================
static void * stosl(void * dst, long val, long len)
{
- asm( "rep; stosl"
+ asm volatile ( "rep; stosl"
: "=c" (len), "=D" (dst)
: "0" (len), "1" (dst), "a" (val)
: "memory" );
return dst;
}
-static void drawColorRectangle( unsigned short x,
+void drawColorRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
vram = (char *) VIDEO(baseAddr) +
VIDEO(rowBytes) * y + pixelBytes * x;
+ width = MIN(width, VIDEO(width) - x);
+ height = MIN(height, VIDEO(height) - y);
+
while ( height-- )
{
int rem = ( pixelBytes * width ) % 4;
//==========================================================================
// drawDataRectangle
-static void drawDataRectangle( unsigned short x,
- unsigned short y,
- unsigned short width,
- unsigned short height,
- unsigned char * data )
+void drawDataRectangle( unsigned short x,
+ unsigned short y,
+ unsigned short width,
+ unsigned short height,
+ unsigned char * data )
{
+ unsigned short drawWidth;
long pixelBytes = VIDEO(depth) / 8;
- char * vram = (char *) VIDEO(baseAddr) +
- VIDEO(rowBytes) * y + pixelBytes * x;
+ unsigned char * vram = (unsigned char *) VIDEO(baseAddr) +
+ VIDEO(rowBytes) * y + pixelBytes * x;
- while ( height-- )
- {
- bcopy( data, vram, width * pixelBytes );
+ drawWidth = MIN(width, VIDEO(width) - x);
+ height = MIN(height, VIDEO(height) - y);
+ while ( height-- ) {
+ bcopy( data, vram, drawWidth * pixelBytes );
vram += VIDEO(rowBytes);
data += width * pixelBytes;
}
}
+
+//==========================================================================
+// setBorderColor
+
+static void
+setBorderColor( unsigned char colorIndex )
+{
+ long color = lookUpCLUTIndex( colorIndex, 32 );
+ VBEInfoBlock vbeInfo;
+ int err;
+
+ // Get VBE controller info.
+
+ bzero( &vbeInfo, sizeof(vbeInfo) );
+ err = getVBEInfo( &vbeInfo );
+ if ( err != errSuccess )
+ {
+ return;
+ }
+
+}
+
+
//==========================================================================
// setVESATextMode
// Update KernBootStruct using info provided by the selected
// VESA mode.
- bootArgs->graphicsMode = TEXT_MODE;
- bootArgs->video.v_baseAddr = 0xb8000;
- bootArgs->video.v_width = minfo.XResolution;
- bootArgs->video.v_height = minfo.YResolution;
- bootArgs->video.v_depth = 8;
- bootArgs->video.v_rowBytes = 0x8000;
+ bootArgs->Video.v_display = VGA_TEXT_MODE;
+ bootArgs->Video.v_baseAddr = 0xb8000;
+ bootArgs->Video.v_width = minfo.XResolution;
+ bootArgs->Video.v_height = minfo.YResolution;
+ bootArgs->Video.v_depth = 8;
+ bootArgs->Video.v_rowBytes = 0x8000;
return errSuccess; // always return success
}
//==========================================================================
// setVideoMode
//
-// Set the video mode to TEXT_MODE or GRAPHICS_MODE.
+// Set the video mode to VGA_TEXT_MODE or GRAPHICS_MODE.
void
setVideoMode( int mode )
count = getNumberArrayFromProperty( kGraphicsModeKey, params, 4 );
if ( count < 3 )
{
- params[0] = 1024; // Default graphics mode is 1024x768x16.
+ params[0] = 1024; // Default graphics mode is 1024x768x32.
params[1] = 768;
- params[2] = 16;
+ params[2] = 32;
}
// Map from pixel format to bits per pixel.
err = setVESAGraphicsMode( params[0], params[1], params[2], params[3] );
if ( err == errSuccess )
{
- // If this boolean is set to true, then the console driver
- // in the kernel will show the animated color wheel on the
- // upper left corner.
-
- bootArgs->video.v_display = !gVerboseMode;
-
- if (!gVerboseMode) {
- drawBootGraphics( params[0], params[1], params[2], params[3] );
+ if (gVerboseMode) {
+ // Tell the kernel to use text mode on a linear frame buffer display
+ bootArgs->Video.v_display = FB_TEXT_MODE;
+ } else {
+ bootArgs->Video.v_display = GRAPHICS_MODE;
+ drawBootGraphics();
}
}
}
- if ( (mode == TEXT_MODE) || (err != errSuccess) )
+ if ( (mode == VGA_TEXT_MODE) || (err != errSuccess) )
{
count = getNumberArrayFromProperty( kTextModeKey, params, 2 );
if ( count < 2 )
}
setVESATextMode( params[0], params[1], 4 );
- bootArgs->video.v_display = 0;
+ bootArgs->Video.v_display = VGA_TEXT_MODE;
}
currentIndicator = 0;
}
//==========================================================================
-// Return the current video mode, TEXT_MODE or GRAPHICS_MODE.
+// Return the current video mode, VGA_TEXT_MODE or GRAPHICS_MODE.
int getVideoMode(void)
{
- return bootArgs->graphicsMode;
+ return bootArgs->Video.v_display;
}
//==========================================================================
// Display and clear the activity indicator.
static char indicator[] = {'-', '\\', '|', '/', '-', '\\', '|', '/', '\0'};
+#define kNumIndicators (sizeof(indicator) - 1)
// To prevent a ridiculously fast-spinning indicator,
// ensure a minimum of 1/9 sec between animation frames.
else
lastTickTime = currentTickTime;
- if ( getVideoMode() == TEXT_MODE )
+ if ( getVideoMode() == VGA_TEXT_MODE )
{
- string[0] = indicator[currentIndicator];
+ if (currentIndicator >= kNumIndicators) currentIndicator = 0;
+ string[0] = indicator[currentIndicator++];
printf(string);
- if (indicator[++currentIndicator] == 0)
- currentIndicator = 0;
}
}
void
clearActivityIndicator( void )
{
- if ( getVideoMode() == TEXT_MODE )
+ if ( getVideoMode() == VGA_TEXT_MODE )
{
printf(" \b");
}
}
+