WIP: modified version of echo server that reads in page-sized chunks

This commit is contained in:
kris 2019-01-03 23:25:58 +00:00
parent c797852324
commit 84611ad5e3

418
ethernet/ethernet/main.s Normal file
View File

@ -0,0 +1,418 @@
;
; main.s
; ethernet
;
; Created by Kris Kennaway on 03/01/2019.
; Copyright © 2019 Kris Kennaway. All rights reserved.
;
.include "apple2.inc"
.org $8000
.proc main
; TCP SOCKET DEMO FOR W5100/UTHERNET II
; BY D. FINNIGAN
; OCTOBER 2015
;
; UPDATED 09 JAN 2016 6*
; UPDATED 13 FEB 2017, C. TORRENCE
; -REMOVED SEPARATE PATH FOR WRAP, ADD DEBUG PRINT
; SLOT 1 I/O ADDRESSES FOR THE W5100
WMODE = $C094
WADRH = $C095
WADRL = $C096
WDATA = $C097
; W5100 LOCATIONS
MACADDR = $0009 ; MAC ADDRESS
SRCIP = $000F ; SOURCE IP ADDRESS
RMSR = $001A ; RECEIVE BUFFER SIZE
; SOCKET 0 LOCATIONS
S0MR = $0400 ; SOCKET 0 MODE REGISTER
S0CR = $0401 ; COMMAND REGISTER
S0IR = $0402 ; INTERRUPT REGISTER
S0SR = $0403 ; STATUS REGISTER
S0LOCALPORT = $0404 ; LOCAL PORT
S0FORADDR = $040C ; FOREIGN ADDRESS
S0FORPORT = $0410 ; FOREIGN PORT
S0MSS = $0412 ; MAX SEGMENT SIZE
S0PROTO = $0414 ; IP PROTOCOL
S0TOS = $0415 ; DS/ECN (FORMER TOS)
S0TTL = $0416 ; IP TIME TO LIVE
S0TXFSR = $0420 ; TX FREE SIZE REGISTER
S0TXRR = $0422 ; TX READ POINTER REGISTER
S0TXWR = $0424 ; TX WRITE POINTER REGISTER
S0RXRSR = $0426 ; RX RECEIVED SIZE REGISTER
S0RXRD = $0428 ; RX READ POINTER REGISTER
; SOCKET 0 PARAMETERS
RXBASE = $6000 ; SOCKET 0 RX BASE ADDR
RXMASK = $1FFF ; SOCKET 0 8KB ADDRESS MASK
TXBASE = $4000 ; SOCKET 0 TX BASE ADDR
TXMASK = RXMASK ; SOCKET 0 TX MASK
; SOCKET COMMANDS
SCOPEN = $01 ; OPEN
SCLISTEN = $02 ; LISTEN
SCCONNECT = $04 ; CONNECT
SCDISCON = $08 ; DISCONNECT
SCCLOSE = $10 ; CLOSE
SCSEND = $20 ; SEND
SCSENDMAC = $21 ; SEND MAC
SCSENDKEEP = $22 ; SEND KEEP ALIVE
SCRECV = $40 ; RECV
; SOCKET STATUS
STCLOSED = $00
STINIT = $13
STLISTEN = $14
STESTABLISHED = $17
STCLOSEWAIT = $1C
STUDP = $22
STIPRAW = $32
STMAXRAW = $42
STPPOE = $5F
; MONITOR SUBROUTINES
KBD = $C000
KBDSTRB = $C010
COUT = $FDED
PRBYTE = $FDDA
PRNTAX = $F941
; ZERO-PAGE STORAGE
PTR = $06 ; 2 BYTES FOR APPLE BUFFER
GETSIZE = $08 ; 2 BYTES FOR RX_RSR
GETOFFSET = $0A ; 2 BYTES FOR OFFSET ADDR
GETSTARTADR = $0C ; 2 BYTES FOR PHYSICAL ADDR
; RESET AND CONFIGURE W5100
LDA #6 ; 5 RETRIES TO GET CONNECTION
STA PTR ; NUMBER OF RETRIES
BPL RESET ; ALWAYS TAKEN
SRCADDR: .byte $C0,$A8,$01,147 ; 192.168.2.5 W5100 IP
FADDR: .byte $C0,$A8,$01,15 ; 192.168.2.1 FOREIGN IP
FPORT: .byte $4E,$20 ; 20000 FOREIGN PORT
MAC: .byte $00,$08,$DC,$01,$02,$03 ; W5100 MAC ADDRESS
RESET:
LDA #$80 ; reset
STA WMODE
LDA #3 ; CONFIGURE WITH AUTO-INCREMENT
STA WMODE
; ASSIGN MAC ADDRESS
LDA #>MACADDR
STA WADRH
LDA #<MACADDR
STA WADRL
LDX #0
@L1:
LDA MAC,X
STA WDATA ; USING AUTO-INCREMENT
INX
CPX #6 ;COMPLETED?
BNE @L1
; ASSIGN A SOURCE IP ADDRESS
LDA #<SRCIP
STA WADRL
LDX #0
@L2:
LDA SRCADDR,X
STA WDATA
INX
CPX #4
BNE @L2
;CONFIGURE BUFFER SIZES
LDA #<RMSR
STA WADRL
LDA #3 ; 8KB TO SOCKET 0
STA WDATA ; SET RECEIVE BUFFER
STA WDATA ; SET TRANSMIT BUFFER
; CONFIGRE SOCKET 0 FOR TCP
LDA #>S0MR
STA WADRH
LDA #<S0MR
STA WADRL
LDA #1 ; TCP MODE
STA WDATA
; SET LOCAL PORT NUMBER
LDA #<S0LOCALPORT
STA WADRL
LDA #$C0 ; HIGH BYTE OF LOCAL PORT
STA WDATA
LDA #0 ; LOW BYTE
STA WDATA
; SET FOREIGN ADDRESS
LDA #<S0FORADDR
STA WADRL
LDX #0
@L3:
LDA FADDR,X
STA WDATA
INX
CPX #4
BNE @L3
; SET FOREIGN PORT
LDA FPORT ; HIGH BYTE OF FOREIGN PORT
STA WDATA ; ADDR PTR IS AT FOREIGN PORT
LDA FPORT+1 ; LOW BYTE OF PORT
STA WDATA
; OPEN SOCKET
LDA #<S0CR
STA WADRL
LDA #SCOPEN ;OPEN COMMAND
STA WDATA
; CHECK STATUS REGISTER TO SEE IF SUCCEEDED
LDA #<S0SR
STA WADRL
LDA WDATA
CMP #STINIT ; IS IT SOCK_INIT?
BEQ OPENED
LDY #0
@L4:
LDA @SOCKERR,Y
BEQ @LDONE
JSR COUT
INY
BNE @L4
@LDONE: BRK
@SOCKERR: .byte $d5,$d4,$c8,$c5,$d2,$ce,$c5,$d4,$a0,$c9,$c9,$ba,$a0,$c3,$cf,$d5,$cc,$c4,$a0,$ce,$cf,$d4,$a0,$cf,$d0,$c5,$ce,$a0,$d3,$cf,$c3,$cb,$c5,$d4,$a1
; "UTHERNET II: COULD NOT OPEN SOCKET!"
.byte $8D,$00 ; cr+null
; TCP SOCKET WAITING FOR NEXT COMMAND
OPENED:
LDA #<S0CR
STA WADRL
LDA #SCCONNECT
STA WDATA
; WAIT FOR TCP TO CONNECT AND BECOME ESTABLISHED
CHECKTEST:
LDA #<S0SR
STA WADRL
LDA WDATA ; GET SOCKET STATUS
BEQ FAILED ; 0 = SOCKET CLOSED, ERROR
CMP #STESTABLISHED
BEQ SETUP ; SUCCESS
BNE CHECKTEST
FAILED:
DEC PTR
BEQ ERRDONE ; TOO MANY FAILURES
LDA #$AE ; "."
JSR COUT
JMP RESET ; TRY AGAIN
ERRDONE:
LDY #0
@L:
LDA ERRMSG,Y
BEQ @DONE
JSR COUT
INY
BNE @L
@DONE: BRK
ERRMSG: .byte $d3,$cf,$c3,$cb,$c5,$d4,$a0,$c3,$cf,$d5,$cc,$c4,$a0,$ce,$cf,$d4,$a0,$c3,$cf,$ce,$ce,$c5,$c3,$d4,$a0,$ad,$a0,$c3,$c8,$c5,$c3,$cb,$a0,$d2,$c5,$cd,$cf,$d4,$c5,$a0,$c8,$cf,$d3,$d4
; "SOCKET COULD NOT CONNECT - CHECK REMOTE HOST"
.byte $8D,$00
SETUP:
; CALCULATE OFFSET ADDRESS USING READ POINTER AND RX MASK
LDA #<S0RXRD
STA WADRL
LDA WDATA ; HIGH BYTE
AND #>RXMASK
STA GETOFFSET+1
LDA WDATA ; LOW BYTE
AND #<RXMASK
STA GETOFFSET
;JSR DEBUG
;RTS
; CHECK FOR ANY RECEIVED DATA
CHECKRECV:
BIT KBD ; KEYPRESS?
BPL @NEXT
LDA KBDSTRB
JMP CLOSECONN ; CLOSE CONNECTION
@NEXT:
LDA #<S0RXRSR ; S0 RECEIVED SIZE REGISTER
STA WADRL
LDA WDATA ; HIGH BYTE OF RECEIVED SIZE
ORA WDATA ; LOW BYTE
BEQ NORECV ; NO DATA TO READ
JMP RECV ; THERE IS DATA
NORECV:
NOP ; LITTLE DELAY ...
NOP
JMP CHECKRECV ; CHECK AGAIN
; THERE IS DATA TO READ - COMPUTE THE PHYSICAL ADDRESS
RECV:
LDA #<S0RXRSR ; GET RECEIVED SIZE AGAIN
STA WADRL
LDA WDATA
;JSR $FDDA
beq CHECKRECV ; expected >=1 page
LDA WDATA ; XXX: do I have to read it? DOn't think so
; We know there is at least a page in the buffer, so read it
; CALCULATE PHYSICAL ADDRESS WITHIN W5100 RX BUFFER
CLC
LDA GETOFFSET
ADC #<RXBASE
STA GETSTARTADR
LDA GETOFFSET+1
ADC #>RXBASE
STA GETSTARTADR+1
; SET BUFFER ADDRESS ON W5100
JSR DEBUG ; UNCOMMENT FOR W5100 DEBUG INFO
LDA GETSTARTADR+1 ; HIGH BYTE FIRST
STA WADRH
LDA GETSTARTADR
STA WADRL
; SET BUFFER ADDRESS ON APPLE
; XXX can hoist this out of the loop and let the low byte wrap
LDA #0 ; LOW BYTE OF BUFFER
STA PTR
LDA #$50 ; HIGH BYTE
STA PTR+1
; BEGIN COPY
LDY #$00
@L:
LDA WDATA
STA (PTR),Y
JSR CLEANOUT ; DEBUG PRINT
INY
BNE @L
LDA #$8D ; <CR>
JSR COUT ; DEBUG PRINT
; UPDATE REXRD TO REFLECT DATA WE JUST READ
UPDATERXRD:
CLC
LDA #>S0RXRD ; NEED HIGH BYTE HERE
STA WADRH ; XXX needed? I think this is already set
LDA #<S0RXRD
STA WADRL
LDA WDATA ; HIGH BYTE
TAY ; SAVE
LDA WDATA ; LOW BYTE ; needed? I don't think so
INY
LDA #<S0RXRD
STA WADRL ; XXX already there?
; INC WDATA ; Does this work? If it accesses twice it will auto-inc
STY WDATA ; SEND HIGH BYTE
; ADC GETSIZE ; ADD LOW BYTE OF RECEIVED SIZE
; TAX ; SAVE
; TYA ; GET HIGH BYTE BACK
; ADC GETSIZE+1 ; ADD HIGH BYTE OF RECEIVED SIE
; TAY ; SAVE
; LDA #<S0RXRD
; STA WADRL
; STY WDATA ; SEND HIGH BYTE
; STX WDATA ; SEND LOW BYTE
; SEND THE RECV COMMAND
LDA #<S0CR
STA WADRL
LDA #SCRECV
STA WDATA
JMP CHECKRECV
; CLOSE TCP CONNECTION
CLOSECONN:
LDA #>S0CR ; HIGH BYTE NEEDED
STA WADRH
LDA #<S0CR
STA WADRL
LDA #SCDISCON ; DISCONNECT
STA WDATA ; SEND COMMAND
; CHECK FOR CLOSED STATUS
CHECKCLOSED:
LDX #0
@L:
LDA #<S0SR
STA WADRL
LDA WDATA
BEQ ISCLOSED
NOP
NOP
NOP
INX
BNE @L ; DON'T WAIT FOREVER
ISCLOSED:
RTS ; SOCKET IS CLOSED
; SUPPORT SUBROUTINE: CLEANOUT
; "CLEANS UP" OUTPUT FOR THE APPLE BY
; SETTING THE HIGH BIT AND DOING SOME SUBSTITUTIONS
CLEANOUT:
ORA #%10000000 ; SET HIGH BIT
CMP #$8A ; NEWLINE?
BNE @OUT
LDA #$8D ; CONVERT TO <CR>
@OUT:
JMP COUT ; THIS WILL DO THE RTS
; DEBUG - PRINT W5100 STARTADR AND SIZE
DEBUG:
LDA #$A0 ; " "
JSR COUT
LDA #$A4 ; "$"
JSR COUT
LDA GETSTARTADR+1
LDX GETSTARTADR
JSR PRNTAX
; LDA #$A0 ; " "
; JSR COUT
; LDA #$A4 ; "$"
; JSR COUT
; LDA GETSIZE+1
; LDX GETSIZE
; JSR PRNTAX
LDA #$8D
JMP COUT ; THIS WILL DO THE RTS
.endproc