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 "main.h"
17 #include "sysdeps.h"
18 #include "hatari-glue.h"
19 #include "maccess.h"
20 #include "memory.h"
21
22 #include "tos.h"
23 #include "ide.h"
24 #include "ioMem.h"
25 #include "reset.h"
26 #include "stMemory.h"
27 #include "m68000.h"
28 #include "configuration.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;
37
38 static uae_u32 STmem_size;
39 uae_u32 TTmem_size = 0;
40 static uae_u32 TTmem_mask;
41
42 #define STmem_start 0x00000000
43 #define ROMmem_start 0x00E00000
44 #define IdeMem_start 0x00F00000
45 #define IOmem_start 0x00FF0000
46 #define TTmem_start 0x01000000 /* TOS 3 and TOS 4 always expect extra RAM at this address */
47 #define TTmem_end 0x80000000 /* Max value for end of TT ram, which gives 2047 MB */
48
49 #define IdeMem_size 65536
50 #define IOmem_size 65536
51 #define ROMmem_size (0x00FF0000 - 0x00E00000) /* So we cover both possible ROM regions + cartridge */
52
53 #define STmem_mask 0x00ffffff
54 #define ROMmem_mask 0x00ffffff
55 #define IdeMem_mask (IdeMem_size - 1)
56 #define IOmem_mask (IOmem_size - 1)
57
58 /* Some prototypes: */
59 static int REGPARAM3 STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
60 static uae_u8 REGPARAM3 *STmem_xlate (uaecptr addr) REGPARAM;
61
62
63
64 #ifdef WINUAE_FOR_HATARI
65 #undef NATMEM_OFFSET
66 #endif
67
68 #ifdef NATMEM_OFFSET
69 bool canbang;
70 int candirect = -1;
71 #endif
72
73 #ifdef JIT
74 /* Set by each memory handler that does not simply access real memory. */
75 int special_mem;
76 #endif
77
78 #ifdef NATMEM_OFFSET
isdirectjit(void)79 static bool isdirectjit (void)
80 {
81 return currprefs.cachesize && !currprefs.comptrustbyte;
82 }
83
canjit(void)84 static bool canjit (void)
85 {
86 if (currprefs.cpu_model < 68020 || currprefs.address_space_24)
87 return false;
88 return true;
89 }
needmman(void)90 static bool needmman (void)
91 {
92 if (!currprefs.jit_direct_compatible_memory)
93 return false;
94 #ifdef _WIN32
95 return true;
96 #endif
97 if (canjit ())
98 return true;
99 return false;
100 }
101
nocanbang(void)102 static void nocanbang (void)
103 {
104 if (canbang) {
105 write_log(_T("Switching JIT direct off!\n"));
106 }
107 canbang = 0;
108 }
109 #endif
110
111 uae_u8 ce_banktype[65536];
112 uae_u8 ce_cachable[65536];
113
114
115 /* The address space setting used during the last reset. */
116 static bool last_address_space_24;
117
118 addrbank *mem_banks[MEMORY_BANKS];
119
120 /* This has two functions. It either holds a host address that, when added
121 to the 68k address, gives the host address corresponding to that 68k
122 address (in which case the value in this array is even), OR it holds the
123 same value as mem_banks, for those banks that have baseaddr==0. In that
124 case, bit 0 is set (the memory access routines will take care of it). */
125
126 uae_u8 *baseaddr[MEMORY_BANKS];
127
128 #ifdef NO_INLINE_MEMORY_ACCESS
longget(uaecptr addr)129 __inline__ uae_u32 longget (uaecptr addr)
130 {
131 return call_mem_get_func (get_mem_bank (addr).lget, addr);
132 }
wordget(uaecptr addr)133 __inline__ uae_u32 wordget (uaecptr addr)
134 {
135 return call_mem_get_func (get_mem_bank (addr).wget, addr);
136 }
byteget(uaecptr addr)137 __inline__ uae_u32 byteget (uaecptr addr)
138 {
139 return call_mem_get_func (get_mem_bank (addr).bget, addr);
140 }
longput(uaecptr addr,uae_u32 l)141 __inline__ void longput (uaecptr addr, uae_u32 l)
142 {
143 call_mem_put_func (get_mem_bank (addr).lput, addr, l);
144 }
wordput(uaecptr addr,uae_u32 w)145 __inline__ void wordput (uaecptr addr, uae_u32 w)
146 {
147 call_mem_put_func (get_mem_bank (addr).wput, addr, w);
148 }
byteput(uaecptr addr,uae_u32 b)149 __inline__ void byteput (uaecptr addr, uae_u32 b)
150 {
151 call_mem_put_func (get_mem_bank (addr).bput, addr, b);
152 }
153 #endif
154
addr_valid(const TCHAR * txt,uaecptr addr,uae_u32 len)155 int addr_valid (const TCHAR *txt, uaecptr addr, uae_u32 len)
156 {
157 addrbank *ab = &get_mem_bank(addr);
158 if (ab == 0 || !(ab->flags & (ABFLAG_RAM | ABFLAG_ROM)) || addr < 0x100 || len > 16777215 || !valid_address (addr, len)) {
159 write_log (_T("corrupt %s pointer %x (%d) detected!\n"), txt, addr, len);
160 return 0;
161 }
162 return 1;
163 }
164
165 static uae_u32 REGPARAM3 dummy_lget (uaecptr) REGPARAM;
166 static uae_u32 REGPARAM3 dummy_wget (uaecptr) REGPARAM;
167 static uae_u32 REGPARAM3 dummy_bget (uaecptr) REGPARAM;
168 static void REGPARAM3 dummy_lput (uaecptr, uae_u32) REGPARAM;
169 static void REGPARAM3 dummy_wput (uaecptr, uae_u32) REGPARAM;
170 static void REGPARAM3 dummy_bput (uaecptr, uae_u32) REGPARAM;
171 static int REGPARAM3 dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
172
173 #define MAX_ILG 200
174 #define NONEXISTINGDATA 0
175 //#define NONEXISTINGDATA 0xffffffff
176
177
print_illegal_counted(const char * txt,uaecptr addr)178 static void print_illegal_counted(const char *txt, uaecptr addr)
179 {
180 if (!illegal_mem || illegal_count >= MAX_ILG)
181 return;
182
183 write_log("%s at %08lx\n", txt, (long)addr);
184 if (++illegal_count == MAX_ILG)
185 write_log("Suppressing further messages about illegal memory accesses.\n");
186 }
187
188 /* **** A dummy bank that only contains zeros **** */
189 /* TODO [NP] : in many cases, we should not return 0 but a value depending on the data */
190 /* last accessed on the bus */
191
dummylog(int rw,uaecptr addr,int size,uae_u32 val,int ins)192 static void dummylog (int rw, uaecptr addr, int size, uae_u32 val, int ins)
193 {
194 if (illegal_count >= MAX_ILG && MAX_ILG > 0)
195 return;
196 #ifndef WINUAE_FOR_HATARI
197 /* ignore Zorro3 expansion space */
198 if (addr >= 0xff000000 && addr <= 0xff000200)
199 return;
200 /* autoconfig and extended rom */
201 if (addr >= 0xe00000 && addr <= 0xf7ffff)
202 return;
203 /* motherboard ram */
204 if (addr >= 0x08000000 && addr <= 0x08000007)
205 return;
206 if (addr >= 0x07f00000 && addr <= 0x07f00007)
207 return;
208 if (addr >= 0x07f7fff0 && addr <= 0x07ffffff)
209 return;
210 #endif
211 if (MAX_ILG >= 0)
212 illegal_count++;
213 if (ins) {
214 write_log (_T("WARNING: Illegal opcode %cget at %08x PC=%x\n"),
215 size == 2 ? 'w' : 'l', addr, M68K_GETPC);
216 } else if (rw) {
217 write_log (_T("Illegal %cput at %08x=%08x PC=%x\n"),
218 size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, val, M68K_GETPC);
219 } else {
220 write_log (_T("Illegal %cget at %08x PC=%x\n"),
221 size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, M68K_GETPC);
222 }
223 }
224
dummy_put(uaecptr addr,int size,uae_u32 val)225 void dummy_put (uaecptr addr, int size, uae_u32 val)
226 {
227 #ifndef WINUAE_FOR_HATARI
228 #if FLASHEMU
229 if (addr >= 0xf00000 && addr < 0xf80000 && size < 2)
230 flash_write(addr, val);
231 #endif
232
233 if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) {
234 if (gary_timeout)
235 gary_wait (addr, size, true);
236 if (gary_toenb && currprefs.mmu_model)
237 exception2 (addr, true, size, regs.s ? 4 : 0);
238 }
239
240 #else
241 /* Hatari : do nothing in case of dummy_put */
242 #endif
243 }
244
dummy_get(uaecptr addr,int size,bool inst,uae_u32 defvalue)245 uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue)
246 {
247 uae_u32 v = defvalue;
248
249 #ifndef WINUAE_FOR_HATARI
250 #if FLASHEMU
251 if (addr >= 0xf00000 && addr < 0xf80000 && size < 2) {
252 if (addr < 0xf60000)
253 return flash_read(addr);
254 return 8;
255 }
256 #endif
257 #if ACA500x_DEVELOPMENT
258 if (addr == 0xb03000) {
259 return 0xffff;
260 }
261 if (addr == 0xb07000) {
262 return 0x0000;
263 }
264 if (addr == 0xb2f800) {
265 return 0xffff;
266 }
267 if (addr == 0xb3b800) {
268 return 0x0000;
269 }
270 if (addr == 0xb3f800) {
271 return currprefs.cpu_model > 68000 ? 0x0000 : 0xffff;
272 }
273 if (addr == 0xb0b000) {
274 extern bool isideint(void);
275 return isideint() ? 0xffff : 0x0000;
276 }
277 #endif
278 if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) {
279 if (gary_timeout)
280 gary_wait (addr, size, false);
281 if (gary_toenb)
282 exception2 (addr, false, size, (regs.s ? 4 : 0) | (inst ? 0 : 1));
283 return v;
284 }
285
286 if (currprefs.cpu_model >= 68040)
287 return v;
288 if (!currprefs.cpu_compatible)
289 return v;
290 if (currprefs.address_space_24)
291 addr &= 0x00ffffff;
292 if (addr >= 0x10000000)
293 return v;
294 if ((currprefs.cpu_model <= 68010) || (currprefs.cpu_model == 68020 && (currprefs.chipset_mask & CSMASK_AGA) && currprefs.address_space_24)) {
295 if (size == 4) {
296 v = regs.db & 0xffff;
297 if (addr & 1)
298 v = (v << 8) | (v >> 8);
299 v = (v << 16) | v;
300 } else if (size == 2) {
301 v = regs.db & 0xffff;
302 if (addr & 1)
303 v = (v << 8) | (v >> 8);
304 } else {
305 v = regs.db;
306 v = (addr & 1) ? (v & 0xff) : ((v >> 8) & 0xff);
307 }
308 }
309 #if 0
310 if (addr >= 0x10000000)
311 write_log (_T("%08X %d = %08x\n"), addr, size, v);
312 #endif
313
314 #else
315 /* Hatari : TODO returns 0 for now, but we should use last databus value */
316 v = 0;
317 #endif
318 return v;
319 }
320
dummy_lget(uaecptr addr)321 static uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
322 {
323 if (illegal_mem)
324 dummylog (0, addr, 4, 0, 0);
325 return dummy_get (addr, 4, false, NONEXISTINGDATA);
326 }
dummy_lgeti(uaecptr addr)327 uae_u32 REGPARAM2 dummy_lgeti (uaecptr addr)
328 {
329 if (illegal_mem)
330 dummylog (0, addr, 4, 0, 1);
331 return dummy_get (addr, 4, true, NONEXISTINGDATA);
332 }
333
dummy_wget(uaecptr addr)334 static uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
335 {
336 if (illegal_mem)
337 dummylog (0, addr, 2, 0, 0);
338 return dummy_get (addr, 2, false, NONEXISTINGDATA);
339 }
dummy_wgeti(uaecptr addr)340 uae_u32 REGPARAM2 dummy_wgeti (uaecptr addr)
341 {
342 if (illegal_mem)
343 dummylog (0, addr, 2, 0, 1);
344 return dummy_get (addr, 2, true, NONEXISTINGDATA);
345 }
346
dummy_bget(uaecptr addr)347 static uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
348 {
349 if (illegal_mem)
350 dummylog (0, addr, 1, 0, 0);
351 return dummy_get (addr, 1, false, NONEXISTINGDATA);
352 }
353
dummy_lput(uaecptr addr,uae_u32 l)354 static void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
355 {
356 if (illegal_mem)
357 dummylog (1, addr, 4, l, 0);
358 dummy_put (addr, 4, l);
359 }
dummy_wput(uaecptr addr,uae_u32 w)360 static void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
361 {
362 if (illegal_mem)
363 dummylog (1, addr, 2, w, 0);
364 dummy_put (addr, 2, w);
365 }
dummy_bput(uaecptr addr,uae_u32 b)366 static void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
367 {
368 if (illegal_mem)
369 dummylog (1, addr, 1, b, 0);
370 dummy_put (addr, 1, b);
371 }
372
dummy_check(uaecptr addr,uae_u32 size)373 static int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
374 {
375 return 0;
376 }
377
dummy_xlate(uaecptr addr)378 static uae_u8 REGPARAM3 *dummy_xlate(uaecptr addr)
379 {
380 write_log("Your Atari program just did something terribly stupid:"
381 " dummy_xlate($%x)\n", addr);
382 /*Reset_Warm();*/
383 return STmem_xlate(addr); /* So we don't crash. */
384 }
385
386
387 #ifndef WINUAE_FOR_HATARI
none_put(uaecptr addr,uae_u32 v)388 static void REGPARAM2 none_put (uaecptr addr, uae_u32 v)
389 {
390 }
ones_get(uaecptr addr)391 static uae_u32 REGPARAM2 ones_get (uaecptr addr)
392 {
393 return 0xffffffff;
394 }
395
get_sub_bank(uaecptr * paddr)396 addrbank *get_sub_bank(uaecptr *paddr)
397 {
398 int i;
399 uaecptr addr = *paddr;
400 addrbank *ab = &get_mem_bank(addr);
401 struct addrbank_sub *sb = ab->sub_banks;
402 if (!sb)
403 return &dummy_bank;
404 for (i = 0; sb[i].bank; i++) {
405 int offset = addr & 65535;
406 if (offset < sb[i + 1].offset) {
407 uae_u32 mask = sb[i].mask;
408 uae_u32 maskval = sb[i].maskval;
409 if ((offset & mask) == maskval) {
410 *paddr = addr - sb[i].suboffset;
411 return sb[i].bank;
412 }
413 }
414 }
415 *paddr = addr - sb[i - 1].suboffset;
416 return sb[i - 1].bank;
417 }
sub_bank_lget(uaecptr addr)418 uae_u32 REGPARAM3 sub_bank_lget (uaecptr addr) REGPARAM
419 {
420 addrbank *ab = get_sub_bank(&addr);
421 return ab->lget(addr);
422 }
sub_bank_wget(uaecptr addr)423 uae_u32 REGPARAM3 sub_bank_wget(uaecptr addr) REGPARAM
424 {
425 addrbank *ab = get_sub_bank(&addr);
426 return ab->wget(addr);
427 }
sub_bank_bget(uaecptr addr)428 uae_u32 REGPARAM3 sub_bank_bget(uaecptr addr) REGPARAM
429 {
430 addrbank *ab = get_sub_bank(&addr);
431 return ab->bget(addr);
432 }
sub_bank_lput(uaecptr addr,uae_u32 v)433 void REGPARAM3 sub_bank_lput(uaecptr addr, uae_u32 v) REGPARAM
434 {
435 addrbank *ab = get_sub_bank(&addr);
436 ab->lput(addr, v);
437 }
sub_bank_wput(uaecptr addr,uae_u32 v)438 void REGPARAM3 sub_bank_wput(uaecptr addr, uae_u32 v) REGPARAM
439 {
440 addrbank *ab = get_sub_bank(&addr);
441 ab->wput(addr, v);
442 }
sub_bank_bput(uaecptr addr,uae_u32 v)443 void REGPARAM3 sub_bank_bput(uaecptr addr, uae_u32 v) REGPARAM
444 {
445 addrbank *ab = get_sub_bank(&addr);
446
447 /* last accessed on the bus */ab->bput(addr, v);
448 }
sub_bank_lgeti(uaecptr addr)449 uae_u32 REGPARAM3 sub_bank_lgeti(uaecptr addr) REGPARAM
450 {
451 addrbank *ab = get_sub_bank(&addr);
452 return ab->lgeti(addr);
453 }
sub_bank_wgeti(uaecptr addr)454 uae_u32 REGPARAM3 sub_bank_wgeti(uaecptr addr) REGPARAM
455 {
456 addrbank *ab = get_sub_bank(&addr);
457 return ab->wgeti(addr);
458 }
sub_bank_check(uaecptr addr,uae_u32 size)459 int REGPARAM3 sub_bank_check(uaecptr addr, uae_u32 size) REGPARAM
460 {
461 addrbank *ab = get_sub_bank(&addr);
462 return ab->check(addr, size);
463 }
sub_bank_xlate(uaecptr addr)464 uae_u8 *REGPARAM3 sub_bank_xlate(uaecptr addr) REGPARAM
465 {
466 addrbank *ab = get_sub_bank(&addr);
467 return ab->xlateaddr(addr);
468 }
469 #endif
470
471
472 /* **** This memory bank only generates bus errors **** */
473
BusErrMem_lget(uaecptr addr)474 static uae_u32 REGPARAM3 BusErrMem_lget(uaecptr addr)
475 {
476 print_illegal_counted("Bus error lget", addr);
477
478 M68000_BusError(addr, 1, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
479 return 0;
480 }
481
BusErrMem_wget(uaecptr addr)482 static uae_u32 REGPARAM3 BusErrMem_wget(uaecptr addr)
483 {
484 print_illegal_counted("Bus error wget", addr);
485
486 M68000_BusError(addr, 1, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
487 return 0;
488 }
489
BusErrMem_bget(uaecptr addr)490 static uae_u32 REGPARAM3 BusErrMem_bget(uaecptr addr)
491 {
492 print_illegal_counted("Bus error bget", addr);
493
494 M68000_BusError(addr, 1, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
495 return 0;
496 }
497
BusErrMem_lput(uaecptr addr,uae_u32 l)498 static void REGPARAM3 BusErrMem_lput(uaecptr addr, uae_u32 l)
499 {
500 print_illegal_counted("Bus error lput", addr);
501
502 M68000_BusError(addr, 0, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
503 }
504
BusErrMem_wput(uaecptr addr,uae_u32 w)505 static void REGPARAM3 BusErrMem_wput(uaecptr addr, uae_u32 w)
506 {
507 print_illegal_counted("Bus error wput", addr);
508
509 M68000_BusError(addr, 0, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
510 }
511
BusErrMem_bput(uaecptr addr,uae_u32 b)512 static void REGPARAM3 BusErrMem_bput(uaecptr addr, uae_u32 b)
513 {
514 print_illegal_counted("Bus error bput", addr);
515
516 M68000_BusError(addr, 0, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
517 }
518
BusErrMem_check(uaecptr addr,uae_u32 size)519 static int REGPARAM3 BusErrMem_check(uaecptr addr, uae_u32 size)
520 {
521 if (illegal_mem)
522 write_log ("Bus error check at %08lx\n", (long)addr);
523
524 return 0;
525 }
526
BusErrMem_xlate(uaecptr addr)527 static uae_u8 REGPARAM3 *BusErrMem_xlate (uaecptr addr)
528 {
529 write_log("Your Atari program just did something terribly stupid:"
530 " BusErrMem_xlate($%x)\n", addr);
531
532 /*M68000_BusError(addr);*/
533 return STmem_xlate(addr); /* So we don't crash. */
534 }
535
536
537 /* **** ST RAM memory **** */
538
539 /*static uae_u8 *STmemory;*/
540 #define STmemory STRam
541
STmem_lget(uaecptr addr)542 static uae_u32 REGPARAM3 STmem_lget(uaecptr addr)
543 {
544 addr -= STmem_start & STmem_mask;
545 addr &= STmem_mask;
546 return do_get_mem_long(STmemory + addr);
547 }
548
STmem_wget(uaecptr addr)549 static uae_u32 REGPARAM3 STmem_wget(uaecptr addr)
550 {
551 addr -= STmem_start & STmem_mask;
552 addr &= STmem_mask;
553 return do_get_mem_word(STmemory + addr);
554 }
555
STmem_bget(uaecptr addr)556 static uae_u32 REGPARAM3 STmem_bget(uaecptr addr)
557 {
558 addr -= STmem_start & STmem_mask;
559 addr &= STmem_mask;
560 return STmemory[addr];
561 }
562
STmem_lput(uaecptr addr,uae_u32 l)563 static void REGPARAM3 STmem_lput(uaecptr addr, uae_u32 l)
564 {
565 addr -= STmem_start & STmem_mask;
566 addr &= STmem_mask;
567 do_put_mem_long(STmemory + addr, l);
568 }
569
STmem_wput(uaecptr addr,uae_u32 w)570 static void REGPARAM3 STmem_wput(uaecptr addr, uae_u32 w)
571 {
572 addr -= STmem_start & STmem_mask;
573 addr &= STmem_mask;
574 do_put_mem_word(STmemory + addr, w);
575 }
576
STmem_bput(uaecptr addr,uae_u32 b)577 static void REGPARAM3 STmem_bput(uaecptr addr, uae_u32 b)
578 {
579 addr -= STmem_start & STmem_mask;
580 addr &= STmem_mask;
581 STmemory[addr] = b;
582 }
583
STmem_check(uaecptr addr,uae_u32 size)584 static int REGPARAM3 STmem_check(uaecptr addr, uae_u32 size)
585 {
586 addr -= STmem_start & STmem_mask;
587 addr &= STmem_mask;
588 return (addr + size) <= STmem_size;
589 }
590
STmem_xlate(uaecptr addr)591 static uae_u8 REGPARAM3 *STmem_xlate(uaecptr addr)
592 {
593 addr -= STmem_start & STmem_mask;
594 addr &= STmem_mask;
595 return STmemory + addr;
596 }
597
598 /* Same functions for ST RAM but with MMU/MCU enabled to translate addresses */
599
STmem_lget_MMU(uaecptr addr)600 static uae_u32 REGPARAM3 STmem_lget_MMU(uaecptr addr)
601 {
602 addr -= STmem_start & STmem_mask;
603 addr &= STmem_mask;
604 addr = STMemory_MMU_Translate_Addr ( addr );
605 return do_get_mem_long(STmemory + addr);
606 }
607
STmem_wget_MMU(uaecptr addr)608 static uae_u32 REGPARAM3 STmem_wget_MMU(uaecptr addr)
609 {
610 addr -= STmem_start & STmem_mask;
611 addr &= STmem_mask;
612 addr = STMemory_MMU_Translate_Addr ( addr );
613 return do_get_mem_word(STmemory + addr);
614 }
615
STmem_bget_MMU(uaecptr addr)616 static uae_u32 REGPARAM3 STmem_bget_MMU(uaecptr addr)
617 {
618 addr -= STmem_start & STmem_mask;
619 addr &= STmem_mask;
620 addr = STMemory_MMU_Translate_Addr ( addr );
621 return STmemory[addr];
622 }
623
STmem_lput_MMU(uaecptr addr,uae_u32 l)624 static void REGPARAM3 STmem_lput_MMU(uaecptr addr, uae_u32 l)
625 {
626 addr -= STmem_start & STmem_mask;
627 addr &= STmem_mask;
628 addr = STMemory_MMU_Translate_Addr ( addr );
629 do_put_mem_long(STmemory + addr, l);
630 }
631
STmem_wput_MMU(uaecptr addr,uae_u32 w)632 static void REGPARAM3 STmem_wput_MMU(uaecptr addr, uae_u32 w)
633 {
634 addr -= STmem_start & STmem_mask;
635 addr &= STmem_mask;
636 addr = STMemory_MMU_Translate_Addr ( addr );
637 do_put_mem_word(STmemory + addr, w);
638 }
639
STmem_bput_MMU(uaecptr addr,uae_u32 b)640 static void REGPARAM3 STmem_bput_MMU(uaecptr addr, uae_u32 b)
641 {
642 addr -= STmem_start & STmem_mask;
643 addr &= STmem_mask;
644 addr = STMemory_MMU_Translate_Addr ( addr );
645 STmemory[addr] = b;
646 }
647
648
649 /*
650 * **** ST RAM system memory ****
651 * We need a separate mem bank for this region since the first 0x800 bytes on
652 * the ST can only be accessed in supervisor mode. Note that the very first
653 * 8 bytes of the ST memory are also a mirror of the TOS ROM, so they are write
654 * protected!
655 */
SysMem_lget(uaecptr addr)656 static uae_u32 REGPARAM3 SysMem_lget(uaecptr addr)
657 {
658 uaecptr addr_in = addr;
659
660 addr -= STmem_start & STmem_mask;
661 addr &= STmem_mask;
662
663 if(addr < 0x800 && !regs.s)
664 {
665 M68000_BusError(addr_in, 1, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
666 return 0;
667 }
668
669 return do_get_mem_long(STmemory + addr);
670 }
671
SysMem_wget(uaecptr addr)672 static uae_u32 REGPARAM3 SysMem_wget(uaecptr addr)
673 {
674 uaecptr addr_in = addr;
675
676 addr -= STmem_start & STmem_mask;
677 addr &= STmem_mask;
678
679 /* Only CPU will trigger bus error if bit S=0, not the blitter */
680 if(addr < 0x800 && !regs.s && BusMode == BUS_MODE_CPU)
681 {
682 M68000_BusError(addr_in, 1, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
683 return 0;
684 }
685
686 return do_get_mem_word(STmemory + addr);
687 }
688
SysMem_bget(uaecptr addr)689 static uae_u32 REGPARAM3 SysMem_bget(uaecptr addr)
690 {
691 uaecptr addr_in = addr;
692
693 addr -= STmem_start & STmem_mask;
694 addr &= STmem_mask;
695
696 if(addr < 0x800 && !regs.s)
697 {
698 M68000_BusError(addr_in, 1, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
699 return 0;
700 }
701
702 return STmemory[addr];
703 }
704
SysMem_lput(uaecptr addr,uae_u32 l)705 static void REGPARAM3 SysMem_lput(uaecptr addr, uae_u32 l)
706 {
707 uaecptr addr_in = addr;
708
709 addr -= STmem_start & STmem_mask;
710 addr &= STmem_mask;
711
712 if(addr < 0x8 || (addr < 0x800 && !regs.s))
713 {
714 M68000_BusError(addr_in, 0, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
715 return;
716 }
717
718 do_put_mem_long(STmemory + addr, l);
719 }
720
SysMem_wput(uaecptr addr,uae_u32 w)721 static void REGPARAM3 SysMem_wput(uaecptr addr, uae_u32 w)
722 {
723 uaecptr addr_in = addr;
724
725 addr -= STmem_start & STmem_mask;
726 addr &= STmem_mask;
727
728 /* Only CPU will trigger bus error if bit S=0, not the blitter */
729 if(addr < 0x8 || (addr < 0x800 && !regs.s))
730 {
731 if ( BusMode == BUS_MODE_CPU )
732 {
733 M68000_BusError(addr_in, 0, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
734 return;
735 }
736 /* If blitter writes < 0x8 then it should be ignored, else the write should be made */
737 else if ( ( BusMode == BUS_MODE_BLITTER ) && ( addr < 0x8 ) )
738 return;
739 }
740
741 do_put_mem_word(STmemory + addr, w);
742 }
743
SysMem_bput(uaecptr addr,uae_u32 b)744 static void REGPARAM3 SysMem_bput(uaecptr addr, uae_u32 b)
745 {
746 uaecptr addr_in = addr;
747
748 addr -= STmem_start & STmem_mask;
749 addr &= STmem_mask;
750
751 if(addr < 0x8 || (addr < 0x800 && !regs.s))
752 {
753 M68000_BusError(addr_in, 0, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
754 return;
755 }
756
757 STmemory[addr] = b;
758 }
759
760 /* Same functions for ST RAM system but with MMU/MCU enabled to translate addresses */
761
SysMem_lget_MMU(uaecptr addr)762 static uae_u32 REGPARAM3 SysMem_lget_MMU(uaecptr addr)
763 {
764 uaecptr addr_in = addr;
765
766 addr -= STmem_start & STmem_mask;
767 addr &= STmem_mask;
768
769 if(addr < 0x800 && !regs.s)
770 {
771 M68000_BusError(addr_in, 1, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
772 return 0;
773 }
774
775 addr = STMemory_MMU_Translate_Addr ( addr );
776 return do_get_mem_long(STmemory + addr);
777 }
778
SysMem_wget_MMU(uaecptr addr)779 static uae_u32 REGPARAM3 SysMem_wget_MMU(uaecptr addr)
780 {
781 uaecptr addr_in = addr;
782
783 addr -= STmem_start & STmem_mask;
784 addr &= STmem_mask;
785
786 /* Only CPU will trigger bus error if bit S=0, not the blitter */
787 if(addr < 0x800 && !regs.s && BusMode == BUS_MODE_CPU)
788 {
789 M68000_BusError(addr_in, 1, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
790 return 0;
791 }
792
793 addr = STMemory_MMU_Translate_Addr ( addr );
794 return do_get_mem_word(STmemory + addr);
795 }
796
SysMem_bget_MMU(uaecptr addr)797 static uae_u32 REGPARAM3 SysMem_bget_MMU(uaecptr addr)
798 {
799 uaecptr addr_in = addr;
800
801 addr -= STmem_start & STmem_mask;
802 addr &= STmem_mask;
803
804 if(addr < 0x800 && !regs.s)
805 {
806 M68000_BusError(addr_in, 1, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
807 return 0;
808 }
809
810 addr = STMemory_MMU_Translate_Addr ( addr );
811 return STmemory[addr];
812 }
813
SysMem_lput_MMU(uaecptr addr,uae_u32 l)814 static void REGPARAM3 SysMem_lput_MMU(uaecptr addr, uae_u32 l)
815 {
816 uaecptr addr_in = addr;
817
818 addr -= STmem_start & STmem_mask;
819 addr &= STmem_mask;
820
821 if(addr < 0x8 || (addr < 0x800 && !regs.s))
822 {
823 M68000_BusError(addr_in, 0, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
824 return;
825 }
826
827 addr = STMemory_MMU_Translate_Addr ( addr );
828 do_put_mem_long(STmemory + addr, l);
829 }
830
SysMem_wput_MMU(uaecptr addr,uae_u32 w)831 static void REGPARAM3 SysMem_wput_MMU(uaecptr addr, uae_u32 w)
832 {
833 uaecptr addr_in = addr;
834
835 addr -= STmem_start & STmem_mask;
836 addr &= STmem_mask;
837
838 /* Only CPU will trigger bus error if bit S=0, not the blitter */
839 if(addr < 0x8 || (addr < 0x800 && !regs.s))
840 {
841 if ( BusMode == BUS_MODE_CPU )
842 {
843 M68000_BusError(addr_in, 0, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
844 return;
845 }
846 /* If blitter writes < 0x8 then it should be ignored, else the write should be made */
847 else if ( ( BusMode == BUS_MODE_BLITTER ) && ( addr < 0x8 ) )
848 return;
849 }
850
851 addr = STMemory_MMU_Translate_Addr ( addr );
852 do_put_mem_word(STmemory + addr, w);
853 }
854
SysMem_bput_MMU(uaecptr addr,uae_u32 b)855 static void REGPARAM3 SysMem_bput_MMU(uaecptr addr, uae_u32 b)
856 {
857 uaecptr addr_in = addr;
858
859 addr -= STmem_start & STmem_mask;
860 addr &= STmem_mask;
861
862 if(addr < 0x8 || (addr < 0x800 && !regs.s))
863 {
864 M68000_BusError(addr_in, 0, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
865 return;
866 }
867
868 addr = STMemory_MMU_Translate_Addr ( addr );
869 STmemory[addr] = b;
870 }
871
872
873 /*
874 * **** Void memory ****
875 * Between the ST-RAM end and the 4 MB barrier, there is a void memory space:
876 * Reading depends on current activity on the bus and writing does nothing at all.
877 *
878 * [NP] : When there's no memory, it will return the latest data that was read on the bus.
879 * In many cases, this will return the word that was just read in the 68000's
880 * prefetch register to decode the next opcode (tested on a real STF)
881 *
882 * STF : this seems to always return the last data word on the bus read by the CPU (tested on real STF)
883 * STE : result seems also related to what the shifter displays, it can be data read by the CPU or by
884 * the shifter ; for now do the same as STF [TODO improve this ? No program are known to depend on it]
885 */
886
VoidMem_lget(uaecptr addr)887 static uae_u32 REGPARAM3 VoidMem_lget(uaecptr addr)
888 {
889 return ( regs.db<<16 ) | regs.db;
890 }
891
VoidMem_wget(uaecptr addr)892 static uae_u32 REGPARAM3 VoidMem_wget(uaecptr addr)
893 {
894 return regs.db;
895 }
896
VoidMem_bget(uaecptr addr)897 static uae_u32 REGPARAM3 VoidMem_bget(uaecptr addr)
898 {
899 return regs.db;
900 }
901
VoidMem_lput(uaecptr addr,uae_u32 l)902 static void REGPARAM3 VoidMem_lput(uaecptr addr, uae_u32 l)
903 {
904 }
905
VoidMem_wput(uaecptr addr,uae_u32 w)906 static void REGPARAM3 VoidMem_wput(uaecptr addr, uae_u32 w)
907 {
908 }
909
VoidMem_bput(uaecptr addr,uae_u32 b)910 static void REGPARAM3 VoidMem_bput (uaecptr addr, uae_u32 b)
911 {
912 }
913
VoidMem_check(uaecptr addr,uae_u32 size)914 static int REGPARAM3 VoidMem_check(uaecptr addr, uae_u32 size)
915 {
916 if (illegal_mem)
917 write_log ("Void memory check at %08lx\n", (long)addr);
918
919 return 0;
920 }
921
VoidMem_xlate(uaecptr addr)922 static uae_u8 REGPARAM3 *VoidMem_xlate (uaecptr addr)
923 {
924 write_log("Your Atari program just did something terribly stupid:"
925 " VoidMem_xlate($%x)\n", addr);
926
927 return STmem_xlate(addr); /* So we don't crash. */
928 }
929
930
931 /* **** TT fast memory **** */
932
933 uae_u8 *TTmemory;
934
TTmem_lget(uaecptr addr)935 static uae_u32 REGPARAM3 TTmem_lget(uaecptr addr)
936 {
937 addr -= TTmem_start & TTmem_mask;
938 addr &= TTmem_mask;
939 return do_get_mem_long(TTmemory + addr);
940 }
941
TTmem_wget(uaecptr addr)942 static uae_u32 REGPARAM3 TTmem_wget(uaecptr addr)
943 {
944 addr -= TTmem_start & TTmem_mask;
945 addr &= TTmem_mask;
946 return do_get_mem_word(TTmemory + addr);
947 }
948
TTmem_bget(uaecptr addr)949 static uae_u32 REGPARAM3 TTmem_bget(uaecptr addr)
950 {
951 addr -= TTmem_start & TTmem_mask;
952 addr &= TTmem_mask;
953 return TTmemory[addr];
954 }
955
TTmem_lput(uaecptr addr,uae_u32 l)956 static void REGPARAM3 TTmem_lput(uaecptr addr, uae_u32 l)
957 {
958 addr -= TTmem_start & TTmem_mask;
959 addr &= TTmem_mask;
960 do_put_mem_long(TTmemory + addr, l);
961 }
962
TTmem_wput(uaecptr addr,uae_u32 w)963 static void REGPARAM3 TTmem_wput(uaecptr addr, uae_u32 w)
964 {
965 addr -= TTmem_start & TTmem_mask;
966 addr &= TTmem_mask;
967 do_put_mem_word(TTmemory + addr, w);
968 }
969
TTmem_bput(uaecptr addr,uae_u32 b)970 static void REGPARAM3 TTmem_bput(uaecptr addr, uae_u32 b)
971 {
972 addr -= TTmem_start & TTmem_mask;
973 addr &= TTmem_mask;
974 TTmemory[addr] = b;
975 }
976
TTmem_check(uaecptr addr,uae_u32 size)977 static int REGPARAM3 TTmem_check(uaecptr addr, uae_u32 size)
978 {
979 addr -= TTmem_start & TTmem_mask;
980 addr &= TTmem_mask;
981 return (addr + size) <= TTmem_size;
982 }
983
TTmem_xlate(uaecptr addr)984 static uae_u8 REGPARAM3 *TTmem_xlate(uaecptr addr)
985 {
986 addr -= TTmem_start & TTmem_mask;
987 addr &= TTmem_mask;
988 return TTmemory + addr;
989 }
990
991
992 /* **** ROM memory **** */
993
994 uae_u8 *ROMmemory;
995
ROMmem_lget(uaecptr addr)996 static uae_u32 REGPARAM3 ROMmem_lget(uaecptr addr)
997 {
998 addr -= ROMmem_start & ROMmem_mask;
999 addr &= ROMmem_mask;
1000 return do_get_mem_long(ROMmemory + addr);
1001 }
1002
ROMmem_wget(uaecptr addr)1003 static uae_u32 REGPARAM3 ROMmem_wget(uaecptr addr)
1004 {
1005 addr -= ROMmem_start & ROMmem_mask;
1006 addr &= ROMmem_mask;
1007 return do_get_mem_word(ROMmemory + addr);
1008 }
1009
ROMmem_bget(uaecptr addr)1010 static uae_u32 REGPARAM3 ROMmem_bget(uaecptr addr)
1011 {
1012 addr -= ROMmem_start & ROMmem_mask;
1013 addr &= ROMmem_mask;
1014 return ROMmemory[addr];
1015 }
1016
ROMmem_lput(uaecptr addr,uae_u32 b)1017 static void REGPARAM3 ROMmem_lput(uaecptr addr, uae_u32 b)
1018 {
1019 print_illegal_counted("Illegal ROMmem lput", addr);
1020
1021 M68000_BusError(addr, 0, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1022 }
1023
ROMmem_wput(uaecptr addr,uae_u32 b)1024 static void REGPARAM3 ROMmem_wput(uaecptr addr, uae_u32 b)
1025 {
1026 print_illegal_counted("Illegal ROMmem wput", addr);
1027
1028 M68000_BusError(addr, 0, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1029 }
1030
ROMmem_bput(uaecptr addr,uae_u32 b)1031 static void REGPARAM3 ROMmem_bput(uaecptr addr, uae_u32 b)
1032 {
1033 print_illegal_counted("Illegal ROMmem bput", addr);
1034
1035 M68000_BusError(addr, 0, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1036 }
1037
ROMmem_check(uaecptr addr,uae_u32 size)1038 static int REGPARAM3 ROMmem_check(uaecptr addr, uae_u32 size)
1039 {
1040 addr -= ROMmem_start & ROMmem_mask;
1041 addr &= ROMmem_mask;
1042 return (addr + size) <= ROMmem_size;
1043 }
1044
ROMmem_xlate(uaecptr addr)1045 static uae_u8 REGPARAM3 *ROMmem_xlate(uaecptr addr)
1046 {
1047 addr -= ROMmem_start & ROMmem_mask;
1048 addr &= ROMmem_mask;
1049 return ROMmemory + addr;
1050 }
1051
1052
1053 /* IDE controller IO memory */
1054 /* see also ide.c */
1055
1056 static uae_u8 *IdeMemory;
1057
IdeMem_check(uaecptr addr,uae_u32 size)1058 static int REGPARAM3 IdeMem_check(uaecptr addr, uae_u32 size)
1059 {
1060 addr -= IdeMem_start;
1061 addr &= IdeMem_mask;
1062 return (addr + size) <= IdeMem_size;
1063 }
1064
IdeMem_xlate(uaecptr addr)1065 static uae_u8 REGPARAM3 *IdeMem_xlate(uaecptr addr)
1066 {
1067 addr -= IdeMem_start;
1068 addr &= IdeMem_mask;
1069 return IdeMemory + addr;
1070 }
1071
1072
1073 /* Hardware IO memory */
1074 /* see also ioMem.c */
1075
1076 uae_u8 *IOmemory;
1077
IOmem_check(uaecptr addr,uae_u32 size)1078 static int REGPARAM3 IOmem_check(uaecptr addr, uae_u32 size)
1079 {
1080 addr -= IOmem_start;
1081 addr &= IOmem_mask;
1082 return (addr + size) <= IOmem_size;
1083 }
1084
IOmem_xlate(uaecptr addr)1085 static uae_u8 REGPARAM3 *IOmem_xlate(uaecptr addr)
1086 {
1087 addr -= IOmem_start;
1088 addr &= IOmem_mask;
1089 return IOmemory + addr;
1090 }
1091
1092
1093
1094 /* **** Address banks **** */
1095
1096 addrbank dummy_bank =
1097 {
1098 dummy_lget, dummy_wget, dummy_bget,
1099 dummy_lput, dummy_wput, dummy_bput,
1100 dummy_xlate, dummy_check, NULL, NULL, NULL,
1101 dummy_lget, dummy_wget, ABFLAG_NONE
1102 // dummy_lgeti, dummy_wgeti, ABFLAG_NONE
1103 };
1104
1105 static addrbank BusErrMem_bank =
1106 {
1107 BusErrMem_lget, BusErrMem_wget, BusErrMem_bget,
1108 BusErrMem_lput, BusErrMem_wput, BusErrMem_bput,
1109 BusErrMem_xlate, BusErrMem_check, NULL, "bus_err_mem" , "BusError memory",
1110 BusErrMem_lget, BusErrMem_wget, ABFLAG_NONE
1111 };
1112
1113 static addrbank STmem_bank =
1114 {
1115 STmem_lget, STmem_wget, STmem_bget,
1116 STmem_lput, STmem_wput, STmem_bput,
1117 STmem_xlate, STmem_check, NULL, "st_mem" , "ST memory",
1118 STmem_lget, STmem_wget, ABFLAG_RAM
1119 };
1120
1121 static addrbank SysMem_bank =
1122 {
1123 SysMem_lget, SysMem_wget, SysMem_bget,
1124 SysMem_lput, SysMem_wput, SysMem_bput,
1125 STmem_xlate, STmem_check, NULL, "sys_mem" , "Sys memory",
1126 SysMem_lget, SysMem_wget, ABFLAG_RAM
1127 };
1128
1129 static addrbank STmem_bank_MMU = /* similar to STmem_bank with MMU/MCU enabled */
1130 {
1131 STmem_lget_MMU, STmem_wget_MMU, STmem_bget_MMU,
1132 STmem_lput_MMU, STmem_wput_MMU, STmem_bput_MMU,
1133 STmem_xlate, STmem_check, NULL, "st_mem" , "ST memory + MMU",
1134 STmem_lget_MMU, STmem_wget_MMU, ABFLAG_RAM
1135 };
1136
1137 static addrbank SysMem_bank_MMU = /* similar to STmem_bank with MMU/MCU enabled */
1138 {
1139 SysMem_lget_MMU, SysMem_wget_MMU, SysMem_bget_MMU,
1140 SysMem_lput_MMU, SysMem_wput_MMU, SysMem_bput_MMU,
1141 STmem_xlate, STmem_check, NULL, "sys_mem" , "Sys memory + MMU",
1142 SysMem_lget_MMU, SysMem_wget_MMU, ABFLAG_RAM
1143 };
1144
1145 static addrbank VoidMem_bank =
1146 {
1147 VoidMem_lget, VoidMem_wget, VoidMem_bget,
1148 VoidMem_lput, VoidMem_wput, VoidMem_bput,
1149 VoidMem_xlate, VoidMem_check, NULL, "void_mem" , "Void memory",
1150 VoidMem_lget, VoidMem_wget, ABFLAG_NONE
1151 };
1152
1153 static addrbank TTmem_bank =
1154 {
1155 TTmem_lget, TTmem_wget, TTmem_bget,
1156 TTmem_lput, TTmem_wput, TTmem_bput,
1157 TTmem_xlate, TTmem_check, NULL, "tt_mem" , "TT memory",
1158 TTmem_lget, TTmem_wget, ABFLAG_RAM /* NP TODO : use ABFLAG_RAM_TT for non DMA RAM */
1159 };
1160
1161 static addrbank ROMmem_bank =
1162 {
1163 ROMmem_lget, ROMmem_wget, ROMmem_bget,
1164 ROMmem_lput, ROMmem_wput, ROMmem_bput,
1165 ROMmem_xlate, ROMmem_check, NULL, "rom_mem" , "ROM memory",
1166 ROMmem_lget, ROMmem_wget, ABFLAG_ROM
1167 };
1168
1169 static addrbank IdeMem_bank =
1170 {
1171 Ide_Mem_lget, Ide_Mem_wget, Ide_Mem_bget,
1172 Ide_Mem_lput, Ide_Mem_wput, Ide_Mem_bput,
1173 IdeMem_xlate, IdeMem_check, NULL, "ide_mem" , "IDE memory",
1174 Ide_Mem_lget, Ide_Mem_wget, ABFLAG_IO
1175 };
1176
1177 static addrbank IOmem_bank =
1178 {
1179 IoMem_lget, IoMem_wget, IoMem_bget,
1180 IoMem_lput, IoMem_wput, IoMem_bput,
1181 IOmem_xlate, IOmem_check, NULL, "io_mem" , "IO memory",
1182 IoMem_lget, IoMem_wget, ABFLAG_IO
1183 };
1184
1185
1186 #ifdef WINUAE_FOR_HATARI
1187 #undef NATMEM_OFFSET /* Don't use shm in Hatari */
1188 #endif
1189
1190 #ifndef NATMEM_OFFSET
1191 //extern uae_u8 *natmem_offset, *natmem_offset_end;
1192
mapped_malloc(addrbank * ab)1193 bool mapped_malloc (addrbank *ab)
1194 {
1195 ab->startmask = ab->start;
1196 ab->baseaddr = xcalloc (uae_u8, ab->reserved_size + 4);
1197 ab->allocated_size = ab->baseaddr != NULL ? ab->reserved_size : 0;
1198 return ab->baseaddr != NULL;
1199 }
1200
mapped_free(addrbank * ab)1201 void mapped_free (addrbank *ab)
1202 {
1203 xfree(ab->baseaddr);
1204 ab->allocated_size = 0;
1205 ab->baseaddr = NULL;
1206 }
1207
1208 #else
1209
1210 #include <sys/ipc.h>
1211 #include <sys/shm.h>
1212 #include <unistd.h>
1213 #include <sys/mman.h>
1214
1215 shmpiece *shm_start;
1216
dumplist(void)1217 static void dumplist (void)
1218 {
1219 shmpiece *x = shm_start;
1220 write_log (_T("Start Dump:\n"));
1221 while (x) {
1222 write_log (_T("this=%p,Native %p,id %d,prev=%p,next=%p,size=0x%08x\n"),
1223 x, x->native_address, x->id, x->prev, x->next, x->size);
1224 x = x->next;
1225 }
1226 write_log (_T("End Dump:\n"));
1227 }
1228
find_shmpiece(uae_u8 * base,bool safe)1229 static shmpiece *find_shmpiece (uae_u8 *base, bool safe)
1230 {
1231 shmpiece *x = shm_start;
1232
1233 while (x && x->native_address != base)
1234 x = x->next;
1235 if (!x) {
1236 #ifndef WINUAE_FOR_HATARI
1237 if (safe || bogomem_aliasing)
1238 #else
1239 if (safe)
1240 #endif
1241 return 0;
1242 write_log (_T("NATMEM: Failure to find mapping at %08lx, %p\n"), base - NATMEM_OFFSET, base);
1243 nocanbang ();
1244 return 0;
1245 }
1246 return x;
1247 }
1248
delete_shmmaps(uae_u32 start,uae_u32 size)1249 static void delete_shmmaps (uae_u32 start, uae_u32 size)
1250 {
1251 if (!needmman ())
1252 return;
1253
1254 while (size) {
1255 uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1256 if (base) {
1257 shmpiece *x;
1258 //base = ((uae_u8*)NATMEM_OFFSET)+start;
1259
1260 x = find_shmpiece (base, true);
1261 if (!x)
1262 return;
1263
1264 if (x->size > size) {
1265 if (isdirectjit ())
1266 write_log (_T("NATMEM WARNING: size mismatch mapping at %08x (size %08x, delsize %08x)\n"),start,x->size,size);
1267 size = x->size;
1268 }
1269
1270 uae_shmdt (x->native_address);
1271 size -= x->size;
1272 start += x->size;
1273 if (x->next)
1274 x->next->prev = x->prev; /* remove this one from the list */
1275 if (x->prev)
1276 x->prev->next = x->next;
1277 else
1278 shm_start = x->next;
1279 xfree (x);
1280 } else {
1281 size -= 0x10000;
1282 start += 0x10000;
1283 }
1284 }
1285 }
1286
add_shmmaps(uae_u32 start,addrbank * what)1287 static void add_shmmaps (uae_u32 start, addrbank *what)
1288 {
1289 shmpiece *x = shm_start;
1290 shmpiece *y;
1291 uae_u8 *base = what->baseaddr;
1292
1293 if (!needmman ())
1294 return;
1295
1296 if (!base)
1297 return;
1298
1299 if (what->jit_read_flag && what->jit_write_flag)
1300 return;
1301
1302 x = find_shmpiece (base, false);
1303 if (!x)
1304 return;
1305
1306 y = xmalloc (shmpiece, 1);
1307 *y = *x;
1308 base = ((uae_u8 *) NATMEM_OFFSET) + start;
1309 y->native_address = (uae_u8*)uae_shmat (what, y->id, base, 0, NULL);
1310 if (y->native_address == (void *) -1) {
1311 write_log (_T("NATMEM: Failure to map existing at %08x (%p)\n"), start, base);
1312 dumplist ();
1313 nocanbang ();
1314 return;
1315 }
1316 y->next = shm_start;
1317 y->prev = NULL;
1318 if (y->next)
1319 y->next->prev = y;
1320 shm_start = y;
1321 }
1322
1323 #define MAPPED_MALLOC_DEBUG 0
1324
mapped_malloc(addrbank * ab)1325 bool mapped_malloc (addrbank *ab)
1326 {
1327 int id;
1328 void *answer;
1329 shmpiece *x;
1330 bool rtgmem = (ab->flags & ABFLAG_RTG) != 0;
1331 static int recurse;
1332
1333 if (ab->allocated_size) {
1334 write_log(_T("mapped_malloc with memory bank '%s' already allocated!?\n"), ab->name);
1335 }
1336 ab->allocated_size = 0;
1337
1338 if (ab->label && ab->label[0] == '*') {
1339 if (ab->start == 0 || ab->start == 0xffffffff) {
1340 write_log(_T("mapped_malloc(*) without start address!\n"));
1341 return false;
1342 }
1343 }
1344
1345 struct uae_mman_data md = { 0 };
1346 uaecptr start = ab->start;
1347 if (uae_mman_info(ab, &md)) {
1348 start = md.start;
1349 }
1350 ab->startmask = start;
1351 if (!md.directsupport || (ab->flags & ABFLAG_ALLOCINDIRECT)) {
1352 if (!(ab->flags & ABFLAG_ALLOCINDIRECT)) {
1353 if (canbang) {
1354 write_log(_T("JIT direct switched off: %s\n"), ab->name);
1355 }
1356 nocanbang();
1357 }
1358 ab->flags &= ~ABFLAG_DIRECTMAP;
1359 if (ab->flags & ABFLAG_NOALLOC) {
1360 ab->allocated_size = ab->reserved_size;
1361 #if MAPPED_MALLOC_DEBUG
1362 write_log(_T("mapped_malloc noalloc %s\n"), ab->name);
1363 #endif
1364 return true;
1365 }
1366 ab->baseaddr = xcalloc (uae_u8, ab->reserved_size + 4);
1367 if (ab->baseaddr)
1368 ab->allocated_size = ab->reserved_size;
1369 #if MAPPED_MALLOC_DEBUG
1370 write_log(_T("mapped_malloc nodirect %s %p\n"), ab->name, ab->baseaddr);
1371 #endif
1372 return ab->baseaddr != NULL;
1373 }
1374
1375 id = uae_shmget (UAE_IPC_PRIVATE, ab, 0x1ff);
1376 if (id == -1) {
1377 nocanbang ();
1378 if (recurse)
1379 return NULL;
1380 recurse++;
1381 mapped_malloc (ab);
1382 recurse--;
1383 return ab->baseaddr != NULL;
1384 }
1385 if (!(ab->flags & ABFLAG_NOALLOC)) {
1386 answer = uae_shmat (iab, id, NULL, 0, &md));
1387 uae_shmctl (id, UAE_IPC_RMID, NULL);
1388 } else {
1389 write_log(_T("MMAN: mapped_malloc using existing baseaddr %p\n"), ab->baseaddr);
1390 answer = ab->baseaddr;
1391 }
1392 if (answer != (void *) -1) {
1393 x = xmalloc (shmpiece, 1);
1394 x->native_address = (uae_u8*)answer;
1395 x->id = id;
1396 x->size = ab->reserved_size;
1397 x->name = ab->label;
1398 x->next = shm_start;
1399 x->prev = NULL;
1400 if (x->next)
1401 x->next->prev = x;
1402 shm_start = x;
1403 ab->baseaddr = x->native_address;
1404 if (ab->baseaddr)
1405 ab->allocated_size = ab->reserved_size;
1406 ab->flags |= ABFLAG_DIRECTMAP;
1407 #if MAPPED_MALLOC_DEBUG
1408 write_log(_T("mapped_malloc direct %s %p\n"), ab->name, ab->baseaddr);
1409 #endif
1410 return ab->baseaddr != NULL;
1411 }
1412 if (recurse)
1413 return NULL;
1414 nocanbang ();
1415 recurse++;
1416 mapped_malloc (ab);
1417 recurse--;
1418 #if MAPPED_MALLOC_DEBUG
1419 write_log(_T("mapped_malloc indirect %s %p\n"), ab->name, ab->baseaddr);
1420 #endif
1421 return ab->baseaddr != NULL;}
1422 }
1423
1424 #endif
1425
1426 static void init_mem_banks (void)
1427 {
1428 unsigned int i;
1429 // unsigned so i << 16 won't overflow to negative when i >= 32768
1430 for (i = 0; i < MEMORY_BANKS; i++)
1431 put_mem_bank (i << 16, &dummy_bank, 0);
1432 #ifdef NATMEM_OFFSET
1433 delete_shmmaps (0, 0xFFFF0000);
1434 #endif
1435 }
1436
1437
1438
1439 #ifdef WINUAE_FOR_HATARI
1440 /*
1441 * Check if an address points to a memory region that causes bus error
1442 * Returns true if region gives bus error
1443 */
1444 bool memory_region_bus_error ( uaecptr addr )
1445 {
1446 return mem_banks[bankindex(addr)] == &BusErrMem_bank;
1447 }
1448 #endif
1449
1450
1451 /*
1452 * Initialize some extra parameters for the memory banks in CE mode
1453 * By default, we set all banks to CHIP16 and not cachable
1454 *
1455 * Possible values for ce_banktype :
1456 * CE_MEMBANK_CHIP16 shared between CPU and DMA, bus width = 16 bits
1457 * CE_MEMBANK_CHIP32 shared between CPU and DMA, bus width = 32 bits (AGA chipset)
1458 * CE_MEMBANK_FAST16 accessible only to the CPU, bus width = 16 bits
1459 * CE_MEMBANK_FAST32 accessible only to the CPU, bus width = 32 bits
1460 * CE_MEMBANK_CIA Amiga only, for CIA chips
1461 *
1462 * Possible values for ce_cachable :
1463 * bit 0 : cachable yes/no for data
1464 * bit 1 : burst mode allowed when caching data yes/no
1465 * bit 7 : cachable yes/no for instructions
1466 * bit 6 : burst mode allowed when caching instructions yes/no
1467 */
1468 static void init_ce_banks (void)
1469 {
1470 /* Default to CHIP16 */
1471 memset (ce_banktype, CE_MEMBANK_CHIP16, sizeof ce_banktype);
1472
1473 /* Default to not cachable */
1474 memset (ce_cachable, 0, sizeof ce_cachable);
1475 }
1476
1477
1478 /*
1479 * For CE mode, set banktype and cachable for a memory region
1480 */
1481 static void fill_ce_banks (int start, int size, int banktype, int cachable )
1482 {
1483 int i;
1484
1485 for ( i=start ; i<start+size ; i++ )
1486 {
1487 ce_banktype[ i ] = banktype;
1488 ce_cachable[ i ] = cachable;
1489 }
1490 }
1491
1492
1493 /*
1494 * Initialize the standard RAM memory banks
1495 * - Unmodified STF/STE can have a max of 4 MB, but we can allow up to 14 MB
1496 * if RAM detection code is bypassed in the ROM (see tos.c)
1497 * - Falcon/TT can have up to 14 MB
1498 * Depending on the current config, we enable MMU/MCU to translate addresses on
1499 * each access (eg during boot when TOS checks RAM size)
1500 *
1501 * Most of the time, MMU bank size will be the same as RAM bank size and we use the "usual" non-MMU version
1502 * which considers logical address == physical address and gives faster result
1503 *
1504 * See stMemory.c for the address translation used by the MMU/MCU
1505 */
1506 void memory_map_Standard_RAM ( Uint32 MMU_Bank0_Size , Uint32 MMU_Bank1_Size )
1507 {
1508 Log_Printf(LOG_DEBUG, "memory_map_Standard_RAM total=%d ram0=%d ram1=%d mmu0=%d mmu1=%d\n", STmem_size, RAM_Bank0_Size, RAM_Bank1_Size, MMU_Bank0_Size, MMU_Bank1_Size);
1509
1510 /* Between 0 and 4MB barrier, we default to void space */
1511 map_banks_ce(&VoidMem_bank, 0x00, 0x400000 >> 16, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1512
1513 /* Space between 4MB barrier and TOS ROM causes a bus error */
1514 map_banks_ce(&BusErrMem_bank, 0x400000 >> 16, 0xA0, 0 , CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1515
1516 /* Now map main ST RAM, overwriting the void and bus error regions if necessary */
1517 /* - Map the ST system RAM from 0 to 0x10000 (required for supervisor check between 0x0 and 0x800) */
1518 /* - Map rest of the ST RAM from 0x10000 to STmem_size */
1519 /* If possible/needed we enable MMU/MCU translation for maximum accuracy (when sizes of banks differ between MMU and RAM) */
1520 if ( ( Config_IsMachineST() || Config_IsMachineSTE() )
1521 && !ConfigureParams.System.bFastBoot
1522 && !ConfigureParams.Screen.bUseExtVdiResolutions
1523 && STmem_size <= 0x400000
1524 && ( ( MMU_Bank0_Size != RAM_Bank0_Size ) || ( ( RAM_Bank1_Size > 0 ) && ( MMU_Bank1_Size != RAM_Bank1_Size ) ) )
1525 && !bRamTosImage
1526 )
1527 {
1528 /* We map memory according to the logical MMU configuration and we will translate addresses on each memory access. */
1529 /* RAM bank 0 can never be empty, but RAM bank 1 can be empty. If there's no RAM bank 1, then we must */
1530 /* use 'Void' region directly, we don't map it to STmem_bank_MMU */
1531 Log_Printf(LOG_DEBUG, "memory_map_Standard_RAM - enable MMU %d %d %d\n",
1532 STmem_size, MMU_Bank0_Size, MMU_Bank1_Size);
1533
1534 /* Map RAM bank 0 to MMU bank 0 */
1535 map_banks_ce(&SysMem_bank_MMU, 0x00, 0x10000 >> 16, 0, CE_MEMBANK_CHIP16, CACHE_ENABLE_BOTH);
1536 map_banks_ce(&STmem_bank_MMU, 0x10000 >> 16, ( MMU_Bank0_Size - 0x10000 ) >> 16,
1537 0, CE_MEMBANK_CHIP16, CACHE_ENABLE_BOTH);
1538
1539 /* If RAM bank 1 exists, we map it after MMU bank 0 ; else we keep void region */
1540 if ( RAM_Bank1_Size > 0 )
1541 map_banks_ce(&STmem_bank_MMU, MMU_Bank0_Size >> 16, MMU_Bank1_Size >> 16,
1542 0, CE_MEMBANK_CHIP16, CACHE_ENABLE_BOTH);
1543
1544 /* [NP] There's a special case when bank0=128 and bank1=2048 : addresses between $40000 and $80000 */
1545 /* are returning 'void' region too, which creates a "hole" in the memory mapping */
1546 /* (this might be a bug / forgotten case by Atari in the STF non-IMP MMU as this memory */
1547 /* configuration was certainly never used in real machines) */
1548 if ( ( MMU_Bank0_Size == MEM_BANK_SIZE_128 ) && ( MMU_Bank1_Size == MEM_BANK_SIZE_2048 ) )
1549 {
1550 map_banks_ce(&VoidMem_bank, 0x40000 >> 16, 0x40000 >> 16, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1551 }
1552 }
1553 else
1554 {
1555 /* Don't enable MMU address translation */
1556 map_banks_ce(&SysMem_bank, 0x00, 0x10000 >> 16, 0, CE_MEMBANK_CHIP16, CACHE_ENABLE_BOTH);
1557 map_banks_ce(&STmem_bank, 0x10000 >> 16, ( STmem_size - 0x10000 ) >> 16, 0, CE_MEMBANK_CHIP16, CACHE_ENABLE_BOTH);
1558 }
1559 }
1560
1561
1562 /*
1563 * Initialize all the memory banks
1564 */
1565 void memory_init(uae_u32 NewSTMemSize, uae_u32 NewTTMemSize, uae_u32 NewRomMemStart)
1566 {
1567 int addr;
1568
1569 last_address_space_24 = currprefs.address_space_24;
1570
1571 /* Round to next multiple of 65536 bytes */
1572 STmem_size = (NewSTMemSize + 65535) & 0xFFFF0000;
1573 TTmem_size = (NewTTMemSize + 65535) & 0xFFFF0000;
1574
1575 //fprintf ( stderr , "memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n", STmem_size, TTmem_size, NewRomMemStart);
1576 /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
1577 STmem_size, TTmem_size, NewRomMemStart);*/
1578
1579 #if ENABLE_SMALL_MEM
1580
1581 /* Allocate memory for ROM areas, IDE and IO memory space (0xE00000 - 0xFFFFFF) */
1582 ROMmemory = malloc(2*1024*1024);
1583 if (!ROMmemory) {
1584 fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
1585 SDL_Quit();
1586 exit(1);
1587 }
1588 IdeMemory = ROMmemory + 0x100000;
1589 IOmemory = ROMmemory + 0x1f0000;
1590
1591 /* Allocate memory for normal ST RAM */
1592 STmemory = malloc(STmem_size);
1593 while (!STmemory && STmem_size > 512*1024) {
1594 STmem_size >>= 1;
1595 STmemory = (uae_u8 *)malloc (STmem_size);
1596 if (STmemory)
1597 write_log ("Reducing STmem size to %dkb\n", STmem_size >> 10);
1598 }
1599 if (!STmemory) {
1600 write_log ("virtual memory exhausted (STmemory)!\n");
1601 SDL_Quit();
1602 exit(1);
1603 }
1604
1605 #else
1606
1607 /* STmemory points to the 16 MiB STRam array, we just have to set up
1608 * the remaining pointers here: */
1609 ROMmemory = STRam + ROMmem_start;
1610 IdeMemory = STRam + IdeMem_start;
1611 IOmemory = STRam + IOmem_start;
1612
1613 #endif
1614
1615 init_mem_banks();
1616 init_ce_banks();
1617
1618 /* Set the infos about memory pointers for each mem bank, used for direct memory access in stMemory.c */
1619 STmem_bank.baseaddr = STmemory;
1620 STmem_bank.mask = STmem_mask;
1621 STmem_bank.start = STmem_start;
1622
1623 SysMem_bank.baseaddr = STmemory;
1624 SysMem_bank.mask = STmem_mask;
1625 SysMem_bank.start = STmem_start;
1626
1627 STmem_bank_MMU.baseaddr = STmemory;
1628 STmem_bank_MMU.mask = STmem_mask;
1629 STmem_bank_MMU.start = STmem_start;
1630
1631 SysMem_bank_MMU.baseaddr = STmemory;
1632 SysMem_bank_MMU.mask = STmem_mask;
1633 SysMem_bank_MMU.start = STmem_start;
1634
1635 dummy_bank.baseaddr = NULL; /* No real memory allocated for this region */
1636 VoidMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
1637 BusErrMem_bank.baseaddr = NULL; /* No real memory allocated for this region */
1638
1639
1640 /* Map the standard RAM (Max is 4 MB on unmodified STF/STE) */
1641 memory_map_Standard_RAM ( MMU_Bank0_Size , MMU_Bank1_Size );
1642
1643
1644 /* Handle extra RAM on TT and Falcon starting at 0x1000000 and up to 0x80000000 */
1645 /* This requires the CPU to use 32 bit addressing */
1646 TTmemory = NULL;
1647 if (!currprefs.address_space_24)
1648 {
1649 /* If there's no Fast-RAM, region 0x01000000 - 0x80000000 (2047 MB) must return bus errors */
1650 map_banks_ce ( &BusErrMem_bank, TTmem_start >> 16, ( TTmem_end - TTmem_start ) >> 16, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1651
1652 if ( TTmem_size > 0 )
1653 {
1654 TTmemory = (uae_u8 *)malloc ( TTmem_size );
1655
1656 if ( TTmemory != NULL )
1657 {
1658 /* 32 bit RAM for CPU only + cache/burst allowed */
1659 map_banks_ce ( &TTmem_bank, TTmem_start >> 16, TTmem_size >> 16, 0, CE_MEMBANK_FAST32, CACHE_ENABLE_ALL);
1660 TTmem_mask = 0xffffffff;
1661 TTmem_bank.baseaddr = TTmemory;
1662 TTmem_bank.mask = TTmem_mask;
1663 TTmem_bank.start = TTmem_start;
1664 }
1665 else
1666 {
1667 write_log ("can't allocate %d MB for TT RAM\n" , TTmem_size / ( 1024*1024 ) );
1668 TTmem_size = 0;
1669 }
1670 }
1671 }
1672
1673
1674 /* ROM memory: */
1675 /* Depending on which ROM version we are using, the other ROM region is illegal! */
1676 if(NewRomMemStart == 0xFC0000)
1677 {
1678 map_banks_ce(&ROMmem_bank, 0xFC0000 >> 16, 0x3, 0, CE_MEMBANK_FAST16, CACHE_ENABLE_BOTH); /* [NP] tested on real STF, no bus wait from ROM */
1679 map_banks_ce(&BusErrMem_bank, 0xE00000 >> 16, 0x10, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1680 }
1681 else if(NewRomMemStart == 0xE00000)
1682 {
1683 map_banks_ce(&ROMmem_bank, 0xE00000 >> 16, 0x10, 0, CE_MEMBANK_FAST16, CACHE_ENABLE_BOTH); /* [NP] tested on real STF, no bus wait from ROM */
1684 map_banks_ce(&BusErrMem_bank, 0xFC0000 >> 16, 0x3, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1685 }
1686 else
1687 {
1688 write_log("Illegal ROM memory start!\n");
1689 }
1690
1691 /* Cartridge memory: */
1692 map_banks_ce(&ROMmem_bank, 0xFA0000 >> 16, 0x2, 0, CE_MEMBANK_FAST16, CACHE_ENABLE_BOTH); /* [NP] tested on real STF, no bus wait from cartridge */
1693 ROMmem_bank.baseaddr = ROMmemory;
1694 ROMmem_bank.mask = ROMmem_mask;
1695 ROMmem_bank.start = ROMmem_start;
1696
1697 /* IO memory: */
1698 map_banks_ce(&IOmem_bank, IOmem_start>>16, 0x1, 0, CE_MEMBANK_FAST16, CE_MEMBANK_NOT_CACHABLE); /* [NP] tested on real STF, no bus wait for IO memory */
1699 IOmem_bank.baseaddr = IOmemory; /* except for some shifter registers */
1700 IOmem_bank.mask = IOmem_mask;
1701 IOmem_bank.start = IOmem_start;
1702
1703 /* IDE controller memory region: */
1704 map_banks_ce(&IdeMem_bank, IdeMem_start >> 16, 0x1, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE); /* IDE controller on the Falcon */
1705 IdeMem_bank.baseaddr = IdeMemory;
1706 IdeMem_bank.mask = IdeMem_mask;
1707 IdeMem_bank.start = IdeMem_start ;
1708
1709 /* Illegal memory regions cause a bus error on the ST: */
1710 map_banks_ce(&BusErrMem_bank, 0xF10000 >> 16, 0x9, 0, CE_MEMBANK_CHIP16, CE_MEMBANK_NOT_CACHABLE);
1711
1712 /* According to the "Atari TT030 Hardware Reference Manual", the
1713 * lowest 16 MBs (i.e. the 24-bit address space) are always mirrored
1714 * to 0xff000000, so we remap memory 00xxxxxx to FFxxxxxx here. If not,
1715 * we'd get some crashes when booting TOS 3 and 4 (e.g. both TOS 3.06
1716 * and TOS 4.04 touch 0xffff8606 before setting up the MMU tables) */
1717 if (!currprefs.address_space_24)
1718 {
1719 /* Copy all 256 banks 0x0000-0x00FF to banks 0xFF00-0xFFFF */
1720 for ( addr=0x0 ; addr<=0x00ffffff ; addr+=0x10000 )
1721 {
1722 //printf ( "put mem %x %x\n" , addr , addr|0xff000000 );
1723 put_mem_bank ( 0xff000000|addr , &get_mem_bank ( addr ) , 0 );
1724
1725 /* Copy the CE parameters */
1726 ce_banktype[ (0xff000000|addr)>>16 ] = ce_banktype[ addr>>16 ];
1727 ce_cachable[ (0xff000000|addr)>>16 ] = ce_cachable[ addr>>16 ];
1728 }
1729 }
1730
1731 illegal_count = 0;
1732 }
1733
1734
1735 /*
1736 * Uninitialize the memory banks.
1737 */
1738 void memory_uninit (void)
1739 {
1740 /* Here, we free allocated memory from memory_init */
1741 if (TTmemory) {
1742 free(TTmemory);
1743 TTmemory = NULL;
1744 }
1745
1746 #if ENABLE_SMALL_MEM
1747
1748 if (STmemory) {
1749 free(STmemory);
1750 STmemory = NULL;
1751 }
1752
1753 if (ROMmemory) {
1754 free(ROMmemory);
1755 ROMmemory = NULL;
1756 }
1757
1758 #endif /* ENABLE_SMALL_MEM */
1759 }
1760
1761
1762 static void map_banks2 (addrbank *bank, int start, int size, int realsize, int quick)
1763 {
1764 #ifndef WINUAE_FOR_HATARI
1765 int bnr, old;
1766 unsigned long int hioffs = 0, endhioffs = 0x100;
1767 addrbank *orgbank = bank;
1768 uae_u32 realstart = start;
1769 #else
1770 int bnr;
1771 unsigned long int hioffs = 0, endhioffs = 0x100;
1772 uae_u32 realstart __attribute__((unused)) = start;
1773 #endif
1774
1775 //printf ( "map %x %x 24=%d\n" , start<<16 , size<<16 , currprefs.address_space_24 );
1776 #ifndef WINUAE_FOR_HATARI
1777 if (quick <= 0)
1778 old = debug_bankchange (-1);
1779 #endif
1780 flush_icache_hard (3); /* Sure don't want to keep any old mappings around! */
1781 #ifdef NATMEM_OFFSET
1782 if (!quick)
1783 delete_shmmaps (start << 16, size << 16);
1784 #endif
1785
1786 if (!realsize)
1787 realsize = size << 16;
1788
1789 if ((size << 16) < realsize) {
1790 write_log (_T("Broken mapping, size=%x, realsize=%x\nStart is %x\n"),
1791 size, realsize, start);
1792 }
1793
1794 #ifndef ADDRESS_SPACE_24BIT
1795 if (start >= 0x100) {
1796 int real_left = 0;
1797 for (bnr = start; bnr < start + size; bnr++) {
1798 if (!real_left) {
1799 realstart = bnr;
1800 real_left = realsize >> 16;
1801 #ifdef NATMEM_OFFSET
1802 if (!quick)
1803 add_shmmaps (realstart << 16, bank);
1804 #endif
1805 }
1806 put_mem_bank (bnr << 16, bank, realstart << 16);
1807 real_left--;
1808 }
1809 #ifndef WINUAE_FOR_HATARI
1810 if (quick <= 0)
1811 debug_bankchange (old);
1812 #endif
1813 return;
1814 }
1815 #endif
1816 if (last_address_space_24)
1817 endhioffs = 0x10000;
1818 #ifdef ADDRESS_SPACE_24BIT
1819 endhioffs = 0x100;
1820 #endif
1821 for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1822 int real_left = 0;
1823 for (bnr = start; bnr < start + size; bnr++) {
1824 if (!real_left) {
1825 realstart = bnr + hioffs;
1826 real_left = realsize >> 16;
1827 #ifdef NATMEM_OFFSET
1828 if (!quick)
1829 add_shmmaps (realstart << 16, bank);
1830 #endif
1831 }
1832 put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1833
1834 /* Copy the CE parameters for bank/start */
1835 ce_banktype[ (bnr + hioffs) ] = ce_banktype[ start ];
1836 ce_cachable[ (bnr + hioffs) ] = ce_cachable[ start ];
1837 //printf ( "ce copy %x %x\n" , ce_banktype[ (bnr + hioffs) ] , ce_cachable[ (bnr + hioffs) ] );
1838 real_left--;
1839 }
1840 }
1841 #ifndef WINUAE_FOR_HATARI
1842 if (quick <= 0)
1843 debug_bankchange (old);
1844 fill_ce_banks ();
1845 #endif
1846 }
1847
1848 void map_banks (addrbank *bank, int start, int size, int realsize)
1849 {
1850 map_banks2 (bank, start, size, realsize, 0);
1851 }
1852 void map_banks_quick (addrbank *bank, int start, int size, int realsize)
1853 {
1854 map_banks2 (bank, start, size, realsize, 1);
1855 }
1856 void map_banks_nojitdirect (addrbank *bank, int start, int size, int realsize)
1857 {
1858 map_banks2 (bank, start, size, realsize, -1);
1859 }
1860
1861 void map_banks_ce (addrbank *bank, int start, int size, int realsize , int banktype, int cachable )
1862 {
1863 fill_ce_banks (start, size, banktype, cachable );
1864 map_banks2 (bank, start, size, realsize, 0);
1865 }
1866
1867
1868
1869
1870 void memory_hardreset (void)
1871 {
1872 }
1873
1874
1875 /*
1876 * Called from newcpu.c / m68k_go() when cpu_hardreset==true
1877 * Clear RAM at STmemory and TTmemory
1878 */
1879 void memory_clear (void)
1880 {
1881 // [NP] Don't clear memory for now, because it would erase memory after restoring a memory snapshot
1882 // TODO : handle memstate save/restore from m68_go as in winuae ?
1883 #if 0
1884 if ( STmemory )
1885 memset ( STmemory , 0 , STmem_size );
1886 if ( TTmemory )
1887 memset ( TTmemory , 0 , TTmem_size );
1888 #endif
1889 }
1890
1891
1892