1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Memory management
5 *
6 * (c) 1995 Bernd Schmidt
7 */
8 
9 #define DEBUG_STUPID 0
10 
11 #include "sysconfig.h"
12 #include "sysdeps.h"
13 
14 #include "options.h"
15 #include "uae.h"
16 #include "uae/memory.h"
17 #include "rommgr.h"
18 #include "ersatz.h"
19 #include "zfile.h"
20 #include "custom.h"
21 #include "events.h"
22 #include "newcpu.h"
23 #include "autoconf.h"
24 #include "savestate.h"
25 #include "ar.h"
26 #include "crc32.h"
27 #include "gui.h"
28 #include "cdtv.h"
29 #include "akiko.h"
30 #include "arcadia.h"
31 #include "enforcer.h"
32 #include "threaddep/thread.h"
33 #include "a2091.h"
34 #include "gayle.h"
35 #include "debug.h"
36 #include "gfxboard.h"
37 #include "cpuboard.h"
38 #include "uae/ppc.h"
39 #include "devices.h"
40 
41 #ifdef FSUAE // NL
42 #undef _WIN32
43 #endif
44 
45 #ifdef FSUAE // NL
46 extern uae_u8 *natmem_offset, *natmem_offset_end;
47 #endif
48 
49 bool canbang;
50 static bool rom_write_enabled;
51 #ifdef JIT
52 /* Set by each memory handler that does not simply access real memory. */
53 int special_mem;
54 #endif
55 static int mem_hardreset;
56 static bool roms_modified;
57 
58 #define FLASHEMU 0
59 
isdirectjit(void)60 static bool isdirectjit (void)
61 {
62 	return currprefs.cachesize && !currprefs.comptrustbyte;
63 }
64 
canjit(void)65 static bool canjit (void)
66 {
67 	if (currprefs.cpu_model < 68020 || currprefs.address_space_24)
68 		return false;
69 	return true;
70 }
needmman(void)71 static bool needmman (void)
72 {
73 	if (!jit_direct_compatible_memory)
74 		return false;
75 #ifdef _WIN32
76 #ifdef FSUAE
77     // FIXME: check if FS-UAE should return true here for Windows as well
78 #endif
79 	return true;
80 #endif
81 	if (canjit ())
82 		return true;
83 	return false;
84 }
85 
nocanbang(void)86 static void nocanbang (void)
87 {
88 	canbang = 0;
89 }
90 
91 uae_u8 ce_banktype[65536];
92 uae_u8 ce_cachable[65536];
93 
94 static size_t bootrom_filepos, chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos, mem25bit_filepos;
95 
96 /* Set if we notice during initialization that settings changed,
97 and we must clear all memory to prevent bogus contents from confusing
98 the Kickstart.  */
99 static bool need_hardreset;
100 static int bogomem_aliasing;
101 
102 /* The address space setting used during the last reset.  */
103 static bool last_address_space_24;
104 
105 addrbank *mem_banks[MEMORY_BANKS];
106 
107 /* This has two functions. It either holds a host address that, when added
108 to the 68k address, gives the host address corresponding to that 68k
109 address (in which case the value in this array is even), OR it holds the
110 same value as mem_banks, for those banks that have baseaddr==0. In that
111 case, bit 0 is set (the memory access routines will take care of it).  */
112 
113 uae_u8 *baseaddr[MEMORY_BANKS];
114 
115 #ifdef NO_INLINE_MEMORY_ACCESS
longget(uaecptr addr)116 __inline__ uae_u32 longget (uaecptr addr)
117 {
118 	return call_mem_get_func (get_mem_bank (addr).lget, addr);
119 }
wordget(uaecptr addr)120 __inline__ uae_u32 wordget (uaecptr addr)
121 {
122 	return call_mem_get_func (get_mem_bank (addr).wget, addr);
123 }
byteget(uaecptr addr)124 __inline__ uae_u32 byteget (uaecptr addr)
125 {
126 	return call_mem_get_func (get_mem_bank (addr).bget, addr);
127 }
longput(uaecptr addr,uae_u32 l)128 __inline__ void longput (uaecptr addr, uae_u32 l)
129 {
130 	call_mem_put_func (get_mem_bank (addr).lput, addr, l);
131 }
wordput(uaecptr addr,uae_u32 w)132 __inline__ void wordput (uaecptr addr, uae_u32 w)
133 {
134 	call_mem_put_func (get_mem_bank (addr).wput, addr, w);
135 }
byteput(uaecptr addr,uae_u32 b)136 __inline__ void byteput (uaecptr addr, uae_u32 b)
137 {
138 	call_mem_put_func (get_mem_bank (addr).bput, addr, b);
139 }
140 #endif
141 
addr_valid(const TCHAR * txt,uaecptr addr,uae_u32 len)142 int addr_valid (const TCHAR *txt, uaecptr addr, uae_u32 len)
143 {
144 	addrbank *ab = &get_mem_bank(addr);
145 	if (ab == 0 || !(ab->flags & (ABFLAG_RAM | ABFLAG_ROM)) || addr < 0x100 || len > 16777215 || !valid_address (addr, len)) {
146 		write_log (_T("corrupt %s pointer %x (%d) detected!\n"), txt, addr, len);
147 		return 0;
148 	}
149 	return 1;
150 }
151 
152 static int illegal_count;
153 /* A dummy bank that only contains zeros */
154 
155 static uae_u32 REGPARAM3 dummy_lget (uaecptr) REGPARAM;
156 static uae_u32 REGPARAM3 dummy_wget (uaecptr) REGPARAM;
157 static uae_u32 REGPARAM3 dummy_bget (uaecptr) REGPARAM;
158 static void REGPARAM3 dummy_lput (uaecptr, uae_u32) REGPARAM;
159 static void REGPARAM3 dummy_wput (uaecptr, uae_u32) REGPARAM;
160 static void REGPARAM3 dummy_bput (uaecptr, uae_u32) REGPARAM;
161 static int REGPARAM3 dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
162 
163 #define	MAX_ILG 1000
164 #define NONEXISTINGDATA 0
165 //#define NONEXISTINGDATA 0xffffffff
166 
dummylog(int rw,uaecptr addr,int size,uae_u32 val,int ins)167 static void dummylog (int rw, uaecptr addr, int size, uae_u32 val, int ins)
168 {
169 	if (illegal_count >= MAX_ILG && MAX_ILG > 0)
170 		return;
171 	/* ignore Zorro3 expansion space */
172 	if (addr >= 0xff000000 && addr <= 0xff000200)
173 		return;
174 	/* autoconfig and extended rom */
175 	if (addr >= 0xe00000 && addr <= 0xf7ffff)
176 		return;
177 	/* motherboard ram */
178 	if (addr >= 0x08000000 && addr <= 0x08000007)
179 		return;
180 	if (addr >= 0x07f00000 && addr <= 0x07f00007)
181 		return;
182 	if (addr >= 0x07f7fff0 && addr <= 0x07ffffff)
183 		return;
184 	if (MAX_ILG >= 0)
185 		illegal_count++;
186 	if (ins) {
187 		write_log (_T("WARNING: Illegal opcode %cget at %08x PC=%x\n"),
188 			size == 2 ? 'w' : 'l', addr, M68K_GETPC);
189 	} else if (rw) {
190 		write_log (_T("Illegal %cput at %08x=%08x PC=%x\n"),
191 			size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, val, M68K_GETPC);
192 	} else {
193 		write_log (_T("Illegal %cget at %08x PC=%x\n"),
194 			size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, M68K_GETPC);
195 	}
196 }
197 
198 // 250ms delay
gary_wait(uaecptr addr,int size,bool write)199 static void gary_wait(uaecptr addr, int size, bool write)
200 {
201 	static int cnt = 50;
202 
203 #if 0
204 	int lines = 313 * 12;
205 	while (lines-- > 0)
206 		x_do_cycles(228 * CYCLE_UNIT);
207 #endif
208 
209 	if (cnt > 0) {
210 		write_log (_T("Gary timeout: %08x %d %c PC=%08x\n"), addr, size, write ? 'W' : 'R', M68K_GETPC);
211 		cnt--;
212 	}
213 }
214 
gary_nonrange(uaecptr addr)215 static bool gary_nonrange(uaecptr addr)
216 {
217 	if (currprefs.cs_fatgaryrev < 0)
218 		return false;
219 	if (addr < 0xb80000)
220 		return false;
221 	if (addr >= 0xd00000 && addr < 0xdc0000)
222 		return true;
223 	if (addr >= 0xdd0000 && addr < 0xde0000)
224 		return true;
225 	if (addr >= 0xdf8000 && addr < 0xe00000)
226 		return false;
227 	if (addr >= 0xe80000 && addr < 0xf80000)
228 		return false;
229 	return true;
230 }
231 
dummy_put(uaecptr addr,int size,uae_u32 val)232 void dummy_put (uaecptr addr, int size, uae_u32 val)
233 {
234 #if FLASHEMU
235 	if (addr >= 0xf00000 && addr < 0xf80000 && size < 2)
236 		flash_write(addr, val);
237 #endif
238 	if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) {
239 		if (gary_timeout)
240 			gary_wait (addr, size, true);
241 		if (gary_toenb && currprefs.mmu_model)
242 			exception2 (addr, true, size, regs.s ? 4 : 0);
243 	}
244 }
245 
dummy_get_safe(uaecptr addr,int size,bool inst,uae_u32 defvalue)246 uae_u32 dummy_get_safe(uaecptr addr, int size, bool inst, uae_u32 defvalue)
247 {
248 	uae_u32 v = defvalue;
249 	if (currprefs.cpu_model >= 68040)
250 		return v;
251 	if (!currprefs.cpu_compatible)
252 		return v;
253 	if (currprefs.address_space_24)
254 		addr &= 0x00ffffff;
255 	if (addr >= 0x10000000)
256 		return v;
257 	if ((currprefs.cpu_model <= 68010) || (currprefs.cpu_model == 68020 && (currprefs.chipset_mask & CSMASK_AGA) && currprefs.address_space_24)) {
258 		if (size == 4) {
259 			v = regs.db & 0xffff;
260 			if (addr & 1)
261 				v = (v << 8) | (v >> 8);
262 			v = (v << 16) | v;
263 		} else if (size == 2) {
264 			v = regs.db & 0xffff;
265 			if (addr & 1)
266 				v = (v << 8) | (v >> 8);
267 		} else {
268 			v = regs.db;
269 			v = (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff);
270 		}
271 	}
272 	return v;
273 }
274 
dummy_get(uaecptr addr,int size,bool inst,uae_u32 defvalue)275 uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue)
276 {
277 	uae_u32 v = defvalue;
278 
279 #if FLASHEMU
280 	if (addr >= 0xf00000 && addr < 0xf80000 && size < 2) {
281 		if (addr < 0xf60000)
282 			return flash_read(addr);
283 		return 8;
284 	}
285 #endif
286 
287 	if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) {
288 		if (gary_timeout)
289 			gary_wait (addr, size, false);
290 		if (gary_toenb)
291 			exception2 (addr, false, size, (regs.s ? 4 : 0) | (inst ? 0 : 1));
292 		return v;
293 	}
294 
295 	return dummy_get_safe(addr, size, inst, defvalue);
296 }
297 
dummy_lget(uaecptr addr)298 static uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
299 {
300 	if (currprefs.illegal_mem)
301 		dummylog (0, addr, 4, 0, 0);
302 	return dummy_get (addr, 4, false, NONEXISTINGDATA);
303 }
dummy_lgeti(uaecptr addr)304 uae_u32 REGPARAM2 dummy_lgeti (uaecptr addr)
305 {
306 	if (currprefs.illegal_mem)
307 		dummylog (0, addr, 4, 0, 1);
308 	return dummy_get (addr, 4, true, NONEXISTINGDATA);
309 }
310 
dummy_wget(uaecptr addr)311 static uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
312 {
313 #if 0
314 	if (addr == 0xb0b000) {
315 		extern uae_u16 isideint(void);
316 		return isideint();
317 	}
318 #endif
319 	if (currprefs.illegal_mem)
320 		dummylog (0, addr, 2, 0, 0);
321 	return dummy_get (addr, 2, false, NONEXISTINGDATA);
322 }
dummy_wgeti(uaecptr addr)323 uae_u32 REGPARAM2 dummy_wgeti (uaecptr addr)
324 {
325 	if (currprefs.illegal_mem)
326 		dummylog (0, addr, 2, 0, 1);
327 	return dummy_get (addr, 2, true, NONEXISTINGDATA);
328 }
329 
dummy_bget(uaecptr addr)330 static uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
331 {
332 	if (currprefs.illegal_mem)
333 		dummylog (0, addr, 1, 0, 0);
334 	return dummy_get (addr, 1, false, NONEXISTINGDATA);
335 }
336 
dummy_lput(uaecptr addr,uae_u32 l)337 static void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
338 {
339 	if (currprefs.illegal_mem)
340 		dummylog (1, addr, 4, l, 0);
341 	dummy_put (addr, 4, l);
342 }
dummy_wput(uaecptr addr,uae_u32 w)343 static void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
344 {
345 	if (currprefs.illegal_mem)
346 		dummylog (1, addr, 2, w, 0);
347 	dummy_put (addr, 2, w);
348 }
dummy_bput(uaecptr addr,uae_u32 b)349 static void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
350 {
351 	if (currprefs.illegal_mem)
352 		dummylog (1, addr, 1, b, 0);
353 	dummy_put (addr, 1, b);
354 }
355 
dummy_check(uaecptr addr,uae_u32 size)356 static int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
357 {
358 	return 0;
359 }
360 
none_put(uaecptr addr,uae_u32 v)361 static void REGPARAM2 none_put (uaecptr addr, uae_u32 v)
362 {
363 }
ones_get(uaecptr addr)364 static uae_u32 REGPARAM2 ones_get (uaecptr addr)
365 {
366 	return 0xffffffff;
367 }
368 
get_sub_bank(uaecptr * paddr)369 addrbank *get_sub_bank(uaecptr *paddr)
370 {
371 	int i;
372 	uaecptr addr = *paddr;
373 	addrbank *ab = &get_mem_bank(addr);
374 	struct addrbank_sub *sb = ab->sub_banks;
375 	if (!sb)
376 		return &dummy_bank;
377 	for (i = 0; sb[i].bank; i++) {
378 		int offset = addr & 65535;
379 		if (offset < sb[i + 1].offset) {
380 			uae_u32 mask = sb[i].mask;
381 			uae_u32 maskval = sb[i].maskval;
382 			if ((offset & mask) == maskval) {
383 				*paddr = addr - sb[i].suboffset;
384 				return sb[i].bank;
385 			}
386 		}
387 	}
388 	*paddr = addr - sb[i - 1].suboffset;
389 	return sb[i - 1].bank;
390 }
sub_bank_lget(uaecptr addr)391 uae_u32 REGPARAM3 sub_bank_lget (uaecptr addr) REGPARAM
392 {
393 	addrbank *ab = get_sub_bank(&addr);
394 	return ab->lget(addr);
395 }
sub_bank_wget(uaecptr addr)396 uae_u32 REGPARAM3 sub_bank_wget(uaecptr addr) REGPARAM
397 {
398 	addrbank *ab = get_sub_bank(&addr);
399 	return ab->wget(addr);
400 }
sub_bank_bget(uaecptr addr)401 uae_u32 REGPARAM3 sub_bank_bget(uaecptr addr) REGPARAM
402 {
403 	addrbank *ab = get_sub_bank(&addr);
404 	return ab->bget(addr);
405 }
sub_bank_lput(uaecptr addr,uae_u32 v)406 void REGPARAM3 sub_bank_lput(uaecptr addr, uae_u32 v) REGPARAM
407 {
408 	addrbank *ab = get_sub_bank(&addr);
409 	ab->lput(addr, v);
410 }
sub_bank_wput(uaecptr addr,uae_u32 v)411 void REGPARAM3 sub_bank_wput(uaecptr addr, uae_u32 v) REGPARAM
412 {
413 	addrbank *ab = get_sub_bank(&addr);
414 	ab->wput(addr, v);
415 }
sub_bank_bput(uaecptr addr,uae_u32 v)416 void REGPARAM3 sub_bank_bput(uaecptr addr, uae_u32 v) REGPARAM
417 {
418 	addrbank *ab = get_sub_bank(&addr);
419 	ab->bput(addr, v);
420 }
sub_bank_lgeti(uaecptr addr)421 uae_u32 REGPARAM3 sub_bank_lgeti(uaecptr addr) REGPARAM
422 {
423 	addrbank *ab = get_sub_bank(&addr);
424 	return ab->lgeti(addr);
425 }
sub_bank_wgeti(uaecptr addr)426 uae_u32 REGPARAM3 sub_bank_wgeti(uaecptr addr) REGPARAM
427 {
428 	addrbank *ab = get_sub_bank(&addr);
429 	return ab->wgeti(addr);
430 }
sub_bank_check(uaecptr addr,uae_u32 size)431 int REGPARAM3 sub_bank_check(uaecptr addr, uae_u32 size) REGPARAM
432 {
433 	addrbank *ab = get_sub_bank(&addr);
434 	return ab->check(addr, size);
435 }
sub_bank_xlate(uaecptr addr)436 uae_u8 *REGPARAM3 sub_bank_xlate(uaecptr addr) REGPARAM
437 {
438 	addrbank *ab = get_sub_bank(&addr);
439 	return ab->xlateaddr(addr);
440 }
441 
442 
443 /* Chip memory */
444 
445 static uae_u32 chipmem_full_mask;
446 static uae_u32 chipmem_full_size;
447 
448 static int REGPARAM3 chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
449 static uae_u8 *REGPARAM3 chipmem_xlate (uaecptr addr) REGPARAM;
450 
451 #ifdef AGA
452 
453 /* AGA ce-chipram access */
454 
ce2_timeout(void)455 static void ce2_timeout (void)
456 {
457 	wait_cpu_cycle_read (0, -1);
458 }
459 
chipmem_lget_ce2(uaecptr addr)460 static uae_u32 REGPARAM2 chipmem_lget_ce2 (uaecptr addr)
461 {
462 	uae_u32 *m;
463 
464 	addr &= chipmem_bank.mask;
465 	m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
466 	ce2_timeout ();
467 	return do_get_mem_long (m);
468 }
469 
chipmem_wget_ce2(uaecptr addr)470 static uae_u32 REGPARAM2 chipmem_wget_ce2 (uaecptr addr)
471 {
472 	uae_u16 *m, v;
473 
474 	addr &= chipmem_bank.mask;
475 	m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
476 	ce2_timeout ();
477 	v = do_get_mem_word (m);
478 	return v;
479 }
480 
chipmem_bget_ce2(uaecptr addr)481 static uae_u32 REGPARAM2 chipmem_bget_ce2 (uaecptr addr)
482 {
483 	addr &= chipmem_bank.mask;
484 	ce2_timeout ();
485 	return chipmem_bank.baseaddr[addr];
486 }
487 
chipmem_lput_ce2(uaecptr addr,uae_u32 l)488 static void REGPARAM2 chipmem_lput_ce2 (uaecptr addr, uae_u32 l)
489 {
490 	uae_u32 *m;
491 
492 	addr &= chipmem_bank.mask;
493 	m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
494 	ce2_timeout ();
495 	do_put_mem_long (m, l);
496 }
497 
chipmem_wput_ce2(uaecptr addr,uae_u32 w)498 static void REGPARAM2 chipmem_wput_ce2 (uaecptr addr, uae_u32 w)
499 {
500 	uae_u16 *m;
501 
502 	addr &= chipmem_bank.mask;
503 	m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
504 	ce2_timeout ();
505 	do_put_mem_word (m, w);
506 }
507 
chipmem_bput_ce2(uaecptr addr,uae_u32 b)508 static void REGPARAM2 chipmem_bput_ce2 (uaecptr addr, uae_u32 b)
509 {
510 	addr &= chipmem_bank.mask;
511 	ce2_timeout ();
512 	chipmem_bank.baseaddr[addr] = b;
513 }
514 
515 #endif
516 
chipmem_lget(uaecptr addr)517 static uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
518 {
519 	uae_u32 *m;
520 
521 	addr &= chipmem_bank.mask;
522 	m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
523 #ifdef FSUAE
524 #ifdef DEBUG_MEM
525 	write_log("chipmem_lget %08x = %08x\n", addr, do_get_mem_long (m));
526 #endif
527 #endif
528 	return do_get_mem_long (m);
529 }
530 
chipmem_wget(uaecptr addr)531 static uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
532 {
533 	uae_u16 *m, v;
534 
535 	addr &= chipmem_bank.mask;
536 	m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
537 	v = do_get_mem_word (m);
538 #ifdef FSUAE
539 #ifdef DEBUG_MEM
540 	write_log("chipmem_wget %08x = %08x\n", addr, v);
541 #endif
542 #endif
543 	return v;
544 }
545 
chipmem_bget(uaecptr addr)546 static uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
547 {
548 	uae_u8 v;
549 	addr &= chipmem_bank.mask;
550 	v = chipmem_bank.baseaddr[addr];
551 #ifdef FSUAE
552 #ifdef DEBUG_MEM
553 	write_log("chipmem_wget %08x = %08x\n", addr, v);
554 #endif
555 #endif
556 	return v;
557 }
558 
chipmem_lput(uaecptr addr,uae_u32 l)559 void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
560 {
561 #ifdef FSUAE
562 #ifdef DEBUG_MEM
563 	write_log("chipmem_lput %08x %08x\n", addr, l);
564 #endif
565 #endif
566 #ifdef FSUAE
567 #ifdef DEBUG_SYNC_MEMORY
568 	write_sync_log("cl %08x %08x\n", addr, l);
569 #endif
570 #endif
571 	uae_u32 *m;
572 
573 	addr &= chipmem_bank.mask;
574 	m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
575 	do_put_mem_long (m, l);
576 }
577 
chipmem_wput(uaecptr addr,uae_u32 w)578 void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
579 {
580 #ifdef FSUAE
581 #ifdef DEBUG_MEM
582 	write_log("chipmem_wput %08x %08x\n", addr, w);
583 #endif
584 #endif
585 #ifdef FSUAE
586 #ifdef DEBUG_SYNC_MEMORY
587 	write_sync_log("cw %08x %08x\n", addr, w);
588 #endif
589 #endif
590 	uae_u16 *m;
591 
592 	addr &= chipmem_bank.mask;
593 	m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
594 	do_put_mem_word (m, w);
595 }
596 
chipmem_bput(uaecptr addr,uae_u32 b)597 void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
598 {
599 #ifdef FSUAE
600 #ifdef DEBUG_MEM
601 	write_log("chipmem_bput %08x %08x\n", addr, b);
602 #endif
603 #endif
604 #ifdef FSUAE
605 #ifdef DEBUG_SYNC_MEMORY
606 	write_sync_log("cb %08x %08x\n", addr, b);
607 #endif
608 #endif
609 	addr &= chipmem_bank.mask;
610 	chipmem_bank.baseaddr[addr] = b;
611 }
612 
613 /* cpu chipmem access inside agnus addressable ram but no ram available */
chipmem_dummy(void)614 static uae_u32 chipmem_dummy (void)
615 {
616 	/* not really right but something random that has more ones than zeros.. */
617 	return 0xffff & ~((1 << (uaerand () & 31)) | (1 << (uaerand () & 31)));
618 }
619 
chipmem_dummy_bput(uaecptr addr,uae_u32 b)620 static void REGPARAM2 chipmem_dummy_bput (uaecptr addr, uae_u32 b)
621 {
622 }
chipmem_dummy_wput(uaecptr addr,uae_u32 b)623 static void REGPARAM2 chipmem_dummy_wput (uaecptr addr, uae_u32 b)
624 {
625 }
chipmem_dummy_lput(uaecptr addr,uae_u32 b)626 static void REGPARAM2 chipmem_dummy_lput (uaecptr addr, uae_u32 b)
627 {
628 }
629 
chipmem_dummy_bget(uaecptr addr)630 static uae_u32 REGPARAM2 chipmem_dummy_bget (uaecptr addr)
631 {
632 	return chipmem_dummy ();
633 }
chipmem_dummy_wget(uaecptr addr)634 static uae_u32 REGPARAM2 chipmem_dummy_wget (uaecptr addr)
635 {
636 	return chipmem_dummy ();
637 }
chipmem_dummy_lget(uaecptr addr)638 static uae_u32 REGPARAM2 chipmem_dummy_lget (uaecptr addr)
639 {
640 	return (chipmem_dummy () << 16) | chipmem_dummy ();
641 }
642 
chipmem_agnus_lget(uaecptr addr)643 static uae_u32 REGPARAM2 chipmem_agnus_lget (uaecptr addr)
644 {
645 	uae_u32 *m;
646 
647 	addr &= chipmem_full_mask;
648 	if (addr >= chipmem_full_size - 3)
649 		return 0;
650 	m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
651 #ifdef FSUAE
652 #ifdef DEBUG_MEM
653 	write_log("chipmem_agnus_lget %08x = %08x\n", addr, do_get_mem_long (m));
654 #endif
655 #endif
656 	return do_get_mem_long (m);
657 }
658 
chipmem_agnus_wget(uaecptr addr)659 uae_u32 REGPARAM2 chipmem_agnus_wget (uaecptr addr)
660 {
661 	uae_u16 *m;
662 
663 	addr &= chipmem_full_mask;
664 	if (addr >= chipmem_full_size - 1)
665 		return 0;
666 	m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
667 #ifdef FSUAE
668 #ifdef DEBUG_MEM
669 	write_log("chipmem_agnus_lget %08x = %08x\n", addr, do_get_mem_word (m));
670 #endif
671 #endif
672 	return do_get_mem_word (m);
673 }
674 
chipmem_agnus_bget(uaecptr addr)675 static uae_u32 REGPARAM2 chipmem_agnus_bget (uaecptr addr)
676 {
677 	addr &= chipmem_full_mask;
678 	if (addr >= chipmem_full_size)
679 		return 0;
680 #ifdef FSUAE
681 #ifdef DEBUG_MEM
682 	write_log("chipmem_agnus_lget %08x = %08x\n", addr, chipmem_bank.baseaddr[addr]);
683 #endif
684 #endif
685 	return chipmem_bank.baseaddr[addr];
686 }
687 
chipmem_agnus_lput(uaecptr addr,uae_u32 l)688 static void REGPARAM2 chipmem_agnus_lput (uaecptr addr, uae_u32 l)
689 {
690 #ifdef FSUAE
691 #ifdef DEBUG_MEM
692 	write_log("chipmem_agnus_lput %08x %08x\n", addr, l);
693 #endif
694 #endif
695 	uae_u32 *m;
696 
697 	addr &= chipmem_full_mask;
698 	if (addr >= chipmem_full_size - 3)
699 		return;
700 	m = (uae_u32 *)(chipmem_bank.baseaddr + addr);
701 	do_put_mem_long (m, l);
702 }
703 
chipmem_agnus_wput(uaecptr addr,uae_u32 w)704 void REGPARAM2 chipmem_agnus_wput (uaecptr addr, uae_u32 w)
705 {
706 #ifdef FSUAE
707 #ifdef DEBUG_MEM
708 	write_log("chipmem_agnus_wput %08x %08x\n", addr, w);
709 #endif
710 #endif
711 	uae_u16 *m;
712 
713 	addr &= chipmem_full_mask;
714 	if (addr >= chipmem_full_size - 1)
715 		return;
716 	m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
717 	do_put_mem_word (m, w);
718 }
719 
chipmem_agnus_bput(uaecptr addr,uae_u32 b)720 static void REGPARAM2 chipmem_agnus_bput (uaecptr addr, uae_u32 b)
721 {
722 #ifdef FSUAE
723 #ifdef DEBUG_MEM
724 	write_log("chipmem_agnus_bput %08x %08x\n", addr, b);
725 #endif
726 #endif
727 	addr &= chipmem_full_mask;
728 	if (addr >= chipmem_full_size)
729 		return;
730 	chipmem_bank.baseaddr[addr] = b;
731 }
732 
chipmem_check(uaecptr addr,uae_u32 size)733 static int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
734 {
735 	addr &= chipmem_bank.mask;
736 	return (addr + size) <= chipmem_full_size;
737 }
738 
chipmem_xlate(uaecptr addr)739 static uae_u8 *REGPARAM2 chipmem_xlate (uaecptr addr)
740 {
741 	addr &= chipmem_bank.mask;
742 	return chipmem_bank.baseaddr + addr;
743 }
744 
chipmem_lput_bigmem(uaecptr addr,uae_u32 v)745 STATIC_INLINE void REGPARAM2 chipmem_lput_bigmem (uaecptr addr, uae_u32 v)
746 {
747 	put_long (addr, v);
748 }
chipmem_wput_bigmem(uaecptr addr,uae_u32 v)749 STATIC_INLINE void REGPARAM2 chipmem_wput_bigmem (uaecptr addr, uae_u32 v)
750 {
751 	put_word (addr, v);
752 }
chipmem_bput_bigmem(uaecptr addr,uae_u32 v)753 STATIC_INLINE void REGPARAM2 chipmem_bput_bigmem (uaecptr addr, uae_u32 v)
754 {
755 	put_byte (addr, v);
756 }
chipmem_lget_bigmem(uaecptr addr)757 STATIC_INLINE uae_u32 REGPARAM2 chipmem_lget_bigmem (uaecptr addr)
758 {
759 	return get_long (addr);
760 }
chipmem_wget_bigmem(uaecptr addr)761 STATIC_INLINE uae_u32 REGPARAM2 chipmem_wget_bigmem (uaecptr addr)
762 {
763 	return get_word (addr);
764 }
chipmem_bget_bigmem(uaecptr addr)765 STATIC_INLINE uae_u32 REGPARAM2 chipmem_bget_bigmem (uaecptr addr)
766 {
767 	return get_byte (addr);
768 }
chipmem_check_bigmem(uaecptr addr,uae_u32 size)769 STATIC_INLINE int REGPARAM2 chipmem_check_bigmem (uaecptr addr, uae_u32 size)
770 {
771 	return valid_address (addr, size);
772 }
chipmem_xlate_bigmem(uaecptr addr)773 STATIC_INLINE uae_u8* REGPARAM2 chipmem_xlate_bigmem (uaecptr addr)
774 {
775 	return get_real_address (addr);
776 }
777 
778 uae_u32 (REGPARAM2 *chipmem_lget_indirect)(uaecptr);
779 uae_u32 (REGPARAM2 *chipmem_wget_indirect)(uaecptr);
780 uae_u32 (REGPARAM2 *chipmem_bget_indirect)(uaecptr);
781 void (REGPARAM2 *chipmem_lput_indirect)(uaecptr, uae_u32);
782 void (REGPARAM2 *chipmem_wput_indirect)(uaecptr, uae_u32);
783 void (REGPARAM2 *chipmem_bput_indirect)(uaecptr, uae_u32);
784 int (REGPARAM2 *chipmem_check_indirect)(uaecptr, uae_u32);
785 uae_u8 *(REGPARAM2 *chipmem_xlate_indirect)(uaecptr);
786 
chipmem_setindirect(void)787 static void chipmem_setindirect (void)
788 {
789 	if (currprefs.z3chipmem_size) {
790 		chipmem_lget_indirect = chipmem_lget_bigmem;
791 		chipmem_wget_indirect = chipmem_wget_bigmem;
792 		chipmem_bget_indirect = chipmem_bget_bigmem;
793 		chipmem_lput_indirect = chipmem_lput_bigmem;
794 		chipmem_wput_indirect = chipmem_wput_bigmem;
795 		chipmem_bput_indirect = chipmem_bput_bigmem;
796 		chipmem_check_indirect = chipmem_check_bigmem;
797 		chipmem_xlate_indirect = chipmem_xlate_bigmem;
798 	} else {
799 		chipmem_lget_indirect = chipmem_lget;
800 		chipmem_wget_indirect = chipmem_agnus_wget;
801 		chipmem_bget_indirect = chipmem_agnus_bget;
802 		chipmem_lput_indirect = chipmem_lput;
803 		chipmem_wput_indirect = chipmem_agnus_wput;
804 		chipmem_bput_indirect = chipmem_agnus_bput;
805 		chipmem_check_indirect = chipmem_check;
806 		chipmem_xlate_indirect = chipmem_xlate;
807 	}
808 }
809 
810 /* Slow memory */
811 
812 MEMORY_FUNCTIONS(bogomem);
813 
814 /* CDTV expension memory card memory */
815 
816 MEMORY_FUNCTIONS(cardmem);
817 
818 /* A3000 motherboard fast memory */
819 
820 MEMORY_FUNCTIONS(a3000lmem);
821 MEMORY_FUNCTIONS(a3000hmem);
822 
823 /* 25bit memory (0x01000000) */
824 
825 MEMORY_FUNCTIONS(mem25bit);
826 
827 
828 /* Kick memory */
829 
830 uae_u16 kickstart_version;
831 
832 /*
833 * A1000 kickstart RAM handling
834 *
835 * RESET instruction unhides boot ROM and disables write protection
836 * write access to boot ROM hides boot ROM and enables write protection
837 *
838 */
839 static int a1000_kickstart_mode;
840 static uae_u8 *a1000_bootrom;
a1000_handle_kickstart(int mode)841 static void a1000_handle_kickstart (int mode)
842 {
843 	if (!a1000_bootrom)
844 		return;
845 	protect_roms (false);
846 	if (mode == 0) {
847 		a1000_kickstart_mode = 0;
848 		memcpy (kickmem_bank.baseaddr, kickmem_bank.baseaddr + ROM_SIZE_256, ROM_SIZE_256);
849 		kickstart_version = (kickmem_bank.baseaddr[ROM_SIZE_256 + 12] << 8) | kickmem_bank.baseaddr[ROM_SIZE_256 + 13];
850 	} else {
851 		a1000_kickstart_mode = 1;
852 		memcpy (kickmem_bank.baseaddr, a1000_bootrom, ROM_SIZE_256);
853 		kickstart_version = 0;
854 	}
855 	if (kickstart_version == 0xffff)
856 		kickstart_version = 0;
857 }
858 
a1000_reset(void)859 void a1000_reset (void)
860 {
861 	a1000_handle_kickstart (1);
862 }
863 
864 static void REGPARAM3 kickmem_lput (uaecptr, uae_u32) REGPARAM;
865 static void REGPARAM3 kickmem_wput (uaecptr, uae_u32) REGPARAM;
866 static void REGPARAM3 kickmem_bput (uaecptr, uae_u32) REGPARAM;
867 
868 MEMORY_BGET(kickmem);
869 MEMORY_WGET(kickmem);
870 MEMORY_LGET(kickmem);
871 MEMORY_CHECK(kickmem);
872 MEMORY_XLATE(kickmem);
873 
kickmem_lput(uaecptr addr,uae_u32 b)874 static void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
875 {
876 	uae_u32 *m;
877 	if (currprefs.rom_readwrite && rom_write_enabled) {
878 		addr &= kickmem_bank.mask;
879 		m = (uae_u32 *)(kickmem_bank.baseaddr + addr);
880 		do_put_mem_long (m, b);
881 #if 0
882 		if (addr == ROM_SIZE_512-4) {
883 			rom_write_enabled = false;
884 			write_log (_T("ROM write disabled\n"));
885 		}
886 #endif
887 	} else if (a1000_kickstart_mode) {
888 		if (addr >= 0xfc0000) {
889 			addr &= kickmem_bank.mask;
890 			m = (uae_u32 *)(kickmem_bank.baseaddr + addr);
891 			do_put_mem_long (m, b);
892 			return;
893 		} else
894 			a1000_handle_kickstart (0);
895 	} else if (currprefs.illegal_mem) {
896 		write_log (_T("Illegal kickmem lput at %08x\n"), addr);
897 	}
898 }
899 
kickmem_wput(uaecptr addr,uae_u32 b)900 static void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
901 {
902 	uae_u16 *m;
903 	if (currprefs.rom_readwrite && rom_write_enabled) {
904 		addr &= kickmem_bank.mask;
905 		m = (uae_u16 *)(kickmem_bank.baseaddr + addr);
906 		do_put_mem_word (m, b);
907 	} else if (a1000_kickstart_mode) {
908 		if (addr >= 0xfc0000) {
909 			addr &= kickmem_bank.mask;
910 			m = (uae_u16 *)(kickmem_bank.baseaddr + addr);
911 			do_put_mem_word (m, b);
912 			return;
913 		} else
914 			a1000_handle_kickstart (0);
915 	} else if (currprefs.illegal_mem) {
916 		write_log (_T("Illegal kickmem wput at %08x\n"), addr);
917 	}
918 }
919 
kickmem_bput(uaecptr addr,uae_u32 b)920 static void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
921 {
922 	if (currprefs.rom_readwrite && rom_write_enabled) {
923 		addr &= kickmem_bank.mask;
924 		kickmem_bank.baseaddr[addr] = b;
925 	} else if (a1000_kickstart_mode) {
926 		if (addr >= 0xfc0000) {
927 			addr &= kickmem_bank.mask;
928 			kickmem_bank.baseaddr[addr] = b;
929 			return;
930 		} else
931 			a1000_handle_kickstart (0);
932 	} else if (currprefs.illegal_mem) {
933 		write_log (_T("Illegal kickmem bput at %08x\n"), addr);
934 	}
935 }
936 
kickmem2_lput(uaecptr addr,uae_u32 l)937 static void REGPARAM2 kickmem2_lput (uaecptr addr, uae_u32 l)
938 {
939 	uae_u32 *m;
940 	addr &= kickmem_bank.mask;
941 	m = (uae_u32 *)(kickmem_bank.baseaddr + addr);
942 	do_put_mem_long (m, l);
943 }
944 
kickmem2_wput(uaecptr addr,uae_u32 w)945 static void REGPARAM2 kickmem2_wput (uaecptr addr, uae_u32 w)
946 {
947 	uae_u16 *m;
948 	addr &= kickmem_bank.mask;
949 	m = (uae_u16 *)(kickmem_bank.baseaddr + addr);
950 	do_put_mem_word (m, w);
951 }
952 
kickmem2_bput(uaecptr addr,uae_u32 b)953 static void REGPARAM2 kickmem2_bput (uaecptr addr, uae_u32 b)
954 {
955 	addr &= kickmem_bank.mask;
956 	kickmem_bank.baseaddr[addr] = b;
957 }
958 
959 /* CD32/CDTV extended kick memory */
960 
961 static int extendedkickmem_type;
962 
963 #define EXTENDED_ROM_CD32 1
964 #define EXTENDED_ROM_CDTV 2
965 #define EXTENDED_ROM_KS 3
966 #define EXTENDED_ROM_ARCADIA 4
967 
968 static void REGPARAM3 extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
969 static void REGPARAM3 extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
970 static void REGPARAM3 extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
971 
972 MEMORY_BGET(extendedkickmem);
973 MEMORY_WGET(extendedkickmem);
974 MEMORY_LGET(extendedkickmem);
975 MEMORY_CHECK(extendedkickmem);
976 MEMORY_XLATE(extendedkickmem);
977 
extendedkickmem_lput(uaecptr addr,uae_u32 b)978 static void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
979 {
980 	if (currprefs.illegal_mem)
981 		write_log (_T("Illegal extendedkickmem lput at %08x\n"), addr);
982 }
extendedkickmem_wput(uaecptr addr,uae_u32 b)983 static void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
984 {
985 	if (currprefs.illegal_mem)
986 		write_log (_T("Illegal extendedkickmem wput at %08x\n"), addr);
987 }
extendedkickmem_bput(uaecptr addr,uae_u32 b)988 static void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
989 {
990 	if (currprefs.illegal_mem)
991 		write_log (_T("Illegal extendedkickmem lput at %08x\n"), addr);
992 }
993 
994 
995 static void REGPARAM3 extendedkickmem2_lput (uaecptr, uae_u32) REGPARAM;
996 static void REGPARAM3 extendedkickmem2_wput (uaecptr, uae_u32) REGPARAM;
997 static void REGPARAM3 extendedkickmem2_bput (uaecptr, uae_u32) REGPARAM;
998 
999 MEMORY_BGET(extendedkickmem2);
1000 MEMORY_WGET(extendedkickmem2);
1001 MEMORY_LGET(extendedkickmem2);
1002 MEMORY_CHECK(extendedkickmem2);
1003 MEMORY_XLATE(extendedkickmem2);
1004 
extendedkickmem2_lput(uaecptr addr,uae_u32 b)1005 static void REGPARAM2 extendedkickmem2_lput (uaecptr addr, uae_u32 b)
1006 {
1007 	if (currprefs.illegal_mem)
1008 		write_log (_T("Illegal extendedkickmem2 lput at %08x\n"), addr);
1009 }
extendedkickmem2_wput(uaecptr addr,uae_u32 b)1010 static void REGPARAM2 extendedkickmem2_wput (uaecptr addr, uae_u32 b)
1011 {
1012 	if (currprefs.illegal_mem)
1013 		write_log (_T("Illegal extendedkickmem2 wput at %08x\n"), addr);
1014 }
extendedkickmem2_bput(uaecptr addr,uae_u32 b)1015 static void REGPARAM2 extendedkickmem2_bput (uaecptr addr, uae_u32 b)
1016 {
1017 	if (currprefs.illegal_mem)
1018 		write_log (_T("Illegal extendedkickmem2 lput at %08x\n"), addr);
1019 }
1020 
1021 /* Default memory access functions */
1022 
default_check(uaecptr a,uae_u32 b)1023 int REGPARAM2 default_check (uaecptr a, uae_u32 b)
1024 {
1025 	return 0;
1026 }
1027 
1028 static int be_cnt;
1029 
default_xlate(uaecptr addr)1030 uae_u8 *REGPARAM2 default_xlate (uaecptr addr)
1031 {
1032 	static int recursive;
1033 
1034 	if (recursive) {
1035 		cpu_halt(CPU_HALT_OPCODE_FETCH_FROM_NON_EXISTING_ADDRESS);
1036 		return kickmem_xlate(2);
1037 	}
1038 	recursive++;
1039 	int size = currprefs.cpu_model >= 68020 ? 4 : 2;
1040 	if (quit_program == 0) {
1041 		/* do this only in 68010+ mode, there are some tricky A500 programs.. */
1042 		if ((currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) && !currprefs.mmu_model) {
1043 #if defined(ENFORCER)
1044 			enforcer_disable ();
1045 #endif
1046 			if (be_cnt < 3) {
1047 				int i, j;
1048 				uaecptr a2 = addr - 32;
1049 				uaecptr a3 = m68k_getpc () - 32;
1050 				write_log (_T("Your Amiga program just did something terribly stupid %08X PC=%08X\n"), addr, M68K_GETPC);
1051 				if (debugging || DEBUG_STUPID) {
1052 					activate_debugger ();
1053 					m68k_dumpstate (0);
1054 				}
1055 				for (i = 0; i < 10; i++) {
1056 					write_log (_T("%08X "), i >= 5 ? a3 : a2);
1057 					for (j = 0; j < 16; j += 2) {
1058 						write_log (_T(" %04X"), get_word (i >= 5 ? a3 : a2));
1059 						if (i >= 5) a3 += 2; else a2 += 2;
1060 					}
1061 					write_log (_T("\n"));
1062 				}
1063 				memory_map_dump ();
1064 			}
1065 			if (0 || (gary_toenb && (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))))) {
1066 				exception2 (addr, false, size, regs.s ? 4 : 0);
1067 			} else {
1068 				cpu_halt(CPU_HALT_OPCODE_FETCH_FROM_NON_EXISTING_ADDRESS);
1069 			}
1070 		}
1071 	}
1072 	recursive--;
1073 	return kickmem_xlate (2); /* So we don't crash. */
1074 }
1075 
1076 /* Address banks */
1077 
1078 addrbank dummy_bank = {
1079 	dummy_lget, dummy_wget, dummy_bget,
1080 	dummy_lput, dummy_wput, dummy_bput,
1081 	default_xlate, dummy_check, NULL, NULL, NULL,
1082 	dummy_lgeti, dummy_wgeti,
1083 	ABFLAG_NONE, S_READ, S_WRITE
1084 };
1085 
1086 addrbank ones_bank = {
1087 	ones_get, ones_get, ones_get,
1088 	none_put, none_put, none_put,
1089 	default_xlate, dummy_check, NULL, NULL, _T("Ones"),
1090 	dummy_lgeti, dummy_wgeti,
1091 	ABFLAG_NONE, S_READ, S_WRITE
1092 };
1093 
1094 addrbank chipmem_bank = {
1095 	chipmem_lget, chipmem_wget, chipmem_bget,
1096 	chipmem_lput, chipmem_wput, chipmem_bput,
1097 	chipmem_xlate, chipmem_check, NULL, _T("chip"), _T("Chip memory"),
1098 	chipmem_lget, chipmem_wget,
1099 	ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CHIPRAM, 0, 0
1100 };
1101 
1102 addrbank chipmem_dummy_bank = {
1103 	chipmem_dummy_lget, chipmem_dummy_wget, chipmem_dummy_bget,
1104 	chipmem_dummy_lput, chipmem_dummy_wput, chipmem_dummy_bput,
1105 	default_xlate, dummy_check, NULL, NULL, _T("Dummy Chip memory"),
1106 	dummy_lgeti, dummy_wgeti,
1107 	ABFLAG_IO | ABFLAG_CHIPRAM, S_READ, S_WRITE
1108 };
1109 
1110 
1111 #ifdef AGA
1112 addrbank chipmem_bank_ce2 = {
1113 	chipmem_lget_ce2, chipmem_wget_ce2, chipmem_bget_ce2,
1114 	chipmem_lput_ce2, chipmem_wput_ce2, chipmem_bput_ce2,
1115 	chipmem_xlate, chipmem_check, NULL, NULL, _T("Chip memory (68020 'ce')"),
1116 	chipmem_lget_ce2, chipmem_wget_ce2,
1117 	ABFLAG_RAM | ABFLAG_CHIPRAM, S_READ, S_WRITE
1118 };
1119 #endif
1120 
1121 addrbank bogomem_bank = {
1122 	bogomem_lget, bogomem_wget, bogomem_bget,
1123 	bogomem_lput, bogomem_wput, bogomem_bput,
1124 	bogomem_xlate, bogomem_check, NULL, _T("bogo"), _T("Slow memory"),
1125 	bogomem_lget, bogomem_wget,
1126 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1127 };
1128 
1129 addrbank cardmem_bank = {
1130 	cardmem_lget, cardmem_wget, cardmem_bget,
1131 	cardmem_lput, cardmem_wput, cardmem_bput,
1132 	cardmem_xlate, cardmem_check, NULL, _T("rom_e0"), _T("CDTV memory card"),
1133 	cardmem_lget, cardmem_wget,
1134 	ABFLAG_RAM, 0, 0
1135 };
1136 
1137 addrbank mem25bit_bank = {
1138 	mem25bit_lget, mem25bit_wget, mem25bit_bget,
1139 	mem25bit_lput, mem25bit_wput, mem25bit_bput,
1140 	mem25bit_xlate, mem25bit_check, NULL, _T("25bitmem"), _T("25bit memory"),
1141 	mem25bit_lget, mem25bit_wget,
1142 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1143 };
1144 
1145 addrbank a3000lmem_bank = {
1146 	a3000lmem_lget, a3000lmem_wget, a3000lmem_bget,
1147 	a3000lmem_lput, a3000lmem_wput, a3000lmem_bput,
1148 	a3000lmem_xlate, a3000lmem_check, NULL, _T("ramsey_low"), _T("RAMSEY memory (low)"),
1149 	a3000lmem_lget, a3000lmem_wget,
1150 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1151 };
1152 
1153 addrbank a3000hmem_bank = {
1154 	a3000hmem_lget, a3000hmem_wget, a3000hmem_bget,
1155 	a3000hmem_lput, a3000hmem_wput, a3000hmem_bput,
1156 	a3000hmem_xlate, a3000hmem_check, NULL, _T("ramsey_high"), _T("RAMSEY memory (high)"),
1157 	a3000hmem_lget, a3000hmem_wget,
1158 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1159 };
1160 
1161 addrbank kickmem_bank = {
1162 	kickmem_lget, kickmem_wget, kickmem_bget,
1163 	kickmem_lput, kickmem_wput, kickmem_bput,
1164 	kickmem_xlate, kickmem_check, NULL, _T("kick"), _T("Kickstart ROM"),
1165 	kickmem_lget, kickmem_wget,
1166 	ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE
1167 };
1168 
1169 addrbank kickram_bank = {
1170 	kickmem_lget, kickmem_wget, kickmem_bget,
1171 	kickmem2_lput, kickmem2_wput, kickmem2_bput,
1172 	kickmem_xlate, kickmem_check, NULL, NULL, _T("Kickstart Shadow RAM"),
1173 	kickmem_lget, kickmem_wget,
1174 	ABFLAG_UNK | ABFLAG_SAFE, 0, S_WRITE
1175 };
1176 
1177 addrbank extendedkickmem_bank = {
1178 	extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
1179 	extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
1180 	extendedkickmem_xlate, extendedkickmem_check, NULL, NULL, _T("Extended Kickstart ROM"),
1181 	extendedkickmem_lget, extendedkickmem_wget,
1182 	ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE
1183 };
1184 addrbank extendedkickmem2_bank = {
1185 	extendedkickmem2_lget, extendedkickmem2_wget, extendedkickmem2_bget,
1186 	extendedkickmem2_lput, extendedkickmem2_wput, extendedkickmem2_bput,
1187 	extendedkickmem2_xlate, extendedkickmem2_check, NULL, _T("rom_a8"), _T("Extended 2nd Kickstart ROM"),
1188 	extendedkickmem2_lget, extendedkickmem2_wget,
1189 	ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE
1190 };
1191 
1192 MEMORY_FUNCTIONS(custmem1);
1193 MEMORY_FUNCTIONS(custmem2);
1194 
1195 addrbank custmem1_bank = {
1196 	custmem1_lget, custmem1_wget, custmem1_bget,
1197 	custmem1_lput, custmem1_wput, custmem1_bput,
1198 	custmem1_xlate, custmem1_check, NULL, _T("custmem1"), _T("Non-autoconfig RAM #1"),
1199 	custmem1_lget, custmem1_wget,
1200 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1201 };
1202 addrbank custmem2_bank = {
1203 	custmem2_lget, custmem2_wget, custmem2_bget,
1204 	custmem2_lput, custmem2_wput, custmem2_bput,
1205 	custmem2_xlate, custmem2_check, NULL, _T("custmem2"), _T("Non-autoconfig RAM #2"),
1206 	custmem2_lget, custmem2_wget,
1207 	ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
1208 };
1209 
1210 #define fkickmem_size ROM_SIZE_512
1211 static int a3000_f0;
a3000_fakekick(int map)1212 void a3000_fakekick (int map)
1213 {
1214 	static uae_u8 *kickstore;
1215 
1216 	protect_roms (false);
1217 	if (map) {
1218 		uae_u8 *fkickmemory = a3000lmem_bank.baseaddr + a3000lmem_bank.allocated - fkickmem_size;
1219 		if (fkickmemory[2] == 0x4e && fkickmemory[3] == 0xf9 && fkickmemory[4] == 0x00) {
1220 			if (!kickstore)
1221 				kickstore = xmalloc (uae_u8, fkickmem_size);
1222 			memcpy (kickstore, kickmem_bank.baseaddr, fkickmem_size);
1223 			if (fkickmemory[5] == 0xfc) {
1224 				memcpy (kickmem_bank.baseaddr, fkickmemory, fkickmem_size / 2);
1225 				memcpy (kickmem_bank.baseaddr + fkickmem_size / 2, fkickmemory, fkickmem_size / 2);
1226 				extendedkickmem_bank.allocated = 65536;
1227 				extendedkickmem_bank.label = _T("rom_f0");
1228 				extendedkickmem_bank.mask = extendedkickmem_bank.allocated - 1;
1229 				mapped_malloc (&extendedkickmem_bank);
1230 				memcpy (extendedkickmem_bank.baseaddr, fkickmemory + fkickmem_size / 2, 65536);
1231 				map_banks (&extendedkickmem_bank, 0xf0, 1, 1);
1232 				a3000_f0 = 1;
1233 			} else {
1234 				memcpy (kickmem_bank.baseaddr, fkickmemory, fkickmem_size);
1235 			}
1236 		}
1237 	} else {
1238 		if (a3000_f0) {
1239 			map_banks (&dummy_bank, 0xf0, 1, 1);
1240 			mapped_free (&extendedkickmem_bank);
1241 			a3000_f0 = 0;
1242 		}
1243 		if (kickstore)
1244 			memcpy (kickmem_bank.baseaddr, kickstore, fkickmem_size);
1245 		xfree (kickstore);
1246 		kickstore = NULL;
1247 	}
1248 	protect_roms (true);
1249 }
1250 
1251 static const uae_char *kickstring = "exec.library";
1252 
1253 #ifdef FSUAE // NL
1254 
log_kickstart(uae_u8 * mem,int size)1255 static void log_kickstart(uae_u8 *mem, int size)
1256 {
1257 	uae_u32 crc32 = get_crc32(mem, size);
1258 	struct romdata *rd = getromdatabycrc(crc32);
1259 	if (rd) {
1260 		char tmp[MAX_DPATH];
1261 		getromname(rd, tmp);
1262 		printf("UAE: %s\n", tmp);
1263 	} else {
1264 		printf("UAE: KS ROM %08x (%d bytes)\n", crc32, size);
1265 	}
1266 }
1267 
1268 #endif
1269 
read_kickstart(struct zfile * f,uae_u8 * mem,int size,int dochecksum,int noalias)1270 static int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int noalias)
1271 {
1272 	uae_char buffer[20];
1273 	int i, j, oldpos;
1274 	int cr = 0, kickdisk = 0;
1275 
1276 	if (size < 0) {
1277 		zfile_fseek (f, 0, SEEK_END);
1278 		size = zfile_ftell (f) & ~0x3ff;
1279 		zfile_fseek (f, 0, SEEK_SET);
1280 	}
1281 	oldpos = zfile_ftell (f);
1282 	i = zfile_fread (buffer, 1, 11, f);
1283 	if (!memcmp (buffer, "KICK", 4)) {
1284 		zfile_fseek (f, 512, SEEK_SET);
1285 		kickdisk = 1;
1286 #if 0
1287 	} else if (size >= ROM_SIZE_512 && !memcmp (buffer, "AMIG", 4)) {
1288 		/* ReKick */
1289 		zfile_fseek (f, oldpos + 0x6c, SEEK_SET);
1290 		cr = 2;
1291 #endif
1292 	} else if (memcmp ((uae_char*)buffer, "AMIROMTYPE1", 11) != 0) {
1293 		zfile_fseek (f, oldpos, SEEK_SET);
1294 	} else {
1295 		cloanto_rom = 1;
1296 		cr = 1;
1297 	}
1298 
1299 	memset (mem, 0, size);
1300 	for (i = 0; i < 8; i++)
1301 		mem[size - 16 + i * 2 + 1] = 0x18 + i;
1302 	mem[size - 20] = size >> 24;
1303 	mem[size - 19] = size >> 16;
1304 	mem[size - 18] = size >>  8;
1305 	mem[size - 17] = size >>  0;
1306 
1307 	i = zfile_fread (mem, 1, size, f);
1308 
1309 	if (kickdisk && i > ROM_SIZE_256)
1310 		i = ROM_SIZE_256;
1311 #if 0
1312 	if (i >= ROM_SIZE_256 && (i != ROM_SIZE_256 && i != ROM_SIZE_512 && i != ROM_SIZE_512 * 2 && i != ROM_SIZE_512 * 4)) {
1313 		notify_user (NUMSG_KSROMREADERROR);
1314 		return 0;
1315 	}
1316 #endif
1317 	if (i < size - 20)
1318 		kickstart_fix_checksum (mem, size);
1319 	j = 1;
1320 	while (j < i)
1321 		j <<= 1;
1322 	i = j;
1323 
1324 	if (!noalias && i == size / 2)
1325 		memcpy (mem + size / 2, mem, size / 2);
1326 
1327 	if (cr) {
1328 		if (!decode_rom (mem, size, cr, i))
1329 			return 0;
1330 	}
1331 #ifdef FSUAE
1332 	/* When i >= ROM_SIZE_256, a full kickstart ROM is in use, and we
1333 	 * don't want the A1000 KS bootstrap-specific behavior in this case. */
1334 #endif
1335 	if (currprefs.cs_a1000ram && i < ROM_SIZE_256) {
1336 		int off = 0;
1337 		if (!a1000_bootrom)
1338 			a1000_bootrom = xcalloc (uae_u8, ROM_SIZE_256);
1339 #ifdef FSUAE
1340 		/* FIXME: This loop looks a bit suspicious. When the A1000 bootstrap
1341 		 * ROM is 64 KB, this loop looks like it repeats the ROM. Fair enough,
1342 		 * but with <, it will only fill it three times and leave the upper
1343 		 * 64 KB alone (will be zeroed by xcalloc). Is this intentional, or
1344 		 * should it be <= here? -Frode. */
1345 #endif
1346 		while (off + i < ROM_SIZE_256) {
1347 			memcpy (a1000_bootrom + off, kickmem_bank.baseaddr, i);
1348 			off += i;
1349 		}
1350 		memset (kickmem_bank.baseaddr, 0, kickmem_bank.allocated);
1351 		a1000_handle_kickstart (1);
1352 		dochecksum = 0;
1353 		i = ROM_SIZE_512;
1354 	}
1355 
1356 	for (j = 0; j < 256 && i >= ROM_SIZE_256; j++) {
1357 		if (!memcmp (mem + j, kickstring, strlen (kickstring) + 1))
1358 			break;
1359 	}
1360 
1361 	if (j == 256 || i < ROM_SIZE_256)
1362 		dochecksum = 0;
1363 	if (dochecksum)
1364 		kickstart_checksum (mem, size);
1365 #ifdef FSUAE
1366 	log_kickstart(mem, i);
1367 #endif
1368 	return i;
1369 }
1370 
load_extendedkickstart(const TCHAR * romextfile,int type)1371 static bool load_extendedkickstart (const TCHAR *romextfile, int type)
1372 {
1373 	struct zfile *f;
1374 	int size, off;
1375 	bool ret = false;
1376 
1377 	if (_tcslen (romextfile) == 0)
1378 		return false;
1379 #ifdef ARCADIA
1380 	if (is_arcadia_rom (romextfile) == ARCADIA_BIOS) {
1381 		extendedkickmem_type = EXTENDED_ROM_ARCADIA;
1382 		return false;
1383 	}
1384 #endif
1385 	f = read_rom_name (romextfile);
1386 	if (!f) {
1387 		notify_user (NUMSG_NOEXTROM);
1388 		return false;
1389 	}
1390 	zfile_fseek (f, 0, SEEK_END);
1391 	size = zfile_ftell (f);
1392 	extendedkickmem_bank.allocated = ROM_SIZE_512;
1393 	off = 0;
1394 	if (type == 0) {
1395 		if (currprefs.cs_cd32cd) {
1396 			extendedkickmem_type = EXTENDED_ROM_CD32;
1397 		} else if (currprefs.cs_cdtvcd || currprefs.cs_cdtvram) {
1398 			extendedkickmem_type = EXTENDED_ROM_CDTV;
1399 		} else if (size > 300000) {
1400 			extendedkickmem_type = EXTENDED_ROM_CD32;
1401 		} else if (need_uae_boot_rom () != 0xf00000) {
1402 			extendedkickmem_type = EXTENDED_ROM_CDTV;
1403 		}
1404 	} else {
1405 		extendedkickmem_type = type;
1406 	}
1407 	if (extendedkickmem_type) {
1408 		zfile_fseek (f, off, SEEK_SET);
1409 		switch (extendedkickmem_type) {
1410 		case EXTENDED_ROM_CDTV:
1411 			extendedkickmem_bank.label = _T("rom_f0");
1412 			mapped_malloc (&extendedkickmem_bank);
1413 			extendedkickmem_bank.start = 0xf00000;
1414 			break;
1415 		case EXTENDED_ROM_CD32:
1416 			extendedkickmem_bank.label = _T("rom_e0");
1417 			mapped_malloc (&extendedkickmem_bank);
1418 			extendedkickmem_bank.start = 0xe00000;
1419 			break;
1420 		}
1421 		if (extendedkickmem_bank.baseaddr) {
1422 			read_kickstart (f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated, 0, 1);
1423 			extendedkickmem_bank.mask = extendedkickmem_bank.allocated - 1;
1424 			ret = true;
1425 		}
1426 	}
1427 	zfile_fclose (f);
1428 	return ret;
1429 }
1430 
patch_shapeshifter(uae_u8 * kickmemory)1431 static int patch_shapeshifter (uae_u8 *kickmemory)
1432 {
1433 	/* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
1434 	* Changes 'lea $400,a0' and 'lea $1000,a0' to 'lea $3000,a0' for
1435 	* ShapeShifter compatability.
1436 	*/
1437 	int i, patched = 0;
1438 	uae_u8 kickshift1[] = { 0x41, 0xf8, 0x04, 0x00 };
1439 	uae_u8 kickshift2[] = { 0x41, 0xf8, 0x10, 0x00 };
1440 	uae_u8 kickshift3[] = { 0x43, 0xf8, 0x04, 0x00 };
1441 
1442 	for (i = 0x200; i < 0x300; i++) {
1443 		if (!memcmp (kickmemory + i, kickshift1, sizeof (kickshift1)) ||
1444 			!memcmp (kickmemory + i, kickshift2, sizeof (kickshift2)) ||
1445 			!memcmp (kickmemory + i, kickshift3, sizeof (kickshift3))) {
1446 				kickmemory[i + 2] = 0x30;
1447 				write_log (_T("Kickstart KickShifted @%04X\n"), i);
1448 				patched++;
1449 		}
1450 	}
1451 	return patched;
1452 }
1453 
1454 /* disable incompatible drivers */
patch_residents(uae_u8 * kickmemory,int size)1455 static int patch_residents (uae_u8 *kickmemory, int size)
1456 {
1457 	int i, j, patched = 0;
1458 	const uae_char *residents[] = { "NCR scsi.device", NULL };
1459 	// "scsi.device", "carddisk.device", "card.resource" };
1460 	uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000;
1461 
1462 	if (currprefs.cs_mbdmac != 2) {
1463 		for (i = 0; i < size - 100; i++) {
1464 			if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
1465 				uaecptr addr;
1466 				addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
1467 				if (addr != i + base)
1468 					continue;
1469 				addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
1470 				if (addr >= base && addr < base + size) {
1471 					j = 0;
1472 					while (residents[j]) {
1473 						if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
1474 							TCHAR *s = au (residents[j]);
1475 							write_log (_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base);
1476 							xfree (s);
1477 							kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
1478 							patched++;
1479 							break;
1480 						}
1481 						j++;
1482 					}
1483 				}
1484 			}
1485 		}
1486 	}
1487 	return patched;
1488 }
1489 
patch_kick(void)1490 static void patch_kick (void)
1491 {
1492 	int patched = 0;
1493 	if (kickmem_bank.allocated >= ROM_SIZE_512 && currprefs.kickshifter)
1494 		patched += patch_shapeshifter (kickmem_bank.baseaddr);
1495 	patched += patch_residents (kickmem_bank.baseaddr, kickmem_bank.allocated);
1496 	if (extendedkickmem_bank.baseaddr) {
1497 		patched += patch_residents (extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated);
1498 		if (patched)
1499 			kickstart_fix_checksum (extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated);
1500 	}
1501 	if (patched)
1502 		kickstart_fix_checksum (kickmem_bank.baseaddr, kickmem_bank.allocated);
1503 }
1504 
1505 #ifdef FSUAE
1506 #include "fs/data.h"
1507 #else
1508 extern unsigned char arosrom[];
1509 extern unsigned int arosrom_len;
1510 #endif
1511 extern int seriallog;
load_kickstart_replacement(void)1512 static bool load_kickstart_replacement (void)
1513 {
1514 	struct zfile *f;
1515 
1516 #ifdef FSUAE // NL
1517 	char *data;
1518 	int data_size;
1519 	if (fs_data_file_content("share/fs-uae/aros-amiga-m68k-ext.bin",
1520 							 &data, &data_size) != 0) {
1521 		//printf("%d\n", false);
1522 		return false;
1523 	}
1524 	f = zfile_fopen_data(_T("aros-ext.bin"), data_size, (const uae_u8*) data);
1525 #else
1526 	f = zfile_fopen_data (_T("aros.gz"), arosrom_len, arosrom);
1527 	if (!f)
1528 		return false;
1529 	f = zfile_gunzip (f);
1530 	if (!f)
1531 		return false;
1532 #endif
1533 
1534 	extendedkickmem_bank.allocated = ROM_SIZE_512;
1535 	extendedkickmem_bank.mask = ROM_SIZE_512 - 1;
1536 	extendedkickmem_bank.label = _T("rom_e0");
1537 	extendedkickmem_type = EXTENDED_ROM_KS;
1538 	mapped_malloc (&extendedkickmem_bank);
1539 	read_kickstart (f, extendedkickmem_bank.baseaddr, ROM_SIZE_512, 0, 1);
1540 
1541 #ifdef FSUAE
1542 	zfile_fclose(f);
1543 	free(data);
1544 	if (fs_data_file_content("share/fs-uae/aros-amiga-m68k-rom.bin",
1545 							 &data, &data_size) != 0) {
1546 		return false;
1547 	}
1548 	f = zfile_fopen_data(_T("aros-rom.bin"), data_size, (const uae_u8*) data);
1549 #endif
1550 
1551 	kickmem_bank.allocated = ROM_SIZE_512;
1552 	kickmem_bank.mask = ROM_SIZE_512 - 1;
1553 	read_kickstart (f, kickmem_bank.baseaddr, ROM_SIZE_512, 1, 0);
1554 
1555 	zfile_fclose (f);
1556 #ifdef FSUAE
1557 	free(data);
1558 #endif
1559 
1560 	seriallog = -1;
1561 
1562 	// if 68000-68020 config without any other fast ram with m68k aros: enable special extra RAM.
1563 	if (currprefs.cpu_model <= 68020 &&
1564 		currprefs.cachesize == 0 &&
1565 		currprefs.fastmem_size == 0 &&
1566 		currprefs.z3fastmem_size == 0 &&
1567 		currprefs.mbresmem_high_size == 0 &&
1568 		currprefs.mbresmem_low_size == 0 &&
1569 		currprefs.cpuboardmem1_size == 0) {
1570 
1571 		changed_prefs.custom_memory_addrs[0] = currprefs.custom_memory_addrs[0] = 0xa80000;
1572 		changed_prefs.custom_memory_sizes[0] = currprefs.custom_memory_sizes[0] = 512 * 1024;
1573 		changed_prefs.custom_memory_mask[0] = currprefs.custom_memory_mask[0] = 0;
1574 		changed_prefs.custom_memory_addrs[1] = currprefs.custom_memory_addrs[1] = 0xb00000;
1575 		changed_prefs.custom_memory_sizes[1] = currprefs.custom_memory_sizes[1] = 512 * 1024;
1576 		changed_prefs.custom_memory_mask[1] = currprefs.custom_memory_mask[1] = 0;
1577 
1578 	}
1579 
1580 	return true;
1581 }
1582 
load_kickstart(void)1583 static int load_kickstart (void)
1584 {
1585 	struct zfile *f;
1586 	TCHAR tmprom[MAX_DPATH], tmprom2[MAX_DPATH];
1587 
1588 	cloanto_rom = 0;
1589 	if (!_tcscmp (currprefs.romfile, _T(":AROS")))
1590 		return load_kickstart_replacement ();
1591 	f = read_rom_name (currprefs.romfile);
1592 	_tcscpy (tmprom, currprefs.romfile);
1593 	if (f == NULL) {
1594 		_stprintf (tmprom2, _T("%s%s"), start_path_data, currprefs.romfile);
1595 		f = rom_fopen (tmprom2, _T("rb"), ZFD_NORMAL);
1596 		if (f == NULL) {
1597 			_stprintf (currprefs.romfile, _T("%sroms/kick.rom"), start_path_data);
1598 			f = rom_fopen (currprefs.romfile, _T("rb"), ZFD_NORMAL);
1599 			if (f == NULL) {
1600 				_stprintf (currprefs.romfile, _T("%skick.rom"), start_path_data);
1601 				f = rom_fopen (currprefs.romfile, _T("rb"), ZFD_NORMAL);
1602 				if (f == NULL) {
1603 					_stprintf (currprefs.romfile, _T("%s../shared/rom/kick.rom"), start_path_data);
1604 					f = rom_fopen (currprefs.romfile, _T("rb"), ZFD_NORMAL);
1605 					if (f == NULL) {
1606 						_stprintf (currprefs.romfile, _T("%s../System/rom/kick.rom"), start_path_data);
1607 						f = rom_fopen (currprefs.romfile, _T("rb"), ZFD_NORMAL);
1608 						if (f == NULL)
1609 							f = read_rom_name_guess (tmprom);
1610 					}
1611 				}
1612 			}
1613 		} else {
1614 			_tcscpy (currprefs.romfile, tmprom2);
1615 		}
1616 	}
1617 	addkeydir (currprefs.romfile);
1618 	if (f == NULL) /* still no luck */
1619 		goto err;
1620 
1621 	if (f != NULL) {
1622 #ifdef FSUAE
1623 #if 0
1624 		printf("KICKSTART: %s\n", currprefs.romfile);
1625 #endif
1626 #endif
1627 		int filesize, size, maxsize;
1628 		int kspos = ROM_SIZE_512;
1629 		int extpos = 0;
1630 
1631 		maxsize = ROM_SIZE_512;
1632 		zfile_fseek (f, 0, SEEK_END);
1633 		filesize = zfile_ftell (f);
1634 		zfile_fseek (f, 0, SEEK_SET);
1635 		if (filesize == 1760 * 512) {
1636 			filesize = ROM_SIZE_256;
1637 			maxsize = ROM_SIZE_256;
1638 		}
1639 		if (filesize == ROM_SIZE_512 + 8) {
1640 			/* GVP 0xf0 kickstart */
1641 			zfile_fseek (f, 8, SEEK_SET);
1642 		}
1643 		if (filesize >= ROM_SIZE_512 * 2) {
1644 #ifdef FSUAE
1645 			// FIXME: is the intention here to find kspos via romdata?
1646 #endif
1647 			struct romdata *rd = getromdatabyzfile(f);
1648 			zfile_fseek (f, kspos, SEEK_SET);
1649 		}
1650 		if (filesize >= ROM_SIZE_512 * 4) {
1651 			kspos = ROM_SIZE_512 * 3;
1652 			extpos = 0;
1653 			zfile_fseek (f, kspos, SEEK_SET);
1654 		}
1655 		size = read_kickstart (f, kickmem_bank.baseaddr, maxsize, 1, 0);
1656 		if (size == 0)
1657 			goto err;
1658 		kickmem_bank.mask = size - 1;
1659 		kickmem_bank.allocated = size;
1660 		if (filesize >= ROM_SIZE_512 * 2 && !extendedkickmem_type) {
1661 			extendedkickmem_bank.allocated = ROM_SIZE_512;
1662 			if (currprefs.cs_cdtvcd || currprefs.cs_cdtvram) {
1663 				extendedkickmem_type = EXTENDED_ROM_CDTV;
1664 				extendedkickmem_bank.allocated *= 2;
1665 				extendedkickmem_bank.label = _T("rom_f0");
1666 				extendedkickmem_bank.start = 0xf00000;
1667 			} else {
1668 				extendedkickmem_type = EXTENDED_ROM_KS;
1669 				extendedkickmem_bank.label = _T("rom_e0");
1670 				extendedkickmem_bank.start = 0xe00000;
1671 			}
1672 			mapped_malloc (&extendedkickmem_bank);
1673 			zfile_fseek (f, extpos, SEEK_SET);
1674 			read_kickstart (f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated, 0, 1);
1675 			extendedkickmem_bank.mask = extendedkickmem_bank.allocated - 1;
1676 		}
1677 		if (filesize > ROM_SIZE_512 * 2) {
1678 			extendedkickmem2_bank.allocated = ROM_SIZE_512 * 2;
1679 			mapped_malloc (&extendedkickmem2_bank);
1680 			zfile_fseek (f, extpos + ROM_SIZE_512, SEEK_SET);
1681 			read_kickstart (f, extendedkickmem2_bank.baseaddr, ROM_SIZE_512, 0, 1);
1682 			zfile_fseek (f, extpos + ROM_SIZE_512 * 2, SEEK_SET);
1683 			read_kickstart (f, extendedkickmem2_bank.baseaddr + ROM_SIZE_512, ROM_SIZE_512, 0, 1);
1684 			extendedkickmem2_bank.mask = extendedkickmem2_bank.allocated - 1;
1685 			extendedkickmem2_bank.start = 0xa80000;
1686 		}
1687 	}
1688 
1689 #if defined(AMIGA)
1690 chk_sum:
1691 #endif
1692 
1693 	kickstart_version = (kickmem_bank.baseaddr[12] << 8) | kickmem_bank.baseaddr[13];
1694 	if (kickstart_version == 0xffff) {
1695 		// 1.0-1.1 and older
1696 		kickstart_version = (kickmem_bank.baseaddr[16] << 8) | kickmem_bank.baseaddr[17];
1697 		if (kickstart_version > 33)
1698 			kickstart_version = 0;
1699 	}
1700 	zfile_fclose (f);
1701 	return 1;
1702 err:
1703 	_tcscpy (currprefs.romfile, tmprom);
1704 	zfile_fclose (f);
1705 	return 0;
1706 }
1707 
1708 #ifndef NATMEM_OFFSET
1709 
mapped_malloc(addrbank * ab)1710 bool mapped_malloc (addrbank *ab)
1711 {
1712 	ab->startmask = ab->start;
1713 	ab->baseaddr = xcalloc (uae_u8, ab->allocated + 4);
1714 	return ab->baseaddr != NULL;
1715 }
1716 
mapped_free(addrbank * ab)1717 void mapped_free (addrbank *ab)
1718 {
1719 	xfree(ab->baseaddr);
1720 	ab->baseaddr = NULL;
1721 }
1722 
1723 #else
1724 
1725 #include <uae/mman.h>
1726 
1727 shmpiece *shm_start;
1728 
dumplist(void)1729 static void dumplist (void)
1730 {
1731 	shmpiece *x = shm_start;
1732 	write_log (_T("Start Dump:\n"));
1733 	while (x) {
1734 		write_log (_T("this=%p,Native %p,id %d,prev=%p,next=%p,size=0x%08x\n"),
1735 			x, x->native_address, x->id, x->prev, x->next, x->size);
1736 		x = x->next;
1737 	}
1738 	write_log (_T("End Dump:\n"));
1739 }
1740 
find_shmpiece(uae_u8 * base,bool safe)1741 static shmpiece *find_shmpiece (uae_u8 *base, bool safe)
1742 {
1743 	shmpiece *x = shm_start;
1744 
1745 	while (x && x->native_address != base)
1746 		x = x->next;
1747 	if (!x) {
1748 		if (safe || bogomem_aliasing)
1749 			return 0;
1750 		write_log (_T("NATMEM: Failure to find mapping at %08lx, %p\n"), base - NATMEM_OFFSET, base);
1751 		nocanbang ();
1752 		return 0;
1753 	}
1754 	return x;
1755 }
1756 
delete_shmmaps(uae_u32 start,uae_u32 size)1757 static void delete_shmmaps (uae_u32 start, uae_u32 size)
1758 {
1759 	if (!needmman ())
1760 		return;
1761 
1762 	while (size) {
1763 		uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1764 		if (base) {
1765 			shmpiece *x;
1766 			//base = ((uae_u8*)NATMEM_OFFSET)+start;
1767 
1768 			x = find_shmpiece (base, true);
1769 			if (!x)
1770 				return;
1771 
1772 			if (x->size > size) {
1773 				if (isdirectjit ())
1774 					write_log (_T("NATMEM WARNING: size mismatch mapping at %08x (size %08x, delsize %08x)\n"),start,x->size,size);
1775 				size = x->size;
1776 			}
1777 
1778 			uae_shmdt (x->native_address);
1779 			size -= x->size;
1780 			start += x->size;
1781 			if (x->next)
1782 				x->next->prev = x->prev;	/* remove this one from the list */
1783 			if (x->prev)
1784 				x->prev->next = x->next;
1785 			else
1786 				shm_start = x->next;
1787 			xfree (x);
1788 		} else {
1789 			size -= 0x10000;
1790 			start += 0x10000;
1791 		}
1792 	}
1793 }
1794 
add_shmmaps(uae_u32 start,addrbank * what)1795 static void add_shmmaps (uae_u32 start, addrbank *what)
1796 {
1797 	shmpiece *x = shm_start;
1798 	shmpiece *y;
1799 	uae_u8 *base = what->baseaddr;
1800 
1801 	if (!needmman ())
1802 		return;
1803 
1804 	if (!base)
1805 		return;
1806 
1807 	x = find_shmpiece (base, false);
1808 	if (!x)
1809 		return;
1810 
1811 	y = xmalloc (shmpiece, 1);
1812 	*y = *x;
1813 	base = ((uae_u8 *) NATMEM_OFFSET) + start;
1814 	y->native_address = (uae_u8*)uae_shmat (what, y->id, base, 0);
1815 	if (y->native_address == (void *) -1) {
1816 		write_log (_T("NATMEM: Failure to map existing at %08x (%p)\n"), start, base);
1817 		dumplist ();
1818 		nocanbang ();
1819 		return;
1820 	}
1821 	y->next = shm_start;
1822 	y->prev = NULL;
1823 	if (y->next)
1824 		y->next->prev = y;
1825 	shm_start = y;
1826 }
1827 
1828 #define MAPPED_MALLOC_DEBUG 0
1829 
mapped_malloc(addrbank * ab)1830 bool mapped_malloc (addrbank *ab)
1831 {
1832 #ifdef FSUAE
1833 	write_log(_T("MMAN: mapped_malloc 0x%08x start=0x%08x %s (%s)\n"),
1834 			  ab->allocated, ab->start, ab->name, ab->label);
1835 	write_log(_T("MMAN: Flags:%s%s%s%s%s%s%s%s%s%s%s\n"),
1836 			  (ab->flags & ABFLAG_RAM) ? " RAM" : "",
1837 			  (ab->flags & ABFLAG_ROM) ? " ROM" : "",
1838 			  (ab->flags & ABFLAG_ROMIN) ? " ROMIN" : "",
1839 			  (ab->flags & ABFLAG_IO) ? " IO" : "",
1840 			  (ab->flags & ABFLAG_NONE) ? " NONE" : "",
1841 			  (ab->flags & ABFLAG_SAFE) ? " SAFE" : "",
1842 			  (ab->flags & ABFLAG_INDIRECT) ? " INDIRECT" : "",
1843 			  (ab->flags & ABFLAG_NOALLOC) ? " NOALLOC" : "",
1844 			  (ab->flags & ABFLAG_RTG) ? " RTG" : "",
1845 			  (ab->flags & ABFLAG_THREADSAFE) ? " THREADSAFE" : "",
1846 			  (ab->flags & ABFLAG_DIRECTMAP) ? " DIRECTMAP" : "");
1847 #endif
1848 	int id;
1849 	void *answer;
1850 	shmpiece *x;
1851 	bool rtgmem = (ab->flags & ABFLAG_RTG) != 0;
1852 	static int recurse;
1853 
1854 	ab->startmask = ab->start;
1855 	if (!needmman () && (!rtgmem || currprefs.cpu_model < 68020)) {
1856 		nocanbang ();
1857 		ab->flags &= ~ABFLAG_DIRECTMAP;
1858 		if (ab->flags & ABFLAG_NOALLOC) {
1859 #if MAPPED_MALLOC_DEBUG
1860 			write_log(_T("mapped_malloc noalloc %s\n"), ab->name);
1861 #endif
1862 			return true;
1863 		}
1864 		ab->baseaddr = xcalloc (uae_u8, ab->allocated + 4);
1865 #if MAPPED_MALLOC_DEBUG
1866 		write_log(_T("mapped_malloc nodirect %s %p\n"), ab->name, ab->baseaddr);
1867 #endif
1868 		return ab->baseaddr != NULL;
1869 	}
1870 
1871 	id = uae_shmget (UAE_IPC_PRIVATE, ab->allocated, 0x1ff, ab->label);
1872 	if (id == -1) {
1873 		nocanbang ();
1874 		if (recurse)
1875 			return 0;
1876 		recurse++;
1877 		mapped_malloc (ab);
1878 		recurse--;
1879 		return ab->baseaddr != NULL;
1880 	}
1881 	if (!(ab->flags & ABFLAG_NOALLOC)) {
1882 		answer = uae_shmat (ab, id, 0, 0);
1883 		uae_shmctl (id, UAE_IPC_RMID, NULL);
1884 	} else {
1885 		write_log(_T("MMAN: mapped_malloc using existing baseaddr %p\n"), ab->baseaddr);
1886 		answer = ab->baseaddr;
1887 	}
1888 	if (answer != (void *) -1) {
1889 		x = xmalloc (shmpiece, 1);
1890 		x->native_address = (uae_u8*)answer;
1891 		x->id = id;
1892 		x->size = ab->allocated;
1893 		x->name = ab->label;
1894 		x->next = shm_start;
1895 		x->prev = NULL;
1896 		if (x->next)
1897 			x->next->prev = x;
1898 		shm_start = x;
1899 		ab->baseaddr = x->native_address;
1900 		ab->flags |= ABFLAG_DIRECTMAP;
1901 #if MAPPED_MALLOC_DEBUG
1902 		write_log(_T("mapped_malloc direct %s %p\n"), ab->name, ab->baseaddr);
1903 #endif
1904 		return ab->baseaddr != NULL;
1905 	}
1906 	if (recurse)
1907 		return 0;
1908 	nocanbang ();
1909 	recurse++;
1910 	mapped_malloc (ab);
1911 	recurse--;
1912 #if MAPPED_MALLOC_DEBUG
1913 	write_log(_T("mapped_malloc indirect %s %p\n"), ab->name, ab->baseaddr);
1914 #endif
1915 	return ab->baseaddr != NULL;
1916 }
1917 
1918 #endif
1919 
init_mem_banks(void)1920 static void init_mem_banks (void)
1921 {
1922 	// unsigned so i << 16 won't overflow to negative when i >= 32768
1923 	for (unsigned int i = 0; i < MEMORY_BANKS; i++)
1924 		put_mem_bank (i << 16, &dummy_bank, 0);
1925 #ifdef NATMEM_OFFSET
1926 	delete_shmmaps (0, 0xFFFF0000);
1927 #endif
1928 }
1929 
singlebit(uae_u32 v)1930 static bool singlebit (uae_u32 v)
1931 {
1932 	while (v && !(v & 1))
1933 		v >>= 1;
1934 	return (v & ~1) == 0;
1935 }
1936 
allocate_memory(void)1937 static void allocate_memory (void)
1938 {
1939 	bogomem_aliasing = 0;
1940 
1941 	bool bogoreset = (bogomem_bank.flags & ABFLAG_NOALLOC) != 0 &&
1942 		(chipmem_bank.allocated != currprefs.chipmem_size || bogomem_bank.allocated != currprefs.bogomem_size);
1943 
1944 	if (bogoreset) {
1945 		mapped_free(&chipmem_bank);
1946 		mapped_free(&bogomem_bank);
1947 	}
1948 
1949 	/* emulate 0.5M+0.5M with 1M Agnus chip ram aliasing */
1950 	if (currprefs.chipmem_size == 0x80000 && currprefs.bogomem_size >= 0x80000 &&
1951 		(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && !(currprefs.chipset_mask & CSMASK_AGA) && currprefs.cpu_model < 68020) {
1952 			if ((chipmem_bank.allocated != currprefs.chipmem_size || bogomem_bank.allocated != currprefs.bogomem_size)) {
1953 				int memsize1, memsize2;
1954 				mapped_free (&chipmem_bank);
1955 				mapped_free (&bogomem_bank);
1956 				bogomem_bank.allocated = 0;
1957 				memsize1 = chipmem_bank.allocated = currprefs.chipmem_size;
1958 				memsize2 = bogomem_bank.allocated = currprefs.bogomem_size;
1959 				chipmem_bank.mask = chipmem_bank.allocated - 1;
1960 				chipmem_bank.start = chipmem_start_addr;
1961 				chipmem_full_mask = bogomem_bank.allocated * 2 - 1;
1962 				chipmem_full_size = 0x80000 * 2;
1963 				chipmem_bank.allocated = memsize1 + memsize2;
1964 				mapped_malloc (&chipmem_bank);
1965 				chipmem_bank.allocated = currprefs.chipmem_size;
1966 				bogomem_bank.baseaddr = chipmem_bank.baseaddr + memsize1;
1967 				bogomem_bank.mask = bogomem_bank.allocated - 1;
1968 				bogomem_bank.start = bogomem_start_addr;
1969 				bogomem_bank.flags |= ABFLAG_NOALLOC;
1970 				if (chipmem_bank.baseaddr == 0) {
1971 					write_log (_T("Fatal error: out of memory for chipmem.\n"));
1972 					chipmem_bank.allocated = 0;
1973 				} else {
1974 					need_hardreset = true;
1975 				}
1976 			}
1977 			bogomem_aliasing = 1;
1978 	} else if (currprefs.chipmem_size == 0x80000 && currprefs.bogomem_size >= 0x80000 &&
1979 		!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.cs_1mchipjumper && currprefs.cpu_model < 68020) {
1980 			if ((chipmem_bank.allocated != currprefs.chipmem_size || bogomem_bank.allocated != currprefs.bogomem_size)) {
1981 				int memsize1, memsize2;
1982 				mapped_free (&chipmem_bank);
1983 				mapped_free (&bogomem_bank);
1984 				bogomem_bank.allocated = 0;
1985 				memsize1 = chipmem_bank.allocated = currprefs.chipmem_size;
1986 				memsize2 = bogomem_bank.allocated = currprefs.bogomem_size;
1987 				chipmem_bank.mask = chipmem_bank.allocated - 1;
1988 				chipmem_bank.start = chipmem_start_addr;
1989 				chipmem_full_mask = chipmem_bank.allocated - 1;
1990 				chipmem_full_size = chipmem_bank.allocated;
1991 				chipmem_bank.allocated = memsize1 + memsize2;
1992 				mapped_malloc (&chipmem_bank);
1993 				chipmem_bank.allocated = currprefs.chipmem_size;
1994 				bogomem_bank.baseaddr = chipmem_bank.baseaddr + memsize1;
1995 				bogomem_bank.mask = bogomem_bank.allocated - 1;
1996 				bogomem_bank.start = chipmem_bank.start + currprefs.chipmem_size;
1997 				bogomem_bank.flags |= ABFLAG_NOALLOC;
1998 				if (chipmem_bank.baseaddr == 0) {
1999 					write_log (_T("Fatal error: out of memory for chipmem.\n"));
2000 					chipmem_bank.allocated = 0;
2001 				} else {
2002 					need_hardreset = true;
2003 				}
2004 			}
2005 			bogomem_aliasing = 2;
2006 	}
2007 
2008 	if (chipmem_bank.allocated != currprefs.chipmem_size || bogoreset) {
2009 		int memsize;
2010 		mapped_free (&chipmem_bank);
2011 		chipmem_bank.flags &= ~ABFLAG_NOALLOC;
2012 		if (currprefs.chipmem_size > 2 * 1024 * 1024) {
2013 			if (currprefs.fastmem_size >= 524288)
2014 				free_fastmemory (0);
2015 			if (currprefs.fastmem2_size >= 524288)
2016 				free_fastmemory (1);
2017 		}
2018 
2019 		memsize = chipmem_bank.allocated = chipmem_full_size = currprefs.chipmem_size;
2020 		chipmem_full_mask = chipmem_bank.mask = chipmem_bank.allocated - 1;
2021 		chipmem_bank.start = chipmem_start_addr;
2022 		if (!currprefs.cachesize && memsize < 0x100000)
2023 			memsize = 0x100000;
2024 		if (memsize > 0x100000 && memsize < 0x200000)
2025 			memsize = 0x200000;
2026 		chipmem_bank.allocated = memsize;
2027 		mapped_malloc (&chipmem_bank);
2028 		chipmem_bank.allocated = currprefs.chipmem_size;
2029 		if (chipmem_bank.baseaddr == 0) {
2030 			write_log (_T("Fatal error: out of memory for chipmem.\n"));
2031 			chipmem_bank.allocated = 0;
2032 		} else {
2033 			need_hardreset = true;
2034 			if (memsize > chipmem_bank.allocated)
2035 				memset (chipmem_bank.baseaddr + chipmem_bank.allocated, 0xff, memsize - chipmem_bank.allocated);
2036 		}
2037 		currprefs.chipset_mask = changed_prefs.chipset_mask;
2038 		chipmem_full_mask = chipmem_bank.allocated - 1;
2039 		if (!currprefs.cachesize) {
2040 			if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
2041 				if (chipmem_bank.allocated < 0x100000)
2042 					chipmem_full_mask = 0x100000 - 1;
2043 				if (chipmem_bank.allocated > 0x100000 && chipmem_bank.allocated < 0x200000)
2044 					chipmem_full_mask = chipmem_bank.mask = 0x200000 - 1;
2045 			} else if (currprefs.cs_1mchipjumper) {
2046 				chipmem_full_mask = 0x80000 - 1;
2047 			}
2048 		}
2049 	}
2050 
2051 	if (bogomem_bank.allocated != currprefs.bogomem_size || bogoreset) {
2052 		if (!(bogomem_bank.allocated == 0x200000 && currprefs.bogomem_size == 0x180000)) {
2053 			mapped_free (&bogomem_bank);
2054 			bogomem_bank.flags &= ~ABFLAG_NOALLOC;
2055 			bogomem_bank.allocated = 0;
2056 
2057 			bogomem_bank.allocated = currprefs.bogomem_size;
2058 			if (bogomem_bank.allocated >= 0x180000)
2059 				bogomem_bank.allocated = 0x200000;
2060 			bogomem_bank.mask = bogomem_bank.allocated - 1;
2061 			bogomem_bank.start = bogomem_start_addr;
2062 
2063 			if (bogomem_bank.allocated) {
2064 				if (!mapped_malloc (&bogomem_bank)) {
2065 					write_log (_T("Out of memory for bogomem.\n"));
2066 					bogomem_bank.allocated = 0;
2067 				}
2068 			}
2069 			need_hardreset = true;
2070 		}
2071 	}
2072 	if (mem25bit_bank.allocated != currprefs.mem25bit_size) {
2073 		mapped_free(&mem25bit_bank);
2074 
2075 		mem25bit_bank.allocated = currprefs.mem25bit_size;
2076 		mem25bit_bank.mask = mem25bit_bank.allocated - 1;
2077 		mem25bit_bank.start = 0x01000000;
2078 		if (mem25bit_bank.allocated) {
2079 			if (!mapped_malloc(&mem25bit_bank)) {
2080 				write_log(_T("Out of memory for 25 bit memory.\n"));
2081 				mem25bit_bank.allocated = 0;
2082 			}
2083 		}
2084 		need_hardreset = true;
2085 	}
2086 	if (a3000lmem_bank.allocated != currprefs.mbresmem_low_size) {
2087 		mapped_free (&a3000lmem_bank);
2088 
2089 		a3000lmem_bank.allocated = currprefs.mbresmem_low_size;
2090 		a3000lmem_bank.mask = a3000lmem_bank.allocated - 1;
2091 		a3000lmem_bank.start = 0x08000000 - a3000lmem_bank.allocated;
2092 		if (a3000lmem_bank.allocated) {
2093 			if (!mapped_malloc (&a3000lmem_bank)) {
2094 				write_log (_T("Out of memory for a3000lowmem.\n"));
2095 				a3000lmem_bank.allocated = 0;
2096 			}
2097 		}
2098 		need_hardreset = true;
2099 	}
2100 	if (a3000hmem_bank.allocated != currprefs.mbresmem_high_size) {
2101 		mapped_free (&a3000hmem_bank);
2102 
2103 		a3000hmem_bank.allocated = currprefs.mbresmem_high_size;
2104 		a3000hmem_bank.mask = a3000hmem_bank.allocated - 1;
2105 		a3000hmem_bank.start = 0x08000000;
2106 		if (a3000hmem_bank.allocated) {
2107 			if (!mapped_malloc (&a3000hmem_bank)) {
2108 				write_log (_T("Out of memory for a3000highmem.\n"));
2109 				a3000hmem_bank.allocated = 0;
2110 			}
2111 		}
2112 		need_hardreset = true;
2113 	}
2114 #ifdef CDTV
2115 	if (cardmem_bank.allocated != currprefs.cs_cdtvcard * 1024) {
2116 		mapped_free (&cardmem_bank);
2117 		cardmem_bank.baseaddr = NULL;
2118 
2119 		cardmem_bank.allocated = currprefs.cs_cdtvcard * 1024;
2120 		cardmem_bank.mask = cardmem_bank.allocated - 1;
2121 		cardmem_bank.start = 0xe00000;
2122 		if (cardmem_bank.allocated) {
2123 			if (!mapped_malloc (&cardmem_bank)) {
2124 				write_log (_T("Out of memory for cardmem.\n"));
2125 				cardmem_bank.allocated = 0;
2126 			}
2127 		}
2128 		cdtv_loadcardmem(cardmem_bank.baseaddr, cardmem_bank.allocated);
2129 	}
2130 #endif
2131 	if (custmem1_bank.allocated != currprefs.custom_memory_sizes[0]) {
2132 		mapped_free (&custmem1_bank);
2133 		custmem1_bank.allocated = currprefs.custom_memory_sizes[0];
2134 		// custmem1 and 2 can have non-power of 2 size so only set correct mask if size is power of 2.
2135 		custmem1_bank.mask = singlebit (custmem1_bank.allocated) ? custmem1_bank.allocated - 1 : -1;
2136 		custmem1_bank.start = currprefs.custom_memory_addrs[0];
2137 		if (custmem1_bank.allocated) {
2138 			if (!mapped_malloc (&custmem1_bank))
2139 				custmem1_bank.allocated = 0;
2140 		}
2141 	}
2142 	if (custmem2_bank.allocated != currprefs.custom_memory_sizes[1]) {
2143 		mapped_free (&custmem2_bank);
2144 		custmem2_bank.allocated = currprefs.custom_memory_sizes[1];
2145 		custmem2_bank.mask = singlebit (custmem2_bank.allocated) ? custmem2_bank.allocated - 1 : -1;
2146 		custmem2_bank.start = currprefs.custom_memory_addrs[1];
2147 		if (custmem2_bank.allocated) {
2148 			if (!mapped_malloc (&custmem2_bank))
2149 				custmem2_bank.allocated = 0;
2150 		}
2151 	}
2152 
2153 #ifdef SAVESTATE
2154 	if (savestate_state == STATE_RESTORE) {
2155 		if (bootrom_filepos) {
2156 			protect_roms (false);
2157 			restore_ram (bootrom_filepos, rtarea_bank.baseaddr);
2158 			protect_roms (true);
2159 		}
2160 		restore_ram (chip_filepos, chipmem_bank.baseaddr);
2161 		if (bogomem_bank.allocated > 0)
2162 			restore_ram (bogo_filepos, bogomem_bank.baseaddr);
2163 		if (mem25bit_bank.allocated > 0)
2164 			restore_ram(mem25bit_filepos, mem25bit_bank.baseaddr);
2165 		if (a3000lmem_bank.allocated > 0)
2166 			restore_ram (a3000lmem_filepos, a3000lmem_bank.baseaddr);
2167 		if (a3000hmem_bank.allocated > 0)
2168 			restore_ram (a3000hmem_filepos, a3000hmem_bank.baseaddr);
2169 	}
2170 #endif
2171 
2172 #ifdef AGA
2173 	chipmem_bank_ce2.baseaddr = chipmem_bank.baseaddr;
2174 #endif
2175 	bootrom_filepos = 0;
2176 	chip_filepos = 0;
2177 	bogo_filepos = 0;
2178 	a3000lmem_filepos = 0;
2179 	a3000hmem_filepos = 0;
2180 	cpuboard_init();
2181 }
2182 
fill_ce_banks(void)2183 static void fill_ce_banks (void)
2184 {
2185 	int i;
2186 
2187 	if (currprefs.cpu_model <= 68010) {
2188 		memset (ce_banktype, CE_MEMBANK_FAST16, sizeof ce_banktype);
2189 	} else {
2190 		memset (ce_banktype, CE_MEMBANK_FAST32, sizeof ce_banktype);
2191 	}
2192 	// data cachable regions (2 = burst supported)
2193 	memset(ce_cachable, 0, sizeof ce_cachable);
2194 	memset(ce_cachable + (0x00200000 >> 16), 1 | 2, currprefs.fastmem_size >> 16);
2195 	memset(ce_cachable + (0x00c00000 >> 16), 1, currprefs.bogomem_size >> 16);
2196 	memset(ce_cachable + (z3fastmem_bank.start >> 16), 1 | 2, currprefs.z3fastmem_size >> 16);
2197 	memset(ce_cachable + (z3fastmem2_bank.start >> 16), 1 | 2, currprefs.z3fastmem2_size >> 16);
2198 	memset(ce_cachable + (a3000hmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_high_size >> 16);
2199 	memset(ce_cachable + (a3000lmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_low_size >> 16);
2200 	memset(ce_cachable + (mem25bit_bank.start >> 16), 1 | 2, currprefs.mem25bit_size >> 16);
2201 
2202 	if (get_mem_bank (0).flags & ABFLAG_CHIPRAM) {
2203 		for (i = 0; i < (0x200000 >> 16); i++) {
2204 			ce_banktype[i] = (currprefs.cs_mbdmac || (currprefs.chipset_mask & CSMASK_AGA)) ? CE_MEMBANK_CHIP32 : CE_MEMBANK_CHIP16;
2205 		}
2206 	}
2207 	if (!currprefs.cs_slowmemisfast) {
2208 		for (i = (0xc00000 >> 16); i < (0xe00000 >> 16); i++)
2209 			ce_banktype[i] = ce_banktype[0];
2210 		for (i = (bogomem_bank.start >> 16); i < ((bogomem_bank.start + bogomem_bank.allocated) >> 16); i++)
2211 			ce_banktype[i] = ce_banktype[0];
2212 	}
2213 	for (i = (0xd00000 >> 16); i < (0xe00000 >> 16); i++)
2214 		ce_banktype[i] = CE_MEMBANK_CHIP16;
2215 	for (i = (0xa00000 >> 16); i < (0xc00000 >> 16); i++) {
2216 		addrbank *b;
2217 		ce_banktype[i] = CE_MEMBANK_CIA;
2218 		b = &get_mem_bank (i << 16);
2219 		if (!(b->flags & ABFLAG_CIA)) {
2220 			ce_banktype[i] = CE_MEMBANK_FAST32;
2221 			ce_cachable[i] = 1;
2222 		}
2223 	}
2224 	// CD32 ROM is 16-bit
2225 	if (currprefs.cs_cd32cd) {
2226 		for (i = (0xe00000 >> 16); i < (0xe80000 >> 16); i++)
2227 			ce_banktype[i] = CE_MEMBANK_FAST16;
2228 		for (i = (0xf80000 >> 16); i <= (0xff0000 >> 16); i++)
2229 			ce_banktype[i] = CE_MEMBANK_FAST16;
2230 	}
2231 
2232 	// A4000T NCR is 32-bit
2233 	if (currprefs.cs_mbdmac == 2) {
2234 		ce_banktype[0xdd0000 >> 16] = CE_MEMBANK_FAST32;
2235 	}
2236 
2237 	if (currprefs.address_space_24) {
2238 		for (i = 1; i < 256; i++)
2239 			memcpy (&ce_banktype[i * 256], &ce_banktype[0], 256);
2240 	}
2241 }
2242 
map_overlay(int chip)2243 void map_overlay (int chip)
2244 {
2245 	int size;
2246 	addrbank *cb;
2247 
2248 	size = chipmem_bank.allocated >= 0x180000 ? (chipmem_bank.allocated >> 16) : 32;
2249 	if (bogomem_aliasing)
2250 		size = 8;
2251 	cb = &chipmem_bank;
2252 #ifdef AGA
2253 #if 0
2254 	if (currprefs.cpu_cycle_exact && currprefs.cpu_model >= 68020)
2255 		cb = &chipmem_bank_ce2;
2256 #endif
2257 #endif
2258 	if (chip) {
2259 		map_banks (&dummy_bank, 0, size, 0);
2260 		if (!isdirectjit ()) {
2261 			if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && bogomem_bank.allocated == 0) {
2262 				map_banks(cb, 0, size, chipmem_bank.allocated);
2263 				int start = chipmem_bank.allocated >> 16;
2264 				if (chipmem_bank.allocated < 0x100000) {
2265 					if (currprefs.cs_1mchipjumper) {
2266 						int dummy = (0x100000 - chipmem_bank.allocated) >> 16;
2267 						map_banks (&chipmem_dummy_bank, start, dummy, 0);
2268 						map_banks (&chipmem_dummy_bank, start + 16, dummy, 0);
2269 					}
2270 				} else if (chipmem_bank.allocated < 0x200000 && chipmem_bank.allocated > 0x100000) {
2271 					int dummy = (0x200000 - chipmem_bank.allocated) >> 16;
2272 					map_banks (&chipmem_dummy_bank, start, dummy, 0);
2273 				}
2274 			} else {
2275 				map_banks(cb, 0, 32, chipmem_bank.allocated);
2276 			}
2277 		} else {
2278 			map_banks (cb, 0, chipmem_bank.allocated >> 16, 0);
2279 		}
2280 	} else {
2281 		addrbank *rb = NULL;
2282 		if (size < 32 && bogomem_aliasing == 0)
2283 			size = 32;
2284 		cb = get_mem_bank_real(0xf00000);
2285 		if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word (0xf00000) == 0x1114)
2286 			rb = cb;
2287 		cb = get_mem_bank_real(0xe00000);
2288 		if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word (0xe00000) == 0x1114)
2289 			rb = cb;
2290 		if (!rb)
2291 			rb = &kickmem_bank;
2292 		map_banks (rb, 0, size, 0x80000);
2293 	}
2294 	fill_ce_banks ();
2295 	cpuboard_overlay_override();
2296 	if (!isrestore () && valid_address (regs.pc, 4))
2297 		m68k_setpc_normal (m68k_getpc ());
2298 }
2299 
getz2size(struct uae_prefs * p)2300 uae_s32 getz2size (struct uae_prefs *p)
2301 {
2302 	ULONG start;
2303 	start = p->fastmem_size;
2304 	if (p->rtgmem_size && gfxboard_get_configtype(p->rtgmem_type) == 2) {
2305 		while (start & (p->rtgmem_size - 1) && start < 8 * 1024 * 1024)
2306 			start += 1024 * 1024;
2307 		if (start + p->rtgmem_size > 8 * 1024 * 1024)
2308 			return -1;
2309 	}
2310 	start += p->rtgmem_size;
2311 	return start;
2312 }
2313 
getz2endaddr(void)2314 uae_u32 getz2endaddr (void)
2315 {
2316 	ULONG start;
2317 	start = currprefs.fastmem_size;
2318 	if (currprefs.rtgmem_size && gfxboard_get_configtype(currprefs.rtgmem_type) == 2) {
2319 		if (!start)
2320 			start = 0x00200000;
2321 		while (start & (currprefs.rtgmem_size - 1) && start < 4 * 1024 * 1024)
2322 			start += 1024 * 1024;
2323 	}
2324 	return start + 2 * 1024 * 1024;
2325 }
2326 
map_banks_set(addrbank * bank,int start,int size,int realsize)2327 static void map_banks_set(addrbank *bank, int start, int size, int realsize)
2328 {
2329 	bank->startmask = start << 16;
2330 	map_banks(bank, start, size, realsize);
2331 }
2332 
memory_clear(void)2333 void memory_clear (void)
2334 {
2335 	mem_hardreset = 0;
2336 	if (savestate_state == STATE_RESTORE)
2337 		return;
2338 	if (chipmem_bank.baseaddr)
2339 		memset(chipmem_bank.baseaddr, 0, chipmem_bank.allocated);
2340 	if (bogomem_bank.baseaddr)
2341 		memset(bogomem_bank.baseaddr, 0, bogomem_bank.allocated);
2342 	if (mem25bit_bank.baseaddr)
2343 		memset(mem25bit_bank.baseaddr, 0, mem25bit_bank.allocated);
2344 	if (a3000lmem_bank.baseaddr)
2345 		memset(a3000lmem_bank.baseaddr, 0, a3000lmem_bank.allocated);
2346 	if (a3000hmem_bank.baseaddr)
2347 		memset(a3000hmem_bank.baseaddr, 0, a3000hmem_bank.allocated);
2348 	expansion_clear ();
2349 	cpuboard_clear();
2350 }
2351 
restore_roms(void)2352 static void restore_roms(void)
2353 {
2354 	roms_modified = false;
2355 	protect_roms (false);
2356 	write_log (_T("ROM loader.. (%s)\n"), currprefs.romfile);
2357 	kickstart_rom = 1;
2358 	a1000_handle_kickstart (0);
2359 	xfree (a1000_bootrom);
2360 	a1000_bootrom = 0;
2361 	a1000_kickstart_mode = 0;
2362 
2363 	memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
2364 	memcpy (currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile);
2365 	need_hardreset = true;
2366 	mapped_free (&extendedkickmem_bank);
2367 	mapped_free (&extendedkickmem2_bank);
2368 	extendedkickmem_bank.allocated = 0;
2369 	extendedkickmem2_bank.allocated = 0;
2370 	extendedkickmem_type = 0;
2371 	load_extendedkickstart (currprefs.romextfile, 0);
2372 	load_extendedkickstart (currprefs.romextfile2, EXTENDED_ROM_CDTV);
2373 	kickmem_bank.mask = ROM_SIZE_512 - 1;
2374 	if (!load_kickstart ()) {
2375 		if (_tcslen (currprefs.romfile) > 0) {
2376 			error_log (_T("Failed to open '%s'\n"), currprefs.romfile);
2377 			notify_user (NUMSG_NOROM);
2378 		}
2379 		load_kickstart_replacement ();
2380 	} else {
2381 		struct romdata *rd = getromdatabydata (kickmem_bank.baseaddr, kickmem_bank.allocated);
2382 		if (rd) {
2383 			write_log (_T("Known ROM '%s' loaded\n"), rd->name);
2384 			if ((rd->cpu & 8) && changed_prefs.cpu_model < 68030) {
2385 				notify_user (NUMSG_KS68030PLUS);
2386 				uae_restart (-1, NULL);
2387 			} else if ((rd->cpu & 3) == 3 && changed_prefs.cpu_model != 68030) {
2388 				notify_user (NUMSG_KS68030);
2389 				uae_restart (-1, NULL);
2390 			} else if ((rd->cpu & 3) == 1 && changed_prefs.cpu_model < 68020) {
2391 				notify_user (NUMSG_KS68EC020);
2392 				uae_restart (-1, NULL);
2393 			} else if ((rd->cpu & 3) == 2 && (changed_prefs.cpu_model < 68020 || changed_prefs.address_space_24)) {
2394 				notify_user (NUMSG_KS68020);
2395 				uae_restart (-1, NULL);
2396 			}
2397 			if (rd->cloanto)
2398 				cloanto_rom = 1;
2399 			kickstart_rom = 0;
2400 			if ((rd->type & (ROMTYPE_SPECIALKICK | ROMTYPE_KICK)) == ROMTYPE_KICK)
2401 				kickstart_rom = 1;
2402 			if ((rd->cpu & 4) && currprefs.cs_compatible) {
2403 				/* A4000 ROM = need ramsey, gary and ide */
2404 				if (currprefs.cs_ramseyrev < 0)
2405 					changed_prefs.cs_ramseyrev = currprefs.cs_ramseyrev = 0x0f;
2406 				changed_prefs.cs_fatgaryrev = currprefs.cs_fatgaryrev = 0;
2407 				if (currprefs.cs_ide != IDE_A4000)
2408 					changed_prefs.cs_ide = currprefs.cs_ide = -1;
2409 			}
2410 		} else {
2411 			write_log (_T("Unknown ROM '%s' loaded\n"), currprefs.romfile);
2412 		}
2413 	}
2414 	patch_kick ();
2415 	write_log (_T("ROM loader end\n"));
2416 	protect_roms (true);
2417 }
2418 
reload_roms(void)2419 void reload_roms(void)
2420 {
2421 	if (roms_modified)
2422 		restore_roms();
2423 }
2424 
memory_reset(void)2425 void memory_reset (void)
2426 {
2427 	int bnk, bnk_end;
2428 	bool gayleorfatgary;
2429 
2430 	need_hardreset = false;
2431 	rom_write_enabled = true;
2432 	/* Use changed_prefs, as m68k_reset is called later.  */
2433 	if (last_address_space_24 != changed_prefs.address_space_24)
2434 		need_hardreset = true;
2435 	last_address_space_24 = changed_prefs.address_space_24;
2436 
2437 	if (mem_hardreset > 2)
2438 		memory_init ();
2439 
2440 	be_cnt = 0;
2441 	currprefs.chipmem_size = changed_prefs.chipmem_size;
2442 	currprefs.bogomem_size = changed_prefs.bogomem_size;
2443 	currprefs.mbresmem_low_size = changed_prefs.mbresmem_low_size;
2444 	currprefs.mbresmem_high_size = changed_prefs.mbresmem_high_size;
2445 	currprefs.cs_ksmirror_e0 = changed_prefs.cs_ksmirror_e0;
2446 	currprefs.cs_ksmirror_a8 = changed_prefs.cs_ksmirror_a8;
2447 	currprefs.cs_ciaoverlay = changed_prefs.cs_ciaoverlay;
2448 	currprefs.cs_cdtvram = changed_prefs.cs_cdtvram;
2449 	currprefs.cs_cdtvcard = changed_prefs.cs_cdtvcard;
2450 	currprefs.cs_a1000ram = changed_prefs.cs_a1000ram;
2451 	currprefs.cs_ide = changed_prefs.cs_ide;
2452 	currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev;
2453 	currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev;
2454 	cpuboard_reset();
2455 
2456 	gayleorfatgary = (currprefs.chipset_mask & CSMASK_AGA) || currprefs.cs_pcmcia || currprefs.cs_ide > 0 || currprefs.cs_mbdmac;
2457 
2458 	init_mem_banks ();
2459 	allocate_memory ();
2460 	chipmem_setindirect ();
2461 
2462 	if (mem_hardreset > 1 || ((roms_modified || a1000_bootrom) && is_hardreset())
2463 		|| _tcscmp (currprefs.romfile, changed_prefs.romfile) != 0
2464 		|| _tcscmp (currprefs.romextfile, changed_prefs.romextfile) != 0)
2465 	{
2466 		restore_roms();
2467 	}
2468 
2469 	if ((cloanto_rom || extendedkickmem_bank.allocated) && currprefs.maprom && currprefs.maprom < 0x01000000) {
2470 #ifdef FSUAE
2471 	    write_log("MAPROM: cloanto_rom=%d extendedkickmem_bank.allocated=%u\n", cloanto_rom, extendedkickmem_bank.allocated);
2472 	    write_log("MAPROM: Setting address 0x00a80000 (was 0x%08x)\n", currprefs.maprom);
2473 #endif
2474 		currprefs.maprom = changed_prefs.maprom = 0x00a80000;
2475 		if (extendedkickmem2_bank.allocated) // can't do if 2M ROM
2476 			currprefs.maprom = changed_prefs.maprom = 0;
2477 	}
2478 
2479 	map_banks (&custom_bank, 0xC0, 0xE0 - 0xC0, 0);
2480 	map_banks (&cia_bank, 0xA0, 32, 0);
2481 	if (!currprefs.cs_a1000ram && currprefs.cs_rtc != 3)
2482 		/* D80000 - DDFFFF not mapped (A1000 or A2000 = custom chips) */
2483 		map_banks (&dummy_bank, 0xD8, 6, 0);
2484 
2485 	/* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if Gayle or Fat Gary) */
2486 	bnk = chipmem_bank.allocated >> 16;
2487 	if (bnk < 0x20 + (currprefs.fastmem_size >> 16))
2488 		bnk = 0x20 + (currprefs.fastmem_size >> 16);
2489 	bnk_end = gayleorfatgary ? 0xBF : 0xA0;
2490 	map_banks (&dummy_bank, bnk, bnk_end - bnk, 0);
2491 	if (gayleorfatgary) {
2492 		 // a3000 or a4000 = custom chips from 0xc0 to 0xd0
2493 		if (currprefs.cs_ide == IDE_A4000 || currprefs.cs_mbdmac)
2494 			map_banks (&dummy_bank, 0xd0, 8, 0);
2495 		else
2496 			map_banks (&dummy_bank, 0xc0, 0xd8 - 0xc0, 0);
2497 	}
2498 
2499 	if (bogomem_bank.baseaddr) {
2500 		int t = currprefs.bogomem_size >> 16;
2501 		if (t > 0x1C)
2502 			t = 0x1C;
2503 		if (t > 0x18 && ((currprefs.chipset_mask & CSMASK_AGA) || (currprefs.cpu_model >= 68020 && !currprefs.address_space_24)))
2504 			t = 0x18;
2505 		if (bogomem_aliasing == 2)
2506 			map_banks (&bogomem_bank, 0x08, t, 0);
2507 		else
2508 			map_banks (&bogomem_bank, 0xC0, t, 0);
2509 	}
2510 	if (currprefs.cs_ide || currprefs.cs_pcmcia) {
2511 		if (currprefs.cs_ide == IDE_A600A1200 || currprefs.cs_pcmcia) {
2512 			map_banks (&gayle_bank, 0xD8, 6, 0);
2513 			map_banks (&gayle2_bank, 0xDD, 2, 0);
2514 		}
2515 		gayle_map_pcmcia ();
2516 		if (currprefs.cs_ide == IDE_A4000 || currprefs.cs_mbdmac == 2)
2517 			map_banks (&gayle_bank, 0xDD, 1, 0);
2518 		if (currprefs.cs_ide < 0 && !currprefs.cs_pcmcia)
2519 			map_banks (&gayle_bank, 0xD8, 6, 0);
2520 		if (currprefs.cs_ide < 0)
2521 			map_banks (&gayle_bank, 0xDD, 1, 0);
2522 	}
2523 	if (currprefs.cs_rtc == 3) // A2000 clock
2524 		map_banks (&clock_bank, 0xD8, 4, 0);
2525 	if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 2 || currprefs.cs_cdtvram)
2526 		map_banks (&clock_bank, 0xDC, 1, 0);
2527 	else if (currprefs.cs_ksmirror_a8 || currprefs.cs_ide > 0 || currprefs.cs_pcmcia)
2528 		map_banks (&clock_bank, 0xDC, 1, 0); /* none clock */
2529 	if (currprefs.cs_fatgaryrev >= 0 || currprefs.cs_ramseyrev >= 0)
2530 		map_banks (&mbres_bank, 0xDE, 1, 0);
2531 #ifdef CD32
2532 	if (currprefs.cs_cd32c2p || currprefs.cs_cd32cd || currprefs.cs_cd32nvram) {
2533 		map_banks (&akiko_bank, AKIKO_BASE >> 16, 1, 0);
2534 		map_banks (&gayle2_bank, 0xDD, 2, 0);
2535 	}
2536 #endif
2537 #ifdef CDTV
2538 	if (currprefs.cs_cdtvcr) {
2539 		map_banks(&cdtvcr_bank, 0xB8, 1, 0);
2540 	} else if (currprefs.cs_cdtvcd) {
2541 		cdtv_check_banks ();
2542 	}
2543 #endif
2544 #ifdef A2091
2545 	if (currprefs.cs_mbdmac == 1)
2546 		a3000scsi_reset ();
2547 #endif
2548 
2549 	if (mem25bit_bank.baseaddr)
2550 		map_banks(&mem25bit_bank, mem25bit_bank.start >> 16, mem25bit_bank.allocated >> 16, 0);
2551 	if (a3000lmem_bank.baseaddr)
2552 		map_banks(&a3000lmem_bank, a3000lmem_bank.start >> 16, a3000lmem_bank.allocated >> 16, 0);
2553 	if (a3000hmem_bank.baseaddr)
2554 		map_banks(&a3000hmem_bank, a3000hmem_bank.start >> 16, a3000hmem_bank.allocated >> 16, 0);
2555 #ifdef CDTV
2556 	if (cardmem_bank.baseaddr)
2557 		map_banks (&cardmem_bank, cardmem_bank.start >> 16, cardmem_bank.allocated >> 16, 0);
2558 #endif
2559 	cpuboard_map();
2560 	map_banks_set(&kickmem_bank, 0xF8, 8, 0);
2561 	if (currprefs.maprom) {
2562 		if (!cpuboard_maprom())
2563 			map_banks_set(&kickram_bank, currprefs.maprom >> 16, extendedkickmem2_bank.allocated ? 32 : (extendedkickmem_bank.allocated ? 16 : 8), 0);
2564 	}
2565 	/* map beta Kickstarts at 0x200000/0xC00000/0xF00000 */
2566 	if (kickmem_bank.baseaddr[0] == 0x11 && kickmem_bank.baseaddr[2] == 0x4e && kickmem_bank.baseaddr[3] == 0xf9 && kickmem_bank.baseaddr[4] == 0x00) {
2567 		uae_u32 addr = kickmem_bank.baseaddr[5];
2568 		if (addr == 0x20 && currprefs.chipmem_size <= 0x200000 && currprefs.fastmem_size == 0)
2569 			map_banks_set(&kickmem_bank, addr, 8, 0);
2570 		if (addr == 0xC0 && currprefs.bogomem_size == 0)
2571 			map_banks_set(&kickmem_bank, addr, 8, 0);
2572 		if (addr == 0xF0)
2573 			map_banks_set(&kickmem_bank, addr, 8, 0);
2574 	}
2575 
2576 	if (a1000_bootrom)
2577 		a1000_handle_kickstart (1);
2578 
2579 #ifdef AUTOCONFIG
2580 	map_banks (&expamem_bank, 0xE8, 1, 0);
2581 #endif
2582 
2583 	if (a3000_f0)
2584 		map_banks_set(&extendedkickmem_bank, 0xf0, 1, 0);
2585 
2586 	/* Map the chipmem into all of the lower 8MB */
2587 	map_overlay (1);
2588 
2589 	switch (extendedkickmem_type) {
2590 	case EXTENDED_ROM_KS:
2591 		map_banks_set(&extendedkickmem_bank, 0xE0, 8, 0);
2592 		break;
2593 #ifdef CDTV
2594 	case EXTENDED_ROM_CDTV:
2595 		map_banks_set(&extendedkickmem_bank, 0xF0, extendedkickmem_bank.allocated == 2 * ROM_SIZE_512 ? 16 : 8, 0);
2596 		break;
2597 #endif
2598 #ifdef CD32
2599 	case EXTENDED_ROM_CD32:
2600 		map_banks_set(&extendedkickmem_bank, 0xE0, 8, 0);
2601 		break;
2602 #endif
2603 	}
2604 
2605 #ifdef AUTOCONFIG
2606 	if (need_uae_boot_rom ())
2607 		map_banks_set(&rtarea_bank, rtarea_base >> 16, 1, 0);
2608 #endif
2609 
2610 	if ((cloanto_rom || currprefs.cs_ksmirror_e0) && (currprefs.maprom != 0xe00000) && !extendedkickmem_type) {
2611 #ifdef FSUAE
2612 		if (currprefs.cs_ksmirror_e0) {
2613 			write_log("MAPROM: cs_ksmirror_e0 set - mirroring kickstart at 0x00e00000\n");
2614 		}
2615 		else if (cloanto_rom) {
2616 			write_log("MAPROM: cloanto_rom set - mirroring kickstart at 0x00e00000\n");
2617 		}
2618 #endif
2619 		map_banks(&kickmem_bank, 0xE0, 8, 0);
2620 	}
2621 	if (currprefs.cs_ksmirror_a8) {
2622 		if (extendedkickmem2_bank.allocated) {
2623 			map_banks_set(&extendedkickmem2_bank, 0xa8, 16, 0);
2624 		} else {
2625 			struct romdata *rd = getromdatabypath (currprefs.cartfile);
2626 			if (!rd || rd->id != 63) {
2627 				if (extendedkickmem_type == EXTENDED_ROM_CD32 || extendedkickmem_type == EXTENDED_ROM_KS)
2628 					map_banks(&extendedkickmem_bank, 0xb0, 8, 0);
2629 				else
2630 					map_banks(&kickmem_bank, 0xb0, 8, 0);
2631 				map_banks(&kickmem_bank, 0xa8, 8, 0);
2632 			}
2633 		}
2634 	}
2635 
2636 #ifdef ARCADIA
2637 	if (is_arcadia_rom (currprefs.romextfile) == ARCADIA_BIOS) {
2638 		if (_tcscmp (currprefs.romextfile, changed_prefs.romextfile) != 0)
2639 			memcpy (currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile);
2640 		if (_tcscmp (currprefs.cartfile, changed_prefs.cartfile) != 0)
2641 			memcpy (currprefs.cartfile, changed_prefs.cartfile, sizeof currprefs.cartfile);
2642 		arcadia_unmap ();
2643 		is_arcadia_rom (currprefs.romextfile);
2644 		is_arcadia_rom (currprefs.cartfile);
2645 		arcadia_map_banks ();
2646 	}
2647 #endif
2648 
2649 #ifdef ACTION_REPLAY
2650 #ifdef ARCADIA
2651 	if (!arcadia_bios) {
2652 #endif
2653 		action_replay_memory_reset ();
2654 #ifdef ARCADIA
2655 	}
2656 #endif
2657 #endif
2658 
2659 	for (int i = 0; i < 2; i++) {
2660 		if (currprefs.custom_memory_sizes[i]) {
2661 			map_banks (i == 0 ? &custmem1_bank : &custmem2_bank,
2662 				currprefs.custom_memory_addrs[i] >> 16,
2663 				currprefs.custom_memory_sizes[i] >> 16, 0);
2664 			if (currprefs.custom_memory_mask[i]) {
2665 				for (int j = currprefs.custom_memory_addrs[i]; j & currprefs.custom_memory_mask[i]; j += currprefs.custom_memory_sizes[i]) {
2666 					map_banks(i == 0 ? &custmem1_bank : &custmem2_bank, j >> 16, currprefs.custom_memory_sizes[i] >> 16, 0);
2667 				}
2668 			}
2669 		}
2670 	}
2671 
2672 	if (mem_hardreset) {
2673 		memory_clear ();
2674 	}
2675 	write_log (_T("memory init end\n"));
2676 }
2677 
2678 
memory_init(void)2679 void memory_init (void)
2680 {
2681 	init_mem_banks ();
2682 	virtualdevice_init ();
2683 
2684 	chipmem_bank.allocated = 0;
2685 	bogomem_bank.allocated = 0;
2686 	kickmem_bank.baseaddr = NULL;
2687 	extendedkickmem_bank.baseaddr = NULL;
2688 	extendedkickmem_bank.allocated = 0;
2689 	extendedkickmem2_bank.baseaddr = NULL;
2690 	extendedkickmem2_bank.allocated = 0;
2691 	extendedkickmem_type = 0;
2692 	chipmem_bank.baseaddr = 0;
2693 	mem25bit_bank.allocated = mem25bit_bank.allocated = 0;
2694 	a3000lmem_bank.allocated = a3000hmem_bank.allocated = 0;
2695 	a3000lmem_bank.baseaddr = a3000hmem_bank.baseaddr = NULL;
2696 	bogomem_bank.baseaddr = NULL;
2697 	cardmem_bank.baseaddr = NULL;
2698 	custmem1_bank.allocated = custmem2_bank.allocated = 0;
2699 	custmem1_bank.baseaddr = NULL;
2700 	custmem2_bank.baseaddr = NULL;
2701 
2702 	kickmem_bank.allocated = ROM_SIZE_512;
2703 	mapped_malloc (&kickmem_bank);
2704 	memset (kickmem_bank.baseaddr, 0, ROM_SIZE_512);
2705 	_tcscpy (currprefs.romfile, _T("<none>"));
2706 	currprefs.romextfile[0] = 0;
2707 	cpuboard_reset();
2708 
2709 #ifdef ACTION_REPLAY
2710 	action_replay_unload (0);
2711 	action_replay_load ();
2712 	action_replay_init (1);
2713 #ifdef ACTION_REPLAY_HRTMON
2714 	hrtmon_load ();
2715 #endif
2716 #endif
2717 }
2718 
memory_cleanup(void)2719 void memory_cleanup (void)
2720 {
2721 	mapped_free(&mem25bit_bank);
2722 	mapped_free(&a3000lmem_bank);
2723 	mapped_free(&a3000hmem_bank);
2724 	mapped_free(&bogomem_bank);
2725 	mapped_free(&kickmem_bank);
2726 	xfree(a1000_bootrom);
2727 	mapped_free(&chipmem_bank);
2728 #ifdef CDTV
2729 	if (cardmem_bank.baseaddr) {
2730 		cdtv_savecardmem (cardmem_bank.baseaddr, cardmem_bank.allocated);
2731 		mapped_free (&cardmem_bank);
2732 	}
2733 #endif
2734 	mapped_free (&custmem1_bank);
2735 	mapped_free (&custmem2_bank);
2736 
2737 	bogomem_bank.baseaddr = NULL;
2738 	kickmem_bank.baseaddr = NULL;
2739 	mem25bit_bank.baseaddr = NULL;
2740 	a3000lmem_bank.baseaddr = a3000hmem_bank.baseaddr = NULL;
2741 	a1000_bootrom = NULL;
2742 	a1000_kickstart_mode = 0;
2743 	chipmem_bank.baseaddr = NULL;
2744 	cardmem_bank.baseaddr = NULL;
2745 	custmem1_bank.baseaddr = NULL;
2746 	custmem2_bank.baseaddr = NULL;
2747 
2748 	cpuboard_cleanup();
2749 #ifdef ACTION_REPLAY
2750 	action_replay_cleanup();
2751 #endif
2752 #ifdef ARCADIA
2753 	arcadia_unmap ();
2754 #endif
2755 }
2756 
set_roms_modified(void)2757 void set_roms_modified(void)
2758 {
2759 #ifdef FSUAE
2760 	write_log("set roms_modified = true;\n");
2761 #endif
2762 	roms_modified = true;
2763 }
2764 
memory_hardreset(int mode)2765 void memory_hardreset (int mode)
2766 {
2767 	if (mode + 1 > mem_hardreset)
2768 		mem_hardreset = mode + 1;
2769 }
2770 
2771 // do not map if it conflicts with custom banks
map_banks_cond(addrbank * bank,int start,int size,int realsize)2772 void map_banks_cond (addrbank *bank, int start, int size, int realsize)
2773 {
2774 	for (int i = 0; i < MAX_CUSTOM_MEMORY_ADDRS; i++) {
2775 		int cstart = currprefs.custom_memory_addrs[i] >> 16;
2776 		if (!cstart)
2777 			continue;
2778 		int csize = currprefs.custom_memory_sizes[i] >> 16;
2779 		if (!csize)
2780 			continue;
2781 		if (start <= cstart && start + size >= cstart)
2782 			return;
2783 		if (cstart <= start && (cstart + size >= start || start + size > cstart))
2784 			return;
2785 	}
2786 	map_banks (bank, start, size, realsize);
2787 }
2788 
2789 #ifdef WITH_THREADED_CPU
2790 
2791 struct addrbank_thread {
2792 	addrbank *orig;
2793 	addrbank ab;
2794 };
2795 
2796 #define MAX_THREAD_BANKS 200
2797 static addrbank_thread *thread_banks[MAX_THREAD_BANKS];
2798 static addrbank *thread_mem_banks[MEMORY_BANKS];
2799 static int thread_banks_used;
2800 
threadcpu_lput(uaecptr addr,uae_u32 l)2801 static void REGPARAM2 threadcpu_lput(uaecptr addr, uae_u32 l)
2802 {
2803 	cpu_semaphore_get();
2804 	thread_mem_banks[bankindex(addr)]->lput(addr, l);
2805 	cpu_semaphore_release();
2806 }
2807 
threadcpu_wput(uaecptr addr,uae_u32 w)2808 static void REGPARAM2 threadcpu_wput(uaecptr addr, uae_u32 w)
2809 {
2810 	cpu_semaphore_get();
2811 	thread_mem_banks[bankindex(addr)]->wput(addr, w);
2812 	cpu_semaphore_release();
2813 }
2814 
threadcpu_bput(uaecptr addr,uae_u32 b)2815 static void REGPARAM2 threadcpu_bput(uaecptr addr, uae_u32 b)
2816 {
2817 	cpu_semaphore_get();
2818 	thread_mem_banks[bankindex(addr)]->bput(addr, b);
2819 	cpu_semaphore_release();
2820 }
threadcpu_lget(uaecptr addr)2821 static uae_u32 REGPARAM2 threadcpu_lget(uaecptr addr)
2822 {
2823 	cpu_semaphore_get();
2824 	uae_u32 v = thread_mem_banks[bankindex(addr)]->lget(addr);
2825 	cpu_semaphore_release();
2826 	return v;
2827 }
threadcpu_wget(uaecptr addr)2828 static uae_u32 REGPARAM2 threadcpu_wget(uaecptr addr)
2829 {
2830 	cpu_semaphore_get();
2831 	uae_u32 v = thread_mem_banks[bankindex(addr)]->wget(addr);
2832 	cpu_semaphore_release();
2833 	return v;
2834 }
threadcpu_bget(uaecptr addr)2835 uae_u32 REGPARAM2 threadcpu_bget(uaecptr addr)
2836 {
2837 	cpu_semaphore_get();
2838 	uae_u32 v = thread_mem_banks[bankindex(addr)]->bget(addr);
2839 	cpu_semaphore_release();
2840 	return v;
2841 }
2842 
get_bank_cpu_thread(addrbank * bank)2843 static addrbank *get_bank_cpu_thread(addrbank *bank)
2844 {
2845 	if (bank->flags & ABFLAG_THREADSAFE)
2846 		return bank;
2847 	if (bank == &dummy_bank)
2848 		return bank;
2849 
2850 	for (int i = 0; i < thread_banks_used; i++) {
2851 		if (thread_banks[i]->orig == bank) {
2852 			return &thread_banks[i]->ab;
2853 		}
2854 	}
2855 	struct addrbank_thread *at = thread_banks[thread_banks_used];
2856 	if (!at)
2857 		at = xcalloc(addrbank_thread, 1);
2858 	thread_banks[thread_banks_used++] = at;
2859 	at->orig = bank;
2860 	memcpy(&at->ab, bank, sizeof addrbank);
2861 	addrbank *tb = &at->ab;
2862 	tb->lget = threadcpu_lget;
2863 	tb->wget = threadcpu_wget;
2864 	tb->bget = threadcpu_bget;
2865 	tb->lput = threadcpu_lput;
2866 	tb->wput = threadcpu_wput;
2867 	tb->bput = threadcpu_bput;
2868 	// wgeti/lgeti should always point to real RAM
2869 	return tb;
2870 }
2871 #endif
2872 
map_banks2(addrbank * bank,int start,int size,int realsize,int quick)2873 static void map_banks2 (addrbank *bank, int start, int size, int realsize, int quick)
2874 {
2875 	int bnr, old;
2876 	unsigned long int hioffs = 0, endhioffs = 0x100;
2877 	uae_u32 realstart = start;
2878 	addrbank *orig_bank = NULL;
2879 
2880 #ifdef WITH_THREADED_CPU
2881 	if (currprefs.cpu_thread) {
2882 		addrbank *b = bank;
2883 		bank = get_bank_cpu_thread(bank);
2884 		if (b != bank)
2885 			orig_bank = b;
2886 	}
2887 #endif
2888 
2889 	if (quick <= 0)
2890 		old = debug_bankchange (-1);
2891 	flush_icache_hard (0, 3); /* Sure don't want to keep any old mappings around! */
2892 #ifdef NATMEM_OFFSET
2893 	if (!quick)
2894 		delete_shmmaps (start << 16, size << 16);
2895 #endif
2896 
2897 	if (!realsize)
2898 		realsize = size << 16;
2899 
2900 	if ((size << 16) < realsize) {
2901 		write_log (_T("Broken mapping, size=%x, realsize=%x\nStart is %x\n"),
2902 			size, realsize, start);
2903 	}
2904 
2905 #ifndef ADDRESS_SPACE_24BIT
2906 	if (start >= 0x100) {
2907 		int real_left = 0;
2908 		for (bnr = start; bnr < start + size; bnr++) {
2909 			if (!real_left) {
2910 				realstart = bnr;
2911 				real_left = realsize >> 16;
2912 #ifdef NATMEM_OFFSET
2913 				if (!quick)
2914 					add_shmmaps (realstart << 16, bank);
2915 #endif
2916 			}
2917 			put_mem_bank (bnr << 16, bank, realstart << 16);
2918 #ifdef WITH_THREADED_CPU
2919 			if (currprefs.cpu_thread) {
2920 				if (orig_bank)
2921 					put_mem_bank(bnr << 16, orig_bank, realstart << 16);
2922 				thread_mem_banks[bnr] = orig_bank;
2923 			}
2924 #endif
2925 			real_left--;
2926 		}
2927 		if (quick <= 0)
2928 			debug_bankchange (old);
2929 		return;
2930 	}
2931 #endif
2932 	if (last_address_space_24)
2933 		endhioffs = 0x10000;
2934 #ifdef ADDRESS_SPACE_24BIT
2935 	endhioffs = 0x100;
2936 #endif
2937 	for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
2938 		int real_left = 0;
2939 		for (bnr = start; bnr < start + size; bnr++) {
2940 			if (!real_left) {
2941 				realstart = bnr + hioffs;
2942 				real_left = realsize >> 16;
2943 #ifdef NATMEM_OFFSET
2944 				if (!quick)
2945 					add_shmmaps (realstart << 16, bank);
2946 #endif
2947 			}
2948 			put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
2949 #ifdef WITH_THREADED_CPU
2950 			if (currprefs.cpu_thread) {
2951 				if (orig_bank)
2952 					put_mem_bank((bnr + hioffs) << 16, bank, realstart << 16);
2953 				thread_mem_banks[bnr + hioffs] = orig_bank;
2954 			}
2955 #endif
2956 			real_left--;
2957 		}
2958 	}
2959 	if (quick <= 0)
2960 		debug_bankchange (old);
2961 	fill_ce_banks ();
2962 }
2963 
2964 #ifdef WITH_PPC
ppc_generate_map_banks(addrbank * bank,int start,int size)2965 static void ppc_generate_map_banks(addrbank *bank, int start, int size)
2966 {
2967 	uae_u32 bankaddr = start << 16;
2968 	uae_u32 banksize = size << 16;
2969 	if (bank->sub_banks) {
2970 		uae_u32 subbankaddr = bankaddr;
2971 		addrbank *ab = NULL;
2972 		for (int i = 0; i <= 65536; i += MEMORY_MIN_SUBBANK) {
2973 			uae_u32 addr = bankaddr + i;
2974 			addrbank *ab2 = get_sub_bank(&addr);
2975 			if (ab2 != ab && ab != NULL) {
2976 				ppc_map_banks(subbankaddr, (bankaddr + i) - subbankaddr, ab->name, (ab->flags & ABFLAG_PPCIOSPACE) ? NULL : ab->baseaddr, ab == &dummy_bank);
2977 				subbankaddr = bankaddr + i;
2978 			}
2979 			ab = ab2;
2980 		}
2981 	} else {
2982 		// ABFLAG_PPCIOSPACE = map as indirect even if baseaddr is non-NULL
2983 		ppc_map_banks(bankaddr, banksize, bank->name, (bank->flags & ABFLAG_PPCIOSPACE) ? NULL: bank->baseaddr, bank == &dummy_bank);
2984 	}
2985 }
2986 #endif
2987 
map_banks(addrbank * bank,int start,int size,int realsize)2988 void map_banks (addrbank *bank, int start, int size, int realsize)
2989 {
2990 	map_banks2 (bank, start, size, realsize, 0);
2991 #ifdef WITH_PPC
2992 	ppc_generate_map_banks(bank, start, size);
2993 #endif
2994 }
2995 
validate_banks_z3(addrbank * bank,int start,int size)2996 bool validate_banks_z3(addrbank *bank, int start, int size)
2997 {
2998 	if (start < 0x1000 || size <= 0) {
2999 		error_log(_T("Z3 invalid map_banks(%s) start=%08x size=%08x\n"), bank->name, start << 16, size << 16);
3000 		cpu_halt(CPU_HALT_AUTOCONFIG_CONFLICT);
3001 		return false;
3002 	}
3003 	if (size > 0x4000 || start + size > 0xf000) {
3004 		error_log(_T("Z3 invalid map_banks(%s) start=%08x size=%08x\n"), bank->name, start << 16, size << 16);
3005 		return false;
3006 	}
3007 	for (int i = start; i < start + size; i++) {
3008 		addrbank *ab = &get_mem_bank(start << 16);
3009 		if (ab != &dummy_bank && ab != bank) {
3010 			error_log(_T("Z3 map_banks(%s) attempting to override existing memory bank '%s' at %08x!\n"), bank->name, ab->name, i << 16);
3011 			return false;
3012 		}
3013 	}
3014 	return true;
3015 }
3016 
map_banks_z3(addrbank * bank,int start,int size)3017 void map_banks_z3(addrbank *bank, int start, int size)
3018 {
3019 	if (!validate_banks_z3(bank, start, size))
3020 		return;
3021 	map_banks(bank, start, size, 0);
3022 }
3023 
validate_banks_z2(addrbank * bank,int start,int size)3024 bool validate_banks_z2(addrbank *bank, int start, int size)
3025 {
3026 	if (start < 0x20 || (start >= 0xa0 && start < 0xe9) || start >= 0xf0) {
3027 		error_log(_T("Z2 map_banks(%s) with invalid start address %08X\n"), bank->name, start << 16);
3028 		cpu_halt(CPU_HALT_AUTOCONFIG_CONFLICT);
3029 		return false;
3030 	}
3031 	if (start >= 0xe9) {
3032 		if (start + size > 0xf0) {
3033 			error_log(_T("Z2 map_banks(%s) with invalid region %08x - %08X\n"), bank->name, start << 16, (start + size) << 16);
3034 			cpu_halt(CPU_HALT_AUTOCONFIG_CONFLICT);
3035 			return false;
3036 		}
3037 	} else {
3038 		if (start + size > 0xa0) {
3039 			error_log(_T("Z2 map_banks(%s) with invalid region %08x - %08X\n"), bank->name, start << 16, (start + size) << 16);
3040 			cpu_halt(CPU_HALT_AUTOCONFIG_CONFLICT);
3041 			return false;
3042 		}
3043 	}
3044 	if (size <= 0 || size > 0x80) {
3045 		error_log(_T("Z2 map_banks(%s) with invalid size %08x\n"), size);
3046 		cpu_halt(CPU_HALT_AUTOCONFIG_CONFLICT);
3047 		return false;
3048 	}
3049 	for (int i = start; i < start + size; i++) {
3050 		addrbank *ab = &get_mem_bank(start << 16);
3051 		if (ab != &dummy_bank) {
3052 			error_log(_T("Z2 map_banks(%s) attempting to override existing memory bank '%s' at %08x!\n"), bank->name, ab->name, i << 16);
3053 			return false;
3054 		}
3055 	}
3056 	return true;
3057 }
3058 
3059 
map_banks_z2(addrbank * bank,int start,int size)3060 void map_banks_z2 (addrbank *bank, int start, int size)
3061 {
3062 	if (!validate_banks_z2(bank, start, size))
3063 		return;
3064 	map_banks (bank, start, size, 0);
3065 }
3066 
3067 
map_banks_quick(addrbank * bank,int start,int size,int realsize)3068 void map_banks_quick (addrbank *bank, int start, int size, int realsize)
3069 {
3070 	map_banks2 (bank, start, size, realsize, 1);
3071 #ifdef WITH_PPC
3072 	ppc_generate_map_banks(bank, start, size);
3073 #endif
3074 }
map_banks_nojitdirect(addrbank * bank,int start,int size,int realsize)3075 void map_banks_nojitdirect (addrbank *bank, int start, int size, int realsize)
3076 {
3077 	map_banks2 (bank, start, size, realsize, -1);
3078 #ifdef WITH_PPC
3079 	ppc_generate_map_banks(bank, start, size);
3080 #endif
3081 }
3082 
3083 #ifdef SAVESTATE
3084 
3085 /* memory save/restore code */
3086 
save_bootrom(int * len)3087 uae_u8 *save_bootrom (int *len)
3088 {
3089 	if (!uae_boot_rom_type)
3090 		return 0;
3091 	*len = uae_boot_rom_size;
3092 	return rtarea_bank.baseaddr;
3093 }
3094 
save_cram(int * len)3095 uae_u8 *save_cram (int *len)
3096 {
3097 	*len = chipmem_bank.allocated;
3098 	return chipmem_bank.baseaddr;
3099 }
3100 
save_bram(int * len)3101 uae_u8 *save_bram (int *len)
3102 {
3103 	*len = bogomem_bank.allocated;
3104 	return bogomem_bank.baseaddr;
3105 }
3106 
save_mem25bitram(int * len)3107 static uae_u8 *save_mem25bitram (int *len)
3108 {
3109 	*len = mem25bit_bank.allocated;
3110 	return mem25bit_bank.baseaddr;
3111 }
3112 
save_a3000lram(int * len)3113 uae_u8 *save_a3000lram (int *len)
3114 {
3115 	*len = a3000lmem_bank.allocated;
3116 	return a3000lmem_bank.baseaddr;
3117 }
3118 
save_a3000hram(int * len)3119 uae_u8 *save_a3000hram (int *len)
3120 {
3121 	*len = a3000hmem_bank.allocated;
3122 	return a3000hmem_bank.baseaddr;
3123 }
3124 
restore_bootrom(int len,size_t filepos)3125 void restore_bootrom (int len, size_t filepos)
3126 {
3127 	bootrom_filepos = filepos;
3128 }
3129 
restore_cram(int len,size_t filepos)3130 void restore_cram (int len, size_t filepos)
3131 {
3132 	chip_filepos = filepos;
3133 	changed_prefs.chipmem_size = len;
3134 }
3135 
restore_bram(int len,size_t filepos)3136 void restore_bram (int len, size_t filepos)
3137 {
3138 	bogo_filepos = filepos;
3139 	changed_prefs.bogomem_size = len;
3140 }
3141 
restore_a3000lram(int len,size_t filepos)3142 void restore_a3000lram (int len, size_t filepos)
3143 {
3144 	a3000lmem_filepos = filepos;
3145 	changed_prefs.mbresmem_low_size = len;
3146 }
3147 
restore_a3000hram(int len,size_t filepos)3148 void restore_a3000hram (int len, size_t filepos)
3149 {
3150 	a3000hmem_filepos = filepos;
3151 	changed_prefs.mbresmem_high_size = len;
3152 }
3153 
restore_rom(uae_u8 * src)3154 uae_u8 *restore_rom (uae_u8 *src)
3155 {
3156 	uae_u32 crc32, mem_start, mem_size, mem_type, version;
3157 	TCHAR *s, *romn;
3158 	int i, crcdet;
3159 	struct romlist *rl = romlist_getit ();
3160 
3161 	mem_start = restore_u32 ();
3162 	mem_size = restore_u32 ();
3163 	mem_type = restore_u32 ();
3164 	version = restore_u32 ();
3165 	crc32 = restore_u32 ();
3166 	romn = restore_string ();
3167 	crcdet = 0;
3168 	for (i = 0; i < romlist_count (); i++) {
3169 		if (rl[i].rd->crc32 == crc32 && crc32) {
3170 			if (zfile_exists (rl[i].path)) {
3171 				switch (mem_type)
3172 				{
3173 				case 0:
3174 					_tcsncpy (changed_prefs.romfile, rl[i].path, 255);
3175 					break;
3176 				case 1:
3177 					_tcsncpy (changed_prefs.romextfile, rl[i].path, 255);
3178 					break;
3179 				}
3180 				write_log (_T("ROM '%s' = '%s'\n"), romn, rl[i].path);
3181 				crcdet = 1;
3182 			} else {
3183 				write_log (_T("ROM '%s' = '%s' invalid rom scanner path!"), romn, rl[i].path);
3184 			}
3185 			break;
3186 		}
3187 	}
3188 	s = restore_string ();
3189 	if (!crcdet) {
3190 		if (zfile_exists (s)) {
3191 			switch (mem_type)
3192 			{
3193 			case 0:
3194 				_tcsncpy (changed_prefs.romfile, s, 255);
3195 				break;
3196 			case 1:
3197 				_tcsncpy (changed_prefs.romextfile, s, 255);
3198 				break;
3199 			}
3200 			write_log (_T("ROM detected (path) as '%s'\n"), s);
3201 			crcdet = 1;
3202 		}
3203 	}
3204 	xfree (s);
3205 	if (!crcdet)
3206 		write_log (_T("WARNING: ROM '%s' %d.%d (CRC32=%08x %08x-%08x) not found!\n"),
3207 			romn, version >> 16, version & 0xffff, crc32, mem_start, mem_start + mem_size - 1);
3208 	xfree (romn);
3209 	return src;
3210 }
3211 
save_rom(int first,int * len,uae_u8 * dstptr)3212 uae_u8 *save_rom (int first, int *len, uae_u8 *dstptr)
3213 {
3214 	static int count;
3215 	uae_u8 *dst, *dstbak;
3216 	uae_u8 *mem_real_start;
3217 	uae_u32 version;
3218 	TCHAR *path;
3219 	int mem_start, mem_size, mem_type, saverom;
3220 	int i;
3221 	TCHAR tmpname[1000];
3222 
3223 	version = 0;
3224 	saverom = 0;
3225 	if (first)
3226 		count = 0;
3227 	for (;;) {
3228 		mem_type = count;
3229 		mem_size = 0;
3230 		switch (count) {
3231 		case 0: /* Kickstart ROM */
3232 			mem_start = 0xf80000;
3233 			mem_real_start = kickmem_bank.baseaddr;
3234 			mem_size = kickmem_bank.allocated;
3235 			path = currprefs.romfile;
3236 			/* 256KB or 512KB ROM? */
3237 			for (i = 0; i < mem_size / 2 - 4; i++) {
3238 				if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
3239 					break;
3240 			}
3241 			if (i == mem_size / 2 - 4) {
3242 				mem_size /= 2;
3243 				mem_start += ROM_SIZE_256;
3244 			}
3245 			version = longget (mem_start + 12); /* version+revision */
3246 			_stprintf (tmpname, _T("Kickstart %d.%d"), wordget (mem_start + 12), wordget (mem_start + 14));
3247 			break;
3248 		case 1: /* Extended ROM */
3249 			if (!extendedkickmem_type)
3250 				break;
3251 			mem_start = extendedkickmem_bank.start;
3252 			mem_real_start = extendedkickmem_bank.baseaddr;
3253 			mem_size = extendedkickmem_bank.allocated;
3254 			path = currprefs.romextfile;
3255 			version = longget (mem_start + 12); /* version+revision */
3256 			if (version == 0xffffffff)
3257 				version = longget (mem_start + 16);
3258 			_stprintf (tmpname, _T("Extended"));
3259 			break;
3260 		default:
3261 			return 0;
3262 		}
3263 		count++;
3264 		if (mem_size)
3265 			break;
3266 	}
3267 	if (dstptr)
3268 		dstbak = dst = dstptr;
3269 	else
3270 		dstbak = dst = xmalloc (uae_u8, 4 + 4 + 4 + 4 + 4 + 256 + 256 + mem_size);
3271 	save_u32 (mem_start);
3272 	save_u32 (mem_size);
3273 	save_u32 (mem_type);
3274 	save_u32 (version);
3275 	save_u32 (get_crc32 (mem_real_start, mem_size));
3276 	save_string (tmpname);
3277 	save_string (path);
3278 	if (saverom) {
3279 		for (i = 0; i < mem_size; i++)
3280 			*dst++ = byteget (mem_start + i);
3281 	}
3282 	*len = dst - dstbak;
3283 	return dstbak;
3284 }
3285 
3286 #endif /* SAVESTATE */
3287 
3288 /* memory helpers */
3289 
memcpyha_safe(uaecptr dst,const uae_u8 * src,int size)3290 void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size)
3291 {
3292 	if (!addr_valid (_T("memcpyha"), dst, size))
3293 		return;
3294 	while (size--)
3295 		put_byte (dst++, *src++);
3296 }
memcpyha(uaecptr dst,const uae_u8 * src,int size)3297 void memcpyha (uaecptr dst, const uae_u8 *src, int size)
3298 {
3299 	while (size--)
3300 		put_byte (dst++, *src++);
3301 }
memcpyah_safe(uae_u8 * dst,uaecptr src,int size)3302 void memcpyah_safe (uae_u8 *dst, uaecptr src, int size)
3303 {
3304 	if (!addr_valid (_T("memcpyah"), src, size))
3305 		return;
3306 	while (size--)
3307 		*dst++ = get_byte (src++);
3308 }
memcpyah(uae_u8 * dst,uaecptr src,int size)3309 void memcpyah (uae_u8 *dst, uaecptr src, int size)
3310 {
3311 	while (size--)
3312 		*dst++ = get_byte (src++);
3313 }
strcpyah_safe(uae_char * dst,uaecptr src,int maxsize)3314 uae_char *strcpyah_safe (uae_char *dst, uaecptr src, int maxsize)
3315 {
3316 	uae_char *res = dst;
3317 	uae_u8 b;
3318 	dst[0] = 0;
3319 	do {
3320 		if (!addr_valid (_T("_tcscpyah"), src, 1))
3321 			return res;
3322 		b = get_byte (src++);
3323 		*dst++ = b;
3324 		*dst = 0;
3325 		maxsize--;
3326 		if (maxsize <= 1)
3327 			break;
3328 	} while (b);
3329 	return res;
3330 }
strcpyha_safe(uaecptr dst,const uae_char * src)3331 uaecptr strcpyha_safe (uaecptr dst, const uae_char *src)
3332 {
3333 	uaecptr res = dst;
3334 	uae_u8 b;
3335 	do {
3336 		if (!addr_valid (_T("_tcscpyha"), dst, 1))
3337 			return res;
3338 		b = *src++;
3339 		put_byte (dst++, b);
3340 	} while (b);
3341 	return res;
3342 }
3343 #ifdef FSUAE
3344 
uae_get_memory_checksum(void * data,int size)3345 int uae_get_memory_checksum(void *data, int size)
3346 {
3347 	uint32_t checksum = 0;
3348 	int bank_size;
3349     uint32_t *mem;
3350     int pos = 0;
3351 
3352     mem = (uint32_t *) chipmem_bank.baseaddr;
3353     bank_size = chipmem_bank.allocated / 4;
3354     if (data) {
3355         if (pos + bank_size * 4 <= size) {
3356             memcpy((char *) data + pos, mem, bank_size * 4);
3357         }
3358         pos += bank_size * 4;
3359     }
3360     for (int i = 0; i < bank_size; i++) {
3361         //checksum = (checksum + *mem) & 0x00ffffff;
3362     	checksum += *mem;
3363         mem++;
3364     }
3365 
3366     mem = (uint32_t *) bogomem_bank.baseaddr;
3367     bank_size = bogomem_bank.allocated / 4;
3368     if (data) {
3369         if (pos + bank_size * 4 <= size) {
3370             memcpy((char *) data + pos, mem, bank_size * 4);
3371         }
3372         pos += bank_size * 4;
3373     }
3374     for (int i = 0; i < bank_size; i++) {
3375     	checksum += *mem;
3376         mem++;
3377     }
3378 
3379     mem = (uint32_t *) fastmem_bank.baseaddr;
3380     bank_size = fastmem_bank.allocated / 4;
3381     if (data) {
3382         if (pos + bank_size * 4 <= size) {
3383             memcpy((char *) data + pos, mem, bank_size * 4);
3384         }
3385         pos += bank_size * 4;
3386     }
3387     for (int i = 0; i < bank_size; i++) {
3388         checksum += *mem;
3389         mem++;
3390     }
3391 
3392     return checksum;
3393 }
3394 
3395 #endif
3396