Synchronized with documentations/db/credits.
[AROS.git] / rom / devs / trackdisk / trackdisk_hw.h
blob1132f56002a5868a7581b4822fafedb461521144
1 #ifndef TRACKDISK_HW_H
2 #define TRACKDISK_HW_H
4 /*
5 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
6 $Id$
8 Desc: Hardware defs for trackdisk
9 Lang: English
12 #include <exec/types.h>
13 #include <asm/io.h>
15 /* Prototypes */
16 void td_motoron(UBYTE,struct TrackDiskBase *,BOOL);
17 void td_select(UBYTE,struct TrackDiskBase *);
18 void td_motoroff(UBYTE,struct TrackDiskBase *);
19 UBYTE td_getprotstatus(UBYTE,struct TrackDiskBase *);
20 int td_dinit(struct TrackDiskBase *);
21 int td_recalibrate(unsigned char, char, int, struct TrackDiskBase *);
22 int td_rseek(UBYTE , UBYTE , UBYTE , struct TrackDiskBase *);
23 int td_read(struct IOExtTD *, struct TrackDiskBase *);
24 int td_write(struct IOExtTD *, struct TrackDiskBase *);
25 int td_update(struct TDU *, struct TrackDiskBase *);
26 int td_format(struct IOExtTD *, struct TrackDiskBase *);
27 int td_waitint(struct TrackDiskBase *,UBYTE,BOOL);
28 UBYTE td_getDiskChange(void);
32 Drive parameters.
33 There is only one possible drive type at this moment - 1.44MB 3.5" floppy.
34 5.25" floppies are not supported at this moment. In future one should add other
35 drives support (including 2.88MB drives).
38 #define DP_STOTAL 2880 /* Sectors total */
39 #define DP_SECTORS 18 /* Sectors per cyl */
40 #define DP_SIDES 2 /* No of sides */
41 #define DP_TRACKS 80
42 #define DP_GAP1 0x1b /* Gap for reading */
43 #define DP_SPEC1 0xc1 /* SRT=4ms, HUT=16ms */
44 #define DP_GAP2 0x6c /* Gap for formatting */
45 #define DP_SPEC2 0x10 /* HLT=16ms, use DMA */
46 #define DP_SSIZE 0x02 /* SectSize=512b */
48 /* I/O ports used by the FDC */
49 #define FDC_SRB 0x3f1 /* Status register B */
50 #define FDC_DOR 0x3f2 /* Digital output register */
51 #define FDC_TDR 0x3f3 /* Tape drive register */
52 #define FDC_MSR 0x3f4 /* Main status register (R) */
53 #define FDC_DSR 0x3f4 /* Data rate select (W) */
54 #define FDC_FIFO 0x3f5 /* FIFO */
55 #define FDC_DIR 0x3f7 /* Digital input register (R) */
56 #define FDC_CCR 0x3f7 /* Configuration control register (W) */
58 /* Status register B bits */
59 #define SRBB_IDLE 0x00
60 #define SRBB_PD 0x01
61 #define SRBB_IDLEMSK 0x02
63 #define SRBF_IDLE (1<<SRBB_IDLE)
64 #define SRBF_PD (1<<SRBB_PD)
65 #define SRBF_IDLEMSK (1<<SRBB_IDLEMSK)
67 /* Digital output register bits */
68 #define DORB_DSEL 0x00
69 #define DORB_RESET 0x02
70 #define DORB_DMA 0x03
71 #define DORB_MOT0 0x04
72 #define DORB_MOT1 0x05
74 #define DORF_DSEL (1<<DORB_DSEL)
75 #define DORF_RESET (1<<DORB_RESET)
76 #define DORF_DMA (1<<DORB_DMA)
77 #define DORF_MOT0 (1<<DORB_MOT0)
78 #define DORF_MOT1 (1<<DORB_MOT1)
80 /* Tape drive register bits */
81 #define TDRB_TS0 0x00
82 #define TDRB_TS1 0x01
83 #define TDRB_BSEL 0x02
85 #define TDRF_TS0 (1<<TDRB_TS0)
86 #define TDRF_TS1 (1<<TDRB_TS1)
87 #define TDRF_BSEL (1<<TDRB_BSEL)
89 /* Main status register bits */
90 #define MSRB_D0BSY 0x00
91 #define MSRB_D1BSY 0x01
92 #define MSRB_CMDBSY 0x04
93 #define MSRB_NONDMA 0x05
94 #define MSRB_DIO 0x06
95 #define MSRB_RQM 0x07
97 #define MSRF_D0BSY (1<<MSRB_D0BSY)
98 #define MSRF_D1BSY (1<<MSRB_D1BSY)
99 #define MSRF_CMDBSY (1<<MSRB_CMDBSY)
100 #define MSRF_NONDMA (1<<MSRB_NONDMA)
101 #define MSRF_DIO (1<<MSRB_DIO)
102 #define MSRF_RQM (1<<MSRB_RQM)
104 /* Datarate select bits */
105 #define DSRB_DRATE0 0x00
106 #define DSRB_DRATE1 0x01
107 #define DSRB_PCOMP0 0x02
108 #define DSRB_PCOMP1 0x03
109 #define DSRB_PCOMP2 0x04
110 #define DSRB_PDOSC 0x05
111 #define DSRB_PDOWN 0x06
112 #define DSRB_RESET 0x07
114 #define DSRF_DRATE0 (1<<DSRB_DRATE0)
115 #define DSRF_DRATE1 (1<<DSRB_DRATE1)
116 #define DSRF_PCOMP0 (1<<DSRB_PCOMP0)
117 #define DSRF_PCOMP1 (1<<DSRB_PCOMP1)
118 #define DSRF_PCOMP2 (1<<DSRB_PCOMP2)
119 #define DSRF_PDOSC (1<<DSRB_PDOSC)
120 #define DSRF_PDOWN (1<<DSRB_PDOWN)
121 #define DSRF_RESET (1<<DSRB_RESET)
123 /* Digital input register bits */
124 #define DIRB_DCHG 0x07
126 #define DIRF_DCHG (1<<DIRB_DCHG)
128 /* Bits of FD_ST0 */
129 #define ST0_DS 0x03 /* drive select mask */
130 #define ST0_HA 0x04 /* Head (Address) */
131 #define ST0_NR 0x08 /* Not Ready */
132 #define ST0_ECE 0x10 /* Equipment check error */
133 #define ST0_SE 0x20 /* Seek end */
134 #define ST0_INTR 0xC0 /* Interrupt code mask */
136 /* Bits of FD_ST1 */
137 #define ST1_MAM 0x01 /* Missing Address Mark */
138 #define ST1_WP 0x02 /* Write Protect */
139 #define ST1_ND 0x04 /* No Data - unreadable */
140 #define ST1_OR 0x10 /* OverRun */
141 #define ST1_CRC 0x20 /* CRC error in data or addr */
142 #define ST1_EOC 0x80 /* End Of Cylinder */
144 /* Bits of FD_ST2 */
145 #define ST2_MAM 0x01 /* Missing Address Mark (again) */
146 #define ST2_BC 0x02 /* Bad Cylinder */
147 #define ST2_SNS 0x04 /* Scan Not Satisfied */
148 #define ST2_SEH 0x08 /* Scan Equal Hit */
149 #define ST2_WC 0x10 /* Wrong Cylinder */
150 #define ST2_CRC 0x20 /* CRC error in data field */
151 #define ST2_CM 0x40 /* Control Mark = deleted */
153 /* Bits of FD_ST3 */
154 #define ST3_HA 0x04 /* Head (Address) */
155 #define ST3_DS 0x08 /* drive is double-sided */
156 #define ST3_TZ 0x10 /* Track Zero signal (1=track 0) */
157 #define ST3_RY 0x20 /* drive is ready */
158 #define ST3_WP 0x40 /* Write Protect */
159 #define ST3_FT 0x80 /* Drive Fault */
161 /* Values for FD_COMMAND */
162 #define FD_RECALIBRATE 0x07 /* move to track 0 */
163 #define FD_SEEK 0x0F /* seek track */
164 #define FD_READ 0x66 /* read with MFM, SKip deleted */
165 #define FD_WRITE 0x45 /* write with MFM */
166 #define FD_SENSEI 0x08 /* Sense Interrupt Status */
167 #define FD_SPECIFY 0x03 /* specify HUT etc */
168 #define FD_FORMAT 0x4D /* format one track */
169 #define FD_VERSION 0x10 /* get version code */
170 #define FD_PARTID 0x18 /* get part id */
171 #define FD_CONFIGURE 0x13 /* configure FIFO operation */
172 #define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */
173 #define FD_GETSTATUS 0x04 /* read ST3 */
174 #define FD_DUMPREGS 0x0E /* dump the contents of the fdc regs */
175 #define FD_READID 0x4A /* prints the header of a sector */
176 #define FD_UNLOCK 0x14 /* Fifo config unlock */
177 #define FD_LOCK 0x94 /* Fifo config lock */
178 #define FD_RSEEK_OUT 0x8F /* seek out (i.e. to lower tracks) */
179 #define FD_RSEEK_IN 0xCF /* seek in (i.e. to higher tracks) */
180 #define FD_PDMODE 0x17 /* Configure powerdown mode */
185 * This really should be somewhere else, like in a hidd.dma or so
186 * And it should not look like this, considering licenses etc.
189 /* DMA section based on linuxish /asm/dma.h */
191 #define dma_outb outb
192 #define dma_inb inb
193 #define MAX_DMA_CHANNELS 8
195 /* The maximum address that we can perform a DMA transfer to on this platform */
196 #define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000)
198 /* 8237 DMA controllers */
199 #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
200 #define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
202 /* DMA controller registers */
203 #define DMA1_CMD_REG 0x08 /* command register (w) */
204 #define DMA1_STAT_REG 0x08 /* status register (r) */
205 #define DMA1_REQ_REG 0x09 /* request register (w) */
206 #define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
207 #define DMA1_MODE_REG 0x0B /* mode register (w) */
208 #define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
209 #define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
210 #define DMA1_RESET_REG 0x0D /* Master Clear (w) */
211 #define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
212 #define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
214 #define DMA2_CMD_REG 0xD0 /* command register (w) */
215 #define DMA2_STAT_REG 0xD0 /* status register (r) */
216 #define DMA2_REQ_REG 0xD2 /* request register (w) */
217 #define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
218 #define DMA2_MODE_REG 0xD6 /* mode register (w) */
219 #define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
220 #define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
221 #define DMA2_RESET_REG 0xDA /* Master Clear (w) */
222 #define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
223 #define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
225 #define DMA_ADDR_0 0x00 /* DMA address registers */
226 #define DMA_ADDR_1 0x02
227 #define DMA_ADDR_2 0x04
228 #define DMA_ADDR_3 0x06
229 #define DMA_ADDR_4 0xC0
230 #define DMA_ADDR_5 0xC4
231 #define DMA_ADDR_6 0xC8
232 #define DMA_ADDR_7 0xCC
234 #define DMA_CNT_0 0x01 /* DMA count registers */
235 #define DMA_CNT_1 0x03
236 #define DMA_CNT_2 0x05
237 #define DMA_CNT_3 0x07
238 #define DMA_CNT_4 0xC2
239 #define DMA_CNT_5 0xC6
240 #define DMA_CNT_6 0xCA
241 #define DMA_CNT_7 0xCE
243 #define DMA_PAGE_0 0x87 /* DMA page registers */
244 #define DMA_PAGE_1 0x83
245 #define DMA_PAGE_2 0x81
246 #define DMA_PAGE_3 0x82
247 #define DMA_PAGE_5 0x8B
248 #define DMA_PAGE_6 0x89
249 #define DMA_PAGE_7 0x8A
251 #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
252 #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
253 #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
255 #define DMA_AUTOINIT 0x10
257 /* enable/disable a specific DMA channel */
258 static __inline__ void enable_dma(unsigned int dmanr)
260 if (dmanr<=3)
261 dma_outb(dmanr, DMA1_MASK_REG);
262 else
263 dma_outb(dmanr & 3, DMA2_MASK_REG);
266 static __inline__ void disable_dma(unsigned int dmanr)
268 if (dmanr<=3)
269 dma_outb(dmanr | 4, DMA1_MASK_REG);
270 else
271 dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
274 /* Clear the 'DMA Pointer Flip Flop'.
275 * Write 0 for LSB/MSB, 1 for MSB/LSB access.
276 * Use this once to initialize the FF to a known state.
277 * After that, keep track of it. :-)
278 * --- In order to do that, the DMA routines below should ---
279 * --- only be used while holding the DMA lock ! ---
281 static __inline__ void clear_dma_ff(unsigned int dmanr)
283 if (dmanr<=3)
284 dma_outb(0, DMA1_CLEAR_FF_REG);
285 else
286 dma_outb(0, DMA2_CLEAR_FF_REG);
289 /* set mode (above) for a specific DMA channel */
290 static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
292 if (dmanr<=3)
293 dma_outb(mode | dmanr, DMA1_MODE_REG);
294 else
295 dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
298 /* Set only the page register bits of the transfer address.
299 * This is used for successive transfers when we know the contents of
300 * the lower 16 bits of the DMA current address register, but a 64k boundary
301 * may have been crossed.
303 static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
305 switch(dmanr) {
306 case 0:
307 dma_outb(pagenr, DMA_PAGE_0);
308 break;
309 case 1:
310 dma_outb(pagenr, DMA_PAGE_1);
311 break;
312 case 2:
313 dma_outb(pagenr, DMA_PAGE_2);
314 break;
315 case 3:
316 dma_outb(pagenr, DMA_PAGE_3);
317 break;
318 case 5:
319 dma_outb(pagenr & 0xfe, DMA_PAGE_5);
320 break;
321 case 6:
322 dma_outb(pagenr & 0xfe, DMA_PAGE_6);
323 break;
324 case 7:
325 dma_outb(pagenr & 0xfe, DMA_PAGE_7);
326 break;
330 /* Set transfer address & page bits for specific DMA channel.
331 * Assumes dma flipflop is clear.
333 static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
335 set_dma_page(dmanr, a>>16);
336 if (dmanr <= 3) {
337 dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
338 dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
339 } else {
340 dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
341 dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
346 /* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
347 * a specific DMA channel.
348 * You must ensure the parameters are valid.
349 * NOTE: from a manual: "the number of transfers is one more
350 * than the initial word count"! This is taken into account.
351 * Assumes dma flip-flop is clear.
352 * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
354 static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
356 count--;
357 if (dmanr <= 3) {
358 dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
359 dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
360 } else {
361 dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
362 dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
366 #endif /* TRACKDISK_HW_H */