XMODEM Receiver and Transmitter

Introduction

The file Common\XmodemTxRx.fth implements the XMODEM 128 and 1024 byte protocols in both directions. Use with AIDE requires AIDE release 3.00 upwards. A very simplified version of the 128 byte checksum receive code may be found in Common\MinXmodemRx.fth and is ideal for Flash reprogramming.

The original shorter code that just handles the 128 byte protocol is available as Common\XmodemTxRx128.fth.

No test code is provided for this file as the system has been tested by comparison of transferred binary files.

Words in XmodemTxRx.fth

Configuration

1 equ XmodemTx? \ -- n
Non-zero to compile transmit code

1 equ XmodemRx? \ -- n
Non-zero to compile receive code.

Constants and variables

$0101 equ blkerror
A block number error has occurred.

$0103 equ noreply
There was no reply within one second.

$0104 equ crcerror
Bad CRC or checksum.

$0105 equ overflow
Too many blocks were sent.

$010 equ maxerrs        \ -- n
Maximum number of errors before transfer is aborted.

#1024 Buffer: x-buffer  \ -- addr
Holds a 128 or 1024 byte Xmodem data block.

#128 value /Xblk        \ -- n
Holds Xmodem block size, 1024 or 128.

0 value Xmode           \ -- n
Holds 0 for checksum mode, nz for CRC-16.

Common code

: init-blks             \ addr #bytes -- #blks
Given the size of an image, return the number of complete 128 byte blocks, set the variable CUR-ADDRESS to ADDR and set the variable BLK# to 1.

: +Xcrc         \ crc char -- crc'
Update the XMODEM CRC with the given character. The initial value should be zero.

XMODEM transmission

: (To-Buffer)   \ --
Move 128/1024 bytes from the memory pointed to by CUR-ADDRESS into X-BUFFER. This is the default action of TO-BUFFER. The variable CUR-ADDRESS is set by BIN-DOWN and friends.

Defer To-Buffer \ --
Copy the next 128/1024 bytes to transmit to X-BUFFER. They are then transmitted from X-BUFFER. You can change this action as required by your application. The default action is (TO-BUFFER).

: ?Ack          \ -- ; wait for char, abort if not ACK
Wait for a character and terminate the transfer and abort if the character is not an ACK.

: Send-Block    \ Blk# -- ; transmit a block
Transmit the 128/1024 byte contents of X-BUFFER to the host.

: Bin-Down      \ addr #bytes -- ; transfer memory to host
Download (transmit) the given block of memory to the host using the XMODEM 128/1024 byte block protocol. On entry, the variable CUR-ADDRESS is set to addr on entry and #bytes is rounded up to a 128/1024 byte unit.

XMODEM reception

: ser-flush     \ -- ; flush the link input
Flush all input characters from the host/target link.

: send-ack      \ -- ; send ACK
Transmit an ACK character.

: send-nak      \ -- ; Transmit a NAK character
Transmit a NAK character, usually to trigger a retransmit.

: send-can      \ -- ; send CAN character
Transmit a CAN character.

: toomanyerrs?  \ -- T|F ; true if too many errors
Return true if too many comms errors have occurred.

: (From-Buffer) \ --
Move 128/1024 bytes from X-BUFFER into the memory pointed to by CUR-ADDRESS.

Defer From-Buffer       \ --
Move 128/1024 bytes from X-BUFFER into the memory pointed to by CUR-ADDRESS. CUR-ADDRESS is set up by BIN-UP and friends. The default action is (FROM-BUFFER). You can modify the action to suit your own application.

: TimedKey      \ -- char|-1
As KEY but returns -1 on timeout of 100 ms

: Get-Block     \ --
Receive an XMODEM 128/1024 byte data block from the host, processing the header and checksum data.

: (WaitResponse)        \ --
Wait for up to one second for a character.

: SendReq       \ --
If Xmode is set, send a C character, otherwise send a NAK.

0 value /RXms   \ --
Holds the transfer time in milliseconds.

: Bin-Up        \ addr len -- status ; status 0 = GOOD
Upload (receive) a block of data of the given size into memory using the XMODEM 128/1024 byte block protocol. An error status is returned, 0 indicating success. On entry, the variable CUR-ADDRESS is set to addr on entry and len is rounded up to a 128/1024 byte unit. Note that an error return of $0105 indicates the the file being sent is larger than the len input parameter.

: RecvXmodem    \ addr len -- len' status ; status=0=good
Upload (receive) a block of data of the given maximum size into memory using the XMODEM 128/1024 byte block protocol. The number of bytes correctly received and an error status are returned, 0 indicating success. See BIN-UP above for more details.

Defaults

If you have changed the operation of the buffer handling routines, you can restore them.

: Xmodem-1k     \ --
Default to 1k byte Xmodem blocks with CRCs. This usually gives the fastest transfers and best error checking.

: Xmodem-128    \ --
Default to 128 byte Xmodem blocks with checksums. This works with virtually all terminal emulators.

: XmodemDefaults        \ --
Set the XModem transfer routines to their default host copy operations.

Test code

: (NullFrom)    \ --
Dummy for testing receive.

: +NullRecv     \ --
Use the dummy receiver.