; kern_wasm.asm ; ; Open Watcom WASM/MASM-syntax port of the old TASM IDEAL kern.asm. ; Intended for 16-bit DOS large memory model builds on Linux with Open Watcom v2. ; ; Keep kern.asm as the historical TASM source and use this file for the ; reproducible Open Watcom build. .286 .model large .data enterIPX dd 0 .code public _IPXinit public _IPXopen_socket public _IPXclose_socket public _IPXlisten public _xmemmove public _Net_Call public _C32_LoadNios_Probe public _C32_GetFunc_Probe public _C32_CallVersion_Nios_Probe public _C32_MapLock_Probe public _C32_NCP87_Raw5_Probe public _C32_OpenRef_Probe public _C32_MapVar_Probe public _Net_Call_VLM_Raw _IPXinit proc far push bp mov bp, sp push ds push si push di mov ax, 7A00h int 2Fh cmp al, 0FFh jne ipxinit_done mov cx, @data mov ds, cx mov word ptr enterIPX, di mov ax, es mov word ptr enterIPX+2, ax mov al, 1 ipxinit_done: mov ah, 0 pop di pop si pop ds pop bp ret _IPXinit endp _xmemmove proc far push bp mov bp, sp ; far procedure stack layout, large model: ; [bp+0] old bp ; [bp+2] return offset ; [bp+4] return segment ; [bp+6] z offset ; [bp+8] z segment ; [bp+10] q offset ; [bp+12] q segment ; [bp+14] nmbr cli mov cx, [bp+14] or cx, cx jz xmem_done push ds push si push di pushf lds si, dword ptr [bp+10] les di, dword ptr [bp+6] cmp di, si jl xmem_forward std dec cx add di, cx add si, cx inc cx jmp xmem_copy xmem_forward: cld xmem_copy: rep movsb popf pop di pop si pop ds xmem_done: pop bp sti ret _xmemmove endp _IPXopen_socket proc far push bp mov bp, sp push ds push si push di ; int IPXopen_socket(UI sock, int live) mov ax, [bp+8] ; live mov dx, [bp+6] ; sock mov bx, @data mov ds, bx mov bx, 0 call dword ptr enterIPX cmp al, 0FFh jne ipxopen_not_already mov ax, -1 ; socket already open jmp ipxopen_done ipxopen_not_already: cmp al, 0FEh jne ipxopen_ok mov ax, -2 ; socket table full jmp ipxopen_done ipxopen_ok: mov ax, dx ipxopen_done: pop di pop si pop ds pop bp ret _IPXopen_socket endp _IPXclose_socket proc far push bp mov bp, sp push ds push si push di ; void IPXclose_socket(UI sock) mov dx, [bp+6] mov bx, @data mov ds, bx mov bx, 1 call dword ptr enterIPX pop di pop si pop ds pop bp ret _IPXclose_socket endp _IPXlisten proc far push bp mov bp, sp push ds push si push di ; int IPXlisten(ECB *ecb) les si, dword ptr [bp+6] mov bx, @data mov ds, bx mov bx, 4 call dword ptr enterIPX pop di pop si pop ds pop bp mov ah, 0 ret _IPXlisten endp _Net_Call proc far push bp mov bp, sp ; int Net_Call(UI func, void *req, void *repl) ; [bp+6] func ; [bp+8] req offset ; [bp+10] req segment ; [bp+12] repl offset ; [bp+14] repl segment mov ax, [bp+6] push ds push si push di pushf lds si, dword ptr [bp+8] les di, dword ptr [bp+12] int 21h popf pop di pop si pop ds pop bp mov ah, 0 ret _Net_Call endp ; int Net_Call_VLM_Raw(UI ax, UI bx, UI cx, UI dx, ; void *req, void *repl, ; UI p1, UI p2, UI p3) ; ; Experimental VLM entry caller. ; INT 2F AX=7A20 returns ES:BX = VLM entry if AX == 0000. ; ; Register setup for VLM entry: ; AX, BX, CX, DX from function args ; DS:SI = req ; ES:DI = repl ; ; Extra stack args pushed before calling VLM entry: ; p3, p2, p1 ; ; For NWCREQUEST/VLM test: ; AX=function ; BX=numReqFrags ; CX=connid ; DX=numReplyFrags ; DS:SI=reqFragList ; ES:DI=replyFragList ; p1=6, p2=20h, p3=0 _Net_Call_VLM_Raw proc far push bp mov bp, sp sub sp, 4 push ds push si push di push es mov ax, 7A20h xor bx, bx int 2Fh or ax, ax jz vlm_raw_found mov ax, 88FFh jmp short vlm_raw_done vlm_raw_found: ; save VLM entry ES:BX in stack locals mov [bp-4], bx mov ax, es mov [bp-2], ax ; load caller-requested registers mov ax, [bp+6] mov bx, [bp+8] mov cx, [bp+10] mov dx, [bp+12] lds si, dword ptr [bp+14] les di, dword ptr [bp+18] push word ptr [bp+26] push word ptr [bp+24] push word ptr [bp+22] call dword ptr [bp-4] vlm_raw_done: pop es pop di pop si pop ds mov sp, bp pop bp ret _Net_Call_VLM_Raw endp ; int C32_LoadNios_Probe(UI axfunc, void *outbuf) ; ; 16-bit object, but captures 32-bit ESI and ECX using manual 386 opcodes. ; This keeps the OMF/linker in 16-bit mode while still reading Client32/NIOS ; values returned by: ; INT 2F AX=D8C1 ; ; outbuf: ; +00 word AX after INT 2F ; +02 dword ESI after INT 2F ; +06 dword ECX after INT 2F ; +0A word BX ; +0C word CX low ; +0E word DX ; +10 word SI low ; +12 word DS ; +14 word ES _C32_LoadNios_Probe proc far push bp mov bp, sp push ds push es push si push di ; xor ecx, ecx db 66h, 33h, 0C9h ; xor esi, esi db 66h, 33h, 0F6h mov ax, [bp+6] int 2Fh push ds push es push si push cx push bx push dx push ax les di, dword ptr [bp+8] ; restore AX result into AX and store word at out+0 pop ax mov es:[di+0], ax ; Store ESI dword at es:[di+2]. ; Encoding: ES override + operand-size prefix + MOV r/m32,r32 ; mov es:[di+02], esi = 26 66 89 75 02 db 26h, 66h, 89h, 75h, 02h ; Store ECX dword at es:[di+6]. ; mov es:[di+06], ecx = 26 66 89 4Dh 06 db 26h, 66h, 89h, 4Dh, 06h pop dx pop bx pop cx mov es:[di+10], bx mov es:[di+12], cx mov es:[di+14], dx pop ax ; saved SI mov es:[di+16], ax pop ax ; saved ES pop bx ; saved DS mov es:[di+18], bx mov es:[di+20], ax pop di pop si pop es pop ds pop bp xor ah, ah ret _C32_LoadNios_Probe endp ; int C32_GetFunc_Probe(char *name, void *outbuf) ; ; 16-bit OMF Client32 function resolver probe. ; This mimics C32BEGINUSE for one function name: ; INT 2F AX=D8C1 ; save ESI as far pointer to __Nios+8 function resolver ; push name segment ; push name offset ; push 0 ; push 0 ; call far [ESI] ; add sp,8 ; ; outbuf: ; +00 word load AX from INT2F ; +02 dword ESI from INT2F ; +06 dword ECX from INT2F ; +0A word resolver return AX ; +0C word resolver return DX ; +0E word BX ; +10 word CX _C32_GetFunc_Probe proc far push bp mov bp, sp sub sp, 4 push ds push es push si push di ; clear ECX/ESI db 66h, 33h, 0C9h db 66h, 33h, 0F6h mov ax, 0D8C1h int 2Fh ; save ESI dword to [bp-4] db 66h, 89h, 76h, 0FCh push ax ; save load AX ; call resolver only if AX == 0 or ax, ax jne c32get_store_fail push word ptr [bp+8] ; name segment push word ptr [bp+6] ; name offset push 0 push 0 call dword ptr [bp-4] add sp, 8 jmp short c32get_store c32get_store_fail: xor dx, dx xor ax, ax c32get_store: push dx push ax les di, dword ptr [bp+10] pop ax ; resolver AX pop dx ; resolver DX pop bx ; load AX saved in BX temporarily mov es:[di+0], bx ; Store ESI dword at out+2: ES override + operand prefix db 26h, 66h, 89h, 75h, 02h ; Store ECX dword at out+6 db 26h, 66h, 89h, 4Dh, 06h mov es:[di+10], ax mov es:[di+12], dx mov es:[di+14], bx mov es:[di+16], cx pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret _C32_GetFunc_Probe endp ; int C32_CallVersion_Nios_Probe(void *outbuf) ; ; Safe Client32 version call using the exact d32wrap convention: ; 1) INT 2F AX=D8C1 ; 2) use ESI resolver to resolve "CLIENT32GetVersion" ; 3) call ECX trampoline, not the function pointer directly: ; push 0 ; push 0 ; push fn_seg ; push fn_off ; call ECX ; add sp,8 ; ; outbuf: ; +00 load AX ; +02 resolver off ; +04 resolver seg ; +06 trampoline off ; +08 trampoline seg ; +0A fn off ; +0C fn seg ; +0E call AX ; +10 call DX ; +12 flags _C32_CallVersion_Nios_Probe proc far push bp mov bp, sp sub sp, 12 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 ESI resolver at [bp-4] db 66h, 89h, 76h, 0FCh ; save ECX trampoline at [bp-8] db 66h, 89h, 4Eh, 0F8h push ax ; load AX for output or ax, ax jne c32ver_fail push cs push offset c32ver_name push 0 push 0 call dword ptr [bp-4] add sp, 8 ; resolver returns DX:AX function pointer mov [bp-12], ax mov [bp-10], dx or ax, dx je c32ver_fail ; d32wrap _CLIENT32GetVersion convention: push 0 push 0 push word ptr [bp-10] push word ptr [bp-12] call dword ptr [bp-8] add sp, 8 pushf push dx push ax jmp short c32ver_store c32ver_fail: xor dx, dx xor ax, ax pushf push dx push ax c32ver_store: les di, dword ptr [bp+6] 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 cx, word ptr [bp-12] mov es:[di+10], cx mov cx, word ptr [bp-10] mov es:[di+12], cx mov es:[di+14], ax mov es:[di+16], dx mov es:[di+18], bx popf pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret c32ver_name db 'CLIENT32GetVersion',0 _C32_CallVersion_Nios_Probe endp ; int C32_MapLock_Probe(void *ptr, UI len, void *outbuf) ; ; 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 ; ; push len_hi ; push len_lo ; push flat_hi ; push flat_lo ; push 0 ; push 3 ; call ESI ; unlock ; ; 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, 8 push ds push es push si push di ; 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 jne mapflat_fail ; 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 ; save mapped flat DX:AX at [bp-8] mov word ptr [bp-8], ax mov word ptr [bp-6], dx ; 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 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 pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret _C32_MapLock_Probe endp ; int C32_OpenRef_Probe(UI refLo, UI refHi, void *outbuf) ; ; Opens a Client32 connection by connection reference using the same d32wrap ; convention as _CONNOpenByReference / w95ocref.o. ; ; Input: ; refLo/refHi = connection reference, e.g. C32PRIMREF returned 0028:0000. ; ; outbuf: ; +00 load AX from D8C1 ; +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 handle low ; +14 handle high _C32_OpenRef_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 c32openref_fail ; resolve "CONNOpenByReference" push cs push offset c32openref_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 c32openref_have_func jmp c32openref_fail c32openref_have_func: ; local output handle dword at [bp-20] mov word ptr [bp-20], 0 mov word ptr [bp-18], 0 ; MapLockFlat(&handle, 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 ; Call NIOS trampoline command 5 / CONNOpenByReference. ; This matches d32wrap _CONNOpenByReference after w95ocref: ; flat handle ptr, ; refHi/refLo, ; 0,0, ; FEFE FEFE FEFE FEFE, ; command 5, ; function ptr. push word ptr [bp-22] ; flat handle high push word ptr [bp-24] ; flat handle low push word ptr [bp+8] ; ref high push word ptr [bp+6] ; ref low push 0 push 0 push 0fefeH push 0fefeH push 0fefeH push 0fefeH push 0 push 5 push word ptr [bp-14] ; function seg push word ptr [bp-16] ; function off call dword ptr [bp-12] add sp, 1cH mov [bp-28], ax mov [bp-26], dx ; UnlockFlat(handle flat, 4) 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 c32openref_store c32openref_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 c32openref_store: les di, dword ptr [bp+10] 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 c32openref_name db 'CONNOpenByReference',0 _C32_OpenRef_Probe endp ; int C32_MapVar_Probe(UI specLen, UI flag, void *outbuf) ; ; Exact-ish raw version of w95mconn.o::__C32MapConn16To32 second step. ; ; It emulates: ; C32MAPCONNONE 40 -> server name MARS ; NWCSCANCONNINFO(scanIterator/result ptr, ; scanInfoLevel=0A, scanConnInfo=NWCString/SPECTDATA "MARS", ; scanFlags=1, connInfoVersion=0, ; returnInfoLevel=0, returnConnInfo=NULL, ; connReference local) ; ; But calls Client32 CONNScanInfo directly through ECX/NIOS command 0A. ; ; outbuf: ; +00 load AX ; +02 resolver off ; +04 resolver seg ; +06 trampoline off ; +08 trampoline seg ; +0A function off ; +0C function seg ; +0E ret AX ; +10 ret DX ; +12 resultRef low ; corresponds to caller output ptr in w95mconn ; +14 resultRef high ; +16 connRefLocal low ; corresponds to d32conni local -1c ; +18 connRefLocal high _C32_MapVar_Probe proc far push bp mov bp, sp sub sp, 140 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 c32mapvar_fail ; resolve "CONNScanInfo" push cs push offset c32mapvar_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 c32mapvar_have_func jmp c32mapvar_fail c32mapvar_have_func: ; resultRef/output dword at [bp-20], init 0 mov word ptr [bp-20], 0 mov word ptr [bp-18], 0 ; connReference local dword at [bp-24], init 0 mov word ptr [bp-24], 0 mov word ptr [bp-22], 0 ; string buffer at [bp-80], copy "MARS", zero padded enough lea di, -80[bp] push ss pop es mov byte ptr es:[di+0], 'M' mov byte ptr es:[di+1], 'A' mov byte ptr es:[di+2], 'R' mov byte ptr es:[di+3], 'S' mov byte ptr es:[di+4], 0 ; Map string buffer len 31h -> [bp-28] push 0 push 31H push ss lea ax, -80[bp] push ax push 0 push 2 call dword ptr [bp-8] add sp, 0cH mov [bp-28], ax mov [bp-26], dx ; Build SPECTDATA/NWCString transfer block at [bp-48], len 10h. ; Mirrors d32conni initialization for server-name scan. mov ax, [bp+6] mov word ptr [bp-48], ax mov word ptr [bp-46], 0 mov ax, [bp-28] mov word ptr [bp-44], ax mov ax, [bp-26] mov word ptr [bp-42], ax mov word ptr [bp-40], 1 mov word ptr [bp-38], 0 mov word ptr [bp-36], 0 mov word ptr [bp-34], 0 ; Map scanInfo spectdata block len 10h -> [bp-32] push 0 push 10H push ss lea ax, -48[bp] push ax push 0 push 2 call dword ptr [bp-8] add sp, 0cH mov [bp-32], ax mov [bp-30], dx ; Map resultRef/output len4 -> [bp-56] (this is w95mconn caller ptr) 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-56], ax mov [bp-54], dx ; Map connReference local len4 -> [bp-60] push 0 push 4 push ss lea ax, -24[bp] push ax push 0 push 2 call dword ptr [bp-8] add sp, 0cH mov [bp-60], ax mov [bp-58], dx ; Raw CONNScanInfo via NIOS, following d32wrap _CONNScanInfo ; argument order from d32conni L$115. push word ptr [bp-58] ; connReference flat high push word ptr [bp-60] ; connReference flat low push 0 ; returnConnInfo flat high = NULL push 0 ; returnConnInfo flat low = NULL push 0 ; returnInfoLen high push 0 ; returnInfoLen low push 0 ; returnInfoLevel high push 4 ; returnInfoLevel low, as d32conni L$115 push 0 ; scan flag high push word ptr [bp+8] ; scan flag low push word ptr [bp-30] ; scanInfo flat high push word ptr [bp-32] ; scanInfo flat low push 0 ; scanInfoLevel high push 0aH ; scanInfoLevel low = SERVER_NAME push word ptr [bp-54] ; scanIterator/result flat high push word ptr [bp-56] ; scanIterator/result flat low 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-64], ax mov [bp-62], dx ; Unlock maps. push 0 push 4 push word ptr [bp-58] push word ptr [bp-60] push 0 push 3 call dword ptr [bp-8] add sp, 0cH push 0 push 4 push word ptr [bp-54] push word ptr [bp-56] push 0 push 3 call dword ptr [bp-8] add sp, 0cH push 0 push 10H push word ptr [bp-30] push word ptr [bp-32] push 0 push 3 call dword ptr [bp-8] add sp, 0cH push 0 push 31H push word ptr [bp-26] push word ptr [bp-28] push 0 push 3 call dword ptr [bp-8] add sp, 0cH jmp short c32mapvar_store c32mapvar_fail: mov word ptr [bp-16], 0 mov word ptr [bp-14], 0 mov word ptr [bp-64], 0ffffH mov word ptr [bp-62], 0ffffH mov word ptr [bp-20], 0 mov word ptr [bp-18], 0 mov word ptr [bp-24], 0 mov word ptr [bp-22], 0 c32mapvar_store: les di, dword ptr [bp+10] 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-64] mov es:[di+14], ax mov ax, [bp-62] mov es:[di+16], ax mov ax, [bp-20] mov es:[di+18], ax mov ax, [bp-18] mov es:[di+20], ax mov ax, [bp-24] mov es:[di+22], ax mov ax, [bp-22] mov es:[di+24], ax pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret c32mapvar_name db 'CONNScanInfo',0 _C32_MapVar_Probe endp ; int C32_NCP87_Raw5_Probe(UI connLo, UI connHi, ; void *hdr, UI hdrLen, ; void *path, UI pathLen, ; void *rep0, UI rep0Len, ; void *rep1, UI rep1Len, ; void *outbuf) ; ; Same as C32_NCP87_Raw_Probe but uses d32wrap-compatible 5-slot ; fragment tables: 5 * 8 = 0x28 bytes for request and reply. _C32_NCP87_Raw5_Probe proc far push bp mov bp, sp sub sp, 180 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-2], ax db 66h, 89h, 76h, 0FAh ; resolver at [bp-6] db 66h, 89h, 4Eh, 0F6h ; trampoline at [bp-10] or ax, ax jne raw5_fail ; resolve COMPATNcpRequestReply push cs push offset raw5_name push 0 push 0 call dword ptr [bp-6] add sp, 8 mov [bp-14], ax mov [bp-12], dx or ax, dx jne raw5_have_func jmp raw5_fail raw5_have_func: ; actual reply len dword at [bp-36] mov word ptr [bp-36], 0 mov word ptr [bp-34], 0 ; map hdr -> [bp-20] push 0 push word ptr [bp+0eH] push word ptr [bp+0cH] push word ptr [bp+0aH] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-20], ax mov [bp-18], dx ; map path -> [bp-24] push 0 push word ptr [bp+14H] push word ptr [bp+12H] push word ptr [bp+10H] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-24], ax mov [bp-22], dx ; map rep0 -> [bp-28] push 0 push word ptr [bp+1aH] push word ptr [bp+18H] push word ptr [bp+16H] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-28], ax mov [bp-26], dx ; map rep1 -> [bp-32] push 0 push word ptr [bp+20H] push word ptr [bp+1eH] push word ptr [bp+1cH] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-32], ax mov [bp-30], dx ; zero req table [bp-160] len 40 and reply table [bp-120] len 40 push ss pop es cld xor ax, ax lea di, -160[bp] mov cx, 20 rep stosw lea di, -120[bp] mov cx, 20 rep stosw ; req entry0 = hdr mov ax, [bp-20] mov [bp-160], ax mov ax, [bp-18] mov [bp-158], ax mov ax, [bp+0eH] mov [bp-156], ax mov word ptr [bp-154], 0 ; req entry1 = path mov ax, [bp-24] mov [bp-152], ax mov ax, [bp-22] mov [bp-150], ax mov ax, [bp+14H] mov [bp-148], ax mov word ptr [bp-146], 0 ; reply entry0 = rep0 mov ax, [bp-28] mov [bp-120], ax mov ax, [bp-26] mov [bp-118], ax mov ax, [bp+1aH] mov [bp-116], ax mov word ptr [bp-114], 0 ; reply entry1 = rep1 mov ax, [bp-32] mov [bp-112], ax mov ax, [bp-30] mov [bp-110], ax mov ax, [bp+20H] mov [bp-108], ax mov word ptr [bp-106], 0 ; map req table 0x28 -> [bp-40] push 0 push 28H push ss lea ax, -160[bp] push ax push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-40], ax mov [bp-38], dx ; map reply table 0x28 -> [bp-44] push 0 push 28H push ss lea ax, -120[bp] push ax push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-44], ax mov [bp-42], dx ; map actual reply len -> [bp-48] push 0 push 4 push ss lea ax, -36[bp] push ax push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-48], ax mov [bp-46], dx ; call COMPAT via NIOS command 8 push word ptr [bp-46] push word ptr [bp-48] push word ptr [bp-42] push word ptr [bp-44] push 0 push 2 push word ptr [bp-38] push word ptr [bp-40] push 0 push 2 push 0 push 57H push 0 push 0 push word ptr [bp+8] push word ptr [bp+6] push 0 push 8 push word ptr [bp-12] push word ptr [bp-14] call dword ptr [bp-10] add sp, 28H mov [bp-52], ax mov [bp-50], dx ; unlock important mappings only; ignore return push 0 push 4 push word ptr [bp-46] push word ptr [bp-48] push 0 push 3 call dword ptr [bp-6] add sp, 0cH push 0 push 28H push word ptr [bp-42] push word ptr [bp-44] push 0 push 3 call dword ptr [bp-6] add sp, 0cH push 0 push 28H push word ptr [bp-38] push word ptr [bp-40] push 0 push 3 call dword ptr [bp-6] add sp, 0cH jmp short raw5_store raw5_fail: mov word ptr [bp-14], 0 mov word ptr [bp-12], 0 mov word ptr [bp-52], 0ffffH mov word ptr [bp-50], 0ffffH mov word ptr [bp-36], 0 mov word ptr [bp-34], 0 raw5_store: les di, dword ptr [bp+22H] mov ax, [bp-2] mov es:[di+0], ax mov ax, [bp-6] mov es:[di+2], ax mov ax, [bp-4] mov es:[di+4], ax mov ax, [bp-10] mov es:[di+6], ax mov ax, [bp-8] mov es:[di+8], ax mov ax, [bp-14] mov es:[di+10], ax mov ax, [bp-12] mov es:[di+12], ax mov ax, [bp-52] mov es:[di+14], ax mov ax, [bp-50] mov es:[di+16], ax mov ax, [bp-36] mov es:[di+18], ax mov ax, [bp-34] mov es:[di+20], ax pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret raw5_name db 'COMPATNcpRequestReply',0 _C32_NCP87_Raw5_Probe endp end