os/kernelhwsrv/brdbootldr/ubootldr/display.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // bootldr\src\display\display.cpp
    15 // 
    16 //
    17 
    18 #define FILE_ID	0x44495350
    19 #define DEFINE_COLOURS
    20 
    21 //
    22 // Defining ENABLE_TRANSFER_STATS will display simplistic average and point
    23 // transfer rates in bytes per second and provide an estimate of the length of
    24 // time remaining.
    25 //
    26 #define ENABLE_TRANSFER_STATS
    27 
    28 #include "bootldr.h"
    29 #include <videodriver.h>
    30 #include <hal.h>
    31 
    32 TUint8* Screen;
    33 TInt Screenwidth, Screenheight;		// screen dimentions in pixels
    34 TInt XPos;
    35 TInt YPos;
    36 TUint Colours;
    37 TUint PixelSize = 1;	// size of a pixel in bytes
    38 
    39 TUint Progress[2];
    40 TUint Pixels[2];
    41 TUint Limit[2];
    42 TUint32 ProgressTime[2];
    43 TUint32 StartTime;
    44 
    45 // Palette entries are in the platform's config.h
    46 const TUint16 Palette[16]=	{
    47 		KPaletteEntBlack		| KPaletteEntPBS,
    48 		KPaletteEntMidBlue,		// 1
    49 		KPaletteEntMidGreen,	// 2
    50 		KPaletteEntMidCyan,		// 3
    51 		KPaletteEntMidRed,		// 4
    52 		KPaletteEntMidMagenta,	// 5
    53 		KPaletteEntMidYellow,	// 6
    54 		KPaletteEntDimWhite,	// 7
    55 		KPaletteEntGray,		// 8
    56 		KPaletteEntBlue,		// 9
    57 		KPaletteEntGreen,		// 10 A
    58 		KPaletteEntCyan,		// 11 B
    59 		KPaletteEntRed,			// 12 C
    60 		KPaletteEntMagenta,		// 13 D
    61 		KPaletteEntYellow,		// 14 E
    62 		KPaletteEntWhite 		// 15 F
    63 		};
    64 
    65 const TUint KRgbBlack		= 0x000000;
    66 //const TUint KRgbDarkGray	= 0x555555;
    67 const TUint KRgbDarkRed		= 0x800000;
    68 const TUint KRgbDarkGreen	= 0x008000;
    69 const TUint KRgbDarkYellow	= 0x808000;
    70 const TUint KRgbDarkBlue	= 0x000080;
    71 const TUint KRgbDarkMagenta	= 0x800080;
    72 const TUint KRgbDarkCyan	= 0x008080;
    73 const TUint KRgbRed			= 0xFF0000;
    74 //const TUint KRgbGreen		= 0x00FF00;
    75 const TUint KRgbYellow		= 0xFFFF00;
    76 const TUint KRgbBlue		= 0x0000FF;
    77 const TUint KRgbMagenta		= 0xFF00FF;
    78 const TUint KRgbCyan		= 0x00FFFF;
    79 const TUint KRgbGray		= 0xAAAAAA;
    80 const TUint KRgbWhite		= 0xFFFFFF;
    81 
    82 const TUint KRgbDimWhite    = 0xCCCCCC;
    83 
    84 const TUint32 Palette32[16] =
    85 {
    86     KRgbBlack,       // 0
    87     KRgbDarkBlue,    // 1
    88     KRgbDarkGreen,   // 2
    89     KRgbDarkCyan,    // 3
    90     KRgbDarkRed,     // 4
    91     KRgbDarkMagenta, // 5
    92     KRgbDarkYellow,  // 6
    93     KRgbDimWhite,    // 7 KRgbDarkGray()
    94     KRgbGray,        // 8
    95     KRgbBlue,        // 9
    96     KRgbDarkGreen,   // 10
    97     KRgbCyan,        // 11
    98     KRgbRed,         // 12
    99     KRgbMagenta,     // 13
   100     KRgbYellow,      // 14
   101     KRgbWhite        // 15
   102 };
   103 
   104 // KForeground, Kbackground and [I]Pcolour entries are indexes into the palette.
   105 // The progress bar colours are of the form "(foreground << 8) | background"
   106 const TUint8 KForeground = 15;
   107 const TUint8 KBackground = 9;
   108 const TUint PColour[2]={ 0xa08, 0xc08 };		//	(10|8) and (12|8)
   109 const TUint IPColour[2]={ 0x809, 0x809 };		//	(8|9) and (8|9)
   110 
   111 #define NUM_FONTS	96
   112 #define FONT_HEIGHT	10
   113 #define FONT_WIDTH	8
   114 
   115 #define SCREEN_SIZE			(Screenheight*Screenwidth*PixelSize)			// number of pixels (size in bytes)
   116 
   117 #define MAX_COLUMN			(Screenwidth/FONT_WIDTH)			// chars per line e.g. 80 or 40
   118 #define MAX_ROW				(Screenheight/FONT_HEIGHT)			// lines per screen e.g. 48 or 24
   119 #define PROGRESSBAR0_ROW	(MAX_ROW-1)							// row in which to draw progress bar 0
   120 #define PROGRESSBAR1_ROW	(MAX_ROW-2)							// row in which to draw progress bar 1
   121 #define STATS_ROW			(MAX_ROW-3)							// DEBUGGING row in which to write eta/bps
   122 //
   123 // ascii character code - 32 == character index into bootldr table
   124 //
   125 extern const TUint8 Font[NUM_FONTS][FONT_HEIGHT] =
   126  	{
   127 		{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
   128 		{0x30,0x78,0x78,0x78,0x30,0x00,0x30,0x00,0x00,0x00},	//!
   129 		{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
   130 		{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00},	//#
   131 		{0x30,0x7C,0xC0,0x78,0x0C,0xF8,0x30,0x00,0x00,0x00},	//$
   132 		{0x00,0xC6,0xCC,0x18,0x30,0x66,0xC6,0x00,0x00,0x00},
   133 		{0x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00,0x00,0x00},
   134 		{0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
   135 		{0x18,0x30,0x60,0x60,0x60,0x30,0x18,0x00,0x00,0x00},
   136 		{0x60,0x30,0x18,0x18,0x18,0x30,0x60,0x00,0x00,0x00},
   137 		{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00},
   138 		{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00,0x00,0x00},
   139 		{0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00},
   140 		{0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00},	//-
   141 		{0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},	//.
   142 		{0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00},	///
   143 
   144 		{0x7C,0xC6,0xCE,0xDE,0xF6,0xE6,0x7C,0x00,0x00,0x00},	//0
   145 		{0x30,0x70,0x30,0x30,0x30,0x30,0xFC,0x00,0x00,0x00},
   146 		{0x78,0xCC,0x0C,0x38,0x60,0xCC,0xFC,0x00,0x00,0x00},
   147 		{0x78,0xCC,0x0C,0x38,0x0C,0xCC,0x78,0x00,0x00,0x00},
   148 		{0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x1E,0x00,0x00,0x00},
   149 		{0xFC,0xC0,0xF8,0x0C,0x0C,0xCC,0x78,0x00,0x00,0x00},
   150 		{0x38,0x60,0xC0,0xF8,0xCC,0xCC,0x78,0x00,0x00,0x00},
   151 		{0xFC,0xCC,0x0C,0x18,0x30,0x30,0x30,0x00,0x00,0x00},
   152 		{0x78,0xCC,0xCC,0x78,0xCC,0xCC,0x78,0x00,0x00,0x00},
   153 		{0x78,0xCC,0xCC,0x7C,0x0C,0x18,0x70,0x00,0x00,0x00},	//9
   154 		{0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00},	//:
   155 		{0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x60,0x00,0x00},	//;
   156 		{0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x00,0x00,0x00},	//<
   157 		{0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,0x00,0x00},	//=
   158 		{0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x00,0x00},	//>
   159 		{0x78,0xCC,0x0C,0x18,0x30,0x00,0x30,0x00,0x00,0x00},	//?
   160 
   161 		{0x7C,0xC6,0xDE,0xDE,0xDE,0xC0,0x78,0x00,0x00,0x00},	//@
   162 		{0x30,0x78,0xCC,0xCC,0xFC,0xCC,0xCC,0x00,0x00,0x00},	//A
   163 		{0xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00,0x00,0x00},	//B
   164 		{0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,0x00,0x00},	//C
   165 		{0xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00},	//D
   166 		{0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00,0x00,0x00},	//E
   167 		{0x7E,0x60,0x60,0x78,0x60,0x60,0x60,0x00,0x00,0x00},	//F
   168 		{0x3C,0x66,0xC0,0xC0,0xCE,0x66,0x3E,0x00,0x00,0x00},	//G
   169 		{0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00,0x00,0x00},	//H
   170 		{0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00},	//I
   171 		{0x1E,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0x00,0x00},	//J
   172 		{0xE6,0x66,0x6C,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00},	//K
   173 		{0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00,0x00},	//L
   174 		{0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,0x00,0x00},	//M
   175 		{0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00,0x00,0x00},	//N
   176 		{0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00},	//O
   177 
   178 		{0xFC,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,0x00,0x00},	//P
   179 		{0x78,0xCC,0xCC,0xCC,0xDC,0x78,0x1C,0x00,0x00,0x00},	//Q
   180 		{0xFC,0x66,0x66,0x7C,0x6C,0x66,0xE6,0x00,0x00,0x00},	//R
   181 		{0x78,0xCC,0xE0,0x70,0x1C,0xCC,0x78,0x00,0x00,0x00},	//S
   182 		{0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00},	//T
   183 		{0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFC,0x00,0x00,0x00},	//U
   184 		{0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00},	//V
   185 		{0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00,0x00,0x00},	//W
   186 		{0xC6,0xC6,0x6C,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00},	//X
   187 		{0xCC,0xCC,0xCC,0x78,0x30,0x30,0x78,0x00,0x00,0x00},	//Y
   188 		{0xFE,0x06,0x0C,0x18,0x30,0x60,0xFE,0x00,0x00,0x00},	//Z
   189 		{0x78,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00,0x00},
   190 		{0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,0x00},
   191 		{0x78,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00,0x00},
   192 		{0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00},
   193 		{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00},
   194 
   195 		{0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
   196 		{0x00,0x00,0x78,0x0C,0x7C,0xCC,0x76,0x00,0x00,0x00},
   197 		{0xE0,0x60,0x60,0x7C,0x66,0x66,0xDC,0x00,0x00,0x00},
   198 		{0x00,0x00,0x78,0xCC,0xC0,0xCC,0x78,0x00,0x00,0x00},
   199 		{0x1C,0x0C,0x0C,0x7C,0xCC,0xCC,0x76,0x00,0x00,0x00},
   200 		{0x00,0x00,0x78,0xCC,0xFC,0xC0,0x78,0x00,0x00,0x00},
   201 		{0x38,0x6C,0x60,0xF0,0x60,0x60,0xF0,0x00,0x00,0x00},
   202 		{0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0xF8,0x00,0x00},
   203 		{0xE0,0x60,0x6C,0x76,0x66,0x66,0xE6,0x00,0x00,0x00},
   204 		{0x30,0x00,0x70,0x30,0x30,0x30,0x78,0x00,0x00,0x00},
   205 		{0x0C,0x00,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0x00},
   206 		{0xE0,0x60,0x66,0x6C,0x78,0x6C,0xE6,0x00,0x00,0x00},
   207 		{0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00},
   208 		{0x00,0x00,0xCC,0xFE,0xFE,0xD6,0xC6,0x00,0x00,0x00},
   209 		{0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0x00,0x00,0x00},
   210 		{0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00},
   211 
   212 		{0x00,0x00,0xDC,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00},
   213 		{0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0x1E,0x00,0x00},
   214 		{0x00,0x00,0xDC,0x76,0x66,0x60,0xF0,0x00,0x00,0x00},
   215 		{0x00,0x00,0x7C,0xC0,0x78,0x0C,0xF8,0x00,0x00,0x00},
   216 		{0x10,0x30,0x7C,0x30,0x30,0x34,0x18,0x00,0x00,0x00},
   217 		{0x00,0x00,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00},
   218 		{0x00,0x00,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00},
   219 		{0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x6C,0x00,0x00,0x00},
   220 		{0x00,0x00,0xC6,0x6C,0x38,0x6C,0xC6,0x00,0x00,0x00},
   221 		{0x00,0x00,0xCC,0xCC,0xCC,0x7C,0x0C,0xF8,0x00,0x00},
   222 		{0x00,0x00,0xFC,0x98,0x30,0x64,0xFC,0x00,0x00,0x00},
   223 		{0x1C,0x30,0x30,0xE0,0x30,0x30,0x1C,0x00,0x00,0x00},
   224 		{0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x00,0x00},
   225 		{0xE0,0x30,0x30,0x1C,0x30,0x30,0xE0,0x00,0x00,0x00},
   226 		{0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
   227 		{0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00},
   228 	};
   229 
   230 inline void ColourPixel(TInt aXPos, TInt aYPos, TUint aColour)
   231 /**
   232 colour a pixel on the screen
   233 @param aXPos	pixel's X coordinate
   234 @param aYPos	pixel's Y coordinate
   235 @param aColour	chosen colour specified as a palette index
   236 */
   237 {
   238 	TUint8* pV = (TUint8*)Screen + (aYPos * (Screenwidth * PixelSize)) + (aXPos * PixelSize);
   239 
   240 	switch(PixelSize)
   241 		{
   242 		case 4:
   243 			*(TUint32*)pV = Palette32[aColour];
   244 			break;
   245 		case 2:
   246 			*pV++ = Palette[aColour] & 0xFF ;
   247 			*pV = Palette[aColour] >> 8 ;
   248 			break;
   249 		case 1:
   250 			*pV = aColour;
   251 			break;
   252 		default:
   253 			// Kern::Fault("BOOTLDR colourpixel: Unsupported bpp", PixelSize);
   254 			BOOT_FAULT();
   255 		}
   256 }
   257 
   258 #ifndef USE_ASM_DISPLAYCHAR
   259 void DisplayChar(TInt aChar, TInt aXPos, TInt aYPos, TUint aColours)
   260 /**
   261 Write a character to the framebuffer
   262 @param aChar	Character to draw
   263 @param aXPos	Character's column
   264 @param aYPos	Character's row
   265 @param aColour	Palette index specified (foreground << 8| background)
   266 */
   267 	{
   268 	// Convert the ascii value into an index for the Font table
   269 	TInt tmpChar = aChar - 32;
   270 
   271 	// Validate this is a valid font index
   272 	if (tmpChar < 0 || tmpChar >= NUM_FONTS)
   273 		return;
   274 
   275 	// Validate coordinates lie within range.
   276 	if (aXPos > MAX_COLUMN-1 || aYPos > MAX_ROW-1)
   277 		return;
   278 
   279 	// for each line of the font
   280 	for (TUint line=0 ; line < FONT_HEIGHT ; line++)
   281 		{
   282 		TUint8 tmpLine = Font[tmpChar][line];
   283 		TUint8 tmpMask = 0x80;
   284 		// for each pixel of the line
   285 		for (TUint pixel=0 ; pixel < FONT_WIDTH ; pixel++)
   286 			{
   287 			ColourPixel(aXPos * FONT_WIDTH + pixel,
   288 						aYPos * FONT_HEIGHT + line,
   289 						(tmpLine & tmpMask) ? aColours >> 8 : aColours & 0xFF);
   290 
   291 			// Shift the mask one bit downward to examine the next pixel
   292 			tmpMask = tmpMask >> 1;
   293 			}
   294 		}
   295 
   296 	return;
   297 	}
   298 #endif
   299 
   300 
   301 GLDEF_C void ClearScreen()
   302 /**
   303 Set all the pixels on the screen to the background
   304 */
   305 	{
   306 	for (TInt y = 0 ; y<Screenheight ; y++)
   307 		for (TInt x = 0 ; x<Screenwidth ; x++)
   308 			ColourPixel(x, y, KBackground);
   309 
   310 	XPos=0;
   311 	YPos=0;
   312 	Colours=(KForeground<<8)|KBackground;
   313 	}
   314 
   315 void ScrollScreen()
   316 /**
   317 Move all the pixels in the scrolling text area up one line and fill the
   318 last line with the background colour
   319 */
   320 	{
   321 	TUint8* pV=Screen;
   322 	wordmove(pV, pV+(Screenwidth*PixelSize*FONT_HEIGHT), (Screenwidth*PixelSize*(Screenheight-(2*FONT_HEIGHT))-(Screenwidth*PixelSize*FONT_HEIGHT)));
   323 	pV+=(Screenwidth*PixelSize*(Screenheight-(2*FONT_HEIGHT))-(Screenwidth*PixelSize*FONT_HEIGHT));
   324 
   325 	TInt StartLine = (Screenheight-(4*FONT_HEIGHT));
   326 	for (TInt y = StartLine ; y<(StartLine+FONT_HEIGHT) ; y++)
   327 		for (TInt x = 0 ; x<Screenwidth ; x++)
   328 			ColourPixel(x, y, KBackground);
   329 	}
   330 
   331 void ScrollScreenDown()
   332 /**
   333 Move all the pixels in the scrolling text area down one line and fill the
   334 first line with the background colour
   335 */
   336 	{
   337 	TUint8* pV=Screen;
   338 	wordmove(pV+(Screenwidth*PixelSize*FONT_HEIGHT), pV, (Screenwidth*PixelSize*(Screenheight-(2*FONT_HEIGHT))-(Screenwidth*PixelSize*FONT_HEIGHT)));
   339 
   340 	for (TInt y = 0 ; y<FONT_HEIGHT ; y++)
   341 		for (TInt x = 0 ; x<Screenwidth ; x++)
   342 			ColourPixel(x, y, KBackground);
   343 
   344 	}
   345 
   346 void CurDown()
   347 /**
   348 Move the cursor down the screen, scrolling the text area if necessary
   349 */
   350 	{
   351 	if (++YPos==(MAX_ROW-3))
   352 		{
   353 		YPos=(MAX_ROW-4);
   354 		ScrollScreen();
   355 		}
   356 	}
   357 
   358 void CurUp()
   359 /**
   360 Move the cursor up the screen, scrolling the text area if necessary
   361 */
   362 	{
   363 	if (--YPos<0)
   364 		{
   365 		YPos=0;
   366 		ScrollScreenDown();
   367 		}
   368 	}
   369 
   370 void CurRight()
   371 /**
   372 Move the cursor along the screen, scrolling the text area if necessary
   373 */
   374 	{
   375 	if (++XPos==MAX_COLUMN)
   376 		{
   377 		XPos=0;
   378 		CurDown();
   379 		}
   380 	}
   381 
   382 void CurLeft()
   383 /**
   384 Move the cursor backwards along the screen, scrolling the text area if necessary
   385 */
   386 	{
   387 	if (--XPos<0)
   388 		{
   389 		XPos=MAX_COLUMN-1;
   390 		CurUp();
   391 		}
   392 	}
   393 
   394 void SetPos(TInt X, TInt Y)
   395 /**
   396 Set the cursor to a point on the screen
   397 @param X	Character's column
   398 @param Y	Character's row
   399 */
   400 	{
   401 	XPos=X;
   402 	YPos=Y;
   403 	}
   404 
   405 void PutChar(TUint aChar)
   406 /**
   407 Write a character to the screen then moves the cursor to the next position,
   408 scrolling the screen if necessary
   409 @param aChar	Character to write
   410 */
   411 	{
   412 	switch (aChar)
   413 		{
   414 		case 0x08: CurLeft(); return;		// BS '\b'
   415 		case 0x09: CurRight(); return;		// HT '\t'
   416 		case 0x0a: CurDown(); return;		// LF '\n'
   417 		case 0x0b: CurUp(); return;			// VT '\v'
   418 		case 0x0c: ClearScreen(); return;	// FF '\f'
   419 		case 0x0d: XPos=0; return;			// CR '\r'
   420 		default: break;
   421 		}
   422 	DisplayChar(aChar,XPos,YPos,Colours);
   423 	if (++XPos==MAX_COLUMN)					// chars per line
   424 		{
   425 		XPos=0;
   426 		if (++YPos==(MAX_ROW-3))	// lines per screen - 3 for progress bars & stats
   427 			{
   428 			YPos=(MAX_ROW-4);		// lines per screen - 4
   429 			ScrollScreen();
   430 			}
   431 		}
   432 	}
   433 
   434 GLDEF_C void PrintToScreen(TRefByValue<const TDesC> aFmt, ...)
   435 	{
   436 	VA_LIST list;
   437 	VA_START(list,aFmt);
   438 
   439 	TBuf<0x100> aBuf;
   440 	aBuf.AppendFormatList(aFmt,list);
   441 	PutString(aBuf);
   442 	//RDebug::RawPrint(aBuf);
   443 	}
   444 
   445 void PutString(const TDesC& aBuf)
   446 /**
   447 For each character in the given string write it to the screen
   448 @param aString	String of characters to write
   449 */
   450 	{
   451 	const TText* pS=aBuf.Ptr();
   452 	const TText* pE=pS+aBuf.Length();
   453 	if (pS!=pE)
   454 		{
   455 		while (pS<pE)
   456 			PutChar(*pS++);
   457 		}
   458 	}
   459 
   460 GLDEF_C void InitProgressBar(TInt aId, TUint aLimit, const TDesC& aBuf)
   461 /**
   462 Initialise a progress bar, writes a label and sets the pixels to the
   463 background colour
   464 @param aId		configure Bar0 or Bar1
   465 @param aLimit	Sets the upper bound of the value given to Update
   466 @param aTitle	Label to place before the progress bar (7 characters wide)
   467 */
   468 	{
   469 	const TText* aTitle=aBuf.Ptr();
   470 	TInt line=aId ? PROGRESSBAR0_ROW : PROGRESSBAR1_ROW;
   471 	Progress[aId]=0;
   472 	if (aId==0)
   473 			StartTime=0;
   474 
   475 	Pixels[aId]=0;
   476 	Limit[aId]=aLimit;
   477 	char c;
   478 	TInt x=0;
   479 	while ((c=*aTitle++)!=0 && x<7)
   480 		{
   481 		DisplayChar(c,x,line,Colours);
   482 		++x;
   483 		}
   484 	if (x<7)
   485 		x=7;
   486 	for (; x<(MAX_COLUMN-1); ++x)
   487 		DisplayChar(0x7f,x,line,IPColour[aId]);
   488 	}
   489 
   490 GLDEF_C void UpdateProgressBar(TInt aId, TUint aProgress)
   491 /**
   492 Update a progress bar filling in the bar to a new position
   493 If ENABLE_TRANSFER_STATS has been defined at build time the function will
   494 generate some simple statistics.
   495 @param aId			update Bar0 or Bar1
   496 @param aProgress	The point value between 0 and the given aLimit
   497 */
   498 	{
   499 	TInt line=aId ? PROGRESSBAR0_ROW : PROGRESSBAR1_ROW;
   500 	TUint old_pixels=Pixels[aId];
   501 
   502 #ifdef ENABLE_TRANSFER_STATS
   503 	// turn this on and get a few statistics as it loads
   504 	if (aId==0) {
   505 			if (StartTime == 0) {
   506 					StartTime = User::NTickCount();
   507 					ProgressTime[aId] = StartTime;
   508 			}
   509 			TUint avg_bps=0, bps=0, eta=0;
   510 			TUint32 timenow = User::NTickCount();
   511 			TUint32 delta_time = timenow - ProgressTime[aId];
   512 			ProgressTime[aId] = timenow;
   513 			if (delta_time) {
   514 					bps = ((aProgress - Progress[aId]) * 1000) / delta_time;		// delta bytes / delta milliseconds
   515 
   516 					delta_time = (timenow - StartTime);					// milliseconds since started
   517 					if (delta_time) {
   518 							avg_bps = ((TUint64)aProgress  * 1000) / delta_time;
   519 							eta = (Limit[aId] - aProgress) / avg_bps;
   520 					}
   521 			}
   522 
   523 			TInt savedXPos=XPos, savedYPos=YPos;
   524 			XPos=0;
   525 			YPos=STATS_ROW;
   526 //			Printf("C/s avg: %7d point: %7d ETA: %d    ", avg_bps, bps, eta);
   527 			PrintToScreen(_L("point: %7d ETA: %d    "), bps, eta);
   528 			XPos=savedXPos;
   529 			YPos=savedYPos;
   530 	}
   531 #endif
   532 
   533 	Progress[aId]=aProgress;
   534 	Int64 prog64=aProgress;
   535 	prog64*=(Screenwidth - (8*FONT_WIDTH));		// screenwidth in pixels - 8 characters
   536 	prog64/=Limit[aId];
   537 	TUint pixels=(TUint)prog64;
   538 	if (pixels>old_pixels)
   539 		{
   540 		Pixels[aId]=pixels;
   541 
   542 		while (old_pixels<pixels)
   543 			{
   544 			for (TInt i=0; i<6; ++i)
   545 				ColourPixel( old_pixels + (7*FONT_WIDTH), (line * FONT_HEIGHT) + 2 + i  , (PColour[aId]>>8));
   546 
   547 			++old_pixels;
   548 			}
   549 		}
   550 	}
   551 
   552 void InitDisplay()
   553 /**
   554 Reads the properties of the screen from the HAL and configures the settings so
   555 this driver can colour in pixels.
   556 */
   557     {
   558 	TInt iDisplayMode;
   559 	TInt iScreenAddress;
   560 	TInt iBitsPerPixel;
   561 	TInt iIsPalettized;
   562 	TInt offset;
   563 
   564 	HAL::Get(HAL::EDisplayMode, iDisplayMode);
   565 	iBitsPerPixel = iDisplayMode; //getbpp needs the current mode as its param
   566 	HAL::Get(HAL::EDisplayBitsPerPixel, iBitsPerPixel);	
   567 
   568 	iIsPalettized = iDisplayMode; //ispalettized needs the current mode as its param
   569 	HAL::Get(HAL::EDisplayIsPalettized, iIsPalettized);	
   570 
   571 	HAL::Get(HAL::EDisplayMemoryAddress, iScreenAddress);
   572 	
   573 	offset = iDisplayMode;
   574 	HAL::Get(HAL::EDisplayOffsetToFirstPixel, offset);
   575 	iScreenAddress += offset;
   576 
   577 	// get the dimentions of the screen
   578 	HAL::Get(HAL::EDisplayXPixels, Screenwidth);
   579 	HAL::Get(HAL::EDisplayYPixels, Screenheight);
   580 	
   581 	Screen = (TUint8 *)iScreenAddress;
   582 
   583 #if 0
   584 	RDebug::Printf("EDisplayMode %d", iDisplayMode);
   585 	RDebug::Printf("EDisplayBitsPerPixel %d", iBitsPerPixel);
   586 	RDebug::Printf("EDisplayIsPalettized %d", iIsPalettized);
   587 	RDebug::Printf("EDisplayMemoryAddress 0x%x (after offset)", iScreenAddress);
   588 	RDebug::Printf("EDisplayOffsetToFirstPixel  %d",offset);
   589 	RDebug::Printf("EDisplayXPixels  %d",Screenwidth);
   590 	RDebug::Printf("EDisplayYPixels  %d", Screenheight);
   591 #endif
   592 	
   593 	// get the bits per pixel to work out the size
   594 	if (iBitsPerPixel == 32)
   595 		{
   596 		PixelSize = 4;
   597 		}
   598 	else if (iBitsPerPixel == 16)
   599 		{
   600 		PixelSize = 2;
   601 		}
   602 	else if (iBitsPerPixel == 8)
   603 		{
   604 #if 0
   605 		// derive where the palette is located - assumes when no offset to first
   606 		// pixel the palette is at end of framebuffer.
   607 		TUint8* pV;
   608 		if(vidBuf().iOffsetToFirstPixel)
   609 			pV=(TUint8*)(vidBuf().iVideoAddress);
   610 		else
   611 			pV=(TUint8*)(vidBuf().iVideoAddress)+SCREEN_SIZE;
   612 
   613 		// Kern::Printf("Screenbuffer 0x%x palette 0x%x (%dx%d)",Screen,pV,Screenwidth,Screenheight);
   614 		PixelSize = 1;
   615 		memcpy(pV,Palette,32);
   616 #endif
   617 		}
   618 	else
   619 		{
   620 		RDebug::Printf("BOOTLDR display: Unsupported bpp %d",iBitsPerPixel);
   621 		BOOT_FAULT();
   622 		}
   623 
   624 	ClearScreen();
   625 	}