revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-amiga / disk / disk_intern_init.c
blob0b04908c110ce5a5e9f33642463a445e65f4f794
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/types.h>
7 #include <exec/alerts.h>
8 #include <exec/lists.h>
9 #include <exec/execbase.h>
11 #include <proto/disk.h>
12 #include <resources/disk.h>
13 #include <proto/cia.h>
15 #include <hardware/custom.h>
16 #include <hardware/cia.h>
17 #include <hardware/intbits.h>
19 #include <disk_intern.h>
21 #define HAVE_NO_DF0_DISK_ID 1
23 #define DEBUG 0
24 #include <aros/debug.h>
26 void readunitid_internal (struct DiscResource *DiskBase, LONG unitNum)
28 volatile struct CIA *ciaa = (struct CIA*)0xbfe001;
29 volatile struct CIA *ciab = (struct CIA*)0xbfd000;
30 UBYTE unitmask = 8 << unitNum;
31 ULONG id = 0;
32 UBYTE i;
34 ciab->ciaprb &= ~0x80; // MTR
35 ciab->ciaprb &= ~unitmask; // SELx
36 ciab->ciaprb |= unitmask; // SELX
37 ciab->ciaprb |= 0x80; // MTR
38 ciab->ciaprb &= ~unitmask; // SELx
39 ciab->ciaprb |= unitmask; // SELX
40 for (i = 0; i < 32; i++) {
41 ciab->ciaprb &= ~unitmask; // SELx
42 id <<= 1;
43 if (ciaa->ciapra & 0x20)
44 id |= 1;
45 ciab->ciaprb |= unitmask; // SELX
47 if (unitNum == 0 && HAVE_NO_DF0_DISK_ID && id == DRT_EMPTY)
48 id = DRT_AMIGA;
49 DiskBase->dr_UnitID[unitNum] = id;
52 static AROS_INTH3(disk_index_interrupt, struct DiscResource *, DiskBase, mask, custom)
54 AROS_INTFUNC_INIT
56 if (DiskBase->dr_Current && DiskBase->dr_Current->dru_Index.is_Code) {
57 D(bug("disk_index %p %p\n", DiskBase->dr_Current->dru_Index.is_Code, DiskBase->dr_Current->dru_Index.is_Data));
58 return AROS_INTC3(DiskBase->dr_Current->dru_Index.is_Code,
59 DiskBase->dr_Current->dru_Index.is_Data,
60 0, custom);
62 return 0;
64 AROS_INTFUNC_EXIT
67 static AROS_INTH3(disk_sync_interrupt, struct DiscResource *, DiskBase, mask, _custom)
69 AROS_INTFUNC_INIT
71 volatile struct Custom *custom = _custom;
72 custom->intreq = INTF_DSKSYNC;
73 if (DiskBase->dr_Current && DiskBase->dr_Current->dru_DiscSync.is_Code) {
74 D(bug("disk_sync %p %p\n", DiskBase->dr_Current->dru_DiscSync.is_Code, DiskBase->dr_Current->dru_DiscSync.is_Data));
75 return AROS_INTC3(DiskBase->dr_Current->dru_DiscSync.is_Code,
76 DiskBase->dr_Current->dru_DiscSync.is_Data,
77 0, custom);
79 return 0;
81 AROS_INTFUNC_EXIT
84 static AROS_INTH3(disk_block_interrupt, struct DiscResource *, DiskBase, mask, _custom)
86 AROS_INTFUNC_INIT
88 volatile struct Custom *custom = _custom;
89 custom->intreq = INTF_DSKBLK;
90 if (DiskBase->dr_Current && DiskBase->dr_Current->dru_DiscBlock.is_Code) {
91 D(bug("disk_block %p %p\n", DiskBase->dr_Current->dru_DiscBlock.is_Code, DiskBase->dr_Current->dru_DiscBlock.is_Data));
92 return AROS_INTC3(DiskBase->dr_Current->dru_DiscBlock.is_Code,
93 DiskBase->dr_Current->dru_DiscBlock.is_Data,
94 0, custom);
96 return FALSE;
98 AROS_INTFUNC_EXIT
101 BOOL disk_internal_init (struct DiscResource *DiskBase)
103 DiskBase->dr_SysLib = (struct Library*)SysBase;
105 volatile struct Custom *custom = (struct Custom*)0xdff000;
106 volatile struct CIA *ciaa = (struct CIA*)0xbfe001;
107 volatile struct CIA *ciab = (struct CIA*)0xbfd000;
108 struct Interrupt *inter;
109 UBYTE i;
111 DiskBase->dr_CiaResource = OpenResource("ciab.resource");
112 if (!DiskBase->dr_CiaResource)
113 Alert(AT_DeadEnd | AG_OpenRes | AO_DiskRsrc);
115 NEWLIST(&DiskBase->dr_Waiting);
117 ciaa->ciaddra &= ~(0x20 | 0x10 | 0x08 | 0x04); // RDY TK0 WPRO CHNG = input
118 ciab->ciaprb = 0xff; // inactive
119 ciab->ciaddrb = 0xff; // MTR SELx SIDE DIR STEP = inactive and output
121 custom->dsklen = 0x4000; // dsklen idle
122 custom->dmacon = 0x8010; // disk dma on
123 custom->dsksync = 0x4489; // sync
124 custom->adkcon = 0x7f00;
125 custom->adkcon = 0x8000 | 0x1000 | 0x0400 | 0x0100; // mfm, wordsync, fast
127 inter = &DiskBase->dr_Index;
128 inter->is_Node.ln_Pri = 0;
129 inter->is_Node.ln_Type = NT_INTERRUPT;
130 inter->is_Node.ln_Name = "disk index";
131 inter->is_Code = (APTR)disk_index_interrupt;
132 inter->is_Data = DiskBase;
133 Disable();
134 AddICRVector(DiskBase->dr_CiaResource, 4, inter); // CIA-B F = index
135 // don't want index interrupts unless requested
136 AbleICR(DiskBase->dr_CiaResource, 1 << 4);
137 Enable();
139 inter = &DiskBase->dr_DiscSync;
140 inter->is_Node.ln_Pri = 0;
141 inter->is_Node.ln_Type = NT_INTERRUPT;
142 inter->is_Node.ln_Name = "disk sync";
143 inter->is_Code = (APTR)disk_sync_interrupt;
144 inter->is_Data = DiskBase;
145 Disable();
146 SetIntVector(INTB_DSKSYNC, inter);
147 custom->intena = INTF_DSKSYNC;
148 Enable();
150 inter = &DiskBase->dr_DiscBlock;
151 inter->is_Node.ln_Pri = 0;
152 inter->is_Node.ln_Type = NT_INTERRUPT;
153 inter->is_Node.ln_Name = "disk dma done";
154 inter->is_Code = (APTR)disk_block_interrupt;
155 inter->is_Data = DiskBase;
156 Disable();
157 SetIntVector(INTB_DSKBLK, inter);
158 custom->intena = INTF_DSKBLK;
159 Enable();
161 // detect drives
162 for (i = 0; i < 4; i++) {
163 readunitid_internal(DiskBase, i);
164 D(bug("DF%d: %08x\n", i, DiskBase->dr_UnitID[i]));
167 return TRUE;