diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | bochsrc | 1 | ||||
-rw-r--r-- | stage3/font.asm | 243 | ||||
-rw-r--r-- | stage3/font.c | 42 | ||||
-rw-r--r-- | stage3/font.h | 9 | ||||
-rw-r--r-- | stage3/gfx.c | 14 | ||||
-rw-r--r-- | stage3/gfx.h | 6 | ||||
-rw-r--r-- | stage3/halt.c | 7 | ||||
-rw-r--r-- | stage3/halt.h | 1 | ||||
-rw-r--r-- | stage3/heap.c | 123 | ||||
-rw-r--r-- | stage3/heap.h | 16 | ||||
-rw-r--r-- | stage3/letters.c | 213 | ||||
-rw-r--r-- | stage3/letters_legacy.asm | 81 | ||||
-rw-r--r-- | stage3/main.c | 25 | ||||
-rw-r--r-- | stage3/paging.h | 3 |
15 files changed, 521 insertions, 268 deletions
@@ -17,7 +17,10 @@ STAGE3 = \ stage3/halt.o \ stage3/framebuffer.o \ stage3/memory.o \ - stage3/paging.o + stage3/paging.o \ + stage3/heap.o \ + stage3/font.o \ + stage3/letters.o lizzyx.img: stage1.out stage2.out stage3.out cat stage{1,2,3}.out > lizzyx.img @@ -1,3 +1,4 @@ floppya: 1_44=lizzyx.img, status=inserted boot: a display_library: x, options="gui_debug" +megs: 32 diff --git a/stage3/font.asm b/stage3/font.asm deleted file mode 100644 index b73edab..0000000 --- a/stage3/font.asm +++ /dev/null @@ -1,243 +0,0 @@ -global debug - -%define GFXINFO 0x1000-10 -%define PITCH GFXINFO+0 -%define WIDTH GFXINFO+2 -%define HEIGHT GFXINFO+4 -%define FRAMEBUFFER GFXINFO+6 - -section .text - -; str in rdi -debug: - mov r9, [line] - - mov rax, rcx - mov rbx, 15 - xor rdx, rdx - mul rbx - - cmp rax, [HEIGHT] - jmp .char - - xor rax, rax - xor r9, r9 - -.char: - xor rax, rax - - mov al, [rdi] - cmp al, 0 - je .return - - cmp al, ' ' - je .space - - cmp al, 'a' - jb .invalid - - cmp al, 'z' - ja .invalid - - sub al, 'a' - mov bl, 15 - mul bl - - add rax, letters - mov r8, rax - - jmp .render - -.space: - mov r8, letters.space - -.render: - -.target: - xor rdx, rdx - mul [PITCH] - - xor rbx, rbx - mov ebx, [FRAMEBUFFER] - add rax, rbx - - inc rdi - jmp debug - -.return: - ret - -.invalid: - mov rdi, .invalid_msg - call debug - jmp $ - -.invalid_msg: "invalid character in message", 0 - -section .data - -line: dq 0 - -letters: -.a: db -1, 1, 1, -1, 0, 1, -1, 1, 1, -1, 0, 1, -1, 0, 1 -.b: db -1, 1, 0, -1, 0, 1, -1, 1, 1, -1, 0, 1, -1, 1, 1 -.c: db -1, 1, 1, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 1, 1 -.d: db -1, 1, 0, -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 1, 1 -e: db -1, 1, 1, -1, 0, 0, -1, 1, 1, -1, 0, 0, -1, 1, 1 -f: db -1, 1, 1, -1, 0, 0, -1, 1, 1, -1, 0, 0, -1, 0, 0 -g: db -1, 1, 1, -1, 0, 0, -1, 0, 1, -1, 0, 1, -1, 1, 1 -h: db -1, 0, 1, -1, 0, 1, -1, 1, 1, -1, 0, 1, -1, 0, 1 -i: db -0, 1, 0, -0, 1, 0, -0, 1, 0, -0, 1, 0, -0, 1, 0 -j: db -0, 0, 1, -0, 0, 1, -0, 0, 1, -0, 0, 1, -1, 1, 1 -k: db -1, 0, 1, -1, 1, 0, -1, 0, 0, -1, 1, 0, -1, 0, 1, -l: db -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 1, 1 -m: db -1, 0, 1, -1, 1, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1 -n: db -1, 0, 1, -1, 0, 1, -1, 1, 1, -1, 1, 1, -1, 0, 1 -o: db -1, 1, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 1, 1 -p: db -1, 1, 1, -1, 0, 1, -1, 1, 1, -1, 0, 0, -1, 0, 0 -q: db -1, 1, 1, -1, 0, 1, -1, 1, 1, -1, 1, 1, -0, 0, 1 -r: db -1, 1, 1, -1, 0, 1, -1, 1, 1, -1, 1, 0, -1, 0, 1 -s: db -1, 1, 1, -1, 0, 0, -1, 1, 1, -0, 0, 1, -1, 1, 1 -t: db -1, 1, 1, -0, 1, 0, -0, 1, 0, -0, 1, 0, -0, 1, 0 -u: db -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 1, 1 -v: db -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, -0, 1, 0 -w: db -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 1, 1, -1, 0, 1 -x: db -1, 0, 1, -1, 0, 1, -0, 1, 0, -1, 0, 1, -1, 0, 1 -y: db -1, 0, 1, -1, 0, 1, -1, 1, 1, -0, 1, 0, -0, 1, 0 -z: db -1, 1, 1, -0, 0, 1, -0, 1, 0 -1, 0, 0 -1, 1, 1 -.space: -0, 0, 0, -0, 0, 0, -0, 0, 0, -0, 0, 0, -0, 0, 0 diff --git a/stage3/font.c b/stage3/font.c new file mode 100644 index 0000000..c9ef520 --- /dev/null +++ b/stage3/font.c @@ -0,0 +1,42 @@ +#include "font.h" +#include "gfx.h" + +#define FONT_SIZE 3 + +static const u16 outer_width = (CHAR_WIDTH + 2) * FONT_SIZE; +static const u16 outer_height = (CHAR_HEIGHT + 2) * FONT_SIZE; + +extern u8 letters['z' - 'a' + 1][CHAR_HEIGHT * CHAR_WIDTH]; + +static u16 line_count = 0; + +static void print_chr(u16 at_x, u16 at_y, char c) +{ + u16 base_x = at_x * outer_width; + u16 base_y = at_y * outer_height; + + gfx_set_area(base_x, base_y, outer_width, outer_height, 0xFF000000); + + if (c > 'z' || c < 'a') + return; + + for (u16 x = 0; x < CHAR_WIDTH; x++) + for (u16 y = 0; y < CHAR_HEIGHT; y++) { + if (!letters[c - 'a'][y * CHAR_WIDTH + x]) + continue; + + gfx_set_area( + base_x + (x + 1) * FONT_SIZE, + base_y + (y + 1) * FONT_SIZE, + FONT_SIZE, FONT_SIZE, 0xFFFFFFFF); + } +} + +void print(char *line) +{ + for (u16 x = 0; *line != '\0'; ++x, ++line) + print_chr(x, line_count, *line); + + line_count++; +} + diff --git a/stage3/font.h b/stage3/font.h new file mode 100644 index 0000000..fe525ac --- /dev/null +++ b/stage3/font.h @@ -0,0 +1,9 @@ +#ifndef _FONT_H_ +#define _FONT_H_ + +#define CHAR_WIDTH 3 +#define CHAR_HEIGHT 5 + +void print(char *line); + +#endif diff --git a/stage3/gfx.c b/stage3/gfx.c index 0ecf423..2afc766 100644 --- a/stage3/gfx.c +++ b/stage3/gfx.c @@ -1,6 +1,6 @@ #include "gfx.h" -struct GfxInfo *gfxinfo = (void *) (0x1000-10); +struct GfxInfo *gfx_info = (void *) (0x1000-10); // byteswap u32 make_color(color col) @@ -12,17 +12,17 @@ u32 make_color(color col) & ((u32) col.a << 24); } -void set_pixel(u16 x, u16 y, u32 col) +void gfx_set_pixel(u16 x, u16 y, u32 col) { - *((u32 *) (u64) (gfxinfo->framebuffer + y * gfxinfo->pitch + x * sizeof col)) = col; + *((u32 *) (u64) (gfx_info->framebuffer + y * gfx_info->pitch + x * sizeof col)) = col; } -void set_region(u16 x, u16 y, u16 w, u16 h, u32 col) +void gfx_set_area(u16 x, u16 y, u16 w, u16 h, u32 col) { - void *cbeg = (void *) (u64) (gfxinfo->framebuffer + y * gfxinfo->pitch + x * sizeof col); - void *cend = cbeg + h * gfxinfo->pitch; + void *cbeg = (void *) (u64) (gfx_info->framebuffer + y * gfx_info->pitch + x * sizeof col); + void *cend = cbeg + h * gfx_info->pitch; - for (; cbeg < cend; cbeg += gfxinfo->pitch) { + for (; cbeg < cend; cbeg += gfx_info->pitch) { void *rbeg = cbeg; void *rend = rbeg + w * sizeof col; diff --git a/stage3/gfx.h b/stage3/gfx.h index e4e5d8b..cf89a9e 100644 --- a/stage3/gfx.h +++ b/stage3/gfx.h @@ -8,14 +8,14 @@ extern struct __attribute__((packed)) GfxInfo { u16 width; u16 height; u32 framebuffer; -} *gfxinfo; +} *gfx_info; typedef struct { u8 r, g, b, a; } color; u32 make_color(color col); -void set_pixel(u16 x, u16 y, u32 col); -void set_region(u16 x, u16 y, u16 w, u16 h, u32 col); +void gfx_set_pixel(u16 x, u16 y, u32 col); +void gfx_set_area(u16 x, u16 y, u16 w, u16 h, u32 col); #endif diff --git a/stage3/halt.c b/stage3/halt.c index 63ad8e2..39bc3c9 100644 --- a/stage3/halt.c +++ b/stage3/halt.c @@ -1,7 +1,14 @@ #include "halt.h" +#include "font.h" void halt() { for (;;) ; } + +void panic(char *msg) +{ + print(msg); + halt(); +} diff --git a/stage3/halt.h b/stage3/halt.h index 9521dd9..b4d0d14 100644 --- a/stage3/halt.h +++ b/stage3/halt.h @@ -2,5 +2,6 @@ #define _HALT_H_ void halt(); +void panic(char *msg); #endif diff --git a/stage3/heap.c b/stage3/heap.c new file mode 100644 index 0000000..d9bc583 --- /dev/null +++ b/stage3/heap.c @@ -0,0 +1,123 @@ +#include "halt.h" +#include "heap.h" + +#define PAGESIZE 0x1000 +#define MAGIC ((void *) 0x69) + +typedef struct __attribute__((packed)) Header { + struct Header *next; + usize size; +} Header; + +static Header init_free_ptr; +static Header *free_ptr = nil; + +void free(void *ptr) +{ + Header *h = ((Header *) ptr) - 1; + + if (h->next != MAGIC) + panic("free: invalid pointer"); + + Header *next = free_ptr->next; + free_ptr->next = h; + h->next = next; +} + +static void defragment() +{ + //usize num_blocks = 0; + panic("defragment not implemented"); +} + +void *try_malloc(usize size) +{ + for (Header *prev = free_ptr;; prev = prev->next) { + Header *h = prev->next; + + if (h->size < size) { + if (h == free_ptr) + break; + else + continue; + } + + if (h->size <= size + sizeof(Header)) { + prev->next = h->next; + } else { + // split + h->size -= size; + h = ((void *) h) + sizeof(Header) + h->size; + h->size = size; + } + + h->next = MAGIC; + free_ptr = prev; + return h + 1; + } + + return nil; +} + +void *malloc(usize size) +{ + void *p; + + p = try_malloc(size); + if (p) return p; + defragment(); + + p = try_malloc(size); + if (p) return p; + panic("out of memory"); + + return nil; +} + +void heap_init() +{ + free_ptr = &init_free_ptr; + free_ptr->size = 0; + free_ptr->next = free_ptr; +} + +void heap_add(void *ptr, usize size) +{ + // discard blocks that are too small + if (size <= sizeof(Header)) + return; + + Header *h = ptr; + h->next = MAGIC; + h->size = size - sizeof(Header); + + free(h + 1); +} + +void heap_add_region(MemRegion *region) +{ + switch (region->used) { + // region is reserved + case -1: + break; + + // region is entirely free + case 0: + heap_add(region->start, region->size); + break; + + // region is partly used + default: { + void *region_end = region->start + region->size; + + // rounds up region->start to pagesize align + void *use_begin = (void *) ((u64) (region->start + PAGESIZE - 1) & (PAGESIZE - 1)); + void *use_end = use_begin + region->used; + + heap_add(region->start, use_begin - region->start); + heap_add(use_end, region_end - use_end); + } + } + + region->used = -1; // just to be safe +} diff --git a/stage3/heap.h b/stage3/heap.h new file mode 100644 index 0000000..dd38693 --- /dev/null +++ b/stage3/heap.h @@ -0,0 +1,16 @@ +#ifndef _HEAP_H_ +#define _HEAP_H_ + +#include "def.h" +#include "paging.h" + +void heap_init(); + +void heap_add(void *ptr, usize size); +void heap_add_region(MemRegion *region); + +void *try_malloc(usize size); +void *malloc(usize siz); +void free(void *ptr); + +#endif diff --git a/stage3/letters.c b/stage3/letters.c new file mode 100644 index 0000000..11f1d46 --- /dev/null +++ b/stage3/letters.c @@ -0,0 +1,213 @@ +#include "font.h" +#include "def.h" + +u8 letters['z' - 'a' + 1][CHAR_HEIGHT * CHAR_WIDTH] = { + // a + { + 1, 1, 1, + 1, 0, 1, + 1, 1, 1, + 1, 0, 1, + 1, 0, 1 + }, + // b + { + 1, 1, 0, + 1, 0, 1, + 1, 1, 1, + 1, 0, 1, + 1, 1, 0 + }, + // c + { + 1, 1, 1, + 1, 0, 0, + 1, 0, 0, + 1, 0, 0, + 1, 1, 1 + }, + // d + { + 1, 1, 0, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 1, 0 + }, + // e + { + 1, 1, 1, + 1, 0, 0, + 1, 1, 1, + 1, 0, 0, + 1, 1, 1 + }, + // f + { + 1, 1, 1, + 1, 0, 0, + 1, 1, 1, + 1, 0, 0, + 1, 0, 0 + }, + // g + { + 1, 1, 1, + 1, 0, 0, + 1, 0, 1, + 1, 0, 1, + 1, 1, 1 + }, + // h + { + 1, 0, 1, + 1, 0, 1, + 1, 1, 1, + 1, 0, 1, + 1, 0, 1 + }, + // i + { + 0, 1, 0, + 0, 1, 0, + 0, 1, 0, + 0, 1, 0, + 0, 1, 0 + }, + // j + { + 0, 0, 1, + 0, 0, 1, + 0, 0, 1, + 0, 0, 1, + 1, 1, 1 + }, + // k + { + 1, 0, 1, + 1, 1, 0, + 1, 0, 0, + 1, 1, 0, + 1, 0, 1, + }, + // l + { + 1, 0, 0, + 1, 0, 0, + 1, 0, 0, + 1, 0, 0, + 1, 1, 1 + }, + // m + { + 1, 0, 1, + 1, 1, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1 + }, + // n + { + 1, 0, 1, + 1, 0, 1, + 1, 1, 1, + 1, 1, 1, + 1, 0, 1 + }, + // o + { + 1, 1, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 1, 1 + }, + // p + { + 1, 1, 1, + 1, 0, 1, + 1, 1, 1, + 1, 0, 0, + 1, 0, 0 + }, + // q + { + 1, 1, 1, + 1, 0, 1, + 1, 0, 1, + 1, 1, 1, + 0, 0, 1 + }, + // r + { + 1, 1, 1, + 1, 0, 1, + 1, 1, 1, + 1, 1, 0, + 1, 0, 1 + }, + // s + { + 1, 1, 1, + 1, 0, 0, + 1, 1, 1, + 0, 0, 1, + 1, 1, 1 + }, + // t + { + 1, 1, 1, + 0, 1, 0, + 0, 1, 0, + 0, 1, 0, + 0, 1, 0 + }, + // u + { + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 1, 1 + }, + // v + { + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 0, 1, 0 + }, + // w + { + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 1, 1, + 1, 0, 1 + }, + // x + { + 1, 0, 1, + 1, 0, 1, + 0, 1, 0, + 1, 0, 1, + 1, 0, 1 + }, + // y + { + 1, 0, 1, + 1, 0, 1, + 1, 1, 1, + 0, 1, 0, + 0, 1, 0 + }, + // z + { + 1, 1, 1, + 0, 0, 1, + 0, 1, 0, + 1, 0, 0, + 1, 1, 1 + } +}; diff --git a/stage3/letters_legacy.asm b/stage3/letters_legacy.asm new file mode 100644 index 0000000..50f04ec --- /dev/null +++ b/stage3/letters_legacy.asm @@ -0,0 +1,81 @@ +global letters + +%define GFXINFO 0x1000-10 +%define PITCH GFXINFO+0 +%define WIDTH GFXINFO+2 +%define HEIGHT GFXINFO+4 +%define FRAMEBUFFER GFXINFO+6 + +section .text + +; str in rdi +legacy_debug: + mov r9, [line] + + mov rax, rcx + mov rbx, 15 + xor rdx, rdx + mul rbx + + cmp rax, [HEIGHT] + jmp .char + + xor rax, rax + xor r9, r9 + +.char: + xor rax, rax + + mov al, [rdi] + cmp al, 0 + je .return + + cmp al, ' ' + je .space + + cmp al, 'a' + jb .invalid + + cmp al, 'z' + ja .invalid + + sub al, 'a' + mov bl, 15 + mul bl + + add rax, letters + mov r8, rax + + jmp .render + +.space: + mov r8, letters.space + +.render: + +.target: + xor rdx, rdx + mul [PITCH] + + xor rbx, rbx + mov ebx, [FRAMEBUFFER] + add rax, rbx + + inc rdi + jmp debug + +.return: + ret + +.invalid: + mov rdi, .invalid_msg + call debug + jmp $ + +.invalid_msg: "invalid character in message", 0 + +section .data + +line: dq 0 + +letters: diff --git a/stage3/main.c b/stage3/main.c index 7c84d05..ab0b3a5 100644 --- a/stage3/main.c +++ b/stage3/main.c @@ -2,30 +2,31 @@ #include "def.h" #include "gfx.h" #include "halt.h" +#include "heap.h" +#include "font.h" void clear_screen(); // framebuffer.asm void kmain() { clear_screen(); + heap_init(); - for (MemRegion *mmap = (void *) 0x500; mmap->start != nil; mmap++) - page_region(mmap); +#define MMAP for (MemRegion *mreg = (void *) 0x500; mreg->start != nil; mreg++) + + MMAP page_region(mreg); page_region(&(MemRegion) { - .start = (void *) (u64) gfxinfo->framebuffer, - .size = gfxinfo->pitch * gfxinfo->height, - .type = MEM_RESERVED, - .zero = 0, + .start = (void *) (u64) gfx_info->framebuffer, + .size = gfx_info->pitch * gfx_info->height, + .used = MEM_RESERVED, }); - /* - for (u16 x = 0; x < gfxinfo->width; x++) - for (u16 y = 0; y < gfxinfo->height; y++) - set_pixel(x, y, 0x0087CEEB); - */ + MMAP heap_add_region(mreg); + + gfx_set_area(0, 0, gfx_info->width, gfx_info->height, 0xFF87CEEB); - set_region(0, 0, gfxinfo->width, gfxinfo->height, 0x0087CEEB); + print("abcdefghijklmnopqrstuvwxyz"); halt(); } diff --git a/stage3/paging.h b/stage3/paging.h index b9a3930..e05ab1a 100644 --- a/stage3/paging.h +++ b/stage3/paging.h @@ -11,8 +11,7 @@ typedef enum { typedef struct __attribute__((packed)) { void *start; usize size; - u16 type; - u16 zero; + u32 used; } MemRegion; void page_region(MemRegion *region); |