https://github.com/akkartik/mu/blob/master/apps/tile.mu
 1 # little example program: animate a line in text-mode
 2 #
 3 # To run (on Linux and x86):
 4 #   $ git clone https://github.com/akkartik/mu
 5 #   $ cd mu
 6 #   $ ./translate_mu apps/tile.mu
 7 #   $ ./a.elf
 8 # You should see a line drawn on a blank screen. Press a key. You should see
 9 # the line seem to fall down the screen. Press a second key to quit.
10 # https://archive.org/details/akkartik-2min-2020-07-01
11 
12 fn main -> exit-status/ebx: int {
13   clear-screen
14   move-cursor-on-screen 5, 5
15   print-string-to-screen "_________"
16   enable-keyboard-immediate-mode
17   var dummy/eax: byte <- read-key
18   var row/eax: int <- copy 5
19   {
20     compare row, 0xe  # 15
21     break-if-=
22     animate row
23     row <- increment
24     sleep 0 0x5f5e100  # 100ms
25     loop
26   }
27   var dummy/eax: byte <- read-key
28   enable-keyboard-type-mode
29   clear-screen
30   exit-status <- copy 0
31 }
32 
33 fn animate row: int {
34   var col/eax: int <- copy 5
35   {
36     compare col, 0xe
37     break-if-=
38     move-cursor-on-screen row, col
39     print-string-to-screen " "
40     increment row
41     move-cursor-on-screen row, col
42     print-string-to-screen "_"
43     decrement row
44     col <- increment
45     loop
46   }
47 }
48 
49 type timespec {
50   tv_sec: int
51   tv_nsec: int
52 }
53 
54 # prototype wrapper around syscall_nanosleep
55 # nsecs must be less than 999999999 or 0x3b9ac9ff nanoseconds
56 fn sleep secs: int, nsecs: int {
57   var t: timespec
58   # initialize t
59   var tmp/eax: (addr int) <- get t, tv_sec
60   var tmp2/ecx: int <- copy secs
61   copy-to *tmp, tmp2
62   tmp <- get t, tv_nsec
63   tmp2 <- copy nsecs
64   copy-to *tmp, tmp2
65   # perform the syscall
66   var t-addr/ebx: (addr timespec) <- address t
67   var rem-addr/ecx: (addr timespec) <- copy 0
68   syscall_nanosleep
69 }