;; #LAYOUT# STD * #TAKE ;; #LAYOUT# * * #IGNORE ; ; The network entries of the Arnitech jump table (mc64 only, arnitech's ADR 0027): whole ; Ethernet frames through the CS8900A at the RR-Net socket, polled, from the Destination ; Address to the end of the data, without the CRC. The chip is found by its Product ID, so ; the routines find an RR-Net on any C64 that has one. Register semantics are the CS8900A ; datasheet's (Cirrus Logic DS271F5) and its 8-bit mode's (AN181). ; ; SAL holds the pointer to the frame or buffer, EAL the bytes left, as LOAD and SAVE use them. ; !ifdef CONFIG_ARNITECH_CONTROLLER { ; PacketPage addresses, all but the Product ID's in page $01 CS_PRODUCT_ID = $630E ; at $0000, low byte first CS_RX_CFG = $02 ; bit 6 Skip_1 CS_RX_CTL = $04 CS_LINE_CTL = $12 CS_SELF_CTL = $14 ; bit 6 RESET CS_RX_EVENT = $24 ; bit 8 RxOK CS_SELF_ST = $36 ; bit 7 INITD CS_BUS_ST = $38 ; bit 7 TxBidErr, bit 8 Rdy4TxNOW CS_IA = $58 ; Individual Address, $0158-$015D CS_RX_CTL_VALUE = $0D05 ; RxOKA, IndividualA, BroadcastA CS_LINE_VALUE = $00D3 ; SerRxON, SerTxON CS_TX_AFTER_ALL = $C0 ; TxCMD: start once the whole frame is in the chip NET_NONE_WAITING = $00 NET_NO_CARD = $01 NET_NO_ROOM = $02 NET_LENGTH_REFUSED = $03 NET_TOO_LONG = $04 ; ; NET_INIT, $FF0C: see ff00.arnitech_jumptable.s ; arnitech_net_init: jsr arnitech_net_probe bcs @2 lda #CS_SELF_CTL jsr arnitech_net_point lda #$40 ; RESET, which points the PacketPage pointer at $0000 sta RRNET_PP_DATA lda #CS_SELF_ST jsr arnitech_net_point @1: lda RRNET_PP_DATA bpl @1 ; until INITD +phy_trash_a lda #CS_RX_CTL ldx #CS_RX_CTL_VALUE jsr arnitech_net_write lda #CS_LINE_CTL ldx #CS_LINE_VALUE jsr arnitech_net_write +ply_trash_a clc @2: rts ; ; NET_MAC, $FF0F: see ff00.arnitech_jumptable.s ; arnitech_net_mac: stx SAL+0 sty SAL+1 jsr arnitech_net_probe bcs @2 ldy #$00 @1: tya ora #CS_IA ; $58, $5A, $5C jsr arnitech_net_point lda RRNET_PP_DATA+0 sta (SAL), y iny lda RRNET_PP_DATA+1 sta (SAL), y iny cpy #$06 bne @1 clc @2: rts ; ; NET_SEND, $FF12: see ff00.arnitech_jumptable.s ; arnitech_net_send: jsr arnitech_net_args lda #NET_NO_CARD bcs arnitech_net_done lda #CS_TX_AFTER_ALL ; TxCMD, which the high byte's write gives the chip sta RRNET_TX_CMD+0 lda #$00 sta RRNET_TX_CMD+1 lda EAL+0 ; TxLength: the bid, at the high byte's write sta RRNET_TX_LENGTH+0 lda EAL+1 sta RRNET_TX_LENGTH+1 lda #CS_BUS_ST jsr arnitech_net_point lda RRNET_PP_DATA+0 bmi @1 ; TxBidErr lda RRNET_PP_DATA+1 lsr ; Rdy4TxNOW into carry lda #NET_NO_ROOM bcc arnitech_net_fail clv ; memory to chip jmp arnitech_net_copy ; carry clear @1: lda #NET_LENGTH_REFUSED ; FALLTROUGH arnitech_net_fail: sec ; FALLTROUGH arnitech_net_done: rts ; ; NET_RECV, $FF15: see ff00.arnitech_jumptable.s ; arnitech_net_recv: jsr arnitech_net_args lda #NET_NO_CARD bcs arnitech_net_done lda #CS_RX_EVENT jsr arnitech_net_point lda RRNET_PP_DATA+1 ; reading the event clears it lsr ; RxOK into carry lda #NET_NONE_WAITING bcc arnitech_net_fail lda RRNET_RX_TX_DATA+1 ; RxStatus, high byte first, not needed lda RRNET_RX_TX_DATA+0 ldx RRNET_RX_TX_DATA+1 ; RxLength, high byte first lda RRNET_RX_TX_DATA+0 cpx EAL+1 bne @1 cmp EAL+0 beq @2 @1: bcs @3 ; longer than the buffer @2: sta EAL+0 stx EAL+1 pha txa pha bit arnitech_net_copy_end ; an RTS, $60: sets V, chip to memory jsr arnitech_net_copy pla tay pla tax clc rts @3: lda #CS_RX_CFG jsr arnitech_net_point lda RRNET_PP_DATA+0 ora #$40 ; Skip_1: the frame is dropped sta RRNET_PP_DATA+0 lda #NET_TOO_LONG bne arnitech_net_fail ; branch always ; ; The pointer from the zero page address in A into SAL, the length in X/Y into EAL, and the ; chip probed. Out: carry clear if it answers. ; arnitech_net_args: stx EAL+0 sty EAL+1 tax lda $00, x sta SAL+0 lda $01, x sta SAL+1 ; FALLTROUGH ; ; Whether the chip answers: its Product ID at PacketPage $0000. Out: carry clear if it does. ; X and Y are kept. ; arnitech_net_probe: lda #$00 sta RRNET_PP_POINTER+0 sta RRNET_PP_POINTER+1 lda RRNET_PP_DATA+0 cmp #CS_PRODUCT_ID bne @1 clc rts @1: sec rts ; ; PacketPage register $01xx, xx in A, written with X (low byte) and Y (high byte) ; arnitech_net_write: jsr arnitech_net_point stx RRNET_PP_DATA+0 sty RRNET_PP_DATA+1 rts ; ; The PacketPage pointer at $01xx, xx in A. X and Y are kept. ; arnitech_net_point: sta RRNET_PP_POINTER+0 lda #$01 sta RRNET_PP_POINTER+1 rts ; ; EAL bytes between the chip's receive and transmit data port and SAL: from the chip with V ; set, to it with V clear. Even bytes go through the port's low byte, odd ones through its ; high byte. Out: carry clear. ; arnitech_net_copy: ldy #$00 @1: lda EAL+0 ora EAL+1 beq @4 tya and #$01 tax bvs @2 lda (SAL), y cpx #$01 ; plain stores: an indexed one reads the port beq @7 ; first, which takes a byte of a received frame sta RRNET_RX_TX_DATA+0 bvc @3 ; branch always @7: sta RRNET_RX_TX_DATA+1 bvc @3 ; branch always @2: lda RRNET_RX_TX_DATA, x sta (SAL), y @3: iny bne @5 inc SAL+1 @5: lda EAL+0 bne @6 dec EAL+1 @6: dec EAL+0 jmp @1 @4: clc arnitech_net_copy_end: rts }