# Bootstrap guide This guide tells you about the gory details you need to know to create or maintain a port of Collapse OS. This is some pretty hairy stuff and you should have read doc/usage, doc/impl and doc/cross first. Is is also recommended that you use the z80 port (arch/z80/blk.fs) as a reference as you read this guide. What is Collapse OS? It is a binary placed either in ROM on in RAM by a bootloader. That binary, when executed, initializes itself to a Forth interpreter. In most cases, that Forth interpreter will have some access to a mass storage device, which allows it to access Collapse OS' disk blocks and bootstrap itself some more. This binary can be separated in 5 distinct layers: 1. Arch-specific boot code (B302 for Z80) 2. Arch-specific boot words (B304 for Z80) 3. Arch-independant core words (low) (B210) 4. Drivers, might contain arch-specific code 5. Arch-independant core words (high) (B226) # Boot code The boot code, which is arch-specific, contains these elements: 1. A jump to the early initialization routine 2. The stable ABI (see doc/impl) 3. Core routines. At this point, lblnext, lblxt, lblcell, lblval and lbldoes are set. 4. The early initialization routines which initializes PSP and RSP and then executes BOOT from its address in the stable ABI. # Boot words Then come the implementation of core Forth words in native assembly. This is a limited set of words that implement core operations: QUIT ABORT EXIT BYE RCNT SCNT * /MOD TICKS (b) (n) (br) (?br) (next) C@ @ C! ! AND OR XOR NOT + - R> >R R~ DUP ?DUP DROP SWAP OVER ROT EXECUTE On CPUs having I/O ports, PC! and PC@ are also needed. This is the absolute minimum set of words that a port needs to be functional. If it only implements those words, however, it's going to be very slow. Some forth core words are defined with "?:" instead of ":". If those words are part of the native words, they're going to be used instead of their forth version and will result in a much faster binary. # Core words (low) Then comes the part where we begin defining words in Forth. Core words are designed to be cross-compiled, from a full Forth interpreter. This means that it has access to more than boot words. This comes with tricky limitations. See doc/cross. # Drivers Core words don't include (key?) and (emit) implementations be- cause that's hardware-dependant. This is where we need to load code that implement it, as well as any other driver code we want to include in the binary. This includes subsystems. We do it now because if we wait until the high layer of core words is loaded, we'll have messed up immediates and ":" will be broken. If we load our code before, we won't have access to a wide vocabulary. See doc/drivers for more details. # Core words (high) The final layer of core words contains the BOOT word as well as tricky immediates which, if they're defined sooner, mess cross compilation up. Once this layer is loaded, we become severly limited in the words we can use without messing up. # Building it So that's the anatomy of a Collapse OS binary. How do you build one? If your machine is already covered by a recipe, you're in luck: follow instructions. If you're deploying to a new machine, you'll have to write a new xcomp (cross compilation) unit. Let's look at its anatomy. First, we have constants. Some of them are device- specific, but some of them are always there. SYSVARS is the address at which the RAM starts on the system. System variables will go there and use $80 bytes. See doc/impl. HERESTART determines where... HERE is at startup. 0 means "same as CURRENT". You will likely need more constants than that, but this depends on your architecture and drivers. Then comes time time to load the blocks that will compile the thing. Order is important. First come XCOMP followed by the assembler (example, Z80A). Then comes CPU-specific macros, constants further loader words such as the "C" units. They always live in B301 (see doc/blk). The loader word for this is ARCHM. It's important that it's loaded before XCOMPC because it's being executed during xcomp, not included in the target binary. Now comes the real deal: XCOMPC. It's the "forth" part of xcomp and from this point on, we're in "target" mode. Everything we define ends up in the target binary (see doc/cross). The first unit that comes after this is the "C" unit (example: Z80C). "C" is for "code". It's the layers 1 and 2 from the layer list at the top of this document. We're done with the CPU-specific part! Now comes COREL, for "core words (low)". Then comes the custom part: drivers and subsystems. This part is heavily dependant on the target system and varies a lot. After that, you need to define a INIT word. This will be called by BOOT right before spitting the prompt. This is usually used to call init words of all subsystems. All xcomp unit end with XWRAP, a helper word that loads "high" core words and then wrap things up (set CURRENT and LATEST in the stable ABI). You're done! To produce a Collapse OS binary, you run that xcomp unit and then observe the values of XORG and HERE. That will give you the start and stop offset of your binary, which you can then copy to your target media. Good luck!