xen32os/xenrom/text.asm
2024-02-07 23:23:47 +01:00

204 lines
3.8 KiB
NASM

font_table: #include_bin "data/font_table.dat"
font_data: #include_bin "data/font_data.dat"
; defines FONT_SIZE and FONT_LINE_HEIGHT
#include "data/font_data.inc"
; input:
; r0: pointer to frame buffer
; r1: frame buffer width
; r2: pointer to string to draw
; r3: x coordinate to draw at
; r4: y coordinate to draw at
; r5: text box left
; r6: text box right
; r7: text box bottom
; r30: text delay (ms, blocking)
; r31: text color
; returns:
; r0, r1, r5, r6, r7, r30, r31 kept
; r2: pointer to last char drawn
; r3: x coordinate to next char to draw
; r4: y coordinate to next char to draw
draw_str_at:
; store char pointer in r8
mov r8, r2
draw_str_at_loop:
cmp r30, 0
ifnz call font_sleep
; r2: current char
movz.8 r2, [r8]
cmp r2, 0 ; check for null terminator
ifz jmp draw_str_at_loop_end
; check for newline
cmp r2, 10
ifz jmp draw_str_at_newline
; r9: char entry
mov r9, r2
mul r9, 7
add r9, font_table
; r10: width, r11: end x
movz.8 r10, [r9]
mov r11, r3
add r11, r10
; are we after the edge?
cmp r11, r6
iflt jmp draw_str_at_loop_draw
; if we have a space, don't reset
cmp r2, 32
ifz jmp draw_str_at_loop_draw
draw_str_at_linebreak:
mov r3, r5 ; reset x
; update end x
mov r11, r5
add r11, r10
; step to next line, check if we've overrun the box
add r4, FONT_LINE_HEIGHT
cmp r4, r7
ifgteq jmp draw_str_at_loop_end
draw_str_at_loop_draw:
push r0
push r1
push r2
push r3
push r4
call draw_char_at
pop r4
pop r3
pop r2
pop r1
pop r0
draw_str_at_spaceskip:
inc r8 ; update string index
mov r3, r11 ; update x coordinate
add r3, FONT_SIZE ; padding
jmp draw_str_at_loop
draw_str_at_newline:
inc r8 ; update string index
mov r3, r5 ; reset x
; step to next line, check if we've overrur the box
add r4, FONT_LINE_HEIGHT
cmp r4, r7
ifgteq jmp draw_str_at_loop_end
jmp draw_str_at_loop
draw_str_at_loop_end:
; restore char pointer into r2
mov r2, r8
ret
; input:
; r0: pointer to frame buffer
; r1: frame buffer width
; r2: char to draw
; r3: x coordinate to draw at
; r4: y coordinate to draw at
; r31: color
; returns:
; nothing
draw_char_at:
push r5
push r6
push r7
push r8
push r9
; r5: width
; r7: baseline
; r8: char data pointer
; r9: number of pixels to draw
mul r2, 7 ; size of char
add r2, font_table
movz.8 r5, [r2]
inc r2
movz.8 r9, [r2]
mul r9, r5
inc r2
movz.8 r7, [r2]
inc r2
mov r8, [r2]
add r8, font_data
; adjust y for baseline
sub r4, r7
; calculate init framebuffer address into r4
mul r4, r1
add r4, r3
mul r4, 4
add r4, r0
; r6: x counter in glyph
; r9: countdown
mov r6, 0
draw_char_at_loop:
cmp r9, 0 ; zero terminator
ifz jmp draw_char_at_loop_done
cmp.8 [r8], 0
ifnz mov [r4], r31
inc r8 ; advance glyph data pointer
dec r9 ; lower count
add r4, 4 ; advance screen pointer
inc r6 ; advance x counter
cmp r6, r5 ; are we at the end of the glyph line?
ifnz jmp draw_char_at_loop
; move screen pointer down one (x4 for 4 bytes per pixel)
add r4, r1
add r4, r1
add r4, r1
add r4, r1
sub r4, r5
sub r4, r5
sub r4, r5
sub r4, r5
mov r6, 0
jmp draw_char_at_loop
draw_char_at_loop_done:
pop r9
pop r8
pop r7
pop r6
pop r5
ret
; input
; r30: time to sleep (ms)
font_sleep:
push r0
push r1
; r0: end time
; r1: current time
in r0, 0x8000_0706 ; RTC uptime (ms)
add r0, r30
font_sleep_busyloop:
in r1, 0x8000_0706
cmp r1, r0
iflt jmp font_sleep_busyloop
pop r1
pop r0
ret