undar-lang/test/paint.asm.lisp

415 lines
11 KiB
Common Lisp

((code
(label main
; Open screen
; use load immediate because it is a pointer to a string, not a value
(load-immediate $0 &screen-namespace)
(load-immediate $11 0)
(syscall OPEN $0 $11)
(load-immediate $16 1) ; device info call
(load-immediate $17 16) ; sizeof screen device info
(malloc $18 $17)
(syscall IOCTL $0 $16 $18)
(load-immediate $1 12) ; offset for width
(add-nat $19 $18 $1)
(get $20 $19) ; load width
(load-immediate $1 8) ; offset for size
(add-nat $19 $18 $1)
(get $22 $19) ; load size
(malloc $21 $22) ; malloc frame buffer
(syscall WRITE $0 $21 $22)
(load-immediate $16 &mouse-namespace)
(load-immediate $3 12) ; malloc sizeof mouse data
(malloc $4 $3)
(label draw-loop
; load mouse click data
(syscall READ $16 $2 $3 $4)
(load-immediate $5 4) ; offset for x
(add-nat $6 $5 $2)
(get $7 $6) ; load x
(load-immediate $5 8) ; offset for y
(add-nat $6 $5 $2)
(get $8 $6) ; load y
(load-immediate $5 12) ; offset for btn1
(add-nat $6 $5 $2)
(get-8 $9 $6) ; load btn1 pressed
(load-immediate $5 13) ; offset for btn2
(add-nat $6 $5 $2)
(get-8 $10 $6) ; load btn2 pressed
(load-immediate $14 20) ; box size
; first row
(push $21)
(push $20)
(load $1 &BLACK)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(syscall WRITE $0 $21 $22)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
(push $20)
(load $1 &WHITE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 2
(push $21)
(push $20)
(load $1 &CHARCOAL)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 21)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
(push $20)
(load $1 &DARK-GRAY)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 21)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 3
(push $21)
(push $20)
(load $1 &RED)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 41)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
(push $20)
(load $1 &ORANGE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 41)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 3
(push $21)
(push $20)
(load $1 &YELLOW)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 61)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
(push $20)
(load $1 &GREEN)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 61)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 4
(push $21)
(push $20)
(load $1 &BLUE)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 81)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
(push $20)
(load $1 &PURPLE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 81)
(push $13)
(call &draw-outlined-swatch)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(syscall WRITE $0 $21 $22)
(jump-eq-nat &draw-loop $9 $11)
(mul-nat $15 $8 $20) ; $15 = y * width
(add-nat $15 $15 $7) ; $15 += x
(add-nat $15 $21 $15) ; $15 = base + pixel_offset
(load-immediate $1 4) ; need to add offset for fat pointer size
(add-nat $15 $15 $1)
(load $22 &SELECTED-COLOR) ; color
(store-8 $15 $22) ; draw color at screen [x,y]
(jump-eq-nat &draw-loop $10 $11))
; Flush and halt
(halt))
(label set-color-if-clicked
; Pop inputs from stack (in reverse order of pushing)
(pop $12) ; $12 = btn1 down?
(pop $11) ; $11 = color
(pop $0) ; $0 = click_x
(pop $1) ; $1 = click_y
(pop $2) ; $2 = box_x
(pop $3) ; $3 = box_y
(pop $5) ; $5 = box_size
; Compute right = box_x + box_size
(add-int $6 $2 $5) ; $6 = right edge
; Compute bottom = box_y + box_size
(add-int $7 $3 $5) ; $7 = bottom edge
; Check 1: click_x >= box_x ?
(jump-ge-int &check2 $0 $2)
(return)
(label check2)
; Check 2: click_x <= right ?
(jump-le-int &check3 $0 $6)
(return)
(label check3)
; Check 3: click_y >= box_y ?
(jump-ge-int &check4 $1 $3)
(return)
(label check4)
; Check 4: click_y <= bottom ?
(jump-le-int &check5 $1 $7)
(return)
(label check5) ; if it was selected then set the color
(load-immediate $13 1)
(jump-eq-int &set-color $12 $13)
(return)
(label set-color)
(load-immediate $10 &SELECTED-COLOR)
(store-8 $10 $11)
(return))
(label draw-outlined-swatch
(pop $3) ; y
(pop $2) ; x
(pop $1) ; color
(pop $20)
(pop $21)
; Constants
(load $4 &GRAY)
(load $10 &SELECTED-COLOR)
(jump-eq-int &set-selected $10 $1)
(jump-eq-int &end-set-selected $4 $4)
(label set-selected)
(load $4 &DARK-GRAY)
(label end-set-selected)
(load-immediate $5 20) ; outline size
(load-immediate $6 17) ; fill size
(load-immediate $7 2) ; offset
(push $21) ; base
(push $20) ; width
(push $4) ; color (gray)
(push $2) ; x
(push $3) ; y
(push $5) ; width (20)
(push $5) ; height (20)
(call &draw-box)
(add-int $8 $2 $7) ; x + 2
(add-int $9 $3 $7) ; y + 2
(push $21) ; base
(push $20) ; width
(push $1) ; color (original)
(push $8) ; x + 2
(push $9) ; y + 2
(push $6) ; width (17)
(push $6) ; height (17)
(call &draw-box)
(return))
; draw-box(color, x, y)
; Pops: y, x, color
(label draw-box
; Pop arguments (reverse order)
(pop $14) ; height
(pop $12) ; width
(pop $13) ; y_start
(pop $11) ; x_start
(pop $3) ; color
(pop $2) ; width
(pop $21) ; base
; Constants
(load-immediate $1 1) ; increment
; Compute start address: base + y*640 + x
(mul-int $15 $13 $2) ; $15 = y * 640
(add-int $15 $15 $11) ; $15 += x
(add-nat $15 $21 $15) ; $15 = base + pixel_offset
(load-immediate $25 4)
(add-nat $15 $15 $25) ; need to add offset for fat pointer size
(register-move $4 $15)
; Outer loop: height times
(register-move $5 $14) ; $5 = row counter
(label draw-box-outer
(add-int $6 $4 $12) ; $6 = row end = current + width
(register-move $7 $4) ; $7 = pixel pointer
(memset-8 $7 $3 $12) ; draw row
(add-int $4 $4 $2) ; next row (+= 640)
(sub-int $5 $5 $1) ; decrement row count
(jump-gt-int &draw-box-outer $5 0))
(return)))
(data
(label screen-namespace "/dev/screen/0")
(label mouse-namespace "/dev/mouse/0")
(label SELECTED-COLOR 255)
(label BLACK 0)
(label WHITE 255)
(label CHARCOAL 36)
(label DARK-GRAY 73)
(label GRAY 146)
(label LIGHT-GRAY 182)
(label DARK-RED 128)
(label RED 224)
(label DARK-YELLOW 144)
(label YELLOW 252)
(label DARK-TEAL 9)
(label TEAL 18)
(label DARK-GREEN 12)
(label GREEN 16)
(label LIME 28)
(label LIGHT-CYAN 159)
(label NAVY 2)
(label BLUE 3)
(label DEEP-SKY-BLUE 10)
(label LIGHT-BLUE 19)
(label PURPLE 131)
(label LIGHT-PURPLE 147)
(label DARK-MAGENTA 130)
(label MAGENTA 227)
(label PLUM 129)
(label PINK 226)
(label SADDLE-BROWN 72)
(label PERU 141)
(label SIENNA 136)
(label ORANGE 241)
(label DARK-ORANGE 208)
(label GOLD 244)))