From 6f7633cf682c42984a9f12e1cf16c7123599f77e Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Tue, 5 May 2020 20:16:24 +0200 Subject: color! --- 01_exercise/bootloader.c | 99 ++++++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/01_exercise/bootloader.c b/01_exercise/bootloader.c index 07b3dcc..0500ce4 100644 --- a/01_exercise/bootloader.c +++ b/01_exercise/bootloader.c @@ -1,30 +1,60 @@ /* needs to stay the first line */ -asm(".code16gcc\njmp $0, $main"); +asm(".code16gcc;" + "jmp $0, $main"); -/* space for additional code */ +/* + * 0 black + * 1 blue + * 2 green + * 3 cyan + * 4 red + * 5 magenta + * 6 brown + * 7 light gray + * 8 dark gray + * 9 light blue + * A light green + * B light cyan + * C light red + * D light magenta + * E yellow + * F white + */ -char WRITE_CHARACTER_TTY = 0x0E; +#define BG_COLOR 0x0 +#define FG_COLOR 0x4 +#define TEXT_COLOR (BG_COLOR << 4 | FG_COLOR) -// Syscall found here http://www.ctyme.com/intr/rb-0106.htm void putc(char c) { - short command = WRITE_CHARACTER_TTY << 8 | c; - // volatile because there is no output, so the function might get optimized - // away - // clang-format off - asm volatile( - "int $0x10;" - ::"a"(command) - ); - // clang-format on + asm volatile("mov $0x0E, %%ah;" + "int $0x10;" ::"al"(c)); +} + +void putc_color(char c, char color) { + asm volatile("mov $0x09, %%ah;" // using Int 10h AH=09 for attributes + "and $0x00FF, %%bx;" // erase higher bits of bx + "mov $0x0001, %%cx;" // write the char once + "int $0x10;" // we need to manually move the cursor + "mov $0x0300, %%eax;" // get cursor position + "int $0x10;" + "add $0x1, %%dl;" // raise column by one + "mov $0x0200, %%eax;" // set cursor position + "int $0x10;" ::"al"(c), + "bl"(color) + : "cx", "dx"); } void print(char const *const str) { for (int i = 0; str[i] != '\0'; ++i) { - putc(str[i]); + putc_color(str[i], TEXT_COLOR); } } -// Syscall found here http://www.ctyme.com/intr/rb-1754.htm +void new_line() { + putc('\n'); + putc('\r'); +} + char getc() { char ret; asm volatile( @@ -48,21 +78,20 @@ char getc() { return ret; } -void sleep(short ms) { - long ys = ms * 1000; - short cx = ys >> 16; - short dx = ys; - +void sleep(long ys) { // http://www.ctyme.com/intr/rb-1525.htm : Int 15/AH=86h bios wait - char ah = 0x86; - char al = 0x00; - short command = ah << 8 | al; - - asm volatile("int $0x15;" : : "a"(command), "cx"(cx), "dx"(dx)); + asm volatile("mov $0x8600, %%ax;" + "int $0x15;" ::"cx"((ys >> 16)), + "dx"(ys)); } void main(void) { - print("Hello!\n\r"); + print("Hello!"); + new_line(); + + asm volatile("mov $0x00A2, %%ax;" // switch to video mode + "int $0x10" :: + : "ax"); while (1) { char buf[9]; @@ -70,8 +99,9 @@ void main(void) { char c = getc(); if (c == '\r') { if (i == 0) { // empty entry - print("Reboot!\n\r"); - sleep(250); // too see the reboot print out, even if short + print("Reboot!"); + sleep(500000); // sleep 500ms, to see the reboot print out, even if + // short asm volatile( "cli;" // disable interrupts "mov $0x0FE, %%al;" // tell the keyboard controller to... @@ -80,21 +110,18 @@ void main(void) { "hlt;" // some motherboards require this "jmp .halt;" :: // and again, just to be sure : "al"); - return; } else { break; } } buf[i] = c; buf[i + 1] = 0; - putc('*'); - } - while (1) { - if (getc() == '\r') - break; + putc_color('*', 0x02); // hard coded green on black } - print("\n\r"); + while (getc() != '\r') + ; + new_line(); print(buf); - print("\n\r"); + new_line(); } } \ No newline at end of file -- cgit v1.2.3-54-g00ecf