# DVX Loader

Bootstrap loader for the DVX desktop environment. Builds as
`bin/dvx.exe` -- the only native executable in the system. Everything
else is a dynamically loaded DXE3 module: libraries (`.lib`), widget
plug-ins (`.wgt`), and applications (`.app`).


## What It Does

On launch, `dvx.exe` performs these steps in order:

1. `chdir` into the directory containing the executable. From that
   point on, the working directory is the install root and all
   relative paths (`LIBS/`, `WIDGETS/`, `APPS/`, `CONFIG/`, `SYSTEM/`)
   resolve relative to it.
2. Truncate `dvx.log`, then use append-per-write thereafter.
3. Call `platformInit()` to suppress Ctrl+C, mask the default DOS
   break handler, and prepare the signal-handling path for later.
4. Switch the display into VGA mode 13h and paint the splash screen
   from `SYSTEM/SPLASH.RAW` (raw palette + pixels, as produced by
   `bmp2raw`).
5. Call `platformRegisterDxeExports()` to publish platform entry
   points and a curated set of libc / libm / libgcc symbols to the
   DXE dynamic symbol resolver. This makes the loader the single
   source of truth for these symbols so that every DXE module
   resolves them consistently.
6. Scan and load all modules in two phases (see below), updating the
   splash progress bar as each module loads.
7. Check whether help files need rebuilding (the module set changed
   since the last boot); if so, run the integrated help compiler.
8. Find `shellMain` via `dlsym` across every loaded module and call
   it. The shell takes over from here.
9. When `shellMain` returns, close every module handle in reverse
   load order and exit.


## Two-Phase Module Loading

### Phase 1: Libraries (`LIBS/*.lib`)

Recursive scan of the `LIBS/` tree for `.lib` files. Each module may
have a `.dep` file (same base name, `.dep` extension) listing
base names of modules that must load first. The loader resolves the
dependency graph and loads in topological order.

Typical load order (determined entirely by `.dep` files):

```
libtasks.lib   (no deps)
libdvx.lib     (deps: libtasks)
texthelp.lib   (deps: libtasks, libdvx)
listhelp.lib   (deps: libtasks, libdvx)
dvxshell.lib   (deps: libtasks, libdvx, texthelp, listhelp)
taskmgr.lib    (deps: dvxshell, libtasks, libdvx, texthelp, listhelp)
serial.lib     (deps: libtasks, libdvx)
dvxsql.lib     (deps: libtasks, libdvx)
basrt.lib      (deps: libtasks, libdvx)
```

### Phase 2: Widgets (`WIDGETS/*.wgt`)

Same algorithm applied to the `WIDGETS/` tree. Widget modules may
also declare dependencies (for example, `comboBox` depends on
`texthelp` and `listhelp`).

Immediately after each widget module loads, the loader looks up the
symbol `wgtRegister` and, if present, calls it. That entry point
registers the widget's class and API with the core so the shell and
apps can then create instances of it.


## Dependency File Format

`.dep` files are plain text. Each line is one dependency base name
(case-insensitive, no extension). Blank lines and lines starting
with `#` are ignored.

Example (`comboBox.dep`):

```
# combobox uses the shared text-editing helpers and the shared
# list/dropdown helpers.
texthelp
listhelp
```

Missing dependencies are detected before any module is loaded and
abort the boot with a clear fatal error, so a misconfigured
install fails early rather than crashing partway through.


## Hosted Components

### `dvxLog()`

The global logging function is defined in `loaderMain.c` and exported
to every DXE. It appends a single line to `dvx.log`, opening and
closing the file per call. This means the log is never held open and
its contents are safe to read even if the system crashes.

```c
void dvxLog(const char *fmt, ...);
```

### `stb_ds`

`STB_DS_IMPLEMENTATION` is compiled into the loader so the
implementation is shared across the loader's translation units
(`loaderMain.o`, `dvxPrefs.o`). The loader uses plain `realloc` /
`free` for stb_ds; per-app memory tracking applies to DXE allocations
via the export table mappings described below.

### Platform Layer

`dvxPlatformDos.c` is compiled into the loader (not into
`libdvx.lib`). All platform functions are exported to DXE modules via
the export table. This includes:

* Video -- VESA VBE init, linear framebuffer mapping, mode
  enumeration
* Input -- INT 33h mouse, INT 16h keyboard, CuteMouse wheel API
* Span fills / copies -- `rep stosl` / `rep movsd` asm inner loops at
  8, 16, and 32 bpp
* DXE support -- symbol registration, symbol overrides
* Crash handling -- signal handler installation, register dump
  logging
* System utilities -- memory info, directory creation, path helpers

### Per-App Memory Tracking

The DXE export table maps the standard C allocation symbols to
DVX-tracked wrappers:

| C symbol   | Mapped to       | Behaviour |
|------------|-----------------|-----------|
| `malloc`   | `dvxMalloc`     | Allocation is attributed to the current app ID. |
| `calloc`   | `dvxCalloc`     | Same. |
| `realloc`  | `dvxRealloc`    | Attribution transfers with the resized block. |
| `free`     | `dvxFree`       | Decrements the app's tracked usage. |
| `strdup`   | `dvxStrdup`     | Tracks the duplicated buffer. |

This is transparent to DXE code -- apps call `malloc` normally and
the tracked wrapper runs instead. The Task Manager reads per-app
usage via `dvxMemGetAppUsage()`, and `dvxMemResetApp()` zeros the
counter when an app is reaped.

### Integrated Help Compilation

The help compiler (`dvxhlpc.c`) is built a second time as an object
file with `-DHLPC_NO_MAIN` and linked into the loader. On boot, the
loader compares the currently-loaded module set against the last-run
state recorded in `DVX.INI`. If it has changed, the loader
re-compiles the affected help files before starting the shell, so
newly-installed widgets and libraries contribute to the system help
without a manual step.

### Splash Screen

`SYSTEM/SPLASH.RAW` is a 320x200 256-colour image in raw
palette-plus-pixels format (as emitted by `bmp2raw`). The loader
drops to VGA mode 13h, paints the splash, and updates a progress bar
as modules load. The splash stays up until the shell switches into
its configured VESA mode.


## Files

| File | Description |
|------|-------------|
| `loaderMain.c` | Entry point, module scanner, dependency resolver, logger, splash, help-recompile hook. |
| `stddclmr.h`   | Standard disclaimer. Included by `loaderMain.c`; leave it alone. |
| `Makefile`     | Builds `bin/dvx.exe`. |


## Build

```
make            # build bin/dvx.exe
make clean      # remove the binary and intermediate objects
```

The loader is cross-compiled with the DJGPP toolchain
(`i586-pc-msdosdjgpp-gcc`). The resulting `a.out` is converted with
`exe2coff`, and the CWSDPMI stub (`CWSDSTUB.EXE`) is prepended so the
final `dvx.exe` runs stand-alone on DOS without a separate DPMI host.

Linked translation units: `loaderMain.c` + `dvxPlatformDos.c` +
`dvxPlatformUtil.c` + `dvxPrefs.c` + `dvxhlpc.c` (as
`-DHLPC_NO_MAIN`).
