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