This commit is contained in:
Mario Fetka
2026-05-23 17:29:01 +02:00
parent 30db93ec8d
commit 64ab3a4fab
3 changed files with 151 additions and 0 deletions

1
kern.h
View File

@@ -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);

View File

@@ -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

View File

@@ -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);