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