\ ***************************************************************************** \ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License \ * which accompanies this distribution, and is available at \ * http://www.opensource.org/licenses/bsd-license.php \ * \ * Contributors: \ * IBM Corporation - initial implementation \ ****************************************************************************/ 01 CONSTANT XM-SOH \ Start of header 04 CONSTANT XM-EOT \ End-of-transmission 06 CONSTANT XM-ACK \ Acknowledge 15 CONSTANT XM-NAK \ Neg. acknowledge 0 VALUE xm-retries \ Retry count 0 VALUE xm-block# \ * \ * Internal function: \ * wait seconds for a new character \ * : xmodem-get-byte ( timeout -- byte|-1 ) d# 1000 * 0 DO key? IF key UNLOOP EXIT THEN 1 ms LOOP -1 ; \ * \ * Internal function: \ * Receive one XMODEM packet, check block number and check sum. \ * : xmodem-rx-packet ( address -- success? ) 1 xmodem-get-byte \ Get block number dup 0 < IF 2drop false EXIT \ Timeout THEN 1 xmodem-get-byte \ Get neg. block number dup 0 < IF 3drop false EXIT \ Timeout THEN rot 0 ( blk# ~blk# address chksum ) 80 0 DO 1 xmodem-get-byte dup 0 < IF ( blk# ~blk# address chksum byte ) 3drop 2drop UNLOOP FALSE EXIT THEN dup 3 pick c! ( blk# ~blk# address chksum byte ) + swap 1+ swap ( blk# ~blk# address+1 chksum' ) LOOP ( blk# ~blk# address chksum ) \ Check sum: 0ff and 1 xmodem-get-byte <> IF \ CRC failed! 3drop FALSE EXIT THEN drop ( blk# ~blk# ) \ finally check if block numbers are ok: over xm-block# <> IF \ Wrong block number! 2drop FALSE EXIT THEN ( blk# ~blk# ) ff xor = ; \ * \ * Internal function: \ * Load file to given address via XMODEM protocol \ * : (xmodem-load) ( address -- bytes ) 1 to xm-block# 0 to xm-retries dup BEGIN d# 10 xmodem-get-byte dup >r CASE XM-SOH OF dup xmodem-rx-packet IF \ A packet has been received successfully XM-ACK emit 80 + ( start-addr next-addr R: rx-byte ) 0 to xm-retries \ Reset retry count xm-block# 1+ ff and to xm-block# \ Increase current block# ELSE \ Error while receiving packet XM-NAK emit xm-retries 1+ to xm-retries \ Increase retry count THEN ENDOF XM-EOT OF XM-ACK emit ENDOF dup OF XM-NAK emit xm-retries 1+ to xm-retries \ Increase retry count ENDOF ENDCASE r> XM-EOT = xm-retries d# 10 >= OR UNTIL ( start-address end-address ) swap - ( bytes received ) ; \ * \ * Load file to load-base via XMODEM protocol \ * : xmodem-load ( -- bytes ) cr ." Waiting for start of XMODEM upload..." cr get-load-base (xmodem-load) ;