forked from PoliEcho-holding-org/kern
116 lines
2.6 KiB
C
116 lines
2.6 KiB
C
#include "stdint.h"
|
|
#include "fat32.h"
|
|
#include "stdio.h"
|
|
#include "defs.h"
|
|
#include "disk.h"
|
|
#include "menu.h"
|
|
#include "kbd.h"
|
|
|
|
noreturn void panic() {
|
|
setAttr(0x04);
|
|
text(COLS/2, ROWS/2, "[ PANIC ]");
|
|
while (1) __asm__ volatile ("cli; hlt");
|
|
}
|
|
|
|
void drawPartitions(struct MBR* mbr, uint8_t sel);
|
|
void partitonInfo(struct partition* part);
|
|
struct partition* menu(struct MBR* mbr);
|
|
|
|
__section("entry")
|
|
noreturn void main() {
|
|
keyboardInit();
|
|
struct MBR mbr;
|
|
readSectors(0, 1, &mbr);
|
|
struct partition* bootpart = menu(&mbr);
|
|
|
|
setAttr(0x0f);
|
|
cls();
|
|
showCursor();
|
|
|
|
if (fat32_init(bootpart) != 0) {
|
|
setAttr(0x0c);
|
|
printf("Failed to initialize FAT32.");
|
|
panic();
|
|
}
|
|
|
|
while (1);
|
|
}
|
|
|
|
struct partition* menu(struct MBR* mbr) {
|
|
// Select bootable partition by default
|
|
uint8_t selected = 0;
|
|
for (size_t i = 0; i < 4; i++) {
|
|
if (mbr->partitions[i].bootable != BOOTABLE) continue;
|
|
selected = i;
|
|
break;
|
|
}
|
|
|
|
// Initial draw
|
|
setAttr(0x0f);
|
|
cls();
|
|
hideCursor();
|
|
rect(0, 0, COLS, ROWS);
|
|
hline(0, 2, COLS);
|
|
setAttr(0x02);
|
|
text(COLS / 2, 1, "KBOOT");
|
|
drawPartitions(mbr, selected);
|
|
partitonInfo(&mbr->partitions[selected]);
|
|
|
|
while (1) {
|
|
// Check for up/down arrow keys or enter
|
|
uint8_t scancode = getScancode();
|
|
if (scancode == SC_ENTER) { // Boot selected
|
|
if (mbr->partitions[selected].type != 0) break;
|
|
|
|
// Don't allow booting an unused partition
|
|
setAttr(0x4f);
|
|
text(COLS / 2, ROWS / 2 + 6, "Unused Partition");
|
|
} else if (scancode != SC_EXTENDED) continue; // Not an arrow key
|
|
|
|
scancode = getScancode();
|
|
if (scancode == SCE_ARROW_UP) selected--;
|
|
else if (scancode == SCE_ARROW_DOWN) selected++;
|
|
else continue;
|
|
|
|
if (selected == 0xff) selected = 3;
|
|
else if (selected == 4) selected = 0;
|
|
|
|
// Redraw
|
|
drawPartitions(mbr, selected);
|
|
partitonInfo(&mbr->partitions[selected]);
|
|
}
|
|
|
|
return &mbr->partitions[selected];
|
|
}
|
|
|
|
void drawPartitions(struct MBR* mbr, uint8_t sel) {
|
|
uint32_t basey = ROWS / 2 - 2;
|
|
for (size_t i = 0; i < 4; i++) {
|
|
if (i == sel) setAttr(0xf0);
|
|
else if (mbr->partitions[i].type == 0) setAttr(0x04);
|
|
else setAttr(0x0f);
|
|
|
|
text(COLS / 2, basey + i, " [ Partition %d ] ", i+1);
|
|
}
|
|
}
|
|
|
|
void partitonInfo(struct partition* part) {
|
|
uint32_t basey = ROWS / 2 + 6;
|
|
setAttr(0x02);
|
|
|
|
// Clear previous text
|
|
fill(1, basey, COLS - 2, 3, '\0');
|
|
|
|
if (part->type == 0) {
|
|
text(COLS / 2, basey, "Unused Partition");
|
|
return;
|
|
}
|
|
|
|
text(COLS / 2, basey, "Type: %02x%s", part->type,
|
|
(part->bootable == BOOTABLE) ? " Bootable" : "");
|
|
text(COLS / 2, basey + 1, "Start LBA: %d; End LBA: %d",
|
|
part->startLBA, part->startLBA + part->size);
|
|
text(COLS / 2, basey + 2, "Length: 0x%x", part->size);
|
|
}
|
|
|