diff --git a/inc/ip65.h b/inc/ip65.h index e62b2e7..8022d24 100644 --- a/inc/ip65.h +++ b/inc/ip65.h @@ -234,10 +234,58 @@ bool tcp_send_keep_alive(void); // Query an SNTP server for current UTC time // // Inputs: SNTP server IP address -// Output: The number of seconds since 00:00 on Jan 1, 1900 (UTC) +// Output: The number of seconds since 00:00 on Jan 1 1900 (UTC), 0 on error // uint32_t __fastcall__ sntp_get_time(uint32_t server); +// Download a file from a TFTP server and provide data to user supplied vector. +// +// Inputs: server: IP address of server to receive file from +// name: Name of file to download +// callback: Vector to call once for each 512 byte packet received +// buf: Pointer to buffer containing data received +// len: 512 if buffer is full, otherwise number of bytes +// in the buffer +// Output: true if an error occured, false otherwise +// +bool __fastcall__ tftp_download(uint32_t server, const char* name, + void __fastcall__ (*callback)(const uint8_t* buf, + uint16_t len)); + +// Download a file from a TFTP server and provide data to specified memory location. +// +// Inputs: server: IP address of server to receive file from +// name: Name of file to download +// buf: Pointer to buffer containing data received +// Output: Length of data received, 0 on error +// +uint16_t __fastcall__ tftp_download_to_memory(uint32_t server, const char* name, + const uint8_t* buf); + +// Upload a file to a TFTP server with data retrieved from user supplied vector. +// +// Inputs: server: IP address of server to send file to +// name: Name of file to upload +// callback: Vector to call once for each 512 byte packet to be sent +// buf: Pointer to buffer containing data to be sent +// Output: 512 if buffer is full, otherwise number of bytes +// in the buffer +// Output: true if an error occured, false otherwise +// +bool __fastcall__ tftp_upload(uint32_t server, const char* name, + uint16_t __fastcall__ (*callback)(const uint8_t* buf)); + +// Upload a file to a TFTP server with data retrieved from specified memory location. +// +// Inputs: server: IP address of server to send file to +// name: Name of file to upload +// buf: Pointer to buffer containing data to be sent +// len: Length of data to be sent +// Output: true if an error occured, false otherwise +// +bool __fastcall__ tftp_upload_from_memory(uint32_t server, const char* name, + const uint8_t* buf, uint16_t len); + // Start an HTTP server // // This routine will stay in an endless loop that is broken only if user press the abort key. diff --git a/ip65/Makefile b/ip65/Makefile index b4353c6..c35a3b9 100644 --- a/ip65/Makefile +++ b/ip65/Makefile @@ -32,6 +32,7 @@ IP65OBJS=\ ip65_c.o \ tcp_c.o \ tftp.o \ + tftp_c.o \ timer.o \ timer_c.o \ output_buffer.o \ diff --git a/ip65/tftp.s b/ip65/tftp.s index 2ca4854..85d6215 100644 --- a/ip65/tftp.s +++ b/ip65/tftp.s @@ -13,6 +13,7 @@ TFTP_TIMER_MASK = $F8 ; mask lower two bits, means we wait for 8 x1/4 .export tftp_download .export tftp_upload .export tftp_data_block_length +.export tftp_current_memloc .export tftp_set_callback_vector .export tftp_callback_vector .export tftp_clear_callbacks @@ -125,7 +126,7 @@ tftp_upload: ; inputs: ; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast) ; tftp_filename: pointer to null terminated name of file to download -; tftp_load_address: memory location that dir will be stored in, or $0000 to +; tftp_load_address: memory location that data will be stored in, or $0000 to ; treat first 2 bytes received from tftp server as memory address that rest ; of file should be loaded into (e.g. if downloading a C64 'prg' file) ; outputs: carry flag is set if there was an error @@ -529,7 +530,8 @@ copy_ram_to_tftp_block: ; outputs: none tftp_set_callback_vector: stax tftp_callback_vector+1 - inc tftp_callback_address_set + lda #1 + sta tftp_callback_address_set rts ; clear callback vectors, i.e. all future transfers read from/write to RAM diff --git a/ip65/tftp_c.s b/ip65/tftp_c.s new file mode 100644 index 0000000..fa2119b --- /dev/null +++ b/ip65/tftp_c.s @@ -0,0 +1,109 @@ +.include "../inc/common.inc" + +.export _tftp_download +.export _tftp_download_to_memory +.export _tftp_upload +.export _tftp_upload_from_memory + +.import tftp_download +.import tftp_upload +.import tftp_upload_from_memory +.import tftp_set_callback_vector +.import tftp_clear_callbacks +.import tftp_ip +.import tftp_load_address +.import tftp_data_block_length +.import tftp_current_memloc +.import tftp_filename +.import tftp_filesize + +.import pushax, popax, popeax +.importzp sreg + + +.data + +callback: + clc + adc #02 ; skip the 2 byte length at start of buffer + bcc :+ + inx +: jsr pushax + ldax tftp_data_block_length +jmpvector: + jmp $ffff + + +.code + +_tftp_download: + stax jmpvector+1 + ldax #callback + jsr tftp_set_callback_vector + jsr popax + stax tftp_filename + jsr popeax + stax tftp_ip + ldax sreg + stax tftp_ip+2 + jsr tftp_download + ldx #$00 + txa + rol + rts + +_tftp_download_to_memory: + stax tftp_load_address + jsr tftp_clear_callbacks + jsr popax + stax tftp_filename + jsr popeax + stax tftp_ip + ldax sreg + stax tftp_ip+2 + jsr tftp_download + bcs error + sec + lda tftp_current_memloc + sbc tftp_load_address + tay + lda tftp_current_memloc+1 + sbc tftp_load_address+1 + tax + tya + rts + +error: + ldx #$00 + txa + rts + +_tftp_upload: + jsr tftp_set_callback_vector + jsr popax + stax tftp_filename + jsr popeax + stax tftp_ip + ldax sreg + stax tftp_ip+2 + jsr tftp_upload + ldx #$00 + txa + rol + rts + +_tftp_upload_from_memory: + stax tftp_filesize + jsr popax + stax tftp_load_address + jsr popax + stax tftp_filename + jsr popeax + stax tftp_ip + ldax sreg + stax tftp_ip+2 + jsr tftp_upload_from_memory + ldx #$00 + txa + rol + rts