https://github.com/akkartik/mu/blob/main/507line.mu
  1 fn draw-line screen: (addr screen), x0: int, y0: int, x1: int, y1: int, color: int {
  2   var dx: int
  3   var dy: int
  4   var sx: int
  5   var sy: int
  6   var err: int
  7   # dx = abs(x1-x0)
  8   var tmp2/ecx: int <- copy x1
  9   tmp2 <- subtract x0
 10   var tmp/eax: int <- abs tmp2
 11   copy-to dx, tmp
 12   # sx = sgn(x1-x0)
 13   tmp <- sgn tmp2
 14   copy-to sx, tmp
 15   # dy = -abs(y1-y0)
 16   tmp2 <- copy y1
 17   tmp2 <- subtract y0
 18   tmp <- abs tmp2
 19   tmp <- negate
 20   copy-to dy, tmp
 21   # sy = sgn(y1-y0)
 22   tmp <- sgn tmp2
 23   copy-to sy, tmp
 24   # err = dx + dy
 25   tmp <- copy dy
 26   tmp <- add dx
 27   copy-to err, tmp
 28   #
 29   var x/ecx: int <- copy x0
 30   var y/edx: int <- copy y0
 31   $draw-line:loop: {
 32     pixel screen, x, y, color
 33     # if (x == x1 && y == y1) break
 34     {
 35       compare x, x1
 36       break-if-!=
 37       compare y, y1
 38       break-if-!=
 39       break $draw-line:loop
 40     }
 41     # e2 = err*2
 42     var e2/ebx: int <- copy err
 43     e2 <- shift-left 1
 44     # if (e2 >= dy) { err += dy; x += sx; }
 45     {
 46       compare e2, dy
 47       break-if-<
 48       tmp <- copy dy
 49       add-to err, tmp
 50       x <- add sx
 51     }
 52     # if (e2 <= dx) { err += dx; y += sy; }
 53     {
 54       compare e2, dx
 55       break-if->
 56       tmp <- copy dx
 57       add-to err, tmp
 58       y <- add sy
 59     }
 60     loop
 61   }
 62 }
 63 
 64 fn draw-horizontal-line screen: (addr screen), y: int, x0: int, x1: int, color: int {
 65   var x/eax: int <- copy x0
 66   {
 67     compare x, x1
 68     break-if->=
 69     pixel screen, x, y, color
 70     x <- increment
 71     loop
 72   }
 73 }
 74 
 75 fn draw-vertical-line screen: (addr screen), x: int, y0: int, y1: int, color: int {
 76   var y/eax: int <- copy y0
 77   {
 78     compare y, y1
 79     break-if->=
 80     pixel screen, x, y, color
 81     y <- increment
 82     loop
 83   }
 84 }
 85 
 86 fn draw-rect screen: (addr screen), xmin: int, ymin: int, xmax: int, ymax: int, color: int {
 87   var y/eax: int <- copy ymin
 88   {
 89     compare y, ymax
 90     break-if->=
 91     draw-horizontal-line screen, y, xmin, xmax, color
 92     y <- increment
 93     loop
 94   }
 95 }
 96 
 97 # 0 <= u <= 1
 98 fn line-point u: float, x0: int, x1: int -> _/eax: int {
 99   var one/eax: int <- copy 1
100   var u-prime/xmm0: float <- convert one
101   u-prime <- subtract u
102   var result/xmm1: float <- convert x0
103   result <- multiply u-prime
104   var term2/xmm2: float <- convert x1
105   term2 <- multiply u
106   result <- add term2
107   var result/eax: int <- convert result
108   return result
109 }