|
|
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:
12: #include "options.h"
1.1.1.3 root 13: #include "uae.h"
1.1 root 14: #include "memory.h"
1.1.1.17! root 15: #include "romlist.h"
1.1 root 16: #include "ersatz.h"
17: #include "zfile.h"
1.1.1.9 root 18: #include "custom.h"
19: #include "events.h"
20: #include "newcpu.h"
1.1.1.11 root 21: #include "autoconf.h"
1.1.1.9 root 22: #include "savestate.h"
1.1.1.15 root 23: #include "crc32.h"
1.1.1.17! root 24: #include "gui.h"
1.1 root 25:
1.1.1.2 root 26: #ifdef USE_MAPPED_MEMORY
1.1 root 27: #include <sys/mman.h>
28: #endif
29:
30: int ersatzkickfile = 0;
31:
1.1.1.4 root 32: uae_u32 allocated_chipmem;
33: uae_u32 allocated_fastmem;
34: uae_u32 allocated_bogomem;
35: uae_u32 allocated_gfxmem;
36: uae_u32 allocated_z3fastmem;
1.1.1.17! root 37: uae_u32 allocated_a3000lmem;
! 38: uae_u32 allocated_a3000hmem;
1.1.1.15 root 39:
1.1.1.17! root 40: static long chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos;
1.1.1.15 root 41:
1.1.1.17! root 42: /* Set if we notice during initialization that settings changed,
! 43: and we must clear all memory to prevent bogus contents from confusing
! 44: the Kickstart. */
! 45: static int need_hardreset;
1.1.1.15 root 46:
1.1.1.17! root 47: /* The address space setting used during the last reset. */
! 48: static int last_address_space_24;
1.1.1.15 root 49:
1.1.1.3 root 50: addrbank *mem_banks[65536];
1.1.1.9 root 51:
52: /* This has two functions. It either holds a host address that, when added
53: to the 68k address, gives the host address corresponding to that 68k
54: address (in which case the value in this array is even), OR it holds the
55: same value as mem_banks, for those banks that have baseaddr==0. In that
56: case, bit 0 is set (the memory access routines will take care of it). */
57:
58: uae_u8 *baseaddr[65536];
1.1 root 59:
1.1.1.2 root 60: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5 root 61: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2 root 62: {
1.1.1.5 root 63: return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2 root 64: }
1.1.1.5 root 65: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2 root 66: {
1.1.1.5 root 67: return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2 root 68: }
1.1.1.5 root 69: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2 root 70: {
1.1.1.5 root 71: return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2 root 72: }
1.1.1.5 root 73: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2 root 74: {
1.1.1.5 root 75: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2 root 76: }
1.1.1.5 root 77: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2 root 78: {
1.1.1.5 root 79: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2 root 80: }
1.1.1.5 root 81: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2 root 82: {
1.1.1.5 root 83: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2 root 84: }
85: #endif
86:
1.1.1.17! root 87: static uae_u32 chipmem_mask, chipmem_full_mask;
! 88: static uae_u32 kickmem_mask, extendedkickmem_mask, bogomem_mask;
! 89: static uae_u32 a3000lmem_mask, a3000hmem_mask;
1.1 root 90:
1.1.1.11 root 91: static int illegal_count;
1.1.1.3 root 92: /* A dummy bank that only contains zeros */
93:
1.1.1.4 root 94: static uae_u32 dummy_lget (uaecptr) REGPARAM;
95: static uae_u32 dummy_wget (uaecptr) REGPARAM;
96: static uae_u32 dummy_bget (uaecptr) REGPARAM;
97: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
98: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
99: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
100: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
101:
102: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
103: {
1.1.1.11 root 104: if (currprefs.illegal_mem) {
105: if (illegal_count < 20) {
106: illegal_count++;
107: write_log ("Illegal lget at %08lx\n", addr);
108: }
109: }
1.1.1.4 root 110:
1.1.1.9 root 111: return 0xFFFFFFFF;
1.1 root 112: }
113:
1.1.1.4 root 114: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1 root 115: {
1.1.1.11 root 116: if (currprefs.illegal_mem) {
117: if (illegal_count < 20) {
118: illegal_count++;
119: write_log ("Illegal wget at %08lx\n", addr);
120: }
121: }
1.1.1.12 root 122:
1.1.1.9 root 123: return 0xFFFF;
1.1 root 124: }
125:
1.1.1.4 root 126: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1 root 127: {
1.1.1.11 root 128: if (currprefs.illegal_mem) {
129: if (illegal_count < 20) {
130: illegal_count++;
131: write_log ("Illegal bget at %08lx\n", addr);
132: }
133: }
1.1.1.4 root 134:
1.1.1.9 root 135: return 0xFF;
1.1 root 136: }
137:
1.1.1.4 root 138: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1 root 139: {
1.1.1.11 root 140: if (currprefs.illegal_mem) {
141: if (illegal_count < 20) {
142: illegal_count++;
143: write_log ("Illegal lput at %08lx\n", addr);
144: }
145: }
1.1.1.3 root 146: }
1.1.1.17! root 147:
1.1.1.4 root 148: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 149: {
1.1.1.11 root 150: if (currprefs.illegal_mem) {
151: if (illegal_count < 20) {
152: illegal_count++;
153: write_log ("Illegal wput at %08lx\n", addr);
154: }
155: }
1.1.1.3 root 156: }
1.1.1.17! root 157:
1.1.1.4 root 158: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 159: {
1.1.1.11 root 160: if (currprefs.illegal_mem) {
161: if (illegal_count < 20) {
162: illegal_count++;
163: write_log ("Illegal bput at %08lx\n", addr);
164: }
165: }
1.1 root 166: }
167:
1.1.1.4 root 168: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1 root 169: {
1.1.1.11 root 170: if (currprefs.illegal_mem) {
171: if (illegal_count < 20) {
172: illegal_count++;
173: write_log ("Illegal check at %08lx\n", addr);
174: }
175: }
1.1.1.4 root 176:
1.1 root 177: return 0;
178: }
179:
180: /* Chip memory */
181:
1.1.1.3 root 182: uae_u8 *chipmemory;
1.1 root 183:
1.1.1.4 root 184: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
185: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1 root 186:
1.1.1.4 root 187: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1 root 188: {
1.1.1.3 root 189: uae_u32 *m;
1.1.1.8 root 190:
1.1 root 191: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 192: addr &= chipmem_mask;
1.1.1.3 root 193: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 194: return do_get_mem_long (m);
1.1 root 195: }
196:
1.1.1.4 root 197: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1 root 198: {
1.1.1.3 root 199: uae_u16 *m;
1.1.1.8 root 200:
1.1 root 201: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 202: addr &= chipmem_mask;
1.1.1.3 root 203: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 204: return do_get_mem_word (m);
1.1 root 205: }
206:
1.1.1.4 root 207: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1 root 208: {
209: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 210: addr &= chipmem_mask;
1.1 root 211: return chipmemory[addr];
212: }
213:
1.1.1.4 root 214: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1 root 215: {
1.1.1.3 root 216: uae_u32 *m;
1.1.1.8 root 217:
1.1 root 218: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 219: addr &= chipmem_mask;
1.1.1.3 root 220: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 221: do_put_mem_long (m, l);
1.1 root 222: }
223:
1.1.1.4 root 224: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1 root 225: {
1.1.1.3 root 226: uae_u16 *m;
1.1.1.8 root 227:
1.1 root 228: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 229: addr &= chipmem_mask;
1.1.1.3 root 230: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 231: do_put_mem_word (m, w);
1.1 root 232: }
233:
1.1.1.4 root 234: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1 root 235: {
236: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 237: addr &= chipmem_mask;
1.1 root 238: chipmemory[addr] = b;
239: }
240:
1.1.1.17! root 241: uae_u32 REGPARAM2 chipmem_agnus_wget (uaecptr addr)
! 242: {
! 243: uae_u16 *m;
! 244:
! 245: addr &= chipmem_full_mask;
! 246: m = (uae_u16 *)(chipmemory + addr);
! 247: return do_get_mem_word (m);
! 248: }
! 249:
! 250: void REGPARAM2 chipmem_agnus_wput (uaecptr addr, uae_u32 w)
! 251: {
! 252: uae_u16 *m;
! 253:
! 254: addr &= chipmem_full_mask;
! 255: if (addr >= allocated_chipmem)
! 256: return;
! 257: m = (uae_u16 *)(chipmemory + addr);
! 258: do_put_mem_word (m, w);
! 259: }
! 260:
1.1.1.4 root 261: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1 root 262: {
263: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 264: addr &= chipmem_mask;
1.1.1.4 root 265: return (addr + size) <= allocated_chipmem;
1.1 root 266: }
267:
1.1.1.4 root 268: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1 root 269: {
270: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 271: addr &= chipmem_mask;
1.1 root 272: return chipmemory + addr;
273: }
274:
275: /* Slow memory */
276:
1.1.1.3 root 277: static uae_u8 *bogomemory;
1.1 root 278:
1.1.1.4 root 279: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
280: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
281: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
282: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
283: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
284: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
285: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
286: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1 root 287:
1.1.1.4 root 288: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1 root 289: {
1.1.1.3 root 290: uae_u32 *m;
1.1 root 291: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 292: addr &= bogomem_mask;
1.1.1.3 root 293: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 294: return do_get_mem_long (m);
1.1 root 295: }
296:
1.1.1.4 root 297: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1 root 298: {
1.1.1.3 root 299: uae_u16 *m;
1.1 root 300: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 301: addr &= bogomem_mask;
1.1.1.3 root 302: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 303: return do_get_mem_word (m);
1.1 root 304: }
305:
1.1.1.4 root 306: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1 root 307: {
308: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 309: addr &= bogomem_mask;
1.1 root 310: return bogomemory[addr];
311: }
312:
1.1.1.4 root 313: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1 root 314: {
1.1.1.3 root 315: uae_u32 *m;
1.1 root 316: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 317: addr &= bogomem_mask;
1.1.1.3 root 318: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 319: do_put_mem_long (m, l);
1.1 root 320: }
321:
1.1.1.4 root 322: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1 root 323: {
1.1.1.3 root 324: uae_u16 *m;
1.1 root 325: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 326: addr &= bogomem_mask;
1.1.1.3 root 327: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 328: do_put_mem_word (m, w);
1.1 root 329: }
330:
1.1.1.4 root 331: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1 root 332: {
333: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 334: addr &= bogomem_mask;
1.1 root 335: bogomemory[addr] = b;
336: }
337:
1.1.1.4 root 338: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1 root 339: {
1.1.1.2 root 340: addr -= bogomem_start & bogomem_mask;
341: addr &= bogomem_mask;
1.1.1.4 root 342: return (addr + size) <= allocated_bogomem;
1.1 root 343: }
344:
1.1.1.4 root 345: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1 root 346: {
1.1.1.2 root 347: addr -= bogomem_start & bogomem_mask;
348: addr &= bogomem_mask;
1.1 root 349: return bogomemory + addr;
350: }
351:
1.1.1.17! root 352: /* A3000 motherboard fastmemory. */
! 353: static uae_u8 *a3000lmemory, *a3000hmemory;
! 354: uae_u32 a3000lmem_start, a3000hmem_start;
! 355:
! 356: static uae_u32 a3000lmem_lget (uaecptr) REGPARAM;
! 357: static uae_u32 a3000lmem_wget (uaecptr) REGPARAM;
! 358: static uae_u32 a3000lmem_bget (uaecptr) REGPARAM;
! 359: static void a3000lmem_lput (uaecptr, uae_u32) REGPARAM;
! 360: static void a3000lmem_wput (uaecptr, uae_u32) REGPARAM;
! 361: static void a3000lmem_bput (uaecptr, uae_u32) REGPARAM;
! 362: static int a3000lmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3 root 363:
1.1.1.17! root 364: static uae_u32 REGPARAM2 a3000lmem_lget (uaecptr addr)
! 365: {
! 366: uae_u32 *m;
! 367: addr &= a3000lmem_mask;
! 368: m = (uae_u32 *)(a3000lmemory + addr);
! 369: return do_get_mem_long (m);
! 370: }
! 371:
! 372: static uae_u32 REGPARAM2 a3000lmem_wget (uaecptr addr)
! 373: {
! 374: uae_u16 *m;
! 375: addr &= a3000lmem_mask;
! 376: m = (uae_u16 *)(a3000lmemory + addr);
! 377: return do_get_mem_word (m);
! 378: }
1.1 root 379:
1.1.1.17! root 380: static uae_u32 REGPARAM2 a3000lmem_bget (uaecptr addr)
! 381: {
! 382: addr &= a3000lmem_mask;
! 383: return a3000lmemory[addr];
! 384: }
1.1.1.3 root 385:
1.1.1.17! root 386: static void REGPARAM2 a3000lmem_lput (uaecptr addr, uae_u32 l)
1.1.1.3 root 387: {
388: uae_u32 *m;
1.1.1.17! root 389: addr &= a3000lmem_mask;
! 390: m = (uae_u32 *)(a3000lmemory + addr);
! 391: do_put_mem_long (m, l);
! 392: }
! 393:
! 394: static void REGPARAM2 a3000lmem_wput (uaecptr addr, uae_u32 w)
! 395: {
! 396: uae_u16 *m;
! 397: addr &= a3000lmem_mask;
! 398: m = (uae_u16 *)(a3000lmemory + addr);
! 399: do_put_mem_word (m, w);
! 400: }
! 401:
! 402: static void REGPARAM2 a3000lmem_bput (uaecptr addr, uae_u32 b)
! 403: {
! 404: addr &= a3000lmem_mask;
! 405: a3000lmemory[addr] = b;
! 406: }
! 407:
! 408: static int REGPARAM2 a3000lmem_check (uaecptr addr, uae_u32 size)
! 409: {
! 410: addr &= a3000lmem_mask;
! 411: return (addr + size) <= allocated_a3000lmem;
! 412: }
! 413:
! 414: static uae_u8 *REGPARAM2 a3000lmem_xlate (uaecptr addr)
! 415: {
! 416: addr &= a3000lmem_mask;
! 417: return a3000lmemory + addr;
! 418: }
! 419:
! 420: static uae_u32 a3000hmem_lget (uaecptr) REGPARAM;
! 421: static uae_u32 a3000hmem_wget (uaecptr) REGPARAM;
! 422: static uae_u32 a3000hmem_bget (uaecptr) REGPARAM;
! 423: static void a3000hmem_lput (uaecptr, uae_u32) REGPARAM;
! 424: static void a3000hmem_wput (uaecptr, uae_u32) REGPARAM;
! 425: static void a3000hmem_bput (uaecptr, uae_u32) REGPARAM;
! 426: static int a3000hmem_check (uaecptr addr, uae_u32 size) REGPARAM;
! 427: static uae_u8 *a3000hmem_xlate (uaecptr addr) REGPARAM;
! 428:
! 429: static uae_u32 REGPARAM2 a3000hmem_lget (uaecptr addr)
! 430: {
! 431: uae_u32 *m;
! 432: addr &= a3000hmem_mask;
! 433: m = (uae_u32 *)(a3000hmemory + addr);
1.1.1.5 root 434: return do_get_mem_long (m);
1.1.1.3 root 435: }
1.1 root 436:
1.1.1.17! root 437: static uae_u32 REGPARAM2 a3000hmem_wget (uaecptr addr)
1.1.1.3 root 438: {
439: uae_u16 *m;
1.1.1.17! root 440: addr &= a3000hmem_mask;
! 441: m = (uae_u16 *)(a3000hmemory + addr);
1.1.1.5 root 442: return do_get_mem_word (m);
1.1.1.3 root 443: }
1.1 root 444:
1.1.1.17! root 445: static uae_u32 REGPARAM2 a3000hmem_bget (uaecptr addr)
1.1 root 446: {
1.1.1.17! root 447: addr &= a3000hmem_mask;
! 448: return a3000hmemory[addr];
1.1 root 449: }
450:
1.1.1.17! root 451: static void REGPARAM2 a3000hmem_lput (uaecptr addr, uae_u32 l)
1.1 root 452: {
1.1.1.3 root 453: uae_u32 *m;
1.1.1.17! root 454: addr &= a3000hmem_mask;
! 455: m = (uae_u32 *)(a3000hmemory + addr);
1.1.1.5 root 456: do_put_mem_long (m, l);
1.1.1.3 root 457: }
458:
1.1.1.17! root 459: static void REGPARAM2 a3000hmem_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 460: {
461: uae_u16 *m;
1.1.1.17! root 462: addr &= a3000hmem_mask;
! 463: m = (uae_u16 *)(a3000hmemory + addr);
1.1.1.5 root 464: do_put_mem_word (m, w);
1.1.1.3 root 465: }
466:
1.1.1.17! root 467: static void REGPARAM2 a3000hmem_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 468: {
1.1.1.17! root 469: addr &= a3000hmem_mask;
! 470: a3000hmemory[addr] = b;
1.1.1.3 root 471: }
472:
1.1.1.17! root 473: static int REGPARAM2 a3000hmem_check (uaecptr addr, uae_u32 size)
1.1.1.3 root 474: {
1.1.1.17! root 475: addr &= a3000hmem_mask;
! 476: return (addr + size) <= allocated_a3000hmem;
1.1 root 477: }
478:
1.1.1.17! root 479: static uae_u8 *REGPARAM2 a3000hmem_xlate (uaecptr addr)
1.1.1.3 root 480: {
1.1.1.17! root 481: addr &= a3000hmem_mask;
! 482: return a3000hmemory + addr;
1.1.1.3 root 483: }
484:
485: /* Kick memory */
486:
487: uae_u8 *kickmemory;
1.1.1.17! root 488: uae_u16 kickstart_version;
1.1.1.3 root 489:
1.1.1.12 root 490: /*
491: * A1000 kickstart RAM handling
492: *
493: * RESET instruction unhides boot ROM and disables write protection
494: * write access to boot ROM hides boot ROM and enables write protection
495: *
496: */
497: static int a1000_kickstart_mode;
498: static uae_u8 *a1000_bootrom;
499: static void a1000_handle_kickstart (int mode)
500: {
1.1.1.17! root 501: if (!a1000_bootrom)
! 502: return;
1.1.1.12 root 503: if (mode == 0) {
504: a1000_kickstart_mode = 0;
505: memcpy (kickmemory, kickmemory + 262144, 262144);
1.1.1.17! root 506: kickstart_version = (kickmemory[262144 + 12] << 8) | kickmemory[262144 + 13];
1.1.1.12 root 507: } else {
508: a1000_kickstart_mode = 1;
1.1.1.17! root 509: memcpy (kickmemory, a1000_bootrom, 262144);
! 510: kickstart_version = 0;
1.1.1.12 root 511: }
512: }
513:
1.1.1.17! root 514: void a1000_reset (void)
! 515: {
! 516: a1000_handle_kickstart (1);
! 517: }
! 518:
1.1.1.4 root 519: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
520: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
521: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
1.1.1.12 root 522: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
523: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
524: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
525: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.4 root 526: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 527:
1.1.1.4 root 528: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1 root 529: {
1.1.1.3 root 530: uae_u32 *m;
1.1 root 531: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 532: addr &= kickmem_mask;
1.1.1.3 root 533: m = (uae_u32 *)(kickmemory + addr);
1.1.1.5 root 534: return do_get_mem_long (m);
1.1 root 535: }
536:
1.1.1.4 root 537: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1 root 538: {
1.1.1.3 root 539: uae_u16 *m;
1.1 root 540: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 541: addr &= kickmem_mask;
1.1.1.3 root 542: m = (uae_u16 *)(kickmemory + addr);
1.1.1.5 root 543: return do_get_mem_word (m);
1.1 root 544: }
545:
1.1.1.4 root 546: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1 root 547: {
548: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 549: addr &= kickmem_mask;
1.1 root 550: return kickmemory[addr];
551: }
552:
1.1.1.4 root 553: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1 root 554: {
1.1.1.12 root 555: uae_u32 *m;
556: if (a1000_kickstart_mode) {
557: if (addr >= 0xfc0000) {
558: addr -= kickmem_start & kickmem_mask;
559: addr &= kickmem_mask;
560: m = (uae_u32 *)(kickmemory + addr);
561: do_put_mem_long (m, b);
562: return;
563: } else
564: a1000_handle_kickstart (0);
565: } else if (currprefs.illegal_mem)
1.1.1.4 root 566: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 567: }
568:
1.1.1.4 root 569: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1 root 570: {
1.1.1.12 root 571: uae_u16 *m;
572: if (a1000_kickstart_mode) {
573: if (addr >= 0xfc0000) {
574: addr -= kickmem_start & kickmem_mask;
575: addr &= kickmem_mask;
576: m = (uae_u16 *)(kickmemory + addr);
577: do_put_mem_word (m, b);
578: return;
579: } else
580: a1000_handle_kickstart (0);
581: } else if (currprefs.illegal_mem)
1.1.1.4 root 582: write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1 root 583: }
584:
1.1.1.4 root 585: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1 root 586: {
1.1.1.12 root 587: if (a1000_kickstart_mode) {
588: if (addr >= 0xfc0000) {
589: addr -= kickmem_start & kickmem_mask;
590: addr &= kickmem_mask;
591: kickmemory[addr] = b;
592: return;
593: } else
594: a1000_handle_kickstart (0);
595: } else if (currprefs.illegal_mem)
1.1.1.4 root 596: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 597: }
598:
1.1.1.4 root 599: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1 root 600: {
1.1.1.2 root 601: addr -= kickmem_start & kickmem_mask;
602: addr &= kickmem_mask;
1.1.1.4 root 603: return (addr + size) <= kickmem_size;
1.1 root 604: }
605:
1.1.1.4 root 606: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1 root 607: {
1.1.1.2 root 608: addr -= kickmem_start & kickmem_mask;
609: addr &= kickmem_mask;
1.1 root 610: return kickmemory + addr;
611: }
612:
1.1.1.12 root 613: /* CD32/CDTV extended kick memory */
1.1.1.3 root 614:
1.1.1.12 root 615: uae_u8 *extendedkickmemory;
616: static int extendedkickmem_size;
617: static uae_u32 extendedkickmem_start;
618:
619: #define EXTENDED_ROM_CD32 1
620: #define EXTENDED_ROM_CDTV 2
621:
622: static int extromtype (void)
623: {
624: switch (extendedkickmem_size) {
625: case 524288:
626: return EXTENDED_ROM_CD32;
627: case 262144:
628: return EXTENDED_ROM_CDTV;
629: }
1.1.1.3 root 630: return 0;
631: }
632:
1.1.1.12 root 633: static uae_u32 extendedkickmem_lget (uaecptr) REGPARAM;
634: static uae_u32 extendedkickmem_wget (uaecptr) REGPARAM;
635: static uae_u32 extendedkickmem_bget (uaecptr) REGPARAM;
636: static void extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
637: static void extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
638: static void extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
639: static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
640: static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM;
641:
1.1.1.17! root 642: static uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr)
1.1.1.3 root 643: {
1.1.1.12 root 644: uae_u32 *m;
645: addr -= extendedkickmem_start & extendedkickmem_mask;
646: addr &= extendedkickmem_mask;
647: m = (uae_u32 *)(extendedkickmemory + addr);
648: return do_get_mem_long (m);
1.1.1.3 root 649: }
650:
1.1.1.17! root 651: static uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr)
1.1 root 652: {
1.1.1.12 root 653: uae_u16 *m;
654: addr -= extendedkickmem_start & extendedkickmem_mask;
655: addr &= extendedkickmem_mask;
656: m = (uae_u16 *)(extendedkickmemory + addr);
657: return do_get_mem_word (m);
658: }
1.1.1.3 root 659:
1.1.1.17! root 660: static uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr)
1.1.1.12 root 661: {
662: addr -= extendedkickmem_start & extendedkickmem_mask;
663: addr &= extendedkickmem_mask;
664: return extendedkickmemory[addr];
665: }
1.1.1.3 root 666:
1.1.1.17! root 667: static void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
1.1.1.12 root 668: {
669: if (currprefs.illegal_mem)
670: write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
671: }
1.1.1.3 root 672:
1.1.1.17! root 673: static void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
1.1.1.12 root 674: {
675: if (currprefs.illegal_mem)
676: write_log ("Illegal extendedkickmem wput at %08lx\n", addr);
677: }
1.1.1.3 root 678:
1.1.1.17! root 679: static void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
1.1.1.12 root 680: {
681: if (currprefs.illegal_mem)
682: write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
683: }
1.1.1.3 root 684:
1.1.1.17! root 685: static int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size)
1.1.1.12 root 686: {
687: addr -= extendedkickmem_start & extendedkickmem_mask;
688: addr &= extendedkickmem_mask;
689: return (addr + size) <= extendedkickmem_size;
690: }
1.1.1.3 root 691:
1.1.1.17! root 692: static uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr)
1.1.1.12 root 693: {
694: addr -= extendedkickmem_start & extendedkickmem_mask;
695: addr &= extendedkickmem_mask;
696: return extendedkickmemory + addr;
697: }
1.1.1.2 root 698:
1.1.1.12 root 699: /* Default memory access functions */
700:
701: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
702: {
703: return 0;
704: }
705:
706: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
707: {
708: write_log ("Your Amiga program just did something terribly stupid\n");
1.1.1.15 root 709: uae_reset (1);
1.1.1.17! root 710:
! 711: set_special (SPCFLAG_RESTORE_SANITY);
! 712: /* rtarea_bank has an infinite loop in m68k space, which we use to avoid a
! 713: * crash. */
! 714: return rtarea_bank.xlateaddr (0xF0FFC0);
1.1 root 715: }
716:
717: /* Address banks */
718:
719: addrbank dummy_bank = {
720: dummy_lget, dummy_wget, dummy_bget,
721: dummy_lput, dummy_wput, dummy_bput,
1.1.1.17! root 722: default_xlate, dummy_check, NULL, NULL
1.1.1.3 root 723: };
724:
1.1 root 725: addrbank chipmem_bank = {
726: chipmem_lget, chipmem_wget, chipmem_bget,
727: chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.17! root 728: chipmem_xlate, chipmem_check, NULL, "Chip memory"
1.1 root 729: };
730:
731: addrbank bogomem_bank = {
732: bogomem_lget, bogomem_wget, bogomem_bget,
733: bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.17! root 734: bogomem_xlate, bogomem_check, NULL, "Slow memory"
1.1 root 735: };
736:
1.1.1.17! root 737: addrbank a3000lmem_bank = {
! 738: a3000lmem_lget, a3000lmem_wget, a3000lmem_bget,
! 739: a3000lmem_lput, a3000lmem_wput, a3000lmem_bput,
! 740: a3000lmem_xlate, a3000lmem_check, NULL, "RAMSEY memory (low)"
! 741: };
! 742:
! 743: addrbank a3000hmem_bank = {
! 744: a3000hmem_lget, a3000hmem_wget, a3000hmem_bget,
! 745: a3000hmem_lput, a3000hmem_wput, a3000hmem_bput,
! 746: a3000hmem_xlate, a3000hmem_check, NULL, "RAMSEY memory (high)"
1.1.1.3 root 747: };
748:
1.1 root 749: addrbank kickmem_bank = {
750: kickmem_lget, kickmem_wget, kickmem_bget,
751: kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.17! root 752: kickmem_xlate, kickmem_check, NULL, "Kickstart ROM"
1.1 root 753: };
754:
1.1.1.12 root 755: addrbank extendedkickmem_bank = {
756: extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
757: extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
1.1.1.17! root 758: extendedkickmem_xlate, extendedkickmem_check, NULL, "Extended Kickstart ROM"
1.1.1.12 root 759: };
760:
761: static int kickstart_checksum (uae_u8 *mem, int size)
762: {
763: uae_u32 cksum = 0, prevck = 0;
764: int i;
765: for (i = 0; i < size; i += 4) {
766: uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
767: cksum += data;
768: if (cksum < prevck)
769: cksum++;
770: prevck = cksum;
771: }
772: if (cksum != 0xFFFFFFFFul) {
773: write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
774: }
775: return 0;
776: }
777:
1.1.1.17! root 778: static const char kickstring[] = "exec.library";
! 779:
! 780: static int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom)
1.1.1.12 root 781: {
782: unsigned char buffer[20];
1.1.1.17! root 783: int i, j, cr = 0;
1.1.1.12 root 784:
785: if (cloanto_rom)
786: *cloanto_rom = 0;
1.1.1.17! root 787: i = zfile_fread (buffer, 1, 11, f);
1.1.1.12 root 788: if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) {
1.1.1.17! root 789: zfile_fseek (f, 0, SEEK_SET);
1.1.1.12 root 790: } else {
791: cr = 1;
792: }
793:
1.1.1.17! root 794: if (cloanto_rom)
! 795: *cloanto_rom = cr;
! 796:
! 797: i = zfile_fread (mem, 1, size, f);
! 798:
! 799: if (i != 8192 && i != 65536 && i != 131072 && i != 262144 && i != 524288 && i != 524288 * 2 && i != 524288 * 4) {
! 800: gui_message ("Error while reading Kickstart ROM file.");
1.1.1.12 root 801: return 0;
802: }
1.1.1.17! root 803: if (i == size / 2)
! 804: memcpy (mem + size / 2, mem, size / 2);
! 805:
! 806: if (cr) {
! 807: if (!decode_cloanto_rom (mem, size, i, 0))
! 808: return 0;
! 809: }
! 810: if (currprefs.cs_a1000ram) {
! 811: int off = 0;
! 812: a1000_bootrom = xcalloc (262144, 1);
! 813: while (off + i < 262144) {
! 814: memcpy (a1000_bootrom + off, kickmemory, i);
! 815: off += i;
! 816: }
! 817: memset (kickmemory, 0, kickmem_size);
! 818: a1000_handle_kickstart (1);
! 819: dochecksum = 0;
! 820: i = 524288;
! 821: }
! 822:
! 823: zfile_fclose (f);
! 824:
! 825: for (j = 0; j < 256 && i >= 262144; j++) {
! 826: if (!memcmp (mem + j, kickstring, strlen (kickstring) + 1))
! 827: break;
! 828: }
1.1.1.12 root 829:
1.1.1.17! root 830: if (j == 256 || i < 262144)
! 831: dochecksum = 0;
! 832: if (dochecksum)
1.1.1.12 root 833: kickstart_checksum (mem, size);
1.1.1.17! root 834:
1.1.1.12 root 835: return 1;
836: }
837:
838: static int load_extendedkickstart (void)
839: {
1.1.1.17! root 840: struct zfile *f;
1.1.1.12 root 841: int size;
842:
843: if (strlen (currprefs.romextfile) == 0)
844: return 0;
845: f = zfile_open (currprefs.romextfile, "rb");
846: if (!f) {
847: write_log ("No extended Kickstart ROM found");
848: return 0;
849: }
850:
1.1.1.17! root 851: zfile_fseek (f, 0, SEEK_END);
! 852: size = zfile_ftell (f);
1.1.1.12 root 853: if (size > 300000)
854: extendedkickmem_size = 524288;
855: else
856: extendedkickmem_size = 262144;
1.1.1.17! root 857: zfile_fseek (f, 0, SEEK_SET);
1.1.1.12 root 858:
859: switch (extromtype ()) {
860: case EXTENDED_ROM_CDTV:
861: extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_f0");
862: extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
863: break;
864: case EXTENDED_ROM_CD32:
865: extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
866: extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
867: break;
868: }
869: read_kickstart (f, extendedkickmemory, 524288, 0, 0);
870: return 1;
871: }
872:
873:
1.1.1.17! root 874: static void kickstart_fix_checksum (uae_u8 *mem, int size)
! 875: {
! 876: uae_u32 cksum = 0, prevck = 0;
! 877: int i, ch = size == 524288 ? 0x7ffe8 : 0x3e;
! 878:
! 879: mem[ch] = 0;
! 880: mem[ch + 1] = 0;
! 881: mem[ch + 2] = 0;
! 882: mem[ch + 3] = 0;
! 883: for (i = 0; i < size; i+=4) {
! 884: uae_u32 data = (mem[i] << 24) | (mem[i + 1] << 16) | (mem[i + 2] << 8) | mem[i + 3];
! 885: cksum += data;
! 886: if (cksum < prevck)
! 887: cksum++;
! 888: prevck = cksum;
! 889: }
! 890: cksum ^= 0xffffffff;
! 891: mem[ch++] = cksum >> 24;
! 892: mem[ch++] = cksum >> 16;
! 893: mem[ch++] = cksum >> 8;
! 894: mem[ch++] = cksum >> 0;
! 895: }
! 896:
! 897: static int patch_shapeshifter (uae_u8 *kickmemory)
! 898: {
! 899: /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
! 900: * Changes 'lea $400,a0' and 'lea $1000,a0' to 'lea $3000,a0' for
! 901: * ShapeShifter compatability.
! 902: */
! 903: int i, patched = 0;
! 904: uae_u8 kickshift1[] = { 0x41, 0xf8, 0x04, 0x00 };
! 905: uae_u8 kickshift2[] = { 0x41, 0xf8, 0x10, 0x00 };
! 906: uae_u8 kickshift3[] = { 0x43, 0xf8, 0x04, 0x00 };
! 907:
! 908: for (i = 0x200; i < 0x300; i++) {
! 909: if (!memcmp (kickmemory + i, kickshift1, sizeof (kickshift1)) ||
! 910: !memcmp (kickmemory + i, kickshift2, sizeof (kickshift2)) ||
! 911: !memcmp (kickmemory + i, kickshift3, sizeof (kickshift3))) {
! 912: kickmemory[i + 2] = 0x30;
! 913: write_log ("Kickstart KickShifted @%04.4X\n", i);
! 914: patched++;
! 915: }
! 916: }
! 917: return patched;
! 918: }
! 919:
! 920: /* disable incompatible drivers */
! 921: static int patch_residents (uae_u8 *kickmemory, int size)
! 922: {
! 923: int i, j, patched = 0;
! 924: char *residents[] = {
! 925: "NCR scsi.device",
! 926: "scsi.device", "carddisk.device", "card.resource",
! 927: NULL
! 928: };
! 929: uaecptr base = size == 524288 ? 0xf80000 : 0xfc0000;
! 930:
! 931: for (i = 0; i < size - 100; i++) {
! 932: if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
! 933: uaecptr addr;
! 934: addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
! 935: if (addr != i + base)
! 936: continue;
! 937: addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
! 938: if (addr >= base && addr < base + size) {
! 939: j = 0;
! 940: while (residents[j]) {
! 941: if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
! 942: write_log ("KSPatcher: '%s' at %08.8X disabled\n", residents[j], i + base);
! 943: kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
! 944: patched++;
! 945: break;
! 946: }
! 947: j++;
! 948: }
! 949: }
! 950: }
! 951: }
! 952: return patched;
! 953: }
! 954:
! 955: static void patch_kick(void)
! 956: {
! 957: int patched = 0;
! 958: if (kickmem_size >= 524288 && currprefs.kickshifter)
! 959: patched += patch_shapeshifter (kickmemory);
! 960: patched += patch_residents (kickmemory, kickmem_size);
! 961: if (extendedkickmemory) {
! 962: patched += patch_residents (extendedkickmemory, extendedkickmem_size);
! 963: if (patched)
! 964: kickstart_fix_checksum (extendedkickmemory, extendedkickmem_size);
! 965: }
! 966: if (patched)
! 967: kickstart_fix_checksum (kickmemory, kickmem_size);
! 968: }
! 969:
1.1.1.12 root 970: static int load_kickstart (void)
971: {
1.1.1.17! root 972: struct zfile *f = NULL;
! 973: int i;
! 974:
! 975: if (currprefs.rom_crc32) {
! 976: for (i = 0;; i++) {
! 977: struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1);
! 978: if (!rl)
! 979: break;
! 980: if (rl->rd->crc32 == currprefs.rom_crc32) {
! 981: f = zfile_open (rl->path, "rb");
! 982: break;
! 983: }
! 984: }
! 985: } else
! 986: f = zfile_open (currprefs.romfile, "rb");
1.1.1.12 root 987:
988: if (f == NULL) {
1.1.1.17! root 989: #if defined (AMIGA)
1.1.1.12 root 990: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
991: if (!getenv (USE_UAE_ERSATZ)) {
992: write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
993: memcpy (kickmemory, (char *) 0x1000000 - kickmem_size, kickmem_size);
994: kickstart_checksum (kickmemory, kickmem_size);
995: goto chk_sum;
996: }
997: #endif
998: return 0;
999: }
1000:
1001: if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom))
1002: return 0;
1003:
1.1.1.17! root 1004: #if defined (AMIGA)
1.1.1.12 root 1005: chk_sum:
1006: #endif
1.1.1.17! root 1007: kickstart_version = (kickmemory[12] << 8) | kickmemory[13];
1.1.1.12 root 1008:
1009: return 1;
1010: }
1011:
1.1 root 1012: char *address_space, *good_address_map;
1013: int good_address_fd;
1.1.1.4 root 1014:
1.1.1.9 root 1015: #ifndef NATMEM_OFFSET
1016:
1.1.1.12 root 1017: uae_u8 *mapped_malloc (size_t s, char *file)
1.1.1.4 root 1018: {
1.1.1.13 root 1019: return calloc (s, 1);
1.1.1.4 root 1020: }
1021:
1.1.1.9 root 1022: void mapped_free (uae_u8 *p)
1.1 root 1023: {
1.1.1.9 root 1024: free (p);
1025: }
1026: #else
1.1.1.3 root 1027:
1.1.1.9 root 1028: #include <sys/ipc.h>
1029: #include <sys/shm.h>
1030: #include <unistd.h>
1031: #include <sys/mman.h>
1032:
1.1.1.12 root 1033: shmpiece *shm_start = NULL;
1034: int canbang = 1;
1.1.1.9 root 1035:
1.1.1.12 root 1036: static void dumplist (void)
1.1.1.9 root 1037: {
1.1.1.12 root 1038: shmpiece *x = shm_start;
1.1.1.9 root 1039: printf ("Start Dump:\n");
1040: while (x) {
1041: printf (" this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
1.1.1.12 root 1042: x, x->native_address, x->id, x->prev, x->next, x->size);
1.1.1.9 root 1043: x = x->next;
1.1.1.2 root 1044: }
1.1.1.9 root 1045: printf ("End Dump:\n");
1046: }
1.1 root 1047:
1.1.1.9 root 1048: static shmpiece *find_shmpiece (uae_u8 *base)
1049: {
1050: shmpiece *x = shm_start;
1.1 root 1051:
1.1.1.9 root 1052: while (x && x->native_address != base)
1053: x = x->next;
1054: if (!x) {
1.1.1.12 root 1055: printf ("NATMEM: Failure to find mapping at %p\n", base);
1056: dumplist ();
1.1.1.9 root 1057: canbang = 0;
1058: return 0;
1059: }
1060: return x;
1061: }
1.1.1.3 root 1062:
1.1.1.9 root 1063: static void delete_shmmaps (uae_u32 start, uae_u32 size)
1064: {
1065: if (!canbang)
1066: return;
1067:
1068: while (size) {
1.1.1.12 root 1069: uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1.1.1.9 root 1070: if (base) {
1071: shmpiece *x;
1.1.1.12 root 1072: base = ((uae_u8 *) NATMEM_OFFSET) + start;
1.1.1.9 root 1073:
1074: x = find_shmpiece (base);
1.1.1.12 root 1075: if (!x)
1.1.1.9 root 1076: return;
1077:
1078: if (x->size > size) {
1.1.1.17! root 1079: printf ("NATMEM: Failure to delete mapping at %08x (size %08x, delsize %08x)\n", start, x->size, size);
1.1.1.12 root 1080: dumplist ();
1.1.1.9 root 1081: canbang = 0;
1082: return;
1083: }
1084: shmdt (x->native_address);
1085: size -= x->size;
1086: start += x->size;
1087: if (x->next)
1.1.1.12 root 1088: x->next->prev = x->prev; /* remove this one from the list */
1.1.1.9 root 1089: if (x->prev)
1090: x->prev->next = x->next;
1091: else
1092: shm_start = x->next;
1.1.1.12 root 1093: free (x);
1.1.1.9 root 1094: } else {
1095: size -= 0x10000;
1096: start += 0x10000;
1097: }
1.1.1.3 root 1098: }
1.1.1.9 root 1099: }
1.1.1.12 root 1100:
1.1.1.9 root 1101: static void add_shmmaps (uae_u32 start, addrbank *what)
1102: {
1103: shmpiece *x = shm_start;
1104: shmpiece *y;
1105: uae_u8 *base = what->baseaddr;
1106:
1107: if (!canbang)
1108: return;
1109: if (!base)
1110: return;
1111:
1112: x = find_shmpiece (base);
1.1.1.12 root 1113: if (!x)
1.1.1.9 root 1114: return;
1115: y = malloc (sizeof (shmpiece));
1116: *y = *x;
1.1.1.12 root 1117: base = ((uae_u8 *) NATMEM_OFFSET) + start;
1118: y->native_address = shmat (y->id, base, 0);
1119: if (y->native_address == (void *) -1) {
1.1.1.17! root 1120: printf ("NATMEM: Failure to map existing at %08x (%p)\n", start, base);
1.1.1.12 root 1121: perror ("shmat");
1122: dumplist ();
1.1.1.9 root 1123: canbang = 0;
1124: return;
1.1.1.2 root 1125: }
1.1.1.9 root 1126: y->next = shm_start;
1127: y->prev = NULL;
1128: if (y->next)
1129: y->next->prev = y;
1130: shm_start = y;
1131: }
1132:
1133: uae_u8 *mapped_malloc (size_t s, char *file)
1134: {
1.1.1.12 root 1135: int id;
1.1.1.9 root 1136: void *answer;
1137: shmpiece *x;
1138:
1.1.1.12 root 1139: if (!canbang)
1.1.1.9 root 1140: return malloc (s);
1141:
1.1.1.12 root 1142: id = shmget (IPC_PRIVATE, s, 0x1ff, file);
1.1.1.9 root 1143: if (id == 1) {
1144: canbang = 0;
1145: return mapped_malloc (s, file);
1146: }
1.1.1.12 root 1147: answer = shmat (id, 0, 0);
1148: shmctl (id, IPC_RMID, NULL);
1149: if (answer != (void *) -1) {
1150: x = malloc (sizeof (shmpiece));
1.1.1.9 root 1151: x->native_address = answer;
1152: x->id = id;
1153: x->size = s;
1154: x->next = shm_start;
1155: x->prev = NULL;
1156: if (x->next)
1157: x->next->prev = x;
1158: shm_start = x;
1159:
1160: return answer;
1161: }
1162: canbang = 0;
1163: return mapped_malloc (s, file);
1164: }
1165:
1.1.1.10 root 1166: void mapped_free (uae_u8 *base)
1.1.1.9 root 1167: {
1168: shmpiece *x = find_shmpiece (base);
1.1.1.12 root 1169: if (!x)
1.1.1.9 root 1170: abort ();
1171: shmdt (x->native_address);
1172: }
1173:
1.1 root 1174: #endif
1.1.1.6 root 1175:
1.1.1.9 root 1176: static void init_mem_banks (void)
1177: {
1178: int i;
1179: for (i = 0; i < 65536; i++)
1180: put_mem_bank (i << 16, &dummy_bank, 0);
1181: }
1182:
1183: static void allocate_memory (void)
1184: {
1185: if (allocated_chipmem != currprefs.chipmem_size) {
1.1.1.17! root 1186: int memsize;
1.1.1.9 root 1187: if (chipmemory)
1188: mapped_free (chipmemory);
1189: chipmemory = 0;
1190:
1.1.1.17! root 1191: memsize = allocated_chipmem = currprefs.chipmem_size;
1.1.1.9 root 1192: chipmem_mask = allocated_chipmem - 1;
1193:
1.1.1.17! root 1194: if (memsize < 0x100000)
! 1195: memsize = 0x100000;
! 1196: chipmemory = mapped_malloc (memsize, "chip");
1.1.1.9 root 1197: if (chipmemory == 0) {
1198: write_log ("Fatal error: out of memory for chipmem.\n");
1199: allocated_chipmem = 0;
1.1.1.17! root 1200: } else {
! 1201: need_hardreset = 1;
! 1202: if (memsize != allocated_chipmem)
! 1203: memset (chipmemory + allocated_chipmem, 0xff, memsize - allocated_chipmem);
! 1204: }
1.1.1.9 root 1205: }
1206:
1.1.1.17! root 1207: chipmem_full_mask = allocated_chipmem - 1;
! 1208: if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && allocated_chipmem < 0x100000)
! 1209: chipmem_full_mask = 0x100000 - 1;
! 1210:
1.1.1.9 root 1211: if (allocated_bogomem != currprefs.bogomem_size) {
1212: if (bogomemory)
1213: mapped_free (bogomemory);
1214: bogomemory = 0;
1215:
1216: allocated_bogomem = currprefs.bogomem_size;
1217: bogomem_mask = allocated_bogomem - 1;
1218:
1219: if (allocated_bogomem) {
1220: bogomemory = mapped_malloc (allocated_bogomem, "bogo");
1221: if (bogomemory == 0) {
1222: write_log ("Out of memory for bogomem.\n");
1223: allocated_bogomem = 0;
1224: }
1225: }
1.1.1.17! root 1226: need_hardreset = 1;
1.1.1.9 root 1227: }
1.1.1.17! root 1228:
! 1229: if (allocated_a3000lmem != currprefs.mbresmem_low_size) {
! 1230: if (a3000lmemory)
! 1231: mapped_free (a3000lmemory);
! 1232: a3000lmemory = 0;
! 1233:
! 1234: allocated_a3000lmem = currprefs.mbresmem_low_size;
! 1235: a3000lmem_mask = allocated_a3000lmem - 1;
! 1236: a3000lmem_start = 0x08000000 - allocated_a3000lmem;
! 1237: if (allocated_a3000lmem) {
! 1238: a3000lmemory = mapped_malloc (allocated_a3000lmem, "ramsey_low");
! 1239: if (a3000lmemory == 0) {
! 1240: write_log ("Out of memory for a3000lowmem.\n");
! 1241: allocated_a3000lmem = 0;
! 1242: }
! 1243: }
! 1244: need_hardreset = 1;
! 1245: }
! 1246:
! 1247: if (allocated_a3000hmem != currprefs.mbresmem_high_size) {
! 1248: if (a3000hmemory)
! 1249: mapped_free (a3000hmemory);
! 1250: a3000hmemory = 0;
! 1251:
! 1252: allocated_a3000hmem = currprefs.mbresmem_high_size;
! 1253: a3000hmem_mask = allocated_a3000hmem - 1;
! 1254: a3000hmem_start = 0x08000000;
! 1255: if (allocated_a3000hmem) {
! 1256: a3000hmemory = mapped_malloc (allocated_a3000hmem, "ramsey_high");
! 1257: if (a3000hmemory == 0) {
! 1258: write_log ("Out of memory for a3000highmem.\n");
! 1259: allocated_a3000hmem = 0;
1.1.1.9 root 1260: }
1261: }
1.1.1.17! root 1262: need_hardreset = 1;
1.1.1.9 root 1263: }
1264:
1265: if (savestate_state == STATE_RESTORE) {
1.1.1.17! root 1266: restore_ram (chip_filepos, chipmemory);
1.1.1.9 root 1267: if (allocated_bogomem > 0) {
1.1.1.17! root 1268: restore_ram (bogo_filepos, bogomemory);
1.1.1.9 root 1269: }
1.1.1.17! root 1270: if (allocated_a3000lmem > 0)
! 1271: restore_ram (a3000lmem_filepos, a3000lmemory);
! 1272: if (allocated_a3000hmem > 0)
! 1273: restore_ram (a3000hmem_filepos, a3000hmemory);
1.1.1.9 root 1274: }
1275: chipmem_bank.baseaddr = chipmemory;
1276: bogomem_bank.baseaddr = bogomemory;
1.1.1.17! root 1277: a3000lmem_bank.baseaddr = a3000lmemory;
! 1278: a3000hmem_bank.baseaddr = a3000hmemory;
! 1279: }
! 1280:
! 1281: void map_overlay (int chip)
! 1282: {
! 1283: int i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
! 1284: addrbank *cb;
! 1285:
! 1286: cb = &chipmem_bank;
! 1287: if (chip)
! 1288: map_banks (cb, 0, i, allocated_chipmem);
! 1289: else
! 1290: map_banks (&kickmem_bank, 0, i, 0x80000);
! 1291: if (savestate_state != STATE_RESTORE)
! 1292: m68k_setpc (m68k_getpc ());
1.1.1.9 root 1293: }
1294:
1295: void memory_reset (void)
1296: {
1.1.1.17! root 1297: int bnk, bnk_end;
1.1.1.9 root 1298:
1299: #ifdef NATMEM_OFFSET
1300: delete_shmmaps (0, 0xFFFF0000);
1301: #endif
1.1.1.4 root 1302: init_mem_banks ();
1.1.1.3 root 1303:
1.1.1.9 root 1304: currprefs.chipmem_size = changed_prefs.chipmem_size;
1305: currprefs.bogomem_size = changed_prefs.bogomem_size;
1.1.1.17! root 1306: currprefs.mbresmem_low_size = changed_prefs.mbresmem_low_size;
! 1307: currprefs.mbresmem_high_size = changed_prefs.mbresmem_high_size;
! 1308: currprefs.chipset_mask = changed_prefs.chipset_mask;
! 1309: currprefs.cs_a1000ram = changed_prefs.cs_a1000ram;
! 1310: currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev;
! 1311: currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev;
! 1312: currprefs.cs_ide = changed_prefs.cs_ide;
! 1313: currprefs.bootrom = changed_prefs.bootrom;
! 1314:
! 1315: need_hardreset = 0;
! 1316: /* Use changed_prefs, as m68k_reset is called later. */
! 1317: if (last_address_space_24 != changed_prefs.address_space_24)
! 1318: need_hardreset = 1;
1.1.1.9 root 1319:
1.1.1.17! root 1320: last_address_space_24 = changed_prefs.address_space_24;
1.1.1.9 root 1321: allocate_memory ();
1322:
1.1.1.17! root 1323: if (currprefs.rom_crc32 != changed_prefs.rom_crc32
! 1324: || strcmp (currprefs.romfile, changed_prefs.romfile) != 0
! 1325: || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0)
! 1326: {
1.1.1.10 root 1327: ersatzkickfile = 0;
1.1.1.17! root 1328: a1000_handle_kickstart (0);
! 1329: free (a1000_bootrom);
! 1330: a1000_bootrom = 0;
! 1331: a1000_kickstart_mode = 0;
! 1332:
! 1333: currprefs.rom_crc32 = changed_prefs.rom_crc32;
1.1.1.10 root 1334: memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
1335: memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
1.1.1.17! root 1336: need_hardreset = 1;
1.1.1.12 root 1337: if (!load_kickstart ()) {
1.1.1.10 root 1338: init_ersatz_rom (kickmemory);
1339: ersatzkickfile = 1;
1340: }
1.1.1.17! root 1341: patch_kick ();
1.1.1.12 root 1342: }
1.1 root 1343:
1.1.1.17! root 1344: map_banks (&custom_bank, 0xC0, 0xE0 - 0xC0, 0);
1.1.1.9 root 1345: map_banks (&cia_bank, 0xA0, 32, 0);
1.1.1.17! root 1346: if (!currprefs.cs_a1000ram)
! 1347: /* D80000 - DDFFFF not mapped (A1000 = custom chips) */
! 1348: map_banks (&dummy_bank, 0xD8, 6, 0);
! 1349:
! 1350: /* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if PCMCIA or AGA) */
! 1351: bnk = allocated_chipmem >> 16;
! 1352: if (bnk < 0x20)
! 1353: bnk = 0x20;
! 1354: bnk_end = (currprefs.chipset_mask & CSMASK_AGA) ? 0xBF : 0xA0;
! 1355: map_banks (&dummy_bank, bnk, bnk_end - bnk, 0);
! 1356: if (currprefs.chipset_mask & CSMASK_AGA)
! 1357: map_banks (&dummy_bank, 0xc0, 0xd8 - 0xc0, 0);
1.1.1.3 root 1358:
1.1.1.9 root 1359: if (bogomemory != 0) {
1360: int t = allocated_bogomem >> 16;
1361: if (t > 0x1C)
1362: t = 0x1C;
1.1.1.17! root 1363: if (t > 0x10 && ((currprefs.chipset_mask & CSMASK_AGA) || currprefs.cpu_model >= 68020))
! 1364: t = 0x10;
1.1.1.9 root 1365: map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
1366: }
1.1.1.17! root 1367: if (currprefs.cs_ide) {
! 1368: if (currprefs.cs_ide == 1) {
! 1369: map_banks (&gayle_bank, 0xD8, 6, 0);
! 1370: map_banks (&gayle2_bank, 0xDD, 2, 0);
! 1371: // map_banks (&gayle_attr_bank, 0xA0, 8, 0); only if PCMCIA card inserted */
! 1372: }
! 1373: if (currprefs.cs_ide == 2) {
! 1374: map_banks (&gayle_bank, 0xDD, 1, 0);
! 1375: }
! 1376: if (currprefs.cs_ide < 0) {
! 1377: map_banks (&gayle_bank, 0xD8, 6, 0);
! 1378: map_banks (&gayle_bank, 0xDD, 1, 0);
! 1379: }
! 1380: }
! 1381: if (currprefs.cs_rtc)
! 1382: map_banks (&clock_bank, 0xDC, 1, 0);
! 1383: if (currprefs.cs_fatgaryrev >= 0 || currprefs.cs_ramseyrev >= 0)
! 1384: map_banks (&mbres_bank, 0xDE, 1, 0);
! 1385:
! 1386: if (a3000lmemory != 0)
! 1387: map_banks (&a3000lmem_bank, a3000lmem_start >> 16, allocated_a3000lmem >> 16, 0);
! 1388: if (a3000hmemory != 0)
! 1389: map_banks (&a3000hmem_bank, a3000hmem_start >> 16, allocated_a3000hmem >> 16, 0);
! 1390:
! 1391: if (currprefs.bootrom) {
! 1392: uae_boot_rom = 1;
! 1393: map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
! 1394: } else
! 1395: uae_boot_rom = 0;
1.1.1.9 root 1396:
1397: map_banks (&kickmem_bank, 0xF8, 8, 0);
1.1.1.17! root 1398:
! 1399: a1000_reset ();
1.1.1.9 root 1400: map_banks (&expamem_bank, 0xE8, 1, 0);
1401:
1.1.1.17! root 1402: /* Map the chipmem into all of the lower 8MB */
! 1403: map_overlay (1);
! 1404:
1.1.1.12 root 1405: switch (extromtype ()) {
1406: case EXTENDED_ROM_CDTV:
1407: map_banks (&extendedkickmem_bank, 0xF0, 4, 0);
1408: break;
1409: case EXTENDED_ROM_CD32:
1410: map_banks (&extendedkickmem_bank, 0xE0, 8, 0);
1411: break;
1412: default:
1413: if (cloanto_rom)
1414: map_banks (&kickmem_bank, 0xE0, 8, 0);
1415: }
1.1.1.17! root 1416:
! 1417: if (need_hardreset)
! 1418: memory_hardreset ();
1.1.1.9 root 1419: }
1420:
1421: void memory_init (void)
1422: {
1423: allocated_chipmem = 0;
1424: allocated_bogomem = 0;
1425: kickmemory = 0;
1.1.1.12 root 1426: extendedkickmemory = 0;
1.1.1.9 root 1427: chipmemory = 0;
1.1.1.17! root 1428: allocated_a3000lmem = allocated_a3000hmem = 0;
! 1429: a3000lmemory = a3000hmemory = 0;
1.1.1.9 root 1430: bogomemory = 0;
1431:
1432: kickmemory = mapped_malloc (kickmem_size, "kick");
1433: kickmem_bank.baseaddr = kickmemory;
1.1.1.3 root 1434:
1.1.1.12 root 1435: load_extendedkickstart ();
1436: if (!load_kickstart ()) {
1.1.1.3 root 1437: init_ersatz_rom (kickmemory);
1.1 root 1438: ersatzkickfile = 1;
1439: }
1.1.1.3 root 1440:
1.1.1.9 root 1441: init_mem_banks ();
1442: memory_reset ();
1.1.1.4 root 1443:
1444: kickmem_mask = kickmem_size - 1;
1.1.1.12 root 1445: extendedkickmem_mask = extendedkickmem_size - 1;
1.1 root 1446: }
1447:
1.1.1.12 root 1448: void memory_cleanup (void)
1.1.1.10 root 1449: {
1.1.1.17! root 1450: if (a3000lmemory)
! 1451: mapped_free (a3000lmemory);
! 1452: if (a3000hmemory)
! 1453: mapped_free (a3000hmemory);
1.1.1.10 root 1454: if (bogomemory)
1455: mapped_free (bogomemory);
1456: if (kickmemory)
1457: mapped_free (kickmemory);
1.1.1.12 root 1458: if (a1000_bootrom)
1459: free (a1000_bootrom);
1.1.1.10 root 1460: if (chipmemory)
1461: mapped_free (chipmemory);
1.1.1.12 root 1462:
1.1.1.17! root 1463: a3000lmemory = a3000hmemory = 0;
1.1.1.10 root 1464: bogomemory = 0;
1465: kickmemory = 0;
1.1.1.12 root 1466: a1000_bootrom = 0;
1.1.1.10 root 1467: chipmemory = 0;
1468: }
1469:
1.1.1.17! root 1470: void memory_hardreset (void)
! 1471: {
! 1472: if (savestate_state == STATE_RESTORE)
! 1473: return;
! 1474: if (chipmemory)
! 1475: memset (chipmemory, 0, allocated_chipmem);
! 1476: if (bogomemory)
! 1477: memset (bogomemory, 0, allocated_bogomem);
! 1478: if (a3000lmemory)
! 1479: memset (a3000lmemory, 0, allocated_a3000lmem);
! 1480: if (a3000hmemory)
! 1481: memset (a3000hmemory, 0, allocated_a3000hmem);
! 1482: expansion_clear ();
! 1483: }
! 1484:
1.1.1.9 root 1485: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1 root 1486: {
1487: int bnr;
1.1.1.3 root 1488: unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.12 root 1489: addrbank *orgbank = bank;
1.1.1.9 root 1490: uae_u32 realstart = start;
1.1.1.12 root 1491:
1492: flush_icache (1); /* Sure don't want to keep any old mappings around! */
1.1.1.9 root 1493: #ifdef NATMEM_OFFSET
1494: delete_shmmaps (start << 16, size << 16);
1495: #endif
1.1.1.12 root 1496:
1.1.1.9 root 1497: if (!realsize)
1498: realsize = size << 16;
1499:
1500: if ((size << 16) < realsize) {
1.1.1.11 root 1501: write_log ("Please report to [email protected], and mention:\n");
1.1.1.12 root 1502: write_log ("Broken mapping, size=%x, realsize=%x\n", size, realsize);
1503: write_log ("Start is %x\n", start);
1.1.1.11 root 1504: write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9 root 1505: abort ();
1506: }
1.1.1.3 root 1507:
1508: if (start >= 0x100) {
1.1.1.10 root 1509: int real_left = 0;
1.1.1.9 root 1510: for (bnr = start; bnr < start + size; bnr++) {
1511: if (!real_left) {
1512: realstart = bnr;
1.1.1.12 root 1513: real_left = realsize >> 16;
1.1.1.9 root 1514: #ifdef NATMEM_OFFSET
1515: add_shmmaps (realstart << 16, bank);
1516: #endif
1517: }
1.1.1.12 root 1518: put_mem_bank (bnr << 16, bank, realstart << 16);
1.1.1.9 root 1519: real_left--;
1520: }
1.1.1.3 root 1521: return;
1522: }
1.1.1.17! root 1523: /* Already in currprefs, since we get called after m68k_reset. */
! 1524: if (last_address_space_24)
1.1.1.10 root 1525: endhioffs = 0x10000;
1.1.1.9 root 1526: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10 root 1527: int real_left = 0;
1.1.1.12 root 1528: for (bnr = start; bnr < start + size; bnr++) {
1.1.1.9 root 1529: if (!real_left) {
1530: realstart = bnr + hioffs;
1531: real_left = realsize >> 16;
1532: #ifdef NATMEM_OFFSET
1533: add_shmmaps (realstart << 16, bank);
1534: #endif
1535: }
1.1.1.12 root 1536: put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1.1.1.9 root 1537: real_left--;
1538: }
1539: }
1540: }
1541:
1542:
1543: /* memory save/restore code */
1544:
1545: uae_u8 *save_cram (int *len)
1546: {
1547: *len = allocated_chipmem;
1548: return chipmemory;
1549: }
1550:
1551: uae_u8 *save_bram (int *len)
1552: {
1553: *len = allocated_bogomem;
1554: return bogomemory;
1555: }
1556:
1.1.1.17! root 1557: uae_u8 *save_a3000lram (int *len)
! 1558: {
! 1559: *len = allocated_a3000lmem;
! 1560: return a3000lmemory;
! 1561: }
! 1562:
! 1563: uae_u8 *save_a3000hram (int *len)
! 1564: {
! 1565: *len = allocated_a3000hmem;
! 1566: return a3000hmemory;
! 1567: }
! 1568:
1.1.1.9 root 1569: void restore_cram (int len, long filepos)
1570: {
1571: chip_filepos = filepos;
1572: changed_prefs.chipmem_size = len;
1573: }
1574:
1575: void restore_bram (int len, long filepos)
1576: {
1577: bogo_filepos = filepos;
1578: changed_prefs.bogomem_size = len;
1579: }
1580:
1.1.1.17! root 1581: void restore_a3000lram (int len, size_t filepos)
! 1582: {
! 1583: a3000lmem_filepos = filepos;
! 1584: changed_prefs.mbresmem_low_size = len;
! 1585: }
! 1586:
! 1587: void restore_a3000hram (int len, size_t filepos)
! 1588: {
! 1589: a3000hmem_filepos = filepos;
! 1590: changed_prefs.mbresmem_high_size = len;
! 1591: }
! 1592:
1.1.1.16 root 1593: const uae_u8 *restore_rom (const uae_u8 *src)
1.1.1.9 root 1594: {
1.1.1.17! root 1595: struct romdata *rom;
1.1.1.15 root 1596: uae_u32 crc32;
1.1.1.17! root 1597: char *romname;
1.1.1.15 root 1598: int i;
1599:
1.1.1.9 root 1600: restore_u32 ();
1601: restore_u32 ();
1602: restore_u32 ();
1603: restore_u32 ();
1.1.1.15 root 1604: crc32 = restore_u32 ();
1605:
1.1.1.17! root 1606: rom = getromdatabycrc (crc32);
! 1607: if (rom)
! 1608: changed_prefs.rom_crc32 = crc32;
1.1.1.9 root 1609:
1610: return src;
1611: }
1612:
1.1.1.15 root 1613: uae_u8 *save_rom (int first, int *len, uae_u8 *dstptr)
1.1.1.9 root 1614: {
1615: static int count;
1616: uae_u8 *dst, *dstbak;
1617: uae_u8 *mem_real_start;
1618: int mem_start, mem_size, mem_type, i, saverom;
1619:
1620: saverom = 0;
1.1.1.12 root 1621: if (first)
1622: count = 0;
1.1.1.9 root 1623: for (;;) {
1624: mem_type = count;
1.1.1.12 root 1625: switch (count) {
1626: case 0: /* Kickstart ROM */
1.1.1.9 root 1627: mem_start = 0xf80000;
1628: mem_real_start = kickmemory;
1629: mem_size = kickmem_size;
1630: /* 256KB or 512KB ROM? */
1.1.1.12 root 1631: for (i = 0; i < mem_size / 2 - 4; i++) {
1632: if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
1633: break;
1.1.1.9 root 1634: }
1.1.1.12 root 1635: if (i == mem_size / 2 - 4) {
1.1.1.9 root 1636: mem_size /= 2;
1637: mem_start += 262144;
1638: }
1639: mem_type = 0;
1640: break;
1.1.1.12 root 1641: default:
1.1.1.9 root 1642: return 0;
1643: }
1.1.1.12 root 1644: count++;
1645: if (mem_size)
1646: break;
1.1.1.9 root 1647: }
1.1.1.15 root 1648: if (dstptr)
1649: dstbak = dst = dstptr;
1650: else
1651: dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
1.1.1.9 root 1652: save_u32 (mem_start);
1653: save_u32 (mem_size);
1654: save_u32 (mem_type);
1.1.1.12 root 1655: save_u32 (longget (mem_start + 12)); /* version+revision */
1.1.1.15 root 1656: save_u32 (get_crc32 (kickmemory, mem_size));
1.1.1.12 root 1657: sprintf (dst, "Kickstart %d.%d", wordget (mem_start + 12), wordget (mem_start + 14));
1.1.1.9 root 1658: dst += strlen (dst) + 1;
1659: if (saverom) {
1.1.1.12 root 1660: for (i = 0; i < mem_size; i++)
1661: *dst++ = byteget (mem_start + i);
1.1.1.9 root 1662: }
1663: *len = dst - dstbak;
1664: return dstbak;
1.1 root 1665: }
1.1.1.17! root 1666:
! 1667: /* memory helpers */
! 1668:
! 1669: static int addr_valid (char *txt, uaecptr addr, uae_u32 len)
! 1670: {
! 1671: addrbank *ab = &get_mem_bank (addr);
! 1672: if (ab == 0 || addr < 0x100
! 1673: || len < 0 || len > 16777215 || !valid_address (addr, len)) {
! 1674: write_log ("corrupt %s pointer %x (%d) detected!\n", txt, addr, len);
! 1675: return 0;
! 1676: }
! 1677: return 1;
! 1678: }
! 1679:
! 1680: void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size)
! 1681: {
! 1682: if (!addr_valid ("memcpyha", dst, size))
! 1683: return;
! 1684: while (size--)
! 1685: put_byte (dst++, *src++);
! 1686: }
! 1687:
! 1688: void memcpyha (uaecptr dst, const uae_u8 *src, int size)
! 1689: {
! 1690: while (size--)
! 1691: put_byte (dst++, *src++);
! 1692: }
! 1693:
! 1694: void memcpyah_safe (uae_u8 *dst, uaecptr src, int size)
! 1695: {
! 1696: if (!addr_valid ("memcpyah", src, size))
! 1697: return;
! 1698: while (size--)
! 1699: *dst++ = get_byte (src++);
! 1700: }
! 1701:
! 1702: void memcpyah (uae_u8 *dst, uaecptr src, int size)
! 1703: {
! 1704: while (size--)
! 1705: *dst++ = get_byte (src++);
! 1706: }
! 1707:
! 1708: char *strcpyah_safe (char *dst, uaecptr src)
! 1709: {
! 1710: char *res = dst;
! 1711: uae_u8 b;
! 1712: do {
! 1713: if (!addr_valid ("strcpyah", src, 1))
! 1714: return res;
! 1715: b = get_byte (src++);
! 1716: *dst++ = b;
! 1717: } while (b);
! 1718: return res;
! 1719: }
! 1720:
! 1721: uaecptr strcpyha_safe (uaecptr dst, const char *src)
! 1722: {
! 1723: uaecptr res = dst;
! 1724: uae_u8 b;
! 1725: do {
! 1726: if (!addr_valid ("strcpyha", dst, 1))
! 1727: return res;
! 1728: b = *src++;
! 1729: put_byte (dst++, b);
! 1730: } while (b);
! 1731: return res;
! 1732: }
! 1733:
! 1734: uae_u32 strncpyha (uae_u32 dst, const char *src, int size)
! 1735: {
! 1736: uae_u32 res = dst;
! 1737: while (size--) {
! 1738: put_byte (dst++, *src);
! 1739: if (!*src++)
! 1740: return res;
! 1741: }
! 1742: return res;
! 1743: }
! 1744:
! 1745: uae_u32 strncpyha_safe (uae_u32 dst, const char *src, int size)
! 1746: {
! 1747: uae_u32 res = dst;
! 1748: while (size--) {
! 1749: if (!addr_valid ("strcpyha", dst, 1))
! 1750: return res;
! 1751: put_byte (dst++, *src);
! 1752: if (!*src++)
! 1753: return res;
! 1754: }
! 1755: return res;
! 1756: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.