diff --git a/kern.h b/kern.h index 818a4d1..5b66362 100644 --- a/kern.h +++ b/kern.h @@ -16,11 +16,10 @@ 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_CallVersion_Nios_Probe(void *outbuf); +extern int KERN_CALL C32_MapLock_Probe(void *ptr, UI len, 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); -extern int KERN_CALL Net_Call_NWCVLMREQ(UI flags, void *regblk, - UI p1, UI p2, UI p3); extern int KERN_CALL Net_Call_C(UI func, void *req, void *repl); extern int KERN_CALL Net_Call_CX(UI func, UI bx, UI cx, UI dx, void *req, void *repl); diff --git a/kern_wasm.asm b/kern_wasm.asm index a870b3a..3a1a811 100644 --- a/kern_wasm.asm +++ b/kern_wasm.asm @@ -23,8 +23,8 @@ public _Net_Call public _C32_LoadNios_Probe public _C32_GetFunc_Probe public _C32_CallVersion_Nios_Probe +public _C32_MapLock_Probe public _Net_Call_VLM_Raw -public _Net_Call_NWCVLMREQ _IPXinit proc far push bp @@ -593,115 +593,119 @@ c32ver_name db 'CLIENT32GetVersion',0 _C32_CallVersion_Nios_Probe endp -; int Net_Call_NWCVLMREQ(UI flags, void *regblk, UI p1, UI p2, UI p3) +; int C32_MapLock_Probe(void *ptr, UI len, void *outbuf) ; -; 16-bit wrapper that reproduces the DeveloperNet NWCVLMREQ register-block -; calling convention, but without using Novell globals. +; Probe d32wrap.o __MapLockFlat / __UnlockFlat: +; INT 2F AX=D8C1 +; ESI resolver returned by D8C1 is used with command 2 and 3: +; push len_hi +; push len_lo +; push seg +; push off +; push 0 +; push 2 +; call ESI ; returns flat DX:AX ; -; regblk layout, same as dvlmreq.o: -; +00 SI -; +02 DS -; +04 DI -; +06 ES -; +08 AX -; +0A BX -; +0C CX -; +0E DX +; push len_hi +; push len_lo +; push flat_hi +; push flat_lo +; push 0 +; push 3 +; call ESI ; unlock ; -; It calls the VLM entry returned by INT 2F AX=7A20. -; Stack args are pushed as p3,p2,p1, exactly like NWCVLMREQ. -_Net_Call_NWCVLMREQ proc far +; outbuf: +; +00 load AX +; +02 ESI off +; +04 ESI seg +; +06 map AX low +; +08 map DX high +; +0A unlock AX +; +0C unlock DX +_C32_MapLock_Probe proc far push bp mov bp, sp - sub sp, 4 + sub sp, 8 push ds + push es push si push di - push es - mov ax, 7A20h - xor bx, bx + ; clear ECX/ESI + db 66h, 33h, 0C9h + db 66h, 33h, 0F6h + + mov ax, 0D8C1h int 2Fh + + ; save ESI resolver at [bp-4] + db 66h, 89h, 76h, 0FCh + push ax ; load AX + or ax, ax - jz nwcvlm_found + jne mapflat_fail - mov ax, 88FFh - jmp short nwcvlm_done - -nwcvlm_found: - ; save VLM entry ES:BX in [bp-4] - mov [bp-4], bx - mov ax, es - mov [bp-2], ax - - les bx, dword ptr [bp+8] ; regblk - - ; Match NWCVLMREQ defaulting: - ; if !(flags & 2), set regblk.ES to current ES. - ; We normally pass flags=2, so this is skipped. - test word ptr [bp+6], 2 - jne nwcvlm_skip_es - mov ax, es - mov word ptr es:[bx+6], ax -nwcvlm_skip_es: - - ; if !(flags & 1), set regblk.DS to current DS. - test word ptr [bp+6], 1 - jne nwcvlm_skip_ds - mov ax, ds - mov word ptr es:[bx+2], ax -nwcvlm_skip_ds: - - ; Load target registers from regblk. - mov ax, word ptr es:[bx+0Ah] - push ax ; target BX - mov ax, word ptr es:[bx+6] - push ax ; target ES - - mov ax, word ptr es:[bx+8] - mov cx, word ptr es:[bx+0Ch] - mov dx, word ptr es:[bx+0Eh] - mov si, word ptr es:[bx+0] - mov di, word ptr es:[bx+4] - mov ds, word ptr es:[bx+2] - - pop es - pop bx - - push word ptr [bp+10h] ; p3 - push word ptr [bp+0eh] ; p2 - push word ptr [bp+0ch] ; p1 + ; MapLockFlat(ptr, len) + push 0 + push word ptr [bp+10] ; len + push word ptr [bp+8] ; ptr seg + push word ptr [bp+6] ; ptr off + push 0 + push 2 call dword ptr [bp-4] + add sp, 0cH - ; Store registers back into regblk. - push bx - push es + ; save mapped flat DX:AX at [bp-8] + mov word ptr [bp-8], ax + mov word ptr [bp-6], dx - les bx, dword ptr [bp+8] - mov word ptr es:[bx+8], ax - pop ax - mov word ptr es:[bx+6], ax - pop ax - mov word ptr es:[bx+0Ah], ax - mov word ptr es:[bx+0Ch], cx - mov word ptr es:[bx+0Eh], dx - mov word ptr es:[bx+0], si - mov word ptr es:[bx+4], di - mov word ptr es:[bx+2], ds + ; UnlockFlat(flat, len) + push 0 + push word ptr [bp+10] ; len + push dx + push ax + push 0 + push 3 + call dword ptr [bp-4] + add sp, 0cH - mov ax, word ptr es:[bx+8] + jmp short mapflat_store + +mapflat_fail: + xor dx, dx + xor ax, ax + mov word ptr [bp-8], ax + mov word ptr [bp-6], dx + +mapflat_store: + les di, dword ptr [bp+12] + + mov bx, ax ; unlock AX + mov cx, dx ; unlock DX + pop ax ; load AX + + mov es:[di+0], ax + mov ax, word ptr [bp-4] + mov es:[di+2], ax + mov ax, word ptr [bp-2] + mov es:[di+4], ax + mov ax, word ptr [bp-8] + mov es:[di+6], ax + mov ax, word ptr [bp-6] + mov es:[di+8], ax + mov es:[di+10], bx + mov es:[di+12], cx -nwcvlm_done: - pop es pop di pop si + pop es pop ds - mov sp, bp pop bp + xor ah, ah ret -_Net_Call_NWCVLMREQ endp +_C32_MapLock_Probe endp end diff --git a/nwtests.c b/nwtests.c index aa75072..70fe3a6 100644 --- a/nwtests.c +++ b/nwtests.c @@ -1259,156 +1259,42 @@ static int tests_c32callver2(void) } -static void tests_set_reg_word(uint8 *r, int off, UI val) +static int tests_c32mapflat(void) { - tests_put_word_lh(r + off, (uint16)val); -} + uint8 out[32]; + char sample[32]; + uint16 load_ax, esi_off, esi_seg; + uint16 map_lo, map_hi; + uint16 unl_ax, unl_dx; -static UI tests_get_reg_word(uint8 *r, int off) -{ - return (UI)(r[off] | ((UI)r[off + 1] << 8)); -} + strcpy(sample, "C32MAPFLAT"); + memset(out, 0, sizeof(out)); -static void tests_dump_vlm_regs(char *title, uint8 *r) -{ - fprintf(stdout, "%s SI=%04X DS=%04X DI=%04X ES=%04X AX=%04X BX=%04X CX=%04X DX=%04X\n", - title, - tests_get_reg_word(r, 0), - tests_get_reg_word(r, 2), - tests_get_reg_word(r, 4), - tests_get_reg_word(r, 6), - tests_get_reg_word(r, 8), - tests_get_reg_word(r, 10), - tests_get_reg_word(r, 12), - tests_get_reg_word(r, 14)); -} + fprintf(stdout, "TEST C32MAPFLAT\n"); + fprintf(stdout, "Probe d32wrap __MapLockFlat/__UnlockFlat via NIOS resolver\n"); + fprintf(stdout, "sample ptr=%04X:%04X len=%u text=%s\n", + FP_SEG(sample), FP_OFF(sample), (UI)strlen(sample) + 1, sample); -static int tests_c32mapconn(void) -{ - int drive; - uint8 connid = 0; - uint8 dhandle = 0; - uint8 flags = 0; - uint8 regs[16]; - uint8 reply[128]; - int rc; + C32_MapLock_Probe(sample, (UI)strlen(sample) + 1, out); - drive = tests_get_current_drive(); - if (get_drive_info((uint8)drive, &connid, &dhandle, &flags)) { - fprintf(stdout, "get_drive_info failed\n"); - return(1); - } + load_ax = tests_get_word_lh(out + 0); + esi_off = tests_get_word_lh(out + 2); + esi_seg = tests_get_word_lh(out + 4); + map_lo = tests_get_word_lh(out + 6); + map_hi = tests_get_word_lh(out + 8); + unl_ax = tests_get_word_lh(out + 10); + unl_dx = tests_get_word_lh(out + 12); - memset(regs, 0, sizeof(regs)); - memset(reply, 0, sizeof(reply)); + fprintf(stdout, "Load AX=%04X Resolver=%04X:%04X\n", + load_ax, esi_seg, esi_off); + fprintf(stdout, "MapLock returned flat=%04X:%04X\n", map_hi, map_lo); + fprintf(stdout, "Unlock returned DX:AX=%04X:%04X\n", unl_dx, unl_ax); + tests_dump_bytes("RAW:", out, 14); - /* - * First half of DeveloperNet __C32MapConn16To32: - * - * reg.CX = conn16 - * reg.ES:DI = reply buffer - * NWCVLMREQ(flags=2, regblk, p1=0Dh, p2=10h, p3=0) - * - * The reply buffer should contain the connection/server reference string - * that w95mconn.o later passes to NWCSCANCONNINFO. - */ - tests_set_reg_word(regs, 4, FP_OFF(reply)); /* DI */ - tests_set_reg_word(regs, 6, FP_SEG(reply)); /* ES */ - tests_set_reg_word(regs, 12, connid); /* CX */ - - fprintf(stdout, "TEST C32MAPCONN step1, __C32MapConn16To32 VLM probe\n"); - fprintf(stdout, "drive=%c: connid=%u dhandle=%u flags=%02X\n", - 'A' + drive, connid, dhandle, flags); - tests_dump_vlm_regs("REG in :", regs); - fprintf(stdout, "Call NWCVLMREQ flags=2 p1=000D p2=0010 p3=0000\n"); - - rc = Net_Call_NWCVLMREQ(2, regs, 0x000D, 0x0010, 0); - - fprintf(stdout, "NWCVLMREQ rc=%04X\n", rc); - tests_dump_vlm_regs("REG out:", regs); - tests_dump_bytes("REPLY:", reply, 64); - fprintf(stdout, "REPLY text: %s\n", reply); - - fprintf(stdout, "\nIf REPLY contains a server/conn string, next step is NWCSCANCONNINFO.\n"); - return(0); -} - - -static int tests_c32mapconn_value(UI conn16, UI label) -{ - uint8 regs[16]; - uint8 reply[128]; - int rc; - - memset(regs, 0, sizeof(regs)); - memset(reply, 0, sizeof(reply)); - - tests_set_reg_word(regs, 4, FP_OFF(reply)); /* DI */ - tests_set_reg_word(regs, 6, FP_SEG(reply)); /* ES */ - tests_set_reg_word(regs, 12, conn16); /* CX */ - - fprintf(stdout, "\nC32MAPCONN value=%u label=%u\n", conn16, label); - tests_dump_vlm_regs("REG in :", regs); - fprintf(stdout, "Call NWCVLMREQ flags=2 p1=000D p2=0010 p3=0000\n"); - - rc = Net_Call_NWCVLMREQ(2, regs, 0x000D, 0x0010, 0); - - fprintf(stdout, "NWCVLMREQ rc=%04X\n", rc); - tests_dump_vlm_regs("REG out:", regs); - tests_dump_bytes("REPLY:", reply, 64); - fprintf(stdout, "REPLY text: %s\n", reply); - - return rc; -} - -static int tests_c32mapconnone(int argc, char *argv[]) -{ - UI val; - - if (argc < 3) { - fprintf(stdout, "Usage: TESTS C32MAPCONNONE value\n"); - return(1); - } - - val = (UI)atoi(argv[2]); - return tests_c32mapconn_value(val, val); -} - -static int tests_c32mapconnmatrix(void) -{ - int drive; - uint8 connid = 0; - uint8 dhandle = 0; - uint8 flags = 0; - UI values[12]; - int i; - - drive = tests_get_current_drive(); - get_drive_info((uint8)drive, &connid, &dhandle, &flags); - - values[0] = 0; - values[1] = 1; - values[2] = 2; - values[3] = 3; - values[4] = 4; - values[5] = (UI)connid; - values[6] = (UI)dhandle; - values[7] = (UI)drive; - values[8] = (UI)(drive + 1); - values[9] = 0x31; - values[10] = 0x3130; - values[11] = 0xffff; - - fprintf(stdout, "TEST C32MAPCONNMATRIX paged\n"); - fprintf(stdout, "drive=%c: connid=%u dhandle=%u flags=%02X\n", - 'A' + drive, connid, dhandle, flags); - tests_wait_key(); - - for (i = 0; i < 12; i++) { - tests_c32mapconn_value(values[i], (UI)i); - if (i != 11) - tests_wait_key(); - } + if (load_ax == 0 && (map_lo || map_hi)) + fprintf(stdout, "\nMapLockFlat appears to work.\n"); + else + fprintf(stdout, "\nMapLockFlat did not return a flat pointer.\n"); return(0); } @@ -1432,14 +1318,8 @@ int func_tests(int argc, char *argv[], int mode) if (tests_same_arg(argv[1], "C32CALLVER2")) return tests_c32callver2(); - if (tests_same_arg(argv[1], "C32MAPCONN")) - return tests_c32mapconn(); - - if (tests_same_arg(argv[1], "C32MAPCONNONE")) - return tests_c32mapconnone(argc, argv); - - if (tests_same_arg(argv[1], "C32MAPCONNMATRIX")) - return tests_c32mapconnmatrix(); + if (tests_same_arg(argv[1], "C32MAPFLAT")) + return tests_c32mapflat(); if (tests_same_arg(argv[1], "NWREQ87")) return tests_nwreq87(argc, argv);