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