#include #include #include #include #include #include #include //README //this file has some temporary workarounds until I get further into development //this isn't going to be the serial driver I end up keeping #define VIDEO_BUFFER PHYS_TO_VIRT(0xb8000) #define MAX_LOOPBACK_ATTEMPTS 20 //later we'll set it up for interrupting instead of polling bool init_serial(uint16_t port) { outb_wait(port + 1, 0x00); outb_wait(port + 2, 0x00); outb_wait(port + 3, 0x80); outb_wait(port + 0, 0x01); //here outb_wait(port + 1, 0x00); outb_wait(port + 3, 0x03); outb_wait(port + 2, 0xc7); outb_wait(port + 4, 0x0b); outb_wait(port + 4, 0x1e); //we shouldn't accept this as a loopback success. //I'm making an exception because my dell desktop has a faulty serial port //that requires some extra effort. uint8_t loopback_byte; for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) { outb_wait(port + 0, 0xae); // test char loopback_byte = inb(port); if(loopback_byte == 0xae) break; } if(loopback_byte != 0xae) { //I'm sorry if these next few lines give you a stroke. They gave me one. //My old Dell test desktop has disfunctional serial hardware that only works after a reboot. //Seeing we don't have ACPI set up yet, we can't reboot without crashing. //IM GOING TO REMOVE THIS ONCE I DEVELOP THE "REAL" SERIAL DRIVER!!!! asm("mov rax, 0\n" "div rax\n"); return false; } outb_wait(port + 4, 0x0f); return true; } void _putchar_serial(uint16_t port, char msg) { while(!(inb(port + 5) & 0x20)); //wait for transmit to be done outb_wait(port, msg); } static unsigned int on_char = 0; static unsigned int on_line = 0; void clear_screen() { char *screen_buffer = (void *)VIDEO_BUFFER; for(unsigned int i = 0; i <= (80 * 25); i++) screen_buffer[i * 2] = ' '; on_char = 0; on_line = 0; } void next_line() { if(on_line >= 25) { on_line = 0; clear_screen(); } else { on_line++; } on_char = 0; } void move_cursor(unsigned int x, unsigned int y) { //yeah yeah yeah, it doens't test for overflows... I'm gonna delete this once i get serial working //on my second desktop on_char = x; on_line = y; } //until we get serial working on hp void _putchar_screen(char msg) { if(on_char >= 80) { next_line(); } else if(msg == '\n') { next_line(); return; } char *screen_buffer = (void *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))); *screen_buffer = msg; on_char++; }