OpenCores
URL https://opencores.org/ocsvn/rf6809/rf6809/trunk

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [software/] [boot/] [xmodem.asm] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 robfinch
; ============================================================================
2
;        __
3
;   \\__/ o\    (C) 2022  Robert Finch, Waterloo
4
;    \  __ /    All rights reserved.
5
;     \/_//     robfinch@opencores.org
6
;       ||
7
;
8
;
9
; BSD 3-Clause License
10
; Redistribution and use in source and binary forms, with or without
11
; modification, are permitted provided that the following conditions are met:
12
;
13
; 1. Redistributions of source code must retain the above copyright notice, this
14
;    list of conditions and the following disclaimer.
15
;
16
; 2. Redistributions in binary form must reproduce the above copyright notice,
17
;    this list of conditions and the following disclaimer in the documentation
18
;    and/or other materials provided with the distribution.
19
;
20
; 3. Neither the name of the copyright holder nor the names of its
21
;    contributors may be used to endorse or promote products derived from
22
;    this software without specific prior written permission.
23
;
24
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
;
35
; ============================================================================
36
;
37
; Xmodem variables
38
;
39
xm_timer                                EQU             $FFC020
40
xm_protocol                     EQU             $9F5
41
xm_flag                                 EQU             $9F6
42
xm_checksum                     EQU             $9F7
43
xm_tmp2                                 EQU             $9F8
44
xm_packetnum            EQU             $9FA
45
xm_tmp                                  EQU             $9FC
46
xm_crc                                  EQU             $9FE
47
xm_ibuf                                 EQU             $A00    ; to $A7F
48
xm_obuf                                 EQU             $A80    ; to $AFF
49
 
50
; ------------------------------------------------------------------------------
51
; Send data using XModem.
52
; ------------------------------------------------------------------------------
53
 
54
xm_SendStart:
55
        lbsr    GetRange
56
        ldx             mon_r1+2                                ; x = buffer address
57
        tfr             x,u
58
        ldb             #1                                                      ; packet numbers start at one
59
        stb             xm_packetnum+1
60
        ; Wait for receiver to send a NAK
61
xm_send:
62
        ldd             #-1                                                     ; select blocking input
63
        swi
64
        fcb             MF_INCH
65
        cmpb    #NAK                                            ; should have got a NAK
66
        beq             xm_send5
67
        cmpb    #'C'                                            ; or a 'C'
68
        bne             xm_send
69
xm_send5:
70
        stb             xm_protocol
71
xm_send4:
72
        ldb             #SOH                                            ; send start
73
        swi
74
        fcb             OUTCH
75
        ldb             xm_packetnum+1  ; send packet number
76
        swi
77
        fcb             MF_OUTCH
78
        comb                                                                    ; one's complement
79
        swi
80
        fcb             MF_OUTCH                                ; send packet number complement
81
        clra                                                                    ; acca = byte count
82
        tfr             x,u                                                     ; u = buffer address
83
xm_send1:
84
        ldb             ,u+                                                     ; grab a byte from the buffer
85
        swi
86
        fcb             MF_OUTCH                                ; send it out
87
        inca
88
        cmpa    #128                                            ; number of bytes in payload
89
        blo             xm_send1
90
        ldb             xm_protocol
91
        cmpb    #'C'                                            ; CRC protocol?
92
        bne             xm_send2
93
        bsr             xm_calc_crc                     ; compute CRC
94
        ldd             xm_crc                                  ; get crc
95
        lsra                                                                    ; transfer high eight bits first, so
96
        rorb                                                                    ; right shift D by eight
97
        lsra
98
        rorb
99
        lsra
100
        rorb
101
        lsra
102
        rorb
103
        lsra
104
        rorb
105
        lsra
106
        rorb
107
        lsra
108
        rorb
109
        lsra
110
        rorb
111
        swi
112
        fcb             MF_OUTCH                                ; send out the byte
113
        ldd             xm_crc                                  ; get back CRC
114
        swi
