memory.c
1 /* 2 * UAE - The Un*x Amiga Emulator 3 * 4 * Memory management 5 * 6 * (c) 1995 Bernd Schmidt 7 */ 8 9 #include "shared.h" 10 11 #include "memory.h" 12 #include "custom.h" 13 #include "cia.h" 14 #ifdef HAS_ERSATZ 15 #include "ersatz.h" 16 int ersatzkickfile = 0; 17 #endif 18 19 #define HALF_CHIPMEM 1 20 21 #define HALF_KICKIMAGE 1 22 23 int buserr; 24 addrbank membanks[256]; 25 26 27 /* Default memory access functions */ 28 29 int default_check(CPTR a, ULONG b) 30 { 31 return 0; 32 } 33 34 UWORD *default_xlate(CPTR a) 35 { 36 emu_printf("Your Amiga program just did something terribly stupid\n"); 37 return 0; 38 } 39 40 /* A dummy bank that only contains zeros */ 41 42 ULONG dummy_lget(CPTR addr) 43 { 44 return 0; 45 } 46 47 UWORD dummy_wget(CPTR addr) 48 { 49 return 0; 50 } 51 52 UBYTE dummy_bget(CPTR addr) 53 { 54 return 0; 55 } 56 57 void dummy_lput(CPTR addr, ULONG l) 58 { 59 } 60 61 void dummy_wput(CPTR addr, UWORD w) 62 { 63 } 64 65 void dummy_bput(CPTR addr, UBYTE b) 66 { 67 } 68 69 int dummy_check(CPTR addr, ULONG size) 70 { 71 return 0; 72 } 73 74 UWORD *dummy_xlate(CPTR addr) 75 { 76 return NULL; 77 } 78 79 /* Chip memory */ 80 81 UWORD *chipmemory=NULL; 82 void *chipmemory_end=NULL; 83 #ifdef HALF_CHIPMEM 84 static UBYTE chipmemextra[chipmem_size/2]; 85 UWORD *chipmemory2=(UWORD*)&chipmemextra[0]; 86 #else 87 UWORD *chipmemory2=NULL; 88 #endif 89 90 extern UWORD *chipmemoryadd; 91 92 ULONG chipmem_lget(CPTR addr) 93 { 94 if (chipmemory != chipmemoryadd) { 95 emu_printf("aaaaaa"); 96 //delay(100); 97 chipmemory = chipmemoryadd; 98 } 99 100 addr -= chipmem_start; 101 addr &= chipmem_size-1; 102 #ifdef HALF_CHIPMEM 103 if (addr >= 0x040000) { 104 addr -= 0x040000; 105 return ((ULONG)chipmemory2[addr >> 1] << 16) | chipmemory2[(addr >> 1)+1]; 106 } 107 #endif 108 return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1]; 109 } 110 111 UWORD chipmem_wget(CPTR addr) 112 { 113 /* 114 if (chipmemory != chipmemoryadd) { 115 emu_printf("aaaaaa"); 116 delay(100); 117 chipmemory = chipmemoryadd; 118 } 119 */ 120 addr -= chipmem_start; 121 addr &= chipmem_size-1; 122 #ifdef HALF_CHIPMEM 123 if (addr >= 0x040000) { 124 addr -= 0x040000; 125 return chipmemory2[addr >> 1]; 126 } 127 #endif 128 return chipmemory[addr >> 1]; 129 } 130 131 UBYTE chipmem_bget(CPTR addr) 132 { 133 /* 134 if (chipmemory != chipmemoryadd) { 135 emu_printf("aaaaaa"); 136 delay(100); 137 chipmemory = chipmemoryadd; 138 } 139 */ 140 addr -= chipmem_start; 141 addr &= chipmem_size-1; 142 #ifdef HALF_CHIPMEM 143 if (addr >= 0x040000) { 144 addr -= 0x040000; 145 if (addr & 1) 146 return chipmemory2[addr >> 1]; 147 else 148 return chipmemory2[addr >> 1] >> 8; 149 } 150 #endif 151 if (addr & 1) 152 return chipmemory[addr >> 1]; 153 else 154 return chipmemory[addr >> 1] >> 8; 155 } 156 157 void chipmem_lput(CPTR addr, ULONG l) 158 { 159 addr -= chipmem_start; 160 addr &= chipmem_size-1; 161 #ifdef HALF_CHIPMEM 162 if (addr >= 0x040000) { 163 addr -= 0x040000; 164 chipmemory2[addr >> 1] = l >> 16; 165 chipmemory2[(addr >> 1)+1] = (UWORD)l; 166 return; 167 } 168 #endif 169 chipmemory[addr >> 1] = l >> 16; 170 chipmemory[(addr >> 1)+1] = (UWORD)l; 171 } 172 173 void chipmem_wput(CPTR addr, UWORD w) 174 { 175 addr -= chipmem_start; 176 addr &= chipmem_size-1; 177 #ifdef HALF_CHIPMEM 178 if (addr >= 0x040000) { 179 addr -= 0x040000; 180 chipmemory2[addr >> 1] = w; 181 return; 182 } 183 #endif 184 chipmemory[addr >> 1] = w; 185 } 186 187 void chipmem_bput(CPTR addr, UBYTE b) 188 { 189 addr -= chipmem_start; 190 addr &= chipmem_size-1; 191 #ifdef HALF_CHIPMEM 192 if (addr >= 0x040000) { 193 addr -= 0x040000; 194 if (!(addr & 1)) { 195 chipmemory2[addr>>1] = (chipmemory2[addr>>1] & 0xff) | (((UWORD)b) << 8); 196 } else { 197 chipmemory2[addr>>1] = (chipmemory2[addr>>1] & 0xff00) | b; 198 } 199 return; 200 } 201 #endif 202 if (!(addr & 1)) { 203 chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8); 204 } else { 205 chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b; 206 } 207 } 208 209 int chipmem_check(CPTR addr, ULONG size) 210 { 211 addr -= chipmem_start; 212 addr &= chipmem_size-1; 213 return (addr + size) < chipmem_size; 214 } 215 216 UWORD *chipmem_xlate(CPTR addr) 217 { 218 addr -= chipmem_start; 219 addr &= chipmem_size-1; 220 #ifdef HALF_CHIPMEM 221 if (addr >= 0x040000) { 222 addr -= 0x040000; 223 return chipmemory2 + (addr >> 1); 224 } 225 #endif 226 return chipmemory + (addr >> 1); 227 } 228 229 230 /* Kick memory */ 231 232 static int zkickfile = 0; 233 234 #ifdef HAS_KICKFILE 235 static UWORD kick[kickmem_size/2]; 236 #else 237 #ifdef HALF_KICKIMAGE 238 #include "kick13_swapped.h" 239 #else 240 #include "kickfull_swapped.h" 241 #endif 242 #endif 243 static UWORD *kickmemory=(UWORD*)&kick[0]; 244 245 246 static ULONG kickmem_lget(CPTR) REGPARAM; 247 static UWORD kickmem_wget(CPTR) REGPARAM; 248 static UBYTE kickmem_bget(CPTR) REGPARAM; 249 static void kickmem_lput(CPTR, ULONG) REGPARAM; 250 static void kickmem_wput(CPTR, UWORD) REGPARAM; 251 static void kickmem_bput(CPTR, UBYTE) REGPARAM; 252 static int kickmem_check(CPTR addr, ULONG size) REGPARAM; 253 static UWORD *kickmem_xlate(CPTR addr) REGPARAM; 254 255 256 ULONG kickmem_lget(CPTR addr) 257 { 258 addr -= kickmem_start; 259 addr &= kickmem_size-1; 260 #ifdef HALF_KICKIMAGE 261 if (addr >= 0x040000) {addr -= 0x040000;} 262 #endif 263 return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1]; 264 } 265 266 UWORD kickmem_wget(CPTR addr) 267 { 268 addr -= kickmem_start; 269 addr &= kickmem_size-1; 270 #ifdef HALF_KICKIMAGE 271 if (addr >= 0x040000) {addr -= 0x040000;} 272 #endif 273 return kickmemory[addr >> 1]; 274 } 275 276 UBYTE kickmem_bget(CPTR addr) 277 { 278 addr -= kickmem_start; 279 addr &= kickmem_size-1; 280 #ifdef HALF_KICKIMAGE 281 if (addr >= 0x040000) {addr -= 0x040000;} 282 #endif 283 return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8); 284 } 285 286 void kickmem_lput(CPTR a, ULONG b) 287 { 288 } 289 290 void kickmem_wput(CPTR a, UWORD b) 291 { 292 } 293 294 void kickmem_bput(CPTR a, UBYTE b) 295 { 296 } 297 298 int kickmem_check(CPTR addr, ULONG size) 299 { 300 addr -= kickmem_start; 301 addr &= kickmem_size-1; 302 return (addr + size) < kickmem_size; 303 } 304 305 UWORD *kickmem_xlate(CPTR addr) 306 { 307 addr -= kickmem_start; 308 addr &= kickmem_size-1; 309 #ifdef HALF_KICKIMAGE 310 if (addr >= 0x040000) {addr -= 0x040000;} 311 #endif 312 return kickmemory + (addr >> 1); 313 } 314 315 316 317 #ifdef HAS_BOGOMEM 318 319 /* Slow memory */ 320 321 static UWORD *bogomemory; 322 323 static ULONG bogomem_lget(CPTR) REGPARAM; 324 static UWORD bogomem_wget(CPTR) REGPARAM; 325 static UBYTE bogomem_bget(CPTR) REGPARAM; 326 static void bogomem_lput(CPTR, ULONG) REGPARAM; 327 static void bogomem_wput(CPTR, UWORD) REGPARAM; 328 static void bogomem_bput(CPTR, UBYTE) REGPARAM; 329 static int bogomem_check(CPTR addr, ULONG size) REGPARAM; 330 static UWORD *bogomem_xlate(CPTR addr) REGPARAM; 331 332 ULONG bogomem_lget(CPTR addr) 333 { 334 addr -= bogomem_start & (bogomem_size-1); 335 addr &= bogomem_size-1; 336 return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1]; 337 } 338 339 UWORD bogomem_wget(CPTR addr) 340 { 341 addr -= bogomem_start & (bogomem_size-1); 342 addr &= bogomem_size-1; 343 return bogomemory[addr >> 1]; 344 } 345 346 UBYTE bogomem_bget(CPTR addr) 347 { 348 addr -= bogomem_start & (bogomem_size-1); 349 addr &= bogomem_size-1; 350 if (addr & 1) 351 return bogomemory[addr >> 1]; 352 else 353 return bogomemory[addr >> 1] >> 8; 354 } 355 356 void bogomem_lput(CPTR addr, ULONG l) 357 { 358 addr -= bogomem_start & (bogomem_size-1); 359 addr &= bogomem_size-1; 360 bogomemory[addr >> 1] = l >> 16; 361 bogomemory[(addr >> 1)+1] = (UWORD)l; 362 } 363 364 void bogomem_wput(CPTR addr, UWORD w) 365 { 366 addr -= bogomem_start & (bogomem_size-1); 367 addr &= bogomem_size-1; 368 bogomemory[addr >> 1] = w; 369 } 370 371 void bogomem_bput(CPTR addr, UBYTE b) 372 { 373 addr -= bogomem_start & (bogomem_size-1); 374 addr &= bogomem_size-1; 375 if (!(addr & 1)) { 376 bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8); 377 } else { 378 bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b; 379 } 380 } 381 382 int bogomem_check(CPTR addr, ULONG size) 383 { 384 addr -= bogomem_start & (bogomem_size-1); 385 addr &= bogomem_size-1; 386 return (addr + size) < bogomem_size; 387 } 388 389 UWORD *bogomem_xlate(CPTR addr) 390 { 391 addr -= bogomem_start & (bogomem_size-1); 392 addr &= bogomem_size-1; 393 return bogomemory + (addr >> 1); 394 } 395 #endif 396 397 #ifdef HAS_KICKFILE 398 int processFileInMem(char * infile, char * outfile, char * arrname, unsigned char * data, int size) { 399 400 FILE *fp_wr = stdout; 401 if ((fp_wr = fopen (outfile, "wb")) == NULL) 402 { 403 fprintf (stderr, "Error: can not create file %s\n", outfile); 404 } 405 406 int cnt=0; 407 fprintf(fp_wr, "const unsigned char %s[%d] = {\n", arrname, size); 408 409 cnt = 0; 410 for (int i = 0; i < size; i++) { 411 cnt++; 412 if (cnt == 16) { 413 fprintf(fp_wr, "0x%02X,\n",data[i]); 414 } 415 else { 416 fprintf(fp_wr, "0x%02X,",data[i]); 417 } 418 cnt &= 15; 419 } 420 fprintf(fp_wr, "};\n"); 421 422 fclose (fp_wr); 423 return 1; 424 } 425 426 static int load_kickstart(void) 427 { 428 int i; 429 ULONG cksum = 0, prevck = 0; 430 unsigned char buffer[8]; 431 432 FILE *f = fopen(romfile, "rb"); 433 434 if (f == NULL) { 435 emu_printf("No Kickstart ROM found.\n"); 436 return 0; 437 } 438 439 fread(buffer, 1, 8, f); 440 if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) { 441 emu_printf("You seem to have a ZKick file there... You probably lose.\n"); 442 zkickfile = 1; 443 } else 444 fseek(f, 0, SEEK_SET); 445 446 i = fread(kick, 1, kickmem_size, f); 447 if (i == kickmem_size/2) { 448 emu_printf("Warning: Kickstart is only 256K.\n"); 449 memcpy (kick + kickmem_size/4, kick, kickmem_size/2); 450 } else if (i != kickmem_size) { 451 emu_printf("Error while reading Kickstart.\n"); 452 return 0; 453 } 454 fclose (f); 455 456 for (i = 0; i < kickmem_size/2; i++) { 457 UWORD *p = kick + i; 458 UBYTE *bp = (UBYTE *)p; 459 *p = (*bp << 8) | *(bp+1); 460 } 461 462 463 for (i = 0; i < kickmem_size/4; i++) { 464 ULONG data = kick[i*2]*65536 + kick[i*2+1]; 465 cksum += data; 466 if (cksum < prevck) 467 cksum++; 468 prevck = cksum; 469 } 470 if (cksum != 0xFFFFFFFF) { 471 emu_printf("Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n"); 472 } 473 474 return 1; 475 } 476 #endif 477 478 479 /* Address banks */ 480 481 addrbank dummy_bank = { 482 dummy_lget, dummy_wget, dummy_bget, 483 dummy_lput, dummy_wput, dummy_bput, 484 dummy_xlate, dummy_check 485 }; 486 487 addrbank chipmem_bank = { 488 chipmem_lget, chipmem_wget, chipmem_bget, 489 chipmem_lput, chipmem_wput, chipmem_bput, 490 chipmem_xlate, chipmem_check 491 }; 492 493 addrbank kickmem_bank = { 494 kickmem_lget, kickmem_wget, kickmem_bget, 495 kickmem_lput, kickmem_wput, kickmem_bput, 496 kickmem_xlate, kickmem_check 497 }; 498 499 #ifdef HAS_BOGOMEM 500 addrbank bogomem_bank = { 501 bogomem_lget, bogomem_wget, bogomem_bget, 502 bogomem_lput, bogomem_wput, bogomem_bput, 503 bogomem_xlate, bogomem_check 504 }; 505 #endif 506 507 508 void memory_init(void) 509 { 510 int i; 511 buserr = 0; 512 513 #ifdef HALF_CHIPMEM 514 chipmemory = (WORD*)emu_Malloc(chipmem_size/2); 515 chipmemoryadd = chipmemory; 516 memset(chipmemory, 0, chipmem_size/2); 517 memset(chipmemory2, 0, chipmem_size/2); 518 chipmemory_end = chipmemory; 519 chipmemory_end += chipmem_size/2; 520 #else 521 chipmemory = (WORD*)emu_Malloc(chipmem_size); 522 memset(chipmemory, 0, chipmem_size); 523 chipmemory_end = chipmemory; 524 chipmemory_end += chipmem_size; 525 #endif 526 527 for(i = 0; i < 256; i++) 528 membanks[i] = dummy_bank; 529 530 /* Map the chipmem into all of the lower 16MB */ 531 map_banks(chipmem_bank, 0x00, 256); //chipmem_size>>16?? 532 map_banks(custom_bank, 0xC0, 0x20); 533 map_banks(cia_bank, 0xA0, 0x20); 534 535 //0x000000 - 0x080000 536 //0xA00000 - 0xBFFFFF 537 //0xC00000 - 0xDFFFFF 538 //0xF80000 - 0xFFFFFF 539 540 541 //map_banks(clock_bank, 0xDC, 1); 542 //map_banks(rtarea_bank, 0xF0, 1); 543 //rtarea_init (); 544 545 #ifdef HAS_KICKFILE 546 if (!load_kickstart()) { 547 #ifdef HAS_ERSATZ 548 init_ersatz_rom(kickmemory); 549 ersatzkickfile = 1; 550 #endif 551 } 552 //processFileInMem("kick13.rom","kickbig.h","kick",kick,kickmem_size); 553 #endif 554 555 if (zkickfile) 556 map_banks(kickmem_bank, 0x20, 8); 557 558 map_banks(kickmem_bank, 0xF8, 8); 559 560 #ifdef HAS_BOGOMEM 561 if (bogomem_size > 0) { 562 bogomemory = (UWORD *)emu_malloc (bogomem_size); 563 map_banks(bogomem_bank, 0xC0, bogomem_size >> 16); 564 } 565 #endif 566 567 #ifdef HAS_EXPANMEM 568 fastmem_size = 0x200000; 569 if (!zkickfile) 570 map_banks(expamem_bank, 0xE8, 1); 571 #endif 572 } 573 574 void map_banks(addrbank bank, int start, int size) 575 { 576 int bnr; 577 // int hioffs = 0; 578 //#if CPU_LEVEL < 2 579 // for (hioffs = 0; hioffs < 256; hioffs++) 580 //#endif 581 for (bnr = start; bnr < start+size; bnr++) 582 membanks[bnr /*+ hioffs * 256*/] = bank; 583 }