git-svn-id: http://svn.code.sf.net/p/netboot65/code@177 93682198-c243-4bdb-bd91-e943c89aac3b

This commit is contained in:
jonnosan 2009-08-17 04:23:05 +00:00
parent 2760650688
commit 0a2982105b
7 changed files with 272 additions and 10 deletions

View File

@ -124,5 +124,6 @@ NB65_ERROR_CONNECTION_RESET_BY_PEER EQU $89
NB65_ERROR_CONNECTION_CLOSED EQU $8A NB65_ERROR_CONNECTION_CLOSED EQU $8A
NB65_ERROR_FILE_ACCESS_FAILURE EQU $90 NB65_ERROR_FILE_ACCESS_FAILURE EQU $90
NB65_MALFORMED_URL EQU $A0 NB65_MALFORMED_URL EQU $A0
NB65_DNS_LOOKUP_FAILED EQU $A1
NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE
NB65_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF NB65_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF

View File

@ -52,7 +52,8 @@ ip65_error: .res 1 ;last error code
;outputs: AX set to a pseudo-random 16 bit number ;outputs: AX set to a pseudo-random 16 bit number
ip65_random_word: ip65_random_word:
jsr timer_read ;sets AX jsr timer_read ;sets AX
adc $d018 ;on a c64, this is the raster register ; adc $d018 ;on a c64, this is the raster register
adc $d41b; on a c64, this is a 'random' number from the SID
pha pha
adc ip65_ctr_arp adc ip65_ctr_arp
ora #$08 ;make sure we grab at least 8 bytes from eth_inp ora #$08 ;make sure we grab at least 8 bytes from eth_inp

View File

@ -1,6 +1,4 @@
;text file parsing routines ;text file parsing routines
; first call parser_init
; then call parser_skip_next
.export parse_integer .export parse_integer
.importzp copy_dest .importzp copy_dest

View File

@ -23,6 +23,7 @@ MAX_TCP_PACKETS_SENT=8 ;timeout after sending 8 messages will be about 7 sec
.export tcp_connect_ip .export tcp_connect_ip
.export tcp_send_data_len .export tcp_send_data_len
.export tcp_send .export tcp_send
.export tcp_send_string
.export tcp_close .export tcp_close
.export tcp_listen .export tcp_listen
@ -368,6 +369,33 @@ tcp_close:
rts rts
tcp_send_string:
;send a string over the current tcp connection
;inputs:
; tcp connection should already be opened
; AX: pointer to buffer - data up to (but not including)
; the first nul byte will be sent. max of 255 bytes will be sent.
;outputs:
; carry flag is set if an error occured, clear otherwise
stax tcp_send_data_ptr
stax copy_src
lda #0
tay
sta tcp_send_data_len
sta tcp_send_data_len+1
lda (copy_src),y
bne @find_end_of_string
rts ; if the string is empty, don't send anything!
@find_end_of_string:
lda (copy_src),y
beq @done
inc tcp_send_data_len
iny
bne @find_end_of_string
@done:
ldax tcp_send_data_ptr
;now we can fall through into tcp_send
tcp_send: tcp_send:
;send tcp data ;send tcp data
;inputs: ;inputs:
@ -378,6 +406,7 @@ tcp_send:
; carry flag is set if an error occured, clear otherwise ; carry flag is set if an error occured, clear otherwise
stax tcp_send_data_ptr stax tcp_send_data_ptr
lda tcp_state lda tcp_state
cmp #tcp_cxn_state_established cmp #tcp_cxn_state_established
beq @connection_established beq @connection_established
@ -646,8 +675,19 @@ tcp_process:
bit tcp_inp+tcp_flags_field bit tcp_inp+tcp_flags_field
beq @not_reset beq @not_reset
jsr check_current_connection jsr check_current_connection
bcs @not_current_connection_on_rst bcs @not_current_connection_on_rst
;connection has been reset so mark it as closed ;for some reason, search.twitter.com is sending RSTs with ID=$1234 (i.e. echoing the inbound ID)
;but then keeps the connection open and ends up sending the file.
;so lets ignore a reset with ID=$1234
lda ip_inp+ip_id
cmp #$34
bne @not_invalid_reset
lda ip_inp+ip_id+1
cmp #$12
bne @not_invalid_reset
jmp @send_ack
@not_invalid_reset:
;connection has been reset so mark it as closed
lda #tcp_cxn_state_closed lda #tcp_cxn_state_closed
sta tcp_state sta tcp_state
lda #NB65_ERROR_CONNECTION_RESET_BY_PEER lda #NB65_ERROR_CONNECTION_RESET_BY_PEER

View File

