summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--bochsrc1
-rw-r--r--stage3/font.asm243
-rw-r--r--stage3/font.c42
-rw-r--r--stage3/font.h9
-rw-r--r--stage3/gfx.c14
-rw-r--r--stage3/gfx.h6
-rw-r--r--stage3/halt.c7
-rw-r--r--stage3/halt.h1
-rw-r--r--stage3/heap.c123
-rw-r--r--stage3/heap.h16
-rw-r--r--stage3/letters.c213
-rw-r--r--stage3/letters_legacy.asm81
-rw-r--r--stage3/main.c25
-rw-r--r--stage3/paging.h3
15 files changed, 521 insertions, 268 deletions
diff --git a/Makefile b/Makefile
index cf58fa7..b9e677b 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/bochsrc b/bochsrc
index 842f2a0..8b486a5 100644
--- a/bochsrc
+++ b/bochsrc
@@ -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);