|
|
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.3 root 44: addrbank *mem_banks[65536];
1.1.1.9 root 45:
46: /* This has two functions. It either holds a host address that, when added
47: to the 68k address, gives the host address corresponding to that 68k
48: address (in which case the value in this array is even), OR it holds the
49: same value as mem_banks, for those banks that have baseaddr==0. In that
50: case, bit 0 is set (the memory access routines will take care of it). */
51:
52: uae_u8 *baseaddr[65536];
1.1 root 53:
1.1.1.2 root 54: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5 root 55: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2 root 56: {
1.1.1.5 root 57: return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2 root 58: }
1.1.1.5 root 59: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2 root 60: {
1.1.1.5 root 61: return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2 root 62: }
1.1.1.5 root 63: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2 root 64: {
1.1.1.5 root 65: return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2 root 66: }
1.1.1.5 root 67: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2 root 68: {
1.1.1.5 root 69: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2 root 70: }
1.1.1.5 root 71: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2 root 72: {
1.1.1.5 root 73: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2 root 74: }
1.1.1.5 root 75: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2 root 76: {
1.1.1.5 root 77: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2 root 78: }
79: #endif
80:
1.1.1.3 root 81: uae_u32 chipmem_mask, kickmem_mask, bogomem_mask, a3000mem_mask;
1.1 root 82:
1.1.1.11! root 83: static int illegal_count;
1.1.1.3 root 84: /* A dummy bank that only contains zeros */
85:
1.1.1.4 root 86: static uae_u32 dummy_lget (uaecptr) REGPARAM;
87: static uae_u32 dummy_wget (uaecptr) REGPARAM;
88: static uae_u32 dummy_bget (uaecptr) REGPARAM;
89: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
90: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
91: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
92: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
93:
94: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
95: {
1.1.1.8 root 96: special_mem |= S_READ;
1.1.1.11! root 97: if (currprefs.illegal_mem) {
! 98: if (illegal_count < 20) {
! 99: illegal_count++;
! 100: write_log ("Illegal lget at %08lx\n", addr);
! 101: }
! 102: }
1.1.1.4 root 103:
1.1.1.9 root 104: return 0xFFFFFFFF;
1.1 root 105: }
106:
1.1.1.4 root 107: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1 root 108: {
1.1.1.8 root 109: special_mem |= S_READ;
1.1.1.11! root 110: if (currprefs.illegal_mem) {
! 111: if (illegal_count < 20) {
! 112: illegal_count++;
! 113: write_log ("Illegal wget at %08lx\n", addr);
! 114: }
! 115: }
! 116:
1.1.1.9 root 117: return 0xFFFF;
1.1 root 118: }
119:
1.1.1.4 root 120: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1 root 121: {
1.1.1.8 root 122: special_mem |= S_READ;
1.1.1.11! root 123: if (currprefs.illegal_mem) {
! 124: if (illegal_count < 20) {
! 125: illegal_count++;
! 126: write_log ("Illegal bget at %08lx\n", addr);
! 127: }
! 128: }
1.1.1.4 root 129:
1.1.1.9 root 130: return 0xFF;
1.1 root 131: }
132:
1.1.1.4 root 133: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1 root 134: {
1.1.1.8 root 135: special_mem |= S_WRITE;
1.1.1.11! root 136: if (currprefs.illegal_mem) {
! 137: if (illegal_count < 20) {
! 138: illegal_count++;
! 139: write_log ("Illegal lput at %08lx\n", addr);
! 140: }
! 141: }
1.1.1.3 root 142: }
1.1.1.4 root 143: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 144: {
1.1.1.8 root 145: special_mem |= S_WRITE;
1.1.1.11! root 146: if (currprefs.illegal_mem) {
! 147: if (illegal_count < 20) {
! 148: illegal_count++;
! 149: write_log ("Illegal wput at %08lx\n", addr);
! 150: }
! 151: }
1.1.1.3 root 152: }
1.1.1.4 root 153: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 154: {
1.1.1.8 root 155: special_mem |= S_WRITE;
1.1.1.11! root 156: if (currprefs.illegal_mem) {
! 157: if (illegal_count < 20) {
! 158: illegal_count++;
! 159: write_log ("Illegal bput at %08lx\n", addr);
! 160: }
! 161: }
1.1 root 162: }
163:
1.1.1.4 root 164: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1 root 165: {
1.1.1.9 root 166: special_mem |= S_READ;
1.1.1.11! root 167: if (currprefs.illegal_mem) {
! 168: if (illegal_count < 20) {
! 169: illegal_count++;
! 170: write_log ("Illegal check at %08lx\n", addr);
! 171: }
! 172: }
1.1.1.4 root 173:
1.1 root 174: return 0;
175: }
176:
1.1.1.3 root 177: /* A3000 "motherboard resources" bank. */
1.1.1.4 root 178: static uae_u32 mbres_lget (uaecptr) REGPARAM;
179: static uae_u32 mbres_wget (uaecptr) REGPARAM;
180: static uae_u32 mbres_bget (uaecptr) REGPARAM;
181: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
182: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
183: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
184: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3 root 185:
186: static int mbres_val = 0;
187:
1.1.1.4 root 188: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3 root 189: {
1.1.1.8 root 190: special_mem |= S_READ;
1.1.1.4 root 191: if (currprefs.illegal_mem)
192: write_log ("Illegal lget at %08lx\n", addr);
193:
1.1 root 194: return 0;
195: }
196:
1.1.1.4 root 197: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1 root 198: {
1.1.1.8 root 199: special_mem |= S_READ;
1.1.1.4 root 200: if (currprefs.illegal_mem)
201: write_log ("Illegal wget at %08lx\n", addr);
202:
1.1 root 203: return 0;
204: }
205:
1.1.1.4 root 206: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3 root 207: {
1.1.1.8 root 208: special_mem |= S_READ;
1.1.1.4 root 209: if (currprefs.illegal_mem)
210: write_log ("Illegal bget at %08lx\n", addr);
211:
1.1.1.3 root 212: return (addr & 0xFFFF) == 3 ? mbres_val : 0;
213: }
214:
1.1.1.4 root 215: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1 root 216: {
1.1.1.8 root 217: special_mem |= S_WRITE;
1.1.1.4 root 218: if (currprefs.illegal_mem)
219: write_log ("Illegal lput at %08lx\n", addr);
1.1 root 220: }
1.1.1.4 root 221: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1 root 222: {
1.1.1.8 root 223: special_mem |= S_WRITE;
1.1.1.4 root 224: if (currprefs.illegal_mem)
225: write_log ("Illegal wput at %08lx\n", addr);
1.1 root 226: }
1.1.1.4 root 227: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1 root 228: {
1.1.1.8 root 229: special_mem |= S_WRITE;
1.1.1.4 root 230: if (currprefs.illegal_mem)
231: write_log ("Illegal bput at %08lx\n", addr);
232:
1.1.1.3 root 233: if ((addr & 0xFFFF) == 3)
234: mbres_val = b;
1.1 root 235: }
236:
1.1.1.4 root 237: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1 root 238: {
1.1.1.4 root 239: if (currprefs.illegal_mem)
240: write_log ("Illegal check at %08lx\n", addr);
241:
1.1 root 242: return 0;
243: }
244:
245: /* Chip memory */
246:
1.1.1.3 root 247: uae_u8 *chipmemory;
1.1 root 248:
1.1.1.4 root 249: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
250: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1 root 251:
1.1.1.4 root 252: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1 root 253: {
1.1.1.3 root 254: uae_u32 *m;
1.1.1.8 root 255:
1.1 root 256: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 257: addr &= chipmem_mask;
1.1.1.3 root 258: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 259: return do_get_mem_long (m);
1.1 root 260: }
261:
1.1.1.4 root 262: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1 root 263: {
1.1.1.3 root 264: uae_u16 *m;
1.1.1.8 root 265:
1.1 root 266: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 267: addr &= chipmem_mask;
1.1.1.3 root 268: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 269: return do_get_mem_word (m);
1.1 root 270: }
271:
1.1.1.4 root 272: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1 root 273: {
274: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 275: addr &= chipmem_mask;
1.1 root 276: return chipmemory[addr];
277: }
278:
1.1.1.4 root 279: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1 root 280: {
1.1.1.3 root 281: uae_u32 *m;
1.1.1.8 root 282:
1.1 root 283: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 284: addr &= chipmem_mask;
1.1.1.3 root 285: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 286: do_put_mem_long (m, l);
1.1 root 287: }
288:
1.1.1.4 root 289: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1 root 290: {
1.1.1.3 root 291: uae_u16 *m;
1.1.1.8 root 292:
1.1 root 293: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 294: addr &= chipmem_mask;
1.1.1.3 root 295: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 296: do_put_mem_word (m, w);
1.1 root 297: }
298:
1.1.1.4 root 299: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1 root 300: {
301: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 302: addr &= chipmem_mask;
1.1 root 303: chipmemory[addr] = b;
304: }
305:
1.1.1.4 root 306: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1 root 307: {
308: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 309: addr &= chipmem_mask;
1.1.1.4 root 310: return (addr + size) <= allocated_chipmem;
1.1 root 311: }
312:
1.1.1.4 root 313: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1 root 314: {
315: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 316: addr &= chipmem_mask;
1.1 root 317: return chipmemory + addr;
318: }
319:
320: /* Slow memory */
321:
1.1.1.3 root 322: static uae_u8 *bogomemory;
1.1 root 323:
1.1.1.4 root 324: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
325: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
326: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
327: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
328: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
329: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
330: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
331: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1 root 332:
1.1.1.4 root 333: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1 root 334: {
1.1.1.3 root 335: uae_u32 *m;
1.1 root 336: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 337: addr &= bogomem_mask;
1.1.1.3 root 338: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 339: return do_get_mem_long (m);
1.1 root 340: }
341:
1.1.1.4 root 342: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1 root 343: {
1.1.1.3 root 344: uae_u16 *m;
1.1 root 345: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 346: addr &= bogomem_mask;
1.1.1.3 root 347: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 348: return do_get_mem_word (m);
1.1 root 349: }
350:
1.1.1.4 root 351: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1 root 352: {
353: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 354: addr &= bogomem_mask;
1.1 root 355: return bogomemory[addr];
356: }
357:
1.1.1.4 root 358: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1 root 359: {
1.1.1.3 root 360: uae_u32 *m;
1.1 root 361: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 362: addr &= bogomem_mask;
1.1.1.3 root 363: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 364: do_put_mem_long (m, l);
1.1 root 365: }
366:
1.1.1.4 root 367: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1 root 368: {
1.1.1.3 root 369: uae_u16 *m;
1.1 root 370: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 371: addr &= bogomem_mask;
1.1.1.3 root 372: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 373: do_put_mem_word (m, w);
1.1 root 374: }
375:
1.1.1.4 root 376: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1 root 377: {
378: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 379: addr &= bogomem_mask;
1.1 root 380: bogomemory[addr] = b;
381: }
382:
1.1.1.4 root 383: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1 root 384: {
1.1.1.2 root 385: addr -= bogomem_start & bogomem_mask;
386: addr &= bogomem_mask;
1.1.1.4 root 387: return (addr + size) <= allocated_bogomem;
1.1 root 388: }
389:
1.1.1.4 root 390: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1 root 391: {
1.1.1.2 root 392: addr -= bogomem_start & bogomem_mask;
393: addr &= bogomem_mask;
1.1 root 394: return bogomemory + addr;
395: }
396:
1.1.1.3 root 397: /* A3000 motherboard fast memory */
398:
399: static uae_u8 *a3000memory;
1.1 root 400:
1.1.1.4 root 401: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
402: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
403: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
404: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
405: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
406: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
407: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
408: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 409:
1.1.1.4 root 410: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3 root 411: {
412: uae_u32 *m;
413: addr -= a3000mem_start & a3000mem_mask;
414: addr &= a3000mem_mask;
415: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 416: return do_get_mem_long (m);
1.1.1.3 root 417: }
1.1 root 418:
1.1.1.4 root 419: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3 root 420: {
421: uae_u16 *m;
422: addr -= a3000mem_start & a3000mem_mask;
423: addr &= a3000mem_mask;
424: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 425: return do_get_mem_word (m);
1.1.1.3 root 426: }
1.1 root 427:
1.1.1.4 root 428: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1 root 429: {
1.1.1.3 root 430: addr -= a3000mem_start & a3000mem_mask;
431: addr &= a3000mem_mask;
432: return a3000memory[addr];
1.1 root 433: }
434:
1.1.1.4 root 435: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1 root 436: {
1.1.1.3 root 437: uae_u32 *m;
438: addr -= a3000mem_start & a3000mem_mask;
439: addr &= a3000mem_mask;
440: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 441: do_put_mem_long (m, l);
1.1.1.3 root 442: }
443:
1.1.1.4 root 444: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 445: {
446: uae_u16 *m;
447: addr -= a3000mem_start & a3000mem_mask;
448: addr &= a3000mem_mask;
449: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 450: do_put_mem_word (m, w);
1.1.1.3 root 451: }
452:
1.1.1.4 root 453: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 454: {
455: addr -= a3000mem_start & a3000mem_mask;
456: addr &= a3000mem_mask;
457: a3000memory[addr] = b;
458: }
459:
1.1.1.4 root 460: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3 root 461: {
462: addr -= a3000mem_start & a3000mem_mask;
463: addr &= a3000mem_mask;
1.1.1.4 root 464: return (addr + size) <= allocated_a3000mem;
1.1 root 465: }
466:
1.1.1.3 root 467: uae_u8 REGPARAM2 *a3000mem_xlate(uaecptr addr)
468: {
469: addr -= a3000mem_start & a3000mem_mask;
470: addr &= a3000mem_mask;
471: return a3000memory + addr;
472: }
473:
474: /* Kick memory */
475:
476: uae_u8 *kickmemory;
477:
1.1.1.4 root 478: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
479: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
480: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
481: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
482: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
483: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
484: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
485: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 486:
1.1.1.4 root 487: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1 root 488: {
1.1.1.3 root 489: uae_u32 *m;
1.1 root 490: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 491: addr &= kickmem_mask;
1.1.1.3 root 492: m = (uae_u32 *)(kickmemory + addr);
1.1.1.5 root 493: return do_get_mem_long (m);
1.1 root 494: }
495:
1.1.1.4 root 496: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1 root 497: {
1.1.1.3 root 498: uae_u16 *m;
1.1 root 499: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 500: addr &= kickmem_mask;
1.1.1.3 root 501: m = (uae_u16 *)(kickmemory + addr);
1.1.1.5 root 502: return do_get_mem_word (m);
1.1 root 503: }
504:
1.1.1.4 root 505: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1 root 506: {
507: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 508: addr &= kickmem_mask;
1.1 root 509: return kickmemory[addr];
510: }
511:
1.1.1.4 root 512: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1 root 513: {
1.1.1.4 root 514: if (currprefs.illegal_mem)
515: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 516: }
517:
1.1.1.4 root 518: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1 root 519: {
1.1.1.4 root 520: if (currprefs.illegal_mem)
521: write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1 root 522: }
523:
1.1.1.4 root 524: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1 root 525: {
1.1.1.4 root 526: if (currprefs.illegal_mem)
527: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 528: }
529:
1.1.1.4 root 530: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1 root 531: {
1.1.1.2 root 532: addr -= kickmem_start & kickmem_mask;
533: addr &= kickmem_mask;
1.1.1.4 root 534: return (addr + size) <= kickmem_size;
1.1 root 535: }
536:
1.1.1.4 root 537: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1 root 538: {
1.1.1.2 root 539: addr -= kickmem_start & kickmem_mask;
540: addr &= kickmem_mask;
1.1 root 541: return kickmemory + addr;
542: }
543:
1.1.1.3 root 544: /* Default memory access functions */
545:
1.1.1.4 root 546: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
1.1.1.3 root 547: {
548: return 0;
549: }
550:
1.1.1.4 root 551: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
1.1.1.3 root 552: {
553: write_log ("Your Amiga program just did something terribly stupid\n");
554: uae_reset();
555: return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
556: }
557:
1.1.1.4 root 558: static int load_kickstart (void)
1.1 root 559: {
560: int i;
1.1.1.3 root 561: uae_u32 cksum = 0, prevck = 0;
562: unsigned char buffer[20];
563:
1.1.1.6 root 564: FILE *f = zfile_open (currprefs.romfile, "rb");
1.1.1.3 root 565:
566: if (f == NULL) {
567: write_log ("No Kickstart ROM found.\n");
1.1.1.6 root 568: #if defined AMIGA || defined __POS__
1.1.1.2 root 569: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
1.1.1.6 root 570: if (!getenv (USE_UAE_ERSATZ)) {
1.1.1.11! root 571: write_log ("Using current ROM. (create ENV:%s to "
1.1.1.6 root 572: "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
573: memcpy (kickmemory, (char*)0x1000000 - kickmem_size, kickmem_size);
1.1.1.2 root 574: goto chk_sum;
575: }
576: #endif
1.1 root 577: return 0;
578: }
1.1.1.3 root 579:
580: i = fread (buffer, 1, 11, f);
581: if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) != 0)
582: fseek (f, 0, SEEK_SET);
583:
584: i = fread (kickmemory, 1, kickmem_size, f);
1.1 root 585: if (i == kickmem_size/2) {
586: memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
587: } else if (i != kickmem_size) {
1.1.1.3 root 588: write_log ("Error while reading Kickstart.\n");
1.1 root 589: return 0;
590: }
591: zfile_close (f);
1.1.1.3 root 592:
593: cloanto_rom = 0;
594: if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) == 0) {
595: FILE *keyf;
596: uae_u8 *p;
597: long size, cnt, t;
598:
599: cloanto_rom = 1;
600: write_log ("ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
1.1.1.6 root 601: if (strlen (currprefs.keyfile) == 0) {
1.1.1.3 root 602: write_log ("No filename given for ROM key file.\n");
603: return 0;
604: }
1.1.1.6 root 605: keyf = zfile_open (currprefs.keyfile, "rb");
1.1.1.3 root 606: if (keyf == 0) {
607: write_log ("Could not find ROM key file.\n");
608: return 0;
609: }
610: p = (uae_u8 *)xmalloc (524288);
611: size = fread (p, 1, 524288, keyf);
612:
613: for (t = cnt = 0; cnt < kickmem_size; cnt++, t = (t + 1) % size) {
614: kickmemory[cnt] ^= p[t];
615: if (i == cnt+1)
616: t = size-1;
617: }
618: fclose (keyf);
619: free (p);
620: }
1.1.1.2 root 621: #if defined(AMIGA)
622: chk_sum:
623: #endif
624:
1.1 root 625: for (i = 0; i < kickmem_size; i+=4) {
1.1.1.3 root 626: uae_u32 data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
1.1 root 627: cksum += data;
628: if (cksum < prevck)
629: cksum++;
630: prevck = cksum;
631: }
1.1.1.2 root 632: if (cksum != 0xFFFFFFFFul) {
1.1.1.4 root 633: write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
1.1 root 634: }
635: return 1;
636: }
637:
638: /* Address banks */
639:
640: addrbank dummy_bank = {
641: dummy_lget, dummy_wget, dummy_bget,
642: dummy_lput, dummy_wput, dummy_bput,
1.1.1.9 root 643: default_xlate, dummy_check, NULL
1.1 root 644: };
645:
1.1.1.3 root 646: addrbank mbres_bank = {
647: mbres_lget, mbres_wget, mbres_bget,
648: mbres_lput, mbres_wput, mbres_bput,
1.1.1.9 root 649: default_xlate, mbres_check, NULL
1.1.1.3 root 650: };
651:
1.1 root 652: addrbank chipmem_bank = {
653: chipmem_lget, chipmem_wget, chipmem_bget,
654: chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.9 root 655: chipmem_xlate, chipmem_check, NULL
1.1 root 656: };
657:
658: addrbank bogomem_bank = {
659: bogomem_lget, bogomem_wget, bogomem_bget,
660: bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.9 root 661: bogomem_xlate, bogomem_check, NULL
1.1 root 662: };
663:
1.1.1.3 root 664: addrbank a3000mem_bank = {
665: a3000mem_lget, a3000mem_wget, a3000mem_bget,
666: a3000mem_lput, a3000mem_wput, a3000mem_bput,
1.1.1.9 root 667: a3000mem_xlate, a3000mem_check, NULL
1.1.1.3 root 668: };
669:
1.1 root 670: addrbank kickmem_bank = {
671: kickmem_lget, kickmem_wget, kickmem_bget,
672: kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.9 root 673: kickmem_xlate, kickmem_check, NULL
1.1 root 674: };
675:
676: char *address_space, *good_address_map;
677: int good_address_fd;
1.1.1.4 root 678:
1.1.1.9 root 679: #ifndef NATMEM_OFFSET
680:
681: uae_u8 *mapped_malloc (size_t s, char* file)
1.1.1.4 root 682: {
1.1.1.9 root 683: return malloc (s);
1.1.1.4 root 684: }
685:
1.1.1.9 root 686: void mapped_free (uae_u8 *p)
1.1 root 687: {
1.1.1.9 root 688: free (p);
689: }
690: #else
1.1.1.3 root 691:
1.1.1.9 root 692: #include <sys/ipc.h>
693: #include <sys/shm.h>
694: #include <unistd.h>
695: #include <sys/mman.h>
696:
697: shmpiece *shm_start=NULL;
698: int canbang=1;
699:
700: static void dumplist(void)
701: {
702: shmpiece *x=shm_start;
703: printf ("Start Dump:\n");
704: while (x) {
705: printf (" this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
706: x, x->native_address, x->id, x->prev, x->next,x->size);
707: x = x->next;
1.1.1.2 root 708: }
1.1.1.9 root 709: printf ("End Dump:\n");
710: }
1.1 root 711:
1.1.1.9 root 712: static shmpiece *find_shmpiece (uae_u8 *base)
713: {
714: shmpiece *x = shm_start;
1.1 root 715:
1.1.1.9 root 716: while (x && x->native_address != base)
717: x = x->next;
718: if (!x) {
719: printf("NATMEM: Failure to find mapping at %p\n",base);
720: dumplist();
721: canbang = 0;
722: return 0;
723: }
724: return x;
725: }
1.1.1.3 root 726:
1.1.1.9 root 727: static void delete_shmmaps (uae_u32 start, uae_u32 size)
728: {
729: if (!canbang)
730: return;
731:
732: while (size) {
733: uae_u8 *base = mem_banks[bankindex(start)]->baseaddr;
734: if (base) {
735: shmpiece *x;
736: base = ((uae_u8*)NATMEM_OFFSET)+start;
737:
738: x = find_shmpiece (base);
739: if (! x)
740: return;
741:
742: if (x->size > size) {
743: printf("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n",start,x->size,size);
744: dumplist();
745: canbang = 0;
746: return;
747: }
748: shmdt (x->native_address);
749: size -= x->size;
750: start += x->size;
751: if (x->next)
752: x->next->prev = x->prev; /* remove this one from the list */
753: if (x->prev)
754: x->prev->next = x->next;
755: else
756: shm_start = x->next;
757: free(x);
758: } else {
759: size -= 0x10000;
760: start += 0x10000;
761: }
1.1.1.3 root 762: }
1.1.1.9 root 763: }
764:
765: static void add_shmmaps (uae_u32 start, addrbank *what)
766: {
767: shmpiece *x = shm_start;
768: shmpiece *y;
769: uae_u8 *base = what->baseaddr;
770:
771: if (!canbang)
772: return;
773: if (!base)
774: return;
775:
776: x = find_shmpiece (base);
777: if (! x)
778: return;
779: y = malloc (sizeof (shmpiece));
780: *y = *x;
781: base = ((uae_u8*)NATMEM_OFFSET) + start;
782: y->native_address = shmat (y->id,base,0);
783: if (y->native_address == (void*)-1) {
784: printf("NATMEM: Failure to map existing at %08x(%p)\n",start,base);
785: perror("shmat");
786: dumplist();
787: canbang = 0;
788: return;
1.1.1.2 root 789: }
1.1.1.9 root 790: y->next = shm_start;
791: y->prev = NULL;
792: if (y->next)
793: y->next->prev = y;
794: shm_start = y;
795: }
796:
797: uae_u8 *mapped_malloc (size_t s, char *file)
798: {
799: int id;
800: void *answer;
801: shmpiece *x;
802:
803: if (!canbang)
804: return malloc (s);
805:
806: id = shmget (IPC_PRIVATE, s, 0x1ff);
807: if (id == 1) {
808: canbang = 0;
809: return mapped_malloc (s, file);
810: }
811: answer = shmat (id,0,0);
812: shmctl (id,IPC_RMID,NULL);
813: if (answer != (void*)-1) {
814: x = malloc (sizeof(shmpiece));
815: x->native_address = answer;
816: x->id = id;
817: x->size = s;
818: x->next = shm_start;
819: x->prev = NULL;
820: if (x->next)
821: x->next->prev = x;
822: shm_start = x;
823:
824: return answer;
825: }
826: canbang = 0;
827: return mapped_malloc (s, file);
828: }
829:
1.1.1.10 root 830: void mapped_free (uae_u8 *base)
1.1.1.9 root 831: {
832: shmpiece *x = find_shmpiece (base);
833: if (! x)
834: abort ();
835: shmdt (x->native_address);
836: }
837:
1.1 root 838: #endif
1.1.1.6 root 839:
1.1.1.9 root 840: static void init_mem_banks (void)
841: {
842: int i;
843: for (i = 0; i < 65536; i++)
844: put_mem_bank (i << 16, &dummy_bank, 0);
845: }
846:
847: static void allocate_memory (void)
848: {
849: if (allocated_chipmem != currprefs.chipmem_size) {
850: if (chipmemory)
851: mapped_free (chipmemory);
852: chipmemory = 0;
853:
854: allocated_chipmem = currprefs.chipmem_size;
855: chipmem_mask = allocated_chipmem - 1;
856:
857: chipmemory = mapped_malloc (allocated_chipmem, "chip");
858: if (chipmemory == 0) {
859: write_log ("Fatal error: out of memory for chipmem.\n");
860: allocated_chipmem = 0;
861: } else
862: do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
863: }
864:
865: if (allocated_bogomem != currprefs.bogomem_size) {
866: if (bogomemory)
867: mapped_free (bogomemory);
868: bogomemory = 0;
869:
870: allocated_bogomem = currprefs.bogomem_size;
871: bogomem_mask = allocated_bogomem - 1;
872:
873: if (allocated_bogomem) {
874: bogomemory = mapped_malloc (allocated_bogomem, "bogo");
875: if (bogomemory == 0) {
876: write_log ("Out of memory for bogomem.\n");
877: allocated_bogomem = 0;
878: }
879: }
880: }
881: if (allocated_a3000mem != currprefs.a3000mem_size) {
882: if (a3000memory)
883: mapped_free (a3000memory);
884: a3000memory = 0;
885:
886: allocated_a3000mem = currprefs.a3000mem_size;
887: a3000mem_mask = allocated_a3000mem - 1;
888:
889: if (allocated_a3000mem) {
890: a3000memory = mapped_malloc (allocated_a3000mem, "a3000");
891: if (a3000memory == 0) {
892: write_log ("Out of memory for a3000mem.\n");
893: allocated_a3000mem = 0;
894: }
895: }
896: }
897:
898: if (savestate_state == STATE_RESTORE) {
899: fseek (savestate_file, chip_filepos, SEEK_SET);
900: fread (chipmemory, 1, allocated_chipmem, savestate_file);
901: if (allocated_bogomem > 0) {
902: fseek (savestate_file, bogo_filepos, SEEK_SET);
903: fread (bogomemory, 1, allocated_bogomem, savestate_file);
904: }
905: }
906: chipmem_bank.baseaddr = chipmemory;
907: bogomem_bank.baseaddr = bogomemory;
908: }
909:
910: void memory_reset (void)
911: {
912: int i, custom_start;
913:
914: #ifdef NATMEM_OFFSET
915: delete_shmmaps (0, 0xFFFF0000);
916: #endif
1.1.1.4 root 917: init_mem_banks ();
1.1.1.3 root 918:
1.1.1.9 root 919: currprefs.chipmem_size = changed_prefs.chipmem_size;
920: currprefs.bogomem_size = changed_prefs.bogomem_size;
921: currprefs.a3000mem_size = changed_prefs.a3000mem_size;
922:
923: allocate_memory ();
924:
1.1.1.10 root 925: if (strcmp (currprefs.romfile, changed_prefs.romfile) != 0
926: || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0)
927: {
928: ersatzkickfile = 0;
929: memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
930: memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
931: /* Clear out whatever data remains across a reset. */
932: memset (chipmemory, 0, allocated_chipmem);
933: if (! load_kickstart ()) {
934: init_ersatz_rom (kickmemory);
935: ersatzkickfile = 1;
936: }
937: }
1.1.1.9 root 938: /* Map the chipmem into all of the lower 8MB */
939: i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
940: map_banks (&chipmem_bank, 0x00, i, allocated_chipmem);
941:
1.1.1.3 root 942: custom_start = 0xC0;
1.1 root 943:
1.1.1.9 root 944: map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0);
945: map_banks (&cia_bank, 0xA0, 32, 0);
946: map_banks (&clock_bank, 0xDC, 1, 0);
1.1.1.3 root 947:
948: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
949: * range on an Amiga without expansion memory? */
1.1.1.4 root 950: custom_start = allocated_chipmem >> 16;
1.1.1.3 root 951: if (custom_start < 0x20)
952: custom_start = 0x20;
1.1.1.9 root 953: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
1.1.1.3 root 954: /*map_banks (&mbres_bank, 0xDE, 1);*/
955:
1.1.1.9 root 956: if (bogomemory != 0) {
957: int t = allocated_bogomem >> 16;
958: if (t > 0x1C)
959: t = 0x1C;
960: map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
961: }
1.1.1.4 root 962: if (a3000memory != 0)
1.1.1.9 root 963: map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16,
964: allocated_a3000mem);
965:
1.1.1.11! root 966: map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
1.1.1.9 root 967:
968: map_banks (&kickmem_bank, 0xF8, 8, 0);
969: map_banks (&expamem_bank, 0xE8, 1, 0);
970:
971: if (cloanto_rom)
972: map_banks (&kickmem_bank, 0xE0, 8, 0);
973: }
974:
975: void memory_init (void)
976: {
977: allocated_chipmem = 0;
978: allocated_bogomem = 0;
979: allocated_a3000mem = 0;
980: kickmemory = 0;
981: chipmemory = 0;
982: a3000memory = 0;
983: bogomemory = 0;
984:
985: kickmemory = mapped_malloc (kickmem_size, "kick");
986: kickmem_bank.baseaddr = kickmemory;
1.1.1.3 root 987:
1.1.1.4 root 988: if (! load_kickstart ()) {
1.1.1.3 root 989: init_ersatz_rom (kickmemory);
1.1 root 990: ersatzkickfile = 1;
991: }
1.1.1.3 root 992:
1.1.1.9 root 993: init_mem_banks ();
994: memory_reset ();
1.1.1.4 root 995:
996: kickmem_mask = kickmem_size - 1;
1.1 root 997: }
998:
1.1.1.10 root 999: void memory_cleanup( void )
1000: {
1001: if (a3000memory)
1002: mapped_free (a3000memory);
1003: if (bogomemory)
1004: mapped_free (bogomemory);
1005: if (kickmemory)
1006: mapped_free (kickmemory);
1007: if (chipmemory)
1008: mapped_free (chipmemory);
1009:
1010: a3000memory = 0;
1011: bogomemory = 0;
1012: kickmemory = 0;
1013: chipmemory = 0;
1014: }
1015:
1.1.1.9 root 1016: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1 root 1017: {
1018: int bnr;
1.1.1.3 root 1019: unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.9 root 1020: addrbank* orgbank = bank;
1021: uae_u32 realstart = start;
1022:
1023: flush_icache(1); /* Sure don't want to keep any old mappings around! */
1024: #ifdef NATMEM_OFFSET
1025: delete_shmmaps (start << 16, size << 16);
1026: #endif
1027:
1028: if (!realsize)
1029: realsize = size << 16;
1030:
1031: if ((size << 16) < realsize) {
1.1.1.11! root 1032: write_log ("Please report to [email protected], and mention:\n");
! 1033: write_log ("Broken mapping, size=%x, realsize=%x\n",size,realsize);
! 1034: write_log ("Start is %x\n",start);
! 1035: write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9 root 1036: abort ();
1037: }
1.1.1.3 root 1038:
1039: if (start >= 0x100) {
1.1.1.10 root 1040: int real_left = 0;
1.1.1.9 root 1041: for (bnr = start; bnr < start + size; bnr++) {
1042: if (!real_left) {
1043: realstart = bnr;
1044: real_left = realsize>>16;
1045: #ifdef NATMEM_OFFSET
1046: add_shmmaps (realstart << 16, bank);
1047: #endif
1048: }
1049: put_mem_bank (bnr << 16, bank, realstart<<16);
1050: real_left--;
1051: }
1.1.1.3 root 1052: return;
1053: }
1.1.1.10 root 1054: if (currprefs.address_space_24)
1055: endhioffs = 0x10000;
1.1.1.9 root 1056: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10 root 1057: int real_left = 0;
1.1.1.9 root 1058: for (bnr = start; bnr < start+size; bnr++) {
1059: if (!real_left) {
1060: realstart = bnr + hioffs;
1061: real_left = realsize >> 16;
1062: #ifdef NATMEM_OFFSET
1063: add_shmmaps (realstart << 16, bank);
1064: #endif
1065: }
1066: put_mem_bank((bnr + hioffs) << 16, bank,realstart<<16);
1067: real_left--;
1068: }
1069: }
1070: }
1071:
1072:
1073: /* memory save/restore code */
1074:
1075: uae_u8 *save_cram (int *len)
1076: {
1077: *len = allocated_chipmem;
1078: return chipmemory;
1079: }
1080:
1081: uae_u8 *save_bram (int *len)
1082: {
1083: *len = allocated_bogomem;
1084: return bogomemory;
1085: }
1086:
1087: void restore_cram (int len, long filepos)
1088: {
1089: chip_filepos = filepos;
1090: changed_prefs.chipmem_size = len;
1091: }
1092:
1093: void restore_bram (int len, long filepos)
1094: {
1095: bogo_filepos = filepos;
1096: changed_prefs.bogomem_size = len;
1097: }
1098:
1099: uae_u8 *restore_rom (uae_u8 *src)
1100: {
1101: restore_u32 ();
1102: restore_u32 ();
1103: restore_u32 ();
1104: restore_u32 ();
1105: restore_u32 ();
1106:
1107: return src;
1108: }
1109:
1110: uae_u8 *save_rom (int first, int *len)
1111: {
1112: static int count;
1113: uae_u8 *dst, *dstbak;
1114: uae_u8 *mem_real_start;
1115: int mem_start, mem_size, mem_type, i, saverom;
1116:
1117: saverom = 0;
1118: if (first) count = 0;
1119: for (;;) {
1120: mem_type = count;
1121: switch (count)
1122: {
1123: case 0: /* Kickstart ROM */
1124: mem_start = 0xf80000;
1125: mem_real_start = kickmemory;
1126: mem_size = kickmem_size;
1127: /* 256KB or 512KB ROM? */
1128: for(i = 0; i < mem_size / 2 - 4; i++) {
1129: if(longget (i + mem_start) != longget(i + mem_start + mem_size / 2)) break;
1130: }
1131: if(i == mem_size / 2 - 4) {
1132: mem_size /= 2;
1133: mem_start += 262144;
1134: }
1135: mem_type = 0;
1136: break;
1137: default:
1138: return 0;
1139: }
1140: count++;
1141: if (mem_size) break;
1142: }
1143: dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
1144: save_u32 (mem_start);
1145: save_u32 (mem_size);
1146: save_u32 (mem_type);
1147: save_u32 (longget (mem_start + 12)); /* version+revision */
1148: save_u32 (0);
1149: sprintf (dst, "Kickstart %d.%d", wordget(mem_start + 12), wordget(mem_start + 14));
1150: dst += strlen (dst) + 1;
1151: if (saverom) {
1152: for(i = 0; i < mem_size; i++) *dst++ = byteget(mem_start + i);
1153: }
1154: *len = dst - dstbak;
1155: return dstbak;
1.1 root 1156: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.