2 * low-level functions for the SWIM floppy controller
4 * needs assembly language because is very timing dependent
5 * this controller exists only on macintosh 680x0 based
7 * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
9 * based on Alastair Bridgewater SWIM analysis, 2001
10 * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
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.
17 * 2004-08-21 (lv) - Initial implementation
18 * 2008-11-05 (lv) - add get_swim_mode
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
49 .global swim_read_sector_header
50 swim_read_sector_header:
52 moveml %d1-%d5/%a0-%a4,%sp@-
55 moveml %sp@+, %d1-%d5/%a0-%a4
60 .byte 0xa1, 0xa1, 0xa1, 0xfe
62 .byte 0xa1, 0xa1, 0xa1, 0xfb
66 lea %a3@(read_handshake), %a2
67 lea %a3@(read_mark), %a3
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)
79 lea sector_address_mark, %a0
85 dbmi %d2, wait_addr_mark_byte
90 dbne %d1, wait_addr_mark_byte
99 moveb %a3@, %a4@(o_track)
101 moveq #max_retry, %d2
107 moveb %a3@, %a4@(o_side)
109 moveq #max_retry, %d2
115 moveb %a3@, %a4@(o_sector)
117 moveq #max_retry, %d2
123 moveb %a3@, %a4@(o_size)
125 moveq #max_retry, %d2
131 moveb %a3@, %a4@(o_crc0)
133 moveq #max_retry, %d2
139 moveb %a3@, %a4@(o_crc1)
141 tstb %a3@(read_error - read_mark)
145 moveb #0x18, %a3@(write_mode0 - read_mark)
149 moveb #0x18, %a3@(write_mode0 - read_mark)
152 .global swim_read_sector_data
153 swim_read_sector_data:
155 moveml %d1-%d5/%a0-%a5,%sp@-
156 movel %a6@(0x0c), %a4
158 moveml %sp@+, %d1-%d5/%a0-%a5
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
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)
177 lea sector_data_mark, %a0
180 /* wait data address mark */
185 dbmi %d2, wait_data_mark_byte
190 dbne %d1, wait_data_mark_byte
195 tstb %a3@(read_error - read_mark)
197 movel #sector_size-1, %d4 /* sector size */
199 movew #max_retry, %d2
203 dbne %d2, read_data_loop
207 dbne %d4, read_new_data
210 dbra %d4, read_new_data
215 movew #max_retry, %d2
224 moveq #max_retry, %d2
234 tstb %a3@(read_error - read_mark)
236 moveb #0x18, %a3@(write_mode0 - read_mark)
238 /* return number of bytes read */
240 movel #sector_size, %d0
245 moveb #0x18, %a3@(write_mode0 - read_mark)