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