115
        fcb             MF_OUTCH                                ; and send out low byte
116
        bra             xm_send3
117
xm_send2:
118
        bsr             xm_calc_checksum
119
        ldb             xm_checksum
120
        swi
121
        fcb             MF_OUTCH
122
xm_send3:
123
        swi
124
        ldd             #-1                                                     ; block until input is present
125
        fcb             MF_INCH
126
        cmpb    #ACK
127
        bne             xm_send4                                ; not an ACK then resend the record
128
        inc             xm_packetnum            ; increment packet number
129
        leax    128,x                                           ; advance buffer pointer
130
        cmpx    mon_r2+2
131
        blo             xm_send4                                ; go send next record
132
        ldb             #EOT                                            ; send end of transmission
133
        swi
134
        fcb             MF_OUTCH
135
        swi
136
        fcb             MF_OUTCH
137
        swi
138
        fcb             MF_OUTCH
139
        rts
140
 
141
; ------------------------------------------------------------------------------
142
; Get a byte, checking for a receive timeout.
143
;
144
; Returns:
145
;               accb = byte (0 to 255) or -1 if timed out
146
; ------------------------------------------------------------------------------
147
 
148
xm_getbyte:
149
xm_gb1:
150
        tst             xm_timer                ; check the timeout - 2048 ticks (3 seconds approx.)
151
        bmi             xm_gb2
152
        clra                                                    ; non-blocking
153
        clrb
154
        swi
155
        fcb             MF_INCH                 ; try and get a character
156
        bmi             xm_gb1                  ; if no character, try again
157
        bsr             xm_outbyteAsHex
158
        rts
159
xm_gb2:
160
        ldb             #-1
161
        rts
162
 
163
; ------------------------------------------------------------------------------
164
; XModem Receive
165
;
166
; Parameters:
167
;               none
168
; Modifies:
169
;               All
170
;       Returns:
171
;               none
172
; ------------------------------------------------------------------------------
173
 
174
xm_ReceiveStart:
175
        lbsr    Delay3s                         ; give a little bit of time for sender
176
        lbsr    Delay3s
177
        lbsr    Delay3s
178
        lbsr    GetNumber                       ; Get the transfer address
179
        tstb                                                            ; Make sure we got a value
180
        lbeq    Monitor
181
        ldx             mon_numwka+2    ; X = transfer address
182
        clr             xm_packetnum    ; initialize
183
        lda             #'C'                                    ; try for CRC first
184
        sta             xm_protocol
185
xm_receive:
186
        lda             #2                                              ; number of times to retry -1
187
xm_rcv5:
188
        ldb             xm_protocol             ; indicate we want a transfer (send protocol byte)
189
        swi
190
        fcb             MF_SerialPutchar
191
xm_rcv4:
192
        clr             xm_timer                ; clear the timeout
193
xm_rcv1:
194
        bsr             xm_getbyte
195
        tstb
196
        bmi             xm_retry1               ; timeout on protocol id?
197
        cmpb    #SOH                            ; it should be start of a transfer
198
        beq             xm_SOH
199
        cmpb    #EOT
200
        beq             xm_EOT                  ; or end of transfer (EOT)
201
        cmpb    #CAN
202
        beq             xm_receive      ; might be a cancel
203
        cmpb    #ETB
204
        beq             xm_EOT
205
xm_rcv_nak:                                     ; wasn't a valid start so
206
        ldb             #NAK                            ; send a NAK
207
        swi
208
        fcb             MF_SerialPutchar        ; and try again
209
        bra             xm_rcv4
210
xm_SOH:
211
        bsr             xm_getbyte      ; get packet number
212
        bmi             xm_rcv_to1
213
        stb             xm_packetnum+1
214
        pshs    b                                               ; save it
215
        bsr             xm_getbyte      ; get complement of packet number
216
        bmi             xm_rcv_to2
217
        addb    ,s                                      ; add the two values
218
        andb    #$FF                            ; the sum should be $FF
219
        subb    #$FF
220
        stb             xm_flag                 ; should be storing a zero if there is no error
