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