diff options
-rw-r--r-- | baremetal/104test.subx | 32 | ||||
-rw-r--r-- | baremetal/400.mu | 4 | ||||
-rw-r--r-- | baremetal/500clear-screen.mu | 17 | ||||
-rw-r--r-- | baremetal/502test.mu | 18 | ||||
-rw-r--r-- | baremetal/README.md | 7 | ||||
-rw-r--r-- | baremetal/mu-init.subx | 12 |
6 files changed, 87 insertions, 3 deletions
diff --git a/baremetal/104test.subx b/baremetal/104test.subx new file mode 100644 index 00000000..5b14049e --- /dev/null +++ b/baremetal/104test.subx @@ -0,0 +1,32 @@ +# Some helpers needed only because Mu doesn't support globals at the moment. + +== code + +count-test-failure: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # + ff 0/subop/increment *Num-test-failures +$count-test-failure:end: + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +num-test-failures: # -> _/eax: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # + 8b/-> *Num-test-failures 0/r32/eax +$num-test-failures:end: + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +== data + +Num-test-failures: + 0/imm32 diff --git a/baremetal/400.mu b/baremetal/400.mu index 0f345e01..ff84a643 100644 --- a/baremetal/400.mu +++ b/baremetal/400.mu @@ -7,6 +7,10 @@ sig set-cursor-position screen: (addr screen), x: int, y: int # keyboard sig read-key kbd: (addr keyboard) -> _/eax: byte +# tests +sig count-test-failure +sig num-test-failures -> _/eax: int + # streams sig clear-stream f: (addr stream _) sig rewind-stream f: (addr stream _) diff --git a/baremetal/500clear-screen.mu b/baremetal/500clear-screen.mu new file mode 100644 index 00000000..0dbcdee2 --- /dev/null +++ b/baremetal/500clear-screen.mu @@ -0,0 +1,17 @@ +fn clear-screen screen: (addr screen) { + var y/eax: int <- copy 0 + { + compare y, 0x300 # 768 + break-if->= + var x/edx: int <- copy 0 + { + compare x, 0x400 # 1024 + break-if->= + pixel 0, x, y, 0 # black + x <- increment + loop + } + y <- increment + loop + } +} diff --git a/baremetal/502test.mu b/baremetal/502test.mu new file mode 100644 index 00000000..94063a70 --- /dev/null +++ b/baremetal/502test.mu @@ -0,0 +1,18 @@ +# print msg to screen if a != b, otherwise print "." +fn check-ints-equal _a: int, b: int, msg: (addr array byte) { + var a/eax: int <- copy _a + compare a, b + { + break-if-= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, msg, 3 # 3=cyan + count-test-failure + } + { + break-if-!= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ".", 3 # 3=cyan + } +} + +fn test-check-ints-equal { + check-ints-equal 0, 0, "abc" +} diff --git a/baremetal/README.md b/baremetal/README.md index 96e7c900..dcc78e71 100644 --- a/baremetal/README.md +++ b/baremetal/README.md @@ -30,8 +30,11 @@ operating systems. There's also currently no code/data segment separation, just labels and bytes. I promise not to write self-modifying code. Security and sandboxing is still an open question. -Most programs here assume `main` starts at address 0x9000 (7KB or 14 disk -sectors past the BIOS entrypoint). See baremetal/boot.hex for details. +Programs start executing at address 0x9000. See baremetal/boot.hex for +details. + +Mu programs always run all their automated tests first. `main` only runs if +there are no failing tests. See baremetal/mu-init.subx for details. So far the programs have only been tested in Qemu and Bochs emulators. diff --git a/baremetal/mu-init.subx b/baremetal/mu-init.subx index 232b3b49..77e62ede 100644 --- a/baremetal/mu-init.subx +++ b/baremetal/mu-init.subx @@ -9,7 +9,17 @@ # initialize stack bd/copy-to-ebp 0/imm32 # no heap yet -(main) +# +# always first run tests +(run-tests) +(num-test-failures) # => eax +# call main if tests all passed +{ + 3d/compare-eax-and 0/imm32 + 75/jump-if-!= break/disp8 + (clear-screen) + (main) +} # hang indefinitely { |