; 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

_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

end
