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