DVX_GUI/loader
2026-03-26 21:15:20 -05:00
..
loaderMain.c Dynamic memory tracking improved. Callback app reaping fixed. 2026-03-26 19:06:13 -05:00
Makefile MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
README.md Code and docs cleanup. 2026-03-26 21:15:20 -05:00

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.

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.