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
170 lines
5.2 KiB
C
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;
|
|
}
|