-
Notifications
You must be signed in to change notification settings - Fork 1
/
xmodem_send.s
116 lines (105 loc) · 3.81 KB
/
xmodem_send.s
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
; XMODEM Sender for the 6502
; transfer 256 bytes pages over serial using xmodem protocol
; exemple : 1000-17FF
; B03:10 18 B00G
cout = $fded
;crout = $fd8e
prbyte = $fdda
; XMODEM Control Character Constants
SOH = $01 ; start block
EOT = $04 ; end of text marker
ACK = $06 ; good block acknowledged
NAK = $15 ; bad block acknowledged
.include "apple_enc.inc"
.include "macros.inc"
.enc "apple"
.if DIRECT
* = $B00
jmp XModemSend
.fi
; parameters
start .fill 1 ; data pointer (two byte variable)
end .fill 1
; program
XModemSend
jsr ssc.init ; init serial card 19200 8n1
jsr ssc.flush ; flush ssc buffer
.if DIRECT
prc "XMODEM SEND\n"
.fi
lda #0
sta blknum ; set block counter to 0
- jsr ssc.getc3s
bcc - ; wait for something to come in...
cmp #NAK ; is it the NAK to start a chksum xfer?
beq +
.if DIRECT
jmp Abort ; not NAK, abort
.else
jmp -
.fi
+
.if DIRECT
prc "SEND DATA\n"
.fi
ldy #0 ; init y
sty ptr
lda start ; write start to ptr
sta ptr+1
NextBlk inc blknum ; inc block counter
lda #10 ; error counter set to
sta errcnt ; 10 max retries
StartBlk
.if DIRECT
lda #'.'
jsr cout
.fi
lda #SOH
jsr ssc.putc ; send SOH = start of header
lda blknum
jsr ssc.putc ; send count
eor #$FF
jsr ssc.putc ; send neg count
lda #0 ; Y = 0
sta blksum ; init blksum
- lda $1234,y ; send 128 bytes of data
ptr = * - 2
jsr ssc.putc ; send current byte
clc
adc blksum ; add mod 256 to blksum
sta blksum
iny
beq EndLoop ; end of loop2
bpl - ; in loop1
cpy #$80 ; end of loop1 == start of loop2
bne - ; in loop2
EndLoop lda blksum ; end of loop1 (Y==$80) or loop2 (Y==$0)
jsr ssc.putc ; send chksum
jsr ssc.getc3s ; Wait for Ack/Nack
bcc SetError ; No chr received after 3 seconds, resend
cmp #ACK ; Chr received... is it:
bne SetError ; No ACK => error
cpy #128 ; if end of loop1, next block
beq NextBlk ; after blksum sending
inc ptr+1 ; next page
lda ptr+1
cmp end ; if < end, Loop again
bne NextBlk
ExitSend lda #EOT ; send final EOT
jsr ssc.putc
.if DIRECT
prc "\nTRANSFER OK\n"
.fi
rts
SetError dec errcnt ; decr error counter
bne StartBlk ; if not null, resend block
.if DIRECT
Abort jsr ssc.flush ; yes, too many errors, flush buffer,
Exit_Err prc "\nERROR!\n"
.fi
rts
ssc .binclude "ssc.s"
; variables
blknum .fill 1 ; block number
errcnt .fill 1 ; error counter 10 is the limit
blksum .fill 1 ; chksum