about summary refs log tree commit diff stats
path: root/mu-init.subx
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-03-03 22:09:50 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-03-03 22:21:03 -0800
commit71e4f3812982dba2efb471283d310224e8db363e (patch)
treeea111a1acb8b8845dbda39c0e1b4bac1d198143b /mu-init.subx
parentc6b928be29ac8cdb4e4d6e1eaa20420ff03e5a4c (diff)
downloadmu-71e4f3812982dba2efb471283d310224e8db363e.tar.gz
7842 - new directory organization
Baremetal is now the default build target and therefore has its sources
at the top-level. Baremetal programs build using the phase-2 Mu toolchain
that requires a Linux kernel. This phase-2 codebase which used to be at
the top-level is now under the linux/ directory. Finally, the phase-2 toolchain,
while self-hosting, has a way to bootstrap from a C implementation, which
is now stored in linux/bootstrap. The bootstrap C implementation uses some
literate programming tools that are now in linux/bootstrap/tools.

So the whole thing has gotten inverted. Each directory should build one
artifact and include the main sources (along with standard library). Tools
used for building it are relegated to sub-directories, even though those
tools are often useful in their own right, and have had lots of interesting
programs written using them.

A couple of things have gotten dropped in this process:
  - I had old ways to run on just a Linux kernel, or with a Soso kernel.
    No more.
  - I had some old tooling for running a single test at the cursor. I haven't
    used that lately. Maybe I'll bring it back one day.

The reorg isn't done yet. Still to do:
  - redo documentation everywhere. All the README files, all other markdown,
    particularly vocabulary.md.
  - clean up how-to-run comments at the start of programs everywhere
  - rethink what to do with the html/ directory. Do we even want to keep
    supporting it?

In spite of these shortcomings, all the scripts at the top-level, linux/
and linux/bootstrap are working. The names of the scripts also feel reasonable.
This is a good milestone to take stock at.
Diffstat (limited to 'mu-init.subx')
-rw-r--r--mu-init.subx77
1 files changed, 21 insertions, 56 deletions
diff --git a/mu-init.subx b/mu-init.subx
index feab920f..26b83451 100644
--- a/mu-init.subx
+++ b/mu-init.subx
@@ -1,62 +1,27 @@
 # Initialize the minimal runtime for Mu programs.
 #
-# See translate_mu for how this file is used.
+# See translate_mu_baremetal for how this file is used.
 #
-# Mu programs start at a function called 'main' with this signature:
-#   fn main args: (addr array addr array byte) -> _/ebx: int
-# If your program doesn't need commandline arguments you can drop it:
-#   fn main -> _/ebx: int
-#
-# Notice that the output must be in ebx, so that the exit() syscall can pick
-# it up.
+# Mu baremetal programs start at a function called 'main' without inouts or outputs.
 
 == code
 
-Entry:
-    # we don't use ebp in Entry; just initialize it
-    bd/copy-to-ebp 0/imm32
-    # - save argc and argv
-    # var argc-and-argv/esi
-    89/<- %esi 4/r32/esp
-$Entry:initialize-heap:
-    # - initialize the heap
-    (new-segment *Heap-size Heap)
-$Entry:initialize-args:
-    # - convert argv from null-terminated 'kernel' strings to length-prefixed Mu strings
-    # var argc/edx: int
-    8b/-> *esi 2/r32/edx
-    # argc is in words; convert it to bytes
-    c1/shift 4/subop/left %edx 2/imm8
-    # var tmp/ebx: handle
-    68/push 0/imm32
-    68/push 0/imm32
-    89/<- %ebx 4/r32/esp
-    # var args/edi: (addr array (addr array byte))
-    (allocate-array Heap %edx %ebx)
-    (lookup *ebx *(ebx+4))  # => eax
-    89/<- %edi 0/r32/eax
-    # var curr/ecx: (addr kernel-string) = argv
-    8d/copy-address *(esi+4) 1/r32/ecx
-    # var max/edx: (addr kernel-string) = argv+4+argc
-    8d/copy-address *(ecx+edx) 2/r32/edx
-    # var dest/esi: (addr (addr array byte)) = args+4
-    8d/copy-address *(edi+4) 6/r32/esi
-    {
-      # if (curr >= max) break
-      39/compare %ecx 2/r32/edx
-      73/jump-if-addr>= break/disp8
-      # *dest = kernel-string-to-string(*curr)
-      (kernel-string-to-string Heap *ecx %ebx)
-      (lookup *ebx *(ebx+4))  # => eax
-      89/<- *esi 0/r32/eax
-      # curr += 4
-      81 0/subop/add %ecx 4/imm32
-      # dest += 4
-      81 0/subop/add %esi 4/imm32
-      #
-      eb/jump loop/disp8
-    }
-    # - run Mu program
-    (main %edi)  # => ebx
-    # - exit
-    (syscall_exit)
+# initialize stack
+bd/copy-to-ebp 0/imm32
+# always first run tests
+(run-tests)
+(num-test-failures)  # => eax
+# call main if tests all passed
+{
+  3d/compare-eax-and 0/imm32
+  75/jump-if-!= break/disp8
+  (clear-real-screen)
+  c7 0/subop/copy *Real-screen-cursor-x 0/imm32
+  c7 0/subop/copy *Real-screen-cursor-y 0/imm32
+  (main)
+}
+
+# hang indefinitely
+{
+  eb/jump loop/disp8
+}
class="p">(initialSize=4): TQueue[T] = ## creates a new queue. `initialSize` needs to be a power of 2. assert IsPowerOfTwo(initialSize) result.mask = initialSize-1 newSeq(result.data, initialSize) proc len*[T](q: TQueue[T]): int = ## returns the number of elements of `q`. result = q.count iterator items*[T](q: TQueue[T]): T = ## yields every element of `q`. var i = q.rd var c = q.count while c > 0: dec c yield q.data[i] i = (i + 1) and q.mask proc add*[T](q: var TQueue[T], item: T) = ## adds an `item` to the end of the queue `q`. var cap = q.mask+1 if q.count >= cap: var n: seq[T] newSeq(n, cap*2) var i = 0 for x in items(q): shallowCopy(n[i], x) inc i shallowCopy(q.data, n) q.mask = cap*2 - 1 q.wr = q.count q.rd = 0 inc q.count q.data[q.wr] = item q.wr = (q.wr + 1) and q.mask proc enqueue*[T](q: var TQueue[T], item: T) = ## alias for the ``add`` operation. add(q, item) proc dequeue*[T](q: var TQueue[T]): T = ## removes and returns the first element of the queue `q`. assert q.count > 0 dec q.count result = q.data[q.rd] q.rd = (q.rd + 1) and q.mask proc `$`*[T](q: TQueue[T]): string = ## turns a queue into its string representation. result = "[" for x in items(q): if result.len > 1: result.add(", ") result.add($x) result.add("]") when isMainModule: var q = initQueue[int]() q.add(123) q.add(9) q.add(4) var first = q.dequeue q.add(56) q.add(6) var second = q.dequeue q.add(789) assert first == 123 assert second == 9 assert($q == "[4, 56, 6, 789]")