|
|
1.1.1.3 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
1.1.1.3 root 3: *
1.1 root 4: * memory management
1.1.1.3 root 5: *
1.1 root 6: * Copyright 1995 Bernd Schmidt
7: */
8:
1.1.1.8 root 9: extern void memory_reset (void);
1.1.1.13! root 10: extern void a1000_reset (void);
1.1.1.7 root 11:
1.1.1.3 root 12: typedef uae_u32 (*mem_get_func)(uaecptr) REGPARAM;
13: typedef void (*mem_put_func)(uaecptr, uae_u32) REGPARAM;
14: typedef uae_u8 *(*xlate_func)(uaecptr) REGPARAM;
15: typedef int (*check_func)(uaecptr, uae_u32) REGPARAM;
1.1.1.2 root 16:
17: extern char *address_space, *good_address_map;
1.1.1.3 root 18: extern uae_u8 *chipmemory;
1.1.1.2 root 19:
1.1.1.4 root 20: extern uae_u32 allocated_chipmem;
21: extern uae_u32 allocated_fastmem;
22: extern uae_u32 allocated_bogomem;
23: extern uae_u32 allocated_gfxmem;
24: extern uae_u32 allocated_z3fastmem;
25: extern uae_u32 allocated_a3000mem;
26:
1.1.1.2 root 27: #undef DIRECT_MEMFUNCS_SUCCESSFUL
1.1.1.4 root 28: #include "machdep/maccess.h"
1.1.1.2 root 29:
30: #ifndef CAN_MAP_MEMORY
31: #undef USE_COMPILER
32: #endif
33:
34: #if defined(USE_COMPILER) && !defined(USE_MAPPED_MEMORY)
35: #define USE_MAPPED_MEMORY
36: #endif
37:
1.1 root 38: #define kickmem_size 0x080000
39:
1.1.1.3 root 40: #define chipmem_start 0x00000000
41: #define bogomem_start 0x00C00000
42: #define a3000mem_start 0x07000000
43: #define kickmem_start 0x00F80000
1.1 root 44:
45: extern int ersatzkickfile;
1.1.1.9 root 46: extern int cloanto_rom;
1.1.1.13! root 47: extern uae_u16 kickstart_version;
! 48: extern int uae_boot_rom, uae_boot_rom_size;
1.1 root 49:
1.1.1.8 root 50: extern uae_u8* baseaddr[];
51:
1.1 root 52: typedef struct {
53: /* These ones should be self-explanatory... */
1.1.1.3 root 54: mem_get_func lget, wget, bget;
1.1.1.2 root 55: mem_put_func lput, wput, bput;
1.1.1.3 root 56: /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can
57: * be used to address memory without calling the wget/wput functions.
1.1 root 58: * This doesn't work for all memory banks, so this function may call
59: * abort(). */
60: xlate_func xlateaddr;
61: /* To prevent calls to abort(), use check before calling xlateaddr.
62: * It checks not only that the memory bank can do xlateaddr, but also
1.1.1.3 root 63: * that the pointer points to an area of at least the specified size.
1.1 root 64: * This is used for example to translate bitplane pointers in custom.c */
65: check_func check;
1.1.1.8 root 66: /* For those banks that refer to real memory, we can save the whole trouble
67: of going through function calls, and instead simply grab the memory
68: ourselves. This holds the memory address where the start of memory is
69: for this particular bank. */
70: uae_u8 *baseaddr;
1.1.1.13! root 71: const char *name;
1.1 root 72: } addrbank;
73:
1.1.1.8 root 74: extern uae_u8 *filesysory;
1.1.1.13! root 75: extern uae_u8 *rtarea;
1.1.1.3 root 76:
1.1 root 77: extern addrbank chipmem_bank;
78: extern addrbank kickmem_bank;
79: extern addrbank custom_bank;
80: extern addrbank clock_bank;
81: extern addrbank cia_bank;
82: extern addrbank rtarea_bank;
83: extern addrbank expamem_bank;
84: extern addrbank fastmem_bank;
1.1.1.3 root 85: extern addrbank gfxmem_bank;
1.1.1.13! root 86: extern addrbank gayle_bank;
! 87: extern addrbank gayle2_bank;
! 88: extern addrbank gayle_attr_bank;
! 89: extern addrbank mbres_bank;
1.1 root 90:
91: extern void rtarea_init (void);
1.1.1.2 root 92: extern void rtarea_setup (void);
1.1 root 93: extern void expamem_init (void);
94: extern void expamem_reset (void);
95:
1.1.1.3 root 96: extern uae_u32 gfxmem_start;
97: extern uae_u8 *gfxmemory;
98: extern uae_u32 gfxmem_mask;
99: extern int address_space_24;
1.1 root 100:
101: /* Default memory access functions */
102:
1.1.1.3 root 103: extern int default_check(uaecptr addr, uae_u32 size) REGPARAM;
104: extern uae_u8 *default_xlate(uaecptr addr) REGPARAM;
1.1 root 105:
1.1.1.3 root 106: #define bankindex(addr) (((uaecptr)(addr)) >> 16)
1.1 root 107:
1.1.1.3 root 108: extern addrbank *mem_banks[65536];
1.1.1.8 root 109: extern uae_u8 *baseaddr[65536];
1.1.1.3 root 110: #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
1.1.1.8 root 111: #define put_mem_bank(addr, b, realstart) do { \
112: (mem_banks[bankindex(addr)] = (b)); \
113: if ((b)->baseaddr) \
1.1.1.11 root 114: baseaddr[bankindex(addr)] = (b)->baseaddr - (realstart); \
1.1.1.8 root 115: else \
1.1.1.11 root 116: baseaddr[bankindex(addr)] = (uae_u8*)(((long)b)+1); \
1.1.1.8 root 117: } while (0)
1.1.1.3 root 118:
1.1.1.9 root 119: extern void memory_init (void);
120: extern void memory_cleanup (void);
121: extern void map_banks (addrbank *bank, int first, int count, int realsize);
1.1.1.13! root 122: extern void map_overlay (int chip);
1.1.1.2 root 123:
124: #ifndef NO_INLINE_MEMORY_ACCESS
125:
1.1.1.3 root 126: #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
127: #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
128: #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
129: #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
130: #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
131: #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
1.1.1.2 root 132:
133: #else
134:
1.1.1.3 root 135: extern uae_u32 alongget(uaecptr addr);
136: extern uae_u32 awordget(uaecptr addr);
137: extern uae_u32 longget(uaecptr addr);
138: extern uae_u32 wordget(uaecptr addr);
139: extern uae_u32 byteget(uaecptr addr);
140: extern void longput(uaecptr addr, uae_u32 l);
141: extern void wordput(uaecptr addr, uae_u32 w);
142: extern void byteput(uaecptr addr, uae_u32 b);
1.1.1.2 root 143:
144: #endif
145:
146: #ifndef MD_HAVE_MEM_1_FUNCS
147:
148: #define longget_1 longget
149: #define wordget_1 wordget
150: #define byteget_1 byteget
151: #define longput_1 longput
152: #define wordput_1 wordput
153: #define byteput_1 byteput
154:
155: #endif
156:
1.1.1.13! root 157: STATIC_INLINE uae_u32 get_long (uaecptr addr)
1.1 root 158: {
1.1.1.3 root 159: return longget_1(addr);
1.1 root 160: }
1.1.1.13! root 161: STATIC_INLINE uae_u32 get_word (uaecptr addr)
1.1 root 162: {
1.1.1.3 root 163: return wordget_1(addr);
1.1 root 164: }
1.1.1.13! root 165: STATIC_INLINE uae_u32 get_byte (uaecptr addr)
1.1 root 166: {
1.1.1.3 root 167: return byteget_1(addr);
1.1 root 168: }
1.1.1.13! root 169:
! 170: /*
! 171: * Read a host pointer from addr
! 172: */
! 173: #if SIZEOF_VOID_P == 4
! 174: # define get_pointer(addr) ((void *)get_long (addr))
! 175: #else
! 176: # if SIZEOF_VOID_P == 8
! 177: STATIC_INLINE void *get_pointer (uaecptr addr)
! 178: {
! 179: const unsigned int n = SIZEOF_VOID_P / 4;
! 180: union {
! 181: void *ptr;
! 182: uae_u32 longs[SIZEOF_VOID_P / 4];
! 183: } p;
! 184: unsigned int i;
! 185:
! 186: for (i = 0; i < n; i++) {
! 187: #ifdef WORDS_BIGENDIAN
! 188: p.longs[i] = get_long (addr + i * 4);
! 189: #else
! 190: p.longs[n - 1 - i] = get_long (addr + i * 4);
! 191: #endif
! 192: }
! 193: return p.ptr;
! 194: }
! 195: # else
! 196: # error "Unknown or unsupported pointer size."
! 197: # endif
! 198: #endif
! 199:
! 200: STATIC_INLINE void put_long (uaecptr addr, uae_u32 l)
1.1 root 201: {
1.1.1.2 root 202: longput_1(addr, l);
1.1 root 203: }
1.1.1.13! root 204: STATIC_INLINE void put_word (uaecptr addr, uae_u32 w)
1.1 root 205: {
1.1.1.2 root 206: wordput_1(addr, w);
1.1 root 207: }
1.1.1.13! root 208: STATIC_INLINE void put_byte (uaecptr addr, uae_u32 b)
1.1 root 209: {
1.1.1.2 root 210: byteput_1(addr, b);
1.1 root 211: }
212:
1.1.1.13! root 213: /*
! 214: * Store host pointer v at addr
! 215: */
! 216: #if SIZEOF_VOID_P == 4
! 217: # define put_pointer(addr, p) (put_long ((addr), (uae_u32)(p)))
! 218: #else
! 219: # if SIZEOF_VOID_P == 8
! 220: STATIC_INLINE void put_pointer (uaecptr addr, void *v)
! 221: {
! 222: const unsigned int n = SIZEOF_VOID_P / 4;
! 223: union {
! 224: void *ptr;
! 225: uae_u32 longs[SIZEOF_VOID_P / 4];
! 226: } p;
! 227: unsigned int i;
! 228:
! 229: p.ptr = v;
! 230:
! 231: for (i = 0; i < n; i++) {
! 232: #ifdef WORDS_BIGENDIAN
! 233: put_long (addr + i * 4, p.longs[i]);
! 234: #else
! 235: put_long (addr + i * 4, p.longs[n - 1 - i]);
! 236: #endif
! 237: }
! 238: }
! 239: # endif
! 240: #endif
! 241:
! 242: STATIC_INLINE uae_u8 *get_real_address (uaecptr addr)
1.1 root 243: {
1.1.1.3 root 244: return get_mem_bank(addr).xlateaddr(addr);
1.1 root 245: }
246:
1.1.1.5 root 247: STATIC_INLINE int valid_address(uaecptr addr, uae_u32 size)
1.1 root 248: {
1.1.1.3 root 249: return get_mem_bank(addr).check(addr, size);
1.1 root 250: }
1.1.1.6 root 251:
252: /* For faster access in custom chip emulation. */
253: extern uae_u32 chipmem_lget (uaecptr) REGPARAM;
254: extern uae_u32 chipmem_wget (uaecptr) REGPARAM;
255: extern uae_u32 chipmem_bget (uaecptr) REGPARAM;
256: extern void chipmem_lput (uaecptr, uae_u32) REGPARAM;
257: extern void chipmem_wput (uaecptr, uae_u32) REGPARAM;
258: extern void chipmem_bput (uaecptr, uae_u32) REGPARAM;
1.1.1.8 root 259:
1.1.1.13! root 260: extern uae_u32 chipmem_agnus_wget (uaecptr) REGPARAM;
! 261: extern void chipmem_agnus_wput (uaecptr, uae_u32) REGPARAM;
! 262:
1.1.1.8 root 263: #ifdef NATMEM_OFFSET
264:
265: typedef struct shmpiece_reg {
266: uae_u8 *native_address;
267: int id;
268: uae_u32 size;
269: struct shmpiece_reg *next;
270: struct shmpiece_reg *prev;
271: } shmpiece;
272:
273: extern shmpiece *shm_start;
274: extern int canbang;
275:
276: #endif
277:
278: extern uae_u8 *mapped_malloc (size_t, char *);
1.1.1.9 root 279: extern void mapped_free (uae_u8 *);
1.1.1.13! root 280: extern void memory_hardreset (void);
1.1.1.10 root 281:
1.1.1.13! root 282: uaecptr strcpyha_safe (uaecptr dst, const char *src);
! 283: uaecptr strncpyha_safe (uaecptr dst, const char *src, int size);
! 284: extern char *strcpyah_safe (char *dst, uaecptr src);
! 285: extern void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size);
! 286: extern void memcpyha (uaecptr dst, const uae_u8 *src, int size);
! 287: extern void memcpyah_safe (uae_u8 *dst, uaecptr src, int size);
! 288: extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.