|
|
1.1 root 1: /*
1.1.1.4 root 2: * UAE - The Un*x Amiga Emulator - CPU core
1.1 root 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.1.4 root 9: *
1.1.1.16 root 10: * This file is distributed under the GNU General Public License, version 2
11: * or at your option any later version. Read the file gpl.txt for details.
1.1 root 12: */
1.1.1.13 root 13: const char Memory_fileid[] = "Hatari memory.c : " __DATE__ " " __TIME__;
1.1 root 14:
1.1.1.17 root 15: #include <SDL.h>
1.1.1.10 root 16: #include "config.h"
1.1 root 17: #include "sysdeps.h"
18: #include "hatari-glue.h"
19: #include "maccess.h"
20: #include "memory.h"
1.1.1.14 root 21:
22: #include "main.h"
23: #include "tos.h"
24: #include "ide.h"
25: #include "ioMem.h"
26: #include "reset.h"
27: #include "stMemory.h"
28: #include "m68000.h"
1.1.1.18! root 29: #include "configuration.h"
1.1.1.14 root 30:
1.1.1.5 root 31: #include "newcpu.h"
1.1 root 32:
33:
1.1.1.10 root 34: /* Set illegal_mem to 1 for debug output: */
35: #define illegal_mem 1
36:
1.1.1.17 root 37: static int illegal_count = 50;
1.1.1.10 root 38:
1.1.1.18! root 39: static uae_u32 STmem_size;
! 40: uae_u32 TTmem_size = 0;
1.1.1.6 root 41: static uae_u32 TTmem_mask;
1.1 root 42:
1.1.1.5 root 43: #define STmem_start 0x00000000
44: #define ROMmem_start 0x00E00000
1.1.1.10 root 45: #define IdeMem_start 0x00F00000
1.1.1.5 root 46: #define IOmem_start 0x00FF0000
1.1.1.18! root 47: #define TTmem_start 0x01000000 /* TOS 3 and TOS 4 always expect extra RAM at this address */
! 48: #define TTmem_end 0x80000000 /* Max value for end of TT ram, which gives 2047 MB */
1.1 root 49:
1.1.1.10 root 50: #define IdeMem_size 65536
1.1.1.5 root 51: #define IOmem_size 65536
52: #define ROMmem_size (0x00FF0000 - 0x00E00000) /* So we cover both possible ROM regions + cartridge */
1.1 root 53:
1.1.1.5 root 54: #define STmem_mask 0x00ffffff
55: #define ROMmem_mask 0x00ffffff
1.1.1.10 root 56: #define IdeMem_mask (IdeMem_size - 1)
1.1.1.5 root 57: #define IOmem_mask (IOmem_size - 1)
1.1 root 58:
59:
60: #ifdef SAVE_MEMORY_BANKS
61: addrbank *mem_banks[65536];
62: #else
63: addrbank mem_banks[65536];
64: #endif
65:
66: #ifdef NO_INLINE_MEMORY_ACCESS
67: __inline__ uae_u32 longget (uaecptr addr)
68: {
69: return call_mem_get_func (get_mem_bank (addr).lget, addr);
70: }
71: __inline__ uae_u32 wordget (uaecptr addr)
72: {
73: return call_mem_get_func (get_mem_bank (addr).wget, addr);
74: }
75: __inline__ uae_u32 byteget (uaecptr addr)
76: {
77: return call_mem_get_func (get_mem_bank (addr).bget, addr);
78: }
79: __inline__ void longput (uaecptr addr, uae_u32 l)
80: {
81: call_mem_put_func (get_mem_bank (addr).lput, addr, l);
82: }
83: __inline__ void wordput (uaecptr addr, uae_u32 w)
84: {
85: call_mem_put_func (get_mem_bank (addr).wput, addr, w);
86: }
87: __inline__ void byteput (uaecptr addr, uae_u32 b)
88: {
89: call_mem_put_func (get_mem_bank (addr).bput, addr, b);
90: }
91: #endif
92:
93:
1.1.1.5 root 94: /* Some prototypes: */
95: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
96: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
97:
98:
1.1.1.17 root 99: static void print_illegal_counted(const char *txt, uaecptr addr)
100: {
101: if (!illegal_mem || illegal_count <= 0)
102: return;
103:
104: write_log("%s at %08lx\n", txt, (long)addr);
105: if (--illegal_count == 0)
106: write_log("Suppressing further messages about illegal memory accesses.\n");
107: }
108:
109:
1.1 root 110: /* A dummy bank that only contains zeros */
111:
1.1.1.6 root 112: static uae_u32 dummy_lget(uaecptr addr)
1.1 root 113: {
114: if (illegal_mem)
1.1.1.3 root 115: write_log ("Illegal lget at %08lx\n", (long)addr);
1.1 root 116:
117: return 0;
118: }
119:
1.1.1.6 root 120: static uae_u32 dummy_wget(uaecptr addr)
1.1 root 121: {
122: if (illegal_mem)
1.1.1.3 root 123: write_log ("Illegal wget at %08lx\n", (long)addr);
1.1 root 124:
125: return 0;
126: }
127:
1.1.1.6 root 128: static uae_u32 dummy_bget(uaecptr addr)
1.1 root 129: {
130: if (illegal_mem)
1.1.1.3 root 131: write_log ("Illegal bget at %08lx\n", (long)addr);
1.1 root 132:
133: return 0;
134: }
135:
1.1.1.6 root 136: static void dummy_lput(uaecptr addr, uae_u32 l)
1.1 root 137: {
138: if (illegal_mem)
1.1.1.3 root 139: write_log ("Illegal lput at %08lx\n", (long)addr);
1.1 root 140: }
1.1.1.5 root 141:
1.1.1.6 root 142: static void dummy_wput(uaecptr addr, uae_u32 w)
1.1 root 143: {
144: if (illegal_mem)
1.1.1.3 root 145: write_log ("Illegal wput at %08lx\n", (long)addr);
1.1 root 146: }
1.1.1.5 root 147:
1.1.1.6 root 148: static void dummy_bput(uaecptr addr, uae_u32 b)
1.1 root 149: {
150: if (illegal_mem)
1.1.1.3 root 151: write_log ("Illegal bput at %08lx\n", (long)addr);
1.1 root 152: }
153:
1.1.1.6 root 154: static int dummy_check(uaecptr addr, uae_u32 size)
1.1 root 155: {
156: return 0;
157: }
158:
1.1.1.6 root 159: static uae_u8 *dummy_xlate(uaecptr addr)
1.1.1.5 root 160: {
161: write_log("Your Atari program just did something terribly stupid:"
162: " dummy_xlate($%x)\n", addr);
163: /*Reset_Warm();*/
164: return STmem_xlate(addr); /* So we don't crash. */
165: }
1.1 root 166:
167:
1.1.1.5 root 168: /* **** This memory bank only generates bus errors **** */
1.1 root 169:
1.1.1.6 root 170: static uae_u32 BusErrMem_lget(uaecptr addr)
1.1.1.5 root 171: {
1.1.1.17 root 172: print_illegal_counted("Bus error lget", addr);
1.1.1.5 root 173:
1.1.1.18! root 174: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 175: return 0;
176: }
177:
1.1.1.6 root 178: static uae_u32 BusErrMem_wget(uaecptr addr)
1.1.1.5 root 179: {
1.1.1.17 root 180: print_illegal_counted("Bus error wget", addr);
1.1.1.5 root 181:
1.1.1.18! root 182: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 183: return 0;
184: }
185:
1.1.1.6 root 186: static uae_u32 BusErrMem_bget(uaecptr addr)
1.1.1.5 root 187: {
1.1.1.17 root 188: print_illegal_counted("Bus error bget", addr);
1.1.1.5 root 189:
1.1.1.18! root 190: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 191: return 0;
192: }
193:
1.1.1.6 root 194: static void BusErrMem_lput(uaecptr addr, uae_u32 l)
1.1.1.5 root 195: {
1.1.1.17 root 196: print_illegal_counted("Bus error lput", addr);
1.1.1.5 root 197:
1.1.1.18! root 198: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 199: }
200:
1.1.1.6 root 201: static void BusErrMem_wput(uaecptr addr, uae_u32 w)
1.1.1.5 root 202: {
1.1.1.17 root 203: print_illegal_counted("Bus error wput", addr);
1.1.1.5 root 204:
1.1.1.18! root 205: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 206: }
207:
1.1.1.6 root 208: static void BusErrMem_bput(uaecptr addr, uae_u32 b)
1.1.1.5 root 209: {
1.1.1.17 root 210: print_illegal_counted("Bus error bput", addr);
1.1.1.5 root 211:
1.1.1.18! root 212: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 213: }
214:
1.1.1.6 root 215: static int BusErrMem_check(uaecptr addr, uae_u32 size)
1.1.1.5 root 216: {
217: return 0;
218: }
219:
1.1.1.6 root 220: static uae_u8 *BusErrMem_xlate (uaecptr addr)
1.1.1.5 root 221: {
222: write_log("Your Atari program just did something terribly stupid:"
223: " BusErrMem_xlate($%x)\n", addr);
224:
225: /*M68000_BusError(addr);*/
226: return STmem_xlate(addr); /* So we don't crash. */
227: }
228:
229:
230: /* **** ST RAM memory **** */
231:
1.1.1.9 root 232: /*static uae_u8 *STmemory;*/
233: #define STmemory STRam
1.1 root 234:
1.1.1.6 root 235: static uae_u32 STmem_lget(uaecptr addr)
1.1 root 236: {
237: addr -= STmem_start & STmem_mask;
238: addr &= STmem_mask;
1.1.1.7 root 239: return do_get_mem_long(STmemory + addr);
1.1 root 240: }
241:
1.1.1.6 root 242: static uae_u32 STmem_wget(uaecptr addr)
1.1 root 243: {
244: addr -= STmem_start & STmem_mask;
245: addr &= STmem_mask;
1.1.1.7 root 246: return do_get_mem_word(STmemory + addr);
1.1 root 247: }
248:
1.1.1.6 root 249: static uae_u32 STmem_bget(uaecptr addr)
1.1 root 250: {
251: addr -= STmem_start & STmem_mask;
252: addr &= STmem_mask;
253: return STmemory[addr];
254: }
255:
1.1.1.6 root 256: static void STmem_lput(uaecptr addr, uae_u32 l)
1.1 root 257: {
258: addr -= STmem_start & STmem_mask;
259: addr &= STmem_mask;
1.1.1.7 root 260: do_put_mem_long(STmemory + addr, l);
1.1 root 261: }
262:
1.1.1.6 root 263: static void STmem_wput(uaecptr addr, uae_u32 w)
1.1 root 264: {
265: addr -= STmem_start & STmem_mask;
266: addr &= STmem_mask;
1.1.1.7 root 267: do_put_mem_word(STmemory + addr, w);
1.1 root 268: }
269:
1.1.1.6 root 270: static void STmem_bput(uaecptr addr, uae_u32 b)
1.1 root 271: {
272: addr -= STmem_start & STmem_mask;
273: addr &= STmem_mask;
274: STmemory[addr] = b;
275: }
276:
1.1.1.6 root 277: static int STmem_check(uaecptr addr, uae_u32 size)
1.1 root 278: {
279: addr -= STmem_start & STmem_mask;
280: addr &= STmem_mask;
1.1.1.5 root 281: return (addr + size) <= STmem_size;
1.1 root 282: }
283:
1.1.1.6 root 284: static uae_u8 *STmem_xlate(uaecptr addr)
1.1 root 285: {
286: addr -= STmem_start & STmem_mask;
287: addr &= STmem_mask;
288: return STmemory + addr;
289: }
290:
291:
1.1.1.5 root 292: /*
293: * **** ST RAM system memory ****
294: * We need a separate mem bank for this region since the first 0x800 bytes on
295: * the ST can only be accessed in supervisor mode. Note that the very first
296: * 8 bytes of the ST memory are also a mirror of the TOS ROM, so they are write
297: * protected!
298: */
1.1.1.6 root 299: static uae_u32 SysMem_lget(uaecptr addr)
1.1.1.5 root 300: {
1.1.1.18! root 301: addr -= STmem_start & STmem_mask;
! 302: addr &= STmem_mask;
! 303:
1.1.1.5 root 304: if(addr < 0x800 && !regs.s)
305: {
1.1.1.18! root 306: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 307: return 0;
308: }
309:
1.1.1.7 root 310: return do_get_mem_long(STmemory + addr);
1.1.1.5 root 311: }
312:
1.1.1.6 root 313: static uae_u32 SysMem_wget(uaecptr addr)
1.1.1.5 root 314: {
1.1.1.18! root 315: addr -= STmem_start & STmem_mask;
! 316: addr &= STmem_mask;
! 317:
1.1.1.5 root 318: if(addr < 0x800 && !regs.s)
319: {
1.1.1.18! root 320: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 321: return 0;
322: }
323:
1.1.1.7 root 324: return do_get_mem_word(STmemory + addr);
1.1.1.5 root 325: }
326:
1.1.1.6 root 327: static uae_u32 SysMem_bget(uaecptr addr)
1.1.1.5 root 328: {
1.1.1.18! root 329: addr -= STmem_start & STmem_mask;
! 330: addr &= STmem_mask;
! 331:
1.1.1.5 root 332: if(addr < 0x800 && !regs.s)
333: {
1.1.1.18! root 334: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 335: return 0;
336: }
337:
338: return STmemory[addr];
339: }
340:
1.1.1.6 root 341: static void SysMem_lput(uaecptr addr, uae_u32 l)
1.1.1.5 root 342: {
1.1.1.18! root 343: addr -= STmem_start & STmem_mask;
! 344: addr &= STmem_mask;
! 345:
1.1.1.5 root 346: if(addr < 0x8 || (addr < 0x800 && !regs.s))
347: {
1.1.1.18! root 348: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 349: return;
350: }
351:
1.1.1.7 root 352: do_put_mem_long(STmemory + addr, l);
1.1.1.5 root 353: }
354:
1.1.1.6 root 355: static void SysMem_wput(uaecptr addr, uae_u32 w)
1.1.1.5 root 356: {
1.1.1.18! root 357: addr -= STmem_start & STmem_mask;
! 358: addr &= STmem_mask;
! 359:
1.1.1.5 root 360: if(addr < 0x8 || (addr < 0x800 && !regs.s))
361: {
1.1.1.18! root 362: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 363: return;
364: }
365:
1.1.1.7 root 366: do_put_mem_word(STmemory + addr, w);
1.1.1.5 root 367: }
368:
1.1.1.6 root 369: static void SysMem_bput(uaecptr addr, uae_u32 b)
1.1.1.5 root 370: {
1.1.1.18! root 371: addr -= STmem_start & STmem_mask;
! 372: addr &= STmem_mask;
! 373:
1.1.1.5 root 374: if(addr < 0x8 || (addr < 0x800 && !regs.s))
375: {
1.1.1.18! root 376: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 377: return;
378: }
379:
380: STmemory[addr] = b;
381: }
382:
383:
384: /*
385: * **** Void memory ****
386: * Between the ST-RAM end and the 4 MB barrier, there is a void memory space:
387: * Reading always returns the same value and writing does nothing at all.
1.1.1.17 root 388: * [NP] : this is not correct, reading does not always return 0, when there's
389: * no memory, it will return the latest data that was read on the bus.
390: * In many cases, this will return the word that was just read in the 68000's
391: * prefetch register to decode the next opcode (tested on a real STF)
1.1.1.5 root 392: */
393:
1.1.1.6 root 394: static uae_u32 VoidMem_lget(uaecptr addr)
1.1.1.5 root 395: {
396: return 0;
397: }
398:
1.1.1.6 root 399: static uae_u32 VoidMem_wget(uaecptr addr)
1.1.1.5 root 400: {
401: return 0;
402: }
403:
1.1.1.6 root 404: static uae_u32 VoidMem_bget(uaecptr addr)
1.1.1.5 root 405: {
406: return 0;
407: }
408:
1.1.1.6 root 409: static void VoidMem_lput(uaecptr addr, uae_u32 l)
1.1.1.5 root 410: {
411: }
412:
1.1.1.6 root 413: static void VoidMem_wput(uaecptr addr, uae_u32 w)
1.1.1.5 root 414: {
415: }
416:
1.1.1.6 root 417: static void VoidMem_bput (uaecptr addr, uae_u32 b)
1.1.1.5 root 418: {
419: }
420:
1.1.1.6 root 421: static int VoidMem_check(uaecptr addr, uae_u32 size)
1.1.1.5 root 422: {
423: return 0;
424: }
425:
1.1.1.6 root 426: static uae_u8 *VoidMem_xlate (uaecptr addr)
1.1.1.5 root 427: {
428: write_log("Your Atari program just did something terribly stupid:"
429: " VoidMem_xlate($%x)\n", addr);
430:
431: return STmem_xlate(addr); /* So we don't crash. */
432: }
433:
434:
1.1.1.18! root 435: /* **** TT fast memory **** */
1.1 root 436:
1.1.1.18! root 437: uae_u8 *TTmemory;
1.1 root 438:
1.1.1.6 root 439: static uae_u32 TTmem_lget(uaecptr addr)
1.1 root 440: {
441: addr -= TTmem_start & TTmem_mask;
442: addr &= TTmem_mask;
1.1.1.7 root 443: return do_get_mem_long(TTmemory + addr);
1.1 root 444: }
445:
1.1.1.6 root 446: static uae_u32 TTmem_wget(uaecptr addr)
1.1 root 447: {
448: addr -= TTmem_start & TTmem_mask;
449: addr &= TTmem_mask;
1.1.1.7 root 450: return do_get_mem_word(TTmemory + addr);
1.1 root 451: }
452:
1.1.1.6 root 453: static uae_u32 TTmem_bget(uaecptr addr)
1.1 root 454: {
455: addr -= TTmem_start & TTmem_mask;
456: addr &= TTmem_mask;
457: return TTmemory[addr];
458: }
459:
1.1.1.6 root 460: static void TTmem_lput(uaecptr addr, uae_u32 l)
1.1 root 461: {
462: addr -= TTmem_start & TTmem_mask;
463: addr &= TTmem_mask;
1.1.1.7 root 464: do_put_mem_long(TTmemory + addr, l);
1.1 root 465: }
466:
1.1.1.6 root 467: static void TTmem_wput(uaecptr addr, uae_u32 w)
1.1 root 468: {
469: addr -= TTmem_start & TTmem_mask;
470: addr &= TTmem_mask;
1.1.1.7 root 471: do_put_mem_word(TTmemory + addr, w);
1.1 root 472: }
473:
1.1.1.6 root 474: static void TTmem_bput(uaecptr addr, uae_u32 b)
1.1 root 475: {
476: addr -= TTmem_start & TTmem_mask;
477: addr &= TTmem_mask;
478: TTmemory[addr] = b;
479: }
480:
1.1.1.6 root 481: static int TTmem_check(uaecptr addr, uae_u32 size)
1.1 root 482: {
483: addr -= TTmem_start & TTmem_mask;
484: addr &= TTmem_mask;
1.1.1.5 root 485: return (addr + size) <= TTmem_size;
1.1 root 486: }
487:
1.1.1.6 root 488: static uae_u8 *TTmem_xlate(uaecptr addr)
1.1 root 489: {
490: addr -= TTmem_start & TTmem_mask;
491: addr &= TTmem_mask;
492: return TTmemory + addr;
493: }
494:
1.1.1.5 root 495:
496: /* **** ROM memory **** */
1.1 root 497:
1.1.1.10 root 498: uae_u8 *ROMmemory;
1.1 root 499:
1.1.1.6 root 500: static uae_u32 ROMmem_lget(uaecptr addr)
1.1 root 501: {
502: addr -= ROMmem_start & ROMmem_mask;
503: addr &= ROMmem_mask;
1.1.1.7 root 504: return do_get_mem_long(ROMmemory + addr);
1.1 root 505: }
506:
1.1.1.6 root 507: static uae_u32 ROMmem_wget(uaecptr addr)
1.1 root 508: {
509: addr -= ROMmem_start & ROMmem_mask;
510: addr &= ROMmem_mask;
1.1.1.7 root 511: return do_get_mem_word(ROMmemory + addr);
1.1 root 512: }
513:
1.1.1.6 root 514: static uae_u32 ROMmem_bget(uaecptr addr)
1.1 root 515: {
516: addr -= ROMmem_start & ROMmem_mask;
517: addr &= ROMmem_mask;
518: return ROMmemory[addr];
519: }
520:
1.1.1.6 root 521: static void ROMmem_lput(uaecptr addr, uae_u32 b)
1.1 root 522: {
1.1.1.17 root 523: print_illegal_counted("Illegal ROMmem lput", (long)addr);
1.1.1.5 root 524:
1.1.1.18! root 525: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1 root 526: }
527:
1.1.1.6 root 528: static void ROMmem_wput(uaecptr addr, uae_u32 b)
1.1 root 529: {
1.1.1.17 root 530: print_illegal_counted("Illegal ROMmem wput", (long)addr);
1.1.1.5 root 531:
1.1.1.18! root 532: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1 root 533: }
534:
1.1.1.6 root 535: static void ROMmem_bput(uaecptr addr, uae_u32 b)
1.1 root 536: {
1.1.1.17 root 537: print_illegal_counted("Illegal ROMmem bput", (long)addr);
1.1.1.5 root 538:
1.1.1.18! root 539: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1 root 540: }
541:
1.1.1.6 root 542: static int ROMmem_check(uaecptr addr, uae_u32 size)
1.1 root 543: {
544: addr -= ROMmem_start & ROMmem_mask;
545: addr &= ROMmem_mask;
546: return (addr + size) <= ROMmem_size;
547: }
548:
1.1.1.6 root 549: static uae_u8 *ROMmem_xlate(uaecptr addr)
1.1 root 550: {
551: addr -= ROMmem_start & ROMmem_mask;
552: addr &= ROMmem_mask;
553: return ROMmemory + addr;
554: }
555:
556:
1.1.1.10 root 557: /* IDE controller IO memory */
558: /* see also ide.c */
559:
560: static uae_u8 *IdeMemory;
561:
562: static int IdeMem_check(uaecptr addr, uae_u32 size)
563: {
564: addr -= IdeMem_start;
565: addr &= IdeMem_mask;
566: return (addr + size) <= IdeMem_size;
567: }
568:
569: static uae_u8 *IdeMem_xlate(uaecptr addr)
570: {
571: addr -= IdeMem_start;
572: addr &= IdeMem_mask;
573: return IdeMemory + addr;
574: }
575:
576:
1.1 root 577: /* Hardware IO memory */
1.1.1.10 root 578: /* see also ioMem.c */
1.1 root 579:
1.1.1.10 root 580: uae_u8 *IOmemory;
1.1 root 581:
1.1.1.6 root 582: static int IOmem_check(uaecptr addr, uae_u32 size)
1.1 root 583: {
1.1.1.5 root 584: addr -= IOmem_start;
1.1 root 585: addr &= IOmem_mask;
586: return (addr + size) <= IOmem_size;
587: }
588:
1.1.1.6 root 589: static uae_u8 *IOmem_xlate(uaecptr addr)
1.1 root 590: {
1.1.1.5 root 591: addr -= IOmem_start;
1.1 root 592: addr &= IOmem_mask;
593: return IOmemory + addr;
594: }
595:
596:
597:
1.1.1.5 root 598: /* **** Address banks **** */
1.1 root 599:
1.1.1.6 root 600: static addrbank dummy_bank =
601: {
1.1 root 602: dummy_lget, dummy_wget, dummy_bget,
603: dummy_lput, dummy_wput, dummy_bput,
1.1.1.18! root 604: dummy_xlate, dummy_check, NULL, ABFLAG_NONE
1.1.1.5 root 605: };
606:
1.1.1.6 root 607: static addrbank BusErrMem_bank =
608: {
1.1.1.5 root 609: BusErrMem_lget, BusErrMem_wget, BusErrMem_bget,
610: BusErrMem_lput, BusErrMem_wput, BusErrMem_bput,
1.1.1.18! root 611: BusErrMem_xlate, BusErrMem_check, NULL, ABFLAG_NONE
1.1 root 612: };
613:
1.1.1.6 root 614: static addrbank STmem_bank =
615: {
1.1 root 616: STmem_lget, STmem_wget, STmem_bget,
617: STmem_lput, STmem_wput, STmem_bput,
1.1.1.18! root 618: STmem_xlate, STmem_check, NULL, ABFLAG_RAM
1.1 root 619: };
620:
1.1.1.6 root 621: static addrbank SysMem_bank =
622: {
1.1.1.5 root 623: SysMem_lget, SysMem_wget, SysMem_bget,
624: SysMem_lput, SysMem_wput, SysMem_bput,
1.1.1.18! root 625: STmem_xlate, STmem_check, NULL, ABFLAG_RAM
1.1.1.5 root 626: };
627:
1.1.1.6 root 628: static addrbank VoidMem_bank =
629: {
1.1.1.5 root 630: VoidMem_lget, VoidMem_wget, VoidMem_bget,
631: VoidMem_lput, VoidMem_wput, VoidMem_bput,
1.1.1.18! root 632: VoidMem_xlate, VoidMem_check , NULL, ABFLAG_NONE
1.1.1.5 root 633: };
634:
1.1.1.6 root 635: static addrbank TTmem_bank =
636: {
1.1 root 637: TTmem_lget, TTmem_wget, TTmem_bget,
638: TTmem_lput, TTmem_wput, TTmem_bput,
1.1.1.18! root 639: TTmem_xlate, TTmem_check, NULL, ABFLAG_RAM
1.1 root 640: };
641:
1.1.1.6 root 642: static addrbank ROMmem_bank =
643: {
1.1 root 644: ROMmem_lget, ROMmem_wget, ROMmem_bget,
645: ROMmem_lput, ROMmem_wput, ROMmem_bput,
1.1.1.18! root 646: ROMmem_xlate, ROMmem_check, NULL, ABFLAG_ROM
1.1 root 647: };
648:
1.1.1.10 root 649: static addrbank IdeMem_bank =
650: {
651: Ide_Mem_lget, Ide_Mem_wget, Ide_Mem_bget,
652: Ide_Mem_lput, Ide_Mem_wput, Ide_Mem_bput,
1.1.1.18! root 653: IdeMem_xlate, IdeMem_check, NULL, ABFLAG_IO
1.1.1.10 root 654: };
655:
1.1.1.6 root 656: static addrbank IOmem_bank =
657: {
1.1.1.7 root 658: IoMem_lget, IoMem_wget, IoMem_bget,
659: IoMem_lput, IoMem_wput, IoMem_bput,
1.1.1.18! root 660: IOmem_xlate, IOmem_check, NULL, ABFLAG_IO
1.1 root 661: };
662:
663:
1.1.1.5 root 664:
1.1 root 665: static void init_mem_banks (void)
666: {
667: int i;
668: for (i = 0; i < 65536; i++)
669: put_mem_bank (i<<16, &dummy_bank);
670: }
671:
672:
673: /*
1.1.1.18! root 674: * Check if an address points to a memory region that causes bus error
! 675: * Returns true if region gives bus error
! 676: */
! 677: bool memory_region_bus_error ( uaecptr addr )
! 678: {
! 679: return mem_banks[bankindex(addr)] == &BusErrMem_bank;
! 680: }
! 681:
! 682:
! 683: /*
1.1.1.5 root 684: * Initialize the memory banks
685: */
1.1.1.8 root 686: void memory_init(uae_u32 nNewSTMemSize, uae_u32 nNewTTMemSize, uae_u32 nNewRomMemStart)
1.1.1.5 root 687: {
1.1.1.8 root 688: STmem_size = (nNewSTMemSize + 65535) & 0xFFFF0000;
689: TTmem_size = (nNewTTMemSize + 65535) & 0xFFFF0000;
1.1.1.5 root 690:
691: /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
1.1.1.8 root 692: STmem_size, TTmem_size, nNewRomMemStart);*/
1.1.1.5 root 693:
1.1.1.10 root 694: #if ENABLE_SMALL_MEM
1.1.1.9 root 695:
1.1.1.18! root 696: /* Allocate memory for ROM areas, IDE and IO memory space (0xE00000 - 0xFFFFFF) */
1.1.1.10 root 697: ROMmemory = malloc(2*1024*1024);
698: if (!ROMmemory) {
699: fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
1.1.1.11 root 700: SDL_Quit();
1.1.1.10 root 701: exit(1);
702: }
703: IdeMemory = ROMmemory + 0x100000;
704: IOmemory = ROMmemory + 0x1f0000;
705:
706: /* Allocate memory for normal ST RAM */
707: STmemory = malloc(STmem_size);
708: while (!STmemory && STmem_size > 512*1024) {
1.1.1.5 root 709: STmem_size >>= 1;
710: STmemory = (uae_u8 *)malloc (STmem_size);
1.1 root 711: if (STmemory)
1.1.1.10 root 712: write_log ("Reducing STmem size to %dkb\n", STmem_size >> 10);
1.1 root 713: }
1.1.1.10 root 714: if (!STmemory) {
1.1 root 715: write_log ("virtual memory exhausted (STmemory)!\n");
1.1.1.11 root 716: SDL_Quit();
1.1.1.10 root 717: exit(1);
1.1 root 718: }
1.1.1.10 root 719:
720: #else
721:
722: /* STmemory points to the 16 MiB STRam array, we just have to set up
723: * the remaining pointers here: */
724: ROMmemory = STRam + ROMmem_start;
725: IdeMemory = STRam + IdeMem_start;
726: IOmemory = STRam + IOmem_start;
727:
728: #endif
1.1 root 729:
1.1.1.5 root 730: init_mem_banks();
1.1 root 731:
1.1.1.18! root 732: /* Set the infos about memory pointers for each mem bank, used for direct memory access in stMemory.c */
! 733: STmem_bank.baseaddr = STmemory;
! 734: STmem_bank.mask = STmem_mask;
! 735: STmem_bank.start = STmem_start;
! 736:
! 737: SysMem_bank.baseaddr = STmemory;
! 738: SysMem_bank.mask = STmem_mask;
! 739: SysMem_bank.start = STmem_start;
! 740:
! 741: dummy_bank.baseaddr = NULL; /* No real memory allocated for this region */
! 742: VoidMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
! 743: BusErrMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
! 744:
! 745:
1.1.1.8 root 746: /* Map the ST system RAM: */
1.1.1.5 root 747: map_banks(&SysMem_bank, 0x00, 1);
1.1.1.8 root 748: /* Between STRamEnd and 4MB barrier, there is void space: */
749: map_banks(&VoidMem_bank, 0x08, 0x38);
750: /* Space between 4MB barrier and TOS ROM causes a bus error: */
751: map_banks(&BusErrMem_bank, 0x400000 >> 16, 0xA0);
752: /* Now map main ST RAM, overwriting the void and bus error regions if necessary: */
1.1.1.5 root 753: map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1);
754:
1.1.1.18! root 755:
! 756: /* Handle extra RAM on TT and Falcon starting at 0x1000000 and up to 0x80000000 */
! 757: /* This requires the CPU to use 32 bit addressing */
! 758: /* NOTE : code backported from cpu/memory.c, but as bAddressSpace24 is always true with old */
! 759: /* UAE's core, TT RAM is not supported at the moment */
! 760: TTmemory = NULL;
! 761: if ( ConfigureParams.System.bAddressSpace24 == false )
! 762: {
! 763: /* If there's no extra RAM on a TT, region 0x01000000 - 0x80000000 (2047 MB) must return bus errors */
! 764: if ( ConfigureParams.System.nMachineType == MACHINE_TT )
! 765: map_banks ( &BusErrMem_bank, TTmem_start >> 16, ( TTmem_end - TTmem_start ) >> 16 );
! 766:
! 767: if ( TTmem_size > 0 )
! 768: {
! 769: TTmemory = (uae_u8 *)malloc ( TTmem_size );
! 770:
! 771: if ( TTmemory != NULL )
! 772: {
! 773: map_banks ( &TTmem_bank, TTmem_start >> 16, TTmem_size >> 16 );
! 774: TTmem_mask = 0xffffffff;
! 775: TTmem_bank.baseaddr = TTmemory;
! 776: TTmem_bank.mask = TTmem_mask;
! 777: TTmem_bank.start = TTmem_start;
! 778: }
! 779: else
! 780: {
! 781: write_log ("can't allocate %d MB for TT RAM\n" , TTmem_size / ( 1024*1024 ) );
! 782: TTmem_size = 0;
! 783: }
! 784: }
! 785: }
! 786:
1.1.1.5 root 787:
788: /* ROM memory: */
789: /* Depending on which ROM version we are using, the other ROM region is illegal! */
1.1.1.8 root 790: if(nNewRomMemStart == 0xFC0000)
1.1.1.5 root 791: {
792: map_banks(&ROMmem_bank, 0xFC0000 >> 16, 0x3);
793: map_banks(&BusErrMem_bank, 0xE00000 >> 16, 0x10);
794: }
1.1.1.8 root 795: else if(nNewRomMemStart == 0xE00000)
1.1.1.5 root 796: {
797: map_banks(&ROMmem_bank, 0xE00000 >> 16, 0x10);
798: map_banks(&BusErrMem_bank, 0xFC0000 >> 16, 0x3);
799: }
1.1 root 800: else
1.1.1.5 root 801: {
802: write_log("Illegal ROM memory start!\n");
803: }
1.1 root 804:
1.1.1.5 root 805: /* Cartridge memory: */
806: map_banks(&ROMmem_bank, 0xFA0000 >> 16, 0x2);
1.1.1.18! root 807: ROMmem_bank.baseaddr = ROMmemory;
! 808: ROMmem_bank.mask = ROMmem_mask;
! 809: ROMmem_bank.start = ROMmem_start;
1.1 root 810:
1.1.1.5 root 811: /* IO memory: */
812: map_banks(&IOmem_bank, IOmem_start>>16, 0x1);
1.1.1.18! root 813: IOmem_bank.baseaddr = IOmemory;
! 814: IOmem_bank.mask = IOmem_mask;
! 815: IOmem_bank.start = IOmem_start;
1.1 root 816:
1.1.1.10 root 817: /* IDE controller memory region: */
818: map_banks(&IdeMem_bank, IdeMem_start >> 16, 0x1); /* IDE controller on the Falcon */
1.1.1.18! root 819: IdeMem_bank.baseaddr = IdeMemory;
! 820: IdeMem_bank.mask = IdeMem_mask;
! 821: IdeMem_bank.start = IdeMem_start ;
1.1.1.10 root 822:
1.1.1.5 root 823: /* Illegal memory regions cause a bus error on the ST: */
1.1.1.10 root 824: map_banks(&BusErrMem_bank, 0xF10000 >> 16, 0x9);
1.1.1.17 root 825:
826: illegal_count = 50;
1.1 root 827: }
828:
1.1.1.5 root 829:
830: /*
831: * Uninitialize the memory banks.
832: */
833: void memory_uninit (void)
834: {
835: /* Here, we free allocated memory from memory_init */
1.1.1.10 root 836: if (TTmem_size > 0) {
837: free(TTmemory);
838: TTmemory = NULL;
839: }
840:
841: #if ENABLE_SMALL_MEM
842:
843: if (STmemory) {
844: free(STmemory);
845: STmemory = NULL;
846: }
847:
848: if (ROMmemory) {
849: free(ROMmemory);
850: ROMmemory = NULL;
1.1.1.5 root 851: }
1.1.1.10 root 852:
853: #endif /* ENABLE_SMALL_MEM */
1.1.1.5 root 854: }
855:
856:
1.1 root 857: void map_banks (addrbank *bank, int start, int size)
858: {
859: int bnr;
860: unsigned long int hioffs = 0, endhioffs = 0x100;
861:
862: if (start >= 0x100) {
863: for (bnr = start; bnr < start + size; bnr++)
864: put_mem_bank (bnr << 16, bank);
865: return;
866: }
867: /* Some ROMs apparently require a 24 bit address space... */
1.1.1.10 root 868: if (currprefs.address_space_24)
1.1 root 869: endhioffs = 0x10000;
870: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
871: for (bnr = start; bnr < start+size; bnr++)
872: put_mem_bank ((bnr + hioffs) << 16, bank);
873: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.