; ---------------------------------------------------------------------------
; NETWORK.ASM - Serial and network card driver (c) 1996 - 2005 Chris Evans
; ---------------------------------------------------------------------------
Ethpnext      dd 0ffff0000h
Ethdevattr    dw 1000000000000100b 
Ethstrategy   dw offset _eth_strategy
Ethinterrupt  dw offset _eth_interrupt
Eth_device    db 'ETH0    ' ; Blank-padded device (or 10-byte block device sub-unit number)
; Jump table 
nettable      db 9
              dw cs:net_init    ; 0 - initialize driver
              dw cs:net_err     ; 1 - media change check 
              dw cs:net_err     ; 2 - build BPB
              dw cs:net_err     ; 3 - IOCTL string output
              dw cs:net_input   ; 4 - input
              dw cs:net_input   ; 5 - nondestructive input
              dw cs:net_err     ; 6 - input status
              dw cs:net_err     ; 7 - input flush
              dw cs:net_output  ; 8 - output
              dw cs:net_err     ; 9 - output w/ verify

;a few useful Ethernet definitions.
RUNT		equ	60		;smallest legal size packet, no fcs
GIANT		equ	1514		;largest legal size packet, no fcs
EADDR_LEN	equ	6		;Ethernet address length.
ARCADDR_LEN	equ	1
BLUEBOOK	equ	1
IEEE8023	equ	11
majver		equ	10		;version number of the infrastructure.
MAX_ADDR_LEN	equ	16		;maximum number of bytes in our address.
MAX_HANDLE	equ	10		;maximum number of handles.
MAX_P_LEN	equ	8		;maximum type length
MAX_MULTICAST	equ	8		;maximum number of multicast addresses.
;  Packet Driver Error numbers
NO_PKT_ERROR    equ     0               ;no error at all.
BAD_HANDLE	equ	1		;invalid handle number
NO_CLASS	equ	2		;no interfaces of specified class found
NO_TYPE		equ	3		;no interfaces of specified type found
NO_NUMBER	equ	4		;no interfaces of specified number found
BAD_TYPE	equ	5		;bad packet type specified
NO_MULTICAST	equ	6		;this interface does not support
					;multicast
CANT_TERMINATE	equ	7		;this packet driver cannot terminate
BAD_MODE	equ	8		;an invalid receiver mode was specified
NO_SPACE	equ	9		;operation failed because of
					;insufficient space
TYPE_INUSE	equ	10		;the type had previously been accessed,
					;and not released.
BAD_COMMAND	equ	11		;the command was out of range, or not
					;implemented
CANT_SEND	equ	12		;the packet couldn't be sent (usually
					;hardware error)
CANT_SET	equ	13		;hardware address couldn't be changed
					;(more than 1 handle open)
BAD_ADDRESS     equ     14         ;hardware address has bad length or format
CANT_RESET      equ     15 ;Couldn't reset interface (more than 1 handle open).
BAD_IOCB	equ	16		;an invalid iocb was specified

IP_ETH   EQU 0800h
hsnsize  EQU 20                         ; HOSTNAME= should be a env. variable
hostname db 'localhost      ',0
NetID    dw 2e2eh
DEFMAC   db 6 dup(2eh)                                ; OS default MAC addess
DEFMAC2  db 0ceh,27h,5bh,03,20,06                     ; Chris's Packets!
pktlen   dw ?
next_pkt dw ?
rcvbuf   dw ?
NET_PRN_SETUP db 64 dup(0)
MAC         db 6 dup(0)
MAC_DEST    db 6 dup(0)
MAC_BCAST   db 6 dup(0ffh)
ethtype     dw IP_ETH
route_tb_sz dw ?      ; route_table=(uniqueips*buffermin) 07/16/2006  08:14 PM

NET:

net_init proc far
         call cs:Init_NE2000
         jc   no_ne2000
              mov  al, 1
              mov  cs:ne2000card, al
              _echo 'N'
              _echo 'E'
              _echo '2'
              _echo 'K'
              _echo '0'
              _newline
no_ne2000:
         mov  ax, 300h
         xor  bx, bx
         mov  bl, 3
         call cs:detect_3c501
         jnc  no_3com
         ; ... indicated by port/irq variables in 3c50x.asm
              ; _output Eth_device, 8, 1
              _echo 'E'
              _echo 'T'
              _echo 'H'
              _echo '0'
              _newline
no_3com:
         ; if found then set up ISR receiver...

      ret
_eth_strategy:

        retf
_eth_interrupt:

        retf
net_init endp

net_input proc far

      ret
net_input endp

net_output proc far

      ret
net_output endp

netinfo proc far
           mov  al, cs:ne2000card
           or   al, al
           jz   _chk_3comi
                _print ne2000found, 1
                ; _echo '['
                ; mov  ax, cs:NE2000BASE
                ; call put_hex
                ; _echo 'H'
                ; _echo ']'
                _echo ' '               
_chk_3comi:
           mov  ax, cs:_3cBASE
           cmp  ax, 0 
           je   _netinfx
                _print _3comfound, 1
                _echo '['
                mov  ax, cs:_3cBASE
                call put_hex
                _echo '/'
                xor  ax, ax
                mov  al, cs:_3cIRQ 
                call put_hex
                ; _echo 'H'
                _echo ']'
_netinfx:  _newline
           ret
netinfo endp

net_info proc far
      xor  ax, ax
      mov  ax, cs:_3cBASE
      add  al, cs:ne2000card
      or   ax, ax
      jz   no_info4u
           call netinfo
no_info4u:
      ret
net_info endp

net_err proc far

      ret
net_err endp

