first pass at xmodem send - partially working

git-svn-id: http://svn.code.sf.net/p/netboot65/code@230 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
jonnosan 2009-12-20 11:14:43 +00:00
parent 406f66d648
commit b8f64a4a0b
2 changed files with 228 additions and 45 deletions

View File

@ -17,6 +17,7 @@ NAK = $15
CAN = $18
.export xmodem_receive
.export xmodem_send
.export xmodem_iac_escape ;are IAC bytes ($FF) escaped?
@ -40,6 +41,9 @@ CAN = $18
got_byte:
jmp $ffff
get_byte:
jmp $ffff
next_char:
lda buffer_length
bne @not_eof
@ -63,9 +67,23 @@ next_char:
sbc #0
sta buffer_length+1
pla
clc
clc
rts
emit_a:
emit_a_ptr=*+1
sta $ffff
inc emit_a_ptr
bne :+
inc emit_a_ptr+1
:
inc xmodem_block_buffer_length
bne :+
inc xmodem_block_buffer_length+1
:
rts
.bss
original_tcp_callback: .res 2
@ -74,16 +92,110 @@ getc_timeout_seconds: .res 1
buffer_length: .res 2
.code
xmodem_receive:
;recieve a file via XMODEM (checksum mode only, not CRC)
;assumes that a tcp connection has already been set up, and that the other end is waiting to start sending
;inputs: AX points to routine to call once for each byte in downloaded file (e.g. save to disk, print to screen, whatever) - byte will be in A
xmodem_send:
;send a file via XMODEM (checksum mode only, not CRC)
;assumes that a tcp connection has already been set up, and that the other end is waiting to start receiving
;inputs: AX points to routine to call once for each byte in file to send (e.g. save to disk, print to screen, whatever) - byte will be in A, carry flag set means EOF
; xmodem_iac_escape should be set to non-zero if the remote end escapes $FF bytes (i.e. if it is a real telnet server)
;outputs: none
stax get_byte+1
jsr xmodem_transfer_setup
@send_block:
ldax #sending
jsr print_ascii_as_native
ldax #block_number_msg
jsr print_ascii_as_native
lda expected_block_number
jsr print_hex
jsr print_cr
@wait_for_ack_or_nak:
lda #XMODEM_TIMEOUT_SECONDS
jsr getc
bcs @synch_error
cmp #ACK
beq @got_ack
cmp #NAK
beq @got_nak
@synch_error:
pha
lda user_abort
beq @no_user_abort
jmp xmodem_transfer_exit
@no_user_abort:
lda #'('
jsr print_a
pla
jsr print_hex
lda #')'
jsr print_a
inc error_number
ldax #sync_error_msg
jsr print_ascii_as_native
ldax #error_count_msg
jsr print_ascii_as_native
lda error_number
jsr print_hex
jsr print_cr
lda error_number
cmp #XMODEM_MAX_ERRORS
bcc @wait_for_ack_or_nak
lda #KPR_ERROR_TOO_MANY_ERRORS
sta ip65_error
jmp xmodem_transfer_exit
@got_ack:
inc expected_block_number
@got_nak:
lda #0
sta checksum
sta xmodem_block_buffer_length
sta xmodem_block_buffer_length+1
ldax #xmodem_block_buffer
stax emit_a_ptr
lda #SOH
jsr emit_a
lda expected_block_number
jsr emit_a
eor #$ff
jsr emit_a
lda #$80
sta block_ptr
@copy_one_byte:
lda #$1; FIX ME
pha
clc
adc checksum
sta checksum
pla
jsr emit_a
dec block_ptr
bne @copy_one_byte
lda checksum
jsr emit_a
ldax xmodem_block_buffer_length
stax tcp_send_data_len
ldax #xmodem_block_buffer
jsr tcp_send
jmp @send_block
rts
stax got_byte+1
xmodem_transfer_setup:
lda #0
sta buffer_length
sta buffer_length+1
@ -95,8 +207,20 @@ xmodem_receive:
ldax tcp_callback
stax original_tcp_callback
ldax #xmodem_receive_callback
ldax #xmodem_tcp_callback
stax tcp_callback
rts
xmodem_receive:
;recieve a file via XMODEM (checksum mode only, not CRC)
;assumes that a tcp connection has already been set up, and that the other end is waiting to start sending
;inputs: AX points to routine to call once for each byte in downloaded file (e.g. save to disk, print to screen, whatever) - byte will be in A
; xmodem_iac_escape should be set to non-zero if the remote end escapes $FF bytes (i.e. if it is a real telnet server)
;outputs: none
stax got_byte+1
jsr xmodem_transfer_setup
jsr send_nak
@ -119,12 +243,14 @@ xmodem_receive:
bcc @got_block_start
lda user_abort
beq @no_user_abort
jmp @exit
jmp xmodem_transfer_exit
@no_user_abort:
jsr send_nak
inc error_number
ldax #timeout_msg
jsr print_ascii_as_native
ldax #error_count_msg
jsr print_ascii_as_native
lda error_number
jsr print_hex
jsr print_cr
@ -133,13 +259,13 @@ xmodem_receive:
bcc @wait_for_block_start
lda #KPR_ERROR_TOO_MANY_ERRORS
sta ip65_error
jmp @exit
jmp xmodem_transfer_exit
@got_block_start:
cmp #EOT
bne :+
jsr send_ack
clc
jmp @exit
jmp xmodem_transfer_exit
:
cmp #SOH
bne @wait_for_block_start
@ -176,7 +302,7 @@ xmodem_receive:
lda #XMODEM_TIMEOUT_SECONDS
jsr getc
bcc :+
jmp @exit
jmp xmodem_transfer_exit
:
ldx block_ptr
sta xmodem_block_buffer,x
@ -189,6 +315,7 @@ xmodem_receive:
ldax #checksum_msg
jsr print_ascii_as_native
lda checksum
jsr print_hex
@ -197,7 +324,7 @@ xmodem_receive:
lda #XMODEM_TIMEOUT_SECONDS
jsr getc
bcs @exit
bcs xmodem_transfer_exit
sta received_checksum
jsr print_hex
jsr print_cr
@ -209,6 +336,8 @@ xmodem_receive:
inc error_number
ldax #checksum_error_msg
jsr print_ascii_as_native
ldax #error_count_msg
jsr print_ascii_as_native
lda error_number
jsr print_hex
jsr print_cr
@ -219,7 +348,7 @@ xmodem_receive:
:
lda #KPR_ERROR_TOO_MANY_ERRORS
sta ip65_error
jmp @exit
jmp xmodem_transfer_exit
jsr send_nak
jmp @next_block
@ -247,13 +376,14 @@ xmodem_receive:
jmp @next_block
clc
@exit:
xmodem_transfer_exit:
ldax original_tcp_callback
stax tcp_callback
rts
xmodem_receive_callback:
xmodem_tcp_callback:
lda tcp_inbound_data_length+1
cmp #$ff
bne @not_eof
@ -268,8 +398,8 @@ xmodem_receive_callback:
ldax tcp_inbound_data_length
stax buffer_length
jmp copymem
jsr copymem
rts
send_nak:
ldax #1
@ -331,6 +461,7 @@ getc:
lda $dc09 ;time of day clock: seconds
cmp getc_timeout_end
bne @poll_loop
lda #00
sec
rts
@ -343,14 +474,18 @@ getc:
block_number_msg: .byte " block $",0
expecting: .byte "expecting",0
receiving: .byte "receiving",0
sending: .byte "sending",0
bad_block_number: .byte "bad block number",0
checksum_msg: .byte "checksum $",0
checksum_error_msg : .byte "checksum error - error count $",0
timeout_msg: .byte "timeout error - error count $",0
checksum_error_msg : .byte "checksum",0
timeout_msg: .byte "timeout error",0
sync_error_msg: .byte "sync",0
error_count_msg: .byte " error - error count $",0
.segment "APP_SCRATCH"
xmodem_stream_buffer: .res 1600
xmodem_block_buffer: .res 128
xmodem_block_buffer: .res 300
xmodem_block_buffer_length: .res 2
expected_block_number: .res 1
actual_block_number: .res 1
checksum: .res 1

