Subversion Repositories Kolibri OS

Rev

Rev 3158 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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