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