Small fixes and even more logging added.
[AROS.git] / arch / m68k-amiga / expansion / configboard.c
blobaee4210d70ea792b67f94a9920fdfb3fdfeca8fc
1 /*
2 Copyright © 1995-2007, 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 #define Z3SLOT 0x01000000
17 /* do not touch. Ugly hack. UAE direct JIT versions need this */
18 /* check UAE expansion.c for ugly details */
19 AROS_UFH5(void, writeexpansion,
20 AROS_UFHA(APTR, board, A0),
21 AROS_UFHA(APTR, configdev, A3), // <- configdev = A3. This is important.
22 AROS_UFHA(UBYTE, type, D0),
23 AROS_UFHA(UWORD, startaddr, D1),
24 AROS_UFHA(struct ExpansionBase *, ExpansionBase, A6))
26 AROS_USERFUNC_INIT
28 if (type == ERT_ZORROII) {
29 WriteExpansionByte(board, 18, startaddr);
30 } else {
31 WriteExpansionWord(board, 17, startaddr);
34 AROS_USERFUNC_EXIT
37 /*****************************************************************************
39 NAME */
40 #include <clib/expansion_protos.h>
42 AROS_LH2(BOOL, ConfigBoard,
44 /* SYNOPSIS */
45 AROS_LHA(APTR , board, A0),
46 AROS_LHA(struct ConfigDev *, configDev, A1),
48 /* LOCATION */
49 struct ExpansionBase *, ExpansionBase, 10, Expansion)
51 /* FUNCTION
53 INPUTS
55 RESULT
57 NOTES
59 EXAMPLE
61 BUGS
63 SEE ALSO
65 INTERNALS
67 HISTORY
68 27-11-96 digulla automatically created from
69 expansion_lib.fd and clib/expansion_protos.h
71 *****************************************************************************/
73 AROS_LIBFUNC_INIT
75 UBYTE type = configDev->cd_Rom.er_Type & ERT_TYPEMASK;
76 BOOL memorydevice;
77 ULONG size = configDev->cd_BoardSize;
79 D(bug("Configuring board: mfg=%d prod=%d size=%08x type=%02x\n",
80 configDev->cd_Rom.er_Manufacturer, configDev->cd_Rom.er_Product, size, configDev->cd_Rom.er_Type));
82 memorydevice = (configDev->cd_Rom.er_Type & ERTF_MEMLIST) != 0;
83 if (type == ERT_ZORROIII) {
84 UWORD prevslot;
85 UWORD endslot = 255;
86 UWORD slotsize = (size + 0x00ffffff) / Z3SLOT;
87 if (IntExpBase(ExpansionBase)->eb_z3Slot == 0)
88 IntExpBase(ExpansionBase)->eb_z3Slot = 0x40000000 / Z3SLOT;
89 prevslot = IntExpBase(ExpansionBase)->eb_z3Slot;
90 D(bug("size=%d prev=%d end=%d\n", slotsize, prevslot, endslot));
91 if (prevslot + slotsize <= endslot) {
92 ULONG startaddr = prevslot * Z3SLOT;
93 IntExpBase(ExpansionBase)->eb_z3Slot += slotsize;
94 configDev->cd_BoardAddr = (APTR)startaddr;
95 configDev->cd_Flags |= CDF_CONFIGME;
96 AROS_UFC5(void, writeexpansion,
97 AROS_UFCA(APTR, board, A0),
98 AROS_UFCA(APTR, configDev, A3),
99 AROS_UFCA(UBYTE, type, D0),
100 AROS_UFCA(UWORD, (startaddr >> 16), D1),
101 AROS_UFCA(struct ExpansionBase*, ExpansionBase, A6)
103 D(bug("-> configured, %p - %p\n", startaddr, startaddr + configDev->cd_BoardSize - 1));
104 return TRUE;
106 } else {
107 ULONG start, end, addr, align;
108 UBYTE *space;
109 start = 0x00200000;
110 end = 0x009FFFFF;
111 space = IntExpBase(ExpansionBase)->eb_z2Slots;
112 align = configDev->cd_BoardSize;
113 if (!memorydevice) {
114 start = 0x00E90000;
115 end = 0x00EFFFFF;
116 align = size;
117 /* Blizzard 1240/1260 SCSI kit (128k rom) must be at 0x00EA0000
118 * Does this mean all >64k boards must be 128k aligned? */
119 if (size > E_SLOTSIZE)
120 start = 0x00EA0000;
122 for (addr = start; addr < end; addr += align) {
123 ULONG startaddr = addr;
124 UWORD offset = startaddr / (E_SLOTSIZE * SLOTSPERBYTE);
125 BYTE bit = 7 - ((startaddr / E_SLOTSIZE) % SLOTSPERBYTE);
126 UBYTE res = space[offset];
127 ULONG sizeleft = size;
129 if (res & (1 << bit))
130 continue;
132 // found free start address
133 if (size >= E_SLOTSIZE * SLOTSPERBYTE) {
134 // needs at least 1 byte and is always aligned to byte
135 while (space[offset] == 0 && sizeleft >= E_SLOTSIZE && offset <= end / (E_SLOTSIZE * SLOTSPERBYTE)) {
136 offset++;
137 sizeleft -= E_SLOTSIZE * SLOTSPERBYTE;
139 } else {
140 // bit by bit small board check (fits in one byte)
141 while ((res & (1 << bit)) == 0 && sizeleft >= E_SLOTSIZE && bit >= 0) {
142 sizeleft -= E_SLOTSIZE;
143 bit--;
147 if (sizeleft >= E_SLOTSIZE)
148 continue;
150 configDev->cd_BoardAddr = (APTR)startaddr;
151 configDev->cd_Flags |= CDF_CONFIGME;
152 AROS_UFC5(void, writeexpansion,
153 AROS_UFCA(APTR, board, A0),
154 AROS_UFCA(APTR, configDev, A3),
155 AROS_UFCA(UBYTE, type, D0),
156 AROS_UFCA(UWORD, (startaddr >> 16), D1),
157 AROS_UFCA(struct ExpansionBase*, ExpansionBase, A6)
159 D(bug("-> configured, %p - %p\n", startaddr, startaddr + configDev->cd_BoardSize - 1));
161 // do not remove this, configDev->cd_BoardAddr
162 // might have changed inside writeexpansion
163 startaddr = (ULONG)configDev->cd_BoardAddr;
164 offset = startaddr / (E_SLOTSIZE * SLOTSPERBYTE);
165 bit = 7 - ((startaddr / E_SLOTSIZE) % SLOTSPERBYTE);
166 sizeleft = size;
167 // now allocate area we reserved
168 while (sizeleft >= E_SLOTSIZE) {
169 space[offset] |= 1 << bit;
170 sizeleft -= E_SLOTSIZE;
171 bit--;
174 return TRUE;
178 D(bug("Configuration failed!\n"));
179 if (!(configDev->cd_Flags & ERFF_NOSHUTUP)) {
180 configDev->cd_Flags |= CDF_SHUTUP;
181 WriteExpansionByte(board, 19, 0); // SHUT-UP!
182 } else {
183 // uh?
185 return FALSE;
187 AROS_LIBFUNC_EXIT
188 } /* ConfigBoard */