|
|
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"
18:
1.1.1.2 root 19: #ifdef USE_MAPPED_MEMORY
1.1 root 20: #include <sys/mman.h>
21: #endif
22:
23: int ersatzkickfile = 0;
24:
1.1.1.4 root 25: uae_u32 allocated_chipmem;
26: uae_u32 allocated_fastmem;
27: uae_u32 allocated_bogomem;
28: uae_u32 allocated_gfxmem;
29: uae_u32 allocated_z3fastmem;
30: uae_u32 allocated_a3000mem;
31:
1.1.1.3 root 32: #ifdef SAVE_MEMORY_BANKS
33: addrbank *mem_banks[65536];
34: #else
35: addrbank mem_banks[65536];
36: #endif
1.1 root 37:
1.1.1.2 root 38: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5 root 39: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2 root 40: {
1.1.1.5 root 41: return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2 root 42: }
1.1.1.5 root 43: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2 root 44: {
1.1.1.5 root 45: return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2 root 46: }
1.1.1.5 root 47: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2 root 48: {
1.1.1.5 root 49: return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2 root 50: }
1.1.1.5 root 51: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2 root 52: {
1.1.1.5 root 53: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2 root 54: }
1.1.1.5 root 55: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2 root 56: {
1.1.1.5 root 57: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2 root 58: }
1.1.1.5 root 59: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2 root 60: {
1.1.1.5 root 61: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2 root 62: }
63: #endif
64:
1.1.1.3 root 65: uae_u32 chipmem_mask, kickmem_mask, bogomem_mask, a3000mem_mask;
1.1 root 66:
1.1.1.3 root 67: /* A dummy bank that only contains zeros */
68:
1.1.1.4 root 69: static uae_u32 dummy_lget (uaecptr) REGPARAM;
70: static uae_u32 dummy_wget (uaecptr) REGPARAM;
71: static uae_u32 dummy_bget (uaecptr) REGPARAM;
72: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
73: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
74: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
75: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
76:
77: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
78: {
79: if (currprefs.illegal_mem)
80: write_log ("Illegal lget at %08lx\n", addr);
81:
1.1 root 82: return 0;
83: }
84:
1.1.1.4 root 85: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1 root 86: {
1.1.1.4 root 87: if (currprefs.illegal_mem)
88: write_log ("Illegal wget at %08lx\n", addr);
89:
1.1 root 90: return 0;
91: }
92:
1.1.1.4 root 93: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1 root 94: {
1.1.1.4 root 95: if (currprefs.illegal_mem)
96: write_log ("Illegal bget at %08lx\n", addr);
97:
1.1 root 98: return 0;
99: }
100:
1.1.1.4 root 101: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1 root 102: {
1.1.1.4 root 103: if (currprefs.illegal_mem)
104: write_log ("Illegal lput at %08lx\n", addr);
1.1.1.3 root 105: }
1.1.1.4 root 106: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 107: {
1.1.1.4 root 108: if (currprefs.illegal_mem)
109: write_log ("Illegal wput at %08lx\n", addr);
1.1.1.3 root 110: }
1.1.1.4 root 111: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 112: {
1.1.1.4 root 113: if (currprefs.illegal_mem)
114: write_log ("Illegal bput at %08lx\n", addr);
1.1 root 115: }
116:
1.1.1.4 root 117: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1 root 118: {
1.1.1.4 root 119: if (currprefs.illegal_mem)
120: write_log ("Illegal check at %08lx\n", addr);
121:
1.1 root 122: return 0;
123: }
124:
1.1.1.3 root 125: /* A3000 "motherboard resources" bank. */
1.1.1.4 root 126: static uae_u32 mbres_lget (uaecptr) REGPARAM;
127: static uae_u32 mbres_wget (uaecptr) REGPARAM;
128: static uae_u32 mbres_bget (uaecptr) REGPARAM;
129: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
130: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
131: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
132: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3 root 133:
134: static int mbres_val = 0;
135:
1.1.1.4 root 136: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3 root 137: {
1.1.1.4 root 138: if (currprefs.illegal_mem)
139: write_log ("Illegal lget at %08lx\n", addr);
140:
1.1 root 141: return 0;
142: }
143:
1.1.1.4 root 144: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1 root 145: {
1.1.1.4 root 146: if (currprefs.illegal_mem)
147: write_log ("Illegal wget at %08lx\n", addr);
148:
1.1 root 149: return 0;
150: }
151:
1.1.1.4 root 152: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3 root 153: {
1.1.1.4 root 154: if (currprefs.illegal_mem)
155: write_log ("Illegal bget at %08lx\n", addr);
156:
1.1.1.3 root 157: return (addr & 0xFFFF) == 3 ? mbres_val : 0;
158: }
159:
1.1.1.4 root 160: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1 root 161: {
1.1.1.4 root 162: if (currprefs.illegal_mem)
163: write_log ("Illegal lput at %08lx\n", addr);
1.1 root 164: }
1.1.1.4 root 165: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1 root 166: {
1.1.1.4 root 167: if (currprefs.illegal_mem)
168: write_log ("Illegal wput at %08lx\n", addr);
1.1 root 169: }
1.1.1.4 root 170: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1 root 171: {
1.1.1.4 root 172: if (currprefs.illegal_mem)
173: write_log ("Illegal bput at %08lx\n", addr);
174:
1.1.1.3 root 175: if ((addr & 0xFFFF) == 3)
176: mbres_val = b;
1.1 root 177: }
178:
1.1.1.4 root 179: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1 root 180: {
1.1.1.4 root 181: if (currprefs.illegal_mem)
182: write_log ("Illegal check at %08lx\n", addr);
183:
1.1 root 184: return 0;
185: }
186:
187: /* Chip memory */
188:
1.1.1.3 root 189: uae_u8 *chipmemory;
1.1 root 190:
1.1.1.4 root 191: static uae_u32 chipmem_lget (uaecptr) REGPARAM;
192: static uae_u32 chipmem_wget (uaecptr) REGPARAM;
193: static uae_u32 chipmem_bget (uaecptr) REGPARAM;
194: static void chipmem_lput (uaecptr, uae_u32) REGPARAM;
195: static void chipmem_wput (uaecptr, uae_u32) REGPARAM;
196: static void chipmem_bput (uaecptr, uae_u32) REGPARAM;
197: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
198: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1 root 199:
1.1.1.4 root 200: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1 root 201: {
1.1.1.3 root 202: uae_u32 *m;
1.1 root 203: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 204: addr &= chipmem_mask;
1.1.1.3 root 205: m = (uae_u32 *)(chipmemory + addr);
1.1.1.5 root 206: return do_get_mem_long (m);
1.1 root 207: }
208:
1.1.1.4 root 209: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1 root 210: {
1.1.1.3 root 211: uae_u16 *m;
1.1 root 212: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 213: addr &= chipmem_mask;
1.1.1.3 root 214: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 215: return do_get_mem_word (m);
1.1 root 216: }
217:
1.1.1.4 root 218: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1 root 219: {
220: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 221: addr &= chipmem_mask;
1.1 root 222: return chipmemory[addr];
223: }
224:
1.1.1.4 root 225: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1 root 226: {
1.1.1.3 root 227: uae_u32 *m;
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_u32 *)(chipmemory + addr);
1.1.1.5 root 231: do_put_mem_long (m, l);
1.1 root 232: }
233:
1.1.1.4 root 234: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1 root 235: {
1.1.1.3 root 236: uae_u16 *m;
1.1 root 237: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 238: addr &= chipmem_mask;
1.1.1.3 root 239: m = (uae_u16 *)(chipmemory + addr);
1.1.1.5 root 240: do_put_mem_word (m, w);
1.1 root 241: }
242:
1.1.1.4 root 243: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1 root 244: {
245: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 246: addr &= chipmem_mask;
1.1 root 247: chipmemory[addr] = b;
248: }
249:
1.1.1.4 root 250: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1 root 251: {
252: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 253: addr &= chipmem_mask;
1.1.1.4 root 254: return (addr + size) <= allocated_chipmem;
1.1 root 255: }
256:
1.1.1.4 root 257: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1 root 258: {
259: addr -= chipmem_start & chipmem_mask;
1.1.1.2 root 260: addr &= chipmem_mask;
1.1 root 261: return chipmemory + addr;
262: }
263:
264: /* Slow memory */
265:
1.1.1.3 root 266: static uae_u8 *bogomemory;
1.1 root 267:
1.1.1.4 root 268: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
269: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
270: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
271: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
272: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
273: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
274: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
275: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1 root 276:
1.1.1.4 root 277: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1 root 278: {
1.1.1.3 root 279: uae_u32 *m;
1.1 root 280: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 281: addr &= bogomem_mask;
1.1.1.3 root 282: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 283: return do_get_mem_long (m);
1.1 root 284: }
285:
1.1.1.4 root 286: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1 root 287: {
1.1.1.3 root 288: uae_u16 *m;
1.1 root 289: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 290: addr &= bogomem_mask;
1.1.1.3 root 291: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 292: return do_get_mem_word (m);
1.1 root 293: }
294:
1.1.1.4 root 295: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1 root 296: {
297: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 298: addr &= bogomem_mask;
1.1 root 299: return bogomemory[addr];
300: }
301:
1.1.1.4 root 302: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1 root 303: {
1.1.1.3 root 304: uae_u32 *m;
1.1 root 305: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 306: addr &= bogomem_mask;
1.1.1.3 root 307: m = (uae_u32 *)(bogomemory + addr);
1.1.1.5 root 308: do_put_mem_long (m, l);
1.1 root 309: }
310:
1.1.1.4 root 311: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1 root 312: {
1.1.1.3 root 313: uae_u16 *m;
1.1 root 314: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 315: addr &= bogomem_mask;
1.1.1.3 root 316: m = (uae_u16 *)(bogomemory + addr);
1.1.1.5 root 317: do_put_mem_word (m, w);
1.1 root 318: }
319:
1.1.1.4 root 320: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1 root 321: {
322: addr -= bogomem_start & bogomem_mask;
1.1.1.2 root 323: addr &= bogomem_mask;
1.1 root 324: bogomemory[addr] = b;
325: }
326:
1.1.1.4 root 327: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1 root 328: {
1.1.1.2 root 329: addr -= bogomem_start & bogomem_mask;
330: addr &= bogomem_mask;
1.1.1.4 root 331: return (addr + size) <= allocated_bogomem;
1.1 root 332: }
333:
1.1.1.4 root 334: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1 root 335: {
1.1.1.2 root 336: addr -= bogomem_start & bogomem_mask;
337: addr &= bogomem_mask;
1.1 root 338: return bogomemory + addr;
339: }
340:
1.1.1.3 root 341: /* A3000 motherboard fast memory */
342:
343: static uae_u8 *a3000memory;
1.1 root 344:
1.1.1.4 root 345: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
346: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
347: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
348: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
349: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
350: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
351: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
352: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 353:
1.1.1.4 root 354: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3 root 355: {
356: uae_u32 *m;
357: addr -= a3000mem_start & a3000mem_mask;
358: addr &= a3000mem_mask;
359: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 360: return do_get_mem_long (m);
1.1.1.3 root 361: }
1.1 root 362:
1.1.1.4 root 363: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3 root 364: {
365: uae_u16 *m;
366: addr -= a3000mem_start & a3000mem_mask;
367: addr &= a3000mem_mask;
368: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 369: return do_get_mem_word (m);
1.1.1.3 root 370: }
1.1 root 371:
1.1.1.4 root 372: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1 root 373: {
1.1.1.3 root 374: addr -= a3000mem_start & a3000mem_mask;
375: addr &= a3000mem_mask;
376: return a3000memory[addr];
1.1 root 377: }
378:
1.1.1.4 root 379: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1 root 380: {
1.1.1.3 root 381: uae_u32 *m;
382: addr -= a3000mem_start & a3000mem_mask;
383: addr &= a3000mem_mask;
384: m = (uae_u32 *)(a3000memory + addr);
1.1.1.5 root 385: do_put_mem_long (m, l);
1.1.1.3 root 386: }
387:
1.1.1.4 root 388: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3 root 389: {
390: uae_u16 *m;
391: addr -= a3000mem_start & a3000mem_mask;
392: addr &= a3000mem_mask;
393: m = (uae_u16 *)(a3000memory + addr);
1.1.1.5 root 394: do_put_mem_word (m, w);
1.1.1.3 root 395: }
396:
1.1.1.4 root 397: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3 root 398: {
399: addr -= a3000mem_start & a3000mem_mask;
400: addr &= a3000mem_mask;
401: a3000memory[addr] = b;
402: }
403:
1.1.1.4 root 404: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3 root 405: {
406: addr -= a3000mem_start & a3000mem_mask;
407: addr &= a3000mem_mask;
1.1.1.4 root 408: return (addr + size) <= allocated_a3000mem;
1.1 root 409: }
410:
1.1.1.3 root 411: uae_u8 REGPARAM2 *a3000mem_xlate(uaecptr addr)
412: {
413: addr -= a3000mem_start & a3000mem_mask;
414: addr &= a3000mem_mask;
415: return a3000memory + addr;
416: }
417:
418: /* Kick memory */
419:
420: uae_u8 *kickmemory;
421:
1.1.1.4 root 422: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
423: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
424: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
425: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
426: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
427: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
428: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
429: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3 root 430:
1.1.1.4 root 431: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1 root 432: {
1.1.1.3 root 433: uae_u32 *m;
1.1 root 434: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 435: addr &= kickmem_mask;
1.1.1.3 root 436: m = (uae_u32 *)(kickmemory + addr);
1.1.1.5 root 437: return do_get_mem_long (m);
1.1 root 438: }
439:
1.1.1.4 root 440: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1 root 441: {
1.1.1.3 root 442: uae_u16 *m;
1.1 root 443: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 444: addr &= kickmem_mask;
1.1.1.3 root 445: m = (uae_u16 *)(kickmemory + addr);
1.1.1.5 root 446: return do_get_mem_word (m);
1.1 root 447: }
448:
1.1.1.4 root 449: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1 root 450: {
451: addr -= kickmem_start & kickmem_mask;
1.1.1.2 root 452: addr &= kickmem_mask;
1.1 root 453: return kickmemory[addr];
454: }
455:
1.1.1.4 root 456: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1 root 457: {
1.1.1.4 root 458: if (currprefs.illegal_mem)
459: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 460: }
461:
1.1.1.4 root 462: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1 root 463: {
1.1.1.4 root 464: if (currprefs.illegal_mem)
465: write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1 root 466: }
467:
1.1.1.4 root 468: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1 root 469: {
1.1.1.4 root 470: if (currprefs.illegal_mem)
471: write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1 root 472: }
473:
1.1.1.4 root 474: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1 root 475: {
1.1.1.2 root 476: addr -= kickmem_start & kickmem_mask;
477: addr &= kickmem_mask;
1.1.1.4 root 478: return (addr + size) <= kickmem_size;
1.1 root 479: }
480:
1.1.1.4 root 481: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1 root 482: {
1.1.1.2 root 483: addr -= kickmem_start & kickmem_mask;
484: addr &= kickmem_mask;
1.1 root 485: return kickmemory + addr;
486: }
487:
1.1.1.3 root 488: /* Default memory access functions */
489:
1.1.1.4 root 490: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
1.1.1.3 root 491: {
492: return 0;
493: }
494:
1.1.1.4 root 495: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
1.1.1.3 root 496: {
497: write_log ("Your Amiga program just did something terribly stupid\n");
498: uae_reset();
499: return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
500: }
501:
1.1.1.4 root 502: static int load_kickstart (void)
1.1 root 503: {
504: int i;
1.1.1.3 root 505: uae_u32 cksum = 0, prevck = 0;
506: unsigned char buffer[20];
507:
1.1.1.6 ! root 508: FILE *f = zfile_open (currprefs.romfile, "rb");
1.1.1.3 root 509:
510: if (f == NULL) {
511: write_log ("No Kickstart ROM found.\n");
1.1.1.6 ! root 512: #if defined AMIGA || defined __POS__
1.1.1.2 root 513: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
1.1.1.6 ! root 514: if (!getenv (USE_UAE_ERSATZ)) {
! 515: fprintf (stderr, "Using current ROM. (create ENV:%s to "
! 516: "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
! 517: memcpy (kickmemory, (char*)0x1000000 - kickmem_size, kickmem_size);
1.1.1.2 root 518: goto chk_sum;
519: }
520: #endif
1.1 root 521: return 0;
522: }
1.1.1.3 root 523:
524: i = fread (buffer, 1, 11, f);
525: if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) != 0)
526: fseek (f, 0, SEEK_SET);
527:
528: i = fread (kickmemory, 1, kickmem_size, f);
1.1 root 529: if (i == kickmem_size/2) {
530: memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
531: } else if (i != kickmem_size) {
1.1.1.3 root 532: write_log ("Error while reading Kickstart.\n");
1.1 root 533: return 0;
534: }
535: zfile_close (f);
1.1.1.3 root 536:
537: cloanto_rom = 0;
538: if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) == 0) {
539: FILE *keyf;
540: uae_u8 *p;
541: long size, cnt, t;
542:
543: cloanto_rom = 1;
544: write_log ("ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
1.1.1.6 ! root 545: if (strlen (currprefs.keyfile) == 0) {
1.1.1.3 root 546: write_log ("No filename given for ROM key file.\n");
547: return 0;
548: }
1.1.1.6 ! root 549: keyf = zfile_open (currprefs.keyfile, "rb");
1.1.1.3 root 550: if (keyf == 0) {
551: write_log ("Could not find ROM key file.\n");
552: return 0;
553: }
554: p = (uae_u8 *)xmalloc (524288);
555: size = fread (p, 1, 524288, keyf);
556:
557: for (t = cnt = 0; cnt < kickmem_size; cnt++, t = (t + 1) % size) {
558: kickmemory[cnt] ^= p[t];
559: if (i == cnt+1)
560: t = size-1;
561: }
562: fclose (keyf);
563: free (p);
564: }
1.1.1.2 root 565: #if defined(AMIGA)
566: chk_sum:
567: #endif
568:
1.1 root 569: for (i = 0; i < kickmem_size; i+=4) {
1.1.1.3 root 570: uae_u32 data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
1.1 root 571: cksum += data;
572: if (cksum < prevck)
573: cksum++;
574: prevck = cksum;
575: }
1.1.1.2 root 576: if (cksum != 0xFFFFFFFFul) {
1.1.1.4 root 577: write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
1.1 root 578: }
579: return 1;
580: }
581:
582: /* Address banks */
583:
584: addrbank dummy_bank = {
585: dummy_lget, dummy_wget, dummy_bget,
586: dummy_lput, dummy_wput, dummy_bput,
587: default_xlate, dummy_check
588: };
589:
1.1.1.3 root 590: addrbank mbres_bank = {
591: mbres_lget, mbres_wget, mbres_bget,
592: mbres_lput, mbres_wput, mbres_bput,
593: default_xlate, mbres_check
594: };
595:
1.1 root 596: addrbank chipmem_bank = {
597: chipmem_lget, chipmem_wget, chipmem_bget,
598: chipmem_lput, chipmem_wput, chipmem_bput,
599: chipmem_xlate, chipmem_check
600: };
601:
602: addrbank bogomem_bank = {
603: bogomem_lget, bogomem_wget, bogomem_bget,
604: bogomem_lput, bogomem_wput, bogomem_bput,
605: bogomem_xlate, bogomem_check
606: };
607:
1.1.1.3 root 608: addrbank a3000mem_bank = {
609: a3000mem_lget, a3000mem_wget, a3000mem_bget,
610: a3000mem_lput, a3000mem_wput, a3000mem_bput,
611: a3000mem_xlate, a3000mem_check
612: };
613:
1.1 root 614: addrbank kickmem_bank = {
615: kickmem_lget, kickmem_wget, kickmem_bget,
616: kickmem_lput, kickmem_wput, kickmem_bput,
617: kickmem_xlate, kickmem_check
618: };
619:
620: char *address_space, *good_address_map;
621: int good_address_fd;
1.1.1.4 root 622:
623: static void init_mem_banks (void)
624: {
625: int i;
626: for (i = 0; i < 65536; i++)
627: put_mem_bank (i<<16, &dummy_bank);
628: }
629:
1.1.1.2 root 630: #define MAKE_USER_PROGRAMS_BEHAVE 1
1.1.1.4 root 631: void memory_init (void)
1.1 root 632: {
633: char buffer[4096];
634: char *nam;
635: int i, fd;
1.1.1.3 root 636: int custom_start;
1.1 root 637:
1.1.1.4 root 638: allocated_chipmem = currprefs.chipmem_size;
639: allocated_bogomem = currprefs.bogomem_size;
640: allocated_a3000mem = currprefs.a3000mem_size;
1.1.1.3 root 641:
1.1.1.2 root 642: #ifdef USE_MAPPED_MEMORY
1.1.1.4 root 643: fd = open ("/dev/zero", O_RDWR);
644: good_address_map = mmap (NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
1.1.1.2 root 645: /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon
646: * as a decrunch routine tries to do color register hacks. */
1.1.1.4 root 647: address_space = mmap (NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0);
1.1.1.2 root 648: if ((int)address_space < 0 || (int)good_address_map < 0) {
1.1.1.3 root 649: write_log ("Your system does not have enough virtual memory - increase swap.\n");
1.1.1.4 root 650: abort ();
1.1.1.2 root 651: }
652: #ifdef MAKE_USER_PROGRAMS_BEHAVE
1.1.1.4 root 653: memset (address_space + 0xDFF180, 0xFF, 32*2);
1.1.1.2 root 654: #else
655: /* Likewise. This is mostly for mouse button checks. */
656: if (USER_PROGRAMS_BEHAVE)
1.1.1.4 root 657: memset (address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000);
1.1.1.2 root 658: #endif
1.1.1.4 root 659: chipmemory = mmap (address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
660: kickmemory = mmap (address_space + 0xF80000, 0x80000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
1.1 root 661:
662: close(fd);
663:
1.1.1.4 root 664: good_address_fd = open (nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600);
1.1.1.3 root 665: memset (buffer, 1, sizeof(buffer));
666: write (good_address_fd, buffer, sizeof buffer);
667: unlink (nam);
1.1 root 668:
1.1.1.4 root 669: for (i = 0; i < allocated_chipmem; i += 4096)
670: mmap (good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
671: good_address_fd, 0);
1.1 root 672: for (i = 0; i < kickmem_size; i += 4096)
1.1.1.4 root 673: mmap (good_address_map + i + 0x1000000 - kickmem_size, 4096, PROT_READ,
674: MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
1.1 root 675: #else
1.1.1.4 root 676: kickmemory = (uae_u8 *)xmalloc (kickmem_size);
677: chipmemory = (uae_u8 *)malloc (allocated_chipmem);
1.1.1.3 root 678:
1.1.1.4 root 679: while (! chipmemory && allocated_chipmem > 512*1024) {
680: allocated_chipmem >>= 1;
681: chipmemory = (uae_u8 *)malloc (allocated_chipmem);
1.1.1.3 root 682: if (chipmemory)
1.1.1.4 root 683: fprintf (stderr, "Reducing chipmem size to %dkb\n", allocated_chipmem >> 10);
1.1.1.3 root 684: }
1.1.1.4 root 685: if (! chipmemory) {
1.1.1.3 root 686: write_log ("virtual memory exhausted (chipmemory)!\n");
1.1.1.4 root 687: abort ();
1.1.1.2 root 688: }
1.1 root 689: #endif
1.1.1.6 ! root 690:
! 691: do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
1.1.1.4 root 692: init_mem_banks ();
1.1.1.3 root 693:
1.1 root 694: /* Map the chipmem into all of the lower 16MB */
1.1.1.3 root 695: map_banks (&chipmem_bank, 0x00, 256);
696: custom_start = 0xC0;
1.1 root 697:
1.1.1.3 root 698: map_banks (&custom_bank, custom_start, 0xE0-custom_start);
699: map_banks (&cia_bank, 0xA0, 32);
700: map_banks (&clock_bank, 0xDC, 1);
701:
702: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
703: * range on an Amiga without expansion memory? */
1.1.1.4 root 704: custom_start = allocated_chipmem >> 16;
1.1.1.3 root 705: if (custom_start < 0x20)
706: custom_start = 0x20;
707: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start);
708: /*map_banks (&mbres_bank, 0xDE, 1);*/
709:
1.1.1.4 root 710: if (allocated_bogomem > 0)
711: bogomemory = (uae_u8 *)xmalloc (allocated_bogomem);
712: if (bogomemory != 0)
713: map_banks (&bogomem_bank, 0xC0, allocated_bogomem >> 16);
714: else
715: allocated_bogomem = 0;
716:
717: if (allocated_a3000mem > 0)
718: a3000memory = (uae_u8 *)xmalloc (allocated_a3000mem);
719: if (a3000memory != 0)
720: map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16);
721: else
722: allocated_a3000mem = 0;
1.1.1.3 root 723:
724: map_banks (&rtarea_bank, 0xF0, 1);
1.1.1.4 root 725: if (! load_kickstart ()) {
1.1.1.3 root 726: init_ersatz_rom (kickmemory);
1.1 root 727: ersatzkickfile = 1;
728: }
1.1.1.3 root 729: map_banks (&kickmem_bank, 0xF8, 8);
730: map_banks (&expamem_bank, 0xE8, 1);
731:
732: if (cloanto_rom)
733: map_banks (&kickmem_bank, 0xE0, 8);
1.1.1.4 root 734:
735: chipmem_mask = allocated_chipmem- 1;
736: kickmem_mask = kickmem_size - 1;
737: bogomem_mask = allocated_bogomem - 1;
738: a3000mem_mask = allocated_a3000mem - 1;
739:
1.1 root 740: }
741:
1.1.1.4 root 742: void map_banks (addrbank *bank, int start, int size)
1.1 root 743: {
744: int bnr;
1.1.1.3 root 745: unsigned long int hioffs = 0, endhioffs = 0x100;
746:
747: if (start >= 0x100) {
748: for (bnr = start; bnr < start + size; bnr++)
749: put_mem_bank (bnr << 16, bank);
750: return;
751: }
752: /* Some '020 Kickstarts apparently require a 24 bit address space... */
753: if (currprefs.address_space_24)
754: endhioffs = 0x10000;
755: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
756: for (bnr = start; bnr < start+size; bnr++)
1.1.1.5 root 757: put_mem_bank ((bnr + hioffs) << 16, bank);
1.1 root 758: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.