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
;
51 ULONG size
= configDev
->cd_BoardSize
;
53 D(bug("Configuring board: cd=%p mfg=%d prod=%d size=%08x type=%02x\n",
54 configDev
, configDev
->cd_Rom
.er_Manufacturer
, configDev
->cd_Rom
.er_Product
, size
, configDev
->cd_Rom
.er_Type
));
56 memorydevice
= (configDev
->cd_Rom
.er_Type
& ERTF_MEMLIST
) != 0;
57 if (type
== ERT_ZORROIII
) {
58 UWORD prevslot
, newslot
;
60 UWORD slotsize
= (size
+ 0x00ffffff) / Z3SLOT
;
61 if (IntExpBase(ExpansionBase
)->z3Slot
== 0)
62 IntExpBase(ExpansionBase
)->z3Slot
= 0x40000000 / Z3SLOT
;
63 prevslot
= IntExpBase(ExpansionBase
)->z3Slot
;
65 newslot
= (prevslot
+ slotsize
- 1) & ~(slotsize
- 1);
66 D(bug("size=%d prev=%d new=%d end=%d\n", slotsize
, prevslot
, newslot
, endslot
));
67 if (newslot
+ slotsize
<= endslot
) {
68 ULONG startaddr
= newslot
* Z3SLOT
;
69 configDev
->cd_BoardAddr
= (APTR
)startaddr
;
70 configDev
->cd_SlotAddr
= IntExpBase(ExpansionBase
)->z3Slot
;
71 configDev
->cd_SlotSize
= slotsize
;
72 configDev
->cd_Flags
|= CDF_CONFIGME
;
73 IntExpBase(ExpansionBase
)->z3Slot
= newslot
+ slotsize
;
74 AROS_UFC5NR(void, writeexpansion
,
75 AROS_UFCA(APTR
, board
, A0
),
76 AROS_UFCA(APTR
, configDev
, A3
),
77 AROS_UFCA(UBYTE
, type
, D0
),
78 AROS_UFCA(UWORD
, (startaddr
>> 16), D1
),
79 AROS_UFCA(struct ExpansionBase
*, ExpansionBase
, A6
)
81 D(bug("-> configured, %p - %p\n", startaddr
, startaddr
+ configDev
->cd_BoardSize
- 1));
85 ULONG start
, end
, addr
, step
;
89 for (area
= 0; area
< 2; area
++) {
91 if (area
== 0 && (size
>= 8 * E_SLOTSIZE
|| memorydevice
))
101 space
= IntExpBase(ExpansionBase
)->z2Slots
;
103 for (addr
= start
; addr
< end
; addr
+= step
) {
104 ULONG startaddr
= addr
;
105 UWORD offset
= startaddr
/ (E_SLOTSIZE
* SLOTSPERBYTE
);
106 BYTE bit
= 7 - ((startaddr
/ E_SLOTSIZE
) % SLOTSPERBYTE
);
107 UBYTE res
= space
[offset
];
108 ULONG sizeleft
= size
;
110 if (res
& (1 << bit
))
113 if (size
< 4 * 1024 * 1024) {
114 // handle alignment, 128k boards must be 128k aligned and so on..
115 if ((startaddr
& (size
- 1)) != 0)
118 // 4M and 8M boards have different alignment requirements
119 if (startaddr
!= 0x00200000 && startaddr
!= 0x00600000)
123 // found free start address
124 if (size
>= E_SLOTSIZE
* SLOTSPERBYTE
) {
125 // needs at least 1 byte and is always aligned to byte
126 while (space
[offset
] == 0 && sizeleft
>= E_SLOTSIZE
&& offset
<= end
/ (E_SLOTSIZE
* SLOTSPERBYTE
)) {
128 sizeleft
-= E_SLOTSIZE
* SLOTSPERBYTE
;
131 // bit by bit small board check (fits in one byte)
132 while ((res
& (1 << bit
)) == 0 && sizeleft
>= E_SLOTSIZE
&& bit
>= 0) {
133 sizeleft
-= E_SLOTSIZE
;
138 if (sizeleft
>= E_SLOTSIZE
)
141 configDev
->cd_BoardAddr
= (APTR
)startaddr
;
142 configDev
->cd_Flags
|= CDF_CONFIGME
;
143 configDev
->cd_SlotAddr
= (startaddr
>> 16);
144 configDev
->cd_SlotSize
= size
>> 16;
145 AROS_UFC5NR(void, writeexpansion
,
146 AROS_UFCA(APTR
, board
, A0
),
147 AROS_UFCA(APTR
, configDev
, A3
),
148 AROS_UFCA(UBYTE
, type
, D0
),
149 AROS_UFCA(UWORD
, (startaddr
>> 16), D1
),
150 AROS_UFCA(struct ExpansionBase
*, ExpansionBase
, A6
)
152 D(bug("-> configured, %p - %p\n", startaddr
, startaddr
+ configDev
->cd_BoardSize
- 1));
154 // do not remove this, configDev->cd_BoardAddr
155 // might have changed inside writeexpansion
156 startaddr
= (ULONG
)configDev
->cd_BoardAddr
;
157 offset
= startaddr
/ (E_SLOTSIZE
* SLOTSPERBYTE
);
158 bit
= 7 - ((startaddr
/ E_SLOTSIZE
) % SLOTSPERBYTE
);
160 // now allocate area we reserved
161 while (sizeleft
>= E_SLOTSIZE
) {
162 space
[offset
] |= 1 << bit
;
163 sizeleft
-= E_SLOTSIZE
;
172 D(bug("Configuration failed!\n"));
173 if (!(configDev
->cd_Flags
& ERFF_NOSHUTUP
)) {
174 configDev
->cd_Flags
|= CDF_SHUTUP
;
175 WriteExpansionByte(board
, 19, 0); // SHUT-UP!