2 #include <exec/types.h>
3 #include <exec/alerts.h>
4 #include <exec/lists.h>
5 #include <exec/execbase.h>
7 #include <proto/disk.h>
8 #include <resources/disk.h>
11 #include <hardware/custom.h>
12 #include <hardware/cia.h>
13 #include <hardware/intbits.h>
15 #include <disk_intern.h>
17 #define HAVE_NO_DF0_DISK_ID 1
20 #include <aros/debug.h>
22 void readunitid_internal (struct DiscResource
*DiskBase
, LONG unitNum
)
24 volatile struct CIA
*ciaa
= (struct CIA
*)0xbfe001;
25 volatile struct CIA
*ciab
= (struct CIA
*)0xbfd000;
26 UBYTE unitmask
= 8 << unitNum
;
30 ciab
->ciaprb
&= ~0x80; // MTR
31 ciab
->ciaprb
&= ~unitmask
; // SELx
32 ciab
->ciaprb
|= unitmask
; // SELX
33 ciab
->ciaprb
|= 0x80; // MTR
34 ciab
->ciaprb
&= ~unitmask
; // SELx
35 ciab
->ciaprb
|= unitmask
; // SELX
36 for (i
= 0; i
< 32; i
++) {
37 ciab
->ciaprb
&= ~unitmask
; // SELx
39 if (ciaa
->ciapra
& 0x20)
41 ciab
->ciaprb
|= unitmask
; // SELX
43 if (unitNum
== 0 && HAVE_NO_DF0_DISK_ID
&& id
== DRT_EMPTY
)
45 DiskBase
->dr_UnitID
[unitNum
] = id
;
48 static AROS_INTH3(disk_index_interrupt
, struct DiscResource
*, DiskBase
, mask
, custom
)
52 if (DiskBase
->dr_Current
&& DiskBase
->dr_Current
->dru_Index
.is_Code
) {
53 D(bug("disk_index %p %p\n", DiskBase
->dr_Current
->dru_Index
.is_Code
, DiskBase
->dr_Current
->dru_Index
.is_Data
));
54 return AROS_INTC3(DiskBase
->dr_Current
->dru_Index
.is_Code
,
55 DiskBase
->dr_Current
->dru_Index
.is_Data
,
63 static AROS_INTH3(disk_sync_interrupt
, struct DiscResource
*, DiskBase
, mask
, _custom
)
67 volatile struct Custom
*custom
= _custom
;
68 custom
->intreq
= INTF_DSKSYNC
;
69 if (DiskBase
->dr_Current
&& DiskBase
->dr_Current
->dru_DiscSync
.is_Code
) {
70 D(bug("disk_sync %p %p\n", DiskBase
->dr_Current
->dru_DiscSync
.is_Code
, DiskBase
->dr_Current
->dru_DiscSync
.is_Data
));
71 return AROS_INTC3(DiskBase
->dr_Current
->dru_DiscSync
.is_Code
,
72 DiskBase
->dr_Current
->dru_DiscSync
.is_Data
,
80 static AROS_INTH3(disk_block_interrupt
, struct DiscResource
*, DiskBase
, mask
, _custom
)
84 volatile struct Custom
*custom
= _custom
;
85 custom
->intreq
= INTF_DSKBLK
;
86 if (DiskBase
->dr_Current
&& DiskBase
->dr_Current
->dru_DiscBlock
.is_Code
) {
87 D(bug("disk_block %p %p\n", DiskBase
->dr_Current
->dru_DiscBlock
.is_Code
, DiskBase
->dr_Current
->dru_DiscBlock
.is_Data
));
88 return AROS_INTC3(DiskBase
->dr_Current
->dru_DiscBlock
.is_Code
,
89 DiskBase
->dr_Current
->dru_DiscBlock
.is_Data
,
97 BOOL
disk_internal_init (struct DiscResource
*DiskBase
)
99 DiskBase
->dr_SysLib
= (struct Library
*)SysBase
;
101 volatile struct Custom
*custom
= (struct Custom
*)0xdff000;
102 volatile struct CIA
*ciaa
= (struct CIA
*)0xbfe001;
103 volatile struct CIA
*ciab
= (struct CIA
*)0xbfd000;
104 struct Interrupt
*inter
;
107 DiskBase
->dr_CiaResource
= OpenResource("ciab.resource");
108 if (!DiskBase
->dr_CiaResource
)
109 Alert(AT_DeadEnd
| AG_OpenRes
| AO_DiskRsrc
);
111 NEWLIST(&DiskBase
->dr_Waiting
);
113 ciaa
->ciaddra
&= ~(0x20 | 0x10 | 0x08 | 0x04); // RDY TK0 WPRO CHNG = input
114 ciab
->ciaprb
= 0xff; // inactive
115 ciab
->ciaddrb
= 0xff; // MTR SELx SIDE DIR STEP = inactive and output
117 custom
->dsklen
= 0x4000; // dsklen idle
118 custom
->dmacon
= 0x8010; // disk dma on
119 custom
->dsksync
= 0x4489; // sync
120 custom
->adkcon
= 0x7f00;
121 custom
->adkcon
= 0x8000 | 0x1000 | 0x0400 | 0x0100; // mfm, wordsync, fast
123 inter
= &DiskBase
->dr_Index
;
124 inter
->is_Node
.ln_Pri
= 0;
125 inter
->is_Node
.ln_Type
= NT_INTERRUPT
;
126 inter
->is_Node
.ln_Name
= "disk index";
127 inter
->is_Code
= (APTR
)disk_index_interrupt
;
128 inter
->is_Data
= DiskBase
;
130 AddICRVector(DiskBase
->dr_CiaResource
, 4, inter
); // CIA-B F = index
131 // don't want index interrupts unless requested
132 AbleICR(DiskBase
->dr_CiaResource
, 1 << 4);
135 inter
= &DiskBase
->dr_DiscSync
;
136 inter
->is_Node
.ln_Pri
= 0;
137 inter
->is_Node
.ln_Type
= NT_INTERRUPT
;
138 inter
->is_Node
.ln_Name
= "disk sync";
139 inter
->is_Code
= (APTR
)disk_sync_interrupt
;
140 inter
->is_Data
= DiskBase
;
142 SetIntVector(INTB_DSKSYNC
, inter
);
143 custom
->intena
= INTF_DSKSYNC
;
146 inter
= &DiskBase
->dr_DiscBlock
;
147 inter
->is_Node
.ln_Pri
= 0;
148 inter
->is_Node
.ln_Type
= NT_INTERRUPT
;
149 inter
->is_Node
.ln_Name
= "disk dma done";
150 inter
->is_Code
= (APTR
)disk_block_interrupt
;
151 inter
->is_Data
= DiskBase
;
153 SetIntVector(INTB_DSKBLK
, inter
);
154 custom
->intena
= INTF_DSKBLK
;
158 for (i
= 0; i
< 4; i
++) {
159 readunitid_internal(DiskBase
, i
);
160 D(bug("DF%d: %08x\n", i
, DiskBase
->dr_UnitID
[i
]));