|
|
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 "config.h"
13: #include "options.h"
1.1.1.3 root 14: #include "uae.h"
1.1 root 15: #include "memory.h"
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 root 23:
1.1.1.2 root 24: #ifdef USE_MAPPED_MEMORY
1.1 root 25: #include <sys/mman.h>
26: #endif
27:
1.1.1.8 root 28: /* Set by each memory handler that does not simply access real memory. */
29: int special_mem;
30:
1.1 root 31: int ersatzkickfile = 0;
32:
1.1.1.4 root 33: uae_u32 allocated_chipmem;
34: uae_u32 allocated_fastmem;
35: uae_u32 allocated_bogomem;
36: uae_u32 allocated_gfxmem;
37: uae_u32 allocated_z3fastmem;
38: uae_u32 allocated_a3000mem;
39:
1.1.1.9 root 40: static long chip_filepos;
41: static long bogo_filepos;
42: static long rom_filepos;
43:
1.1.1.3 root 44: addrbank *mem_banks[65536];
1.1.1.9 root 45:
46: /* This has two functions. It either holds a host address that, when added
47: to the 68k address, gives the host address corresponding to that 68k
48: address (in which case the value in this array is even), OR it holds the
49: same value as mem_banks, for those banks that have baseaddr==0. In that
50: case, bit 0 is set (the memory access routines will take care of it). */
51:
52: uae_u8 *baseaddr[65536];
1.1 root 53:
1.1.1.2 root 54: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5 root 55: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2 root 56: {
1.1.1.5 root 57: return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2 root 58: }
1.1.1.5 root 59: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2 root 60: {
1.1.1.5 root 61: return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2 root 62: }
1.1.1.5 root 63: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2 root 64: {
1.1.1.5 root 65: return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2 root 66: }
1.1.1.5 root 67: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2 root 68: {
1.1.1.5 root 69: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2 root 70: }
1.1.1.5 root 71: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2 root 72: {
1.1.1.5 root 73: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2 root 74: }
1.1.1.5 root 75: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2 root 76: {
1.1.1.5 root 77: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2 root 78: }
79: #endif
80:
1.1.1.12 root 81: uae_u32 chipmem_mask, kickmem_mask, extendedkickmem_mask, bogomem_mask, a3000mem_mask;
1.1 root 82:
1.1.1.11 root 83: static int illegal_count;
1.1.1.3 root 84: /* A dummy bank that only contains zeros */
85:
1.1.1.4 root 86: static uae_u32 dummy_lget (uaecptr) REGPARAM;
87: static uae_u32 dummy_wget (uaecptr) REGPARAM;
88: static uae_u32 dummy_bget (uaecptr) REGPARAM;
89: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
90: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
91: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
92: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
93:
94: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
95: {
1.1.1.8 root 96: special_mem |= S_READ;
1.1.1.11 root 97: if (currprefs.illegal_mem) {
98: if (illegal_count < 20) {
99: illegal_count++;
100: write_log ("Illegal lget at %08lx\n", addr);
101: }
102: }
1.1.1.4 root 103:
1.1.1.9 root 104: return 0xFFFFFFFF;
1.1 root 105: }
106:
1.1.1.4 root 107: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1 root 108: {
1.1.1.8 root 109: special_mem |= S_READ;
1.1.1.11 root 110: if (currprefs.illegal_mem) {
111: if (illegal_count < 20) {
112: illegal_count++;
113: write_log ("Illegal wget at %08lx\n", addr);
114: }
115: }
1.1.1.12 root 116:
1.1.1.9 root 117: return 0xFFFF;
1.1 root 118: }
119:
1.1.1.4 root 120: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1 root 121: {
1.1.1.8 root 122: special_mem |= S_READ;
1.1.1.11 root 123: if (currprefs.illegal_mem) {
124: if (illegal_count < 20) {
125: illegal_count++;
126: write_log ("Illegal bget at %08lx\n", addr);
127: }
128: }
1.1.1.4 root 129:
1.1.1.9 root 130: return 0xFF;
1.1 root 131: }
132:
1.1.1.4 root 133: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1 root 134: {
1.1.1.8 root 135: special_mem |= S_WRITE;
1.1.1.11 root 136: if (currprefs.illegal_mem) {
137: if (illegal_count < 20) {
138: illegal_count++;
139: write_log ("Illegal lput at %08lx\n", addr);
140: }
141: }
1.1.1.3 root 142: }
1.1.1.4 root 143: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 144: {
1.1.1.8 root 145: special_mem |= S_WRITE;
1.1.1.11 root 146: if (currprefs.illegal_mem) {
147: if (illegal_count < 20) {
148: illegal_count++;
149: write_log ("Illegal wput at %08lx\n", addr);
150: }
151: }
1.1.1.3 root 152: }
1.1.1.4 root 153: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 154: {
1.1.1.8 root 155: special_mem |= S_WRITE;
1.1.1.11 root 156: if (currprefs.illegal_mem) {
157: if (illegal_count < 20) {
158: illegal_count++;
159: write_log ("Illegal bput at %08lx\n", addr);
160: }
161: }
1.1 root 162: }
163:
1.1.1.4 root 164: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1 root 165: {
1.1.1.9 root 166: special_mem |= S_READ;
1.1.1.11 root 167: if (currprefs.illegal_mem) {
168: if (illegal_count < 20) {
169: illegal_count++;
170: write_log ("Illegal check at %08lx\n", addr);
171: }
172: }
1.1.1.4 root 173:
1.1 root 174: return 0;
175: }
176:
1.1.1.3 root 177: /* A3000 "motherboard resources" bank. */
1.1.1.4 root 178: static uae_u32 mbres_lget (uaecptr) REGPARAM;
179: static uae_u32 mbres_wget (uaecptr) REGPARAM;
180: static uae_u32 mbres_bget (uaecptr) REGPARAM;
181: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
182: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
183: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
184: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3 root 185:
186: static int mbres_val = 0;
187:
1.1.1.4 root 188: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3 root 189: {
1.1.1.8 root 190: special_mem |= S_READ;
1.1.1.4 root 191: if (currprefs.illegal_mem)
192: write_log ("Illegal lget at %08lx\n", addr);
193:
1.1 root 194: return 0;
195: }
196:
1.1.1.4 root 197: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1 root 198: {
1.1.1.8 root 199: special_mem |= S_READ;
1.1.1.4 root 200: if (currprefs.illegal_mem)
201: write_log ("Illegal wget at %08lx\n", addr);
202:
1.1 root 203: return 0;
204: }
205:
1.1.1.4 root 206: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3 root 207: {
1.1.1.8 root 208: special_mem |= S_READ;
1.1.1.4 root 209: if (currprefs.illegal_mem)
210: write_log ("Illegal bget at %08lx\n", addr);
211:
1.1.1.3 root 212: return (addr & 0xFFFF) == 3 ? mbres_val : 0;
213: }
214:
1.1.1.4 root 215: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1 root 216: {
1.1.1.8 root 217: special_mem |= S_WRITE;
1.1.1.4 root 218: if (currprefs.illegal_mem)
219: write_log ("Illegal lput at %08lx\n", addr);
1.1 root 220: }
1.1.1.4 root 221: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1 root 222: {
1.1.1.8 root 223: special_mem |= S_WRITE;
1.1.1.4 root 224: if (currprefs.illegal_mem)
225: write_log ("Illegal wput at %08lx\n", addr);
1.1 root 226: }
1.1.1.4 root 227: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1 root 228: {
1.1.1.8 root 229: special_mem |= S_WRITE;
1.1.1.4 root 230: if (currprefs.illegal_mem)
231: write_log ("Illegal bput at %08lx\n", addr);
232:
1.1.1.3 root 233: if ((addr & 0xFFFF) == 3)
234: mbres_val = b;
1.1 root 235: }
236:
1.1.1.4 root 237: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1 root 238: {
1.1.1.4 root 239: if (currprefs.illegal_mem)
240: write_log ("Illegal check at %08lx\n", addr);
241:
1.1 root 242: return 0;
243: }
244:
245: /* Chip memory */
246:
1.1.1.3 root 247: uae_u8 *chipmemory;
1.1 root 248:
1.1.1.4 root 249: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
250: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1 root 251:
1.1.1.4 root 252: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1 root 253: {
1.1.1.3 root 254: uae_u32 *m;
1.1.1.8 root 255:
1.1 root 256: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 257: addr &= chipmem_mask;
1.1.1.3 root 258: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 259: return do_get_mem_long (m);
1.1 root 260: }
261:
1.1.1.4 root 262: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1 root 263: {
1.1.1.3 root 264: uae_u16 *m;
1.1.1.8 root 265:
1.1 root 266: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 267: addr &= chipmem_mask;
1.1.1.3 root 268: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 269: return do_get_mem_word (m);
1.1 root 270: }
271:
1.1.1.4 root 272: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1 root 273: {
274: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 275: addr &= chipmem_mask;
1.1 root 276: return chipmemory[addr];
277: }
278:
1.1.1.4 root 279: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1 root 280: {
1.1.1.3 root 281: uae_u32 *m;
1.1.1.8 root 282:
1.1 root 283: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 284: addr &= chipmem_mask;
1.1.1.3 root 285: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 286: do_put_mem_long (m, l);
1.1 root 287: }
288:
1.1.1.4 root 289: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1 root 290: {
1.1.1.3 root 291: uae_u16 *m;
1.1.1.8 root 292:
1.1 root 293: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 294: addr &= chipmem_mask;
1.1.1.3 root 295: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 296: do_put_mem_word (m, w);
1.1 root 297: }
298:
1.1.1.4 root 299: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1 root 300: {
301: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 302: addr &= chipmem_mask;
1.1 root 303: chipmemory[addr] = b;
304: }
305:
1.1.1.4 root 306: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1 root 307: {
308: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 309: addr &= chipmem_mask;
1.1.1.4 root 310: return (addr + size) <= allocated_chipmem;
1.1 root 311: }
312:
1.1.1.4 root 313: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1 root 314: {
315: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 316: addr &= chipmem_mask;
1.1 root 317: return chipmemory + addr;
318: }
319:
320: /* Slow memory */
321:
1.1.1.3 root 322: static uae_u8 *bogomemory;
1.1 root 323:
1.1.1.4 root 324: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
325: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
326: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
327: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
328: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
329: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
330: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
331: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1 root 332:
1.1.1.4 root 333: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1 root 334: {
1.1.1.3 root 335: uae_u32 *m;
1.1 root 336: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 337: addr &= bogomem_mask;
1.1.1.3 root 338: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 339: return do_get_mem_long (m);
1.1 root 340: }
341:
1.1.1.4 root 342: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1 root 343: {
1.1.1.3 root 344: uae_u16 *m;
1.1 root 345: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 346: addr &= bogomem_mask;
1.1.1.3 root 347: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 348: return do_get_mem_word (m);
1.1 root 349: }
350:
1.1.1.4 root 351: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1 root 352: {
353: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 354: addr &= bogomem_mask;
1.1 root 355: return bogomemory[addr];
356: }
357:
1.1.1.4 root 358: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1 root 359: {
1.1.1.3 root 360: uae_u32 *m;
1.1 root 361: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 362: addr &= bogomem_mask;
1.1.1.3 root 363: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 364: do_put_mem_long (m, l);
1.1 root 365: }
366:
1.1.1.4 root 367: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1 root 368: {
1.1.1.3 root 369: uae_u16 *m;
1.1 root 370: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 371: addr &= bogomem_mask;
1.1.1.3 root 372: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 373: do_put_mem_word (m, w);
1.1 root 374: }
375:
1.1.1.4 root 376: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1 root 377: {
378: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 379: addr &= bogomem_mask;
1.1 root 380: bogomemory[addr] = b;
381: }
382:
1.1.1.4 root 383: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1 root 384: {
1.1.1.2 root 385: addr -= bogomem_start & bogomem_mask;
386: addr &= bogomem_mask;
1.1.1.4 root 387: return (addr + size) <= allocated_bogomem;
1.1 root 388: }
389:
1.1.1.4 root 390: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1 root 391: {
1.1.1.2 root 392: addr -= bogomem_start & bogomem_mask;
393: addr &= bogomem_mask;
1.1 root 394: return bogomemory + addr;
395: }
396:
1.1.1.3 root 397: /* A3000 motherboard fast memory */
398:
399: static uae_u8 *a3000memory;
1.1 root 400:
1.1.1.4 root 401: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
402: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
403: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
404: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
405: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
406: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
407: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
408: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 409:
1.1.1.4 root 410: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3 root 411: {
412: uae_u32 *m;
413: addr -= a3000mem_start & a3000mem_mask;
414: addr &= a3000mem_mask;
415: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 416: return do_get_mem_long (m);
1.1.1.3 root 417: }
1.1 root 418:
1.1.1.4 root 419: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3 root 420: {
421: uae_u16 *m;
422: addr -= a3000mem_start & a3000mem_mask;
423: addr &= a3000mem_mask;
424: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 425: return do_get_mem_word (m);
1.1.1.3 root 426: }
1.1 root 427:
1.1.1.4 root 428: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1 root 429: {
1.1.1.3 root 430: addr -= a3000mem_start & a3000mem_mask;
431: addr &= a3000mem_mask;
432: return a3000memory[addr];
1.1 root 433: }
434:
1.1.1.4 root 435: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1 root 436: {
1.1.1.3 root 437: uae_u32 *m;
438: addr -= a3000mem_start & a3000mem_mask;
439: addr &= a3000mem_mask;
440: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 441: do_put_mem_long (m, l);
1.1.1.3 root 442: }
443:
1.1.1.4 root 444: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 445: {
446: uae_u16 *m;
447: addr -= a3000mem_start & a3000mem_mask;
448: addr &= a3000mem_mask;
449: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 450: do_put_mem_word (m, w);
1.1.1.3 root 451: }
452:
1.1.1.4 root 453: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 454: {
455: addr -= a3000mem_start & a3000mem_mask;
456: addr &= a3000mem_mask;
457: a3000memory[addr] = b;
458: }
459:
1.1.1.4 root 460: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3 root 461: {
462: addr -= a3000mem_start & a3000mem_mask;
463: addr &= a3000mem_mask;
1.1.1.4 root 464: return (addr + size) <= allocated_a3000mem;
1.1 root 465: }
466:
1.1.1.12 root 467: uae_u8 REGPARAM2 *a3000mem_xlate (uaecptr addr)
1.1.1.3 root 468: {
469: addr -= a3000mem_start & a3000mem_mask;
470: addr &= a3000mem_mask;
471: return a3000memory + addr;
472: }
473:
474: /* Kick memory */
475:
476: uae_u8 *kickmemory;
477:
1.1.1.12 root 478: /*
479: * A1000 kickstart RAM handling
480: *
481: * RESET instruction unhides boot ROM and disables write protection
482: * write access to boot ROM hides boot ROM and enables write protection
483: *
484: */
485: static int a1000_kickstart_mode;
486: static uae_u8 *a1000_bootrom;
487: static void a1000_handle_kickstart (int mode)
488: {
489: if (mode == 0) {
490: a1000_kickstart_mode = 0;
491: memcpy (kickmemory, kickmemory + 262144, 262144);
492: } else {
493: a1000_kickstart_mode = 1;
494: memset (kickmemory, 0, 262144);
495: memcpy (kickmemory, a1000_bootrom, 8192);
496: memcpy (kickmemory + 131072, a1000_bootrom, 8192);
497: }
498: }
499:
1.1.1.4 root 500: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
501: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
502: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
1.1.1.12 root 503: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
504: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
505: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
506: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.4 root 507: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 508:
1.1.1.4 root 509: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1 root 510: {
1.1.1.3 root 511: uae_u32 *m;
1.1 root 512: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 513: addr &= kickmem_mask;
1.1.1.3 root 514: m = (uae_u32 *)(kickmemory + addr);
1.1.1.5 root 515: return do_get_mem_long (m);
1.1 root 516: }
517:
1.1.1.4 root 518: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1 root 519: {
1.1.1.3 root 520: uae_u16 *m;
1.1 root 521: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 522: addr &= kickmem_mask;
1.1.1.3 root 523: m = (uae_u16 *)(kickmemory + addr);
1.1.1.5 root 524: return do_get_mem_word (m);
1.1 root 525: }
526:
1.1.1.4 root 527: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1 root 528: {
529: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 530: addr &= kickmem_mask;
1.1 root 531: return kickmemory[addr];
532: }
533:
1.1.1.4 root 534: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1 root 535: {
1.1.1.12 root 536: uae_u32 *m;
537: if (a1000_kickstart_mode) {
538: if (addr >= 0xfc0000) {
539: addr -= kickmem_start & kickmem_mask;
540: addr &= kickmem_mask;
541: m = (uae_u32 *)(kickmemory + addr);
542: do_put_mem_long (m, b);
543: return;
544: } else
545: a1000_handle_kickstart (0);
546: } else if (currprefs.illegal_mem)
1.1.1.4 root 547: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 548: }
549:
1.1.1.4 root 550: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1 root 551: {
1.1.1.12 root 552: uae_u16 *m;
553: if (a1000_kickstart_mode) {
554: if (addr >= 0xfc0000) {
555: addr -= kickmem_start & kickmem_mask;
556: addr &= kickmem_mask;
557: m = (uae_u16 *)(kickmemory + addr);
558: do_put_mem_word (m, b);
559: return;
560: } else
561: a1000_handle_kickstart (0);
562: } else if (currprefs.illegal_mem)
1.1.1.4 root 563: write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1 root 564: }
565:
1.1.1.4 root 566: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1 root 567: {
1.1.1.12 root 568: if (a1000_kickstart_mode) {
569: if (addr >= 0xfc0000) {
570: addr -= kickmem_start & kickmem_mask;
571: addr &= kickmem_mask;
572: kickmemory[addr] = b;
573: return;
574: } else
575: a1000_handle_kickstart (0);
576: } else if (currprefs.illegal_mem)
1.1.1.4 root 577: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 578: }
579:
1.1.1.4 root 580: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1 root 581: {
1.1.1.2 root 582: addr -= kickmem_start & kickmem_mask;
583: addr &= kickmem_mask;
1.1.1.4 root 584: return (addr + size) <= kickmem_size;
1.1 root 585: }
586:
1.1.1.4 root 587: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1 root 588: {
1.1.1.2 root 589: addr -= kickmem_start & kickmem_mask;
590: addr &= kickmem_mask;
1.1 root 591: return kickmemory + addr;
592: }
593:
1.1.1.12 root 594: /* CD32/CDTV extended kick memory */
1.1.1.3 root 595:
1.1.1.12 root 596: uae_u8 *extendedkickmemory;
597: static int extendedkickmem_size;
598: static uae_u32 extendedkickmem_start;
599:
600: #define EXTENDED_ROM_CD32 1
601: #define EXTENDED_ROM_CDTV 2
602:
603: static int extromtype (void)
604: {
605: switch (extendedkickmem_size) {
606: case 524288:
607: return EXTENDED_ROM_CD32;
608: case 262144:
609: return EXTENDED_ROM_CDTV;
610: }
1.1.1.3 root 611: return 0;
612: }
613:
1.1.1.12 root 614: static uae_u32 extendedkickmem_lget (uaecptr) REGPARAM;
615: static uae_u32 extendedkickmem_wget (uaecptr) REGPARAM;
616: static uae_u32 extendedkickmem_bget (uaecptr) REGPARAM;
617: static void extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
618: static void extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
619: static void extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
620: static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
621: static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM;
622:
623: uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr)
1.1.1.3 root 624: {
1.1.1.12 root 625: uae_u32 *m;
626: addr -= extendedkickmem_start & extendedkickmem_mask;
627: addr &= extendedkickmem_mask;
628: m = (uae_u32 *)(extendedkickmemory + addr);
629: return do_get_mem_long (m);
1.1.1.3 root 630: }
631:
1.1.1.12 root 632: uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr)
1.1 root 633: {
1.1.1.12 root 634: uae_u16 *m;
635: addr -= extendedkickmem_start & extendedkickmem_mask;
636: addr &= extendedkickmem_mask;
637: m = (uae_u16 *)(extendedkickmemory + addr);
638: return do_get_mem_word (m);
639: }
1.1.1.3 root 640:
1.1.1.12 root 641: uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr)
642: {
643: addr -= extendedkickmem_start & extendedkickmem_mask;
644: addr &= extendedkickmem_mask;
645: return extendedkickmemory[addr];
646: }
1.1.1.3 root 647:
1.1.1.12 root 648: void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
649: {
650: if (currprefs.illegal_mem)
651: write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
652: }
1.1.1.3 root 653:
1.1.1.12 root 654: void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
655: {
656: if (currprefs.illegal_mem)
657: write_log ("Illegal extendedkickmem wput at %08lx\n", addr);
658: }
1.1.1.3 root 659:
1.1.1.12 root 660: void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
661: {
662: if (currprefs.illegal_mem)
663: write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
664: }
1.1.1.3 root 665:
1.1.1.12 root 666: int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size)
667: {
668: addr -= extendedkickmem_start & extendedkickmem_mask;
669: addr &= extendedkickmem_mask;
670: return (addr + size) <= extendedkickmem_size;
671: }
1.1.1.3 root 672:
1.1.1.12 root 673: uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr)
674: {
675: addr -= extendedkickmem_start & extendedkickmem_mask;
676: addr &= extendedkickmem_mask;
677: return extendedkickmemory + addr;
678: }
1.1.1.2 root 679:
1.1.1.12 root 680: /* Default memory access functions */
681:
682: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
683: {
684: return 0;
685: }
686:
687: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
688: {
689: write_log ("Your Amiga program just did something terribly stupid\n");
690: uae_reset ();
691: return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
1.1 root 692: }
693:
694: /* Address banks */
695:
696: addrbank dummy_bank = {
697: dummy_lget, dummy_wget, dummy_bget,
698: dummy_lput, dummy_wput, dummy_bput,
1.1.1.9 root 699: default_xlate, dummy_check, NULL
1.1 root 700: };
701:
1.1.1.3 root 702: addrbank mbres_bank = {
703: mbres_lget, mbres_wget, mbres_bget,
704: mbres_lput, mbres_wput, mbres_bput,
1.1.1.9 root 705: default_xlate, mbres_check, NULL
1.1.1.3 root 706: };
707:
1.1 root 708: addrbank chipmem_bank = {
709: chipmem_lget, chipmem_wget, chipmem_bget,
710: chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.9 root 711: chipmem_xlate, chipmem_check, NULL
1.1 root 712: };
713:
714: addrbank bogomem_bank = {
715: bogomem_lget, bogomem_wget, bogomem_bget,
716: bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.9 root 717: bogomem_xlate, bogomem_check, NULL
1.1 root 718: };
719:
1.1.1.3 root 720: addrbank a3000mem_bank = {
721: a3000mem_lget, a3000mem_wget, a3000mem_bget,
722: a3000mem_lput, a3000mem_wput, a3000mem_bput,
1.1.1.9 root 723: a3000mem_xlate, a3000mem_check, NULL
1.1.1.3 root 724: };
725:
1.1 root 726: addrbank kickmem_bank = {
727: kickmem_lget, kickmem_wget, kickmem_bget,
728: kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.9 root 729: kickmem_xlate, kickmem_check, NULL
1.1 root 730: };
731:
1.1.1.12 root 732: addrbank extendedkickmem_bank = {
733: extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
734: extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
735: extendedkickmem_xlate, extendedkickmem_check, NULL
736: };
737:
738: static int decode_cloanto_rom (uae_u8 *mem, int size, int real_size)
739: {
740: FILE *keyf;
741: uae_u8 *p;
742: long cnt, t;
743: int keysize;
744:
745: if (strlen (currprefs.keyfile) == 0) {
746: write_log ("No filename given for ROM key file and ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
747: return 0;
748: }
749: keyf = zfile_open (currprefs.keyfile, "rb");
750: if (keyf == 0) {
751: write_log ("Could not find specified ROM key-file.\n");
752: return 0;
753: }
754:
755: p = (uae_u8 *) xmalloc (524288);
756: keysize = fread (p, 1, 524288, keyf);
757: for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize) {
758: mem[cnt] ^= p[t];
759: if (real_size == cnt + 1)
760: t = keysize - 1;
761: }
762: fclose (keyf);
763: free (p);
764: return 1;
765: }
766:
767: static int kickstart_checksum (uae_u8 *mem, int size)
768: {
769: uae_u32 cksum = 0, prevck = 0;
770: int i;
771: for (i = 0; i < size; i += 4) {
772: uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
773: cksum += data;
774: if (cksum < prevck)
775: cksum++;
776: prevck = cksum;
777: }
778: if (cksum != 0xFFFFFFFFul) {
779: write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
780: }
781: return 0;
782: }
783:
784: static int read_kickstart (FILE *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom)
785: {
786: unsigned char buffer[20];
787: int i, cr = 0;
788:
789: if (cloanto_rom)
790: *cloanto_rom = 0;
791: i = fread (buffer, 1, 11, f);
792: if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) {
793: fseek (f, 0, SEEK_SET);
794: } else {
795: cr = 1;
796: }
797:
798: i = fread (mem, 1, size, f);
799: if (i == 8192) {
800: a1000_bootrom = malloc (8192);
801: memcpy (a1000_bootrom, kickmemory, 8192);
802: a1000_handle_kickstart (1);
803: } else if (i == size / 2) {
804: memcpy (mem + size / 2, mem, i);
805: } else if (i != size) {
806: write_log ("Error while reading Kickstart.\n");
807: zfile_close (f);
808: return 0;
809: }
810: zfile_close (f);
811:
812: if (cr)
813: decode_cloanto_rom (mem, size, i);
814: if (dochecksum && i >= 262144)
815: kickstart_checksum (mem, size);
816: if (cloanto_rom)
817: *cloanto_rom = cr;
818: return 1;
819: }
820:
821: static int load_extendedkickstart (void)
822: {
823: FILE *f;
824: int size;
825:
826: if (strlen (currprefs.romextfile) == 0)
827: return 0;
828: f = zfile_open (currprefs.romextfile, "rb");
829: if (!f) {
830: write_log ("No extended Kickstart ROM found");
831: return 0;
832: }
833:
834: fseek (f, 0, SEEK_END);
835: size = ftell (f);
836: if (size > 300000)
837: extendedkickmem_size = 524288;
838: else
839: extendedkickmem_size = 262144;
840: fseek (f, 0, SEEK_SET);
841:
842: switch (extromtype ()) {
843: case EXTENDED_ROM_CDTV:
844: extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_f0");
845: extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
846: break;
847: case EXTENDED_ROM_CD32:
848: extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
849: extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
850: break;
851: }
852: read_kickstart (f, extendedkickmemory, 524288, 0, 0);
853: fclose (f);
854: return 1;
855: }
856:
857:
858: static int load_kickstart (void)
859: {
860: FILE *f = zfile_open (currprefs.romfile, "rb");
861:
862: if (f == NULL) {
863: #if defined(AMIGA)||defined(__POS__)
864: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
865: if (!getenv (USE_UAE_ERSATZ)) {
866: write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
867: memcpy (kickmemory, (char *) 0x1000000 - kickmem_size, kickmem_size);
868: kickstart_checksum (kickmemory, kickmem_size);
869: goto chk_sum;
870: }
871: #endif
872: return 0;
873: }
874:
875: if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom))
876: return 0;
877:
878: #if defined(AMIGA)
879: chk_sum:
880: #endif
881:
882: if (currprefs.kickshifter) {
883: /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
884: Changes 'lea $400,a0' to 'lea $2000,a0' for ShapeShifter compatability.
885: NOTE: lea is 0x41f8, so we should do this better with a search for
886: 0x41f80400 --> 0x41f82000
887: */
888: if (kickmemory[0x24a] == 0x04 && kickmemory[0x24b] == 0x00) { /* Kick 3.0 */
889: kickmemory[0x24a] = 0x20;
890: kickmemory[0x7ffea] -= 0x1c;
891: write_log ("Kickstart KickShifted\n");
892: } else if (kickmemory[0x26e] == 0x04 && kickmemory[0x26f] == 0x00) { /* Kick 3.1 */
893: kickmemory[0x26e] = 0x20;
894: kickmemory[0x7ffea] -= 0x1c;
895: write_log ("Kickstart KickShifted\n");
896: } else if (kickmemory[0x24e] == 0x04 && kickmemory[0x24f] == 0x00) { /* Kick 2.04 */
897: kickmemory[0x24e] = 0x20;
898: kickmemory[0x7ffea] -= 0x1c;
899: write_log ("Kickstart KickShifted\n");
900: }
901: }
902: return 1;
903: }
904:
1.1 root 905: char *address_space, *good_address_map;
906: int good_address_fd;
1.1.1.4 root 907:
1.1.1.9 root 908: #ifndef NATMEM_OFFSET
909:
1.1.1.12 root 910: uae_u8 *mapped_malloc (size_t s, char *file)
1.1.1.4 root 911: {
1.1.1.13! root 912: return calloc (s, 1);
1.1.1.4 root 913: }
914:
1.1.1.9 root 915: void mapped_free (uae_u8 *p)
1.1 root 916: {
1.1.1.9 root 917: free (p);
918: }
919: #else
1.1.1.3 root 920:
1.1.1.9 root 921: #include <sys/ipc.h>
922: #include <sys/shm.h>
923: #include <unistd.h>
924: #include <sys/mman.h>
925:
1.1.1.12 root 926: shmpiece *shm_start = NULL;
927: int canbang = 1;
1.1.1.9 root 928:
1.1.1.12 root 929: static void dumplist (void)
1.1.1.9 root 930: {
1.1.1.12 root 931: shmpiece *x = shm_start;
1.1.1.9 root 932: printf ("Start Dump:\n");
933: while (x) {
934: printf (" this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
1.1.1.12 root 935: x, x->native_address, x->id, x->prev, x->next, x->size);
1.1.1.9 root 936: x = x->next;
1.1.1.2 root 937: }
1.1.1.9 root 938: printf ("End Dump:\n");
939: }
1.1 root 940:
1.1.1.9 root 941: static shmpiece *find_shmpiece (uae_u8 *base)
942: {
943: shmpiece *x = shm_start;
1.1 root 944:
1.1.1.9 root 945: while (x && x->native_address != base)
946: x = x->next;
947: if (!x) {
1.1.1.12 root 948: printf ("NATMEM: Failure to find mapping at %p\n", base);
949: dumplist ();
1.1.1.9 root 950: canbang = 0;
951: return 0;
952: }
953: return x;
954: }
1.1.1.3 root 955:
1.1.1.9 root 956: static void delete_shmmaps (uae_u32 start, uae_u32 size)
957: {
958: if (!canbang)
959: return;
960:
961: while (size) {
1.1.1.12 root 962: uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1.1.1.9 root 963: if (base) {
964: shmpiece *x;
1.1.1.12 root 965: base = ((uae_u8 *) NATMEM_OFFSET) + start;
1.1.1.9 root 966:
967: x = find_shmpiece (base);
1.1.1.12 root 968: if (!x)
1.1.1.9 root 969: return;
970:
971: if (x->size > size) {
1.1.1.12 root 972: printf ("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n", start, x->size, size);
973: dumplist ();
1.1.1.9 root 974: canbang = 0;
975: return;
976: }
977: shmdt (x->native_address);
978: size -= x->size;
979: start += x->size;
980: if (x->next)
1.1.1.12 root 981: x->next->prev = x->prev; /* remove this one from the list */
1.1.1.9 root 982: if (x->prev)
983: x->prev->next = x->next;
984: else
985: shm_start = x->next;
1.1.1.12 root 986: free (x);
1.1.1.9 root 987: } else {
988: size -= 0x10000;
989: start += 0x10000;
990: }
1.1.1.3 root 991: }
1.1.1.9 root 992: }
1.1.1.12 root 993:
1.1.1.9 root 994: static void add_shmmaps (uae_u32 start, addrbank *what)
995: {
996: shmpiece *x = shm_start;
997: shmpiece *y;
998: uae_u8 *base = what->baseaddr;
999:
1000: if (!canbang)
1001: return;
1002: if (!base)
1003: return;
1004:
1005: x = find_shmpiece (base);
1.1.1.12 root 1006: if (!x)
1.1.1.9 root 1007: return;
1008: y = malloc (sizeof (shmpiece));
1009: *y = *x;
1.1.1.12 root 1010: base = ((uae_u8 *) NATMEM_OFFSET) + start;
1011: y->native_address = shmat (y->id, base, 0);
1012: if (y->native_address == (void *) -1) {
1013: printf ("NATMEM: Failure to map existing at %08x(%p)\n", start, base);
1014: perror ("shmat");
1015: dumplist ();
1.1.1.9 root 1016: canbang = 0;
1017: return;
1.1.1.2 root 1018: }
1.1.1.9 root 1019: y->next = shm_start;
1020: y->prev = NULL;
1021: if (y->next)
1022: y->next->prev = y;
1023: shm_start = y;
1024: }
1025:
1026: uae_u8 *mapped_malloc (size_t s, char *file)
1027: {
1.1.1.12 root 1028: int id;
1.1.1.9 root 1029: void *answer;
1030: shmpiece *x;
1031:
1.1.1.12 root 1032: if (!canbang)
1.1.1.9 root 1033: return malloc (s);
1034:
1.1.1.12 root 1035: id = shmget (IPC_PRIVATE, s, 0x1ff, file);
1.1.1.9 root 1036: if (id == 1) {
1037: canbang = 0;
1038: return mapped_malloc (s, file);
1039: }
1.1.1.12 root 1040: answer = shmat (id, 0, 0);
1041: shmctl (id, IPC_RMID, NULL);
1042: if (answer != (void *) -1) {
1043: x = malloc (sizeof (shmpiece));
1.1.1.9 root 1044: x->native_address = answer;
1045: x->id = id;
1046: x->size = s;
1047: x->next = shm_start;
1048: x->prev = NULL;
1049: if (x->next)
1050: x->next->prev = x;
1051: shm_start = x;
1052:
1053: return answer;
1054: }
1055: canbang = 0;
1056: return mapped_malloc (s, file);
1057: }
1058:
1.1.1.10 root 1059: void mapped_free (uae_u8 *base)
1.1.1.9 root 1060: {
1061: shmpiece *x = find_shmpiece (base);
1.1.1.12 root 1062: if (!x)
1.1.1.9 root 1063: abort ();
1064: shmdt (x->native_address);
1065: }
1066:
1.1 root 1067: #endif
1.1.1.6 root 1068:
1.1.1.9 root 1069: static void init_mem_banks (void)
1070: {
1071: int i;
1072: for (i = 0; i < 65536; i++)
1073: put_mem_bank (i << 16, &dummy_bank, 0);
1074: }
1075:
1076: static void allocate_memory (void)
1077: {
1078: if (allocated_chipmem != currprefs.chipmem_size) {
1079: if (chipmemory)
1080: mapped_free (chipmemory);
1081: chipmemory = 0;
1082:
1083: allocated_chipmem = currprefs.chipmem_size;
1084: chipmem_mask = allocated_chipmem - 1;
1085:
1086: chipmemory = mapped_malloc (allocated_chipmem, "chip");
1087: if (chipmemory == 0) {
1088: write_log ("Fatal error: out of memory for chipmem.\n");
1089: allocated_chipmem = 0;
1090: } else
1091: do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
1092: }
1093:
1094: if (allocated_bogomem != currprefs.bogomem_size) {
1095: if (bogomemory)
1096: mapped_free (bogomemory);
1097: bogomemory = 0;
1098:
1099: allocated_bogomem = currprefs.bogomem_size;
1100: bogomem_mask = allocated_bogomem - 1;
1101:
1102: if (allocated_bogomem) {
1103: bogomemory = mapped_malloc (allocated_bogomem, "bogo");
1104: if (bogomemory == 0) {
1105: write_log ("Out of memory for bogomem.\n");
1106: allocated_bogomem = 0;
1107: }
1108: }
1109: }
1110: if (allocated_a3000mem != currprefs.a3000mem_size) {
1111: if (a3000memory)
1112: mapped_free (a3000memory);
1113: a3000memory = 0;
1114:
1115: allocated_a3000mem = currprefs.a3000mem_size;
1116: a3000mem_mask = allocated_a3000mem - 1;
1117:
1118: if (allocated_a3000mem) {
1119: a3000memory = mapped_malloc (allocated_a3000mem, "a3000");
1120: if (a3000memory == 0) {
1121: write_log ("Out of memory for a3000mem.\n");
1122: allocated_a3000mem = 0;
1123: }
1124: }
1125: }
1126:
1127: if (savestate_state == STATE_RESTORE) {
1128: fseek (savestate_file, chip_filepos, SEEK_SET);
1129: fread (chipmemory, 1, allocated_chipmem, savestate_file);
1130: if (allocated_bogomem > 0) {
1131: fseek (savestate_file, bogo_filepos, SEEK_SET);
1132: fread (bogomemory, 1, allocated_bogomem, savestate_file);
1133: }
1134: }
1135: chipmem_bank.baseaddr = chipmemory;
1136: bogomem_bank.baseaddr = bogomemory;
1137: }
1138:
1139: void memory_reset (void)
1140: {
1141: int i, custom_start;
1142:
1143: #ifdef NATMEM_OFFSET
1144: delete_shmmaps (0, 0xFFFF0000);
1145: #endif
1.1.1.4 root 1146: init_mem_banks ();
1.1.1.3 root 1147:
1.1.1.9 root 1148: currprefs.chipmem_size = changed_prefs.chipmem_size;
1149: currprefs.bogomem_size = changed_prefs.bogomem_size;
1150: currprefs.a3000mem_size = changed_prefs.a3000mem_size;
1151:
1152: allocate_memory ();
1153:
1.1.1.12 root 1154: if (strcmp (currprefs.romfile, changed_prefs.romfile) != 0 || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0) {
1.1.1.10 root 1155: ersatzkickfile = 0;
1156: memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
1157: memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
1158: /* Clear out whatever data remains across a reset. */
1159: memset (chipmemory, 0, allocated_chipmem);
1.1.1.12 root 1160: if (!load_kickstart ()) {
1.1.1.10 root 1161: init_ersatz_rom (kickmemory);
1162: ersatzkickfile = 1;
1163: }
1.1.1.12 root 1164: }
1.1.1.9 root 1165: /* Map the chipmem into all of the lower 8MB */
1166: i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
1167: map_banks (&chipmem_bank, 0x00, i, allocated_chipmem);
1168:
1.1.1.3 root 1169: custom_start = 0xC0;
1.1 root 1170:
1.1.1.9 root 1171: map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0);
1172: map_banks (&cia_bank, 0xA0, 32, 0);
1173: map_banks (&clock_bank, 0xDC, 1, 0);
1.1.1.3 root 1174:
1175: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
1176: * range on an Amiga without expansion memory? */
1.1.1.4 root 1177: custom_start = allocated_chipmem >> 16;
1.1.1.3 root 1178: if (custom_start < 0x20)
1179: custom_start = 0x20;
1.1.1.9 root 1180: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
1.1.1.12 root 1181: /*map_banks (&mbres_bank, 0xDE, 1); */
1.1.1.3 root 1182:
1.1.1.9 root 1183: if (bogomemory != 0) {
1184: int t = allocated_bogomem >> 16;
1185: if (t > 0x1C)
1186: t = 0x1C;
1187: map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
1188: }
1.1.1.4 root 1189: if (a3000memory != 0)
1.1.1.12 root 1190: map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16, allocated_a3000mem);
1.1.1.9 root 1191:
1.1.1.11 root 1192: map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
1.1.1.9 root 1193:
1194: map_banks (&kickmem_bank, 0xF8, 8, 0);
1.1.1.12 root 1195: if (a1000_bootrom)
1196: a1000_handle_kickstart (1);
1.1.1.9 root 1197: map_banks (&expamem_bank, 0xE8, 1, 0);
1198:
1.1.1.12 root 1199: switch (extromtype ()) {
1200: case EXTENDED_ROM_CDTV:
1201: map_banks (&extendedkickmem_bank, 0xF0, 4, 0);
1202: break;
1203: case EXTENDED_ROM_CD32:
1204: map_banks (&extendedkickmem_bank, 0xE0, 8, 0);
1205: break;
1206: default:
1207: if (cloanto_rom)
1208: map_banks (&kickmem_bank, 0xE0, 8, 0);
1209: }
1.1.1.9 root 1210: }
1211:
1212: void memory_init (void)
1213: {
1214: allocated_chipmem = 0;
1215: allocated_bogomem = 0;
1216: allocated_a3000mem = 0;
1217: kickmemory = 0;
1.1.1.12 root 1218: extendedkickmemory = 0;
1.1.1.9 root 1219: chipmemory = 0;
1220: a3000memory = 0;
1221: bogomemory = 0;
1222:
1223: kickmemory = mapped_malloc (kickmem_size, "kick");
1224: kickmem_bank.baseaddr = kickmemory;
1.1.1.3 root 1225:
1.1.1.12 root 1226: load_extendedkickstart ();
1227: if (!load_kickstart ()) {
1.1.1.3 root 1228: init_ersatz_rom (kickmemory);
1.1 root 1229: ersatzkickfile = 1;
1230: }
1.1.1.3 root 1231:
1.1.1.9 root 1232: init_mem_banks ();
1233: memory_reset ();
1.1.1.4 root 1234:
1235: kickmem_mask = kickmem_size - 1;
1.1.1.12 root 1236: extendedkickmem_mask = extendedkickmem_size - 1;
1.1 root 1237: }
1238:
1.1.1.12 root 1239: void memory_cleanup (void)
1.1.1.10 root 1240: {
1241: if (a3000memory)
1242: mapped_free (a3000memory);
1243: if (bogomemory)
1244: mapped_free (bogomemory);
1245: if (kickmemory)
1246: mapped_free (kickmemory);
1.1.1.12 root 1247: if (a1000_bootrom)
1248: free (a1000_bootrom);
1.1.1.10 root 1249: if (chipmemory)
1250: mapped_free (chipmemory);
1.1.1.12 root 1251:
1.1.1.10 root 1252: a3000memory = 0;
1253: bogomemory = 0;
1254: kickmemory = 0;
1.1.1.12 root 1255: a1000_bootrom = 0;
1.1.1.10 root 1256: chipmemory = 0;
1257: }
1258:
1.1.1.9 root 1259: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1 root 1260: {
1261: int bnr;
1.1.1.3 root 1262: unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.12 root 1263: addrbank *orgbank = bank;
1.1.1.9 root 1264: uae_u32 realstart = start;
1.1.1.12 root 1265:
1266: flush_icache (1); /* Sure don't want to keep any old mappings around! */
1.1.1.9 root 1267: #ifdef NATMEM_OFFSET
1268: delete_shmmaps (start << 16, size << 16);
1269: #endif
1.1.1.12 root 1270:
1.1.1.9 root 1271: if (!realsize)
1272: realsize = size << 16;
1273:
1274: if ((size << 16) < realsize) {
1.1.1.11 root 1275: write_log ("Please report to [email protected], and mention:\n");
1.1.1.12 root 1276: write_log ("Broken mapping, size=%x, realsize=%x\n", size, realsize);
1277: write_log ("Start is %x\n", start);
1.1.1.11 root 1278: write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9 root 1279: abort ();
1280: }
1.1.1.3 root 1281:
1282: if (start >= 0x100) {
1.1.1.10 root 1283: int real_left = 0;
1.1.1.9 root 1284: for (bnr = start; bnr < start + size; bnr++) {
1285: if (!real_left) {
1286: realstart = bnr;
1.1.1.12 root 1287: real_left = realsize >> 16;
1.1.1.9 root 1288: #ifdef NATMEM_OFFSET
1289: add_shmmaps (realstart << 16, bank);
1290: #endif
1291: }
1.1.1.12 root 1292: put_mem_bank (bnr << 16, bank, realstart << 16);
1.1.1.9 root 1293: real_left--;
1294: }
1.1.1.3 root 1295: return;
1296: }
1.1.1.10 root 1297: if (currprefs.address_space_24)
1298: endhioffs = 0x10000;
1.1.1.9 root 1299: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10 root 1300: int real_left = 0;
1.1.1.12 root 1301: for (bnr = start; bnr < start + size; bnr++) {
1.1.1.9 root 1302: if (!real_left) {
1303: realstart = bnr + hioffs;
1304: real_left = realsize >> 16;
1305: #ifdef NATMEM_OFFSET
1306: add_shmmaps (realstart << 16, bank);
1307: #endif
1308: }
1.1.1.12 root 1309: put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1.1.1.9 root 1310: real_left--;
1311: }
1312: }
1313: }
1314:
1315:
1316: /* memory save/restore code */
1317:
1318: uae_u8 *save_cram (int *len)
1319: {
1320: *len = allocated_chipmem;
1321: return chipmemory;
1322: }
1323:
1324: uae_u8 *save_bram (int *len)
1325: {
1326: *len = allocated_bogomem;
1327: return bogomemory;
1328: }
1329:
1330: void restore_cram (int len, long filepos)
1331: {
1332: chip_filepos = filepos;
1333: changed_prefs.chipmem_size = len;
1334: }
1335:
1336: void restore_bram (int len, long filepos)
1337: {
1338: bogo_filepos = filepos;
1339: changed_prefs.bogomem_size = len;
1340: }
1341:
1342: uae_u8 *restore_rom (uae_u8 *src)
1343: {
1344: restore_u32 ();
1345: restore_u32 ();
1346: restore_u32 ();
1347: restore_u32 ();
1348: restore_u32 ();
1349:
1350: return src;
1351: }
1352:
1353: uae_u8 *save_rom (int first, int *len)
1354: {
1355: static int count;
1356: uae_u8 *dst, *dstbak;
1357: uae_u8 *mem_real_start;
1358: int mem_start, mem_size, mem_type, i, saverom;
1359:
1360: saverom = 0;
1.1.1.12 root 1361: if (first)
1362: count = 0;
1.1.1.9 root 1363: for (;;) {
1364: mem_type = count;
1.1.1.12 root 1365: switch (count) {
1366: case 0: /* Kickstart ROM */
1.1.1.9 root 1367: mem_start = 0xf80000;
1368: mem_real_start = kickmemory;
1369: mem_size = kickmem_size;
1370: /* 256KB or 512KB ROM? */
1.1.1.12 root 1371: for (i = 0; i < mem_size / 2 - 4; i++) {
1372: if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
1373: break;
1.1.1.9 root 1374: }
1.1.1.12 root 1375: if (i == mem_size / 2 - 4) {
1.1.1.9 root 1376: mem_size /= 2;
1377: mem_start += 262144;
1378: }
1379: mem_type = 0;
1380: break;
1.1.1.12 root 1381: default:
1.1.1.9 root 1382: return 0;
1383: }
1.1.1.12 root 1384: count++;
1385: if (mem_size)
1386: break;
1.1.1.9 root 1387: }
1388: dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
1389: save_u32 (mem_start);
1390: save_u32 (mem_size);
1391: save_u32 (mem_type);
1.1.1.12 root 1392: save_u32 (longget (mem_start + 12)); /* version+revision */
1.1.1.9 root 1393: save_u32 (0);
1.1.1.12 root 1394: sprintf (dst, "Kickstart %d.%d", wordget (mem_start + 12), wordget (mem_start + 14));
1.1.1.9 root 1395: dst += strlen (dst) + 1;
1396: if (saverom) {
1.1.1.12 root 1397: for (i = 0; i < mem_size; i++)
1398: *dst++ = byteget (mem_start + i);
1.1.1.9 root 1399: }
1400: *len = dst - dstbak;
1401: return dstbak;
1.1 root 1402: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.