Files
mars-dosutils/kern_wasm.asm
Mario Fetka 50524cf759 dosutils: add GPL-2 headers and file descriptions
Add GPL-2-or-later license headers to the DOS utility source files and
document the purpose and local dependencies of each C, header and assembler
file.

Preserve the original Martin Stover copyright attribution for the historic
MARS-NWE utility sources, including files that did not previously carry an
explicit header but are part of the original tool set. Add Mario Fetka as the
2026 copyright holder for the current maintenance work, and use Mario-only
headers for files without original Martin Stover ownership.

Also add a root-level COPYING file containing the GPL-2 license text.
2026-05-29 08:07:09 +02:00

990 lines
24 KiB
NASM

;
; mars-nwe-dosutils - NetWare/DOS utility tools.
;
; Copyright (C) 2026 Mario Fetka
; Copyright (C) 1993,1996 Martin Stover, Marburg, Germany
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, see <http://www.gnu.org/licenses/>.
; Purpose: Open Watcom WASM/MASM-syntax port of the low-level DOS, IPX, NetWare requester and Client32 glue.
; Depends on: kern.h declarations, netcall.c and c32ncp.c callers, net.h shared types.
;
; 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_NCP87_Raw5_Probe
public _C32_OpenRef_Probe
public _C32_MapVar_Probe
_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 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