Change license from GPLv3 to LGPLv3.
[seabios.git] / src / post_menu.c
1 // Menu presented during final phase of "post".
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2002  MandrakeSoft S.A.
5 //
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
7
8 #include "biosvar.h" // GET_EBDA
9 #include "util.h" // mdelay
10 #include "bregs.h" // struct bregs
11 #include "boot.h" // IPL
12
13 static int
14 check_for_keystroke()
15 {
16     struct bregs br;
17     memset(&br, 0, sizeof(br));
18     br.ah = 1;
19     call16_int(0x16, &br);
20     return !(br.flags & F_ZF);
21 }
22
23 static int
24 get_keystroke()
25 {
26     struct bregs br;
27     memset(&br, 0, sizeof(br));
28     call16_int(0x16, &br);
29     return br.ah;
30 }
31
32 static void
33 usleep(u32 usec)
34 {
35     struct bregs br;
36     memset(&br, 0, sizeof(br));
37     br.ah = 0x86;
38     br.cx = usec >> 16;
39     br.dx = usec;
40     call16_int(0x15, &br);
41 }
42
43 static int
44 timed_check_for_keystroke(int msec)
45 {
46     while (msec > 0) {
47         if (check_for_keystroke())
48             return 1;
49         usleep(50*1000);
50         msec -= 50;
51     }
52     return 0;
53 }
54
55 void
56 interactive_bootmenu()
57 {
58     if (! CONFIG_BOOTMENU)
59         return;
60
61     while (check_for_keystroke())
62         get_keystroke();
63
64     printf("Press F12 for boot menu.\n\n");
65
66     if (!timed_check_for_keystroke(2500))
67         return;
68     int scan_code = get_keystroke();
69     if (scan_code != 0x86)
70         /* not F12 */
71         return;
72
73     while (check_for_keystroke())
74         get_keystroke();
75
76     printf("Select boot device:\n\n");
77
78     int count = IPL.count;
79     int i;
80     for (i = 0; i < count; i++) {
81         printf("%d. ", i+1);
82         printf_bootdev(i);
83         printf("\n");
84     }
85
86     for (;;) {
87         scan_code = get_keystroke();
88         if (scan_code == 0x01 || scan_code == 0x58)
89             /* ESC or F12 */
90             break;
91         if (scan_code <= count + 1) {
92             // Add user choice to the boot order.
93             u16 choice = scan_code - 1;
94             u32 bootorder = IPL.bootorder;
95             IPL.bootorder = (bootorder << 4) | choice;
96             break;
97         }
98     }
99     printf("\n");
100 }