mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-10-14 05:24:07 +00:00
added facility for user-defined callbacks when data arrives from tftp server
git-svn-id: http://svn.code.sf.net/p/netboot65/code@61 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
parent
03472de9f8
commit
71035ea9e4
@ -11,6 +11,9 @@
|
|||||||
.export tftp_ip
|
.export tftp_ip
|
||||||
.export tftp_download
|
.export tftp_download
|
||||||
.export tftp_directory_listing
|
.export tftp_directory_listing
|
||||||
|
.export tftp_data_block_length
|
||||||
|
.export tftp_set_download_callback
|
||||||
|
.export tftp_data_block_length
|
||||||
|
|
||||||
.import ip65_process
|
.import ip65_process
|
||||||
|
|
||||||
@ -56,7 +59,7 @@ tftp_client_port_low_byte: .res 1
|
|||||||
tftp_load_address: .res 2 ;address file will be (or was) downloaded to
|
tftp_load_address: .res 2 ;address file will be (or was) downloaded to
|
||||||
tftp_ip: .res 4 ;ip address of tftp server - set to 255.255.255.255 (broadcast) to send request to all tftp servers on local lan
|
tftp_ip: .res 4 ;ip address of tftp server - set to 255.255.255.255 (broadcast) to send request to all tftp servers on local lan
|
||||||
|
|
||||||
tftp_bytes_to_copy: .res 2
|
tftp_data_block_length: .res 2
|
||||||
tftp_current_memloc: .res 2
|
tftp_current_memloc: .res 2
|
||||||
|
|
||||||
; tftp state machine
|
; tftp state machine
|
||||||
@ -85,10 +88,15 @@ tftp_opcode: .res 2 ; will be set to 4 if we are doing a RRQ, or 7 if we are doi
|
|||||||
; currently only supported by tftp server built in to 'netboot65' server)
|
; currently only supported by tftp server built in to 'netboot65' server)
|
||||||
; inputs:
|
; inputs:
|
||||||
; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast)
|
; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast)
|
||||||
; tftp_load_address: memory location that dir will be stored in
|
|
||||||
; tftp_filename: pointer to null terminated filemask (e.g. "*.prg",0)
|
; tftp_filename: pointer to null terminated filemask (e.g. "*.prg",0)
|
||||||
; outputs: carry flag is set if there was an error
|
; tftp_load_address: memory location that dir will be stored in (NB - this field is
|
||||||
; if there was no error, the buffer at tftp_load_address will be filled
|
; ignored if a callback vector has been set with tftp_set_download_callback)
|
||||||
|
; outputs: carry flag is set if there was an error, clear otherwise
|
||||||
|
; if a callback vector has been set with tftp_set_download_callback
|
||||||
|
; then the specified routine will be called once for each 512 byte packet
|
||||||
|
; sent from the tftp server (each time AX will point at data block just arrived,
|
||||||
|
; and tftp_data_block_length will contain number of bytes in that data block)
|
||||||
|
; otherwise, the buffer at tftp_load_address will be filled
|
||||||
; with null-terminated strings containing the names of all files on the
|
; with null-terminated strings containing the names of all files on the
|
||||||
; server that matched the specified file mask, and an additional null
|
; server that matched the specified file mask, and an additional null
|
||||||
; byte will follow the null byte terminating the last file name.
|
; byte will follow the null byte terminating the last file name.
|
||||||
@ -102,14 +110,19 @@ tftp_directory_listing:
|
|||||||
;download a file from a tftp server
|
;download a file from a tftp server
|
||||||
; inputs:
|
; inputs:
|
||||||
; tftp_ip: ip address of host to download from (set to 255.255.255.255 for broadcast)
|
; 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 dir will be stored in, or $0000 to
|
||||||
; treat first 2 bytes received from tftp server as memory address that rest
|
; 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)
|
; of file should be loaded into (e.g. if downloading a C64 'prg' file)
|
||||||
; tftp_filename: pointer to null terminated name of file to download
|
|
||||||
; outputs: carry flag is set if there was an error
|
; outputs: carry flag is set if there was an error
|
||||||
; if there was no error, the buffer at tftp_load_address will be filled
|
; if a callback vector has been set with tftp_set_download_callback
|
||||||
|
; then the specified routine will be called once for each 512 byte packet
|
||||||
|
; sent from the tftp server (each time AX will point at data block just arrived,
|
||||||
|
; and tftp_data_block_length will contain number of bytes in that data block)
|
||||||
|
; otherwise, the buffer at tftp_load_address will be filled
|
||||||
; with file downloaded.
|
; with file downloaded.
|
||||||
; tftp_load_address: will be set to the actual address loaded into
|
; tftp_load_address: will be set to the actual address loaded into (NB - this field is
|
||||||
|
; ignored if a callback vector has been set with tftp_set_download_callback)
|
||||||
tftp_download:
|
tftp_download:
|
||||||
ldax #$0100 ;opcode 01 = RRQ
|
ldax #$0100 ;opcode 01 = RRQ
|
||||||
set_tftp_opcode:
|
set_tftp_opcode:
|
||||||
@ -285,12 +298,17 @@ tftp_in:
|
|||||||
jmp @not_data_block
|
jmp @not_data_block
|
||||||
:
|
:
|
||||||
|
|
||||||
|
|
||||||
lda #0
|
lda #0
|
||||||
sta tftp_just_set_new_load_address ;clear the flag
|
sta tftp_just_set_new_load_address ;clear the flag
|
||||||
clc
|
clc
|
||||||
lda tftp_load_address
|
lda tftp_load_address
|
||||||
adc tftp_load_address+1 ;is load address currently $0000?
|
adc tftp_load_address+1 ;is load address currently $0000?
|
||||||
bne @dont_set_load_address
|
bne @dont_set_load_address
|
||||||
|
|
||||||
|
lda tftp_callback_address_set ;have we overridden the default handler?
|
||||||
|
bne @dont_set_load_address ;if so, don't skip the first two bytes in the file
|
||||||
|
|
||||||
ldax udp_inp+$0c ;get first two bytes of data
|
ldax udp_inp+$0c ;get first two bytes of data
|
||||||
stax tftp_load_address ;make them the new load adress
|
stax tftp_load_address ;make them the new load adress
|
||||||
stax tftp_current_memloc ;also the current memory destination
|
stax tftp_current_memloc ;also the current memory destination
|
||||||
@ -336,30 +354,21 @@ tftp_in:
|
|||||||
sbc #$0e ;take off the length of the UDP header+OPCODE + BLOCK + first 2 bytes (memory location)
|
sbc #$0e ;take off the length of the UDP header+OPCODE + BLOCK + first 2 bytes (memory location)
|
||||||
@adjusted_header_length:
|
@adjusted_header_length:
|
||||||
|
|
||||||
sta tftp_bytes_to_copy
|
sta tftp_data_block_length
|
||||||
lda udp_inp+4 ;get high byte of the length of the UDP packet
|
lda udp_inp+4 ;get high byte of the length of the UDP packet
|
||||||
sbc #0
|
sbc #0
|
||||||
sta tftp_bytes_to_copy+1
|
sta tftp_data_block_length+1
|
||||||
|
|
||||||
lda tftp_just_set_new_load_address
|
lda tftp_just_set_new_load_address
|
||||||
bne @skip_first_2_bytes_in_calculating_copy_src
|
bne @skip_first_2_bytes_in_calculating_copy_src
|
||||||
ldax #udp_inp+$0c
|
ldax #udp_inp+$0c
|
||||||
jmp @got_copy_src
|
jmp @got_pointer_to_tftp_data
|
||||||
@skip_first_2_bytes_in_calculating_copy_src:
|
@skip_first_2_bytes_in_calculating_copy_src:
|
||||||
ldax #udp_inp+$0e
|
ldax #udp_inp+$0e
|
||||||
@got_copy_src:
|
@got_pointer_to_tftp_data:
|
||||||
stax copy_src
|
|
||||||
ldax tftp_current_memloc
|
jsr tftp_download_callback
|
||||||
stax copy_dest
|
|
||||||
ldax tftp_bytes_to_copy
|
|
||||||
jsr copymem
|
|
||||||
clc
|
|
||||||
lda tftp_bytes_to_copy ;update the location where the next data will go
|
|
||||||
adc tftp_current_memloc
|
|
||||||
sta tftp_current_memloc
|
|
||||||
lda tftp_bytes_to_copy+1
|
|
||||||
adc tftp_current_memloc+1
|
|
||||||
sta tftp_current_memloc+1
|
|
||||||
lda udp_inp+4 ;check the length of the UDP packet
|
lda udp_inp+4 ;check the length of the UDP packet
|
||||||
cmp #02
|
cmp #02
|
||||||
bne @last_block
|
bne @last_block
|
||||||
@ -375,5 +384,43 @@ tftp_in:
|
|||||||
lda #tftp_complete
|
lda #tftp_complete
|
||||||
sta tftp_state
|
sta tftp_state
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;default handler when block arrives:
|
||||||
|
;copy to RAM
|
||||||
|
;assumes tftp_data_block_length has been set, and AX should point to start of data
|
||||||
|
copy_tftp_block_to_ram:
|
||||||
|
stax copy_src
|
||||||
|
ldax tftp_current_memloc
|
||||||
|
stax copy_dest
|
||||||
|
ldax tftp_data_block_length
|
||||||
|
jsr copymem
|
||||||
|
clc
|
||||||
|
lda tftp_data_block_length ;update the location where the next data will go
|
||||||
|
adc tftp_current_memloc
|
||||||
|
sta tftp_current_memloc
|
||||||
|
lda tftp_data_block_length+1
|
||||||
|
adc tftp_current_memloc+1
|
||||||
|
sta tftp_current_memloc+1
|
||||||
|
rts
|
||||||
|
|
||||||
|
;set up vector of routine to be called when each 512 packet arrives from tftp server
|
||||||
|
;when vector is called, AX will point to data that was downloaded, and
|
||||||
|
;tftp_data_block_length will be set to length of downloaded data block. This will be
|
||||||
|
;equal to $200 (512) for each block EXCEPT the final block. THe final block will
|
||||||
|
;always be less than $200 bytes - if the file is an exact multiple if $200 bytes
|
||||||
|
;long, then a final block will be received with length $00.
|
||||||
|
; inputs:
|
||||||
|
; AX - address of routine to call for each packet.
|
||||||
|
; outputs: none
|
||||||
|
tftp_set_download_callback:
|
||||||
|
stax tftp_download_callback+1
|
||||||
|
|
||||||
.rodata
|
.rodata
|
||||||
tftp_octet_mode: .asciiz "OCTET"
|
tftp_octet_mode: .asciiz "OCTET"
|
||||||
|
|
||||||
|
.data
|
||||||
|
tftp_download_callback:
|
||||||
|
jmp copy_tftp_block_to_ram ;vector for action to take when a data block received (default is to store block in RAM)
|
||||||
|
|
||||||
|
tftp_callback_address_set: .byte 0
|
Loading…
Reference in New Issue
Block a user