221
        ldy             #0                                      ; y = payload byte counter
222
        tfr             x,u
223
xm_rcv2:
224
        bsr             xm_getbyte
225
        bmi             xm_rcv_to1
226
        stb             ,u+                                     ; store the byte to memory
227
        iny
228
        cmpy    #128                            ; 128 bytes per payload
229
        blo             xm_rcv2
230
        bsr             xm_getbyte      ; get checksum or CRC byte
231
        bmi             xm_rcv_to1
232
        stb             xm_tmp                  ; stuff checksum/CRC byte
233
        ldb             xm_protocol
234
        cmpb    #'C'
235
        bne             xm_rcv_chksum
236
        bsr             xm_getbyte      ; get low order CRC byte
237
        bmi             xm_rcv_to1
238
        lda             xm_tmp                  ; get the high byte
239
        aslb                                                    ; prepare to combine high and low order
240
        aslb
241
        aslb
242
        aslb
243
        lsra                                                    ; shift low nybble of acca into accb
244
        rorb
245
        lsra
246
        rorb
247
        lsra
248
        rorb
249
        lsra
250
        rorb
251
        anda    #$00F                                   ; mask off any extra bits
252
        std     xm_tmp2
253
        bsr             xm_calc_crc             ; compute the CRC-16 for the received data
254
        ldd             xm_crc                          ; and compare to received value
255
        cmpd    xm_tmp2
256
        bra             xm_rcv3
257
xm_rcv_chksum:
258
        bsr             xm_calc_checksum
259
        ldb             xm_checksum
260
        cmpb    xm_tmp                          ; where we stuffed the byte
261
xm_rcv3:
262
        bne             xm_rcv_nak              ; if not the same, NAK
263
        tst             xm_flag
264
        bne             xm_rcv_nak              ; bad packet number?
265
        ldb             #ACK                                    ; packet recieved okay, send back an ACK
266
        swi
267
        fcb             MF_SerialPutchar
268
        ldb             xm_packetnum+1  ; did we receive the same packet
269
        cmpb    xm_packetnum
270
        beq             xm_rcv4                         ; same packet received, dont update buffer pointer
271
        stb             xm_packetnum    ; update last seen packet number
272
        leax    128,x                                   ; increment buffer pointer
273
        bra             xm_rcv4                         ; and go back for next packet
274
xm_rcv_to2:
275
        leas    1,s                                             ; get rid of stacked byte
276
xm_rcv_to1:
277
        ldd             #msgXmTimeout
278
        swi
279
        fcb             MF_DisplayString
280
        lbra    Monitor
281
xm_EOT:                                                         ; end of transmission received, return
282
        ldb             #ACK                                    ; ACK the EOT
283
        swi
284
        fcb             MF_SerialPutchar
285
        lbra    Monitor
286
xm_retry1:
287
        deca
288
        bpl             xm_rcv5
289
        lda             xm_protocol
290
        cmpa    #NAK                                    ; are we already lowered down to checksum protocol?
291
        beq             xm_noTransmitter        ; did we try both checksum and CRC?
292
        lda             #NAK
293
        sta             xm_protocol
294
        bra             xm_receive
295
xm_noTransmitter:
296
        ldd             #msgXmNoTransmitter
297
        swi
298
        fcb             MF_DisplayString
299
        lbra    Monitor
300
 
301
msgXmTimeout:
302
        fcb             "Xmodem: timed out",CR,LF,0
303
msgXmNoTransmitter:
304
        fcb             "XModem: transmitter not responding",CR,LF,0
305
 
306
; ------------------------------------------------------------------------------
307
; Calculate checksum value. The checksum is simply the low order eight bits of
308
; the sum of all the bytes in the payload area.
309
;
310
; Stack space:
311
;               two words
312
;       Modifies:
313
;               xm_checksum             contains the checksum value for the record
314
; Parameters:
315
;               X = buffer address
316
;       Returns:
317
;               none
318
; ------------------------------------------------------------------------------
319
 
