#include "../tdkpin_application.h" #include #include #include #include Win16FarPtr g_object_windows_application; HINSTANCE16 g_win16_previous_instance; HINSTANCE16 g_win16_instance; uint16_t g_win16_show_command; Win16FarPtr g_object_windows_dispatch_proc; uint16_t g_object_windows_thunk_code_selector; Win16FarPtr g_object_windows_free_thunk; Win16FarPtr g_object_windows_message_hook; Win16FarPtr g_win16_message_box; static bool g_reserve_unallocated; static unsigned g_ensure_calls; static Win16FarPtr g_disposed; static uint16_t g_error; static Win16FarPtr g_validator_result; static bool g_create_result; static int16_t g_execute_result; static Win16FarPtr g_validate_proc; static Win16FarPtr g_error_proc; static Win16FarPtr g_create_proc; static Win16FarPtr g_execute_proc; static INT16 g_message_box_response; static char g_message_text[32]; static uint16_t g_exit_status; static jmp_buf g_exit_jump; bool borland_heap_reserve_is_unallocated(void) { return g_reserve_unallocated; } void borland_ensure_heap_reserve(void) { g_ensure_calls++; } void borland_dispose_object(Win16FarPtr object) { g_disposed = object; } void win16_call_object_u16_method( Win16FarPtr procedure, Win16FarPtr object, uint16_t argument) { (void)object; assert(procedure == g_error_proc); g_error = argument; } Win16FarPtr win16_call_application_window_method( Win16FarPtr procedure, Win16FarPtr application, Win16FarPtr window) { (void)application; (void)window; assert(procedure == g_validate_proc); return g_validator_result; } bool win16_call_object_bool_method( Win16FarPtr procedure, Win16FarPtr object) { (void)object; assert(procedure == g_create_proc); return g_create_result; } int16_t win16_call_object_int_method( Win16FarPtr procedure, Win16FarPtr object) { (void)object; assert(procedure == g_execute_proc); return g_execute_result; } INT16 wvsprintf16( char *output, const char *format, const uint16_t *arguments) { assert(strcmp(format, "Error code = %d. Continue?") == 0); return (INT16)snprintf( output, 32, format, (int16_t)arguments[0]); } INT16 win16_call_message_box( Win16FarPtr procedure, HWND16 owner, const char *text, const char *caption, UINT16 type) { assert(procedure == g_win16_message_box); assert(owner == 0 && type == 0x14); assert(strcmp(caption, "Application Error") == 0); strcpy(g_message_text, text); return g_message_box_response; } _Noreturn void borland_runtime_exit(uint16_t status) { g_exit_status = status; longjmp(g_exit_jump, 1); } static void write_far(uint16_t offset, Win16FarPtr pointer) { win16_write_u16( win16_dgroup_pointer(offset), 0, win16_far_offset(pointer)); win16_write_u16( win16_dgroup_pointer((uint16_t)(offset + 2)), 0, win16_far_selector(pointer)); } static void reset_state(void) { g_reserve_unallocated = false; g_ensure_calls = 0; g_disposed = 0; g_error = 0; } int main(void) { static uint8_t dgroup[0x1000]; static uint8_t application_bytes[64]; static uint8_t window_bytes[64]; win16_reset_segment_bindings(); win16_bind_segment(0x5000, dgroup, sizeof(dgroup), true); win16_set_dgroup_selector(0x5000); win16_bind_segment( 0x7000, application_bytes, sizeof(application_bytes), true); win16_bind_segment(0x7100, window_bytes, sizeof(window_bytes), true); Win16FarPtr application = win16_make_far_pointer(0x7000, 2); Win16FarPtr window = win16_make_far_pointer(0x7100, 2); uint16_t app_vmt = 0x0100; uint16_t window_vmt = 0x0200; win16_write_u16(application, 0, app_vmt); win16_write_u16(window, 0, window_vmt); g_validate_proc = win16_make_far_pointer(0x6000, 0x1000); g_error_proc = win16_make_far_pointer(0x6000, 0x2000); g_create_proc = win16_make_far_pointer(0x6100, 0x3000); g_execute_proc = win16_make_far_pointer(0x6100, 0x4000); g_win16_message_box = win16_make_far_pointer(0x6200, 0x5000); write_far(app_vmt + 0x3c, g_validate_proc); write_far(app_vmt + 0x40, g_error_proc); write_far(window_vmt + 0x20, g_create_proc); write_far(window_vmt + 0x4c, g_execute_proc); reset_state(); assert(object_windows_application_validate_window(application, 0) == 0); win16_write_u16(window, 2, 0); assert(object_windows_application_validate_window(application, window) == window); reset_state(); win16_write_u16(window, 2, 5); assert(object_windows_application_validate_window(application, window) == 0); assert(g_error == 5 && g_disposed == window && g_ensure_calls == 0); reset_state(); g_reserve_unallocated = true; win16_write_u16(window, 2, 0); assert(object_windows_application_validate_window(application, window) == 0); assert(g_error == 0xfffe && g_disposed == window && g_ensure_calls == 1); reset_state(); g_validator_result = window; g_create_result = true; assert(object_windows_application_make_window(application, window) == window); assert(g_disposed == 0); reset_state(); g_validator_result = window; g_create_result = false; win16_write_u16(window, 2, 7); assert(object_windows_application_make_window(application, window) == 0); assert(g_error == 7 && g_disposed == window); reset_state(); g_validator_result = 0; assert(object_windows_application_make_window(application, window) == 0); assert(g_disposed == 0); reset_state(); g_validator_result = window; g_execute_result = 4; assert(object_windows_application_exec_dialog(application, window) == 4); assert(g_disposed == window && g_error == 0); reset_state(); g_validator_result = window; g_execute_result = -1; assert(object_windows_application_exec_dialog(application, window) == 2); assert(g_error == 0xffff && g_disposed == window); reset_state(); g_validator_result = 0; assert(object_windows_application_exec_dialog(application, window) == 2); assert(g_disposed == 0); g_message_box_response = 6; object_windows_application_error(application, 123); assert(strcmp(g_message_text, "Error code = 123. Continue?") == 0); g_message_box_response = 7; if (setjmp(g_exit_jump) == 0) { object_windows_application_error(application, 0x8123); assert(false); } assert(g_exit_status == 0x8123); assert(strcmp(g_message_text, "Error code = -32477. Continue?") == 0); return 0; }