blob: 1221922128302f65c294f151d719440697c93bcf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
\ *****************************************************************************
\ * 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
get-load-base (xmodem-load)
;
|