From ea08635ca4be05404a740dbea518534888d8314d Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Wed, 11 Sep 2013 20:48:23 +0200
Subject: [PATCH 1/2] Optimized CS8900A driver for speed and size.
- Speed: The primary byte copy loops are reduzed to the bare minimum by adjusting the base pointer 'ptr' and loop register 'y' in such a way that the 'y' overflow matches the low byte of the loop size.
- Size: Factored out all repeated code into subroutines. Introduced a loop for setting the MAC address.
Additional minor changes:
- Activate frame reception as last step of initialization after CS8900A configuration.
- Properly set internal address bits used by the CS8900A.
---
cpu/6502/net/cs8900a.S | 223 +++++++++++++++++++----------------------
1 file changed, 103 insertions(+), 120 deletions(-)
diff --git a/cpu/6502/net/cs8900a.S b/cpu/6502/net/cs8900a.S
index 52ab7a285..e0a0837af 100644
--- a/cpu/6502/net/cs8900a.S
+++ b/cpu/6502/net/cs8900a.S
@@ -74,14 +74,7 @@ fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03
.byte fixup17-fixup16, fixup18-fixup17, fixup19-fixup18
.byte fixup20-fixup19, fixup21-fixup20, fixup22-fixup21
.byte fixup23-fixup22, fixup24-fixup23, fixup25-fixup24
- .byte fixup26-fixup25, fixup27-fixup26, fixup28-fixup27
- .byte fixup29-fixup28, fixup30-fixup29, fixup31-fixup30
- .byte fixup32-fixup31, fixup33-fixup32, fixup34-fixup33
- .byte fixup35-fixup34, fixup36-fixup35, fixup37-fixup36
- .byte fixup38-fixup37, fixup39-fixup38, fixup40-fixup39
- .byte fixup41-fixup40, fixup42-fixup41, fixup43-fixup42
- .byte fixup44-fixup43, fixup45-fixup44, fixup46-fixup45
- .byte fixup47-fixup46, fixup48-fixup47
+ .byte fixup26-fixup25
fixups = * - fixup
@@ -140,56 +133,39 @@ fixup01:lda isq+1
ora #$01 ; Set clockport bit
fixup02:sta isq+1
- ; Turn on transmission and reception of frames
- ; PACKETPP = $0112, PPDATA = $00C0
- lda #$12
- ldx #$01
-fixup03:sta packetpp
-fixup04:stx packetpp+1
- lda #$C0
- ldx #$00
-fixup05:sta ppdata
-fixup06:stx ppdata+1
-
; Accept valid unicast + broadcast frames
; PACKETPP = $0104, PPDATA = $0D05
lda #$04
- ldx #$01
-fixup07:sta packetpp
-fixup08:stx packetpp+1
+ jsr packetpp_01
lda #$05
ldx #$0D
-fixup09:sta ppdata
-fixup10:stx ppdata+1
+fixup03:sta ppdata
+fixup04:stx ppdata+1
; Set MAC address
; PACKETPP = $0158, PPDATA = MAC[0], MAC[1]
- lda #$58
- ldx #$01
-fixup11:sta packetpp
-fixup12:stx packetpp+1
- lda mac
- ldx mac+1
-fixup13:sta ppdata
-fixup14:stx ppdata+1
; PACKETPP = $015A, PPDATA = MAC[2], MAC[3]
- lda #$5A
- ldx #$01
-fixup15:sta packetpp
-fixup16:stx packetpp+1
- lda mac+2
- ldx mac+3
-fixup17:sta ppdata
-fixup18:stx ppdata+1
- ; PACKETPP = 0x015C, PPDATA = MAC[4], MAC[5]
- lda #$5C
- ldx #$01
-fixup19:sta packetpp
-fixup20:stx packetpp+1
- lda mac+4
- ldx mac+5
-fixup21:sta ppdata
-fixup22:stx ppdata+1
+ ; PACKETPP = $015C, PPDATA = MAC[4], MAC[5]
+ ldy #$58
+: tya
+ jsr packetpp_01
+ lda mac-$58,y
+ ldx mac-$58+1,y
+fixup05:sta ppdata
+fixup06:stx ppdata+1
+ iny
+ iny
+ cpy #$58+6
+ bcc :-
+
+ ; Turn on transmission and reception of frames
+ ; PACKETPP = $0112, PPDATA = $00D3
+ lda #$12
+ jsr packetpp_01
+ lda #$D3
+ ldx #$00
+fixup07:sta ppdata
+fixup08:stx ppdata+1
rts
;---------------------------------------------------------------------
@@ -199,10 +175,8 @@ poll:
; are any valid unicast frames avaliable
; PACKETPP = $0124, PPDATA & $0D00 ?
lda #$24
- ldx #$01
-fixup23:sta packetpp
-fixup24:stx packetpp+1
-fixup25:lda ppdata+1
+ jsr packetpp_01
+fixup09:lda ppdata+1
and #$0D
bne :+
@@ -216,27 +190,23 @@ fixup25:lda ppdata+1
; Read receiver event and discard it
; RXTXREG
:
-fixup26:ldx rxtxreg+1
-fixup27:lda rxtxreg
+fixup10:ldx rxtxreg+1
+fixup11:lda rxtxreg
; Read frame length
; cnt = len = RXTXREG
-fixup28:ldx rxtxreg+1
-fixup29:lda rxtxreg
+fixup12:ldx rxtxreg+1
+fixup13:lda rxtxreg
sta len
stx len+1
sta cnt
stx cnt+1
; Adjust odd frame length
- lsr
- bcc :+
- inc cnt
- bne :+
- inc cnt+1
+ jsr adjustcnt
; Is bufsize < cnt ?
-: sec
+ sec
lda bufsize
sbc cnt
lda bufsize+1
@@ -244,14 +214,7 @@ fixup29:lda rxtxreg
bcs :+
; Yes, skip frame
- ; PACKETPP = $0102, PPDATA = PPDATA | $0040
- lda #$02
- ldx #$01
-fixup30:sta packetpp
-fixup31:stx packetpp+1
-fixup32:lda ppdata
- ora #$40
-fixup33:sta ppdata
+ jsr skipframe
; No frame ready
lda #$00
@@ -259,25 +222,18 @@ fixup33:sta ppdata
rts
; Read bytes into buffer
-: lda bufaddr
- ldx bufaddr+1
- sta ptr
- stx ptr+1
- ldx cnt+1
- ldy #$00
-read:
-fixup34:lda rxtxreg
+: jsr adjustptr
+:
+fixup14:lda rxtxreg
sta (ptr),y
iny
-fixup35:lda rxtxreg+1
+fixup15:lda rxtxreg+1
sta (ptr),y
iny
- bne :+
+ bne :-
inc ptr+1
-: cpy cnt
- bne read
dex
- bpl read
+ bpl :-
; Return frame length
lda len
@@ -292,44 +248,31 @@ send:
stx cnt+1
; Transmit command
- lda #$C0
+ lda #$C9
ldx #$00
-fixup36:sta txcmd
-fixup37:stx txcmd+1
+fixup16:sta txcmd
+fixup17:stx txcmd+1
lda cnt
ldx cnt+1
-fixup38:sta txlen
-fixup39:stx txlen+1
+fixup18:sta txlen
+fixup19:stx txlen+1
; Adjust odd frame length
- lsr
- bcc :+
- inc cnt
- bne :+
- inc cnt+1
+ jsr adjustcnt
; 8 retries
-: ldy #$08
+ ldy #$08
; Check for avaliable buffer space
; PACKETPP = $0138, PPDATA & $0100 ?
: lda #$38
- ldx #$01
-fixup40:sta packetpp
-fixup41:stx packetpp+1
-fixup42:lda ppdata+1
+ jsr packetpp_01
+fixup20:lda ppdata+1
and #$01
bne :+
; No space avaliable, skip a received frame
- ; PACKETPP = $0102, PPDATA = PPDATA | $0040
- lda #$02
- ldx #$01
-fixup43:sta packetpp
-fixup44:stx packetpp+1
-fixup45:lda ppdata
- ora #$40
-fixup46:sta ppdata
+ jsr skipframe
; And try again
dey
@@ -340,24 +283,17 @@ fixup46:sta ppdata
; --------------
; Write bytes from buffer
-: lda bufaddr
- ldx bufaddr+1
- sta ptr
- stx ptr+1
- ldx cnt+1
- ldy #$00
-write: lda (ptr),y
-fixup47:sta rxtxreg
+: jsr adjustptr
+: lda (ptr),y
+fixup21:sta rxtxreg
iny
lda (ptr),y
-fixup48:sta rxtxreg+1
+fixup22:sta rxtxreg+1
iny
- bne :+
+ bne :-
inc ptr+1
-: cpy cnt
- bne write
dex
- bpl write
+ bpl :-
rts
;---------------------------------------------------------------------
@@ -366,3 +302,50 @@ exit:
rts
;---------------------------------------------------------------------
+
+packetpp_01:
+ ldx #$01
+fixup23:sta packetpp
+fixup24:stx packetpp+1
+ rts
+
+;---------------------------------------------------------------------
+
+skipframe:
+ ; PACKETPP = $0102, PPDATA = PPDATA | $0040
+ lda #$02
+ jsr packetpp_01
+fixup25:lda ppdata
+ ora #$40
+fixup26:sta ppdata
+ rts
+
+;---------------------------------------------------------------------
+
+adjustcnt:
+ lsr
+ bcc :+
+ inc cnt
+ bne :+
+ inc cnt+1
+: rts
+
+;---------------------------------------------------------------------
+
+adjustptr:
+ lda cnt
+ eor #$FF ; Two's complement part 1
+ tay
+ iny ; Two's complement part 2
+ sty reg
+ sec
+ lda bufaddr
+ sbc reg
+ sta ptr
+ lda bufaddr+1
+ sbc #$00
+ sta ptr+1
+ ldx cnt+1
+ rts
+
+;---------------------------------------------------------------------
From 2263c1aa55df8b264482c0cc3615699748e7eb4a Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Thu, 12 Sep 2013 23:10:37 +0200
Subject: [PATCH 2/2] - Optimized LAN91C96 driver for speed and size.
- Speed: The primary byte copy loops are reduzed to the bare minimum by adjusting the base pointer 'ptr' and loop register 'y' in such a way that the 'y' overflow matches the low byte of the loop size.
- Introduced a loop for setting the MAC address.
Additional minor fix:
- Properly start self modification with first location.
---
cpu/6502/net/lan91c96.S | 143 ++++++++++++++++++++--------------------
1 file changed, 70 insertions(+), 73 deletions(-)
diff --git a/cpu/6502/net/lan91c96.S b/cpu/6502/net/lan91c96.S
index b6b7a296b..d943ca1b1 100644
--- a/cpu/6502/net/lan91c96.S
+++ b/cpu/6502/net/lan91c96.S
@@ -78,8 +78,7 @@ fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03
.byte fixup29-fixup28, fixup30-fixup29, fixup31-fixup30
.byte fixup32-fixup31, fixup33-fixup32, fixup34-fixup33
.byte fixup35-fixup34, fixup36-fixup35, fixup37-fixup36
- .byte fixup38-fixup37, fixup39-fixup38, fixup40-fixup39
- .byte fixup41-fixup40, fixup42-fixup41
+ .byte fixup38-fixup37
fixups = * - fixup
@@ -160,14 +159,14 @@ init:
; Reset ETH card
: lda #$00 ; Bank 0
-fixup00:sta ethbsr
+fixup01:sta ethbsr
lda #%10000000 ; Software reset
-fixup01:sta ethrcr+1
+fixup02:sta ethrcr+1
ldy #$00
-fixup02:sty ethrcr
-fixup03:sty ethrcr+1
+fixup03:sty ethrcr
+fixup04:sty ethrcr+1
; Delay
: cmp ($FF,x) ; 6 cycles
@@ -179,45 +178,39 @@ fixup03:sty ethrcr+1
; Enable transmit and receive
lda #%10000001 ; Enable transmit TXENA, PAD_EN
ldx #%00000011 ; Enable receive, strip CRC ???
-fixup04:sta ethtcr
-fixup05:stx ethrcr+1
+fixup05:sta ethtcr
+fixup06:stx ethrcr+1
lda #$01 ; Bank 1
-fixup06:sta ethbsr
+fixup07:sta ethbsr
-fixup07:lda ethcr+1
+fixup08:lda ethcr+1
ora #%00010000 ; No wait (IOCHRDY)
-fixup08:sta ethcr+1
+fixup09:sta ethcr+1
lda #%00001001 ; Auto release
-fixup09:sta ethctr+1
+fixup10:sta ethctr+1
; Set MAC address
- lda mac
- ldx mac+1
-fixup10:sta ethiar
-fixup11:stx ethiar+1
- lda mac+2
- ldx mac+3
-fixup12:sta ethiar+2
-fixup13:stx ethiar+3
- lda mac+4
- ldx mac+5
-fixup14:sta ethiar+4
-fixup15:stx ethiar+5
+ ldy #$00
+: lda mac,y
+fixup11:sta ethiar,y
+ iny
+ cpy #$06
+ bcc :-
; Set interrupt mask
lda #$02 ; Bank 2
-fixup16:sta ethbsr
+fixup12:sta ethbsr
lda #%00000000 ; No interrupts
-fixup17:sta ethmsk
+fixup13:sta ethmsk
rts
;---------------------------------------------------------------------
poll:
-fixup18:lda ethist
+fixup14:lda ethist
and #%00000001 ; RCV INT
bne :+
@@ -230,12 +223,12 @@ fixup18:lda ethist
: lda #$00
ldx #%11100000 ; RCV, AUTO INCR., READ
-fixup19:sta ethptr
-fixup20:stx ethptr+1
+fixup15:sta ethptr
+fixup16:stx ethptr+1
; Last word contains 'last data byte' and $60 or 'fill byte' and $40
-fixup21:lda ethdata ; Status word
-fixup22:lda ethdata ; Need high byte only
+fixup17:lda ethdata ; Status word
+fixup18:lda ethdata ; Need high byte only
; Move ODDFRM bit into carry:
; - Even packet length -> carry clear -> subtract 6 bytes
@@ -247,10 +240,10 @@ fixup22:lda ethdata ; Need high byte only
lsr
; The packet contains 3 extra words
-fixup23:lda ethdata ; Total number of bytes
+fixup19:lda ethdata ; Total number of bytes
sbc #$05 ; Actually 5 or 6 depending on carry
sta len
-fixup24:lda ethdata
+fixup20:lda ethdata
sbc #$00
sta len+1
@@ -265,7 +258,7 @@ fixup24:lda ethdata
; Yes, skip packet
; Remove and release RX packet from the FIFO
lda #%10000000
-fixup25:sta ethmmucr
+fixup21:sta ethmmucr
; No packet available
lda #$00
@@ -273,26 +266,19 @@ fixup25:sta ethmmucr
rts
; Read bytes into buffer
-: lda bufaddr
- ldx bufaddr+1
- sta ptr
- stx ptr+1
- ldx len+1
- ldy #$00
-read:
-fixup26:lda ethdata
+: jsr adjustptr
+:
+fixup22:lda ethdata
sta (ptr),y
iny
- bne :+
+ bne :-
inc ptr+1
-: cpy len
- bne read
dex
- bpl read
+ bpl :-
; Remove and release RX packet from the FIFO
lda #%10000000
-fixup27:sta ethmmucr
+fixup23:sta ethmmucr
; Return packet length
lda len
@@ -309,14 +295,14 @@ send:
; Allocate memory for TX
txa
ora #%00100000
-fixup28:sta ethmmucr
+fixup24:sta ethmmucr
; 8 retries
ldy #$08
; Wait for allocation ready
:
-fixup29:lda ethist
+fixup25:lda ethist
and #%00001000 ; ALLOC INT
bne :+
@@ -330,21 +316,21 @@ fixup29:lda ethist
; Acknowledge interrupt, is it necessary ???
: lda #%00001000
-fixup30:sta ethack
+fixup26:sta ethack
; Set packet address
-fixup31:lda etharr
-fixup32:sta ethpnr
+fixup27:lda etharr
+fixup28:sta ethpnr
lda #$00
ldx #%01000000 ; AUTO INCR.
-fixup33:sta ethptr
-fixup34:stx ethptr+1
+fixup29:sta ethptr
+fixup30:stx ethptr+1
; Status written by CSMA
lda #$00
-fixup35:sta ethdata
-fixup36:sta ethdata
+fixup31:sta ethdata
+fixup32:sta ethdata
; Check packet length parity:
; - Even packet length -> carry set -> add 6 bytes
@@ -356,30 +342,23 @@ fixup36:sta ethdata
; The packet contains 3 extra words
lda len
adc #$05 ; Actually 5 or 6 depending on carry
-fixup37:sta ethdata
+fixup33:sta ethdata
lda len+1
adc #$00
-fixup38:sta ethdata
+fixup34:sta ethdata
; Send the packet
; ---------------
; Write bytes from buffer
- lda bufaddr
- ldx bufaddr+1
- sta ptr
- stx ptr+1
- ldx len+1
- ldy #$00
-write: lda (ptr),y
-fixup39:sta ethdata
+ jsr adjustptr
+: lda (ptr),y
+fixup35:sta ethdata
iny
- bne :+
+ bne :-
inc ptr+1
-: cpy len
- bne write
dex
- bpl write
+ bpl :-
; Odd packet length ?
lda len
@@ -392,13 +371,13 @@ fixup39:sta ethdata
; No
: lda #$00
-fixup40:sta ethdata ; Fill byte
+fixup36:sta ethdata ; Fill byte
:
-fixup41:sta ethdata ; Control byte
+fixup37:sta ethdata ; Control byte
; Add packet to FIFO
lda #%11000000 ; ENQUEUE PACKET - transmit packet
-fixup42:sta ethmmucr
+fixup38:sta ethmmucr
rts
;---------------------------------------------------------------------
@@ -407,3 +386,21 @@ exit:
rts
;---------------------------------------------------------------------
+
+adjustptr:
+ lda len
+ eor #$FF ; Two's complement part 1
+ tay
+ iny ; Two's complement part 2
+ sty reg
+ sec
+ lda bufaddr
+ sbc reg
+ sta ptr
+ lda bufaddr+1
+ sbc #$00
+ sta ptr+1
+ ldx len+1
+ rts
+
+;---------------------------------------------------------------------