Subversion Repositories Kolibri OS

Rev

Rev 1173 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;; ne2000 driver for KolibriOS                                     ;;
  7. ;;                                                                 ;;
  8. ;;    Written by hidnplayr@kolibrios.org                           ;;
  9. ;;                                                                 ;;
  10. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  11. ;;             Version 2, June 1991                                ;;
  12. ;;                                                                 ;;
  13. ;; current status (september 2009) - INCOMPLETE                    ;;
  14. ;;                                                                 ;;
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16.  
  17. format MS COFF
  18.  
  19. API_VERSION     equ 0x01000100
  20.  
  21. DEBUG equ 1
  22. __DEBUG__ equ 1
  23. __DEBUG_LEVEL__ equ 1
  24.  
  25. include 'proc32.inc'
  26. include 'imports.inc'
  27. include 'fdo.inc'
  28.  
  29. OS_BASE         equ 0x80000000
  30. new_app_base    equ 0x0
  31. PROC_BASE       equ OS_BASE+0x0080000
  32.  
  33. ; PCI Bus defines
  34. PCI_HEADER_TYPE             equ     0x0e  ;8 bit
  35. PCI_BASE_ADDRESS_0          equ     0x10  ;32 bit
  36. PCI_BASE_ADDRESS_5          equ     0x24  ;32 bits
  37. PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
  38. PCI_VENDOR_ID               equ     0x00  ;16 bit
  39. PCI_BASE_ADDRESS_IO_MASK    equ     0xFFFFFFFC
  40.  
  41. struc IOCTL {
  42.       .handle      dd ?
  43.       .io_code     dd ?
  44.       .input       dd ?
  45.       .inp_size    dd ?
  46.       .output      dd ?
  47.       .out_size    dd ?
  48. }
  49.  
  50. virtual at 0
  51.   IOCTL IOCTL
  52. end virtual
  53.  
  54. struc ETH_DEVICE {
  55. ; pointers to procedures
  56.       .unload           dd ?
  57.       .reset            dd ?
  58.       .transmit         dd ?
  59.       .set_MAC          dd ?
  60.       .get_MAC          dd ?
  61.       .set_mode         dd ?
  62.       .get_mode         dd ?
  63. ; status
  64.       .bytes_tx         dq ?
  65.       .bytes_rx         dq ?
  66.       .packets_tx       dd ?
  67.       .packets_rx       dd ?
  68.       .mode             dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
  69.       .name             dd ?
  70.       .mac              dp ?
  71. ; device specific
  72.       .io_addr          dw ?
  73.       .irq_line         db ?
  74.       .pci_bus          db ?
  75.       .pci_dev          db ?
  76.  
  77.       .flags            db ?
  78.       .vendor           db ?
  79.       .asic_base        dw ?
  80.       .memsize          db ?
  81.       .rx_start         db ?
  82.       .tx_start         db ?
  83.       .bmem             dd ?
  84.       .rmem             dd ?
  85.       .romdata          rb 16
  86.       .size:
  87.  
  88. }
  89.  
  90. virtual at 0
  91.   device ETH_DEVICE
  92. end virtual
  93.  
  94. public START
  95. public service_proc
  96. public version
  97.  
  98.         MAX_ne2000                equ 16          ; Max number of devices this driver may handle
  99.  
  100.         P0_PSTART                 equ 0x01
  101.         P0_PSTOP                  equ 0x02
  102.         P0_BOUND                  equ 0x03
  103.         P0_TSR                    equ 0x04
  104.         P0_TPSR                   equ 0x04
  105.         P0_TBCR0                  equ 0x05
  106.         P0_TBCR1                  equ 0x06
  107.         P0_ISR                    equ 0x07
  108.         P0_RSAR0                  equ 0x08
  109.         P0_RSAR1                  equ 0x09
  110.         P0_RBCR0                  equ 0x0A
  111.         P0_RBCR1                  equ 0x0B
  112.         P0_RSR                    equ 0x0C
  113.         P0_RCR                    equ 0x0C
  114.         P0_TCR                    equ 0x0D
  115.         P0_DCR                    equ 0x0E
  116.         P0_IMR                    equ 0x0F
  117.  
  118.         P1_PAR0                   equ 0x01
  119.         P1_PAR1                   equ 0x02
  120.         P1_PAR2                   equ 0x03
  121.         P1_PAR3                   equ 0x04
  122.         P1_PAR4                   equ 0x05
  123.         P1_PAR5                   equ 0x06
  124.         P1_CURR                   equ 0x07
  125.         P1_MAR0                   equ 0x08
  126.  
  127.         CMD_PS0                   equ 0x00        ;  Page 0 select
  128.         CMD_PS1                   equ 0x40        ;  Page 1 select
  129.         CMD_PS2                   equ 0x80        ;  Page 2 select
  130.         CMD_RD2                   equ 0x20        ;  Remote DMA control
  131.         CMD_RD1                   equ 0x10
  132.         CMD_RD0                   equ 0x08
  133.         CMD_TXP                   equ 0x04        ;  transmit packet
  134.         CMD_STA                   equ 0x02        ;  start
  135.         CMD_STP                   equ 0x01        ;  stop
  136.  
  137.         RCR_MON                   equ 0x20        ;  monitor mode
  138.  
  139.         DCR_FT1                   equ 0x40
  140.         DCR_LS                    equ 0x08        ;  Loopback select
  141.         DCR_WTS                   equ 0x01        ;  Word transfer select
  142.  
  143.         ISR_PRX                   equ 0x01        ;  successful recv
  144.         ISR_PTX                   equ 0x02        ;  successful xmit
  145.         ISR_RXE                   equ 0x04        ;  receive error
  146.         ISR_TXE                   equ 0x08        ;  transmit error
  147.         ISR_OVW                   equ 0x10        ;  Overflow
  148.         ISR_CNT                   equ 0x20        ;  Counter overflow
  149.         ISR_RDC                   equ 0x40        ;  Remote DMA complete
  150.         ISR_RST                   equ 0x80        ;  reset
  151.  
  152.         IRQ_MASK                  equ ISR_PRX ; + ISR_PTX + ISR_TXE
  153.  
  154.         RSTAT_PRX                 equ 0x01        ;  successful recv
  155.         RSTAT_CRC                 equ 0x02        ;  CRC error
  156.         RSTAT_FAE                 equ 0x04        ;  Frame alignment error
  157.         RSTAT_OVER                equ 0x08        ;  FIFO overrun
  158.  
  159.         TXBUF_SIZE                equ 6
  160.         RXBUF_END                 equ 32
  161.         PAGE_SIZE                 equ 256
  162.  
  163.         ETH_ALEN                  equ 6
  164.         ETH_HLEN                  equ 14
  165.         ETH_ZLEN                  equ 60
  166.         ETH_FRAME_LEN             equ 1514
  167.  
  168.         FLAG_PIO                  equ 0x01
  169.         FLAG_16BIT                equ 0x02
  170.         ASIC_PIO                  equ 0
  171.  
  172.         VENDOR_NONE               equ 0
  173.         VENDOR_WD                 equ 1
  174.         VENDOR_NOVELL             equ 2
  175.         VENDOR_3COM               equ 3
  176.  
  177.         NE_ASIC_OFFSET            equ 0x10
  178.         NE_RESET                  equ 0x0F        ; Used to reset card
  179.         NE_DATA                   equ 0x00        ; Used to read/write NIC mem
  180.  
  181.         MEM_8192                  equ 32
  182.         MEM_16384                 equ 64
  183.         MEM_32768                 equ 128
  184.  
  185.         ISA_MAX_ADDR              equ 0x400
  186.  
  187. ;------------------------------------------------
  188.  
  189.         LAST_IO = 0
  190.  
  191. macro set_io addr {
  192.  
  193.         if      addr = 0
  194.                 mov     dx, [ebp + device.io_addr]
  195.         else
  196.                 add     edx, addr - LAST_IO
  197.         end if
  198.  
  199.         LAST_IO = addr
  200.  
  201.  
  202. }
  203.  
  204. ;-------------------------------------------------
  205.  
  206.  
  207. section '.flat' code readable align 16
  208.  
  209. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  210. ;;
  211. ;; proc START
  212. ;;
  213. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  214.  
  215. proc START stdcall, state:dword
  216.  
  217.         cmp     [state], 1
  218.         jne     .exit
  219.   .entry:
  220.         DEBUGF 2,"Registering rtl8029 service \n"
  221.         stdcall RegService, my_service, service_proc
  222.         ret
  223.   .fail:
  224.   .exit:
  225.         xor     eax, eax
  226.         ret
  227.  
  228. endp
  229.  
  230.  
  231. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  232. ;;
  233. ;; proc SERVICE_PROC
  234. ;;
  235. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  236. align 4
  237. proc service_proc ;stdcall, ioctl:dword
  238.         push    ebp
  239.  
  240.         mov     edx, [esp+8];[ioctl]
  241.         mov     eax, [edx+IOCTL.io_code]
  242.  
  243. ;------------------------------------------------------
  244.                        ;---------------
  245.         cmp     eax, 0 ;SRV_GETVERSION
  246.         jne     @F     ;---------------
  247.  
  248.         cmp     [edx+IOCTL.out_size], 4
  249.         jl      .fail
  250.         mov     eax, [edx+IOCTL.output]
  251.         mov     [eax], dword API_VERSION
  252.  
  253.         xor     eax, eax
  254.         pop     ebp
  255.         ret     4
  256.  
  257. ;------------------------------------------------------
  258.   @@:                  ;---------
  259.         cmp     eax, 1 ;SRV_HOOK
  260.         jne     @F     ;---------
  261.  
  262.         DEBUGF  2,"Checking if device is already listed..\n"
  263.  
  264.         mov     eax, [edx+IOCTL.input]
  265.  
  266.         cmp     [edx+IOCTL.inp_size], 3
  267.         jl      .fail
  268.         cmp     byte [eax], 1
  269.         je      .pci
  270.  
  271.         cmp     [edx+IOCTL.inp_size], 4
  272.         jl      .fail
  273.         cmp     byte [eax], 0
  274.         je      .isa
  275.  
  276.         jmp     .fail
  277.  
  278.   .pci:
  279.  
  280.         mov     esi, ne2000_LIST
  281.         mov     ecx, [ne2000_DEV]
  282.         test    ecx, ecx
  283.         jz      .firstdevice_pci
  284.         mov     bx , [eax+1]
  285.   .nextdevice:
  286.         lodsd
  287.         cmp     bx , word [eax + device.pci_bus] ; compare with pci and device num in ne2000 list
  288.         je      find_device_num
  289.         loop    .nextdevice
  290.  
  291.   .firstdevice_pci:
  292.         call    create_new_struct
  293.  
  294.         mov     eax, [edx+IOCTL.input]         ; save the pci bus and device numbers
  295.         mov     cx , [eax+1]                     ;
  296.         mov     [ebx+device.pci_bus], cl       ;
  297.         mov     [ebx+device.pci_dev], ch       ;
  298.  
  299.         mov     edx, PCI_BASE_ADDRESS_0        ; find the base io address
  300.   .sb_reg_check:
  301.   ;
  302.         movzx   eax, byte [ebx+device.pci_bus] ;
  303.         movzx   ecx, byte [ebx+device.pci_dev] ;
  304.                                                ;
  305.         push    edx ecx
  306.         stdcall PciRead16, eax ,ecx ,edx       ;
  307.         pop     ecx edx
  308.                                                ;
  309.         mov     [ebx+device.io_addr], ax       ;
  310.         and     eax, PCI_BASE_ADDRESS_IO_MASK  ;
  311.         test    eax, eax                       ;
  312.         jz      .sb_inc_reg                    ;
  313.         movzx   eax, [ebx+device.io_addr]      ;
  314.         and     eax, PCI_BASE_ADDRESS_SPACE_IO ;
  315.         test    eax, eax                       ;
  316.         jz      .sb_inc_reg                    ;
  317.                                                ;
  318.         movzx   eax, [ebx+device.io_addr]      ;
  319.         and     eax, PCI_BASE_ADDRESS_IO_MASK  ;
  320.         mov     [ebx+device.io_addr], ax       ;
  321.                                                ;
  322.         jmp     .got_io                        ;
  323.                                                ;
  324.   .sb_inc_reg:                             ;
  325.         add     edx, 4                         ;
  326.         cmp     edx, PCI_BASE_ADDRESS_5        ;
  327.         jbe     .sb_reg_check                  ;
  328.  
  329.   .got_io:
  330.         movzx   eax, byte [ebx+device.pci_bus] ; find IRQ line
  331.         movzx   ecx, byte [ebx+device.pci_dev] ;
  332.         push    ebx
  333.         stdcall PciRead8, eax ,ecx ,0x3c       ; 0x3c is the offset where irq can be found
  334.         pop     ebx
  335.         mov     byte [ebx+device.irq_line], al ;
  336.  
  337.         jmp     .hook
  338.  
  339.   .isa:
  340.  
  341.         mov     esi, ne2000_LIST
  342.         mov     ecx, [ne2000_DEV]
  343.         test    ecx, ecx
  344.         jz      .firstdevice_isa
  345.         mov     bx , [eax+1]
  346.         mov     dl , [eax+3]
  347.   .nextdevice_isa:
  348.         lodsd
  349.         cmp     bx , [eax + device.io_addr]
  350.         jne     .maybenext
  351.         cmp     dl , [eax + device.irq_line]
  352.         je      find_device_num
  353.   .maybenext:
  354.         loop    .nextdevice_isa
  355.  
  356.  
  357.  
  358.   .firstdevice_isa:
  359.         call    create_new_struct
  360.  
  361.         mov     eax, [edx+IOCTL.input]
  362.         mov     cx , [eax+1]
  363.         mov     [ebx+device.io_addr], cx
  364.         mov     cl, [eax+3]
  365.         mov     [ebx+device.irq_line], cl
  366.  
  367.   .hook:
  368.  
  369.         DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",[ebx+device.pci_dev]:1,[ebx+device.pci_bus]:1,[ebx+device.irq_line]:1,[ebx+device.io_addr]:4
  370.  
  371.         call    probe                                                   ; this function will output in eax
  372.         test    eax, eax
  373.         jnz     .err                                                    ; If an error occured, exit
  374.  
  375.         mov     eax, [ne2000_DEV]
  376.         mov     [ne2000_LIST+4*eax], ebx
  377.         inc     [ne2000_DEV]
  378.  
  379.         call    EthRegDev                                    ; Register the device to kernel (ebx points to device struct)
  380.         cmp     eax, -1
  381.         jz      .err
  382.         pop     ebp
  383.         ret     4
  384.  
  385.   .err:
  386.         stdcall KernelFree, ebx
  387.  
  388.         jmp     .fail
  389.  
  390. ;------------------------------------------------------
  391.   @@:
  392. .fail:
  393.         or      eax, -1
  394.         pop     ebp
  395.         ret     4
  396.  
  397. ;------------------------------------------------------
  398. endp
  399.  
  400.  
  401. create_new_struct:
  402.  
  403.         cmp     [ne2000_DEV], MAX_ne2000
  404.         jge     .fail
  405.  
  406.         push    edx
  407.         stdcall KernelAlloc, device.size
  408.         pop     edx
  409.         test    eax, eax
  410.         jz      .fail
  411.         mov     ebx, eax
  412.  
  413.         mov     dword [ebx+device.reset], reset
  414.         mov     dword [ebx+device.transmit], transmit
  415.         mov     dword [ebx+device.get_MAC], read_mac
  416.         mov     dword [ebx+device.set_MAC], write_mac
  417.         mov     dword [ebx+device.unload], unload
  418.  
  419.         ret
  420.  
  421. .fail:
  422.         add     esp, 4
  423.         or      eax, -1
  424.         ret
  425.  
  426. find_device_num:
  427.  
  428.         DEBUGF  1,"Trying to find device number of already registered device\n"
  429.         mov     ebx, eax
  430.         call    EthStruc2Dev                                            ; This kernel procedure converts a pointer to device struct in ebx
  431.                                                                         ; into a device number in edi
  432.         mov     eax, edi                                                ; Application wants it in eax instead
  433.         DEBUGF  1,"Kernel says: %u\n", eax
  434.         ret
  435.  
  436.  
  437. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  438. ;;                                                                        ;;
  439. ;;        Actual Hardware dependent code starts here                      ;;
  440. ;;                                                                        ;;
  441. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  442.  
  443.  
  444. unload:   ; TODO
  445.         or      eax, -1
  446.         ret
  447.  
  448.  
  449.  
  450. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  451. ;;
  452. ;;  probe: enables the device and clears the rx buffer
  453. ;;
  454. ;;  Destroys: eax, ebx, ecx, edx
  455. ;;
  456. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  457.  
  458. probe:
  459.         mov     ebp, ebx        ;---
  460.  
  461.         mov     [ebp + device.vendor], VENDOR_NONE
  462.         mov     [ebp + device.bmem], 0
  463.         mov     ax, [ebp + device.io_addr]
  464.         add     ax, NE_ASIC_OFFSET
  465.         mov     [ebp + device.asic_base], ax
  466.  
  467.         DEBUGF  2,"Trying 16-bit mode\n"
  468.  
  469.         or      [ebp + device.flags], FLAG_16BIT or FLAG_PIO
  470.         mov     [ebp + device.memsize], MEM_32768
  471.         mov     [ebp + device.tx_start], 64
  472.         mov     [ebp + device.rx_start], TXBUF_SIZE + 64
  473.  
  474.         set_io  0
  475.         set_io  P0_DCR
  476.         mov     al, DCR_WTS + DCR_FT1 + DCR_LS
  477.         out     dx, al
  478.  
  479.         set_io  P0_PSTART
  480.         mov     al, MEM_16384
  481.         out     dx, al
  482.  
  483.         set_io  P0_PSTOP
  484.         mov     al, MEM_32768
  485.         out     dx, al
  486.  
  487.         mov     esi, test_data
  488.         mov     bx, 16384
  489.         mov     cx, 14
  490.         call    eth_pio_write
  491.  
  492.         mov     bx, 16384
  493.         mov     cx, 14
  494.         lea     edi, [ebp + device.romdata]
  495.         call    eth_pio_read
  496.  
  497.         lea     esi, [ebp + device.romdata]
  498.         mov     edi, test_data
  499.         mov     ecx, 13
  500.  
  501.      repz    cmpsb
  502.      jz      ep_set_vendor
  503.  
  504.  
  505.         DEBUGF  2,"Trying 8-bit mode\n"
  506.  
  507.         mov     [ebp + device.flags], FLAG_PIO
  508.         mov     [ebp + device.memsize], MEM_16384
  509.         mov     [ebp + device.tx_start], 32
  510.         mov     [ebp + device.rx_start], TXBUF_SIZE + 32
  511.  
  512.         mov     dx, [ebp + device.asic_base]
  513.         add     dx, NE_RESET
  514.  
  515.         in      al, dx
  516.         out     dx, al
  517.  
  518.         in      al, 0x84
  519.  
  520.         set_io  0
  521.         mov     al, CMD_RD2 + CMD_STP
  522.         out     dx, al
  523.  
  524.         set_io  P0_RCR
  525.         mov     al, RCR_MON
  526.         out     dx, al
  527.  
  528.         set_io  P0_DCR
  529.         mov     al, DCR_FT1 + DCR_LS
  530.         out     dx, al
  531.  
  532.         set_io  P0_PSTART
  533.         mov     al, MEM_8192
  534.         out     dx, al
  535.  
  536.         set_io  P0_PSTOP
  537.         mov     al, MEM_16384
  538.         out     dx, al
  539.  
  540.         mov     esi, test_data
  541.         mov     bx, 8192
  542.         mov     cx, 14
  543.         call    eth_pio_write
  544.  
  545.         mov     bx, 8192
  546.         mov     cx, 14
  547.         lea     edi, [ebp + device.romdata]
  548.         call    eth_pio_read
  549.  
  550.         mov     esi, test_data
  551.         lea     edi, [ebp + device.romdata]
  552.         mov     ecx, 13
  553.  
  554.     repz      cmpsb
  555.     jz        ep_set_vendor
  556.  
  557.         DEBUGF  2,"This is not a valid ne2000 device!\n"
  558.         or      eax, -1
  559.         ret
  560.  
  561.  
  562. ep_set_vendor:
  563.  
  564.         cmp     [ebp + device.io_addr], ISA_MAX_ADDR
  565.         jbe     ep_001
  566.  
  567.         DEBUGF  2,"Card is using PCI bus\n"
  568.  
  569. ;;;        or      [ebp + device.flags], FLAG_16BIT
  570.  
  571. ep_001:
  572.         mov     [ebp + device.vendor], VENDOR_NOVELL
  573.  
  574. ep_check_have_vendor:
  575.  
  576.         mov     ebx, ebp        ;----
  577.  
  578.         mov     al, [ebp + device.vendor]
  579.         cmp     al, VENDOR_NONE
  580.   ;;;;      je      rtl8029_exit
  581.  
  582.         cmp     al, VENDOR_3COM
  583.         je      reset
  584.  
  585.         mov     eax, [ebp + device.bmem]
  586.         mov     [ebp + device.rmem], eax
  587.  
  588.         ;-- hack
  589.         mov     ebx, ebp
  590.         call    read_mac
  591.  
  592.  
  593.         push    .hack
  594.         sub     esp, 6
  595.         mov     edi, esp
  596.         lea     esi, [ebp + device.mac]
  597.         movsd
  598.         movsw
  599.  
  600.         jmp     write_mac
  601.        .hack:
  602.         ;--- hack
  603.  
  604.  
  605. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  606. ;;
  607. ;;   reset: Place the chip into a virgin state
  608. ;;
  609. ;;   Destroys: eax, ebx, ecx, edx
  610. ;;
  611. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  612.  
  613. reset:
  614.         mov     ebp, ebx        ;---
  615.  
  616.  
  617.         DEBUGF  2,"Resetting rtl8029\n"
  618.  
  619. ; attach int handler
  620.         movzx   eax, [ebp+device.irq_line]
  621.         DEBUGF  1,"Attaching int handler to irq %x\n",eax:1
  622.         stdcall AttachIntHandler, eax, int_handler, dword 0
  623.  
  624. ; Stop mode
  625.  
  626.         set_io  0
  627.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STP
  628.         out     dx, al
  629.  
  630.         set_io  P0_DCR
  631.         test    [ebp + device.flags], FLAG_16BIT
  632.         jz      nsr_001
  633.  
  634.         mov     al, 0x49
  635.         jmp     nsr_002
  636.  
  637. nsr_001:
  638.         mov     al, 0x48
  639.  
  640. nsr_002:
  641.         out     dx, al
  642.  
  643.  
  644. ;clear remote bytes count
  645.         set_io  0
  646.  
  647.         xor     al, al
  648.  
  649.         set_io  P0_RBCR0
  650.         out     dx, al
  651.  
  652.         set_io  P0_RBCR1
  653.         out     dx, al
  654.  
  655.  
  656. ;initialize Receive configuration register
  657.         set_io  P0_RCR
  658.         mov     al, 0x20        ; monitor mode
  659.         out     dx, al
  660.  
  661.  
  662. ; transmit configuration register
  663.         set_io  P0_TCR
  664.         mov     al, 2           ; internal loopback
  665.         out     dx, al
  666.  
  667.  
  668. ; transmit page stuff
  669.         set_io  P0_TPSR
  670.         mov     al, [ebp + device.tx_start]
  671.         out     dx, al
  672.  
  673. ; set receive control register ;;;;
  674.         set_io  P0_RCR
  675.         mov     al, 4           ; accept broadcast
  676.         out     dx, al
  677.  
  678. ; pagestart
  679.         set_io  P0_PSTART
  680.         mov     al, [ebp + device.rx_start]
  681.         out     dx, al
  682.  
  683. ; pagestop
  684.         set_io  P0_PSTOP
  685.         mov     al, [ebp + device.memsize]
  686.         out     dx, al
  687.  
  688. ; page boundary
  689.         set_io  P0_BOUND
  690.         mov     al, [ebp + device.memsize]
  691.         dec     al
  692.         out     dx, al
  693.  
  694.  
  695. ;;clear IRQ mask
  696. ;        set_io  P0_IMR
  697. ;        xor     al, al
  698. ;        out     dx, al
  699.  
  700.         set_io  0
  701.         mov     al, CMD_PS1 + CMD_RD2 + CMD_STP ; page 1, stop mode
  702.         out     dx, al
  703.  
  704.         set_io  P1_CURR
  705.         mov     al, [ebp + device.rx_start]
  706.         out     dx, al
  707.  
  708.         set_io  0
  709.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA ; go to page 0
  710.         out     dx, al
  711.  
  712. ; Read MAC address
  713.         mov     ebx, ebp        ;----
  714.         call    read_mac
  715.  
  716. ; clear interupt status
  717.         set_io  0
  718.         set_io  P0_ISR
  719.         mov     al, 0xff
  720.         out     dx, al
  721.  
  722. ; set IRQ mask
  723.         set_io  P0_IMR
  724.         mov     al, IRQ_MASK
  725.         out     dx, al
  726.  
  727. ;; start mode
  728. ;        set_io  0
  729. ;        mov     al, CMD_STA
  730. ;        out     dx, al
  731.  
  732. ; clear transmit control register
  733.         set_io  P0_TCR
  734.         mov     al, 0           ; no loopback
  735.         out     dx, al
  736.  
  737.  
  738. ; Indicate that we have successfully reset the card
  739.         DEBUGF  2,"Done!\n"
  740.         xor     eax, eax
  741.  
  742.         mov     ebx, ebp        ;------
  743.  
  744.         ret
  745.  
  746.  
  747.  
  748. ;***************************************************************************
  749. ;   Function
  750. ;      transmit
  751. ; buffer in [esp], size in [esp+4], pointer to device struct in ebx
  752. ;***************************************************************************
  753.  
  754. align 4
  755. transmit:
  756.         mov     ebp, ebx
  757.  
  758.         mov     esi, [esp]
  759.         mov     ecx, [esp + 4]
  760.         DEBUGF  2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
  761.         DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2
  762.  
  763.         cmp     dword [esp+4], ETH_FRAME_LEN
  764.         jg      .finish ; packet is too long
  765.         cmp     dword [esp+4], 60
  766.         jl      .finish ; packet is too short
  767.  
  768.         xor     bl, bl
  769.         mov     bh, [ebp + device.tx_start]
  770.         push    cx
  771.         call    eth_pio_write
  772.         pop     cx
  773.  
  774.         set_io  0
  775.         mov     al, CMD_PS0 + CMD_RD2 + CMD_STA
  776.         out     dx, al
  777.  
  778.         set_io  P0_TPSR
  779.         mov     al, [ebp + device.tx_start]
  780.         out     dx, al
  781.  
  782.         set_io  P0_TBCR0
  783.         mov     al, cl
  784.         out     dx, al
  785.  
  786.         set_io  P0_TBCR1
  787.         mov     al, ch
  788.         out     dx, al
  789.  
  790.         set_io  0
  791.         mov     al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
  792.         out     dx, al
  793.  
  794.         DEBUGF  2," - Packet Sent!\n"
  795. .finish:
  796.         mov     ebx, ebp
  797.  
  798.         call    KernelFree
  799.         add     esp, 4 ; pop (balance stack)
  800.         xor     eax, eax
  801.  
  802.         ret
  803.  
  804.  
  805. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  806. ;
  807. ; Interrupt handler
  808. ;
  809. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  810. align 4
  811. int_handler:
  812.  
  813.         DEBUGF  2,"IRQ %x ",eax:2
  814.  
  815. ; find pointer of device wich made INT occur
  816.         mov     esi, ne2000_LIST
  817.         mov     ecx, [ne2000_DEV]
  818. .nextdevice:
  819.         mov     ebp, dword [esi]
  820.  
  821.         set_io  0               ; We chould check ISR instead..
  822.         set_io  P0_ISR
  823.         in      al, dx
  824.  
  825.         DEBUGF  2,"isr %x ",eax:2
  826.  
  827.         test    al, ISR_PRX
  828.         jnz     .rx
  829.  
  830.         add     esi, 4
  831.  
  832.         loop    .nextdevice
  833.         ret
  834.  
  835. ; looks like we've found it!
  836. .rx:
  837.  
  838.  
  839.         sub     esp, 14+8                         ; allocate memory for temp variables in stack
  840.  
  841.         eth_type        equ esp
  842.         pkthdr          equ esp + 2
  843.         pktoff          equ esp + 6
  844.         eth_rx_data_ptr equ esp + 8
  845.         eth_tmp_len     equ esp + 12
  846.  
  847.         pointer         equ esp + 14
  848.         size            equ esp + 18
  849.  
  850.         stdcall KernelAlloc, ETH_FRAME_LEN
  851.         mov     [pointer], eax
  852.         mov     [eth_rx_data_ptr], eax
  853.  
  854.         set_io  P0_BOUND
  855.         in      al, dx
  856.         inc     al
  857.  
  858.         cmp     al, [ebp + device.memsize]
  859.         jb      .nsp_001
  860.  
  861.         mov     al, [ebp + device.rx_start]
  862.  
  863. .nsp_001:
  864.         mov     ch, al
  865.  
  866.         set_io  0
  867.         mov     al, CMD_PS1
  868.         out     dx, al
  869.  
  870.         set_io  P1_CURR
  871.         in      al, dx               ; get current page
  872.         mov     cl, al
  873.  
  874.         set_io  0
  875.         mov     al, CMD_PS0
  876.         out     dx, al
  877.  
  878.         cmp     cl, [ebp + device.memsize]
  879.         jb      .nsp_002
  880.  
  881.         mov     cl, [ebp + device.rx_start]
  882.  
  883. .nsp_002:
  884.         cmp     cl, ch
  885.         je      .fail
  886.  
  887.         xor     ax, ax
  888.         mov     ah, ch
  889.  
  890.         mov     [pktoff], ax
  891.  
  892.         mov     al, [ebp + device.flags]
  893.         test    al, FLAG_PIO
  894.         jz      .nsp_003
  895.  
  896.         mov     bx, word [pktoff]
  897.         lea     edi, [pkthdr]
  898.         mov     cx, 4
  899.         call    eth_pio_read
  900.         jmp     .nsp_004
  901.  
  902. .nsp_003:
  903.         mov     edi, [ebp + device.rmem]
  904.         movzx   eax, word [pktoff]
  905.         add     edi, eax
  906.         mov     eax, [edi]
  907.         mov     [pkthdr], eax
  908.  
  909. .nsp_004:
  910.         add     word[pktoff] , 4
  911.  
  912.         xor     eax, eax
  913.         mov     ax, [pkthdr + 2]
  914.         sub     ax, 4
  915.  
  916.         DEBUGF  2,"Received %u bytes\n",eax
  917.  
  918.         mov     [eth_tmp_len], ax
  919.         mov     dword[size], eax
  920.  
  921.         cmp     ax, ETH_ZLEN
  922.         jb      .fail
  923.  
  924.         cmp     ax, ETH_FRAME_LEN
  925.         ja      .fail
  926.  
  927.         mov     al, [pkthdr]
  928.         test    al, RSTAT_PRX
  929.         jz      .fail
  930.  
  931.    ; Right, we can now get the data
  932.  
  933.         mov     bh, [ebp + device.memsize]
  934.         sub     bx, [pktoff]
  935.  
  936.         cmp     [eth_tmp_len], bx
  937.         jbe     .nsp_005
  938.  
  939.         mov     al, [ebp + device.flags]
  940.         test    al, FLAG_PIO
  941.         jz      .nsp_006
  942.  
  943.         push    bx
  944.         mov     cx, bx
  945.         mov     bx, [pktoff]
  946.         mov     edi, [eth_rx_data_ptr]
  947.         call    eth_pio_read
  948.         pop     bx
  949.         jmp     .nsp_007
  950.  
  951. .nsp_006:
  952.    ; Not implemented, as we are using PIO mode on this card
  953.  
  954. .nsp_007:
  955.         xor     al, al
  956.         mov     ah, [ebp + device.rx_start]
  957.         mov     [pktoff], ax
  958.  
  959.         add     [eth_rx_data_ptr], ebx
  960.  
  961.         mov     ax, [eth_tmp_len]
  962.         sub     ax, bx
  963.         mov     [eth_tmp_len], ax
  964.  
  965. .nsp_005:
  966.         test    [ebp + device.flags], FLAG_PIO
  967.         jz      .nsp_008
  968.  
  969.         xor     ebx, ebx
  970.         mov     bx, [pktoff]
  971.         xor     ecx, ecx
  972.         mov     cx, [eth_tmp_len]
  973.         mov     edi, [eth_rx_data_ptr]
  974.         call    eth_pio_read
  975.         jmp     .nsp_009
  976.  
  977. .nsp_008:
  978.    ; Not implemented, as we are using PIO mode on this card
  979.  
  980. .nsp_009:
  981.         mov     al, [pkthdr+1]
  982.         cmp     al, [ebp + device.rx_start]
  983.         jne     .nsp_010
  984.  
  985.         mov     al, [ebp + device.memsize]
  986.  
  987. .nsp_010:
  988.         set_io  0
  989.         set_io  P0_BOUND
  990.         dec     al
  991.         out     dx, al
  992.  
  993.         add     esp, 14
  994.  
  995.         mov     ebx, ebp
  996.         jmp     EthReceiver     ;;;
  997.  
  998. .fail:
  999.         add     esp, 14+8
  1000.         DEBUGF  2,"done\n"
  1001. ret
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007. ;;;;;;;;;;;;;;;;;;;;;;;
  1008. ;;                   ;;
  1009. ;; Write MAC address ;;
  1010. ;;                   ;;
  1011. ;;;;;;;;;;;;;;;;;;;;;;;
  1012.  
  1013. align 4
  1014. write_mac:      ; in: mac on stack
  1015.  
  1016.         mov     ebp, ebx        ;---
  1017.  
  1018.         DEBUGF  1,"Writing MAC: "
  1019.  
  1020.         set_io  0
  1021.         mov     al, CMD_PS1; + CMD_RD2 + CMD_STP
  1022.         out     dx, al
  1023.  
  1024.         set_io  P1_PAR0
  1025.         mov     esi, esp
  1026.         mov     cx, 6
  1027.  @@:
  1028.         lodsb
  1029.         out     dx, al
  1030.         inc     dx
  1031.         loopw   @r
  1032.  
  1033.         add     esp, 6
  1034.  
  1035.         mov     ebx, ebp        ;---
  1036.  
  1037. ; Notice this procedure does not ret, but continues to read_mac instead.
  1038.  
  1039. ;;;;;;;;;;;;;;;;;;;;;;
  1040. ;;                  ;;
  1041. ;; Read MAC address ;;
  1042. ;;                  ;;
  1043. ;;;;;;;;;;;;;;;;;;;;;;
  1044.  
  1045. read_mac:
  1046.  
  1047.         mov     ebp, ebx        ;-----
  1048.  
  1049.         DEBUGF  1,"Reading MAC: "
  1050.  
  1051. ;        set_io  0
  1052. ;        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP ; select page 1
  1053. ;        out     dx, al
  1054. ;
  1055. ;        set_io  P1_PAR0
  1056. ;        lea     edi, [ebp + device.mac]
  1057. ;
  1058. ;        mov     cx, 6
  1059. ; .loop:
  1060. ;        in      al, dx
  1061. ;        stosb
  1062. ;        inc     dx
  1063. ;        loopw   .loop
  1064. ;
  1065. ;        lea     edi, [ebp + device.mac]
  1066. ;        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",[edi+0]:2,[edi+1]:2,[edi+2]:2,[edi+3]:2,[edi+4]:2,[edi+5]:2
  1067. ;
  1068. ;        set_io  0
  1069. ;        mov     al, CMD_PS0; + CMD_RD2 + CMD_STA  ; set page back to 0
  1070. ;        out     dx, al
  1071.  
  1072.  
  1073.         mov     bx, 0
  1074.         mov     cx, 16
  1075.         lea     edi, [ebp + device.romdata]
  1076.         call    eth_pio_read
  1077.  
  1078.         lea     esi, [ebp + device.romdata]
  1079.         lea     edi, [ebp + device.mac]
  1080.         mov     ecx, 6
  1081.  
  1082.   .loop:
  1083.         movsb
  1084.         test    [ebp + device.flags], FLAG_16BIT
  1085.         jz      .8bit
  1086.         inc     esi
  1087.   .8bit:
  1088.         loop    .loop
  1089.  
  1090.  
  1091.         mov     ebx, ebp        ;---
  1092.  
  1093.         ret
  1094.  
  1095.  
  1096. ;***************************************************************************
  1097. ;   Function
  1098. ;      eth_pio_read
  1099. ;
  1100. ;   Description
  1101. ;       Read a frame from the ethernet card via Programmed I/O
  1102. ;      src in bx
  1103. ;      cnt in cx
  1104. ;       dst in edi
  1105. ;***************************************************************************
  1106. eth_pio_read:
  1107.  
  1108.         DEBUGF  1,"Eth PIO Read from %x to %x, %u bytes ",bx,edi,cx
  1109.  
  1110.         set_io  0
  1111.         mov     al, CMD_RD2 + CMD_STA
  1112.         out     dx, al
  1113.  
  1114.         mov     al, cl
  1115.         set_io  P0_RBCR0
  1116.         out     dx, al
  1117.  
  1118.         mov     al, ch
  1119.         set_io  P0_RBCR1
  1120.         out     dx, al
  1121.  
  1122.         mov     al, bl
  1123.         set_io  P0_RSAR0
  1124.         out     dx, al
  1125.  
  1126.         mov     al, bh
  1127.         set_io  P0_RSAR1
  1128.         out     dx, al
  1129.  
  1130.         mov     al, CMD_RD0 + CMD_STA
  1131.         set_io  0
  1132.         out     dx, al
  1133.  
  1134.         mov     dx, [ebp + device.asic_base]
  1135.  
  1136.         test    [ebp+device.flags], FLAG_16BIT
  1137.         jz      epr_003
  1138.  
  1139.         DEBUGF  1,"in 16-bits mode"
  1140.  
  1141.         shr     cx, 1   ; note that if the number was odd, carry flag will be set
  1142.         pushf           ; save the flags for later
  1143.  
  1144. epr_002:
  1145.         in      ax, dx
  1146.         stosw
  1147.         loopw   epr_002
  1148.  
  1149.         inc     cx
  1150.         popf
  1151.         jnc     epr_004
  1152.  
  1153. epr_003:
  1154.         in      al, dx
  1155.         stosb
  1156.         loopw   epr_003
  1157.  
  1158.  
  1159. epr_004:
  1160.         set_io  0
  1161.         set_io  P0_ISR
  1162.  
  1163. epr_005:                                ; Wait for Remote DMA Complete
  1164.         in      al, dx
  1165.         test    al, ISR_RDC
  1166.         jz      epr_005
  1167. ;        and     al, not ISR_RDC
  1168.         out     dx, al                  ; clear the bit
  1169.  
  1170.  
  1171.         DEBUGF  1,"\n"
  1172.         ret
  1173.  
  1174.  
  1175.  
  1176.  
  1177. ;***************************************************************************
  1178. ;   Function
  1179. ;      eth_pio_write
  1180. ;
  1181. ;   Description
  1182. ;       writes a frame to the ethernet card via Programmed I/O
  1183. ;      dst in bx
  1184. ;      cnt in cx
  1185. ;       src in esi
  1186. ;***************************************************************************
  1187. eth_pio_write:
  1188.  
  1189.         DEBUGF  1,"Eth PIO Write from %x to %x, %u bytes ",esi,bx,cx
  1190.  
  1191.         set_io  0
  1192.         mov     al, CMD_RD2 + CMD_STA
  1193.         out     dx, al
  1194.  
  1195.         set_io  P0_ISR
  1196.         mov     al, ISR_RDC
  1197.         out     dx, al
  1198.  
  1199.         set_io  P0_RBCR0
  1200.         mov     al, cl
  1201.         out     dx, al
  1202.  
  1203.         set_io  P0_RBCR1
  1204.         mov     al, ch
  1205.         out     dx, al
  1206.  
  1207.         set_io  P0_RSAR0
  1208.         mov     al,   bl
  1209.         out     dx, al
  1210.  
  1211.         set_io  P0_RSAR1
  1212.         mov     al,   bh
  1213.         out     dx, al
  1214.  
  1215.         set_io  0
  1216.         mov     al, CMD_RD1 + CMD_STA
  1217.         out     dx, al
  1218.  
  1219.         mov     dx, [ebp + device.asic_base]
  1220.         test    [ebp + device.flags], FLAG_16BIT
  1221.         jz      epw_003
  1222.  
  1223.         DEBUGF  1,"in 16-bits mode"
  1224.  
  1225.         shr     cx, 1   ; note that if the number was odd, carry flag will be set
  1226.         pushf           ; save the flags for later
  1227.  
  1228. epw_002:
  1229.         lodsw
  1230.         out     dx, ax
  1231.         loopw   epw_002
  1232.  
  1233.         popf
  1234.         jnc     epw_004
  1235.         inc     cx
  1236.  
  1237. epw_003:
  1238.         lodsb
  1239.         out     dx, al
  1240.         loopw   epw_003
  1241.  
  1242. epw_004:
  1243.         set_io  0
  1244.         set_io  P0_ISR
  1245.  
  1246. epw_005:                                ; Wait for Remote DMA Complete
  1247.         in      al, dx
  1248.         test    al, ISR_RDC
  1249.         jz      epw_005
  1250. ;        and     al, not ISR_RDC
  1251.         out     dx, al                  ; clear the bit
  1252.  
  1253.  
  1254.         DEBUGF  1,"\n"
  1255.         ret
  1256.  
  1257.  
  1258.  
  1259. ;all initialized data place here
  1260. align 4
  1261.  
  1262. ne2000_DEV      dd 0
  1263. version         dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1264. my_service      db 'ne2000',0  ;max 16 chars include zero
  1265. devicename      db 'Realtek 8029',0
  1266.                 db 'Realtek 8019',0
  1267.                 db 'Realtek 8019AS',0
  1268.                 db 'ne2000',0
  1269.                 db 'DP8390',0
  1270.  
  1271. test_data       db 'NE*000 memory',0
  1272. ;test_buffer     db '             ',0
  1273.  
  1274. include_debug_strings
  1275.  
  1276. section '.data' data readable writable align 16
  1277.  
  1278. ;place all uninitialized data place here
  1279.  
  1280. ne2000_LIST:
  1281. rd MAX_ne2000
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.