1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * AutoConfig (tm) Expansions (ZorroII/III)
5 *
6 * Copyright 1996,1997 Stefan Reinauer <stepan@linux.de>
7 * Copyright 1997 Brian King <Brian_King@Mitel.com>
8 *   - added gfxcard code
9 *
10 */
11 
12 #include "sysconfig.h"
13 #include "sysdeps.h"
14 
15 #include "options.h"
16 #include "uae.h"
17 #include "uae/memory.h"
18 #include "rommgr.h"
19 #include "custom.h"
20 #include "newcpu.h"
21 #include "savestate.h"
22 #include "zfile.h"
23 #include "catweasel.h"
24 #include "cdtv.h"
25 #include "threaddep/thread.h"
26 #include "a2091.h"
27 #include "a2065.h"
28 #include "gfxboard.h"
29 #include "cd32_fmv.h"
30 #include "ncr_scsi.h"
31 #include "ncr9x_scsi.h"
32 #include "scsi.h"
33 #include "debug.h"
34 #include "gayle.h"
35 #include "idecontrollers.h"
36 #include "cpuboard.h"
37 #include "sndboard.h"
38 #include "uae/ppc.h"
39 #include "autoconf.h"
40 #include "specialmonitors.h"
41 #include "inputdevice.h"
42 #include "pci.h"
43 #include "x86.h"
44 #include "filesys.h"
45 
46 // More information in first revision HRM Appendix_G
47 #define BOARD_PROTOAUTOCONFIG 1
48 
49 #define BOARD_AUTOCONFIG_Z2 2
50 #define BOARD_AUTOCONFIG_Z3 3
51 #define BOARD_NONAUTOCONFIG_BEFORE 4
52 #define BOARD_NONAUTOCONFIG_AFTER_Z2 5
53 #define BOARD_NONAUTOCONFIG_AFTER_Z3 6
54 #define BOARD_IGNORE 7
55 
56 #define KS12_BOOT_HACK 1
57 
58 #define EXP_DEBUG 0
59 
60 #define MAX_EXPANSION_BOARD_SPACE 16
61 
62 /* ********************************************************** */
63 /* 00 / 02 */
64 /* er_Type */
65 
66 #define Z2_MEM_8MB		0x00 /* Size of Memory Block */
67 #define Z2_MEM_4MB		0x07
68 #define Z2_MEM_2MB		0x06
69 #define Z2_MEM_1MB		0x05
70 #define Z2_MEM_512KB	0x04
71 #define Z2_MEM_256KB	0x03
72 #define Z2_MEM_128KB	0x02
73 #define Z2_MEM_64KB		0x01
74 /* extended definitions */
75 #define Z3_MEM_16MB		0x00
76 #define Z3_MEM_32MB		0x01
77 #define Z3_MEM_64MB		0x02
78 #define Z3_MEM_128MB	0x03
79 #define Z3_MEM_256MB	0x04
80 #define Z3_MEM_512MB	0x05
81 #define Z3_MEM_1GB		0x06
82 
83 #define chainedconfig	0x08 /* Next config is part of the same card */
84 #define rom_card	0x10 /* ROM vector is valid */
85 #define add_memory	0x20 /* Link RAM into free memory list */
86 
87 /* Type of Expansion Card */
88 #define protoautoconfig 0x40
89 #define zorroII		0xc0
90 #define zorroIII	0x80
91 
92 /* ********************************************************** */
93 /* 04 - 06 & 10-16 */
94 
95 /* Manufacturer */
96 #define commodore_g	 513 /* Commodore Braunschweig (Germany) */
97 #define commodore	 514 /* Commodore West Chester */
98 #define gvp		2017 /* GVP */
99 #define ass		2102 /* Advanced Systems & Software */
100 #define hackers_id	2011 /* Special ID for test cards */
101 
102 /* Card Type */
103 #define commodore_a2091	    3 /* A2091 / A590 Card from C= */
104 #define commodore_a2091_ram 10 /* A2091 / A590 Ram on HD-Card */
105 #define commodore_a2232	    70 /* A2232 Multiport Expansion */
106 #define ass_nexus_scsi	    1 /* Nexus SCSI Controller */
107 
108 #define gvp_series_2_scsi   11
109 #define gvp_iv_24_gfx	    32
110 
111 /* ********************************************************** */
112 /* 08 - 0A  */
113 /* er_Flags */
114 #define Z3_SS_MEM_SAME		0x00
115 #define Z3_SS_MEM_AUTO		0x01
116 #define Z3_SS_MEM_64KB		0x02
117 #define Z3_SS_MEM_128KB		0x03
118 #define Z3_SS_MEM_256KB		0x04
119 #define Z3_SS_MEM_512KB		0x05
120 #define Z3_SS_MEM_1MB		0x06 /* Zorro III card subsize */
121 #define Z3_SS_MEM_2MB		0x07
122 #define Z3_SS_MEM_4MB		0x08
123 #define Z3_SS_MEM_6MB		0x09
124 #define Z3_SS_MEM_8MB		0x0a
125 #define Z3_SS_MEM_10MB		0x0b
126 #define Z3_SS_MEM_12MB		0x0c
127 #define Z3_SS_MEM_14MB		0x0d
128 #define Z3_SS_MEM_defunct1	0x0e
129 #define Z3_SS_MEM_defunct2	0x0f
130 
131 #define force_z3	0x10 /* *MUST* be set if card is Z3 */
132 #define ext_size	0x20 /* Use extended size table for bits 0-2 of er_Type */
133 #define no_shutup	0x40 /* Card cannot receive Shut_up_forever */
134 #define care_addr	0x80 /* Z2=Adress HAS to be $200000-$9fffff Z3=1->mem,0=io */
135 
136 /* ********************************************************** */
137 /* 40-42 */
138 /* ec_interrupt (unused) */
139 
140 #define enable_irq	0x01 /* enable Interrupt */
141 #define reset_card	0x04 /* Reset of Expansion Card - must be 0 */
142 #define card_int2	0x10 /* READ ONLY: IRQ 2 active */
143 #define card_irq6	0x20 /* READ ONLY: IRQ 6 active */
144 #define card_irq7	0x40 /* READ ONLY: IRQ 7 active */
145 #define does_irq	0x80 /* READ ONLY: Card currently throws IRQ */
146 
147 /* ********************************************************** */
148 
149 /* ROM defines (DiagVec) */
150 
151 #define rom_4bit	(0x00<<14) /* ROM width */
152 #define rom_8bit	(0x01<<14)
153 #define rom_16bit	(0x02<<14)
154 
155 #define rom_never	(0x00<<12) /* Never run Boot Code */
156 #define rom_install	(0x01<<12) /* run code at install time */
157 #define rom_binddrv	(0x02<<12) /* run code with binddrivers */
158 
159 uaecptr ROM_filesys_resname, ROM_filesys_resid;
160 uaecptr ROM_filesys_diagentry;
161 uaecptr ROM_hardfile_resname, ROM_hardfile_resid;
162 uaecptr ROM_hardfile_init;
163 int uae_boot_rom_type;
164 int uae_boot_rom_size; /* size = code size only */
165 static bool chipdone;
166 
167 /* ********************************************************** */
168 
169 struct card_data
170 {
171 	addrbank *(*initrc)(struct romconfig*);
172 	addrbank *(*initnum)(int);
173 	addrbank *(*map)(void);
174 	struct romconfig *rc;
175 	const TCHAR *name;
176 	int flags;
177 	int zorro;
178 };
179 
180 static struct card_data cards[MAX_EXPANSION_BOARD_SPACE];
181 
182 static int ecard, cardno, z3num;
183 static addrbank *expamem_bank_current;
184 
185 static uae_u16 uae_id;
186 
isnonautoconfig(int v)187 static bool isnonautoconfig(int v)
188 {
189 	return v == BOARD_NONAUTOCONFIG_AFTER_Z2 ||
190 		v == BOARD_NONAUTOCONFIG_AFTER_Z3 ||
191 		v == BOARD_NONAUTOCONFIG_BEFORE;
192 }
193 
ks12orolder(void)194 static bool ks12orolder(void)
195 {
196 	/* check if Kickstart version is below 1.3 */
197 	return kickstart_version && kickstart_version < 34;
198 }
ks11orolder(void)199 static bool ks11orolder(void)
200 {
201 	return kickstart_version && kickstart_version < 33;
202 }
203 
204 
205 /* ********************************************************** */
206 
207 /* Please note: ZorroIII implementation seems to work different
208 * than described in the HRM. This claims that ZorroIII config
209 * address is 0xff000000 while the ZorroII config space starts
210 * at 0x00e80000. In reality, both, Z2 and Z3 cards are
211 * configured in the ZorroII config space. Kickstart 3.1 doesn't
212 * even do a single read or write access to the ZorroIII space.
213 * The original Amiga include files tell the same as the HRM.
214 * ZorroIII: If you set ext_size in er_Flags and give a Z2-size
215 * in er_Type you can very likely add some ZorroII address space
216 * to a ZorroIII card on a real Amiga. This is not implemented
217 * yet.
218 *  -- Stefan
219 *
220 * Surprising that 0xFF000000 isn't used. Maybe it depends on the
221 * ROM. Anyway, the HRM says that Z3 cards may appear in Z2 config
222 * space, so what we are doing here is correct.
223 *  -- Bernd
224 */
225 
226 /* Autoconfig address space at 0xE80000 */
227 static uae_u8 expamem[65536];
228 
229 static uae_u8 expamem_lo;
230 static uae_u16 expamem_hi;
231 static uaecptr expamem_z3_sum;
232 uaecptr expamem_z3_pointer;
233 uaecptr expamem_z2_pointer;
234 uae_u32 expamem_z3_size;
235 uae_u32 expamem_z2_size;
236 static uae_u32 expamem_board_size;
237 static uae_u32 expamem_board_pointer;
238 static bool z3hack_override;
239 
set_expamem_z3_hack_override(bool overridenoz3hack)240 void set_expamem_z3_hack_override(bool overridenoz3hack)
241 {
242 	z3hack_override = overridenoz3hack;
243 }
244 
expamem_z3hack(struct uae_prefs * p)245 bool expamem_z3hack(struct uae_prefs *p)
246 {
247 	if (z3hack_override)
248 		return false;
249 #ifdef WITH_PPC
250 	if (regs.halted && ppc_state)
251 		return false;
252 #endif
253 	return p->z3_mapping_mode == Z3MAPPING_AUTO || p->z3_mapping_mode == Z3MAPPING_UAE || cpuboard_memorytype(p) == BOARD_MEMORY_BLIZZARD_12xx;
254 }
255 
256 /* Ugly hack for >2M chip RAM in single pool
257  * We can't add it any later or early boot menu
258  * stops working because it sets kicktag at the end
259  * of chip ram...
260  */
addextrachip(uae_u32 sysbase)261 static void addextrachip (uae_u32 sysbase)
262 {
263 	if (currprefs.chipmem_size <= 0x00200000)
264 		return;
265 	if (sysbase & 0x80000001)
266 		return;
267 	if (!valid_address (sysbase, 1000))
268 		return;
269 	uae_u32 ml = get_long (sysbase + 322);
270 	if (!valid_address (ml, 32))
271 		return;
272 	uae_u32 next;
273 	while ((next = get_long (ml))) {
274 		if (!valid_address (ml, 32))
275 			return;
276 		uae_u32 upper = get_long (ml + 24);
277 		uae_u32 lower = get_long (ml + 20);
278 		if (lower & ~0xffff) {
279 			ml = next;
280 			continue;
281 		}
282 		uae_u16 attr = get_word (ml + 14);
283 		if ((attr & 0x8002) != 2) {
284 			ml = next;
285 			continue;
286 		}
287 		if (upper >= currprefs.chipmem_size)
288 			return;
289 		uae_u32 added = currprefs.chipmem_size - upper;
290 		uae_u32 first = get_long (ml + 16);
291 		put_long (ml + 24, currprefs.chipmem_size); // mh_Upper
292 		put_long (ml + 28, get_long (ml + 28) + added); // mh_Free
293 		uae_u32 next;
294 		while (first) {
295 			next = first;
296 			first = get_long (next);
297 		}
298 		uae_u32 bytes = get_long (next + 4);
299 		if (next + bytes == 0x00200000) {
300 			put_long (next + 4, currprefs.chipmem_size - next);
301 		} else {
302 			put_long (0x00200000 + 0, 0);
303 			put_long (0x00200000 + 4, added);
304 			put_long (next, 0x00200000);
305 		}
306 		return;
307 	}
308 }
309 
310 addrbank expamem_null, expamem_none;
311 
312 DECLARE_MEMORY_FUNCTIONS(expamem);
313 addrbank expamem_bank = {
314 	expamem_lget, expamem_wget, expamem_bget,
315 	expamem_lput, expamem_wput, expamem_bput,
316 	default_xlate, default_check, NULL, NULL, _T("Autoconfig Z2"),
317 	dummy_lgeti, dummy_wgeti,
318 	ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
319 };
320 DECLARE_MEMORY_FUNCTIONS(expamemz3);
321 static addrbank expamemz3_bank = {
322 	expamemz3_lget, expamemz3_wget, expamemz3_bget,
323 	expamemz3_lput, expamemz3_wput, expamemz3_bput,
324 	default_xlate, default_check, NULL, NULL, _T("Autoconfig Z3"),
325 	dummy_lgeti, dummy_wgeti,
326 	ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
327 };
328 
expamem_map_clear(void)329 static addrbank *expamem_map_clear (void)
330 {
331 	write_log (_T("expamem_map_clear() got called. Shouldn't happen.\n"));
332 	return NULL;
333 }
334 
expamem_init_clear(void)335 static void expamem_init_clear (void)
336 {
337 	memset (expamem, 0xff, sizeof expamem);
338 }
339 /* autoconfig area is "non-existing" after last device */
expamem_init_clear_zero(void)340 static void expamem_init_clear_zero (void)
341 {
342 	map_banks(&dummy_bank, 0xe8, 1, 0);
343 	if (!currprefs.address_space_24)
344 		map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
345 }
346 
expamem_init_clear2(void)347 static void expamem_init_clear2 (void)
348 {
349 	expamem_bank.name = _T("Autoconfig Z2");
350 	expamemz3_bank.name = _T("Autoconfig Z3");
351 	expamem_init_clear_zero ();
352 	ecard = cardno;
353 }
354 
expamem_init_last(void)355 static addrbank *expamem_init_last (void)
356 {
357 	expamem_init_clear2 ();
358 	write_log (_T("Memory map after autoconfig:\n"));
359 	memory_map_dump ();
360 	return NULL;
361 }
362 
expamem_read(int addr)363 static uae_u8 REGPARAM2 expamem_read(int addr)
364 {
365 	uae_u8 b = (expamem[addr] & 0xf0) | (expamem[addr + 2] >> 4);
366 	if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42)
367 		return b;
368 	b = ~b;
369 	return b;
370 }
371 
expamem_write(uaecptr addr,uae_u32 value)372 static void REGPARAM2 expamem_write(uaecptr addr, uae_u32 value)
373 {
374 	addr &= 0xffff;
375 	if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
376 		expamem[addr] = (value & 0xf0);
377 		expamem[addr + 2] = (value & 0x0f) << 4;
378 	} else {
379 		expamem[addr] = ~(value & 0xf0);
380 		expamem[addr + 2] = ~((value & 0x0f) << 4);
381 	}
382 }
383 
expamem_type(void)384 static int REGPARAM2 expamem_type (void)
385 {
386 	return expamem_read(0) & 0xc0;
387 }
388 
call_card_init(int index)389 static void call_card_init(int index)
390 {
391 	addrbank *ab, *abe;
392 	uae_u8 code;
393 	uae_u32 expamem_z3_pointer_old;
394 
395 	expamem_bank.name = cards[ecard].name ? cards[ecard].name : _T("None");
396 	if (cards[ecard].initnum)
397 		ab = cards[ecard].initnum(0);
398 	else
399 		ab = cards[ecard].initrc(cards[ecard].rc);
400 	expamem_z3_size = 0;
401 	if (ab == &expamem_none) {
402 		expamem_init_clear();
403 		expamem_init_clear_zero();
404 		map_banks(&expamem_bank, 0xE8, 1, 0);
405 		if (!currprefs.address_space_24)
406 			map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
407 		expamem_bank_current = NULL;
408 		return;
409 	}
410 	if (ab == &expamem_null) {
411 		expamem_next(NULL, NULL);
412 		return;
413 	}
414 
415 	abe = ab;
416 	if (!abe)
417 		abe = &expamem_bank;
418 	if (abe != &expamem_bank) {
419 		for (int i = 0; i < 16 * 4; i++)
420 			expamem[i] = abe->bget(i);
421 	}
422 
423 	code = expamem_read(0);
424 	if ((code & 0xc0) == zorroII) {
425 		// Z2
426 		code &= 7;
427 		if (code == 0)
428 			expamem_z2_size = 8 * 1024 * 1024;
429 		else
430 			expamem_z2_size = 32768 << code;
431 
432 		expamem_board_size = expamem_z2_size;
433 		expamem_board_pointer = expamem_z2_pointer;
434 
435 	} else if ((code & 0xc0) == zorroIII) {
436 		// Z3
437 		if (expamem_z3_sum < Z3BASE_UAE) {
438 			expamem_z3_sum = currprefs.z3autoconfig_start;
439 			if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024 && expamem_z3_sum == Z3BASE_UAE)
440 				expamem_z3_sum += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
441 			if (!expamem_z3hack(&currprefs))
442 				expamem_z3_sum = Z3BASE_REAL;
443 			if (expamem_z3_sum == Z3BASE_UAE) {
444 				expamem_z3_sum += currprefs.z3chipmem_size;
445 			}
446 		}
447 
448 		expamem_z3_pointer = expamem_z3_sum;
449 
450 		code &= 7;
451 		if (expamem_read(8) & ext_size)
452 			expamem_z3_size = (16 * 1024 * 1024) << code;
453 		else
454 			expamem_z3_size = 16 * 1024 * 1024;
455 		expamem_z3_sum += expamem_z3_size;
456 
457 		expamem_z3_pointer_old = expamem_z3_pointer;
458 		// align 32M boards (FastLane is 32M and needs to be aligned)
459 		if (expamem_z3_size <= 32 * 1024 * 1024)
460 			expamem_z3_pointer = (expamem_z3_pointer + expamem_z3_size - 1) & ~(expamem_z3_size - 1);
461 
462 		expamem_z3_sum += expamem_z3_pointer - expamem_z3_pointer_old;
463 
464 		expamem_board_size = expamem_z3_size;
465 		expamem_board_pointer = expamem_z3_pointer;
466 
467 	} else if ((code & 0xc0) == 0x40) {
468 		// 0x40 = "Box without init/diagnostic code"
469 		// proto autoconfig "box" size.
470 		//expamem_z2_size = (1 << ((code >> 3) & 7)) * 4096;
471 		// much easier this way, all old-style boards were made for
472 		// A1000 and didn't have passthrough connector.
473 		expamem_z2_size = 65536;
474 		expamem_board_size = expamem_z2_size;
475 		expamem_board_pointer = expamem_z2_pointer;
476 	}
477 
478 	if (ab) {
479 		// non-NULL: not using expamem_bank
480 		expamem_bank_current = ab;
481 		if ((cards[ecard].flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
482 			map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
483 			map_banks(&dummy_bank, 0xE8, 1, 0);
484 		} else {
485 			map_banks(&expamem_bank, 0xE8, 1, 0);
486 			if (!currprefs.address_space_24)
487 				map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
488 		}
489 	} else {
490 		if ((cards[ecard].flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
491 			map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
492 			map_banks(&dummy_bank, 0xE8, 1, 0);
493 			expamem_bank_current = &expamem_bank;
494 		} else {
495 			map_banks(&expamem_bank, 0xE8, 1, 0);
496 			if (!currprefs.address_space_24)
497 				map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
498 			expamem_bank_current = NULL;
499 		}
500 	}
501 }
502 
boardmessage(addrbank * mapped,bool success)503 static void boardmessage(addrbank *mapped, bool success)
504 {
505 	uae_u8 type = expamem_read(0);
506 	int size = expamem_board_size;
507 	TCHAR sizemod = 'K';
508 
509 	size /= 1024;
510 	if (size > 8 * 1024) {
511 		sizemod = 'M';
512 		size /= 1024;
513 	}
514 	write_log (_T("Card %d: Z%d 0x%08x %4d%c %s %s%s\n"),
515 		ecard + 1, (type & 0xc0) == zorroII ? 2 : ((type & 0xc0) == zorroIII ? 3 : 1),
516 		expamem_board_pointer, size, sizemod,
517 		type & rom_card ? _T("ROM") : (type & add_memory ? _T("RAM") : _T("IO ")),
518 		mapped->name,
519 		success ? _T("") : _T(" SHUT UP"));
520 #if 0
521 	for (int i = 0; i < 16; i++) {
522 		write_log(_T("%s%02X"), i > 0 ? _T(".") : _T(""), expamem_read(i * 4));
523 	}
524 	write_log(_T("\n"));
525 #endif
526 }
527 
expamem_shutup(addrbank * mapped)528 void expamem_shutup(addrbank *mapped)
529 {
530 	if (mapped)
531 		boardmessage(mapped, false);
532 }
533 
expamem_next(addrbank * mapped,addrbank * next)534 void expamem_next (addrbank *mapped, addrbank *next)
535 {
536 	if (mapped)
537 		boardmessage(mapped, true);
538 
539 	expamem_init_clear();
540 	expamem_init_clear_zero();
541 	for (;;) {
542 		++ecard;
543 		if (ecard >= cardno)
544 			break;
545 		struct card_data *ec = &cards[ecard];
546 		if (ec->initrc && isnonautoconfig(ec->zorro)) {
547 			ec->initrc(cards[ecard].rc);
548 		} else {
549 			call_card_init(ecard);
550 			break;
551 		}
552 	}
553 	if (ecard >= cardno) {
554 		expamem_init_clear2();
555 		expamem_init_last();
556 	}
557 }
558 
559 
expamem_lget(uaecptr addr)560 static uae_u32 REGPARAM2 expamem_lget (uaecptr addr)
561 {
562 	if (expamem_bank_current && expamem_bank_current != &expamem_bank)
563 		return expamem_bank_current->lget(addr);
564 	write_log (_T("warning: Z2 READ.L from address $%08x PC=%x\n"), addr, M68K_GETPC);
565 	return (expamem_wget (addr) << 16) | expamem_wget (addr + 2);
566 }
567 
expamem_wget(uaecptr addr)568 static uae_u32 REGPARAM2 expamem_wget (uaecptr addr)
569 {
570 	if (expamem_bank_current && expamem_bank_current != &expamem_bank)
571 		return expamem_bank_current->wget(addr);
572 	if (expamem_type() != zorroIII) {
573 		if (expamem_bank_current && expamem_bank_current != &expamem_bank)
574 			return expamem_bank_current->bget(addr) << 8;
575 	}
576 	uae_u32 v = (expamem_bget (addr) << 8) | expamem_bget (addr + 1);
577 	if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) {
578 		uae_u32 val = v;
579 		cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &val, 2, false);
580 		v = val;
581 	}
582 	write_log (_T("warning: READ.W from address $%08x=%04x PC=%x\n"), addr, v & 0xffff, M68K_GETPC);
583 	return v;
584 }
585 
expamem_bget(uaecptr addr)586 static uae_u32 REGPARAM2 expamem_bget (uaecptr addr)
587 {
588 	uae_u8 b;
589 	if (!chipdone) {
590 		chipdone = true;
591 		addextrachip (get_long (4));
592 	}
593 	if (expamem_bank_current && expamem_bank_current != &expamem_bank)
594 		return expamem_bank_current->bget(addr);
595 	addr &= 0xFFFF;
596 	b = expamem[addr];
597 	if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) {
598 		uae_u32 val = b;
599 		cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &val, 1, false);
600 		b = val;
601 	}
602 #if EXP_DEBUG
603 	write_log (_T("expamem_bget %x %x\n"), addr, b);
604 #endif
605 	return b;
606 }
607 
expamem_lput(uaecptr addr,uae_u32 value)608 static void REGPARAM2 expamem_lput (uaecptr addr, uae_u32 value)
609 {
610 	if (expamem_bank_current && expamem_bank_current != &expamem_bank) {
611 		expamem_bank_current->lput(addr, value);
612 		return;
613 	}
614 	write_log (_T("warning: Z2 WRITE.L to address $%08x : value $%08x\n"), addr, value);
615 }
616 
expamem_wput(uaecptr addr,uae_u32 value)617 static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
618 {
619 #if EXP_DEBUG
620 	write_log (_T("expamem_wput %x %x\n"), addr, value);
621 #endif
622 	value &= 0xffff;
623 	if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) {
624 		if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &value, 2, true))
625 			return;
626 	}
627 	if (ecard >= cardno)
628 		return;
629 	if (expamem_type () != zorroIII) {
630 		write_log (_T("warning: WRITE.W to address $%08x : value $%x PC=%08x\n"), addr, value, M68K_GETPC);
631 	}
632 	switch (addr & 0xff) {
633 	case 0x48:
634 		// A2630 boot rom writes WORDs to Z2 boards!
635 		if (expamem_type() == zorroII) {
636 			expamem_lo = 0;
637 			expamem_hi = (value >> 8) & 0xff;
638 			expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16;
639 			expamem_board_pointer = expamem_z2_pointer;
640 			if (cards[ecard].map) {
641 				expamem_next(cards[ecard].map(), NULL);
642 				return;
643 			}
644 			if (expamem_bank_current && expamem_bank_current != &expamem_bank) {
645 				expamem_bank_current->bput(addr, value >> 8);
646 				return;
647 			}
648 		}
649 		break;
650 	case 0x44:
651 		if (expamem_type() == zorroIII) {
652 			uaecptr addr;
653 			expamem_hi = value & 0xff00;
654 			addr = (expamem_hi | (expamem_lo >> 4)) << 16;
655 			if (!expamem_z3hack(&currprefs)) {
656 				expamem_z3_pointer = addr;
657 			} else {
658 				if (addr != expamem_z3_pointer) {
659 					put_word (regs.regs[11] + 0x20, expamem_z3_pointer >> 16);
660 					put_word (regs.regs[11] + 0x28, expamem_z3_pointer >> 16);
661 				}
662 			}
663 			expamem_board_pointer = expamem_z3_pointer;
664 		}
665 		if (cards[ecard].map) {
666 			expamem_next(cards[ecard].map(), NULL);
667 			return;
668 		}
669 		break;
670 	case 0x4c:
671 		if (cards[ecard].map) {
672 			expamem_next (NULL, NULL);
673 			return;
674 		}
675 		break;
676 	}
677 	if (expamem_bank_current && expamem_bank_current != &expamem_bank)
678 		expamem_bank_current->wput(addr, value);
679 }
680 
expamem_bput(uaecptr addr,uae_u32 value)681 static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
682 {
683 #if EXP_DEBUG
684 	write_log (_T("expamem_bput %x %x\n"), addr, value);
685 #endif
686 	value &= 0xff;
687 	if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8) {
688 		if (cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].e8(addr, &value, 1, true))
689 			return;
690 	}
691 	if (ecard >= cardno)
692 		return;
693 	if (expamem_type() == protoautoconfig) {
694 		switch (addr & 0xff) {
695 		case 0x22:
696 			expamem_hi = value & 0x7f;
697 			expamem_z2_pointer = 0xe80000 | (expamem_hi * 4096);
698 			expamem_board_pointer = expamem_z2_pointer;
699 			if (cards[ecard].map) {
700 				expamem_next(cards[ecard].map(), NULL);
701 				return;
702 			}
703 			break;
704 		}
705 	} else {
706 		switch (addr & 0xff) {
707 		case 0x48:
708 			if (expamem_type() == zorroII) {
709 				expamem_hi = value & 0xff;
710 				expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16;
711 				expamem_board_pointer = expamem_z2_pointer;
712 				if (cards[ecard].map) {
713 					expamem_next(cards[ecard].map(), NULL);
714 					return;
715 				}
716 			} else {
717 				expamem_lo = value & 0xff;
718 			}
719 			break;
720 
721 		case 0x4a:
722 			if (expamem_type () == zorroII)
723 				expamem_lo = value & 0xff;
724 			break;
725 
726 		case 0x4c:
727 			if (cards[ecard].map) {
728 				expamem_next(expamem_bank_current, NULL);
729 				return;
730 			}
731 			break;
732 		}
733 	}
734 	if (expamem_bank_current && expamem_bank_current != &expamem_bank)
735 		expamem_bank_current->bput(addr, value);
736 }
737 
expamemz3_bget(uaecptr addr)738 static uae_u32 REGPARAM2 expamemz3_bget (uaecptr addr)
739 {
740 	int reg = addr & 0xff;
741 	if (!expamem_bank_current)
742 		return 0;
743 	if (addr & 0x100)
744 		reg += 2;
745 	return expamem_bank_current->bget(reg + 0);
746 }
747 
expamemz3_wget(uaecptr addr)748 static uae_u32 REGPARAM2 expamemz3_wget (uaecptr addr)
749 {
750 	uae_u32 v = (expamemz3_bget (addr) << 8) | expamemz3_bget (addr + 1);
751 	write_log (_T("warning: Z3 READ.W from address $%08x=%04x PC=%x\n"), addr, v & 0xffff, M68K_GETPC);
752 	return v;
753 }
754 
expamemz3_lget(uaecptr addr)755 static uae_u32 REGPARAM2 expamemz3_lget (uaecptr addr)
756 {
757 	write_log (_T("warning: Z3 READ.L from address $%08x PC=%x\n"), addr, M68K_GETPC);
758 	return (expamemz3_wget (addr) << 16) | expamemz3_wget (addr + 2);
759 }
760 
expamemz3_bput(uaecptr addr,uae_u32 value)761 static void REGPARAM2 expamemz3_bput (uaecptr addr, uae_u32 value)
762 {
763 	int reg = addr & 0xff;
764 	if (!expamem_bank_current)
765 		return;
766 	if (addr & 0x100)
767 		reg += 2;
768 	if (reg == 0x48) {
769 		if (expamem_type() == zorroII) {
770 			expamem_hi = value & 0xff;
771 			expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16;
772 			expamem_board_pointer = expamem_z2_pointer;
773 		} else {
774 			expamem_lo = value & 0xff;
775 		}
776 	} else if (reg == 0x4a) {
777 		if (expamem_type() == zorroII)
778 			expamem_lo = value & 0xff;
779 	}
780 	expamem_bank_current->bput(reg, value);
781 }
782 
expamemz3_wput(uaecptr addr,uae_u32 value)783 static void REGPARAM2 expamemz3_wput (uaecptr addr, uae_u32 value)
784 {
785 	int reg = addr & 0xff;
786 	if (!expamem_bank_current)
787 		return;
788 	if (addr & 0x100)
789 		reg += 2;
790 	if (reg == 0x44) {
791 		if (expamem_type() == zorroIII) {
792 			uaecptr addr;
793 			expamem_hi = value & 0xff00;
794 			addr = (expamem_hi | (expamem_lo >> 4)) << 16;;
795 			if (!expamem_z3hack(&currprefs)) {
796 				expamem_z3_pointer = addr;
797 			} else {
798 				if (addr != expamem_z3_pointer) {
799 					put_word (regs.regs[11] + 0x20, expamem_z3_pointer >> 16);
800 					put_word (regs.regs[11] + 0x28, expamem_z3_pointer >> 16);
801 				}
802 			}
803 			expamem_board_pointer = expamem_z3_pointer;
804 		}
805 	}
806 	expamem_bank_current->wput(reg, value);
807 }
expamemz3_lput(uaecptr addr,uae_u32 value)808 static void REGPARAM2 expamemz3_lput (uaecptr addr, uae_u32 value)
809 {
810 	write_log (_T("warning: Z3 WRITE.L to address $%08x : value $%08x\n"), addr, value);
811 }
812 
813 #ifdef CD32
814 
expamem_map_cd32fmv(void)815 static addrbank *expamem_map_cd32fmv (void)
816 {
817 	return cd32_fmv_init (expamem_z2_pointer);
818 }
819 
expamem_init_cd32fmv(int devnum)820 static addrbank *expamem_init_cd32fmv (int devnum)
821 {
822 	int ids[] = { 23, -1 };
823 	struct romlist *rl = getromlistbyids (ids, NULL);
824 	struct romdata *rd;
825 	struct zfile *z;
826 
827 	expamem_init_clear ();
828 	if (!rl)
829 		return NULL;
830 	write_log (_T("CD32 FMV ROM '%s' %d.%d\n"), rl->path, rl->rd->ver, rl->rd->rev);
831 	rd = rl->rd;
832 	z = read_rom (rd);
833 	if (z) {
834 		zfile_fread (expamem, 128, 1, z);
835 		zfile_fclose (z);
836 	}
837 	return NULL;
838 }
839 
840 #endif
841 
842 /* ********************************************************** */
843 
844 /*
845 *  Fast Memory
846 */
847 
848 
849 MEMORY_FUNCTIONS(fastmem);
850 MEMORY_FUNCTIONS(fastmem_nojit);
851 MEMORY_FUNCTIONS(fastmem2);
852 MEMORY_FUNCTIONS(fastmem2_nojit);
853 
854 addrbank fastmem_bank = {
855 	fastmem_lget, fastmem_wget, fastmem_bget,
856 	fastmem_lput, fastmem_wput, fastmem_bput,
857 	fastmem_xlate, fastmem_check, NULL, _T("fast"), _T("Fast memory"),
858 	fastmem_lget, fastmem_wget,
859 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
860 };
861 addrbank fastmem_nojit_bank = {
862 	fastmem_nojit_lget, fastmem_nojit_wget, fastmem_bget,
863 	fastmem_nojit_lput, fastmem_nojit_wput, fastmem_bput,
864 	fastmem_nojit_xlate, fastmem_nojit_check, NULL, NULL, _T("Fast memory (nojit)"),
865 	fastmem_nojit_lget, fastmem_nojit_wget,
866 	ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
867 };
868 addrbank fastmem2_bank = {
869 	fastmem2_lget, fastmem2_wget, fastmem2_bget,
870 	fastmem2_lput, fastmem2_wput, fastmem2_bput,
871 	fastmem2_xlate, fastmem2_check, NULL,_T("fast2"), _T("Fast memory 2"),
872 	fastmem2_lget, fastmem2_wget,
873 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
874 };
875 addrbank fastmem2_nojit_bank = {
876 	fastmem2_nojit_lget, fastmem2_nojit_wget, fastmem2_nojit_bget,
877 	fastmem2_nojit_lput, fastmem2_nojit_wput, fastmem2_nojit_bput,
878 	fastmem2_nojit_xlate, fastmem2_nojit_check, NULL, NULL, _T("Fast memory #2 (nojit)"),
879 	fastmem2_nojit_lget, fastmem2_nojit_wget,
880 	ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
881 };
882 
883 static addrbank *fastbanks[] =
884 {
885 	&fastmem_bank,
886 	&fastmem_nojit_bank,
887 	&fastmem2_bank,
888 	&fastmem2_nojit_bank
889 };
890 
891 #ifdef CATWEASEL
892 
893 /*
894 * Catweasel ZorroII
895 */
896 
897 DECLARE_MEMORY_FUNCTIONS(catweasel);
898 
899 static uae_u32 catweasel_mask;
900 static uae_u32 catweasel_start;
901 
catweasel_lget(uaecptr addr)902 static uae_u32 REGPARAM2 catweasel_lget (uaecptr addr)
903 {
904 	write_log (_T("catweasel_lget @%08X!\n"),addr);
905 	return 0;
906 }
907 
catweasel_wget(uaecptr addr)908 static uae_u32 REGPARAM2 catweasel_wget (uaecptr addr)
909 {
910 	write_log (_T("catweasel_wget @%08X!\n"),addr);
911 	return 0;
912 }
913 
catweasel_bget(uaecptr addr)914 static uae_u32 REGPARAM2 catweasel_bget (uaecptr addr)
915 {
916 	addr -= catweasel_start & catweasel_mask;
917 	addr &= catweasel_mask;
918 	return catweasel_do_bget (addr);
919 }
920 
catweasel_lput(uaecptr addr,uae_u32 l)921 static void REGPARAM2 catweasel_lput (uaecptr addr, uae_u32 l)
922 {
923 	write_log (_T("catweasel_lput @%08X=%08X!\n"),addr,l);
924 }
925 
catweasel_wput(uaecptr addr,uae_u32 w)926 static void REGPARAM2 catweasel_wput (uaecptr addr, uae_u32 w)
927 {
928 	write_log (_T("catweasel_wput @%08X=%04X!\n"),addr,w);
929 }
930 
catweasel_bput(uaecptr addr,uae_u32 b)931 static void REGPARAM2 catweasel_bput (uaecptr addr, uae_u32 b)
932 {
933 	addr -= catweasel_start & catweasel_mask;
934 	addr &= catweasel_mask;
935 	catweasel_do_bput (addr, b);
936 }
937 
catweasel_check(uaecptr addr,uae_u32 size)938 static int REGPARAM2 catweasel_check (uaecptr addr, uae_u32 size)
939 {
940 	return 0;
941 }
942 
catweasel_xlate(uaecptr addr)943 static uae_u8 *REGPARAM2 catweasel_xlate (uaecptr addr)
944 {
945 	write_log (_T("catweasel_xlate @%08X size %08X\n"), addr);
946 	return 0;
947 }
948 
949 static addrbank catweasel_bank = {
950 	catweasel_lget, catweasel_wget, catweasel_bget,
951 	catweasel_lput, catweasel_wput, catweasel_bput,
952 	catweasel_xlate, catweasel_check, NULL, NULL, _T("Catweasel"),
953 	dummy_lgeti, dummy_wgeti,
954 	ABFLAG_IO, S_READ, S_WRITE
955 };
956 
expamem_map_catweasel(void)957 static addrbank *expamem_map_catweasel (void)
958 {
959 	catweasel_start = expamem_z2_pointer;
960 	map_banks_z2(&catweasel_bank, catweasel_start >> 16, 1);
961 	return &catweasel_bank;
962 }
963 
expamem_init_catweasel(int devnum)964 static addrbank *expamem_init_catweasel (int devnum)
965 {
966 	uae_u8 productid = cwc.type >= CATWEASEL_TYPE_MK3 ? 66 : 200;
967 	uae_u16 vendorid = cwc.type >= CATWEASEL_TYPE_MK3 ? 4626 : 5001;
968 
969 	catweasel_mask = (cwc.type >= CATWEASEL_TYPE_MK3) ? 0xffff : 0x1ffff;
970 
971 	expamem_init_clear ();
972 
973 	expamem_write (0x00, (cwc.type >= CATWEASEL_TYPE_MK3 ? Z2_MEM_64KB : Z2_MEM_128KB) | zorroII);
974 
975 	expamem_write (0x04, productid);
976 
977 	expamem_write (0x08, 0);
978 
979 	expamem_write (0x10, vendorid >> 8);
980 	expamem_write (0x14, vendorid & 0xff);
981 
982 	expamem_write (0x18, 0x00); /* ser.no. Byte 0 */
983 	expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */
984 	expamem_write (0x20, 0x00); /* ser.no. Byte 2 */
985 	expamem_write (0x24, 0x00); /* ser.no. Byte 3 */
986 
987 	expamem_write (0x28, 0x00); /* Rom-Offset hi */
988 	expamem_write (0x2c, 0x00); /* ROM-Offset lo */
989 
990 	expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
991 	return NULL;
992 }
993 
994 #endif
995 
996 #ifdef FILESYS
997 
998 /*
999 * Filesystem device ROM
1000 * This is very simple, the Amiga shouldn't be doing things with it.
1001 */
1002 
1003 DECLARE_MEMORY_FUNCTIONS(filesys);
1004 addrbank filesys_bank = {
1005 	filesys_lget, filesys_wget, filesys_bget,
1006 	filesys_lput, filesys_wput, filesys_bput,
1007 	default_xlate, default_check, NULL, _T("filesys"), _T("Filesystem autoconfig"),
1008 	dummy_lgeti, dummy_wgeti,
1009 	ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
1010 };
1011 
1012 static uae_u32 filesys_start; /* Determined by the OS */
1013 
filesys_lget(uaecptr addr)1014 static uae_u32 REGPARAM2 filesys_lget (uaecptr addr)
1015 {
1016 	uae_u8 *m;
1017 	addr -= filesys_start & 65535;
1018 	addr &= 65535;
1019 	m = filesys_bank.baseaddr + addr;
1020 #if EXP_DEBUG
1021 	write_log (_T("filesys_lget %x %x\n"), addr, do_get_mem_long ((uae_u32 *)m));
1022 #endif
1023 	return do_get_mem_long ((uae_u32 *)m);
1024 }
1025 
filesys_wget(uaecptr addr)1026 static uae_u32 REGPARAM2 filesys_wget (uaecptr addr)
1027 {
1028 	uae_u8 *m;
1029 	addr -= filesys_start & 65535;
1030 	addr &= 65535;
1031 	m = filesys_bank.baseaddr + addr;
1032 #if EXP_DEBUG
1033 	write_log (_T("filesys_wget %x %x\n"), addr, do_get_mem_word ((uae_u16 *)m));
1034 #endif
1035 	return do_get_mem_word ((uae_u16 *)m);
1036 }
1037 
filesys_bget(uaecptr addr)1038 static uae_u32 REGPARAM2 filesys_bget (uaecptr addr)
1039 {
1040 	addr -= filesys_start & 65535;
1041 	addr &= 65535;
1042 #if EXP_DEBUG
1043 	write_log (_T("filesys_bget %x %x\n"), addr, filesys_bank.baseaddr[addr]);
1044 #endif
1045 	return filesys_bank.baseaddr[addr];
1046 }
1047 
filesys_lput(uaecptr addr,uae_u32 l)1048 static void REGPARAM2 filesys_lput (uaecptr addr, uae_u32 l)
1049 {
1050 	write_log (_T("filesys_lput called PC=%08x\n"), M68K_GETPC);
1051 }
1052 
filesys_wput(uaecptr addr,uae_u32 w)1053 static void REGPARAM2 filesys_wput (uaecptr addr, uae_u32 w)
1054 {
1055 	write_log (_T("filesys_wput called PC=%08x\n"), M68K_GETPC);
1056 }
1057 
filesys_bput(uaecptr addr,uae_u32 b)1058 static void REGPARAM2 filesys_bput (uaecptr addr, uae_u32 b)
1059 {
1060 #if EXP_DEBUG
1061 	write_log (_T("filesys_bput %x %x\n"), addr, b);
1062 #endif
1063 }
1064 
1065 #endif /* FILESYS */
1066 
1067 // experimental hardware uae board
1068 
1069 DECLARE_MEMORY_FUNCTIONS(uaeboard);
1070 addrbank uaeboard_bank = {
1071 	uaeboard_lget, uaeboard_wget, uaeboard_bget,
1072 	uaeboard_lput, uaeboard_wput, uaeboard_bput,
1073 	default_xlate, default_check, NULL, _T("uaeboard"), _T("uae x autoconfig board"),
1074 	dummy_lgeti, dummy_wgeti,
1075 	ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
1076 };
1077 
1078 static uae_u32 uaeboard_start; /* Determined by the OS */
1079 #define UAEBOARD_RAM_SIZE 16384
1080 #define UAEBOARD_RAM_OFFSET (65536 - UAEBOARD_RAM_SIZE)
1081 #define UAEBOARD_IO_INTERFACE (UAEBOARD_RAM_OFFSET - 16)
1082 static uae_u8 uaeboard_io_state;
1083 static uae_u32 uaeboard_io_size, uaeboard_mem_ptr, uaeboard_mem_use;
1084 
uaeboard_wget(uaecptr addr)1085 static uae_u32 REGPARAM2 uaeboard_wget(uaecptr addr)
1086 {
1087 	uae_u8 *m;
1088 	addr -= uaeboard_start & 65535;
1089 	addr &= 65535;
1090 	if (addr == 0x200 || addr == 0x201) {
1091 		mousehack_wakeup();
1092 	}
1093 	m = uaeboard_bank.baseaddr + addr;
1094 #if EXP_DEBUG
1095 	write_log(_T("uaeboard_wget %x %x\n"), addr, do_get_mem_word((uae_u16 *)m));
1096 #endif
1097 	uae_u16 v = do_get_mem_word((uae_u16 *)m);
1098 
1099 	if (addr >= UAEBOARD_IO_INTERFACE) {
1100 		if (uaeboard_io_state & 16) {
1101 			uaeboard_mem_ptr &= (UAEBOARD_RAM_SIZE - 1);
1102 			if (uaeboard_mem_ptr + uaeboard_io_size > UAEBOARD_RAM_SIZE)
1103 				uaeboard_mem_ptr = 0;
1104 			if (addr == UAEBOARD_IO_INTERFACE + 8) {
1105 				uaeboard_io_state |= 32;
1106 				uaeboard_mem_use = uaeboard_mem_ptr + UAEBOARD_RAM_OFFSET;
1107 				v = uaeboard_mem_use >> 16;
1108 			} else if (addr == UAEBOARD_IO_INTERFACE + 8 + 2) {
1109 				uaeboard_io_state |= 64;
1110 				uaeboard_mem_use = uaeboard_mem_ptr + UAEBOARD_RAM_OFFSET;
1111 				v = uaeboard_mem_use >> 0;
1112 			}
1113 			if ((uaeboard_io_state & (32 | 64 | 128)) == (32 | 64)) {
1114 				uaeboard_mem_ptr += uaeboard_io_size;
1115 				uaeboard_io_state |= 128;
1116 			}
1117 		}
1118 	}
1119 
1120 	return v;
1121 }
1122 
uaeboard_lget(uaecptr addr)1123 static uae_u32 REGPARAM2 uaeboard_lget(uaecptr addr)
1124 {
1125 	addr -= uaeboard_start & 65535;
1126 	addr &= 65535;
1127 	uae_u32 v = uaeboard_wget(addr) << 16;
1128 	v |= uaeboard_wget(addr + 2);
1129 	return v;
1130 }
1131 
uaeboard_bget(uaecptr addr)1132 static uae_u32 REGPARAM2 uaeboard_bget(uaecptr addr)
1133 {
1134 	addr -= uaeboard_start & 65535;
1135 	addr &= 65535;
1136 	if (addr == 0x200 || addr == 0x201) {
1137 		mousehack_wakeup();
1138 	} else if (addr == UAEBOARD_IO_INTERFACE) {
1139 		uaeboard_bank.baseaddr[UAEBOARD_IO_INTERFACE] = uaeboard_io_state == 0;
1140 		if (!uaeboard_io_state) {
1141 			// mark allocated
1142 			uaeboard_io_state = 1;
1143 		}
1144 	} else if (addr == UAEBOARD_IO_INTERFACE + 2) {
1145 		if (uaeboard_io_state & 8) {
1146 			uaeboard_bank.baseaddr[addr] = 1;
1147 			uaeboard_io_state |= 16;
1148 		}
1149 	} else if (addr == uaeboard_mem_use) {
1150 		uaeboard_bank.baseaddr[addr] = 1;
1151 	}
1152 #if EXP_DEBUG
1153 	write_log(_T("uaeboard_bget %x %x\n"), addr, uaeboard_bank.baseaddr[addr]);
1154 #endif
1155 	return uaeboard_bank.baseaddr[addr];
1156 }
1157 
uaeboard_wput(uaecptr addr,uae_u32 w)1158 static void REGPARAM2 uaeboard_wput(uaecptr addr, uae_u32 w)
1159 {
1160 	addr -= uaeboard_start & 65535;
1161 	addr &= 65535;
1162 	if (addr >= 0x200 + 0x20 && addr < 0x200 + 0x24) {
1163 		mousehack_write(addr - 0x200, w);
1164 	} else if (addr >= UAEBOARD_IO_INTERFACE) {
1165 		uae_u16 *m = (uae_u16 *)(uaeboard_bank.baseaddr + addr);
1166 		do_put_mem_word(m, w);
1167 		if (uaeboard_io_state) {
1168 			if (addr == UAEBOARD_IO_INTERFACE + 4)
1169 				uaeboard_io_state |= 2;
1170 			if (addr == UAEBOARD_IO_INTERFACE + 6)
1171 				uaeboard_io_state |= 4;
1172 			if (uaeboard_io_state == (1 | 2 | 4)) {
1173 				uae_u32 *m2 = (uae_u32 *)(uaeboard_bank.baseaddr + UAEBOARD_IO_INTERFACE + 4);
1174 				// size received
1175 				uaeboard_io_state |= 8;
1176 				uaeboard_io_size = do_get_mem_long(m2);
1177 			}
1178 		}
1179 		// writing command byte executes it
1180 		if (addr == uaeboard_mem_use) {
1181 			w &= 0xffff;
1182 			if (w != 0xffff && w != 0) {
1183 				uae_u32 *m2 = (uae_u32 *)(uaeboard_bank.baseaddr + addr);
1184 				do_put_mem_long(m2 + 1, uaeboard_demux(m2));
1185 			}
1186 		}
1187 	}
1188 #if EXP_DEBUG
1189 	write_log(_T("uaeboard_wput %08x = %04x PC=%08x\n"), addr, w, M68K_GETPC);
1190 #endif
1191 }
1192 
uaeboard_lput(uaecptr addr,uae_u32 l)1193 static void REGPARAM2 uaeboard_lput(uaecptr addr, uae_u32 l)
1194 {
1195 	addr -= uaeboard_start & 65535;
1196 	addr &= 65535;
1197 	if (addr >= 0x200 + 0x20 && addr < 0x200 + 0x24) {
1198 		mousehack_write(addr - 0x200, l >> 16);
1199 		mousehack_write(addr - 0x200 + 2, l);
1200 	} else if (addr >= UAEBOARD_IO_INTERFACE) {
1201 		uaeboard_wput(addr, l >> 16);
1202 		uaeboard_wput(addr + 2, l);
1203 	}
1204 #if EXP_DEBUG
1205 	write_log(_T("uaeboard_lput %08x = %08x PC=%08x\n"), addr, l, M68K_GETPC);
1206 #endif
1207 }
1208 
uaeboard_bput(uaecptr addr,uae_u32 b)1209 static void REGPARAM2 uaeboard_bput(uaecptr addr, uae_u32 b)
1210 {
1211 	addr -= uaeboard_start & 65535;
1212 	addr &= 65535;
1213 	if (addr == uaeboard_mem_use) {
1214 		uaeboard_io_size = 0;
1215 		uaeboard_mem_use = 0;
1216 		uaeboard_io_state = 0;
1217 	}
1218 	if (addr >= UAEBOARD_RAM_OFFSET) {
1219 		uaeboard_bank.baseaddr[addr] = b;
1220 	}
1221 #if EXP_DEBUG
1222 	write_log(_T("uaeboard_bput %x %x\n"), addr, b);
1223 #endif
1224 }
1225 
expamem_map_uaeboard(void)1226 static addrbank *expamem_map_uaeboard(void)
1227 {
1228 	uaeboard_start = expamem_z2_pointer;
1229 	map_banks_z2(&uaeboard_bank, uaeboard_start >> 16, 1);
1230 	return &uaeboard_bank;
1231 }
expamem_init_uaeboard(int devnum)1232 static addrbank* expamem_init_uaeboard(int devnum)
1233 {
1234 	uae_u8 *p = uaeboard_bank.baseaddr;
1235 
1236 	expamem_init_clear();
1237 	expamem_write(0x00, (currprefs.uaeboard > 1 ? Z2_MEM_128KB : Z2_MEM_64KB) | zorroII);
1238 
1239 	expamem_write(0x08, no_shutup);
1240 
1241 	expamem_write(0x04, 1);
1242 	expamem_write(0x10, 6502 >> 8);
1243 	expamem_write(0x14, 6502 & 0xff);
1244 
1245 	expamem_write(0x18, 0x00); /* ser.no. Byte 0 */
1246 	expamem_write(0x1c, 0x00); /* ser.no. Byte 1 */
1247 	expamem_write(0x20, 0x00); /* ser.no. Byte 2 */
1248 	expamem_write(0x24, 0x01); /* ser.no. Byte 3 */
1249 
1250 							   /* er_InitDiagVec */
1251 	expamem_write(0x28, 0x00); /* Rom-Offset hi */
1252 	expamem_write(0x2c, 0x00); /* ROM-Offset lo */
1253 
1254 	memcpy(p, expamem, 0x100);
1255 
1256 	p += 0x100;
1257 
1258 	p[0] = 0x00;
1259 	p[1] = 0x00;
1260 	p[2] = 0x02;
1261 	p[3] = 0x00;
1262 
1263 	p[4] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 24);
1264 	p[5] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 16);
1265 	p[6] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 8);
1266 	p[7] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 0);
1267 	uaeboard_io_state = 0;
1268 
1269 	return NULL;
1270 }
1271 
1272 /*
1273 *  Z3fastmem Memory
1274 */
1275 
1276 MEMORY_FUNCTIONS(z3fastmem);
1277 MEMORY_FUNCTIONS(z3fastmem2);
1278 MEMORY_FUNCTIONS(z3chipmem);
1279 
1280 addrbank z3fastmem_bank = {
1281 	z3fastmem_lget, z3fastmem_wget, z3fastmem_bget,
1282 	z3fastmem_lput, z3fastmem_wput, z3fastmem_bput,
1283 	z3fastmem_xlate, z3fastmem_check, NULL, _T("z3"), _T("Zorro III Fast RAM"),
1284 	z3fastmem_lget, z3fastmem_wget,
1285 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1286 };
1287 addrbank z3fastmem2_bank = {
1288 	z3fastmem2_lget, z3fastmem2_wget, z3fastmem2_bget,
1289 	z3fastmem2_lput, z3fastmem2_wput, z3fastmem2_bput,
1290 	z3fastmem2_xlate, z3fastmem2_check, NULL, _T("z3_2"), _T("Zorro III Fast RAM #2"),
1291 	z3fastmem2_lget, z3fastmem2_wget,
1292 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1293 };
1294 addrbank z3chipmem_bank = {
1295 	z3chipmem_lget, z3chipmem_wget, z3chipmem_bget,
1296 	z3chipmem_lput, z3chipmem_wput, z3chipmem_bput,
1297 	z3chipmem_xlate, z3chipmem_check, NULL, _T("z3_chip"), _T("MegaChipRAM"),
1298 	z3chipmem_lget, z3chipmem_wget,
1299 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1300 };
1301 
1302 /* ********************************************************** */
1303 
1304 /*
1305 *     Expansion Card (ZORRO II) for 64/128/256/512KB 1/2/4/8MB of Fast Memory
1306 */
1307 
expamem_map_fastcard_2(int boardnum)1308 static addrbank *expamem_map_fastcard_2 (int boardnum)
1309 {
1310 	uae_u32 start = ((expamem_hi | (expamem_lo >> 4)) << 16);
1311 	addrbank *ab = fastbanks[boardnum * 2 + ((start < 0x00A00000) ? 0 : 1)];
1312 	uae_u32 size = ab->allocated;
1313 	ab->start = start;
1314 	if (ab->start) {
1315 		map_banks_z2(ab, ab->start >> 16, size >> 16);
1316 	}
1317 	return ab;
1318 }
1319 
fastmem_autoconfig(int boardnum,int zorro,uae_u8 type,uae_u32 serial,int allocated)1320 static void fastmem_autoconfig(int boardnum, int zorro, uae_u8 type, uae_u32 serial, int allocated)
1321 {
1322 	uae_u16 mid = 0;
1323 	uae_u8 pid;
1324 	uae_u8 flags = care_addr;
1325 	DEVICE_MEMORY_CALLBACK dmc = NULL;
1326 	struct romconfig *dmc_rc = NULL;
1327 	uae_u8 ac[16] = { 0 };
1328 
1329 	if (boardnum == 1) {
1330 		const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
1331 		if (cst->memory_mid) {
1332 			mid = cst->memory_mid;
1333 			pid = cst->memory_pid;
1334 			serial = cst->memory_serial;
1335 		}
1336 	} else if (boardnum == 0) {
1337 		for (int i = 0; expansionroms[i].name; i++) {
1338 			const struct expansionromtype *erc = &expansionroms[i];
1339 			if (((erc->zorro == zorro) || (zorro < 0 && erc->zorro >= BOARD_NONAUTOCONFIG_BEFORE)) && cfgfile_board_enabled(&currprefs, erc->romtype, 0)) {
1340 				struct romconfig *rc = get_device_romconfig(&currprefs, erc->romtype, 0);
1341 				if (erc->subtypes) {
1342 					const struct expansionsubromtype *srt = &erc->subtypes[rc->subtype];
1343 					if (srt->memory_mid) {
1344 						mid = srt->memory_mid;
1345 						pid = srt->memory_pid;
1346 						serial = srt->memory_serial;
1347 						if (!srt->memory_after)
1348 							type |= chainedconfig;
1349 					}
1350 				} else {
1351 					if (erc->memory_mid) {
1352 						mid = erc->memory_mid;
1353 						pid = erc->memory_pid;
1354 						serial = erc->memory_serial;
1355 						if (!erc->memory_after)
1356 							type |= chainedconfig;
1357 					}
1358 				}
1359 				dmc = erc->memory_callback;
1360 				dmc_rc = rc;
1361 				break;
1362 			}
1363 		}
1364 	}
1365 
1366 	if (!mid) {
1367 		if (zorro <= 2) {
1368 			pid = currprefs.maprom && !currprefs.cpuboard_type ? 1 : 81;
1369 		} else {
1370 			int subsize = (allocated == 0x100000 ? Z3_SS_MEM_1MB
1371 						   : allocated == 0x200000 ? Z3_SS_MEM_2MB
1372 						   : allocated == 0x400000 ? Z3_SS_MEM_4MB
1373 						   : allocated == 0x800000 ? Z3_SS_MEM_8MB
1374 						   : Z3_SS_MEM_SAME);
1375 			pid = currprefs.maprom && !currprefs.cpuboard_type ? 3 : 83;
1376 			flags |= force_z3 | (allocated > 0x800000 ? ext_size : subsize);
1377 		}
1378 		mid = uae_id;
1379 	}
1380 
1381 	ac[0x00 / 4] = type;
1382 	ac[0x04 / 4] = pid;
1383 	ac[0x08 / 4] = flags;
1384 	ac[0x10 / 4] = mid >> 8;
1385 	ac[0x14 / 4] = (uae_u8)mid;
1386 	ac[0x18 / 4] = serial >> 24;
1387 	ac[0x1c / 4] = serial >> 16;
1388 	ac[0x20 / 4] = serial >> 8;
1389 	ac[0x24 / 4] = serial >> 0;
1390 
1391 	if (dmc && dmc_rc)
1392 		dmc(dmc_rc, ac, allocated);
1393 
1394 	expamem_write(0x00, ac[0x00 / 4]);
1395 	expamem_write(0x04, ac[0x04 / 4]);
1396 	expamem_write(0x08, ac[0x08 / 4]);
1397 	expamem_write(0x10, ac[0x10 / 4]);
1398 	expamem_write(0x14, ac[0x14 / 4]);
1399 
1400 	expamem_write(0x18, ac[0x18 / 4]); /* ser.no. Byte 0 */
1401 	expamem_write(0x1c, ac[0x1c / 4]); /* ser.no. Byte 1 */
1402 	expamem_write(0x20, ac[0x20 / 4]); /* ser.no. Byte 2 */
1403 	expamem_write(0x24, ac[0x24 / 4]); /* ser.no. Byte 3 */
1404 
1405 	expamem_write(0x28, 0x00); /* ROM-Offset hi */
1406 	expamem_write(0x2c, 0x00); /* ROM-Offset lo */
1407 
1408 	expamem_write(0x40, 0x00); /* Ctrl/Statusreg.*/
1409 }
1410 
1411 static const uae_u8 a2630_autoconfig[] = { 0xe7, 0x51, 0x40, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1412 
expamem_init_fastcard_2(int boardnum)1413 static addrbank *expamem_init_fastcard_2(int boardnum)
1414 {
1415 	uae_u8 type = add_memory | zorroII;
1416 	int allocated = boardnum ? fastmem2_bank.allocated : fastmem_bank.allocated;
1417 	uae_u32 serial = 1;
1418 
1419 	if (allocated == 0)
1420 		return &expamem_null;
1421 
1422 	expamem_init_clear ();
1423 	if (allocated == 65536)
1424 		type |= Z2_MEM_64KB;
1425 	else if (allocated == 131072)
1426 		type |= Z2_MEM_128KB;
1427 	else if (allocated == 262144)
1428 		type |= Z2_MEM_256KB;
1429 	else if (allocated == 524288)
1430 		type |= Z2_MEM_512KB;
1431 	else if (allocated == 0x100000)
1432 		type |= Z2_MEM_1MB;
1433 	else if (allocated == 0x200000)
1434 		type |= Z2_MEM_2MB;
1435 	else if (allocated == 0x400000)
1436 		type |= Z2_MEM_4MB;
1437 	else if (allocated == 0x800000)
1438 		type |= Z2_MEM_8MB;
1439 
1440 	if (boardnum == 1) {
1441 		if (ISCPUBOARD(BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0)) {
1442 			for (int i = 1; i < 16; i++)
1443 				expamem_write(i * 4, a2630_autoconfig[i]);
1444 			type &= 7;
1445 			type |= a2630_autoconfig[0] & ~7;
1446 			expamem_write(0, type);
1447 			return NULL;
1448 		}
1449 	}
1450 
1451 	fastmem_autoconfig(boardnum, BOARD_AUTOCONFIG_Z2, type, serial, allocated);
1452 	fastmem_autoconfig(boardnum, -1, type, serial, allocated);
1453 
1454 	return NULL;
1455 }
1456 
expamem_init_fastcard(int boardnum)1457 static addrbank *expamem_init_fastcard(int boardnum)
1458 {
1459 	return expamem_init_fastcard_2(0);
1460 }
expamem_init_fastcard2(int boardnum)1461 static addrbank *expamem_init_fastcard2(int boardnum)
1462 {
1463 	return expamem_init_fastcard_2(1);
1464 }
expamem_map_fastcard(void)1465 static addrbank *expamem_map_fastcard (void)
1466 {
1467 	return expamem_map_fastcard_2 (0);
1468 }
expamem_map_fastcard2(void)1469 static addrbank *expamem_map_fastcard2 (void)
1470 {
1471 	return expamem_map_fastcard_2 (1);
1472 }
1473 
expansion_is_next_board_fastram(void)1474 bool expansion_is_next_board_fastram(void)
1475 {
1476 	return ecard + 1 < MAX_EXPANSION_BOARD_SPACE && cards[ecard + 1].map == expamem_map_fastcard;
1477 }
1478 
1479 /* ********************************************************** */
1480 
1481 #ifdef FILESYS
1482 
1483 /*
1484 * Filesystem device
1485 */
1486 
expamem_map_filesys_update(void)1487 static void expamem_map_filesys_update(void)
1488 {
1489 	/* 68k code needs to know this. */
1490 	uaecptr a = here();
1491 	org(rtarea_base + RTAREA_FSBOARD);
1492 	dl(filesys_start + 0x2000);
1493 	org(a);
1494 }
1495 
expamem_map_filesys(void)1496 static addrbank *expamem_map_filesys (void)
1497 {
1498 	// Warn if PPC doing autoconfig and UAE expansion enabled
1499 	static bool warned;
1500 	if (!warned && regs.halted < 0) {
1501 		warned = true;
1502 		// can't show dialogs from PPC thread, deadlock danger.
1503 		regs.halted = -2;
1504 	}
1505 
1506 	filesys_start = expamem_z2_pointer;
1507 	map_banks_z2(&filesys_bank, filesys_start >> 16, 1);
1508 	expamem_map_filesys_update();
1509 	return &filesys_bank;
1510 }
1511 
1512 #define FILESYS_DIAGPOINT 0x01e0
1513 #define FILESYS_BOOTPOINT 0x01e6
1514 #define FILESYS_DIAGAREA 0x2000
1515 
1516 #if KS12_BOOT_HACK
add_ks12_boot_hack(void)1517 static void add_ks12_boot_hack(void)
1518 {
1519 	uaecptr name = ds(_T("UAE boot"));
1520 	align(2);
1521 	uaecptr code = here();
1522 	// allocate fake diagarea
1523 	dl(0x48e73f3e); // movem.l d2-d7/a2-a6,-(sp)
1524 	dw(0x203c); // move.l #x,d0
1525 	dl(0x0300);
1526 	dw(0x7201); // moveq #1,d1
1527 	dl(0x4eaeff3a); // jsr -0xc6(a6)
1528 	dw(0x2440); // move.l d0,a2 ;diag area
1529 	dw(0x9bcd); // sub.l a5,a5 ;expansionbase
1530 	dw(0x97cb); // sub.l a3,a3 ;configdev
1531 	dw(0x4eb9); // jsr
1532 	dl(ROM_filesys_diagentry);
1533 	dl(0x4cdf7cfc); // movem.l (sp)+,d2-d7/a2-a6
1534 	dw(0x4e75);
1535 	// struct Resident
1536 	uaecptr addr = here();
1537 	dw(0x4afc);
1538 	dl(addr);
1539 	dl(addr + 26);
1540 	db(1); // RTF_COLDSTART
1541 	db((uae_u8)kickstart_version); // version
1542 	db(0); // NT_UNKNOWN
1543 	db(1); // priority
1544 	dl(name);
1545 	dl(name);
1546 	dl(code);
1547 }
1548 #endif
1549 
expamem_init_filesys(int devnum)1550 static addrbank* expamem_init_filesys (int devnum)
1551 {
1552 	bool ks12 = ks12orolder();
1553 	bool hide = currprefs.uae_hide_autoconfig;
1554 
1555 	/* struct DiagArea - the size has to be large enough to store several device ROMTags */
1556 	uae_u8 diagarea[] = { 0x90, 0x00, /* da_Config, da_Flags */
1557 		0x02, 0x00, /* da_Size */
1558 		FILESYS_DIAGPOINT >> 8, FILESYS_DIAGPOINT & 0xff,
1559 		FILESYS_BOOTPOINT >> 8, FILESYS_BOOTPOINT & 0xff,
1560 		0, hide ? 0 : 14, // Name offset
1561 		0, 0, 0, 0,
1562 		hide ? 0 : 'U', hide ? 0 : 'A', hide ? 0 : 'E', 0
1563 	};
1564 
1565 	expamem_init_clear ();
1566 	expamem_write (0x00, Z2_MEM_64KB | zorroII | (ks12 ? 0 : rom_card));
1567 
1568 	expamem_write (0x08, no_shutup);
1569 
1570 	expamem_write (0x04, currprefs.maprom && !currprefs.cpuboard_type ? 2 : 82);
1571 	expamem_write (0x10, uae_id >> 8);
1572 	expamem_write (0x14, uae_id & 0xff);
1573 
1574 	expamem_write (0x18, 0x00); /* ser.no. Byte 0 */
1575 	expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */
1576 	expamem_write (0x20, 0x00); /* ser.no. Byte 2 */
1577 	expamem_write (0x24, 0x01); /* ser.no. Byte 3 */
1578 
1579 	/* er_InitDiagVec */
1580 	expamem_write (0x28, 0x20); /* Rom-Offset hi */
1581 	expamem_write (0x2c, 0x00); /* ROM-Offset lo */
1582 
1583 	expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
1584 
1585 	/* Build a DiagArea */
1586 	memcpy (expamem + FILESYS_DIAGAREA, diagarea, sizeof diagarea);
1587 
1588 	/* Call DiagEntry */
1589 	do_put_mem_word ((uae_u16 *)(expamem + FILESYS_DIAGAREA + FILESYS_DIAGPOINT), 0x4EF9); /* JMP */
1590 	do_put_mem_long ((uae_u32 *)(expamem + FILESYS_DIAGAREA + FILESYS_DIAGPOINT + 2), ROM_filesys_diagentry);
1591 
1592 	/* What comes next is a plain bootblock */
1593 	do_put_mem_word ((uae_u16 *)(expamem + FILESYS_DIAGAREA + FILESYS_BOOTPOINT), 0x4EF9); /* JMP */
1594 	do_put_mem_long ((uae_u32 *)(expamem + FILESYS_DIAGAREA + FILESYS_BOOTPOINT + 2), EXPANSION_bootcode);
1595 
1596 	if (ks12)
1597 		add_ks12_boot_hack();
1598 
1599 	memcpy (filesys_bank.baseaddr, expamem, 0x3000);
1600 	return NULL;
1601 }
1602 
1603 #endif
1604 
1605 /*
1606 * Zorro III expansion memory
1607 */
1608 
expamem_map_z3fastmem_2(addrbank * bank,uaecptr * startp,uae_u32 size,uae_u32 allocated,int chip)1609 static addrbank * expamem_map_z3fastmem_2 (addrbank *bank, uaecptr *startp, uae_u32 size, uae_u32 allocated, int chip)
1610 {
1611 	int z3fs = expamem_z3_pointer;
1612 	int start = *startp;
1613 
1614 	if (expamem_z3hack(&currprefs)) {
1615 		if (z3fs && start != z3fs) {
1616 			write_log (_T("WARNING: Z3MEM mapping changed from $%08x to $%08x\n"), start, z3fs);
1617 			map_banks(&dummy_bank, start >> 16, size >> 16, allocated);
1618 			*startp = z3fs;
1619 			map_banks_z3(bank, start >> 16, size >> 16);
1620 		}
1621 	} else {
1622 		map_banks_z3(bank, z3fs >> 16, size >> 16);
1623 		start = z3fs;
1624 		*startp = z3fs;
1625 	}
1626 	return bank;
1627 }
1628 
expamem_map_z3fastmem(void)1629 static addrbank *expamem_map_z3fastmem (void)
1630 {
1631 	return expamem_map_z3fastmem_2 (&z3fastmem_bank, &z3fastmem_bank.start, currprefs.z3fastmem_size, z3fastmem_bank.allocated, 0);
1632 }
expamem_map_z3fastmem2(void)1633 static addrbank *expamem_map_z3fastmem2 (void)
1634 {
1635 	return expamem_map_z3fastmem_2 (&z3fastmem2_bank, &z3fastmem2_bank.start, currprefs.z3fastmem2_size, z3fastmem2_bank.allocated, 0);
1636 }
1637 
expamem_init_z3fastmem_2(int boardnum,addrbank * bank,uae_u32 start,uae_u32 size,uae_u32 allocated)1638 static addrbank *expamem_init_z3fastmem_2(int boardnum, addrbank *bank, uae_u32 start, uae_u32 size, uae_u32 allocated)
1639 {
1640 	int code = (allocated == 0x100000 ? Z2_MEM_1MB
1641 		: allocated == 0x200000 ? Z2_MEM_2MB
1642 		: allocated == 0x400000 ? Z2_MEM_4MB
1643 		: allocated == 0x800000 ? Z2_MEM_8MB
1644 		: allocated == 0x1000000 ? Z3_MEM_16MB
1645 		: allocated == 0x2000000 ? Z3_MEM_32MB
1646 		: allocated == 0x4000000 ? Z3_MEM_64MB
1647 		: allocated == 0x8000000 ? Z3_MEM_128MB
1648 		: allocated == 0x10000000 ? Z3_MEM_256MB
1649 		: allocated == 0x20000000 ? Z3_MEM_512MB
1650 		: Z3_MEM_1GB);
1651 
1652 	if (allocated < 0x1000000)
1653 		code = Z3_MEM_16MB; /* Z3 physical board size is always at least 16M */
1654 
1655 	expamem_init_clear ();
1656 	fastmem_autoconfig(boardnum, BOARD_AUTOCONFIG_Z3, add_memory | zorroIII | code, 1, allocated);
1657 	map_banks_z3(bank, start >> 16, size >> 16);
1658 	return NULL;
1659 }
expamem_init_z3fastmem(int devnum)1660 static addrbank *expamem_init_z3fastmem (int devnum)
1661 {
1662 	return expamem_init_z3fastmem_2 (0, &z3fastmem_bank, z3fastmem_bank.start, currprefs.z3fastmem_size, z3fastmem_bank.allocated);
1663 }
expamem_init_z3fastmem2(int devnum)1664 static addrbank *expamem_init_z3fastmem2(int devnum)
1665 {
1666 	return expamem_init_z3fastmem_2 (1, &z3fastmem2_bank, z3fastmem2_bank.start, currprefs.z3fastmem2_size, z3fastmem2_bank.allocated);
1667 }
1668 
1669 #ifdef PICASSO96
1670 /*
1671 *  Fake Graphics Card (ZORRO III) - BDK
1672 */
1673 
expamem_map_gfxcard_z3(void)1674 static addrbank *expamem_map_gfxcard_z3 (void)
1675 {
1676 	gfxmem_bank.start = expamem_z3_pointer;
1677 	map_banks_z3(&gfxmem_bank, gfxmem_bank.start >> 16, gfxmem_bank.allocated >> 16);
1678 	return &gfxmem_bank;
1679 }
1680 
expamem_map_gfxcard_z2(void)1681 static addrbank *expamem_map_gfxcard_z2 (void)
1682 {
1683 	gfxmem_bank.start = expamem_z2_pointer;
1684 	map_banks_z2(&gfxmem_bank, gfxmem_bank.start >> 16, gfxmem_bank.allocated >> 16);
1685 	return &gfxmem_bank;
1686 }
1687 
expamem_init_gfxcard(bool z3)1688 static addrbank *expamem_init_gfxcard (bool z3)
1689 {
1690 	int code = (gfxmem_bank.allocated == 0x100000 ? Z2_MEM_1MB
1691 		: gfxmem_bank.allocated == 0x200000 ? Z2_MEM_2MB
1692 		: gfxmem_bank.allocated == 0x400000 ? Z2_MEM_4MB
1693 		: gfxmem_bank.allocated == 0x800000 ? Z2_MEM_8MB
1694 		: gfxmem_bank.allocated == 0x1000000 ? Z3_MEM_16MB
1695 		: gfxmem_bank.allocated == 0x2000000 ? Z3_MEM_32MB
1696 		: gfxmem_bank.allocated == 0x4000000 ? Z3_MEM_64MB
1697 		: gfxmem_bank.allocated == 0x8000000 ? Z3_MEM_128MB
1698 		: gfxmem_bank.allocated == 0x10000000 ? Z3_MEM_256MB
1699 		: gfxmem_bank.allocated == 0x20000000 ? Z3_MEM_512MB
1700 		: Z3_MEM_1GB);
1701 	int subsize = (gfxmem_bank.allocated == 0x100000 ? Z3_SS_MEM_1MB
1702 		: gfxmem_bank.allocated == 0x200000 ? Z3_SS_MEM_2MB
1703 		: gfxmem_bank.allocated == 0x400000 ? Z3_SS_MEM_4MB
1704 		: gfxmem_bank.allocated == 0x800000 ? Z3_SS_MEM_8MB
1705 		: Z3_SS_MEM_SAME);
1706 
1707 	if (gfxmem_bank.allocated < 0x1000000 && z3)
1708 		code = Z3_MEM_16MB; /* Z3 physical board size is always at least 16M */
1709 
1710 	expamem_init_clear ();
1711 	expamem_write (0x00, (z3 ? zorroIII : zorroII) | code);
1712 
1713 	expamem_write (0x08, care_addr | (z3 ? (force_z3 | (gfxmem_bank.allocated > 0x800000 ? ext_size: subsize)) : 0));
1714 	expamem_write (0x04, 96);
1715 
1716 	expamem_write (0x10, uae_id >> 8);
1717 	expamem_write (0x14, uae_id & 0xff);
1718 
1719 	expamem_write (0x18, 0x00); /* ser.no. Byte 0 */
1720 	expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */
1721 	expamem_write (0x20, 0x00); /* ser.no. Byte 2 */
1722 	expamem_write (0x24, 0x01); /* ser.no. Byte 3 */
1723 
1724 	expamem_write (0x28, 0x00); /* ROM-Offset hi */
1725 	expamem_write (0x2c, 0x00); /* ROM-Offset lo */
1726 
1727 	expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
1728 	return NULL;
1729 }
expamem_init_gfxcard_z3(int devnum)1730 static addrbank *expamem_init_gfxcard_z3(int devnum)
1731 {
1732 	return expamem_init_gfxcard (true);
1733 }
expamem_init_gfxcard_z2(int devnum)1734 static addrbank *expamem_init_gfxcard_z2 (int devnum)
1735 {
1736 	return expamem_init_gfxcard (false);
1737 }
1738 #endif
1739 
1740 
1741 #ifdef SAVESTATE
1742 static size_t fast_filepos, fast2_filepos, z3_filepos, z3_filepos2, z3_fileposchip, p96_filepos;
1743 #endif
1744 
free_fastmemory(int boardnum)1745 void free_fastmemory (int boardnum)
1746 {
1747 	if (!boardnum) {
1748 		mapped_free (&fastmem_bank);
1749 	} else {
1750 		mapped_free (&fastmem2_bank);
1751 	}
1752 }
1753 
mapped_malloc_dynamic(uae_u32 * currpsize,uae_u32 * changedpsize,addrbank * bank,int max,const TCHAR * name)1754 static bool mapped_malloc_dynamic (uae_u32 *currpsize, uae_u32 *changedpsize, addrbank *bank, int max, const TCHAR *name)
1755 {
1756 	int alloc = *currpsize;
1757 
1758 	bank->allocated = 0;
1759 	bank->baseaddr = NULL;
1760 	bank->mask = 0;
1761 
1762 	if (!alloc)
1763 		return false;
1764 
1765 	while (alloc >= max * 1024 * 1024) {
1766 		bank->mask = alloc - 1;
1767 		bank->allocated = alloc;
1768 		bank->label = name;
1769 		if (mapped_malloc (bank)) {
1770 			*currpsize = alloc;
1771 			*changedpsize = alloc;
1772 			return true;
1773 		}
1774 		write_log (_T("Out of memory for %s, %d bytes.\n"), name, alloc);
1775 		alloc /= 2;
1776 	}
1777 
1778 	return false;
1779 }
1780 
expansion_startaddress(uaecptr addr,uae_u32 size)1781 uaecptr expansion_startaddress(uaecptr addr, uae_u32 size)
1782 {
1783 	if (!size)
1784 		return addr;
1785 	if (size < 16 * 1024 * 1024)
1786 		size = 16 * 1024 * 1024;
1787 	if (!expamem_z3hack(&currprefs))
1788 		return (addr + size - 1) & ~(size - 1);
1789 	return addr;
1790 }
1791 
allocate_expamem(void)1792 static void allocate_expamem (void)
1793 {
1794 	currprefs.fastmem_size = changed_prefs.fastmem_size;
1795 	currprefs.fastmem2_size = changed_prefs.fastmem2_size;
1796 	currprefs.z3fastmem_size = changed_prefs.z3fastmem_size;
1797 	currprefs.z3fastmem2_size = changed_prefs.z3fastmem2_size;
1798 	currprefs.rtgmem_size = changed_prefs.rtgmem_size;
1799 	currprefs.rtgmem_type = changed_prefs.rtgmem_type;
1800 	currprefs.z3chipmem_size = changed_prefs.z3chipmem_size;
1801 
1802 	z3chipmem_bank.start = Z3BASE_UAE;
1803 	z3fastmem_bank.start = currprefs.z3autoconfig_start;
1804 	if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024)
1805 		z3chipmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
1806 	if (!expamem_z3hack(&currprefs))
1807 		z3fastmem_bank.start = Z3BASE_REAL;
1808 	if (z3fastmem_bank.start == Z3BASE_REAL) {
1809 		int z3off = cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].z3extra;
1810 		if (z3off) {
1811 			z3fastmem_bank.start += z3off;
1812 			z3fastmem_bank.start = expansion_startaddress(z3fastmem_bank.start, currprefs.z3fastmem_size);
1813 		}
1814 	}
1815 	if (z3fastmem_bank.start == Z3BASE_UAE) {
1816 		if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024)
1817 			z3fastmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
1818 		z3fastmem_bank.start += currprefs.z3chipmem_size;
1819 	}
1820 	z3fastmem2_bank.start = z3fastmem_bank.start + currprefs.z3fastmem_size;
1821 
1822 	if (currprefs.z3chipmem_size && z3fastmem_bank.start - z3chipmem_bank.start < currprefs.z3chipmem_size)
1823 		currprefs.z3chipmem_size = changed_prefs.z3chipmem_size = 0;
1824 
1825 	if (fastmem_bank.allocated != currprefs.fastmem_size) {
1826 		free_fastmemory (0);
1827 
1828 		fastmem_bank.allocated = currprefs.fastmem_size;
1829 		fastmem_bank.mask = fastmem_bank.allocated - 1;
1830 
1831 		fastmem_nojit_bank.allocated = fastmem_bank.allocated;
1832 		fastmem_nojit_bank.mask = fastmem_bank.mask;
1833 
1834 		if (fastmem_bank.allocated) {
1835 			mapped_malloc (&fastmem_bank);
1836 			fastmem_nojit_bank.baseaddr = fastmem_bank.baseaddr;
1837 			if (fastmem_bank.baseaddr == 0) {
1838 				write_log (_T("Out of memory for fastmem card.\n"));
1839 				fastmem_bank.allocated = 0;
1840 				fastmem_nojit_bank.allocated = 0;
1841 			}
1842 		}
1843 		memory_hardreset (1);
1844 	}
1845 
1846 	if (fastmem2_bank.allocated != currprefs.fastmem2_size) {
1847 		free_fastmemory (1);
1848 
1849 		fastmem2_bank.allocated = currprefs.fastmem2_size;
1850 		fastmem2_bank.mask = fastmem2_bank.allocated - 1;
1851 
1852 		fastmem2_nojit_bank.allocated = fastmem2_bank.allocated;
1853 		fastmem2_nojit_bank.mask = fastmem2_bank.mask;
1854 
1855 		if (fastmem2_bank.allocated) {
1856 			mapped_malloc (&fastmem2_bank);
1857 			fastmem2_nojit_bank.baseaddr = fastmem2_bank.baseaddr;
1858 			if (fastmem2_bank.baseaddr == 0) {
1859 				write_log (_T("Out of memory for fastmem2 card.\n"));
1860 				fastmem2_bank.allocated = 0;
1861 				fastmem2_nojit_bank.allocated = 0;
1862 			}
1863 		}
1864 		memory_hardreset (1);
1865 	}
1866 
1867 	if (z3fastmem_bank.allocated != currprefs.z3fastmem_size) {
1868 		mapped_free (&z3fastmem_bank);
1869 		mapped_malloc_dynamic (&currprefs.z3fastmem_size, &changed_prefs.z3fastmem_size, &z3fastmem_bank, 1, _T("z3"));
1870 		memory_hardreset (1);
1871 	}
1872 	if (z3fastmem2_bank.allocated != currprefs.z3fastmem2_size) {
1873 		mapped_free (&z3fastmem2_bank);
1874 
1875 		z3fastmem2_bank.allocated = currprefs.z3fastmem2_size;
1876 		z3fastmem2_bank.mask = z3fastmem2_bank.allocated - 1;
1877 
1878 		if (z3fastmem2_bank.allocated) {
1879 			mapped_malloc (&z3fastmem2_bank);
1880 			if (z3fastmem2_bank.baseaddr == 0) {
1881 				write_log (_T("Out of memory for 32 bit fast memory #2.\n"));
1882 				z3fastmem2_bank.allocated = 0;
1883 			}
1884 		}
1885 		memory_hardreset (1);
1886 	}
1887 	if (z3chipmem_bank.allocated != currprefs.z3chipmem_size) {
1888 		mapped_free (&z3chipmem_bank);
1889 		mapped_malloc_dynamic (&currprefs.z3chipmem_size, &changed_prefs.z3chipmem_size, &z3chipmem_bank, 16, _T("z3_chip"));
1890 		memory_hardreset (1);
1891 	}
1892 
1893 #ifdef PICASSO96
1894 	if (gfxmem_bank.allocated != currprefs.rtgmem_size) {
1895 		mapped_free (&gfxmem_bank);
1896 		if (currprefs.rtgmem_type < GFXBOARD_HARDWARE)
1897 			mapped_malloc_dynamic (&currprefs.rtgmem_size, &changed_prefs.rtgmem_size, &gfxmem_bank, 1, currprefs.rtgmem_type ? _T("z3_gfx") : _T("z2_gfx"));
1898 		memory_hardreset (1);
1899 	}
1900 #endif
1901 
1902 #ifdef SAVESTATE
1903 	if (savestate_state == STATE_RESTORE) {
1904 		if (fastmem_bank.allocated > 0) {
1905 			restore_ram (fast_filepos, fastmem_bank.baseaddr);
1906 			if (!fastmem_bank.start) {
1907 				// old statefile compatibility support
1908 				fastmem_bank.start = 0x00200000;
1909 			}
1910 			map_banks(&fastmem_bank, fastmem_bank.start >> 16, currprefs.fastmem_size >> 16,
1911 					fastmem_bank.allocated);
1912 		}
1913 		if (fastmem2_bank.allocated > 0) {
1914 			restore_ram (fast2_filepos, fastmem2_bank.baseaddr);
1915 			map_banks(&fastmem2_bank, fastmem2_bank.start >> 16, currprefs.fastmem2_size >> 16,
1916 				fastmem2_bank.allocated);
1917 		}
1918 		if (z3fastmem_bank.allocated > 0) {
1919 			restore_ram (z3_filepos, z3fastmem_bank.baseaddr);
1920 			map_banks(&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16,
1921 				z3fastmem_bank.allocated);
1922 		}
1923 		if (z3fastmem2_bank.allocated > 0) {
1924 			restore_ram (z3_filepos2, z3fastmem2_bank.baseaddr);
1925 			map_banks(&z3fastmem2_bank, z3fastmem2_bank.start >> 16, currprefs.z3fastmem2_size >> 16,
1926 				z3fastmem2_bank.allocated);
1927 		}
1928 		if (z3chipmem_bank.allocated > 0) {
1929 			restore_ram (z3_fileposchip, z3chipmem_bank.baseaddr);
1930 			map_banks(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16,
1931 				z3chipmem_bank.allocated);
1932 		}
1933 #ifdef PICASSO96
1934 		if (gfxmem_bank.allocated > 0 && gfxmem_bank.start > 0) {
1935 			restore_ram (p96_filepos, gfxmem_bank.baseaddr);
1936 			map_banks(&gfxmem_bank, gfxmem_bank.start >> 16, currprefs.rtgmem_size >> 16,
1937 				gfxmem_bank.allocated);
1938 		}
1939 #endif
1940 	}
1941 #endif /* SAVESTATE */
1942 }
1943 
check_boot_rom(int * boot_rom_type)1944 static uaecptr check_boot_rom (int *boot_rom_type)
1945 {
1946 	uaecptr b = RTAREA_DEFAULT;
1947 	addrbank *ab;
1948 
1949 	*boot_rom_type = 0;
1950 	if (currprefs.boot_rom == 1)
1951 		return 0;
1952 	*boot_rom_type = 1;
1953 	if (currprefs.cs_cdtvcd || currprefs.cs_cdtvscsi || currprefs.uae_hide > 1)
1954 		b = RTAREA_BACKUP;
1955 	if (currprefs.cs_mbdmac == 1 || currprefs.cpuboard_type)
1956 		b = RTAREA_BACKUP;
1957 	// CSPPC enables MMU at boot and remaps 0xea0000->0xeffff.
1958 	if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC))
1959 		b = RTAREA_BACKUP_2;
1960 	ab = &get_mem_bank (RTAREA_DEFAULT);
1961 	if (ab) {
1962 		if (valid_address (RTAREA_DEFAULT, 65536))
1963 			b = RTAREA_BACKUP;
1964 	}
1965 	if (nr_directory_units (NULL))
1966 		return b;
1967 	if (nr_directory_units (&currprefs))
1968 		return b;
1969 	if (currprefs.socket_emu)
1970 		return b;
1971 	if (currprefs.uaeserial)
1972 		return b;
1973 	if (currprefs.scsi == 1)
1974 		return b;
1975 	if (currprefs.sana2)
1976 		return b;
1977 	if (currprefs.input_tablet > 0)
1978 		return b;
1979 	if (currprefs.rtgmem_size && currprefs.rtgmem_type < GFXBOARD_HARDWARE)
1980 		return b;
1981 	if (currprefs.win32_automount_removable)
1982 		return b;
1983 	if (currprefs.chipmem_size > 2 * 1024 * 1024)
1984 		return b;
1985 	if (currprefs.z3chipmem_size)
1986 		return b;
1987 	if (currprefs.boot_rom >= 3)
1988 		return b;
1989 	if (currprefs.boot_rom == 2 && b == 0xf00000) {
1990 		*boot_rom_type = -1;
1991 		return b;
1992 	}
1993 	*boot_rom_type = 0;
1994 	return 0;
1995 }
1996 
need_uae_boot_rom(void)1997 uaecptr need_uae_boot_rom (void)
1998 {
1999 	uaecptr v;
2000 
2001 	uae_boot_rom_type = 0;
2002 	v = check_boot_rom (&uae_boot_rom_type);
2003 	if (!rtarea_base) {
2004 		uae_boot_rom_type = 0;
2005 		v = 0;
2006 	}
2007 	return v;
2008 }
2009 
add_cpu_expansions(int zorro)2010 static void add_cpu_expansions(int zorro)
2011 {
2012 	const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
2013 	if (cst->init && cst->initzorro == zorro) {
2014 		int idx;
2015 		struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, 0, &idx);
2016 		struct romconfig *rc = &brc->roms[idx];
2017 		cards[cardno].flags = cst->initflag;
2018 		cards[cardno].name = cst->name;
2019 		cards[cardno].initrc = cst->init;
2020 		cards[cardno].rc = rc;
2021 		cards[cardno].zorro = zorro;
2022 		cards[cardno++].map = NULL;
2023 		if (cst->init2) {
2024 			cards[cardno].flags = cst->initflag;
2025 			cards[cardno].name = cst->name;
2026 			cards[cardno].initrc = cst->init2;
2027 			cards[cardno].zorro = zorro;
2028 			cards[cardno++].map = NULL;
2029 		}
2030 	}
2031 }
2032 
add_fastram_after_expansion(int zorro)2033 static bool add_fastram_after_expansion(int zorro)
2034 {
2035 	for (int i = 0; expansionroms[i].name; i++) {
2036 		const struct expansionromtype *ert = &expansionroms[i];
2037 		if (ert->zorro == zorro) {
2038 			for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
2039 				struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, j);
2040 				if (rc) {
2041 					if (ert->subtypes) {
2042 						const struct expansionsubromtype *srt = &ert->subtypes[rc->subtype];
2043 						return srt->memory_after;
2044 					}
2045 					return ert->memory_after;
2046 				}
2047 			}
2048 		}
2049 	}
2050 	return false;
2051 }
2052 
add_expansions(int zorro)2053 static void add_expansions(int zorro)
2054 {
2055 	for (int i = 0; expansionroms[i].name; i++) {
2056 		const struct expansionromtype *ert = &expansionroms[i];
2057 		if (ert->zorro == zorro) {
2058 			for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
2059 				struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, j);
2060 				if (rc) {
2061 					if (zorro == 1) {
2062 						ert->init(rc);
2063 						if (ert->init2)
2064 							ert->init2(rc);
2065 					} else {
2066 						cards[cardno].flags = 0;
2067 						cards[cardno].name = ert->name;
2068 						cards[cardno].initrc = ert->init;
2069 						cards[cardno].rc = rc;
2070 						cards[cardno].zorro = zorro;
2071 						cards[cardno++].map = NULL;
2072 						if (ert->init2) {
2073 							cards[cardno].flags = 0;
2074 							cards[cardno].name = ert->name;
2075 							cards[cardno].initrc = ert->init2;
2076 							cards[cardno].rc = rc;
2077 							cards[cardno].zorro = zorro;
2078 							cards[cardno++].map = NULL;
2079 						}
2080 					}
2081 				}
2082 			}
2083 		}
2084 	}
2085 }
2086 
expamem_reset(void)2087 void expamem_reset (void)
2088 {
2089 	int do_mount = 1;
2090 
2091 	ecard = 0;
2092 	cardno = 0;
2093 	chipdone = false;
2094 
2095 	if (currprefs.uae_hide)
2096 		uae_id = commodore;
2097 	else
2098 		uae_id = hackers_id;
2099 
2100 	allocate_expamem ();
2101 	expamem_bank.name = _T("Autoconfig [reset]");
2102 
2103 	if (need_uae_boot_rom() == 0)
2104 		do_mount = 0;
2105 	if (uae_boot_rom_type <= 0)
2106 		do_mount = 0;
2107 
2108 	/* check if Kickstart version is below 1.3 */
2109 	if (ks12orolder() && do_mount) {
2110 		/* warn user */
2111 #if KS12_BOOT_HACK
2112 		do_mount = -1;
2113 		if (ks11orolder()) {
2114 			filesys_start = 0xe90000;
2115 			map_banks_z2(&filesys_bank, filesys_start >> 16, 1);
2116 			expamem_init_filesys(0);
2117 			expamem_map_filesys_update();
2118 		}
2119 #else
2120 		write_log(_T("Kickstart version is below 1.3!  Disabling automount devices.\n"));
2121 		do_mount = 0;
2122 #endif
2123 	}
2124 
2125 	if (currprefs.cpuboard_type) {
2126 		// This may require first 128k slot.
2127 		cards[cardno].flags = 1;
2128 		cards[cardno].name = _T("CPUBoard");
2129 		cards[cardno].initrc = cpuboard_autoconfig_init;
2130 		cards[cardno++].map = NULL;
2131 	}
2132 
2133 	// add possible non-autoconfig boards
2134 	add_cpu_expansions(BOARD_NONAUTOCONFIG_BEFORE);
2135 	add_expansions(BOARD_NONAUTOCONFIG_BEFORE);
2136 
2137 	bool fastmem_after = false;
2138 	if (currprefs.fastmem_autoconfig) {
2139 		fastmem_after = add_fastram_after_expansion(BOARD_AUTOCONFIG_Z2);
2140 		if (!fastmem_after && fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
2141 			cards[cardno].flags = 0;
2142 			cards[cardno].name = _T("Z2Fast");
2143 			cards[cardno].initnum = expamem_init_fastcard;
2144 			cards[cardno++].map = expamem_map_fastcard;
2145 		}
2146 		if (fastmem2_bank.baseaddr != NULL && (fastmem2_bank.allocated <= 262144  || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
2147 			cards[cardno].flags = 0;
2148 			cards[cardno].name = _T("Z2Fast2");
2149 			cards[cardno].initnum = expamem_init_fastcard2;
2150 			cards[cardno++].map = expamem_map_fastcard2;
2151 		}
2152 	} else {
2153 		if (fastmem_bank.baseaddr) {
2154 			fastmem_bank.name = _T("Fast memory (non-autoconfig)");
2155 			map_banks(&fastmem_bank, 0x00200000 >> 16, fastmem_bank.allocated >> 16, 0);
2156 		}
2157 		if (fastmem2_bank.baseaddr != NULL) {
2158 			fastmem2_bank.name = _T("Fast memory 2 (non-autoconfig)");
2159 			map_banks(&fastmem2_bank, (0x00200000 + fastmem_bank.allocated) >> 16, fastmem2_bank.allocated >> 16, 0);
2160 		}
2161 	}
2162 
2163 	// immediately after Z2Fast so that they can be emulated as A590/A2091 with fast ram.
2164 	add_cpu_expansions(BOARD_AUTOCONFIG_Z2);
2165 	add_expansions(BOARD_AUTOCONFIG_Z2);
2166 
2167 	add_cpu_expansions(BOARD_NONAUTOCONFIG_AFTER_Z2);
2168 	add_expansions(BOARD_NONAUTOCONFIG_AFTER_Z2);
2169 
2170 	if (fastmem_after && currprefs.fastmem_autoconfig) {
2171 		if (fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
2172 			cards[cardno].flags = 0;
2173 			cards[cardno].name = _T("Z2Fast");
2174 			cards[cardno].initnum = expamem_init_fastcard;
2175 			cards[cardno++].map = expamem_map_fastcard;
2176 		}
2177 	}
2178 
2179 #ifdef CDTV
2180 	if (currprefs.cs_cdtvcd && !currprefs.cs_cdtvcr) {
2181 		cards[cardno].flags = 0;
2182 		cards[cardno].name = _T("CDTV DMAC");
2183 		cards[cardno].initrc = cdtv_init;
2184 		cards[cardno++].map = NULL;
2185 	}
2186 #endif
2187 #ifdef CD32
2188 	if (currprefs.cs_cd32cd && currprefs.fastmem_size == 0 && currprefs.chipmem_size <= 0x200000 && currprefs.cs_cd32fmv) {
2189 		cards[cardno].flags = 0;
2190 		cards[cardno].name = _T("CD32MPEG");
2191 		cards[cardno].initnum = expamem_init_cd32fmv;
2192 		cards[cardno++].map = expamem_map_cd32fmv;
2193 	}
2194 #endif
2195 #ifdef A2065
2196 	if (currprefs.a2065name[0]) {
2197 		cards[cardno].flags = 0;
2198 		cards[cardno].name = _T("A2065");
2199 		cards[cardno].initnum = a2065_init;
2200 		cards[cardno++].map = NULL;
2201 	}
2202 #endif
2203 #ifdef FILESYS
2204 	if (do_mount) {
2205 		cards[cardno].flags = 0;
2206 		cards[cardno].name = _T("UAEFS");
2207 		cards[cardno].initnum = expamem_init_filesys;
2208 		cards[cardno++].map = expamem_map_filesys;
2209 	}
2210 	if (currprefs.uaeboard) {
2211 		cards[cardno].flags = 0;
2212 		cards[cardno].name = _T("UAEBOARD");
2213 		cards[cardno].initnum = expamem_init_uaeboard;
2214 		cards[cardno++].map = expamem_map_uaeboard;
2215 	}
2216 #endif
2217 #ifdef CATWEASEL
2218 	if (currprefs.catweasel && catweasel_init ()) {
2219 		cards[cardno].flags = 0;
2220 		cards[cardno].name = _T("CWMK2");
2221 		cards[cardno].initnum = expamem_init_catweasel;
2222 		cards[cardno++].map = expamem_map_catweasel;
2223 	}
2224 #endif
2225 #ifdef PICASSO96
2226 	if (currprefs.rtgmem_type == GFXBOARD_UAE_Z2 && gfxmem_bank.baseaddr != NULL) {
2227 		cards[cardno].flags = 4;
2228 		cards[cardno].name = _T("Z2RTG");
2229 		cards[cardno].initnum = expamem_init_gfxcard_z2;
2230 		cards[cardno++].map = expamem_map_gfxcard_z2;
2231 	}
2232 #endif
2233 #ifdef GFXBOARD
2234 	if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(currprefs.rtgmem_type) <= 2) {
2235 		cards[cardno].flags = 4;
2236 		if (currprefs.rtgmem_type == GFXBOARD_A2410) {
2237 			cards[cardno].name = _T("Gfxboard A2410");
2238 			cards[cardno++].initnum = tms_init;
2239 		} else {
2240 			cards[cardno].name = _T("Gfxboard VRAM Zorro II");
2241 			cards[cardno++].initnum = gfxboard_init_memory;
2242 			if (gfxboard_num_boards (currprefs.rtgmem_type) == 3) {
2243 				cards[cardno].flags = 0;
2244 				cards[cardno].name = _T("Gfxboard VRAM Zorro II Extra");
2245 				cards[cardno++].initnum = gfxboard_init_memory_p4_z2;
2246 			}
2247 			if (gfxboard_is_registers (currprefs.rtgmem_type)) {
2248 				cards[cardno].flags = 0;
2249 				cards[cardno].name = _T ("Gfxboard Registers");
2250 				cards[cardno++].initnum = gfxboard_init_registers;
2251 			}
2252 		}
2253 	}
2254 #endif
2255 #ifdef WITH_TOCCATA
2256 	if (currprefs.sound_toccata) {
2257 		cards[cardno].flags = 0;
2258 		cards[cardno].name = _T("Toccata");
2259 		cards[cardno++].initnum = sndboard_init;
2260 	}
2261 #endif
2262 	if (currprefs.monitoremu == MONITOREMU_FIRECRACKER24) {
2263 		cards[cardno].flags = 0;
2264 		cards[cardno].name = _T("FireCracker24");
2265 		cards[cardno++].initnum = specialmonitor_autoconfig_init;
2266 	}
2267 
2268 	/* Z3 boards last */
2269 	if (!currprefs.address_space_24) {
2270 
2271 		add_cpu_expansions(BOARD_AUTOCONFIG_Z3);
2272 
2273 		if (z3fastmem_bank.baseaddr != NULL) {
2274 			bool alwaysmapz3 = currprefs.z3_mapping_mode != Z3MAPPING_REAL;
2275 			z3num = 0;
2276 			cards[cardno].flags = 2 | 1;
2277 			cards[cardno].name = _T("Z3Fast");
2278 			cards[cardno].initnum = expamem_init_z3fastmem;
2279 			cards[cardno++].map = expamem_map_z3fastmem;
2280 			if (alwaysmapz3 || expamem_z3hack(&currprefs))
2281 				map_banks_z3(&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16);
2282 			if (z3fastmem2_bank.baseaddr != NULL) {
2283 				cards[cardno].flags = 2 | 1;
2284 				cards[cardno].name = _T("Z3Fast2");
2285 				cards[cardno].initnum = expamem_init_z3fastmem2;
2286 				cards[cardno++].map = expamem_map_z3fastmem2;
2287 				if (alwaysmapz3 || expamem_z3hack(&currprefs))
2288 					map_banks_z3(&z3fastmem2_bank, z3fastmem2_bank.start >> 16, currprefs.z3fastmem2_size >> 16);
2289 			}
2290 		}
2291 		if (z3chipmem_bank.baseaddr != NULL)
2292 			map_banks_z3(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16);
2293 #ifdef PICASSO96
2294 		if (currprefs.rtgmem_type == GFXBOARD_UAE_Z3 && gfxmem_bank.baseaddr != NULL) {
2295 			cards[cardno].flags = 4 | 1;
2296 			cards[cardno].name = _T("Z3RTG");
2297 			cards[cardno].initnum = expamem_init_gfxcard_z3;
2298 			cards[cardno++].map = expamem_map_gfxcard_z3;
2299 		}
2300 #endif
2301 #ifdef GFXBOARD
2302 		if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(currprefs.rtgmem_type) == 3) {
2303 			cards[cardno].flags = 4 | 1;
2304 			cards[cardno].name = _T ("Gfxboard VRAM Zorro III");
2305 			cards[cardno++].initnum = gfxboard_init_memory;
2306 			cards[cardno].flags = 1;
2307 			cards[cardno].name = _T ("Gfxboard Registers");
2308 			cards[cardno++].initnum = gfxboard_init_registers;
2309 		}
2310 #endif
2311 
2312 		add_expansions(BOARD_AUTOCONFIG_Z3);
2313 
2314 	}
2315 
2316 	add_cpu_expansions(BOARD_NONAUTOCONFIG_AFTER_Z3);
2317 	add_expansions(BOARD_NONAUTOCONFIG_AFTER_Z3);
2318 
2319 	expamem_z3_pointer = 0;
2320 	expamem_z3_sum = 0;
2321 	expamem_z2_pointer = 0;
2322 	if (cardno == 0 || savestate_state)
2323 		expamem_init_clear_zero ();
2324 	else
2325 		call_card_init(0);
2326 }
2327 
expansion_init(void)2328 void expansion_init (void)
2329 {
2330 	if (savestate_state != STATE_RESTORE) {
2331 
2332 		fastmem_bank.allocated = 0;
2333 		fastmem_bank.mask = fastmem_bank.start = 0;
2334 		fastmem_bank.baseaddr = NULL;
2335 		fastmem_nojit_bank.allocated = 0;
2336 		fastmem_nojit_bank.mask = fastmem_nojit_bank.start = 0;
2337 		fastmem_nojit_bank.baseaddr = NULL;
2338 
2339 		fastmem2_bank.allocated = 0;
2340 		fastmem2_bank.mask = fastmem2_bank.start = 0;
2341 		fastmem2_bank.baseaddr = NULL;
2342 		fastmem2_nojit_bank.allocated = 0;
2343 		fastmem2_nojit_bank.mask = fastmem2_nojit_bank.start = 0;
2344 		fastmem2_nojit_bank.baseaddr = NULL;
2345 
2346 #ifdef PICASSO96
2347 		gfxmem_bank.allocated = 0;
2348 		gfxmem_bank.mask = gfxmem_bank.start = 0;
2349 		gfxmem_bank.baseaddr = NULL;
2350 #endif
2351 
2352 #ifdef CATWEASEL
2353 		catweasel_mask = catweasel_start = 0;
2354 #endif
2355 
2356 		z3fastmem_bank.allocated = 0;
2357 		z3fastmem_bank.mask = z3fastmem_bank.start = 0;
2358 		z3fastmem_bank.baseaddr = NULL;
2359 
2360 		z3fastmem2_bank.allocated = 0;
2361 		z3fastmem2_bank.mask = z3fastmem2_bank.start = 0;
2362 		z3fastmem2_bank.baseaddr = NULL;
2363 
2364 		z3chipmem_bank.allocated = 0;
2365 		z3chipmem_bank.mask = z3chipmem_bank.start = 0;
2366 		z3chipmem_bank.baseaddr = NULL;
2367 	}
2368 
2369 #ifdef FILESYS
2370 	filesys_start = 0;
2371 #endif
2372 
2373 	allocate_expamem ();
2374 
2375 #ifdef FILESYS
2376 	filesys_bank.allocated = 0x10000;
2377 	if (!mapped_malloc (&filesys_bank)) {
2378 		write_log (_T("virtual memory exhausted (filesysory)!\n"));
2379 		exit (0);
2380 	}
2381 #endif
2382 	if (currprefs.uaeboard) {
2383 		uaeboard_bank.allocated = 0x10000;
2384 		mapped_malloc(&uaeboard_bank);
2385 	}
2386 }
2387 
expansion_cleanup(void)2388 void expansion_cleanup (void)
2389 {
2390 	mapped_free (&fastmem_bank);
2391 	fastmem_nojit_bank.baseaddr = NULL;
2392 	mapped_free (&fastmem2_bank);
2393 	fastmem2_nojit_bank.baseaddr = NULL;
2394 	mapped_free (&z3fastmem_bank);
2395 	mapped_free (&z3fastmem2_bank);
2396 	mapped_free (&z3chipmem_bank);
2397 
2398 #ifdef PICASSO96
2399 	if (currprefs.rtgmem_type < GFXBOARD_HARDWARE)
2400 		mapped_free (&gfxmem_bank);
2401 #endif
2402 
2403 #ifdef FILESYS
2404 	mapped_free (&filesys_bank);
2405 #endif
2406 	if (currprefs.uaeboard) {
2407 		mapped_free(&uaeboard_bank);
2408 	}
2409 
2410 #ifdef CATWEASEL
2411 	catweasel_free ();
2412 #endif
2413 }
2414 
clear_bank(addrbank * ab)2415 static void clear_bank (addrbank *ab)
2416 {
2417 	if (!ab->baseaddr || !ab->allocated)
2418 		return;
2419 	memset (ab->baseaddr, 0, ab->allocated > 0x800000 ? 0x800000 : ab->allocated);
2420 }
2421 
expansion_clear(void)2422 void expansion_clear (void)
2423 {
2424 	clear_bank (&fastmem_bank);
2425 	clear_bank (&fastmem2_bank);
2426 	clear_bank (&z3fastmem_bank);
2427 	clear_bank (&z3fastmem2_bank);
2428 	clear_bank (&z3chipmem_bank);
2429 	clear_bank (&gfxmem_bank);
2430 }
2431 
2432 #ifdef SAVESTATE
2433 
2434 /* State save/restore code.  */
2435 
save_fram(int * len,int num)2436 uae_u8 *save_fram (int *len, int num)
2437 {
2438 	if (num) {
2439 		*len = fastmem2_bank.allocated;
2440 		return fastmem2_bank.baseaddr;
2441 	} else {
2442 		*len = fastmem_bank.allocated;
2443 		return fastmem_bank.baseaddr;
2444 	}
2445 }
2446 
save_zram(int * len,int num)2447 uae_u8 *save_zram (int *len, int num)
2448 {
2449 	if (num < 0) {
2450 		*len = z3chipmem_bank.allocated;
2451 		return z3chipmem_bank.baseaddr;
2452 	}
2453 	*len = num ? z3fastmem2_bank.allocated : z3fastmem_bank.allocated;
2454 	return num ? z3fastmem2_bank.baseaddr : z3fastmem_bank.baseaddr;
2455 }
2456 
save_pram(int * len)2457 uae_u8 *save_pram (int *len)
2458 {
2459 	*len = gfxmem_bank.allocated;
2460 	return gfxmem_bank.baseaddr;
2461 }
2462 
restore_fram(int len,size_t filepos,int num)2463 void restore_fram (int len, size_t filepos, int num)
2464 {
2465 	if (num) {
2466 		fast2_filepos = filepos;
2467 		changed_prefs.fastmem2_size = len;
2468 	} else {
2469 		fast_filepos = filepos;
2470 		changed_prefs.fastmem_size = len;
2471 	}
2472 }
2473 
restore_fram2(int len,size_t filepos)2474 static void restore_fram2 (int len, size_t filepos)
2475 {
2476 	fast2_filepos = filepos;
2477 	changed_prefs.fastmem2_size = len;
2478 }
2479 
restore_zram(int len,size_t filepos,int num)2480 void restore_zram (int len, size_t filepos, int num)
2481 {
2482 	if (num == -1) {
2483 		z3_fileposchip = filepos;
2484 		changed_prefs.z3chipmem_size = len;
2485 	} else if (num == 1) {
2486 		z3_filepos2 = filepos;
2487 		changed_prefs.z3fastmem2_size = len;
2488 	} else {
2489 		z3_filepos = filepos;
2490 		changed_prefs.z3fastmem_size = len;
2491 	}
2492 }
2493 
restore_pram(int len,size_t filepos)2494 void restore_pram (int len, size_t filepos)
2495 {
2496 	p96_filepos = filepos;
2497 	changed_prefs.rtgmem_size = len;
2498 }
2499 
save_expansion(int * len,uae_u8 * dstptr)2500 uae_u8 *save_expansion (int *len, uae_u8 *dstptr)
2501 {
2502 	uae_u8 *dst, *dstbak;
2503 	if (dstptr)
2504 		dst = dstbak = dstptr;
2505 	else
2506 		dstbak = dst = xmalloc (uae_u8, 6 * 4);
2507 	save_u32 (fastmem_bank.start);
2508 	save_u32 (z3fastmem_bank.start);
2509 	save_u32 (gfxmem_bank.start);
2510 	save_u32 (rtarea_base);
2511 	save_u32 (fastmem_bank.start);
2512 	*len = 4 + 4 + 4 + 4 + 4;
2513 	return dstbak;
2514 }
2515 
restore_expansion(uae_u8 * src)2516 uae_u8 *restore_expansion (uae_u8 *src)
2517 {
2518 	fastmem_bank.start = restore_u32 ();
2519 	z3fastmem_bank.start = restore_u32 ();
2520 	gfxmem_bank.start = restore_u32 ();
2521 	rtarea_base = restore_u32 ();
2522 	fastmem2_bank.start = restore_u32 ();
2523 	if (rtarea_base != 0 && rtarea_base != RTAREA_DEFAULT && rtarea_base != RTAREA_BACKUP && rtarea_base != RTAREA_BACKUP_2)
2524 		rtarea_base = 0;
2525 	return src;
2526 }
2527 
2528 #endif /* SAVESTATE */
2529 
2530 #if 0
2531 static const struct expansionsubromtype a2090_sub[] = {
2532 	{
2533 		_T("A2090a"), _T("a2090a"),
2534 		0, 0, 0,
2535 		{ 0 },
2536 	},
2537 	{
2538 		_T("A2090a + 1M RAM"), _T("a2090a_2"),
2539 		0, 0, 0,
2540 		{ 0 },
2541 	},
2542 	{
2543 		NULL
2544 	}
2545 };
2546 #endif
2547 static const struct expansionsubromtype a2091_sub[] = {
2548 	{
2549 		_T("DMAC-01"), _T("dmac01"), 0,
2550 		commodore, commodore_a2091_ram, 0, true,
2551 		{ 0 }
2552 	},
2553 	{
2554 		_T("DMAC-02"), _T("dmac02"), 0,
2555 		commodore, commodore_a2091_ram, 0, true,
2556 		{ 0 }
2557 	},
2558 	{
2559 		NULL
2560 	}
2561 };
2562 static const struct expansionsubromtype gvp1_sub[] = {
2563 	{
2564 		_T("Impact A2000-1/X"), _T("a2000-1"), 0,
2565 		1761, 8, 0, false,
2566 		{ 0 }
2567 	},
2568 	{
2569 		_T("Impact A2000-HC"), _T("a2000-hc"), 0,
2570 		1761, 8, 0, false,
2571 		{ 0 }
2572 	},
2573 	{
2574 		_T("Impact A2000-HC+2"), _T("a2000-hc+"), 0,
2575 		1761, 8, 0, false,
2576 		{ 0 }
2577 	},
2578 	{
2579 		NULL
2580 	}
2581 };
2582 static const struct expansionsubromtype masoboshi_sub[] = {
2583 	{
2584 		_T("MC-302"), _T("mc-302"), 0,
2585 		2157, 3, 0, false,
2586 		{ 0 }
2587 	},
2588 	{
2589 		_T("MC-702"), _T("mc-702"), 0,
2590 		2157, 3, 0, false,
2591 		{ 0 }
2592 	},
2593 	{
2594 		NULL
2595 	}
2596 };
2597 static const struct expansionsubromtype rochard_sub[] = {
2598 	{
2599 		_T("IDE"), _T("ide"), 0,
2600 		2144, 2, 0, false,
2601 		{ 0 }
2602 	},
2603 	{
2604 		_T("IDE+SCSI"), _T("scsi"), 0,
2605 		2144, 2, 0, false,
2606 		{ 0 }
2607 	},
2608 	{
2609 		NULL
2610 	}
2611 };
2612 static const struct expansionsubromtype supra_sub[] = {
2613 	{
2614 		_T("A500 ByteSync/XP"), _T("bytesync"), ROMTYPE_NONE | ROMTYPE_SUPRA,
2615 		1056, 9, 0, false,
2616 		{ 0xd1, 13, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
2617 	},
2618 	{
2619 		_T("A2000 Word Sync"), _T("wordsync"), ROMTYPE_NONE | ROMTYPE_SUPRA,
2620 		1056, 9, 0, false,
2621 		{ 0xd1, 12, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
2622 	},
2623 	{
2624 		_T("A500 Autoboot"), _T("500"), ROMTYPE_NONE | ROMTYPE_SUPRA,
2625 		1056, 5, 0, false,
2626 		{ 0xd1, 8, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
2627 	},
2628 	{
2629 		_T("Non Autoboot (4x4)"), _T("4x4"), ROMTYPE_NOT | ROMTYPE_SUPRA,
2630 		1056, 2, 0, false,
2631 		{ 0xc1, 1, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2632 	},
2633 	{
2634 		_T("A2000 DMA"), _T("dma"), ROMTYPE_NONE | ROMTYPE_SUPRADMA,
2635 		1056, 2, 0, false,
2636 		{ 0xd1, 3, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00 },
2637 	},
2638 	{
2639 		NULL
2640 	}
2641 };
2642 
2643 static const struct expansionsubromtype mediator_sub[] = {
2644 	{
2645 		_T("1200"), _T("1200"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
2646 	},
2647 	{
2648 		_T("1200SX"), _T("1200sx"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
2649 	},
2650 	{
2651 		_T("1200TX"), _T("1200tx"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
2652 	},
2653 	{
2654 		_T("4000MK2"), _T("4000mkii"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
2655 	},
2656 	{
2657 		NULL
2658 	}
2659 };
2660 static const struct expansionboardsettings mediator_settings[] = {
2661 	{
2662 		_T("Full PCI DMA"),
2663 		_T("fulldma")
2664 	},
2665 	{
2666 		_T("Win Size"),
2667 		_T("winsize")
2668 	},
2669 	{
2670 		_T("Swap Config"),
2671 		_T("swapconfig")
2672 	},
2673 	{
2674 		NULL
2675 	}
2676 };
2677 static const struct expansionboardsettings bridge_settings[] = {
2678 	{
2679 		_T("Full PCI DMA"),
2680 		_T("fulldma")
2681 	},
2682 	{
2683 		NULL
2684 	}
2685 };
2686 
2687 static const struct expansionboardsettings x86at286_bridge_settings[] = {
2688 	{
2689 		// 14
2690 		_T("Default video\0") _T("Monochrome\0") _T("Color\0"),
2691 		_T("video\0") _T("mono\0") _T("color\0"),
2692 		true, false, 14
2693 	},
2694 	{
2695 		// 15
2696 		_T("Keyboard lock"),
2697 		_T("keylock"),
2698 		false
2699 	},
2700 	{	// 16 - 18
2701 		_T("Memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0"),
2702 		_T("memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0"),
2703 		true, false, 0
2704 	},
2705 	{	// 19 - 20
2706 		_T("CPU core\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
2707 		_T("cpu\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
2708 		true, false, 0
2709 	},
2710 	{	// 22
2711 		_T("FPU"),
2712 		_T("fpu"),
2713 		false, false, 1
2714 	},
2715 	{	// 23 - 25
2716 		_T("CPU Arch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2717 		_T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2718 		true, false, 0
2719 	},
2720 	{
2721 		NULL
2722 	}
2723 };
2724 
2725 static const struct expansionboardsettings x86at386_bridge_settings[] = {
2726 	{
2727 		// 15
2728 		_T("Keyboard lock"),
2729 		_T("keylock"),
2730 		false, false, 15
2731 	},
2732 	{	// 16 - 18
2733 		_T("Memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0") _T("64M\0"),
2734 		_T("memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0") _T("64M\0"),
2735 		true, false, 0
2736 	},
2737 	{	// 19 - 20
2738 		_T("CPU core\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
2739 		_T("cpu\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
2740 		true, false, 0
2741 	},
2742 	{	// 22
2743 		_T("FPU"),
2744 		_T("fpu"),
2745 		false, false, 1
2746 	},
2747 	{	// 23 - 25
2748 		_T("CPU Arch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2749 		_T("cpuarch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2750 		true, false, 0
2751 	},
2752 	{
2753 		NULL
2754 	}
2755 };
2756 
2757 static const struct expansionboardsettings x86_bridge_settings[] = {
2758 	{
2759 		// 2-3
2760 		_T("Memory (SW1:3-4)\0") _T("128K\0") _T("256K\0") _T("512K\0") _T("640K\0"),
2761 		_T("memory\0") _T("128k\0") _T("256k\0") _T("512k\0") _T("640k\0"),
2762 		true, false, 2
2763 	},
2764 	{
2765 		// 4-5
2766 		_T("Default video (J1)\0") _T("Monochrome\0") _T("Color 40x25\0") _T("Color 80x25\0") _T("None\0"),
2767 		_T("video\0") _T("mono\0") _T("color40\0") _T("color80\0") _T("none\0"),
2768 		true, false, 0
2769 	},
2770 	{	// 19 - 21
2771 		_T("CPU core\0") _T("Fake86\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
2772 		_T("cpu\0") _T("fake86\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
2773 		true, false, 19 - 6
2774 	},
2775 	{	// 22
2776 		_T("FPU (DOSBox CPU only)"),
2777 		_T("fpu")
2778 	},
2779 	{	// 23 - 25
2780 		_T("CPU Arch (DOSBox CPU only)\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2781 		_T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2782 		true, false, 0
2783 	},
2784 	{
2785 		NULL
2786 	}
2787 };
2788 
2789 static const struct expansionboardsettings x86_bridge_sidecar_settings[] = {
2790 	{
2791 		// 0
2792 		_T("System Diagnostics (SW1:1)"),
2793 		_T("diagnostics"),
2794 	},
2795 	{
2796 		// 1
2797 		_T("8037 installed (SW1:2)"),
2798 		_T("fpu"),
2799 	},
2800 	{
2801 		// 2-3
2802 		_T("Memory (SW1:3-4)\0") _T("128K\0") _T("256K\0") _T("512K\0") _T("640K\0"),
2803 		_T("memory\0") _T("128k\0") _T("256k\0") _T("512k\0") _T("640k\0"),
2804 		true
2805 	},
2806 	{
2807 		// 4-5
2808 		_T("Default video (SW1:5-6)\0") _T("Monochrome\0") _T("Color 40x25\0") _T("Color 80x25\0") _T("None\0"),
2809 		_T("video\0") _T("mono\0") _T("color40\0") _T("color80\0") _T("none\0"),
2810 		true
2811 	},
2812 	{
2813 		// 6-7
2814 		_T("Floppy drives (SW1:7-8)\0") _T("1\0") _T("2\0") _T("3\0") _T("4\0"),
2815 		_T("floppy\0") _T("floppy1\0") _T("floppy2\0") _T("floppy3\0") _T("floppy4\0"),
2816 		true
2817 	},
2818 	{
2819 		// 8
2820 		_T("Disable mono video emulation (SW2:1)"),
2821 		_T("mono_card")
2822 	},
2823 	{
2824 		// 9
2825 		_T("Disable color video emulation (SW2:2)"),
2826 		_T("color_card")
2827 	},
2828 	{
2829 		// 10-11
2830 		_T("Address sector (SW2:3-4)\0") _T("A0000-AFFFF (1)\0") _T("A0000-AFFFF (2)\0") _T("D0000-DFFFF\0") _T("E0000-EFFFF\0"),
2831 		_T("memory\0") _T("sector_a0000_1\0") _T("sector_a0000_2\0") _T("sector_d0000\0") _T("sector_e0000\0"),
2832 		true
2833 	},
2834 	{
2835 		// 12
2836 		_T("Disable parallel port emulation (J11)"),
2837 		_T("parport_card")
2838 	},
2839 	{	// 19 - 21
2840 		_T("CPU core\0") _T("Fake86\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
2841 		_T("cpu\0") _T("fake86\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
2842 		true, false, 19 - 13
2843 	},
2844 	{	// 22
2845 		_T("FPU (DOSBox CPU only)"),
2846 		_T("fpu")
2847 	},
2848 	{	// 23 - 25
2849 		_T("CPU Arch (DOSBox CPU only)\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2850 		_T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
2851 		true, false, 0
2852 	},
2853 	{
2854 		NULL
2855 	}
2856 };
2857 
2858 static const struct expansionboardsettings x86_athdxt_settings[] = {
2859 	{
2860 		_T("ROM Address\0") _T("0xCC000\0") _T("0xDC000\0") _T("0xEC000\0"),
2861 		_T("baseaddress\0") _T("0xcc000\0") _T("0xdc000\0") _T("0xec000\0"),
2862 		true
2863 	},
2864 	{
2865 		NULL
2866 	}
2867 };
2868 
fastlane_memory_callback(struct romconfig * rc,uae_u8 * ac,int size)2869 static void fastlane_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
2870 {
2871 	struct zfile *z = read_device_from_romconfig(rc, 0);
2872 	if (z) {
2873 		// load autoconfig data from rom file
2874 		uae_u8 act[16] = { 0 };
2875 		zfile_fseek(z, 0x80, SEEK_SET);
2876 		zfile_fread(act, 1, 16, z);
2877 		zfile_fclose(z);
2878 		for(int i = 1; i < 16; i++) {
2879 			ac[i] = ~act[i];
2880 			act[i] = ~act[i];
2881 		}
2882 		// don't overwrite uae configured memory size
2883 		ac[0] = (ac[0] & 7) | (act[0] & 0xf8);
2884 		ac[2] = (ac[2] & 0x0f) | (act[2] & 0xf0);
2885 	}
2886 }
hda506_memory_callback(struct romconfig * rc,uae_u8 * ac,int size)2887 static void hda506_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
2888 {
2889 	if (currprefs.cs_a1000ram)
2890 		ac[1] = 1;
2891 	else
2892 		ac[1] = 2;
2893 }
nexus_memory_callback(struct romconfig * rc,uae_u8 * ac,int size)2894 static void nexus_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
2895 {
2896 	if (rc->device_settings & 1)
2897 		ac[0] &= ~(1 << 5);
2898 	if (size <= 2 * 1024 * 1024)
2899 		ac[1] = 2;
2900 	else if (size <= 4 * 1024 * 1024)
2901 		ac[1] = 4;
2902 	else
2903 		ac[1] = 8;
2904 }
2905 static const struct expansionboardsettings golemfast_settings[] = {
2906 	{
2907 		_T("IDE"),
2908 		_T("ide")
2909 	},
2910 	{
2911 		NULL
2912 	}
2913 };
2914 static const struct expansionboardsettings nexus_settings[] = {
2915 	{
2916 		_T("MEM TEST"),
2917 		_T("memtest")
2918 	},
2919 	{
2920 		NULL
2921 	}
2922 };
2923 static const struct expansionboardsettings adscsi2000_settings[] = {
2924 	{
2925 		_T("Cache (B)"),
2926 		_T("B")
2927 	},
2928 	{
2929 		NULL
2930 	}
2931 };
2932 static const struct expansionboardsettings warpengine_settings[] = {
2933 	{
2934 		_T("Jumper H"),
2935 		_T("jumper_h")
2936 	},
2937 	{
2938 		_T("Jumper J"),
2939 		_T("jumper_j")
2940 	},
2941 	{
2942 		_T("Jumper K"),
2943 		_T("jumper_k")
2944 	},
2945 	{
2946 		NULL
2947 	}
2948 };
2949 static const struct expansionboardsettings a4091_settings[] = {
2950 	{
2951 		_T("Fast Bus"),
2952 		_T("fastbus"),
2953 	},
2954 	{
2955 		_T("Delayed autoboot"),
2956 		_T("delayedautoboot")
2957 	},
2958 	{
2959 		_T("Syncronous mode"),
2960 		_T("syncmode")
2961 	},
2962 	{
2963 		_T("Termination"),
2964 		_T("term")
2965 	},
2966 	{
2967 		_T("LUN"),
2968 		_T("lun")
2969 	},
2970 	{
2971 		NULL
2972 	}
2973 };
2974 
2975 
2976 const struct expansionromtype expansionroms[] = {
2977 	{
2978 		_T("cpuboard"), _T("Accelerator"), _T("Accelerator"),
2979 		NULL, NULL, add_cpuboard_unit, ROMTYPE_CPUBOARD, 0, 0, 0, true,
2980 		NULL, 0,
2981 		false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE
2982 	},
2983 	{
2984 		_T("grex"), _T("G-REX"), _T("DCE"),
2985 		grex_init, NULL, NULL, ROMTYPE_GREX | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
2986 		NULL, 0,
2987 		false, EXPANSIONTYPE_PCI_BRIDGE
2988 	},
2989 	{
2990 		_T("mediator"), _T("Mediator"), _T("Elbox"),
2991 		mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false,
2992 		mediator_sub, 0,
2993 		false, EXPANSIONTYPE_PCI_BRIDGE,
2994 		0, 0, 0, false, NULL,
2995 		false,
2996 		mediator_settings
2997 	},
2998 	{
2999 		_T("prometheus"), _T("Prometheus"), _T("Matay"),
3000 		prometheus_init, NULL, NULL, ROMTYPE_PROMETHEUS | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false,
3001 		NULL, 0,
3002 		false, EXPANSIONTYPE_PCI_BRIDGE,
3003 		0, 0, 0, false, NULL,
3004 		false,
3005 		bridge_settings
3006 	},
3007 	{
3008 		_T("apollo"), _T("Apollo 500/2000"), _T("3-State"),
3009 		apollo_init_hd, NULL, apollo_add_scsi_unit, ROMTYPE_APOLLOHD, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3010 		NULL, 0,
3011 		false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE,
3012 		8738, 0, 0
3013 	},
3014 	{
3015 		_T("add500"), _T("ADD-500"), _T("Archos"),
3016 		add500_init, NULL, add500_add_scsi_unit, ROMTYPE_ADD500, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3017 		NULL, 0,
3018 		false, EXPANSIONTYPE_SCSI,
3019 		8498, 27, 0, true, NULL
3020 	},
3021 	{
3022 		_T("blizzardscsikitiv"), _T("SCSI Kit IV"), _T("Blizzard"),
3023 		NULL, NULL, cpuboard_ncr9x_add_scsi_unit, ROMTYPE_BLIZKIT4, 0, 0, 0, true,
3024 		NULL, 0,
3025 		false, EXPANSIONTYPE_SCSI
3026 	},
3027 	{
3028 		_T("oktagon2008"), _T("Oktagon 2008"), _T("BSC/Alfa Data"),
3029 		ncr_oktagon_autoconfig_init, NULL, oktagon_add_scsi_unit, ROMTYPE_OKTAGON, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3030 		NULL, 0,
3031 		true, EXPANSIONTYPE_SCSI
3032 	},
3033 	{
3034 		_T("alfapower"), _T("AlfaPower/AT-Bus 2008"), _T("BSC/Alfa Data"),
3035 		alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFA, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3036 		NULL, 0,
3037 		false, EXPANSIONTYPE_IDE,
3038 		2092, 8, 0
3039 	},
3040 	{
3041 		_T("alfapowerplus"), _T("AlfaPower Plus"), _T("BSC/Alfa Data"),
3042 		alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFAPLUS, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3043 		NULL, 0,
3044 		false, EXPANSIONTYPE_IDE,
3045 		2092, 8, 0
3046 	},
3047 	{
3048 		_T("cltda1000scsi"), _T("A1000/A2000 SCSI"), _T("C-Ltd"),
3049 		cltda1000scsi_init, NULL, cltda1000scsi_add_scsi_unit, ROMTYPE_CLTDSCSI | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3050 		NULL, 0,
3051 		false, EXPANSIONTYPE_SCSI,
3052 		0, 0, 0, false, NULL,
3053 		false, NULL,
3054 		{ 0xc1, 0x0c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3055 	},
3056 	{
3057 		_T("a2090a"), _T("A2090a"), _T("Commodore"),
3058 		a2090_init, NULL, a2090_add_scsi_unit, ROMTYPE_A2090 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3059 		NULL, 0,
3060 		true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_CUSTOM_SECONDARY
3061 	},
3062 	{
3063 		_T("a2091"), _T("A590/A2091"), _T("Commodore"),
3064 		a2091_init, NULL, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3065 		a2091_sub, 1,
3066 		true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_CUSTOM_SECONDARY,
3067 		0, 0, 0, true, NULL
3068 	},
3069 	{
3070 		_T("a4091"), _T("A4091"), _T("Commodore"),
3071 		ncr710_a4091_autoconfig_init, NULL, a4091_add_scsi_unit, ROMTYPE_A4091, 0, 0, BOARD_AUTOCONFIG_Z3, false,
3072 		NULL, 0,
3073 		false, EXPANSIONTYPE_SCSI,
3074 		0, 0, 0, false, NULL,
3075 		true, a4091_settings
3076 	},
3077 	{
3078 		_T("dataflyerscsiplus"), _T("DataFlyer SCSI+"), _T("Expansion Systems"),
3079 		dataflyer_init, NULL, dataflyer_add_scsi_unit, ROMTYPE_DATAFLYER | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3080 		NULL, 0,
3081 		false, EXPANSIONTYPE_SCSI
3082 	},
3083 	{
3084 		_T("gvp1"), _T("GVP Series I"), _T("Great Valley Products"),
3085 		gvp_init_s1, NULL, gvp_s1_add_scsi_unit, ROMTYPE_GVPS1 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, BOARD_AUTOCONFIG_Z2, false,
3086 		gvp1_sub, 1,
3087 		true, EXPANSIONTYPE_SCSI
3088 	},
3089 	{
3090 		_T("gvp"), _T("GVP Series II"), _T("Great Valley Products"),
3091 		gvp_init_s2, NULL, gvp_s2_add_scsi_unit, ROMTYPE_GVPS2 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, BOARD_AUTOCONFIG_Z2, false,
3092 		NULL, 0,
3093 		true, EXPANSIONTYPE_SCSI,
3094 		2017, 10, 0
3095 	},
3096 	{
3097 		_T("vector"), _T("Vector Falcon 8000"), _T("HK-Computer"),
3098 		vector_init, NULL, vector_add_scsi_unit, ROMTYPE_VECTOR, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3099 		NULL, 0,
3100 		false, EXPANSIONTYPE_SCSI
3101 	},
3102 	{
3103 		_T("adide"), _T("AdIDE"), _T("ICD"),
3104 		adide_init, NULL, adide_add_ide_unit, ROMTYPE_ADIDE | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3105 		NULL, 0,
3106 		true, EXPANSIONTYPE_IDE
3107 	},
3108 	{
3109 		_T("adscsi2000"), _T("AdSCSI Advantage 2000"), _T("ICD"),
3110 		adscsi_init, NULL, adscsi_add_scsi_unit, ROMTYPE_ADSCSI, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3111 		NULL, 0,
3112 		false, EXPANSIONTYPE_SCSI,
3113 		0, 0, 0, false, NULL,
3114 		true,
3115 		adscsi2000_settings
3116 	},
3117 	{
3118 		_T("kommos"), _T("A500/A2000 SCSI"), _T("J?rgen Kommos"),
3119 		kommos_init, NULL, kommos_add_scsi_unit, ROMTYPE_KOMMOS, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3120 		NULL, 0,
3121 		false, EXPANSIONTYPE_SCSI
3122 	},
3123 	{
3124 		_T("golem"), _T("Golem SCSI II"), _T("Kupke"),
3125 		golem_init, NULL, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3126 		NULL, 0,
3127 		true, EXPANSIONTYPE_SCSI,
3128 		2079, 3, 0
3129 	},
3130 	{
3131 		_T("golemfast"), _T("Golem Fast SCSI/IDE"), _T("Kupke"),
3132 		golemfast_init, NULL, golemfast_add_idescsi_unit, ROMTYPE_GOLEMFAST, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3133 		NULL, 0,
3134 		true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE,
3135 		0, 0, 0, false, NULL,
3136 		true,
3137 		golemfast_settings
3138 	},
3139 	{
3140 		_T("multievolution"), _T("Multi Evolution 500/2000"), _T("MacroSystem"),
3141 		ncr_multievolution_init, NULL, multievolution_add_scsi_unit, ROMTYPE_MEVOLUTION, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3142 		NULL, 0,
3143 		false, EXPANSIONTYPE_SCSI,
3144 		18260, 8, 0, true
3145 	},
3146 	{
3147 		_T("paradox"), _T("Paradox SCSI"), _T("Mainhattan Data"),
3148 		paradox_init, NULL, paradox_add_scsi_unit, ROMTYPE_PARADOX | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, false,
3149 		NULL, 0,
3150 		true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_PARALLEL_ADAPTER
3151 	},
3152 	{
3153 		_T("mtecat"), _T("AT 500"), _T("M-Tec"),
3154 		mtec_init, NULL, mtec_add_ide_unit, ROMTYPE_MTEC, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3155 		NULL, 0,
3156 		true, EXPANSIONTYPE_IDE
3157 	},
3158 	{
3159 		_T("masoboshi"), _T("MasterCard"), _T("Masoboshi"),
3160 		masoboshi_init, NULL, masoboshi_add_idescsi_unit, ROMTYPE_MASOBOSHI | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3161 		masoboshi_sub, 0,
3162 		true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE
3163 	},
3164 	{
3165 		_T("stardrive"), _T("StarDrive"), _T("Microbotics"),
3166 		stardrive_init, NULL, stardrive_add_scsi_unit, ROMTYPE_STARDRIVE | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3167 		NULL, 0,
3168 		false, EXPANSIONTYPE_SCSI,
3169 		1010, 0, 0, false, NULL,
3170 		false, NULL,
3171 		{ 0xc1, 2, 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3172 
3173 	},
3174 	{
3175 		_T("fastlane"), _T("Fastlane"), _T("Phase 5"),
3176 		ncr_fastlane_autoconfig_init, NULL, fastlane_add_scsi_unit, ROMTYPE_FASTLANE, 0, 0, BOARD_AUTOCONFIG_Z3, false,
3177 		NULL, 0,
3178 		false, EXPANSIONTYPE_SCSI,
3179 		8512, 10, 0, false, fastlane_memory_callback
3180 	},
3181 	{
3182 		_T("phoenixboard"), _T("Phoenix Board SCSI"), _T("Phoenix Microtechnologies"),
3183 		phoenixboard_init, NULL, phoenixboard_add_scsi_unit, ROMTYPE_PHOENIXB, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3184 		NULL, 0,
3185 		true, EXPANSIONTYPE_SCSI,
3186 	},
3187 	{
3188 		_T("ptnexus"), _T("Nexus"), _T("Preferred Technologies"),
3189 		ptnexus_init, NULL, ptnexus_add_scsi_unit, ROMTYPE_PTNEXUS | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3190 		NULL, 0,
3191 		false, EXPANSIONTYPE_SCSI,
3192 		2102, 4, 0, false, nexus_memory_callback,
3193 		false, nexus_settings,
3194 		{ 0xd1, 0x01, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
3195 	},
3196 	{
3197 		_T("protar"), _T("A500 HD"), _T("Protar"),
3198 		protar_init, NULL, protar_add_ide_unit, ROMTYPE_PROTAR, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3199 		NULL, 0,
3200 		true, EXPANSIONTYPE_SCSI,
3201 		4149, 51, 0
3202 	},
3203 	{
3204 		_T("rochard"), _T("RocHard RH800C"), _T("Roctec"),
3205 		rochard_init, NULL, rochard_add_idescsi_unit, ROMTYPE_ROCHARD | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3206 		rochard_sub, 0,
3207 		true, EXPANSIONTYPE_IDE | EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE_PORT_DOUBLED,
3208 		2144, 2, 0
3209 	},
3210 	{
3211 		_T("supradrive"), _T("SupraDrive"), _T("Supra Corporation"),
3212 		supra_init, NULL, supra_add_scsi_unit, ROMTYPE_SUPRA | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
3213 		supra_sub, 0,
3214 		true, EXPANSIONTYPE_SCSI
3215 	},
3216 #if 0 /* driver is MIA, 3rd party ScottDevice driver is not enough for full implementation. */
3217 	{
3218 		_T("microforge"), _T("Hard Disk"), _T("Micro Forge"),
3219 		microforge_init, NULL, microforge_add_scsi_unit, ROMTYPE_MICROFORGE | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3220 		NULL, 0,
3221 		false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI
3222 	},
3223 #endif
3224 
3225 	{
3226 		_T("omtiadapter"), _T("OMTI-Adapter"), _T("C't"),
3227 		omtiadapter_init, NULL, omtiadapter_scsi_unit, ROMTYPE_OMTIADAPTER | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3228 		NULL, 0,
3229 		false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
3230 	},
3231 	{
3232 		_T("alf1"), _T("A.L.F."), _T("Elaborate Bytes"),
3233 		alf1_init, NULL, alf1_add_scsi_unit, ROMTYPE_ALF1 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3234 		NULL, 0,
3235 		false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
3236 	},
3237 	{
3238 		_T("promigos"), _T("Promigos"), _T("Flesch und H?rnemann"),
3239 		promigos_init, NULL, promigos_add_scsi_unit, ROMTYPE_PROMIGOS | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3240 		NULL, 0,
3241 		false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
3242 	},
3243 	{
3244 		_T("tecmar"), _T("T-Card/T-Disk"), _T("Tecmar"),
3245 		tecmar_init, NULL, tecmar_add_scsi_unit, ROMTYPE_TECMAR | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3246 		NULL, 0,
3247 		false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI
3248 	},
3249 	{
3250 		_T("system2000"), _T("System 2000"), _T("Vortex"),
3251 		system2000_init, NULL, system2000_add_scsi_unit, ROMTYPE_SYSTEM2000 | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3252 		NULL, 0,
3253 		false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
3254 	},
3255 	{
3256 		_T("xebec"), _T("9720H"), _T("Xebec"),
3257 		xebec_init, NULL, xebec_add_scsi_unit, ROMTYPE_XEBEC | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
3258 		NULL, 0,
3259 		false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI
3260 	},
3261 #if 0
3262 	{
3263 		_T("kronos"), _T("Kronos"), _T("C-Ltd"),
3264 		kronos_init, kronos_add_scsi_unit, ROMTYPE_KRONOS, 0, 0, 2, false,
3265 		NULL, 0,
3266 		false, EXPANSIONTYPE_SCSI,
3267 		0, 0, 0,
3268 		{ 0xd1, 4, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
3269 	},
3270 #endif
3271 	{
3272 		_T("hda506"), _T("HDA-506"), _T("Spirit Technology"),
3273 		hda506_init, NULL, hda506_add_scsi_unit, ROMTYPE_HDA506 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3274 		NULL, 0,
3275 		false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI,
3276 		0, 0, 0, false, NULL,
3277 		false, NULL,
3278 		{ 0xc1, 0x04, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
3279 	},
3280 	{
3281 		_T("amax"), _T("AMAX ROM dongle"), _T("ReadySoft"),
3282 		NULL, NULL, NULL, ROMTYPE_AMAX | ROMTYPE_NONE, 0, 0, 0, false
3283 	},
3284 
3285 #if 0
3286 	{
3287 		_T("x86_xt_hd"), _T("x86 XT"), _T("x86"),
3288 		x86_xt_hd_init, NULL, x86_add_xt_hd_unit, ROMTYPE_X86_HD | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
3289 		NULL, 0,
3290 		false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
3291 	},
3292 #endif
3293 	{
3294 		_T("x86athdprimary"), _T("AT IDE Primary"), _T("x86"),
3295 		x86_at_hd_init_1, NULL, x86_add_at_hd_unit_1, ROMTYPE_X86_AT_HD1 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
3296 		NULL, 0,
3297 		false, EXPANSIONTYPE_IDE
3298 	},
3299 	{
3300 		_T("x86athdsecondary"), _T("AT IDE Secondary"), _T("x86"),
3301 		x86_at_hd_init_2, NULL, x86_add_at_hd_unit_2, ROMTYPE_X86_AT_HD2 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
3302 		NULL, 0,
3303 		false, EXPANSIONTYPE_IDE
3304 	},
3305 	{
3306 		_T("x86athdxt"), _T("XTIDE Universal BIOS HD"), _T("x86"),
3307 		x86_at_hd_init_xt, NULL, x86_add_at_hd_unit_xt, ROMTYPE_X86_XT_IDE | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
3308 		NULL, 0,
3309 		false, EXPANSIONTYPE_IDE,
3310 		0, 0, 0, false, NULL,
3311 		false,
3312 		x86_athdxt_settings
3313 	},
3314 
3315 	{
3316 		_T("a1060"), _T("A1060 Sidecar"), _T("Commodore"),
3317 		a1060_init, NULL, NULL, ROMTYPE_A1060 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3318 		NULL, 0,
3319 		false, EXPANSIONTYPE_X86_BRIDGE,
3320 		0, 0, 0, false, NULL,
3321 		false,
3322 		x86_bridge_sidecar_settings
3323 	},
3324 	{
3325 		_T("a2088"), _T("A2088"), _T("Commodore"),
3326 		a2088xt_init, NULL, NULL, ROMTYPE_A2088 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3327 		NULL, 0,
3328 		false, EXPANSIONTYPE_X86_BRIDGE,
3329 		0, 0, 0, false, NULL,
3330 		false,
3331 		x86_bridge_settings
3332 	},
3333 	{
3334 		_T("a2088t"), _T("A2088T"), _T("Commodore"),
3335 		a2088t_init, NULL, NULL, ROMTYPE_A2088T | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3336 		NULL, 0,
3337 		false, EXPANSIONTYPE_X86_BRIDGE,
3338 		0, 0, 0, false, NULL,
3339 		false,
3340 		x86_bridge_settings
3341 	},
3342 	{
3343 		_T("a2286"), _T("A2286"), _T("Commodore"),
3344 		a2286_init, NULL, NULL, ROMTYPE_A2286 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3345 		NULL, 0,
3346 		false, EXPANSIONTYPE_X86_BRIDGE,
3347 		0, 0, 0, false, NULL,
3348 		false,
3349 		x86at286_bridge_settings
3350 	},
3351 	{
3352 		_T("a2386"), _T("A2386SX"), _T("Commodore"),
3353 		a2386_init, NULL, NULL, ROMTYPE_A2386 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true,
3354 		NULL, 0,
3355 		false, EXPANSIONTYPE_X86_BRIDGE,
3356 		0, 0, 0, false, NULL,
3357 		false,
3358 		x86at386_bridge_settings
3359 	},
3360 
3361 	// only here for rom selection
3362 	{
3363 		_T("picassoiv"), _T("Picasso IV"), _T("Village Tronic"),
3364 		NULL, NULL, NULL, ROMTYPE_PICASSOIV | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,
3365 		NULL, 0,
3366 		false, EXPANSIONTYPE_RTG,
3367 	},
3368 	{
3369 		_T("x86vga"), _T("x86 VGA"), _T("x86"),
3370 		NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,
3371 		NULL, 0,
3372 		false, EXPANSIONTYPE_RTG,
3373 	},
3374 
3375 	{
3376 		NULL
3377 	}
3378 };
3379 
3380 static const struct expansionboardsettings blizzardboard_settings[] = {
3381 	{
3382 		_T("MapROM"),
3383 		_T("maprom")
3384 	},
3385 	{
3386 		NULL
3387 	}
3388 };
3389 
3390 static const struct cpuboardsubtype gvpboard_sub[] = {
3391 	{
3392 		_T("A3001 Series I"),
3393 		_T("A3001SI"),
3394 		ROMTYPE_CB_A3001S1, 0,
3395 		gvp_add_ide_unit, EXPANSIONTYPE_IDE | EXPANSIONTYPE_24BIT,
3396 		BOARD_MEMORY_Z2,
3397 		8 * 1024 * 1024,
3398 		0,
3399 		gvp_ide_rom_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 0
3400 	},
3401 	{
3402 		_T("A3001 Series II"),
3403 		_T("A3001SII"),
3404 		0, 0,
3405 		gvp_add_ide_unit, EXPANSIONTYPE_IDE | EXPANSIONTYPE_24BIT,
3406 		BOARD_MEMORY_Z2,
3407 		8 * 1024 * 1024,
3408 		0,
3409 		gvp_ide_rom_autoconfig_init, gvp_ide_controller_autoconfig_init, BOARD_AUTOCONFIG_Z2, 0
3410 	},
3411 	{
3412 		_T("A530"),
3413 		_T("GVPA530"),
3414 		ROMTYPE_GVPS2, 0,
3415 		gvp_s2_add_accelerator_scsi_unit, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_24BIT,
3416 		BOARD_MEMORY_Z2,
3417 		8 * 1024 * 1024,
3418 		0,
3419 		gvp_init_accelerator, NULL, BOARD_AUTOCONFIG_Z2, 1,
3420 		NULL, NULL,
3421 		2017, 9, 0, false
3422 	},
3423 	{
3424 		_T("G-Force 030"),
3425 		_T("GVPGFORCE030"),
3426 		ROMTYPE_GVPS2, ROMTYPE_GVPS12,
3427 		gvp_s2_add_accelerator_scsi_unit, EXPANSIONTYPE_SCSI,
3428 		BOARD_MEMORY_25BITMEM,
3429 		128 * 1024 * 1024,
3430 		0,
3431 		gvp_init_accelerator, NULL, BOARD_AUTOCONFIG_Z2, 1
3432 	},
3433 	{
3434 		_T("Tek Magic 2040/2060"),
3435 		_T("TekMagic"),
3436 		ROMTYPE_CB_TEKMAGIC, 0,
3437 		tekmagic_add_scsi_unit, EXPANSIONTYPE_SCSI,
3438 		BOARD_MEMORY_HIGHMEM,
3439 		128 * 1024 * 1024
3440 	},
3441 	{
3442 		NULL
3443 	}
3444 };
3445 static const struct cpuboardsubtype blizzardboard_sub[] = {
3446 	{
3447 		_T("Blizzard 1230 IV"),
3448 		_T("Blizzard1230IV"),
3449 		ROMTYPE_CB_BLIZ1230, 0,
3450 		NULL, 0,
3451 		BOARD_MEMORY_BLIZZARD_12xx,
3452 		256 * 1024 * 1024,
3453 		0,
3454 		NULL, NULL, 0, 0,
3455 		blizzardboard_settings
3456 	},
3457 	{
3458 		_T("Blizzard 1260"),
3459 		_T("Blizzard1260"),
3460 		ROMTYPE_CB_BLIZ1260, 0,
3461 		NULL, 0,
3462 		BOARD_MEMORY_BLIZZARD_12xx,
3463 		256 * 1024 * 1024,
3464 		0,
3465 		NULL, NULL, 0, 0,
3466 		blizzardboard_settings
3467 	},
3468 	{
3469 		_T("Blizzard 2060"),
3470 		_T("Blizzard2060"),
3471 		ROMTYPE_CB_BLIZ2060, 0,
3472 		cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI,
3473 		BOARD_MEMORY_HIGHMEM,
3474 		128 * 1024 * 1024,
3475 		0,
3476 		NULL, NULL, 0, 0,
3477 		blizzardboard_settings
3478 	},
3479 	{
3480 		_T("Blizzard PPC"),
3481 		_T("BlizzardPPC"),
3482 		ROMTYPE_CB_BLIZPPC, 0,
3483 		blizzardppc_add_scsi_unit, EXPANSIONTYPE_SCSI,
3484 		BOARD_MEMORY_BLIZZARD_PPC,
3485 		256 * 1024 * 1024
3486 	},
3487 	{
3488 		NULL
3489 	}
3490 };
3491 static const struct cpuboardsubtype cyberstormboard_sub[] = {
3492 	{
3493 		_T("CyberStorm MK I"),
3494 		_T("CyberStormMK1"),
3495 		ROMTYPE_CB_CSMK1, 0,
3496 		cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI,
3497 		BOARD_MEMORY_HIGHMEM,
3498 		128 * 1024 * 1024
3499 	},
3500 	{
3501 		_T("CyberStorm MK II"),
3502 		_T("CyberStormMK2"),
3503 		ROMTYPE_CB_CSMK2, 0,
3504 		cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI,
3505 		BOARD_MEMORY_HIGHMEM,
3506 		128 * 1024 * 1024
3507 	},
3508 	{
3509 		_T("CyberStorm MK III"),
3510 		_T("CyberStormMK3"),
3511 		ROMTYPE_CB_CSMK3, 0,
3512 		cyberstorm_add_scsi_unit, EXPANSIONTYPE_SCSI,
3513 		BOARD_MEMORY_HIGHMEM,
3514 		128 * 1024 * 1024
3515 	},
3516 	{
3517 		_T("CyberStorm PPC"),
3518 		_T("CyberStormPPC"),
3519 		ROMTYPE_CB_CSPPC, 0,
3520 		cyberstorm_add_scsi_unit, EXPANSIONTYPE_SCSI,
3521 		BOARD_MEMORY_HIGHMEM,
3522 		128 * 1024 * 1024
3523 	},
3524 	{
3525 		NULL
3526 	}
3527 };
3528 static const struct cpuboardsubtype warpengine_sub[] = {
3529 	{
3530 		_T("Warp Engine A4000"),
3531 		_T("WarpEngineA4000"),
3532 		ROMTYPE_CB_WENGINE, 0,
3533 		warpengine_add_scsi_unit, EXPANSIONTYPE_SCSI,
3534 		BOARD_MEMORY_HIGHMEM,
3535 		128 * 1024 * 1024,
3536 		0x01000000,
3537 		ncr710_warpengine_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z3, 1,
3538 		warpengine_settings
3539 	},
3540 	{
3541 		NULL
3542 	}
3543 };
3544 static const struct expansionboardsettings mtec_settings[] = {
3545 	{
3546 		_T("SCSI disabled"),
3547 		_T("scsioff")
3548 	},
3549 	{
3550 		NULL
3551 	}
3552 };
3553 static const struct cpuboardsubtype mtec_sub[] = {
3554 	{
3555 		_T("E-Matrix 530"),
3556 		_T("e-matrix530"),
3557 		ROMTYPE_CB_EMATRIX, 0,
3558 		ematrix_add_scsi_unit, EXPANSIONTYPE_SCSI,
3559 		BOARD_MEMORY_EMATRIX,
3560 		128 * 1024 * 1024,
3561 		0,
3562 		ncr_ematrix_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 1,
3563 		mtec_settings
3564 	},
3565 	{
3566 		NULL
3567 	}
3568 };
3569 static const struct expansionboardsettings a26x0board_settings[] = {
3570 	{
3571 		_T("OSMODE (J304)"),
3572 		_T("j304")
3573 	},
3574 	{
3575 		NULL
3576 	}
3577 };
3578 static const struct cpuboardsubtype commodore_sub[] = {
3579 	{
3580 		_T("A2620/A2630"),
3581 		_T("A2630"),
3582 		ROMTYPE_CB_A26x0, 0,
3583 		NULL, 0,
3584 		BOARD_MEMORY_25BITMEM,
3585 		128 * 1024 * 1024,
3586 		0,
3587 		NULL, NULL, 0, 0,
3588 		a26x0board_settings,
3589 		cpuboard_io_special
3590 	},
3591 	{
3592 		NULL
3593 	}
3594 };
3595 static const struct cpuboardsubtype dbk_sub[] = {
3596 	{
3597 		_T("1230/1240"),
3598 		_T("DKB12x0"),
3599 		ROMTYPE_CB_DKB12x0, 0,
3600 		cpuboard_dkb_add_scsi_unit, EXPANSIONTYPE_SCSI,
3601 		0,
3602 		128 * 1024 * 1024,
3603 		0,
3604 		ncr_dkb_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 0
3605 	},
3606 	{
3607 		_T("Wildfire"),
3608 		_T("wildfire"),
3609 		ROMTYPE_CB_DBK_WF, 0,
3610 		wildfire_add_scsi_unit, EXPANSIONTYPE_SCSI,
3611 		BOARD_MEMORY_HIGHMEM,
3612 		128 * 1024 * 1024,
3613 		0,
3614 		dkb_wildfire_pci_init, NULL, BOARD_NONAUTOCONFIG_BEFORE, 0
3615 	},
3616 	{
3617 		NULL
3618 	}
3619 };
3620 static const struct cpuboardsubtype fusionforty_sub[] = {
3621 	{
3622 		_T("Fusion Forty"),
3623 		_T("FusionForty"),
3624 		ROMTYPE_CB_FUSION, 0,
3625 		NULL, 0,
3626 		BOARD_MEMORY_HIGHMEM,
3627 		128 * 1024 * 1024
3628 	},
3629 	{
3630 		NULL
3631 	}
3632 };
3633 static const struct cpuboardsubtype apollo_sub[] = {
3634 	{
3635 		_T("Apollo 1240/1260"),
3636 		_T("Apollo"),
3637 		ROMTYPE_CB_APOLLO, 0,
3638 		apollo_add_scsi_unit, EXPANSIONTYPE_SCSI,
3639 		BOARD_MEMORY_HIGHMEM,
3640 		128 * 1024 * 1024,
3641 		0,
3642 		apollo_init_cpu, NULL, 2, 0
3643 	},
3644 	{
3645 		NULL
3646 	}
3647 };
3648 static const struct cpuboardsubtype kupkeboard_sub[] = {
3649 	{
3650 		_T("Golem 030"),
3651 		_T("golem030"),
3652 		ROMTYPE_CB_GOLEM030, 0,
3653 		NULL, 0,
3654 		BOARD_MEMORY_25BITMEM,
3655 		16 * 1024 * 1024
3656 	},
3657 	{
3658 		NULL
3659 	}
3660 };
3661 static const struct cpuboardsubtype icboard_sub[] = {
3662 	{
3663 		_T("ACA 500"),
3664 		_T("aca500"),
3665 		ROMTYPE_CB_ACA500, 0,
3666 		NULL, EXPANSIONTYPE_24BIT
3667 	},
3668 	{
3669 		NULL
3670 	}
3671 };
3672 static const struct cpuboardsubtype dceboard_sub[] = {
3673 	{
3674 		_T("SX32 Pro"),
3675 		_T("sx32pro"),
3676 		ROMTYPE_CB_SX32PRO, 0,
3677 		NULL, 0,
3678 		BOARD_MEMORY_EMATRIX,
3679 		64 * 1024 * 1024
3680 	},
3681 	{
3682 		NULL
3683 	}
3684 };
3685 
3686 static const struct cpuboardsubtype dummy_sub[] = {
3687 	{ NULL }
3688 };
3689 
3690 const struct cpuboardtype cpuboards[] = {
3691 	{
3692 		-1,
3693 		_T("-"),
3694 		dummy_sub, 0
3695 	},
3696 	{
3697 		BOARD_ACT,
3698 		_T("ACT"),
3699 		apollo_sub, 0
3700 	},
3701 	{
3702 		BOARD_COMMODORE,
3703 		_T("Commodore"),
3704 		commodore_sub, 0
3705 	},
3706 	{
3707 		BOARD_DCE,
3708 		_T("DCE"),
3709 		dceboard_sub, 0
3710 	},
3711 	{
3712 		BOARD_DKB,
3713 		_T("DKB"),
3714 		dbk_sub, 0
3715 	},
3716 	{
3717 		BOARD_GVP,
3718 		_T("Great Valley Products"),
3719 		gvpboard_sub, 0
3720 	},
3721 	{
3722 		BOARD_KUPKE,
3723 		_T("Kupke"),
3724 		kupkeboard_sub, 0
3725 	},
3726 	{
3727 		BOARD_MACROSYSTEM,
3728 		_T("MacroSystem"),
3729 		warpengine_sub, 0
3730 	},
3731 	{
3732 		BOARD_MTEC,
3733 		_T("M-Tec"),
3734 		mtec_sub, 0
3735 	},
3736 	{
3737 		BOARD_BLIZZARD,
3738 		_T("Phase 5 - Blizzard"),
3739 		blizzardboard_sub, 0
3740 	},
3741 	{
3742 		BOARD_CYBERSTORM,
3743 		_T("Phase 5 - CyberStorm"),
3744 		cyberstormboard_sub, 0
3745 	},
3746 	{
3747 		BOARD_RCS,
3748 		_T("RCS Management"),
3749 		fusionforty_sub, 0
3750 	},
3751 #if 0
3752 	{
3753 		BOARD_IC,
3754 		_T("Individual Computers"),
3755 		icboard_sub, 0
3756 	},
3757 #endif
3758 	{
3759 		0
3760 	}
3761 };
3762