PageRenderTime 31ms CodeModel.GetById 19ms app.highlight 3ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/block/swim_asm.S

https://bitbucket.org/ndreys/linux-sunxi
Assembly | 247 lines | 193 code | 54 blank | 0 comment | 1 complexity | c4baf6043c019901dc05baa645a20b4c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  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