Replace the partial mechanics transcriptions with a separate, readable C11 reconstruction of the complete Win16 image while preserving the original raw Ghidra export as immutable evidence. Cover all ordinary and overlapping entry points, Borland runtime behavior, Win16 imports, segmented data, callbacks, resources, indirect control flow, physics, rendering, persistence, and startup/shutdown lifecycles. Add deterministic extraction and audit tooling plus address-linked ledgers for functions, imports, DGROUP ranges and objects, relocations, resources, and callbacks. The final gate records zero raw, partial, restored, unknown, blocked, or unclassified required units. Keep the semantic-fidelity boundary explicit: the portable C is not claimed to reproduce a byte-identical Borland NE build. Add strict focused harnesses for every reconstructed C unit, exact resource round-trip checks, and a 16-bit Borland Real48 reference probe. No Rust source or Cargo metadata is changed in this phase. Test Plan: - `bash original/tools/test_reconstructed_c.sh` -- passed - `bash original/tools/probe_real48_reference.sh` -- passed bit-for-bit - `python3 original/tools/audit_reconstruction.py --require-complete` -- passed - `git diff --cached --check` -- passed - `git diff HEAD -- '*.rs' Cargo.toml Cargo.lock` -- empty
103 lines
2.9 KiB
C
103 lines
2.9 KiB
C
#include "../tdkpin_borland_startup.h"
|
|
|
|
#include <assert.h>
|
|
#include <setjmp.h>
|
|
|
|
HINSTANCE16 g_win16_previous_instance;
|
|
HINSTANCE16 g_win16_instance;
|
|
uint16_t g_win16_show_command;
|
|
Win16FarPtr g_borland_command_line;
|
|
uint16_t g_borland_windows_mode;
|
|
uint16_t g_borland_huge_pointer_increment;
|
|
uint8_t g_borland_cpu_level;
|
|
|
|
static jmp_buf g_termination_jump;
|
|
static uint8_t g_termination_status;
|
|
static unsigned g_call_count;
|
|
static uint16_t g_init_app_result;
|
|
static uint32_t g_win_flags;
|
|
static BorlandWin16StartupRegisters g_expected;
|
|
|
|
void WaitEvent16(uint16_t event)
|
|
{
|
|
assert(g_call_count++ == 0);
|
|
assert(event == 0);
|
|
assert(g_win16_previous_instance == g_expected.previous_instance);
|
|
assert(g_win16_instance == g_expected.instance);
|
|
assert(g_win16_show_command == g_expected.show_command);
|
|
assert(g_borland_command_line == g_expected.command_line);
|
|
assert(g_borland_windows_mode ==
|
|
win16_far_selector(g_expected.command_line));
|
|
}
|
|
|
|
uint16_t InitApp16(HINSTANCE16 instance)
|
|
{
|
|
assert(g_call_count++ == 1);
|
|
assert(instance == g_expected.instance);
|
|
return g_init_app_result;
|
|
}
|
|
|
|
uint32_t GetWinFlags16(void)
|
|
{
|
|
assert(g_call_count++ == 2);
|
|
return g_win_flags;
|
|
}
|
|
|
|
_Noreturn void win16_dos_terminate(uint8_t status)
|
|
{
|
|
g_termination_status = status;
|
|
longjmp(g_termination_jump, 1);
|
|
}
|
|
|
|
static void run_success(uint32_t flags, uint8_t expected_cpu_level)
|
|
{
|
|
g_call_count = 0;
|
|
g_init_app_result = 1;
|
|
g_win_flags = flags;
|
|
g_borland_huge_pointer_increment = 0;
|
|
borland_initialize_win16_runtime(&g_expected);
|
|
assert(g_call_count == 3);
|
|
assert(g_borland_cpu_level == expected_cpu_level);
|
|
assert(g_borland_huge_pointer_increment == 8);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
g_expected = (BorlandWin16StartupRegisters){
|
|
.loader_ax = 1,
|
|
.command_line = win16_make_far_pointer(0x3456, 0x789a),
|
|
.show_command = 7,
|
|
.previous_instance = 0x1111,
|
|
.instance = 0x2222,
|
|
};
|
|
|
|
run_success(0x40, 0); /* WF_CPU086 */
|
|
run_success(0x02, 1); /* WF_CPU286 */
|
|
run_success(0x04, 2); /* WF_CPU386 */
|
|
run_success(0x0104, 2); /* only AL participates */
|
|
|
|
g_expected.loader_ax = 0;
|
|
g_call_count = 0;
|
|
g_win16_instance = 0xaaaa;
|
|
if (setjmp(g_termination_jump) == 0) {
|
|
borland_initialize_win16_runtime(&g_expected);
|
|
assert(false);
|
|
}
|
|
assert(g_termination_status == 0xff);
|
|
assert(g_call_count == 0 && g_win16_instance == 0xaaaa);
|
|
|
|
g_expected.loader_ax = 1;
|
|
g_call_count = 0;
|
|
g_init_app_result = 0;
|
|
g_borland_huge_pointer_increment = 0xaaaa;
|
|
if (setjmp(g_termination_jump) == 0) {
|
|
borland_initialize_win16_runtime(&g_expected);
|
|
assert(false);
|
|
}
|
|
assert(g_termination_status == 0xff);
|
|
assert(g_call_count == 2);
|
|
assert(g_win16_instance == g_expected.instance);
|
|
assert(g_borland_huge_pointer_increment == 0xaaaa);
|
|
return 0;
|
|
}
|