|
|
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.20! root 692: * Initialize the standard RAM memory banks
! 693: */
! 694: void memory_map_Standard_RAM ( Uint32 MMU_Bank0_Size , Uint32 MMU_Bank1_Size )
! 695: {
! 696: map_banks(&SysMem_bank, 0x00, 1);
! 697: /* Between STRamEnd and 4MB barrier, there is void space: */
! 698: map_banks(&VoidMem_bank, 0x08, 0x38);
! 699: /* Space between 4MB barrier and TOS ROM causes a bus error: */
! 700: map_banks(&BusErrMem_bank, 0x400000 >> 16, 0xA0);
! 701: /* Now map main ST RAM, overwriting the void and bus error regions if necessary: */
! 702: map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1);
! 703: }
! 704:
! 705:
! 706: /*
1.1.1.5 root 707: * Initialize the memory banks
708: */
1.1.1.8 root 709: void memory_init(uae_u32 nNewSTMemSize, uae_u32 nNewTTMemSize, uae_u32 nNewRomMemStart)
1.1.1.5 root 710: {
1.1.1.8 root 711: STmem_size = (nNewSTMemSize + 65535) & 0xFFFF0000;
712: TTmem_size = (nNewTTMemSize + 65535) & 0xFFFF0000;
1.1.1.5 root 713:
714: /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
1.1.1.8 root 715: STmem_size, TTmem_size, nNewRomMemStart);*/
1.1.1.5 root 716:
1.1.1.10 root 717: #if ENABLE_SMALL_MEM
1.1.1.9 root 718:
1.1.1.18 root 719: /* Allocate memory for ROM areas, IDE and IO memory space (0xE00000 - 0xFFFFFF) */
1.1.1.10 root 720: ROMmemory = malloc(2*1024*1024);
721: if (!ROMmemory) {
722: fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
1.1.1.11 root 723: SDL_Quit();
1.1.1.10 root 724: exit(1);
725: }
726: IdeMemory = ROMmemory + 0x100000;
727: IOmemory = ROMmemory + 0x1f0000;
728:
729: /* Allocate memory for normal ST RAM */
730: STmemory = malloc(STmem_size);
731: while (!STmemory && STmem_size > 512*1024) {
1.1.1.5 root 732: STmem_size >>= 1;
733: STmemory = (uae_u8 *)malloc (STmem_size);
1.1 root 734: if (STmemory)
1.1.1.10 root 735: write_log ("Reducing STmem size to %dkb\n", STmem_size >> 10);
1.1 root 736: }
1.1.1.10 root 737: if (!STmemory) {
1.1 root 738: write_log ("virtual memory exhausted (STmemory)!\n");
1.1.1.11 root 739: SDL_Quit();
1.1.1.10 root 740: exit(1);
1.1 root 741: }
1.1.1.10 root 742:
743: #else
744:
745: /* STmemory points to the 16 MiB STRam array, we just have to set up
746: * the remaining pointers here: */
747: ROMmemory = STRam + ROMmem_start;
748: IdeMemory = STRam + IdeMem_start;
749: IOmemory = STRam + IOmem_start;
750:
751: #endif
1.1 root 752:
1.1.1.5 root 753: init_mem_banks();
1.1 root 754:
1.1.1.18 root 755: /* Set the infos about memory pointers for each mem bank, used for direct memory access in stMemory.c */
756: STmem_bank.baseaddr = STmemory;
757: STmem_bank.mask = STmem_mask;
758: STmem_bank.start = STmem_start;
759:
760: SysMem_bank.baseaddr = STmemory;
761: SysMem_bank.mask = STmem_mask;
762: SysMem_bank.start = STmem_start;
763:
764: dummy_bank.baseaddr = NULL; /* No real memory allocated for this region */
765: VoidMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
766: BusErrMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
767:
768:
1.1.1.20! root 769: /* Map the standard RAM (Max is 4 MB on unmodified STF/STE) */
! 770: memory_map_Standard_RAM ( MMU_Bank0_Size , MMU_Bank1_Size );
1.1.1.5 root 771:
1.1.1.18 root 772:
773: /* Handle extra RAM on TT and Falcon starting at 0x1000000 and up to 0x80000000 */
774: /* This requires the CPU to use 32 bit addressing */
775: /* NOTE : code backported from cpu/memory.c, but as bAddressSpace24 is always true with old */
776: /* UAE's core, TT RAM is not supported at the moment */
777: TTmemory = NULL;
778: if ( ConfigureParams.System.bAddressSpace24 == false )
779: {
780: /* If there's no extra RAM on a TT, region 0x01000000 - 0x80000000 (2047 MB) must return bus errors */
781: if ( ConfigureParams.System.nMachineType == MACHINE_TT )
782: map_banks ( &BusErrMem_bank, TTmem_start >> 16, ( TTmem_end - TTmem_start ) >> 16 );
783:
784: if ( TTmem_size > 0 )
785: {
786: TTmemory = (uae_u8 *)malloc ( TTmem_size );
787:
788: if ( TTmemory != NULL )
789: {
790: map_banks ( &TTmem_bank, TTmem_start >> 16, TTmem_size >> 16 );
791: TTmem_mask = 0xffffffff;
792: TTmem_bank.baseaddr = TTmemory;
793: TTmem_bank.mask = TTmem_mask;
794: TTmem_bank.start = TTmem_start;
795: }
796: else
797: {
798: write_log ("can't allocate %d MB for TT RAM\n" , TTmem_size / ( 1024*1024 ) );
799: TTmem_size = 0;
800: }
801: }
802: }
803:
1.1.1.5 root 804:
805: /* ROM memory: */
806: /* Depending on which ROM version we are using, the other ROM region is illegal! */
1.1.1.8 root 807: if(nNewRomMemStart == 0xFC0000)
1.1.1.5 root 808: {
809: map_banks(&ROMmem_bank, 0xFC0000 >> 16, 0x3);
810: map_banks(&BusErrMem_bank, 0xE00000 >> 16, 0x10);
811: }
1.1.1.8 root 812: else if(nNewRomMemStart == 0xE00000)
1.1.1.5 root 813: {
814: map_banks(&ROMmem_bank, 0xE00000 >> 16, 0x10);
815: map_banks(&BusErrMem_bank, 0xFC0000 >> 16, 0x3);
816: }
1.1 root 817: else
1.1.1.5 root 818: {
819: write_log("Illegal ROM memory start!\n");
820: }
1.1 root 821:
1.1.1.5 root 822: /* Cartridge memory: */
823: map_banks(&ROMmem_bank, 0xFA0000 >> 16, 0x2);
1.1.1.18 root 824: ROMmem_bank.baseaddr = ROMmemory;
825: ROMmem_bank.mask = ROMmem_mask;
826: ROMmem_bank.start = ROMmem_start;
1.1 root 827:
1.1.1.5 root 828: /* IO memory: */
829: map_banks(&IOmem_bank, IOmem_start>>16, 0x1);
1.1.1.18 root 830: IOmem_bank.baseaddr = IOmemory;
831: IOmem_bank.mask = IOmem_mask;
832: IOmem_bank.start = IOmem_start;
1.1 root 833:
1.1.1.10 root 834: /* IDE controller memory region: */
835: map_banks(&IdeMem_bank, IdeMem_start >> 16, 0x1); /* IDE controller on the Falcon */
1.1.1.18 root 836: IdeMem_bank.baseaddr = IdeMemory;
837: IdeMem_bank.mask = IdeMem_mask;
838: IdeMem_bank.start = IdeMem_start ;
1.1.1.10 root 839:
1.1.1.5 root 840: /* Illegal memory regions cause a bus error on the ST: */
1.1.1.10 root 841: map_banks(&BusErrMem_bank, 0xF10000 >> 16, 0x9);
1.1.1.17 root 842:
843: illegal_count = 50;
1.1 root 844: }
845:
1.1.1.5 root 846:
847: /*
848: * Uninitialize the memory banks.
849: */
850: void memory_uninit (void)
851: {
852: /* Here, we free allocated memory from memory_init */
1.1.1.10 root 853: if (TTmem_size > 0) {
854: free(TTmemory);
855: TTmemory = NULL;
856: }
857:
858: #if ENABLE_SMALL_MEM
859:
860: if (STmemory) {
861: free(STmemory);
862: STmemory = NULL;
863: }
864:
865: if (ROMmemory) {
866: free(ROMmemory);
867: ROMmemory = NULL;
1.1.1.5 root 868: }
1.1.1.10 root 869:
870: #endif /* ENABLE_SMALL_MEM */
1.1.1.5 root 871: }
872:
873:
1.1 root 874: void map_banks (addrbank *bank, int start, int size)
875: {
876: int bnr;
877: unsigned long int hioffs = 0, endhioffs = 0x100;
878:
879: if (start >= 0x100) {
880: for (bnr = start; bnr < start + size; bnr++)
881: put_mem_bank (bnr << 16, bank);
882: return;
883: }
884: /* Some ROMs apparently require a 24 bit address space... */
1.1.1.10 root 885: if (currprefs.address_space_24)
1.1 root 886: endhioffs = 0x10000;
887: for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
888: for (bnr = start; bnr < start+size; bnr++)
889: put_mem_bank ((bnr + hioffs) << 16, bank);
890: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.