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