2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
10 #include <aros/debug.h>
11 #include "expansion_intern.h"
12 #include <proto/expansion.h>
13 #include <aros/asmcall.h>
15 /* See rom/expansion/configboard.c for documentation */
17 #define Z3SLOT 0x01000000
19 /* do not touch. Ugly hack. UAE direct JIT versions need this */
20 /* check UAE expansion.c for ugly details */
21 AROS_UFH5(void, writeexpansion
,
22 AROS_UFHA(APTR
, board
, A0
),
23 AROS_UFHA(APTR
, configdev
, A3
), // <- configdev = A3. This is important.
24 AROS_UFHA(UBYTE
, type
, D0
),
25 AROS_UFHA(UWORD
, startaddr
, D1
),
26 AROS_UFHA(struct ExpansionBase
*, ExpansionBase
, A6
))
30 if (type
== ERT_ZORROII
) {
31 WriteExpansionByte(board
, 18, startaddr
);
33 WriteExpansionWord(board
, 17, startaddr
);
40 #include <clib/expansion_protos.h>
42 AROS_LH2(BOOL
, ConfigBoard
,
43 AROS_LHA(APTR
, board
, A0
),
44 AROS_LHA(struct ConfigDev
*, configDev
, A1
),
45 struct ExpansionBase
*, ExpansionBase
, 10, Expansion
)
49 UBYTE type
= configDev
->cd_Rom
.er_Type
& ERT_TYPEMASK
;
50 ULONG size
= configDev
->cd_BoardSize
;
52 D(bug("Configuring board: cd=%p mfg=%d prod=%d size=%08x type=%02x\n",
53 configDev
, configDev
->cd_Rom
.er_Manufacturer
, configDev
->cd_Rom
.er_Product
, size
, configDev
->cd_Rom
.er_Type
));
55 if (type
== ERT_ZORROIII
) {
56 UWORD prevslot
, newslot
;
58 UWORD slotsize
= (size
+ 0x00ffffff) / Z3SLOT
;
59 if (IntExpBase(ExpansionBase
)->z3Slot
== 0)
60 IntExpBase(ExpansionBase
)->z3Slot
= 0x40000000 / Z3SLOT
;
61 prevslot
= IntExpBase(ExpansionBase
)->z3Slot
;
63 newslot
= (prevslot
+ slotsize
- 1) & ~(slotsize
- 1);
64 D(bug("size=%d prev=%d new=%d end=%d\n", slotsize
, prevslot
, newslot
, endslot
));
65 if (newslot
+ slotsize
<= endslot
) {
66 ULONG startaddr
= newslot
* Z3SLOT
;
67 configDev
->cd_BoardAddr
= (APTR
)startaddr
;
68 configDev
->cd_SlotAddr
= IntExpBase(ExpansionBase
)->z3Slot
;
69 configDev
->cd_SlotSize
= slotsize
;
70 configDev
->cd_Flags
|= CDF_CONFIGME
;
71 IntExpBase(ExpansionBase
)->z3Slot
= newslot
+ slotsize
;
72 AROS_UFC5NR(void, writeexpansion
,
73 AROS_UFCA(APTR
, board
, A0
),
74 AROS_UFCA(APTR
, configDev
, A3
),
75 AROS_UFCA(UBYTE
, type
, D0
),
76 AROS_UFCA(UWORD
, (startaddr
>> 16), D1
),
77 AROS_UFCA(struct ExpansionBase
*, ExpansionBase
, A6
)
79 D(bug("-> configured, %p - %p\n", startaddr
, startaddr
+ configDev
->cd_BoardSize
- 1));
83 ULONG start
, end
, addr
, step
;
87 for (area
= 0; area
< 2; area
++) {
89 if (area
== 0 && size
>= 8 * E_SLOTSIZE
)
99 space
= IntExpBase(ExpansionBase
)->z2Slots
;
101 for (addr
= start
; addr
< end
; addr
+= step
) {
102 ULONG startaddr
= addr
;
103 UWORD offset
= startaddr
/ (E_SLOTSIZE
* SLOTSPERBYTE
);
104 BYTE bit
= 7 - ((startaddr
/ E_SLOTSIZE
) % SLOTSPERBYTE
);
105 UBYTE res
= space
[offset
];
106 ULONG sizeleft
= size
;
108 if (res
& (1 << bit
))
111 if (size
< 4 * 1024 * 1024) {
112 // handle alignment, 128k boards must be 128k aligned and so on..
113 if ((startaddr
& (size
- 1)) != 0)
116 // 4M and 8M boards have different alignment requirements
117 if (startaddr
!= 0x00200000 && startaddr
!= 0x00600000)
121 // found free start address
122 if (size
>= E_SLOTSIZE
* SLOTSPERBYTE
) {
123 // needs at least 1 byte and is always aligned to byte
124 while (space
[offset
] == 0 && sizeleft
>= E_SLOTSIZE
&& offset
<= end
/ (E_SLOTSIZE
* SLOTSPERBYTE
)) {
126 sizeleft
-= E_SLOTSIZE
* SLOTSPERBYTE
;
129 // bit by bit small board check (fits in one byte)
130 while ((res
& (1 << bit
)) == 0 && sizeleft
>= E_SLOTSIZE
&& bit
>= 0) {
131 sizeleft
-= E_SLOTSIZE
;
136 if (sizeleft
>= E_SLOTSIZE
)
139 configDev
->cd_BoardAddr
= (APTR
)startaddr
;
140 configDev
->cd_Flags
|= CDF_CONFIGME
;
141 configDev
->cd_SlotAddr
= (startaddr
>> 16);
142 configDev
->cd_SlotSize
= size
>> 16;
143 AROS_UFC5NR(void, writeexpansion
,
144 AROS_UFCA(APTR
, board
, A0
),
145 AROS_UFCA(APTR
, configDev
, A3
),
146 AROS_UFCA(UBYTE
, type
, D0
),
147 AROS_UFCA(UWORD
, (startaddr
>> 16), D1
),
148 AROS_UFCA(struct ExpansionBase
*, ExpansionBase
, A6
)
150 D(bug("-> configured, %p - %p\n", startaddr
, startaddr
+ configDev
->cd_BoardSize
- 1));
152 // do not remove this, configDev->cd_BoardAddr
153 // might have changed inside writeexpansion
154 startaddr
= (ULONG
)configDev
->cd_BoardAddr
;
155 offset
= startaddr
/ (E_SLOTSIZE
* SLOTSPERBYTE
);
156 bit
= 7 - ((startaddr
/ E_SLOTSIZE
) % SLOTSPERBYTE
);
158 // now allocate area we reserved
159 while (sizeleft
>= E_SLOTSIZE
) {
160 space
[offset
] |= 1 << bit
;
161 sizeleft
-= E_SLOTSIZE
;
170 D(bug("Configuration failed!\n"));
171 if (!(configDev
->cd_Flags
& ERFF_NOSHUTUP
)) {
172 configDev
->cd_Flags
|= CDF_SHUTUP
;
173 WriteExpansionByte(board
, 19, 0); // SHUT-UP!