Root/drivers/block/swim_asm.S

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 <Laurent@lvivier.info>
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
50swim_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
59sector_address_mark:
60    .byte 0xa1, 0xa1, 0xa1, 0xfe
61sector_data_mark:
62    .byte 0xa1, 0xa1, 0xa1, 0xfb
63
64mfm_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
71wait_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
82wait_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
95amark0: tstb %a2@
96    dbmi %d2, amark0
97    bpl signal_nonyb
98
99    moveb %a3@, %a4@(o_track)
100
101    moveq #max_retry, %d2
102
103amark1: tstb %a2@
104    dbmi %d2, amark1
105    bpl signal_nonyb
106
107    moveb %a3@, %a4@(o_side)
108
109    moveq #max_retry, %d2
110
111amark2: tstb %a2@
112    dbmi %d2, amark2
113    bpl signal_nonyb
114
115    moveb %a3@, %a4@(o_sector)
116
117    moveq #max_retry, %d2
118
119amark3: tstb %a2@
120    dbmi %d2, amark3
121    bpl signal_nonyb
122
123    moveb %a3@, %a4@(o_size)
124
125    moveq #max_retry, %d2
126
127crc0: tstb %a2@
128    dbmi %d2, crc0
129    bpl signal_nonyb
130
131    moveb %a3@, %a4@(o_crc0)
132
133    moveq #max_retry, %d2
134
135crc1: 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
143header_exit:
144    moveq #0, %d0
145    moveb #0x18, %a3@(write_mode0 - read_mark)
146    rts
147signal_nonyb:
148    moveq #-1, %d0
149    moveb #0x18, %a3@(write_mode0 - read_mark)
150    rts
151
152    .global swim_read_sector_data
153swim_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
162mfm_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
169wait_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
182wait_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 */
198read_new_data:
199    movew #max_retry, %d2
200read_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
211exit_loop:
212
213    /* read CRC */
214
215    movew #max_retry, %d2
216data_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
226data_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
244data_exit:
245    moveb #0x18, %a3@(write_mode0 - read_mark)
246    moveq #-1, %d0
247    rts
248

Archive Download this file



interactive