| .. | ||
| loaderMain.c | ||
| Makefile | ||
| README.md | ||
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
- Changes working directory to the directory containing
dvx.exe - Truncates
dvx.logand initializes logging - Calls
platformInit()to suppress Ctrl+C and install signal handlers - Calls
platformRegisterDxeExports()to register platform and C runtime symbols (libc, libm, libgcc) for DXE module resolution - Scans and loads all modules in two phases (see below)
- Finds
shellMain()viadlsymacross loaded modules - Calls
shellMain()-- the shell takes over from here - 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.
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 movsdasm 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.