ip65 technical reference

File : drivers/cs8900a.s

 Ethernet driver for CS8900A chip (as used in RR-NET and Uthernet adapters)

 Based on Doc Bacardi's tftp source

functions

functiondescription
eth_init
initialize the ethernet adaptor
inputs: none
outputs: carry flag is set if there was an error, clear otherwise
eth_rx
receive a packet
inputs: none
outputs:
 if there was an error receiving the packet (or no packet was ready) then carry flag is set
 if packet was received correctly then carry flag is clear, 
 eth_inp contains the received packet, 
 and eth_inp_len contains the length of the packet
eth_tx
 send a packet
inputs:
 eth_outp: packet to send
 eth_outp_len: length of packet to send
outputs:
 if there was an error sending the packet then carry flag is set
 otherwise carry flag is cleared

implementation

; Ethernet driver for CS8900A chip (as used in RR-NET and Uthernet adapters)
;
; Based on Doc Bacardi's tftp source


.ifndef KPR_API_VERSION_NUMBER
  .define EQU     =
  .include "../inc/kipper_constants.i"
.endif

.include "../inc/common.i"
.include "cs8900a.i"

  .export eth_init
  .export eth_rx
  .export eth_tx

  .import eth_inp
  .import eth_inp_len
  .import eth_outp
  .import eth_outp_len

  .importzp eth_dest
  .importzp eth_src
  .importzp eth_type
  .importzp eth_data

  .import cs_init
  .import cs_packet_page
  .import cs_packet_data
  .import cs_rxtx_data
  .import cs_tx_cmd
  .import cs_tx_len

  .import cfg_mac

  .import ip65_error

  .macro write_page page, value
  lda #page/2
  ldx #value
  jsr cs_write_page
  .endmacro


  .segment "IP65ZP" : zeropage

eth_packet:  .res 2


  
  .code

;initialize the ethernet adaptor
;inputs: none
;outputs: carry flag is set if there was an error, clear otherwise
eth_init:
  jsr cs_init

  lda #0      ; check magic signature
  jsr cs_read_page
  cpx #$0e
  bne @notfound
  cpy #$63
  bne @notfound

  lda #1
  jsr cs_read_page
  cpx #0
  bne @notfound
  ; y contains chip rev

  write_page pp_self_ctl, $0055  ; $0114, reset chip

  write_page pp_rx_ctl, $0d05  ; $0104, accept individual and broadcast packets

  lda #pp_ia/2      ; $0158, write mac address
  ldx cfg_mac
  ldy cfg_mac + 1
  jsr cs_write_page

  lda #pp_ia/2 + 1
  ldx cfg_mac + 2
  ldy cfg_mac + 3
  jsr cs_write_page

  lda #pp_ia/2 + 2
  ldx cfg_mac + 4
  ldy cfg_mac + 5
  jsr cs_write_page

  write_page pp_line_ctl, $00d3  ; $0112, enable rx and tx

  clc
  rts

@notfound:
  sec
  rts


;receive a packet
;inputs: none
;outputs:
; if there was an error receiving the packet (or no packet was ready) then carry flag is set
; if packet was received correctly then carry flag is clear, 
; eth_inp contains the received packet, 
; and eth_inp_len contains the length of the packet
eth_rx:
  lda #$24      ; check rx status
  sta cs_packet_page
  lda #$01
  sta cs_packet_page + 1

  lda cs_packet_data + 1
  and #$0d
  bne :+

  sec        ; no packet ready
  rts

:  lda cs_rxtx_data + 1    ; ignore status
  lda cs_rxtx_data

  lda cs_rxtx_data + 1    ; read packet length
  sta eth_inp_len + 1
  tax        ; save
  lda cs_rxtx_data
  sta eth_inp_len

  lda #eth_inp
  sta eth_packet + 1

  ldy #0
  cpx #0        ; < 256 bytes left?
  beq @tail

@get256:
  lda cs_rxtx_data
  sta (eth_packet),y
  iny
  lda cs_rxtx_data + 1
  sta (eth_packet),y
  iny
  bne @get256
  inc eth_packet + 1
  dex
  bne @get256

@tail:
  lda eth_inp_len      ; bytes left / 2, round up
  lsr
  adc #0
  beq @done
  tax

@get:
  lda cs_rxtx_data
  sta (eth_packet),y
  iny
  lda cs_rxtx_data + 1
  sta (eth_packet),y
  iny
  dex
  bne @get

@done:
  clc
  rts


; send a packet
;inputs:
; eth_outp: packet to send
; eth_outp_len: length of packet to send
;outputs:
; if there was an error sending the packet then carry flag is set
; otherwise carry flag is cleared
eth_tx:
  
  lda #$c9      ; ask for buffer space
  sta cs_tx_cmd
  lda #0
  sta cs_tx_cmd + 1

  lda eth_outp_len    ; set length
  sta cs_tx_len
  lda eth_outp_len + 1
  sta cs_tx_len + 1
  cmp #6
  bmi :+
  lda #KPR_ERROR_INPUT_TOO_LARGE
  sta ip65_error
  sec        ; oversized packet
  rts

:  lda #pp_bus_status
  sta cs_packet_page + 1

@waitspace:
  lda cs_packet_data + 1    ; wait for space
  ldx cs_packet_data
  lsr
  bcs @gotspace
  jsr @done      ; polling too fast doesn't work, delay added by David Schmidt
  jmp @waitspace
@gotspace:
  ldax #eth_outp      ; send packet
  stax eth_packet

  ldy #0
  ldx eth_outp_len + 1
  beq @tail

@send256:
  lda (eth_packet),y
  sta cs_rxtx_data
  iny
  lda (eth_packet),y
  sta cs_rxtx_data + 1
  iny
  bne @send256
  inc eth_packet + 1
  dex
  bne @send256

@tail:
  ldx eth_outp_len
  beq @done

@send:
  lda (eth_packet),y
  sta cs_rxtx_data
  dex
  beq @done
  iny
  lda (eth_packet),y
  sta cs_rxtx_data + 1
  iny
  dex
  bne @send

@done:          ; also used by timeout code above
  clc
  rts


; read X/Y from page A * 2
cs_read_page:
  asl
  sta cs_packet_page
  lda #0
  rol
  sta cs_packet_page + 1
  ldx cs_packet_data
  ldy cs_packet_data + 1
  rts

; write X/Y to page A * 2
cs_write_page:
  asl
  sta cs_packet_page
  lda #0
  rol
  sta cs_packet_page + 1
  stx cs_packet_data
  sty cs_packet_data + 1
  rts



;-- LICENSE FOR cs8900a.s --
; The contents of this file are subject to the Mozilla Public License
; Version 1.1 (the "License"); you may not use this file except in
; compliance with the License. You may obtain a copy of the License at
; http://www.mozilla.org/MPL/
; 
; Software distributed under the License is distributed on an "AS IS"
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
; License for the specific language governing rights and limitations
; under the License.
; 
; The Original Code is ip65.
; 
; The Initial Developer of the Original Code is Per Olofsson,
; MagerValp@gmail.com.
; Portions created by the Initial Developer are Copyright (C) 2009
; Per Olofsson. All Rights Reserved.  
; -- LICENSE END --