From 64ab3a4fabb4128c7b1a930e6c61b4c728a49b55 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sat, 23 May 2026 17:29:01 +0200 Subject: [PATCH] tests --- kern.h | 1 + kern_wasm.asm | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ nwtests.c | 43 ++++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/kern.h b/kern.h index 1218aed..d07ca87 100644 --- a/kern.h +++ b/kern.h @@ -15,6 +15,7 @@ extern void KERN_CALL xmemmove(void *ziel, void *quelle, UI anz); extern int KERN_CALL Net_Call(UI func, void *req, void *repl); extern int KERN_CALL C32_LoadNios_Probe(UI axfunc, void *outbuf); extern int KERN_CALL C32_GetFunc_Probe(char *name, void *outbuf); +extern int KERN_CALL C32_CallName0_Probe(char *name, void *outbuf); extern int KERN_CALL Net_Call_VLM_Raw(UI ax, UI bx, UI cx, UI dx, void *req, void *repl, UI p1, UI p2, UI p3); diff --git a/kern_wasm.asm b/kern_wasm.asm index d928077..a8af853 100644 --- a/kern_wasm.asm +++ b/kern_wasm.asm @@ -22,6 +22,7 @@ public _xmemmove public _Net_Call public _C32_LoadNios_Probe public _C32_GetFunc_Probe +public _C32_CallName0_Probe public _Net_Call_VLM_Raw _IPXinit proc far @@ -466,4 +467,110 @@ c32get_store: _C32_GetFunc_Probe endp +; int C32_CallName0_Probe(char *name, void *outbuf) +; +; Resolve Client32 function by name via NIOS resolver returned by D8C1, +; then call resolved function with zero arguments. +; +; This is safe for CLIENT32GetVersion. Do not use for functions needing args. +; +; outbuf: +; +00 load AX +; +02 resolver ptr off +; +04 resolver ptr seg +; +06 resolved fn off +; +08 resolved fn seg +; +0A call return AX +; +0C call return DX +; +0E call return FLAGS +_C32_CallName0_Probe proc far + push bp + mov bp, sp + sub sp, 8 + + push ds + push es + push si + push di + pushf + + ; clear ECX/ESI + db 66h, 33h, 0C9h + db 66h, 33h, 0F6h + + mov ax, 0D8C1h + int 2Fh + + ; save resolver ESI at [bp-4] + db 66h, 89h, 76h, 0FCh + + push ax ; load AX + + or ax, ax + jne c32call_store_fail + + ; resolve function name: + ; push name segment, name offset, 0, 0; call resolver; add sp,8 + push word ptr [bp+8] + push word ptr [bp+6] + push 0 + push 0 + call dword ptr [bp-4] + add sp, 8 + + ; save resolved function pointer DX:AX at [bp-8] + mov word ptr [bp-8], ax + mov word ptr [bp-6], dx + + or ax, dx + je c32call_store_fail2 + + ; call resolved function with zero args + call dword ptr [bp-8] + pushf + push dx + push ax + jmp short c32call_store + +c32call_store_fail2: + xor dx, dx + xor ax, ax +c32call_store_fail: + pushf + push dx + push ax + +c32call_store: + les di, dword ptr [bp+10] + + pop ax ; call AX + pop dx ; call DX + pop bx ; flags + pop cx ; load AX + + mov es:[di+0], cx + mov cx, word ptr [bp-4] + mov es:[di+2], cx + mov cx, word ptr [bp-2] + mov es:[di+4], cx + mov cx, word ptr [bp-8] + mov es:[di+6], cx + mov cx, word ptr [bp-6] + mov es:[di+8], cx + mov es:[di+10], ax + mov es:[di+12], dx + mov es:[di+14], bx + + popf + pop di + pop si + pop es + pop ds + mov sp, bp + pop bp + xor ah, ah + ret +_C32_CallName0_Probe endp + + end diff --git a/nwtests.c b/nwtests.c index ba530f7..97bf43d 100644 --- a/nwtests.c +++ b/nwtests.c @@ -1218,6 +1218,46 @@ static int tests_c32getfunc(void) } +static int tests_c32callver(void) +{ + uint8 out[32]; + uint16 load_ax; + uint16 res_off, res_seg; + uint16 fn_off, fn_seg; + uint16 call_ax, call_dx, flags; + + memset(out, 0, sizeof(out)); + + fprintf(stdout, "TEST C32CALLVER\n"); + fprintf(stdout, "Resolve and call CLIENT32GetVersion with zero args\n\n"); + + C32_CallName0_Probe("CLIENT32GetVersion", out); + + load_ax = tests_get_word_lh(out + 0); + res_off = tests_get_word_lh(out + 2); + res_seg = tests_get_word_lh(out + 4); + fn_off = tests_get_word_lh(out + 6); + fn_seg = tests_get_word_lh(out + 8); + call_ax = tests_get_word_lh(out + 10); + call_dx = tests_get_word_lh(out + 12); + flags = tests_get_word_lh(out + 14); + + fprintf(stdout, "Load AX=%04X\n", load_ax); + fprintf(stdout, "Resolver=%04X:%04X\n", res_seg, res_off); + fprintf(stdout, "Function=%04X:%04X\n", fn_seg, fn_off); + fprintf(stdout, "Call returned DX:AX=%04X:%04X FLAGS=%04X\n", + call_dx, call_ax, flags); + tests_dump_bytes("RAW:", out, 16); + + if (fn_off || fn_seg) + fprintf(stdout, "\nFunction pointer resolved.\n"); + if (call_ax || call_dx) + fprintf(stdout, "Call returned non-zero version value.\n"); + + return(0); +} + + int func_tests(int argc, char *argv[], int mode) { if (argc >= 2) { @@ -1233,6 +1273,9 @@ int func_tests(int argc, char *argv[], int mode) if (tests_same_arg(argv[1], "C32GETFUNC")) return tests_c32getfunc(); + if (tests_same_arg(argv[1], "C32CALLVER")) + return tests_c32callver(); + if (tests_same_arg(argv[1], "NWREQ87")) return tests_nwreq87(argc, argv);