Files
ddidderr 8b99e9607c feat(reconstruction): complete binary-backed C recovery
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
2026-08-23 16:41:17 +02:00

151 lines
4.6 KiB
C

#include "../tdkpin_game_application.h"
#include <assert.h>
#include <setjmp.h>
static unsigned g_sequence;
static Win16FarPtr g_application;
static uint8_t g_multimedia_args[3];
static uint16_t g_module_offset;
static uint16_t g_module_selector;
HINSTANCE16 g_win16_previous_instance;
HINSTANCE16 g_win16_instance;
Win16FarPtr g_win16_message_box;
static Win16FarPtr g_constructed_main;
static Win16FarPtr g_constructor_title;
static INT16 g_message_box_result;
static uint16_t g_exit_status;
static jmp_buf g_exit_jump;
static unsigned g_base_builder_calls;
void object_windows_application_initialize(Win16FarPtr application)
{
assert(++g_sequence == 1);
assert(application == g_application);
}
uint8_t multimedia_initialize_export(
uint8_t argument_1,
uint8_t argument_2,
uint8_t argument_3,
uint16_t argument_4,
uint16_t argument_5)
{
assert(++g_sequence == 2);
g_multimedia_args[0] = argument_1;
g_multimedia_args[1] = argument_2;
g_multimedia_args[2] = argument_3;
g_module_offset = argument_4;
g_module_selector = argument_5;
return 0;
}
Win16FarPtr tdkpin_main_window_construct(
Win16FarPtr object,
uint16_t vmt,
Win16FarPtr title,
Win16FarPtr parent)
{
assert(object == 0 && vmt == 0x009e && parent == 0);
g_constructor_title = title;
return g_constructed_main;
}
INT16 win16_call_message_box_far(
Win16FarPtr procedure,
HWND16 owner,
Win16FarPtr text,
Win16FarPtr caption,
UINT16 type)
{
assert(procedure == g_win16_message_box && owner == 0);
assert(text == win16_make_far_pointer(0x5000, 0x0245));
assert(caption == win16_make_far_pointer(0x5000, 0x022c));
assert(type == 0x2010);
return g_message_box_result;
}
_Noreturn void borland_runtime_exit(uint16_t status)
{
g_exit_status = status;
longjmp(g_exit_jump, 1);
}
void object_windows_build_window_class(
Win16FarPtr window, WNDCLASS16 *window_class)
{
assert(window == g_application);
*window_class = (WNDCLASS16){.style = 3, .background_brush = 6};
g_base_builder_calls++;
}
HICON16 LoadIcon16(HINSTANCE16 instance, Win16FarPtr resource)
{
assert(instance == g_win16_instance);
assert(resource == win16_make_far_pointer(0, 0x03e4));
return 0x1111;
}
HCURSOR16 LoadCursor16(HINSTANCE16 instance, Win16FarPtr resource)
{
assert(instance == 0 && resource == win16_make_far_pointer(0, 0x7f00));
return 0x2222;
}
HGDIOBJ16 GetStockObject16(INT16 object)
{
assert(object == 0 || object == 5);
return (HGDIOBJ16)(0x3000 + object);
}
int main(void)
{
static uint8_t dgroup[0x1000];
win16_reset_segment_bindings();
win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true);
win16_set_dgroup_selector(0x5000);
g_application = win16_make_far_pointer(0x7000, 2);
g_sequence = 0;
tdkpin_application_init_instance(g_application);
assert(g_sequence == 2);
assert(g_multimedia_args[0] == 1 && g_multimedia_args[1] == 1);
assert(g_multimedia_args[2] == 1);
assert(g_module_offset == 0x0222 && g_module_selector == 0x5000);
static uint8_t application_bytes[32];
win16_bind_segment(
0x7000, application_bytes, sizeof(application_bytes), true);
g_application = win16_make_far_pointer(0x7000, 2);
g_win16_previous_instance = 0;
g_constructed_main = win16_make_far_pointer(0x7100, 0x1234);
tdkpin_application_init_application(g_application);
assert(g_constructor_title == win16_make_far_pointer(0x5000, 0x022c));
assert(win16_read_far_pointer(g_application, 8) == g_constructed_main);
g_win16_previous_instance = 1;
g_win16_message_box = win16_make_far_pointer(0x6000, 0x1111);
g_message_box_result = 1;
g_exit_status = 0xffff;
if (setjmp(g_exit_jump) == 0) {
tdkpin_application_init_application(g_application);
assert(false);
}
assert(g_exit_status == 0);
WNDCLASS16 descriptor;
g_win16_instance = 0x4444;
g_base_builder_calls = 0;
tdkpin_build_main_window_class(g_application, &descriptor);
assert(descriptor.style == 0x3000);
assert(descriptor.icon == 0x1111 && descriptor.cursor == 0x2222);
assert(descriptor.background_brush == 0x3000);
assert(descriptor.instance == 0x4444);
assert(descriptor.class_extra_bytes == 0 && descriptor.window_extra_bytes == 0);
tdkpin_build_stock_brush_class_a(g_application, &descriptor);
assert(descriptor.style == 0x3803 && descriptor.background_brush == 0x3005);
tdkpin_build_stock_brush_class_b(g_application, &descriptor);
assert(descriptor.style == 0x3803 && descriptor.background_brush == 0x3005);
assert(g_base_builder_calls == 3);
return 0;
}