VirtualBox

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

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

Moved the LOGO_* defines and LOGOHDR to a common header instead of keeping duplicates around the place.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.1 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 if (is_fade_in)
663 {
664 for (i = 0; i <= LOGO_SHOW_STEPS; i++)
665 {
666 set_logo_x(start_x);
667 set_logo_y(scr_height - start_y);
668 set_logo_width(width);
669 set_logo_height(height);
670 set_logo_depth(depth);
671
672 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i);
673
674 if (uBootMenu == 2)
675 show_boot_text(i);
676
677 wait(16 / WAIT_MS, 0);
678 }
679 }
680 else
681 {
682 set_logo_x(start_x);
683 set_logo_y(scr_height - start_y);
684 set_logo_width(width);
685 set_logo_height(height);
686 set_logo_depth(depth);
687
688 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | LOGO_SHOW_STEPS);
689
690 if (uBootMenu == 2)
691 show_boot_text(LOGO_SHOW_STEPS);
692 }
693
694 // Wait (interval in milliseconds)
695 if (!f12_pressed)
696 {
697 scode = wait(logo_time / WAIT_MS, 0);
698 if (scode == F12_SCAN_CODE)
699 f12_pressed = 1;
700 }
701
702 // Fade out (only if F12 was not pressed)
703 if (is_fade_out && !f12_pressed)
704 {
705 for (i = LOGO_SHOW_STEPS; i > 0 ; i--)
706 {
707 set_logo_x(start_x);
708 set_logo_y(scr_height - start_y);
709 set_logo_width(width);
710 set_logo_height(height);
711 set_logo_depth(depth);
712 outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i);
713
714 if (uBootMenu == 2)
715 show_boot_text(i);
716
717 scode = wait(16 / WAIT_MS, 0);
718 if (scode == F12_SCAN_CODE)
719 f12_pressed = 1;
720 }
721 }
722 }
723
724 goto done;
725
726error:
727 if (!is_logo_failed)
728 {
729 is_logo_failed = 1;
730
731 logo_hdr_size = 0;
732
733 // Switch to defaul logo
734 outw(LOGO_IO_PORT, LOGO_CMD_SET_DEFAULT);
735
736 goto show_bmp;
737 }
738done:
739
740 // Clear forced boot drive setting.
741 write_byte(ebda_seg,&EbdaData->uForceBootDevice, 0);
742
743 // Don't restore previous video mode
744 // The default text mode should be set up. (defect #1235)
745 set_mode(0x0003);
746
747 // If Setup menu enabled
748 if (uBootMenu)
749 {
750 // If the graphics logo disabled
751 if (!is_fade_in && !is_fade_out && !logo_time)
752 {
753 int i;
754
755 if (uBootMenu == 2)
756 printf("Press F12 to select boot device.");
757
758 // if the user has pressed F12 don't wait here
759 if (!f12_pressed)
760 {
761 // Wait for timeout or keystroke
762 scode = wait(F12_WAIT_TIME, 1);
763 if (scode == F12_SCAN_CODE)
764 f12_pressed = 1;
765 }
766 }
767
768 // If F12 pressed, show boot menu
769 if (f12_pressed)
770 {
771 Bit8u boot_device = 0;
772 Bit8u boot_drive = 0;
773
774 clear_screen();
775
776 // Show menu
777 printf("\n"
778 "VirtualBox temporary boot device selection\n"
779 "\n"
780 "Detected Hard disks:\n"
781 "\n");
782 print_detected_harddisks();
783 printf("\n"
784 "Other boot devices:\n"
785 " f) Floppy\n"
786 " c) CD-ROM\n"
787 " l) LAN\n"
788 "\n"
789 " b) Continue booting\n");
790
791
792
793 // Wait for keystroke
794 for (;;)
795 {
796 do
797 {
798 scode = wait(WAIT_HZ, 1);
799 } while (scode == 0);
800
801 if (scode == 0x30)
802 {
803 // 'b' ... continue
804 break;
805 }
806
807 // Check if hard disk was selected
808 if ((scode >= 0x02) && (scode <= 0x09))
809 {
810 boot_drive = get_boot_drive(scode);
811
812 /*
813 * We support a maximum of 8 boot drives.
814 * If this value is bigger than 7 not all
815 * values are used and the user pressed
816 * and invalid key.
817 * Wait for the next pressed key.
818 */
819 if (boot_drive > 7)
820 continue;
821
822 write_byte(ebda_seg, &EbdaData->uForceBootDrive, boot_drive);
823 boot_device = 0x02;
824 break;
825 }
826
827 switch (scode)
828 {
829 case 0x21:
830 // Floppy
831 boot_device = 0x01;
832 break;
833 case 0x2e:
834 // CD-ROM
835 boot_device = 0x03;
836 break;
837 case 0x26:
838 // LAN
839 boot_device = 0x04;
840 break;
841 }
842
843 if (boot_device != 0)
844 break;
845 }
846
847 write_byte(ebda_seg, &EbdaData->uForceBootDevice, boot_device);
848
849 // Switch to text mode. Clears screen and enables cursor again.
850 set_mode(0x0003);
851 }
852 }
853
854 // Restore PIT ticks
855 wait_uninit();
856
857 return;
858}
859
860
861void delay_boot(secs)
862 Bit16u secs;
863{
864 Bit16u i;
865
866 if (!secs)
867 return;
868
869 // Set PIT to 1ms ticks
870 wait_init();
871
872 printf("Delaying boot for %d seconds:", secs);
873 for (i = secs; i > 0; i--)
874 {
875 printf(" %d", i);
876 wait(WAIT_HZ, 0);
877 }
878 printf("\n");
879 // Restore PIT ticks
880 wait_uninit();
881}
882
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