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
328 lines
9.2 KiB
C
328 lines
9.2 KiB
C
#include "../tdkpin_tpwincrt_lifecycle.h"
|
|
|
|
#include "../tdkpin_borland_files.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdatomic.h>
|
|
#include <string.h>
|
|
|
|
HINSTANCE16 g_win16_previous_instance;
|
|
HINSTANCE16 g_win16_instance;
|
|
uint16_t g_win16_show_command;
|
|
Win16FarPtr g_borland_command_line;
|
|
uint16_t g_borland_windows_mode;
|
|
uint16_t g_borland_huge_pointer_increment;
|
|
uint8_t g_borland_cpu_level;
|
|
|
|
HWND16 g_tpwincrt_window;
|
|
uint8_t g_tpwincrt_window_created;
|
|
uint8_t g_tpwincrt_break_check_enabled;
|
|
WNDCLASS16 g_tpwincrt_window_class;
|
|
int16_t g_tpwincrt_initial_x;
|
|
int16_t g_tpwincrt_initial_y;
|
|
int16_t g_tpwincrt_initial_width;
|
|
int16_t g_tpwincrt_initial_height;
|
|
const char g_tpwincrt_inactive_format[14] = "(Inactive %s)";
|
|
char g_tpwincrt_window_title[80];
|
|
Win16FarPtr g_tpwincrt_saved_exit_proc;
|
|
|
|
Win16FarPtr g_borland_exit_proc;
|
|
uint16_t g_borland_error_offset;
|
|
uint16_t g_borland_error_segment;
|
|
_Atomic uint16_t g_borland_io_result;
|
|
uint8_t g_borland_file_mode;
|
|
|
|
static unsigned g_create_calls;
|
|
static Win16FarPtr g_create_class;
|
|
static Win16FarPtr g_create_title;
|
|
static uint32_t g_create_style;
|
|
static INT16 g_create_x;
|
|
static INT16 g_create_y;
|
|
static INT16 g_create_width;
|
|
static INT16 g_create_height;
|
|
static HINSTANCE16 g_create_instance;
|
|
static unsigned g_show_calls;
|
|
static unsigned g_update_calls;
|
|
static unsigned g_icon_calls;
|
|
static unsigned g_cursor_calls;
|
|
static unsigned g_register_calls;
|
|
static unsigned g_text_init_calls;
|
|
static Win16FarPtr g_text_records[2];
|
|
static unsigned g_reset_calls;
|
|
static unsigned g_rewrite_calls;
|
|
static unsigned g_require_calls;
|
|
static unsigned g_module_name_calls;
|
|
static unsigned g_oem_calls;
|
|
static unsigned g_set_title_calls;
|
|
static unsigned g_get_menu_calls;
|
|
static unsigned g_enable_calls;
|
|
static unsigned g_get_message_calls;
|
|
static unsigned g_translate_calls;
|
|
static unsigned g_dispatch_calls;
|
|
|
|
HWND16 CreateWindow16(
|
|
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(parent == 0 && menu == 0 && parameter == 0);
|
|
g_create_calls++;
|
|
g_create_class = class_name;
|
|
g_create_title = window_name;
|
|
g_create_style = style;
|
|
g_create_x = x;
|
|
g_create_y = y;
|
|
g_create_width = width;
|
|
g_create_height = height;
|
|
g_create_instance = instance;
|
|
return 0x4321;
|
|
}
|
|
|
|
BOOL16 ShowWindow16(HWND16 window, INT16 command)
|
|
{
|
|
assert(window == 0x4321 && command == (INT16)g_win16_show_command);
|
|
g_show_calls++;
|
|
return 1;
|
|
}
|
|
|
|
BOOL16 UpdateWindow16(HWND16 window)
|
|
{
|
|
assert(window == g_tpwincrt_window);
|
|
g_update_calls++;
|
|
return 1;
|
|
}
|
|
|
|
HICON16 LoadIcon16(HINSTANCE16 instance, Win16FarPtr resource)
|
|
{
|
|
assert(instance == 0 && resource == win16_make_far_pointer(0, 0x7f00));
|
|
g_icon_calls++;
|
|
return 0x1111;
|
|
}
|
|
|
|
HCURSOR16 LoadCursor16(HINSTANCE16 instance, Win16FarPtr resource)
|
|
{
|
|
assert(instance == 0 && resource == win16_make_far_pointer(0, 0x7f00));
|
|
g_cursor_calls++;
|
|
return 0x2222;
|
|
}
|
|
|
|
uint16_t RegisterClass16(const WNDCLASS16 *window_class)
|
|
{
|
|
assert(window_class == &g_tpwincrt_window_class);
|
|
assert(window_class->instance == g_win16_instance);
|
|
assert(window_class->icon == 0x1111 && window_class->cursor == 0x2222);
|
|
assert(window_class->background_brush == 6);
|
|
g_register_calls++;
|
|
return 1;
|
|
}
|
|
|
|
void tpwincrt_initialize_text_record(Win16FarPtr record)
|
|
{
|
|
assert(g_text_init_calls < 2);
|
|
g_text_records[g_text_init_calls++] = record;
|
|
}
|
|
|
|
void borland_reset_file(Win16FarPtr record)
|
|
{
|
|
assert(record == win16_dgroup_pointer(0x4b38));
|
|
g_reset_calls++;
|
|
}
|
|
|
|
void borland_rewrite_file(Win16FarPtr record)
|
|
{
|
|
assert(record == win16_dgroup_pointer(0x4c38));
|
|
g_rewrite_calls++;
|
|
}
|
|
|
|
void borland_require_io_success(void)
|
|
{
|
|
g_require_calls++;
|
|
}
|
|
|
|
UINT16 GetModuleFileNameFar16(
|
|
HINSTANCE16 module, Win16FarPtr buffer, UINT16 size)
|
|
{
|
|
assert(module == g_win16_instance);
|
|
assert(buffer == win16_dgroup_pointer(0x4a6e) && size == 0x50);
|
|
g_module_name_calls++;
|
|
return 7;
|
|
}
|
|
|
|
INT16 OemToAnsi16(Win16FarPtr source, Win16FarPtr destination)
|
|
{
|
|
assert(source == win16_dgroup_pointer(0x4a6e));
|
|
assert(destination == source);
|
|
g_oem_calls++;
|
|
return 1;
|
|
}
|
|
|
|
INT16 wvsprintf16(
|
|
char *output, const char *format, const uint16_t *arguments)
|
|
{
|
|
assert(format == g_tpwincrt_inactive_format);
|
|
Win16FarPtr title = win16_dgroup_pointer(0x4a6e);
|
|
assert(arguments[0] == win16_far_offset(title));
|
|
assert(arguments[1] == win16_far_selector(title));
|
|
memcpy(output, "inactive", 9);
|
|
return 8;
|
|
}
|
|
|
|
BOOL16 SetWindowText16(HWND16 window, const char *text)
|
|
{
|
|
assert(window == g_tpwincrt_window && strcmp(text, "inactive") == 0);
|
|
g_set_title_calls++;
|
|
return 1;
|
|
}
|
|
|
|
HMENU16 GetSystemMenu16(HWND16 window, BOOL16 revert)
|
|
{
|
|
assert(window == g_tpwincrt_window && revert == 0);
|
|
g_get_menu_calls++;
|
|
return 0x7777;
|
|
}
|
|
|
|
BOOL16 EnableMenuItem16(HMENU16 menu, UINT16 item, UINT16 flags)
|
|
{
|
|
assert(menu == 0x7777 && item == 0xf060 && flags == 0);
|
|
g_enable_calls++;
|
|
return 1;
|
|
}
|
|
|
|
BOOL16 GetMessage16(
|
|
MSG16 *message,
|
|
HWND16 window,
|
|
UINT16 minimum_message,
|
|
UINT16 maximum_message)
|
|
{
|
|
assert(window == 0 && minimum_message == 0 && maximum_message == 0);
|
|
g_get_message_calls++;
|
|
message->message = WIN16_WM_PAINT;
|
|
return g_get_message_calls < 3;
|
|
}
|
|
|
|
BOOL16 TranslateMessage16(const MSG16 *message)
|
|
{
|
|
assert(message->message == WIN16_WM_PAINT);
|
|
g_translate_calls++;
|
|
return 1;
|
|
}
|
|
|
|
LRESULT16 DispatchMessage16(const MSG16 *message)
|
|
{
|
|
assert(message->message == WIN16_WM_PAINT);
|
|
g_dispatch_calls++;
|
|
return 0;
|
|
}
|
|
|
|
static void reset_counts(void)
|
|
{
|
|
g_create_calls = 0;
|
|
g_show_calls = 0;
|
|
g_update_calls = 0;
|
|
g_icon_calls = 0;
|
|
g_cursor_calls = 0;
|
|
g_register_calls = 0;
|
|
g_text_init_calls = 0;
|
|
g_reset_calls = 0;
|
|
g_rewrite_calls = 0;
|
|
g_require_calls = 0;
|
|
g_module_name_calls = 0;
|
|
g_oem_calls = 0;
|
|
g_set_title_calls = 0;
|
|
g_get_menu_calls = 0;
|
|
g_enable_calls = 0;
|
|
g_get_message_calls = 0;
|
|
g_translate_calls = 0;
|
|
g_dispatch_calls = 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
static uint8_t dgroup[0x6000];
|
|
static uint8_t code[0x3000];
|
|
win16_reset_segment_bindings();
|
|
win16_bind_segment(0x7000, dgroup, sizeof(dgroup), true);
|
|
win16_set_dgroup_selector(0x7000);
|
|
win16_bind_ne_segment(2, 0x6000, code, sizeof(code), false);
|
|
|
|
g_tpwincrt_window_class.class_name =
|
|
win16_make_far_pointer(0x7000, 0x057c);
|
|
g_tpwincrt_initial_x = (int16_t)0x8000;
|
|
g_tpwincrt_initial_y = (int16_t)0x8000;
|
|
g_tpwincrt_initial_width = (int16_t)0x8000;
|
|
g_tpwincrt_initial_height = (int16_t)0x8000;
|
|
g_win16_instance = 0x1234;
|
|
g_win16_show_command = 7;
|
|
|
|
reset_counts();
|
|
g_tpwincrt_window_created = 0;
|
|
tpwincrt_create_window();
|
|
assert(g_create_calls == 1 && g_show_calls == 1 && g_update_calls == 1);
|
|
assert(g_tpwincrt_window == 0x4321);
|
|
assert(g_create_class == g_tpwincrt_window_class.class_name);
|
|
assert(g_create_title == win16_dgroup_pointer(0x4a6e));
|
|
assert(g_create_style == 0x00ff0000u);
|
|
assert(g_create_x == (int16_t)0x8000 &&
|
|
g_create_y == (int16_t)0x8000);
|
|
assert(g_create_width == (int16_t)0x8000 &&
|
|
g_create_height == (int16_t)0x8000);
|
|
assert(g_create_instance == g_win16_instance);
|
|
g_tpwincrt_window_created = 1;
|
|
tpwincrt_create_window();
|
|
assert(g_create_calls == 1);
|
|
|
|
reset_counts();
|
|
g_win16_previous_instance = 0;
|
|
g_borland_exit_proc = win16_make_far_pointer(0x5555, 0x4444);
|
|
tpwincrt_initialize_runtime_unit();
|
|
assert(g_icon_calls == 1 && g_cursor_calls == 1 && g_register_calls == 1);
|
|
assert(g_text_init_calls == 2);
|
|
assert(g_text_records[0] == win16_dgroup_pointer(0x4b38));
|
|
assert(g_text_records[1] == win16_dgroup_pointer(0x4c38));
|
|
assert(g_reset_calls == 1 && g_rewrite_calls == 1 && g_require_calls == 2);
|
|
assert(g_module_name_calls == 1 && g_oem_calls == 1);
|
|
assert(g_tpwincrt_saved_exit_proc ==
|
|
win16_make_far_pointer(0x5555, 0x4444));
|
|
assert(g_borland_exit_proc ==
|
|
win16_make_far_pointer(0x6000, 0x24a5));
|
|
|
|
reset_counts();
|
|
g_win16_previous_instance = 1;
|
|
g_borland_exit_proc = 0;
|
|
tpwincrt_initialize_runtime_unit();
|
|
assert(g_icon_calls == 0 && g_cursor_calls == 0 && g_register_calls == 0);
|
|
assert(g_text_init_calls == 2 && g_reset_calls == 1 && g_rewrite_calls == 1);
|
|
|
|
reset_counts();
|
|
g_tpwincrt_saved_exit_proc = win16_make_far_pointer(0xaaaa, 0xbbbb);
|
|
g_borland_exit_proc = 0;
|
|
g_tpwincrt_window_created = 1;
|
|
g_tpwincrt_window = 0x4321;
|
|
g_borland_error_offset = 0;
|
|
g_borland_error_segment = 0;
|
|
g_tpwincrt_break_check_enabled = 1;
|
|
tpwincrt_shutdown_exit_proc();
|
|
assert(g_borland_exit_proc == g_tpwincrt_saved_exit_proc);
|
|
assert(g_set_title_calls == 1 && g_get_menu_calls == 1 &&
|
|
g_enable_calls == 1);
|
|
assert(g_tpwincrt_break_check_enabled == 0);
|
|
assert(g_get_message_calls == 3);
|
|
assert(g_translate_calls == 2 && g_dispatch_calls == 2);
|
|
|
|
reset_counts();
|
|
g_borland_exit_proc = 0;
|
|
g_borland_error_offset = 1;
|
|
tpwincrt_shutdown_exit_proc();
|
|
assert(g_borland_exit_proc == g_tpwincrt_saved_exit_proc);
|
|
assert(g_set_title_calls == 0 && g_get_message_calls == 0);
|
|
return 0;
|
|
}
|