Removed autodocs of arch specific variants of ROM modules.
[AROS.git] / arch / m68k-amiga / expansion / configboard.c
blob4fb95c1291e7d6b735d7c269fb44fb8a86618268
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #define DEBUG 1
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))
28 AROS_USERFUNC_INIT
30 if (type == ERT_ZORROII) {
31 WriteExpansionByte(board, 18, startaddr);
32 } else {
33 WriteExpansionWord(board, 17, startaddr);
36 AROS_USERFUNC_EXIT
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)
47 AROS_LIBFUNC_INIT
49 UBYTE type = configDev->cd_Rom.er_Type & ERT_TYPEMASK;
50 BOOL memorydevice;
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;
59 UWORD endslot = 255;
60 UWORD slotsize = (size + 0x00ffffff) / Z3SLOT;
61 if (IntExpBase(ExpansionBase)->eb_z3Slot == 0)
62 IntExpBase(ExpansionBase)->eb_z3Slot = 0x40000000 / Z3SLOT;
63 prevslot = IntExpBase(ExpansionBase)->eb_z3Slot;
64 // handle alignment
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)->eb_z3Slot;
71 configDev->cd_SlotSize = slotsize;
72 configDev->cd_Flags |= CDF_CONFIGME;
73 IntExpBase(ExpansionBase)->eb_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));
82 return TRUE;
84 } else {
85 ULONG start, end, addr, step;
86 UBYTE *space;
87 UBYTE area;
89 for (area = 0; area < 2; area++) {
91 if (area == 0 && (size >= 8 * E_SLOTSIZE || memorydevice))
92 continue;
94 if (area == 0) {
95 start = 0x00E90000;
96 end = 0x00EFFFFF;
97 } else {
98 start = 0x00200000;
99 end = 0x009FFFFF;
101 space = IntExpBase(ExpansionBase)->eb_z2Slots;
102 step = 0x00010000;
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))
111 continue;
113 if (size < 4 * 1024 * 1024) {
114 // handle alignment, 128k boards must be 128k aligned and so on..
115 if ((startaddr & (size - 1)) != 0)
116 continue;
117 } else {
118 // 4M and 8M boards have different alignment requirements
119 if (startaddr != 0x00200000 && startaddr != 0x00600000)
120 continue;
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)) {
127 offset++;
128 sizeleft -= E_SLOTSIZE * SLOTSPERBYTE;
130 } else {
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;
134 bit--;
138 if (sizeleft >= E_SLOTSIZE)
139 continue;
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);
159 sizeleft = size;
160 // now allocate area we reserved
161 while (sizeleft >= E_SLOTSIZE) {
162 space[offset] |= 1 << bit;
163 sizeleft -= E_SLOTSIZE;
164 bit--;
167 return TRUE;
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!
176 } else {
177 // uh?
179 return FALSE;
181 AROS_LIBFUNC_EXIT
182 } /* ConfigBoard */