|
|
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: #include "hatari-glue.h" ! 12: #include "maccess.h" ! 13: #include "memory.h" ! 14: #include "../includes/tos.h" ! 15: /* ! 16: #include "config.h" ! 17: #include "options.h" ! 18: #include "uae.h" ! 19: */ ! 20: #ifdef USE_MAPPED_MEMORY ! 21: #include <sys/mman.h> ! 22: #endif ! 23: ! 24: #include "../includes/intercept.h" ! 25: ! 26: ! 27: extern unsigned char STRam[16*1024*1024]; /* See hatari.c */ ! 28: ! 29: ! 30: /* Set by each memory handler that does not simply access real memory. */ ! 31: int special_mem; ! 32: ! 33: uae_u32 allocated_STmem; ! 34: uae_u32 allocated_TTmem; ! 35: ! 36: uae_u32 STmem_mask, ROMmem_mask, IOmem_mask, TTmem_mask; ! 37: ! 38: ! 39: #ifdef SAVE_MEMORY_BANKS ! 40: addrbank *mem_banks[65536]; ! 41: #else ! 42: addrbank mem_banks[65536]; ! 43: #endif ! 44: ! 45: #ifdef NO_INLINE_MEMORY_ACCESS ! 46: __inline__ uae_u32 longget (uaecptr addr) ! 47: { ! 48: return call_mem_get_func (get_mem_bank (addr).lget, addr); ! 49: } ! 50: __inline__ uae_u32 wordget (uaecptr addr) ! 51: { ! 52: return call_mem_get_func (get_mem_bank (addr).wget, addr); ! 53: } ! 54: __inline__ uae_u32 byteget (uaecptr addr) ! 55: { ! 56: return call_mem_get_func (get_mem_bank (addr).bget, addr); ! 57: } ! 58: __inline__ void longput (uaecptr addr, uae_u32 l) ! 59: { ! 60: call_mem_put_func (get_mem_bank (addr).lput, addr, l); ! 61: } ! 62: __inline__ void wordput (uaecptr addr, uae_u32 w) ! 63: { ! 64: call_mem_put_func (get_mem_bank (addr).wput, addr, w); ! 65: } ! 66: __inline__ void byteput (uaecptr addr, uae_u32 b) ! 67: { ! 68: call_mem_put_func (get_mem_bank (addr).bput, addr, b); ! 69: } ! 70: #endif ! 71: ! 72: ! 73: /* A dummy bank that only contains zeros */ ! 74: ! 75: static uae_u32 dummy_lget (uaecptr) REGPARAM; ! 76: static uae_u32 dummy_wget (uaecptr) REGPARAM; ! 77: static uae_u32 dummy_bget (uaecptr) REGPARAM; ! 78: static void dummy_lput (uaecptr, uae_u32) REGPARAM; ! 79: static void dummy_wput (uaecptr, uae_u32) REGPARAM; ! 80: static void dummy_bput (uaecptr, uae_u32) REGPARAM; ! 81: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM; ! 82: ! 83: uae_u32 REGPARAM2 dummy_lget (uaecptr addr) ! 84: { ! 85: special_mem |= S_READ; ! 86: if (illegal_mem) ! 87: write_log ("Illegal lget at %08lx\n", addr); ! 88: ! 89: return 0; ! 90: } ! 91: ! 92: uae_u32 REGPARAM2 dummy_wget (uaecptr addr) ! 93: { ! 94: special_mem |= S_READ; ! 95: if (illegal_mem) ! 96: write_log ("Illegal wget at %08lx\n", addr); ! 97: ! 98: return 0; ! 99: } ! 100: ! 101: uae_u32 REGPARAM2 dummy_bget (uaecptr addr) ! 102: { ! 103: special_mem |= S_READ; ! 104: if (illegal_mem) ! 105: write_log ("Illegal bget at %08lx\n", addr); ! 106: ! 107: return 0; ! 108: } ! 109: ! 110: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) ! 111: { ! 112: special_mem |= S_WRITE; ! 113: if (illegal_mem) ! 114: write_log ("Illegal lput at %08lx\n", addr); ! 115: } ! 116: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w) ! 117: { ! 118: special_mem |= S_WRITE; ! 119: if (illegal_mem) ! 120: write_log ("Illegal wput at %08lx\n", addr); ! 121: } ! 122: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b) ! 123: { ! 124: special_mem |= S_WRITE; ! 125: if (illegal_mem) ! 126: write_log ("Illegal bput at %08lx\n", addr); ! 127: } ! 128: ! 129: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size) ! 130: { ! 131: if (illegal_mem) ! 132: write_log ("Illegal check at %08lx\n", addr); ! 133: ! 134: return 0; ! 135: } ! 136: ! 137: ! 138: /* ST RAM memory */ ! 139: ! 140: uae_u8 *STmemory; ! 141: ! 142: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM; ! 143: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM; ! 144: ! 145: uae_u32 REGPARAM2 STmem_lget (uaecptr addr) ! 146: { ! 147: uae_u32 *m; ! 148: ! 149: addr -= STmem_start & STmem_mask; ! 150: addr &= STmem_mask; ! 151: m = (uae_u32 *)(STmemory + addr); ! 152: return do_get_mem_long (m); ! 153: } ! 154: ! 155: uae_u32 REGPARAM2 STmem_wget (uaecptr addr) ! 156: { ! 157: uae_u16 *m; ! 158: ! 159: addr -= STmem_start & STmem_mask; ! 160: addr &= STmem_mask; ! 161: m = (uae_u16 *)(STmemory + addr); ! 162: return do_get_mem_word (m); ! 163: } ! 164: ! 165: uae_u32 REGPARAM2 STmem_bget (uaecptr addr) ! 166: { ! 167: addr -= STmem_start & STmem_mask; ! 168: addr &= STmem_mask; ! 169: return STmemory[addr]; ! 170: } ! 171: ! 172: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l) ! 173: { ! 174: uae_u32 *m; ! 175: ! 176: addr -= STmem_start & STmem_mask; ! 177: addr &= STmem_mask; ! 178: m = (uae_u32 *)(STmemory + addr); ! 179: do_put_mem_long (m, l); ! 180: } ! 181: ! 182: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w) ! 183: { ! 184: uae_u16 *m; ! 185: ! 186: addr -= STmem_start & STmem_mask; ! 187: addr &= STmem_mask; ! 188: m = (uae_u16 *)(STmemory + addr); ! 189: do_put_mem_word (m, w); ! 190: } ! 191: ! 192: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b) ! 193: { ! 194: addr -= STmem_start & STmem_mask; ! 195: addr &= STmem_mask; ! 196: STmemory[addr] = b; ! 197: } ! 198: ! 199: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size) ! 200: { ! 201: addr -= STmem_start & STmem_mask; ! 202: addr &= STmem_mask; ! 203: return (addr + size) <= allocated_STmem; ! 204: } ! 205: ! 206: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr) ! 207: { ! 208: addr -= STmem_start & STmem_mask; ! 209: addr &= STmem_mask; ! 210: return STmemory + addr; ! 211: } ! 212: ! 213: ! 214: /* TT fast memory */ ! 215: ! 216: static uae_u8 *TTmemory; ! 217: ! 218: static uae_u32 TTmem_lget (uaecptr) REGPARAM; ! 219: static uae_u32 TTmem_wget (uaecptr) REGPARAM; ! 220: static uae_u32 TTmem_bget (uaecptr) REGPARAM; ! 221: static void TTmem_lput (uaecptr, uae_u32) REGPARAM; ! 222: static void TTmem_wput (uaecptr, uae_u32) REGPARAM; ! 223: static void TTmem_bput (uaecptr, uae_u32) REGPARAM; ! 224: static int TTmem_check (uaecptr addr, uae_u32 size) REGPARAM; ! 225: static uae_u8 *TTmem_xlate (uaecptr addr) REGPARAM; ! 226: ! 227: uae_u32 REGPARAM2 TTmem_lget (uaecptr addr) ! 228: { ! 229: uae_u32 *m; ! 230: addr -= TTmem_start & TTmem_mask; ! 231: addr &= TTmem_mask; ! 232: m = (uae_u32 *)(TTmemory + addr); ! 233: return do_get_mem_long (m); ! 234: } ! 235: ! 236: uae_u32 REGPARAM2 TTmem_wget (uaecptr addr) ! 237: { ! 238: uae_u16 *m; ! 239: addr -= TTmem_start & TTmem_mask; ! 240: addr &= TTmem_mask; ! 241: m = (uae_u16 *)(TTmemory + addr); ! 242: return do_get_mem_word (m); ! 243: } ! 244: ! 245: uae_u32 REGPARAM2 TTmem_bget (uaecptr addr) ! 246: { ! 247: addr -= TTmem_start & TTmem_mask; ! 248: addr &= TTmem_mask; ! 249: return TTmemory[addr]; ! 250: } ! 251: ! 252: void REGPARAM2 TTmem_lput (uaecptr addr, uae_u32 l) ! 253: { ! 254: uae_u32 *m; ! 255: addr -= TTmem_start & TTmem_mask; ! 256: addr &= TTmem_mask; ! 257: m = (uae_u32 *)(TTmemory + addr); ! 258: do_put_mem_long (m, l); ! 259: } ! 260: ! 261: void REGPARAM2 TTmem_wput (uaecptr addr, uae_u32 w) ! 262: { ! 263: uae_u16 *m; ! 264: addr -= TTmem_start & TTmem_mask; ! 265: addr &= TTmem_mask; ! 266: m = (uae_u16 *)(TTmemory + addr); ! 267: do_put_mem_word (m, w); ! 268: } ! 269: ! 270: void REGPARAM2 TTmem_bput (uaecptr addr, uae_u32 b) ! 271: { ! 272: addr -= TTmem_start & TTmem_mask; ! 273: addr &= TTmem_mask; ! 274: TTmemory[addr] = b; ! 275: } ! 276: ! 277: int REGPARAM2 TTmem_check (uaecptr addr, uae_u32 size) ! 278: { ! 279: addr -= TTmem_start & TTmem_mask; ! 280: addr &= TTmem_mask; ! 281: return (addr + size) <= allocated_TTmem; ! 282: } ! 283: ! 284: uae_u8 REGPARAM2 *TTmem_xlate(uaecptr addr) ! 285: { ! 286: addr -= TTmem_start & TTmem_mask; ! 287: addr &= TTmem_mask; ! 288: return TTmemory + addr; ! 289: } ! 290: ! 291: /* ROM memory */ ! 292: ! 293: uae_u8 *ROMmemory; ! 294: ! 295: static uae_u32 ROMmem_lget (uaecptr) REGPARAM; ! 296: static uae_u32 ROMmem_wget (uaecptr) REGPARAM; ! 297: static uae_u32 ROMmem_bget (uaecptr) REGPARAM; ! 298: static void ROMmem_lput (uaecptr, uae_u32) REGPARAM; ! 299: static void ROMmem_wput (uaecptr, uae_u32) REGPARAM; ! 300: static void ROMmem_bput (uaecptr, uae_u32) REGPARAM; ! 301: static int ROMmem_check (uaecptr addr, uae_u32 size) REGPARAM; ! 302: static uae_u8 *ROMmem_xlate (uaecptr addr) REGPARAM; ! 303: ! 304: uae_u32 REGPARAM2 ROMmem_lget (uaecptr addr) ! 305: { ! 306: uae_u32 *m; ! 307: addr -= ROMmem_start & ROMmem_mask; ! 308: addr &= ROMmem_mask; ! 309: m = (uae_u32 *)(ROMmemory + addr); ! 310: return do_get_mem_long (m); ! 311: } ! 312: ! 313: uae_u32 REGPARAM2 ROMmem_wget (uaecptr addr) ! 314: { ! 315: uae_u16 *m; ! 316: addr -= ROMmem_start & ROMmem_mask; ! 317: addr &= ROMmem_mask; ! 318: m = (uae_u16 *)(ROMmemory + addr); ! 319: return do_get_mem_word (m); ! 320: } ! 321: ! 322: uae_u32 REGPARAM2 ROMmem_bget (uaecptr addr) ! 323: { ! 324: addr -= ROMmem_start & ROMmem_mask; ! 325: addr &= ROMmem_mask; ! 326: return ROMmemory[addr]; ! 327: } ! 328: ! 329: void REGPARAM2 ROMmem_lput (uaecptr addr, uae_u32 b) ! 330: { ! 331: if (illegal_mem) ! 332: write_log ("Illegal ROMmem lput at %08lx\n", addr); ! 333: } ! 334: ! 335: void REGPARAM2 ROMmem_wput (uaecptr addr, uae_u32 b) ! 336: { ! 337: if (illegal_mem) ! 338: write_log ("Illegal ROMmem wput at %08lx\n", addr); ! 339: } ! 340: ! 341: void REGPARAM2 ROMmem_bput (uaecptr addr, uae_u32 b) ! 342: { ! 343: if (illegal_mem) ! 344: write_log ("Illegal ROMmem lput at %08lx\n", addr); ! 345: } ! 346: ! 347: int REGPARAM2 ROMmem_check (uaecptr addr, uae_u32 size) ! 348: { ! 349: addr -= ROMmem_start & ROMmem_mask; ! 350: addr &= ROMmem_mask; ! 351: return (addr + size) <= ROMmem_size; ! 352: } ! 353: ! 354: uae_u8 REGPARAM2 *ROMmem_xlate (uaecptr addr) ! 355: { ! 356: addr -= ROMmem_start & ROMmem_mask; ! 357: addr &= ROMmem_mask; ! 358: return ROMmemory + addr; ! 359: } ! 360: ! 361: ! 362: /* Hardware IO memory */ ! 363: /* see also intercept.c */ ! 364: ! 365: uae_u8 *IOmemory; ! 366: ! 367: static int IOmem_check (uaecptr addr, uae_u32 size) REGPARAM; ! 368: static uae_u8 *IOmem_xlate (uaecptr addr) REGPARAM; ! 369: ! 370: int REGPARAM2 IOmem_check (uaecptr addr, uae_u32 size) ! 371: { ! 372: addr -= IOmem_start & IOmem_mask; ! 373: addr &= IOmem_mask; ! 374: return (addr + size) <= IOmem_size; ! 375: } ! 376: ! 377: uae_u8 REGPARAM2 *IOmem_xlate (uaecptr addr) ! 378: { ! 379: addr -= IOmem_start & IOmem_mask; ! 380: addr &= IOmem_mask; ! 381: return IOmemory + addr; ! 382: } ! 383: ! 384: ! 385: ! 386: /* Default memory access functions */ ! 387: ! 388: int REGPARAM2 default_check (uaecptr a, uae_u32 b) ! 389: { ! 390: return 0; ! 391: } ! 392: ! 393: uae_u8 REGPARAM2 *default_xlate (uaecptr a) ! 394: { ! 395: write_log ("Your Atari program just did something terribly stupid\n"); ! 396: Reset_Warm(); ! 397: return ROMmem_xlate (get_long (0xFC0000)); /* So we don't crash. */ ! 398: } ! 399: ! 400: ! 401: /* Address banks */ ! 402: ! 403: addrbank dummy_bank = { ! 404: dummy_lget, dummy_wget, dummy_bget, ! 405: dummy_lput, dummy_wput, dummy_bput, ! 406: default_xlate, dummy_check ! 407: }; ! 408: ! 409: addrbank STmem_bank = { ! 410: STmem_lget, STmem_wget, STmem_bget, ! 411: STmem_lput, STmem_wput, STmem_bput, ! 412: STmem_xlate, STmem_check ! 413: }; ! 414: ! 415: addrbank TTmem_bank = { ! 416: TTmem_lget, TTmem_wget, TTmem_bget, ! 417: TTmem_lput, TTmem_wput, TTmem_bput, ! 418: TTmem_xlate, TTmem_check ! 419: }; ! 420: ! 421: addrbank ROMmem_bank = { ! 422: ROMmem_lget, ROMmem_wget, ROMmem_bget, ! 423: ROMmem_lput, ROMmem_wput, ROMmem_bput, ! 424: ROMmem_xlate, ROMmem_check ! 425: }; ! 426: ! 427: addrbank IOmem_bank = { ! 428: Intercept_ReadLong, Intercept_ReadWord, Intercept_ReadByte, ! 429: Intercept_WriteLong, Intercept_WriteWord, Intercept_WriteByte, ! 430: IOmem_xlate, IOmem_check ! 431: }; ! 432: ! 433: ! 434: char *address_space, *good_address_map; ! 435: int good_address_fd; ! 436: ! 437: static void init_mem_banks (void) ! 438: { ! 439: int i; ! 440: for (i = 0; i < 65536; i++) ! 441: put_mem_bank (i<<16, &dummy_bank); ! 442: } ! 443: ! 444: #define MAKE_USER_PROGRAMS_BEHAVE 1 ! 445: void memory_init (void) ! 446: { ! 447: char buffer[4096]; ! 448: char *nam; ! 449: int i, fd; ! 450: /*int custom_start;*/ ! 451: ! 452: allocated_STmem = STmem_size; ! 453: allocated_TTmem = TTmem_size; ! 454: ! 455: #ifdef USE_MAPPED_MEMORY ! 456: #error So nicht ! 457: fd = open ("/dev/zero", O_RDWR); ! 458: good_address_map = mmap (NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0); ! 459: /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon ! 460: * as a decrunch routine tries to do color register hacks. */ ! 461: address_space = mmap (NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0); ! 462: if ((int)address_space < 0 || (int)good_address_map < 0) { ! 463: write_log ("Your system does not have enough virtual memory - increase swap.\n"); ! 464: abort (); ! 465: } ! 466: #ifdef MAKE_USER_PROGRAMS_BEHAVE ! 467: memset (address_space + 0xDFF180, 0xFF, 32*2); ! 468: #else ! 469: /* Likewise. This is mostly for mouse button checks. */ ! 470: if (USER_PROGRAMS_BEHAVE) ! 471: memset (address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000); ! 472: #endif ! 473: STmemory = mmap (address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0); ! 474: ROMmemory = mmap (address_space + TOSAddress, ROMmem_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0); ! 475: ! 476: close(fd); ! 477: ! 478: good_address_fd = open (nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600); ! 479: memset (buffer, 1, sizeof(buffer)); ! 480: write (good_address_fd, buffer, sizeof buffer); ! 481: unlink (nam); ! 482: ! 483: for (i = 0; i < allocated_STmem; i += 4096) ! 484: mmap (good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, ! 485: good_address_fd, 0); ! 486: for (i = 0; i < ROMmem_size; i += 4096) ! 487: mmap (good_address_map + i + 0x1000000 - ROMmem_size, 4096, PROT_READ, ! 488: MAP_FIXED | MAP_PRIVATE, good_address_fd, 0); ! 489: #else ! 490: ROMmemory = STRam+TOSAddress; /*(uae_u8 *)malloc (ROMmem_size)*/; ! 491: STmemory = STRam; /*(uae_u8 *)malloc (allocated_STmem);*/ ! 492: /* ! 493: while (! STmemory && allocated_STmem > 512*1024) { ! 494: allocated_STmem >>= 1; ! 495: STmemory = (uae_u8 *)malloc (allocated_STmem); ! 496: if (STmemory) ! 497: fprintf (stderr, "Reducing STmem size to %dkb\n", allocated_STmem >> 10); ! 498: } ! 499: if (! STmemory) { ! 500: write_log ("virtual memory exhausted (STmemory)!\n"); ! 501: abort (); ! 502: } ! 503: */ ! 504: #endif ! 505: ! 506: do_put_mem_long ((uae_u32 *)(STmemory), do_get_mem_long((uae_u32 *)ROMmemory)); ! 507: do_put_mem_long ((uae_u32 *)(STmemory + 4), do_get_mem_long((uae_u32 *)(ROMmemory+4))); ! 508: init_mem_banks (); ! 509: ! 510: /* Map the STmem into all of the lower 16MB */ ! 511: map_banks (&STmem_bank, 0x00, 256); ! 512: /* ! 513: custom_start = 0xC0; ! 514: map_banks (&custom_bank, custom_start, 0xE0-custom_start); ! 515: map_banks (&cia_bank, 0xA0, 32); ! 516: map_banks (&clock_bank, 0xDC, 1); ! 517: */ ! 518: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000 ! 519: * range on an Amiga without expansion memory? */ ! 520: /* ! 521: custom_start = allocated_STmem >> 16; ! 522: if (custom_start < 0x20) ! 523: custom_start = 0x20; ! 524: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start); ! 525: */ ! 526: /*map_banks (&TTram_bank, 0xDE, 1);*/ ! 527: ! 528: if (allocated_TTmem > 0) ! 529: TTmemory = (uae_u8 *)malloc (allocated_TTmem); ! 530: if (TTmemory != 0) ! 531: map_banks (&TTmem_bank, TTmem_start >> 16, allocated_TTmem >> 16); ! 532: else ! 533: allocated_TTmem = 0; ! 534: ! 535: map_banks(&ROMmem_bank, ROMmem_start >> 16, ROMmem_size/65536); ! 536: /* map_banks(&ROMmem_bank, 0xFFFC, 4);*/ ! 537: ! 538: map_banks(&IOmem_bank, IOmem_start>>16, 1); ! 539: ! 540: STmem_mask = 0x00ffffff /*allocated_STmem- 1*/; ! 541: ROMmem_mask = 0x00ffffff /*ROMmem_size - 1*/; ! 542: TTmem_mask = allocated_TTmem - 1; ! 543: IOmem_mask = IOmem_size - 1; ! 544: } ! 545: ! 546: void map_banks (addrbank *bank, int start, int size) ! 547: { ! 548: int bnr; ! 549: unsigned long int hioffs = 0, endhioffs = 0x100; ! 550: ! 551: if (start >= 0x100) { ! 552: for (bnr = start; bnr < start + size; bnr++) ! 553: put_mem_bank (bnr << 16, bank); ! 554: return; ! 555: } ! 556: /* Some ROMs apparently require a 24 bit address space... */ ! 557: if (address_space_24) ! 558: endhioffs = 0x10000; ! 559: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) ! 560: for (bnr = start; bnr < start+size; bnr++) ! 561: put_mem_bank ((bnr + hioffs) << 16, bank); ! 562: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.