|
|
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" ! 14: #include "memory.h" ! 15: #include "custom.h" ! 16: #include "cia.h" ! 17: #include "ersatz.h" ! 18: #include "zfile.h" ! 19: #include "events.h" ! 20: #include "newcpu.h" ! 21: #include "compiler.h" ! 22: ! 23: #ifdef USE_COMPILER ! 24: #include <sys/mman.h> ! 25: #endif ! 26: ! 27: int ersatzkickfile = 0; ! 28: ! 29: int buserr; ! 30: addrbank membanks[65536]; ! 31: ! 32: /* Default memory access functions */ ! 33: ! 34: int default_check(CPTR a, ULONG b) ! 35: { ! 36: return 0; ! 37: } ! 38: ! 39: UBYTE *default_xlate(CPTR a) ! 40: { ! 41: fprintf(stderr, "Your Amiga program just did something terribly stupid\n"); ! 42: return 0; ! 43: } ! 44: ! 45: UWORD default_awget(CPTR addr) ! 46: { ! 47: default_xlate(addr); ! 48: return 0; ! 49: } ! 50: ! 51: ULONG default_alget(CPTR addr) ! 52: { ! 53: default_xlate(addr); ! 54: return 0; ! 55: } ! 56: ! 57: /* A dummy bank that only contains zeros */ ! 58: ! 59: static ULONG dummy_lget(CPTR) REGPARAM; ! 60: static UWORD dummy_wget(CPTR) REGPARAM; ! 61: static UBYTE dummy_bget(CPTR) REGPARAM; ! 62: static void dummy_lput(CPTR, ULONG) REGPARAM; ! 63: static void dummy_wput(CPTR, UWORD) REGPARAM; ! 64: static void dummy_bput(CPTR, UBYTE) REGPARAM; ! 65: static int dummy_check(CPTR addr, ULONG size) REGPARAM; ! 66: ! 67: ULONG dummy_lget(CPTR addr) ! 68: { ! 69: if (illegal_mem) printf("Illegal lget at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 70: return 0; ! 71: } ! 72: ! 73: UWORD dummy_wget(CPTR addr) ! 74: { ! 75: if (illegal_mem) printf("Illegal wget at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 76: return 0; ! 77: } ! 78: ! 79: UBYTE dummy_bget(CPTR addr) ! 80: { ! 81: if (illegal_mem) printf("Illegal bget at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 82: return 0; ! 83: } ! 84: ! 85: void dummy_lput(CPTR addr, ULONG l) ! 86: { ! 87: if (illegal_mem) printf("Illegal lput at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 88: } ! 89: void dummy_wput(CPTR addr, UWORD w) ! 90: { ! 91: if (illegal_mem) printf("Illegal wput at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 92: } ! 93: void dummy_bput(CPTR addr, UBYTE b) ! 94: { ! 95: if (illegal_mem) printf("Illegal bput at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 96: } ! 97: ! 98: int dummy_check(CPTR addr, ULONG size) ! 99: { ! 100: if (illegal_mem) printf("Illegal check at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 101: return 0; ! 102: } ! 103: ! 104: /* Chip memory */ ! 105: ! 106: ULONG chipmem_mask,kickmem_mask,bogomem_mask; ! 107: ! 108: UBYTE *chipmemory; ! 109: ! 110: static ULONG chipmem_alget(CPTR) REGPARAM; ! 111: static UWORD chipmem_awget(CPTR) REGPARAM; ! 112: ! 113: static ULONG chipmem_lget(CPTR) REGPARAM; ! 114: static UWORD chipmem_wget(CPTR) REGPARAM; ! 115: static UBYTE chipmem_bget(CPTR) REGPARAM; ! 116: static void chipmem_lput(CPTR, ULONG) REGPARAM; ! 117: static void chipmem_wput(CPTR, UWORD) REGPARAM; ! 118: static void chipmem_bput(CPTR, UBYTE) REGPARAM; ! 119: ! 120: static int chipmem_check(CPTR addr, ULONG size) REGPARAM; ! 121: static UBYTE *chipmem_xlate(CPTR addr) REGPARAM; ! 122: ! 123: ULONG chipmem_alget(CPTR addr) ! 124: { ! 125: UBYTE *m; ! 126: addr -= chipmem_start & chipmem_mask; ! 127: addr &= chipmem_size-1; ! 128: m = chipmemory + addr; ! 129: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) ! 130: + ((ULONG)m[2] << 8) + ((ULONG)m[3])); ! 131: } ! 132: ! 133: UWORD chipmem_awget(CPTR addr) ! 134: { ! 135: UBYTE *m; ! 136: addr -= chipmem_start & chipmem_mask; ! 137: addr &= chipmem_size-1; ! 138: m = chipmemory + addr; ! 139: return ((UWORD)m[0] << 8) + m[1]; ! 140: } ! 141: ! 142: ULONG chipmem_lget(CPTR addr) ! 143: { ! 144: UBYTE *m; ! 145: addr -= chipmem_start & chipmem_mask; ! 146: addr &= chipmem_size-1; ! 147: m = chipmemory + addr; ! 148: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) ! 149: + ((ULONG)m[2] << 8) + ((ULONG)m[3])); ! 150: } ! 151: ! 152: UWORD chipmem_wget(CPTR addr) ! 153: { ! 154: UBYTE *m; ! 155: addr -= chipmem_start & chipmem_mask; ! 156: addr &= chipmem_size-1; ! 157: m = chipmemory + addr; ! 158: return ((UWORD)m[0] << 8) + m[1]; ! 159: } ! 160: ! 161: UBYTE chipmem_bget(CPTR addr) ! 162: { ! 163: addr -= chipmem_start & chipmem_mask; ! 164: addr &= chipmem_size-1; ! 165: return chipmemory[addr]; ! 166: } ! 167: ! 168: void chipmem_lput(CPTR addr, ULONG l) ! 169: { ! 170: UBYTE *m; ! 171: addr -= chipmem_start & chipmem_mask; ! 172: addr &= chipmem_size-1; ! 173: m = chipmemory + addr; ! 174: m[0] = l >> 24; ! 175: m[1] = l >> 16; ! 176: m[2] = l >> 8; ! 177: m[3] = l; ! 178: } ! 179: ! 180: void chipmem_wput(CPTR addr, UWORD w) ! 181: { ! 182: UBYTE *m; ! 183: addr -= chipmem_start & chipmem_mask; ! 184: addr &= chipmem_size-1; ! 185: m = chipmemory + addr; ! 186: m[0] = w >> 8; ! 187: m[1] = w; ! 188: } ! 189: ! 190: void chipmem_bput(CPTR addr, UBYTE b) ! 191: { ! 192: addr -= chipmem_start & chipmem_mask; ! 193: addr &= chipmem_size-1; ! 194: chipmemory[addr] = b; ! 195: } ! 196: ! 197: int chipmem_check(CPTR addr, ULONG size) ! 198: { ! 199: addr -= chipmem_start & chipmem_mask; ! 200: addr &= chipmem_size-1; ! 201: return (addr + size) < chipmem_size; ! 202: } ! 203: ! 204: UBYTE *chipmem_xlate(CPTR addr) ! 205: { ! 206: addr -= chipmem_start & chipmem_mask; ! 207: addr &= chipmem_size-1; ! 208: return chipmemory + addr; ! 209: } ! 210: ! 211: /* Slow memory */ ! 212: ! 213: static UBYTE *bogomemory; ! 214: ! 215: static ULONG bogomem_alget(CPTR) REGPARAM; ! 216: static UWORD bogomem_awget(CPTR) REGPARAM; ! 217: static ULONG bogomem_lget(CPTR) REGPARAM; ! 218: static UWORD bogomem_wget(CPTR) REGPARAM; ! 219: static UBYTE bogomem_bget(CPTR) REGPARAM; ! 220: static void bogomem_lput(CPTR, ULONG) REGPARAM; ! 221: static void bogomem_wput(CPTR, UWORD) REGPARAM; ! 222: static void bogomem_bput(CPTR, UBYTE) REGPARAM; ! 223: static int bogomem_check(CPTR addr, ULONG size) REGPARAM; ! 224: static UBYTE *bogomem_xlate(CPTR addr) REGPARAM; ! 225: ! 226: ULONG bogomem_alget(CPTR addr) ! 227: { ! 228: UBYTE *m; ! 229: addr -= bogomem_start & bogomem_mask; ! 230: addr &= bogomem_size-1; ! 231: m = bogomemory + addr; ! 232: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) ! 233: + ((ULONG)m[2] << 8) + ((ULONG)m[3])); ! 234: } ! 235: ! 236: UWORD bogomem_awget(CPTR addr) ! 237: { ! 238: UBYTE *m; ! 239: addr -= bogomem_start & bogomem_mask; ! 240: addr &= bogomem_size-1; ! 241: m = bogomemory + addr; ! 242: return ((UWORD)m[0] << 8) + m[1]; ! 243: } ! 244: ! 245: ULONG bogomem_lget(CPTR addr) ! 246: { ! 247: UBYTE *m; ! 248: addr -= bogomem_start & bogomem_mask; ! 249: addr &= bogomem_size-1; ! 250: m = bogomemory + addr; ! 251: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) ! 252: + ((ULONG)m[2] << 8) + ((ULONG)m[3])); ! 253: } ! 254: ! 255: UWORD bogomem_wget(CPTR addr) ! 256: { ! 257: UBYTE *m; ! 258: addr -= bogomem_start & bogomem_mask; ! 259: addr &= bogomem_size-1; ! 260: m = bogomemory + addr; ! 261: return ((UWORD)m[0] << 8) + m[1]; ! 262: } ! 263: ! 264: UBYTE bogomem_bget(CPTR addr) ! 265: { ! 266: addr -= bogomem_start & bogomem_mask; ! 267: addr &= bogomem_size-1; ! 268: return bogomemory[addr]; ! 269: } ! 270: ! 271: void bogomem_lput(CPTR addr, ULONG l) ! 272: { ! 273: UBYTE *m; ! 274: addr -= bogomem_start & bogomem_mask; ! 275: addr &= bogomem_size-1; ! 276: m = bogomemory + addr; ! 277: m[0] = l >> 24; ! 278: m[1] = l >> 16; ! 279: m[2] = l >> 8; ! 280: m[3] = l; ! 281: } ! 282: ! 283: void bogomem_wput(CPTR addr, UWORD w) ! 284: { ! 285: UBYTE *m; ! 286: addr -= bogomem_start & bogomem_mask; ! 287: addr &= bogomem_size-1; ! 288: m = bogomemory + addr; ! 289: m[0] = w >> 8; ! 290: m[1] = w; ! 291: } ! 292: ! 293: void bogomem_bput(CPTR addr, UBYTE b) ! 294: { ! 295: addr -= bogomem_start & bogomem_mask; ! 296: addr &= bogomem_size-1; ! 297: bogomemory[addr] = b; ! 298: } ! 299: ! 300: int bogomem_check(CPTR addr, ULONG size) ! 301: { ! 302: addr -= bogomem_start & (bogomem_size-1); ! 303: addr &= bogomem_size-1; ! 304: return (addr + size) < bogomem_size; ! 305: } ! 306: ! 307: UBYTE *bogomem_xlate(CPTR addr) ! 308: { ! 309: addr -= bogomem_start & (bogomem_size-1); ! 310: addr &= bogomem_size-1; ! 311: return bogomemory + addr; ! 312: } ! 313: ! 314: /* Kick memory */ ! 315: ! 316: static int zkickfile = 0; ! 317: UBYTE *kickmemory; ! 318: ! 319: static ULONG kickmem_alget(CPTR) REGPARAM; ! 320: static UWORD kickmem_awget(CPTR) REGPARAM; ! 321: static ULONG kickmem_lget(CPTR) REGPARAM; ! 322: static UWORD kickmem_wget(CPTR) REGPARAM; ! 323: static UBYTE kickmem_bget(CPTR) REGPARAM; ! 324: static void kickmem_lput(CPTR, ULONG) REGPARAM; ! 325: static void kickmem_wput(CPTR, UWORD) REGPARAM; ! 326: static void kickmem_bput(CPTR, UBYTE) REGPARAM; ! 327: static int kickmem_check(CPTR addr, ULONG size) REGPARAM; ! 328: static UBYTE *kickmem_xlate(CPTR addr) REGPARAM; ! 329: ! 330: ULONG kickmem_alget(CPTR addr) ! 331: { ! 332: UBYTE *m; ! 333: addr -= kickmem_start & kickmem_mask; ! 334: addr &= kickmem_size-1; ! 335: m = kickmemory + addr; ! 336: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) ! 337: + ((ULONG)m[2] << 8) + ((ULONG)m[3])); ! 338: } ! 339: ! 340: UWORD kickmem_awget(CPTR addr) ! 341: { ! 342: UBYTE *m; ! 343: addr -= kickmem_start & kickmem_mask; ! 344: addr &= kickmem_size-1; ! 345: m = kickmemory + addr; ! 346: return ((UWORD)m[0] << 8) + m[1]; ! 347: } ! 348: ! 349: ULONG kickmem_lget(CPTR addr) ! 350: { ! 351: UBYTE *m; ! 352: addr -= kickmem_start & kickmem_mask; ! 353: addr &= kickmem_size-1; ! 354: m = kickmemory + addr; ! 355: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) ! 356: + ((ULONG)m[2] << 8) + ((ULONG)m[3])); ! 357: } ! 358: ! 359: UWORD kickmem_wget(CPTR addr) ! 360: { ! 361: UBYTE *m; ! 362: addr -= kickmem_start & kickmem_mask; ! 363: addr &= kickmem_size-1; ! 364: m = kickmemory + addr; ! 365: return ((UWORD)m[0] << 8) + m[1]; ! 366: } ! 367: ! 368: UBYTE kickmem_bget(CPTR addr) ! 369: { ! 370: addr -= kickmem_start & kickmem_mask; ! 371: addr &= kickmem_size-1; ! 372: return kickmemory[addr]; ! 373: } ! 374: ! 375: void kickmem_lput(CPTR addr, ULONG b) ! 376: { ! 377: if (illegal_mem) printf("Illegal kickmem lput at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 378: } ! 379: ! 380: void kickmem_wput(CPTR addr, UWORD b) ! 381: { ! 382: if (illegal_mem) printf("Illegal kickmem wput at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 383: } ! 384: ! 385: void kickmem_bput(CPTR addr, UBYTE b) ! 386: { ! 387: if (illegal_mem) printf("Illegal kickmem lput at %08lx pc=%08lx\n",addr,m68k_getpc()); ! 388: } ! 389: ! 390: int kickmem_check(CPTR addr, ULONG size) ! 391: { ! 392: addr -= kickmem_start & (kickmem_size-1); ! 393: addr &= kickmem_size-1; ! 394: return (addr + size) < kickmem_size; ! 395: } ! 396: ! 397: UBYTE *kickmem_xlate(CPTR addr) ! 398: { ! 399: addr -= kickmem_start & (kickmem_size-1); ! 400: addr &= kickmem_size-1; ! 401: return kickmemory + addr; ! 402: } ! 403: ! 404: static int load_kickstart(void) ! 405: { ! 406: int i; ! 407: ULONG cksum = 0, prevck = 0; ! 408: unsigned char buffer[8]; ! 409: ! 410: FILE *f = zfile_open(romfile, "rb"); ! 411: ! 412: if (f == NULL) { ! 413: fprintf(stderr, "No Kickstart ROM found.\n"); ! 414: return 0; ! 415: } ! 416: ! 417: fread(buffer, 1, 8, f); ! 418: if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) { ! 419: fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n"); ! 420: zkickfile = 1; ! 421: } else ! 422: fseek(f, 0, SEEK_SET); ! 423: ! 424: i = fread(kickmemory, 1, kickmem_size, f); ! 425: if (i == kickmem_size/2) { ! 426: fprintf(stderr, "Warning: Kickstart is only 256K.\n"); ! 427: memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2); ! 428: } else if (i != kickmem_size) { ! 429: fprintf(stderr, "Error while reading Kickstart.\n"); ! 430: return 0; ! 431: } ! 432: zfile_close (f); ! 433: ! 434: for (i = 0; i < kickmem_size; i+=4) { ! 435: ULONG data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3]; ! 436: cksum += data; ! 437: if (cksum < prevck) ! 438: cksum++; ! 439: prevck = cksum; ! 440: } ! 441: if (cksum != 0xFFFFFFFF) { ! 442: fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n"); ! 443: } ! 444: return 1; ! 445: } ! 446: ! 447: /* Address banks */ ! 448: ! 449: addrbank dummy_bank = { ! 450: default_alget, default_awget, ! 451: dummy_lget, dummy_wget, dummy_bget, ! 452: dummy_lput, dummy_wput, dummy_bput, ! 453: default_xlate, dummy_check ! 454: }; ! 455: ! 456: addrbank chipmem_bank = { ! 457: chipmem_alget, chipmem_awget, ! 458: chipmem_lget, chipmem_wget, chipmem_bget, ! 459: chipmem_lput, chipmem_wput, chipmem_bput, ! 460: chipmem_xlate, chipmem_check ! 461: }; ! 462: ! 463: addrbank bogomem_bank = { ! 464: bogomem_alget, bogomem_awget, ! 465: bogomem_lget, bogomem_wget, bogomem_bget, ! 466: bogomem_lput, bogomem_wput, bogomem_bput, ! 467: bogomem_xlate, bogomem_check ! 468: }; ! 469: ! 470: addrbank kickmem_bank = { ! 471: kickmem_alget, kickmem_awget, ! 472: kickmem_lget, kickmem_wget, kickmem_bget, ! 473: kickmem_lput, kickmem_wput, kickmem_bput, ! 474: kickmem_xlate, kickmem_check ! 475: }; ! 476: ! 477: char *address_space, *good_address_map; ! 478: int good_address_fd; ! 479: ! 480: void memory_init(void) ! 481: { ! 482: char buffer[4096]; ! 483: char *nam; ! 484: int i, fd; ! 485: buserr = 0; ! 486: ! 487: chipmem_mask = chipmem_size - 1; ! 488: kickmem_mask = kickmem_size - 1; ! 489: bogomem_mask = bogomem_size - 1; ! 490: ! 491: #ifdef USE_COMPILER ! 492: fd = open("/dev/zero", O_RDWR); ! 493: good_address_map = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0); ! 494: address_space = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0); ! 495: chipmemory = mmap(address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0); ! 496: kickmemory = mmap(address_space + 0xF80000, 0x80000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0); ! 497: ! 498: close(fd); ! 499: ! 500: good_address_fd = open(nam = tmpnam(NULL), O_CREAT|O_RDWR, 0600); ! 501: memset(buffer,1,sizeof(buffer)); ! 502: write(good_address_fd, buffer,sizeof(buffer)); ! 503: unlink(nam); ! 504: ! 505: for (i = 0; i < chipmem_size; i += 4096) ! 506: mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, ! 507: good_address_fd, 0); ! 508: for (i = 0; i < kickmem_size; i += 4096) ! 509: mmap(good_address_map + i + 0x1000000 - kickmem_size, 4096, PROT_READ, ! 510: MAP_FIXED | MAP_PRIVATE, good_address_fd, 0); ! 511: #else ! 512: chipmemory = (UBYTE *)malloc(chipmem_size); ! 513: kickmemory = (UBYTE *)malloc(kickmem_size); ! 514: #endif ! 515: ! 516: for(i = 0; i < 65536; i++) ! 517: membanks[i] = dummy_bank; ! 518: ! 519: /* Map the chipmem into all of the lower 16MB */ ! 520: map_banks(&chipmem_bank, 0x00, 256); ! 521: map_banks(&custom_bank, 0xC0, 0x20); ! 522: map_banks(&cia_bank, 0xA0, 32); ! 523: map_banks(&clock_bank, 0xDC, 1); ! 524: ! 525: if (bogomem_size > 0) { ! 526: bogomemory = (UBYTE *)malloc(bogomem_size); ! 527: map_banks(&bogomem_bank, 0xC0, bogomem_size >> 16); ! 528: } ! 529: ! 530: map_banks(&rtarea_bank, 0xF0, 1); ! 531: if (!load_kickstart()) { ! 532: init_ersatz_rom(kickmemory); ! 533: ersatzkickfile = 1; ! 534: } ! 535: if (zkickfile) ! 536: map_banks(&kickmem_bank, 0x20, 8); ! 537: ! 538: map_banks(&kickmem_bank, 0xF8, 8); ! 539: if (!zkickfile) ! 540: map_banks(&expamem_bank, 0xE8, 1); ! 541: } ! 542: ! 543: void map_banks(addrbank *bank, int start, int size) ! 544: { ! 545: int bnr; ! 546: int hioffs = 0; ! 547: #if 0 && CPU_LEVEL < 2 ! 548: for (hioffs = 0; hioffs < 256; hioffs++) ! 549: #endif ! 550: for (bnr = start; bnr < start+size; bnr++) ! 551: membanks[bnr + hioffs * 256] = *bank; ! 552: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.