blob: a111708d767d96ce4b64ec00bb277af425653adc [file] [log] [blame]
\ *****************************************************************************
\ * 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 <timeout> 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
load-base (xmodem-load)
;