VirtualBox

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

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

The BIOS logo stuff moved to VGA device. Added 24bpp bitmaps support.

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