From 78357b8852626b510527f3b8d770a7dd8956fcc7 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 16 Jul 2021 08:38:43 -0700 Subject: . --- html/apps/life.mu.html | 320 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 html/apps/life.mu.html (limited to 'html/apps/life.mu.html') diff --git a/html/apps/life.mu.html b/html/apps/life.mu.html new file mode 100644 index 00000000..cc262c2d --- /dev/null +++ b/html/apps/life.mu.html @@ -0,0 +1,320 @@ + + + + +Mu - apps/life.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/apps/life.mu +
+  1 # Conway's Game of Life
+  2 #
+  3 # To build:
+  4 #   $ ./translate apps/life.mu
+  5 # To run:
+  6 #   $ qemu-system-i386 code.img
+  7 
+  8 fn state _grid: (addr array boolean), x: int, y: int -> _/eax: boolean {
+  9   # clip at the edge
+ 10   compare x, 0
+ 11   {
+ 12     break-if->=
+ 13     return 0/false
+ 14   }
+ 15   compare y, 0
+ 16   {
+ 17     break-if->=
+ 18     return 0/false
+ 19   }
+ 20   compare x, 0x100/width
+ 21   {
+ 22     break-if-<
+ 23     return 0/false
+ 24   }
+ 25   compare y, 0xc0/height
+ 26   {
+ 27     break-if-<
+ 28     return 0/false
+ 29   }
+ 30   var idx/eax: int <- copy y
+ 31   idx <- shift-left 8/log2width
+ 32   idx <- add x
+ 33   var grid/esi: (addr array boolean) <- copy _grid
+ 34   var result/eax: (addr boolean) <- index grid, idx
+ 35   return *result
+ 36 }
+ 37 
+ 38 fn set-state _grid: (addr array boolean), x: int, y: int, val: boolean {
+ 39   # don't bother checking bounds
+ 40   var idx/eax: int <- copy y
+ 41   idx <- shift-left 8/log2width
+ 42   idx <- add x
+ 43   var grid/esi: (addr array boolean) <- copy _grid
+ 44   var result/eax: (addr boolean) <- index grid, idx
+ 45   var src/ecx: boolean <- copy val
+ 46   copy-to *result, src
+ 47 }
+ 48 
+ 49 fn num-live-neighbors grid: (addr array boolean), x: int, y: int -> _/eax: int {
+ 50   var result/edi: int <- copy 0
+ 51   # row above: zig
+ 52   decrement y
+ 53   decrement x
+ 54   var s/eax: boolean <- state grid, x, y
+ 55   {
+ 56     compare s, 0/false
+ 57     break-if-=
+ 58     result <- increment
+ 59   }
+ 60   increment x
+ 61   s <- state grid, x, y
+ 62   {
+ 63     compare s, 0/false
+ 64     break-if-=
+ 65     result <- increment
+ 66   }
+ 67   increment x
+ 68   s <- state grid, x, y
+ 69   {
+ 70     compare s, 0/false
+ 71     break-if-=
+ 72     result <- increment
+ 73   }
+ 74   # curr row: zag
+ 75   increment y
+ 76   s <- state grid, x, y
+ 77   {
+ 78     compare s, 0/false
+ 79     break-if-=
+ 80     result <- increment
+ 81   }
+ 82   subtract-from x, 2
+ 83   s <- state grid, x, y
+ 84   {
+ 85     compare s, 0/false
+ 86     break-if-=
+ 87     result <- increment
+ 88   }
+ 89   # row below: zig
+ 90   increment y
+ 91   s <- state grid, x, y
+ 92   {
+ 93     compare s, 0/false
+ 94     break-if-=
+ 95     result <- increment
+ 96   }
+ 97   increment x
+ 98   s <- state grid, x, y
+ 99   {
+100     compare s, 0/false
+101     break-if-=
+102     result <- increment
+103   }
+104   increment x
+105   s <- state grid, x, y
+106   {
+107     compare s, 0/false
+108     break-if-=
+109     result <- increment
+110   }
+111   return result
+112 }
+113 
+114 fn step old-grid: (addr array boolean), new-grid: (addr array boolean) {
+115   var y/ecx: int <- copy 0
+116   {
+117     compare y, 0xc0/height
+118     break-if->=
+119     var x/edx: int <- copy 0
+120     {
+121       compare x, 0x100/width
+122       break-if->=
+123       var n/eax: int <- num-live-neighbors old-grid, x, y
+124       # if neighbors < 2, die of loneliness
+125       {
+126         compare n, 2
+127         break-if->=
+128         set-state new-grid, x, y, 0/dead
+129       }
+130       # if neighbors > 3, die of overcrowding
+131       {
+132         compare n, 3
+133         break-if-<=
+134         set-state new-grid, x, y, 0/dead
+135       }
+136       # if neighbors = 2, preserve state
+137       {
+138         compare n, 2
+139         break-if-!=
+140         var old-state/eax: boolean <- state old-grid, x, y
+141         set-state new-grid, x, y, old-state
+142       }
+143       # if neighbors = 3, cell quickens to life
+144       {
+145         compare n, 3
+146         break-if-!=
+147         set-state new-grid, x, y, 1/live
+148       }
+149       x <- increment
+150       loop
+151     }
+152     y <- increment
+153     loop
+154   }
+155 }
+156 
+157 # color a square of size 'side' starting at x*side, y*side
+158 fn render-square _x: int, _y: int, color: int {
+159   var y/edx: int <- copy _y
+160   y <- shift-left 2/log2side
+161   var side/ebx: int <- copy 1
+162   side <- shift-left 2/log2side
+163   var ymax/ecx: int <- copy y
+164   ymax <- add side
+165   {
+166     compare y, ymax
+167     break-if->=
+168     {
+169       var x/eax: int <- copy _x
+170       x <- shift-left 2/log2side
+171       var xmax/ecx: int <- copy x
+172       xmax <- add side
+173       {
+174         compare x, xmax
+175         break-if->=
+176         pixel-on-real-screen x, y, color
+177         x <- increment
+178         loop
+179       }
+180     }
+181     y <- increment
+182     loop
+183   }
+184 }
+185 
+186 fn render grid: (addr array boolean) {
+187   var y/ecx: int <- copy 0
+188   {
+189     compare y, 0xc0/height
+190     break-if->=
+191     var x/edx: int <- copy 0
+192     {
+193       compare x, 0x100/width
+194       break-if->=
+195       var state/eax: boolean <- state grid, x, y
+196       compare state, 0/false
+197       {
+198         break-if-=
+199         render-square x, y, 3/cyan
+200       }
+201       compare state, 0/false
+202       {
+203         break-if-!=
+204         render-square x, y, 0/black
+205       }
+206       x <- increment
+207       loop
+208     }
+209     y <- increment
+210     loop
+211   }
+212 }
+213 
+214 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
+215 #?   # allocate on the stack
+216 #?   var grid1-storage: (array boolean 0xc000)  # width * height
+217 #?   var grid1/esi: (addr array boolean) <- address grid1-storage
+218 #?   var grid2-storage: (array boolean 0xc000)  # width * height
+219 #?   var grid2/edi: (addr array boolean) <- address grid2-storage
+220   # allocate on the heap
+221   var grid1-storage: (handle array boolean)
+222   var grid1-ah/eax: (addr handle array boolean) <- address grid1-storage
+223   populate grid1-ah, 0xc000  # width * height
+224   var _grid1/eax: (addr array boolean) <- lookup *grid1-ah
+225   var grid1/esi: (addr array boolean) <- copy _grid1
+226   var grid2-storage: (handle array boolean)
+227   var grid2-ah/eax: (addr handle array boolean) <- address grid2-storage
+228   populate grid2-ah, 0xc000  # width * height
+229   var _grid2/eax: (addr array boolean) <- lookup *grid2-ah
+230   var grid2/edi: (addr array boolean) <- copy _grid2
+231   # initialize grid1
+232   set-state grid1, 0x80, 0x5f, 1/live
+233   set-state grid1, 0x81, 0x5f, 1/live
+234   set-state grid1, 0x7f, 0x60, 1/live
+235   set-state grid1, 0x80, 0x60, 1/live
+236   set-state grid1, 0x80, 0x61, 1/live
+237   # render grid1
+238   render grid1
+239   {
+240     var key/eax: byte <- read-key keyboard
+241     compare key, 0
+242 #?     loop-if-=  # press key to step
+243     break-if-!=  # press key to quit  # comment this out to run under bochs; I'm not sure why there's a newline in the keyboard buffer
+244     # iter: grid1 -> grid2
+245     step grid1, grid2
+246     render grid2
+247     # iter: grid2 -> grid1
+248     step grid2, grid1
+249     render grid1
+250     loop
+251   }
+252 }
+
+ + + -- cgit 1.4.1-2-gfad0