320
xm_calc_checksum:
321
        pshs    d,x
322
        clra
323
        clrb
324
xm_cs1:
325
        addb    ,x+
326
        inca
327
        cmpa    #128
328
        blo             xm_cs1
329
        andb    #$FF
330
        stb             xm_checksum
331
        puls    d,x,pc
332
 
333
; ------------------------------------------------------------------------------
334
; Compute CRC-16 of buffer.
335
;
336
;int calcrc(char *ptr, int count)
337
;{
338
;    int  crc;
339
;    char i;
340
;    crc = 0;
341
;    while (--count >= 0)
342
;    {
343
;        crc = crc ^ (int) (*ptr++ << 8);
344
;        i = 8;
345
;        do
346
;        {
347
;            if (crc & 0x8000)
348
;                crc = crc << 1 ^ 0x1021;
349
;            else
350
;                crc = crc << 1;
351
;        } while(--i);
352
;    }
353
;    return (crc);
354
;}
355
;
356
; Modifies:
357
;               xm_crc variable
358
; Parameters:
359
;               u = buffer address
360
; Returns:
361
;               none
362
; ------------------------------------------------------------------------------
363
 
364
xm_calc_crc:
365
        pshs    d,x,y,u
366
        clr             xm_crc
367
        clr             xm_crc+1
368
        ldu             #0                                      ; u = byte count
369
xm_crc1:
370
        ldb             ,x+                                     ; get byte
371
        clr             xm_tmp                  ; save in temp
372
        stb             xm_tmp+1
373
        asl             xm_tmp+1                ; shift temp eight bits to left
374
        rol             xm_tmp
375
        asl             xm_tmp+1
376
        rol             xm_tmp
377
        asl             xm_tmp+1
378
        rol             xm_tmp
379
        asl             xm_tmp+1
380
        rol             xm_tmp
381
        asl             xm_tmp+1
382
        rol             xm_tmp
383
        asl             xm_tmp+1
384
        rol             xm_tmp
385
        asl             xm_tmp+1
386
        rol             xm_tmp
387
        asl             xm_tmp+1
388
        rol             xm_tmp
389
        ldd             xm_crc          ; crc = crc ^ tmp
390
        eora    xm_tmp
391
        eorb    xm_tmp+1
392
        std             xm_crc
393
        ldy             #0
394
xm_crc4:
395
        ldb             xm_crc          ; get high byte
396
        bitb    #$8                             ; check for $8000
397
        beq             xm_crc2         ; no? then just go shift
398
        ldd             xm_crc          ; load
399
        aslb                                            ; shift
400
        rola
401
        eorb    #$021                   ; and xor
402
        eora    #$001
403
        std             xm_crc          ; store it back
404
        bra             xm_crc3
405
xm_crc2:
406
        ldd             xm_crc          ; load
407
        aslb                                            ; shift
408
        rola
409
        std             xm_crc          ; and store
410
xm_crc3:
411
        iny
412
        cmpy    #8                              ; repeat eight times
413
        blo             xm_crc4
414
        leau    1,u                             ; increment byte count
415
        cmpu    #128
416
        ldd             xm_crc          ; we want only a 16-bit CRC
417
        anda    #$0F
418
        std             xm_crc
419
        blo             xm_crc1
420
        puls    d,x,y,u,pc
421
 
422
xm_outbyteAsHex:
423
        pshs    d
424
        ldd             CharOutVec                                              ; get current char out vector
425
        pshs    d                                                                                       ; save it
426
        ldd             #ScreenDisplayChar              ; set output vector to screen display
427
        std             CharOUtVec
428
        ldd             2,s                                                                             ; get passed data
429
        lbsr    DispByteAsHex                                   ; and display on-screen
430
        ldb             #' '
431
        lbsr    ScreenDisplayChar
432
        puls    d                                                                                       ; get back old char out vector
433
        std             CharOutVec                                              ; and restore it
434
        puls    d                                                                                       ; restore input arguments
435
        rts
436
 
437
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.