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
290 lines
9.2 KiB
C
290 lines
9.2 KiB
C
#include "../tdkpin_window_placement.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
|
|
HINSTANCE16 g_win16_instance;
|
|
Win16FarPtr g_object_windows_creating_object;
|
|
|
|
static bool g_enter = true;
|
|
static Win16FarPtr g_parent_mdi_client;
|
|
static Win16FarPtr g_duplicate_result;
|
|
static uint8_t g_flags;
|
|
static bool g_register_result;
|
|
static Win16FarPtr g_class_name;
|
|
static HWND16 g_create_result;
|
|
static HWND16 g_dialog_item_result;
|
|
static Win16FarPtr g_existing_object;
|
|
static int32_t g_previous_wndproc;
|
|
static unsigned g_bind_calls;
|
|
static unsigned g_created_calls;
|
|
static unsigned g_create_ex_calls;
|
|
static unsigned g_mdi_calls;
|
|
|
|
bool borland_enter_object_constructor(
|
|
BorlandObjectCallFrame *frame, uint16_t offset)
|
|
{
|
|
assert(offset == 0);
|
|
if (g_enter && frame->vmt_argument != 0) {
|
|
win16_write_u16(frame->object, 0, frame->vmt_argument);
|
|
}
|
|
return g_enter;
|
|
}
|
|
|
|
Win16FarPtr object_windows_object_construct(
|
|
Win16FarPtr object, uint16_t vmt, Win16FarPtr parent)
|
|
{
|
|
assert(vmt == 0);
|
|
win16_write_u16(object, 6, win16_far_offset(parent));
|
|
win16_write_u16(object, 8, win16_far_selector(parent));
|
|
return object;
|
|
}
|
|
|
|
Win16FarPtr borland_far_strdup(Win16FarPtr source)
|
|
{
|
|
assert(source != 0);
|
|
return g_duplicate_result;
|
|
}
|
|
|
|
Win16FarPtr win16_def_window_proc_pointer(void)
|
|
{
|
|
return win16_make_far_pointer(0x6000, 0x0100);
|
|
}
|
|
|
|
Win16FarPtr win16_def_mdi_child_proc_pointer(void)
|
|
{
|
|
return win16_make_far_pointer(0x6000, 0x0200);
|
|
}
|
|
|
|
void object_windows_update_flags(
|
|
Win16FarPtr object, bool set, uint8_t mask)
|
|
{
|
|
assert(set && mask == 8);
|
|
g_flags |= mask;
|
|
win16_write_u8(win16_far_add_offset(object, 0x16), g_flags);
|
|
}
|
|
|
|
Win16FarPtr win16_call_object_far_method(
|
|
Win16FarPtr procedure, Win16FarPtr object)
|
|
{
|
|
(void)procedure;
|
|
if (win16_far_offset(object) == 0x0300) {
|
|
return g_parent_mdi_client;
|
|
}
|
|
return g_class_name;
|
|
}
|
|
|
|
void object_windows_clear_flag_4(Win16FarPtr object)
|
|
{
|
|
g_flags &= (uint8_t)~4u;
|
|
win16_write_u8(win16_far_add_offset(object, 0x16), g_flags);
|
|
}
|
|
|
|
bool object_windows_has_flags(Win16FarPtr object, uint8_t mask)
|
|
{
|
|
(void)object;
|
|
return (g_flags & mask) == mask;
|
|
}
|
|
|
|
bool win16_call_object_bool_method(
|
|
Win16FarPtr procedure, Win16FarPtr object)
|
|
{
|
|
(void)procedure;
|
|
(void)object;
|
|
return g_register_result;
|
|
}
|
|
|
|
HWND16 GetDlgItem16(HWND16 dialog, INT16 control_id)
|
|
{
|
|
assert(dialog == 0x3333 && control_id == 77);
|
|
return g_dialog_item_result;
|
|
}
|
|
|
|
HWND16 CreateWindowEx16(
|
|
uint32_t extended_style,
|
|
Win16FarPtr class_name,
|
|
Win16FarPtr window_name,
|
|
uint32_t style,
|
|
INT16 x,
|
|
INT16 y,
|
|
INT16 width,
|
|
INT16 height,
|
|
HWND16 parent,
|
|
HMENU16 menu,
|
|
HINSTANCE16 instance,
|
|
Win16FarPtr parameter)
|
|
{
|
|
assert(extended_style == 0x11223344u);
|
|
assert(class_name == g_class_name);
|
|
assert(window_name == g_duplicate_result);
|
|
assert(style == 0x55667788u);
|
|
assert(x == 10 && y == 20 && width == 30 && height == 40);
|
|
assert(parent == 0x3333 && menu == 77 && instance == g_win16_instance);
|
|
assert(parameter == win16_make_far_pointer(0x5000, 0x0550));
|
|
g_create_ex_calls++;
|
|
return g_create_result;
|
|
}
|
|
|
|
LRESULT16 SendMessage16(
|
|
HWND16 window, UINT16 message, WPARAM16 wparam, LPARAM16 lparam)
|
|
{
|
|
assert(window == 0x4444 && message == 0x0220 && wparam == 0);
|
|
Win16FarPtr pointer = (Win16FarPtr)lparam;
|
|
assert(win16_read_far_pointer(pointer, 0) == g_class_name);
|
|
assert(win16_read_far_pointer(pointer, 4) == g_duplicate_result);
|
|
assert(win16_read_u16(win16_far_add_offset(pointer, 8)) == g_win16_instance);
|
|
assert((INT16)win16_read_u16(win16_far_add_offset(pointer, 10)) == 10);
|
|
assert(win16_read_u32(win16_far_add_offset(pointer, 18)) == 0x55667788u);
|
|
assert(win16_read_u32(win16_far_add_offset(pointer, 22)) ==
|
|
win16_make_far_pointer(0x5000, 0x0550));
|
|
g_mdi_calls++;
|
|
return g_create_result;
|
|
}
|
|
|
|
Win16FarPtr object_windows_object_from_window(HWND16 window)
|
|
{
|
|
assert(window != 0);
|
|
return g_existing_object;
|
|
}
|
|
|
|
void object_windows_bind_window(HWND16 window, Win16FarPtr object)
|
|
{
|
|
assert(window != 0 && object != 0);
|
|
g_bind_calls++;
|
|
}
|
|
|
|
int32_t SetWindowLong16(HWND16 window, INT16 index, int32_t value)
|
|
{
|
|
assert(window != 0 && index == -4);
|
|
assert((Win16FarPtr)value == win16_make_far_pointer(0x6000, 0x0300));
|
|
return g_previous_wndproc;
|
|
}
|
|
|
|
void win16_call_object_method(Win16FarPtr procedure, Win16FarPtr object)
|
|
{
|
|
assert(procedure == win16_make_far_pointer(0x6000, 0x0600));
|
|
assert(object != 0);
|
|
g_created_calls++;
|
|
}
|
|
|
|
static void write_far_value(
|
|
Win16FarPtr base, uint16_t offset, Win16FarPtr value)
|
|
{
|
|
win16_write_u16(base, offset, win16_far_offset(value));
|
|
win16_write_u16(
|
|
base, (uint16_t)(offset + 2), win16_far_selector(value));
|
|
}
|
|
|
|
static void prepare_window(
|
|
Win16FarPtr window, Win16FarPtr parent)
|
|
{
|
|
win16_write_u16(window, 0, 0x0100);
|
|
win16_write_u16(window, 2, 0);
|
|
win16_write_u16(window, 4, 0);
|
|
write_far_value(window, 6, parent);
|
|
write_far_value(window, 0x1d, g_duplicate_result);
|
|
win16_write_u32(window, 0x21, 0x55667788u);
|
|
win16_write_u32(window, 0x25, 0x11223344u);
|
|
win16_write_u16(window, 0x29, 10);
|
|
win16_write_u16(window, 0x2b, 20);
|
|
win16_write_u16(window, 0x2d, 30);
|
|
win16_write_u16(window, 0x2f, 40);
|
|
write_far_value(window, 0x31, win16_make_far_pointer(0x5000, 0x0550));
|
|
win16_write_u16(window, 0x35, 77);
|
|
write_far_value(window, 0x12, win16_make_far_pointer(0x6000, 0x0300));
|
|
g_flags = 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
static uint8_t dgroup[0x1000];
|
|
uint8_t stack_anchor = 0;
|
|
uintptr_t stack_base = (uintptr_t)&stack_anchor - 0x8000;
|
|
win16_reset_segment_bindings();
|
|
win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true);
|
|
win16_set_dgroup_selector(0x5000);
|
|
win16_bind_segment(0x7000, (void *)stack_base, 0x10000, true);
|
|
|
|
Win16FarPtr window = win16_make_far_pointer(0x5000, 0x0200);
|
|
Win16FarPtr parent = win16_make_far_pointer(0x5000, 0x0300);
|
|
Win16FarPtr mdi_client = win16_make_far_pointer(0x5000, 0x0400);
|
|
g_duplicate_result = win16_make_far_pointer(0x5000, 0x0500);
|
|
g_class_name = win16_make_far_pointer(0x5000, 0x0520);
|
|
win16_write_u16(parent, 0, 0x0700);
|
|
win16_write_u16(parent, 4, 0x3333);
|
|
win16_write_u16(mdi_client, 4, 0x4444);
|
|
write_far_value(win16_dgroup_pointer(0x0700), 0x30,
|
|
win16_make_far_pointer(0x6000, 0x0700));
|
|
write_far_value(win16_dgroup_pointer(0x0100), 0x1c,
|
|
win16_make_far_pointer(0x6000, 0x0400));
|
|
write_far_value(win16_dgroup_pointer(0x0100), 0x2c,
|
|
win16_make_far_pointer(0x6000, 0x0500));
|
|
write_far_value(win16_dgroup_pointer(0x0100), 0x38,
|
|
win16_make_far_pointer(0x6000, 0x0600));
|
|
|
|
g_parent_mdi_client = 0;
|
|
(void)object_windows_window_construct(
|
|
window, 0x0100, win16_make_far_pointer(0x5000, 0x0540), 0);
|
|
assert(win16_read_u32(win16_far_add_offset(window, 0x21)) == 0x00cf0000u);
|
|
assert(win16_read_far_pointer(window, 0x37) ==
|
|
win16_make_far_pointer(0x6000, 0x0100));
|
|
assert(win16_read_u16(win16_far_add_offset(window, 0x29)) == 0x8000);
|
|
|
|
g_parent_mdi_client = 0;
|
|
(void)object_windows_window_construct(
|
|
window, 0, win16_make_far_pointer(0x5000, 0x0540), parent);
|
|
assert(win16_read_u32(win16_far_add_offset(window, 0x21)) == 0x10000000u);
|
|
g_parent_mdi_client = mdi_client;
|
|
(void)object_windows_window_construct(
|
|
window, 0, win16_make_far_pointer(0x5000, 0x0540), parent);
|
|
assert(win16_read_u32(win16_far_add_offset(window, 0x21)) == 0x04000000u);
|
|
assert(win16_read_far_pointer(window, 0x37) ==
|
|
win16_make_far_pointer(0x6000, 0x0200));
|
|
assert((g_flags & 8) != 0);
|
|
|
|
g_win16_instance = 0x7777;
|
|
g_register_result = true;
|
|
g_existing_object = 0;
|
|
g_previous_wndproc = (int32_t)win16_make_far_pointer(0x6000, 0x0800);
|
|
prepare_window(window, parent);
|
|
g_create_result = 0x8888;
|
|
g_create_ex_calls = 0;
|
|
g_bind_calls = 0;
|
|
g_created_calls = 0;
|
|
win16_set_indeterminate_u16(0);
|
|
assert(object_windows_create_native_window(window) == 1);
|
|
assert(g_create_ex_calls == 1 && g_bind_calls == 1 && g_created_calls == 1);
|
|
assert(g_object_windows_creating_object == window);
|
|
assert(win16_read_far_pointer(window, 0x37) ==
|
|
(Win16FarPtr)g_previous_wndproc);
|
|
|
|
prepare_window(window, parent);
|
|
g_flags = 2;
|
|
g_dialog_item_result = 0x9999;
|
|
g_existing_object = window;
|
|
assert(object_windows_create_native_window(window) == 1);
|
|
assert(win16_read_u16(win16_far_add_offset(window, 4)) == 0x9999);
|
|
|
|
prepare_window(window, parent);
|
|
g_flags = 8;
|
|
g_parent_mdi_client = mdi_client;
|
|
g_create_result = 0xaaaa;
|
|
g_existing_object = window;
|
|
g_mdi_calls = 0;
|
|
assert(object_windows_create_native_window(window) == 1);
|
|
assert(g_mdi_calls == 1);
|
|
|
|
prepare_window(window, parent);
|
|
g_create_result = 0;
|
|
g_existing_object = 0;
|
|
assert(object_windows_create_native_window(window) == 0);
|
|
assert(win16_read_u16(win16_far_add_offset(window, 2)) == 0xffff);
|
|
|
|
prepare_window(window, parent);
|
|
g_register_result = false;
|
|
g_existing_object = window;
|
|
win16_set_indeterminate_u16(0xabcd);
|
|
assert(object_windows_create_native_window(window) == 0xab01);
|
|
return 0;
|
|
}
|