;
; 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 NetWare requester and Client32 transport glue.
; Depends on: ncp.h declarations, ncpcall.c transport helpers and ncpapi.c API wrappers.
;



; ncp.asm
;
; Low-level INT 21h Net_Call and Client32 requester entry points used by the
; DOS NCP transport helpers. This file is split from the former combined
; Open Watcom assembly glue so IPX support can stay in ipx.asm.

.286
.model large

.code

public  _Net_Call
public  _ncp_raw_request
public  _ncp_openref_request
public  _ncp_mapvar_request

_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 ncp_openref_request(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
_ncp_openref_request 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

_ncp_openref_request endp



; int ncp_mapvar_request(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
_ncp_mapvar_request 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

_ncp_mapvar_request endp




; int ncp_raw_request(UI connLo, UI connHi,
;                          void *hdr, UI hdrLen,
;                          void *path, UI pathLen,
;                          void *rep0, UI rep0Len,
;                          void *rep1, UI rep1Len,
;                          void *outbuf)
;
; Sends a raw NCP request through the d32wrap-compatible 5-slot
; fragment tables: 5 * 8 = 0x28 bytes for request and reply.
_ncp_raw_request 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     raw_fail

        ; resolve COMPATNcpRequestReply
        push    cs
        push    offset raw_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     raw_have_func
        jmp     raw_fail

raw_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 raw_store

raw_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

raw_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

raw_name db 'COMPATNcpRequestReply',0

_ncp_raw_request endp

end
