|
|
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 <stdio.h> ! 10: #include <string.h> ! 11: ! 12: #include "config.h" ! 13: #include "amiga.h" ! 14: #include "options.h" ! 15: #include "memory.h" ! 16: #include "custom.h" ! 17: #include "cia.h" ! 18: #include "ersatz.h" ! 19: ! 20: bool buserr; ! 21: ! 22: const char romfile[] = "kick.rom"; ! 23: ! 24: lget_func do_lget[256]; ! 25: wget_func do_wget[256]; ! 26: bget_func do_bget[256]; ! 27: lput_func do_lput[256]; ! 28: wput_func do_wput[256]; ! 29: bput_func do_bput[256]; ! 30: xlate_func do_xlateaddr[256]; ! 31: check_func do_check[256]; ! 32: ! 33: /* Default memory access functions */ ! 34: ! 35: bool default_check(CPTR a, ULONG b) ! 36: { ! 37: return false; ! 38: } ! 39: ! 40: UWORD *default_xlate(CPTR a) ! 41: { ! 42: fprintf(stderr, "Your Amiga program just did something terribly stupid\n"); ! 43: return 0; ! 44: } ! 45: ! 46: /* Chip memory */ ! 47: ! 48: static UWORD chipmemory[chipmem_size/2]; ! 49: ! 50: static ULONG chipmem_lget(CPTR) REGPARAM; ! 51: static UWORD chipmem_wget(CPTR) REGPARAM; ! 52: static UBYTE chipmem_bget(CPTR) REGPARAM; ! 53: static void chipmem_lput(CPTR, ULONG) REGPARAM; ! 54: static void chipmem_wput(CPTR, UWORD) REGPARAM; ! 55: static void chipmem_bput(CPTR, UBYTE) REGPARAM; ! 56: static bool chipmem_check(CPTR addr, ULONG size) REGPARAM; ! 57: static UWORD *chipmem_xlate(CPTR addr) REGPARAM; ! 58: ! 59: ULONG chipmem_lget(CPTR addr) ! 60: { ! 61: addr -= chipmem_start & (chipmem_size-1); ! 62: addr &= chipmem_size-1; ! 63: return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1]; ! 64: } ! 65: ! 66: UWORD chipmem_wget(CPTR addr) ! 67: { ! 68: addr -= chipmem_start & (chipmem_size-1); ! 69: addr &= chipmem_size-1; ! 70: return chipmemory[addr >> 1]; ! 71: } ! 72: ! 73: UBYTE chipmem_bget(CPTR addr) ! 74: { ! 75: addr -= chipmem_start & (chipmem_size-1); ! 76: addr &= chipmem_size-1; ! 77: return chipmemory[addr >> 1] >> (addr & 1 ? 0 : 8); ! 78: } ! 79: ! 80: void chipmem_lput(CPTR addr, ULONG l) ! 81: { ! 82: addr -= chipmem_start & (chipmem_size-1); ! 83: addr &= chipmem_size-1; ! 84: chipmemory[addr >> 1] = l >> 16; ! 85: chipmemory[(addr >> 1)+1] = (UWORD)l; ! 86: } ! 87: ! 88: void chipmem_wput(CPTR addr, UWORD w) ! 89: { ! 90: addr -= chipmem_start & (chipmem_size-1); ! 91: addr &= chipmem_size-1; ! 92: chipmemory[addr >> 1] = w; ! 93: } ! 94: ! 95: void chipmem_bput(CPTR addr, UBYTE b) ! 96: { ! 97: addr -= chipmem_start & (chipmem_size-1); ! 98: addr &= chipmem_size-1; ! 99: if (!(addr & 1)) { ! 100: chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8); ! 101: } else { ! 102: chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b; ! 103: } ! 104: } ! 105: ! 106: bool chipmem_check(CPTR addr, ULONG size) ! 107: { ! 108: addr -= chipmem_start & (chipmem_size-1); ! 109: addr &= chipmem_size-1; ! 110: return (addr + size) < chipmem_size; ! 111: } ! 112: ! 113: UWORD *chipmem_xlate(CPTR addr) ! 114: { ! 115: addr -= chipmem_start & (chipmem_size-1); ! 116: addr &= chipmem_size-1; ! 117: return chipmemory + (addr >> 1); ! 118: } ! 119: ! 120: /* Slow memory */ ! 121: ! 122: static UWORD bogomemory[bogomem_size/2]; ! 123: ! 124: static ULONG bogomem_lget(CPTR) REGPARAM; ! 125: static UWORD bogomem_wget(CPTR) REGPARAM; ! 126: static UBYTE bogomem_bget(CPTR) REGPARAM; ! 127: static void bogomem_lput(CPTR, ULONG) REGPARAM; ! 128: static void bogomem_wput(CPTR, UWORD) REGPARAM; ! 129: static void bogomem_bput(CPTR, UBYTE) REGPARAM; ! 130: static bool bogomem_check(CPTR addr, ULONG size) REGPARAM; ! 131: static UWORD *bogomem_xlate(CPTR addr) REGPARAM; ! 132: ! 133: ULONG bogomem_lget(CPTR addr) ! 134: { ! 135: addr -= bogomem_start & (bogomem_size-1); ! 136: addr &= bogomem_size-1; ! 137: return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1]; ! 138: } ! 139: ! 140: UWORD bogomem_wget(CPTR addr) ! 141: { ! 142: addr -= bogomem_start & (bogomem_size-1); ! 143: addr &= bogomem_size-1; ! 144: return bogomemory[addr >> 1]; ! 145: } ! 146: ! 147: UBYTE bogomem_bget(CPTR addr) ! 148: { ! 149: addr -= bogomem_start & (bogomem_size-1); ! 150: addr &= bogomem_size-1; ! 151: return bogomemory[addr >> 1] >> (addr & 1 ? 0 : 8); ! 152: } ! 153: ! 154: void bogomem_lput(CPTR addr, ULONG l) ! 155: { ! 156: addr -= bogomem_start & (bogomem_size-1); ! 157: addr &= bogomem_size-1; ! 158: bogomemory[addr >> 1] = l >> 16; ! 159: bogomemory[(addr >> 1)+1] = (UWORD)l; ! 160: } ! 161: ! 162: void bogomem_wput(CPTR addr, UWORD w) ! 163: { ! 164: addr -= bogomem_start & (bogomem_size-1); ! 165: addr &= bogomem_size-1; ! 166: bogomemory[addr >> 1] = w; ! 167: } ! 168: ! 169: void bogomem_bput(CPTR addr, UBYTE b) ! 170: { ! 171: addr -= bogomem_start & (bogomem_size-1); ! 172: addr &= bogomem_size-1; ! 173: if (!(addr & 1)) { ! 174: bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8); ! 175: } else { ! 176: bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b; ! 177: } ! 178: } ! 179: ! 180: bool bogomem_check(CPTR addr, ULONG size) ! 181: { ! 182: addr -= bogomem_start & (bogomem_size-1); ! 183: addr &= bogomem_size-1; ! 184: return (addr + size) < bogomem_size; ! 185: } ! 186: ! 187: UWORD *bogomem_xlate(CPTR addr) ! 188: { ! 189: addr -= bogomem_start & (bogomem_size-1); ! 190: addr &= bogomem_size-1; ! 191: return bogomemory + (addr >> 1); ! 192: } ! 193: ! 194: /* Kick memory */ ! 195: ! 196: static UWORD kickmemory[kickmem_size/2]; ! 197: ! 198: static ULONG kickmem_lget(CPTR) REGPARAM; ! 199: static UWORD kickmem_wget(CPTR) REGPARAM; ! 200: static UBYTE kickmem_bget(CPTR) REGPARAM; ! 201: static void kickmem_lput(CPTR, ULONG) REGPARAM; ! 202: static void kickmem_wput(CPTR, UWORD) REGPARAM; ! 203: static void kickmem_bput(CPTR, UBYTE) REGPARAM; ! 204: static bool kickmem_check(CPTR addr, ULONG size) REGPARAM; ! 205: static UWORD *kickmem_xlate(CPTR addr) REGPARAM; ! 206: ! 207: ULONG kickmem_lget(CPTR addr) ! 208: { ! 209: addr -= kickmem_start & (kickmem_size-1); ! 210: addr &= kickmem_size-1; ! 211: return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1]; ! 212: } ! 213: ! 214: UWORD kickmem_wget(CPTR addr) ! 215: { ! 216: addr -= kickmem_start & (kickmem_size-1); ! 217: addr &= kickmem_size-1; ! 218: return kickmemory[addr >> 1]; ! 219: } ! 220: ! 221: UBYTE kickmem_bget(CPTR addr) ! 222: { ! 223: addr -= kickmem_start & (kickmem_size-1); ! 224: addr &= kickmem_size-1; ! 225: return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8); ! 226: } ! 227: ! 228: void kickmem_lput(CPTR a, ULONG b) ! 229: { ! 230: } ! 231: ! 232: void kickmem_wput(CPTR a, UWORD b) ! 233: { ! 234: } ! 235: ! 236: void kickmem_bput(CPTR a, UBYTE b) ! 237: { ! 238: } ! 239: ! 240: bool kickmem_check(CPTR addr, ULONG size) ! 241: { ! 242: addr -= kickmem_start & (kickmem_size-1); ! 243: addr &= kickmem_size-1; ! 244: return (addr + size) < kickmem_size; ! 245: } ! 246: ! 247: UWORD *kickmem_xlate(CPTR addr) ! 248: { ! 249: addr -= kickmem_start & (kickmem_size-1); ! 250: addr &= kickmem_size-1; ! 251: return kickmemory + (addr >> 1); ! 252: } ! 253: ! 254: static bool load_kickstart(void) ! 255: { ! 256: int i; ! 257: ULONG cksum = 0, prevck = 0; ! 258: ! 259: FILE *f = fopen(romfile, "rb"); ! 260: ! 261: if (f == NULL) { ! 262: fprintf(stderr, "No Kickstart ROM found.\n"); ! 263: return false; ! 264: } ! 265: ! 266: for(i = 0; i < kickmem_size/2; i++) { ! 267: unsigned char buffer[2]; ! 268: if (fread(buffer, 1, 2, f) < 2) { ! 269: if (feof(f) && i == kickmem_size/4) { ! 270: fprintf(stderr, "Warning: Kickstart is only 256K.\n"); ! 271: #ifndef __mac__ ! 272: memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/4); ! 273: #else ! 274: memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2); ! 275: #endif ! 276: break; ! 277: } else { ! 278: fprintf(stderr, "Error while reading Kickstart.\n"); ! 279: return false; ! 280: } ! 281: } ! 282: kickmemory[i] = buffer[0]*256 + buffer[1]; ! 283: } ! 284: fclose (f); ! 285: ! 286: for (i = 0; i < kickmem_size/4; i++) { ! 287: ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1]; ! 288: cksum += data; ! 289: if (cksum < prevck) ! 290: cksum++; ! 291: prevck = cksum; ! 292: } ! 293: if (cksum != 0xFFFFFFFF) { ! 294: fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n"); ! 295: } ! 296: return true; ! 297: } ! 298: ! 299: /* Address banks */ ! 300: ! 301: addrbank chipmem_bank = { ! 302: chipmem_lget, chipmem_wget, chipmem_bget, ! 303: chipmem_lput, chipmem_wput, chipmem_bput, ! 304: chipmem_xlate, chipmem_check ! 305: }; ! 306: ! 307: addrbank bogomem_bank = { ! 308: bogomem_lget, bogomem_wget, bogomem_bget, ! 309: bogomem_lput, bogomem_wput, bogomem_bput, ! 310: bogomem_xlate, bogomem_check ! 311: }; ! 312: ! 313: addrbank kickmem_bank = { ! 314: kickmem_lget, kickmem_wget, kickmem_bget, ! 315: kickmem_lput, kickmem_wput, kickmem_bput, ! 316: kickmem_xlate, kickmem_check ! 317: }; ! 318: ! 319: ! 320: #ifdef DUALCPU ! 321: ULONG mempattern; ! 322: bool incpu; ! 323: struct memreads { ! 324: CPTR addr; ! 325: ULONG value; ! 326: } readlog[200]; ! 327: ! 328: int memlogptr = 0; ! 329: ! 330: ULONG get_long(CPTR addr) ! 331: { ! 332: ULONG result; ! 333: mempattern ^= addr ^ 0x99999999; ! 334: if (allowmem || !incpu) { ! 335: result = longget(addr); ! 336: if (incpu) { ! 337: readlog[memlogptr].addr = addr; ! 338: readlog[memlogptr++].value = result; ! 339: } ! 340: } else { ! 341: for(int i=0;i<memlogptr;i++) { ! 342: if (readlog[i].addr == addr) { ! 343: result = readlog[i].value; ! 344: } ! 345: } ! 346: } ! 347: return result; ! 348: } ! 349: ! 350: UWORD get_word(CPTR addr) ! 351: { ! 352: UWORD result; ! 353: mempattern ^= addr ^ 0xAAAAAAAA; ! 354: if (allowmem || !incpu) { ! 355: result = wordget(addr); ! 356: if (incpu) { ! 357: readlog[memlogptr].addr = addr; ! 358: readlog[memlogptr++].value = result; ! 359: } ! 360: } else { ! 361: for(int i=0;i<memlogptr;i++) { ! 362: if (readlog[i].addr == addr) { ! 363: result = readlog[i].value; ! 364: } ! 365: } ! 366: } ! 367: return result; ! 368: } ! 369: ! 370: UBYTE get_byte(CPTR addr) ! 371: { ! 372: UBYTE result; ! 373: mempattern ^= addr ^ 0x55555555; ! 374: if (allowmem || !incpu) { ! 375: result = byteget(addr); ! 376: if (incpu) { ! 377: readlog[memlogptr].addr = addr; ! 378: readlog[memlogptr++].value = result; ! 379: } ! 380: } else { ! 381: for(int i=0;i<memlogptr;i++) { ! 382: if (readlog[i].addr == addr) { ! 383: result = readlog[i].value; ! 384: } ! 385: } ! 386: } ! 387: return result; ! 388: } ! 389: ! 390: void put_long(CPTR addr, ULONG l) ! 391: { ! 392: mempattern ^= addr ^ l ^ 0x09090909; ! 393: longput(addr,l); ! 394: } ! 395: ! 396: void put_word(CPTR addr, UWORD w) ! 397: { ! 398: mempattern ^= addr ^ w ^ 0x0A0A0A0A; ! 399: wordput(addr,w); ! 400: } ! 401: ! 402: void put_byte(CPTR addr, UBYTE b) ! 403: { ! 404: mempattern ^= addr ^ b ^ 0x05050505; ! 405: byteput(addr,b); ! 406: } ! 407: ! 408: #endif ! 409: ! 410: void memory_init(void) ! 411: { ! 412: #ifdef DUALCPU ! 413: allowmem = true; ! 414: #endif ! 415: buserr = false; ! 416: ! 417: map_banks(chipmem_bank, 0, 256); ! 418: ! 419: map_banks(custom_bank, 0xC0, 0x20); ! 420: ! 421: if (use_slow_mem && bogomem_size > 0) { ! 422: map_banks(bogomem_bank, 0xC0, bogomem_size >> 16); ! 423: } ! 424: #if 0 ! 425: if (fastmem_size > 0) ! 426: map_banks(expmem_config_bank, 0xE8, 1); ! 427: #endif ! 428: map_banks(kickmem_bank, 0xF8, 8); ! 429: map_banks(rtarea_bank, 0xF0, 1); rtarea_init (); ! 430: map_banks(cia_bank, 0xBF, 1); ! 431: map_banks(clock_bank, 0xDC, 1); ! 432: ! 433: if (!load_kickstart()) { ! 434: init_ersatz_rom(kickmemory); ! 435: } ! 436: } ! 437: ! 438: void map_banks(addrbank bank, int start, int size) ! 439: { ! 440: int bnr; ! 441: for(bnr=start; bnr < start+size; bnr++) { ! 442: do_lget[bnr] = bank.lget; ! 443: do_wget[bnr] = bank.wget; ! 444: do_bget[bnr] = bank.bget; ! 445: do_lput[bnr] = bank.lput; ! 446: do_wput[bnr] = bank.wput; ! 447: do_bput[bnr] = bank.bput; ! 448: do_xlateaddr[bnr] = bank.xlateaddr; ! 449: do_check[bnr] = bank.check; ! 450: } ! 451: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.