# Cross compilation tools

The unit at [xcomp/tools.fs] is a collection of words helping with cross
compiling a Dusk kernel. Thos tools are mostly about managing offsets of the
kernel's cross compiled dictionary.

To be sure: Dusk doesn't cross compile Forth code. It's too hairy. However, the
native code that the kernel assembles is organized in words, which will live
at at an address that is different on their target host than on the system
they've just been built on.

These differences have to be "fudged up" so that the final binary is something
that runs.

The basic idea is that code words are created through "xcode", which acts like
"code" except that it creates its entry in the "xbindict" dictionary. It also
never calls "wordmark," (none of the target arches actually using wordmark, use
xcomp/tools to build their kernel).

Before we begin spitting our binary we set "org" and "binstart" (from
[asm/label]), which means that we can derive a "xoffset", that is, the
difference in bytes between where the dictionary currently lives and where it's
supposed to live on the target machine.

Then, we spit the stuff.

This will create a dictionary that is functional as it is built, which is
important because we sometimes have to refer to words created with "xcode" at
compile time (we do so through "xwordlbl").

However, that dictionary won't run on its target machine because its "prev"
references are wrong. We apply "orgifydict" on it, which will "break" it on
the build machine, but will "fix" it on the target machine. From that point on,
that dictionary becomes an opaque binary, untraversable from the build machine.

We're ready to write the kernel to the target media.

## kernelbegin/kernelend

Kernel units should call "kernelbegin" right as they begin spitting their binary
contents and "kernelend" (or "kernelendbe" if CPU is big endian) when they're
done spitting binary. This sets the "kernel" and "kernellen" variables which can
then be used by deploy scripts to figure out what to write.

"kernelend" also takes care of calling "orgifydict".

## SYSVARS offset

This unit also contains the offset of all SYSVARS, as described in [doc/data].
The name of the constant is the name of the SYSVAR with a "o" prefix.

## API

### Constants

oXXX       SYSVARS offset (example oCOMPILING yields 4)

### Variables

xbindict  Dictionary of words created through "xcode"

### Values

kernel    Address of the last compiled kernel
kernellen Size in bytes of the last compiled kernel

### Words

tgtallot ( tgtpc -- )
  Call allot0 with "n" being enough to bring "pc" to value "tgtpc". If that
  target has already been passed, raise an error.

xoffset ( -- off )
  Add this offset to a host address to yield a target address.

xcode ( "name" -- )
  Like "code", but add entry to "xbindict".

xlatest ( -- a )
  "xbindict" latest entry with "xoffset" applied

xwordlbl ( "name" -- pc )
  Yields *target* (xoffset applied) address of word "name" found in "xbindict".

orgifydict ( 'dict -- )
  Apply "xoffset" to all "prev" references in dict. After having been orgified,
  "dict" becomes opaque. To allow multiple xdict to be created one after the
  other, "'dict" is set to 0.

orgifydictbe ( 'dict -- )
  Same as orgifydict but write dict link with be! instead.

kernelbegin ( -- )
  Sets "org" and "kernel" to "here" and resets "xbindict".

kernelend ( -- )
  Sets "kernellen" and calls "orgifydict".

kernelendbe ( -- )
  Same as "kernelend" byt calls "orgifydictbe" instead.
