Subversion Repositories Kolibri OS

Rev

Rev 5363 | Details | Compare with Previous | Last modification | View Log | RSS feed

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