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