VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/logo.c@ 7814

Last change on this file since 7814 was 7814, checked in by vboxsync, 17 years ago

Use dirty bits instead of pfnUpdateRect.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 KB
Line 
1#define COMPRESS_NONE 0
2#define COMPRESS_RLE8 1
3#define COMPRESS_RLE4 2
4
5#define BMP_HEADER_OS21 12
6#define BMP_HEADER_OS22 64
7#define BMP_HEADER_WIN3 40
8
9#define WAIT_HZ 64
10#define WAIT_MS 16
11
12#define F12_SCAN_CODE 0x86
13#define F12_WAIT_TIME (3 * WAIT_HZ) /* 3 seconds. Used only if logo disabled. */
14
15#define uint8_t Bit8u
16#define uint16_t Bit16u
17#define uint32_t Bit32u
18#include <VBox/bioslogo.h>
19
20typedef struct
21{
22 Bit8u Blue;
23 Bit8u Green;
24 Bit8u Red;
25} RGBPAL;
26
27/* BMP File Format Bitmap Header. */
28typedef struct
29{
30 Bit16u Type; /* File Type Identifier */
31 Bit32u FileSize; /* Size of File */
32 Bit16u Reserved1; /* Reserved (should be 0) */
33 Bit16u Reserved2; /* Reserved (should be 0) */
34 Bit32u Offset; /* Offset to bitmap data */
35} BMPINFO;
36
37/* OS/2 1.x Information Header Format. */
38typedef struct
39{
40 Bit32u Size; /* Size of Remianing Header */
41 Bit16u Width; /* Width of Bitmap in Pixels */
42 Bit16u Height; /* Height of Bitmap in Pixels */
43 Bit16u Planes; /* Number of Planes */
44 Bit16u BitCount; /* Color Bits Per Pixel */
45} OS2HDR;
46
47/* OS/2 2.0 Information Header Format. */
48typedef struct
49{
50 Bit32u Size; /* Size of Remianing Header */
51 Bit32u Width; /* Width of Bitmap in Pixels */
52 Bit32u Height; /* Height of Bitmap in Pixels */
53 Bit16u Planes; /* Number of Planes */
54 Bit16u BitCount; /* Color Bits Per Pixel */
55 Bit32u Compression; /* Compression Scheme (0=none) */
56 Bit32u SizeImage; /* Size of bitmap in bytes */
57 Bit32u XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
58 Bit32u YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
59 Bit32u ClrUsed; /* Number of Colors in Color Table */
60 Bit32u ClrImportant; /* Number of Important Colors */
61 Bit16u Units; /* Resolution Mesaurement Used */
62 Bit16u Reserved; /* Reserved FIelds (always 0) */
63 Bit16u Recording; /* Orientation of Bitmap */
64 Bit16u Rendering; /* Halftone Algorithm Used on Image */
65 Bit32u Size1; /* Halftone Algorithm Data */
66 Bit32u Size2; /* Halftone Algorithm Data */
67 Bit32u ColorEncoding; /* Color Table Format (always 0) */
68 Bit32u Identifier; /* Misc. Field for Application Use */
69} OS22HDR;
70
71/* Windows 3.x Information Header Format. */
72typedef struct
73{
74 Bit32u Size; /* Size of Remianing Header */
75 Bit32u Width; /* Width of Bitmap in Pixels */
76 Bit32u Height; /* Height of Bitmap in Pixels */
77 Bit16u Planes; /* Number of Planes */
78 Bit16u BitCount; /* Bits Per Pixel */
79 Bit32u Compression; /* Compression Scheme (0=none) */
80 Bit32u SizeImage; /* Size of bitmap in bytes */
81 Bit32u XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
82 Bit32u YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
83 Bit32u ClrUsed; /* Number of Colors in Color Table */
84 Bit32u ClrImportant; /* Number of Important Colors */
85} WINHDR;
86
87
88static unsigned char get_mode();
89static void set_mode();
90static Bit8u wait(ticks, stop_on_key);
91static void write_pixel();
92static Bit8u read_logo_byte();
93static Bit16u read_logo_word();
94
95/**
96 * Get current video mode (VGA).
97 * @returns Video mode.
98 */
99unsigned char get_mode()
100 {
101 ASM_START
102 push bp
103 mov bp, sp
104
105 push bx
106
107 mov ax, #0x0F00
108 int #0x10
109
110 pop bx
111
112 pop bp
113 ASM_END
114 }
115
116/**
117 * Set video mode (VGA).
118 * @params New video mode.
119 */
120void set_mode(mode)
121 Bit8u mode;
122 {
123 ASM_START
124 push bp
125 mov bp, sp
126
127 push ax
128
129 mov ah, #0
130 mov al, 4[bp] ; mode
131 int #0x10
132
133 pop ax
134
135 pop bp
136 ASM_END
137 }
138
139/**
140 * Set VESA video mode.
141 * @params New video mode.
142 */
143Bit16u vesa_set_mode(mode)
144 Bit16u mode;
145 {
146 ASM_START
147 push bp
148 mov bp, sp
149
150 push bx
151
152 mov ax, #0x4f02
153 mov bx, 4[bp] ; mode
154 int #0x10
155
156 pop bx
157
158 pop bp
159 ASM_END
160}
161
162/**
163 * Check for keystroke.
164 * @returns True if keystroke available, False if not.
165 */
166Bit8u check_for_keystroke()
167 {
168 ASM_START
169 mov ax, #0x100
170 int #0x16
171 jz no_key
172 mov al, #1
173 jmp done
174no_key:
175 xor al, al
176done:
177 ASM_END
178}
179
180/**
181 * Get keystroke.
182 * @returns BIOS scan code.
183 */
184Bit8u get_keystroke()
185 {
186 ASM_START
187 mov ax, #0x0
188 int #0x16
189 xchg ah, al
190 ASM_END
191}
192
193void wait_init()
194{
195 // The default is 18.2 ticks per second (~55ms tick interval).
196 // Set the timer to 16ms ticks (64K / (Hz / (PIT_HZ / 64K)) = count).
197 // 0x10000 / (1000 / (1193182 / 0x10000)) = 1193 (0x04a9)
198 // 0x10000 / ( 128 / (1193182 / 0x10000)) = 9321 (0x2469)
199 // 0x10000 / ( 64 / (1193182 / 0x10000)) = 18643 (0x48d3)
200ASM_START
201 mov al, #0x34 ; timer0: binary count, 16bit count, mode 2
202 out 0x43, al
203 mov al, #0xd3 ; Low byte - 64Hz
204 out 0x40, al
205 mov al, #0x48 ; High byte - 64Hz
206 out 0x40, al
207ASM_END
208}
209
210void wait_uninit()
211{
212ASM_START
213 pushf
214 cli
215
216 /* Restore the timer to the default 18.2Hz. */
217 mov al, #0x34 ; timer0: binary count, 16bit count, mode 2
218 out 0x43, al
219 xor ax, ax ; maximum count of 0000H = 18.2Hz
220 out 0x40, al
221 out 0x40, al
222
223 /*
224 * Reinitialize the tick and rollover counts since we've
225 * screwed them up by running the timer at WAIT_HZ for a while.
226 */
227 pushad
228 push ds
229 mov ds, ax ; already 0
230 call timer_tick_post
231 pop ds
232 popad
233
234 popf
235ASM_END
236}
237
238/**
239 * Waits (sleeps) for the given number of ticks.
240 * Checks for keystroke.
241 *
242 * @returns BIOS scan code if available, 0 if not.
243 * @param ticks Number of ticks to sleep.
244 * @param stop_on_key Whether to stop immediately upon keypress.
245 */
246Bit8u wait(ticks, stop_on_key)
247 Bit16u ticks;
248 Bit8u stop_on_key;
249{
250 long ticks_to_wait, delta;
251 Bit32u prev_ticks, t;
252 Bit8u scan_code = 0;
253
254 /*
255 * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock.
256 * We also have to be careful about interrupt storms.
257 */
258ASM_START
259 pushf
260 sti
261ASM_END
262 ticks_to_wait = ticks;
263 prev_ticks = read_dword(0x0, 0x46c);
264 do
265 {
266ASM_START
267 hlt
268ASM_END
269 t = read_dword(0x0, 0x46c);
270 if (t > prev_ticks)
271 {
272 delta = t - prev_ticks; /* The temp var is required or bcc screws up. */
273 ticks_to_wait -= delta;
274 }
275 else if (t < prev_ticks)
276 ticks_to_wait -= t; /* wrapped */
277 prev_ticks = t;
278
279 if (check_for_keystroke())
280 {
281 scan_code = get_keystroke();
282 bios_printf(BIOS_PRINTF_INFO, "Key pressed: %x\n", scan_code);
283 if (stop_on_key)
284 return scan_code;
285 }
286 } while (ticks_to_wait > 0);
287ASM_START
288 popf
289ASM_END
290 return scan_code;
291}
292
293void vesa_set_bank(bank)
294 Bit16u bank;
295 {
296 ASM_START
297 push bp
298 mov bp, sp
299
300 push bx
301 push dx
302
303 mov ax, #0x4f05
304 xor bx, bx
305 mov dx, 4[bp] ; bank
306 int #0x10
307
308 pop dx
309 pop bx
310
311 pop bp
312 ASM_END
313}
314
315Bit8u read_logo_byte(offset)
316 Bit16u offset;
317{
318 if (offset)
319 {
320 outw(LOGO_IO_PORT, LOGO_CMD_SET_OFFSET);
321 outw(LOGO_IO_PORT, offset);
322 }
323 else
324 outw(LOGO_IO_PORT, LOGO_CMD_SET_OFFSET);
325
326 return inb(LOGO_IO_PORT);
327}
328
329Bit16u read_logo_word(offset)
330 Bit16u offset;
331{
332 if (offset)
333 {
334 outw(LOGO_IO_PORT, LOGO_CMD_SET_OFFSET);
335 outw(LOGO_IO_PORT, offset);
336 }
337 else
338 outw(LOGO_IO_PORT, LOGO_CMD_SET_OFFSET);
339
340 return inw(LOGO_IO_PORT);
341}
342
343Bit16u set_logo_x(x)
344 Bit16u x;
345{
346 outw(LOGO_IO_PORT, LOGO_CMD_SET_X);
347 outw(LOGO_IO_PORT, x);
348}
349
350Bit16u set_logo_y(y)
351 Bit16u y;
352{
353 outw(LOGO_IO_PORT, LOGO_CMD_SET_Y);
354 outw(LOGO_IO_PORT, y);
355}
356
357Bit16u set_logo_width(w)
358 Bit16u w;
359{
360 outw(LOGO_IO_PORT, LOGO_CMD_SET_WIDTH);
361 outw(LOGO_IO_PORT, w);
362}
363
364Bit16u set_logo_height(h)
365 Bit16u h;
366{
367 outw(LOGO_IO_PORT, LOGO_CMD_SET_HEIGHT);
368 outw(LOGO_IO_PORT, h);
369}
370
371Bit16u set_logo_depth(d)
372 Bit16u d;
373{
374 outw(LOGO_IO_PORT, LOGO_CMD_SET_DEPTH);
375 outw(LOGO_IO_PORT, d);
376}
377
378Bit16u set_pal_size(s)
379 Bit16u s;
380{
381 outw(LOGO_IO_PORT, LOGO_CMD_SET_PALSIZE);
382 outw(LOGO_IO_PORT, s);
383}
384
385Bit16u set_pal_data(offset)
386 Bit16u offset;
387{
388 outw(LOGO_IO_PORT, LOGO_CMD_SET_OFFSET);
389 outw(LOGO_IO_PORT, offset);
390 outw(LOGO_IO_PORT, LOGO_CMD_SET_PAL);
391}
392
393void clear_screen()
394{
395// Hide cursor, clear screen and move cursor to starting position
396ASM_START
397 push bx
398 push cx
399 push dx
400
401 mov ax, #0x100
402 mov cx, #0x1000
403 int #0x10
404
405 mov ax, #0x700
406 mov bh, #7
407 xor cx, cx
408 mov dx, #0x184f
409 int #0x10
410
411 mov ax, #0x200
412 xor bx, bx
413 xor dx, dx
414 int #0x10
415
416 pop dx
417 pop cx
418 pop bx
419ASM_END
420}
421
422void print_detected_harddisks()
423{
424 Bit16u ebda_seg=read_word(0x0040,0x000E);
425 Bit8u actual_device = 0;
426 Bit8u first_ctrl_printed = 0;
427 Bit8u second_ctrl_printed = 0;
428 Bit8u device;
429
430 device = read_byte(ebda_seg, &EbdaData->ata.hdidmap[actual_device]);
431
432 while ((actual_device < BX_MAX_ATA_DEVICES) && (device < BX_MAX_ATA_DEVICES))
433 {
434 Bit8u device_position;
435
436 device_position = device;
437
438 if ((device_position < 4) && (first_ctrl_printed == 0))
439 {
440 printf("IDE controller:\n");
441 first_ctrl_printed = 1;
442 }
443 else if ((device_position >= 4) && (second_ctrl_printed == 0))
444 {
445 printf("\n\nAHCI controller:\n");
446 second_ctrl_printed = 1;
447 }
448
449 printf("\n %d) ", actual_device+1);
450
451 /*
452 * If actual_device is bigger than or equal 4
453 * this is the next controller and
454 * the positions start at the beginning.
455 */
456 if (device_position >= 4)
457 device_position -= 4;
458
459 if (device_position / 2)
460 printf("Secondary ");
461 else
462 printf("Primary ");
463
464 if (device_position % 2)
465 printf("Slave");
466 else
467 printf("Master");
468
469 actual_device++;
470 device = read_byte(ebda_seg, &EbdaData->ata.hdidmap[actual_device]);
471 }
472
473 printf("\n");
474}
475
476Bit8u get_boot_drive(scode)
477 Bit8u scode;
478{
479 Bit16u ebda_seg=read_word(0x0040,0x000E);
480 Bit8u actual_device;
481 Bit8u detected_devices = 0;
482
483 for (actual_device = 0; actual_device < BX_MAX_ATA_DEVICES; actual_device++)
484 {
485 Bit8u device = read_byte(ebda_seg, &EbdaData->ata.hdidmap[actual_device]);
486
487 if (device < BX_MAX_ATA_DEVICES)
488 {
489 scode--;
490 if (scode == 0x01)
491 return actual_device;
492 }
493 }
494
495 /* Scancode is higher than number of available devices */
496 return 0x08;
497}
498
499show_boot_text(step)
500 Bit16u step;
501{
502 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_TEXT | step);
503}
504
505
506void show_logo()
507{
508 Bit16u ebda_seg=read_word(0x0040,0x000E);
509
510 LOGOHDR *logo_hdr;
511 BMPINFO *bmp_info;
512 OS2HDR *os2_head;
513 OS22HDR *os22_head;
514 WINHDR *win_head;
515 Bit16u logo_hdr_size, tmp, i;
516 Bit32u hdr_size;
517
518 Bit8u is_fade_in, is_fade_out, is_logo_failed, uBootMenu;
519 Bit16u logo_time;
520
521 Bit32u offset;
522
523 Bit8u scode, f12_pressed = 0;
524 Bit8u c;
525
526 // Set PIT to 1ms ticks
527 wait_init();
528
529 is_logo_failed = 0;
530
531 logo_hdr = 0;
532 logo_hdr_size = sizeof(LOGOHDR);
533
534 // Get main signature
535 tmp = read_logo_word(&logo_hdr->u16Signature);
536 if (tmp != 0x66BB)
537 goto done;
538
539 // Get options
540 is_fade_in = read_logo_byte(&logo_hdr->fu8FadeIn);
541 is_fade_out = read_logo_byte(&logo_hdr->fu8FadeOut);
542 logo_time = read_logo_word(&logo_hdr->u16LogoMillies);
543 uBootMenu = read_logo_byte(&logo_hdr->fu8ShowBootMenu);
544
545 // Is Logo disabled?
546 if (!is_fade_in && !is_fade_out && !logo_time)
547 goto done;
548
549show_bmp:
550
551 // Set offset of bitmap header
552 bmp_info = logo_hdr_size;
553 os2_head = os22_head = win_head = logo_hdr_size + sizeof(BMPINFO);
554
555 // Check bitmap ID
556 tmp = read_logo_word(&bmp_info->Type);
557 if (tmp != 0x4D42) // 'BM'
558 {
559 goto error;
560 }
561 else
562 {
563 Bit16u scr_width, scr_height, start_x, start_y;
564 Bit16u width, height, compr, clr_used;
565 Bit16u pad_bytes, depth, planes, palette_size, palette_data;
566
567 // Check the size of the information header that indicates
568 // the structure type
569 hdr_size = read_logo_word(&win_head->Size);
570 hdr_size |= read_logo_word(0) << 16;
571
572 if (hdr_size == BMP_HEADER_OS21) // OS2 1.x header
573 {
574 width = read_logo_word(&os2_head->Width);
575 height = read_logo_word(&os2_head->Height);
576 planes = read_logo_word(&os2_head->Planes);
577 depth = read_logo_word(&os2_head->BitCount);
578 compr = COMPRESS_NONE;
579 clr_used = 0;
580 }
581 else
582 if (hdr_size == BMP_HEADER_OS22) // OS2 2.0 header
583 {
584 width = read_logo_word(&os22_head->Width);
585 height = read_logo_word(&os22_head->Height);
586 planes = read_logo_word(&os22_head->Planes);
587 depth = read_logo_word(&os22_head->BitCount);
588 compr = read_logo_word(&os22_head->Compression);
589 clr_used = read_logo_word(&os22_head->ClrUsed);
590 }
591 else
592 if (hdr_size == BMP_HEADER_WIN3) // Windows 3.x header
593 {
594 width = read_logo_word(&win_head->Width);
595 height = read_logo_word(&win_head->Height);
596 planes = read_logo_word(&win_head->Planes);
597 depth = read_logo_word(&win_head->BitCount);
598 compr = read_logo_word(&win_head->Compression);
599 clr_used = read_logo_word(&win_head->ClrUsed);
600 }
601 else
602 goto error;
603
604 // Test some bitmap fields
605 if (width > 640 || height > 480)
606 goto error;
607
608 if (planes != 1)
609 goto error;
610
611 if (depth != 4 && depth != 8 && depth != 24)
612 goto error;
613
614 if (clr_used > 256)
615 goto error;
616
617 // Bitmap processing
618 if (compr != COMPRESS_NONE)
619 goto error;
620
621 // Screen size
622 scr_width = 640;
623 scr_height = 480;
624
625 // Center of screen
626 start_x = (scr_width - width) / 2;
627 start_y = (scr_height - height) / 2;
628
629 // Read palette
630 if (hdr_size == BMP_HEADER_OS21)
631 {
632 palette_size = (Bit16u) (1 << (planes * depth));
633 }
634 else
635 if (hdr_size == BMP_HEADER_WIN3 || hdr_size == BMP_HEADER_OS22)
636 {
637 if (clr_used)
638 palette_size = clr_used;
639 else
640 palette_size = (Bit16u) (1 << (planes * depth));
641 }
642
643 set_pal_size(palette_size);
644
645 palette_data = logo_hdr_size + sizeof(BMPINFO) + hdr_size;
646 set_pal_data(palette_data);
647
648 // Set video mode #0x142 640x480x32bpp
649 vesa_set_mode(0x142);
650
651 // 0 bank
652 vesa_set_bank(0);
653
654 // Show bitmap
655 tmp = read_logo_word(&bmp_info->Offset);
656 outw(LOGO_IO_PORT, LOGO_CMD_SET_OFFSET);
657 outw(LOGO_IO_PORT, logo_hdr_size + tmp);
658
659 // Clear screen
660 outw(LOGO_IO_PORT, LOGO_CMD_CLS);
661
662 // Set dirty bits
663 outw(LOGO_IO_PORT, LOGO_CMD_SET_DIRTY);
664
665 if (is_fade_in)
666 {
667 for (i = 0; i <= LOGO_SHOW_STEPS; i++)
668 {
669 set_logo_x(start_x);
670 set_logo_y(scr_height - start_y);
671 set_logo_width(width);
672 set_logo_height(height);
673 set_logo_depth(depth);
674
675 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i);
676
677 if (uBootMenu == 2)
678 show_boot_text(i);
679
680 // Blit buffer
681 outw(LOGO_IO_PORT, LOGO_CMD_BUF_BLT);
682
683 // Set dirty bits
684 outw(LOGO_IO_PORT, LOGO_CMD_SET_DIRTY);
685
686 wait(16 / WAIT_MS, 0);
687 }
688 }
689 else
690 {
691 set_logo_x(start_x);
692 set_logo_y(scr_height - start_y);
693 set_logo_width(width);
694 set_logo_height(height);
695 set_logo_depth(depth);
696
697 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | LOGO_SHOW_STEPS);
698
699 if (uBootMenu == 2)
700 show_boot_text(LOGO_SHOW_STEPS);
701
702 // Blit buffer
703 outw(LOGO_IO_PORT, LOGO_CMD_BUF_BLT);
704
705 // Set dirty bits
706 outw(LOGO_IO_PORT, LOGO_CMD_SET_DIRTY);
707 }
708
709 // Wait (interval in milliseconds)
710 if (!f12_pressed)
711 {
712 scode = wait(logo_time / WAIT_MS, 0);
713 if (scode == F12_SCAN_CODE)
714 f12_pressed = 1;
715 }
716
717 // Fade out (only if F12 was not pressed)
718 if (is_fade_out && !f12_pressed)
719 {
720 for (i = LOGO_SHOW_STEPS; i > 0 ; i--)
721 {
722 set_logo_x(start_x);
723 set_logo_y(scr_height - start_y);
724 set_logo_width(width);
725 set_logo_height(height);
726 set_logo_depth(depth);
727 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i);
728
729 if (uBootMenu == 2)
730 show_boot_text(i);
731
732 // Blit buffer
733 outw(LOGO_IO_PORT, LOGO_CMD_BUF_BLT);
734
735 // Set dirty bits
736 outw(LOGO_IO_PORT, LOGO_CMD_SET_DIRTY);
737
738 scode = wait(16 / WAIT_MS, 0);
739 if (scode == F12_SCAN_CODE)
740 f12_pressed = 1;
741 }
742 }
743 }
744
745 goto done;
746
747error:
748 if (!is_logo_failed)
749 {
750 is_logo_failed = 1;
751
752 logo_hdr_size = 0;
753
754 // Switch to defaul logo
755 outw(LOGO_IO_PORT, LOGO_CMD_SET_DEFAULT);
756
757 goto show_bmp;
758 }
759done:
760
761 // Clear forced boot drive setting.
762 write_byte(ebda_seg,&EbdaData->uForceBootDevice, 0);
763
764 // Don't restore previous video mode
765 // The default text mode should be set up. (defect #1235)
766 set_mode(0x0003);
767
768 // If Setup menu enabled
769 if (uBootMenu)
770 {
771 // If the graphics logo disabled
772 if (!is_fade_in && !is_fade_out && !logo_time)
773 {
774 int i;
775
776 if (uBootMenu == 2)
777 printf("Press F12 to select boot device.");
778
779 // if the user has pressed F12 don't wait here
780 if (!f12_pressed)
781 {
782 // Wait for timeout or keystroke
783 scode = wait(F12_WAIT_TIME, 1);
784 if (scode == F12_SCAN_CODE)
785 f12_pressed = 1;
786 }
787 }
788
789 // If F12 pressed, show boot menu
790 if (f12_pressed)
791 {
792 Bit8u boot_device = 0;
793 Bit8u boot_drive = 0;
794
795 clear_screen();
796
797 // Show menu
798 printf("\n"
799 "VirtualBox temporary boot device selection\n"
800 "\n"
801 "Detected Hard disks:\n"
802 "\n");
803 print_detected_harddisks();
804 printf("\n"
805 "Other boot devices:\n"
806 " f) Floppy\n"
807 " c) CD-ROM\n"
808 " l) LAN\n"
809 "\n"
810 " b) Continue booting\n");
811
812
813
814 // Wait for keystroke
815 for (;;)
816 {
817 do
818 {
819 scode = wait(WAIT_HZ, 1);
820 } while (scode == 0);
821
822 if (scode == 0x30)
823 {
824 // 'b' ... continue
825 break;
826 }
827
828 // Check if hard disk was selected
829 if ((scode >= 0x02) && (scode <= 0x09))
830 {
831 boot_drive = get_boot_drive(scode);
832
833 /*
834 * We support a maximum of 8 boot drives.
835 * If this value is bigger than 7 not all
836 * values are used and the user pressed
837 * and invalid key.
838 * Wait for the next pressed key.
839 */
840 if (boot_drive > 7)
841 continue;
842
843 write_byte(ebda_seg, &EbdaData->uForceBootDrive, boot_drive);
844 boot_device = 0x02;
845 break;
846 }
847
848 switch (scode)
849 {
850 case 0x21:
851 // Floppy
852 boot_device = 0x01;
853 break;
854 case 0x2e:
855 // CD-ROM
856 boot_device = 0x03;
857 break;
858 case 0x26:
859 // LAN
860 boot_device = 0x04;
861 break;
862 }
863
864 if (boot_device != 0)
865 break;
866 }
867
868 write_byte(ebda_seg, &EbdaData->uForceBootDevice, boot_device);
869
870 // Switch to text mode. Clears screen and enables cursor again.
871 set_mode(0x0003);
872 }
873 }
874
875 // Restore PIT ticks
876 wait_uninit();
877
878 return;
879}
880
881
882void delay_boot(secs)
883 Bit16u secs;
884{
885 Bit16u i;
886
887 if (!secs)
888 return;
889
890 // Set PIT to 1ms ticks
891 wait_init();
892
893 printf("Delaying boot for %d seconds:", secs);
894 for (i = secs; i > 0; i--)
895 {
896 printf(" %d", i);
897 wait(WAIT_HZ, 0);
898 }
899 printf("\n");
900 // Restore PIT ticks
901 wait_uninit();
902}
903
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette