diff options
Diffstat (limited to '103grapheme.subx')
-rw-r--r-- | 103grapheme.subx | 103 |
1 files changed, 90 insertions, 13 deletions
diff --git a/103grapheme.subx b/103grapheme.subx index fa3b17d4..67e34ca1 100644 --- a/103grapheme.subx +++ b/103grapheme.subx @@ -10,24 +10,23 @@ # Therefore 'x' here is in [0, 128), and 'y' is in [0, 48) # Doesn't update the cursor; where the cursor should go after printing the # current grapheme is a higher-level concern. -draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int, background-color: int +draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # - (draw-grapheme-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30) + (draw-grapheme-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30) # => eax $draw-grapheme-on-real-screen:end: # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return -draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int +draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers - 50/push-eax 51/push-ecx 52/push-edx # if screen-width*screen-height > len(screen-data) abort @@ -49,12 +48,11 @@ draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x 8b/-> *(ebp+8) 0/r32/eax 05/add-to-eax 4/imm32 # - (draw-grapheme-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) + (draw-grapheme-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) # => eax $draw-grapheme-on-screen-array:end: # . restore registers 5a/pop-to-edx 59/pop-to-ecx - 58/pop-to-eax # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp @@ -67,15 +65,12 @@ $draw-grapheme-on-screen-array:abort: (abort "draw-grapheme-on-screen-array: coordinates are off the screen. Are the screen dimensions correct?") # 'buffer' here is not a valid Mu type: a naked address without a length. -draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int +# returns number of 8x16 units printed to screen (1 or 2). +draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers - 50/push-eax - 51/push-ecx - 52/push-edx - 53/push-ebx 56/push-esi # switch screen-width and screen-height from grapheme to pixel units c1 4/subop/shift-left *(ebp+20) 3/imm8/log2-font-width @@ -88,7 +83,64 @@ draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: # var letter-bitmap/esi = font[g] 69/multiply %esi 0x21/imm32/glyph-size 6/r32/esi 81 0/subop/add %esi Font/imm32 + # dispatch based on letter-bitmap->size + b8/copy-to-eax 0/imm32 + 8a/byte-> *esi 0/r32/AL 46/increment-esi # skip size + 3d/compare-eax-and 8/imm32 + { + 75/jump-if-!= break/disp8 + (draw-narrow-grapheme-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) + b8/copy-to-eax 1/imm32 + eb/jump $draw-grapheme-on-screen-buffer:end/disp8 + } + (draw-wide-grapheme-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) + b8/copy-to-eax 2/imm32 +$draw-grapheme-on-screen-buffer:end: + # . restore registers + 5e/pop-to-esi + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +wide-grapheme?: # g: grapheme -> _/eax: boolean + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # eax = g + 8b/-> *(ebp+8) 0/r32/eax + # if (g >= 128) return # characters beyond ASCII currently not supported + 3d/compare-eax-and 0x80/imm32 + 0f 8d/jump-if->= $wide-grapheme?:end/disp32 + # var letter-bitmap/eax = font[g] + 69/multiply %eax 0x21/imm32/glyph-size 0/r32/eax + 05/add-to-eax Font/imm32 + # dispatch based on letter-bitmap->size + 8a/byte-> *eax 0/r32/AL + 25/and-eax-with 0xff/imm32 + 3d/compare-eax-and 8/imm32 + 0f 95/set-if-!= %eax +$wide-grapheme?:end: + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +# buffer: naked address to raw screen RAM without a length +# letter-bitmap: naked address to 8-pixel wide font glyph +draw-narrow-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + 53/push-ebx + 56/push-esi + # esi = letter-bitmap + 8b/-> *(ebp+0xc) 6/r32/esi # var ycurr/edx: int = y*16 8b/-> *(ebp+0x14) 2/r32/edx c1 4/subop/shift-left %edx 4/imm8 @@ -139,7 +191,32 @@ $draw-grapheme-on-screen-buffer:continue: # e9/jump loop/disp32 } -$draw-grapheme-on-screen-buffer:end: +$draw-narrow-grapheme-on-screen-buffer:end: + # . restore registers + 5e/pop-to-esi + 5b/pop-to-ebx + 5a/pop-to-edx + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +# buffer: naked address to raw screen RAM without a length +# letter-bitmap: naked address to 16-pixel wide font glyph +draw-wide-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + 53/push-ebx + 56/push-esi + # HERE +$draw-wide-grapheme-on-screen-buffer:end: # . restore registers 5e/pop-to-esi 5b/pop-to-ebx @@ -198,7 +275,7 @@ draw-cursor-on-real-screen: # g: grapheme 51/push-ecx # (cursor-position-on-real-screen) # => eax, ecx - (draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7) + (draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7) # => eax $draw-cursor-on-real-screen:end: # . restore registers 59/pop-to-ecx |