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