@ -11,18 +11,34 @@
.import output_buffer .import output_buffer
.importzp copy_src .importzp copy_src
.importzp copy_dest .importzp copy_dest
.import copymem
.import ip65_error .import ip65_error
.import ip65_process
.import parser_init .import parser_init
.import parser_skip_next .import parser_skip_next
.import dns_set_hostname .import dns_set_hostname
.import dns_resolve .import dns_resolve
.import parse_integer .import parse_integer
.import dns_ip .import dns_ip
.import tcp_connect
.import tcp_send_string
.import tcp_send_data_len
.import tcp_callback
.import tcp_close
.import tcp_connect_ip
.import tcp_inbound_data_length
.import tcp_inbound_data_ptr
.export url_ip .export url_ip
.export url_port .export url_port
.export url_selector .export url_selector
.export url_resource_type .export url_resource_type
.export url_parse .export url_parse
.export url_download
.export url_download_buffer
.export url_download_buffer_length
target_string=copy_src target_string=copy_src
search_string=copy_dest search_string=copy_dest
@ -41,6 +57,16 @@ selector_buffer=output_buffer
src_ptr: .res 1 src_ptr: .res 1
dest_ptr: .res 1 dest_ptr: .res 1
url_download_buffer: .res 2 ; points to a buffer that url will be downloaded into
url_download_buffer_length: .res 2 ;length of buffer that url will be downloaded into
temp_buffer: .res 2
temp_buffer_length: .res 2
download_flag: .res 1
.code .code
@ -102,7 +128,11 @@ lda #url_type_gopher
jsr dns_set_hostname jsr dns_set_hostname
bcs @exit_with_sec bcs @exit_with_sec
jsr dns_resolve jsr dns_resolve
bcs @exit_with_sec bcc :+
lda #NB65_DNS_LOOKUP_FAILED
sta ip65_error
jmp @exit_with_sec
:
;copy IP address ;copy IP address
ldx #3 ldx #3
: :
@ -138,19 +168,23 @@ lda #url_type_gopher
;first byte after / in a gopher url is the resource type ;first byte after / in a gopher url is the resource type
ldy src_ptr ldy src_ptr
lda (copy_src),y lda (copy_src),y
beq @start_of_selector
sta url_resource_type sta url_resource_type
inc src_ptr inc src_ptr
jmp @start_of_selector jmp @start_of_selector
@not_gopher: @not_gopher:
cmp #url_type_http cmp #url_type_http
bne @done ; if it's not gopher or http, we don't know how to build a selector beq @build_http_request
ldy #3 jmp @done ; if it's not gopher or http, we don't know how to build a selector
@build_http_request:
ldy #get_length-1
sty dest_ptr sty dest_ptr
: :
lda get,y lda get,y
sta (copy_dest),y sta (copy_dest),y
dey dey
bpl :- bpl :-
@start_of_selector: @start_of_selector:
lda #'/' lda #'/'
inc dest_ptr inc dest_ptr
@ -166,6 +200,55 @@ lda #url_type_gopher
inc dest_ptr inc dest_ptr
bne @copy_one_byte bne @copy_one_byte
@end_of_selector: @end_of_selector:
ldx #1 ;number of CRLF at end of gopher request
lda url_type
cmp #url_type_http
bne @final_crlf
;now the HTTP version number & Host: field
ldx #0
:
lda http_version_and_host,x
beq :+
ldy dest_ptr
inc dest_ptr
sta (copy_dest),y
inx
bne :-
:
;now copy the host field
jsr skip_to_hostname
;AX now pointing at hostname
stax copy_src
ldax #selector_buffer
stax copy_dest
lda #0
sta src_ptr
@copy_one_byte_of_hostname:
ldy src_ptr
lda (copy_src),y
beq @end_of_hostname
cmp #':'
beq @end_of_hostname
cmp #'/'
beq @end_of_hostname
inc src_ptr
ldy dest_ptr
sta (copy_dest),y
inc dest_ptr
bne @copy_one_byte_of_hostname
@end_of_hostname:
ldx #2 ;number of CRLF at end of HTTP request
@final_crlf:
ldy dest_ptr ldy dest_ptr
lda #$0d lda #$0d
sta (copy_dest),y sta (copy_dest),y
@ -173,11 +256,16 @@ lda #url_type_gopher
lda #$0a lda #$0a
sta (copy_dest),y sta (copy_dest),y
iny iny
dex
bne @final_crlf
@done: @done:
lda #$00 lda #$00
sta (copy_dest),y sta (copy_dest),y
ldax #selector_buffer ldax #selector_buffer
stax url_selector
clc clc
rts rts
skip_to_hostname: skip_to_hostname:
@ -186,7 +274,135 @@ skip_to_hostname:
ldax #colon_slash_slash ldax #colon_slash_slash
jmp parser_skip_next jmp parser_skip_next
.code
;download a resource specified by an URL
;inputs:
;AX = address of URL string
; url_download_buffer - points to a buffer that url will be downloaded into
; url_download_buffer_length - length of buffer
;outputs:
; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents
; of specified resource (with an extra 2 null bytes at the end),
; AX = length of resource downloaded.
url_download:
jsr url_parse
bcc @url_parsed_ok
rts
@url_parsed_ok:
ldax url_download_buffer
stax temp_buffer
ldax url_download_buffer_length
stax temp_buffer_length
ldx #3 ; save IP address just retrieved
: lda url_ip,x
sta tcp_connect_ip,x
dex
bpl :-
ldax #url_download_callback
stax tcp_callback
ldax url_port
jsr tcp_connect
bcs @error
;connected, now send the selector
ldx #0
stx download_flag
ldax url_selector
jsr tcp_send_string
;now loop until we're done
@download_loop:
jsr ip65_process
lda download_flag
beq @download_loop
jsr tcp_close
clc
@error:
rts
lda #NB65_ERROR_FILE_ACCESS_FAILURE
sta ip65_error
sec
rts
url_download_callback:
lda tcp_inbound_data_length+1
cmp #$ff
bne @not_end_of_file
@end_of_file:
lda #1
sta download_flag
;put a zero byte at the end of the file (in case it was a text file)
ldax temp_buffer
stax copy_dest
lda #0
tay
sta (copy_dest),y
rts
@not_end_of_file:
;copy this chunk to our input buffer
ldax temp_buffer
stax copy_dest
ldax tcp_inbound_data_ptr
stax copy_src
sec
lda temp_buffer_length
sbc tcp_inbound_data_length
pha
lda temp_buffer_length+1
sbc tcp_inbound_data_length+1
bcc @would_overflow_buffer
sta temp_buffer_length+1
pla
sta temp_buffer_length
ldax tcp_inbound_data_length
jsr copymem
;increment the pointer into the input buffer
clc
lda temp_buffer
adc tcp_inbound_data_length
sta temp_buffer
lda temp_buffer+1
adc tcp_inbound_data_length+1
sta temp_buffer+1
; lda #'*'
; jsr print_a
rts
@would_overflow_buffer:
pla ;clean up the stack
ldax temp_buffer_length
jsr copymem
lda temp_buffer
adc temp_buffer_length
sta temp_buffer
lda temp_buffer+1
adc temp_buffer_length+1
sta temp_buffer+1
lda #0
sta temp_buffer_length
sta temp_buffer_length+1
rts
.rodata
get: .byte "GET " get: .byte "GET "
get_length=4
http_version_and_host: .byte " HTTP/1.1",$0d,$0a, "Host: ",0
; http_trailer: .byte " HTTP/1.1",$0a,$0a
; http_trailer_end:
; http_trailer_length=http_trailer_end-http_trailer
colon_slash_slash: .byte ":/" colon_slash_slash: .byte ":/"
slash: .byte "/",0 slash: .byte "/",0
colon: .byte ":",0 colon: .byte ":",0

