mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-11-08 19:10:52 +00:00
276 lines
4.0 KiB
ArmAsm
276 lines
4.0 KiB
ArmAsm
;originally from Per Olofsson's IP65 library - http://www.paradroid.net/ip65
|
|
|
|
; Ethernet driver for CS8900A
|
|
;
|
|
; Based on Doc Bacardi's tftp source
|
|
|
|
|
|
.include "../inc/common.i"
|
|
.include "cs8900a.i"
|
|
|
|
|
|
;.import dbg_dump_eth_header
|
|
|
|
|
|
.export eth_init
|
|
.export eth_rx
|
|
.export eth_tx
|
|
|
|
.export eth_inp
|
|
.export eth_inp_len
|
|
.export eth_outp
|
|
.export eth_outp_len
|
|
|
|
.exportzp eth_dest
|
|
.exportzp eth_src
|
|
.exportzp eth_type
|
|
.exportzp 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
|
|
|
|
|
|
.macro write_page page, value
|
|
lda #page/2
|
|
ldx #<value
|
|
ldy #>value
|
|
jsr cs_write_page
|
|
.endmacro
|
|
|
|
|
|
.segment "IP65ZP" : zeropage
|
|
|
|
eth_packet: .res 2
|
|
|
|
|
|
.bss
|
|
|
|
; input and output buffers
|
|
eth_inp_len: .res 2 ; input packet length
|
|
eth_inp: .res 1518 ; space for input packet
|
|
eth_outp_len: .res 2 ; output packet length
|
|
eth_outp: .res 1518 ; space for output packet
|
|
|
|
; ethernet packet offsets
|
|
eth_dest = 0 ; destination address
|
|
eth_src = 6 ; source address
|
|
eth_type = 12 ; packet type
|
|
eth_data = 14 ; packet data
|
|
|
|
|
|
.code
|
|
|
|
; initialize, return clc on success
|
|
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
|
|
;write_page pp_rx_ctl, $0d85 ; $0104, promiscuous mode
|
|
|
|
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
|
|
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 ; set packet pointer
|
|
sta eth_packet
|
|
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
|
|
eth_tx:
|
|
;jsr dbg_dump_eth_header
|
|
|
|
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
|
|
and #$f8
|
|
beq :+
|
|
|
|
inc $d020
|
|
sec ; oversized packet
|
|
rts
|
|
|
|
: lda #<pp_bus_status ; select bus status register
|
|
sta cs_packet_page
|
|
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
|