1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * low-level functions for the SWIM floppy controller
5 * needs assembly language because is very timing dependent
6 * this controller exists only on macintosh 680x0 based
8 * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
10 * based on Alastair Bridgewater SWIM analysis, 2001
11 * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
13 * 2004-08-21 (lv) - Initial implementation
14 * 2008-11-05 (lv) - add get_swim_mode
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
45 .global swim_read_sector_header
46 swim_read_sector_header:
48 moveml %d1-%d5/%a0-%a4,%sp@-
51 moveml %sp@+, %d1-%d5/%a0-%a4
56 .byte 0xa1, 0xa1, 0xa1, 0xfe
58 .byte 0xa1, 0xa1, 0xa1, 0xfb
62 lea %a3@(read_handshake), %a2
63 lea %a3@(read_mark), %a3
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)
75 lea sector_address_mark, %a0
81 dbmi %d2, wait_addr_mark_byte
86 dbne %d1, wait_addr_mark_byte
95 moveb %a3@, %a4@(o_track)
103 moveb %a3@, %a4@(o_side)
105 moveq #max_retry, %d2
111 moveb %a3@, %a4@(o_sector)
113 moveq #max_retry, %d2
119 moveb %a3@, %a4@(o_size)
121 moveq #max_retry, %d2
127 moveb %a3@, %a4@(o_crc0)
129 moveq #max_retry, %d2
135 moveb %a3@, %a4@(o_crc1)
137 tstb %a3@(read_error - read_mark)
141 moveb #0x18, %a3@(write_mode0 - read_mark)
145 moveb #0x18, %a3@(write_mode0 - read_mark)
148 .global swim_read_sector_data
149 swim_read_sector_data:
151 moveml %d1-%d5/%a0-%a5,%sp@-
152 movel %a6@(0x0c), %a4
154 moveml %sp@+, %d1-%d5/%a0-%a5
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
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)
173 lea sector_data_mark, %a0
176 /* wait data address mark */
181 dbmi %d2, wait_data_mark_byte
186 dbne %d1, wait_data_mark_byte
191 tstb %a3@(read_error - read_mark)
193 movel #sector_size-1, %d4 /* sector size */
195 movew #max_retry, %d2
199 dbne %d2, read_data_loop
203 dbne %d4, read_new_data
206 dbra %d4, read_new_data
211 movew #max_retry, %d2
220 moveq #max_retry, %d2
230 tstb %a3@(read_error - read_mark)
232 moveb #0x18, %a3@(write_mode0 - read_mark)
234 /* return number of bytes read */
236 movel #sector_size, %d0
241 moveb #0x18, %a3@(write_mode0 - read_mark)