View File

@ -31,6 +31,7 @@ all: \
testdottedquad.prg\ testdottedquad.prg\
test_tcp.prg \ test_tcp.prg \
test_parser.prg \ test_parser.prg \
test_get_url.prg \
%.o: %.c %.o: %.c
$(CC) -c $(CFLAGS) $< $(CC) -c $(CFLAGS) $<
@ -44,6 +45,11 @@ all: \
test_tcp.prg: test_tcp.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg test_tcp.prg: test_tcp.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
$(LD) -m test_tcp.map -vm -C ../cfg/c64prg.cfg -o test_tcp.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) $(LD) -m test_tcp.map -vm -C ../cfg/c64prg.cfg -o test_tcp.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB)
test_parser.prg: test_parser.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
$(LD) -m test_parser.map -vm -C ../cfg/c64prg.cfg -o test_parser.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB)
test_get_url.prg: test_get_url.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
$(LD) -m test_get_url.map -vm -C ../cfg/c64prg.cfg -o test_get_url.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB)
%.pg2: %.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2bin.cfg %.pg2: %.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2bin.cfg
$(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB) $(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB)

View File

@ -209,7 +209,7 @@ selector: .asciiz "SELECTOR: "
press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0 press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
atom_file: atom_file:
.incbin "atom_test.xml" ;.incbin "atom_test.xml"
.byte 0 .byte 0