diff options
-rw-r--r-- | baremetal/101screen.subx | 56 | ||||
-rw-r--r-- | baremetal/102keyboard.subx | 3 | ||||
-rw-r--r-- | baremetal/103grapheme.subx | 28 | ||||
-rw-r--r-- | baremetal/400.mu | 8 | ||||
-rw-r--r-- | baremetal/500clear-screen.mu | 17 | ||||
-rw-r--r-- | baremetal/500text-screen.mu | 64 | ||||
-rw-r--r-- | baremetal/503manhattan-line.mu | 18 | ||||
-rw-r--r-- | baremetal/ex2.mu | 2 | ||||
-rw-r--r-- | baremetal/ex3.mu | 2 | ||||
-rw-r--r-- | baremetal/ex6.mu | 2 | ||||
-rw-r--r-- | baremetal/mu-init.subx | 2 |
11 files changed, 124 insertions, 78 deletions
diff --git a/baremetal/101screen.subx b/baremetal/101screen.subx index 225efeec..5a26a86a 100644 --- a/baremetal/101screen.subx +++ b/baremetal/101screen.subx @@ -1,44 +1,38 @@ # Primitives for screen control. +# +# We need to do this in machine code because Mu doesn't have global variables +# yet (for the start of video memory). == code -pixel: # screen: (addr screen), x: int, y: int, color: int +pixel-on-real-screen: # x: int, y: int, color: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax 51/push-ecx - # ecx = screen - 8b/-> *(ebp+8) 1/r32/ecx - 81 7/subop/compare %ecx 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) 1/r32/ecx - 88/byte<- *eax 1/r32/CL - # return - eb $pixel:end/disp8 - } - # TODO: fake screen -$pixel:end: + # bounds checks + 8b/-> *(ebp+8) 0/r32/eax + 3d/compare-eax-and 0/imm32 + 7c/jump-if-< $pixel-on-real-screen:end/disp8 + 3d/compare-eax-and 0x400/imm32/1024 + 7d/jump-if->= $pixel-on-real-screen:end/disp8 + 8b/-> *(ebp+0xc) 0/r32/eax + 3d/compare-eax-and 0/imm32 + 7c/jump-if-< $pixel-on-real-screen:end/disp8 + 3d/compare-eax-and 0x300/imm32/768 + 7d/jump-if->= $pixel-on-real-screen:end/disp8 + # eax = y*1024 + x + 8b/-> *(ebp+0xc) 0/r32/eax + c1/shift 4/subop/left %eax 0xa/imm8 + 03/add-> *(ebp+8) 0/r32/eax + # eax += location of frame buffer + 03/add-> *0x7f28 0/r32/eax # unsafe + # *eax = color + 8b/-> *(ebp+0x10) 1/r32/ecx + 88/byte<- *eax 1/r32/CL +$pixel-on-real-screen:end: # . restore registers 59/pop-to-ecx 58/pop-to-eax diff --git a/baremetal/102keyboard.subx b/baremetal/102keyboard.subx index b047a7c2..f2c22339 100644 --- a/baremetal/102keyboard.subx +++ b/baremetal/102keyboard.subx @@ -1,5 +1,8 @@ # check keyboard for a key # return 0 on no keypress or unrecognized key +# +# We need to do this in machine code because Mu doesn't have global variables +# yet (for the keyboard buffer). == code diff --git a/baremetal/103grapheme.subx b/baremetal/103grapheme.subx index 9b19884f..4ee423d7 100644 --- a/baremetal/103grapheme.subx +++ b/baremetal/103grapheme.subx @@ -1,8 +1,11 @@ -# Use the built-in font to draw a grapheme to screen. +# Use the built-in font to draw a grapheme to real screen. +# +# We need to do this in machine code because Mu doesn't have global variables +# yet (for the start of video memory). == code -draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int +draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -12,28 +15,27 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int 52/push-edx 53/push-ebx 56/push-esi - # TODO: support fake screen; we currently assume 'screen' is always 0 (real) # var letter-bitmap/esi = font[g] - 8b/-> *(ebp+0xc) 6/r32/esi + 8b/-> *(ebp+8) 6/r32/esi c1 4/subop/shift-left %esi 4/imm8 8d/copy-address *(esi+0x8800) 6/r32/esi # font-start # if (letter-bitmap >= 0x9000) return # characters beyond ASCII currently not supported 81 7/subop/compare %esi 0x9000/imm32 7d/jump-if->= $draw-grapheme:end/disp8 # edx = y - 8b/-> *(ebp+0x14) 2/r32/edx + 8b/-> *(ebp+0x10) 2/r32/edx # var ymax/ebx: int = y + 16 - 8b/-> *(ebp+0x14) 3/r32/ebx + 8b/-> *(ebp+0x10) 3/r32/ebx 81 0/subop/add %ebx 0x10/imm32 { # if (y >= ymax) break 39/compare %edx 3/r32/ebx 7d/jump-if->= break/disp8 # eax = x + 7 - 8b/-> *(ebp+0x10) 0/r32/eax + 8b/-> *(ebp+0xc) 0/r32/eax 81 0/subop/add %eax 7/imm32 # var xmin/ecx: int = x - 8b/-> *(ebp+0x10) 1/r32/ecx + 8b/-> *(ebp+0xc) 1/r32/ecx # var row-bitmap/ebx: int = *letter-bitmap 53/push-ebx 8b/-> *esi 3/r32/ebx @@ -46,7 +48,7 @@ draw-grapheme: # screen: (addr screen), g: grapheme, x: int, y: int, color: int # if LSB, draw a pixel { 73/jump-if-not-CF break/disp8 - (pixel *(ebp+8) %eax %edx *(ebp+0x18)) + (pixel-on-real-screen %eax %edx *(ebp+0x14)) } # --x 48/decrement-eax @@ -74,7 +76,7 @@ $draw-grapheme:end: 5d/pop-to-ebp c3/return -cursor-position: # screen: (addr screen) -> _/eax: int, _/ecx: int +cursor-position-on-real-screen: # -> _/eax: int, _/ecx: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -87,16 +89,16 @@ $cursor-position:end: 5d/pop-to-ebp c3/return -set-cursor-position: # screen: (addr screen), x: int, y: int +set-cursor-position-on-real-screen: # x: int, y: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax # TODO: support fake screen; we currently assume 'screen' is always 0 (real) - 8b/-> *(ebp+0xc) 0/r32/eax + 8b/-> *(ebp+8) 0/r32/eax 89/<- *Default-next-x 0/r32/eax - 8b/-> *(ebp+0x10) 0/r32/eax + 8b/-> *(ebp+0xc) 0/r32/eax 89/<- *Default-next-y 0/r32/eax $set-cursor-position:end: # . restore registers diff --git a/baremetal/400.mu b/baremetal/400.mu index ff84a643..5025a51c 100644 --- a/baremetal/400.mu +++ b/baremetal/400.mu @@ -1,8 +1,8 @@ # screen -sig pixel screen: (addr screen), x: int, y: int, color: int -sig draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int -sig cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int -sig set-cursor-position screen: (addr screen), x: int, y: int +sig pixel-on-real-screen x: int, y: int, color: int +sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int +sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int +sig set-cursor-position-on-real-screen x: int, y: int # keyboard sig read-key kbd: (addr keyboard) -> _/eax: byte diff --git a/baremetal/500clear-screen.mu b/baremetal/500clear-screen.mu deleted file mode 100644 index 0dbcdee2..00000000 --- a/baremetal/500clear-screen.mu +++ /dev/null @@ -1,17 +0,0 @@ -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/500text-screen.mu b/baremetal/500text-screen.mu new file mode 100644 index 00000000..525ddb03 --- /dev/null +++ b/baremetal/500text-screen.mu @@ -0,0 +1,64 @@ +# Screen primitives for character-oriented output. +# +# Unlike the top-level, this text mode has no scrolling. + +fn draw-grapheme screen: (addr screen), g: grapheme, x: int, y: int, color: int { + { + compare screen, 0 + break-if-!= + draw-grapheme-on-real-screen g, x, y, color + return + } + # TODO: fake screen +} + +fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int { + { + compare screen, 0 + break-if-!= + var x/eax: int <- copy 0 + var y/ecx: int <- copy 0 + x, y <- cursor-position-on-real-screen + return x, y + } + # TODO: fake screen + return 0, 0 +} + +fn set-cursor-position screen: (addr screen), x: int, y: int { + { + compare screen, 0 + break-if-!= + set-cursor-position-on-real-screen x, y + return + } + # TODO: fake screen +} + +fn clear-screen screen: (addr screen) { + { + compare screen, 0 + break-if-!= + clear-real-screen + return + } + # TODO: fake screen +} + +fn clear-real-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-on-real-screen x, y, 0 # black + x <- increment + loop + } + y <- increment + loop + } +} diff --git a/baremetal/503manhattan-line.mu b/baremetal/503manhattan-line.mu index 0351fcb6..5c51473d 100644 --- a/baremetal/503manhattan-line.mu +++ b/baremetal/503manhattan-line.mu @@ -1,27 +1,27 @@ -fn draw-box screen: (addr screen), x1: int, y1: int, x2: int, y2: int, color: int { - draw-horizontal-line screen, x1, x2, y1, color - draw-vertical-line screen, x1, y1, y2, color - draw-horizontal-line screen, x1, x2, y2, color - draw-vertical-line screen, x2, y1, y2, color +fn draw-box-on-real-screen x1: int, y1: int, x2: int, y2: int, color: int { + draw-horizontal-line-on-real-screen x1, x2, y1, color + draw-vertical-line-on-real-screen x1, y1, y2, color + draw-horizontal-line-on-real-screen x1, x2, y2, color + draw-vertical-line-on-real-screen x2, y1, y2, color } -fn draw-horizontal-line screen: (addr screen), x1: int, x2: int, y: int, color: int { +fn draw-horizontal-line-on-real-screen x1: int, x2: int, y: int, color: int { var x/eax: int <- copy x1 { compare x, x2 break-if->= - pixel screen, x, y, color + pixel-on-real-screen x, y, color x <- increment loop } } -fn draw-vertical-line screen: (addr screen), x: int, y1: int, y2: int, color: int { +fn draw-vertical-line-on-real-screen x: int, y1: int, y2: int, color: int { var y/eax: int <- copy y1 { compare y, y2 break-if->= - pixel screen, x, y, color + pixel-on-real-screen x, y, color y <- increment loop } diff --git a/baremetal/ex2.mu b/baremetal/ex2.mu index b386fe5b..d7a5e0c4 100644 --- a/baremetal/ex2.mu +++ b/baremetal/ex2.mu @@ -21,7 +21,7 @@ fn main { break-if->= var color/ecx: int <- copy x color <- and 0xff - pixel 0, x, y, color + pixel-on-real-screen x, y, color x <- increment loop } diff --git a/baremetal/ex3.mu b/baremetal/ex3.mu index 21e30466..206e22b3 100644 --- a/baremetal/ex3.mu +++ b/baremetal/ex3.mu @@ -18,7 +18,7 @@ fn main { var key/eax: byte <- read-key 0 # real keyboard compare key, 0 loop-if-= # busy wait - pixel 0, x, y, 0x31 # green + pixel-on-real-screen x, y, 0x31 # green x <- increment compare x, 0x400 { diff --git a/baremetal/ex6.mu b/baremetal/ex6.mu index 5e47a57c..72d21f2e 100644 --- a/baremetal/ex6.mu +++ b/baremetal/ex6.mu @@ -11,7 +11,7 @@ fn main { # drawing text within a bounding box - draw-box 0, 0xf, 0x1f, 0x79, 0x51, 0x4 + draw-box-on-real-screen 0xf, 0x1f, 0x79, 0x51, 0x4 var x/eax: int <- copy 0x20 var y/ecx: int <- copy 0x20 x, y <- draw-text-wrapping-right-then-down 0, "hello ", 0x10, 0x20, 0x78, 0x50, x, y, 0xa # (0x10, 0x20) -> (0x78, 0x50) diff --git a/baremetal/mu-init.subx b/baremetal/mu-init.subx index 77e62ede..a1aa4e99 100644 --- a/baremetal/mu-init.subx +++ b/baremetal/mu-init.subx @@ -17,7 +17,7 @@ bd/copy-to-ebp 0/imm32 { 3d/compare-eax-and 0/imm32 75/jump-if-!= break/disp8 - (clear-screen) + (clear-real-screen) (main) } |