|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator - CPU core
3: *
4: * Memory management
5: *
6: * (c) 1995 Bernd Schmidt
7: *
8: * Adaptation to Hatari by Thomas Huth
9: *
10: * This file is distributed under the GNU Public License, version 2 or at
11: * your option any later version. Read the file gpl.txt for details.
12: */
13: static char rcsid[] = "Hatari $Id: memory.c,v 1.12 2003/04/05 22:25:03 thothy Exp $";
14:
15: #include "sysdeps.h"
16: #include "hatari-glue.h"
17: #include "maccess.h"
18: #include "memory.h"
19: #include "../hardware/main.h"
20: #include "../hardware/reset.h"
21: #include "../hardware/decode.h"
22: #include "../hardware/m68000.h"
23: #include "newcpu.h"
24:
25:
26: uae_u32 STmem_size;
27:
28: #define STmem_start 0x00000000
29:
30: #define STmem_mask 0x00ffffff
31:
32:
33: #ifdef SAVE_MEMORY_BANKS
34: addrbank *mem_banks[65536];
35: #else
36: addrbank mem_banks[65536];
37: #endif
38:
39: #ifdef NO_INLINE_MEMORY_ACCESS
40: __inline__ uae_u32 longget (uaecptr addr)
41: {
42: return call_mem_get_func (get_mem_bank (addr).lget, addr);
43: }
44: __inline__ uae_u32 wordget (uaecptr addr)
45: {
46: return call_mem_get_func (get_mem_bank (addr).wget, addr);
47: }
48: __inline__ uae_u32 byteget (uaecptr addr)
49: {
50: return call_mem_get_func (get_mem_bank (addr).bget, addr);
51: }
52: __inline__ void longput (uaecptr addr, uae_u32 l)
53: {
54: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
55: }
56: __inline__ void wordput (uaecptr addr, uae_u32 w)
57: {
58: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
59: }
60: __inline__ void byteput (uaecptr addr, uae_u32 b)
61: {
62: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
63: }
64: #endif
65:
66:
67: /* Some prototypes: */
68: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
69: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
70:
71:
72: /* A dummy bank that only contains zeros */
73:
74: static uae_u32 dummy_lget (uaecptr) REGPARAM;
75: static uae_u32 dummy_wget (uaecptr) REGPARAM;
76: static uae_u32 dummy_bget (uaecptr) REGPARAM;
77: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
78: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
79: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
80: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
81:
82: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
83: {
84: if (illegal_mem)
85: write_log ("Illegal lget at %08lx\n", (long)addr);
86:
87: return 0;
88: }
89:
90: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
91: {
92: if (illegal_mem)
93: write_log ("Illegal wget at %08lx\n", (long)addr);
94:
95: return 0;
96: }
97:
98: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
99: {
100: if (illegal_mem)
101: write_log ("Illegal bget at %08lx\n", (long)addr);
102:
103: return 0;
104: }
105:
106: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
107: {
108: if (illegal_mem)
109: write_log ("Illegal lput at %08lx\n", (long)addr);
110: }
111:
112: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
113: {
114: if (illegal_mem)
115: write_log ("Illegal wput at %08lx\n", (long)addr);
116: }
117:
118: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
119: {
120: if (illegal_mem)
121: write_log ("Illegal bput at %08lx\n", (long)addr);
122: }
123:
124: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
125: {
126: if (illegal_mem)
127: write_log ("Illegal check at %08lx\n", (long)addr);
128:
129: return 0;
130: }
131:
132: uae_u8 REGPARAM2 *dummy_xlate (uaecptr addr)
133: {
134: write_log("Your Atari program just did something terribly stupid:"
135: " dummy_xlate($%x)\n", addr);
136: /*Reset_Warm();*/
137: return STmem_xlate(addr); /* So we don't crash. */
138: }
139:
140:
141: /* **** This memory bank only generates bus errors **** */
142:
143: uae_u32 REGPARAM2 BusErrMem_lget(uaecptr addr)
144: {
145: if (illegal_mem)
146: write_log ("Bus error lget at %08lx\n", (long)addr);
147:
148: M68000_Crash (2);
149: return 0;
150: }
151:
152: uae_u32 REGPARAM2 BusErrMem_wget(uaecptr addr)
153: {
154: if (illegal_mem)
155: write_log ("Bus error wget at %08lx\n", (long)addr);
156:
157: M68000_Crash (2);
158: return 0;
159: }
160:
161: uae_u32 REGPARAM2 BusErrMem_bget(uaecptr addr)
162: {
163: if (illegal_mem)
164: write_log ("Bus error bget at %08lx\n", (long)addr);
165:
166: M68000_Crash (2);
167: return 0;
168: }
169:
170: void REGPARAM2 BusErrMem_lput(uaecptr addr, uae_u32 l)
171: {
172: if (illegal_mem)
173: write_log ("Bus error lput at %08lx\n", (long)addr);
174:
175: M68000_Crash (2);
176: }
177:
178: void REGPARAM2 BusErrMem_wput(uaecptr addr, uae_u32 w)
179: {
180: if (illegal_mem)
181: write_log ("Bus error wput at %08lx\n", (long)addr);
182:
183: M68000_Crash (2);
184: }
185:
186: void REGPARAM2 BusErrMem_bput(uaecptr addr, uae_u32 b)
187: {
188: if (illegal_mem)
189: write_log ("Bus error bput at %08lx\n", (long)addr);
190:
191: M68000_Crash (2);
192: }
193:
194: int REGPARAM2 BusErrMem_check(uaecptr addr, uae_u32 size)
195: {
196: if (illegal_mem)
197: write_log ("Bus error check at %08lx\n", (long)addr);
198:
199: return 0;
200: }
201:
202: uae_u8 REGPARAM2 *BusErrMem_xlate (uaecptr addr)
203: {
204: write_log("Your Atari program just did something terribly stupid:"
205: " BusErrMem_xlate($%x)\n", addr);
206:
207: /*M68000_Crash (2);*/
208: return STmem_xlate(addr); /* So we don't crash. */
209: }
210:
211:
212: /* **** ST RAM memory **** */
213:
214: uae_u8 *STmemory;
215:
216: uae_u32 REGPARAM2 STmem_lget (uaecptr addr)
217: {
218: uae_u32 *m;
219:
220: addr -= STmem_start & STmem_mask;
221: addr &= STmem_mask;
222: m = (uae_u32 *)(STmemory + addr);
223: return do_get_mem_long (m);
224: }
225:
226: uae_u32 REGPARAM2 STmem_wget (uaecptr addr)
227: {
228: uae_u16 *m;
229:
230: addr -= STmem_start & STmem_mask;
231: addr &= STmem_mask;
232: m = (uae_u16 *)(STmemory + addr);
233: return do_get_mem_word (m);
234: }
235:
236: uae_u32 REGPARAM2 STmem_bget (uaecptr addr)
237: {
238: addr -= STmem_start & STmem_mask;
239: addr &= STmem_mask;
240: return STmemory[addr];
241: }
242:
243: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l)
244: {
245: uae_u32 *m;
246:
247: addr -= STmem_start & STmem_mask;
248: addr &= STmem_mask;
249: m = (uae_u32 *)(STmemory + addr);
250: do_put_mem_long (m, l);
251: }
252:
253: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w)
254: {
255: uae_u16 *m;
256:
257: addr -= STmem_start & STmem_mask;
258: addr &= STmem_mask;
259: m = (uae_u16 *)(STmemory + addr);
260: do_put_mem_word (m, w);
261: }
262:
263: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b)
264: {
265: addr -= STmem_start & STmem_mask;
266: addr &= STmem_mask;
267: STmemory[addr] = b;
268: }
269:
270: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size)
271: {
272: addr -= STmem_start & STmem_mask;
273: addr &= STmem_mask;
274: return (addr + size) <= STmem_size;
275: }
276:
277: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr)
278: {
279: addr -= STmem_start & STmem_mask;
280: addr &= STmem_mask;
281: return STmemory + addr;
282: }
283:
284:
285: /*
286: * **** ST RAM system memory ****
287: * We need a separate mem bank for this region since the first 0x800 bytes on
288: * the ST can only be accessed in supervisor mode. Note that the very first
289: * 8 bytes of the ST memory are also a mirror of the TOS ROM, so they are write
290: * protected!
291: */
292: uae_u32 REGPARAM2 SysMem_lget(uaecptr addr)
293: {
294: uae_u32 *m;
295:
296: addr -= STmem_start & STmem_mask;
297: addr &= STmem_mask;
298: m = (uae_u32 *)(STmemory + addr);
299: return do_get_mem_long (m);
300: }
301:
302: uae_u32 REGPARAM2 SysMem_wget(uaecptr addr)
303: {
304: uae_u16 *m;
305:
306: addr -= STmem_start & STmem_mask;
307: addr &= STmem_mask;
308: m = (uae_u16 *)(STmemory + addr);
309: return do_get_mem_word (m);
310: }
311:
312: uae_u32 REGPARAM2 SysMem_bget(uaecptr addr)
313: {
314: addr -= STmem_start & STmem_mask;
315: addr &= STmem_mask;
316: return STmemory[addr];
317: }
318:
319: void REGPARAM2 SysMem_lput(uaecptr addr, uae_u32 l)
320: {
321: uae_u32 *m;
322:
323: addr -= STmem_start & STmem_mask;
324: addr &= STmem_mask;
325: m = (uae_u32 *)(STmemory + addr);
326: do_put_mem_long (m, l);
327: }
328:
329: void REGPARAM2 SysMem_wput(uaecptr addr, uae_u32 w)
330: {
331: uae_u16 *m;
332:
333: addr -= STmem_start & STmem_mask;
334: addr &= STmem_mask;
335: m = (uae_u16 *)(STmemory + addr);
336: do_put_mem_word (m, w);
337: }
338:
339: void REGPARAM2 SysMem_bput(uaecptr addr, uae_u32 b)
340: {
341: addr -= STmem_start & STmem_mask;
342: addr &= STmem_mask;
343: STmemory[addr] = b;
344: }
345:
346:
347: /*
348: * **** Void memory ****
349: * Between the ST-RAM end and the 4 MB barrier, there is a void memory space:
350: * Reading always returns the same value and writing does nothing at all.
351: */
352:
353: uae_u32 REGPARAM2 VoidMem_lget(uaecptr addr)
354: {
355: return 0;
356: }
357:
358: uae_u32 REGPARAM2 VoidMem_wget(uaecptr addr)
359: {
360: return 0;
361: }
362:
363: uae_u32 REGPARAM2 VoidMem_bget(uaecptr addr)
364: {
365: return 0;
366: }
367:
368: void REGPARAM2 VoidMem_lput(uaecptr addr, uae_u32 l)
369: {
370: }
371:
372: void REGPARAM2 VoidMem_wput(uaecptr addr, uae_u32 w)
373: {
374: }
375:
376: void REGPARAM2 VoidMem_bput (uaecptr addr, uae_u32 b)
377: {
378: }
379:
380: int REGPARAM2 VoidMem_check(uaecptr addr, uae_u32 size)
381: {
382: if (illegal_mem)
383: write_log ("Void memory check at %08lx\n", (long)addr);
384:
385: return 0;
386: }
387:
388: uae_u8 REGPARAM2 *VoidMem_xlate (uaecptr addr)
389: {
390: write_log("Your Atari program just did something terribly stupid:"
391: " VoidMem_xlate($%x)\n", addr);
392:
393: return STmem_xlate(addr); /* So we don't crash. */
394: }
395:
396:
397: /* **** Address banks **** */
398:
399: addrbank dummy_bank = {
400: dummy_lget, dummy_wget, dummy_bget,
401: dummy_lput, dummy_wput, dummy_bput,
402: dummy_xlate, dummy_check
403: };
404:
405: addrbank BusErrMem_bank = {
406: BusErrMem_lget, BusErrMem_wget, BusErrMem_bget,
407: BusErrMem_lput, BusErrMem_wput, BusErrMem_bput,
408: BusErrMem_xlate, BusErrMem_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 SysMem_bank = {
418: SysMem_lget, SysMem_wget, SysMem_bget,
419: SysMem_lput, SysMem_wput, SysMem_bput,
420: STmem_xlate, STmem_check
421: };
422:
423: addrbank VoidMem_bank = {
424: VoidMem_lget, VoidMem_wget, VoidMem_bget,
425: VoidMem_lput, VoidMem_wput, VoidMem_bput,
426: VoidMem_xlate, VoidMem_check
427: };
428:
429:
430: char *address_space, *good_address_map;
431: int good_address_fd;
432:
433:
434: static void init_mem_banks (void)
435: {
436: int i;
437: for (i = 0; i < 65536; i++)
438: put_mem_bank (i<<16, &dummy_bank);
439: }
440:
441:
442: /*
443: * Initialize the memory banks
444: */
445: void memory_init(uae_u32 f_STMemSize, uae_u32 f_TTMemSize, uae_u32 f_RomMemStart)
446: {
447: STmem_size = (f_STMemSize + 65535) & 0xFFFF0000;
448:
449: /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
450: STmem_size, TTmem_size, f_RomMemStart);*/
451:
452: STmemory = STRam;
453: /*
454: while (! STmemory && STmem_size > 512*1024) {
455: STmem_size >>= 1;
456: STmemory = (uae_u8 *)malloc (STmem_size);
457: if (STmemory)
458: fprintf (stderr, "Reducing STmem size to %dkb\n", STmem_size >> 10);
459: }
460: if (! STmemory) {
461: write_log ("virtual memory exhausted (STmemory)!\n");
462: abort ();
463: }
464: */
465:
466: init_mem_banks();
467:
468: /* Map the ST RAM: */
469: map_banks(&SysMem_bank, 0x00, 1);
470: map_banks(&VoidMem_bank, 0x08, 0x38); /* Between STRamEnd and 4MB barrier, there is void space! */
471: map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1);
472:
473: /* Illegal memory regions cause a bus error on the ST: */
474: map_banks(&BusErrMem_bank, 0x200000 >> 16, 0xbf); /* Everything above 2mb */
475: }
476:
477:
478: /*
479: * Uninitialize the memory banks.
480: */
481: void memory_uninit (void)
482: {
483: /* Here, we free allocated memory from memory_init */
484: }
485:
486:
487: void map_banks (addrbank *bank, int start, int size)
488: {
489: int bnr;
490: unsigned long int hioffs = 0, endhioffs = 0x100;
491:
492: if (start >= 0x100) {
493: for (bnr = start; bnr < start + size; bnr++)
494: put_mem_bank (bnr << 16, bank);
495: return;
496: }
497: /* Some ROMs apparently require a 24 bit address space... */
498: if (address_space_24)
499: endhioffs = 0x10000;
500: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
501: for (bnr = start; bnr < start+size; bnr++)
502: put_mem_bank ((bnr + hioffs) << 16, bank);
503: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.