Linux Audio

Check our new training course

Loading...
v3.1
 
  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
v6.9.4
  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 <Laurent@lvivier.info>
  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
 46swim_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
 55sector_address_mark:
 56	.byte	0xa1, 0xa1, 0xa1, 0xfe
 57sector_data_mark:
 58	.byte	0xa1, 0xa1, 0xa1, 0xfb
 59
 60mfm_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
 67wait_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
 78wait_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
 91amark0:	tstb	%a2@
 92	dbmi	%d2, amark0
 93	bpl	signal_nonyb
 94
 95	moveb	%a3@, %a4@(o_track)
 96
 97	moveq	#max_retry, %d2
 98
 99amark1:	tstb	%a2@
100	dbmi	%d2, amark1
101	bpl	signal_nonyb
102
103	moveb	%a3@, %a4@(o_side)
104
105	moveq	#max_retry, %d2
106
107amark2:	tstb	%a2@
108	dbmi	%d2, amark2
109	bpl	signal_nonyb
110
111	moveb	%a3@, %a4@(o_sector)
112
113	moveq	#max_retry, %d2
114
115amark3:	tstb	%a2@
116	dbmi	%d2, amark3
117	bpl	signal_nonyb
118
119	moveb	%a3@, %a4@(o_size)
120
121	moveq	#max_retry, %d2
122
123crc0:	tstb	%a2@
124	dbmi	%d2, crc0
125	bpl	signal_nonyb
126
127	moveb	%a3@, %a4@(o_crc0)
128
129	moveq	#max_retry, %d2
130
131crc1:	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
139header_exit:
140	moveq	#0, %d0
141	moveb	#0x18, %a3@(write_mode0 - read_mark)
142	rts
143signal_nonyb:
144	moveq	#-1, %d0
145	moveb	#0x18, %a3@(write_mode0 - read_mark)
146	rts
147
148	.global swim_read_sector_data
149swim_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
158mfm_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
165wait_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
178wait_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 */
194read_new_data:
195	movew	#max_retry, %d2
196read_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
207exit_loop:
208
209	/* read CRC */
210
211	movew	#max_retry, %d2
212data_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
222data_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
240data_exit:
241	moveb	#0x18, %a3@(write_mode0 - read_mark)
242	moveq	#-1, %d0
243	rts