|
|
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"
18:
1.1.1.2 root 19: #ifdef USE_MAPPED_MEMORY
1.1 root 20: #include <sys/mman.h>
21: #endif
22:
23: int ersatzkickfile = 0;
24:
1.1.1.3 ! root 25: #ifdef SAVE_MEMORY_BANKS
! 26: addrbank *mem_banks[65536];
! 27: #else
! 28: addrbank mem_banks[65536];
! 29: #endif
1.1 root 30:
1.1.1.2 root 31: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.3 ! root 32: __inline__ uae_u32 longget(uaecptr addr)
1.1.1.2 root 33: {
1.1.1.3 ! root 34: return call_mem_get_func(get_mem_bank(addr).lget, addr);
1.1.1.2 root 35: }
1.1.1.3 ! root 36: __inline__ uae_u32 wordget(uaecptr addr)
1.1.1.2 root 37: {
1.1.1.3 ! root 38: return call_mem_get_func(get_mem_bank(addr).wget, addr);
1.1.1.2 root 39: }
1.1.1.3 ! root 40: __inline__ uae_u32 byteget(uaecptr addr)
1.1.1.2 root 41: {
1.1.1.3 ! root 42: return call_mem_get_func(get_mem_bank(addr).bget, addr);
1.1.1.2 root 43: }
1.1.1.3 ! root 44: __inline__ void longput(uaecptr addr, uae_u32 l)
1.1.1.2 root 45: {
1.1.1.3 ! root 46: call_mem_put_func(get_mem_bank(addr).lput, addr, l);
1.1.1.2 root 47: }
1.1.1.3 ! root 48: __inline__ void wordput(uaecptr addr, uae_u32 w)
1.1.1.2 root 49: {
1.1.1.3 ! root 50: call_mem_put_func(get_mem_bank(addr).wput, addr, w);
1.1.1.2 root 51: }
1.1.1.3 ! root 52: __inline__ void byteput(uaecptr addr, uae_u32 b)
1.1.1.2 root 53: {
1.1.1.3 ! root 54: call_mem_put_func(get_mem_bank(addr).bput, addr, b);
1.1.1.2 root 55: }
56: #endif
57:
1.1.1.3 ! root 58: uae_u32 chipmem_mask, kickmem_mask, bogomem_mask, a3000mem_mask;
1.1 root 59:
1.1.1.3 ! root 60: /* A dummy bank that only contains zeros */
! 61:
! 62: static uae_u32 dummy_lget(uaecptr) REGPARAM;
! 63: static uae_u32 dummy_wget(uaecptr) REGPARAM;
! 64: static uae_u32 dummy_bget(uaecptr) REGPARAM;
! 65: static void dummy_lput(uaecptr, uae_u32) REGPARAM;
! 66: static void dummy_wput(uaecptr, uae_u32) REGPARAM;
! 67: static void dummy_bput(uaecptr, uae_u32) REGPARAM;
! 68: static int dummy_check(uaecptr addr, uae_u32 size) REGPARAM;
! 69:
! 70: uae_u32 REGPARAM2 dummy_lget(uaecptr addr)
! 71: {
! 72: if (currprefs.illegal_mem) {
! 73: sprintf (warning_buffer, "Illegal lget at %08lx\n", addr);
! 74: write_log (warning_buffer);
! 75: }
1.1 root 76: return 0;
77: }
78:
1.1.1.3 ! root 79: uae_u32 REGPARAM2 dummy_wget(uaecptr addr)
1.1 root 80: {
1.1.1.3 ! root 81: if (currprefs.illegal_mem) {
! 82: sprintf (warning_buffer, "Illegal wget at %08lx\n", addr);
! 83: write_log (warning_buffer);
! 84: }
1.1 root 85: return 0;
86: }
87:
1.1.1.3 ! root 88: uae_u32 REGPARAM2 dummy_bget(uaecptr addr)
1.1 root 89: {
1.1.1.3 ! root 90: if (currprefs.illegal_mem) {
! 91: sprintf (warning_buffer, "Illegal bget at %08lx\n", addr);
! 92: write_log (warning_buffer);
! 93: }
1.1 root 94: return 0;
95: }
96:
1.1.1.3 ! root 97: void REGPARAM2 dummy_lput(uaecptr addr, uae_u32 l)
1.1 root 98: {
1.1.1.3 ! root 99: if (currprefs.illegal_mem) {
! 100: sprintf (warning_buffer, "Illegal lput at %08lx\n", addr);
! 101: write_log (warning_buffer);
! 102: }
! 103: }
! 104: void REGPARAM2 dummy_wput(uaecptr addr, uae_u32 w)
! 105: {
! 106: if (currprefs.illegal_mem) {
! 107: sprintf (warning_buffer, "Illegal wput at %08lx\n", addr);
! 108: write_log (warning_buffer);
! 109: }
! 110: }
! 111: void REGPARAM2 dummy_bput(uaecptr addr, uae_u32 b)
! 112: {
! 113: if (currprefs.illegal_mem) {
! 114: sprintf (warning_buffer, "Illegal bput at %08lx\n", addr);
! 115: write_log (warning_buffer);
! 116: }
1.1 root 117: }
118:
1.1.1.3 ! root 119: int REGPARAM2 dummy_check(uaecptr addr, uae_u32 size)
1.1 root 120: {
1.1.1.3 ! root 121: if (currprefs.illegal_mem) {
! 122: sprintf (warning_buffer, "Illegal check at %08lx\n", addr);
! 123: write_log (warning_buffer);
! 124: }
1.1 root 125: return 0;
126: }
127:
1.1.1.3 ! root 128: /* A3000 "motherboard resources" bank. */
! 129: static uae_u32 mbres_lget(uaecptr) REGPARAM;
! 130: static uae_u32 mbres_wget(uaecptr) REGPARAM;
! 131: static uae_u32 mbres_bget(uaecptr) REGPARAM;
! 132: static void mbres_lput(uaecptr, uae_u32) REGPARAM;
! 133: static void mbres_wput(uaecptr, uae_u32) REGPARAM;
! 134: static void mbres_bput(uaecptr, uae_u32) REGPARAM;
! 135: static int mbres_check(uaecptr addr, uae_u32 size) REGPARAM;
! 136:
! 137: static int mbres_val = 0;
! 138:
! 139: uae_u32 REGPARAM2 mbres_lget(uaecptr addr)
! 140: {
! 141: if (currprefs.illegal_mem) {
! 142: sprintf (warning_buffer, "Illegal lget at %08lx\n", addr);
! 143: write_log (warning_buffer);
! 144: }
1.1 root 145: return 0;
146: }
147:
1.1.1.3 ! root 148: uae_u32 REGPARAM2 mbres_wget(uaecptr addr)
1.1 root 149: {
1.1.1.3 ! root 150: if (currprefs.illegal_mem) {
! 151: sprintf (warning_buffer, "Illegal wget at %08lx\n", addr);
! 152: write_log (warning_buffer);
! 153: }
1.1 root 154: return 0;
155: }
156:
1.1.1.3 ! root 157: uae_u32 REGPARAM2 mbres_bget(uaecptr addr)
! 158: {
! 159: if (currprefs.illegal_mem) {
! 160: sprintf (warning_buffer, "Illegal bget at %08lx\n", addr);
! 161: write_log (warning_buffer);
! 162: }
! 163: return (addr & 0xFFFF) == 3 ? mbres_val : 0;
! 164: }
! 165:
! 166: void REGPARAM2 mbres_lput(uaecptr addr, uae_u32 l)
1.1 root 167: {
1.1.1.3 ! root 168: if (currprefs.illegal_mem) {
! 169: sprintf (warning_buffer, "Illegal lput at %08lx\n", addr);
! 170: write_log (warning_buffer);
! 171: }
1.1 root 172: }
1.1.1.3 ! root 173: void REGPARAM2 mbres_wput(uaecptr addr, uae_u32 w)
1.1 root 174: {
1.1.1.3 ! root 175: if (currprefs.illegal_mem) {
! 176: sprintf (warning_buffer, "Illegal wput at %08lx\n", addr);
! 177: write_log (warning_buffer);
! 178: }
1.1 root 179: }
1.1.1.3 ! root 180: void REGPARAM2 mbres_bput(uaecptr addr, uae_u32 b)
1.1 root 181: {
1.1.1.3 ! root 182: if (currprefs.illegal_mem) {
! 183: sprintf (warning_buffer, "Illegal bput at %08lx\n", addr);
! 184: write_log (warning_buffer);
! 185: }
! 186: if ((addr & 0xFFFF) == 3)
! 187: mbres_val = b;
1.1 root 188: }
189:
1.1.1.3 ! root 190: int REGPARAM2 mbres_check(uaecptr addr, uae_u32 size)
1.1 root 191: {
1.1.1.3 ! root 192: if (currprefs.illegal_mem) {
! 193: sprintf (warning_buffer, "Illegal check at %08lx\n", addr);
! 194: write_log (warning_buffer);
! 195: }
1.1 root 196: return 0;
197: }
198:
199: /* Chip memory */
200:
1.1.1.3 ! root 201: uae_u8 *chipmemory;
1.1 root 202:
1.1.1.3 ! root 203: static uae_u32 chipmem_lget(uaecptr) REGPARAM;
! 204: static uae_u32 chipmem_wget(uaecptr) REGPARAM;
! 205: static uae_u32 chipmem_bget(uaecptr) REGPARAM;
! 206: static void chipmem_lput(uaecptr, uae_u32) REGPARAM;
! 207: static void chipmem_wput(uaecptr, uae_u32) REGPARAM;
! 208: static void chipmem_bput(uaecptr, uae_u32) REGPARAM;
1.1 root 209:
1.1.1.3 ! root 210: static int chipmem_check(uaecptr addr, uae_u32 size) REGPARAM;
! 211: static uae_u8 *chipmem_xlate(uaecptr addr) REGPARAM;
1.1 root 212:
1.1.1.3 ! root 213: uae_u32 REGPARAM2 chipmem_lget(uaecptr addr)
1.1 root 214: {
1.1.1.3 ! root 215: uae_u32 *m;
1.1 root 216: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 217: addr &= chipmem_mask;
1.1.1.3 ! root 218: m = (uae_u32 *)(chipmemory + addr);
1.1.1.2 root 219: return do_get_mem_long(m);
1.1 root 220: }
221:
1.1.1.3 ! root 222: uae_u32 REGPARAM2 chipmem_wget(uaecptr addr)
1.1 root 223: {
1.1.1.3 ! root 224: uae_u16 *m;
1.1 root 225: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 226: addr &= chipmem_mask;
1.1.1.3 ! root 227: m = (uae_u16 *)(chipmemory + addr);
1.1.1.2 root 228: return do_get_mem_word(m);
1.1 root 229: }
230:
1.1.1.3 ! root 231: uae_u32 REGPARAM2 chipmem_bget(uaecptr addr)
1.1 root 232: {
233: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 234: addr &= chipmem_mask;
1.1 root 235: return chipmemory[addr];
236: }
237:
1.1.1.3 ! root 238: void REGPARAM2 chipmem_lput(uaecptr addr, uae_u32 l)
1.1 root 239: {
1.1.1.3 ! root 240: uae_u32 *m;
1.1 root 241: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 242: addr &= chipmem_mask;
1.1.1.3 ! root 243: m = (uae_u32 *)(chipmemory + addr);
1.1.1.2 root 244: do_put_mem_long(m, l);
1.1 root 245: }
246:
1.1.1.3 ! root 247: void REGPARAM2 chipmem_wput(uaecptr addr, uae_u32 w)
1.1 root 248: {
1.1.1.3 ! root 249: uae_u16 *m;
1.1 root 250: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 251: addr &= chipmem_mask;
1.1.1.3 ! root 252: m = (uae_u16 *)(chipmemory + addr);
1.1.1.2 root 253: do_put_mem_word(m, w);
1.1 root 254: }
255:
1.1.1.3 ! root 256: void REGPARAM2 chipmem_bput(uaecptr addr, uae_u32 b)
1.1 root 257: {
258: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 259: addr &= chipmem_mask;
1.1 root 260: chipmemory[addr] = b;
261: }
262:
1.1.1.3 ! root 263: int REGPARAM2 chipmem_check(uaecptr addr, uae_u32 size)
1.1 root 264: {
265: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 266: addr &= chipmem_mask;
1.1 root 267: return (addr + size) < chipmem_size;
268: }
269:
1.1.1.3 ! root 270: uae_u8 REGPARAM2 *chipmem_xlate(uaecptr addr)
1.1 root 271: {
272: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 273: addr &= chipmem_mask;
1.1 root 274: return chipmemory + addr;
275: }
276:
277: /* Slow memory */
278:
1.1.1.3 ! root 279: static uae_u8 *bogomemory;
1.1 root 280:
1.1.1.3 ! root 281: static uae_u32 bogomem_lget(uaecptr) REGPARAM;
! 282: static uae_u32 bogomem_wget(uaecptr) REGPARAM;
! 283: static uae_u32 bogomem_bget(uaecptr) REGPARAM;
! 284: static void bogomem_lput(uaecptr, uae_u32) REGPARAM;
! 285: static void bogomem_wput(uaecptr, uae_u32) REGPARAM;
! 286: static void bogomem_bput(uaecptr, uae_u32) REGPARAM;
! 287: static int bogomem_check(uaecptr addr, uae_u32 size) REGPARAM;
! 288: static uae_u8 *bogomem_xlate(uaecptr addr) REGPARAM;
1.1 root 289:
1.1.1.3 ! root 290: uae_u32 REGPARAM2 bogomem_lget(uaecptr addr)
1.1 root 291: {
1.1.1.3 ! root 292: uae_u32 *m;
1.1 root 293: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 294: addr &= bogomem_mask;
1.1.1.3 ! root 295: m = (uae_u32 *)(bogomemory + addr);
1.1.1.2 root 296: return do_get_mem_long(m);
1.1 root 297: }
298:
1.1.1.3 ! root 299: uae_u32 REGPARAM2 bogomem_wget(uaecptr addr)
1.1 root 300: {
1.1.1.3 ! root 301: uae_u16 *m;
1.1 root 302: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 303: addr &= bogomem_mask;
1.1.1.3 ! root 304: m = (uae_u16 *)(bogomemory + addr);
1.1.1.2 root 305: return do_get_mem_word(m);
1.1 root 306: }
307:
1.1.1.3 ! root 308: uae_u32 REGPARAM2 bogomem_bget(uaecptr addr)
1.1 root 309: {
310: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 311: addr &= bogomem_mask;
1.1 root 312: return bogomemory[addr];
313: }
314:
1.1.1.3 ! root 315: void REGPARAM2 bogomem_lput(uaecptr addr, uae_u32 l)
1.1 root 316: {
1.1.1.3 ! root 317: uae_u32 *m;
1.1 root 318: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 319: addr &= bogomem_mask;
1.1.1.3 ! root 320: m = (uae_u32 *)(bogomemory + addr);
1.1.1.2 root 321: do_put_mem_long(m, l);
1.1 root 322: }
323:
1.1.1.3 ! root 324: void REGPARAM2 bogomem_wput(uaecptr addr, uae_u32 w)
1.1 root 325: {
1.1.1.3 ! root 326: uae_u16 *m;
1.1 root 327: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 328: addr &= bogomem_mask;
1.1.1.3 ! root 329: m = (uae_u16 *)(bogomemory + addr);
1.1.1.2 root 330: do_put_mem_word(m, w);
1.1 root 331: }
332:
1.1.1.3 ! root 333: void REGPARAM2 bogomem_bput(uaecptr addr, uae_u32 b)
1.1 root 334: {
335: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 336: addr &= bogomem_mask;
1.1 root 337: bogomemory[addr] = b;
338: }
339:
1.1.1.3 ! root 340: int REGPARAM2 bogomem_check(uaecptr addr, uae_u32 size)
1.1 root 341: {
1.1.1.2 root 342: addr -= bogomem_start & bogomem_mask;
343: addr &= bogomem_mask;
1.1 root 344: return (addr + size) < bogomem_size;
345: }
346:
1.1.1.3 ! root 347: uae_u8 REGPARAM2 *bogomem_xlate(uaecptr addr)
1.1 root 348: {
1.1.1.2 root 349: addr -= bogomem_start & bogomem_mask;
350: addr &= bogomem_mask;
1.1 root 351: return bogomemory + addr;
352: }
353:
1.1.1.3 ! root 354: /* A3000 motherboard fast memory */
! 355:
! 356: static uae_u8 *a3000memory;
1.1 root 357:
1.1.1.3 ! root 358: static uae_u32 a3000mem_lget(uaecptr) REGPARAM;
! 359: static uae_u32 a3000mem_wget(uaecptr) REGPARAM;
! 360: static uae_u32 a3000mem_bget(uaecptr) REGPARAM;
! 361: static void a3000mem_lput(uaecptr, uae_u32) REGPARAM;
! 362: static void a3000mem_wput(uaecptr, uae_u32) REGPARAM;
! 363: static void a3000mem_bput(uaecptr, uae_u32) REGPARAM;
! 364: static int a3000mem_check(uaecptr addr, uae_u32 size) REGPARAM;
! 365: static uae_u8 *a3000mem_xlate(uaecptr addr) REGPARAM;
! 366:
! 367: uae_u32 REGPARAM2 a3000mem_lget(uaecptr addr)
! 368: {
! 369: uae_u32 *m;
! 370: addr -= a3000mem_start & a3000mem_mask;
! 371: addr &= a3000mem_mask;
! 372: m = (uae_u32 *)(a3000memory + addr);
! 373: return do_get_mem_long(m);
! 374: }
1.1 root 375:
1.1.1.3 ! root 376: uae_u32 REGPARAM2 a3000mem_wget(uaecptr addr)
! 377: {
! 378: uae_u16 *m;
! 379: addr -= a3000mem_start & a3000mem_mask;
! 380: addr &= a3000mem_mask;
! 381: m = (uae_u16 *)(a3000memory + addr);
! 382: return do_get_mem_word(m);
! 383: }
1.1 root 384:
1.1.1.3 ! root 385: uae_u32 REGPARAM2 a3000mem_bget(uaecptr addr)
1.1 root 386: {
1.1.1.3 ! root 387: addr -= a3000mem_start & a3000mem_mask;
! 388: addr &= a3000mem_mask;
! 389: return a3000memory[addr];
1.1 root 390: }
391:
1.1.1.3 ! root 392: void REGPARAM2 a3000mem_lput(uaecptr addr, uae_u32 l)
1.1 root 393: {
1.1.1.3 ! root 394: uae_u32 *m;
! 395: addr -= a3000mem_start & a3000mem_mask;
! 396: addr &= a3000mem_mask;
! 397: m = (uae_u32 *)(a3000memory + addr);
! 398: do_put_mem_long(m, l);
! 399: }
! 400:
! 401: void REGPARAM2 a3000mem_wput(uaecptr addr, uae_u32 w)
! 402: {
! 403: uae_u16 *m;
! 404: addr -= a3000mem_start & a3000mem_mask;
! 405: addr &= a3000mem_mask;
! 406: m = (uae_u16 *)(a3000memory + addr);
! 407: do_put_mem_word(m, w);
! 408: }
! 409:
! 410: void REGPARAM2 a3000mem_bput(uaecptr addr, uae_u32 b)
! 411: {
! 412: addr -= a3000mem_start & a3000mem_mask;
! 413: addr &= a3000mem_mask;
! 414: a3000memory[addr] = b;
! 415: }
! 416:
! 417: int REGPARAM2 a3000mem_check(uaecptr addr, uae_u32 size)
! 418: {
! 419: addr -= a3000mem_start & a3000mem_mask;
! 420: addr &= a3000mem_mask;
! 421: return (addr + size) < a3000mem_size;
1.1 root 422: }
423:
1.1.1.3 ! root 424: uae_u8 REGPARAM2 *a3000mem_xlate(uaecptr addr)
! 425: {
! 426: addr -= a3000mem_start & a3000mem_mask;
! 427: addr &= a3000mem_mask;
! 428: return a3000memory + addr;
! 429: }
! 430:
! 431: /* Kick memory */
! 432:
! 433: uae_u8 *kickmemory;
! 434:
! 435: static uae_u32 kickmem_lget(uaecptr) REGPARAM;
! 436: static uae_u32 kickmem_wget(uaecptr) REGPARAM;
! 437: static uae_u32 kickmem_bget(uaecptr) REGPARAM;
! 438: static void kickmem_lput(uaecptr, uae_u32) REGPARAM;
! 439: static void kickmem_wput(uaecptr, uae_u32) REGPARAM;
! 440: static void kickmem_bput(uaecptr, uae_u32) REGPARAM;
! 441: static int kickmem_check(uaecptr addr, uae_u32 size) REGPARAM;
! 442: static uae_u8 *kickmem_xlate(uaecptr addr) REGPARAM;
! 443:
! 444: uae_u32 REGPARAM2 kickmem_lget(uaecptr addr)
1.1 root 445: {
1.1.1.3 ! root 446: uae_u32 *m;
1.1 root 447: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 448: addr &= kickmem_mask;
1.1.1.3 ! root 449: m = (uae_u32 *)(kickmemory + addr);
! 450: return do_get_mem_long(m);
1.1 root 451: }
452:
1.1.1.3 ! root 453: uae_u32 REGPARAM2 kickmem_wget(uaecptr addr)
1.1 root 454: {
1.1.1.3 ! root 455: uae_u16 *m;
1.1 root 456: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 457: addr &= kickmem_mask;
1.1.1.3 ! root 458: m = (uae_u16 *)(kickmemory + addr);
! 459: return do_get_mem_word(m);
1.1 root 460: }
461:
1.1.1.3 ! root 462: uae_u32 REGPARAM2 kickmem_bget(uaecptr addr)
1.1 root 463: {
464: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 465: addr &= kickmem_mask;
1.1 root 466: return kickmemory[addr];
467: }
468:
1.1.1.3 ! root 469: void REGPARAM2 kickmem_lput(uaecptr addr, uae_u32 b)
1.1 root 470: {
1.1.1.3 ! root 471: if (currprefs.illegal_mem) sprintf (warning_buffer, "Illegal kickmem lput at %08lx\n", addr);
1.1 root 472: }
473:
1.1.1.3 ! root 474: void REGPARAM2 kickmem_wput(uaecptr addr, uae_u32 b)
1.1 root 475: {
1.1.1.3 ! root 476: if (currprefs.illegal_mem) sprintf (warning_buffer, "Illegal kickmem wput at %08lx\n", addr);
1.1 root 477: }
478:
1.1.1.3 ! root 479: void REGPARAM2 kickmem_bput(uaecptr addr, uae_u32 b)
1.1 root 480: {
1.1.1.3 ! root 481: if (currprefs.illegal_mem) sprintf (warning_buffer, "Illegal kickmem lput at %08lx\n", addr);
1.1 root 482: }
483:
1.1.1.3 ! root 484: int REGPARAM2 kickmem_check(uaecptr addr, uae_u32 size)
1.1 root 485: {
1.1.1.2 root 486: addr -= kickmem_start & kickmem_mask;
487: addr &= kickmem_mask;
1.1 root 488: return (addr + size) < kickmem_size;
489: }
490:
1.1.1.3 ! root 491: uae_u8 REGPARAM2 *kickmem_xlate(uaecptr addr)
1.1 root 492: {
1.1.1.2 root 493: addr -= kickmem_start & kickmem_mask;
494: addr &= kickmem_mask;
1.1 root 495: return kickmemory + addr;
496: }
497:
1.1.1.3 ! root 498: /* Default memory access functions */
! 499:
! 500: int REGPARAM2 default_check(uaecptr a, uae_u32 b)
! 501: {
! 502: return 0;
! 503: }
! 504:
! 505: uae_u8 REGPARAM2 *default_xlate(uaecptr a)
! 506: {
! 507: write_log ("Your Amiga program just did something terribly stupid\n");
! 508: uae_reset();
! 509: return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
! 510: }
! 511:
1.1 root 512: static int load_kickstart(void)
513: {
514: int i;
1.1.1.3 ! root 515: uae_u32 cksum = 0, prevck = 0;
! 516: unsigned char buffer[20];
! 517:
1.1 root 518: FILE *f = zfile_open(romfile, "rb");
1.1.1.3 ! root 519:
! 520: if (f == NULL) {
! 521: write_log ("No Kickstart ROM found.\n");
! 522: #if defined(AMIGA)||defined(__POS__)
1.1.1.2 root 523: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
1.1.1.3 ! root 524: if (!getenv(USE_UAE_ERSATZ)) {
! 525: fprintf (stderr, "Using current ROM. (create ENV:%s to "
1.1.1.2 root 526: "use uae's ROM replacement)\n",USE_UAE_ERSATZ);
527: memcpy(kickmemory,(char*)0x1000000-kickmem_size,kickmem_size);
528: goto chk_sum;
529: }
530: #endif
1.1 root 531: return 0;
532: }
1.1.1.3 ! root 533:
! 534: i = fread (buffer, 1, 11, f);
! 535: if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) != 0)
! 536: fseek (f, 0, SEEK_SET);
! 537:
! 538: i = fread (kickmemory, 1, kickmem_size, f);
1.1 root 539: if (i == kickmem_size/2) {
540: memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
541: } else if (i != kickmem_size) {
1.1.1.3 ! root 542: write_log ("Error while reading Kickstart.\n");
1.1 root 543: return 0;
544: }
545: zfile_close (f);
1.1.1.3 ! root 546:
! 547: cloanto_rom = 0;
! 548: if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) == 0) {
! 549: FILE *keyf;
! 550: uae_u8 *p;
! 551: long size, cnt, t;
! 552:
! 553: cloanto_rom = 1;
! 554: write_log ("ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
! 555: if (strlen (keyfile) == 0) {
! 556: write_log ("No filename given for ROM key file.\n");
! 557: return 0;
! 558: }
! 559: keyf = zfile_open (keyfile, "rb");
! 560: if (keyf == 0) {
! 561: write_log ("Could not find ROM key file.\n");
! 562: return 0;
! 563: }
! 564: p = (uae_u8 *)xmalloc (524288);
! 565: size = fread (p, 1, 524288, keyf);
! 566:
! 567: for (t = cnt = 0; cnt < kickmem_size; cnt++, t = (t + 1) % size) {
! 568: kickmemory[cnt] ^= p[t];
! 569: if (i == cnt+1)
! 570: t = size-1;
! 571: }
! 572: fclose (keyf);
! 573: free (p);
! 574: }
1.1.1.2 root 575: #if defined(AMIGA)
576: chk_sum:
577: #endif
578:
1.1 root 579: for (i = 0; i < kickmem_size; i+=4) {
1.1.1.3 ! root 580: uae_u32 data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
1.1 root 581: cksum += data;
582: if (cksum < prevck)
583: cksum++;
584: prevck = cksum;
585: }
1.1.1.2 root 586: if (cksum != 0xFFFFFFFFul) {
1.1.1.3 ! root 587: write_log("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
1.1 root 588: }
589: return 1;
590: }
591:
592: /* Address banks */
593:
594: addrbank dummy_bank = {
595: dummy_lget, dummy_wget, dummy_bget,
596: dummy_lput, dummy_wput, dummy_bput,
597: default_xlate, dummy_check
598: };
599:
1.1.1.3 ! root 600: addrbank mbres_bank = {
! 601: mbres_lget, mbres_wget, mbres_bget,
! 602: mbres_lput, mbres_wput, mbres_bput,
! 603: default_xlate, mbres_check
! 604: };
! 605:
1.1 root 606: addrbank chipmem_bank = {
607: chipmem_lget, chipmem_wget, chipmem_bget,
608: chipmem_lput, chipmem_wput, chipmem_bput,
609: chipmem_xlate, chipmem_check
610: };
611:
612: addrbank bogomem_bank = {
613: bogomem_lget, bogomem_wget, bogomem_bget,
614: bogomem_lput, bogomem_wput, bogomem_bput,
615: bogomem_xlate, bogomem_check
616: };
617:
1.1.1.3 ! root 618: addrbank a3000mem_bank = {
! 619: a3000mem_lget, a3000mem_wget, a3000mem_bget,
! 620: a3000mem_lput, a3000mem_wput, a3000mem_bput,
! 621: a3000mem_xlate, a3000mem_check
! 622: };
! 623:
1.1 root 624: addrbank kickmem_bank = {
625: kickmem_lget, kickmem_wget, kickmem_bget,
626: kickmem_lput, kickmem_wput, kickmem_bput,
627: kickmem_xlate, kickmem_check
628: };
629:
630: char *address_space, *good_address_map;
631: int good_address_fd;
1.1.1.2 root 632: #define MAKE_USER_PROGRAMS_BEHAVE 1
1.1 root 633: void memory_init(void)
634: {
635: char buffer[4096];
636: char *nam;
637: int i, fd;
1.1.1.3 ! root 638: int custom_start;
1.1 root 639:
640: chipmem_mask = chipmem_size - 1;
641: kickmem_mask = kickmem_size - 1;
642: bogomem_mask = bogomem_size - 1;
1.1.1.3 ! root 643: a3000mem_mask = a3000mem_size - 1;
! 644:
1.1.1.2 root 645: #ifdef USE_MAPPED_MEMORY
1.1 root 646: fd = open("/dev/zero", O_RDWR);
647: good_address_map = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
1.1.1.2 root 648: /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon
649: * as a decrunch routine tries to do color register hacks. */
650: address_space = mmap(NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0);
651: if ((int)address_space < 0 || (int)good_address_map < 0) {
1.1.1.3 ! root 652: write_log ("Your system does not have enough virtual memory - increase swap.\n");
1.1.1.2 root 653: abort();
654: }
655: #ifdef MAKE_USER_PROGRAMS_BEHAVE
656: memset(address_space + 0xDFF180, 0xFF, 32*2);
657: #else
658: /* Likewise. This is mostly for mouse button checks. */
659: if (USER_PROGRAMS_BEHAVE)
660: memset(address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000);
661: #endif
1.1 root 662: chipmemory = mmap(address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
663: kickmemory = mmap(address_space + 0xF80000, 0x80000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
664:
665: close(fd);
666:
1.1.1.3 ! root 667: good_address_fd = open(nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600);
! 668: memset (buffer, 1, sizeof(buffer));
! 669: write (good_address_fd, buffer, sizeof buffer);
! 670: unlink (nam);
1.1 root 671:
672: for (i = 0; i < chipmem_size; i += 4096)
673: mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
674: good_address_fd, 0);
675: for (i = 0; i < kickmem_size; i += 4096)
676: mmap(good_address_map + i + 0x1000000 - kickmem_size, 4096, PROT_READ,
677: MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
678: #else
1.1.1.3 ! root 679: kickmemory = (uae_u8 *)xmalloc(kickmem_size);
! 680: chipmemory = (uae_u8 *)malloc(chipmem_size);
! 681:
! 682: while (!chipmemory && chipmem_size > 512*1024) {
! 683: chipmem_size >>= 1;
! 684: chipmem_mask = chipmem_size - 1;
! 685: chipmemory = (uae_u8 *)malloc(chipmem_size);
! 686: if (chipmemory)
! 687: fprintf (stderr, "Reducing chipmem size to %dkb\n", chipmem_size>>10);
! 688: }
! 689: if (!chipmemory) {
! 690: write_log ("virtual memory exhausted (chipmemory)!\n");
! 691: abort();
1.1.1.2 root 692: }
1.1 root 693: #endif
694:
695: for(i = 0; i < 65536; i++)
1.1.1.3 ! root 696: put_mem_bank (i<<16, &dummy_bank);
! 697:
1.1 root 698: /* Map the chipmem into all of the lower 16MB */
1.1.1.3 ! root 699: map_banks (&chipmem_bank, 0x00, 256);
! 700: custom_start = 0xC0;
1.1 root 701:
1.1.1.3 ! root 702: map_banks (&custom_bank, custom_start, 0xE0-custom_start);
! 703: map_banks (&cia_bank, 0xA0, 32);
! 704: map_banks (&clock_bank, 0xDC, 1);
! 705:
! 706: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
! 707: * range on an Amiga without expansion memory? */
! 708: custom_start = chipmem_size >> 16;
! 709: if (custom_start < 0x20)
! 710: custom_start = 0x20;
! 711: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start);
! 712: /*map_banks (&mbres_bank, 0xDE, 1);*/
! 713:
! 714: if (bogomem_size > 0)
! 715: bogomemory = (uae_u8 *)xmalloc (bogomem_size);
! 716: if (bogomem_size > 0)
! 717: map_banks(&bogomem_bank, 0xC0, bogomem_size >> 16);
! 718:
! 719: if (a3000mem_size > 0)
! 720: a3000memory = (uae_u8 *)xmalloc (a3000mem_size);
! 721: if (a3000mem_size > 0)
! 722: map_banks(&a3000mem_bank, a3000mem_start >> 16, a3000mem_size >> 16);
! 723:
! 724: map_banks (&rtarea_bank, 0xF0, 1);
! 725: if (!load_kickstart ()) {
! 726: init_ersatz_rom (kickmemory);
1.1 root 727: ersatzkickfile = 1;
728: }
1.1.1.3 ! root 729: map_banks (&kickmem_bank, 0xF8, 8);
! 730: map_banks (&expamem_bank, 0xE8, 1);
! 731:
! 732: if (cloanto_rom)
! 733: map_banks (&kickmem_bank, 0xE0, 8);
1.1 root 734: }
735:
736: void map_banks(addrbank *bank, int start, int size)
737: {
738: int bnr;
1.1.1.3 ! root 739: unsigned long int hioffs = 0, endhioffs = 0x100;
! 740:
! 741: if (start >= 0x100) {
! 742: for (bnr = start; bnr < start + size; bnr++)
! 743: put_mem_bank (bnr << 16, bank);
! 744: return;
! 745: }
! 746: /* Some '020 Kickstarts apparently require a 24 bit address space... */
! 747: if (currprefs.address_space_24)
! 748: endhioffs = 0x10000;
! 749: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
! 750: for (bnr = start; bnr < start+size; bnr++)
! 751: put_mem_bank((bnr + hioffs) << 16, bank);
1.1 root 752: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.