|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator - CPU core ! 3: * ! 4: * Memory management ! 5: * ! 6: * (c) 1995 Bernd Schmidt ! 7: * ! 8: * Adaptation to Hatari by Thomas Huth ! 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. ! 12: */ ! 13: static char rcsid[] = "Hatari $Id: memory.c,v 1.12 2003/04/05 22:25:03 thothy Exp $"; ! 14: ! 15: #include "sysdeps.h" ! 16: #include "hatari-glue.h" ! 17: #include "maccess.h" ! 18: #include "memory.h" ! 19: #include "../hardware/main.h" ! 20: #include "../hardware/reset.h" ! 21: #include "../hardware/decode.h" ! 22: #include "../hardware/m68000.h" ! 23: #include "newcpu.h" ! 24: ! 25: ! 26: uae_u32 STmem_size; ! 27: ! 28: #define STmem_start 0x00000000 ! 29: ! 30: #define STmem_mask 0x00ffffff ! 31: ! 32: ! 33: #ifdef SAVE_MEMORY_BANKS ! 34: addrbank *mem_banks[65536]; ! 35: #else ! 36: addrbank mem_banks[65536]; ! 37: #endif ! 38: ! 39: #ifdef NO_INLINE_MEMORY_ACCESS ! 40: __inline__ uae_u32 longget (uaecptr addr) ! 41: { ! 42: return call_mem_get_func (get_mem_bank (addr).lget, addr); ! 43: } ! 44: __inline__ uae_u32 wordget (uaecptr addr) ! 45: { ! 46: return call_mem_get_func (get_mem_bank (addr).wget, addr); ! 47: } ! 48: __inline__ uae_u32 byteget (uaecptr addr) ! 49: { ! 50: return call_mem_get_func (get_mem_bank (addr).bget, addr); ! 51: } ! 52: __inline__ void longput (uaecptr addr, uae_u32 l) ! 53: { ! 54: call_mem_put_func (get_mem_bank (addr).lput, addr, l); ! 55: } ! 56: __inline__ void wordput (uaecptr addr, uae_u32 w) ! 57: { ! 58: call_mem_put_func (get_mem_bank (addr).wput, addr, w); ! 59: } ! 60: __inline__ void byteput (uaecptr addr, uae_u32 b) ! 61: { ! 62: call_mem_put_func (get_mem_bank (addr).bput, addr, b); ! 63: } ! 64: #endif ! 65: ! 66: ! 67: /* Some prototypes: */ ! 68: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM; ! 69: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM; ! 70: ! 71: ! 72: /* A dummy bank that only contains zeros */ ! 73: ! 74: static uae_u32 dummy_lget (uaecptr) REGPARAM; ! 75: static uae_u32 dummy_wget (uaecptr) REGPARAM; ! 76: static uae_u32 dummy_bget (uaecptr) REGPARAM; ! 77: static void dummy_lput (uaecptr, uae_u32) REGPARAM; ! 78: static void dummy_wput (uaecptr, uae_u32) REGPARAM; ! 79: static void dummy_bput (uaecptr, uae_u32) REGPARAM; ! 80: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM; ! 81: ! 82: uae_u32 REGPARAM2 dummy_lget (uaecptr addr) ! 83: { ! 84: if (illegal_mem) ! 85: write_log ("Illegal lget at %08lx\n", (long)addr); ! 86: ! 87: return 0; ! 88: } ! 89: ! 90: uae_u32 REGPARAM2 dummy_wget (uaecptr addr) ! 91: { ! 92: if (illegal_mem) ! 93: write_log ("Illegal wget at %08lx\n", (long)addr); ! 94: ! 95: return 0; ! 96: } ! 97: ! 98: uae_u32 REGPARAM2 dummy_bget (uaecptr addr) ! 99: { ! 100: if (illegal_mem) ! 101: write_log ("Illegal bget at %08lx\n", (long)addr); ! 102: ! 103: return 0; ! 104: } ! 105: ! 106: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) ! 107: { ! 108: if (illegal_mem) ! 109: write_log ("Illegal lput at %08lx\n", (long)addr); ! 110: } ! 111: ! 112: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w) ! 113: { ! 114: if (illegal_mem) ! 115: write_log ("Illegal wput at %08lx\n", (long)addr); ! 116: } ! 117: ! 118: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b) ! 119: { ! 120: if (illegal_mem) ! 121: write_log ("Illegal bput at %08lx\n", (long)addr); ! 122: } ! 123: ! 124: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size) ! 125: { ! 126: if (illegal_mem) ! 127: write_log ("Illegal check at %08lx\n", (long)addr); ! 128: ! 129: return 0; ! 130: } ! 131: ! 132: uae_u8 REGPARAM2 *dummy_xlate (uaecptr addr) ! 133: { ! 134: write_log("Your Atari program just did something terribly stupid:" ! 135: " dummy_xlate($%x)\n", addr); ! 136: /*Reset_Warm();*/ ! 137: return STmem_xlate(addr); /* So we don't crash. */ ! 138: } ! 139: ! 140: ! 141: /* **** This memory bank only generates bus errors **** */ ! 142: ! 143: uae_u32 REGPARAM2 BusErrMem_lget(uaecptr addr) ! 144: { ! 145: if (illegal_mem) ! 146: write_log ("Bus error lget at %08lx\n", (long)addr); ! 147: ! 148: M68000_Crash (2); ! 149: return 0; ! 150: } ! 151: ! 152: uae_u32 REGPARAM2 BusErrMem_wget(uaecptr addr) ! 153: { ! 154: if (illegal_mem) ! 155: write_log ("Bus error wget at %08lx\n", (long)addr); ! 156: ! 157: M68000_Crash (2); ! 158: return 0; ! 159: } ! 160: ! 161: uae_u32 REGPARAM2 BusErrMem_bget(uaecptr addr) ! 162: { ! 163: if (illegal_mem) ! 164: write_log ("Bus error bget at %08lx\n", (long)addr); ! 165: ! 166: M68000_Crash (2); ! 167: return 0; ! 168: } ! 169: ! 170: void REGPARAM2 BusErrMem_lput(uaecptr addr, uae_u32 l) ! 171: { ! 172: if (illegal_mem) ! 173: write_log ("Bus error lput at %08lx\n", (long)addr); ! 174: ! 175: M68000_Crash (2); ! 176: } ! 177: ! 178: void REGPARAM2 BusErrMem_wput(uaecptr addr, uae_u32 w) ! 179: { ! 180: if (illegal_mem) ! 181: write_log ("Bus error wput at %08lx\n", (long)addr); ! 182: ! 183: M68000_Crash (2); ! 184: } ! 185: ! 186: void REGPARAM2 BusErrMem_bput(uaecptr addr, uae_u32 b) ! 187: { ! 188: if (illegal_mem) ! 189: write_log ("Bus error bput at %08lx\n", (long)addr); ! 190: ! 191: M68000_Crash (2); ! 192: } ! 193: ! 194: int REGPARAM2 BusErrMem_check(uaecptr addr, uae_u32 size) ! 195: { ! 196: if (illegal_mem) ! 197: write_log ("Bus error check at %08lx\n", (long)addr); ! 198: ! 199: return 0; ! 200: } ! 201: ! 202: uae_u8 REGPARAM2 *BusErrMem_xlate (uaecptr addr) ! 203: { ! 204: write_log("Your Atari program just did something terribly stupid:" ! 205: " BusErrMem_xlate($%x)\n", addr); ! 206: ! 207: /*M68000_Crash (2);*/ ! 208: return STmem_xlate(addr); /* So we don't crash. */ ! 209: } ! 210: ! 211: ! 212: /* **** ST RAM memory **** */ ! 213: ! 214: uae_u8 *STmemory; ! 215: ! 216: uae_u32 REGPARAM2 STmem_lget (uaecptr addr) ! 217: { ! 218: uae_u32 *m; ! 219: ! 220: addr -= STmem_start & STmem_mask; ! 221: addr &= STmem_mask; ! 222: m = (uae_u32 *)(STmemory + addr); ! 223: return do_get_mem_long (m); ! 224: } ! 225: ! 226: uae_u32 REGPARAM2 STmem_wget (uaecptr addr) ! 227: { ! 228: uae_u16 *m; ! 229: ! 230: addr -= STmem_start & STmem_mask; ! 231: addr &= STmem_mask; ! 232: m = (uae_u16 *)(STmemory + addr); ! 233: return do_get_mem_word (m); ! 234: } ! 235: ! 236: uae_u32 REGPARAM2 STmem_bget (uaecptr addr) ! 237: { ! 238: addr -= STmem_start & STmem_mask; ! 239: addr &= STmem_mask; ! 240: return STmemory[addr]; ! 241: } ! 242: ! 243: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l) ! 244: { ! 245: uae_u32 *m; ! 246: ! 247: addr -= STmem_start & STmem_mask; ! 248: addr &= STmem_mask; ! 249: m = (uae_u32 *)(STmemory + addr); ! 250: do_put_mem_long (m, l); ! 251: } ! 252: ! 253: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w) ! 254: { ! 255: uae_u16 *m; ! 256: ! 257: addr -= STmem_start & STmem_mask; ! 258: addr &= STmem_mask; ! 259: m = (uae_u16 *)(STmemory + addr); ! 260: do_put_mem_word (m, w); ! 261: } ! 262: ! 263: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b) ! 264: { ! 265: addr -= STmem_start & STmem_mask; ! 266: addr &= STmem_mask; ! 267: STmemory[addr] = b; ! 268: } ! 269: ! 270: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size) ! 271: { ! 272: addr -= STmem_start & STmem_mask; ! 273: addr &= STmem_mask; ! 274: return (addr + size) <= STmem_size; ! 275: } ! 276: ! 277: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr) ! 278: { ! 279: addr -= STmem_start & STmem_mask; ! 280: addr &= STmem_mask; ! 281: return STmemory + addr; ! 282: } ! 283: ! 284: ! 285: /* ! 286: * **** ST RAM system memory **** ! 287: * We need a separate mem bank for this region since the first 0x800 bytes on ! 288: * the ST can only be accessed in supervisor mode. Note that the very first ! 289: * 8 bytes of the ST memory are also a mirror of the TOS ROM, so they are write ! 290: * protected! ! 291: */ ! 292: uae_u32 REGPARAM2 SysMem_lget(uaecptr addr) ! 293: { ! 294: uae_u32 *m; ! 295: ! 296: addr -= STmem_start & STmem_mask; ! 297: addr &= STmem_mask; ! 298: m = (uae_u32 *)(STmemory + addr); ! 299: return do_get_mem_long (m); ! 300: } ! 301: ! 302: uae_u32 REGPARAM2 SysMem_wget(uaecptr addr) ! 303: { ! 304: uae_u16 *m; ! 305: ! 306: addr -= STmem_start & STmem_mask; ! 307: addr &= STmem_mask; ! 308: m = (uae_u16 *)(STmemory + addr); ! 309: return do_get_mem_word (m); ! 310: } ! 311: ! 312: uae_u32 REGPARAM2 SysMem_bget(uaecptr addr) ! 313: { ! 314: addr -= STmem_start & STmem_mask; ! 315: addr &= STmem_mask; ! 316: return STmemory[addr]; ! 317: } ! 318: ! 319: void REGPARAM2 SysMem_lput(uaecptr addr, uae_u32 l) ! 320: { ! 321: uae_u32 *m; ! 322: ! 323: addr -= STmem_start & STmem_mask; ! 324: addr &= STmem_mask; ! 325: m = (uae_u32 *)(STmemory + addr); ! 326: do_put_mem_long (m, l); ! 327: } ! 328: ! 329: void REGPARAM2 SysMem_wput(uaecptr addr, uae_u32 w) ! 330: { ! 331: uae_u16 *m; ! 332: ! 333: addr -= STmem_start & STmem_mask; ! 334: addr &= STmem_mask; ! 335: m = (uae_u16 *)(STmemory + addr); ! 336: do_put_mem_word (m, w); ! 337: } ! 338: ! 339: void REGPARAM2 SysMem_bput(uaecptr addr, uae_u32 b) ! 340: { ! 341: addr -= STmem_start & STmem_mask; ! 342: addr &= STmem_mask; ! 343: STmemory[addr] = b; ! 344: } ! 345: ! 346: ! 347: /* ! 348: * **** Void memory **** ! 349: * Between the ST-RAM end and the 4 MB barrier, there is a void memory space: ! 350: * Reading always returns the same value and writing does nothing at all. ! 351: */ ! 352: ! 353: uae_u32 REGPARAM2 VoidMem_lget(uaecptr addr) ! 354: { ! 355: return 0; ! 356: } ! 357: ! 358: uae_u32 REGPARAM2 VoidMem_wget(uaecptr addr) ! 359: { ! 360: return 0; ! 361: } ! 362: ! 363: uae_u32 REGPARAM2 VoidMem_bget(uaecptr addr) ! 364: { ! 365: return 0; ! 366: } ! 367: ! 368: void REGPARAM2 VoidMem_lput(uaecptr addr, uae_u32 l) ! 369: { ! 370: } ! 371: ! 372: void REGPARAM2 VoidMem_wput(uaecptr addr, uae_u32 w) ! 373: { ! 374: } ! 375: ! 376: void REGPARAM2 VoidMem_bput (uaecptr addr, uae_u32 b) ! 377: { ! 378: } ! 379: ! 380: int REGPARAM2 VoidMem_check(uaecptr addr, uae_u32 size) ! 381: { ! 382: if (illegal_mem) ! 383: write_log ("Void memory check at %08lx\n", (long)addr); ! 384: ! 385: return 0; ! 386: } ! 387: ! 388: uae_u8 REGPARAM2 *VoidMem_xlate (uaecptr addr) ! 389: { ! 390: write_log("Your Atari program just did something terribly stupid:" ! 391: " VoidMem_xlate($%x)\n", addr); ! 392: ! 393: return STmem_xlate(addr); /* So we don't crash. */ ! 394: } ! 395: ! 396: ! 397: /* **** Address banks **** */ ! 398: ! 399: addrbank dummy_bank = { ! 400: dummy_lget, dummy_wget, dummy_bget, ! 401: dummy_lput, dummy_wput, dummy_bput, ! 402: dummy_xlate, dummy_check ! 403: }; ! 404: ! 405: addrbank BusErrMem_bank = { ! 406: BusErrMem_lget, BusErrMem_wget, BusErrMem_bget, ! 407: BusErrMem_lput, BusErrMem_wput, BusErrMem_bput, ! 408: BusErrMem_xlate, BusErrMem_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 SysMem_bank = { ! 418: SysMem_lget, SysMem_wget, SysMem_bget, ! 419: SysMem_lput, SysMem_wput, SysMem_bput, ! 420: STmem_xlate, STmem_check ! 421: }; ! 422: ! 423: addrbank VoidMem_bank = { ! 424: VoidMem_lget, VoidMem_wget, VoidMem_bget, ! 425: VoidMem_lput, VoidMem_wput, VoidMem_bput, ! 426: VoidMem_xlate, VoidMem_check ! 427: }; ! 428: ! 429: ! 430: char *address_space, *good_address_map; ! 431: int good_address_fd; ! 432: ! 433: ! 434: static void init_mem_banks (void) ! 435: { ! 436: int i; ! 437: for (i = 0; i < 65536; i++) ! 438: put_mem_bank (i<<16, &dummy_bank); ! 439: } ! 440: ! 441: ! 442: /* ! 443: * Initialize the memory banks ! 444: */ ! 445: void memory_init(uae_u32 f_STMemSize, uae_u32 f_TTMemSize, uae_u32 f_RomMemStart) ! 446: { ! 447: STmem_size = (f_STMemSize + 65535) & 0xFFFF0000; ! 448: ! 449: /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n", ! 450: STmem_size, TTmem_size, f_RomMemStart);*/ ! 451: ! 452: STmemory = STRam; ! 453: /* ! 454: while (! STmemory && STmem_size > 512*1024) { ! 455: STmem_size >>= 1; ! 456: STmemory = (uae_u8 *)malloc (STmem_size); ! 457: if (STmemory) ! 458: fprintf (stderr, "Reducing STmem size to %dkb\n", STmem_size >> 10); ! 459: } ! 460: if (! STmemory) { ! 461: write_log ("virtual memory exhausted (STmemory)!\n"); ! 462: abort (); ! 463: } ! 464: */ ! 465: ! 466: init_mem_banks(); ! 467: ! 468: /* Map the ST RAM: */ ! 469: map_banks(&SysMem_bank, 0x00, 1); ! 470: map_banks(&VoidMem_bank, 0x08, 0x38); /* Between STRamEnd and 4MB barrier, there is void space! */ ! 471: map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1); ! 472: ! 473: /* Illegal memory regions cause a bus error on the ST: */ ! 474: map_banks(&BusErrMem_bank, 0x200000 >> 16, 0xbf); /* Everything above 2mb */ ! 475: } ! 476: ! 477: ! 478: /* ! 479: * Uninitialize the memory banks. ! 480: */ ! 481: void memory_uninit (void) ! 482: { ! 483: /* Here, we free allocated memory from memory_init */ ! 484: } ! 485: ! 486: ! 487: void map_banks (addrbank *bank, int start, int size) ! 488: { ! 489: int bnr; ! 490: unsigned long int hioffs = 0, endhioffs = 0x100; ! 491: ! 492: if (start >= 0x100) { ! 493: for (bnr = start; bnr < start + size; bnr++) ! 494: put_mem_bank (bnr << 16, bank); ! 495: return; ! 496: } ! 497: /* Some ROMs apparently require a 24 bit address space... */ ! 498: if (address_space_24) ! 499: endhioffs = 0x10000; ! 500: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) ! 501: for (bnr = start; bnr < start+size; bnr++) ! 502: put_mem_bank ((bnr + hioffs) << 16, bank); ! 503: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.