Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/boot2/graphics.c

Source at commit 575 created 13 years 6 months ago.
By meklort, Ramdisk 10.x extension loading
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 "boot.h"
30#include "graphics.h"
31#include "vbe.h"
32#include "appleClut8.h"
33#include "bootstruct.h"
34#include "IOHibernatePrivate.h"
35
36/*
37 * for spinning disk
38 */
39static int currentIndicator = 0;
40
41int previewTotalSectors = 0;
42int previewLoadedSectors = 0;
43uint8_t *previewSaveunder = 0;
44
45#define VIDEO(x) (bootArgs->Video.v_ ## x)
46
47#define MIN(x, y) ((x) < (y) ? (x) : (y))
48
49#ifndef OPTION_ROM
50#endif
51
52//==========================================================================
53// getVESAModeWithProperties
54//
55// Return the VESA mode that matches the properties specified.
56// If a mode is not found, then return the "best" available mode.
57
58unsigned short
59getVESAModeWithProperties( unsigned short width,
60 unsigned short height,
61 unsigned char bitsPerPixel,
62 unsigned short attributesSet,
63 unsigned short attributesClear,
64 VBEModeInfoBlock * outModeInfo,
65 unsigned short * vesaVersion )
66{
67 VBEInfoBlock vbeInfo;
68 unsigned short * modePtr;
69 VBEModeInfoBlock modeInfo;
70 unsigned char modeBitsPerPixel;
71 unsigned short matchedMode = modeEndOfList;
72 int err;
73
74 // Clear output mode info.
75
76 bzero( outModeInfo, sizeof(*outModeInfo) );
77
78 // Get VBE controller info containing the list of supported modes.
79
80 bzero( &vbeInfo, sizeof(vbeInfo) );
81 strcpy( (char*)&vbeInfo, "VBE2" );
82 err = getVBEInfo( &vbeInfo );
83 if ( err != errSuccess )
84 {
85 return modeEndOfList;
86 }
87
88 // Report the VESA major/minor version number.
89
90 if (vesaVersion) *vesaVersion = vbeInfo.VESAVersion;
91
92 // Loop through the mode list, and find the matching mode.
93
94 for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
95 *modePtr != modeEndOfList; modePtr++ )
96 {
97 // Get mode information.
98
99 bzero( &modeInfo, sizeof(modeInfo) );
100 err = getVBEModeInfo( *modePtr, &modeInfo );
101 if ( err != errSuccess )
102 {
103 continue;
104 }
105
106#if DEBUG
107 printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
108 *modePtr, modeInfo.XResolution, modeInfo.YResolution,
109 modeInfo.BitsPerPixel, modeInfo.MemoryModel,
110 modeInfo.ModeAttributes);
111#endif
112
113 // Filter out unwanted modes based on mode attributes.
114
115 if ( ( ( modeInfo.ModeAttributes & attributesSet ) != attributesSet )
116|| ( ( modeInfo.ModeAttributes & attributesClear ) != 0 ) )
117 {
118 continue;
119 }
120
121 // Pixel depth in bits.
122
123 modeBitsPerPixel = modeInfo.BitsPerPixel;
124
125 if ( ( modeBitsPerPixel == 4 ) && ( modeInfo.MemoryModel == 0 ) )
126 {
127 // Text mode, 16 colors.
128 }
129 else if ( ( modeBitsPerPixel == 8 ) && ( modeInfo.MemoryModel == 4 ) )
130 {
131 // Packed pixel, 256 colors.
132 }
133 else if ( ( ( modeBitsPerPixel == 16 ) || ( modeBitsPerPixel == 15 ) )
134 && ( modeInfo.MemoryModel == 6 )
135 && ( modeInfo.RedMaskSize == 5 )
136 && ( modeInfo.GreenMaskSize == 5 )
137 && ( modeInfo.BlueMaskSize == 5 ) )
138 {
139 // Direct color, 16 bpp (1:5:5:5).
140 modeInfo.BitsPerPixel = modeBitsPerPixel = 16;
141 }
142 else if ( ( modeBitsPerPixel == 32 )
143 && ( modeInfo.MemoryModel == 6 )
144 && ( modeInfo.RedMaskSize == 8 )
145 && ( modeInfo.GreenMaskSize == 8 )
146 && ( modeInfo.BlueMaskSize == 8 ) )
147 {
148 // Direct color, 32 bpp (8:8:8:8).
149 }
150 else
151 {
152 continue; // Not a supported mode.
153 }
154
155 // Modes larger than the specified dimensions are skipped.
156
157 if ( ( modeInfo.XResolution > width ) ||
158( modeInfo.YResolution > height ) )
159 {
160 continue;
161 }
162
163 // Perfect match, we're done looking.
164
165 if ( ( modeInfo.XResolution == width ) &&
166( modeInfo.YResolution == height ) &&
167( modeBitsPerPixel == bitsPerPixel ) )
168 {
169 matchedMode = *modePtr;
170 bcopy( &modeInfo, outModeInfo, sizeof(modeInfo) );
171 break;
172 }
173
174 // Save the next "best" mode in case a perfect match is not found.
175
176 if ( modeInfo.XResolution == outModeInfo->XResolution &&
177modeInfo.YResolution == outModeInfo->YResolution &&
178modeBitsPerPixel <= outModeInfo->BitsPerPixel )
179 {
180 continue; // Saved mode has more depth.
181 }
182 if ( modeInfo.XResolution < outModeInfo->XResolution ||
183modeInfo.YResolution < outModeInfo->YResolution ||
184modeBitsPerPixel < outModeInfo->BitsPerPixel )
185 {
186 continue; // Saved mode has more resolution.
187 }
188
189 matchedMode = *modePtr;
190 bcopy( &modeInfo, outModeInfo, sizeof(modeInfo) );
191 }
192
193 return matchedMode;
194}
195
196//==========================================================================
197// setupPalette
198
199static void setupPalette( VBEPalette * p, const unsigned char * g )
200{
201 int i;
202 unsigned char * source = (unsigned char *) g;
203
204 for (i = 0; i < 256; i++)
205 {
206 (*p)[i] = 0;
207 (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 16; // Red
208 (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 8; // Green
209 (*p)[i] |= ((unsigned long)((*source++) >> 2)); // Blue
210 }
211}
212
213//==========================================================================
214// Simple decompressor for boot images encoded in RLE format.
215
216char * decodeRLE( const void * rleData, int rleBlocks, int outBytes )
217{
218 char *out, *cp;
219
220 struct RLEBlock {
221 unsigned char count;
222 unsigned char value;
223 } * bp = (struct RLEBlock *) rleData;
224
225 out = cp = malloc( outBytes );
226 if ( out == NULL ) return NULL;
227
228 while ( rleBlocks-- )
229 {
230 memset( cp, bp->value, bp->count );
231 cp += bp->count;
232 bp++;
233 }
234
235 return out;
236}
237
238//==========================================================================
239// setVESAGraphicsMode
240
241int setVESAGraphicsMode( unsigned short width, unsigned short height, unsigned char bitsPerPixel, unsigned short refreshRate )
242{
243 VBEModeInfoBlock minfo;
244 unsigned short mode;
245 unsigned short vesaVersion;
246 int err = errFuncNotSupported;
247
248 do {
249 mode = getVESAModeWithProperties( width, height, bitsPerPixel,
250 maColorModeBit |
251 maModeIsSupportedBit |
252 maGraphicsModeBit |
253 maLinearFrameBufferAvailBit,
254 0,
255 &minfo, &vesaVersion );
256 if ( mode == modeEndOfList )
257 {
258 break;
259 }
260
261//
262// FIXME : generateCRTCTiming() causes crash.
263//
264
265// if ( (vesaVersion >> 8) >= 3 && refreshRate >= 60 &&
266// (gBootMode & kBootModeSafe) == 0 )
267// {
268// VBECRTCInfoBlock timing;
269//
270// // Generate CRTC timing for given refresh rate.
271//
272// generateCRTCTiming( minfo.XResolution, minfo.YResolution,
273// refreshRate, kCRTCParamRefreshRate,
274// &timing );
275//
276// // Find the actual pixel clock supported by the hardware.
277//
278// getVBEPixelClock( mode, &timing.PixelClock );
279//
280// // Re-compute CRTC timing based on actual pixel clock.
281//
282// generateCRTCTiming( minfo.XResolution, minfo.YResolution,
283// timing.PixelClock, kCRTCParamPixelClock,
284// &timing );
285//
286// // Set the video mode and use specified CRTC timing.
287//
288// err = setVBEMode( mode | kLinearFrameBufferBit |
289// kCustomRefreshRateBit, &timing );
290// }
291// else
292// {
293// // Set the mode with default refresh rate.
294//
295// err = setVBEMode( mode | kLinearFrameBufferBit, NULL );
296// }
297
298 // Set the mode with default refresh rate.
299
300 err = setVBEMode( mode | kLinearFrameBufferBit, NULL );
301
302 if ( err != errSuccess )
303 {
304 break;
305 }
306
307 // Set 8-bit color palette.
308
309 if ( minfo.BitsPerPixel == 8 )
310 {
311 VBEPalette palette;
312 setupPalette( &palette, appleClut8 );
313 if ((err = setVBEPalette(palette)) != errSuccess)
314 {
315 break;
316 }
317 }
318
319 // Is this required for buggy Video BIOS implementations?
320 // On which adapter?
321
322 if ( minfo.BytesPerScanline == 0 )
323minfo.BytesPerScanline = ( minfo.XResolution *
324 minfo.BitsPerPixel ) >> 3;
325
326 // Update KernBootStruct using info provided by the selected
327 // VESA mode.
328
329 bootArgs->Video.v_display = GRAPHICS_MODE;
330 bootArgs->Video.v_width = minfo.XResolution;
331 bootArgs->Video.v_height = minfo.YResolution;
332 bootArgs->Video.v_depth = minfo.BitsPerPixel;
333 bootArgs->Video.v_rowBytes = minfo.BytesPerScanline;
334 bootArgs->Video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr);
335
336 }
337 while ( 0 );
338
339 return err;
340}
341
342
343#ifndef OPTION_ROM
344
345
346//==========================================================================
347// LookUpCLUTIndex
348
349unsigned long lookUpCLUTIndex( unsigned char index,
350 unsigned char depth )
351{
352 long result, red, green, blue;
353
354 red = appleClut8[index * 3 + 0];
355 green = appleClut8[index * 3 + 1];
356 blue = appleClut8[index * 3 + 2];
357
358 switch (depth) {
359 case 16 :
360 result = ((red & 0xF8) << 7) |
361((green & 0xF8) << 2) |
362((blue & 0xF8) >> 3);
363 result |= (result << 16);
364 break;
365
366 case 32 :
367 result = (red << 16) | (green << 8) | blue;
368 break;
369
370 default :
371 result = index | (index << 8);
372 result |= (result << 16);
373 break;
374 }
375
376 return result;
377}
378
379//==========================================================================
380// drawColorRectangle
381
382void * stosl(void * dst, long val, long len)
383{
384 asm volatile ( "rep; stosl"
385 : "=c" (len), "=D" (dst)
386 : "0" (len), "1" (dst), "a" (val)
387 : "memory" );
388
389 return dst;
390}
391
392void drawColorRectangle( unsigned short x,
393unsigned short y,
394unsigned short width,
395unsigned short height,
396unsigned char colorIndex )
397{
398 long pixelBytes;
399 long color = lookUpCLUTIndex( colorIndex, VIDEO(depth) );
400 char * vram;
401
402 pixelBytes = VIDEO(depth) / 8;
403 vram = (char *) VIDEO(baseAddr) +
404VIDEO(rowBytes) * y + pixelBytes * x;
405
406 width = MIN(width, VIDEO(width) - x);
407 height = MIN(height, VIDEO(height) - y);
408
409 while ( height-- )
410 {
411 int rem = ( pixelBytes * width ) % 4;
412 if ( rem ) bcopy( &color, vram, rem );
413 stosl( vram + rem, color, pixelBytes * width / 4 );
414 vram += VIDEO(rowBytes);
415 }
416}
417
418void
419loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or)
420{
421int x,y, off;
422int red=0x7f, green=0x7f, blue=0x7f;
423for (x=0;x<ow;x++)
424for (y=0;y<oh;y++)
425{
426off=(x*iw)/ow+((y*ih)/oh)*iw;
427switch (ip)
428{
429case 16:
430{
431uint16_t val;
432val=((uint16_t *)input)[off];
433red=(val>>7)&0xf8;
434green=(val>>2)&0xf8;
435blue=(val<<3)&0xf8;
436break;
437}
438case 32:
439{
440uint32_t val;
441val=((uint32_t *)input)[off];
442red=(val>>16)&0xff;
443green=(val>>8)&0xff;
444blue=(val)&0xff;
445break;
446}
447}
448char *ptr=(char *)output+x*(op/8)+y*or;
449switch (op)
450{
451case 16:
452*((uint16_t *)ptr) = ((red & 0xF8) << 7) |
453((green & 0xF8) << 2) |
454((blue & 0xF8) >> 3);
455break;
456case 32 :
457*((uint32_t *)ptr) = (red << 16) | (green << 8) | blue;
458break;
459}
460}
461}
462
463DECLARE_IOHIBERNATEPROGRESSALPHA
464
465void drawPreview(void *src, uint8_t * saveunder)
466{
467uint8_t * screen;
468uint32_t rowBytes, pixelShift;
469uint32_t x, y;
470int32_t blob;
471uint32_t alpha, in, color, result;
472uint8_t * out;
473void *uncomp;
474int origwidth, origheight, origbpx;
475uint32_t saveindex[kIOHibernateProgressCount] = { 0 };
476
477if (src && (uncomp=DecompressData(src, &origwidth, &origheight, &origbpx)))
478{
479if (!setVESAGraphicsMode(origwidth, origheight, origbpx, 0))
480if (initGraphicsMode () != errSuccess)
481return;
482screen = (uint8_t *) VIDEO (baseAddr);
483rowBytes = VIDEO (rowBytes);
484loadImageScale (uncomp, origwidth, origheight, origbpx, screen, VIDEO(width), VIDEO(height), VIDEO(depth), VIDEO (rowBytes));
485}
486else
487{
488if (initGraphicsMode () != errSuccess)
489return;
490screen = (uint8_t *) VIDEO (baseAddr);
491rowBytes = VIDEO (rowBytes);
492// Set the screen to 75% grey.
493 drawColorRectangle(0, 0, VIDEO(width), VIDEO(height), 0x01 /* color index */);
494}
495
496
497pixelShift = VIDEO (depth) >> 4;
498if (pixelShift < 1) return;
499
500screen += ((VIDEO (width)
501- kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))
502+ (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;
503
504for (y = 0; y < kIOHibernateProgressHeight; y++)
505{
506out = screen + y * rowBytes;
507for (blob = 0; blob < kIOHibernateProgressCount; blob++)
508{
509color = blob ? kIOHibernateProgressDarkGray : kIOHibernateProgressMidGray;
510for (x = 0; x < kIOHibernateProgressWidth; x++)
511{
512alpha = gIOHibernateProgressAlpha[y][x];
513result = color;
514if (alpha)
515{
516if (0xff != alpha)
517{
518if (1 == pixelShift)
519{
520in = *((uint16_t *)out) & 0x1f;// 16
521in = (in << 3) | (in >> 2);
522}
523else
524in = *((uint32_t *)out) & 0xff;// 32
525saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++] = in;
526result = ((255 - alpha) * in + alpha * result + 0xff) >> 8;
527}
528if (1 == pixelShift)
529{
530result >>= 3;
531*((uint16_t *)out) = (result << 10) | (result << 5) | result;// 16
532}
533else
534*((uint32_t *)out) = (result << 16) | (result << 8) | result;// 32
535}
536out += (1 << pixelShift);
537}
538out += (kIOHibernateProgressSpacing << pixelShift);
539}
540}
541}
542void updateProgressBar(uint8_t * saveunder, int32_t firstBlob, int32_t select)
543{
544uint8_t * screen;
545uint32_t rowBytes, pixelShift;
546uint32_t x, y;
547int32_t blob, lastBlob;
548uint32_t alpha, in, color, result;
549uint8_t * out;
550uint32_t saveindex[kIOHibernateProgressCount] = { 0 };
551
552pixelShift = VIDEO(depth) >> 4;
553if (pixelShift < 1) return;
554screen = (uint8_t *) VIDEO (baseAddr);
555rowBytes = VIDEO (rowBytes);
556
557screen += ((VIDEO (width)
558- kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))
559+ (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;
560
561lastBlob = (select < kIOHibernateProgressCount) ? select : (kIOHibernateProgressCount - 1);
562
563screen += (firstBlob * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << pixelShift;
564
565for (y = 0; y < kIOHibernateProgressHeight; y++)
566{
567out = screen + y * rowBytes;
568for (blob = firstBlob; blob <= lastBlob; blob++)
569{
570color = (blob < select) ? kIOHibernateProgressLightGray : kIOHibernateProgressMidGray;
571for (x = 0; x < kIOHibernateProgressWidth; x++)
572{
573alpha = gIOHibernateProgressAlpha[y][x];
574result = color;
575if (alpha)
576{
577if (0xff != alpha)
578{
579in = saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++];
580result = ((255 - alpha) * in + alpha * result + 0xff) / 255;
581}
582if (1 == pixelShift)
583{
584result >>= 3;
585*((uint16_t *)out) = (result << 10) | (result << 5) | result;// 16
586}
587else
588*((uint32_t *)out) = (result << 16) | (result << 8) | result;// 32
589}
590out += (1 << pixelShift);
591}
592out += (kIOHibernateProgressSpacing << pixelShift);
593}
594}
595}
596#endif
597
598
599//==========================================================================
600// setVESATextMode
601
602static int
603setVESATextMode( unsigned short cols,
604unsigned short rows,
605unsigned char bitsPerPixel )
606{
607 VBEModeInfoBlock minfo;
608 unsigned short mode = modeEndOfList;
609
610 if ( (cols != 80) || (rows != 25) ) // not 80x25 mode
611 {
612 mode = getVESAModeWithProperties( cols, rows, bitsPerPixel,
613 maColorModeBit |
614 maModeIsSupportedBit,
615 maGraphicsModeBit,
616 &minfo, NULL );
617 }
618
619 if ( ( mode == modeEndOfList ) || ( setVBEMode(mode, NULL) != errSuccess ) )
620 {
621 video_mode( 2 ); // VGA BIOS, 80x25 text mode.
622 minfo.XResolution = 80;
623 minfo.YResolution = 25;
624 }
625
626 // Update KernBootStruct using info provided by the selected
627 // VESA mode.
628
629 bootArgs->Video.v_display = VGA_TEXT_MODE;
630 bootArgs->Video.v_baseAddr = 0xb8000;
631 bootArgs->Video.v_width = minfo.XResolution;
632 bootArgs->Video.v_height = minfo.YResolution;
633 bootArgs->Video.v_depth = 8;
634 bootArgs->Video.v_rowBytes = 0x8000;
635
636 return errSuccess; // always return success
637}
638
639//==========================================================================
640// getNumberArrayFromProperty
641
642int
643getNumberArrayFromProperty( const char * propKey,
644 unsigned long numbers[],
645 unsigned long maxArrayCount )
646{
647 char * propStr;
648 unsigned long count = 0;
649
650 propStr = newStringForKey( (char *) propKey , &bootInfo->bootConfig );
651 if ( propStr )
652 {
653 char * delimiter = propStr;
654 char * p = propStr;
655
656 while ( count < maxArrayCount && *p != '\0' )
657 {
658 unsigned long val = strtoul( p, &delimiter, 10 );
659 if ( p != delimiter )
660 {
661 numbers[count++] = val;
662 p = delimiter;
663 }
664 while ( ( *p != '\0' ) && !isdigit(*p) )
665 p++;
666 }
667
668 free( propStr );
669 }
670
671 return count;
672}
673
674int initGraphicsMode ()
675{
676unsigned long params[4];
677int count;
678
679params[3] = 0;
680count = getNumberArrayFromProperty( kGraphicsModeKey, params, 4 );
681
682// Try to find a resolution if "Graphics Mode" setting is not available.
683if ( count < 3 )
684{
685params[0] = DEFAULT_SCREEN_WIDTH;
686params[1] = DEFAULT_SCREEN_HEIGHT;
687params[2] = 32;
688}
689
690// Map from pixel format to bits per pixel.
691
692if ( params[2] == 256 ) params[2] = 8;
693if ( params[2] == 555 ) params[2] = 16;
694if ( params[2] == 888 ) params[2] = 32;
695
696return setVESAGraphicsMode( params[0], params[1], params[2], params[3] );
697}
698
699//==========================================================================
700// setVideoMode
701//
702// Set the video mode to VGA_TEXT_MODE or GRAPHICS_MODE.
703
704void
705setVideoMode( int mode, int drawgraphics)
706{
707 unsigned long params[4];
708 int count;
709 int err = errSuccess;
710
711 if ( mode == GRAPHICS_MODE )
712 {
713 if ( (err=initGraphicsMode ()) == errSuccess ) {
714if (gVerboseMode) {
715// Tell the kernel to use text mode on a linear frame buffer display
716bootArgs->Video.v_display = FB_TEXT_MODE;
717} else {
718bootArgs->Video.v_display = GRAPHICS_MODE;
719}
720}
721 }
722
723 if ( (mode == VGA_TEXT_MODE) || (err != errSuccess) )
724 {
725 count = getNumberArrayFromProperty( kTextModeKey, params, 2 );
726 if ( count < 2 )
727 {
728 params[0] = 80; // Default text mode is 80x25.
729 params[1] = 25;
730 }
731
732setVESATextMode( params[0], params[1], 4 );
733 bootArgs->Video.v_display = VGA_TEXT_MODE;
734 }
735
736 currentIndicator = 0;
737}
738
739//==========================================================================
740// Return the current video mode, VGA_TEXT_MODE or GRAPHICS_MODE.
741
742inline int getVideoMode(void)
743{
744 return bootArgs->Video.v_display;
745}
746
747//==========================================================================
748// Display and clear the activity indicator.
749
750static char indicator[] = {'-', '\\', '|', '/', '-', '\\', '|', '/', '\0'};
751
752// To prevent a ridiculously fast-spinning indicator,
753// ensure a minimum of 1/9 sec between animation frames.
754#define MIN_TICKS 2
755
756void
757spinActivityIndicator(int sectors)
758{
759 static unsigned long lastTickTime = 0, currentTickTime;
760#ifndef OPTION_ROM
761if (previewTotalSectors && previewSaveunder)
762{
763int blob, lastBlob;
764
765lastBlob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors;
766previewLoadedSectors+=sectors;
767blob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors;
768
769if (blob!=lastBlob)
770updateProgressBar (previewSaveunder, lastBlob, blob);
771return;
772}
773#endif
774currentTickTime = time18(); // late binding
775if (currentTickTime < lastTickTime + MIN_TICKS)
776{
777return;
778}
779else
780{
781lastTickTime = currentTickTime;
782}
783
784if (getVideoMode() == VGA_TEXT_MODE)
785{
786if (currentIndicator >= sizeof(indicator))
787{
788currentIndicator = 0;
789}
790putc(indicator[currentIndicator++]);
791putc('\b');
792}
793}
794
795void
796clearActivityIndicator( void )
797{
798 if ( getVideoMode() == VGA_TEXT_MODE )
799 {
800putc(' ');
801putc('\b');
802 }
803}
804
805

Archive Download this file

Revision: 575