Added section on 'dir2atr' now that there's an "official" download.
[contiki-2.x.git] / cpu / 6502 / net / lan91c96.S
blob78fc46b8244176a8b917af71796e12cfa6fc3074
2 ; Copyright (c) 2003-2007, Adam Dunkels, Josef Soucek and Oliver Schmidt
3 ; All rights reserved. 
5 ; Redistribution and use in source and binary forms, with or without 
6 ; modification, are permitted provided that the following conditions 
7 ; are met: 
8 ; 1. Redistributions of source code must retain the above copyright 
9 ;    notice, this list of conditions and the following disclaimer. 
10 ; 2. Redistributions in binary form must reproduce the above copyright 
11 ;    notice, this list of conditions and the following disclaimer in the 
12 ;    documentation and/or other materials provided with the distribution. 
13 ; 3. Neither the name of the Institute nor the names of its contributors 
14 ;    may be used to endorse or promote products derived from this software 
15 ;    without specific prior written permission. 
17 ; THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
18 ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
19 ; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
20 ; ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
21 ; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
22 ; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
23 ; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
24 ; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
25 ; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
26 ; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
27 ; SUCH DAMAGE. 
29 ; This file is part of the Contiki operating system.
30
31 ; Author: Adam Dunkels <adam@sics.se>, Josef Soucek <josef.soucek@ide64.org>,
32 ;         Oliver Schmidt <ol.sc@web.de>
34 ; $Id: lan91c96.S,v 1.2 2007/12/01 20:23:11 oliverschmidt Exp $
36 ;---------------------------------------------------------------------
38         .segment        "JUMPTABLE"
40         ; Driver signature
41         .byte   $65, $74, $68   ; "eth"
42         .byte   $01             ; Ethernet driver API version number
43         
44         ; Ethernet address
45 mac:    .byte   $00, $80, $0F   ; OUI of Standard Microsystems
46         .byte   $11, $11, $11
48         ; Buffer attributes
49 bufaddr:.res    2               ; Address
50 bufsize:.res    2               ; Size
52         ; Jump table.
53         .addr   init
54         .addr   poll
55         .addr   send
56         .addr   exit
58 ;---------------------------------------------------------------------
60         .zeropage
62 sp:     .res    2               ; Stack pointer (Do not trash !)
63 reg:    .res    2               ; Address of register base
64 ptr:    .res    2               ; Indirect addressing pointer
65 len:    .res    2               ; Frame length
67 ;---------------------------------------------------------------------
69         .segment        "EXTZP": zeropage
70         
71         ; Empty segment to avoid linker warnings
73 ;---------------------------------------------------------------------
75         .rodata
76         
77 fixup:  .byte   fixup02-fixup01, fixup03-fixup02, fixup04-fixup03
78         .byte   fixup05-fixup04, fixup06-fixup05, fixup07-fixup06
79         .byte   fixup08-fixup07, fixup09-fixup08, fixup10-fixup09
80         .byte   fixup11-fixup10, fixup12-fixup11, fixup13-fixup12
81         .byte   fixup14-fixup13, fixup15-fixup14, fixup16-fixup15
82         .byte   fixup17-fixup16, fixup18-fixup17, fixup19-fixup18
83         .byte   fixup20-fixup19, fixup21-fixup20, fixup22-fixup21
84         .byte   fixup23-fixup22, fixup24-fixup23, fixup25-fixup24
85         .byte   fixup26-fixup25, fixup27-fixup26, fixup28-fixup27
86         .byte   fixup29-fixup28, fixup30-fixup29, fixup31-fixup30
87         .byte   fixup32-fixup31, fixup33-fixup32, fixup34-fixup33
88         .byte   fixup35-fixup34, fixup36-fixup35, fixup37-fixup36
89         .byte   fixup38-fixup37, fixup39-fixup38, fixup40-fixup39
90         .byte   fixup41-fixup40, fixup42-fixup41
92 fixups  = * - fixup
94 ;---------------------------------------------------------------------
96 ethbsr          := $FF0E        ; Bank select register             R/W (2B)
98 ; Register bank 0
99 ethtcr          := $FF00        ; Transmition control register     R/W (2B)
100 ethephsr        := $FF02        ; EPH status register              R/O (2B)
101 ethrcr          := $FF04        ; Receive control register         R/W (2B)
102 ethecr          := $FF06        ; Counter register                 R/O (2B)
103 ethmir          := $FF08        ; Memory information register      R/O (2B)
104 ethmcr          := $FF0A        ; Memory Config. reg.    +0 R/W +1 R/O (2B)
106 ; Register bank 1
107 ethcr           := $FF00        ; Configuration register           R/W (2B)
108 ethbar          := $FF02        ; Base address register            R/W (2B)
109 ethiar          := $FF04        ; Individual address register      R/W (6B)
110 ethgpr          := $FF0A        ; General address register         R/W (2B)
111 ethctr          := $FF0C        ; Control register                 R/W (2B)
113 ; Register bank 2
114 ethmmucr        := $FF00        ; MMU command register             W/O (1B)
115 ethautotx       := $FF01        ; AUTO TX start register           R/W (1B)
116 ethpnr          := $FF02        ; Packet number register           R/W (1B)
117 etharr          := $FF03        ; Allocation result register       R/O (1B)
118 ethfifo         := $FF04        ; FIFO ports register              R/O (2B)
119 ethptr          := $FF06        ; Pointer register                 R/W (2B)
120 ethdata         := $FF08        ; Data register                    R/W (4B)
121 ethist          := $FF0C        ; Interrupt status register        R/O (1B)
122 ethack          := $FF0C        ; Interrupt acknowledge register   W/O (1B)
123 ethmsk          := $FF0D        ; Interrupt mask register          R/W (1B)
125 ; Register bank 3
126 ethmt           := $FF00        ; Multicast table                  R/W (8B)
127 ethmgmt         := $FF08        ; Management interface             R/W (2B)
128 ethrev          := $FF0A        ; Revision register                R/W (2B)
129 ethercv         := $FF0C        ; Early RCV register               R/W (2B)
131         .data
133 ;---------------------------------------------------------------------
135 init:
136         ; Save address of register base
137         sta reg
138         stx reg+1
140         ; Start with first fixup location
141         lda #<(fixup01+1)
142         ldx #>(fixup01+1)
143         sta ptr
144         stx ptr+1
145         ldx #$FF
146         ldy #$00
148         ; Fixup address at location
149 :       lda reg
150         ora (ptr),y
151         sta (ptr),y
152         iny
153         lda reg+1
154         sta (ptr),y
155         dey
156         
157         ; Advance to next fixup location
158         inx
159         cpx #fixups
160         bcs :+
161         lda ptr
162         clc
163         adc fixup,x
164         sta ptr
165         bcc :-
166         inc ptr+1
167         bcs :-                  ; Always
169         ; Reset ETH card
170 :       lda #$00                ; Bank 0
171 fixup00:sta ethbsr
172         
173         lda #%10000000          ; Software reset
174 fixup01:sta ethrcr+1
176         ldy #$00
177 fixup02:sty ethrcr
178 fixup03:sty ethrcr+1
180         ; Delay
181 :       cmp ($FF,x)             ; 6 cycles
182         cmp ($FF,x)             ; 6 cycles
183         iny                     ; 2 cycles
184         bne :-                  ; 3 cycles
185                                 ; 17 * 256 = 4352 -> 4,4 ms
187         ; Enable transmit and receive
188         lda #%10000001          ; Enable transmit TXENA, PAD_EN
189         ldx #%00000011          ; Enable receive, strip CRC ???
190 fixup04:sta ethtcr
191 fixup05:stx ethrcr+1
193         lda #$01                ; Bank 1
194 fixup06:sta ethbsr
195         
196 fixup07:lda ethcr+1
197         ora #%00010000          ; No wait (IOCHRDY)
198 fixup08:sta ethcr+1
200         lda #%00001001          ; Auto release
201 fixup09:sta ethctr+1
202   
203         ; Set MAC address
204         lda mac
205         ldx mac+1
206 fixup10:sta ethiar
207 fixup11:stx ethiar+1
208         lda mac+2
209         ldx mac+3
210 fixup12:sta ethiar+2
211 fixup13:stx ethiar+3
212         lda mac+4
213         ldx mac+5
214 fixup14:sta ethiar+4
215 fixup15:stx ethiar+5
217         ; Set interrupt mask
218         lda #$02                ; Bank 2
219 fixup16:sta ethbsr
220         
221         lda #%00000000          ; No interrupts
222 fixup17:sta ethmsk
223         rts
224         
225 ;---------------------------------------------------------------------
227 poll:
228 fixup18:lda ethist
229         and #%00000001          ; RCV INT
230         bne :+
232         ; No packet available
233         tax
234         rts
236         ; Process the incoming packet
237         ; ---------------------------
238         
239 :       lda #$00
240         ldx #%11100000          ; RCV, AUTO INCR., READ
241 fixup19:sta ethptr
242 fixup20:stx ethptr+1
244         ; Last word contains 'last data byte' and $60 or 'fill byte' and $40
245 fixup21:lda ethdata             ; Status word
246 fixup22:lda ethdata             ; Need high byte only
248         ; Move ODDFRM bit into carry:
249         ; - Even packet length -> carry clear -> subtract 6 bytes
250         ; - Odd packet length  -> carry set   -> subtract 5 bytes
251         lsr
252         lsr
253         lsr
254         lsr
255         lsr
256         
257         ; The packet contains 3 extra words
258 fixup23:lda ethdata             ; Total number of bytes
259         sbc #$05                ; Actually 5 or 6 depending on carry
260         sta len
261 fixup24:lda ethdata
262         sbc #$00
263         sta len+1
265         ; Is len > bufsize ?
266         sec
267         lda len
268         sbc bufsize
269         lda len+1
270         sbc bufsize+1
271         bcc :+
273         ; Yes, skip packet
274         ; Remove and release RX packet from the FIFO
275         lda #%10000000
276 fixup25:sta ethmmucr
278         ; No packet available
279         lda #$00
280         tax
281         rts
283         ; Read bytes into buffer
284 :       lda bufaddr
285         ldx bufaddr+1
286         sta ptr
287         stx ptr+1
288         ldx len+1
289         ldy #$00
290 read:
291 fixup26:lda ethdata
292         sta (ptr),y
293         iny
294         bne :+
295         inc ptr+1
296 :       cpy len
297         bne read
298         dex
299         bpl read
300   
301         ; Remove and release RX packet from the FIFO
302         lda #%10000000
303 fixup27:sta ethmmucr
305         ; Return packet length
306         lda len
307         ldx len+1
308         rts
310 ;---------------------------------------------------------------------
312 send:
313         ; Save packet length
314         sta len
315         stx len+1
317         ; Allocate memory for TX
318         txa
319         ora #%00100000
320 fixup28:sta ethmmucr
322         ; 8 retries
323         ldy #$08
325         ; Wait for allocation ready
327 fixup29:lda ethist
328         and #%00001000          ; ALLOC INT
329         bne :+
331         ; Shouldn't we do something here to actively free memory,
332         ; maybe removing and releasing an RX packet from the FIFO ???
334         ; And try again
335         dey
336         bne :-
337         rts
339         ; Acknowledge interrupt, is it necessary ???
340 :       lda #%00001000
341 fixup30:sta ethack
343         ; Set packet address
344 fixup31:lda etharr
345 fixup32:sta ethpnr
347         lda #$00
348         ldx #%01000000          ; AUTO INCR.
349 fixup33:sta ethptr
350 fixup34:stx ethptr+1
352         ; Status written by CSMA
353         lda #$00
354 fixup35:sta ethdata
355 fixup36:sta ethdata
357         ; Check packet length parity:
358         ; - Even packet length -> carry set   -> add 6 bytes
359         ; - Odd packet length  -> carry clear -> add 5 bytes
360         lda len
361         eor #$01
362         lsr
363         
364         ; The packet contains 3 extra words
365         lda len
366         adc #$05                ; Actually 5 or 6 depending on carry
367 fixup37:sta ethdata
368         lda len+1
369         adc #$00
370 fixup38:sta ethdata
372         ; Send the packet
373         ; ---------------
375         ; Write bytes from buffer
376         lda bufaddr
377         ldx bufaddr+1
378         sta ptr
379         stx ptr+1
380         ldx len+1
381         ldy #$00
382 write:  lda (ptr),y
383 fixup39:sta ethdata
384         iny
385         bne :+
386         inc ptr+1
387 :       cpy len
388         bne write
389         dex
390         bpl write
392         ; Odd packet length ?
393         lda len
394         lsr
395         bcc :+
397         ; Yes
398         lda #%00100000          ; ODD
399         bne :++                 ; Always
401         ; No
402 :       lda #$00
403 fixup40:sta ethdata             ; Fill byte
404 :       
405 fixup41:sta ethdata             ; Control byte
407         ; Add packet to FIFO
408         lda #%11000000          ; ENQUEUE PACKET - transmit packet
409 fixup42:sta ethmmucr
410         rts
412 ;---------------------------------------------------------------------
414 exit:
415         rts
416         
417 ;---------------------------------------------------------------------