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

317 lines
11 KiB
C

#include "../tdkpin_window_messages.h"
#include <assert.h>
Win16FarPtr g_object_windows_application;
HINSTANCE16 g_win16_previous_instance;
HINSTANCE16 g_win16_instance;
uint16_t g_win16_show_command;
Win16FarPtr g_win16_message_box;
Win16FarPtr g_object_windows_dispatch_proc;
uint16_t g_object_windows_thunk_code_selector;
Win16FarPtr g_object_windows_free_thunk;
Win16FarPtr g_object_windows_message_hook;
Win16FarPtr g_object_windows_creating_object;
static HWND16 g_dialog_item;
static uint16_t g_dlg_code;
static HWND16 g_focus;
static HWND16 g_parent;
static unsigned g_parent_calls;
static HWND16 g_lookup_window;
static Win16FarPtr g_window_object;
static Win16FarPtr g_child_object;
static Win16FarPtr g_called_proc;
static Win16FarPtr g_called_object;
static ObjectWindowsMessage *g_called_message;
static uint16_t g_window_word;
HWND16 GetDlgItem16(HWND16 dialog, INT16 control_id)
{
assert(dialog == 0x77);
(void)control_id;
return g_dialog_item;
}
LRESULT16 SendMessage16(
HWND16 window, UINT16 message, WPARAM16 wparam, LPARAM16 lparam)
{
assert(window == g_dialog_item && message == 0x87);
assert(wparam == 0 && lparam == 0);
return g_dlg_code;
}
HWND16 GetFocus16(void)
{
return g_focus;
}
HWND16 GetParent16(HWND16 window)
{
assert(window == g_focus);
g_parent_calls++;
return g_parent;
}
BOOL16 IsWindow16(HWND16 window)
{
g_lookup_window = window;
return window != 0;
}
int32_t GetWindowLong16(HWND16 window, INT16 index)
{
assert(window != 0 && index == -4);
return (int32_t)win16_make_far_pointer(0x6000, 0x0100);
}
Win16Handle GetProp16(HWND16 window, Win16FarPtr name)
{
Win16FarPtr object = window == 0x55 ? g_child_object : 0;
return win16_far_offset(name) == 0x067a
? win16_far_selector(object)
: win16_far_offset(object);
}
uint16_t GetWindowWord16(HWND16 window, INT16 index)
{
assert(window != 0 && index == -12);
return g_window_word;
}
void win16_call_object_event_handler(
Win16FarPtr procedure, Win16FarPtr object, Win16FarPtr event)
{
g_called_proc = procedure;
g_called_object = object;
g_called_message = (ObjectWindowsMessage *)(uintptr_t)event;
}
void win16_call_object_message_handler(
Win16FarPtr procedure,
Win16FarPtr object,
ObjectWindowsMessage *message)
{
g_called_proc = procedure;
g_called_object = object;
g_called_message = message;
}
void win16_call_object_message_hook(
Win16FarPtr procedure,
Win16FarPtr object,
Win16FarPtr handler,
HWND16 window,
UINT16 message,
WPARAM16 wparam,
LPARAM16 lparam)
{
(void)procedure;
(void)object;
(void)handler;
(void)window;
(void)message;
(void)wparam;
(void)lparam;
assert(false);
}
static void write_far(uint16_t offset, Win16FarPtr pointer)
{
win16_write_u16(
win16_dgroup_pointer(offset), 0, win16_far_offset(pointer));
win16_write_u16(
win16_dgroup_pointer((uint16_t)(offset + 2)),
0,
win16_far_selector(pointer));
}
static void write_dispatch_table(
uint16_t vmt,
uint16_t table,
uint16_t id,
Win16FarPtr handler)
{
win16_write_u16(win16_dgroup_pointer((uint16_t)(vmt + 4)), 0, table);
win16_write_u16(win16_dgroup_pointer(table), 0, 0);
win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 2)), 0, 0xffff);
win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 4)), 0, 0xffff);
win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 6)), 0, 1);
win16_write_u16(win16_dgroup_pointer((uint16_t)(table + 8)), 0, id);
write_far((uint16_t)(table + 10), handler);
}
static void reset_call(void)
{
g_called_proc = 0;
g_called_object = 0;
g_called_message = 0;
g_dialog_item = 0;
g_dlg_code = 0;
g_focus = 0;
g_parent = 0;
g_parent_calls = 0;
}
int main(void)
{
static uint8_t dgroup[0x1000];
static uint8_t code[0x200];
static uint8_t stack[0x100];
static uint8_t window_bytes[64];
static uint8_t child_bytes[64];
win16_reset_segment_bindings();
win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true);
win16_set_dgroup_selector(0x5000);
win16_bind_segment(0x6000, code, sizeof(code), false);
win16_bind_segment(0x7000, window_bytes, sizeof(window_bytes), true);
win16_bind_segment(0x7100, child_bytes, sizeof(child_bytes), true);
win16_bind_segment(0x7200, stack, sizeof(stack), true);
g_window_object = win16_make_far_pointer(0x7000, 2);
g_child_object = win16_make_far_pointer(0x7100, 2);
uint16_t window_vmt = 0x0100;
uint16_t child_vmt = 0x0200;
win16_write_u16(g_window_object, 0, window_vmt);
win16_write_u16(g_child_object, 0, child_vmt);
win16_write_u16(g_window_object, 4, 0x77);
Win16FarPtr menu_handler = win16_make_far_pointer(0x6100, 0x1000);
Win16FarPtr control_handler = win16_make_far_pointer(0x6100, 0x2000);
Win16FarPtr notify_handler = win16_make_far_pointer(0x6100, 0x3000);
Win16FarPtr default_handler = win16_make_far_pointer(0x6100, 0x4000);
Win16FarPtr default_control = win16_make_far_pointer(0x6100, 0x5000);
write_dispatch_table(window_vmt, 0x0300, 0x8005, control_handler);
write_dispatch_table(child_vmt, 0x0340, 0xa010, menu_handler);
/* Parent table supplies the notification id as a second node. */
win16_write_u16(win16_dgroup_pointer(0x0340), 0, 0x0380);
win16_write_u16(win16_dgroup_pointer(0x0380), 0, 0);
win16_write_u16(win16_dgroup_pointer(0x0382), 0, 0xffff);
win16_write_u16(win16_dgroup_pointer(0x0384), 0, 0xffff);
win16_write_u16(win16_dgroup_pointer(0x0386), 0, 1);
win16_write_u16(win16_dgroup_pointer(0x0388), 0, 0x9002);
write_far(0x038a, notify_handler);
write_far((uint16_t)(window_vmt + 0x0c), default_handler);
write_far((uint16_t)(window_vmt + 0x14), default_control);
write_far((uint16_t)(window_vmt + 0x10), default_handler);
write_far((uint16_t)(child_vmt + 0x10), default_handler);
write_far((uint16_t)(child_vmt + 0x18), default_handler);
write_far((uint16_t)(child_vmt + 0x14), default_control);
ObjectWindowsMessage *message = (ObjectWindowsMessage *)&stack[16];
Win16FarPtr message_far = win16_make_far_pointer(0x7200, 16);
(void)message_far;
reset_call();
*message = (ObjectWindowsMessage){.wparam = 0x0010, .lparam = 0};
g_focus = 0x66;
g_parent = 0x55;
object_windows_wm_command(g_window_object, message);
assert(g_parent_calls == 1 && g_lookup_window == 0x55);
assert(g_called_proc == menu_handler && g_called_object == g_child_object);
reset_call();
*message = (ObjectWindowsMessage){.wparam = 0x6000, .lparam = 0};
object_windows_wm_command(g_window_object, message);
assert(g_called_proc == default_handler &&
g_called_object == g_window_object);
reset_call();
*message = (ObjectWindowsMessage){
.wparam = 0x0100,
.lparam = (LPARAM16)0x00020055u,
};
g_dialog_item = 0x55;
object_windows_wm_command(g_window_object, message);
assert(g_called_proc == notify_handler && g_called_object == g_child_object);
reset_call();
*message = (ObjectWindowsMessage){.wparam = 5, .lparam = 0x66};
object_windows_wm_command(g_window_object, message);
assert(g_called_proc == control_handler &&
g_called_object == g_window_object);
reset_call();
*message = (ObjectWindowsMessage){.wparam = 0x1000, .lparam = 0x66};
object_windows_wm_command(g_window_object, message);
assert(g_called_proc == default_control &&
g_called_object == g_window_object);
reset_call();
win16_write_u8(win16_far_add_offset(g_window_object, 0x16), 1);
*message = (ObjectWindowsMessage){.wparam = 0x0100, .lparam = 0};
g_dialog_item = 0x55;
g_dlg_code = 0x30;
object_windows_wm_command(g_window_object, message);
assert((uint16_t)message->lparam == 0x55);
assert(g_called_proc == default_handler);
assert(g_called_object == g_child_object);
reset_call();
*message = (ObjectWindowsMessage){.wparam = 2, .lparam = 0};
object_windows_route_scroll_notification(g_window_object, message);
assert(g_called_proc == default_handler);
reset_call();
*message = (ObjectWindowsMessage){
.wparam = 2,
.lparam = (LPARAM16)0x00550000u,
};
object_windows_route_scroll_notification(g_window_object, message);
assert(g_called_proc == notify_handler && g_called_object == g_child_object);
reset_call();
*message = (ObjectWindowsMessage){
.wparam = 2,
.lparam = (LPARAM16)0x00660000u,
};
g_window_word = 5;
object_windows_route_scroll_notification(g_window_object, message);
assert(g_called_proc == control_handler &&
g_called_object == g_window_object);
reset_call();
*message = (ObjectWindowsMessage){
.wparam = 2,
.lparam = (LPARAM16)0x00660000u,
};
g_window_word = 0x1000;
object_windows_route_scroll_notification(g_window_object, message);
assert(g_called_proc == default_control &&
g_called_object == g_window_object);
reset_call();
*message = (ObjectWindowsMessage){
.window = 0x77,
.wparam = 0x0010,
};
object_windows_route_command_target(g_window_object, message);
assert(g_called_proc == default_handler &&
g_called_object == g_window_object);
win16_write_u16(g_window_object, 6, win16_far_offset(g_child_object));
win16_write_u16(g_window_object, 8, win16_far_selector(g_child_object));
message->window = 0x66;
object_windows_route_command_target(g_window_object, message);
assert(g_called_proc == menu_handler && g_called_object == g_child_object);
win16_write_u16(g_window_object, 6, 0);
win16_write_u16(g_window_object, 8, 0);
message->window = 0x55;
object_windows_route_command_target(g_window_object, message);
assert(g_called_proc == menu_handler && g_called_object == g_child_object);
reset_call();
*message = (ObjectWindowsMessage){.message = 0x0111, .wparam = 5};
object_windows_forward_event_to_parent(g_window_object, message);
assert(g_called_proc == 0);
win16_write_u16(g_window_object, 6, win16_far_offset(g_child_object));
win16_write_u16(g_window_object, 8, win16_far_selector(g_child_object));
object_windows_forward_event_to_parent(g_window_object, message);
assert(g_called_proc == default_control &&
g_called_object == g_child_object);
reset_call();
*message = (ObjectWindowsMessage){.message = 2};
g_window_word = 5;
object_windows_forward_event_to_parent(g_window_object, message);
assert(g_called_proc == default_control &&
g_called_object == g_child_object);
return 0;
}