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