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

316 lines
9.9 KiB
C

/* ObjectWindows circular child-object list. */
#include "tdkpin_object_list.h"
enum {
CONTAINER_CHILD_TAIL_OFFSET = 0x0a,
CHILD_NEXT_OFFSET = 0x19,
CHILD_WINDOW_HANDLE_OFFSET = 4,
CHILD_CAN_CLOSE_SLOT = 0x3c,
CHILD_BLOCKS_CLOSE_OFFSET = 0x0ec0,
CHILD_GROUP_OFFSET = 0x17,
CHILD_FLAGS_OFFSET = 0x16,
CHILD_ACTIVATE_SLOT = 0x20,
CHILD_TRANSFER_SLOT = 0x40,
CHILD_TRANSFER_FLAG = 0x10,
OBJECT_TRANSFER_POINTER_OFFSET = 0x0e,
};
static Win16FarPtr read_far(Win16FarPtr object, uint16_t offset)
{
return win16_read_far_pointer(object, offset);
}
static void write_far(
Win16FarPtr object, uint16_t offset, Win16FarPtr value)
{
win16_write_u16(object, offset, win16_far_offset(value));
win16_write_u16(
object, (uint16_t)(offset + 2), win16_far_selector(value));
}
/*
* 1018:069a — append one child to a circular singly linked ring.
* The container stores the tail; tail->next is the oldest/head child.
*/
void object_windows_append_child(
Win16FarPtr container, Win16FarPtr child)
{
if (child == 0) {
return;
}
Win16FarPtr tail = read_far(container, CONTAINER_CHILD_TAIL_OFFSET);
if (tail == 0) {
write_far(child, CHILD_NEXT_OFFSET, child);
} else {
write_far(child, CHILD_NEXT_OFFSET,
read_far(tail, CHILD_NEXT_OFFSET));
write_far(tail, CHILD_NEXT_OFFSET, child);
}
write_far(container, CONTAINER_CHILD_TAIL_OFFSET, child);
}
/* 1018:071c — unlink one exact far child, maintaining the tail invariant. */
void object_windows_remove_child(
Win16FarPtr container, Win16FarPtr child)
{
Win16FarPtr tail = read_far(container, CONTAINER_CHILD_TAIL_OFFSET);
if (tail == 0) {
return;
}
Win16FarPtr previous = tail;
while (true) {
Win16FarPtr candidate = read_far(previous, CHILD_NEXT_OFFSET);
if (candidate == child || candidate == tail) {
if (candidate != child) {
return;
}
if (candidate == previous) {
write_far(container, CONTAINER_CHILD_TAIL_OFFSET, 0);
return;
}
if (candidate == tail) {
write_far(container, CONTAINER_CHILD_TAIL_OFFSET, previous);
}
write_far(previous, CHILD_NEXT_OFFSET,
read_far(candidate, CHILD_NEXT_OFFSET));
return;
}
previous = candidate;
}
}
/* 1018:080d — visit head-to-tail and return the first matching child. */
Win16FarPtr object_windows_find_child(
Win16FarPtr container, Win16FarPtr predicate)
{
Win16FarPtr tail = read_far(container, CONTAINER_CHILD_TAIL_OFFSET);
if (tail == 0) {
return 0;
}
Win16FarPtr child = read_far(tail, CHILD_NEXT_OFFSET);
while (true) {
if (win16_call_object_predicate(predicate, child)) {
return child;
}
if (child == tail) {
return 0;
}
child = read_far(child, CHILD_NEXT_OFFSET);
}
}
/*
* 1018:085a — visit every child head-to-tail. The next far pointer is read
* before each callback so the callback may unlink or destroy the current node.
*/
void object_windows_for_each_child(
Win16FarPtr container, Win16FarPtr action)
{
Win16FarPtr tail = read_far(container, CONTAINER_CHILD_TAIL_OFFSET);
if (tail == 0) {
return;
}
Win16FarPtr child = read_far(tail, CHILD_NEXT_OFFSET);
while (child != tail) {
Win16FarPtr next = read_far(child, CHILD_NEXT_OFFSET);
win16_call_object_action(action, child);
child = next;
}
win16_call_object_action(action, tail);
}
/* 1018:08ac — inherited virtual default returning AX=0xffff. */
uint16_t object_windows_minus_one_default(Win16FarPtr object)
{
(void)object;
return 0xffff;
}
/* 1018:0ec0 — predicate: a windowed child whose CanClose returns false. */
bool object_windows_child_blocks_close(
uint16_t ignored, Win16FarPtr child)
{
(void)ignored;
if (win16_read_u16(win16_far_add_offset(
child, CHILD_WINDOW_HANDLE_OFFSET)) == 0) {
return false;
}
uint16_t vmt = win16_read_u16(child);
Win16FarPtr can_close =
win16_read_far_pointer(win16_dgroup_pointer(vmt), CHILD_CAN_CLOSE_SLOT);
return !win16_call_object_bool_method(can_close, child);
}
/* 1018:0ef4 — true exactly when no child blocks container shutdown. */
bool object_windows_all_children_can_close(Win16FarPtr container)
{
Win16FarPtr blocker = object_windows_find_child(
container,
win16_relocated_code_pointer(4, CHILD_BLOCKS_CLOSE_OFFSET));
return blocker == 0;
}
/* 1018:03e9 — nested ForEach callback: dispose the supplied child object. */
void object_windows_dispose_child_callback(
uint16_t ignored, Win16FarPtr child)
{
(void)ignored;
borland_dispose_object(child);
}
/* 1018:0466 — nested predicate for signed group field +0x17. */
bool object_windows_child_group_matches(
int16_t group, Win16FarPtr child)
{
return group >= 0 &&
win16_read_u16(win16_far_add_offset(child, CHILD_GROUP_OFFSET)) ==
(uint16_t)group;
}
/*
* 1018:049e — evaluate one child and preserve the minimized-window text
* refresh side effect. The function returns true only for flag-4 children
* whose VMT +0x20 method returns false.
*/
bool object_windows_try_child_activation(
uint16_t ignored, Win16FarPtr child)
{
(void)ignored;
bool continue_processing = true;
uint8_t flags = win16_read_u8(
win16_far_add_offset(child, CHILD_FLAGS_OFFSET));
if ((flags & 4) != 0) {
uint16_t vmt = win16_read_u16(child);
Win16FarPtr procedure = win16_read_far_pointer(
win16_dgroup_pointer(vmt), CHILD_ACTIVATE_SLOT);
if (!win16_call_object_bool_method(procedure, child)) {
continue_processing = false;
}
}
if (continue_processing) {
HWND16 window = win16_read_u16(win16_far_add_offset(
child, CHILD_WINDOW_HANDLE_OFFSET));
if (IsIconic16(window) != 0) {
char text[82];
(void)GetWindowText16(window, text, 81);
(void)SetWindowText16(window, text);
}
}
return !continue_processing;
}
/* 1018:0524 — group-zero predicate gated by 1018:049e. */
bool object_windows_unindexed_child_matches(
uint16_t ignored, Win16FarPtr child)
{
return win16_read_u16(win16_far_add_offset(
child, CHILD_GROUP_OFFSET)) == 0 &&
object_windows_try_child_activation(ignored, child);
}
static Win16FarPtr find_child_in_group(
Win16FarPtr container, int16_t group, bool require_activation)
{
Win16FarPtr tail = read_far(container, CONTAINER_CHILD_TAIL_OFFSET);
if (tail == 0) {
return 0;
}
Win16FarPtr child = read_far(tail, CHILD_NEXT_OFFSET);
while (true) {
bool matches = object_windows_child_group_matches(group, child);
if (matches &&
(!require_activation ||
object_windows_try_child_activation(0, child))) {
return child;
}
if (child == tail) {
return 0;
}
child = read_far(child, CHILD_NEXT_OFFSET);
}
}
/*
* 1018:055c — scan numbered groups starting at one. Each found child is passed
* through 049e; after the first missing group, group zero is searched for a
* child whose 049e result is true. The unusual final inversion is preserved.
*/
bool object_windows_validate_child_groups(Win16FarPtr container)
{
int16_t group = 1;
bool result = false;
Win16FarPtr child;
do {
child = find_child_in_group(container, group, false);
if (child != 0) {
result = object_windows_try_child_activation(0, child);
}
group++;
} while (!result && child != 0);
if (!result) {
return find_child_in_group(container, 0, true) == 0;
}
return true;
}
/* 1018:0d9b — validate child groups, store status -4, or call VMT +0x44(2). */
void object_windows_prepare_window(Win16FarPtr window)
{
if (!object_windows_validate_child_groups(window)) {
win16_write_u16(window, 2, 0xfffc);
return;
}
uint16_t vmt = win16_read_u16(window);
Win16FarPtr procedure =
win16_read_far_pointer(win16_dgroup_pointer(vmt), 0x44);
win16_call_object_u16_method(procedure, window, 2);
}
/*
* 1018:0dcd — nested transfer callback. Flag 0x10 selects participants;
* VMT +0x40 receives child, direction, and the current far cursor. AX advances
* only the cursor offset with 16-bit wrap, preserving its selector.
*/
void object_windows_transfer_child_callback(
ObjectWindowsTransferContext *context, Win16FarPtr child)
{
uint8_t flags = win16_read_u8(
win16_far_add_offset(child, CHILD_FLAGS_OFFSET));
if ((flags & CHILD_TRANSFER_FLAG) == 0) {
return;
}
uint16_t vmt = win16_read_u16(child);
Win16FarPtr procedure = win16_read_far_pointer(
win16_dgroup_pointer(vmt), CHILD_TRANSFER_SLOT);
uint16_t consumed = win16_call_object_transfer_method(
procedure, child, context->direction, context->cursor);
context->cursor = win16_make_far_pointer(
win16_far_selector(context->cursor),
(uint16_t)(win16_far_offset(context->cursor) + consumed));
}
/* 1018:0e0a — transfer across the circular child list head-to-tail. */
void object_windows_transfer_child_data(
Win16FarPtr object, uint16_t direction)
{
Win16FarPtr cursor =
read_far(object, OBJECT_TRANSFER_POINTER_OFFSET);
if (cursor == 0) {
return;
}
ObjectWindowsTransferContext context = {cursor, direction};
Win16FarPtr tail = read_far(object, CONTAINER_CHILD_TAIL_OFFSET);
if (tail == 0) {
return;
}
Win16FarPtr child = read_far(tail, CHILD_NEXT_OFFSET);
while (child != tail) {
Win16FarPtr next = read_far(child, CHILD_NEXT_OFFSET);
object_windows_transfer_child_callback(&context, child);
child = next;
}
object_windows_transfer_child_callback(&context, tail);
}