|
|
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"
14: #include "memory.h"
15: #include "custom.h"
16: #include "cia.h"
17: #include "ersatz.h"
18: #include "zfile.h"
19: #include "events.h"
20: #include "newcpu.h"
21: #include "compiler.h"
22:
23: #ifdef USE_COMPILER
24: #include <sys/mman.h>
25: #endif
26:
27: int ersatzkickfile = 0;
28:
29: int buserr;
30: addrbank membanks[65536];
31:
32: /* Default memory access functions */
33:
34: int default_check(CPTR a, ULONG b)
35: {
36: return 0;
37: }
38:
39: UBYTE *default_xlate(CPTR a)
40: {
41: fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
42: return 0;
43: }
44:
45: UWORD default_awget(CPTR addr)
46: {
47: default_xlate(addr);
48: return 0;
49: }
50:
51: ULONG default_alget(CPTR addr)
52: {
53: default_xlate(addr);
54: return 0;
55: }
56:
57: /* A dummy bank that only contains zeros */
58:
59: static ULONG dummy_lget(CPTR) REGPARAM;
60: static UWORD dummy_wget(CPTR) REGPARAM;
61: static UBYTE dummy_bget(CPTR) REGPARAM;
62: static void dummy_lput(CPTR, ULONG) REGPARAM;
63: static void dummy_wput(CPTR, UWORD) REGPARAM;
64: static void dummy_bput(CPTR, UBYTE) REGPARAM;
65: static int dummy_check(CPTR addr, ULONG size) REGPARAM;
66:
67: ULONG dummy_lget(CPTR addr)
68: {
69: if (illegal_mem) printf("Illegal lget at %08lx pc=%08lx\n",addr,m68k_getpc());
70: return 0;
71: }
72:
73: UWORD dummy_wget(CPTR addr)
74: {
75: if (illegal_mem) printf("Illegal wget at %08lx pc=%08lx\n",addr,m68k_getpc());
76: return 0;
77: }
78:
79: UBYTE dummy_bget(CPTR addr)
80: {
81: if (illegal_mem) printf("Illegal bget at %08lx pc=%08lx\n",addr,m68k_getpc());
82: return 0;
83: }
84:
85: void dummy_lput(CPTR addr, ULONG l)
86: {
87: if (illegal_mem) printf("Illegal lput at %08lx pc=%08lx\n",addr,m68k_getpc());
88: }
89: void dummy_wput(CPTR addr, UWORD w)
90: {
91: if (illegal_mem) printf("Illegal wput at %08lx pc=%08lx\n",addr,m68k_getpc());
92: }
93: void dummy_bput(CPTR addr, UBYTE b)
94: {
95: if (illegal_mem) printf("Illegal bput at %08lx pc=%08lx\n",addr,m68k_getpc());
96: }
97:
98: int dummy_check(CPTR addr, ULONG size)
99: {
100: if (illegal_mem) printf("Illegal check at %08lx pc=%08lx\n",addr,m68k_getpc());
101: return 0;
102: }
103:
104: /* Chip memory */
105:
106: ULONG chipmem_mask,kickmem_mask,bogomem_mask;
107:
108: UBYTE *chipmemory;
109:
110: static ULONG chipmem_alget(CPTR) REGPARAM;
111: static UWORD chipmem_awget(CPTR) REGPARAM;
112:
113: static ULONG chipmem_lget(CPTR) REGPARAM;
114: static UWORD chipmem_wget(CPTR) REGPARAM;
115: static UBYTE chipmem_bget(CPTR) REGPARAM;
116: static void chipmem_lput(CPTR, ULONG) REGPARAM;
117: static void chipmem_wput(CPTR, UWORD) REGPARAM;
118: static void chipmem_bput(CPTR, UBYTE) REGPARAM;
119:
120: static int chipmem_check(CPTR addr, ULONG size) REGPARAM;
121: static UBYTE *chipmem_xlate(CPTR addr) REGPARAM;
122:
123: ULONG chipmem_alget(CPTR addr)
124: {
125: UBYTE *m;
126: addr -= chipmem_start & chipmem_mask;
127: addr &= chipmem_size-1;
128: m = chipmemory + addr;
129: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16)
130: + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
131: }
132:
133: UWORD chipmem_awget(CPTR addr)
134: {
135: UBYTE *m;
136: addr -= chipmem_start & chipmem_mask;
137: addr &= chipmem_size-1;
138: m = chipmemory + addr;
139: return ((UWORD)m[0] << 8) + m[1];
140: }
141:
142: ULONG chipmem_lget(CPTR addr)
143: {
144: UBYTE *m;
145: addr -= chipmem_start & chipmem_mask;
146: addr &= chipmem_size-1;
147: m = chipmemory + addr;
148: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16)
149: + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
150: }
151:
152: UWORD chipmem_wget(CPTR addr)
153: {
154: UBYTE *m;
155: addr -= chipmem_start & chipmem_mask;
156: addr &= chipmem_size-1;
157: m = chipmemory + addr;
158: return ((UWORD)m[0] << 8) + m[1];
159: }
160:
161: UBYTE chipmem_bget(CPTR addr)
162: {
163: addr -= chipmem_start & chipmem_mask;
164: addr &= chipmem_size-1;
165: return chipmemory[addr];
166: }
167:
168: void chipmem_lput(CPTR addr, ULONG l)
169: {
170: UBYTE *m;
171: addr -= chipmem_start & chipmem_mask;
172: addr &= chipmem_size-1;
173: m = chipmemory + addr;
174: m[0] = l >> 24;
175: m[1] = l >> 16;
176: m[2] = l >> 8;
177: m[3] = l;
178: }
179:
180: void chipmem_wput(CPTR addr, UWORD w)
181: {
182: UBYTE *m;
183: addr -= chipmem_start & chipmem_mask;
184: addr &= chipmem_size-1;
185: m = chipmemory + addr;
186: m[0] = w >> 8;
187: m[1] = w;
188: }
189:
190: void chipmem_bput(CPTR addr, UBYTE b)
191: {
192: addr -= chipmem_start & chipmem_mask;
193: addr &= chipmem_size-1;
194: chipmemory[addr] = b;
195: }
196:
197: int chipmem_check(CPTR addr, ULONG size)
198: {
199: addr -= chipmem_start & chipmem_mask;
200: addr &= chipmem_size-1;
201: return (addr + size) < chipmem_size;
202: }
203:
204: UBYTE *chipmem_xlate(CPTR addr)
205: {
206: addr -= chipmem_start & chipmem_mask;
207: addr &= chipmem_size-1;
208: return chipmemory + addr;
209: }
210:
211: /* Slow memory */
212:
213: static UBYTE *bogomemory;
214:
215: static ULONG bogomem_alget(CPTR) REGPARAM;
216: static UWORD bogomem_awget(CPTR) REGPARAM;
217: static ULONG bogomem_lget(CPTR) REGPARAM;
218: static UWORD bogomem_wget(CPTR) REGPARAM;
219: static UBYTE bogomem_bget(CPTR) REGPARAM;
220: static void bogomem_lput(CPTR, ULONG) REGPARAM;
221: static void bogomem_wput(CPTR, UWORD) REGPARAM;
222: static void bogomem_bput(CPTR, UBYTE) REGPARAM;
223: static int bogomem_check(CPTR addr, ULONG size) REGPARAM;
224: static UBYTE *bogomem_xlate(CPTR addr) REGPARAM;
225:
226: ULONG bogomem_alget(CPTR addr)
227: {
228: UBYTE *m;
229: addr -= bogomem_start & bogomem_mask;
230: addr &= bogomem_size-1;
231: m = bogomemory + addr;
232: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16)
233: + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
234: }
235:
236: UWORD bogomem_awget(CPTR addr)
237: {
238: UBYTE *m;
239: addr -= bogomem_start & bogomem_mask;
240: addr &= bogomem_size-1;
241: m = bogomemory + addr;
242: return ((UWORD)m[0] << 8) + m[1];
243: }
244:
245: ULONG bogomem_lget(CPTR addr)
246: {
247: UBYTE *m;
248: addr -= bogomem_start & bogomem_mask;
249: addr &= bogomem_size-1;
250: m = bogomemory + addr;
251: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16)
252: + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
253: }
254:
255: UWORD bogomem_wget(CPTR addr)
256: {
257: UBYTE *m;
258: addr -= bogomem_start & bogomem_mask;
259: addr &= bogomem_size-1;
260: m = bogomemory + addr;
261: return ((UWORD)m[0] << 8) + m[1];
262: }
263:
264: UBYTE bogomem_bget(CPTR addr)
265: {
266: addr -= bogomem_start & bogomem_mask;
267: addr &= bogomem_size-1;
268: return bogomemory[addr];
269: }
270:
271: void bogomem_lput(CPTR addr, ULONG l)
272: {
273: UBYTE *m;
274: addr -= bogomem_start & bogomem_mask;
275: addr &= bogomem_size-1;
276: m = bogomemory + addr;
277: m[0] = l >> 24;
278: m[1] = l >> 16;
279: m[2] = l >> 8;
280: m[3] = l;
281: }
282:
283: void bogomem_wput(CPTR addr, UWORD w)
284: {
285: UBYTE *m;
286: addr -= bogomem_start & bogomem_mask;
287: addr &= bogomem_size-1;
288: m = bogomemory + addr;
289: m[0] = w >> 8;
290: m[1] = w;
291: }
292:
293: void bogomem_bput(CPTR addr, UBYTE b)
294: {
295: addr -= bogomem_start & bogomem_mask;
296: addr &= bogomem_size-1;
297: bogomemory[addr] = b;
298: }
299:
300: int bogomem_check(CPTR addr, ULONG size)
301: {
302: addr -= bogomem_start & (bogomem_size-1);
303: addr &= bogomem_size-1;
304: return (addr + size) < bogomem_size;
305: }
306:
307: UBYTE *bogomem_xlate(CPTR addr)
308: {
309: addr -= bogomem_start & (bogomem_size-1);
310: addr &= bogomem_size-1;
311: return bogomemory + addr;
312: }
313:
314: /* Kick memory */
315:
316: static int zkickfile = 0;
317: UBYTE *kickmemory;
318:
319: static ULONG kickmem_alget(CPTR) REGPARAM;
320: static UWORD kickmem_awget(CPTR) REGPARAM;
321: static ULONG kickmem_lget(CPTR) REGPARAM;
322: static UWORD kickmem_wget(CPTR) REGPARAM;
323: static UBYTE kickmem_bget(CPTR) REGPARAM;
324: static void kickmem_lput(CPTR, ULONG) REGPARAM;
325: static void kickmem_wput(CPTR, UWORD) REGPARAM;
326: static void kickmem_bput(CPTR, UBYTE) REGPARAM;
327: static int kickmem_check(CPTR addr, ULONG size) REGPARAM;
328: static UBYTE *kickmem_xlate(CPTR addr) REGPARAM;
329:
330: ULONG kickmem_alget(CPTR addr)
331: {
332: UBYTE *m;
333: addr -= kickmem_start & kickmem_mask;
334: addr &= kickmem_size-1;
335: m = kickmemory + addr;
336: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16)
337: + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
338: }
339:
340: UWORD kickmem_awget(CPTR addr)
341: {
342: UBYTE *m;
343: addr -= kickmem_start & kickmem_mask;
344: addr &= kickmem_size-1;
345: m = kickmemory + addr;
346: return ((UWORD)m[0] << 8) + m[1];
347: }
348:
349: ULONG kickmem_lget(CPTR addr)
350: {
351: UBYTE *m;
352: addr -= kickmem_start & kickmem_mask;
353: addr &= kickmem_size-1;
354: m = kickmemory + addr;
355: return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16)
356: + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
357: }
358:
359: UWORD kickmem_wget(CPTR addr)
360: {
361: UBYTE *m;
362: addr -= kickmem_start & kickmem_mask;
363: addr &= kickmem_size-1;
364: m = kickmemory + addr;
365: return ((UWORD)m[0] << 8) + m[1];
366: }
367:
368: UBYTE kickmem_bget(CPTR addr)
369: {
370: addr -= kickmem_start & kickmem_mask;
371: addr &= kickmem_size-1;
372: return kickmemory[addr];
373: }
374:
375: void kickmem_lput(CPTR addr, ULONG b)
376: {
377: if (illegal_mem) printf("Illegal kickmem lput at %08lx pc=%08lx\n",addr,m68k_getpc());
378: }
379:
380: void kickmem_wput(CPTR addr, UWORD b)
381: {
382: if (illegal_mem) printf("Illegal kickmem wput at %08lx pc=%08lx\n",addr,m68k_getpc());
383: }
384:
385: void kickmem_bput(CPTR addr, UBYTE b)
386: {
387: if (illegal_mem) printf("Illegal kickmem lput at %08lx pc=%08lx\n",addr,m68k_getpc());
388: }
389:
390: int kickmem_check(CPTR addr, ULONG size)
391: {
392: addr -= kickmem_start & (kickmem_size-1);
393: addr &= kickmem_size-1;
394: return (addr + size) < kickmem_size;
395: }
396:
397: UBYTE *kickmem_xlate(CPTR addr)
398: {
399: addr -= kickmem_start & (kickmem_size-1);
400: addr &= kickmem_size-1;
401: return kickmemory + addr;
402: }
403:
404: static int load_kickstart(void)
405: {
406: int i;
407: ULONG cksum = 0, prevck = 0;
408: unsigned char buffer[8];
409:
410: FILE *f = zfile_open(romfile, "rb");
411:
412: if (f == NULL) {
413: fprintf(stderr, "No Kickstart ROM found.\n");
414: return 0;
415: }
416:
417: fread(buffer, 1, 8, f);
418: if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
419: fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n");
420: zkickfile = 1;
421: } else
422: fseek(f, 0, SEEK_SET);
423:
424: i = fread(kickmemory, 1, kickmem_size, f);
425: if (i == kickmem_size/2) {
426: fprintf(stderr, "Warning: Kickstart is only 256K.\n");
427: memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
428: } else if (i != kickmem_size) {
429: fprintf(stderr, "Error while reading Kickstart.\n");
430: return 0;
431: }
432: zfile_close (f);
433:
434: for (i = 0; i < kickmem_size; i+=4) {
435: ULONG data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
436: cksum += data;
437: if (cksum < prevck)
438: cksum++;
439: prevck = cksum;
440: }
441: if (cksum != 0xFFFFFFFF) {
442: fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
443: }
444: return 1;
445: }
446:
447: /* Address banks */
448:
449: addrbank dummy_bank = {
450: default_alget, default_awget,
451: dummy_lget, dummy_wget, dummy_bget,
452: dummy_lput, dummy_wput, dummy_bput,
453: default_xlate, dummy_check
454: };
455:
456: addrbank chipmem_bank = {
457: chipmem_alget, chipmem_awget,
458: chipmem_lget, chipmem_wget, chipmem_bget,
459: chipmem_lput, chipmem_wput, chipmem_bput,
460: chipmem_xlate, chipmem_check
461: };
462:
463: addrbank bogomem_bank = {
464: bogomem_alget, bogomem_awget,
465: bogomem_lget, bogomem_wget, bogomem_bget,
466: bogomem_lput, bogomem_wput, bogomem_bput,
467: bogomem_xlate, bogomem_check
468: };
469:
470: addrbank kickmem_bank = {
471: kickmem_alget, kickmem_awget,
472: kickmem_lget, kickmem_wget, kickmem_bget,
473: kickmem_lput, kickmem_wput, kickmem_bput,
474: kickmem_xlate, kickmem_check
475: };
476:
477: char *address_space, *good_address_map;
478: int good_address_fd;
479:
480: void memory_init(void)
481: {
482: char buffer[4096];
483: char *nam;
484: int i, fd;
485: buserr = 0;
486:
487: chipmem_mask = chipmem_size - 1;
488: kickmem_mask = kickmem_size - 1;
489: bogomem_mask = bogomem_size - 1;
490:
491: #ifdef USE_COMPILER
492: fd = open("/dev/zero", O_RDWR);
493: good_address_map = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
494: address_space = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
495: chipmemory = mmap(address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
496: kickmemory = mmap(address_space + 0xF80000, 0x80000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
497:
498: close(fd);
499:
500: good_address_fd = open(nam = tmpnam(NULL), O_CREAT|O_RDWR, 0600);
501: memset(buffer,1,sizeof(buffer));
502: write(good_address_fd, buffer,sizeof(buffer));
503: unlink(nam);
504:
505: for (i = 0; i < chipmem_size; i += 4096)
506: mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
507: good_address_fd, 0);
508: for (i = 0; i < kickmem_size; i += 4096)
509: mmap(good_address_map + i + 0x1000000 - kickmem_size, 4096, PROT_READ,
510: MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
511: #else
512: chipmemory = (UBYTE *)malloc(chipmem_size);
513: kickmemory = (UBYTE *)malloc(kickmem_size);
514: #endif
515:
516: for(i = 0; i < 65536; i++)
517: membanks[i] = dummy_bank;
518:
519: /* Map the chipmem into all of the lower 16MB */
520: map_banks(&chipmem_bank, 0x00, 256);
521: map_banks(&custom_bank, 0xC0, 0x20);
522: map_banks(&cia_bank, 0xA0, 32);
523: map_banks(&clock_bank, 0xDC, 1);
524:
525: if (bogomem_size > 0) {
526: bogomemory = (UBYTE *)malloc(bogomem_size);
527: map_banks(&bogomem_bank, 0xC0, bogomem_size >> 16);
528: }
529:
530: map_banks(&rtarea_bank, 0xF0, 1);
531: if (!load_kickstart()) {
532: init_ersatz_rom(kickmemory);
533: ersatzkickfile = 1;
534: }
535: if (zkickfile)
536: map_banks(&kickmem_bank, 0x20, 8);
537:
538: map_banks(&kickmem_bank, 0xF8, 8);
539: if (!zkickfile)
540: map_banks(&expamem_bank, 0xE8, 1);
541: }
542:
543: void map_banks(addrbank *bank, int start, int size)
544: {
545: int bnr;
546: int hioffs = 0;
547: #if 0 && CPU_LEVEL < 2
548: for (hioffs = 0; hioffs < 256; hioffs++)
549: #endif
550: for (bnr = start; bnr < start+size; bnr++)
551: membanks[bnr + hioffs * 256] = *bank;
552: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.