Files
tdkpin/original/reconstructed/tests/test_object_list.c
T
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

170 lines
5.2 KiB
C

#include "../tdkpin_object_list.h"
#include <assert.h>
static Win16FarPtr g_match;
static Win16FarPtr g_order[8];
static unsigned g_order_count;
static Win16FarPtr g_blocking_child;
static Win16FarPtr g_disposed_child;
bool win16_call_object_predicate(
Win16FarPtr procedure, Win16FarPtr child)
{
if (procedure == win16_make_far_pointer(0x6000, 0x0ec0)) {
return object_windows_child_blocks_close(0, child);
}
assert(procedure == win16_make_far_pointer(0x6000, 0x0100));
g_order[g_order_count++] = child;
return child == g_match;
}
bool win16_call_object_bool_method(
Win16FarPtr procedure, Win16FarPtr object)
{
assert(procedure == win16_make_far_pointer(0x6100, 0x0300));
return object != g_blocking_child;
}
void borland_dispose_object(Win16FarPtr object)
{
g_disposed_child = object;
}
BOOL16 IsIconic16(HWND16 window)
{
(void)window;
return 0;
}
INT16 GetWindowText16(HWND16 window, char *text, INT16 maximum)
{
(void)window;
(void)text;
(void)maximum;
return 0;
}
BOOL16 SetWindowText16(HWND16 window, const char *text)
{
(void)window;
(void)text;
return 0;
}
void win16_call_object_u16_method(
Win16FarPtr procedure, Win16FarPtr object, uint16_t argument)
{
(void)procedure;
(void)object;
(void)argument;
}
uint16_t win16_call_object_transfer_method(
Win16FarPtr procedure,
Win16FarPtr object,
uint16_t direction,
Win16FarPtr cursor)
{
(void)procedure;
(void)object;
(void)direction;
(void)cursor;
return 0;
}
void win16_call_object_action(
Win16FarPtr procedure, Win16FarPtr child)
{
assert(procedure == win16_make_far_pointer(0x6000, 0x0200));
g_order[g_order_count++] = child;
}
static Win16FarPtr next_of(Win16FarPtr child)
{
return win16_read_far_pointer(child, 0x19);
}
int main(void)
{
static uint8_t container_bytes[64];
static uint8_t a_bytes[64];
static uint8_t b_bytes[64];
static uint8_t c_bytes[64];
static uint8_t dgroup[0x1000];
static uint8_t code[0x1000];
win16_reset_segment_bindings();
win16_bind_segment(
0x7000, container_bytes, sizeof(container_bytes), true);
win16_bind_segment(0x7100, a_bytes, sizeof(a_bytes), true);
win16_bind_segment(0x7200, b_bytes, sizeof(b_bytes), true);
win16_bind_segment(0x7300, c_bytes, sizeof(c_bytes), true);
win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true);
win16_set_dgroup_selector(0x5000);
win16_bind_ne_segment(4, 0x6000, code, sizeof(code), false);
Win16FarPtr container = win16_make_far_pointer(0x7000, 2);
Win16FarPtr a = win16_make_far_pointer(0x7100, 2);
Win16FarPtr b = win16_make_far_pointer(0x7200, 2);
Win16FarPtr c = win16_make_far_pointer(0x7300, 2);
object_windows_append_child(container, 0);
assert(win16_read_far_pointer(container, 0x0a) == 0);
object_windows_append_child(container, a);
object_windows_append_child(container, b);
object_windows_append_child(container, c);
assert(win16_read_far_pointer(container, 0x0a) == c);
assert(next_of(a) == b && next_of(b) == c && next_of(c) == a);
win16_write_u16(a, 0, 0x0100);
win16_write_u16(b, 0, 0x0100);
win16_write_u16(c, 0, 0x0100);
win16_write_u16(a, 4, 1);
win16_write_u16(b, 4, 1);
win16_write_u16(c, 4, 1);
win16_write_u16(win16_dgroup_pointer(0x013c), 0, 0x0300);
win16_write_u16(win16_dgroup_pointer(0x013e), 0, 0x6100);
Win16FarPtr predicate = win16_make_far_pointer(0x6000, 0x0100);
g_match = b;
g_order_count = 0;
assert(object_windows_find_child(container, predicate) == b);
assert(g_order_count == 2 && g_order[0] == a && g_order[1] == b);
g_match = 0;
g_order_count = 0;
assert(object_windows_find_child(container, predicate) == 0);
assert(g_order_count == 3 && g_order[2] == c);
g_blocking_child = b;
assert(!object_windows_all_children_can_close(container));
g_blocking_child = 0;
assert(object_windows_all_children_can_close(container));
win16_write_u16(a, 4, 0);
g_blocking_child = a;
assert(object_windows_all_children_can_close(container));
win16_write_u16(a, 4, 1);
g_order_count = 0;
object_windows_for_each_child(
container, win16_make_far_pointer(0x6000, 0x0200));
assert(g_order_count == 3);
assert(g_order[0] == a && g_order[1] == b && g_order[2] == c);
object_windows_remove_child(container, b);
assert(next_of(a) == c && next_of(c) == a);
assert(win16_read_far_pointer(container, 0x0a) == c);
object_windows_remove_child(container, c);
assert(win16_read_far_pointer(container, 0x0a) == a);
assert(next_of(a) == a);
object_windows_remove_child(container, c);
assert(win16_read_far_pointer(container, 0x0a) == a);
object_windows_remove_child(container, a);
assert(win16_read_far_pointer(container, 0x0a) == 0);
assert(object_windows_find_child(container, predicate) == 0);
object_windows_for_each_child(
container, win16_make_far_pointer(0x6000, 0x0200));
assert(object_windows_minus_one_default(container) == 0xffff);
g_disposed_child = 0;
object_windows_dispose_child_callback(0xbeef, b);
assert(g_disposed_child == b);
return 0;
}