diff --git a/baremetal/501draw-text.mu b/baremetal/501draw-text.mu index 5ddb4bf5..fa284d68 100644 --- a/baremetal/501draw-text.mu +++ b/baremetal/501draw-text.mu @@ -1,3 +1,64 @@ +# some primitives for moving the cursor without making assumptions about +# raster order +fn cursor-left screen: (addr screen) { + var cursor-x/eax: int <- copy 0 + var cursor-y/ecx: int <- copy 0 + cursor-x, cursor-y <- cursor-position screen + compare cursor-x, 0 + { + break-if-> + return + } + cursor-x <- subtract 8 # font-width + set-cursor-position screen, cursor-x, cursor-y +} + +fn cursor-right screen: (addr screen) { + var cursor-x/eax: int <- copy 0 + var cursor-y/ecx: int <- copy 0 + cursor-x, cursor-y <- cursor-position screen + compare cursor-x, 0x400 # screen-width + { + break-if-< + return + } + cursor-x <- add 8 # font-width + set-cursor-position screen, cursor-x, cursor-y +} + +fn cursor-up screen: (addr screen) { + var cursor-x/eax: int <- copy 0 + var cursor-y/ecx: int <- copy 0 + cursor-x, cursor-y <- cursor-position screen + compare cursor-y, 0 + { + break-if-> + return + } + cursor-y <- subtract 0x10 # screen-height + set-cursor-position screen, cursor-x, cursor-y +} + +fn cursor-down screen: (addr screen) { + var cursor-x/eax: int <- copy 0 + var cursor-y/ecx: int <- copy 0 + cursor-x, cursor-y <- cursor-position screen + compare cursor-y, 0x300 # screen-height + { + break-if-< + return + } + cursor-y <- add 0x10 # screen-height + set-cursor-position screen, cursor-x, cursor-y +} + +fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int { + var cursor-x/eax: int <- copy 0 + var cursor-y/ecx: int <- copy 0 + cursor-x, cursor-y <- cursor-position screen + draw-grapheme screen, g, cursor-x, cursor-y, color +} + # draw a single line of text from x, y to xmax # return the next 'x' coordinate # if there isn't enough space, return 0 without modifying the screen diff --git a/baremetal/ex7.mu b/baremetal/ex7.mu new file mode 100644 index 00000000..6beac7aa --- /dev/null +++ b/baremetal/ex7.mu @@ -0,0 +1,46 @@ +# Cursor-based motions. +# +# To build a disk image: +# ./translate_mu_baremetal baremetal/ex7.mu # emits disk.img +# To run: +# qemu-system-i386 disk.img +# Or: +# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img +# +# Expected output: an interactive game a bit like "snakes". Try pressing h, j, +# k, l. + +fn main { + { + var key/eax: byte <- read-key 0 + { + compare key, 0x68 # 'h' + break-if-!= + var g/eax: grapheme <- copy 0x2d # '-' + draw-grapheme-at-cursor 0, g, 0x31 + cursor-left 0 + } + { + compare key, 0x6a # 'j' + break-if-!= + var g/eax: grapheme <- copy 0x7c # '|' + draw-grapheme-at-cursor 0, g, 0x31 + cursor-down 0 + } + { + compare key, 0x6b # 'k' + break-if-!= + var g/eax: grapheme <- copy 0x7c # '|' + draw-grapheme-at-cursor 0, g, 0x31 + cursor-up 0 + } + { + compare key, 0x6c # 'l' + break-if-!= + var g/eax: grapheme <- copy 0x2d # '-' + draw-grapheme-at-cursor 0, g, 0x31 + cursor-right 0 + } + loop + } +}