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_FILE_ACCESS_FAILURE EQU $90
NB65_MALFORMED_URL EQU $A0
NB65_DNS_LOOKUP_FAILED EQU $A1
NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE
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
ip65_random_word:
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
adc ip65_ctr_arp
ora #$08 ;make sure we grab at least 8 bytes from eth_inp

View File

@ -1,6 +1,4 @@
;text file parsing routines
; first call parser_init
; then call parser_skip_next
.export parse_integer
.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_send_data_len
.export tcp_send
.export tcp_send_string
.export tcp_close
.export tcp_listen
@ -368,6 +369,33 @@ tcp_close:
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:
;send tcp data
;inputs:
@ -378,6 +406,7 @@ tcp_send:
; carry flag is set if an error occured, clear otherwise
stax tcp_send_data_ptr
lda tcp_state
cmp #tcp_cxn_state_established
beq @connection_established
@ -646,8 +675,19 @@ tcp_process:
bit tcp_inp+tcp_flags_field
beq @not_reset
jsr check_current_connection
bcs @not_current_connection_on_rst
;connection has been reset so mark it as closed
bcs @not_current_connection_on_rst
;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
sta tcp_state
lda #NB65_ERROR_CONNECTION_RESET_BY_PEER

View File

@ -11,18 +11,34 @@
.import output_buffer
.importzp copy_src
.importzp copy_dest
.import copymem
.import ip65_error
.import ip65_process
.import parser_init
.import parser_skip_next
.import dns_set_hostname
.import dns_resolve
.import parse_integer
.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_port
.export url_selector
.export url_resource_type
.export url_parse
.export url_download
.export url_download_buffer
.export url_download_buffer_length
target_string=copy_src
search_string=copy_dest
@ -41,6 +57,16 @@ selector_buffer=output_buffer
src_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
@ -102,7 +128,11 @@ lda #url_type_gopher
jsr dns_set_hostname
bcs @exit_with_sec
jsr dns_resolve
bcs @exit_with_sec
bcc :+
lda #NB65_DNS_LOOKUP_FAILED
sta ip65_error
jmp @exit_with_sec
:
;copy IP address
ldx #3
:
@ -138,19 +168,23 @@ lda #url_type_gopher
;first byte after / in a gopher url is the resource type
ldy src_ptr
lda (copy_src),y
beq @start_of_selector
sta url_resource_type
inc src_ptr
jmp @start_of_selector
@not_gopher:
cmp #url_type_http
bne @done ; if it's not gopher or http, we don't know how to build a selector
ldy #3
beq @build_http_request
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
:
lda get,y
sta (copy_dest),y
dey
bpl :-
@start_of_selector:
lda #'/'
inc dest_ptr
@ -166,6 +200,55 @@ lda #url_type_gopher
inc dest_ptr
bne @copy_one_byte
@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
lda #$0d
sta (copy_dest),y
@ -173,11 +256,16 @@ lda #url_type_gopher
lda #$0a
sta (copy_dest),y
iny
dex
bne @final_crlf
@done:
lda #$00
sta (copy_dest),y
ldax #selector_buffer
stax url_selector
clc
rts
skip_to_hostname:
@ -186,7 +274,135 @@ skip_to_hostname:
ldax #colon_slash_slash
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_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 ":/"
slash: .byte "/",0
colon: .byte ":",0
colon: .byte ":",0

View File

@ -31,6 +31,7 @@ all: \
testdottedquad.prg\
test_tcp.prg \
test_parser.prg \
test_get_url.prg \
%.o: %.c
$(CC) -c $(CFLAGS) $<
@ -44,6 +45,11 @@ all: \
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)
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
$(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
atom_file:
.incbin "atom_test.xml"
;.incbin "atom_test.xml"
.byte 0