duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 6c32cb4746f353edbf610f8f0b53010807362e4e
parent 11f6fc662049e5105054a90d86429d4434174ab5
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Thu,  6 Apr 2023 09:58:09 -0400

HAL transition complete!

Diffstat:
MREADME.md | 13++++++++++---
Dfs/doc/stc.txt | 73-------------------------------------------------------------------------
Mfs/doc/usage.txt | 21++++++++++++++++++---
3 files changed, 28 insertions(+), 79 deletions(-)

diff --git a/README.md b/README.md @@ -67,13 +67,19 @@ generated in the first place. This is so much simpler! Object files? Global symbols? Nah. C functions that don't have a static storage type are simple Forth words. +### Harmonized Assembly Layer + +Dusk features what we call the [Harmonized Assembly Layer][hal] (HAL for short). +This is a cross-CPU assembler, on which the C compiler relies, which prioritizes +implementation and usage simplicity, but is also designed to generate efficient +native code. + ### Shortest path to self-hosting for an "almost C" compiler -Dusk OS self-hosts in about 1000 lines of assembly and a few hundred lines of +Dusk OS self-hosts in about 800 lines of assembly and a few hundred lines of Forth (the exact number depends on the target machine). From there, it bootstraps to DuskCC, which is roughly 2000 lines of Forth code (including -arch-specific backend and assembler). To my knowledge, Dusk OS is unique in -that regard. +arch-specific assemblers). To my knowledge, Dusk OS is unique in that regard. You can pick any C compiler that requires POSIX and it will automatically require order of magnitudes more lines of code to bootstrap because you need @@ -266,6 +272,7 @@ Press Escape to return to prompt. You can try the same thing with: [shproj]: https://sr.ht/~vdupras/duskos [mailinglist]: https://sr.ht/~vdupras/duskos/lists [duskcc]: fs/doc/cc/index.txt +[hal]: fs/doc/hal.txt [livebootstrap]: https://github.com/fosslinux/live-bootstrap [m2planet]: https://git.sr.ht/~oriansj/M2-Planet [builder-hex0]: https://github.com/ironmeld/builder-hex0 diff --git a/fs/doc/stc.txt b/fs/doc/stc.txt @@ -1,73 +0,0 @@ -# Dusk OS is a STC - -This Forth is a Subroutine Thread Code (STC) Forth, that is, each reference to -words is a native call instead of being a reference. The drawback to this -structure, compared to DTC or ITC forths (the ones with a "next" (not the "next" -from iterators, the "core next of forth")), is significantly bigger binary size. -It's also more complex to "disassemble" a compiled word. The upsides, however, -are real juicy. - -First, there's speed. Calling words natively is faster than going through a -"next" loop. - -Second, and most importantly, there's the ability for forth code to freely mix -up with native code. That's huge and we use this extensively in Dusk through -its "meta compilation" capabilities. - -## Meta compilation - -The vast majority of forths have the "compile" class of words. That's your -grampa's compilation and it simply writes down a call to the specified word. -Dusk kernels go further than that and allow the compilation of further native -constructs. - -### Direct PS/RS control - -One of those constructs is direct control over the Parameter and Return Stacks. -The "p+," compiles native code that grows or shrink PS by the specified number -of bytes. "r+," does the same thing for RS. - -For example, here's the implementation of "drop" (from xcomp/bootlo.fs) - -code drop 4 p+, exit, - -Under a i386 kernel, this is the exact equivalent of writing "bp 4 i) add, ret," -to "here". - -In other words, meta compilation words in Dusk are a kind of limited portable -assembler allowing you to sprinkle native code around. - -### The A register - -The "A" register is a (ideally) hardware register that helps making some memory- -related operations less "PS-heavy". "A" is for "Address" and it will generally -contain a memory address upon which it will work. - -Other forths have "A" registers, such as Collapse OS, and this register is -generally directly used by the operator. Not here. The A register is extremely -short-lived and will be written over all the time. Few words are guaranteed to -preserve A, so you'll typically only use it in local, specific places. For -example, ">r" uses the A register: - -: >r -4 r+, RSP>A, A!, ; immediate - -RSP>A, compiles native code that copies the RS pointer to the A register and A!, -compiles native code that pops PS into the address contained in the A register. -By the way, "A" words are "binary modulated", so "8b A!," will compile a native -8b write. - -The A register generally saves us a roundtrip of the address to PS, resulting -in considerable speedups. Let's use another example that illustrates it better: - -: value doer , immediate does> compiling if LIT>A, then toptr@ execute ; - -When we refer to a value in compile mode, we need to compile its address and -then apply the appropriate "to" word (if any) to it. In "regular" forth, this -would be implemented with "litn" followed by, for example, "!". This means that -the address has to be pushed to PS and then popped again during !. With the A -register, we save ourselves this roundtrip. - -This is a small gain, but it's a gain that we get in values, local variables and -struct field access, so it adds up to nice sums. - -See "A register" section in doc/dict for a list of words. diff --git a/fs/doc/usage.txt b/fs/doc/usage.txt @@ -17,10 +17,24 @@ That being said, Dusk OS has some additional features that need explaining: ## Subroutine Threaded Code This Forth is a Subroutine Thread Code (STC) Forth, that is, each reference to -words is a native call instead of being a reference. This means that we don't -have a "next" interpret loop. It's calls all the way down. +words is a native call instead of being a reference. The drawback to this +structure, compared to DTC or ITC forths (the ones with a "next" (not the "next" +from iterators, the "core next of forth")), is significantly bigger binary size. +It's also more complex to "disassemble" a compiled word. The upsides, however, +are real juicy. -See doc/stc for detailed information on what it implies. +First, there's speed. Calling words natively is faster than going through a +"next" loop. + +Second, and most importantly, there's the ability for forth code to freely mix +up with native code. That's huge and we use this extensively in Dusk through +its "meta compilation" capabilities, which is what the HAL is all about. + +## The HAL + +Dusk features a Harmonized Assembly Layer on which DuskCC relies and allows +some really nice tricks. For regular usage, HAL knowledge isn't needed, so it's +not covered here. You can read about it in doc/hal. ## Number literals @@ -452,6 +466,7 @@ the interpreter, but you are hungry for more. What to read next? * doc/sys/io is central to many, many things in Dusk. * doc/sys/file lets you play with the filesystem. * doc/lib/alloc covers dynamic memory allocation. +* doc/hal covers the HAL on which the coolest Dusk features rely. * doc/cc covers Dusk's central feature: its C compiler. * doc/text/ed to edit text files.