Remove graphics code from this PR

This commit is contained in:
2026-09-06 15:48:37 +01:00
parent b63af2f15a
commit 21deca64fd
-672
View File
@@ -1,672 +0,0 @@
; 32 bit graphics library for Symphony
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: Point 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:
; - r1: Status
; * 0 OK
; * SCREEN_INVALID_SIZE width invalid
; * SCREEN_INVALID_MODE bits_per_pixel invalid
; * SCREEN_FB_TOO_SMALL allocation too small
; Clobbers:
; - r2-r6, flags
; Globals written:
; - LOG_STRIDE
; - FB_WIDTH
; - FB_HEIGHT
; - BITS_PER_PIXEL
; Check the magic number
load_16 flags, [globals.MAGIC_ADDRESS]
cmp flags, globals.MAGIC_VALUE
je set_graphics_mode_magic_ok
mov flags, errno.MAGIC_BAD
jmp r13 ; return
set_graphics_mode_magic_ok:
push r8 ; LOG Bytes/pixel
push r9 ; Log width
push r10 ; Height
push r11 ; Size of FB in bytes/pixels
cmp r3, 32
jne not_32_bit_mode
mov r3, SCREEN_MODE_GRAPHICS_32
mov r8, 2
jmp mode_ok
not_32_bit_mode:
cmp r3, 8
jne invalid_mode
mov r3, SCREEN_MODE_GRAPHICS_8
mov r8, 0
jmp mode_ok
invalid_mode:
pop r11
pop r10
pop r9
pop r8
mov flags, errno.SCREEN_INVALID_MODE
jmp r13 ; return
mode_ok:
; Width must be between 4 and 1024
cmp r4, 1024 ; max width of screen
ja width_invalid
cmp r4, 4
jb width_invalid
; Is width a power of two?
mov r9, 10
mov r10, 1024
log_width_loop:
cmp r4, r10
je width_ok
lsr r10, r10, 1
sub r9, r9, 1
cmp r9, 4
jae log_width_loop
width_invalid:
pop r11
pop r10
pop r9
pop r8
mov flags, errno.SCREEN_INVALID_WIDTH
jmp r13 ; return
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 single_buff
; ..we need twice the space
lsl r11, r11, 1
single_buff:
cmp r2, r11
jae size_ok
pop r11
pop r10
pop r9
pop r8
mov flags, errno.SCREEN_FB_TOO_SMALL
jmp r13 ; return
size_ok:
; Set screen mode
screen zr, r3
; 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 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 save_fb_done
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
save_fb_done:
store_32 [globals.FB_DRAW_PTR], r2
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
mov r1, r2 ; Return draw FB
mov r3, 0
mov r4, 0
; TODO call clear
nor r2, zr, 0xff ; Colour = White (32-bit)
pop r11
pop r10
pop r9
pop r8
mov flags, 0 ; OK
jmp r13 ; return
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 fore ground 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:
; - r1: Status
; * 0 OK
; * SCREEN_INVALID_SIZE width invalid
; * SCREEN_INVALID_MODE bits_per_pixel invalid
; * SCREEN_FB_TOO_SMALL allocation too small
; Clobbers:
; - r2-r6, flags
; Globals written:
; - LOG_STRIDE
; - FB_WIDTH
; - FB_HEIGHT
; - BITS_PER_PIXEL
; Check the magic number
load_16 flags, [globals.MAGIC_ADDRESS]
cmp flags, globals.MAGIC_VALUE
je set_text_mode_magic_ok
mov flags, errno.MAGIC_BAD
jmp r13 ; return
set_text_mode_magic_ok:
;TODO: Sanity checks
;TODO: ?Clear screen
push r8 ; LOG Bytes/pixel
push r9 ; Log width
push r10 ; Height
push r11 ; Size of FB in bytes/pixels
cmp r3, 32
jne not_32_bit_text_mode
mov r3, SCREEN_MODE_TEXT_32
mov r8, 2
jmp text_mode_ok
not_32_bit_text_mode:
cmp r3, 8
jne invalid_text_mode
mov r3, SCREEN_MODE_TEXT_8
mov r8, 0
jmp text_mode_ok
invalid_text_mode:
pop r11
pop r10
pop r9
pop r8
mov flags, errno.SCREEN_INVALID_MODE
jmp r13 ; return
text_mode_ok:
; Set screen mode
screen zr, r3
; Set FB pointer
; If double buffering..
cmp r6, 0
je save_fb_single_text_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 save_fb_text_done
save_fb_single_text_buff:
store_32 [globals.FB_SIZE_BYTE], r11
store_32 [globals.FB_DISPLAY_PTR], r2
mov r3, SCREEN_SETTING_DATA_OFFSET
screen r3, r2
save_fb_text_done:
store_32 [globals.FB_DRAW_PTR], r2
; 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
pop r11
pop r10
pop r9
pop r8
mov flags, 0 ; OK
jmp r13 ; return
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.
; 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
; Set screen mode to default 8 bit text
screen zr, zr
; Set FB pointer
store_32 [globals.FB_DISPLAY_PTR], r1
store_32 [globals.FB_DRAW_PTR], r1
; Size is 96*40*1 byte
mov r1, 3840
store_32 [globals.FB_SIZE_BYTE], r1
mov flags, SCREEN_SETTING_DATA_OFFSET
screen flags, r1
; Set default screen font
mov flags, SCREEN_SETTING_FONT
screen flags, zr
; Set foreground to white
mov flags, SCREEN_SETTING_FOREGROUND_COLOR
nor r1, zr, 0xff ; White
screen flags, r1
; Set background to black
mov flags, SCREEN_SETTING_BACKGROUND_COLOR
screen flags, zr
mov flags, 0 ; OK
jmp r13
pub clear:
; void clear()
; Paints the whole screen black
;
; Arguments:
; - None
; Clobbers:
; - r1: Color
; - r2: fill_screen
; - r3: fill_screen
; - r4: fill_screen
; - flags
mov r1, 0 ; Black
; Fall through
pub fill_screen:
; void fill_screen(u32 color)
; Fills the whole screen in a single color.
;
; Arguments:
; - r1: Color, 32 bit RGB0
; Clobbers:
; - r2: Pixel pointer
; - r3: End address
; - r4: Stride
; - flags
; 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]
lsl r3, r3, r4 ; Num bytes in FB
load_32 r2, [globals.FB_DRAW_PTR]
add r3, r3, r2 ; End of FB
load_8 r4, [globals.FB_BYTES_PER_PIXEL]
fill_screen_loop:
; Screen is always a multiple of 4*3
; we can unroll this 12 times.
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
store_32 [r2], r1
add r2, r2, r4
cmp r2, r3
jb fill_screen_loop
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:
; - None
; Clobbers:
; - r1: Old display FB => new draw FB
; - r2: Old draw FB => new display FB
; - flags
; Globals written:
; - FB_DISPLAY_PTR
; - FB_DRAW_PTR
load_32 r1, [globals.FB_DISPLAY_PTR]
load_32 r2, [globals.FB_DRAW_PTR]
mov flags, SCREEN_SETTING_DATA_OFFSET
screen flags, r2
store_32 [globals.FB_DISPLAY_PTR], r2
store_32 [globals.FB_DRAW_PTR], r1
jmp r13 ; return
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
; - r4-r7 ignored but PRESERVED
; Result:
; - None
; Clobbers:
; - flags
; Globals read:
; - FB_DRAW_PTR
; - LOG_WIDTH
; Screen is `1 << WIDTH pixels wide
load_8 flags, [globals.FB_LOG_WIDTH]
; Compute pixel address
lsl flags, r4, flags ; Y * width
add flags, flags, r3 ; Y * width + X
lsl flags, flags, 2 ; pixel to address
load_32 r1, [globals.FB_DRAW_PTR]
add flags, flags, r1 ; += frambuffer_ptr
; Set pixel value
store_32 [flags], r2
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:
; - r7, flags
push r13
; if x0 > x1
; dx = -1
; else
; dx = +1
; endif
cmp r4, r2
or r7, flags, 0x02
lsl r7, r7, 29
asr r7, r7, 30
jmp draw_line_h_loop_in
draw_line_h_loop:
add r2, r2, r7
draw_line_h_loop_in:
qcall draw_pixel
cmp r2, r4
jne draw_line_h_loop
pop r13
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 but PRESERVED
; - r5: Y1 coord
; Returns:
; - r1: Color 24 bit RGB0 PRESERVED
; - r2: X coord PRESERVED
; - r3: Y1 coord
; Clobbers:
; - r7, flags
push r13
; if y0 > y1
; dy = -1
; else
; dy = +1
; endif
cmp r5, r3
or r7, flags, 0x02
lsl r7, r7, 29
asr r7, r7, 30
jmp draw_line_v_loop_in
draw_line_v_loop:
add r3, r3, r7
draw_line_v_loop_in:
qcall draw_pixel
cmp r3, r5
jne draw_line_v_loop
pop r13
jmp r13 ; return
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
; Globals read:
; - FB_DRAW_PTR
; - FB_DRAW_STRIDE
; - ...others I expect
; push r11 ; sy
; push r10 ; dy
; push r9 ; sx
; push r8 ; dx
; int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
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, 1
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, zr ; sx = -1
; endif
draw_line_move_right_done:
; int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
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, 1
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, zr ; sy = -1
; endif
draw_line_move_down_done:
push r12 ; err, err2
push r13 ; lr
; int err = dx+dy /* error value e_xy */
add r12, r8, r10
; loop while(true)
draw_line_loop:
qcall draw_pixel
; err2 = 2*err;
lsl r12, r12, 1
; if (err2 >= dy) { /* e_xy+e_x > 0 */
cmp r12, r10
lsr r12, r12, 1 ; restore err
jl draw_line_loop_skip_x
; if (x0 == x1) break;
cmp r2, r4
je draw_line_loop_done
; err += dy
add r12, r12, r10
; x0 += sx;
add r2, r2, r9
draw_line_loop_skip_x:
; err2 = 2*err;
lsl r12, r12, 1
; if (err2 <= dx) { /* e_xy+e_y < 0 */
cmp r12, r8
lsl r12, r12, 1 ; restore err
jl draw_line_loop_skip_y
; if (y0 == y1) break;
cmp r3, r5
je draw_line_loop_done
; err += dx
add r12, r12, r8
; y0 += sy
add r3, r3, r11
draw_line_loop_skip_y:
jmp draw_line_loop
; endloop
draw_line_loop_done:
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
jmp r13 ; return