Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/block/swim_asm.S
15109 views
1
/*
2
* low-level functions for the SWIM floppy controller
3
*
4
* needs assembly language because is very timing dependent
5
* this controller exists only on macintosh 680x0 based
6
*
7
* Copyright (C) 2004,2008 Laurent Vivier <[email protected]>
8
*
9
* based on Alastair Bridgewater SWIM analysis, 2001
10
* based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
11
*
12
* This program is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU General Public License
14
* as published by the Free Software Foundation; either version
15
* 2 of the License, or (at your option) any later version.
16
*
17
* 2004-08-21 (lv) - Initial implementation
18
* 2008-11-05 (lv) - add get_swim_mode
19
*/
20
21
.equ write_data, 0x0000
22
.equ write_mark, 0x0200
23
.equ write_CRC, 0x0400
24
.equ write_parameter,0x0600
25
.equ write_phase, 0x0800
26
.equ write_setup, 0x0a00
27
.equ write_mode0, 0x0c00
28
.equ write_mode1, 0x0e00
29
.equ read_data, 0x1000
30
.equ read_mark, 0x1200
31
.equ read_error, 0x1400
32
.equ read_parameter, 0x1600
33
.equ read_phase, 0x1800
34
.equ read_setup, 0x1a00
35
.equ read_status, 0x1c00
36
.equ read_handshake, 0x1e00
37
38
.equ o_side, 0
39
.equ o_track, 1
40
.equ o_sector, 2
41
.equ o_size, 3
42
.equ o_crc0, 4
43
.equ o_crc1, 5
44
45
.equ seek_time, 30000
46
.equ max_retry, 40
47
.equ sector_size, 512
48
49
.global swim_read_sector_header
50
swim_read_sector_header:
51
link %a6, #0
52
moveml %d1-%d5/%a0-%a4,%sp@-
53
movel %a6@(0x0c), %a4
54
bsr mfm_read_addrmark
55
moveml %sp@+, %d1-%d5/%a0-%a4
56
unlk %a6
57
rts
58
59
sector_address_mark:
60
.byte 0xa1, 0xa1, 0xa1, 0xfe
61
sector_data_mark:
62
.byte 0xa1, 0xa1, 0xa1, 0xfb
63
64
mfm_read_addrmark:
65
movel %a6@(0x08), %a3
66
lea %a3@(read_handshake), %a2
67
lea %a3@(read_mark), %a3
68
moveq #-1, %d0
69
movew #seek_time, %d2
70
71
wait_header_init:
72
tstb %a3@(read_error - read_mark)
73
moveb #0x18, %a3@(write_mode0 - read_mark)
74
moveb #0x01, %a3@(write_mode1 - read_mark)
75
moveb #0x01, %a3@(write_mode0 - read_mark)
76
tstb %a3@(read_error - read_mark)
77
moveb #0x08, %a3@(write_mode1 - read_mark)
78
79
lea sector_address_mark, %a0
80
moveq #3, %d1
81
82
wait_addr_mark_byte:
83
84
tstb %a2@
85
dbmi %d2, wait_addr_mark_byte
86
bpl header_exit
87
88
moveb %a3@, %d3
89
cmpb %a0@+, %d3
90
dbne %d1, wait_addr_mark_byte
91
bne wait_header_init
92
93
moveq #max_retry, %d2
94
95
amark0: tstb %a2@
96
dbmi %d2, amark0
97
bpl signal_nonyb
98
99
moveb %a3@, %a4@(o_track)
100
101
moveq #max_retry, %d2
102
103
amark1: tstb %a2@
104
dbmi %d2, amark1
105
bpl signal_nonyb
106
107
moveb %a3@, %a4@(o_side)
108
109
moveq #max_retry, %d2
110
111
amark2: tstb %a2@
112
dbmi %d2, amark2
113
bpl signal_nonyb
114
115
moveb %a3@, %a4@(o_sector)
116
117
moveq #max_retry, %d2
118
119
amark3: tstb %a2@
120
dbmi %d2, amark3
121
bpl signal_nonyb
122
123
moveb %a3@, %a4@(o_size)
124
125
moveq #max_retry, %d2
126
127
crc0: tstb %a2@
128
dbmi %d2, crc0
129
bpl signal_nonyb
130
131
moveb %a3@, %a4@(o_crc0)
132
133
moveq #max_retry, %d2
134
135
crc1: tstb %a2@
136
dbmi %d2, crc1
137
bpl signal_nonyb
138
139
moveb %a3@, %a4@(o_crc1)
140
141
tstb %a3@(read_error - read_mark)
142
143
header_exit:
144
moveq #0, %d0
145
moveb #0x18, %a3@(write_mode0 - read_mark)
146
rts
147
signal_nonyb:
148
moveq #-1, %d0
149
moveb #0x18, %a3@(write_mode0 - read_mark)
150
rts
151
152
.global swim_read_sector_data
153
swim_read_sector_data:
154
link %a6, #0
155
moveml %d1-%d5/%a0-%a5,%sp@-
156
movel %a6@(0x0c), %a4
157
bsr mfm_read_data
158
moveml %sp@+, %d1-%d5/%a0-%a5
159
unlk %a6
160
rts
161
162
mfm_read_data:
163
movel %a6@(0x08), %a3
164
lea %a3@(read_handshake), %a2
165
lea %a3@(read_data), %a5
166
lea %a3@(read_mark), %a3
167
movew #seek_time, %d2
168
169
wait_data_init:
170
tstb %a3@(read_error - read_mark)
171
moveb #0x18, %a3@(write_mode0 - read_mark)
172
moveb #0x01, %a3@(write_mode1 - read_mark)
173
moveb #0x01, %a3@(write_mode0 - read_mark)
174
tstb %a3@(read_error - read_mark)
175
moveb #0x08, %a3@(write_mode1 - read_mark)
176
177
lea sector_data_mark, %a0
178
moveq #3, %d1
179
180
/* wait data address mark */
181
182
wait_data_mark_byte:
183
184
tstb %a2@
185
dbmi %d2, wait_data_mark_byte
186
bpl data_exit
187
188
moveb %a3@, %d3
189
cmpb %a0@+, %d3
190
dbne %d1, wait_data_mark_byte
191
bne wait_data_init
192
193
/* read data */
194
195
tstb %a3@(read_error - read_mark)
196
197
movel #sector_size-1, %d4 /* sector size */
198
read_new_data:
199
movew #max_retry, %d2
200
read_data_loop:
201
moveb %a2@, %d5
202
andb #0xc0, %d5
203
dbne %d2, read_data_loop
204
beq data_exit
205
moveb %a5@, %a4@+
206
andb #0x40, %d5
207
dbne %d4, read_new_data
208
beq exit_loop
209
moveb %a5@, %a4@+
210
dbra %d4, read_new_data
211
exit_loop:
212
213
/* read CRC */
214
215
movew #max_retry, %d2
216
data_crc0:
217
218
tstb %a2@
219
dbmi %d2, data_crc0
220
bpl data_exit
221
222
moveb %a3@, %d5
223
224
moveq #max_retry, %d2
225
226
data_crc1:
227
228
tstb %a2@
229
dbmi %d2, data_crc1
230
bpl data_exit
231
232
moveb %a3@, %d5
233
234
tstb %a3@(read_error - read_mark)
235
236
moveb #0x18, %a3@(write_mode0 - read_mark)
237
238
/* return number of bytes read */
239
240
movel #sector_size, %d0
241
addw #1, %d4
242
subl %d4, %d0
243
rts
244
data_exit:
245
moveb #0x18, %a3@(write_mode0 - read_mark)
246
moveq #-1, %d0
247
rts
248
249