|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Memory management
5: *
6: * (c) 1995 Bernd Schmidt
7: */
8:
9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
12: #include "config.h"
13: #include "options.h"
1.1.1.3 root 14: #include "uae.h"
1.1 root 15: #include "memory.h"
16: #include "ersatz.h"
17: #include "zfile.h"
1.1.1.9 root 18: #include "custom.h"
19: #include "events.h"
20: #include "newcpu.h"
1.1.1.11 root 21: #include "autoconf.h"
1.1.1.9 root 22: #include "savestate.h"
1.1 root 23:
1.1.1.2 root 24: #ifdef USE_MAPPED_MEMORY
1.1 root 25: #include <sys/mman.h>
26: #endif
27:
1.1.1.8 root 28: /* Set by each memory handler that does not simply access real memory. */
29: int special_mem;
30:
1.1 root 31: int ersatzkickfile = 0;
32:
1.1.1.4 root 33: uae_u32 allocated_chipmem;
34: uae_u32 allocated_fastmem;
35: uae_u32 allocated_bogomem;
36: uae_u32 allocated_gfxmem;
37: uae_u32 allocated_z3fastmem;
38: uae_u32 allocated_a3000mem;
39:
1.1.1.9 root 40: static long chip_filepos;
41: static long bogo_filepos;
42: static long rom_filepos;
43:
1.1.1.14! root 44: /* ROM management. */
! 45: struct romlist {
! 46: char *path;
! 47: struct romdata *rd;
! 48: };
! 49:
! 50: static struct romlist *rl;
! 51: static int romlist_cnt;
! 52:
! 53: void romlist_add (char *path, struct romdata *rd)
! 54: {
! 55: struct romlist *rl2;
! 56:
! 57: romlist_cnt++;
! 58: rl = realloc (rl, sizeof (struct romlist) * romlist_cnt);
! 59: rl2 = rl + romlist_cnt - 1;
! 60: rl2->path = my_strdup (path);
! 61: rl2->rd = rd;
! 62: }
! 63:
! 64: char *romlist_get (struct romdata *rd)
! 65: {
! 66: int i;
! 67:
! 68: if (!rd)
! 69: return 0;
! 70: for (i = 0; i < romlist_cnt; i++) {
! 71: if (rl[i].rd == rd)
! 72: return rl[i].path;
! 73: }
! 74: return 0;
! 75: }
! 76:
! 77: void romlist_clear (void)
! 78: {
! 79: free (rl);
! 80: rl = 0;
! 81: romlist_cnt = 0;
! 82: }
! 83:
! 84: static struct romdata roms[] = {
! 85: { "Cloanto Amiga Forever ROM key", 0, 0, 0x869ae1b1, 2069, 0, 0, 1, ROMTYPE_KEY },
! 86:
! 87: { "Kickstart v1.0 (A1000)(NTSC)", 0, 0, 0x299790ff, 262144, 1, 0, 0, ROMTYPE_KICK },
! 88: { "Kickstart v1.1 (A1000)(NTSC)", 31, 34, 0xd060572a, 262144, 2, 0, 0, ROMTYPE_KICK },
! 89: { "Kickstart v1.1 (A1000)(PAL)", 31, 34, 0xec86dae2, 262144, 3, 0, 0, ROMTYPE_KICK },
! 90: { "Kickstart v1.2 (A1000)", 33, 166, 0x9ed783d0, 262144, 4, 0, 0, ROMTYPE_KICK },
! 91: { "Kickstart v1.2 (A500,A1000,A2000)", 33, 180, 0xa6ce1636, 262144, 5, 0, 0, ROMTYPE_KICK },
! 92: { "Kickstart v1.3 (A500,A1000,A2000)", 34, 5, 0xc4f0f55f, 262144, 6, 60, 0, ROMTYPE_KICK },
! 93: { "Kickstart v1.3 (A3000)", 34, 5, 0xe0f37258, 262144, 32, 0, 0, ROMTYPE_KICK },
! 94:
! 95: { "Kickstart v2.04 (A500+)", 37, 175, 0xc3bdb240, 524288, 7, 0, 0, ROMTYPE_KICK },
! 96: { "Kickstart v2.05 (A600)", 37, 299, 0x83028fb5, 524288, 8, 0, 0, ROMTYPE_KICK },
! 97: { "Kickstart v2.05 (A600HD)", 37, 300, 0x64466c2a, 524288, 9, 0, 0, ROMTYPE_KICK },
! 98: { "Kickstart v2.05 (A600HD)", 37, 350, 0x43b0df7b, 524288, 10, 0, 0, ROMTYPE_KICK },
! 99:
! 100: { "Kickstart v3.0 (A1200)", 39, 106, 0x6c9b07d2, 524288, 11, 0, 0, ROMTYPE_KICK },
! 101: { "Kickstart v3.0 (A4000)", 39, 106, 0x9e6ac152, 524288, 12, 2, 0, ROMTYPE_KICK },
! 102: { "Kickstart v3.1 (A4000)", 40, 70, 0x2b4566f1, 524288, 13, 2, 0, ROMTYPE_KICK },
! 103: { "Kickstart v3.1 (A500,A600,A2000)", 40, 63, 0xfc24ae0d, 524288, 14, 0, 0, ROMTYPE_KICK },
! 104: { "Kickstart v3.1 (A1200)", 40, 68, 0x1483a091, 524288, 15, 1, 0, ROMTYPE_KICK },
! 105: { "Kickstart v3.1 (A4000)(Cloanto)", 40, 68, 0x43b6dd22, 524288, 31, 2, 1, ROMTYPE_KICK },
! 106: { "Kickstart v3.1 (A4000)", 40, 68, 0xd6bae334, 524288, 16, 2, 0, ROMTYPE_KICK },
! 107: { "Kickstart v3.1 (A4000T)", 40, 70, 0x75932c3a, 524288, 17, 2, 0, ROMTYPE_KICK },
! 108:
! 109: { "CD32 Kickstart v3.1", 40, 60, 0x1e62d4a5, 524288, 18, 1, 0, ROMTYPE_KICKCD32 },
! 110: { "CD32 Extended", 40, 60, 0x87746be2, 524288, 19, 1, 0, ROMTYPE_EXTCD32 },
! 111:
! 112: { "CDTV Extended v1.00", 0, 0, 0x42baa124, 262144, 20, 0, 0, ROMTYPE_EXTCDTV },
! 113: { "CDTV Extended v2.30", 0, 0, 0x30b54232, 262144, 21, 0, 0, ROMTYPE_EXTCDTV },
! 114: { "CDTV Extended v2.07", 0, 0, 0xceae68d2, 262144, 22, 0, 0, ROMTYPE_EXTCDTV },
! 115:
! 116: { "A1000 Bootstrap", 0, 0, 0x62f11c04, 8192, 23, 0, 0, ROMTYPE_KICK },
! 117: { "A1000 Bootstrap", 0, 0, 0x0b1ad2d0, 65536, 24, 0, 0, ROMTYPE_KICK },
! 118:
! 119: { "Action Replay Mk I v1.50", 0, 0, 0xd4ce0675, 65536, 25, 0, 0, ROMTYPE_AR },
! 120: { "Action Replay Mk II v2.05", 0, 0, 0x1287301f , 131072, 26, 0, 0, ROMTYPE_AR },
! 121: { "Action Replay Mk II v2.12", 0, 0, 0x804d0361 , 131072, 27, 0, 0, ROMTYPE_AR },
! 122: { "Action Replay Mk II v2.14", 0, 0, 0x49650e4f, 131072, 28, 0, 0, ROMTYPE_AR },
! 123: { "Action Replay Mk III v3.09", 0, 0, 0x0ed9b5aa, 262144, 29, 0, 0, ROMTYPE_AR },
! 124: { "Action Replay Mk III v3.17", 0, 0, 0xc8a16406, 262144, 30, 0, 0, ROMTYPE_AR },
! 125:
! 126: { "SportTime Table Hockey\0ar_airh", 0, 0, 0, 0, 33, 0, 0, ROMTYPE_ARCADIA },
! 127: { "SportTime Bowling\0ar_bowl", 0, 0, 0, 0, 34, 0, 0, ROMTYPE_ARCADIA },
! 128: { "World Darts\0ar_dart", 0, 0, 0, 0, 35, 0, 0, ROMTYPE_ARCADIA },
! 129: { "Magic Johnson's Fast Break\0ar_fast", 0, 0, 0, 0, 36, 0, 0, ROMTYPE_ARCADIA },
! 130: { "Leader Board Golf\0ar_ldrb", 0, 0, 0, 0, 37, 0, 0, ROMTYPE_ARCADIA },
! 131: { "Leader Board Golf (alt)\0ar_ldrba", 0, 0, 0, 0, 38, 0, 0, ROMTYPE_ARCADIA },
! 132: { "Ninja Mission\0ar_ninj", 0, 0, 0, 0, 39, 0, 0, ROMTYPE_ARCADIA },
! 133: { "Road Wars\0ar_rdwr", 0, 0, 0, 0, 40, 0, 0, ROMTYPE_ARCADIA },
! 134: { "Sidewinder\0ar_sdwr", 0, 0, 0, 0, 41, 0, 0, ROMTYPE_ARCADIA },
! 135: { "Cool Spot\0ar_spot", 0, 0, 0, 0, 42, 0, 0, ROMTYPE_ARCADIA },
! 136: { "Space Ranger\0ar_sprg", 0, 0, 0, 0, 43, 0, 0, ROMTYPE_ARCADIA },
! 137: { "Xenon\0ar_xeon", 0, 0, 0, 0, 44, 0, 0, ROMTYPE_ARCADIA },
! 138:
! 139: { NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
! 140: };
! 141:
! 142: static int decode_cloanto_rom (uae_u8 *mem, int size, int real_size)
! 143: {
! 144: FILE *keyf;
! 145: uae_u8 *p;
! 146: long cnt, t;
! 147: int keysize;
! 148:
! 149: if (strlen (currprefs.keyfile) == 0) {
! 150: write_log ("No filename given for ROM key file and ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
! 151: return 0;
! 152: }
! 153: keyf = zfile_open (currprefs.keyfile, "rb");
! 154: if (keyf == 0) {
! 155: write_log ("Could not find specified ROM key-file.\n");
! 156: return 0;
! 157: }
! 158:
! 159: p = (uae_u8 *) xmalloc (524288);
! 160: keysize = fread (p, 1, 524288, keyf);
! 161: for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize) {
! 162: mem[cnt] ^= p[t];
! 163: if (real_size == cnt + 1)
! 164: t = keysize - 1;
! 165: }
! 166: fclose (keyf);
! 167: free (p);
! 168: return 1;
! 169: }
! 170:
1.1.1.3 root 171: addrbank *mem_banks[65536];
1.1.1.9 root 172:
173: /* This has two functions. It either holds a host address that, when added
174: to the 68k address, gives the host address corresponding to that 68k
175: address (in which case the value in this array is even), OR it holds the
176: same value as mem_banks, for those banks that have baseaddr==0. In that
177: case, bit 0 is set (the memory access routines will take care of it). */
178:
179: uae_u8 *baseaddr[65536];
1.1 root 180:
1.1.1.2 root 181: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5 root 182: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2 root 183: {
1.1.1.5 root 184: return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2 root 185: }
1.1.1.5 root 186: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2 root 187: {
1.1.1.5 root 188: return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2 root 189: }
1.1.1.5 root 190: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2 root 191: {
1.1.1.5 root 192: return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2 root 193: }
1.1.1.5 root 194: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2 root 195: {
1.1.1.5 root 196: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2 root 197: }
1.1.1.5 root 198: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2 root 199: {
1.1.1.5 root 200: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2 root 201: }
1.1.1.5 root 202: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2 root 203: {
1.1.1.5 root 204: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2 root 205: }
206: #endif
207:
1.1.1.12 root 208: uae_u32 chipmem_mask, kickmem_mask, extendedkickmem_mask, bogomem_mask, a3000mem_mask;
1.1 root 209:
1.1.1.11 root 210: static int illegal_count;
1.1.1.3 root 211: /* A dummy bank that only contains zeros */
212:
1.1.1.4 root 213: static uae_u32 dummy_lget (uaecptr) REGPARAM;
214: static uae_u32 dummy_wget (uaecptr) REGPARAM;
215: static uae_u32 dummy_bget (uaecptr) REGPARAM;
216: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
217: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
218: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
219: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
220:
221: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
222: {
1.1.1.8 root 223: special_mem |= S_READ;
1.1.1.11 root 224: if (currprefs.illegal_mem) {
225: if (illegal_count < 20) {
226: illegal_count++;
227: write_log ("Illegal lget at %08lx\n", addr);
228: }
229: }
1.1.1.4 root 230:
1.1.1.9 root 231: return 0xFFFFFFFF;
1.1 root 232: }
233:
1.1.1.4 root 234: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1 root 235: {
1.1.1.8 root 236: special_mem |= S_READ;
1.1.1.11 root 237: if (currprefs.illegal_mem) {
238: if (illegal_count < 20) {
239: illegal_count++;
240: write_log ("Illegal wget at %08lx\n", addr);
241: }
242: }
1.1.1.12 root 243:
1.1.1.9 root 244: return 0xFFFF;
1.1 root 245: }
246:
1.1.1.4 root 247: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1 root 248: {
1.1.1.8 root 249: special_mem |= S_READ;
1.1.1.11 root 250: if (currprefs.illegal_mem) {
251: if (illegal_count < 20) {
252: illegal_count++;
253: write_log ("Illegal bget at %08lx\n", addr);
254: }
255: }
1.1.1.4 root 256:
1.1.1.9 root 257: return 0xFF;
1.1 root 258: }
259:
1.1.1.4 root 260: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1 root 261: {
1.1.1.8 root 262: special_mem |= S_WRITE;
1.1.1.11 root 263: if (currprefs.illegal_mem) {
264: if (illegal_count < 20) {
265: illegal_count++;
266: write_log ("Illegal lput at %08lx\n", addr);
267: }
268: }
1.1.1.3 root 269: }
1.1.1.4 root 270: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 271: {
1.1.1.8 root 272: special_mem |= S_WRITE;
1.1.1.11 root 273: if (currprefs.illegal_mem) {
274: if (illegal_count < 20) {
275: illegal_count++;
276: write_log ("Illegal wput at %08lx\n", addr);
277: }
278: }
1.1.1.3 root 279: }
1.1.1.4 root 280: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 281: {
1.1.1.8 root 282: special_mem |= S_WRITE;
1.1.1.11 root 283: if (currprefs.illegal_mem) {
284: if (illegal_count < 20) {
285: illegal_count++;
286: write_log ("Illegal bput at %08lx\n", addr);
287: }
288: }
1.1 root 289: }
290:
1.1.1.4 root 291: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1 root 292: {
1.1.1.9 root 293: special_mem |= S_READ;
1.1.1.11 root 294: if (currprefs.illegal_mem) {
295: if (illegal_count < 20) {
296: illegal_count++;
297: write_log ("Illegal check at %08lx\n", addr);
298: }
299: }
1.1.1.4 root 300:
1.1 root 301: return 0;
302: }
303:
1.1.1.3 root 304: /* A3000 "motherboard resources" bank. */
1.1.1.4 root 305: static uae_u32 mbres_lget (uaecptr) REGPARAM;
306: static uae_u32 mbres_wget (uaecptr) REGPARAM;
307: static uae_u32 mbres_bget (uaecptr) REGPARAM;
308: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
309: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
310: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
311: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3 root 312:
313: static int mbres_val = 0;
314:
1.1.1.4 root 315: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3 root 316: {
1.1.1.8 root 317: special_mem |= S_READ;
1.1.1.4 root 318: if (currprefs.illegal_mem)
319: write_log ("Illegal lget at %08lx\n", addr);
320:
1.1 root 321: return 0;
322: }
323:
1.1.1.4 root 324: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1 root 325: {
1.1.1.8 root 326: special_mem |= S_READ;
1.1.1.4 root 327: if (currprefs.illegal_mem)
328: write_log ("Illegal wget at %08lx\n", addr);
329:
1.1 root 330: return 0;
331: }
332:
1.1.1.4 root 333: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3 root 334: {
1.1.1.8 root 335: special_mem |= S_READ;
1.1.1.4 root 336: if (currprefs.illegal_mem)
337: write_log ("Illegal bget at %08lx\n", addr);
338:
1.1.1.3 root 339: return (addr & 0xFFFF) == 3 ? mbres_val : 0;
340: }
341:
1.1.1.4 root 342: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1 root 343: {
1.1.1.8 root 344: special_mem |= S_WRITE;
1.1.1.4 root 345: if (currprefs.illegal_mem)
346: write_log ("Illegal lput at %08lx\n", addr);
1.1 root 347: }
1.1.1.4 root 348: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1 root 349: {
1.1.1.8 root 350: special_mem |= S_WRITE;
1.1.1.4 root 351: if (currprefs.illegal_mem)
352: write_log ("Illegal wput at %08lx\n", addr);
1.1 root 353: }
1.1.1.4 root 354: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1 root 355: {
1.1.1.8 root 356: special_mem |= S_WRITE;
1.1.1.4 root 357: if (currprefs.illegal_mem)
358: write_log ("Illegal bput at %08lx\n", addr);
359:
1.1.1.3 root 360: if ((addr & 0xFFFF) == 3)
361: mbres_val = b;
1.1 root 362: }
363:
1.1.1.4 root 364: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1 root 365: {
1.1.1.4 root 366: if (currprefs.illegal_mem)
367: write_log ("Illegal check at %08lx\n", addr);
368:
1.1 root 369: return 0;
370: }
371:
372: /* Chip memory */
373:
1.1.1.3 root 374: uae_u8 *chipmemory;
1.1 root 375:
1.1.1.4 root 376: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
377: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1 root 378:
1.1.1.4 root 379: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1 root 380: {
1.1.1.3 root 381: uae_u32 *m;
1.1.1.8 root 382:
1.1 root 383: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 384: addr &= chipmem_mask;
1.1.1.3 root 385: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 386: return do_get_mem_long (m);
1.1 root 387: }
388:
1.1.1.4 root 389: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1 root 390: {
1.1.1.3 root 391: uae_u16 *m;
1.1.1.8 root 392:
1.1 root 393: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 394: addr &= chipmem_mask;
1.1.1.3 root 395: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 396: return do_get_mem_word (m);
1.1 root 397: }
398:
1.1.1.4 root 399: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1 root 400: {
401: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 402: addr &= chipmem_mask;
1.1 root 403: return chipmemory[addr];
404: }
405:
1.1.1.4 root 406: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1 root 407: {
1.1.1.3 root 408: uae_u32 *m;
1.1.1.8 root 409:
1.1 root 410: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 411: addr &= chipmem_mask;
1.1.1.3 root 412: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 413: do_put_mem_long (m, l);
1.1 root 414: }
415:
1.1.1.4 root 416: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1 root 417: {
1.1.1.3 root 418: uae_u16 *m;
1.1.1.8 root 419:
1.1 root 420: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 421: addr &= chipmem_mask;
1.1.1.3 root 422: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 423: do_put_mem_word (m, w);
1.1 root 424: }
425:
1.1.1.4 root 426: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1 root 427: {
428: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 429: addr &= chipmem_mask;
1.1 root 430: chipmemory[addr] = b;
431: }
432:
1.1.1.4 root 433: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1 root 434: {
435: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 436: addr &= chipmem_mask;
1.1.1.4 root 437: return (addr + size) <= allocated_chipmem;
1.1 root 438: }
439:
1.1.1.4 root 440: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1 root 441: {
442: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 443: addr &= chipmem_mask;
1.1 root 444: return chipmemory + addr;
445: }
446:
447: /* Slow memory */
448:
1.1.1.3 root 449: static uae_u8 *bogomemory;
1.1 root 450:
1.1.1.4 root 451: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
452: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
453: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
454: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
455: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
456: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
457: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
458: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1 root 459:
1.1.1.4 root 460: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1 root 461: {
1.1.1.3 root 462: uae_u32 *m;
1.1 root 463: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 464: addr &= bogomem_mask;
1.1.1.3 root 465: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 466: return do_get_mem_long (m);
1.1 root 467: }
468:
1.1.1.4 root 469: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1 root 470: {
1.1.1.3 root 471: uae_u16 *m;
1.1 root 472: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 473: addr &= bogomem_mask;
1.1.1.3 root 474: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 475: return do_get_mem_word (m);
1.1 root 476: }
477:
1.1.1.4 root 478: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1 root 479: {
480: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 481: addr &= bogomem_mask;
1.1 root 482: return bogomemory[addr];
483: }
484:
1.1.1.4 root 485: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1 root 486: {
1.1.1.3 root 487: uae_u32 *m;
1.1 root 488: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 489: addr &= bogomem_mask;
1.1.1.3 root 490: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 491: do_put_mem_long (m, l);
1.1 root 492: }
493:
1.1.1.4 root 494: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1 root 495: {
1.1.1.3 root 496: uae_u16 *m;
1.1 root 497: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 498: addr &= bogomem_mask;
1.1.1.3 root 499: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 500: do_put_mem_word (m, w);
1.1 root 501: }
502:
1.1.1.4 root 503: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1 root 504: {
505: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 506: addr &= bogomem_mask;
1.1 root 507: bogomemory[addr] = b;
508: }
509:
1.1.1.4 root 510: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1 root 511: {
1.1.1.2 root 512: addr -= bogomem_start & bogomem_mask;
513: addr &= bogomem_mask;
1.1.1.4 root 514: return (addr + size) <= allocated_bogomem;
1.1 root 515: }
516:
1.1.1.4 root 517: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1 root 518: {
1.1.1.2 root 519: addr -= bogomem_start & bogomem_mask;
520: addr &= bogomem_mask;
1.1 root 521: return bogomemory + addr;
522: }
523:
1.1.1.3 root 524: /* A3000 motherboard fast memory */
525:
526: static uae_u8 *a3000memory;
1.1 root 527:
1.1.1.4 root 528: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
529: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
530: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
531: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
532: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
533: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
534: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
535: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 536:
1.1.1.4 root 537: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3 root 538: {
539: uae_u32 *m;
540: addr -= a3000mem_start & a3000mem_mask;
541: addr &= a3000mem_mask;
542: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 543: return do_get_mem_long (m);
1.1.1.3 root 544: }
1.1 root 545:
1.1.1.4 root 546: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3 root 547: {
548: uae_u16 *m;
549: addr -= a3000mem_start & a3000mem_mask;
550: addr &= a3000mem_mask;
551: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 552: return do_get_mem_word (m);
1.1.1.3 root 553: }
1.1 root 554:
1.1.1.4 root 555: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1 root 556: {
1.1.1.3 root 557: addr -= a3000mem_start & a3000mem_mask;
558: addr &= a3000mem_mask;
559: return a3000memory[addr];
1.1 root 560: }
561:
1.1.1.4 root 562: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1 root 563: {
1.1.1.3 root 564: uae_u32 *m;
565: addr -= a3000mem_start & a3000mem_mask;
566: addr &= a3000mem_mask;
567: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 568: do_put_mem_long (m, l);
1.1.1.3 root 569: }
570:
1.1.1.4 root 571: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 572: {
573: uae_u16 *m;
574: addr -= a3000mem_start & a3000mem_mask;
575: addr &= a3000mem_mask;
576: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 577: do_put_mem_word (m, w);
1.1.1.3 root 578: }
579:
1.1.1.4 root 580: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 581: {
582: addr -= a3000mem_start & a3000mem_mask;
583: addr &= a3000mem_mask;
584: a3000memory[addr] = b;
585: }
586:
1.1.1.4 root 587: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3 root 588: {
589: addr -= a3000mem_start & a3000mem_mask;
590: addr &= a3000mem_mask;
1.1.1.4 root 591: return (addr + size) <= allocated_a3000mem;
1.1 root 592: }
593:
1.1.1.12 root 594: uae_u8 REGPARAM2 *a3000mem_xlate (uaecptr addr)
1.1.1.3 root 595: {
596: addr -= a3000mem_start & a3000mem_mask;
597: addr &= a3000mem_mask;
598: return a3000memory + addr;
599: }
600:
601: /* Kick memory */
602:
603: uae_u8 *kickmemory;
604:
1.1.1.12 root 605: /*
606: * A1000 kickstart RAM handling
607: *
608: * RESET instruction unhides boot ROM and disables write protection
609: * write access to boot ROM hides boot ROM and enables write protection
610: *
611: */
612: static int a1000_kickstart_mode;
613: static uae_u8 *a1000_bootrom;
614: static void a1000_handle_kickstart (int mode)
615: {
616: if (mode == 0) {
617: a1000_kickstart_mode = 0;
618: memcpy (kickmemory, kickmemory + 262144, 262144);
619: } else {
620: a1000_kickstart_mode = 1;
621: memset (kickmemory, 0, 262144);
622: memcpy (kickmemory, a1000_bootrom, 8192);
623: memcpy (kickmemory + 131072, a1000_bootrom, 8192);
624: }
625: }
626:
1.1.1.4 root 627: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
628: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
629: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
1.1.1.12 root 630: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
631: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
632: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
633: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.4 root 634: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 635:
1.1.1.4 root 636: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1 root 637: {
1.1.1.3 root 638: uae_u32 *m;
1.1 root 639: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 640: addr &= kickmem_mask;
1.1.1.3 root 641: m = (uae_u32 *)(kickmemory + addr);
1.1.1.5 root 642: return do_get_mem_long (m);
1.1 root 643: }
644:
1.1.1.4 root 645: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1 root 646: {
1.1.1.3 root 647: uae_u16 *m;
1.1 root 648: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 649: addr &= kickmem_mask;
1.1.1.3 root 650: m = (uae_u16 *)(kickmemory + addr);
1.1.1.5 root 651: return do_get_mem_word (m);
1.1 root 652: }
653:
1.1.1.4 root 654: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1 root 655: {
656: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 657: addr &= kickmem_mask;
1.1 root 658: return kickmemory[addr];
659: }
660:
1.1.1.4 root 661: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1 root 662: {
1.1.1.12 root 663: uae_u32 *m;
664: if (a1000_kickstart_mode) {
665: if (addr >= 0xfc0000) {
666: addr -= kickmem_start & kickmem_mask;
667: addr &= kickmem_mask;
668: m = (uae_u32 *)(kickmemory + addr);
669: do_put_mem_long (m, b);
670: return;
671: } else
672: a1000_handle_kickstart (0);
673: } else if (currprefs.illegal_mem)
1.1.1.4 root 674: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 675: }
676:
1.1.1.4 root 677: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1 root 678: {
1.1.1.12 root 679: uae_u16 *m;
680: if (a1000_kickstart_mode) {
681: if (addr >= 0xfc0000) {
682: addr -= kickmem_start & kickmem_mask;
683: addr &= kickmem_mask;
684: m = (uae_u16 *)(kickmemory + addr);
685: do_put_mem_word (m, b);
686: return;
687: } else
688: a1000_handle_kickstart (0);
689: } else if (currprefs.illegal_mem)
1.1.1.4 root 690: write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1 root 691: }
692:
1.1.1.4 root 693: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1 root 694: {
1.1.1.12 root 695: if (a1000_kickstart_mode) {
696: if (addr >= 0xfc0000) {
697: addr -= kickmem_start & kickmem_mask;
698: addr &= kickmem_mask;
699: kickmemory[addr] = b;
700: return;
701: } else
702: a1000_handle_kickstart (0);
703: } else if (currprefs.illegal_mem)
1.1.1.4 root 704: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 705: }
706:
1.1.1.4 root 707: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1 root 708: {
1.1.1.2 root 709: addr -= kickmem_start & kickmem_mask;
710: addr &= kickmem_mask;
1.1.1.4 root 711: return (addr + size) <= kickmem_size;
1.1 root 712: }
713:
1.1.1.4 root 714: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1 root 715: {
1.1.1.2 root 716: addr -= kickmem_start & kickmem_mask;
717: addr &= kickmem_mask;
1.1 root 718: return kickmemory + addr;
719: }
720:
1.1.1.12 root 721: /* CD32/CDTV extended kick memory */
1.1.1.3 root 722:
1.1.1.12 root 723: uae_u8 *extendedkickmemory;
724: static int extendedkickmem_size;
725: static uae_u32 extendedkickmem_start;
726:
727: #define EXTENDED_ROM_CD32 1
728: #define EXTENDED_ROM_CDTV 2
729:
730: static int extromtype (void)
731: {
732: switch (extendedkickmem_size) {
733: case 524288:
734: return EXTENDED_ROM_CD32;
735: case 262144:
736: return EXTENDED_ROM_CDTV;
737: }
1.1.1.3 root 738: return 0;
739: }
740:
1.1.1.12 root 741: static uae_u32 extendedkickmem_lget (uaecptr) REGPARAM;
742: static uae_u32 extendedkickmem_wget (uaecptr) REGPARAM;
743: static uae_u32 extendedkickmem_bget (uaecptr) REGPARAM;
744: static void extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
745: static void extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
746: static void extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
747: static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
748: static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM;
749:
750: uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr)
1.1.1.3 root 751: {
1.1.1.12 root 752: uae_u32 *m;
753: addr -= extendedkickmem_start & extendedkickmem_mask;
754: addr &= extendedkickmem_mask;
755: m = (uae_u32 *)(extendedkickmemory + addr);
756: return do_get_mem_long (m);
1.1.1.3 root 757: }
758:
1.1.1.12 root 759: uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr)
1.1 root 760: {
1.1.1.12 root 761: uae_u16 *m;
762: addr -= extendedkickmem_start & extendedkickmem_mask;
763: addr &= extendedkickmem_mask;
764: m = (uae_u16 *)(extendedkickmemory + addr);
765: return do_get_mem_word (m);
766: }
1.1.1.3 root 767:
1.1.1.12 root 768: uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr)
769: {
770: addr -= extendedkickmem_start & extendedkickmem_mask;
771: addr &= extendedkickmem_mask;
772: return extendedkickmemory[addr];
773: }
1.1.1.3 root 774:
1.1.1.12 root 775: void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
776: {
777: if (currprefs.illegal_mem)
778: write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
779: }
1.1.1.3 root 780:
1.1.1.12 root 781: void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
782: {
783: if (currprefs.illegal_mem)
784: write_log ("Illegal extendedkickmem wput at %08lx\n", addr);
785: }
1.1.1.3 root 786:
1.1.1.12 root 787: void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
788: {
789: if (currprefs.illegal_mem)
790: write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
791: }
1.1.1.3 root 792:
1.1.1.12 root 793: int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size)
794: {
795: addr -= extendedkickmem_start & extendedkickmem_mask;
796: addr &= extendedkickmem_mask;
797: return (addr + size) <= extendedkickmem_size;
798: }
1.1.1.3 root 799:
1.1.1.12 root 800: uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr)
801: {
802: addr -= extendedkickmem_start & extendedkickmem_mask;
803: addr &= extendedkickmem_mask;
804: return extendedkickmemory + addr;
805: }
1.1.1.2 root 806:
1.1.1.12 root 807: /* Default memory access functions */
808:
809: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
810: {
811: return 0;
812: }
813:
814: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
815: {
816: write_log ("Your Amiga program just did something terribly stupid\n");
817: uae_reset ();
818: return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
1.1 root 819: }
820:
821: /* Address banks */
822:
823: addrbank dummy_bank = {
824: dummy_lget, dummy_wget, dummy_bget,
825: dummy_lput, dummy_wput, dummy_bput,
1.1.1.9 root 826: default_xlate, dummy_check, NULL
1.1 root 827: };
828:
1.1.1.3 root 829: addrbank mbres_bank = {
830: mbres_lget, mbres_wget, mbres_bget,
831: mbres_lput, mbres_wput, mbres_bput,
1.1.1.9 root 832: default_xlate, mbres_check, NULL
1.1.1.3 root 833: };
834:
1.1 root 835: addrbank chipmem_bank = {
836: chipmem_lget, chipmem_wget, chipmem_bget,
837: chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.9 root 838: chipmem_xlate, chipmem_check, NULL
1.1 root 839: };
840:
841: addrbank bogomem_bank = {
842: bogomem_lget, bogomem_wget, bogomem_bget,
843: bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.9 root 844: bogomem_xlate, bogomem_check, NULL
1.1 root 845: };
846:
1.1.1.3 root 847: addrbank a3000mem_bank = {
848: a3000mem_lget, a3000mem_wget, a3000mem_bget,
849: a3000mem_lput, a3000mem_wput, a3000mem_bput,
1.1.1.9 root 850: a3000mem_xlate, a3000mem_check, NULL
1.1.1.3 root 851: };
852:
1.1 root 853: addrbank kickmem_bank = {
854: kickmem_lget, kickmem_wget, kickmem_bget,
855: kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.9 root 856: kickmem_xlate, kickmem_check, NULL
1.1 root 857: };
858:
1.1.1.12 root 859: addrbank extendedkickmem_bank = {
860: extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
861: extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
862: extendedkickmem_xlate, extendedkickmem_check, NULL
863: };
864:
865: static int kickstart_checksum (uae_u8 *mem, int size)
866: {
867: uae_u32 cksum = 0, prevck = 0;
868: int i;
869: for (i = 0; i < size; i += 4) {
870: uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
871: cksum += data;
872: if (cksum < prevck)
873: cksum++;
874: prevck = cksum;
875: }
876: if (cksum != 0xFFFFFFFFul) {
877: write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
878: }
879: return 0;
880: }
881:
882: static int read_kickstart (FILE *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom)
883: {
884: unsigned char buffer[20];
885: int i, cr = 0;
886:
887: if (cloanto_rom)
888: *cloanto_rom = 0;
889: i = fread (buffer, 1, 11, f);
890: if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) {
891: fseek (f, 0, SEEK_SET);
892: } else {
893: cr = 1;
894: }
895:
896: i = fread (mem, 1, size, f);
897: if (i == 8192) {
898: a1000_bootrom = malloc (8192);
899: memcpy (a1000_bootrom, kickmemory, 8192);
900: a1000_handle_kickstart (1);
901: } else if (i == size / 2) {
902: memcpy (mem + size / 2, mem, i);
903: } else if (i != size) {
904: write_log ("Error while reading Kickstart.\n");
905: zfile_close (f);
906: return 0;
907: }
908: zfile_close (f);
909:
910: if (cr)
911: decode_cloanto_rom (mem, size, i);
912: if (dochecksum && i >= 262144)
913: kickstart_checksum (mem, size);
914: if (cloanto_rom)
915: *cloanto_rom = cr;
916: return 1;
917: }
918:
919: static int load_extendedkickstart (void)
920: {
921: FILE *f;
922: int size;
923:
924: if (strlen (currprefs.romextfile) == 0)
925: return 0;
926: f = zfile_open (currprefs.romextfile, "rb");
927: if (!f) {
928: write_log ("No extended Kickstart ROM found");
929: return 0;
930: }
931:
932: fseek (f, 0, SEEK_END);
933: size = ftell (f);
934: if (size > 300000)
935: extendedkickmem_size = 524288;
936: else
937: extendedkickmem_size = 262144;
938: fseek (f, 0, SEEK_SET);
939:
940: switch (extromtype ()) {
941: case EXTENDED_ROM_CDTV:
942: extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_f0");
943: extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
944: break;
945: case EXTENDED_ROM_CD32:
946: extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
947: extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
948: break;
949: }
950: read_kickstart (f, extendedkickmemory, 524288, 0, 0);
951: fclose (f);
952: return 1;
953: }
954:
955:
956: static int load_kickstart (void)
957: {
958: FILE *f = zfile_open (currprefs.romfile, "rb");
959:
960: if (f == NULL) {
961: #if defined(AMIGA)||defined(__POS__)
962: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
963: if (!getenv (USE_UAE_ERSATZ)) {
964: write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
965: memcpy (kickmemory, (char *) 0x1000000 - kickmem_size, kickmem_size);
966: kickstart_checksum (kickmemory, kickmem_size);
967: goto chk_sum;
968: }
969: #endif
970: return 0;
971: }
972:
973: if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom))
974: return 0;
975:
976: #if defined(AMIGA)
977: chk_sum:
978: #endif
979:
980: if (currprefs.kickshifter) {
981: /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
982: Changes 'lea $400,a0' to 'lea $2000,a0' for ShapeShifter compatability.
983: NOTE: lea is 0x41f8, so we should do this better with a search for
984: 0x41f80400 --> 0x41f82000
985: */
986: if (kickmemory[0x24a] == 0x04 && kickmemory[0x24b] == 0x00) { /* Kick 3.0 */
987: kickmemory[0x24a] = 0x20;
988: kickmemory[0x7ffea] -= 0x1c;
989: write_log ("Kickstart KickShifted\n");
990: } else if (kickmemory[0x26e] == 0x04 && kickmemory[0x26f] == 0x00) { /* Kick 3.1 */
991: kickmemory[0x26e] = 0x20;
992: kickmemory[0x7ffea] -= 0x1c;
993: write_log ("Kickstart KickShifted\n");
994: } else if (kickmemory[0x24e] == 0x04 && kickmemory[0x24f] == 0x00) { /* Kick 2.04 */
995: kickmemory[0x24e] = 0x20;
996: kickmemory[0x7ffea] -= 0x1c;
997: write_log ("Kickstart KickShifted\n");
998: }
999: }
1000: return 1;
1001: }
1002:
1.1 root 1003: char *address_space, *good_address_map;
1004: int good_address_fd;
1.1.1.4 root 1005:
1.1.1.9 root 1006: #ifndef NATMEM_OFFSET
1007:
1.1.1.12 root 1008: uae_u8 *mapped_malloc (size_t s, char *file)
1.1.1.4 root 1009: {
1.1.1.13 root 1010: return calloc (s, 1);
1.1.1.4 root 1011: }
1012:
1.1.1.9 root 1013: void mapped_free (uae_u8 *p)
1.1 root 1014: {
1.1.1.9 root 1015: free (p);
1016: }
1017: #else
1.1.1.3 root 1018:
1.1.1.9 root 1019: #include <sys/ipc.h>
1020: #include <sys/shm.h>
1021: #include <unistd.h>
1022: #include <sys/mman.h>
1023:
1.1.1.12 root 1024: shmpiece *shm_start = NULL;
1025: int canbang = 1;
1.1.1.9 root 1026:
1.1.1.12 root 1027: static void dumplist (void)
1.1.1.9 root 1028: {
1.1.1.12 root 1029: shmpiece *x = shm_start;
1.1.1.9 root 1030: printf ("Start Dump:\n");
1031: while (x) {
1032: printf (" this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
1.1.1.12 root 1033: x, x->native_address, x->id, x->prev, x->next, x->size);
1.1.1.9 root 1034: x = x->next;
1.1.1.2 root 1035: }
1.1.1.9 root 1036: printf ("End Dump:\n");
1037: }
1.1 root 1038:
1.1.1.9 root 1039: static shmpiece *find_shmpiece (uae_u8 *base)
1040: {
1041: shmpiece *x = shm_start;
1.1 root 1042:
1.1.1.9 root 1043: while (x && x->native_address != base)
1044: x = x->next;
1045: if (!x) {
1.1.1.12 root 1046: printf ("NATMEM: Failure to find mapping at %p\n", base);
1047: dumplist ();
1.1.1.9 root 1048: canbang = 0;
1049: return 0;
1050: }
1051: return x;
1052: }
1.1.1.3 root 1053:
1.1.1.9 root 1054: static void delete_shmmaps (uae_u32 start, uae_u32 size)
1055: {
1056: if (!canbang)
1057: return;
1058:
1059: while (size) {
1.1.1.12 root 1060: uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1.1.1.9 root 1061: if (base) {
1062: shmpiece *x;
1.1.1.12 root 1063: base = ((uae_u8 *) NATMEM_OFFSET) + start;
1.1.1.9 root 1064:
1065: x = find_shmpiece (base);
1.1.1.12 root 1066: if (!x)
1.1.1.9 root 1067: return;
1068:
1069: if (x->size > size) {
1.1.1.12 root 1070: printf ("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n", start, x->size, size);
1071: dumplist ();
1.1.1.9 root 1072: canbang = 0;
1073: return;
1074: }
1075: shmdt (x->native_address);
1076: size -= x->size;
1077: start += x->size;
1078: if (x->next)
1.1.1.12 root 1079: x->next->prev = x->prev; /* remove this one from the list */
1.1.1.9 root 1080: if (x->prev)
1081: x->prev->next = x->next;
1082: else
1083: shm_start = x->next;
1.1.1.12 root 1084: free (x);
1.1.1.9 root 1085: } else {
1086: size -= 0x10000;
1087: start += 0x10000;
1088: }
1.1.1.3 root 1089: }
1.1.1.9 root 1090: }
1.1.1.12 root 1091:
1.1.1.9 root 1092: static void add_shmmaps (uae_u32 start, addrbank *what)
1093: {
1094: shmpiece *x = shm_start;
1095: shmpiece *y;
1096: uae_u8 *base = what->baseaddr;
1097:
1098: if (!canbang)
1099: return;
1100: if (!base)
1101: return;
1102:
1103: x = find_shmpiece (base);
1.1.1.12 root 1104: if (!x)
1.1.1.9 root 1105: return;
1106: y = malloc (sizeof (shmpiece));
1107: *y = *x;
1.1.1.12 root 1108: base = ((uae_u8 *) NATMEM_OFFSET) + start;
1109: y->native_address = shmat (y->id, base, 0);
1110: if (y->native_address == (void *) -1) {
1111: printf ("NATMEM: Failure to map existing at %08x(%p)\n", start, base);
1112: perror ("shmat");
1113: dumplist ();
1.1.1.9 root 1114: canbang = 0;
1115: return;
1.1.1.2 root 1116: }
1.1.1.9 root 1117: y->next = shm_start;
1118: y->prev = NULL;
1119: if (y->next)
1120: y->next->prev = y;
1121: shm_start = y;
1122: }
1123:
1124: uae_u8 *mapped_malloc (size_t s, char *file)
1125: {
1.1.1.12 root 1126: int id;
1.1.1.9 root 1127: void *answer;
1128: shmpiece *x;
1129:
1.1.1.12 root 1130: if (!canbang)
1.1.1.9 root 1131: return malloc (s);
1132:
1.1.1.12 root 1133: id = shmget (IPC_PRIVATE, s, 0x1ff, file);
1.1.1.9 root 1134: if (id == 1) {
1135: canbang = 0;
1136: return mapped_malloc (s, file);
1137: }
1.1.1.12 root 1138: answer = shmat (id, 0, 0);
1139: shmctl (id, IPC_RMID, NULL);
1140: if (answer != (void *) -1) {
1141: x = malloc (sizeof (shmpiece));
1.1.1.9 root 1142: x->native_address = answer;
1143: x->id = id;
1144: x->size = s;
1145: x->next = shm_start;
1146: x->prev = NULL;
1147: if (x->next)
1148: x->next->prev = x;
1149: shm_start = x;
1150:
1151: return answer;
1152: }
1153: canbang = 0;
1154: return mapped_malloc (s, file);
1155: }
1156:
1.1.1.10 root 1157: void mapped_free (uae_u8 *base)
1.1.1.9 root 1158: {
1159: shmpiece *x = find_shmpiece (base);
1.1.1.12 root 1160: if (!x)
1.1.1.9 root 1161: abort ();
1162: shmdt (x->native_address);
1163: }
1164:
1.1 root 1165: #endif
1.1.1.6 root 1166:
1.1.1.9 root 1167: static void init_mem_banks (void)
1168: {
1169: int i;
1170: for (i = 0; i < 65536; i++)
1171: put_mem_bank (i << 16, &dummy_bank, 0);
1172: }
1173:
1174: static void allocate_memory (void)
1175: {
1176: if (allocated_chipmem != currprefs.chipmem_size) {
1177: if (chipmemory)
1178: mapped_free (chipmemory);
1179: chipmemory = 0;
1180:
1181: allocated_chipmem = currprefs.chipmem_size;
1182: chipmem_mask = allocated_chipmem - 1;
1183:
1184: chipmemory = mapped_malloc (allocated_chipmem, "chip");
1185: if (chipmemory == 0) {
1186: write_log ("Fatal error: out of memory for chipmem.\n");
1187: allocated_chipmem = 0;
1188: } else
1189: do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
1190: }
1191:
1192: if (allocated_bogomem != currprefs.bogomem_size) {
1193: if (bogomemory)
1194: mapped_free (bogomemory);
1195: bogomemory = 0;
1196:
1197: allocated_bogomem = currprefs.bogomem_size;
1198: bogomem_mask = allocated_bogomem - 1;
1199:
1200: if (allocated_bogomem) {
1201: bogomemory = mapped_malloc (allocated_bogomem, "bogo");
1202: if (bogomemory == 0) {
1203: write_log ("Out of memory for bogomem.\n");
1204: allocated_bogomem = 0;
1205: }
1206: }
1207: }
1208: if (allocated_a3000mem != currprefs.a3000mem_size) {
1209: if (a3000memory)
1210: mapped_free (a3000memory);
1211: a3000memory = 0;
1212:
1213: allocated_a3000mem = currprefs.a3000mem_size;
1214: a3000mem_mask = allocated_a3000mem - 1;
1215:
1216: if (allocated_a3000mem) {
1217: a3000memory = mapped_malloc (allocated_a3000mem, "a3000");
1218: if (a3000memory == 0) {
1219: write_log ("Out of memory for a3000mem.\n");
1220: allocated_a3000mem = 0;
1221: }
1222: }
1223: }
1224:
1225: if (savestate_state == STATE_RESTORE) {
1226: fseek (savestate_file, chip_filepos, SEEK_SET);
1227: fread (chipmemory, 1, allocated_chipmem, savestate_file);
1228: if (allocated_bogomem > 0) {
1229: fseek (savestate_file, bogo_filepos, SEEK_SET);
1230: fread (bogomemory, 1, allocated_bogomem, savestate_file);
1231: }
1232: }
1233: chipmem_bank.baseaddr = chipmemory;
1234: bogomem_bank.baseaddr = bogomemory;
1235: }
1236:
1237: void memory_reset (void)
1238: {
1239: int i, custom_start;
1240:
1241: #ifdef NATMEM_OFFSET
1242: delete_shmmaps (0, 0xFFFF0000);
1243: #endif
1.1.1.4 root 1244: init_mem_banks ();
1.1.1.3 root 1245:
1.1.1.9 root 1246: currprefs.chipmem_size = changed_prefs.chipmem_size;
1247: currprefs.bogomem_size = changed_prefs.bogomem_size;
1248: currprefs.a3000mem_size = changed_prefs.a3000mem_size;
1249:
1250: allocate_memory ();
1251:
1.1.1.12 root 1252: if (strcmp (currprefs.romfile, changed_prefs.romfile) != 0 || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0) {
1.1.1.10 root 1253: ersatzkickfile = 0;
1254: memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
1255: memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
1256: /* Clear out whatever data remains across a reset. */
1257: memset (chipmemory, 0, allocated_chipmem);
1.1.1.12 root 1258: if (!load_kickstart ()) {
1.1.1.10 root 1259: init_ersatz_rom (kickmemory);
1260: ersatzkickfile = 1;
1261: }
1.1.1.12 root 1262: }
1.1.1.9 root 1263: /* Map the chipmem into all of the lower 8MB */
1264: i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
1265: map_banks (&chipmem_bank, 0x00, i, allocated_chipmem);
1266:
1.1.1.3 root 1267: custom_start = 0xC0;
1.1 root 1268:
1.1.1.9 root 1269: map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0);
1270: map_banks (&cia_bank, 0xA0, 32, 0);
1271: map_banks (&clock_bank, 0xDC, 1, 0);
1.1.1.3 root 1272:
1273: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
1274: * range on an Amiga without expansion memory? */
1.1.1.4 root 1275: custom_start = allocated_chipmem >> 16;
1.1.1.3 root 1276: if (custom_start < 0x20)
1277: custom_start = 0x20;
1.1.1.9 root 1278: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
1.1.1.12 root 1279: /*map_banks (&mbres_bank, 0xDE, 1); */
1.1.1.3 root 1280:
1.1.1.9 root 1281: if (bogomemory != 0) {
1282: int t = allocated_bogomem >> 16;
1283: if (t > 0x1C)
1284: t = 0x1C;
1285: map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
1286: }
1.1.1.4 root 1287: if (a3000memory != 0)
1.1.1.12 root 1288: map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16, allocated_a3000mem);
1.1.1.9 root 1289:
1.1.1.11 root 1290: map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
1.1.1.9 root 1291:
1292: map_banks (&kickmem_bank, 0xF8, 8, 0);
1.1.1.12 root 1293: if (a1000_bootrom)
1294: a1000_handle_kickstart (1);
1.1.1.9 root 1295: map_banks (&expamem_bank, 0xE8, 1, 0);
1296:
1.1.1.12 root 1297: switch (extromtype ()) {
1298: case EXTENDED_ROM_CDTV:
1299: map_banks (&extendedkickmem_bank, 0xF0, 4, 0);
1300: break;
1301: case EXTENDED_ROM_CD32:
1302: map_banks (&extendedkickmem_bank, 0xE0, 8, 0);
1303: break;
1304: default:
1305: if (cloanto_rom)
1306: map_banks (&kickmem_bank, 0xE0, 8, 0);
1307: }
1.1.1.9 root 1308: }
1309:
1310: void memory_init (void)
1311: {
1312: allocated_chipmem = 0;
1313: allocated_bogomem = 0;
1314: allocated_a3000mem = 0;
1315: kickmemory = 0;
1.1.1.12 root 1316: extendedkickmemory = 0;
1.1.1.9 root 1317: chipmemory = 0;
1318: a3000memory = 0;
1319: bogomemory = 0;
1320:
1321: kickmemory = mapped_malloc (kickmem_size, "kick");
1322: kickmem_bank.baseaddr = kickmemory;
1.1.1.3 root 1323:
1.1.1.12 root 1324: load_extendedkickstart ();
1325: if (!load_kickstart ()) {
1.1.1.3 root 1326: init_ersatz_rom (kickmemory);
1.1 root 1327: ersatzkickfile = 1;
1328: }
1.1.1.3 root 1329:
1.1.1.9 root 1330: init_mem_banks ();
1331: memory_reset ();
1.1.1.4 root 1332:
1333: kickmem_mask = kickmem_size - 1;
1.1.1.12 root 1334: extendedkickmem_mask = extendedkickmem_size - 1;
1.1 root 1335: }
1336:
1.1.1.12 root 1337: void memory_cleanup (void)
1.1.1.10 root 1338: {
1339: if (a3000memory)
1340: mapped_free (a3000memory);
1341: if (bogomemory)
1342: mapped_free (bogomemory);
1343: if (kickmemory)
1344: mapped_free (kickmemory);
1.1.1.12 root 1345: if (a1000_bootrom)
1346: free (a1000_bootrom);
1.1.1.10 root 1347: if (chipmemory)
1348: mapped_free (chipmemory);
1.1.1.12 root 1349:
1.1.1.10 root 1350: a3000memory = 0;
1351: bogomemory = 0;
1352: kickmemory = 0;
1.1.1.12 root 1353: a1000_bootrom = 0;
1.1.1.10 root 1354: chipmemory = 0;
1355: }
1356:
1.1.1.9 root 1357: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1 root 1358: {
1359: int bnr;
1.1.1.3 root 1360: unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.12 root 1361: addrbank *orgbank = bank;
1.1.1.9 root 1362: uae_u32 realstart = start;
1.1.1.12 root 1363:
1364: flush_icache (1); /* Sure don't want to keep any old mappings around! */
1.1.1.9 root 1365: #ifdef NATMEM_OFFSET
1366: delete_shmmaps (start << 16, size << 16);
1367: #endif
1.1.1.12 root 1368:
1.1.1.9 root 1369: if (!realsize)
1370: realsize = size << 16;
1371:
1372: if ((size << 16) < realsize) {
1.1.1.11 root 1373: write_log ("Please report to [email protected], and mention:\n");
1.1.1.12 root 1374: write_log ("Broken mapping, size=%x, realsize=%x\n", size, realsize);
1375: write_log ("Start is %x\n", start);
1.1.1.11 root 1376: write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9 root 1377: abort ();
1378: }
1.1.1.3 root 1379:
1380: if (start >= 0x100) {
1.1.1.10 root 1381: int real_left = 0;
1.1.1.9 root 1382: for (bnr = start; bnr < start + size; bnr++) {
1383: if (!real_left) {
1384: realstart = bnr;
1.1.1.12 root 1385: real_left = realsize >> 16;
1.1.1.9 root 1386: #ifdef NATMEM_OFFSET
1387: add_shmmaps (realstart << 16, bank);
1388: #endif
1389: }
1.1.1.12 root 1390: put_mem_bank (bnr << 16, bank, realstart << 16);
1.1.1.9 root 1391: real_left--;
1392: }
1.1.1.3 root 1393: return;
1394: }
1.1.1.10 root 1395: if (currprefs.address_space_24)
1396: endhioffs = 0x10000;
1.1.1.9 root 1397: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10 root 1398: int real_left = 0;
1.1.1.12 root 1399: for (bnr = start; bnr < start + size; bnr++) {
1.1.1.9 root 1400: if (!real_left) {
1401: realstart = bnr + hioffs;
1402: real_left = realsize >> 16;
1403: #ifdef NATMEM_OFFSET
1404: add_shmmaps (realstart << 16, bank);
1405: #endif
1406: }
1.1.1.12 root 1407: put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1.1.1.9 root 1408: real_left--;
1409: }
1410: }
1411: }
1412:
1413:
1414: /* memory save/restore code */
1415:
1416: uae_u8 *save_cram (int *len)
1417: {
1418: *len = allocated_chipmem;
1419: return chipmemory;
1420: }
1421:
1422: uae_u8 *save_bram (int *len)
1423: {
1424: *len = allocated_bogomem;
1425: return bogomemory;
1426: }
1427:
1428: void restore_cram (int len, long filepos)
1429: {
1430: chip_filepos = filepos;
1431: changed_prefs.chipmem_size = len;
1432: }
1433:
1434: void restore_bram (int len, long filepos)
1435: {
1436: bogo_filepos = filepos;
1437: changed_prefs.bogomem_size = len;
1438: }
1439:
1440: uae_u8 *restore_rom (uae_u8 *src)
1441: {
1442: restore_u32 ();
1443: restore_u32 ();
1444: restore_u32 ();
1445: restore_u32 ();
1446: restore_u32 ();
1447:
1448: return src;
1449: }
1450:
1451: uae_u8 *save_rom (int first, int *len)
1452: {
1453: static int count;
1454: uae_u8 *dst, *dstbak;
1455: uae_u8 *mem_real_start;
1456: int mem_start, mem_size, mem_type, i, saverom;
1457:
1458: saverom = 0;
1.1.1.12 root 1459: if (first)
1460: count = 0;
1.1.1.9 root 1461: for (;;) {
1462: mem_type = count;
1.1.1.12 root 1463: switch (count) {
1464: case 0: /* Kickstart ROM */
1.1.1.9 root 1465: mem_start = 0xf80000;
1466: mem_real_start = kickmemory;
1467: mem_size = kickmem_size;
1468: /* 256KB or 512KB ROM? */
1.1.1.12 root 1469: for (i = 0; i < mem_size / 2 - 4; i++) {
1470: if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
1471: break;
1.1.1.9 root 1472: }
1.1.1.12 root 1473: if (i == mem_size / 2 - 4) {
1.1.1.9 root 1474: mem_size /= 2;
1475: mem_start += 262144;
1476: }
1477: mem_type = 0;
1478: break;
1.1.1.12 root 1479: default:
1.1.1.9 root 1480: return 0;
1481: }
1.1.1.12 root 1482: count++;
1483: if (mem_size)
1484: break;
1.1.1.9 root 1485: }
1486: dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
1487: save_u32 (mem_start);
1488: save_u32 (mem_size);
1489: save_u32 (mem_type);
1.1.1.12 root 1490: save_u32 (longget (mem_start + 12)); /* version+revision */
1.1.1.9 root 1491: save_u32 (0);
1.1.1.12 root 1492: sprintf (dst, "Kickstart %d.%d", wordget (mem_start + 12), wordget (mem_start + 14));
1.1.1.9 root 1493: dst += strlen (dst) + 1;
1494: if (saverom) {
1.1.1.12 root 1495: for (i = 0; i < mem_size; i++)
1496: *dst++ = byteget (mem_start + i);
1.1.1.9 root 1497: }
1498: *len = dst - dstbak;
1499: return dstbak;
1.1 root 1500: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.