Subversion Repositories Kolibri OS

Rev

Rev 5074 | Go to most recent revision | 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
668
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
669
;***************************************************************************
670
 
5005 hidnplayr 671
proc transmit stdcall buffer_ptr, buffer_size
3545 hidnplayr 672
 
5005 hidnplayr 673
        pushf
674
        cli
675
 
676
        mov     esi, [buffer_ptr]
677
        mov     ecx, [buffer_size]
678
        DEBUGF  1, "Transmitting packet, buffer:%x, size:%u\n", esi, ecx
3856 hidnplayr 679
        DEBUGF  1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
3545 hidnplayr 680
        [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
681
 
682
        cmp     ecx, ETH_FRAME_LEN
5005 hidnplayr 683
        ja      .err            ; packet is too long
3545 hidnplayr 684
        cmp     ecx, ETH_ZLEN
5005 hidnplayr 685
        jb      .err            ; packet is too short
3545 hidnplayr 686
 
5005 hidnplayr 687
        movzx   edi, [ebx + device.tx_start]
3545 hidnplayr 688
        shl     edi, 8
689
        push    cx
690
        call    PIO_write
691
        pop     cx
692
 
5005 hidnplayr 693
        set_io  [ebx + device.io_addr], 0
694
;        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 695
        mov     al, CMD_PS0 + CMD_RD2 + CMD_STA
696
        out     dx, al
697
 
5005 hidnplayr 698
        set_io  [ebx + device.io_addr], P0_TPSR
699
        mov     al, [ebx + device.tx_start]
3545 hidnplayr 700
        out     dx, al
701
 
5005 hidnplayr 702
        set_io  [ebx + device.io_addr], P0_TBCR0
3545 hidnplayr 703
        mov     al, cl
704
        out     dx, al
705
 
5005 hidnplayr 706
        set_io  [ebx + device.io_addr], P0_TBCR1
3545 hidnplayr 707
        mov     al, ch
708
        out     dx, al
709
 
5005 hidnplayr 710
        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 711
        mov     al, CMD_PS0 + CMD_TXP + CMD_RD2 + CMD_STA
712
        out     dx, al
713
 
3856 hidnplayr 714
        DEBUGF  1, "Packet Sent!\n"
3545 hidnplayr 715
 
5005 hidnplayr 716
        inc     [ebx + device.packets_tx]
717
        mov     eax, [buffer_size]
718
        add     dword[ebx + device.bytes_tx], eax
719
        adc     dword[ebx + device.bytes_tx + 4], 0
3545 hidnplayr 720
 
5005 hidnplayr 721
        invoke  KernelFree, [buffer_ptr]
722
        popf
3545 hidnplayr 723
        xor     eax, eax
5005 hidnplayr 724
        ret
3545 hidnplayr 725
 
3619 hidnplayr 726
  .err:
3856 hidnplayr 727
        DEBUGF  2, "Transmit error!\n"
5005 hidnplayr 728
        invoke  KernelFree, [buffer_ptr]
729
        popf
3545 hidnplayr 730
        or      eax, -1
5005 hidnplayr 731
        ret
3545 hidnplayr 732
 
5005 hidnplayr 733
endp
3545 hidnplayr 734
 
735
 
5005 hidnplayr 736
 
3545 hidnplayr 737
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
738
;
739
; Interrupt handler
740
;
741
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
742
 
743
align 4
744
int_handler:
745
 
746
        push    ebx esi edi
3856 hidnplayr 747
        DEBUGF  1, "INT\n"
3545 hidnplayr 748
 
749
; find pointer of device wich made INT occur
750
 
751
        mov     ecx, [devices]
752
        test    ecx, ecx
753
        jz      .nothing
754
        mov     esi, device_list
755
  .nextdevice:
756
        mov     ebx, [esi]
757
 
5005 hidnplayr 758
        set_io  [ebx + device.io_addr], 0
759
;        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 760
        mov     al, CMD_PS0
761
        out     dx, al
762
 
5005 hidnplayr 763
        set_io  [ebx + device.io_addr], P0_ISR
3545 hidnplayr 764
        in      al, dx
765
        test    al, al
766
        jnz     .got_it
767
  .continue:
768
        add     esi, 4
769
        dec     ecx
770
        jnz     .nextdevice
771
  .nothing:
772
        pop     edi esi ebx
773
        xor     eax, eax
774
 
775
        ret
776
 
777
  .got_it:
3856 hidnplayr 778
        DEBUGF  1, "Device=%x status=%x\n", ebx, eax:2
3545 hidnplayr 779
 
780
        push    ebx
5005 hidnplayr 781
  .rx_loop:
3545 hidnplayr 782
        test    al, ISR_PRX     ; packet received ok ?
783
        jz      .no_rx
5005 hidnplayr 784
        test    [ebx + device.flags], FLAG_PIO
3545 hidnplayr 785
        jz      .no_rx          ; FIXME: Only PIO mode supported for now
786
 
5005 hidnplayr 787
; allocate a buffer
788
        invoke  KernelAlloc, ETH_FRAME_LEN
789
        test    eax, eax
790
        jz      .rx_fail_2
3545 hidnplayr 791
 
5005 hidnplayr 792
; Push return address and packet ptr to stack
3545 hidnplayr 793
        pushd   .no_rx
5005 hidnplayr 794
        pushd   0               ; Reserve some space for the packet size
3545 hidnplayr 795
        push    eax
796
 
797
; read offset for current packet from device
5005 hidnplayr 798
        set_io  [ebx + device.io_addr], 0
799
        set_io  [ebx + device.io_addr], P0_BOUND        ; boundary ptr is offset to next packet we need to read.
3545 hidnplayr 800
        in      al, dx
801
        inc     al
5005 hidnplayr 802
        cmp     al, [ebx + device.memsize]
3545 hidnplayr 803
        jb      @f
5005 hidnplayr 804
        mov     al, [ebx + device.rx_start]
3545 hidnplayr 805
       @@:
806
        mov     ch, al
807
 
5005 hidnplayr 808
        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 809
        mov     al, CMD_PS1
810
        out     dx, al
5005 hidnplayr 811
        set_io  [ebx + device.io_addr], P1_CURR
812
        in      al, dx                          ; get current page in cl
3545 hidnplayr 813
        mov     cl, al
814
 
5005 hidnplayr 815
        set_io  [ebx + device.io_addr], P1_COMMAND
3545 hidnplayr 816
        mov     al, CMD_PS0
817
        out     dx, al
818
 
5005 hidnplayr 819
        cmp     cl, [ebx + device.memsize]
3545 hidnplayr 820
        jb      @f
5005 hidnplayr 821
        mov     cl, [ebx + device.rx_start]
3545 hidnplayr 822
       @@:
823
 
824
        cmp     cl, ch
5005 hidnplayr 825
        je      .rx_fail
3545 hidnplayr 826
        movzx   esi, ch                         ; we are using 256 byte pages
827
        shl     esi, 8                          ; esi now holds the offset for current packet
828
 
5005 hidnplayr 829
; Get packet header in ecx
830
        push    ecx                             ; reserve 4 bytes on stack to put packet header in
3545 hidnplayr 831
        mov     edi, esp
832
        mov     cx, 4
833
        call    PIO_read
5005 hidnplayr 834
        mov     ecx, [esp]
3545 hidnplayr 835
 
836
; check if packet is ok
837
        test    ecx, RSTAT_PRX
5005 hidnplayr 838
        jz      .rx_fail_3
3545 hidnplayr 839
 
840
; calculate packet length in ecx
841
        shr     ecx, 16
842
        sub     ecx, 4                          ; CRC doesnt count as data byte
5005 hidnplayr 843
        mov     [esp + 8], ecx
3545 hidnplayr 844
 
845
; check if packet size is ok
846
        cmp     ecx, ETH_ZLEN
5005 hidnplayr 847
        jb      .rx_fail_3
3545 hidnplayr 848
        cmp     ecx, ETH_FRAME_LEN
5005 hidnplayr 849
        ja      .rx_fail_3
3545 hidnplayr 850
 
851
; update stats
3856 hidnplayr 852
        DEBUGF  1, "Received %u bytes\n", ecx
5005 hidnplayr 853
        add     dword[ebx + device.bytes_rx], ecx
854
        adc     dword[ebx + device.bytes_rx + 4], 0
855
        inc     [ebx + device.packets_rx]
3545 hidnplayr 856
 
857
; update read and write pointers
858
        add     esi, 4
859
        mov     edi, [esp + 4]
860
 
861
; now check if we can read all data at once (if we cross the end boundary, we need to wrap back to the beginning)
862
        xor     eax, eax
5005 hidnplayr 863
        mov     ah, [ebx + device.memsize]
3545 hidnplayr 864
        sub     eax, esi
865
        cmp     ecx, eax                ; eax = number of bytes till end of buffer, ecx = bytes we need to read
866
        jbe     .no_wrap
867
 
868
; Read first part
869
        sub     ecx, eax
870
        push    ecx
871
        mov     ecx, eax
872
        call    PIO_read                ; Read the data
873
 
5005 hidnplayr 874
; update pointers for second read
3545 hidnplayr 875
        add     edi, ecx
876
        pop     ecx
5005 hidnplayr 877
        movzx   esi, [ebx + device.rx_start]
3545 hidnplayr 878
        shl     esi, 8
879
 
880
; now read second part (or only part)
881
  .no_wrap:
882
        call    PIO_read                ; Read the data
883
 
884
; update boundary pointer
885
        pop     eax
886
        mov     al, ah
5005 hidnplayr 887
        cmp     al, [ebx + device.rx_start]
3545 hidnplayr 888
        jne     @f
5005 hidnplayr 889
        mov     al, [ebx + device.memsize]
3545 hidnplayr 890
       @@:
5005 hidnplayr 891
        set_io  [ebx + device.io_addr], 0
892
        set_io  [ebx + device.io_addr], P0_BOUND
3545 hidnplayr 893
        dec     al
894
        out     dx, al
895
 
896
; now send the data to the kernel
5005 hidnplayr 897
        jmp     [Eth_input]
3545 hidnplayr 898
 
5005 hidnplayr 899
  .rx_fail_3:
3545 hidnplayr 900
        add     esp, 4
5005 hidnplayr 901
  .rx_fail:
902
        add     esp, 12
903
  .rx_fail_2:
904
        DEBUGF  2, "Error on receive\n"
3545 hidnplayr 905
  .no_rx:
906
        pop     ebx
3856 hidnplayr 907
        DEBUGF  1, "done\n"
3545 hidnplayr 908
 
5005 hidnplayr 909
        set_io  [ebx + device.io_addr], 0
910
        set_io  [ebx + device.io_addr], P0_ISR
3545 hidnplayr 911
        mov     al, 0xff
912
        out     dx, al
913
 
914
        pop     edi esi ebx
915
 
916
        ret
917
 
918
 
919
;;;;;;;;;;;;;;;;;;;;;;;
920
;;                   ;;
921
;; Write MAC address ;;
922
;;                   ;;
923
;;;;;;;;;;;;;;;;;;;;;;;
924
 
925
align 4
926
write_mac:      ; in: mac on stack (6 bytes)
927
 
3856 hidnplayr 928
        DEBUGF  1, "Writing MAC\n"
3545 hidnplayr 929
 
5005 hidnplayr 930
        set_io  [ebx + device.io_addr], 0
3545 hidnplayr 931
        mov     al, CMD_PS1; + CMD_RD2 + CMD_STP
932
        out     dx, al
933
 
5005 hidnplayr 934
        set_io  [ebx + device.io_addr], P1_PAR0
3545 hidnplayr 935
        mov     esi, esp
936
        mov     cx, 6
937
 @@:
938
        lodsb
939
        out     dx, al
940
        inc     dx
941
        loopw   @r
942
 
943
        add     esp, 6
944
 
945
; Notice this procedure does not ret, but continues to read_mac instead.
946
 
947
;;;;;;;;;;;;;;;;;;;;;;
948
;;                  ;;
949
;; Read MAC address ;;
950
;;                  ;;
951
;;;;;;;;;;;;;;;;;;;;;;
952
 
953
read_mac:
954
 
3856 hidnplayr 955
        DEBUGF  1, "Reading MAC\n"
3545 hidnplayr 956
 
957
        xor     esi, esi
958
        mov     cx, 16
959
        sub     esp, 16
960
        mov     edi, esp
961
        call    PIO_read
962
 
963
        mov     esi, esp
964
        add     esp, 16
5005 hidnplayr 965
        lea     edi, [ebx + device.mac]
3545 hidnplayr 966
        mov     ecx, 6
967
  .loop:
968
        movsb
5005 hidnplayr 969
        test    [ebx + device.flags], FLAG_16BIT
3545 hidnplayr 970
        jz      .8bit
971
        inc     esi
972
  .8bit:
973
        loop    .loop
3856 hidnplayr 974
        DEBUGF  1, "MAC=%x-%x-%x-%x-%x-%x\n",\
5005 hidnplayr 975
        [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 976
 
977
        ret
978
 
979
 
980
;***************************************************************************
981
;
982
;   PIO_read
983
;
984
;   Description
985
;       Read a frame from the ethernet card via Programmed I/O
986
;      src in si
987
;      cnt in cx
988
;       dst in edi
989
;***************************************************************************
990
PIO_read:
991
 
3856 hidnplayr 992
        DEBUGF  1, "PIO Read from %x to %x, %u bytes ", si, edi, cx
3545 hidnplayr 993
 
5005 hidnplayr 994
; stop DMA + start
995
        set_io  [ebx + device.io_addr], 0
996
;        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 997
        mov     al, CMD_RD2 + CMD_STA
998
        out     dx, al
999
 
5005 hidnplayr 1000
; Request confirmation of end of DMA transfer
1001
        set_io  [ebx + device.io_addr], P0_ISR
1002
        mov     al, ISR_RDC
1003
        out     dx, al
1004
 
3545 hidnplayr 1005
; set length of data we're interested in
5005 hidnplayr 1006
        set_io  [ebx + device.io_addr], P0_RBCR0
3545 hidnplayr 1007
        mov     al, cl
1008
        out     dx, al
5005 hidnplayr 1009
        set_io  [ebx + device.io_addr], P0_RBCR1
3545 hidnplayr 1010
        mov     al, ch
1011
        out     dx, al
1012
 
1013
; set offset of what we want to read
5005 hidnplayr 1014
        set_io  [ebx + device.io_addr], P0_RSAR0
3545 hidnplayr 1015
        mov     ax, si
1016
        out     dx, al
5005 hidnplayr 1017
        set_io  [ebx + device.io_addr], P0_RSAR1
3545 hidnplayr 1018
        shr     ax, 8
1019
        out     dx, al
1020
 
1021
; start DMA read
5005 hidnplayr 1022
        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 1023
        mov     al, CMD_RD0 + CMD_STA
1024
        out     dx, al
1025
 
5005 hidnplayr 1026
        set_io  [ebx + device.io_addr], NE_ASIC
1027
        test    [ebx + device.flags], FLAG_16BIT
3545 hidnplayr 1028
        jz      .8bits
3856 hidnplayr 1029
        DEBUGF  1, "(16-bit mode)\n"
3545 hidnplayr 1030
        shr     cx, 1   ; note that if the number was odd, carry flag will be set
1031
        pushf
1032
  .16bits:
1033
        in      ax, dx
1034
        stosw
1035
        loopw   .16bits
1036
        popf
5005 hidnplayr 1037
        jnc     wait_dma_done
1038
        in      al, dx
1039
        stosb
1040
        jmp     wait_dma_done
3545 hidnplayr 1041
 
1042
  .8bits:
3856 hidnplayr 1043
        DEBUGF  1, "(8-bit mode)\n"
3545 hidnplayr 1044
  .8bits_:
1045
        in      al, dx
1046
        stosb
1047
        loopw   .8bits_
5005 hidnplayr 1048
        jmp     wait_dma_done
3545 hidnplayr 1049
 
1050
 
1051
 
1052
 
1053
;***************************************************************************
1054
;
1055
;   PIO_write
1056
;
1057
;   Description
1058
;       writes a frame to the ethernet card via Programmed I/O
1059
;      dst in di
1060
;      cnt in cx
1061
;       src in esi
1062
;***************************************************************************
1063
PIO_write:
1064
 
3856 hidnplayr 1065
        DEBUGF  1, "Eth PIO Write from %x to %x, %u bytes ", esi, di, cx
3545 hidnplayr 1066
 
5005 hidnplayr 1067
; Stop DMA + start
1068
        set_io  [ebx + device.io_addr], 0
1069
;        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 1070
        mov     al, CMD_RD2 + CMD_STA
1071
        out     dx, al
1072
 
5005 hidnplayr 1073
; Request confirmation of end of DMA transfer
1074
        set_io  [ebx + device.io_addr], P0_ISR
3545 hidnplayr 1075
        mov     al, ISR_RDC
1076
        out     dx, al
1077
 
5005 hidnplayr 1078
; Program number of bytes we want to write
1079
        set_io  [ebx + device.io_addr], P0_RBCR0
3545 hidnplayr 1080
        mov     al, cl
1081
        out     dx, al
5005 hidnplayr 1082
        set_io  [ebx + device.io_addr], P0_RBCR1
3545 hidnplayr 1083
        mov     al, ch
1084
        out     dx, al
1085
 
5005 hidnplayr 1086
; Program where we want to write
3545 hidnplayr 1087
        mov     ax, di
5005 hidnplayr 1088
        set_io  [ebx + device.io_addr], P0_RSAR0
3545 hidnplayr 1089
        out     dx, al
1090
        shr     ax, 8
5005 hidnplayr 1091
        set_io  [ebx + device.io_addr], P0_RSAR1
3545 hidnplayr 1092
        out     dx, al
1093
 
5005 hidnplayr 1094
; Set the DMA to write
1095
        set_io  [ebx + device.io_addr], P0_COMMAND
3545 hidnplayr 1096
        mov     al, CMD_RD1 + CMD_STA
1097
        out     dx, al
1098
 
5005 hidnplayr 1099
        set_io  [ebx + device.io_addr], NE_ASIC
1100
        test    [ebx + device.flags], FLAG_16BIT
3545 hidnplayr 1101
        jz      .8_bit
3856 hidnplayr 1102
        DEBUGF  1, "(16-bit mode)\n"
3545 hidnplayr 1103
        shr     cx, 1   ; note that if the number was odd, carry flag will be set
1104
        pushf           ; save the flags for later
1105
  .16bit:
1106
        lodsw
1107
        out     dx, ax
1108
        loopw   .16bit
1109
        popf
5005 hidnplayr 1110
        jnc     wait_dma_done
1111
        lodsb
1112
        out     dx, al
1113
        jmp     wait_dma_done
3545 hidnplayr 1114
 
1115
  .8_bit:
3856 hidnplayr 1116
        DEBUGF  1, "(8-bit mode)\n"
3545 hidnplayr 1117
  .8_bit_:
1118
        lodsb
1119
        out     dx, al
1120
        loopw   .8_bit_
5005 hidnplayr 1121
        jmp     wait_dma_done
3545 hidnplayr 1122
 
5005 hidnplayr 1123
 
1124
 
1125
wait_dma_done:
1126
 
1127
        set_io  [ebx + device.io_addr], 0
1128
        set_io  [ebx + device.io_addr], P0_ISR
1129
  .dmawait:
1130
        in      al, dx
1131
        test    al, ISR_RDC             ; Remote DMA Complete
1132
        jz      .dmawait
3545 hidnplayr 1133
;        and     al, not ISR_RDC
1134
;        out     dx, al                  ; clear the bit
1135
 
1136
        ret
1137
 
1138
 
1139
 
5005 hidnplayr 1140
; End of code
3545 hidnplayr 1141
 
1142
 
5005 hidnplayr 1143
data fixups
1144
end data
3545 hidnplayr 1145
 
5005 hidnplayr 1146
include '../peimport.inc'
3545 hidnplayr 1147
 
5005 hidnplayr 1148
my_service      db 'RTL8029', 0                 ; max 16 chars include zero
3545 hidnplayr 1149
 
5005 hidnplayr 1150
;sz_8029         db 'Realtek 8029', 0
1151
;sz_8019         db 'Realtek 8019', 0
1152
;sz_8019as       db 'Realtek 8019AS', 0
1153
;sz_ne2k         db 'ne2000', 0
1154
;sz_dp8390       db 'DP8390', 0
3545 hidnplayr 1155
 
5005 hidnplayr 1156
include_debug_strings                           ; All data wich FDO uses will be included here
3545 hidnplayr 1157
 
5005 hidnplayr 1158
align 4
1159
devices       dd 0
1160
device_list   rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
3545 hidnplayr 1161