; int is_arcnet (void) {
; int i, y;
; char [1..4] v;
; char x, z;
; v[1] = port(56e0)
; v[2] = port(aae0)
; v[3] = port(0e2e0)
; v[4] = port(1ee0)
; y =0;
; for i=1; i < 5; i++ {
;    x = v[i];
;    if x==ff break
;    if x==0e0 break
;    x = x && 78h 
;    if i==1 {
;         z = x;  
;       } else {
;         if z!=x break
;       }
;    if i==4 {
;    y=1  // found arcnet card
;    } 
; }
; return(y)
; }

include \nxdos\src\kernel\drivers\3c50x.asm 
include \nxdos\src\kernel\drivers\NE2000.asm

; ===========================================================================
create_ethframe proc far
; 9-25-2006 - CE 
; Creates ETHERNET Type 1 frame 
; ES:SI = Buffer
; CX    = Size
; CRC-32 = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 (used in Ethernet)
; ===========================================================================
       xor  ax, ax
       mov  framesize, ax

       push cs
       pop  ds
       lea  di, framebuffer
       mov  bp, di
       push di
       push cx
       mov  di, si
       mov  bl, 0
       call fillarray
       pop  cx
       pop  di

       cmp  cx, 46
       jge  smin_ok
       ; diff = 46 - blockl
       mov  bx, 46
       mov  ax, cx
       xor  dx, dx
       sub  bx, ax
       mov  cx, ax
smin_ok:
       cmp  cx, 1500
       jbe  make_ethframe
       mov  cx, 1500
make_ethframe:
       xor  bx, bx
set_dest_mac:
       mov  al, byte ptr cs:MAC_DEST[bx]
       mov  byte ptr es:[di], al
       inc  di
       inc  bx
       cmp  bx, 5
       jbe  set_dest_mac
       xor  bx, bx
set_src_mac:
       mov  al, byte ptr cs:MAC[bx]
       mov  byte ptr es:[di], al
       inc  di
       inc  bx
       cmp  bx, 5
       jbe  set_src_mac
set_etype:
       mov  ax, ethtype
       ; do I need to swap this ? mar-20-2006
       mov  word ptr es:[di], ax
       inc  di
       inc  di
; elen is for 802.3 w/ 802.2 header and data
;set_elen:
;       mov  word ptr es:[di], cx
;       inc  di
;       inc  di

       push cx
eth_loadpayload:
       mov  al, byte ptr es:[si]
       mov  byte ptr ds:[di], al
       inc  di
       inc  si
       loop eth_loadpayload
       mov  di, bp
       pop  cx
       push cx
       mov  ax, 14
       add  ax, cx
       mov  cx, ax
       xor  bx, bx
eth_crcloop:
       mov  al, byte ptr ds:[di]
       push bx
       call ethercrc32
       pop  bx
       mov  bx, ax
       loop eth_crcloop
       pop  cx
       mov  ax, cx
       mov  bx, 18
       add  ax, bx
       mov  cx, ax
       mov  framesize, cx
       ret
create_ethframe endp

; receiver process algoritm
; if carrier do
;    receive byte
; if not start of frame do wait for start of frame lock (loop to receive byte)
; receive block (read loop)
; check crc and size
;       len => 64   and <= 1518 and CRC passes (len-4)
; tally runts and giants for diagnostic use
; if error increment error count, and discard else
; match destination mac to our mac address or bcast = true forword
; (inform higher levels)

; while (carrier) {




     
; }

framesize   dw ?
framebuffer db 1500 dup(0)
FRAME_SIZE  EQU $ - framebuffer 

NET_MISC proc far
; Query network printer setup
      cmp  al, 3                
      jne  _dos_5e_2
      ; BX    network assign-list index (from 5f02)
      ; ES:DI 64 byte printer setup data
      mov  cx, 64
      push di
      cli
      lea  si, NET_PRN_SETUP
      mov  bx, nxdosbio
      mov  ds, bx
_dos_5e_3_l:
      mov  al, byte ptr [si]
      mov  byte ptr es:[di], al
      inc  si
      inc  di
      loop _dos_5e_3_l
      sti
      pop  di
      mov  cx, 64
      jmp  _dos_5e_x
_dos_5e_2:
      cmp  al, 2                       ; Set network printer setup
      jne  _dos_5e_1
      ; BX    network assign-list index (from 5f02)
      ; CX    length of printer setup data, in bytes
      ; DS:DX Printer setup data, max 64 bytes
      push cx
      mov  si, dx
      cli
      lea  di, NET_PRN_SETUP
      mov  bx, nxdosbio
      mov  es, bx
_dos_5e_2_l:
      mov  al, byte ptr [si]
      mov  byte ptr es:[di], al
      inc  si
      inc  di
      loop _dos_5e_2_l
      sti
      pop  cx
      jmp  _dos_5e_x
_dos_5e_1:
      cmp  al, 1                       ; Set hostname
      jne  _dos_5e_0
      cli                              ; copy DS:DX:0 to hostname
      mov  NetID, cx
      mov  cx, hsnsize
      mov  si, dx
      lea  di, hostname
      mov  bx, nxdosbio
      mov  es, bx
_dos_5e_l:
      dec  cx
      cmp  cx, 0
      je   _dos_5e_0
      mov  al, byte ptr ds:[si]
      mov  byte ptr es:[di], al
      inc  si
      inc  di
      mov  bl, 0
      mov  byte ptr es:[di], bl
      or   al, al
      jnz  _dos_5e_l
      sti
_dos_5e_0:
      ; get machine name
      mov  bx, nxdosbio
      mov  es, bx
      lea  dx, hostname
      mov  cx, NetID ; 00h = network name not valid, else network ID
_dos_5e_x:
      ; rc = (int)network_redirector_mx(REM_PRINTSET, &lr, (void *)Int21AX);
      ret
NET_MISC endp



