From 2d7d1b123d54ecc2be6513b383e2a80fbc269f0b Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Sat, 9 Nov 2013 23:15:20 +0100
Subject: [PATCH] Added 6502 driver for WIZnet W5100 in MACRAW mode.
---
cpu/6502/Makefile.6502 | 2 +-
cpu/6502/net/cs8900a.S | 2 +-
cpu/6502/net/w5100.S | 458 ++++++++++++++++++++++++++
platform/apple2enh/Makefile.apple2enh | 1 +
4 files changed, 461 insertions(+), 2 deletions(-)
create mode 100644 cpu/6502/net/w5100.S
diff --git a/cpu/6502/Makefile.6502 b/cpu/6502/Makefile.6502
index 9ae7549ae..961f714c5 100644
--- a/cpu/6502/Makefile.6502
+++ b/cpu/6502/Makefile.6502
@@ -35,7 +35,7 @@ ifndef CC65_HOME
${error CC65_HOME not defined! You must specify where cc65 resides}
endif
-all: cs8900a.eth lan91c96.eth
+all: cs8900a.eth lan91c96.eth w5100.eth
CONTIKI_TARGET_DIRS = . lib sys
CONTIKI_CPU_DIRS = . lib sys ctk net
diff --git a/cpu/6502/net/cs8900a.S b/cpu/6502/net/cs8900a.S
index 226d8606e..095909dd6 100644
--- a/cpu/6502/net/cs8900a.S
+++ b/cpu/6502/net/cs8900a.S
@@ -56,7 +56,7 @@ bufsize:.res 2 ; Size
.zeropage
-sp: .res 2 ; Stack pointer (Do not trash !)
+sp: .res 2 ; Stack pointer (Do not trash !)
reg: .res 2 ; Address of rxtxreg
ptr: .res 2 ; Indirect addressing pointer
len: .res 2 ; Frame length
diff --git a/cpu/6502/net/w5100.S b/cpu/6502/net/w5100.S
new file mode 100644
index 000000000..bf712fc94
--- /dev/null
+++ b/cpu/6502/net/w5100.S
@@ -0,0 +1,458 @@
+;
+; Copyright (c) 2013, Oliver Schmidt
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+; 3. Neither the name of the Institute nor the names of its contributors
+; may be used to endorse or promote products derived from this software
+; without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+; SUCH DAMAGE.
+;
+; This file is part of the Contiki operating system.
+;
+; Author: Oliver Schmidt
+;
+;---------------------------------------------------------------------
+
+ .segment "JUMPTABLE"
+
+ ; Driver signature
+ .byte $65, $74, $68 ; "eth"
+ .byte $01 ; Ethernet driver API version number
+
+ ; Ethernet address
+mac: .byte $00, $08, $DC ; OUI of WIZnet
+ .byte $11, $11, $11
+
+ ; Buffer attributes
+bufaddr:.res 2 ; Address
+bufsize:.res 2 ; Size
+
+ ; Jump table.
+ .addr init
+ .addr poll
+ .addr send
+ .addr exit
+
+;---------------------------------------------------------------------
+
+ .zeropage
+
+sp: .res 2 ; Stack pointer (Do not trash !)
+reg: .res 2 ; Pointer Register content
+ptr: .res 2 ; Indirect addressing pointer
+len: .res 2 ; Data length
+cnt: .res 2 ; Data length counter
+adv: .res 2 ; Data pointer advancement
+dir: .res 1 ; Transfer direction
+bas: .res 1 ; Socket 0 Base Address (hibyte)
+lim: .res 1 ; Socket 0 memory limit (hibyte)
+tmp: .res 1 ; Temporary value
+
+;---------------------------------------------------------------------
+
+ .rodata
+
+fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03
+ .byte fixup05-fixup04, fixup06-fixup05, fixup07-fixup06
+ .byte fixup08-fixup07, fixup09-fixup08, fixup10-fixup09
+ .byte fixup11-fixup10, fixup12-fixup11, fixup13-fixup12
+ .byte fixup14-fixup13, fixup15-fixup14, fixup16-fixup15
+ .byte fixup17-fixup16, fixup18-fixup17, fixup19-fixup18
+ .byte fixup20-fixup19, fixup21-fixup20, fixup22-fixup21
+ .byte fixup23-fixup22, fixup24-fixup23, fixup25-fixup24
+
+fixups = * - fixup
+
+;---------------------------------------------------------------------
+
+mode := $FF00 ; High byte patched at runtime
+addr := $FF01 ; High byte patched at runtime
+data := $FF03 ; High byte patched at runtime
+
+ .data
+
+;---------------------------------------------------------------------
+
+init:
+ ; Save address of register base
+ sta reg
+ stx reg+1
+
+ ; Start with first fixup location
+ lda #<(fixup01+1)
+ ldx #>(fixup01+1)
+ sta ptr
+ stx ptr+1
+ ldx #$FF
+ ldy #$00
+
+ ; Fixup address at location
+: lda reg
+ ora (ptr),y
+ sta (ptr),y
+ iny
+ lda reg+1
+ sta (ptr),y
+ dey
+
+ ; Advance to next fixup location
+ inx
+ cpx #fixups
+ bcs :+
+ lda ptr
+ clc
+ adc fixup,x
+ sta ptr
+ bcc :-
+ inc ptr+1
+ bcs :- ; Always
+
+ ; S/W Reset
+: lda #$80
+fixup01:sta mode
+:
+fixup02:lda mode
+ bmi :-
+
+ ; Indirect Bus I/F mode, Address Auto-Increment, Ping Block
+ lda #$13
+fixup03:sta mode
+
+ ; Source Hardware Address Register: MAC Address
+ ldx #$00 ; Hibyte
+ ldy #$09 ; Lobyte
+ jsr set_addr
+: lda mac,x
+fixup04:sta data
+ inx
+ cpx #$06
+ bcc :-
+
+ ; RX Memory Size Register: Assign 8KB to socket 0
+ ; TX Memory Size Register: Assign 8KB to socket 0
+ ldx #$00 ; Hibyte
+ ldy #$1A ; Lobyte
+ jsr set_addr
+ lda #$03
+fixup05:sta data
+fixup06:sta data
+
+ ; Socket 0 Mode Register: MACRAW, MAC Filter
+ ; Socket 0 Command Register: OPEN
+ ldy #$00
+ jsr set_addrsocket0
+ lda #$44
+fixup07:sta data
+ lda #$01
+fixup08:sta data
+ rts
+
+;---------------------------------------------------------------------
+
+poll:
+ ; Set parameters for receiving data
+ lda #>$6000 ; Socket 0 RX Base Address
+ ldx #$00 ; Read
+ jsr set_parameters
+
+ ; Socket RX Received Size Register: != 0 ?
+ ldy #$26 ; Socket RX Received Size Register
+ jsr set_addrsocket0
+fixup09:lda data ; Hibyte
+fixup10:ora data ; Lobyte
+ bne :+
+
+ ; No data available
+ tax
+ rts
+
+ ; Process the incoming data
+ ; -------------------------
+
+: ; ldy #$28 ; Socket RX Read Pointer Register
+ ; jsr set_addrsocket0
+
+ ; Calculate and set pyhsical address
+ jsr set_addrphysical
+
+ ; Read MAC raw 2byte packet size header
+ jsr get_datacheckaddr ; Hibyte
+ sta adv+1
+ jsr get_datacheckaddr ; Lobyte
+ sta adv
+
+ ; Subtract 2byte header and set length
+ sec
+ sbc #<$0002
+ sta len
+ sta cnt
+ lda adv+1
+ sbc #>$0002
+ sta len+1
+ sta cnt+1
+
+ ; Is bufsize < length ?
+ lda bufsize
+ cmp len
+ lda bufsize+1
+ sbc len+1
+ bcs :+
+
+ ; Set data length = 0 and skip read
+ lda #$00
+ sta len
+ sta len+1
+ beq :++ ; Always
+
+ ; Read data
+: jsr mov_data
+
+ ; Set parameters for common code
+: lda #$40 ; RECV
+ ldy #$28 ; Socket 0 RX Read Pointer Register
+
+ ; Advance pointer register
+common: jsr set_addrsocket0
+ tay ; Save command
+ lda reg
+ clc
+ adc adv
+ tax
+ lda reg+1
+ adc adv+1
+fixup11:sta data ; Hibyte
+fixup12:stx data ; Lobyte
+
+ ; Set command register
+ tya ; Restore command
+ jsr set_addrcmdreg0
+fixup13:sta data
+
+ ; Return data length (will be ignored for send)
+ lda len
+ ldx len+1
+ rts
+
+;---------------------------------------------------------------------
+
+send:
+ ; Save data length
+ sta len
+ stx len+1
+ sta cnt
+ stx cnt+1
+ sta adv
+ stx adv+1
+
+ ; Set parameters for transmitting data
+ lda #>$4000 ; Socket 0 TX Base Address
+ ldx #$01 ; Write
+ jsr set_parameters
+
+ ; Socket 0 TX Free Size Register: < length ?
+: ldy #$20
+ jsr set_addrsocket0
+fixup14:lda data ; Hibyte
+fixup15:ldx data ; Lobyte
+ cpx len
+ sbc len+1
+ bcc :-
+
+ ; Send the data
+ ; -------------
+
+ ldy #$24 ; Socket TX Write Pointer Register
+ jsr set_addrsocket0
+
+ ; Calculate and set pyhsical address
+ jsr set_addrphysical
+
+ ; Write data
+ jsr mov_data
+
+ ; Set parameters for common code
+ lda #$20 ; SEND
+ ldy #$24 ; Socket TX Write Pointer Register
+ bne common ; Always
+
+;---------------------------------------------------------------------
+
+exit:
+ rts
+
+;---------------------------------------------------------------------
+
+set_addrphysical:
+fixup16:lda data ; Hibyte
+fixup17:ldy data ; Lobyte
+ sta reg+1
+ sty reg
+ and #>$1FFF ; Socket Mask Address (hibyte)
+ ora bas ; Socket Base Address (hibyte)
+ tax
+set_addr:
+fixup18:stx addr ; Hibyte
+fixup19:sty addr+1 ; Lobyte
+ rts
+
+set_addrcmdreg0:
+ ldy #$01 ; Socket Command Register
+set_addrsocket0:
+ ldx #>$0400 ; Socket 0 register base address
+ bne set_addr ; Always
+
+set_addrbase:
+ ldx bas ; Socket Base Address (hibyte)
+ ldy #<$0000 ; Socket Base Address (lobyte)
+ beq set_addr ; Always
+
+get_datacheckaddr:
+fixup20:lda data
+ ldx addr ; Hibyte
+ cpx lim ; Socket memory limit (hibyte)
+ bcs set_addrbase
+ rts
+
+;---------------------------------------------------------------------
+
+set_parameters:
+ ; Setup variables in zero page
+ sta bas ; Socket Base Address
+ clc
+ adc #>$2000 ; Socket memory size
+ sta lim ; Socket memory limit
+ stx dir ; Transfer direction
+
+ ; Set indirect addressing pointer
+ lda bufaddr
+ ldx bufaddr+1
+ sta ptr
+ stx ptr+1
+
+ ; Wait for previous command to complete
+ ; Socket 0 Command Register: = 0 ?
+: jsr set_addrcmdreg0
+fixup21:lda data
+ bne :-
+ rts
+
+;---------------------------------------------------------------------
+
+mov_data:
+ ; Calculate highest R/W address allowing
+ ; to R/W without address wraparound
+ sec
+ lda #<$0000 ; Socket memory limit (lobyte)
+ sbc len
+ tay
+ lda lim ; Socket memory limit (hibyte)
+ sbc len+1
+ tax
+ tya
+
+ ; R/W without address wraparound possible because
+ ; highest R/W address > actual R/W address ?
+ ; sec
+fixup22:sbc addr+1 ; Lobyte
+ tay
+ txa
+fixup23:sbc addr ; Hibyte
+ tax
+ tya
+ bcs :+
+
+ ; Calculate length of first chunk
+ ; clc
+ adc len
+ sta cnt
+ tay
+ txa
+ adc len+1
+ sta cnt+1
+ tax
+ tya
+
+ ; R/W first chunk
+ jsr rw_data
+
+ ; Wraparound R/W address
+ jsr set_addrbase
+
+ ; Set buffer pointer for second chunk
+ clc
+ lda bufaddr
+ adc cnt
+ sta ptr
+ lda bufaddr+1
+ adc cnt+1
+ sta ptr+1
+
+ ; Calculate length of second chunk
+ sec
+ lda len
+ sbc cnt
+ sta cnt
+ lda len+1
+ sbc cnt+1
+ sta cnt+1
+
+ ; Get length of (second) chunk
+: lda cnt
+ ldx cnt+1
+
+ ; R/W (second) chunk
+rw_data:eor #$FF ; Two's complement part 1
+ tay
+ iny ; Two's complement part 2
+ sty tmp
+ sec
+ lda ptr
+ sbc tmp
+ sta ptr
+ lda ptr+1
+ sbc #$00
+ sta ptr+1
+ lda dir ; Transfer direction
+ bne :++
+
+ ; Read data
+:
+fixup24:lda data
+ sta (ptr),y
+ iny
+ bne :-
+ inc ptr+1
+ dex
+ bpl :-
+ rts
+
+ ; Write data
+: lda (ptr),y
+fixup25:sta data
+ iny
+ bne :-
+ inc ptr+1
+ dex
+ bpl :-
+ rts
+
+;---------------------------------------------------------------------
diff --git a/platform/apple2enh/Makefile.apple2enh b/platform/apple2enh/Makefile.apple2enh
index 8f1157524..2ee17b0fc 100644
--- a/platform/apple2enh/Makefile.apple2enh
+++ b/platform/apple2enh/Makefile.apple2enh
@@ -60,6 +60,7 @@ disk: all
java -jar $(AC) -p contiki.dsk contiki.cfg bin 0 < $(CONTIKI)/tools/$(TARGET)/sample.cfg
java -jar $(AC) -p contiki.dsk cs8900a.eth rel 0 < cs8900a.eth
java -jar $(AC) -p contiki.dsk lan91c96.eth rel 0 < lan91c96.eth
+ java -jar $(AC) -p contiki.dsk w5100.eth rel 0 < w5100.eth
ifeq ($(findstring WITH_MOUSE,$(DEFINES)),WITH_MOUSE)
java -jar $(AC) -p contiki.dsk a2e.stdmou.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou
endif