forked from beretta42/zombie
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ip6809.s
309 lines (274 loc) · 4.84 KB
/
ip6809.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
include "zombie.def"
export conn
export tab
export rand
export lfsr
export dev_in
export dev_need_poll
export inbuf
export insize
export inmax
export pdu
export pdulen
.area .data
MAXBUF equ 6 ; fixme: defined by application
;; a array of connections/sockets
tab rmb C_SIZE*6
tabe
;; a free list of packet buffers
bufs rmb 2*MAXBUF ; free buffer stack space
fptr rmb 2 ; free buffer stack pointer
fno rmb 1 ; number of buffer on free list
conn rmb 2 ; working socket
time rmb 1 ; polling pause timer
itime rmb 1 ; pause this much time after empty polls
dev_need_poll
rmb 1 ; set by device driver if polling needed
rand rmb 2 ; random number
inbuf rmb 2 ; current in buffer
inmax rmb 2 ; maximum total receive size
insize rmb 2 ; size of current buffer
pdu rmb 2 ; start of pdu in current buffer
pdulen rmb 2 ; length of pdu in current buffer
.area .code
;;; add a packet buffer to freelist
;;; takes: X = buffer ptr
export freebuff
freebuff
pshs cc,u
cmpx #0
beq out@
orcc #$10
ldu fptr,pcr
stx ,--u
stu fptr,pcr
inc fno,pcr
out@ puls cc,u,pc
;;; get a packet buffer from freelist
;; takes: nothing
;; returns: X = buffer ptr
;; returns: C set on error (out of buffers)
export getbuff
getbuff pshs cc,u
orcc #$10
tst fno,pcr
beq err@
ldu fptr,pcr
ldx ,u++
stu fptr,pcr
dec fno,pcr
puls cc
clra
puls u,pc
err@ puls cc
coma
puls u,pc
;;; Drop the current input buffer
export ip_drop
ip_drop:
pshs x
ldx inbuf,pcr
lbsr freebuff
puls x,pc
;;; init stack
export ip6809_init
ip6809_init
;; reset device polling flag
clr dev_need_poll
;; set random number seed
* ldd #42
* std rand,pcr
;; clear socket/connection table
leay tab,pcr
ldb #tabe-tab
lbsr memclr
;; init our data area
leax fptr,pcr
stx fptr,pcr
clr fno,pcr
;; reset our pol timer
ldb #3 ; fixme: should be set by something else?
stb itime,pcr
stb time,pcr
;; init subsystems
lbsr eth_init
IFNDEF ETH_ONLY
lbsr ip_init
lbsr udp_init
lbsr tcp_init
ENDC
rts
;;; get a socket
;;; takes B = type (C_UDP)
;;; sets conn to new socket, C set on error
export socket
socket pshs x
lda #8
leax tab,pcr
loop@ tst C_FLG,x
beq found@
leax C_SIZE,x
deca
bne loop@
coma
puls x,pc
found@ stx conn,pcr
stb ,x
leay 1,x
ldb #C_SIZE-1
lbsr memclr
clra
puls x,pc
;;; send data to other end of socket
;;; takes conn, X = pdu ptr, D = length
;;; returns nothing
export send
send ; fixme: distribute to known protocols here
; for now just udp
IFNDEF ETH_ONLY
lbra udp_out
ELSE
rts
ENDC
;;; closes a socket
;;; takes conn
;;; returns nothing
export close
close clr [conn,pcr] ; exciting!
rts
;;; Call this when you know there's a packet waiting (say a interrupt
;;; fired). If your drivers is polling, then this will be called from
;;; tick().
dev_in ldx inbuf,pcr ; push to seve input buffer ptr
pshs x
lbsr getbuff ; get new buffer
bcs out@
stx inbuf,pcr
lbsr dev_poll
bcs a@
ldx inbuf,pcr ; send to ether layer
lbsr eth_in
ldb #1
stb time,pcr
bra out@
a@ lbsr ip_drop
out@ puls x
stx inbuf,pcr
rts
;;; call this every tick
export tick
tick lbsr lfsr
ldx conn,pcr
pshs x
;; iterate through each socket
;; decrementing timer, and calling it's callback
;; if zero
lbsr for_sock
a@ lbsr next_sock
bcs cont@ ; fixme: or should we goto poll?
ldx conn,pcr
ldd C_TIME,x
beq a@
subd #1
std C_TIME,x
bne a@
ldy C_CALL,x
beq a@
ldb #C_CALLTO
jsr ,y
bra a@
;; poll device - fixme: this may need a loop
;; to pull all packets from a polled device
cont@ tst dev_need_poll,pcr ;does device need polling?
beq out@
dec time,pcr ; decrement poll timer
bne out@
ldb itime,pcr ; reset pause timer
stb time,pcr
bsr dev_in ; go check for a packet
out@ puls x
stx conn,pcr
rts
;;; start iterating over table via conn
export for_sock
for_sock
pshs x
leax tab-C_SIZE,pcr
stx conn,pcr
puls x,pc
;;; goto next socket
;;; takes: nothing
;;; returns: conn = next used socket, set C on none left
export next_sock
next_sock
pshs x
leax tabe,pcr
pshs x
ldx conn,pcr
ns1 leax C_SIZE,x
cmpx ,s
beq nf@
tst ,x
beq ns1
stx conn,pcr
clra
puls d,x,pc
nf@ coma
puls d,x,pc
;; tick LFSR
lfsr
ldd rand,pcr
lsra
rorb
bcc a@
eora #$b4
a@ std rand,pcr
rts
;;; print a decimal char
export put_dec
put_dec pshs d
clra
a@ inca
subb #10
bcc a@
deca
addb #10+$30
pshs b
tfr a,b
tstb
beq b@
jsr put_dec
b@ puls b
jsr put_char
out@ puls d,pc
;;; print a ip address/mask
;;; takes X - ip addr ptr
export ipprint
ipprint
pshs d,x
lda #4
sta ,-s
bra b@
a@ ldb #'.
lbsr put_char
b@ ldb ,x+
lbsr put_dec
dec ,s
bne a@
leas 1,s
puls d,x,pc
;;; copy from U to Y, B times
export memcpy
memcpy
lda ,u+
sta ,y+
decb
bne memcpy
rts
;;; clear to zero Y, B times
export memclr
memclr
a@ clr ,y+
decb
bne a@
rts