# DVX Loader

Bootstrap loader for the DVX desktop environment. Builds as `dvx.exe`
-- the only native executable in the system. Everything else is a
dynamically loaded DXE3 module.


## What It Does

1. Changes working directory to the directory containing `dvx.exe`
2. Truncates `dvx.log` and initializes logging
3. Calls `platformInit()` to suppress Ctrl+C and install signal handlers
4. Calls `platformRegisterDxeExports()` to register platform and C
   runtime symbols (libc, libm, libgcc) for DXE module resolution
5. Scans and loads all modules in two phases (see below)
6. Finds `shellMain()` via `dlsym` across loaded modules
7. Calls `shellMain()` -- the shell takes over from here
8. On return, closes all module handles in reverse load order


## Two-Phase Module Loading

### Phase 1: Libraries (libs/*.lib)

Recursively scans the `LIBS/` directory 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.

Load order (via 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)
```

### Phase 2: Widgets (widgets/*.wgt)

Recursively scans the `WIDGETS/` directory for `.wgt` files. Widget modules may
also have `.dep` files (e.g., `textinpt.dep` lists `texthelp`).
Loaded in topological order, same as libs.

After loading each module, the loader checks for a `wgtRegister`
export. If present, it is called immediately so the widget registers
its class(es) and API with the core.


## Dependency File Format

Plain text, one dependency base name per line. Empty lines and lines
starting with `#` are ignored. Names are case-insensitive.

Example (`combobox.dep`):
```
texthelp
listhelp
```


## Hosted Components

### dvxLog()

The global logging function is defined in `loaderMain.c` and exported
to all DXE modules. It appends a line to `dvx.log`, opening and
closing the file per write so it is never held open.

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

### stb_ds

The `STB_DS_IMPLEMENTATION` is compiled into the loader with
`STBDS_REALLOC` and `STBDS_FREE` overridden to use `dvxRealloc` and
`dvxFree`. This means all `arrput`/`hmput`/`arrfree` calls in DXE
code route through the per-app memory tracker, so stb_ds memory is
attributed correctly in the Task Manager's memory column. stb_ds
functions are exported to all DXE modules via the platform export
table.

### Platform Layer

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

* Video: VESA VBE init, LFB mapping, mode enumeration
* Input: INT 33h mouse, INT 16h keyboard, CuteMouse wheel API
* Spans: `rep stosl`/`rep movsd` asm inner loops (8/16/32 bpp)
* DXE: symbol registration, symbol overrides
* Crash: signal handler installation, register dump logging
* System: memory info, directory creation, path utilities

### Per-App Memory Tracking

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

| C Symbol | Mapped To | Effect |
|----------|-----------|--------|
| `malloc` | `dvxMalloc` | Allocations attributed to `currentAppId` |
| `calloc` | `dvxCalloc` | Same |
| `realloc` | `dvxRealloc` | Transfers attribution on resize |
| `free` | `dvxFree` | Decrements app's tracked usage |
| `strdup` | `dvxStrdup` | Tracks the duplicated string |

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()`. When an app is reaped, `dvxMemResetApp()` zeroes
its counter.


## Files

| File | Description |
|------|-------------|
| `loaderMain.c` | Entry point, module scanner, dependency resolver, logger |
| `Makefile` | Builds `bin/dvx.exe` |


## Build

```
make            # builds bin/dvx.exe
make clean      # removes objects and binary
```

The loader links `loaderMain.c` + `dvxPlatformDos.c` into a native
DJGPP executable. The CWSDPMI stub is prepended via exe2coff +
CWSDSTUB.EXE for standalone execution.
