|
|
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: #include "hatari-glue.h"
12: #include "maccess.h"
13: #include "memory.h"
14: #include "../includes/tos.h"
15: /*
16: #include "config.h"
17: #include "options.h"
18: #include "uae.h"
19: */
20: #ifdef USE_MAPPED_MEMORY
21: #include <sys/mman.h>
22: #endif
23:
24: #include "../includes/intercept.h"
25:
26:
27: extern unsigned char STRam[16*1024*1024]; /* See hatari.c */
28:
29:
30: /* Set by each memory handler that does not simply access real memory. */
31: int special_mem;
32:
33: uae_u32 allocated_STmem;
34: uae_u32 allocated_TTmem;
35:
36: uae_u32 STmem_mask, ROMmem_mask, IOmem_mask, TTmem_mask;
37:
38:
39: #ifdef SAVE_MEMORY_BANKS
40: addrbank *mem_banks[65536];
41: #else
42: addrbank mem_banks[65536];
43: #endif
44:
45: #ifdef NO_INLINE_MEMORY_ACCESS
46: __inline__ uae_u32 longget (uaecptr addr)
47: {
48: return call_mem_get_func (get_mem_bank (addr).lget, addr);
49: }
50: __inline__ uae_u32 wordget (uaecptr addr)
51: {
52: return call_mem_get_func (get_mem_bank (addr).wget, addr);
53: }
54: __inline__ uae_u32 byteget (uaecptr addr)
55: {
56: return call_mem_get_func (get_mem_bank (addr).bget, addr);
57: }
58: __inline__ void longput (uaecptr addr, uae_u32 l)
59: {
60: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
61: }
62: __inline__ void wordput (uaecptr addr, uae_u32 w)
63: {
64: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
65: }
66: __inline__ void byteput (uaecptr addr, uae_u32 b)
67: {
68: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
69: }
70: #endif
71:
72:
73: /* A dummy bank that only contains zeros */
74:
75: static uae_u32 dummy_lget (uaecptr) REGPARAM;
76: static uae_u32 dummy_wget (uaecptr) REGPARAM;
77: static uae_u32 dummy_bget (uaecptr) REGPARAM;
78: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
79: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
80: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
81: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
82:
83: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
84: {
85: special_mem |= S_READ;
86: if (illegal_mem)
87: write_log ("Illegal lget at %08lx\n", addr);
88:
89: return 0;
90: }
91:
92: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
93: {
94: special_mem |= S_READ;
95: if (illegal_mem)
96: write_log ("Illegal wget at %08lx\n", addr);
97:
98: return 0;
99: }
100:
101: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
102: {
103: special_mem |= S_READ;
104: if (illegal_mem)
105: write_log ("Illegal bget at %08lx\n", addr);
106:
107: return 0;
108: }
109:
110: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
111: {
112: special_mem |= S_WRITE;
113: if (illegal_mem)
114: write_log ("Illegal lput at %08lx\n", addr);
115: }
116: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
117: {
118: special_mem |= S_WRITE;
119: if (illegal_mem)
120: write_log ("Illegal wput at %08lx\n", addr);
121: }
122: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
123: {
124: special_mem |= S_WRITE;
125: if (illegal_mem)
126: write_log ("Illegal bput at %08lx\n", addr);
127: }
128:
129: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
130: {
131: if (illegal_mem)
132: write_log ("Illegal check at %08lx\n", addr);
133:
134: return 0;
135: }
136:
137:
138: /* ST RAM memory */
139:
140: uae_u8 *STmemory;
141:
142: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
143: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
144:
145: uae_u32 REGPARAM2 STmem_lget (uaecptr addr)
146: {
147: uae_u32 *m;
148:
149: addr -= STmem_start & STmem_mask;
150: addr &= STmem_mask;
151: m = (uae_u32 *)(STmemory + addr);
152: return do_get_mem_long (m);
153: }
154:
155: uae_u32 REGPARAM2 STmem_wget (uaecptr addr)
156: {
157: uae_u16 *m;
158:
159: addr -= STmem_start & STmem_mask;
160: addr &= STmem_mask;
161: m = (uae_u16 *)(STmemory + addr);
162: return do_get_mem_word (m);
163: }
164:
165: uae_u32 REGPARAM2 STmem_bget (uaecptr addr)
166: {
167: addr -= STmem_start & STmem_mask;
168: addr &= STmem_mask;
169: return STmemory[addr];
170: }
171:
172: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l)
173: {
174: uae_u32 *m;
175:
176: addr -= STmem_start & STmem_mask;
177: addr &= STmem_mask;
178: m = (uae_u32 *)(STmemory + addr);
179: do_put_mem_long (m, l);
180: }
181:
182: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w)
183: {
184: uae_u16 *m;
185:
186: addr -= STmem_start & STmem_mask;
187: addr &= STmem_mask;
188: m = (uae_u16 *)(STmemory + addr);
189: do_put_mem_word (m, w);
190: }
191:
192: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b)
193: {
194: addr -= STmem_start & STmem_mask;
195: addr &= STmem_mask;
196: STmemory[addr] = b;
197: }
198:
199: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size)
200: {
201: addr -= STmem_start & STmem_mask;
202: addr &= STmem_mask;
203: return (addr + size) <= allocated_STmem;
204: }
205:
206: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr)
207: {
208: addr -= STmem_start & STmem_mask;
209: addr &= STmem_mask;
210: return STmemory + addr;
211: }
212:
213:
214: /* TT fast memory */
215:
216: static uae_u8 *TTmemory;
217:
218: static uae_u32 TTmem_lget (uaecptr) REGPARAM;
219: static uae_u32 TTmem_wget (uaecptr) REGPARAM;
220: static uae_u32 TTmem_bget (uaecptr) REGPARAM;
221: static void TTmem_lput (uaecptr, uae_u32) REGPARAM;
222: static void TTmem_wput (uaecptr, uae_u32) REGPARAM;
223: static void TTmem_bput (uaecptr, uae_u32) REGPARAM;
224: static int TTmem_check (uaecptr addr, uae_u32 size) REGPARAM;
225: static uae_u8 *TTmem_xlate (uaecptr addr) REGPARAM;
226:
227: uae_u32 REGPARAM2 TTmem_lget (uaecptr addr)
228: {
229: uae_u32 *m;
230: addr -= TTmem_start & TTmem_mask;
231: addr &= TTmem_mask;
232: m = (uae_u32 *)(TTmemory + addr);
233: return do_get_mem_long (m);
234: }
235:
236: uae_u32 REGPARAM2 TTmem_wget (uaecptr addr)
237: {
238: uae_u16 *m;
239: addr -= TTmem_start & TTmem_mask;
240: addr &= TTmem_mask;
241: m = (uae_u16 *)(TTmemory + addr);
242: return do_get_mem_word (m);
243: }
244:
245: uae_u32 REGPARAM2 TTmem_bget (uaecptr addr)
246: {
247: addr -= TTmem_start & TTmem_mask;
248: addr &= TTmem_mask;
249: return TTmemory[addr];
250: }
251:
252: void REGPARAM2 TTmem_lput (uaecptr addr, uae_u32 l)
253: {
254: uae_u32 *m;
255: addr -= TTmem_start & TTmem_mask;
256: addr &= TTmem_mask;
257: m = (uae_u32 *)(TTmemory + addr);
258: do_put_mem_long (m, l);
259: }
260:
261: void REGPARAM2 TTmem_wput (uaecptr addr, uae_u32 w)
262: {
263: uae_u16 *m;
264: addr -= TTmem_start & TTmem_mask;
265: addr &= TTmem_mask;
266: m = (uae_u16 *)(TTmemory + addr);
267: do_put_mem_word (m, w);
268: }
269:
270: void REGPARAM2 TTmem_bput (uaecptr addr, uae_u32 b)
271: {
272: addr -= TTmem_start & TTmem_mask;
273: addr &= TTmem_mask;
274: TTmemory[addr] = b;
275: }
276:
277: int REGPARAM2 TTmem_check (uaecptr addr, uae_u32 size)
278: {
279: addr -= TTmem_start & TTmem_mask;
280: addr &= TTmem_mask;
281: return (addr + size) <= allocated_TTmem;
282: }
283:
284: uae_u8 REGPARAM2 *TTmem_xlate(uaecptr addr)
285: {
286: addr -= TTmem_start & TTmem_mask;
287: addr &= TTmem_mask;
288: return TTmemory + addr;
289: }
290:
291: /* ROM memory */
292:
293: uae_u8 *ROMmemory;
294:
295: static uae_u32 ROMmem_lget (uaecptr) REGPARAM;
296: static uae_u32 ROMmem_wget (uaecptr) REGPARAM;
297: static uae_u32 ROMmem_bget (uaecptr) REGPARAM;
298: static void ROMmem_lput (uaecptr, uae_u32) REGPARAM;
299: static void ROMmem_wput (uaecptr, uae_u32) REGPARAM;
300: static void ROMmem_bput (uaecptr, uae_u32) REGPARAM;
301: static int ROMmem_check (uaecptr addr, uae_u32 size) REGPARAM;
302: static uae_u8 *ROMmem_xlate (uaecptr addr) REGPARAM;
303:
304: uae_u32 REGPARAM2 ROMmem_lget (uaecptr addr)
305: {
306: uae_u32 *m;
307: addr -= ROMmem_start & ROMmem_mask;
308: addr &= ROMmem_mask;
309: m = (uae_u32 *)(ROMmemory + addr);
310: return do_get_mem_long (m);
311: }
312:
313: uae_u32 REGPARAM2 ROMmem_wget (uaecptr addr)
314: {
315: uae_u16 *m;
316: addr -= ROMmem_start & ROMmem_mask;
317: addr &= ROMmem_mask;
318: m = (uae_u16 *)(ROMmemory + addr);
319: return do_get_mem_word (m);
320: }
321:
322: uae_u32 REGPARAM2 ROMmem_bget (uaecptr addr)
323: {
324: addr -= ROMmem_start & ROMmem_mask;
325: addr &= ROMmem_mask;
326: return ROMmemory[addr];
327: }
328:
329: void REGPARAM2 ROMmem_lput (uaecptr addr, uae_u32 b)
330: {
331: if (illegal_mem)
332: write_log ("Illegal ROMmem lput at %08lx\n", addr);
333: }
334:
335: void REGPARAM2 ROMmem_wput (uaecptr addr, uae_u32 b)
336: {
337: if (illegal_mem)
338: write_log ("Illegal ROMmem wput at %08lx\n", addr);
339: }
340:
341: void REGPARAM2 ROMmem_bput (uaecptr addr, uae_u32 b)
342: {
343: if (illegal_mem)
344: write_log ("Illegal ROMmem lput at %08lx\n", addr);
345: }
346:
347: int REGPARAM2 ROMmem_check (uaecptr addr, uae_u32 size)
348: {
349: addr -= ROMmem_start & ROMmem_mask;
350: addr &= ROMmem_mask;
351: return (addr + size) <= ROMmem_size;
352: }
353:
354: uae_u8 REGPARAM2 *ROMmem_xlate (uaecptr addr)
355: {
356: addr -= ROMmem_start & ROMmem_mask;
357: addr &= ROMmem_mask;
358: return ROMmemory + addr;
359: }
360:
361:
362: /* Hardware IO memory */
363: /* see also intercept.c */
364:
365: uae_u8 *IOmemory;
366:
367: static int IOmem_check (uaecptr addr, uae_u32 size) REGPARAM;
368: static uae_u8 *IOmem_xlate (uaecptr addr) REGPARAM;
369:
370: int REGPARAM2 IOmem_check (uaecptr addr, uae_u32 size)
371: {
372: addr -= IOmem_start & IOmem_mask;
373: addr &= IOmem_mask;
374: return (addr + size) <= IOmem_size;
375: }
376:
377: uae_u8 REGPARAM2 *IOmem_xlate (uaecptr addr)
378: {
379: addr -= IOmem_start & IOmem_mask;
380: addr &= IOmem_mask;
381: return IOmemory + addr;
382: }
383:
384:
385:
386: /* Default memory access functions */
387:
388: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
389: {
390: return 0;
391: }
392:
393: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
394: {
395: write_log ("Your Atari program just did something terribly stupid\n");
396: Reset_Warm();
397: return ROMmem_xlate (get_long (0xFC0000)); /* So we don't crash. */
398: }
399:
400:
401: /* Address banks */
402:
403: addrbank dummy_bank = {
404: dummy_lget, dummy_wget, dummy_bget,
405: dummy_lput, dummy_wput, dummy_bput,
406: default_xlate, dummy_check
407: };
408:
409: addrbank STmem_bank = {
410: STmem_lget, STmem_wget, STmem_bget,
411: STmem_lput, STmem_wput, STmem_bput,
412: STmem_xlate, STmem_check
413: };
414:
415: addrbank TTmem_bank = {
416: TTmem_lget, TTmem_wget, TTmem_bget,
417: TTmem_lput, TTmem_wput, TTmem_bput,
418: TTmem_xlate, TTmem_check
419: };
420:
421: addrbank ROMmem_bank = {
422: ROMmem_lget, ROMmem_wget, ROMmem_bget,
423: ROMmem_lput, ROMmem_wput, ROMmem_bput,
424: ROMmem_xlate, ROMmem_check
425: };
426:
427: addrbank IOmem_bank = {
428: Intercept_ReadLong, Intercept_ReadWord, Intercept_ReadByte,
429: Intercept_WriteLong, Intercept_WriteWord, Intercept_WriteByte,
430: IOmem_xlate, IOmem_check
431: };
432:
433:
434: char *address_space, *good_address_map;
435: int good_address_fd;
436:
437: static void init_mem_banks (void)
438: {
439: int i;
440: for (i = 0; i < 65536; i++)
441: put_mem_bank (i<<16, &dummy_bank);
442: }
443:
444: #define MAKE_USER_PROGRAMS_BEHAVE 1
445: void memory_init (void)
446: {
447: char buffer[4096];
448: char *nam;
449: int i, fd;
450: /*int custom_start;*/
451:
452: allocated_STmem = STmem_size;
453: allocated_TTmem = TTmem_size;
454:
455: #ifdef USE_MAPPED_MEMORY
456: #error So nicht
457: fd = open ("/dev/zero", O_RDWR);
458: good_address_map = mmap (NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
459: /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon
460: * as a decrunch routine tries to do color register hacks. */
461: address_space = mmap (NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0);
462: if ((int)address_space < 0 || (int)good_address_map < 0) {
463: write_log ("Your system does not have enough virtual memory - increase swap.\n");
464: abort ();
465: }
466: #ifdef MAKE_USER_PROGRAMS_BEHAVE
467: memset (address_space + 0xDFF180, 0xFF, 32*2);
468: #else
469: /* Likewise. This is mostly for mouse button checks. */
470: if (USER_PROGRAMS_BEHAVE)
471: memset (address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000);
472: #endif
473: STmemory = mmap (address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
474: ROMmemory = mmap (address_space + TOSAddress, ROMmem_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
475:
476: close(fd);
477:
478: good_address_fd = open (nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600);
479: memset (buffer, 1, sizeof(buffer));
480: write (good_address_fd, buffer, sizeof buffer);
481: unlink (nam);
482:
483: for (i = 0; i < allocated_STmem; i += 4096)
484: mmap (good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
485: good_address_fd, 0);
486: for (i = 0; i < ROMmem_size; i += 4096)
487: mmap (good_address_map + i + 0x1000000 - ROMmem_size, 4096, PROT_READ,
488: MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
489: #else
490: ROMmemory = STRam+TOSAddress; /*(uae_u8 *)malloc (ROMmem_size)*/;
491: STmemory = STRam; /*(uae_u8 *)malloc (allocated_STmem);*/
492: /*
493: while (! STmemory && allocated_STmem > 512*1024) {
494: allocated_STmem >>= 1;
495: STmemory = (uae_u8 *)malloc (allocated_STmem);
496: if (STmemory)
497: fprintf (stderr, "Reducing STmem size to %dkb\n", allocated_STmem >> 10);
498: }
499: if (! STmemory) {
500: write_log ("virtual memory exhausted (STmemory)!\n");
501: abort ();
502: }
503: */
504: #endif
505:
506: do_put_mem_long ((uae_u32 *)(STmemory), do_get_mem_long((uae_u32 *)ROMmemory));
507: do_put_mem_long ((uae_u32 *)(STmemory + 4), do_get_mem_long((uae_u32 *)(ROMmemory+4)));
508: init_mem_banks ();
509:
510: /* Map the STmem into all of the lower 16MB */
511: map_banks (&STmem_bank, 0x00, 256);
512: /*
513: custom_start = 0xC0;
514: map_banks (&custom_bank, custom_start, 0xE0-custom_start);
515: map_banks (&cia_bank, 0xA0, 32);
516: map_banks (&clock_bank, 0xDC, 1);
517: */
518: /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
519: * range on an Amiga without expansion memory? */
520: /*
521: custom_start = allocated_STmem >> 16;
522: if (custom_start < 0x20)
523: custom_start = 0x20;
524: map_banks (&dummy_bank, custom_start, 0xA0 - custom_start);
525: */
526: /*map_banks (&TTram_bank, 0xDE, 1);*/
527:
528: if (allocated_TTmem > 0)
529: TTmemory = (uae_u8 *)malloc (allocated_TTmem);
530: if (TTmemory != 0)
531: map_banks (&TTmem_bank, TTmem_start >> 16, allocated_TTmem >> 16);
532: else
533: allocated_TTmem = 0;
534:
535: map_banks(&ROMmem_bank, ROMmem_start >> 16, ROMmem_size/65536);
536: /* map_banks(&ROMmem_bank, 0xFFFC, 4);*/
537:
538: map_banks(&IOmem_bank, IOmem_start>>16, 1);
539:
540: STmem_mask = 0x00ffffff /*allocated_STmem- 1*/;
541: ROMmem_mask = 0x00ffffff /*ROMmem_size - 1*/;
542: TTmem_mask = allocated_TTmem - 1;
543: IOmem_mask = IOmem_size - 1;
544: }
545:
546: void map_banks (addrbank *bank, int start, int size)
547: {
548: int bnr;
549: unsigned long int hioffs = 0, endhioffs = 0x100;
550:
551: if (start >= 0x100) {
552: for (bnr = start; bnr < start + size; bnr++)
553: put_mem_bank (bnr << 16, bank);
554: return;
555: }
556: /* Some ROMs apparently require a 24 bit address space... */
557: if (address_space_24)
558: endhioffs = 0x10000;
559: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
560: for (bnr = start; bnr < start+size; bnr++)
561: put_mem_bank ((bnr + hioffs) << 16, bank);
562: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.