|
|
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.19! root 318: /* Only CPU will trigger bus error if bit S=0, not the blitter */
! 319: if(addr < 0x800 && !regs.s && BusMode == BUS_MODE_CPU )
1.1.1.5 root 320: {
1.1.1.18 root 321: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 322: return 0;
323: }
324:
1.1.1.7 root 325: return do_get_mem_word(STmemory + addr);
1.1.1.5 root 326: }
327:
1.1.1.6 root 328: static uae_u32 SysMem_bget(uaecptr addr)
1.1.1.5 root 329: {
1.1.1.18 root 330: addr -= STmem_start & STmem_mask;
331: addr &= STmem_mask;
332:
1.1.1.5 root 333: if(addr < 0x800 && !regs.s)
334: {
1.1.1.18 root 335: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 336: return 0;
337: }
338:
339: return STmemory[addr];
340: }
341:
1.1.1.6 root 342: static void SysMem_lput(uaecptr addr, uae_u32 l)
1.1.1.5 root 343: {
1.1.1.18 root 344: addr -= STmem_start & STmem_mask;
345: addr &= STmem_mask;
346:
1.1.1.5 root 347: if(addr < 0x8 || (addr < 0x800 && !regs.s))
348: {
1.1.1.18 root 349: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 350: return;
351: }
352:
1.1.1.7 root 353: do_put_mem_long(STmemory + addr, l);
1.1.1.5 root 354: }
355:
1.1.1.6 root 356: static void SysMem_wput(uaecptr addr, uae_u32 w)
1.1.1.5 root 357: {
1.1.1.18 root 358: addr -= STmem_start & STmem_mask;
359: addr &= STmem_mask;
360:
1.1.1.19! root 361: /* Only CPU will trigger bus error if bit S=0, not the blitter */
1.1.1.5 root 362: if(addr < 0x8 || (addr < 0x800 && !regs.s))
363: {
1.1.1.19! root 364: if ( BusMode == BUS_MODE_CPU )
! 365: {
! 366: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
! 367: return;
! 368: }
! 369: /* If blitter writes < 0x8 then it should be ignored, else the write should be made */
! 370: else if ( ( BusMode == BUS_MODE_BLITTER ) && ( addr < 0x8 ) )
! 371: return;
1.1.1.5 root 372: }
373:
1.1.1.7 root 374: do_put_mem_word(STmemory + addr, w);
1.1.1.5 root 375: }
376:
1.1.1.6 root 377: static void SysMem_bput(uaecptr addr, uae_u32 b)
1.1.1.5 root 378: {
1.1.1.18 root 379: addr -= STmem_start & STmem_mask;
380: addr &= STmem_mask;
381:
1.1.1.5 root 382: if(addr < 0x8 || (addr < 0x800 && !regs.s))
383: {
1.1.1.18 root 384: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.5 root 385: return;
386: }
387:
388: STmemory[addr] = b;
389: }
390:
391:
392: /*
393: * **** Void memory ****
394: * Between the ST-RAM end and the 4 MB barrier, there is a void memory space:
395: * Reading always returns the same value and writing does nothing at all.
1.1.1.17 root 396: * [NP] : this is not correct, reading does not always return 0, when there's
397: * no memory, it will return the latest data that was read on the bus.
398: * In many cases, this will return the word that was just read in the 68000's
399: * prefetch register to decode the next opcode (tested on a real STF)
1.1.1.5 root 400: */
401:
1.1.1.6 root 402: static uae_u32 VoidMem_lget(uaecptr addr)
1.1.1.5 root 403: {
404: return 0;
405: }
406:
1.1.1.6 root 407: static uae_u32 VoidMem_wget(uaecptr addr)
1.1.1.5 root 408: {
409: return 0;
410: }
411:
1.1.1.6 root 412: static uae_u32 VoidMem_bget(uaecptr addr)
1.1.1.5 root 413: {
414: return 0;
415: }
416:
1.1.1.6 root 417: static void VoidMem_lput(uaecptr addr, uae_u32 l)
1.1.1.5 root 418: {
419: }
420:
1.1.1.6 root 421: static void VoidMem_wput(uaecptr addr, uae_u32 w)
1.1.1.5 root 422: {
423: }
424:
1.1.1.6 root 425: static void VoidMem_bput (uaecptr addr, uae_u32 b)
1.1.1.5 root 426: {
427: }
428:
1.1.1.6 root 429: static int VoidMem_check(uaecptr addr, uae_u32 size)
1.1.1.5 root 430: {
431: return 0;
432: }
433:
1.1.1.6 root 434: static uae_u8 *VoidMem_xlate (uaecptr addr)
1.1.1.5 root 435: {
436: write_log("Your Atari program just did something terribly stupid:"
437: " VoidMem_xlate($%x)\n", addr);
438:
439: return STmem_xlate(addr); /* So we don't crash. */
440: }
441:
442:
1.1.1.18 root 443: /* **** TT fast memory **** */
1.1 root 444:
1.1.1.18 root 445: uae_u8 *TTmemory;
1.1 root 446:
1.1.1.6 root 447: static uae_u32 TTmem_lget(uaecptr addr)
1.1 root 448: {
449: addr -= TTmem_start & TTmem_mask;
450: addr &= TTmem_mask;
1.1.1.7 root 451: return do_get_mem_long(TTmemory + addr);
1.1 root 452: }
453:
1.1.1.6 root 454: static uae_u32 TTmem_wget(uaecptr addr)
1.1 root 455: {
456: addr -= TTmem_start & TTmem_mask;
457: addr &= TTmem_mask;
1.1.1.7 root 458: return do_get_mem_word(TTmemory + addr);
1.1 root 459: }
460:
1.1.1.6 root 461: static uae_u32 TTmem_bget(uaecptr addr)
1.1 root 462: {
463: addr -= TTmem_start & TTmem_mask;
464: addr &= TTmem_mask;
465: return TTmemory[addr];
466: }
467:
1.1.1.6 root 468: static void TTmem_lput(uaecptr addr, uae_u32 l)
1.1 root 469: {
470: addr -= TTmem_start & TTmem_mask;
471: addr &= TTmem_mask;
1.1.1.7 root 472: do_put_mem_long(TTmemory + addr, l);
1.1 root 473: }
474:
1.1.1.6 root 475: static void TTmem_wput(uaecptr addr, uae_u32 w)
1.1 root 476: {
477: addr -= TTmem_start & TTmem_mask;
478: addr &= TTmem_mask;
1.1.1.7 root 479: do_put_mem_word(TTmemory + addr, w);
1.1 root 480: }
481:
1.1.1.6 root 482: static void TTmem_bput(uaecptr addr, uae_u32 b)
1.1 root 483: {
484: addr -= TTmem_start & TTmem_mask;
485: addr &= TTmem_mask;
486: TTmemory[addr] = b;
487: }
488:
1.1.1.6 root 489: static int TTmem_check(uaecptr addr, uae_u32 size)
1.1 root 490: {
491: addr -= TTmem_start & TTmem_mask;
492: addr &= TTmem_mask;
1.1.1.5 root 493: return (addr + size) <= TTmem_size;
1.1 root 494: }
495:
1.1.1.6 root 496: static uae_u8 *TTmem_xlate(uaecptr addr)
1.1 root 497: {
498: addr -= TTmem_start & TTmem_mask;
499: addr &= TTmem_mask;
500: return TTmemory + addr;
501: }
502:
1.1.1.5 root 503:
504: /* **** ROM memory **** */
1.1 root 505:
1.1.1.10 root 506: uae_u8 *ROMmemory;
1.1 root 507:
1.1.1.6 root 508: static uae_u32 ROMmem_lget(uaecptr addr)
1.1 root 509: {
510: addr -= ROMmem_start & ROMmem_mask;
511: addr &= ROMmem_mask;
1.1.1.7 root 512: return do_get_mem_long(ROMmemory + addr);
1.1 root 513: }
514:
1.1.1.6 root 515: static uae_u32 ROMmem_wget(uaecptr addr)
1.1 root 516: {
517: addr -= ROMmem_start & ROMmem_mask;
518: addr &= ROMmem_mask;
1.1.1.7 root 519: return do_get_mem_word(ROMmemory + addr);
1.1 root 520: }
521:
1.1.1.6 root 522: static uae_u32 ROMmem_bget(uaecptr addr)
1.1 root 523: {
524: addr -= ROMmem_start & ROMmem_mask;
525: addr &= ROMmem_mask;
526: return ROMmemory[addr];
527: }
528:
1.1.1.6 root 529: static void ROMmem_lput(uaecptr addr, uae_u32 b)
1.1 root 530: {
1.1.1.17 root 531: print_illegal_counted("Illegal ROMmem lput", (long)addr);
1.1.1.5 root 532:
1.1.1.18 root 533: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1 root 534: }
535:
1.1.1.6 root 536: static void ROMmem_wput(uaecptr addr, uae_u32 b)
1.1 root 537: {
1.1.1.17 root 538: print_illegal_counted("Illegal ROMmem wput", (long)addr);
1.1.1.5 root 539:
1.1.1.18 root 540: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1 root 541: }
542:
1.1.1.6 root 543: static void ROMmem_bput(uaecptr addr, uae_u32 b)
1.1 root 544: {
1.1.1.17 root 545: print_illegal_counted("Illegal ROMmem bput", (long)addr);
1.1.1.5 root 546:
1.1.1.18 root 547: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1 root 548: }
549:
1.1.1.6 root 550: static int ROMmem_check(uaecptr addr, uae_u32 size)
1.1 root 551: {
552: addr -= ROMmem_start & ROMmem_mask;
553: addr &= ROMmem_mask;
554: return (addr + size) <= ROMmem_size;
555: }
556:
1.1.1.6 root 557: static uae_u8 *ROMmem_xlate(uaecptr addr)
1.1 root 558: {
559: addr -= ROMmem_start & ROMmem_mask;
560: addr &= ROMmem_mask;
561: return ROMmemory + addr;
562: }
563:
564:
1.1.1.10 root 565: /* IDE controller IO memory */
566: /* see also ide.c */
567:
568: static uae_u8 *IdeMemory;
569:
570: static int IdeMem_check(uaecptr addr, uae_u32 size)
571: {
572: addr -= IdeMem_start;
573: addr &= IdeMem_mask;
574: return (addr + size) <= IdeMem_size;
575: }
576:
577: static uae_u8 *IdeMem_xlate(uaecptr addr)
578: {
579: addr -= IdeMem_start;
580: addr &= IdeMem_mask;
581: return IdeMemory + addr;
582: }
583:
584:
1.1 root 585: /* Hardware IO memory */
1.1.1.10 root 586: /* see also ioMem.c */
1.1 root 587:
1.1.1.10 root 588: uae_u8 *IOmemory;
1.1 root 589:
1.1.1.6 root 590: static int IOmem_check(uaecptr addr, uae_u32 size)
1.1 root 591: {
1.1.1.5 root 592: addr -= IOmem_start;
1.1 root 593: addr &= IOmem_mask;
594: return (addr + size) <= IOmem_size;
595: }
596:
1.1.1.6 root 597: static uae_u8 *IOmem_xlate(uaecptr addr)
1.1 root 598: {
1.1.1.5 root 599: addr -= IOmem_start;
1.1 root 600: addr &= IOmem_mask;
601: return IOmemory + addr;
602: }
603:
604:
605:
1.1.1.5 root 606: /* **** Address banks **** */
1.1 root 607:
1.1.1.6 root 608: static addrbank dummy_bank =
609: {
1.1 root 610: dummy_lget, dummy_wget, dummy_bget,
611: dummy_lput, dummy_wput, dummy_bput,
1.1.1.18 root 612: dummy_xlate, dummy_check, NULL, ABFLAG_NONE
1.1.1.5 root 613: };
614:
1.1.1.6 root 615: static addrbank BusErrMem_bank =
616: {
1.1.1.5 root 617: BusErrMem_lget, BusErrMem_wget, BusErrMem_bget,
618: BusErrMem_lput, BusErrMem_wput, BusErrMem_bput,
1.1.1.18 root 619: BusErrMem_xlate, BusErrMem_check, NULL, ABFLAG_NONE
1.1 root 620: };
621:
1.1.1.6 root 622: static addrbank STmem_bank =
623: {
1.1 root 624: STmem_lget, STmem_wget, STmem_bget,
625: STmem_lput, STmem_wput, STmem_bput,
1.1.1.18 root 626: STmem_xlate, STmem_check, NULL, ABFLAG_RAM
1.1 root 627: };
628:
1.1.1.6 root 629: static addrbank SysMem_bank =
630: {
1.1.1.5 root 631: SysMem_lget, SysMem_wget, SysMem_bget,
632: SysMem_lput, SysMem_wput, SysMem_bput,
1.1.1.18 root 633: STmem_xlate, STmem_check, NULL, ABFLAG_RAM
1.1.1.5 root 634: };
635:
1.1.1.6 root 636: static addrbank VoidMem_bank =
637: {
1.1.1.5 root 638: VoidMem_lget, VoidMem_wget, VoidMem_bget,
639: VoidMem_lput, VoidMem_wput, VoidMem_bput,
1.1.1.18 root 640: VoidMem_xlate, VoidMem_check , NULL, ABFLAG_NONE
1.1.1.5 root 641: };
642:
1.1.1.6 root 643: static addrbank TTmem_bank =
644: {
1.1 root 645: TTmem_lget, TTmem_wget, TTmem_bget,
646: TTmem_lput, TTmem_wput, TTmem_bput,
1.1.1.18 root 647: TTmem_xlate, TTmem_check, NULL, ABFLAG_RAM
1.1 root 648: };
649:
1.1.1.6 root 650: static addrbank ROMmem_bank =
651: {
1.1 root 652: ROMmem_lget, ROMmem_wget, ROMmem_bget,
653: ROMmem_lput, ROMmem_wput, ROMmem_bput,
1.1.1.18 root 654: ROMmem_xlate, ROMmem_check, NULL, ABFLAG_ROM
1.1 root 655: };
656:
1.1.1.10 root 657: static addrbank IdeMem_bank =
658: {
659: Ide_Mem_lget, Ide_Mem_wget, Ide_Mem_bget,
660: Ide_Mem_lput, Ide_Mem_wput, Ide_Mem_bput,
1.1.1.18 root 661: IdeMem_xlate, IdeMem_check, NULL, ABFLAG_IO
1.1.1.10 root 662: };
663:
1.1.1.6 root 664: static addrbank IOmem_bank =
665: {
1.1.1.7 root 666: IoMem_lget, IoMem_wget, IoMem_bget,
667: IoMem_lput, IoMem_wput, IoMem_bput,
1.1.1.18 root 668: IOmem_xlate, IOmem_check, NULL, ABFLAG_IO
1.1 root 669: };
670:
671:
1.1.1.5 root 672:
1.1 root 673: static void init_mem_banks (void)
674: {
675: int i;
676: for (i = 0; i < 65536; i++)
677: put_mem_bank (i<<16, &dummy_bank);
678: }
679:
680:
681: /*
1.1.1.18 root 682: * Check if an address points to a memory region that causes bus error
683: * Returns true if region gives bus error
684: */
685: bool memory_region_bus_error ( uaecptr addr )
686: {
687: return mem_banks[bankindex(addr)] == &BusErrMem_bank;
688: }
689:
690:
691: /*
1.1.1.5 root 692: * Initialize the memory banks
693: */
1.1.1.8 root 694: void memory_init(uae_u32 nNewSTMemSize, uae_u32 nNewTTMemSize, uae_u32 nNewRomMemStart)
1.1.1.5 root 695: {
1.1.1.8 root 696: STmem_size = (nNewSTMemSize + 65535) & 0xFFFF0000;
697: TTmem_size = (nNewTTMemSize + 65535) & 0xFFFF0000;
1.1.1.5 root 698:
699: /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
1.1.1.8 root 700: STmem_size, TTmem_size, nNewRomMemStart);*/
1.1.1.5 root 701:
1.1.1.10 root 702: #if ENABLE_SMALL_MEM
1.1.1.9 root 703:
1.1.1.18 root 704: /* Allocate memory for ROM areas, IDE and IO memory space (0xE00000 - 0xFFFFFF) */
1.1.1.10 root 705: ROMmemory = malloc(2*1024*1024);
706: if (!ROMmemory) {
707: fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
1.1.1.11 root 708: SDL_Quit();
1.1.1.10 root 709: exit(1);
710: }
711: IdeMemory = ROMmemory + 0x100000;
712: IOmemory = ROMmemory + 0x1f0000;
713:
714: /* Allocate memory for normal ST RAM */
715: STmemory = malloc(STmem_size);
716: while (!STmemory && STmem_size > 512*1024) {
1.1.1.5 root 717: STmem_size >>= 1;
718: STmemory = (uae_u8 *)malloc (STmem_size);
1.1 root 719: if (STmemory)
1.1.1.10 root 720: write_log ("Reducing STmem size to %dkb\n", STmem_size >> 10);
1.1 root 721: }
1.1.1.10 root 722: if (!STmemory) {
1.1 root 723: write_log ("virtual memory exhausted (STmemory)!\n");
1.1.1.11 root 724: SDL_Quit();
1.1.1.10 root 725: exit(1);
1.1 root 726: }
1.1.1.10 root 727:
728: #else
729:
730: /* STmemory points to the 16 MiB STRam array, we just have to set up
731: * the remaining pointers here: */
732: ROMmemory = STRam + ROMmem_start;
733: IdeMemory = STRam + IdeMem_start;
734: IOmemory = STRam + IOmem_start;
735:
736: #endif
1.1 root 737:
1.1.1.5 root 738: init_mem_banks();
1.1 root 739:
1.1.1.18 root 740: /* Set the infos about memory pointers for each mem bank, used for direct memory access in stMemory.c */
741: STmem_bank.baseaddr = STmemory;
742: STmem_bank.mask = STmem_mask;
743: STmem_bank.start = STmem_start;
744:
745: SysMem_bank.baseaddr = STmemory;
746: SysMem_bank.mask = STmem_mask;
747: SysMem_bank.start = STmem_start;
748:
749: dummy_bank.baseaddr = NULL; /* No real memory allocated for this region */
750: VoidMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
751: BusErrMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
752:
753:
1.1.1.8 root 754: /* Map the ST system RAM: */
1.1.1.5 root 755: map_banks(&SysMem_bank, 0x00, 1);
1.1.1.8 root 756: /* Between STRamEnd and 4MB barrier, there is void space: */
757: map_banks(&VoidMem_bank, 0x08, 0x38);
758: /* Space between 4MB barrier and TOS ROM causes a bus error: */
759: map_banks(&BusErrMem_bank, 0x400000 >> 16, 0xA0);
760: /* Now map main ST RAM, overwriting the void and bus error regions if necessary: */
1.1.1.5 root 761: map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1);
762:
1.1.1.18 root 763:
764: /* Handle extra RAM on TT and Falcon starting at 0x1000000 and up to 0x80000000 */
765: /* This requires the CPU to use 32 bit addressing */
766: /* NOTE : code backported from cpu/memory.c, but as bAddressSpace24 is always true with old */
767: /* UAE's core, TT RAM is not supported at the moment */
768: TTmemory = NULL;
769: if ( ConfigureParams.System.bAddressSpace24 == false )
770: {
771: /* If there's no extra RAM on a TT, region 0x01000000 - 0x80000000 (2047 MB) must return bus errors */
772: if ( ConfigureParams.System.nMachineType == MACHINE_TT )
773: map_banks ( &BusErrMem_bank, TTmem_start >> 16, ( TTmem_end - TTmem_start ) >> 16 );
774:
775: if ( TTmem_size > 0 )
776: {
777: TTmemory = (uae_u8 *)malloc ( TTmem_size );
778:
779: if ( TTmemory != NULL )
780: {
781: map_banks ( &TTmem_bank, TTmem_start >> 16, TTmem_size >> 16 );
782: TTmem_mask = 0xffffffff;
783: TTmem_bank.baseaddr = TTmemory;
784: TTmem_bank.mask = TTmem_mask;
785: TTmem_bank.start = TTmem_start;
786: }
787: else
788: {
789: write_log ("can't allocate %d MB for TT RAM\n" , TTmem_size / ( 1024*1024 ) );
790: TTmem_size = 0;
791: }
792: }
793: }
794:
1.1.1.5 root 795:
796: /* ROM memory: */
797: /* Depending on which ROM version we are using, the other ROM region is illegal! */
1.1.1.8 root 798: if(nNewRomMemStart == 0xFC0000)
1.1.1.5 root 799: {
800: map_banks(&ROMmem_bank, 0xFC0000 >> 16, 0x3);
801: map_banks(&BusErrMem_bank, 0xE00000 >> 16, 0x10);
802: }
1.1.1.8 root 803: else if(nNewRomMemStart == 0xE00000)
1.1.1.5 root 804: {
805: map_banks(&ROMmem_bank, 0xE00000 >> 16, 0x10);
806: map_banks(&BusErrMem_bank, 0xFC0000 >> 16, 0x3);
807: }
1.1 root 808: else
1.1.1.5 root 809: {
810: write_log("Illegal ROM memory start!\n");
811: }
1.1 root 812:
1.1.1.5 root 813: /* Cartridge memory: */
814: map_banks(&ROMmem_bank, 0xFA0000 >> 16, 0x2);
1.1.1.18 root 815: ROMmem_bank.baseaddr = ROMmemory;
816: ROMmem_bank.mask = ROMmem_mask;
817: ROMmem_bank.start = ROMmem_start;
1.1 root 818:
1.1.1.5 root 819: /* IO memory: */
820: map_banks(&IOmem_bank, IOmem_start>>16, 0x1);
1.1.1.18 root 821: IOmem_bank.baseaddr = IOmemory;
822: IOmem_bank.mask = IOmem_mask;
823: IOmem_bank.start = IOmem_start;
1.1 root 824:
1.1.1.10 root 825: /* IDE controller memory region: */
826: map_banks(&IdeMem_bank, IdeMem_start >> 16, 0x1); /* IDE controller on the Falcon */
1.1.1.18 root 827: IdeMem_bank.baseaddr = IdeMemory;
828: IdeMem_bank.mask = IdeMem_mask;
829: IdeMem_bank.start = IdeMem_start ;
1.1.1.10 root 830:
1.1.1.5 root 831: /* Illegal memory regions cause a bus error on the ST: */
1.1.1.10 root 832: map_banks(&BusErrMem_bank, 0xF10000 >> 16, 0x9);
1.1.1.17 root 833:
834: illegal_count = 50;
1.1 root 835: }
836:
1.1.1.5 root 837:
838: /*
839: * Uninitialize the memory banks.
840: */
841: void memory_uninit (void)
842: {
843: /* Here, we free allocated memory from memory_init */
1.1.1.10 root 844: if (TTmem_size > 0) {
845: free(TTmemory);
846: TTmemory = NULL;
847: }
848:
849: #if ENABLE_SMALL_MEM
850:
851: if (STmemory) {
852: free(STmemory);
853: STmemory = NULL;
854: }
855:
856: if (ROMmemory) {
857: free(ROMmemory);
858: ROMmemory = NULL;
1.1.1.5 root 859: }
1.1.1.10 root 860:
861: #endif /* ENABLE_SMALL_MEM */
1.1.1.5 root 862: }
863:
864:
1.1 root 865: void map_banks (addrbank *bank, int start, int size)
866: {
867: int bnr;
868: unsigned long int hioffs = 0, endhioffs = 0x100;
869:
870: if (start >= 0x100) {
871: for (bnr = start; bnr < start + size; bnr++)
872: put_mem_bank (bnr << 16, bank);
873: return;
874: }
875: /* Some ROMs apparently require a 24 bit address space... */
1.1.1.10 root 876: if (currprefs.address_space_24)
1.1 root 877: endhioffs = 0x10000;
878: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
879: for (bnr = start; bnr < start+size; bnr++)
880: put_mem_bank ((bnr + hioffs) << 16, bank);
881: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.