2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
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
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
;
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
43 if (ciaa
->ciapra
& 0x20)
45 ciab
->ciaprb
|= unitmask
; // SELX
47 if (unitNum
== 0 && HAVE_NO_DF0_DISK_ID
&& id
== DRT_EMPTY
)
49 DiskBase
->dr_UnitID
[unitNum
] = id
;
52 static AROS_INTH3(disk_index_interrupt
, struct DiscResource
*, DiskBase
, mask
, custom
)
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
,
67 static AROS_INTH3(disk_sync_interrupt
, struct DiscResource
*, DiskBase
, mask
, _custom
)
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
,
84 static AROS_INTH3(disk_block_interrupt
, struct DiscResource
*, DiskBase
, mask
, _custom
)
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
,
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
;
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
;
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);
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
;
146 SetIntVector(INTB_DSKSYNC
, inter
);
147 custom
->intena
= INTF_DSKSYNC
;
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
;
157 SetIntVector(INTB_DSKBLK
, inter
);
158 custom
->intena
= INTF_DSKBLK
;
162 for (i
= 0; i
< 4; i
++) {
163 readunitid_internal(DiskBase
, i
);
164 D(bug("DF%d: %08x\n", i
, DiskBase
->dr_UnitID
[i
]));