1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Misc accelerator board special features
5 * Blizzard 1230 IV, 1240/1260, 2040/2060, PPC
6 * CyberStorm MK1, MK2, MK3, PPC.
7 * TekMagic
8 * Warp Engine
9 *
10 * Copyright 2014 Toni Wilen
11 *
12 */
13 
14 #include "sysconfig.h"
15 #include "sysdeps.h"
16 
17 #include "options.h"
18 #include "uae/memory.h"
19 #include "zfile.h"
20 #include "rommgr.h"
21 #include "autoconf.h"
22 #include "cpuboard.h"
23 #include "custom.h"
24 #include "newcpu.h"
25 #include "ncr_scsi.h"
26 #include "ncr9x_scsi.h"
27 #include "debug.h"
28 #include "flashrom.h"
29 #include "uae.h"
30 #include "uae/ppc.h"
31 #include "uae/vm.h"
32 #include "idecontrollers.h"
33 #include "scsi.h"
34 #include "cpummu030.h"
35 
36 #ifdef FSUAE // NL
37 #include "uae/fs.h"
38 #endif
39 
40 // 00F83B7C 3.1 ROM expansion board diagrom
41 
42 #define PPC_IRQ_DEBUG 0
43 #define CPUBOARD_IO_LOG 0
44 #define CPUBOARD_IRQ_LOG 0
45 
46 #define F0_WAITSTATES (2 * CYCLE_UNIT)
47 
48 // CS MK3/PPC
49 #define CYBERSTORM_MAPROM_BASE 0xfff00000
50 #define CSIII_NCR			0xf40000
51 #define CSIII_BASE			0xf60000
52 #define CSIII_REG_RESET		0x00 // 0x00
53 #define CSIII_REG_IRQ		0x01 // 0x08
54 #define CSIII_REG_WAITSTATE	0x02 // 0x10
55 #define CSIII_REG_SHADOW	0x03 // 0x18
56 #define CSIII_REG_LOCK		0x04 // 0x20
57 #define CSIII_REG_INT		0x05 // 0x28
58 #define CSIII_REG_IPL_EMU	0x06 // 0x30
59 #define CSIII_REG_INT_LVL	0x07 // 0x38
60 
61 // BPPC only
62 #define BPPC_MAPROM_ON		0x12
63 #define BPPC_MAPROM_OFF		0x13
64 #define BPPC_UNLOCK_FLASH	0x92
65 #define BPPC_LOCK_FLASH		0x93
66 #define BPPC_MAGIC_UNLOCK_VALUE 0x42
67 
68 /* bit definitions */
69 #define	P5_SET_CLEAR		0x80
70 
71 /* REQ_RESET 0x00 */
72 // M68K can only reset PPC and vice versa
73 // if P5_SELF_RESET is not active.
74 #define	P5_PPC_RESET		0x10
75 #define	P5_M68K_RESET		0x08
76 #define	P5_AMIGA_RESET		0x04
77 #define	P5_AUX_RESET		0x02
78 #define	P5_SCSI_RESET		0x01
79 
80 /* REG_IRQ 0x08 */
81 #define P5_IRQ_SCSI			0x01
82 #define P5_IRQ_SCSI_EN		0x02
83 // 0x04
84 #define P5_IRQ_PPC_1		0x08
85 #define P5_IRQ_PPC_2		0x10
86 #define P5_IRQ_PPC_3		0x20 // MOS sets this bit
87 // 0x40 always cleared
88 
89 /* REG_WAITSTATE 0x10 */
90 #define	P5_PPC_WRITE		0x08
91 #define	P5_PPC_READ			0x04
92 #define	P5_M68K_WRITE		0x02
93 #define	P5_M68K_READ		0x01
94 
95 /* REG_SHADOW 0x18 */
96 #define	P5_SELF_RESET		0x40
97 // 0x20
98 // 0x10
99 // 0x08 always set
100 #define P5_FLASH			0x04 // Flash writable (CSMK3,CSPPC only)
101 // 0x02 (can be modified even when locked)
102 #define	P5_SHADOW			0x01 // KS MAP ROM
103 
104 /* REG_LOCK 0x20. CSMK3,CSPPC only */
105 #define	P5_MAGIC1			0x60 // REG_SHADOW and flash write protection unlock sequence
106 #define	P5_MAGIC2			0x50
107 #define	P5_MAGIC3			0x30
108 #define	P5_MAGIC4			0x70
109 // when cleared, another CPU gets either stopped or can't access memory until set again.
110 #define P5_LOCK_CPU			0x01
111 
112 /* REG_INT 0x28 */
113 // 0x40 always set
114 // 0x20
115 // 0x10 always set
116 // 0x08
117 // 0x04 // MOS sets this bit
118 #define	P5_ENABLE_IPL		0x02
119 #define	P5_INT_MASTER		0x01 // 1=m68k gets interrupts, 0=ppc gets interrupts.
120 
121 /* IPL_EMU 0x30 */
122 #define	P5_DISABLE_INT		0x40 // if set: all CPU interrupts disabled?
123 #define	P5_M68K_IPL2		0x20
124 #define	P5_M68K_IPL1		0x10
125 #define	P5_M68K_IPL0		0x08
126 #define P5_M68k_IPL_MASK	0x38
127 #define	P5_PPC_IPL2			0x04
128 #define	P5_PPC_IPL1			0x02
129 #define	P5_PPC_IPL0			0x01
130 #define P5_PPC_IPL_MASK		0x07
131 
132 /* INT_LVL 0x38 */
133 #define	P5_LVL7				0x40
134 #define	P5_LVL6				0x20
135 #define	P5_LVL5				0x10
136 #define	P5_LVL4				0x08
137 #define	P5_LVL3				0x04
138 #define	P5_LVL2				0x02
139 #define	P5_LVL1				0x01
140 
141 #define CS_RAM_BASE 0x0c000000
142 
143 #define BLIZZARD_RAM_BASE_48 0x48000000
144 #define BLIZZARD_RAM_BASE_68 0x68000000
145 #define BLIZZARD_RAM_256M_BASE_40 0x40000000
146 #define BLIZZARD_RAM_256M_BASE_70 0x70000000
147 #define BLIZZARD_MAPROM_BASE 0x4ff80000
148 #define BLIZZARD_MAPROM_ENABLE 0x80ffff00
149 #define BLIZZARD_BOARD_DISABLE 0x80fa0000
150 
151 #define CSMK2_BOARD_DISABLE 0x83000000
152 
153 static int cpuboard_size = -1, cpuboard2_size = -1;
154 static int configured;
155 static int blizzard_jit;
156 static int maprom_state;
157 static uae_u32 maprom_base;
158 static int delayed_rom_protect;
159 static int f0rom_size, earom_size;
160 static uae_u8 io_reg[64];
161 static void *flashrom, *flashrom2;
162 static struct zfile *flashrom_file;
163 static int flash_unlocked;
164 static int csmk2_flashaddressing;
165 static bool blizzardmaprom_bank_mapped, blizzardmaprom2_bank_mapped;
166 static bool cpuboard_non_byte_ea;
167 static uae_u16 a2630_io;
168 
169 #ifdef WITH_PPC
170 
171 static bool ppc_irq_pending;
172 
set_ppc_interrupt(void)173 static void set_ppc_interrupt(void)
174 {
175 	if (ppc_irq_pending)
176 		return;
177 #if PPC_IRQ_DEBUG
178 	write_log(_T("set_ppc_interrupt\n"));
179 #endif
180 	uae_ppc_interrupt(true);
181 	ppc_irq_pending = true;
182 }
clear_ppc_interrupt(void)183 static void clear_ppc_interrupt(void)
184 {
185 	if (!ppc_irq_pending)
186 		return;
187 #if PPC_IRQ_DEBUG
188 	write_log(_T("clear_ppc_interrupt\n"));
189 #endif
190 	uae_ppc_interrupt(false);
191 	ppc_irq_pending = false;
192 }
193 
check_ppc_int_lvl(void)194 static void check_ppc_int_lvl(void)
195 {
196 	bool m68kint = (io_reg[CSIII_REG_INT] & P5_INT_MASTER) != 0;
197 	bool active = (io_reg[CSIII_REG_IPL_EMU] & P5_DISABLE_INT) == 0;
198 	bool iplemu = (io_reg[CSIII_REG_INT] & P5_ENABLE_IPL) == 0;
199 
200 	if (m68kint && iplemu && active) {
201 		uae_u8 ppcipl = (~io_reg[CSIII_REG_IPL_EMU]) & P5_PPC_IPL_MASK;
202 		if (ppcipl < 7) {
203 			uae_u8 ilvl = (~io_reg[CSIII_REG_INT_LVL]) & 0x7f;
204 			if (ilvl) {
205 				for (int i = ppcipl; i < 7; i++) {
206 					if (ilvl & (1 << i)) {
207 						set_ppc_interrupt();
208 						return;
209 					}
210 				}
211 			}
212 		}
213 		clear_ppc_interrupt();
214 	}
215 }
216 
ppc_interrupt(int new_m68k_ipl)217 bool ppc_interrupt(int new_m68k_ipl)
218 {
219 	bool m68kint = (io_reg[CSIII_REG_INT] & P5_INT_MASTER) != 0;
220 	bool active = (io_reg[CSIII_REG_IPL_EMU] & P5_DISABLE_INT) == 0;
221 	bool iplemu = (io_reg[CSIII_REG_INT] & P5_ENABLE_IPL) == 0;
222 
223 	if (!active)
224 		return false;
225 
226 	if (!m68kint && iplemu && active) {
227 
228 		uae_u8 ppcipl = (~io_reg[CSIII_REG_IPL_EMU]) & P5_PPC_IPL_MASK;
229 		if (new_m68k_ipl < 0)
230 			new_m68k_ipl = 0;
231 		io_reg[CSIII_REG_IPL_EMU] &= ~P5_M68k_IPL_MASK;
232 		io_reg[CSIII_REG_IPL_EMU] |= (new_m68k_ipl << 3) ^ P5_M68k_IPL_MASK;
233 		if (new_m68k_ipl > ppcipl) {
234 			set_ppc_interrupt();
235 		} else {
236 			clear_ppc_interrupt();
237 		}
238 	}
239 
240 	return m68kint;
241 }
242 
243 #endif /* WITH_PPC */
244 
mapromconfigured(void)245 static bool mapromconfigured(void)
246 {
247 	if (currprefs.maprom)
248 		return true;
249 	if (currprefs.cpuboard_settings)
250 		return true;
251 	return false;
252 }
253 
cpuboard_set_flash_unlocked(bool unlocked)254 void cpuboard_set_flash_unlocked(bool unlocked)
255 {
256 	flash_unlocked = unlocked;
257 }
258 
is_blizzard(void)259 static bool is_blizzard(void)
260 {
261 	return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
262 }
is_blizzard2060(void)263 static bool is_blizzard2060(void)
264 {
265 	return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060);
266 }
is_csmk1(void)267 static bool is_csmk1(void)
268 {
269 	return ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1);
270 }
is_csmk2(void)271 static bool is_csmk2(void)
272 {
273 	return ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2);
274 }
is_csmk3(void)275 static bool is_csmk3(void)
276 {
277 	return ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3) || ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
278 }
is_blizzardppc(void)279 static bool is_blizzardppc(void)
280 {
281 	return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
282 }
is_ppc(void)283 static bool is_ppc(void)
284 {
285 	return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC) || ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
286 }
is_tekmagic(void)287 static bool is_tekmagic(void)
288 {
289 	return ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_TEKMAGIC);
290 }
is_a2630(void)291 static bool is_a2630(void)
292 {
293 	return ISCPUBOARD(BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0);
294 }
is_dkb_12x0(void)295 static bool is_dkb_12x0(void)
296 {
297 	return ISCPUBOARD(BOARD_DKB, BOARD_DKB_SUB_12x0);
298 }
is_dkb_wildfire(void)299 static bool is_dkb_wildfire(void)
300 {
301 	return ISCPUBOARD(BOARD_DKB, BOARD_DKB_SUB_WILDFIRE);
302 }
is_mtec_ematrix530(void)303 static bool is_mtec_ematrix530(void)
304 {
305 	return ISCPUBOARD(BOARD_MTEC, BOARD_MTEC_SUB_EMATRIX530);
306 }
is_fusionforty(void)307 static bool is_fusionforty(void)
308 {
309 	return ISCPUBOARD(BOARD_RCS, BOARD_RCS_SUB_FUSIONFORTY);
310 }
is_apollo(void)311 static bool is_apollo(void)
312 {
313 	return ISCPUBOARD(BOARD_ACT, BOARD_ACT_SUB_APOLLO);
314 }
is_kupke(void)315 static bool is_kupke(void)
316 {
317 	return ISCPUBOARD(BOARD_KUPKE, 0);
318 }
is_sx32pro(void)319 static bool is_sx32pro(void)
320 {
321 	return ISCPUBOARD(BOARD_DCE, 0);
322 }
is_aca500(void)323 static bool is_aca500(void)
324 {
325 	return ISCPUBOARD(BOARD_IC, BOARD_IC_ACA500);
326 }
327 
328 DECLARE_MEMORY_FUNCTIONS(blizzardio);
329 static addrbank blizzardio_bank = {
330 	blizzardio_lget, blizzardio_wget, blizzardio_bget,
331 	blizzardio_lput, blizzardio_wput, blizzardio_bput,
332 	default_xlate, default_check, NULL, NULL, _T("CPUBoard IO"),
333 	blizzardio_wget, blizzardio_bget,
334 	ABFLAG_IO, S_READ, S_WRITE
335 };
336 
337 DECLARE_MEMORY_FUNCTIONS(blizzardram);
338 static addrbank blizzardram_bank = {
339 	blizzardram_lget, blizzardram_wget, blizzardram_bget,
340 	blizzardram_lput, blizzardram_wput, blizzardram_bput,
341 	blizzardram_xlate, blizzardram_check, NULL, NULL, _T("CPUBoard RAM"),
342 	blizzardram_lget, blizzardram_wget,
343 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
344 };
345 
346 DECLARE_MEMORY_FUNCTIONS(blizzardea);
347 static addrbank blizzardea_bank = {
348 	blizzardea_lget, blizzardea_wget, blizzardea_bget,
349 	blizzardea_lput, blizzardea_wput, blizzardea_bput,
350 	blizzardea_xlate, blizzardea_check, NULL, _T("rom_ea"), _T("CPUBoard E9/EA Autoconfig"),
351 	blizzardea_lget, blizzardea_wget,
352 	ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
353 };
354 
355 DECLARE_MEMORY_FUNCTIONS(blizzarde8);
356 static addrbank blizzarde8_bank = {
357 	blizzarde8_lget, blizzarde8_wget, blizzarde8_bget,
358 	blizzarde8_lput, blizzarde8_wput, blizzarde8_bput,
359 	blizzarde8_xlate, blizzarde8_check, NULL, NULL, _T("CPUBoard E8 Autoconfig"),
360 	blizzarde8_lget, blizzarde8_wget,
361 	ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
362 };
363 
364 DECLARE_MEMORY_FUNCTIONS(blizzardf0);
365 static addrbank blizzardf0_bank = {
366 	blizzardf0_lget, blizzardf0_wget, blizzardf0_bget,
367 	blizzardf0_lput, blizzardf0_wput, blizzardf0_bput,
368 	blizzardf0_xlate, blizzardf0_check, NULL, _T("rom_f0_ppc"), _T("CPUBoard F00000"),
369 	blizzardf0_lget, blizzardf0_wget,
370 	ABFLAG_ROM, S_READ, S_WRITE
371 };
372 
373 DECLARE_MEMORY_FUNCTIONS(blizzardram_nojit);
374 static addrbank blizzardram_nojit_bank = {
375 	blizzardram_nojit_lget, blizzardram_nojit_wget, blizzardram_nojit_bget,
376 	blizzardram_nojit_lput, blizzardram_nojit_wput, blizzardram_nojit_bput,
377 	blizzardram_nojit_xlate, blizzardram_nojit_check, NULL, NULL, _T("CPUBoard RAM"),
378 	blizzardram_nojit_lget, blizzardram_nojit_wget,
379 	ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
380 };
381 
382 DECLARE_MEMORY_FUNCTIONS(blizzardmaprom);
383 static addrbank blizzardmaprom_bank = {
384 	blizzardmaprom_lget, blizzardmaprom_wget, blizzardmaprom_bget,
385 	blizzardmaprom_lput, blizzardmaprom_wput, blizzardmaprom_bput,
386 	blizzardmaprom_xlate, blizzardmaprom_check, NULL, _T("maprom"), _T("CPUBoard MAPROM"),
387 	blizzardmaprom_lget, blizzardmaprom_wget,
388 	ABFLAG_RAM, S_READ, S_WRITE
389 };
390 DECLARE_MEMORY_FUNCTIONS(blizzardmaprom2);
391 static addrbank blizzardmaprom2_bank = {
392 	blizzardmaprom2_lget, blizzardmaprom2_wget, blizzardmaprom2_bget,
393 	blizzardmaprom2_lput, blizzardmaprom2_wput, blizzardmaprom2_bput,
394 	blizzardmaprom2_xlate, blizzardmaprom2_check, NULL, _T("maprom2"), _T("CPUBoard MAPROM2"),
395 	blizzardmaprom2_lget, blizzardmaprom2_wget,
396 	ABFLAG_RAM, S_READ, S_WRITE
397 };
398 
399 // hack to map F41000 SCSI SCRIPTS RAM to JIT friendly address
cyberstorm_scsi_ram_put(uaecptr addr,uae_u32 v)400 void cyberstorm_scsi_ram_put(uaecptr addr, uae_u32 v)
401 {
402 	addr &= 0xffff;
403 	addr += (CSIII_NCR & 0x7ffff);
404 	blizzardf0_bank.baseaddr[addr] = v;
405 }
cyberstorm_scsi_ram_get(uaecptr addr)406 uae_u32 cyberstorm_scsi_ram_get(uaecptr addr)
407 {
408 	uae_u32 v;
409 	addr &= 0xffff;
410 	addr += (CSIII_NCR & 0x7ffff);
411 	v = blizzardf0_bank.baseaddr[addr];
412 	return v;
413 }
cyberstorm_scsi_ram_xlate(uaecptr addr)414 uae_u8 *REGPARAM2 cyberstorm_scsi_ram_xlate(uaecptr addr)
415 {
416 	addr &= 0xffff;
417 	addr += (CSIII_NCR & 0x7ffff);
418 	return blizzardf0_bank.baseaddr + addr;
419 }
cyberstorm_scsi_ram_check(uaecptr a,uae_u32 b)420 int REGPARAM2 cyberstorm_scsi_ram_check(uaecptr a, uae_u32 b)
421 {
422 	a &= 0xffff;
423 	return a >= 0x1000 && a + b < 0x3000;
424 }
425 
426 MEMORY_FUNCTIONS(blizzardram);
427 
428 MEMORY_BGET(blizzardram_nojit);
429 MEMORY_WGET(blizzardram_nojit);
430 MEMORY_LGET(blizzardram_nojit);
431 MEMORY_CHECK(blizzardram_nojit);
432 MEMORY_XLATE(blizzardram_nojit);
433 
blizzardram_nojit_lput(uaecptr addr,uae_u32 l)434 static void REGPARAM2 blizzardram_nojit_lput(uaecptr addr, uae_u32 l)
435 {
436 	uae_u32 *m;
437 
438 	addr &= blizzardram_nojit_bank.mask;
439 	if (maprom_state && addr >= maprom_base)
440 		return;
441 	m = (uae_u32 *)(blizzardram_nojit_bank.baseaddr + addr);
442 	do_put_mem_long(m, l);
443 }
blizzardram_nojit_wput(uaecptr addr,uae_u32 w)444 static void REGPARAM2 blizzardram_nojit_wput(uaecptr addr, uae_u32 w)
445 {
446 	uae_u16 *m;
447 
448 	addr &= blizzardram_nojit_bank.mask;
449 	if (maprom_state && addr >= maprom_base)
450 		return;
451 	m = (uae_u16 *)(blizzardram_nojit_bank.baseaddr + addr);
452 	do_put_mem_word(m, w);
453 }
blizzardram_nojit_bput(uaecptr addr,uae_u32 b)454 static void REGPARAM2 blizzardram_nojit_bput(uaecptr addr, uae_u32 b)
455 {
456 	addr &= blizzardram_nojit_bank.mask;
457 	if (maprom_state && addr >= maprom_base)
458 		return;
459 	blizzardram_nojit_bank.baseaddr[addr] = b;
460 }
461 
no_rom_protect(void)462 static void no_rom_protect(void)
463 {
464 	if (delayed_rom_protect)
465 		return;
466 	delayed_rom_protect = 10;
467 	protect_roms(false);
468 }
469 
470 MEMORY_BGET(blizzardmaprom2);
471 MEMORY_WGET(blizzardmaprom2);
472 MEMORY_LGET(blizzardmaprom2);
473 MEMORY_BPUT(blizzardmaprom2);
474 MEMORY_WPUT(blizzardmaprom2);
475 MEMORY_LPUT(blizzardmaprom2);
476 MEMORY_CHECK(blizzardmaprom2);
477 MEMORY_XLATE(blizzardmaprom2);
478 
479 MEMORY_BGET(blizzardmaprom);
480 MEMORY_WGET(blizzardmaprom);
481 MEMORY_LGET(blizzardmaprom);
482 MEMORY_CHECK(blizzardmaprom);
483 MEMORY_XLATE(blizzardmaprom);
484 
blizzardmaprom_lput(uaecptr addr,uae_u32 l)485 static void REGPARAM2 blizzardmaprom_lput(uaecptr addr, uae_u32 l)
486 {
487 	uae_u32 *m;
488 	if (is_blizzard2060() && !maprom_state)
489 		return;
490 	addr &= blizzardmaprom_bank.mask;
491 	m = (uae_u32 *)(blizzardmaprom_bank.baseaddr + addr);
492 	do_put_mem_long(m, l);
493 	if (maprom_state && !(addr & 0x80000)) {
494 		no_rom_protect();
495 		m = (uae_u32 *)(kickmem_bank.baseaddr + addr);
496 		do_put_mem_long(m, l);
497 	}
498 }
blizzardmaprom_wput(uaecptr addr,uae_u32 w)499 static void REGPARAM2 blizzardmaprom_wput(uaecptr addr, uae_u32 w)
500 {
501 	uae_u16 *m;
502 	if (is_blizzard2060() && !maprom_state)
503 		return;
504 	addr &= blizzardmaprom_bank.mask;
505 	m = (uae_u16 *)(blizzardmaprom_bank.baseaddr + addr);
506 	do_put_mem_word(m, w);
507 	if (maprom_state && !(addr & 0x80000)) {
508 		no_rom_protect();
509 		m = (uae_u16 *)(kickmem_bank.baseaddr + addr);
510 		do_put_mem_word(m, w);
511 	}
512 }
blizzardmaprom_bput(uaecptr addr,uae_u32 b)513 static void REGPARAM2 blizzardmaprom_bput(uaecptr addr, uae_u32 b)
514 {
515 	if (is_blizzard2060() && !maprom_state)
516 		return;
517 	addr &= blizzardmaprom_bank.mask;
518 	blizzardmaprom_bank.baseaddr[addr] = b;
519 	if (maprom_state && !(addr & 0x80000)) {
520 		no_rom_protect();
521 		kickmem_bank.baseaddr[addr] = b;
522 	}
523 }
524 
525 MEMORY_CHECK(blizzardea);
526 MEMORY_XLATE(blizzardea);
527 
blizzardf0_slow(int size)528 static void blizzardf0_slow(int size)
529 {
530 	if (is_blizzard() || is_blizzardppc() || is_blizzard2060()) {
531 		if (size == 4)
532 			regs.memory_waitstate_cycles += F0_WAITSTATES * 6;
533 		else if (size == 2)
534 			regs.memory_waitstate_cycles += F0_WAITSTATES * 3;
535 		else
536 			regs.memory_waitstate_cycles += F0_WAITSTATES * 1;
537 	}
538 }
539 
blizzarde8_check(uaecptr addr,uae_u32 size)540 static int REGPARAM2 blizzarde8_check(uaecptr addr, uae_u32 size)
541 {
542 	return 0;
543 }
blizzarde8_xlate(uaecptr addr)544 static uae_u8 *REGPARAM2 blizzarde8_xlate(uaecptr addr)
545 {
546 	return NULL;
547 }
548 
blizzardf0_bget(uaecptr addr)549 static uae_u32 REGPARAM2 blizzardf0_bget(uaecptr addr)
550 {
551 	uae_u8 v;
552 
553 	blizzardf0_slow(1);
554 
555 	if (is_csmk3() || is_blizzardppc()) {
556 		if (flash_unlocked) {
557 			return flash_read(flashrom, addr);
558 		}
559 	} else if (is_csmk2()) {
560 		addr &= 65535;
561 		addr += 65536;
562 		return flash_read(flashrom, addr);
563 	} else if (is_csmk1()) {
564 		addr &= 65535;
565 		addr += 65536;
566 		return flash_read(flashrom, addr);
567 	} else if (is_dkb_wildfire()) {
568 		if (flash_unlocked) {
569 			if (addr & 1)
570 				return flash_read(flashrom2, addr);
571 			else
572 				return flash_read(flashrom, addr);
573 		}
574 	}
575 	addr &= blizzardf0_bank.mask;
576 	v = blizzardf0_bank.baseaddr[addr];
577 	return v;
578 }
blizzardf0_lget(uaecptr addr)579 static uae_u32 REGPARAM2 blizzardf0_lget(uaecptr addr)
580 {
581 	uae_u32 *m;
582 
583 	//write_log(_T("F0 LONGGET %08x\n"), addr);
584 
585 	blizzardf0_slow(4);
586 
587 	addr &= blizzardf0_bank.mask;
588 	m = (uae_u32 *)(blizzardf0_bank.baseaddr + addr);
589 	return do_get_mem_long(m);
590 }
blizzardf0_wget(uaecptr addr)591 static uae_u32 REGPARAM2 blizzardf0_wget(uaecptr addr)
592 {
593 	uae_u16 *m, v;
594 
595 	blizzardf0_slow(2);
596 	if (is_dkb_wildfire() && flash_unlocked) {
597 		v = blizzardf0_bget(addr + 0) << 8;
598 		v |= blizzardf0_bget(addr + 1);
599 	} else {
600 		addr &= blizzardf0_bank.mask;
601 		m = (uae_u16 *)(blizzardf0_bank.baseaddr + addr);
602 		v = do_get_mem_word(m);
603 	}
604 	return v;
605 }
606 
blizzardf0_bput(uaecptr addr,uae_u32 b)607 static void REGPARAM2 blizzardf0_bput(uaecptr addr, uae_u32 b)
608 {
609 	blizzardf0_slow(1);
610 
611 	if (is_csmk3() || is_blizzardppc()) {
612 		if (flash_unlocked) {
613 			flash_write(flashrom, addr, b);
614 		}
615 	} else if (is_csmk2()) {
616 		addr &= 65535;
617 		addr += 65536;
618 		addr &= ~3;
619 		addr |= csmk2_flashaddressing;
620 		flash_write(flashrom, addr, b);
621 	} else if (is_csmk1()) {
622 		addr &= 65535;
623 		addr += 65536;
624 		flash_write(flashrom, addr, b);
625 	} else if (is_dkb_wildfire()) {
626 		if (flash_unlocked) {
627 			if (addr & 1)
628 				flash_write(flashrom2, addr, b);
629 			else
630 				flash_write(flashrom, addr, b);
631 		}
632 	}
633 }
blizzardf0_lput(uaecptr addr,uae_u32 b)634 static void REGPARAM2 blizzardf0_lput(uaecptr addr, uae_u32 b)
635 {
636 	blizzardf0_slow(4);
637 }
blizzardf0_wput(uaecptr addr,uae_u32 b)638 static void REGPARAM2 blizzardf0_wput(uaecptr addr, uae_u32 b)
639 {
640 	blizzardf0_slow(2);
641 	if (is_dkb_wildfire()) {
642 		blizzardf0_bput(addr + 0, b >> 8);
643 		blizzardf0_bput(addr + 1, b >> 0);
644 	}
645 }
646 
647 MEMORY_CHECK(blizzardf0);
648 MEMORY_XLATE(blizzardf0);
649 
blizzardea_lget(uaecptr addr)650 static uae_u32 REGPARAM2 blizzardea_lget(uaecptr addr)
651 {
652 	uae_u32 v = 0;
653 	if (cpuboard_non_byte_ea) {
654 		v = blizzardea_bget(addr + 3) <<  0;
655 		v |= blizzardea_bget(addr + 2) <<  8;
656 		v |= blizzardea_bget(addr + 1) << 16;
657 		v |= blizzardea_bget(addr + 0) << 24;
658 	}
659 	return v;
660 }
blizzardea_wget(uaecptr addr)661 static uae_u32 REGPARAM2 blizzardea_wget(uaecptr addr)
662 {
663 	uae_u32 v = 0;
664 	if (cpuboard_non_byte_ea) {
665 		v  = blizzardea_bget(addr + 1) <<  0;
666 		v |= blizzardea_bget(addr + 0) <<  8;
667 	}
668 	return v;
669 }
blizzardea_bget(uaecptr addr)670 static uae_u32 REGPARAM2 blizzardea_bget(uaecptr addr)
671 {
672 	uae_u8 v;
673 
674 	addr &= blizzardea_bank.mask;
675 	if (is_tekmagic()) {
676 		cpuboard_non_byte_ea = true;
677 		v = cpuboard_ncr710_io_bget(addr);
678 	} else if (is_blizzard2060() && addr >= BLIZZARD_2060_SCSI_OFFSET) {
679 		v = cpuboard_ncr9x_scsi_get(addr);
680 	} else if (is_blizzard()) {
681 		if (addr & BLIZZARD_SCSI_KIT_SCSI_OFFSET)
682 			v = cpuboard_ncr9x_scsi_get(addr);
683 		else
684 			v = blizzardea_bank.baseaddr[addr];
685 	} else if (is_csmk1()) {
686 		if (addr >= CYBERSTORM_MK1_SCSI_OFFSET) {
687 			v = cpuboard_ncr9x_scsi_get(addr);
688 		} else if (flash_active(flashrom, addr)) {
689 			v = flash_read(flashrom, addr);
690 		} else {
691 			v = blizzardea_bank.baseaddr[addr];
692 		}
693 	} else if (is_csmk2()) {
694 		if (addr >= CYBERSTORM_MK2_SCSI_OFFSET) {
695 			v = cpuboard_ncr9x_scsi_get(addr);
696 		} else if (flash_active(flashrom, addr)) {
697 			v = flash_read(flashrom, addr);
698 		} else {
699 			v = blizzardea_bank.baseaddr[addr];
700 		}
701 	} else if (is_mtec_ematrix530()) {
702 		v = blizzardea_bank.baseaddr[addr];
703 		if ((addr & 0xf800) == 0xe800) {
704 			if ((addr & 3) < 2) {
705 				map_banks(&dummy_bank, 0x10000000 >> 16, 0x8000000 >> 16, 0);
706 				if (custmem1_bank.allocated) {
707 					map_banks(&custmem1_bank, (0x18000000 - custmem1_bank.allocated) >> 16, custmem1_bank.allocated >> 16, 0);
708 					if (custmem1_bank.allocated < 128 * 1024 * 1024) {
709 						map_banks(&custmem1_bank, (0x18000000 - 2 * custmem1_bank.allocated) >> 16, custmem1_bank.allocated >> 16, 0);
710 					}
711 				}
712 			}
713 			if ((addr & 3) >= 2) {
714 				map_banks(&dummy_bank, 0x18000000 >> 16, 0x8000000 >> 16, 0);
715 				if (custmem2_bank.allocated) {
716 					map_banks(&custmem2_bank, 0x18000000 >> 16, custmem2_bank.allocated >> 16, 0);
717 					if (custmem2_bank.allocated < 128 * 1024 * 1024) {
718 						map_banks(&custmem2_bank, (0x18000000 + custmem2_bank.allocated) >> 16, custmem2_bank.allocated >> 16, 0);
719 					}
720 				}
721 			}
722 		}
723 	} else {
724 		v = blizzardea_bank.baseaddr[addr];
725 	}
726 	return v;
727 }
728 
blizzardea_lput(uaecptr addr,uae_u32 l)729 static void REGPARAM2 blizzardea_lput(uaecptr addr, uae_u32 l)
730 {
731 	if (cpuboard_non_byte_ea) {
732 		blizzardea_bput(addr + 3, l >> 0);
733 		blizzardea_bput(addr + 2, l >> 8);
734 		blizzardea_bput(addr + 1, l >> 16);
735 		blizzardea_bput(addr + 0, l >> 24);
736 	}
737 }
blizzardea_wput(uaecptr addr,uae_u32 w)738 static void REGPARAM2 blizzardea_wput(uaecptr addr, uae_u32 w)
739 {
740 	if (cpuboard_non_byte_ea) {
741 		blizzardea_bput(addr + 1, w >> 0);
742 		blizzardea_bput(addr + 0, w >> 8);
743 	}
744 }
blizzardea_bput(uaecptr addr,uae_u32 b)745 static void REGPARAM2 blizzardea_bput(uaecptr addr, uae_u32 b)
746 {
747 	addr &= blizzardea_bank.mask;
748 	if (is_tekmagic()) {
749 		cpuboard_non_byte_ea = true;
750 		cpuboard_ncr710_io_bput(addr, b);
751 	} else if (is_blizzard2060() && addr >= BLIZZARD_2060_SCSI_OFFSET) {
752 		cpuboard_ncr9x_scsi_put(addr, b);
753 	} else if ((is_blizzard()) && addr >= BLIZZARD_SCSI_KIT_SCSI_OFFSET) {
754 		cpuboard_ncr9x_scsi_put(addr, b);
755 	} else if (is_csmk1()) {
756 		if (addr >= CYBERSTORM_MK1_SCSI_OFFSET) {
757 			cpuboard_ncr9x_scsi_put(addr, b);
758 		} else {
759 			flash_write(flashrom, addr, b);
760 		}
761 	} else if (is_csmk2()) {
762 		if (addr >= CYBERSTORM_MK2_SCSI_OFFSET) {
763 			cpuboard_ncr9x_scsi_put(addr, b);
764 		}  else {
765 			addr &= ~3;
766 			addr |= csmk2_flashaddressing;
767 			flash_write(flashrom, addr, b);
768 		}
769 	} else if (is_mtec_ematrix530()) {
770 		if ((addr & 0xf800) == 0xe800) {
771 			if ((addr & 3) < 2) {
772 				map_banks(&dummy_bank, 0x10000000 >> 16, 0x8000000 >> 16, 0);
773 				if (custmem1_bank.allocated)
774 					map_banks(&custmem1_bank, (0x18000000 - custmem1_bank.allocated) >> 16, custmem1_bank.allocated >> 16, 0);
775 			}
776 			if ((addr & 3) >= 2) {
777 				map_banks(&dummy_bank, 0x18000000 >> 16, 0x8000000 >> 16, 0);
778 				if (custmem2_bank.allocated)
779 					map_banks(&custmem2_bank, 0x18000000 >> 16, custmem2_bank.allocated >> 16, 0);
780 			}
781 		}
782 	}
783 }
784 
blizzarde8_lput(uaecptr addr,uae_u32 b)785 static void REGPARAM2 blizzarde8_lput(uaecptr addr, uae_u32 b)
786 {
787 }
blizzarde8_wput(uaecptr addr,uae_u32 b)788 static void REGPARAM2 blizzarde8_wput(uaecptr addr, uae_u32 b)
789 {
790 }
blizzarde8_bput(uaecptr addr,uae_u32 b)791 static void REGPARAM2 blizzarde8_bput(uaecptr addr, uae_u32 b)
792 {
793 	b &= 0xff;
794 	addr &= 65535;
795 	if (addr == 0x48 && !configured) {
796 		map_banks(&blizzardea_bank, b, blizzardea_bank.allocated >> 16, 0);
797 		write_log(_T("Accelerator Z2 board autoconfigured at %02X0000\n"), b);
798 		configured = 1;
799 		expamem_next (&blizzardea_bank, NULL);
800 		return;
801 	}
802 	if (addr == 0x4c && !configured) {
803 		write_log(_T("Blizzard Z2 SHUT-UP!\n"));
804 		configured = 1;
805 		expamem_next (NULL, NULL);
806 		return;
807 	}
808 }
blizzarde8_bget(uaecptr addr)809 static uae_u32 REGPARAM2 blizzarde8_bget(uaecptr addr)
810 {
811 	uae_u32 v = 0xffff;
812 	v = blizzardea_bank.baseaddr[addr & blizzardea_bank.mask];
813 	return v;
814 }
blizzarde8_wget(uaecptr addr)815 static uae_u32 REGPARAM2 blizzarde8_wget(uaecptr addr)
816 {
817 	uae_u32 v = 0xffff;
818 	v = (blizzardea_bank.baseaddr[addr & blizzardea_bank.mask] << 8) | blizzardea_bank.baseaddr[(addr + 1) & blizzardea_bank.mask];
819 	return v;
820 }
blizzarde8_lget(uaecptr addr)821 static uae_u32 REGPARAM2 blizzarde8_lget(uaecptr addr)
822 {
823 	uae_u32 v = 0xffff;
824 	v = (blizzarde8_wget(addr) << 16) | blizzarde8_wget(addr + 2);
825 	return v;
826 }
827 
blizzard_copymaprom(void)828 static void blizzard_copymaprom(void)
829 {
830 	if (!maprom_state) {
831 		reload_roms();
832 	} else {
833 		uae_u8 *src = get_real_address(BLIZZARD_MAPROM_BASE);
834 		if (src) {
835 			uae_u8 *dst = kickmem_bank.baseaddr;
836 			protect_roms(false);
837 			memcpy(dst, src, 524288);
838 			protect_roms(true);
839 			set_roms_modified();
840 		}
841 	}
842 }
cyberstorm_copymaprom(void)843 static void cyberstorm_copymaprom(void)
844 {
845 	if (!maprom_state) {
846 		reload_roms();
847 	} else if (blizzardmaprom_bank.baseaddr) {
848 		uae_u8 *src = blizzardmaprom_bank.baseaddr;
849 		uae_u8 *dst = kickmem_bank.baseaddr;
850 #ifdef FSUAE
851 		write_log("cyberstorm_copymaprom src=%p dst=%p\n", src, dst);
852 #endif
853 		protect_roms(false);
854 		memcpy(dst, src, 524288);
855 		protect_roms(true);
856 		set_roms_modified();
857 	}
858 }
cyberstormmk2_copymaprom(void)859 static void cyberstormmk2_copymaprom(void)
860 {
861 	if (blizzardmaprom_bank.baseaddr) {
862 		uae_u8 *src = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 524288;
863 		uae_u8 *dst = kickmem_bank.baseaddr;
864 		protect_roms(false);
865 		memcpy(dst, src, 524288);
866 		protect_roms(true);
867 		set_roms_modified();
868 	}
869 }
cyberstormmk1_copymaprom(void)870 static void cyberstormmk1_copymaprom(void)
871 {
872 	if (blizzardmaprom_bank.baseaddr) {
873 		uae_u8 *src = blizzardmaprom_bank.baseaddr;
874 		uae_u8 *dst = kickmem_bank.baseaddr;
875 		protect_roms(false);
876 		memcpy(dst, src, 524288);
877 		protect_roms(true);
878 		set_roms_modified();
879 	}
880 }
881 
cpuboard_is_ppcboard_irq(void)882 bool cpuboard_is_ppcboard_irq(void)
883 {
884 	if (is_csmk3() || is_blizzardppc()) {
885 		if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
886 			return true;
887 		} else if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
888 			return true;
889 		}
890 	}
891 	return false;
892 }
893 
cpuboard_rethink(void)894 void cpuboard_rethink(void)
895 {
896 	if (is_csmk3() || is_blizzardppc()) {
897 		if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
898 			INTREQ_0(0x8000 | 0x0008);
899 			if (currprefs.cachesize)
900 				uae_int_requested |= 0x010000;
901 			uae_ppc_wakeup_main();
902 		} else if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
903 			INTREQ_0(0x8000 | 0x0008);
904 			if (currprefs.cachesize)
905 				uae_int_requested |= 0x010000;
906 			uae_ppc_wakeup_main();
907 		} else {
908 			uae_int_requested &= ~0x010000;
909 		}
910 #ifdef WITH_PPC
911 		check_ppc_int_lvl();
912 		ppc_interrupt(intlev());
913 #endif
914 	}
915 }
916 
blizzardppc_maprom(void)917 static void blizzardppc_maprom(void)
918 {
919 	if (cpuboard_size <= 2 * 524288)
920 		return;
921 	if (maprom_state) {
922 		map_banks(&blizzardmaprom2_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
923 	} else {
924 		map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
925 	}
926 }
cyberstorm_maprom(void)927 static void cyberstorm_maprom(void)
928 {
929 #ifdef FSUAE
930 	write_log("cyberstorm_maprom\n");
931 #endif
932 	if (a3000hmem_bank.allocated <= 2 * 524288)
933 		return;
934 	if (maprom_state && is_ppc()) {
935 #ifdef FSUAE
936 		write_log("map_banks(&blizzardmaprom2_bank\n");
937 #endif
938 		map_banks(&blizzardmaprom2_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
939 	} else {
940 		map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
941 	}
942 #ifdef FSUAE
943 	write_log("cyberstorm_maprom (done)\n");
944 #endif
945 }
946 
cyberstormmk2_maprom(void)947 static void cyberstormmk2_maprom(void)
948 {
949 	if (maprom_state)
950 		map_banks_nojitdirect(&blizzardmaprom_bank, blizzardmaprom_bank.start >> 16, 524288 >> 16, 0);
951 }
952 
cyberstorm_mk3_ppc_irq(int level)953 void cyberstorm_mk3_ppc_irq(int level)
954 {
955 	if (level)
956 		io_reg[CSIII_REG_IRQ] &= ~P5_IRQ_SCSI;
957 	else
958 		io_reg[CSIII_REG_IRQ] |= P5_IRQ_SCSI;
959 	cpuboard_rethink();
960 }
961 
blizzardppc_irq(int level)962 void blizzardppc_irq(int level)
963 {
964 	if (level)
965 		io_reg[CSIII_REG_IRQ] &= ~P5_IRQ_SCSI;
966 	else
967 		io_reg[CSIII_REG_IRQ] |= P5_IRQ_SCSI;
968 	cpuboard_rethink();
969 }
970 
blizzardio_bget(uaecptr addr)971 static uae_u32 REGPARAM2 blizzardio_bget(uaecptr addr)
972 {
973 	uae_u8 v = 0;
974 	//write_log(_T("CS IO XBGET %08x=%02X PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
975 	if (is_csmk3() || is_blizzardppc()) {
976 		uae_u32 bank = addr & 0x10000;
977 		if (bank == 0) {
978 			int reg = (addr & 0xff) / 8;
979 			v = io_reg[reg];
980 			if (reg == CSIII_REG_LOCK) {
981 				v &= 0x01;
982 				v |= 0x10;
983 				if (is_blizzardppc())
984 					v |= 0x08; // BPPC identification
985 			} else if (reg == CSIII_REG_IRQ)  {
986 				v &= 0x3f;
987 			} else if (reg == CSIII_REG_INT) {
988 				v |= 0x40 | 0x10;
989 			} else if (reg == CSIII_REG_SHADOW) {
990 				v |= 0x08;
991 			} else if (reg == CSIII_REG_RESET) {
992 				v &= 0x1f;
993 			} else if (reg == CSIII_REG_IPL_EMU) {
994 				// PPC not master: m68k IPL = all ones
995 				if (io_reg[CSIII_REG_INT] & P5_INT_MASTER)
996 					v |= P5_M68k_IPL_MASK;
997 			}
998 #if CPUBOARD_IO_LOG > 0
999 			if (reg != CSIII_REG_IRQ || CPUBOARD_IO_LOG > 2)
1000 				write_log(_T("CS IO BGET %08x=%02X PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
1001 #endif
1002 		} else {
1003 #if CPUBOARD_IO_LOG > 0
1004 			write_log(_T("CS IO BGET %08x=%02X PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
1005 #endif
1006 		}
1007 	}
1008 	return v;
1009 }
blizzardio_wget(uaecptr addr)1010 static uae_u32 REGPARAM2 blizzardio_wget(uaecptr addr)
1011 {
1012 	if (is_csmk3() || is_blizzardppc()) {
1013 		;//write_log(_T("CS IO WGET %08x\n"), addr);
1014 		//activate_debugger();
1015 	} else if (is_aca500()) {
1016 		addr &= 0x3f000;
1017 		switch (addr)
1018 		{
1019 			case 0x03000:
1020 			return 0;
1021 			case 0x07000:
1022 			return 0;
1023 			case 0x0b000:
1024 			return 0;
1025 			case 0x0f000:
1026 			return 0;
1027 			case 0x13000:
1028 			return 0;
1029 			case 0x17000:
1030 			return 0;
1031 			case 0x1b000:
1032 			return 0x8000;
1033 			case 0x1f000:
1034 			return 0x8000;
1035 			case 0x23000:
1036 			return 0;
1037 			case 0x27000:
1038 			return 0;
1039 			case 0x2b000:
1040 			return 0;
1041 			case 0x2f000:
1042 			return 0;
1043 			case 0x33000:
1044 			return 0x8000;
1045 			case 0x37000:
1046 			return 0;
1047 			case 0x3b000:
1048 			return 0;
1049 		}
1050 	}
1051 	return 0;
1052 }
blizzardio_lget(uaecptr addr)1053 static uae_u32 REGPARAM2 blizzardio_lget(uaecptr addr)
1054 {
1055 	write_log(_T("CS IO LGET %08x PC=%08x\n"), addr, M68K_GETPC);
1056 	if (is_blizzard2060() && mapromconfigured()) {
1057 		if (addr & 0x10000000) {
1058 			maprom_state = 0;
1059 		} else {
1060 			maprom_state = 1;
1061 		}
1062 	}
1063 	return 0;
1064 }
blizzardio_bput(uaecptr addr,uae_u32 v)1065 static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
1066 {
1067 #if CPUBOARD_IO_LOG > 1
1068 	write_log(_T("CS IO XBPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
1069 #endif
1070 	if (is_fusionforty()) {
1071 		write_log(_T("FusionForty IO XBPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
1072 	} else if (is_csmk2()) {
1073 		csmk2_flashaddressing = addr & 3;
1074 		if (addr == 0x880000e3 && v == 0x2a) {
1075 			maprom_state = 1;
1076 			write_log(_T("CSMKII: MAPROM enabled\n"));
1077 			cyberstormmk2_copymaprom();
1078 		}
1079 	} else if (is_blizzard()) {
1080 		if ((addr & 65535) == (BLIZZARD_MAPROM_ENABLE & 65535)) {
1081 			if (v != 0x42 || maprom_state || !mapromconfigured())
1082 				return;
1083 			maprom_state = 1;
1084 			write_log(_T("Blizzard: MAPROM enabled\n"));
1085 			blizzard_copymaprom();
1086 		}
1087 	} else if (is_csmk3() || is_blizzardppc()) {
1088 #if CPUBOARD_IO_LOG > 0
1089 		write_log(_T("CS IO BPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
1090 #endif
1091 		uae_u32 bank = addr & 0x10000;
1092 		if (bank == 0) {
1093 			addr &= 0xff;
1094 			if (is_blizzardppc()) {
1095 				if (addr == BPPC_UNLOCK_FLASH && v == BPPC_MAGIC_UNLOCK_VALUE) {
1096 					flash_unlocked = 1;
1097 					write_log(_T("BPPC: flash unlocked\n"));
1098 				} else 	if (addr == BPPC_LOCK_FLASH) {
1099 					flash_unlocked = 0;
1100 					write_log(_T("BPPC: flash locked\n"));
1101 				} else if (addr == BPPC_MAPROM_ON) {
1102 					write_log(_T("BPPC: maprom enabled\n"));
1103 					maprom_state = 1;
1104 					cyberstorm_copymaprom();
1105 					blizzardppc_maprom();
1106 				} else if (addr == BPPC_MAPROM_OFF) {
1107 					write_log(_T("BPPC: maprom disabled\n"));
1108 					maprom_state = 0;
1109 					blizzardppc_maprom();
1110 					cyberstorm_copymaprom();
1111 				}
1112 			}
1113 			addr /= 8;
1114 			uae_u8 oldval = io_reg[addr];
1115 			if (addr == CSIII_REG_LOCK) {
1116 				uae_u8 regval = io_reg[CSIII_REG_LOCK] & 0x0f;
1117 				if (v == P5_MAGIC1)
1118 					regval |= P5_MAGIC1;
1119 				else if ((v & 0x70) == P5_MAGIC2 && (io_reg[CSIII_REG_LOCK] & 0x70) == P5_MAGIC1)
1120 					regval |= P5_MAGIC2;
1121 				else if ((v & 0x70) == P5_MAGIC3 && (io_reg[CSIII_REG_LOCK] & 0x70) == P5_MAGIC2)
1122 					regval |= P5_MAGIC3;
1123 				else if ((v & 0x70) == P5_MAGIC4 && (io_reg[CSIII_REG_LOCK] & 0x70) == P5_MAGIC3)
1124 					regval |= P5_MAGIC4;
1125 				if ((regval & 0x70) == P5_MAGIC3)
1126 					flash_unlocked = 1;
1127 				else
1128 					flash_unlocked &= ~2;
1129 				if (v & P5_LOCK_CPU) {
1130 					if (v & 0x80) {
1131 #ifdef WITH_PPC
1132 						if (uae_ppc_cpu_unlock())
1133 #endif
1134 							regval |= P5_LOCK_CPU;
1135 					} else {
1136 #ifdef WITH_PPC
1137 						if (!(regval & P5_LOCK_CPU))
1138 							uae_ppc_cpu_lock();
1139 #endif
1140 						regval &= ~P5_LOCK_CPU;
1141 					}
1142 #if CPUBOARD_IO_LOG > 0
1143 					write_log(_T("CSIII_REG_LOCK bit 0 = %d!\n"), (v & 0x80) ? 1 : 0);
1144 #endif
1145 				}
1146 				io_reg[CSIII_REG_LOCK] = regval;
1147 			} else {
1148 				uae_u32 regval;
1149 				// reg shadow is only writable if unlock sequence is active
1150 				if (addr == CSIII_REG_SHADOW) {
1151 					if (v & 2) {
1152 						// for some reason this unknown bit can be modified even when locked
1153 						io_reg[CSIII_REG_LOCK] &= ~2;
1154 						if (v & 0x80)
1155 							io_reg[CSIII_REG_LOCK] |= 2;
1156 					}
1157 					if ((io_reg[CSIII_REG_LOCK] & 0x70) != P5_MAGIC3)
1158 						return;
1159 				}
1160 				if (v & 0x80)
1161 					io_reg[addr] |= v & 0x7f;
1162 				else
1163 					io_reg[addr] &= ~v;
1164 				regval = io_reg[addr];
1165 				if (addr == CSIII_REG_RESET) {
1166 					map_banks(&dummy_bank, 0xf00000 >> 16, 0x80000 >> 16, 0);
1167 					map_banks(&blizzardio_bank, 0xf60000 >> 16, 0x10000 >> 16, 0);
1168 					if (regval & P5_SCSI_RESET) {
1169 						if ((regval & P5_SCSI_RESET) != (oldval & P5_SCSI_RESET))
1170 							write_log(_T("CS: SCSI reset cleared\n"));
1171 						map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x40000 >> 16, 0);
1172 						if (is_blizzardppc() || flash_size(flashrom) >= 262144) {
1173 							map_banks(&ncr_bank_generic, 0xf40000 >> 16, 0x10000 >> 16, 0);
1174 						} else {
1175 							map_banks(&ncr_bank_cyberstorm, 0xf40000 >> 16, 0x10000 >> 16, 0);
1176 							map_banks(&blizzardio_bank, 0xf50000 >> 16, 0x10000 >> 16, 0);
1177 						}
1178 					} else {
1179 						if ((regval & P5_SCSI_RESET) != (oldval & P5_SCSI_RESET))
1180 							write_log(_T("CS: SCSI reset\n"));
1181 						map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x60000 >> 16, 0);
1182 					}
1183 					if (!(io_reg[CSIII_REG_SHADOW] & P5_SELF_RESET) || uae_self_is_ppc() == false) {
1184 						if ((oldval & P5_PPC_RESET) && !(regval & P5_PPC_RESET)) {
1185 #ifdef WITH_PPC
1186 							uae_ppc_cpu_stop();
1187 #endif
1188 						} else if (!(oldval & P5_PPC_RESET) && (regval & P5_PPC_RESET)) {
1189 #ifdef WITH_PPC
1190 							uae_ppc_cpu_reboot();
1191 #endif
1192 						}
1193 					} else {
1194 						io_reg[CSIII_REG_RESET] &= ~P5_PPC_RESET;
1195 						io_reg[CSIII_REG_RESET] |= oldval & P5_PPC_RESET;
1196 					}
1197 					if (!(io_reg[CSIII_REG_SHADOW] & P5_SELF_RESET) || uae_self_is_ppc() == true) {
1198 						if ((regval & P5_M68K_RESET) && !(oldval & P5_M68K_RESET)) {
1199 							m68k_reset();
1200 							write_log(_T("CS: M68K Reset\n"));
1201 						} else if (!(regval & P5_M68K_RESET) && (oldval & P5_M68K_RESET)) {
1202 							write_log(_T("CS: M68K Halted\n"));
1203 							if (!(regval & P5_PPC_RESET)) {
1204 								write_log(_T("CS: PPC is also halted. STOP.\n"));
1205 								cpu_halt(CPU_HALT_ALL_CPUS_STOPPED);
1206 							} else {
1207 								// halt 68k, leave ppc message processing active.
1208 								cpu_halt(CPU_HALT_PPC_ONLY);
1209 							}
1210 						}
1211 					} else {
1212 						io_reg[CSIII_REG_RESET] &= ~P5_M68K_RESET;
1213 						io_reg[CSIII_REG_RESET] |= oldval & P5_M68K_RESET;
1214 					}
1215 					if (!(io_reg[CSIII_REG_SHADOW] & P5_SELF_RESET)) {
1216 						if (!(regval & P5_AMIGA_RESET)) {
1217 #ifdef WITH_PPC
1218 							uae_ppc_cpu_stop();
1219 #endif
1220 							uae_reset(0, 0);
1221 							write_log(_T("CS: Amiga Reset\n"));
1222 							io_reg[addr] |= P5_AMIGA_RESET;
1223 						}
1224 					} else {
1225 						io_reg[CSIII_REG_RESET] &= ~P5_AMIGA_RESET;
1226 						io_reg[CSIII_REG_RESET] |= oldval & P5_AMIGA_RESET;
1227 					}
1228 				} else if (addr == CSIII_REG_IPL_EMU) {
1229 					// M68K_IPL_MASK is read-only
1230 					regval &= ~P5_M68k_IPL_MASK;
1231 					regval |= oldval & P5_M68k_IPL_MASK;
1232 					bool active = (regval & P5_DISABLE_INT) == 0;
1233 					if (!active) {
1234 #ifdef WITH_PPC
1235 						clear_ppc_interrupt();
1236 #endif
1237 					}
1238 					io_reg[addr] = regval;
1239 #if CPUBOARD_IRQ_LOG > 0
1240 					if ((regval & P5_DISABLE_INT) != (oldval & P5_DISABLE_INT))
1241 						write_log(_T("CS: interrupt state: %s\n"), (regval & P5_DISABLE_INT) ? _T("disabled") : _T("enabled"));
1242 					if ((regval & P5_PPC_IPL_MASK) != (oldval & P5_PPC_IPL_MASK))
1243 						write_log(_T("CS: PPC IPL %02x\n"), (~regval) & P5_PPC_IPL_MASK);
1244 #endif
1245 				} else if (addr == CSIII_REG_INT) {
1246 #if CPUBOARD_IRQ_LOG > 0
1247 					if ((regval & P5_INT_MASTER) != (oldval & P5_INT_MASTER))
1248 						write_log(_T("CS: interrupt master: %s\n"), (regval & P5_INT_MASTER) ? _T("m68k") : _T("ppc"));
1249 					if ((regval & P5_ENABLE_IPL) != (oldval & P5_ENABLE_IPL))
1250 						write_log(_T("CS: IPL state: %s\n"), (regval & P5_ENABLE_IPL) ? _T("disabled") : _T("enabled"));
1251 #endif
1252 				} else if (addr == CSIII_REG_INT_LVL) {
1253 #if CPUBOARD_IRQ_LOG > 0
1254 					if (regval != oldval)
1255 						write_log(_T("CS: interrupt level: %02x\n"), regval);
1256 #endif
1257 				} else if (addr == CSIII_REG_IRQ) {
1258 #if CPUBOARD_IRQ_LOG > 0
1259 					if (regval != oldval)
1260 						write_log(_T("CS: IRQ: %02x\n"), regval);
1261 #endif
1262 				} else if (addr == CSIII_REG_SHADOW) {
1263 					if (is_csmk3() && ((oldval ^ regval) & 1)) {
1264 						maprom_state = (regval & 1) ? 0 : 1;
1265 						write_log(_T("CyberStorm MAPROM = %d\n"), maprom_state);
1266 						cyberstorm_copymaprom();
1267 						cyberstorm_maprom();
1268 					}
1269 					if ((regval & P5_FLASH) != (oldval & P5_FLASH)) {
1270 						flash_unlocked = (regval & P5_FLASH) ? 0 : 1;
1271 						write_log(_T("CS: Flash writable = %d\n"), flash_unlocked);
1272 					}
1273 //					if ((oldval ^ regval) & 7) {
1274 //						activate_debugger();
1275 //					}
1276 				}
1277 				cpuboard_rethink();
1278 			}
1279 		}
1280 	}
1281 }
blizzardio_wput(uaecptr addr,uae_u32 v)1282 static void REGPARAM2 blizzardio_wput(uaecptr addr, uae_u32 v)
1283 {
1284 	if (is_fusionforty()) {
1285 		write_log(_T("FusionForty IO WPUT %08x %04x\n"), addr, v);
1286 	} else if (is_blizzard()) {
1287 		write_log(_T("CS IO WPUT %08x %04x\n"), addr, v);
1288 		if((addr & 65535) == (BLIZZARD_BOARD_DISABLE & 65535)) {
1289 			if (v != 0xcafe)
1290 				return;
1291 			write_log(_T("Blizzard: board disable!\n"));
1292 			cpu_halt(CPU_HALT_ACCELERATOR_CPU_FALLBACK); // not much choice..
1293 		}
1294 	} else if (is_csmk3() || is_blizzardppc()) {
1295 		write_log(_T("CS IO WPUT %08x %04x\n"), addr, v);
1296 	} else if (is_csmk2()) {
1297 		write_log(_T("CS IO WPUT %08x %04x\n"), addr, v);
1298 		if (addr == CSMK2_BOARD_DISABLE) {
1299 			if (v != 0xcafe)
1300 				return;
1301 			write_log(_T("CSMK2: board disable!\n"));
1302 			cpu_halt(CPU_HALT_ACCELERATOR_CPU_FALLBACK); // not much choice..
1303 		}
1304 	}
1305 }
blizzardio_lput(uaecptr addr,uae_u32 v)1306 static void REGPARAM2 blizzardio_lput(uaecptr addr, uae_u32 v)
1307 {
1308 	write_log(_T("CS IO LPUT %08x %08x\n"), addr, v);
1309 	if (is_csmk1()) {
1310 		if (addr == 0x80f80000) {
1311 			maprom_state = 1;
1312 			cyberstormmk1_copymaprom();
1313 		}
1314 	}
1315 	if (is_blizzard2060() && mapromconfigured()) {
1316 		if (addr & 0x10000000) {
1317 			maprom_state = 0;
1318 		} else {
1319 			maprom_state = 1;
1320 		}
1321 	}
1322 }
1323 
cpuboard_hsync(void)1324 void cpuboard_hsync(void)
1325 {
1326 	// we should call check_ppc_int_lvl() immediately
1327 	// after PPC CPU's interrupt flag is cleared but this
1328 	// should be fast enough for now
1329 	if (is_csmk3() || is_blizzardppc()) {
1330 #ifdef WITH_PPC
1331 		check_ppc_int_lvl();
1332 #endif
1333 	}
1334 }
1335 
cpuboard_vsync(void)1336 void cpuboard_vsync(void)
1337 {
1338 	if (delayed_rom_protect <= 0)
1339 		return;
1340 	delayed_rom_protect--;
1341 	if (delayed_rom_protect == 0)
1342 		protect_roms(true);
1343 }
1344 
cpuboard_map(void)1345 void cpuboard_map(void)
1346 {
1347 #ifdef FSUAE
1348     write_log("cpuboard_map currprefs.cpuboard_type = %d\n", currprefs.cpuboard_type);
1349 #endif
1350 	if (!currprefs.cpuboard_type)
1351 		return;
1352 	if (is_blizzard() || is_blizzardppc()) {
1353 #ifdef FSUAE
1354     write_log("is_blizzard() || is_blizzardppc() -> cpuboard_size = %d\n", cpuboard_size);
1355 #endif
1356 		if (cpuboard_size) {
1357 			if (cpuboard_size < 256 * 1024 * 1024) {
1358 				if (blizzard_jit) {
1359 					map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
1360 					map_banks(&blizzardram_bank, BLIZZARD_RAM_BASE_68 >> 16, cpuboard_size >> 16, 0);
1361 				} else {
1362 					for (int i = 0; i < 0x08000000; i += cpuboard_size) {
1363 						map_banks_nojitdirect(&blizzardram_nojit_bank, (BLIZZARD_RAM_BASE_48 + i)  >> 16, cpuboard_size >> 16, 0);
1364 						map_banks_nojitdirect(&blizzardram_nojit_bank, (BLIZZARD_RAM_BASE_68 + i) >> 16, cpuboard_size >> 16, 0);
1365 					}
1366 					if (mapromconfigured() && !is_blizzardppc()) {
1367 						for (int i = 0; i < 0x08000000; i += cpuboard_size) {
1368 							map_banks_nojitdirect(&blizzardmaprom_bank, (BLIZZARD_RAM_BASE_48 + i + cpuboard_size - 524288) >> 16, 524288 >> 16, 0);
1369 							map_banks_nojitdirect(&blizzardmaprom_bank, (BLIZZARD_RAM_BASE_68 + i + cpuboard_size - 524288) >> 16, 524288 >> 16, 0);
1370 						}
1371 					}
1372 				}
1373 			} else {
1374 				map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
1375 			}
1376 		}
1377 		if (!is_blizzardppc()) {
1378 			map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
1379 			map_banks(&blizzardio_bank, BLIZZARD_MAPROM_ENABLE >> 16, 65536 >> 16, 0);
1380 			map_banks(&blizzardio_bank, BLIZZARD_BOARD_DISABLE >> 16, 65536 >> 16, 0);
1381 		} else {
1382 			map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x60000 >> 16, 0);
1383 			map_banks(&blizzardio_bank, 0xf60000 >> 16, (2 * 65536) >> 16, 0);
1384 			blizzardppc_maprom();
1385 		}
1386 	}
1387 	if (is_csmk3()) {
1388 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x40000 >> 16, 0);
1389 		map_banks(&blizzardio_bank, 0xf50000 >> 16, (3 * 65536) >> 16, 0);
1390 		cyberstorm_maprom();
1391 	}
1392 	if (is_csmk2()) {
1393 		map_banks(&blizzardio_bank, 0x88000000 >> 16, 65536 >> 16, 0);
1394 		map_banks(&blizzardio_bank, 0x83000000 >> 16, 65536 >> 16, 0);
1395 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
1396 		cyberstormmk2_maprom();
1397 	}
1398 	if (is_csmk1()) {
1399 		map_banks(&blizzardio_bank, 0x80f80000 >> 16, 65536 >> 16, 0);
1400 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
1401 		map_banks(&blizzardmaprom_bank, 0x07f80000 >> 16, 524288 >> 16, 0);
1402 	}
1403 	if (is_blizzard2060()) {
1404 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
1405 		map_banks(&blizzardio_bank, 0x80000000 >> 16, 0x10000000 >> 16, 0);
1406 		if (mapromconfigured())
1407 			map_banks_nojitdirect(&blizzardmaprom_bank, (a3000hmem_bank.start + a3000hmem_bank.allocated - 524288) >> 16, 524288 >> 16, 0);
1408 	}
1409 	if (is_tekmagic()) {
1410 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0);
1411 		map_banks(&blizzardea_bank, 0xf40000 >> 16, 65536 >> 16, 0);
1412 	}
1413 	if (is_fusionforty()) {
1414 		map_banks(&blizzardf0_bank, 0x00f40000 >> 16, 131072 >> 16, 0);
1415 		map_banks(&blizzardf0_bank, 0x05000000 >> 16, 131072 >> 16, 0);
1416 		map_banks(&blizzardio_bank, 0x021d0000 >> 16, 65536 >> 16, 0);
1417 		map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
1418 	}
1419 	if (is_apollo()) {
1420 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0);
1421 	}
1422 	if (is_dkb_wildfire()) {
1423 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x80000 >> 16, 0);
1424 	}
1425 	if (is_dkb_12x0()) {
1426 		if (cpuboard_size >= 4 * 1024 * 1024) {
1427 			if (cpuboard_size <= 0x4000000) {
1428 				map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, 0x4000000 >> 16, cpuboard_size >> 16);
1429 			} else {
1430 				map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
1431 			}
1432 		}
1433 	}
1434 	if (is_aca500()) {
1435 		map_banks(&blizzardf0_bank, 0xf00000 >> 16, 524288 >> 16, 0);
1436 		map_banks(&blizzardf0_bank, 0xa00000 >> 16, 524288 >> 16, 0);
1437 		map_banks(&blizzardio_bank, 0xb00000 >> 16, 262144 >> 16, 0);
1438 	}
1439 }
1440 
cpuboard_reset(void)1441 void cpuboard_reset(void)
1442 {
1443 	bool hardreset = is_hardreset();
1444 	if (is_blizzard() || is_blizzardppc())
1445 		canbang = 0;
1446 	configured = false;
1447 	delayed_rom_protect = 0;
1448 	currprefs.cpuboardmem1_size = changed_prefs.cpuboardmem1_size;
1449 	if (hardreset || (!mapromconfigured() && (is_blizzard() || is_blizzard2060())))
1450 		maprom_state = 0;
1451 	if (is_csmk3() || is_blizzardppc()) {
1452 		if (hardreset)
1453 			memset(io_reg, 0x7f, sizeof io_reg);
1454 		io_reg[CSIII_REG_RESET] = 0x7f;
1455 		io_reg[CSIII_REG_IRQ] = 0x7f;
1456 		io_reg[CSIII_REG_IPL_EMU] = 0x40;
1457 		io_reg[CSIII_REG_LOCK] = 0x01;
1458 	}
1459 	if (hardreset || is_keyboardreset())
1460 		a2630_io = 0;
1461 	flash_unlocked = 0;
1462 	cpuboard_non_byte_ea = false;
1463 
1464 	flash_free(flashrom);
1465 	flashrom = NULL;
1466 	flash_free(flashrom2);
1467 	flashrom2 = NULL;
1468 	zfile_fclose(flashrom_file);
1469 	flashrom_file = NULL;
1470 }
1471 
cpuboard_cleanup(void)1472 void cpuboard_cleanup(void)
1473 {
1474 	configured = false;
1475 	maprom_state = 0;
1476 
1477 	flash_free(flashrom);
1478 	flashrom = NULL;
1479 	flash_free(flashrom2);
1480 	flashrom2 = NULL;
1481 	zfile_fclose(flashrom_file);
1482 	flashrom_file = NULL;
1483 
1484 	if (blizzard_jit) {
1485 		mapped_free(&blizzardram_bank);
1486 	} else {
1487 		if (blizzardram_nojit_bank.baseaddr) {
1488 #ifdef CPU_64_BIT
1489 			uae_vm_free(blizzardram_nojit_bank.baseaddr, blizzardram_nojit_bank.allocated);
1490 #else
1491 			xfree(blizzardram_nojit_bank.baseaddr);
1492 #endif
1493 		}
1494 	}
1495 	if (blizzardmaprom_bank_mapped)
1496 		mapped_free(&blizzardmaprom_bank);
1497 	if (blizzardmaprom2_bank_mapped)
1498 		mapped_free(&blizzardmaprom2_bank);
1499 
1500 	blizzardram_bank.baseaddr = NULL;
1501 	blizzardram_nojit_bank.baseaddr = NULL;
1502 	blizzardmaprom_bank.baseaddr = NULL;
1503 	blizzardmaprom2_bank.baseaddr = NULL;
1504 	blizzardmaprom_bank_mapped = false;
1505 	blizzardmaprom2_bank_mapped = false;
1506 
1507 	mapped_free(&blizzardf0_bank);
1508 	blizzardf0_bank.baseaddr = NULL;
1509 
1510 	mapped_free(&blizzardea_bank);
1511 	blizzardea_bank.baseaddr = NULL;
1512 
1513 	cpuboard_size = cpuboard2_size = -1;
1514 
1515 	blizzardmaprom_bank.flags &= ~(ABFLAG_INDIRECT | ABFLAG_NOALLOC);
1516 	blizzardmaprom2_bank.flags &= ~(ABFLAG_INDIRECT | ABFLAG_NOALLOC);
1517 }
1518 
cpuboard_init(void)1519 void cpuboard_init(void)
1520 {
1521 	if (!currprefs.cpuboard_type)
1522 		return;
1523 
1524 	if (cpuboard_size == currprefs.cpuboardmem1_size)
1525 		return;
1526 
1527 	cpuboard_cleanup();
1528 
1529 	cpuboard_size = currprefs.cpuboardmem1_size;
1530 
1531 	if (is_kupke() || is_mtec_ematrix530() || is_sx32pro()) {
1532 		// plain 64k autoconfig, nothing else.
1533 		blizzardea_bank.allocated = 65536;
1534 		blizzardea_bank.mask = blizzardea_bank.allocated - 1;
1535 		mapped_malloc(&blizzardea_bank);
1536 
1537 	} else if (is_aca500()) {
1538 
1539 		blizzardf0_bank.start = 0x00f00000;
1540 		blizzardf0_bank.allocated = 524288;
1541 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1542 		mapped_malloc(&blizzardf0_bank);
1543 
1544 	} else if (is_a2630()) {
1545 
1546 		blizzardf0_bank.start = 0x00f00000;
1547 		blizzardf0_bank.allocated = 131072;
1548 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1549 		mapped_malloc(&blizzardf0_bank);
1550 
1551 		blizzardea_bank.allocated = 65536;
1552 		blizzardea_bank.mask = blizzardea_bank.allocated - 1;
1553 		mapped_malloc(&blizzardea_bank);
1554 
1555 	}
1556 	else if (is_dkb_12x0()) {
1557 
1558 		blizzardram_bank.start = 0x10000000;
1559 		blizzardram_bank.allocated = cpuboard_size;
1560 		blizzardram_bank.mask = blizzardram_bank.allocated - 1;
1561 		blizzardram_bank.startmask = 0x10000000;
1562 		blizzardram_bank.label = _T("dkb");
1563 		mapped_malloc(&blizzardram_bank);
1564 
1565 	} else if (is_dkb_wildfire()) {
1566 
1567 		blizzardf0_bank.start = 0x00f00000;
1568 		blizzardf0_bank.allocated = 65536;
1569 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1570 		mapped_malloc(&blizzardf0_bank);
1571 
1572 	} else if (is_apollo()) {
1573 
1574 		blizzardf0_bank.start = 0x00f00000;
1575 		blizzardf0_bank.allocated = 131072;
1576 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1577 		mapped_malloc(&blizzardf0_bank);
1578 
1579 	} else if (is_fusionforty()) {
1580 
1581 		blizzardf0_bank.start = 0x00f40000;
1582 		blizzardf0_bank.allocated = 262144;
1583 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1584 		mapped_malloc(&blizzardf0_bank);
1585 
1586 		blizzardram_bank.start = 0x11000000;
1587 		blizzardram_bank.allocated = cpuboard_size;
1588 		blizzardram_bank.mask = blizzardram_bank.allocated - 1;
1589 		blizzardram_bank.startmask = 0x11000000;
1590 		blizzardram_bank.label = _T("fusionforty");
1591 		mapped_malloc(&blizzardram_bank);
1592 
1593 	} else if (is_tekmagic()) {
1594 
1595 		blizzardf0_bank.start = 0x00f00000;
1596 		blizzardf0_bank.allocated = 131072;
1597 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1598 		mapped_malloc(&blizzardf0_bank);
1599 
1600 		blizzardea_bank.allocated = 65536;
1601 		blizzardea_bank.mask = blizzardea_bank.allocated - 1;
1602 		mapped_malloc(&blizzardea_bank);
1603 
1604 	} else if (is_blizzard() || is_blizzardppc()) {
1605 retry:
1606 		cpuboard_size = currprefs.cpuboardmem1_size;
1607 		if (cpuboard_size < 256 * 1024 * 1024) {
1608 			blizzardram_bank.start = BLIZZARD_RAM_BASE_48;
1609 			blizzardram_bank.allocated = cpuboard_size;
1610 			blizzardram_bank.mask = blizzardram_bank.allocated - 1;
1611 			blizzardram_bank.startmask = BLIZZARD_RAM_BASE_68;
1612 		} else if (currprefs.z3autoconfig_start <= 0x10000000) {
1613 			blizzardram_bank.start = BLIZZARD_RAM_256M_BASE_40;
1614 			blizzardram_bank.allocated = cpuboard_size;
1615 			blizzardram_bank.mask = blizzardram_bank.allocated - 1;
1616 			blizzardram_bank.startmask = BLIZZARD_RAM_256M_BASE_40;
1617 		} else {
1618 			blizzardram_bank.start = BLIZZARD_RAM_256M_BASE_70;
1619 			blizzardram_bank.allocated = cpuboard_size;
1620 			blizzardram_bank.mask = blizzardram_bank.allocated - 1;
1621 			blizzardram_bank.startmask = BLIZZARD_RAM_256M_BASE_70;
1622 		}
1623 
1624 		blizzardram_nojit_bank.start = blizzardram_bank.start;
1625 		blizzardram_nojit_bank.allocated = blizzardram_bank.allocated;
1626 		blizzardram_nojit_bank.mask = blizzardram_bank.mask;
1627 		blizzardram_nojit_bank.startmask = blizzardram_bank.startmask;
1628 
1629 		blizzard_jit = cpuboard_jitdirectompatible(&currprefs);
1630 		if (blizzard_jit) {
1631 			if (cpuboard_size) {
1632 				if (cpuboard_size < 256 * 1024 * 1024)
1633 					blizzardram_bank.label = _T("blizzard");
1634 				else
1635 					blizzardram_bank.label = _T("blizzard_70");
1636 				mapped_malloc(&blizzardram_bank);
1637 			}
1638 		} else {
1639 			if (cpuboard_size) {
1640 #ifdef CPU_64_BIT
1641 				int vm_flags = UAE_VM_32BIT;
1642 #ifdef FSUAE
1643 				if (!g_fs_uae_jit_compiler) {
1644 					/* Not using the JIT compiler, so we do not need "32-bit memory". */
1645 					vm_flags &= ~UAE_VM_32BIT;
1646 				}
1647 #endif
1648 				blizzardram_bank.baseaddr = (uae_u8 *) uae_vm_alloc(
1649 					blizzardram_bank.allocated, vm_flags, UAE_VM_READ_WRITE);
1650 #else
1651 				blizzardram_bank.baseaddr = xmalloc(uae_u8, blizzardram_bank.allocated);
1652 				if (!blizzardram_bank.baseaddr) {
1653 					write_log(_T("MMAN: blizzardram_bank %d MB allocation failed\n"), blizzardram_bank.allocated / (1024 * 1024));
1654 					if (currprefs.cpuboardmem1_size > 16 * 1024 * 1024) {
1655 						currprefs.cpuboardmem1_size /= 2;
1656 						changed_prefs.cpuboardmem1_size = currprefs.cpuboardmem1_size;
1657 						goto retry;
1658 					}
1659 				}
1660 #endif
1661 				write_log(_T("MMAN: Allocated %d bytes (%d MB) for blizzardram_bank at %p\n"),
1662 						  blizzardram_bank.allocated,
1663 						  blizzardram_bank.allocated / (1024 * 1024),
1664 						  blizzardram_bank.baseaddr);
1665 			}
1666 		}
1667 		blizzardram_nojit_bank.baseaddr = blizzardram_bank.baseaddr;
1668 
1669 		maprom_base = blizzardram_bank.allocated - 524288;
1670 
1671 		blizzardf0_bank.start = 0x00f00000;
1672 		blizzardf0_bank.allocated = 524288;
1673 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1674 		mapped_malloc(&blizzardf0_bank);
1675 
1676 		if (!is_blizzardppc()) {
1677 			blizzardea_bank.allocated = 2 * 65536;
1678 			blizzardea_bank.mask = blizzardea_bank.allocated - 1;
1679 			// Blizzard 12xx autoconfig ROM must be mapped at $ea0000-$ebffff, board requires it.
1680 			mapped_malloc(&blizzardea_bank);
1681 		}
1682 
1683 		if (cpuboard_size > 2 * 524288) {
1684 			if (!is_blizzardppc()) {
1685 				blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288;
1686 				blizzardmaprom_bank.start = BLIZZARD_MAPROM_BASE;
1687 				blizzardmaprom_bank.allocated = 524288;
1688 				blizzardmaprom_bank.mask = 524288 - 1;
1689 				blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
1690 				mapped_malloc(&blizzardmaprom_bank);
1691 				blizzardmaprom_bank_mapped = true;
1692 			} else {
1693 				blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288;
1694 				blizzardmaprom_bank.start = CYBERSTORM_MAPROM_BASE;
1695 				blizzardmaprom_bank.allocated = 524288;
1696 				blizzardmaprom_bank.mask = 524288 - 1;
1697 				blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
1698 				mapped_malloc(&blizzardmaprom_bank);
1699 				blizzardmaprom_bank_mapped = true;
1700 				blizzardmaprom2_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 2 * 524288;
1701 				blizzardmaprom2_bank.start = CYBERSTORM_MAPROM_BASE;
1702 				blizzardmaprom2_bank.allocated = 524288;
1703 				blizzardmaprom2_bank.mask = 524288 - 1;
1704 				blizzardmaprom2_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
1705 				mapped_malloc(&blizzardmaprom2_bank);
1706 				blizzardmaprom2_bank_mapped = true;
1707 			}
1708 		}
1709 
1710 	} else if (is_csmk1()) {
1711 
1712 		blizzardf0_bank.start = 0x00f00000;
1713 		blizzardf0_bank.allocated = 65536;
1714 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1715 		mapped_malloc(&blizzardf0_bank);
1716 
1717 		blizzardea_bank.allocated = 2 * 65536;
1718 		blizzardea_bank.mask = 65535 - 1;
1719 		mapped_malloc(&blizzardea_bank);
1720 
1721 		blizzardmaprom_bank.allocated = 524288;
1722 		blizzardmaprom_bank.start = 0x07f80000;
1723 		blizzardmaprom_bank.mask = 524288 - 1;
1724 		blizzardmaprom_bank_mapped = true;
1725 		mapped_malloc(&blizzardmaprom_bank);
1726 
1727 	} else if (is_csmk2() || is_blizzard2060()) {
1728 
1729 		blizzardea_bank.allocated = 2 * 65536;
1730 		blizzardea_bank.mask = blizzardea_bank.allocated - 1;
1731 		mapped_malloc(&blizzardea_bank);
1732 
1733 		blizzardf0_bank.start = 0x00f00000;
1734 		blizzardf0_bank.allocated = 65536;
1735 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1736 		mapped_malloc(&blizzardf0_bank);
1737 
1738 		blizzardmaprom_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 524288;
1739 		blizzardmaprom_bank.start = a3000hmem_bank.start + a3000hmem_bank.allocated - 524288;
1740 		blizzardmaprom_bank.allocated = 524288;
1741 		blizzardmaprom_bank.mask = 524288 - 1;
1742 		blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
1743 		mapped_malloc(&blizzardmaprom_bank);
1744 
1745 	} else if (is_csmk3()) {
1746 
1747 		blizzardram_bank.start = CS_RAM_BASE;
1748 		blizzardram_bank.allocated = cpuboard_size;
1749 		blizzardram_bank.mask = blizzardram_bank.allocated - 1;
1750 		if (cpuboard_size) {
1751 			blizzardram_bank.label = _T("cyberstorm");
1752 			mapped_malloc(&blizzardram_bank);
1753 		}
1754 
1755 		blizzardf0_bank.start = 0x00f00000;
1756 		blizzardf0_bank.allocated = 524288;
1757 		blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
1758 		mapped_malloc(&blizzardf0_bank);
1759 
1760 		if (a3000hmem_bank.allocated > 2 * 524288) {
1761 			blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
1762 			blizzardmaprom_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 1 * 524288;
1763 			blizzardmaprom_bank.start = CYBERSTORM_MAPROM_BASE;
1764 			blizzardmaprom_bank.allocated = 524288;
1765 			blizzardmaprom_bank.mask = 524288 - 1;
1766 			mapped_malloc(&blizzardmaprom_bank);
1767 			blizzardmaprom_bank_mapped = true;
1768 			blizzardmaprom2_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
1769 			blizzardmaprom2_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 2 * 524288;
1770 			blizzardmaprom2_bank.start = CYBERSTORM_MAPROM_BASE;
1771 			blizzardmaprom2_bank.allocated = 524288;
1772 			blizzardmaprom2_bank.mask = 524288 - 1;
1773 			mapped_malloc(&blizzardmaprom2_bank);
1774 			blizzardmaprom2_bank_mapped = true;
1775 		}
1776 	}
1777 }
1778 
cpuboard_overlay_override(void)1779 void cpuboard_overlay_override(void)
1780 {
1781 	if (is_a2630()) {
1782 		if (!(a2630_io & 2))
1783 			map_banks(&blizzardf0_bank, 0xf80000 >> 16, f0rom_size >> 16, 0);
1784 		if (mem25bit_bank.allocated)
1785 			map_banks(&chipmem_bank, (mem25bit_bank.start + mem25bit_bank.allocated) >> 16, (1024 * 1024) >> 16, 0);
1786 		else
1787 			map_banks(&chipmem_bank, 0x01000000 >> 16, (1024 * 1024) >> 16, 0);
1788 	}
1789 }
1790 
cpuboard_clear(void)1791 void cpuboard_clear(void)
1792 {
1793 	if (blizzardmaprom_bank.baseaddr)
1794 		memset(blizzardmaprom_bank.baseaddr, 0, 524288);
1795 	if (blizzardmaprom2_bank.baseaddr)
1796 		memset(blizzardmaprom2_bank.baseaddr, 0, 524288);
1797 	if (is_csmk3()) // SCSI RAM
1798 		memset(blizzardf0_bank.baseaddr + 0x40000, 0, 0x10000);
1799 }
1800 
1801 // Adds resource resident that CSPPC/BPPC flash updater checks.
1802 
1803 #define FAKEPPCROM_OFFSET 32
1804 static const uae_u8 fakeppcrom[] = {
1805 	// struct Resident
1806 	0x4a, 0xfc,
1807 	0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET,
1808 	0x00, 0xf0, 0x01, 0x00,
1809 	0x02, 0x01, 0x00, 0x78,
1810 	0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET + 30,
1811 	0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET + 30,
1812 	0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET + 26,
1813 	// moveq #0,d0; rts
1814 	0x70, 0x00, 0x4e, 0x75
1815 };
1816 static const char fakeppcromtxt_cs[] = { "CyberstormPPC.IDTag" };
1817 static const char fakeppcromtxt_bz[] = { "BlizzardPPC.IDTag" };
1818 
makefakeppcrom(uae_u8 * rom,int type)1819 static void makefakeppcrom(uae_u8 *rom, int type)
1820 {
1821 	memcpy(rom + FAKEPPCROM_OFFSET, fakeppcrom, sizeof fakeppcrom);
1822 	const char *txt = type ? fakeppcromtxt_bz : fakeppcromtxt_cs;
1823 	memcpy(rom + FAKEPPCROM_OFFSET + sizeof fakeppcrom, txt, strlen(txt) + 1);
1824 }
1825 
is_ppc_cpu(struct uae_prefs * p)1826 bool is_ppc_cpu(struct uae_prefs *p)
1827 {
1828 	return is_ppc();
1829 }
1830 
cpuboard_maprom(void)1831 bool cpuboard_maprom(void)
1832 {
1833 	if (!currprefs.cpuboard_type || !cpuboard_size)
1834 		return false;
1835 	if (is_blizzard() || is_blizzardppc()) {
1836 		if (maprom_state)
1837 			blizzard_copymaprom();
1838 	} else if (is_csmk3()) {
1839 		if (maprom_state)
1840 			cyberstorm_copymaprom();
1841 	}
1842 	return true;
1843 }
cpuboard_jitdirectompatible(struct uae_prefs * p)1844 bool cpuboard_jitdirectompatible(struct uae_prefs *p)
1845 {
1846 	if (cpuboard_memorytype(p) == BOARD_MEMORY_BLIZZARD_12xx || cpuboard_memorytype(p) == BOARD_MEMORY_BLIZZARD_PPC) {
1847 		return false;
1848 	}
1849 	return true;
1850 }
1851 
cpuboard_32bit(struct uae_prefs * p)1852 bool cpuboard_32bit(struct uae_prefs *p)
1853 {
1854 	int b = cpuboard_memorytype(p);
1855 	if (p->cpuboard_type) {
1856 		if (!(cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype].deviceflags & EXPANSIONTYPE_24BIT))
1857 			return true;
1858 	}
1859 	return b == BOARD_MEMORY_HIGHMEM ||
1860 		b == BOARD_MEMORY_BLIZZARD_12xx ||
1861 		b == BOARD_MEMORY_BLIZZARD_PPC ||
1862 		b == BOARD_MEMORY_Z3 ||
1863 		b == BOARD_MEMORY_25BITMEM ||
1864 		b == BOARD_MEMORY_EMATRIX;
1865 }
1866 
cpuboard_memorytype(struct uae_prefs * p)1867 int cpuboard_memorytype(struct uae_prefs *p)
1868 {
1869 	if (cpuboards[p->cpuboard_type].subtypes)
1870 		return cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype].memorytype;
1871 	return 0;
1872 }
1873 
cpuboard_maxmemory(struct uae_prefs * p)1874 int cpuboard_maxmemory(struct uae_prefs *p)
1875 {
1876 	if (cpuboards[p->cpuboard_type].subtypes)
1877 		return cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype].maxmemory;
1878 	return 0;
1879 }
1880 
cpuboard_setboard(struct uae_prefs * p,int type,int subtype)1881 void cpuboard_setboard(struct uae_prefs *p, int type, int subtype)
1882 {
1883 	p->cpuboard_type = 0;
1884 	p->cpuboard_subtype = 0;
1885 	for (int i = 0; cpuboards[i].name; i++) {
1886 		if (cpuboards[i].id == type) {
1887 			p->cpuboard_type = type;
1888 			if (subtype >= 0)
1889 				p->cpuboard_subtype = subtype;
1890 			return;
1891 		}
1892 	}
1893 }
1894 
cpuboard_get_reset_pc(uaecptr * stack)1895 uaecptr cpuboard_get_reset_pc(uaecptr *stack)
1896 {
1897 	if (is_aca500()) {
1898 		*stack = get_long(0xa00000);
1899 		return get_long(0xa00004);
1900 	} else {
1901 		*stack = get_long(0);
1902 		return get_long(4);
1903 	}
1904 }
1905 
cpuboard_io_special(int addr,uae_u32 * val,int size,bool write)1906 bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write)
1907 {
1908 	addr &= 65535;
1909 	if (write) {
1910 		uae_u16 w = *val;
1911 		if (is_a2630()) {
1912 			if ((addr == 0x0040 && size == 2) || (addr == 0x0041 && size == 1)) {
1913 				write_log(_T("A2630 write %04x PC=%08x\n"), w, M68K_GETPC);
1914 				a2630_io = w;
1915 				// bit 0: unmap 0x000000
1916 				// bit 1: unmap 0xf80000
1917 				if (w & 2) {
1918 					if (currprefs.mmu_model == 68030) {
1919 						// HACK!
1920 						mmu030_fake_prefetch = 0x4ed0;
1921 					}
1922 					map_banks(&kickmem_bank, 0xF8, 8, 0);
1923 					write_log(_T("A2630 boot rom unmapped\n"));
1924 				}
1925 				// bit 2: autoconfig region enable
1926 				if (w & 4) {
1927 					write_log(_T("A2630 Autoconfig enabled\n"));
1928 					expamem_next(NULL, NULL);
1929 				}
1930 				// bit 3: unknown
1931 				// bit 4: 68000 mode
1932 				if (w & 0x10) {
1933 					write_log(_T("A2630 68000 mode!\n"));
1934 					cpu_halt(CPU_HALT_ACCELERATOR_CPU_FALLBACK);
1935 				}
1936 				return true;
1937 			}
1938 		}
1939 		return false;
1940 	} else {
1941 		if (is_a2630()) {
1942 			// osmode (j304)
1943 			if (addr == 0x0c && (a2630_io & 4) == 0) {
1944 				(*val) |= 0x80;
1945 				if (currprefs.cpuboard_settings & 1)
1946 					(*val) &= ~0x80;
1947 				return true;
1948 			}
1949 		}
1950 	}
1951 	return false;
1952 }
1953 
fixserial(uae_u8 * rom,int size)1954 static void fixserial(uae_u8 *rom, int size)
1955 {
1956 	uae_u8 value1 = rom[16];
1957 	uae_u8 value2 = rom[17];
1958 	uae_u8 value3 = rom[18];
1959 	int seroffset = 17, longseroffset = 24;
1960 	uae_u32 serialnum = 0x1234;
1961 	char serial[10];
1962 	int type = -1;
1963 
1964 	if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC)) {
1965 		value1 = 'I';
1966 		value2 = 'D';
1967 		if (currprefs.cpu_model == 68060)
1968 			value3 = 'H';
1969 		else if (currprefs.fpu_model)
1970 			value3 = 'B';
1971 		else
1972 			value3 = 'A';
1973 		seroffset = 19;
1974 		sprintf(serial, "%04X", serialnum);
1975 		type = 1;
1976 	} else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC)) {
1977 		value1 = 'D';
1978 		value2 = 'B';
1979 		sprintf(serial, "%05X", serialnum);
1980 		value3 = 0;
1981 		seroffset = 18;
1982 		type = 0;
1983 	} else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3)) {
1984 		value1 = 'F';
1985 		sprintf(serial, "%05X", serialnum);
1986 		value2 = value3 = 0;
1987 	} else {
1988 		return;
1989 	}
1990 
1991 	rom[16] = value1;
1992 	if (value2)
1993 		rom[17] = value2;
1994 	if (value3)
1995 		rom[18] = value3;
1996 	if (rom[seroffset] == 0) {
1997 		strcpy((char*)rom + seroffset, serial);
1998 		if (longseroffset) {
1999 			rom[longseroffset + 0] = serialnum >> 24;
2000 			rom[longseroffset + 1] = serialnum >> 16;
2001 			rom[longseroffset + 2] = serialnum >>  8;
2002 			rom[longseroffset + 3] = serialnum >>  0;
2003 		}
2004 	}
2005 
2006 	if (type >= 0 && rom[0] == 0 && rom[1] == 0)
2007 		makefakeppcrom(rom, type);
2008 }
2009 
flashfile_open(const TCHAR * name)2010 static struct zfile *flashfile_open(const TCHAR *name)
2011 {
2012 	struct zfile *f;
2013 	TCHAR path[MAX_DPATH];
2014 	bool rw = true;
2015 
2016 	if (name == NULL || !name[0])
2017 		return NULL;
2018 	f = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
2019 	if (f) {
2020 		if (zfile_iscompressed(f)) {
2021 			rw = false;
2022 		} else {
2023 			zfile_fclose(f);
2024 			f = NULL;
2025 		}
2026 	}
2027 	if (!f) {
2028 		rw = true;
2029 		f = zfile_fopen(name, _T("rb+"), ZFD_NONE);
2030 		if (!f) {
2031 			rw = false;
2032 			f = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
2033 			if (!f) {
2034 				fetch_rompath(path, sizeof path / sizeof(TCHAR));
2035 				_tcscat(path, name);
2036 				rw = true;
2037 				f = zfile_fopen(path, _T("rb+"), ZFD_NONE);
2038 				if (!f) {
2039 					rw = false;
2040 					f = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
2041 				}
2042 			}
2043 		}
2044 	}
2045 	if (f) {
2046 		write_log(_T("CPUBoard '%s' flash file '%s' loaded, %s.\n"),
2047 		cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].name,
2048 		name, rw ? _T("RW") : _T("RO"));
2049 	}
2050 	return f;
2051 }
2052 
board_rom_open(int * roms,const TCHAR * name)2053 static struct zfile *board_rom_open(int *roms, const TCHAR *name)
2054 {
2055 	struct zfile *zf = NULL;
2056 #ifdef FSUAE
2057 	write_log("board_rom_open roms=... name=%s\n", name ? name : "(null)");
2058 #endif
2059 	struct romlist *rl = getromlistbyids(roms, name);
2060 	if (rl)
2061 		zf = read_rom(rl->rd);
2062 	if (!zf && name) {
2063 #ifdef FSUAE
2064 	write_log("zfile_fopen %s\n", name);
2065 #endif
2066 		zf = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
2067 		if (zf) {
2068 			return zf;
2069 		}
2070 		TCHAR path[MAX_DPATH];
2071 		fetch_rompath(path, sizeof path / sizeof(TCHAR));
2072 		_tcscat(path, name);
2073 #ifdef FSUAE
2074 	write_log("zfile_fopen %s\n", path);
2075 #endif
2076 		zf = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
2077 	}
2078 	return zf;
2079 }
2080 
ew(uae_u8 * p,int addr,uae_u8 value)2081 static void ew(uae_u8 *p, int addr, uae_u8 value)
2082 {
2083 	if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
2084 		p[addr] = (value & 0xf0);
2085 		p[addr + 2] = (value & 0x0f) << 4;
2086 	} else {
2087 		p[addr] = ~(value & 0xf0);
2088 		p[addr + 2] = ~((value & 0x0f) << 4);
2089 	}
2090 }
2091 
cpuboard_autoconfig_init(struct romconfig * rc)2092 addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
2093 {
2094 	struct zfile *autoconfig_rom = NULL;
2095 	struct boardromconfig *brc;
2096 	int roms[3], roms2[3];
2097 	bool autoconf = true;
2098 	bool autoconf_stop = false;
2099 	const TCHAR *defaultromname = NULL;
2100 	const TCHAR *romname = NULL;
2101 	bool isflashrom = false;
2102 	struct romdata *rd = NULL;
2103 	const TCHAR *boardname;
2104 
2105 	boardname = cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].name;
2106 
2107 	int idx;
2108 	brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, 0, &idx);
2109 	if (brc)
2110 		romname = brc->roms[idx].romfile;
2111 
2112 	roms[0] = -1;
2113 	roms[1] = -1;
2114 	roms[2] = -1;
2115 	roms2[0] = -1;
2116 	roms2[1] = -1;
2117 	roms2[2] = -1;
2118 	cpuboard_non_byte_ea = false;
2119 	int boardid = cpuboards[currprefs.cpuboard_type].id;
2120 	switch (boardid)
2121 	{
2122 		case BOARD_IC:
2123 		break;
2124 
2125 		case BOARD_COMMODORE:
2126 		switch(currprefs.cpuboard_subtype)
2127 		{
2128 			case BOARD_COMMODORE_SUB_A26x0:
2129 			roms[0] = 105;
2130 			roms[1] = 106;
2131 			break;
2132 		}
2133 		break;
2134 
2135 		case BOARD_ACT:
2136 		switch(currprefs.cpuboard_subtype)
2137 		{
2138 			case BOARD_ACT_SUB_APOLLO:
2139 			roms[0] = 119;
2140 			break;
2141 		}
2142 		break;
2143 
2144 		case BOARD_MTEC:
2145 		switch (currprefs.cpuboard_subtype)
2146 		{
2147 			case BOARD_MTEC_SUB_EMATRIX530:
2148 			roms[0] = 144;
2149 			break;
2150 		}
2151 		break;
2152 
2153 		case BOARD_MACROSYSTEM:
2154 		switch(currprefs.cpuboard_subtype)
2155 		{
2156 			case BOARD_MACROSYSTEM_SUB_WARPENGINE_A4000:
2157 			return &expamem_null;
2158 		}
2159 		break;
2160 
2161 		case BOARD_DKB:
2162 		switch(currprefs.cpuboard_subtype)
2163 		{
2164 			case BOARD_DKB_SUB_12x0:
2165 			return &expamem_null;
2166 			case BOARD_DKB_SUB_WILDFIRE:
2167 			roms[0] = 143;
2168 			break;
2169 		}
2170 		break;
2171 
2172 		case BOARD_RCS:
2173 		switch(currprefs.cpuboard_subtype)
2174 		{
2175 			case BOARD_RCS_SUB_FUSIONFORTY:
2176 			roms[0] = 113;
2177 			break;
2178 		}
2179 		break;
2180 
2181 		case BOARD_GVP:
2182 		switch(currprefs.cpuboard_subtype)
2183 		{
2184 			case BOARD_GVP_SUB_A530:
2185 			case BOARD_GVP_SUB_GFORCE030:
2186 				return &expamem_null;
2187 			case BOARD_GVP_SUB_A3001SI:
2188 			case BOARD_GVP_SUB_A3001SII:
2189 				return &expamem_null;
2190 			case BOARD_GVP_SUB_TEKMAGIC:
2191 				roms[0] = 104;
2192 			break;
2193 		}
2194 		break;
2195 
2196 		case BOARD_CYBERSTORM:
2197 		switch(currprefs.cpuboard_subtype)
2198 		{
2199 			case BOARD_CYBERSTORM_SUB_MK1:
2200 				roms[0] = currprefs.cpu_model == 68040 ? 95 : 101;
2201 				isflashrom = true;
2202 				break;
2203 			case BOARD_CYBERSTORM_SUB_MK2:
2204 				roms[0] = 96;
2205 				isflashrom = true;
2206 				break;
2207 			case BOARD_CYBERSTORM_SUB_MK3:
2208 				roms[0] = 97;
2209 				isflashrom = true;
2210 				break;
2211 			case BOARD_CYBERSTORM_SUB_PPC:
2212 				roms[0] = 98;
2213 				isflashrom = true;
2214 				break;
2215 		}
2216 		break;
2217 
2218 		case BOARD_BLIZZARD:
2219 		switch(currprefs.cpuboard_subtype)
2220 		{
2221 			case BOARD_BLIZZARD_SUB_1230IV:
2222 				roms[0] = 89;
2223 				roms2[0] = 94;
2224 				break;
2225 			case BOARD_BLIZZARD_SUB_1260:
2226 				roms[0] = 90;
2227 				roms2[0] = 94;
2228 				break;
2229 			case BOARD_BLIZZARD_SUB_2060:
2230 				roms[0] = 92;
2231 				break;
2232 			case BOARD_BLIZZARD_SUB_PPC:
2233 				roms[0] = currprefs.cpu_model == 68040 ? 99 : 100;
2234 				isflashrom = true;
2235 				break;
2236 		}
2237 		break;
2238 
2239 		case BOARD_KUPKE:
2240 			roms[0] = 126;
2241 		break;
2242 
2243 		case BOARD_DCE:
2244 			roms[0] = 160;
2245 		break;
2246 
2247 		default:
2248 			return &expamem_null;
2249 	}
2250 
2251 	struct romlist *rl = NULL;
2252 	if (roms[0] >= 0) {
2253 		rl = getromlistbyids(roms, romname);
2254 		if (!rl) {
2255 			rd = getromdatabyids(roms);
2256 			if (!rd)
2257 				return &expamem_null;
2258 		} else {
2259 			rd = rl->rd;
2260 		}
2261 		defaultromname = rd->defaultfilename;
2262 	}
2263 	if (!isflashrom) {
2264 		if (romname)
2265 			autoconfig_rom = zfile_fopen(romname, _T("rb"));
2266 		if (!autoconfig_rom && defaultromname)
2267 			autoconfig_rom = zfile_fopen(defaultromname, _T("rb"));
2268 		if (rl) {
2269 			if (autoconfig_rom) {
2270 				struct romdata *rd2 = getromdatabyids(roms);
2271 				// Do not use image if it is not long enough (odd or even only?)
2272 				if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) {
2273 					zfile_fclose(autoconfig_rom);
2274 					autoconfig_rom = NULL;
2275 				}
2276 			}
2277 			if (!autoconfig_rom)
2278 				autoconfig_rom = read_rom(rl->rd);
2279 		}
2280 	} else {
2281 		autoconfig_rom = flashfile_open(romname);
2282 		if (!autoconfig_rom) {
2283 			if (rl)
2284 				autoconfig_rom = flashfile_open(rl->path);
2285 			if (!autoconfig_rom)
2286 				autoconfig_rom = flashfile_open(defaultromname);
2287 		}
2288 		if (!autoconfig_rom) {
2289 			romwarning(roms);
2290 			write_log(_T("Couldn't open CPUBoard '%s' rom '%s'\n"), boardname, defaultromname);
2291 			return &expamem_null;
2292 		}
2293 	}
2294 
2295 	if (!autoconfig_rom && roms[0] != -1) {
2296 		romwarning(roms);
2297 		write_log (_T("ROM id %d not found for CPUBoard '%s' emulation\n"), roms[0], boardname);
2298 		return &expamem_null;
2299 	}
2300 	if (!autoconfig_rom) {
2301 		write_log(_T("Couldn't open CPUBoard '%s' rom '%s'\n"), boardname, defaultromname);
2302 		return &expamem_null;
2303 	}
2304 
2305 	write_log(_T("CPUBoard '%s' ROM '%s' %lld loaded\n"), boardname, zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom));
2306 
2307 	protect_roms(false);
2308 	cpuboard_non_byte_ea = true;
2309 	if (is_sx32pro()) {
2310 		earom_size = 65536;
2311 		for (int i = 0; i < 32768; i++) {
2312 			uae_u8 b = 0xff;
2313 			zfile_fread(&b, 1, 1, autoconfig_rom);
2314 			blizzardea_bank.baseaddr[i * 2 + 0] = b;
2315 			blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
2316 		}
2317 	} else if (is_mtec_ematrix530()) {
2318 		earom_size = 65536;
2319 		for (int i = 0; i < 32768; i++) {
2320 			uae_u8 b = 0xff;
2321 			zfile_fread(&b, 1, 1, autoconfig_rom);
2322 			blizzardea_bank.baseaddr[i * 2 + 0] = b;
2323 			blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
2324 		}
2325 	} else if (is_dkb_wildfire()) {
2326 		f0rom_size = 65536;
2327 		zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
2328 		flashrom = flash_new(blizzardf0_bank.baseaddr + 0, 32768, 65536, 0x20, flashrom_file, FLASHROM_EVERY_OTHER_BYTE | FLASHROM_PARALLEL_EEPROM);
2329 		flashrom2 = flash_new(blizzardf0_bank.baseaddr + 1, 32768, 65536, 0x20, flashrom_file, FLASHROM_EVERY_OTHER_BYTE | FLASHROM_EVERY_OTHER_BYTE_ODD | FLASHROM_PARALLEL_EEPROM);
2330 		autoconf = false;
2331 	} else if (is_aca500()) {
2332 		f0rom_size = 524288;
2333 		zfile_fread(blizzardf0_bank.baseaddr, f0rom_size, 1, autoconfig_rom);
2334 		autoconf = false;
2335 		if (zfile_needwrite(autoconfig_rom)) {
2336 			flashrom_file = autoconfig_rom;
2337 			autoconfig_rom = NULL;
2338 		}
2339 		flashrom = flash_new(blizzardf0_bank.baseaddr, f0rom_size, f0rom_size, 0xa4, flashrom_file, 0);
2340 	} else if (is_a2630()) {
2341 		f0rom_size = 131072;
2342 		zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
2343 		autoconf = false;
2344 		autoconf_stop = true;
2345 	} else if (is_kupke()) {
2346 		earom_size = 65536;
2347 		for (int i = 0; i < 8192; i++) {
2348 			uae_u8 b = 0xff;
2349 			zfile_fread(&b, 1, 1, autoconfig_rom);
2350 			blizzardea_bank.baseaddr[i * 2 + 0] = b;
2351 			blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
2352 		}
2353 	} else if (is_apollo()) {
2354 		f0rom_size = 131072;
2355 		zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
2356 		autoconf = false;
2357 	} else if (is_fusionforty()) {
2358 		f0rom_size = 262144;
2359 		zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
2360 		autoconf = false;
2361 	} else if (is_tekmagic()) {
2362 		earom_size = 65536;
2363 		f0rom_size = 131072;
2364 		zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
2365 		autoconf = false;
2366 		cpuboard_non_byte_ea = false;
2367 	} else if (is_blizzard2060()) {
2368 		f0rom_size = 65536;
2369 		earom_size = 131072;
2370 		// 2060 = 2x32k
2371 		for (int i = 0; i < 32768; i++) {
2372 			uae_u8 b = 0xff;
2373 			zfile_fread(&b, 1, 1, autoconfig_rom);
2374 			blizzardf0_bank.baseaddr[i * 2 + 1] = b;
2375 			zfile_fread(&b, 1, 1, autoconfig_rom);
2376 			blizzardf0_bank.baseaddr[i * 2 + 0] = b;
2377 			zfile_fread(&b, 1, 1, autoconfig_rom);
2378 			blizzardea_bank.baseaddr[i * 2 + 1] = b;
2379 			zfile_fread(&b, 1, 1, autoconfig_rom);
2380 			blizzardea_bank.baseaddr[i * 2 + 0] = b;
2381 		}
2382 	} else if (is_csmk1()) {
2383 		earom_size = 131072;
2384 		f0rom_size = 65536;
2385 		for (int i = 0; i < 32768; i++) {
2386 			uae_u8 b = 0xff;
2387 			zfile_fread(&b, 1, 1, autoconfig_rom);
2388 			blizzardea_bank.baseaddr[i * 2 + 0] = b;
2389 			blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
2390 		}
2391 		zfile_fread(blizzardea_bank.baseaddr + 65536, 65536, 1, autoconfig_rom);
2392 		if (zfile_needwrite(autoconfig_rom)) {
2393 			flashrom_file = autoconfig_rom;
2394 			autoconfig_rom = NULL;
2395 		}
2396 		flashrom = flash_new(blizzardea_bank.baseaddr, earom_size, earom_size, 0x20, flashrom_file, 0);
2397 		memcpy(blizzardf0_bank.baseaddr, blizzardea_bank.baseaddr + 65536, 65536);
2398 	} else if (is_csmk2()) {
2399 		earom_size = 131072;
2400 		f0rom_size = 65536;
2401 		zfile_fread(blizzardea_bank.baseaddr, earom_size, 1, autoconfig_rom);
2402 		if (zfile_needwrite(autoconfig_rom)) {
2403 			flashrom_file = autoconfig_rom;
2404 			autoconfig_rom = NULL;
2405 		}
2406 		flashrom = flash_new(blizzardea_bank.baseaddr, earom_size, earom_size, 0x20, flashrom_file, 0);
2407 		memcpy(blizzardf0_bank.baseaddr, blizzardea_bank.baseaddr + 65536, 65536);
2408 	} else if (is_csmk3() || is_blizzardppc()) {
2409 		uae_u8 flashtype;
2410 		earom_size = 0;
2411 		if (is_blizzardppc()) {
2412 			flashtype = 0xa4;
2413 			f0rom_size = 524288;
2414 		} else {
2415 			flashtype = 0x20;
2416 			f0rom_size = 131072;
2417 			if (zfile_size(autoconfig_rom) >= 262144) {
2418 				flashtype = 0xa4;
2419 				f0rom_size = 524288;
2420 			}
2421 		}
2422 		// empty rom space must be cleared, not set to ones.
2423 		memset(blizzardf0_bank.baseaddr, 0x00, f0rom_size);
2424 		if (f0rom_size == 524288) // but empty config data must be 0xFF
2425 			memset(blizzardf0_bank.baseaddr + 0x50000, 0xff, 0x10000);
2426 		zfile_fread(blizzardf0_bank.baseaddr, f0rom_size, 1, autoconfig_rom);
2427 		autoconf = false;
2428 		if (zfile_needwrite(autoconfig_rom)) {
2429 			flashrom_file = autoconfig_rom;
2430 			autoconfig_rom = NULL;
2431 		}
2432 		fixserial(blizzardf0_bank.baseaddr, f0rom_size);
2433 		flashrom = flash_new(blizzardf0_bank.baseaddr, f0rom_size, f0rom_size, flashtype, flashrom_file, 0);
2434 	} else {
2435 		// 1230 MK IV / 1240/60
2436 		f0rom_size = 65536;
2437 		earom_size = 131072;
2438 		// 12xx = 1x32k
2439 		for (int i = 0; i < 16384; i++) {
2440 			uae_u8 b = 0xff;
2441 			zfile_fread(&b, 1, 1, autoconfig_rom);
2442 			blizzardf0_bank.baseaddr[i] = b;
2443 			zfile_fread(&b, 1, 1, autoconfig_rom);
2444 			blizzardea_bank.baseaddr[i] = b;
2445 		}
2446 		zfile_fclose(autoconfig_rom);
2447 		autoconfig_rom = NULL;
2448 		if (roms2[0] != -1) {
2449 			int idx2;
2450 			struct boardromconfig *brc2 = get_device_rom(&currprefs, ROMTYPE_BLIZKIT4, 0, &idx2);
2451 			if (brc2 && brc2->roms[idx2].romfile[0])
2452 				autoconfig_rom = board_rom_open(roms2, brc2->roms[idx2].romfile);
2453 			if (autoconfig_rom) {
2454 				memset(blizzardea_bank.baseaddr + 0x10000, 0xff, 65536);
2455 				zfile_fread(blizzardea_bank.baseaddr + 0x10000, 32768, 1, autoconfig_rom);
2456 			}
2457 		}
2458 	}
2459 	protect_roms(true);
2460 	zfile_fclose(autoconfig_rom);
2461 
2462 	if (f0rom_size) {
2463 		if (is_a2630()) {
2464 			if (!(a2630_io & 2))
2465 				map_banks(&blizzardf0_bank, 0xf80000 >> 16, f0rom_size >> 16, 0);
2466 			if (!(a2630_io & 1))
2467 				map_banks(&blizzardf0_bank, 0x000000 >> 16, f0rom_size >> 16, 0);
2468 		} else if (is_fusionforty()) {
2469 			map_banks(&blizzardf0_bank, 0x00f40000 >> 16, f0rom_size >> 16, 0);
2470 			map_banks(&blizzardf0_bank, 0x05000000 >> 16, f0rom_size >> 16, 0);
2471 			map_banks(&blizzardf0_bank, 0x00000000 >> 16, f0rom_size >> 16, 0);
2472 		} else {
2473 			map_banks(&blizzardf0_bank, 0xf00000 >> 16, (f0rom_size > 262144 ? 262144 : f0rom_size) >> 16, 0);
2474 		}
2475 	}
2476 	if (autoconf_stop)
2477 		return &expamem_none;
2478 	if (!autoconf)
2479 		return &expamem_null;
2480 	return &blizzarde8_bank;
2481 }
2482