; ; Copyright (c) 2007, Adam Dunkels and 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: Adam Dunkels , Oliver Schmidt ; ;--------------------------------------------------------------------- .macpack module module_header _cs8900a ; Driver signature .byte $65, $74, $68 ; "eth" .byte $01 ; Ethernet driver API version number ; Ethernet address mac: .byte $00, $0E, $3A ; OUI of Cirrus Logic .ifdef __C64__ .byte $64, $64, $64 .endif .ifdef __C128__ .byte $28, $28, $28 .endif .ifdef __APPLE2__ .byte $A2, $A2, $A2 .endif .ifdef __ATARI__ .byte $A8, $A8, $A8 .endif .ifdef __VIC20__ .byte $20, $20, $20 .endif ; Buffer attributes bufaddr:.res 2 ; Address bufsize:.res 2 ; Size ; Jump table. jmp init jmp poll jmp send jmp exit ;--------------------------------------------------------------------- .if DYN_DRV .zeropage 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 cnt: .res 2 ; Frame length counter .else .include "zeropage.inc" reg := ptr1 ; Address of rxtxreg ptr := ptr2 ; Indirect addressing pointer len := ptr3 ; Frame length cnt := ptr4 ; Frame length counter .endif ;===================================================================== .ifdef __CBM__ .rodata ; Ethernet address rrnet: .byte $28, $CD, $4C ; OUI of Individual Computers .byte $FF ; Reserved for RR-Net ;--------------------------------------------------------------------- .if .defined (__C64__) .or .defined (__C128__) rxtxreg := $DE08 txcmd := $DE0C txlen := $DE0E isq := $DE00 packetpp := $DE02 ppdata := $DE04 .endif .ifdef __VIC20__ rxtxreg := $9808 txcmd := $980C txlen := $980E isq := $9800 packetpp := $9802 ppdata := $9804 .endif ;--------------------------------------------------------------------- .code init: ; Activate C64 RR clockport in order to operate RR-Net ; (RR config register overlays unused CS8900A ISQ register) lda isq+1 ora #$01 ; Set clockport bit sta isq+1 ; Check EISA registration number of Crystal Semiconductor ; PACKETPP = $0000, PPDATA == $630E ? lda #$00 tax jsr packetpp_ax lda #$63^$0E eor ppdata eor ppdata+1 beq :+ sec rts ; "When the RR-Net MK3 is used in cartridge mode, the EEPROM will serve as a ; regular 8k ROM cartridge. It is used as a startup-ROM if the unit is plugged ; directly to a C64. The startup code will initialize the MAC address." ; PACKETPP = $0158, PPDATA == RR-Net[0], RR-Net[1] ? ; PACKETPP = $015A, PPDATA == RR-Net[2], RR-Net[3] ? ; PACKETPP = $015C, AX = PPDATA : ldy #$58 : tya jsr packetpp_a1 lda ppdata ldx ppdata+1 cpy #$58+4 bcs copy cmp rrnet-$58,y bne :+ txa cmp rrnet-$58+1,y bne :+ iny iny bne :- ; Always ; "If the RR-Net MK3 is connected to a clockport, then the last 4 bytes of the ; EEPROM are visible by reading the last 4, normally write-only, registers." ; MAC_LO ^ MAC_HI ^ $55 == CHKSUM0 ? : lda txcmd ; MAC_LO eor txcmd+1 ; MAC_HI eor #$55 cmp txlen ; CHKSUM0 bne reset ; (CHKSUM0 + MAC_LO + MAC_HI) ^ $AA == CHKSUM1 ? clc adc txcmd ; MAC_LO clc adc txcmd+1 ; MAC_HI eor #$AA cmp txlen+1 ; CHKSUM1 bne reset ; "When both checksums match, the CS8900A should be initialized ; to use the MAC Address 28:CD:4C:FF::." ; AX = MAC_LO, MAC_HI lda txcmd ; MAC_LO ldx txcmd+1 ; MAC_HI ; MAC[4], MAC[5] = AX ; MAC[2], MAC[3] = RR-Net[2], RR-Net[3] ; MAC[0], MAC[1] = RR-Net[0], RR-Net[1] copy: ldy #$04 bne :++ ; Always : lda rrnet,y ldx rrnet+1,y : sta mac,y txa sta mac+1,y dey dey bpl :-- .endif ;===================================================================== .ifdef __APPLE2__ .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 fixups = * - fixup ;--------------------------------------------------------------------- ; The addresses are fixed up at runtime rxtxreg := $C080 txcmd := $C084 txlen := $C086 isq := $C088 packetpp := $C08A ppdata := $C08C ;--------------------------------------------------------------------- .data init: ; Convert slot number to slot I/O offset asl asl asl asl sta reg ; 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 (ptr),y and #%10001111 ; Allow for re-init ora reg sta (ptr),y ; Advance to next fixup location inx cpx #fixups bcs :+ lda ptr clc adc fixup,x sta ptr bcc :- inc ptr+1 bcs :- ; Always ; Check EISA registration number of Crystal Semiconductor ; PACKETPP = $0000, PPDATA == $630E ? : lda #$00 tax jsr packetpp_ax lda #$63^$0E fixup01:eor ppdata fixup02:eor ppdata+1 beq reset sec rts .endif ;===================================================================== .ifdef __ATARI__ rxtxreg := $D500 txcmd := $D504 txlen := $D506 isq := $D508 packetpp := $D50A ppdata := $D50C ;--------------------------------------------------------------------- .code init: ; Check EISA registration number of Crystal Semiconductor ; PACKETPP = $0000, PPDATA == $630E ? lda #$00 tax jsr packetpp_ax lda #$63^$0E eor ppdata eor ppdata+1 beq reset sec rts .endif ;===================================================================== reset: ; Initiate a chip-wide reset ; PACKETPP = $0114, PPDATA = $0040 lda #$14 jsr packetpp_a1 ldy #$40 fixup03:sty ppdata : jsr packetpp_a1 fixup04:ldy ppdata and #$40 bne :- ; Accept valid unicast + broadcast frames ; PACKETPP = $0104, PPDATA = $0D05 lda #$04 jsr packetpp_a1 lda #$05 ldx #$0D jsr ppdata_ax ; Set MAC address ; PACKETPP = $0158, PPDATA = MAC[0], MAC[1] ; PACKETPP = $015A, PPDATA = MAC[2], MAC[3] ; PACKETPP = $015C, PPDATA = MAC[4], MAC[5] ldy #$58 : tya jsr packetpp_a1 lda mac-$58,y ldx mac-$58+1,y jsr ppdata_ax iny iny cpy #$58+6 bcc :- ; Turn on transmission and reception of frames ; PACKETPP = $0112, PPDATA = $00D3 lda #$12 jsr packetpp_a1 lda #$D3 ldx #$00 jsr ppdata_ax txa clc rts ;--------------------------------------------------------------------- poll: ; Check receiver event register to see if there ; are any valid unicast frames avaliable ; PACKETPP = $0124, PPDATA & $0D00 ? lda #$24 jsr packetpp_a1 fixup05:lda ppdata+1 and #$0D beq :+ ; Process the incoming frame ; -------------------------- ; Read receiver event and discard it ; RXTXREG fixup06:ldx rxtxreg+1 fixup07:lda rxtxreg ; Read frame length ; cnt = len = RXTXREG fixup08:ldx rxtxreg+1 fixup09:lda rxtxreg sta len stx len+1 sta cnt stx cnt+1 ; Adjust odd frame length jsr adjustcnt ; Is bufsize < cnt ? lda bufsize cmp cnt lda bufsize+1 sbc cnt+1 bcs :++ ; Yes, skip frame jsr skipframe ; No frame ready lda #$00 : tax sec rts ; Read bytes into buffer : jsr adjustptr : fixup10:lda rxtxreg sta (ptr),y iny fixup11:lda rxtxreg+1 sta (ptr),y iny bne :- inc ptr+1 dex bpl :- ; Return frame length lda len ldx len+1 clc rts ;--------------------------------------------------------------------- send: ; Save frame length sta cnt stx cnt+1 ; Transmit command lda #$C9 ldx #$00 fixup12:sta txcmd fixup13:stx txcmd+1 lda cnt ldx cnt+1 fixup14:sta txlen fixup15:stx txlen+1 ; Adjust odd frame length jsr adjustcnt ; 8 retries ldy #$08 ; Check for avaliable buffer space ; PACKETPP = $0138, PPDATA & $0100 ? : lda #$38 jsr packetpp_a1 fixup16:lda ppdata+1 and #$01 bne :+ ; No space avaliable, skip a received frame jsr skipframe ; And try again dey bne :- sec rts ; Send the frame ; -------------- ; Write bytes from buffer : jsr adjustptr : lda (ptr),y fixup17:sta rxtxreg iny lda (ptr),y fixup18:sta rxtxreg+1 iny bne :- inc ptr+1 dex bpl :- clc rts ;--------------------------------------------------------------------- exit: rts ;--------------------------------------------------------------------- packetpp_a1: ldx #$01 packetpp_ax: fixup19:sta packetpp fixup20:stx packetpp+1 rts ;--------------------------------------------------------------------- ppdata_ax: fixup21:sta ppdata fixup22:stx ppdata+1 rts ;--------------------------------------------------------------------- skipframe: ; PACKETPP = $0102, PPDATA = PPDATA | $0040 lda #$02 jsr packetpp_a1 fixup23:lda ppdata ora #$40 fixup24:sta ppdata rts ;--------------------------------------------------------------------- adjustcnt: lsr bcc :+ inc cnt bne :+ inc cnt+1 : rts ;--------------------------------------------------------------------- adjustptr: lda cnt ldx cnt+1 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 rts ;---------------------------------------------------------------------