// Menu presented during final phase of "post". // // Copyright (C) 2008 Kevin O'Connor // Copyright (C) 2002 MandrakeSoft S.A. // // This file may be distributed under the terms of the GNU LGPLv3 license. #include "biosvar.h" // GET_EBDA #include "util.h" // mdelay #include "bregs.h" // struct bregs #include "boot.h" // IPL static int check_for_keystroke() { struct bregs br; memset(&br, 0, sizeof(br)); br.ah = 1; call16_int(0x16, &br); return !(br.flags & F_ZF); } static int get_keystroke() { struct bregs br; memset(&br, 0, sizeof(br)); call16_int(0x16, &br); return br.ah; } static void usleep(u32 usec) { struct bregs br; memset(&br, 0, sizeof(br)); br.ah = 0x86; br.cx = usec >> 16; br.dx = usec; call16_int(0x15, &br); } static int timed_check_for_keystroke(int msec) { while (msec > 0) { if (check_for_keystroke()) return 1; usleep(50*1000); msec -= 50; } return 0; } void interactive_bootmenu() { if (! CONFIG_BOOTMENU) return; while (check_for_keystroke()) get_keystroke(); printf("Press F12 for boot menu.\n\n"); if (!timed_check_for_keystroke(2500)) return; int scan_code = get_keystroke(); if (scan_code != 0x86) /* not F12 */ return; while (check_for_keystroke()) get_keystroke(); printf("Select boot device:\n\n"); int count = IPL.count; int i; for (i = 0; i < count; i++) { printf("%d. ", i+1); printf_bootdev(i); printf("\n"); } for (;;) { scan_code = get_keystroke(); if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ break; if (scan_code <= count + 1) { // Add user choice to the boot order. u16 choice = scan_code - 1; u32 bootorder = IPL.bootorder; IPL.bootorder = (bootorder << 4) | choice; break; } } printf("\n"); }