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