forked from beretta42/zombie
-
Notifications
You must be signed in to change notification settings - Fork 0
/
coconic.s
188 lines (173 loc) · 3.3 KB
/
coconic.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
;;; A driver for RetroInnovation's CoCoNIC card
;;; based on the CS8900A chip
;;;
include "zombie.def"
CARDCTL equ $ff80 ; Jim's cartridge control register
NEWBASE equ $60 ; LSB i/o base (out of MPI's way)
RXTX equ $ff60 ; uint16 data regsiter (LE)
PAGEPTR equ $ff6a ; uint16 pointer register (LE)
PAGEDATA equ $ff6c ; uint16 data register (LE)
TXCMD equ $ff64
TXLEN equ $ff66
export dev_init
export dev_send
export dev_poll
export dev_setaddr
export getpp
export setpp
section .code
;;; Get a 16 bit word from packet page
;;; takes: X address
;;; returns: D data
getpp:
tfr x,d
exg a,b
std PAGEPTR
ldd PAGEDATA
exg a,b
rts
;;; Set a 16 bit word to packet page
;;; takes: X address, D data
;;; returns: nothing
setpp:
pshs d
tfr x,d
exg a,b
std PAGEPTR
puls d
exg a,b
std PAGEDATA
rts
;;; Called to set device address
dev_setaddr:
;; Set chip's MAC
pshs x,y
tfr x,y
ldx #$158 ; X is MAC address in NIC
ldd ,y++ ; get first two MAC address bytes
exg a,b
bsr setpp
ldd ,y++ ; get next two MAC bytes
exg a,b
leax 2,x
bsr setpp
ldd ,y ; and set third two (6 bytes total)
exg a,b
leax 2,x
bsr setpp
puls x,y,pc
;;; Called to initialize Device
;;; returns: C set on error
dev_init:
com dev_need_poll
pshs x,y ; save MAC address ptr
;; change cards address to our non mpi base (ff60)
ldd #$55aa
sta CARDCTL
stb CARDCTL
ldd #$2201
sta CARDCTL
stb CARDCTL
lda #NEWBASE
sta CARDCTL
;; check for card
ldx #0 ; X = pp address
bsr getpp ; get reg: D = reg
cmpd #$630e ; compare chip signature
bne err@ ; not same return error
;; reset chip
ldd #$0040
ldx #$0114
bsr setpp
;; turn on receiver / transmitter
ldd #$00d3 ; Turn on receiver/transmitter
ldx #$112 ;
bsr setpp ;
ldd #$0d05 ; allow reception of our frames + broadcasts
ldx #$104 ;
bsr setpp ;
;; and return
clrb ; clear C
puls x,y,pc
;; return w/ error
err@ comb ; set C
puls x,y,pc ; return
;;; drop a frame
;;; takes: nothing
;;; returns: nothing
drop
ldx #$102
lbsr getpp
orb #$40
bsr setpp
rts
;;; Send a packet to device
;;; takes: X ptr to eth0 frame, D size
dev_send
pshs d,x,y ; save regs
;; send transmit command, length
ldd #$00c0
exg a,b
std TXCMD
puls d
exg a,b
std TXLEN
;; find rounded word length
exg a,b
addd #1
lsra
rorb
tfr d,y ; y is our count
;; wait for room in NIC, drop received frames meanwhile
a@ ldx #$138
lbsr getpp
anda #1
bne b@
bsr drop
bra a@
;; send words from frame to NIC
b@ puls x
c@ ldd ,x++
std RXTX
leay -1,y
bne c@
;; return OK
clrb
puls y,pc
;;; receive packet
;;; returns: C set on no packet waiting
;;; returns: insize = length
dev_poll
pshs d,x,y
;; test for something waiting
ldx #$124
lbsr getpp
anda #$d
beq noth@ ; nothing waiting
;; these accesses are weird, and must be done in
;; this order, it seems.
lda $ff61 ; drop status
ldb $ff60
ldb $ff60 ; get length
lda $ff61
;; is too big?
cmpd inmax,pcr ;
bhi errbig@
std insize,pcr ; save as returned length
;; round up
addd #1
lsra
rorb
tfr d,y ; Y = word count
;; get words from NIC
ldx inbuf,pcr ; X = buffer
b@ ldd RXTX ; get a word
std ,x++ ; save in buffer
leay -1,y ; dec counter
bne b@ ; done?
;; return
clra
puls d,x,y,pc ; pull the rest
errbig@ lbsr drop ; drop the packet
noth@ coma
puls d,x,y,pc ; pull the test