diff options
-rw-r--r-- | baremetal/101screen.subx | 46 | ||||
-rw-r--r-- | baremetal/400.mu | 1 | ||||
-rw-r--r-- | baremetal/ex2.mu | 31 | ||||
-rw-r--r-- | baremetal/mu-init.subx | 17 | ||||
-rwxr-xr-x | translate_mu_baremetal | 9 |
5 files changed, 104 insertions, 0 deletions
diff --git a/baremetal/101screen.subx b/baremetal/101screen.subx new file mode 100644 index 00000000..3e98d96b --- /dev/null +++ b/baremetal/101screen.subx @@ -0,0 +1,46 @@ +# Primitives for screen control. + +pixel: # screen: (addr screen), x: int, y: int, color: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 56/push-esi + # esi = screen + 8b/-> *(ebp+8) 6/r32/esi + 81 7/subop/compare %esi 0/imm32 + { + 75/jump-if-!= break/disp8 + # bounds checks + 8b/-> *(ebp+0xc) 0/r32/eax + 3d/compare-eax-and 0/imm32 + 7c/jump-if-< $pixel:end/disp8 + 3d/compare-eax-and 0x400/imm32/1024 + 7d/jump-if->= $pixel:end/disp8 + 8b/-> *(ebp+0x10) 0/r32/eax + 3d/compare-eax-and 0/imm32 + 7c/jump-if-< $pixel:end/disp8 + 3d/compare-eax-and 0x300/imm32/768 + 7d/jump-if->= $pixel:end/disp8 + # eax = y*1024 + x + 8b/-> *(ebp+0x10) 0/r32/eax + c1/shift 4/subop/left %eax 0xa/imm8 + 03/add-> *(ebp+0xc) 0/r32/eax + # eax += location of frame buffer + 03/add-> *0x7f28 0/r32/eax + # *eax = color + 8b/-> *(ebp+0x14) 6/r32/esi + 88/byte<- *eax 6/r32/esi + # return + eb $pixel:end/disp8 + } + # TODO: fake screen +$pixel:end: + # . restore registers + 5e/pop-to-esi + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return diff --git a/baremetal/400.mu b/baremetal/400.mu new file mode 100644 index 00000000..1121a00a --- /dev/null +++ b/baremetal/400.mu @@ -0,0 +1 @@ +sig pixel screen: (addr screen), x: int, y: int, color: int diff --git a/baremetal/ex2.mu b/baremetal/ex2.mu new file mode 100644 index 00000000..091cb1d0 --- /dev/null +++ b/baremetal/ex2.mu @@ -0,0 +1,31 @@ +# Test out the video mode by filling in the screen with pixels. +# +# To build a disk image: +# ./translate_subx_baremetal baremetal/ex2.subx # emits disk.img +# To run: +# qemu-system-i386 disk.img +# Or: +# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img +# +# Expected output: +# html/baremetal.png + +fn main { + var y/eax: int <- copy 0 + { + compare y, 0x300 # 768 + break-if->= + var color/ecx: int <- copy y + color <- and 0xff + var x/edx: int <- copy 0 + { + compare x, 0x400 # 1024 + break-if->= + pixel 0, x, y, color + x <- increment + loop + } + y <- increment + loop + } +} diff --git a/baremetal/mu-init.subx b/baremetal/mu-init.subx new file mode 100644 index 00000000..232b3b49 --- /dev/null +++ b/baremetal/mu-init.subx @@ -0,0 +1,17 @@ +# Initialize the minimal runtime for Mu programs. +# +# See translate_mu_baremetal for how this file is used. +# +# Mu baremetal programs start at a function called 'main' without inouts or outputs. + +== code + +# initialize stack +bd/copy-to-ebp 0/imm32 +# no heap yet +(main) + +# hang indefinitely +{ + eb/jump loop/disp8 +} diff --git a/translate_mu_baremetal b/translate_mu_baremetal new file mode 100755 index 00000000..66b27b23 --- /dev/null +++ b/translate_mu_baremetal @@ -0,0 +1,9 @@ +#!/bin/sh +# Translate a given Mu program to 'baremetal', a raw disk image that can boot +# and run without any OS. + +set -e + +cat $* baremetal/[0-9]*.mu |apps/mu > a.subx + +./translate_subx_baremetal baremetal/mu-init.subx baremetal/[0-9]*.subx a.subx |