diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-06-16 04:49:57 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-06-16 04:49:57 +1000 |
| commit | 3e9bdcca84e22c997a071dddf37449ead85aed75 (patch) | |
| tree | 06def7ef704b348cdef2b704d3357b79d22f00bd /kernel/con.c | |
Initial commit
Diffstat (limited to 'kernel/con.c')
| -rw-r--r-- | kernel/con.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/kernel/con.c b/kernel/con.c new file mode 100644 index 0000000..b3d2b9d --- /dev/null +++ b/kernel/con.c @@ -0,0 +1,96 @@ +/* + * con.c + * + * Basic VGA text console + */ + +#include <asm/io.h> +#include <kernel/vsprintf.h> +#include <stdarg.h> +#include <stdint.h> + +#define COLS 80 +#define ROWS 25 + +static uint8_t *vram = (uint8_t*) 0xB8000; +static int pos; + +static inline void cursorpos(int pos) { + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t) ((pos >> 9) & 0xFF)); + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t) ((pos >> 1) & 0xFF)); +} + +/* scrolls the console up one line */ +static void scroll_up(void) { + int n = (COLS * (ROWS - 1)) << 1; + uint8_t *p = vram; + + while(n--) { + *p = p[COLS << 1]; + p++; + } + + p = (uint8_t*) (vram + (COLS * (ROWS - 1) << 1)); + n = COLS; + while(n--) { + *p = ' '; + p += 2; + } + + pos -= COLS << 1; + cursorpos(pos); +} + +/* must be called before any console output */ +void con_init(void) { + int n = COLS * ROWS; + uint8_t *p = vram; + + while(n--) { + *(p++) = 0x20; + *(p++) = 0x07; + } + + pos = 0; + cursorpos(0); +} + +/* write a zero-terminated string to console */ +void con_print(char *s) { + uint8_t *p = &vram[pos]; + + while(*s) { + if(*s == '\n') { + pos = (int) (p - vram); + pos = ((pos / (COLS << 1)) + 1) * (COLS << 1); + p = &vram[pos]; + s++; + } else { + *p = *(s++); + p += 2; + } + + pos = (int) (p - vram); + + if(pos >= (COLS * ROWS) << 1) + scroll_up(); + } + + /* update the cursor position */ + cursorpos(pos); +} + +int printf(char *fmt, ...) { + int ret; + char buf[1024]; + va_list ap; + + va_start(ap, fmt); + ret = vsprintf(buf, fmt, ap); + va_end(ap); + + con_print(buf); + return ret; +} |
