From cf9bfbb864668b9d3a8035e3882587ec46550d6e Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sat, 23 May 2026 20:17:37 +0200 Subject: [PATCH] tests --- kern.h | 1 + kern_wasm.asm | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++ nwtests.c | 44 ++++++++++++ 3 files changed, 230 insertions(+) diff --git a/kern.h b/kern.h index b9e89a6..069d214 100644 --- a/kern.h +++ b/kern.h @@ -19,6 +19,7 @@ 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_CallVersion_Nios_Probe(void *outbuf); extern int KERN_CALL C32_MapLock_Probe(void *ptr, UI len, void *outbuf); +extern int KERN_CALL C32_ScanFirst_Probe(void *outbuf); extern int KERN_CALL C32_OpenRef_Probe(UI refLo, UI refHi, void *outbuf); extern int KERN_CALL C32_NCP87_Raw_Probe(UI connLo, UI connHi, void *hdr, UI hdrLen, diff --git a/kern_wasm.asm b/kern_wasm.asm index cfa1097..41d6216 100644 --- a/kern_wasm.asm +++ b/kern_wasm.asm @@ -26,6 +26,7 @@ public _C32_CallVersion_Nios_Probe public _C32_MapLock_Probe public _C32_NCP87_Raw_Probe public _C32_OpenRef_Probe +public _C32_ScanFirst_Probe public _Net_Call_VLM_Raw public _Net_Call_NWCVLMREQ @@ -1324,4 +1325,188 @@ c32openref_name db 'CONNOpenByReference',0 _C32_OpenRef_Probe endp +; int C32_ScanFirst_Probe(void *outbuf) +; +; Experimental minimal CONNScanInfo call through Client32/NIOS. +; It resolves CONNScanInfo and calls NIOS command 0x0A with: +; - no scan criterion +; - no returnConnInfo +; - a 4-byte iterator/connRef buffer +; +; This follows the d32wrap.o _CONNScanInfo call mechanics, but avoids the +; higher-level NWCString/SPECTDATA conversions for the first probe. +; +; outbuf: +; +00 load AX +; +02 resolver off +; +04 resolver seg +; +06 trampoline off +; +08 trampoline seg +; +0A function off +; +0C function seg +; +0E return AX +; +10 return DX +; +12 result/iterator low +; +14 result/iterator high +_C32_ScanFirst_Probe proc far + push bp + mov bp, sp + sub sp, 80 + + push ds + push es + push si + push di + + ; clear ESI/ECX + db 66h, 33h, 0F6h + db 66h, 33h, 0C9h + + mov ax, 0D8C1h + int 2Fh + + mov [bp-4], ax ; load AX + ; resolver ESI -> [bp-8] + db 66h, 89h, 76h, 0F8h + ; trampoline ECX -> [bp-12] + db 66h, 89h, 4Eh, 0F4h + + or ax, ax + jne c32scan_fail + + ; resolve "CONNScanInfo" + push cs + push offset c32scan_name + push 0 + push 0 + call dword ptr [bp-8] + add sp, 8 + mov [bp-16], ax + mov [bp-14], dx + or ax, dx + jne c32scan_have_func + jmp c32scan_fail + +c32scan_have_func: + ; local result/iterator dword at [bp-20] + mov word ptr [bp-20], 0 + mov word ptr [bp-18], 0 + + ; MapLockFlat(&iterator, 4) -> flat [bp-24] + push 0 + push 4 + push ss + lea ax, -20[bp] + push ax + push 0 + push 2 + call dword ptr [bp-8] + add sp, 0cH + mov [bp-24], ax + mov [bp-22], dx + + ; NIOS command 0x0A / CONNScanInfo. + ; Layout mirrors d32wrap _CONNScanInfo's final ECX trampoline call: + ; mapped iterator/result pointer + push word ptr [bp-22] + push word ptr [bp-24] + + ; mapped returnInfo pointer = NULL + push 0 + push 0 + + ; returnInfo length = 0 + push 0 + push 0 + + ; eight scan/return fields = 0 for first/enumerate probe + push 0 + push 0 + push 0 + push 0 + push 0 + push 0 + push 0 + push 0 + + ; mapped scanInfo pointer = NULL + push 0 + push 0 + + ; four reserved/handle words; d32conni uses FEFE placeholders + push 0fefeH + push 0fefeH + push 0fefeH + push 0fefeH + + push 0 + push 0aH + push word ptr [bp-14] + push word ptr [bp-16] + call dword ptr [bp-12] + add sp, 30H + + mov [bp-28], ax + mov [bp-26], dx + + ; Unlock iterator + push 0 + push 4 + push word ptr [bp-22] + push word ptr [bp-24] + push 0 + push 3 + call dword ptr [bp-8] + add sp, 0cH + + jmp short c32scan_store + +c32scan_fail: + mov word ptr [bp-16], 0 + mov word ptr [bp-14], 0 + mov word ptr [bp-28], 0ffffH + mov word ptr [bp-26], 0ffffH + mov word ptr [bp-20], 0 + mov word ptr [bp-18], 0 + +c32scan_store: + les di, dword ptr [bp+6] + + mov ax, [bp-4] + mov es:[di+0], ax + mov ax, [bp-8] + mov es:[di+2], ax + mov ax, [bp-6] + mov es:[di+4], ax + mov ax, [bp-12] + mov es:[di+6], ax + mov ax, [bp-10] + mov es:[di+8], ax + mov ax, [bp-16] + mov es:[di+10], ax + mov ax, [bp-14] + mov es:[di+12], ax + mov ax, [bp-28] + mov es:[di+14], ax + mov ax, [bp-26] + mov es:[di+16], ax + mov ax, [bp-20] + mov es:[di+18], ax + mov ax, [bp-18] + mov es:[di+20], ax + + pop di + pop si + pop es + pop ds + mov sp, bp + pop bp + xor ah, ah + ret + +c32scan_name db 'CONNScanInfo',0 + +_C32_ScanFirst_Probe endp + + end diff --git a/nwtests.c b/nwtests.c index 3fb3b97..c40e41a 100644 --- a/nwtests.c +++ b/nwtests.c @@ -1565,6 +1565,47 @@ static int tests_c32mapconnone(int argc, char *argv[]) } +static int tests_c32scanfirst(void) +{ + uint8 out[32]; + uint16 load_ax, res_off, res_seg, tramp_off, tramp_seg; + uint16 fn_off, fn_seg, ret_ax, ret_dx, ref_lo, ref_hi; + + memset(out, 0, sizeof(out)); + + fprintf(stdout, "TEST C32SCANFIRST\n"); + fprintf(stdout, "Minimal CONNScanInfo enumerate probe, no scan criterion\n"); + + C32_ScanFirst_Probe(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); + tramp_off = tests_get_word_lh(out + 6); + tramp_seg = tests_get_word_lh(out + 8); + fn_off = tests_get_word_lh(out + 10); + fn_seg = tests_get_word_lh(out + 12); + ret_ax = tests_get_word_lh(out + 14); + ret_dx = tests_get_word_lh(out + 16); + ref_lo = tests_get_word_lh(out + 18); + ref_hi = tests_get_word_lh(out + 20); + + fprintf(stdout, "Load AX=%04X Resolver=%04X:%04X Tramp=%04X:%04X\n", + load_ax, res_seg, res_off, tramp_seg, tramp_off); + fprintf(stdout, "Function CONNScanInfo=%04X:%04X\n", fn_seg, fn_off); + fprintf(stdout, "Return DX:AX=%04X:%04X scan/result=%04X:%04X\n", + ret_dx, ret_ax, ref_hi, ref_lo); + tests_dump_bytes("OUT:", out, 22); + + if (ret_ax == 0 && ret_dx == 0 && (ref_lo || ref_hi)) { + fprintf(stdout, "\nTry next:\n"); + fprintf(stdout, " TESTS C32OPENREF %u %u\n", ref_lo, ref_hi); + } + + return(0); +} + + int func_tests(int argc, char *argv[], int mode) { if (argc >= 2) { @@ -1598,6 +1639,9 @@ int func_tests(int argc, char *argv[], int mode) if (tests_same_arg(argv[1], "C32MAPCONNONE")) return tests_c32mapconnone(argc, argv); + if (tests_same_arg(argv[1], "C32SCANFIRST")) + return tests_c32scanfirst(); + if (tests_same_arg(argv[1], "NWREQ87C32MATRIX")) return tests_nwreq87c32matrix();