WIP: Graphics screen and graphics_32/draw_line #23
Executable → Regular
Executable → Regular
+1
@@ -28,3 +28,4 @@ pub const FB_BYTES_PER_PIXEL = 0x2a ; U8 Specialisations should hardcode t
|
|||||||
; * 0 => 8 bits per pixel
|
; * 0 => 8 bits per pixel
|
||||||
; * 2 => 32 bits per pixel
|
; * 2 => 32 bits per pixel
|
||||||
pub const FB_LOG_BPP = 0x2b ; U8 Specialisations should hardcode this
|
pub const FB_LOG_BPP = 0x2b ; U8 Specialisations should hardcode this
|
||||||
|
pub const FB_MODE = 0x2c ; U8 Screen mode: 0 => text; 1 => graphics
|
||||||
|
|||||||
@@ -0,0 +1,444 @@
|
|||||||
|
; 32 bit graphics library for Symphony
|
||||||
|
;
|
||||||
|
; Screen MUST be initialsed by calling `screen.set_graphics_mode`.
|
||||||
|
|
||||||
|
include globals
|
||||||
|
include errno
|
||||||
|
|
||||||
|
pub draw_pixel_safe:
|
||||||
|
; bool draw_pixel_safe(u32 color, u16 x, u16 y)
|
||||||
|
; Checks if the position is valid for the current mode. If not the FB
|
||||||
|
; is not touched and returns -1, otherwise the pixel is drawn on the
|
||||||
|
; current draw framebuffer.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X coord PRESERVED
|
||||||
|
; - r3: Y coord PRESERVED
|
||||||
|
; Returns:
|
||||||
|
; - flags: Status code
|
||||||
|
; Errors: Was the draw sucessful?
|
||||||
|
; - SCREEN_OUTSIDE_FB: if (X,Y) not on screen
|
||||||
|
; Clobbers:
|
||||||
|
; - r6: scratch
|
||||||
|
|
||||||
|
mov r6, 1
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r5, r6, flags
|
||||||
|
cmp r2, r5
|
||||||
|
jb draw_pixel_safe_X_ok
|
||||||
|
mov flags, errno.SCREEN_OUTSIDE_FB
|
||||||
|
jmp r13 ; return
|
||||||
|
draw_pixel_safe_X_ok:
|
||||||
|
mov r6, 1
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r6, r6, flags
|
||||||
|
lsr flags, r6, 1
|
||||||
|
lsr r6, r6, 2 ; (LOG_BPP)
|
||||||
|
add r6, flags, r6
|
||||||
|
cmp r3, r6
|
||||||
|
jb draw_pixel_safe_Y_ok
|
||||||
|
mov flags, errno.SCREEN_OUTSIDE_FB
|
||||||
|
jmp r13 ; return
|
||||||
|
draw_pixel_safe_Y_ok:
|
||||||
|
; Fall through
|
||||||
|
|
||||||
|
pub draw_pixel:
|
||||||
|
; void draw_pixel(u32 color, u16 x, u16 y)
|
||||||
|
; Draw pixel at the position, no checks on position, can potentally write to any memory.
|
||||||
|
; Framebuffer pointer is stored in FB_PTR.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1 Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2 X coord PRESERVED
|
||||||
|
; - r3 Y coord PRESERVED
|
||||||
|
; Result:
|
||||||
|
; - flags: errno.OK
|
||||||
|
; Cobbers:
|
||||||
|
; - r6: Pixel address
|
||||||
|
; Globals read:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_LOG_WIDTH
|
||||||
|
|
||||||
|
; Screen is `1 << WIDTH pixels wide
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
; Compute pixel address
|
||||||
|
lsl flags, r3, flags ; Y * width
|
||||||
|
add flags, flags, r2 ; Y * width + X
|
||||||
|
lsl flags, flags, 2 ; pixel to address
|
||||||
|
load_32 r6, [globals.FB_DRAW_PTR]
|
||||||
|
add flags, flags, r6 ; += frambuffer_ptr
|
||||||
|
; Set pixel value
|
||||||
|
store_32 [flags], r1
|
||||||
|
mov flags, errno.OK ; return OK for draw_pixel_safe
|
||||||
|
jmp r13 ; return
|
||||||
|
|
||||||
|
|
||||||
|
pub draw_line_h:
|
||||||
|
; void draw_line_h(u32 color, u16 x0, u16 y, u16 x1)
|
||||||
|
; Draws a straight horizontal line from (x0, y) to (x1, y) (inclusive) using `color`
|
||||||
|
; on to the current `FB_DRAW_PTR` buffer.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X0 coord
|
||||||
|
; - r3: Y coord PRESERVED
|
||||||
|
; - r4: X1 coord
|
||||||
|
; Returns:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X1 coord
|
||||||
|
; - r3: Y coord PRESERVED
|
||||||
|
; Clobbers:
|
||||||
|
; - r5: pixel ptr
|
||||||
|
; - r6: FB end
|
||||||
|
; - r7: FB increment
|
||||||
|
; - flags
|
||||||
|
; Globals read:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - LOG_WIDTH
|
||||||
|
|
||||||
|
push r13
|
||||||
|
|
||||||
|
; if start.x > end.x
|
||||||
|
; dx = -4 = -1 * bytes_per_pixel
|
||||||
|
; else
|
||||||
|
; dx = +4 = +1 * bytes_per_pixel
|
||||||
|
; endif
|
||||||
|
cmp r4, r2 ; ...00???
|
||||||
|
and r7, flags, 0x04 ; ...00??0
|
||||||
|
or r7, flags, 0x02 ; ...00?10
|
||||||
|
lsl r7, r7, 29 ; ?100...
|
||||||
|
asr r7, r7, 28 ; +/- 4 (Hardcode LOG_BPP)
|
||||||
|
|
||||||
|
mov r5, r3 ; Y1 = Y0 = Y
|
||||||
|
; Fall through
|
||||||
|
|
||||||
|
draw_line_basic:
|
||||||
|
; void draw_line_h(u32 color, u16 x0, u16 y0, u16 x1, u16 y1, _, u32 incr)
|
||||||
|
; Draws a straight line at any multiple of 45° from (x0, y0) to (x1, y1) (inclusive) using `color`
|
||||||
|
; on to the current `FB_DRAW_PTR` buffer.
|
||||||
|
; `r7` contains a precomputed increment to the FB pointer.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X0 coord
|
||||||
|
; - r3: Y0 coord
|
||||||
|
; - r4: X1 coord
|
||||||
|
; - r5: Y1 coord
|
||||||
|
; - r6: ignored, non-standard calling convetion for internal function
|
||||||
|
; - r7: FB pointer increment
|
||||||
|
; Returns:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X1 coord
|
||||||
|
; - r3: Y1 coord
|
||||||
|
; Clobbers:
|
||||||
|
; - r5: last pixel address
|
||||||
|
; - r6: first pixel address/ptr
|
||||||
|
; - r7: FB increment
|
||||||
|
; - flags
|
||||||
|
; Globals read:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_LOG_WIDTH
|
||||||
|
|
||||||
|
; Compute start and end pixel addresses
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r6, r3, flags ; start.y * width
|
||||||
|
add r6, r6, r2 ; start.y * width + start.x
|
||||||
|
mov r2, r4 ; return end.x
|
||||||
|
mov r3, r5 ; return end.y
|
||||||
|
lsl r5, r5, flags ; end.y * width
|
||||||
|
add r5, r5, r2 ; end.y * width + end.x
|
||||||
|
lsl r6, r6, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
lsl r5, r5, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
load_32 flags, [globals.FB_DRAW_PTR]
|
||||||
|
add r6, r6, flags ; pixel_ptr += frambuffer_ptr
|
||||||
|
add r5, r5, flags ; end_ptr += frambuffer_ptr
|
||||||
|
|
||||||
|
jmp draw_line_h_loop_in
|
||||||
|
draw_line_h_loop:
|
||||||
|
add r6, r6, r7
|
||||||
|
draw_line_h_loop_in:
|
||||||
|
; Set pixel value
|
||||||
|
store_32 [r6], r1
|
||||||
|
|
||||||
|
cmp r5, r6
|
||||||
|
jne draw_line_h_loop
|
||||||
|
|
||||||
|
jmp r13 ; return
|
||||||
|
|
||||||
|
|
||||||
|
pub draw_line_v:
|
||||||
|
; void draw_line_v(u32 color, u16 x, u16 _, u16 y0, u16 x1)
|
||||||
|
; Draws a straight verticle line from (x, y0) to (x, y1) (inclusive) using `color`
|
||||||
|
; on to the current `FB_DRAW_PTR` buffer.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X coord PRESERVED
|
||||||
|
; - r3: Y0 coord
|
||||||
|
; - r4: ignored
|
||||||
|
; - r5: Y1 coord
|
||||||
|
|
||||||
|
; Returns:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X coord PRESERVED
|
||||||
|
; - r3: Y1 coord
|
||||||
|
; Clobbers:
|
||||||
|
; - r5: draw_line_basic
|
||||||
|
; - r6: draw_line_basic
|
||||||
|
; - r7: increment
|
||||||
|
; - flags
|
||||||
|
; Globls read:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_LOG_WIDTH
|
||||||
|
|
||||||
|
push r13
|
||||||
|
|
||||||
|
; if start.x > end.x
|
||||||
|
; dx = -4 = -1 * bytes_per_pixel
|
||||||
|
; else
|
||||||
|
; dx = +4 = +1 * bytes_per_pixel
|
||||||
|
; endif
|
||||||
|
cmp r5, r3 ; ...00???
|
||||||
|
and r7, flags, 0x04 ; ...00??0
|
||||||
|
or r7, flags, 0x02 ; ...00?10
|
||||||
|
lsl r7, r7, 29 ; ?100...
|
||||||
|
asr r7, r7, 28 ; +/- 4 (Hardcode LOG_BPP)
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r7, r7, flags ; +/- 4 * width
|
||||||
|
|
||||||
|
mov r4, r2 ; X1 = X0 = X
|
||||||
|
jmp draw_line_basic ; tail call
|
||||||
|
|
||||||
|
|
||||||
|
pub draw_line:
|
||||||
|
; void draw_line(u32 color, u16 x0, u16 y0, u16 x1, u16 y1)
|
||||||
|
; Draws a straight line from (x0, y0) to (x1, y1) (inclusive) using `color`
|
||||||
|
; on to the current `FB_DRAW_PTR` buffer.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X0 coord
|
||||||
|
; - r3: Y0 coord
|
||||||
|
; - r4: X1 coord
|
||||||
|
; - r5: Y1 coord
|
||||||
|
; Returns:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED
|
||||||
|
; - r2: X1 coord
|
||||||
|
; - r3: Y1 coord
|
||||||
|
; Clobbers:
|
||||||
|
; - r4-r7, flags
|
||||||
|
; - r5: draw_pixel
|
||||||
|
; - r6: draw_pixel
|
||||||
|
; Globals read:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_DRAW_STRIDE
|
||||||
|
; - ...others I expect
|
||||||
|
|
||||||
|
; push r13 ; lr
|
||||||
|
; push r12 ; err
|
||||||
|
; push r11 ; sy
|
||||||
|
; push r10 ; dy
|
||||||
|
; push r9 ; sx
|
||||||
|
; push r8 ; dx
|
||||||
|
; - r7: err2
|
||||||
|
|
||||||
|
; Stack () ; empty
|
||||||
|
|
||||||
|
; int dx = abs(x1-x0), sx = x0<x1 ? 4 : -4;
|
||||||
|
cmp r2, r4
|
||||||
|
ja draw_line__move_left
|
||||||
|
jb draw_line__move_right
|
||||||
|
; if x0 == x1
|
||||||
|
jmp draw_line_v ; tail call
|
||||||
|
; elif x0 < x1
|
||||||
|
draw_line__move_right:
|
||||||
|
push r8 ; dx
|
||||||
|
push r9 ; sx
|
||||||
|
sub r8, r4, r2
|
||||||
|
mov r9, 4 ; sx = 1 * FB_BYTES_PER_PIXEL
|
||||||
|
jmp draw_line__move_right_done
|
||||||
|
; else x0 > x1
|
||||||
|
draw_line__move_left:
|
||||||
|
push r8 ; dx
|
||||||
|
push r9 ; sx
|
||||||
|
sub r8, r2, r4
|
||||||
|
nor r9, zr, 3 ; sx = -1 * FB_BYTES_PER_PIXEL
|
||||||
|
; endif
|
||||||
|
draw_line__move_right_done:
|
||||||
|
|
||||||
|
; Stack (r8 r9)
|
||||||
|
|
||||||
|
; int dy = -abs(y1-y0), sy = y0<y1 ? 4 * width : -4 * width;
|
||||||
|
cmp r3, r5
|
||||||
|
jb draw_line__move_down
|
||||||
|
ja draw_line__move_up
|
||||||
|
; if y0 == y0
|
||||||
|
; Restore r8, r9
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
jmp draw_line_h ; tail call
|
||||||
|
; elif y0 < y1
|
||||||
|
draw_line__move_down:
|
||||||
|
push r10 ; dy
|
||||||
|
push r11 ; sy
|
||||||
|
sub r10, r3, r5
|
||||||
|
mov r11, 4 ; sy = 1 * FB_BYTES_PER_PIXEL
|
||||||
|
jmp draw_line__move_down_done
|
||||||
|
; else y0 > y1
|
||||||
|
draw_line__move_up:
|
||||||
|
push r10 ; dy
|
||||||
|
push r11 ; sy
|
||||||
|
sub r10, r5, r3
|
||||||
|
nor r11, zr, 3 ; sy = -1 * FB_BYTES_PER_PIXEL
|
||||||
|
; endif
|
||||||
|
draw_line__move_down_done:
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r11, r11, flags ; sy = +/- 1 * FB_BYTES_PER_PIXEL * width
|
||||||
|
|
||||||
|
; Stack (r8 r9 r10 r11)
|
||||||
|
|
||||||
|
; Compute start and end pixel addresses
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r6, r3, flags ; start.y * width
|
||||||
|
add r6, r6, r2 ; start.y * width + start.x
|
||||||
|
mov r2, r4 ; return end.x
|
||||||
|
mov r3, r5 ; return end.y
|
||||||
|
lsl r5, r5, flags ; end.y * width
|
||||||
|
add r5, r5, r2 ; end.y * width + end.x
|
||||||
|
lsl r6, r6, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
lsl r5, r5, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
load_32 flags, [globals.FB_DRAW_PTR]
|
||||||
|
add r6, r6, flags ; pixel_ptr += frambuffer_ptr
|
||||||
|
add r5, r5, flags ; end_ptr += frambuffer_ptr
|
||||||
|
|
||||||
|
; Stack (r8 r9 r10 r11)
|
||||||
|
|
||||||
|
push r12 ; err
|
||||||
|
push r13 ; lr
|
||||||
|
|
||||||
|
; Stack (r8 r9 r10 r11 r12 r13)
|
||||||
|
|
||||||
|
; int err = dx+dy /* error value e_xy */
|
||||||
|
add r12, r8, r10
|
||||||
|
; loop while(true)
|
||||||
|
draw_line__loop:
|
||||||
|
|
||||||
|
; Draw pixel
|
||||||
|
store_32 [r6], r1
|
||||||
|
|
||||||
|
; err2 = 2*err;
|
||||||
|
lsl r7, r12, 1
|
||||||
|
; if (err2 >= dy) { /* e_xy+e_x > 0 */
|
||||||
|
cmp r7, r10
|
||||||
|
jl draw_line__loop_skip_x
|
||||||
|
; if (x0 == x1) break;
|
||||||
|
cmp r6, r5
|
||||||
|
je draw_line__loop_done
|
||||||
|
; err += dy
|
||||||
|
add r12, r12, r10
|
||||||
|
; x0 += sx;
|
||||||
|
add r6, r6, r9
|
||||||
|
draw_line__loop_skip_x:
|
||||||
|
|
||||||
|
; if (err2 <= dx) { /* e_xy+e_y < 0 */
|
||||||
|
cmp r7, r8
|
||||||
|
jg draw_line__loop_skip_y
|
||||||
|
; if (y0 == y1) break;
|
||||||
|
cmp r6, r5
|
||||||
|
je draw_line__loop_done
|
||||||
|
; err += dx
|
||||||
|
add r12, r12, r8
|
||||||
|
; y0 += sy
|
||||||
|
add r6, r6, r11
|
||||||
|
draw_line__loop_skip_y:
|
||||||
|
jmp draw_line__loop
|
||||||
|
; endloop
|
||||||
|
draw_line__loop_done:
|
||||||
|
|
||||||
|
; Stack (r8 r9 r10 r11 r12 r13)
|
||||||
|
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
jmp r13 ; return
|
||||||
|
|
||||||
|
|
||||||
|
pub fill_rectangle:
|
||||||
|
; void fill_rectangle(u32 fill color, u16 left, u16 top, u16 right, u16 bottom)
|
||||||
|
; Draws a rectangle from (left,top) to (right,bottom) with the outline in `border_color`.
|
||||||
|
; Fills it with `fill_color`
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Fill color 24 bit RGB0
|
||||||
|
; - r2: Left coord
|
||||||
|
; - r3: Top coord
|
||||||
|
; - r4: Right coord
|
||||||
|
; - r5: Bottom coord
|
||||||
|
; Returns:
|
||||||
|
; - r1: Color 24 bit RGB0 PRESERVED???
|
||||||
|
; - r2: X1 coord
|
||||||
|
; - r3: Y1 coord
|
||||||
|
; Clobbers:
|
||||||
|
; - r4-r7, flags
|
||||||
|
; - r5: draw_pixel
|
||||||
|
; - r6: draw_pixel
|
||||||
|
; Globals read:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_DRAW_STRIDE
|
||||||
|
|
||||||
|
|
||||||
|
push r8 ;
|
||||||
|
push r9 ;
|
||||||
|
push r10 ;
|
||||||
|
|
||||||
|
; Compute start and end pixel addresses of first row
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r7, r5, flags ; bottom * width
|
||||||
|
lsl r5, r3, flags ; top * width
|
||||||
|
add r6, r5, r4 ; top * width + right
|
||||||
|
add r5, r5, r2 ; top * width + left
|
||||||
|
add r7, r7, r4 ; bottom * width + right
|
||||||
|
lsl r6, r6, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
lsl r5, r5, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
lsl r7, r7, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
load_32 flags, [globals.FB_DRAW_PTR]
|
||||||
|
add r7, r7, flags ; bottom_right_ptr += frambuffer_ptr
|
||||||
|
add r6, r6, flags ; row_end_ptr += frambuffer_ptr
|
||||||
|
add r5, r5, flags ; pixel_ptr += frambuffer_ptr
|
||||||
|
|
||||||
|
|
||||||
|
mov r8, 4 ; X increment
|
||||||
|
mov r10, 1
|
||||||
|
load_8 flags, [globals.FB_LOG_WIDTH]
|
||||||
|
lsl r10, r10, flags ; screen width
|
||||||
|
sub r9, r10, r4
|
||||||
|
add r9, r9, r2 ; Y wraparound = screen_width - (right-left)
|
||||||
|
lsl r9, r9, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
lsl r10, r10, 2 ; scale pixel to bytes (LOG_BBP)
|
||||||
|
|
||||||
|
|
||||||
|
jmp fill_rectangle__loop_in
|
||||||
|
; For each row
|
||||||
|
fill_rectangle__loop_y:
|
||||||
|
add r5, r5, r9 ; move to start of next row
|
||||||
|
add r6, r6, r10 ; move end_ptr down 1 row
|
||||||
|
fill_rectangle__loop_in:
|
||||||
|
; Draw pixel
|
||||||
|
store_32 [r5], r1
|
||||||
|
; Fill rest of the row
|
||||||
|
fill_rectangle__loop_x:
|
||||||
|
add r5, r5, r8
|
||||||
|
; Draw pixel
|
||||||
|
store_32 [r5], r1
|
||||||
|
cmp r5, r6
|
||||||
|
jb fill_rectangle__loop_x
|
||||||
|
cmp r5, r7
|
||||||
|
jb fill_rectangle__loop_y
|
||||||
|
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
jmp r13 ; return
|
||||||
+535
@@ -0,0 +1,535 @@
|
|||||||
|
;include stdlib/src/globals
|
||||||
|
;include stdlib/src/errno
|
||||||
|
include globals
|
||||||
|
include errno
|
||||||
|
|
||||||
|
const SCREEN_SETTING_MODE = 0 ; Use zr instead
|
||||||
|
const SCREEN_SETTING_DATA_OFFSET = 1
|
||||||
|
const SCREEN_SETTING_RESOLUTION = 2
|
||||||
|
const SCREEN_SETTING_FOREGROUND_COLOR = 2
|
||||||
|
const SCREEN_SETTING_BACKGROUND_COLOR = 3
|
||||||
|
const SCREEN_SETTING_FONT = 4
|
||||||
|
|
||||||
|
const SCREEN_MODE_TEXT_8 = 0
|
||||||
|
const SCREEN_MODE_TEXT_32 = 1
|
||||||
|
const SCREEN_MODE_GRAPHICS_8 = 2
|
||||||
|
const SCREEN_MODE_GRAPHICS_32 = 3
|
||||||
|
|
||||||
|
pub set_graphics_mode:
|
||||||
|
; u16 set_graphics_mode(void *FB_ptr, size_t FB_size, u8 bit_per_pixel, u16 width, bool clear, bool double_buf)
|
||||||
|
; Sets the screen to graphics mode, the resolution, and colour depth.
|
||||||
|
; Optionally clears the screen.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Pointer to allocated framebuffer
|
||||||
|
; - r2: Size of FB allocation, in bytes
|
||||||
|
; - r3: Bits per pixel: One of `8` or `32`
|
||||||
|
; - r4: Width - height is set to `width / 4 * 3`
|
||||||
|
; - r5: If non-zero, clears the current framebuffer.
|
||||||
|
; - r6: If non-zero, enable double buffering
|
||||||
|
; Returns:
|
||||||
|
; - flags: Error code
|
||||||
|
; Clobbers:
|
||||||
|
; - r7: Screen mode setting
|
||||||
|
; Errors:
|
||||||
|
; - 0 OK
|
||||||
|
; - SCREEN_INVALID_SIZE width invalid
|
||||||
|
; - SCREEN_INVALID_MODE bits_per_pixel invalid
|
||||||
|
; - SCREEN_FB_TOO_SMALL allocation too small
|
||||||
|
; - MAGIC_BAD stdlib magic not present
|
||||||
|
; Globals written:
|
||||||
|
; - FB_DISPLAY_PTR
|
||||||
|
; - FB_DISPLAY_DEPTH
|
||||||
|
; - FB_DISPLAY_STRIDE
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_DRAW_DEPTH
|
||||||
|
; - FB_DRAW_STRIDE
|
||||||
|
; - FB_SIZE_BYTE
|
||||||
|
; - FB_WIDTH_PX
|
||||||
|
; - FB_HEIGHT_PX
|
||||||
|
; - FB_LOG_WIDTH
|
||||||
|
; - FB_LOG_STRIDE
|
||||||
|
; - FB_BYTES_PER_PIXEL
|
||||||
|
; - FB_LOG_BPP
|
||||||
|
; - FB_MODE
|
||||||
|
; Globals read:
|
||||||
|
; - MAGIC_ADDRESS
|
||||||
|
|
||||||
|
push r8 ; LOG Bytes/pixel
|
||||||
|
push r9 ; Log width
|
||||||
|
push r10 ; Height
|
||||||
|
push r11 ; Size of FB in bytes/pixels
|
||||||
|
|
||||||
|
; Check the magic number
|
||||||
|
load_16 flags, [globals.MAGIC_ADDRESS]
|
||||||
|
cmp flags, globals.MAGIC_VALUE
|
||||||
|
je set_graphics_mode__magic_ok
|
||||||
|
mov r6, errno.MAGIC_BAD
|
||||||
|
jmp set_graphics_mode__error
|
||||||
|
set_graphics_mode__magic_ok:
|
||||||
|
|
||||||
|
|
||||||
|
cmp r3, 32
|
||||||
|
jne set_graphics_mode__not_32_bit_mode
|
||||||
|
mov r7, SCREEN_MODE_GRAPHICS_32
|
||||||
|
mov r8, 2
|
||||||
|
jmp set_graphics_mode__mode_ok
|
||||||
|
|
||||||
|
set_graphics_mode__not_32_bit_mode:
|
||||||
|
cmp r3, 8
|
||||||
|
jne set_graphics_mode__invalid_mode
|
||||||
|
mov r7, SCREEN_MODE_GRAPHICS_8
|
||||||
|
mov r8, 0
|
||||||
|
jmp set_graphics_mode__mode_ok
|
||||||
|
|
||||||
|
set_graphics_mode__invalid_mode:
|
||||||
|
mov r6, errno.SCREEN_INVALID_MODE
|
||||||
|
jmp set_graphics_mode__error
|
||||||
|
set_graphics_mode__mode_ok:
|
||||||
|
|
||||||
|
; Width must be between 4 and 1024
|
||||||
|
cmp r4, 1024 ; max width of screen
|
||||||
|
ja set_graphics_mode__width_invalid
|
||||||
|
cmp r4, 4
|
||||||
|
jb set_graphics_mode__width_invalid
|
||||||
|
; Compute log base 2 of width, fail if
|
||||||
|
; width is not a exact power of 2
|
||||||
|
mov r9, 10
|
||||||
|
mov r10, 1024
|
||||||
|
set_graphics_mode__log_width_loop:
|
||||||
|
cmp r4, r10
|
||||||
|
je set_graphics_mode__width_ok
|
||||||
|
lsr r10, r10, 1
|
||||||
|
sub r9, r9, 1
|
||||||
|
cmp r9, 4
|
||||||
|
jae set_graphics_mode__log_width_loop
|
||||||
|
set_graphics_mode__width_invalid:
|
||||||
|
mov r6, errno.SCREEN_INVALID_WIDTH
|
||||||
|
jmp set_graphics_mode__error
|
||||||
|
set_graphics_mode__width_ok:
|
||||||
|
; Now r9 = log width
|
||||||
|
|
||||||
|
|
||||||
|
; height = width/4 * 3
|
||||||
|
lsr r4, r4, 2
|
||||||
|
lsl r10, r4, 1
|
||||||
|
add r10, r10, r4 ; height
|
||||||
|
|
||||||
|
; Compute size of FB
|
||||||
|
lsl r11, r10, r9 ; Size of FB in pixels
|
||||||
|
lsl r11, r11, r8 ; Size of FB in bytes
|
||||||
|
; If double buffering..
|
||||||
|
cmp r6, 0
|
||||||
|
je set_graphics_mode__single_buff
|
||||||
|
; ..we need twice the space
|
||||||
|
lsl r11, r11, 1
|
||||||
|
set_graphics_mode__single_buff:
|
||||||
|
cmp r2, r11
|
||||||
|
jae set_graphics_mode__size_ok
|
||||||
|
mov r6, errno.SCREEN_FB_TOO_SMALL
|
||||||
|
jmp set_graphics_mode__error
|
||||||
|
set_graphics_mode__size_ok:
|
||||||
|
|
||||||
|
; Set screen mode
|
||||||
|
screen zr, r7
|
||||||
|
; Set screen size
|
||||||
|
mov flags, SCREEN_SETTING_RESOLUTION
|
||||||
|
; Setting is width/4 - 1
|
||||||
|
sub r4, r4, 1
|
||||||
|
screen flags, r4
|
||||||
|
; Restore width
|
||||||
|
add r4, r4, 1
|
||||||
|
lsl r4, r4, 2
|
||||||
|
|
||||||
|
; Set FB pointer
|
||||||
|
; If double buffering..
|
||||||
|
cmp r6, 0
|
||||||
|
je set_graphics_mode__save_fb_single_buff
|
||||||
|
; ..we want the size of each FB
|
||||||
|
lsr r11, r11, 1
|
||||||
|
store_32 [globals.FB_DISPLAY_PTR], r2
|
||||||
|
mov flags, SCREEN_SETTING_DATA_OFFSET
|
||||||
|
screen flags, r2
|
||||||
|
add r2, r2, r11
|
||||||
|
jmp set_graphics_mode__save_fb_done
|
||||||
|
set_graphics_mode__save_fb_single_buff:
|
||||||
|
store_32 [globals.FB_DISPLAY_PTR], r2
|
||||||
|
mov flags, SCREEN_SETTING_DATA_OFFSET
|
||||||
|
screen flags, r2
|
||||||
|
set_graphics_mode__save_fb_done:
|
||||||
|
store_32 [globals.FB_DRAW_PTR], r2
|
||||||
|
|
||||||
|
store_16 [globals.FB_DISPLAY_DEPTH], r3
|
||||||
|
store_16 [globals.FB_DRAW_DEPTH], r3
|
||||||
|
store_16 [globals.FB_SIZE_BYTE], r11
|
||||||
|
store_16 [globals.FB_WIDTH_PX], r4
|
||||||
|
store_16 [globals.FB_HEIGHT_PX], r10
|
||||||
|
store_8 [globals.FB_LOG_WIDTH], r9
|
||||||
|
store_8 [globals.FB_LOG_BPP], r8
|
||||||
|
|
||||||
|
mov flags, 1
|
||||||
|
lsl r8, flags, r8
|
||||||
|
store_8 [globals.FB_BYTES_PER_PIXEL], r8
|
||||||
|
|
||||||
|
lsl r4, r4, r8 ; Stride in bytes
|
||||||
|
store_16 [globals.FB_DISPLAY_STRIDE], r4
|
||||||
|
store_16 [globals.FB_DRAW_STRIDE], r4
|
||||||
|
|
||||||
|
mov flags, 1 ; Graphics mode
|
||||||
|
store_8 [globals.FB_MODE], flags
|
||||||
|
|
||||||
|
; Clean stack
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
|
||||||
|
cmp r5, 0
|
||||||
|
je set_graphics_mode__not_clear
|
||||||
|
; If double buffering
|
||||||
|
cmp r6, 0
|
||||||
|
je set_graphics_mode__clear_single_fb
|
||||||
|
; Clear one buffer..
|
||||||
|
push r13
|
||||||
|
counter r13
|
||||||
|
add r13, r13, 12
|
||||||
|
jmp clear_graphics_fb ; Call
|
||||||
|
pop r13
|
||||||
|
; ...then the other
|
||||||
|
set_graphics_mode__clear_single_fb:
|
||||||
|
jmp clear_graphics_fb ; Tail call
|
||||||
|
set_graphics_mode__not_clear:
|
||||||
|
|
||||||
|
mov flags, errno.OK
|
||||||
|
jmp r13 ; return
|
||||||
|
|
||||||
|
set_graphics_mode__error:
|
||||||
|
; r6 has the error code
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
mov flags, r6
|
||||||
|
jmp r13 ; return
|
||||||
|
|
||||||
|
|
||||||
|
pub clear:
|
||||||
|
; void clear()
|
||||||
|
; Paints the draw framebuffer black and switches to it
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - None
|
||||||
|
; Returns:
|
||||||
|
; - flags: 0 OK
|
||||||
|
; Clobbers:
|
||||||
|
; - r1: Color
|
||||||
|
; - r2: fill_screen
|
||||||
|
; - r3: fill_screen
|
||||||
|
; - r4: fill_screen
|
||||||
|
; - r5: Alternate link register
|
||||||
|
|
||||||
|
mov r5, r13
|
||||||
|
load_8 flags, [globals.FB_MODE]
|
||||||
|
mov r13, clear__done
|
||||||
|
je clear__graphics
|
||||||
|
jmp clear_text_fb ; Call, return to clear__done
|
||||||
|
clear__graphics:
|
||||||
|
jmp clear_graphics_fb ; Call
|
||||||
|
clear__done:
|
||||||
|
mov r13, r5
|
||||||
|
jmp switch_buffers ; Tail call
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub clear_text_fb:
|
||||||
|
; void clear_text_mode()
|
||||||
|
; Paints the whole text mode screen in the background colour
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - None
|
||||||
|
; Returns:
|
||||||
|
; - flags: 0 OK
|
||||||
|
; Clobbers:
|
||||||
|
; - r1: Color
|
||||||
|
; - r2: Pixel pointer
|
||||||
|
; - r3: End address
|
||||||
|
; - r4: Bytes in FB
|
||||||
|
|
||||||
|
mov r1, 0 ; Blank background colour in either 8 or 32 bit
|
||||||
|
|
||||||
|
mov r3, 3840 ; 96*40 characters on screen
|
||||||
|
load_8 r4, [globals.FB_LOG_BPP]
|
||||||
|
lsl r3, r3, r4 ; Num bytes in FB
|
||||||
|
load_32 r2, [globals.FB_DRAW_PTR]
|
||||||
|
add r3, r3, r2 ; Start of FB
|
||||||
|
lsl r4, r3, r4 ; Num bytes in FB
|
||||||
|
load_32 r2, [globals.FB_DRAW_PTR]
|
||||||
|
add r3, r4, r2 ; End of FB
|
||||||
|
|
||||||
|
jmp fill_screen__loop
|
||||||
|
|
||||||
|
|
||||||
|
pub clear_graphics_fb:
|
||||||
|
; u16 clear_graphics_fb()
|
||||||
|
; Paints all of the current graphics mode draw buffer black
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - None
|
||||||
|
; Returns:
|
||||||
|
; - flags: 0 OK
|
||||||
|
; Clobbers:
|
||||||
|
; - r1: Color
|
||||||
|
; - r2: fill_screen
|
||||||
|
; - r3: fill_screen
|
||||||
|
; - r4: fill_screen
|
||||||
|
|
||||||
|
mov r1, 0 ; Black in either 8 or 32 bit
|
||||||
|
; Fall through
|
||||||
|
|
||||||
|
pub fill_screen:
|
||||||
|
; u16 fill_screen(u32 color)
|
||||||
|
; Fills the whole graphics framebuffer in a single color.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Color. Either 8 bit or 32 bit RGB0
|
||||||
|
; Returns:
|
||||||
|
; - flags: 0 OK
|
||||||
|
; Clobbers:
|
||||||
|
; - r2: Pixel pointer
|
||||||
|
; - r3: End address
|
||||||
|
; - r4: Bytes in FB
|
||||||
|
; Reads globals:
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - LOG_BPP
|
||||||
|
; - LOG_WIDTH
|
||||||
|
; - PIXEL_HEIGHT
|
||||||
|
|
||||||
|
load_8 r2, [globals.FB_LOG_WIDTH]
|
||||||
|
load_16 r3, [globals.FB_HEIGHT_PX]
|
||||||
|
lsl r3, r3, r2
|
||||||
|
load_8 r4, [globals.FB_LOG_BPP]
|
||||||
|
cmp r4, 0
|
||||||
|
jne fill_screen__32_bit
|
||||||
|
; 8-bit: So copy the color so we write 32 bits at a time
|
||||||
|
lsl flags, r1, 8
|
||||||
|
or r1, flags, r1
|
||||||
|
lsl flags, r1, 16
|
||||||
|
or r1, flags, r1
|
||||||
|
fill_screen__32_bit:
|
||||||
|
lsl r4, r3, r4 ; Num bytes in FB
|
||||||
|
load_32 r2, [globals.FB_DRAW_PTR]
|
||||||
|
add r3, r4, r2 ; End of FB
|
||||||
|
; All modes have multiple of 4*3*4 bytes
|
||||||
|
; so we can unroll writing 4 bytes 12 times.
|
||||||
|
; Except: 4x3 8-bit graphics mode has only 12 bytes
|
||||||
|
cmp r4, 12
|
||||||
|
je fill_screen__12
|
||||||
|
fill_screen__loop:
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
fill_screen__12:
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
store_32 [r2], r1
|
||||||
|
add r2, r2, 4
|
||||||
|
cmp r2, r3
|
||||||
|
jb fill_screen__loop
|
||||||
|
|
||||||
|
mov flags, errno.OK
|
||||||
|
jmp switch_buffers ; Tail call
|
||||||
|
|
||||||
|
|
||||||
|
pub set_text_mode_default:
|
||||||
|
; u16 set_text_mode_default(void *FB_ptr)
|
||||||
|
; Sets the screen to default text mode, the font, and colour depth. Also sets fore ground and background colors.
|
||||||
|
; Disables double buffering. Does not clear the screen.
|
||||||
|
; Size of allcation is not checked.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Address of allocated framebuffer
|
||||||
|
; Returns:
|
||||||
|
; - flags: 0 ; OK, never fails
|
||||||
|
; Clobbers:
|
||||||
|
; - r1, flags
|
||||||
|
; Globals written:
|
||||||
|
; - FB_DISPLAY_PTR
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FRAME_BUFFER_SIZE
|
||||||
|
|
||||||
|
; Size is 96*40*1 byte
|
||||||
|
mov r2, 3840 ; Size of FB in bytes
|
||||||
|
mov r3, 8 ; Bits per pixel
|
||||||
|
mov r4, 0 ; Default font
|
||||||
|
mov r5, 0 ; Don't clear
|
||||||
|
mov r6, 0 ; Single buffer
|
||||||
|
|
||||||
|
; Fall through
|
||||||
|
|
||||||
|
pub set_text_mode:
|
||||||
|
; u16 set_text_mode(void *FB_ptr, size_t FB_size, u8 bit_per_pixel, u8 font, bool clear, bool double_buf)
|
||||||
|
; Sets the screen to text mode, the font, and colour depth. Also sets foreground and background colors.
|
||||||
|
; Optionally clears the screen.
|
||||||
|
|
||||||
|
; Arguments:
|
||||||
|
; - r1: Address of allocated framebuffer
|
||||||
|
; - r2: Size of FB allocation, in bytes
|
||||||
|
; - r3: Bits per pixel: One of `8` or `32`
|
||||||
|
; - r4: Font, one of {0,1,2,3}
|
||||||
|
; - r5: If non-zero, clears the current framebuffer.
|
||||||
|
; - r6: If non-zero, enable double buffering
|
||||||
|
; Returns:
|
||||||
|
; - flags: Error code
|
||||||
|
; Clobbers:
|
||||||
|
; - r7: Screen mode setting
|
||||||
|
; Errors:
|
||||||
|
; - 0 OK
|
||||||
|
; - SCREEN_INVALID_SIZE width invalid
|
||||||
|
; - SCREEN_INVALID_MODE bits_per_pixel invalid
|
||||||
|
; - SCREEN_FB_TOO_SMALL allocation too small
|
||||||
|
; Globals written:
|
||||||
|
; - LOG_STRIDE
|
||||||
|
; - FB_WIDTH
|
||||||
|
; - FB_HEIGHT
|
||||||
|
; - BITS_PER_PIXEL
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
; - FB_SIZE_BYTE
|
||||||
|
; - FB_MODE
|
||||||
|
; - FB_SIZE_BYTE
|
||||||
|
; Globals read:
|
||||||
|
; - MAGIC_ADDRESS
|
||||||
|
|
||||||
|
|
||||||
|
push r8 ; LOG Bytes/pixel
|
||||||
|
push r9 ; Log width
|
||||||
|
push r10 ; Height
|
||||||
|
push r11 ; Size of FB in bytes/pixels
|
||||||
|
|
||||||
|
; Check the magic number
|
||||||
|
load_16 flags, [globals.MAGIC_ADDRESS]
|
||||||
|
cmp flags, globals.MAGIC_VALUE
|
||||||
|
je set_text__mode_magic_ok
|
||||||
|
mov r6, errno.MAGIC_BAD
|
||||||
|
jmp set_text_mode__end
|
||||||
|
set_text__mode_magic_ok:
|
||||||
|
|
||||||
|
;TODO: Sanity checks
|
||||||
|
|
||||||
|
cmp r3, 32
|
||||||
|
jne set_text__not_32_bit_text_mode
|
||||||
|
mov r7, SCREEN_MODE_TEXT_32
|
||||||
|
mov r8, 2
|
||||||
|
jmp text_mode__ok
|
||||||
|
|
||||||
|
set_text__not_32_bit_text_mode:
|
||||||
|
cmp r3, 8
|
||||||
|
jne set_text_mode__invalid_mode
|
||||||
|
mov r7, SCREEN_MODE_TEXT_8
|
||||||
|
mov r8, 0
|
||||||
|
jmp text_mode__ok
|
||||||
|
|
||||||
|
set_text_mode__invalid_mode:
|
||||||
|
mov r6, errno.SCREEN_INVALID_MODE
|
||||||
|
jmp set_text_mode__end
|
||||||
|
text_mode__ok:
|
||||||
|
|
||||||
|
_set_test_mode__default:
|
||||||
|
; Set screen mode
|
||||||
|
screen zr, r7
|
||||||
|
|
||||||
|
; Set FB pointer
|
||||||
|
; If double buffering..
|
||||||
|
cmp r6, 0
|
||||||
|
je set_text_mode__save_fb_single_buff
|
||||||
|
; ..we want the size of each FB
|
||||||
|
lsr r11, r11, 1
|
||||||
|
store_32 [globals.FB_SIZE_BYTE], r11
|
||||||
|
store_32 [globals.FB_DISPLAY_PTR], r2
|
||||||
|
mov r3, SCREEN_SETTING_DATA_OFFSET
|
||||||
|
screen r3, r2
|
||||||
|
add r2, r2, r11
|
||||||
|
jmp set_text_mode__save_fb_done
|
||||||
|
set_text_mode__save_fb_single_buff:
|
||||||
|
store_32 [globals.FB_SIZE_BYTE], r11
|
||||||
|
store_32 [globals.FB_DISPLAY_PTR], r2
|
||||||
|
mov r3, SCREEN_SETTING_DATA_OFFSET
|
||||||
|
screen r3, r2
|
||||||
|
set_text_mode__save_fb_done:
|
||||||
|
store_32 [globals.FB_DRAW_PTR], r2
|
||||||
|
|
||||||
|
store_16 [globals.FB_SIZE_BYTE], r11
|
||||||
|
|
||||||
|
; Set screen font
|
||||||
|
; Only 0, 1, 2, 3 are valid
|
||||||
|
and r4, r4, 3
|
||||||
|
mov flags, SCREEN_SETTING_FONT
|
||||||
|
screen flags, r4
|
||||||
|
|
||||||
|
; Set foreground to white
|
||||||
|
mov flags, SCREEN_SETTING_FOREGROUND_COLOR
|
||||||
|
nor r4, zr, 0xff ; White
|
||||||
|
screen flags, r4
|
||||||
|
|
||||||
|
; Set background to black
|
||||||
|
mov flags, SCREEN_SETTING_BACKGROUND_COLOR
|
||||||
|
screen flags, zr
|
||||||
|
|
||||||
|
store_8 [globals.FB_MODE], zr ; Text mode
|
||||||
|
|
||||||
|
;TODO: ?Clear screen
|
||||||
|
|
||||||
|
mov r6, errno.OK
|
||||||
|
|
||||||
|
set_text_mode__end:
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
mov flags, r6
|
||||||
|
jmp r13 ; return
|
||||||
|
|
||||||
|
|
||||||
|
pub switch_buffers: ; SHOULD BE INLINED
|
||||||
|
; void switch_buffers()
|
||||||
|
; Swaps the display and draw buffers, and updates the screen to use the new display buffer.
|
||||||
|
;; Safe to run when single buffered.
|
||||||
|
;
|
||||||
|
; Arguments:
|
||||||
|
; - None
|
||||||
|
; Returns:
|
||||||
|
; - r1: Old display FB => new draw FB
|
||||||
|
; - r2: Old draw FB => new display FB
|
||||||
|
; Preserves:
|
||||||
|
; - flags: So it can be tail called from set_graphics_mode and set_text_mode
|
||||||
|
; Clobbers:
|
||||||
|
; - r3: Setting
|
||||||
|
; Globals written:
|
||||||
|
; - FB_DISPLAY_PTR
|
||||||
|
; - FB_DRAW_PTR
|
||||||
|
|
||||||
|
load_32 r1, [globals.FB_DISPLAY_PTR]
|
||||||
|
load_32 r2, [globals.FB_DRAW_PTR]
|
||||||
|
mov r3, SCREEN_SETTING_DATA_OFFSET
|
||||||
|
screen r3, r2
|
||||||
|
store_32 [globals.FB_DISPLAY_PTR], r2
|
||||||
|
store_32 [globals.FB_DRAW_PTR], r1
|
||||||
|
|
||||||
|
jmp r13 ; return
|
||||||
Executable → Regular
Reference in New Issue
Block a user