diff --git a/.gitignore b/.gitignore
index 97fbd68..770baf3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,3 @@
 *.bin
 mnt/
 build/
-bx_enh_dbg.ini
-serial.out
diff --git a/Makefile b/Makefile
index 695aa47..7864526 100644
--- a/Makefile
+++ b/Makefile
@@ -2,47 +2,24 @@ all: start32.bin
 clean:
 	-@rm *.bin 2> /dev/null || true
 
-start32.bin: src/* font.bin
+start32.bin: src/*
 	fasm src/start32.asm start32.bin
-font.bin: src/font.asm
-	fasm src/font.asm font.bin
-image: start32.bin mount grub-cfg roska.img mnt/roska/
+image: start32.bin mount
 	cp start32.bin mnt/roska/
 	sync
 
-qemu-run: image roska.img
+qemu-multiboot: start32.bin
+	qemu-system-i386 -kernel start32.bin -serial stdio
+qemu-image: image
 	qemu-system-i386 roska.img -serial stdio
-bochs-run: image roska.img
-	touch serial.out
-	bochs -qf bochsrc.txt
+
 mount: roska.img mnt/
 	@if ! mountpoint -q "mnt/"; then \
 		sudo mount -o loop,offset=1048576,umask=177,dmask=022,uid=$(shell id -u),gid=$(shell id -g) roska.img mnt/; \
 	fi;
 umount:
-	@if mountpoint -q "mnt/"; then \
-		sudo umount mnt/; \
-	fi;
+	@sudo umount mnt
 mnt/:
-	@mkdir -p mnt
-mnt/roska/: mount roska.img
-	@mkdir -p mnt/roska
+	@mkdir mnt
 build/:
 	@mkdir build
-
-roska.img: mnt/
-	dd if=/dev/zero of=roska.img bs=1k count=16128
-	echo 'type=83' | sudo sfdisk roska.img
-	sudo losetup /dev/loop0 roska.img
-	sudo losetup /dev/loop1 roska.img -o1048576
-	sudo mkdosfs -F32 -f 2 /dev/loop1
-	sudo mount /dev/loop1 mnt/
-	sudo grub-install --target=i386-pc --root-directory=mnt --boot-directory=mnt/boot --no-floppy --modules="normal part_msdos multiboot" /dev/loop0
-	sudo umount mnt/
-	sudo losetup -d /dev/loop1
-	sudo losetup -d /dev/loop0
-grub-cfg: grub.cfg mount
-	cp grub.cfg mnt/boot/grub/grub.cfg
-lo-unsetup: umount
-	sudo losetup -d /dev/loop1
-	sudo losetup -d /dev/loop0
diff --git a/bochsrc.txt b/bochsrc.txt
deleted file mode 100644
index 32dc163..0000000
--- a/bochsrc.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-display_library:	x, options="gui_debug"
-magic_break:	enabled=1
-romimage:	file=$BXSHARE/BIOS-bochs-legacy
-vgaromimage:	file=$BXSHARE/VGABIOS-lgpl-latest
-clock:	sync=realtime
-cpu:	ips=4294967295, reset_on_triple_fault=false
-megs:	128
-ata0:	enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
-ata0-master:	type=disk, mode=flat, path=roska.img, cylinders=32, heads=16, spt=63
-boot:	disk
-
-# Use `bximage` to get disk geometry
-# Serial is piped to serial.out for your `tail`ing sweetness
-com1:	enabled=1, mode=file, dev=serial.out
diff --git a/grub.cfg b/grub.cfg
deleted file mode 100644
index 30eab69..0000000
--- a/grub.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-menuentry "rOSka" {
-   multiboot /roska/start32.bin
-}
diff --git a/src/font.asm b/src/font.asm
index 42d3fd4..e97def8 100644
--- a/src/font.asm
+++ b/src/font.asm
@@ -1,82 +1,38 @@
-	format binary
-;;; Resolution: 8x12
-	;; 0	NULL
-	db 11001100b
-	db 00110011b
-	db 11001100b
-	db 00110011b
-	db 11001100b
-	db 00110011b
-	db 11001100b
-	db 00110011b
-	db 11001100b
-	db 00110011b
-	db 11001100b
-	db 00110011b
-	;; 1-31 control characters
-	rb 30*12
-	;; 32	Space
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	;; 33	!
-	db 00000000b
-	db 00011000b
-	db 00011000b
-	db 00011000b
-	db 00011000b
-	db 00011000b
-	db 00011000b
-	db 00011000b
-	db 00000000b
-	db 00011000b
-	db 00011000b
-	db 00000000b
-	;; 34	"
-	db 00000000b
-	db 01100110b
-	db 01100110b
-	db 01100110b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	db 00000000b
-	;; 35	#
-	db 00000000b
-	db 01101100b
-	db 01101100b
-	db 11111110b
-	db 01101100b
-	db 01101100b
-	db 01101100b
-	db 01101100b
-	db 11111110b
-	db 01101100b
-	db 01101100b
-	db 00000000b
-	;; 36	$
-	db 00000000b
-	db 00011000b
-	db 01111110b
-	db 01011000b
-	db 01111110b
-	db 01011000b
-	db 01111110b
-	db 00011010b
-	db 00011010b
-	db 00011010b
-	db 01111110b
-	db 00000000b
+;; Thank you Terminus for letting us use this font under SIL licence
+kfont:
+; controlchars
+times 31 db 0x00000000000000000000000000000000
+; space
+db 11000000b
+db 10000000b
+db 00000000b
+db 00000000b
+db 00000000b
+db 00000001b
+db 00000001b
+db 00000001b
+db 00000001b
+db 00000000b
+db 00000000b
+db 00000000b
+db 00000000b
+db 00000000b
+db 00000001b
+db 00000011b
+; !
+db 00000000b
+db 00000000b
+db 00011000b
+db 00011000b
+db 00011000b
+db 00011000b
+db 00011000b
+db 00011000b
+db 00011000b
+db 00000000b
+db 00011000b
+db 00011000b
+db 00000000b
+db 00000000b
+db 00000000b
+db 00000000b
diff --git a/src/framebuffer.asm b/src/framebuffer.asm
index e58e16e..d25ba38 100644
--- a/src/framebuffer.asm
+++ b/src/framebuffer.asm
@@ -1,19 +1,11 @@
-macro kputpixel x*, y*, r*, g*, b* {
-	push b		;b
-	push g		;g
-	push r		;r
-	push y		;y
-	push x		;x
-	call putpixel
-	add esp, 4*5
-}
-
-;; x, y, r, g, b
+;; x, y, brightness
 putpixel:
 	push ebp
 	mov ebp, esp
 
+	push eax
 	push ebx
+	push ecx
 	push edi
 
 	; check pixel is in screen
@@ -36,37 +28,74 @@ putpixel:
 	add edi, eax
 
 
+	; Brightness
+	mov eax, [ebp + 16]
 
 	; Poke videomemory
-	xor eax, eax
-	mov ebx, [ebp+16]
-	mov cl, [mbootinfo.fb_rpos]
-	shl ebx, cl
-	or eax, ebx
-
-	mov ebx, [ebp+20]
-	mov cl, [mbootinfo.fb_gpos]
-	shl ebx, cl
-	or eax, ebx
-
-	mov ebx, [ebp+24]
-	mov cl, [mbootinfo.fb_bpos]
-	shl ebx, cl
-	or eax, ebx
-
-	cmp [mbootinfo.fb_bpp], 32
-	jne .bpp24
-	stosd
-	jmp .done
-.bpp24:
-	stosb
-	shr eax, 8
-	stosb
-	shr eax, 8
-	stosb
+	cld
+	rep stosb
 .done:
 	pop edi
+	pop ecx
 	pop ebx
+	pop eax
 
 	pop ebp
 	ret
+
+; char, x, y
+putchar:
+	push ebp
+	mov ebp, esp
+	push eax
+	push ebx
+	push ecx
+	push edx
+
+	; skip non printable
+	mov eax, [ebp+8] ;char
+	cmp eax, 0x20
+	jl .unprintable
+	cmp eax, 0x7e
+	jg .unprintable
+
+	mov ecx, 16
+	mul ecx
+	mov esi, [kfont+eax]
+
+	mov ebx, [ebp+12] ;x
+	mov edx, [ebp+16] ;y
+
+	cld
+	xor eax, eax
+.loop:
+	lodsb	; load font row to al
+	mov ah, 0
+.loop2:
+	shl al
+	jnc .blankpix
+	; draw a pixel
+	push 0xff
+	push edx ;x
+	push ecx ;y
+.blankpix:
+	inc ah
+	cmp ah, 8
+	je .loop
+
+
+.done:
+	pop edx
+	pop ecx
+	pop ebx
+	pop eax
+	pop ebp
+	ret
+.unprintable:
+	push .unprintablemsg
+	call serialwrite
+	add esp, 4
+	jmp .done
+.unprintablemsg: db 10,"Err: Unprintable char not handled!", 0
+
+include "src/font.asm"
diff --git a/src/itoa.asm b/src/itoa.asm
index 3985f9d..914b214 100644
--- a/src/itoa.asm
+++ b/src/itoa.asm
@@ -1,12 +1,8 @@
 ;; Modified from: https://gist.github.com/SplittyDev/8e728627012e57ac0deac196660014fb
 
-; __itoa(src int, target addr, base)
-;target address returned in EAX
-;EBX, EBP, ESP preserved as our calling convention,
-;refer to docs or something
-
 ;
 ; Routine to convert a 32-bit integer to a string.
+; Registers are preserved.
 ;
 ; EAX: Source integer
 ; EBX: Target address
@@ -30,28 +26,19 @@
 ; ECX: Target address (active)
 ; EDX: Target address (temporary)
 ;
-; return:
-; put original target at EAX
-; (we trust this blindly)
-
-macro kuitoa src*, dest*, base* {
-	push base
-	push dest
-	push src
-	call __uitoa
-	add esp, 3*4
-}
-
 __uitoa:
 .start:
 	push ebp
 	mov ebp, esp
 
+	push eax
 	push ebx
+	push ecx
+	push edx
 
 	mov eax, [ebp+8]
-	mov ebx, [ebp+12]
-	mov ecx, [ebp+16]
+	mov ecx, [ebp+12]
+	mov ebx, [ebp+16]
 
 	mov edx, ecx
 	mov ecx, ebx
@@ -88,9 +75,11 @@ __uitoa:
 	dec ecx
 	jmp .reverse
 .end:
+	pop edx
+	pop ecx
 	pop ebx
+	pop eax
 
-	mov eax, [ebp+12]	; Return target address
 	pop ebp
 	ret
 
diff --git a/src/mbootinfo.asm b/src/mbootinfo.asm
index 3c3db73..2ff07e8 100644
--- a/src/mbootinfo.asm
+++ b/src/mbootinfo.asm
@@ -1,6 +1,7 @@
 mbootgetinfo:
 	push ebp
 	mov ebp, esp
+	push ebx
 	push esi
 	push edi
 	cld
@@ -9,23 +10,23 @@ mbootgetinfo:
 	cmp eax, 0x2badb002
 	jne mbootnomagic
 
-	mov edx, [ebp+12]
-	mov eax, [edx]
+	mov ebx, [ebp+12]
+	mov eax, [ebx]
 	mov [mbootinfo.flags], eax
 
 	;; Get memoryinformation
 	test eax, 1b
 	jz mbootnomeminfo
-	mov eax, [edx+4]
+	mov eax, [ebx+4]
 	mov [mbootinfo.mem_lower], eax
-	mov eax, [edx+8]
+	mov eax, [ebx+8]
 	mov [mbootinfo.mem_upper], eax
 
 	;; Get videoinformation
 	test [mbootinfo.flags], (1 shl 02)
 	jz mbootnovideoinfo
 
-	mov esi, edx
+	mov esi, ebx
 	add esi, 88
 	mov eax, [esi]
 	mov [mbootinfo.fb_addr], eax
@@ -53,8 +54,6 @@ mbootgetinfo:
 	mov [mbootinfo.fb_type], al
 	inc esi
 
-	;garbage?
-	add esi, 2
 	;; r/g/b positions and masks
 	mov ecx, 6
 	mov edi, mbootinfo.fb_rpos
@@ -63,12 +62,13 @@ mbootgetinfo:
 .bytesppcalc:
 	xor eax, eax
 	mov al, [mbootinfo.fb_bpp]
-	mov edx, 8
-	div dl
+	mov ebx, 8
+	div bl
 	mov [mbootinfo.fb_bytespp], al
 .done:
 	pop edi
 	pop esi
+	pop ebx
 	pop ebp
 	ret
 
diff --git a/src/serial.asm b/src/serial.asm
index 2699f01..b4e3353 100644
--- a/src/serial.asm
+++ b/src/serial.asm
@@ -1,14 +1,9 @@
 SERIAL_PORT equ 0x3f8
 serialinitialized db 0
 
-; Write null terminated string in address str_pointer to serial
-macro serw [str_pointer*] {
-	push str_pointer
-	call serialwrite
-	add esp, 4
-}
-
 serialinit:
+	push ax
+
 	;Disable ints
 	mov dx, SERIAL_PORT+1
 	mov al, 0x00
@@ -59,6 +54,7 @@ serialinit:
 	out dx, al
 	mov [serialinitialized], 1
 .end:
+	pop ax
 	ret
 .errormsg db "Serial init failed", 0
 
@@ -68,6 +64,7 @@ serialwrite:
 	push ebp
 	mov ebp, esp
 	push esi
+	push ax
 	cld
 	mov esi, [ebp+8]
 .loop:
@@ -83,6 +80,7 @@ serialwrite:
 	out dx, al
 	jmp .loop
 .done:
+	pop ax
 	pop esi
 	pop ebp
 	ret
diff --git a/src/start32.asm b/src/start32.asm
index e36b4f7..25342cb 100644
--- a/src/start32.asm
+++ b/src/start32.asm
@@ -13,7 +13,7 @@ MB_CHECKSUM          equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS)
 
 VWIDTH  equ 640
 VHEIGHT equ 480
-VDEPTH  equ 32
+VDEPTH  equ 24
 
 multiboot:
 	dd MB_HEADER_MAGIC
@@ -29,17 +29,6 @@ multiboot:
 	dd VHEIGHT	; video height
 	dd VDEPTH	; video depth
 
-; Includes yayyy
-include "src/serial.asm"
-include "src/mbootinfo.asm"
-include "src/itoa.asm"
-include "src/framebuffer.asm"
-include "src/roskalogoraw.asm"
-
-align 4096
-font FILE "font.bin"
-align 4096
-
 start:
 	; Setup stack
 	mov ebp, stack_top
@@ -49,60 +38,77 @@ start:
 	push eax
 
 	call serialinit
-
-	serw stuff.bootmsg
+	push stuff.bootmsg
+	call serialwrite
+	add esp, 4
 
 	call mbootgetinfo
 	add esp, 2*4
 
+	push stuff.fbaddrmsgpfx
+	call serialwrite
+	add esp, 4
+
 	sub esp, 36	;Reserve stack for return
-	mov ebx, esp	;Store str buff addr
+	push dword esp	;Destination address
+	push dword 16	;Base
+	push dword [mbootinfo.fb_addr]	;source
+	call __uitoa
+	add esp, 3*4
+	push esp
+	call serialwrite
+	add esp, 4
 
-	kuitoa [mbootinfo.fb_addr], ebx, 16
-	serw stuff.fbaddrmsgpfx, ebx
+	push stuff.fbdimensionsmsgpfx
+	call serialwrite
+	add esp, 4
+	push dword esp	;destination address
+	push dword 10	;base
+	push dword [mbootinfo.fb_width]
+	call __uitoa
+	add esp, 3*4
+	push esp
+	call serialwrite
+	add esp, 4
+	push stuff.x
+	call serialwrite
+	add esp, 4
 
-	kuitoa [mbootinfo.fb_width], ebx, 10
-	serw stuff.fbdimensionsmsgpfx, ebx, stuff.x
+	push dword esp	;destination address
+	push dword 10	;base
+	push dword [mbootinfo.fb_height]
+	call __uitoa
+	add esp, 3*4
+	push esp
+	call serialwrite
+	add esp, 4
+	push stuff.x
+	call serialwrite
+	add esp, 4
 
-	kuitoa [mbootinfo.fb_height], ebx, 10
-	serw ebx, stuff.x
-
-	movzx eax, byte [mbootinfo.fb_bpp]
-	kuitoa eax, ebx, 10
-	serw ebx
-
-
-	movzx eax, byte [mbootinfo.fb_rpos]
-	kuitoa eax, ebx, 10
-	serw stuff.rpostxt, ebx
-
-	movzx eax, byte [mbootinfo.fb_gpos]
-	kuitoa eax, ebx, 10
-	serw stuff.gpostxt, ebx
-
-	movzx eax, byte [mbootinfo.fb_bpos]
-	kuitoa eax, ebx, 10
-	serw stuff.bpostxt, ebx
-
-
-	movzx eax, byte [mbootinfo.fb_rmasksize]
-	kuitoa eax, ebx, 10
-	serw stuff.rmasksizetxt, ebx
-
-	movzx eax, byte [mbootinfo.fb_gmasksize]
-	kuitoa eax, ebx, 10
-	serw stuff.gmasksizetxt, ebx
-
-	movzx eax, byte [mbootinfo.fb_bmasksize]
-	kuitoa eax, ebx, 10
-	serw stuff.bmasksizetxt, ebx
+	push dword esp	;destination address
+	push dword 10	;base
+	xor eax, eax
+	mov al, [mbootinfo.fb_bpp]
+	push dword eax
+	call __uitoa
+	add esp, 3*4
+	push esp
+	call serialwrite
+	add esp, 4
 
 	add esp, 36	;Clean reserved uitoa return string from stack
 
-	; Draw a green test pixel to bottom-right
-	kputpixel VWIDTH-1, VHEIGHT-1, 0x00, 0xff, 0x00
+	; Draw a test pixel to bottom right corner
+	mov eax, 0xff
+	mov ebx, 767
+	mov ecx, 1023
+	push 0xff
+	push 479
+	push 639
+	call putpixel
+	add esp, 3*4
 
-; Draw a predefined logo in magenta to top-left
 rOSkalogodraw:
 	mov esi, roskalogo
 	mov eax, 0	;Brightness
@@ -110,12 +116,13 @@ rOSkalogodraw:
 	mov ecx, 0	;x
 .loop:
 	lodsb
-
-	push ecx
 	push eax
-	kputpixel ecx, ebx, eax, 0x00, eax
-	pop eax
+	push ebx
+	push ecx
+	call putpixel
 	pop ecx
+	pop ebx
+	pop eax
 
 	inc ecx
 	cmp byte cl, [roskalogo.w]
@@ -125,32 +132,36 @@ rOSkalogodraw:
 	cmp byte bl, [roskalogo.h]
 	jne .loop
 .done:
-jmp hang
 
+push byte 0x21
+push byte 0x21
+push byte 0x21
+call putchar
+add esp, 3*4
 
+	jmp hang
 
 hang:
-	serw .msg
+	push .msg
+	call serialwrite
 	cli
 .loop:
 	hlt
 	jmp .loop
 .msg db 10, "Halting...", 10, 0
 
+include "src/serial.asm"
+include "src/mbootinfo.asm"
+include "src/itoa.asm"
+include "src/framebuffer.asm"
+include "src/roskalogoraw.asm"
+
 stuff:
 	.bootmsg db 10, "=== rOSka ===", 10, 0
 	.fbaddrmsgpfx db 10, "Framebuffer address: 0x", 0
 	.fbdimensionsmsgpfx db 10, "Framebuffer dimensions: ", 0
 	.x db "x", 0
 
-
-	.rpostxt db 10, "rPos: ", 0
-	.gpostxt db 10, "gPos: ", 0
-	.bpostxt db 10, "bPos: ", 0
-	.rmasksizetxt db 10, "rMaskSize: ", 0
-	.gmasksizetxt db 10, "gMaskSize: ", 0
-	.bmasksizetxt db 10, "bMaskSize: ", 0
-
 align 4096
 bss_start:
 ;align 4096