View File

@ -16,6 +16,7 @@
.import tcp_inbound_data_ptr
.import tcp_inbound_data_length
.import xmodem_send
.import xmodem_receive
.import xmodem_iac_escape
@ -74,8 +75,6 @@ init:
jsr print_ascii_as_native
jsr print_cr
lda #'1'
jsr print_a
;connect to port 1000 - xmodem server
@ -91,21 +90,56 @@ init:
ldax #1000
jsr tcp_connect
bcs @error
lda #'2'
jsr print_a
bcc :+
jmp check_for_error
:
ldax #first_message
jsr tcp_send_string
:
jsr ip65_process
lda packet_count
beq :-
ldax #connected
jsr print_ascii_as_native
jsr download_file
jsr check_for_error
jsr upload_file
jsr check_for_error
jsr tcp_close
rts
upload_file:
ldax #uploading
jsr print_ascii_as_native
lda #'3'
jsr print_a
ldax #start_upload
jsr tcp_send_string
bcc :+
@error:
jsr check_for_error
:
jsr open_upload_file
bcc :+
jmp check_for_error
:
ldax #read_byte
jsr xmodem_send
jsr close_file
rts
read_byte:
.byte $92
download_file:
ldax #downloading
jsr print_ascii_as_native
ldax #start_download
jsr tcp_send_string
@ -114,8 +148,7 @@ init:
jsr check_for_error
:
jsr open_file
jsr open_download_file
bcc :+
jmp check_for_error
:
@ -123,11 +156,7 @@ init:
jsr xmodem_receive
jsr close_file
jsr tcp_close
lda #'4'
jsr print_a
rts
@ -160,11 +189,19 @@ check_for_error:
jsr print_cr
rts
open_file:
lda #fname_end-fname
ldx #<fname
ldy #>fname
open_upload_file:
lda #upload_filename_end-upload_filename
ldx #<upload_filename
ldy #>upload_filename
jmp open_file
open_download_file:
lda #download_filename_end-download_filename
ldx #<download_filename
ldy #>download_filename
open_file:
jsr $FFBD ; call SETNAM
lda #$02 ; file number 2
ldx $BA ; last used device number
@ -220,16 +257,27 @@ close_file:
starting:
.byte "saving to "
fname: .byte "@0:XMODEM.TMP,P,W" ; @0: means 'overwrite if existing', ',P,W' is required to make this an output file
fname_end:
download_filename: .byte "@0:XMODEM.TMP,P,W" ; @0: means 'overwrite if existing', ',P,W' is required to make this an output file
download_filename_end:
.byte 0
first_message:
.byte "yo!",0
upload_filename: .byte "XMODEM.TMP"
upload_filename_end:
.byte 0
start_download:
.byte "B",0 ;b=Binary, i.e. trigger IAC escape, R=receive text, i.e. no IAC escape
.byte "B",0 ;B=Binary, i.e. trigger IAC escape, R=receive text, i.e. no IAC escape
.data
start_upload:
.byte "S",0 ;S send via normal checksum mode (not CRC)
.data
uploading: .byte "uploading",10,0
downloading: .byte "downloading",10,0
connected: .byte "connected",10,0
tcp_dest_ip:
.byte 10,5,1,102
; .byte 192,168,160,1