Annotation of uae/src/memory.c, revision 1.1.1.13

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Memory management
                      5:   *
                      6:   * (c) 1995 Bernd Schmidt
                      7:   */
                      8: 
                      9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
                     12: #include "config.h"
                     13: #include "options.h"
1.1.1.3   root       14: #include "uae.h"
1.1       root       15: #include "memory.h"
                     16: #include "ersatz.h"
                     17: #include "zfile.h"
1.1.1.9   root       18: #include "custom.h"
                     19: #include "events.h"
                     20: #include "newcpu.h"
1.1.1.11  root       21: #include "autoconf.h"
1.1.1.9   root       22: #include "savestate.h"
1.1       root       23: 
1.1.1.2   root       24: #ifdef USE_MAPPED_MEMORY
1.1       root       25: #include <sys/mman.h>
                     26: #endif
                     27: 
1.1.1.8   root       28: /* Set by each memory handler that does not simply access real memory.  */
                     29: int special_mem;
                     30: 
1.1       root       31: int ersatzkickfile = 0;
                     32: 
1.1.1.4   root       33: uae_u32 allocated_chipmem;
                     34: uae_u32 allocated_fastmem;
                     35: uae_u32 allocated_bogomem;
                     36: uae_u32 allocated_gfxmem;
                     37: uae_u32 allocated_z3fastmem;
                     38: uae_u32 allocated_a3000mem;
                     39: 
1.1.1.9   root       40: static long chip_filepos;
                     41: static long bogo_filepos;
                     42: static long rom_filepos;
                     43: 
1.1.1.3   root       44: addrbank *mem_banks[65536];
1.1.1.9   root       45: 
                     46: /* This has two functions. It either holds a host address that, when added
                     47:    to the 68k address, gives the host address corresponding to that 68k
                     48:    address (in which case the value in this array is even), OR it holds the
                     49:    same value as mem_banks, for those banks that have baseaddr==0. In that
                     50:    case, bit 0 is set (the memory access routines will take care of it).  */
                     51: 
                     52: uae_u8 *baseaddr[65536];
1.1       root       53: 
1.1.1.2   root       54: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5   root       55: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2   root       56: {
1.1.1.5   root       57:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2   root       58: }
1.1.1.5   root       59: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2   root       60: {
1.1.1.5   root       61:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2   root       62: }
1.1.1.5   root       63: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2   root       64: {
1.1.1.5   root       65:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2   root       66: }
1.1.1.5   root       67: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2   root       68: {
1.1.1.5   root       69:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2   root       70: }
1.1.1.5   root       71: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2   root       72: {
1.1.1.5   root       73:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2   root       74: }
1.1.1.5   root       75: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2   root       76: {
1.1.1.5   root       77:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2   root       78: }
                     79: #endif
                     80: 
1.1.1.12  root       81: uae_u32 chipmem_mask, kickmem_mask, extendedkickmem_mask, bogomem_mask, a3000mem_mask;
1.1       root       82: 
1.1.1.11  root       83: static int illegal_count;
1.1.1.3   root       84: /* A dummy bank that only contains zeros */
                     85: 
1.1.1.4   root       86: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                     87: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                     88: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                     89: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                     90: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                     91: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                     92: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                     93: 
                     94: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                     95: {
1.1.1.8   root       96:     special_mem |= S_READ;
1.1.1.11  root       97:     if (currprefs.illegal_mem) {
                     98:        if (illegal_count < 20) {
                     99:            illegal_count++;
                    100:            write_log ("Illegal lget at %08lx\n", addr);
                    101:        }
                    102:     }
1.1.1.4   root      103: 
1.1.1.9   root      104:     return 0xFFFFFFFF;
1.1       root      105: }
                    106: 
1.1.1.4   root      107: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1       root      108: {
1.1.1.8   root      109:     special_mem |= S_READ;
1.1.1.11  root      110:     if (currprefs.illegal_mem) {
                    111:        if (illegal_count < 20) {
                    112:            illegal_count++;
                    113:            write_log ("Illegal wget at %08lx\n", addr);
                    114:        }
                    115:     }
1.1.1.12  root      116: 
1.1.1.9   root      117:     return 0xFFFF;
1.1       root      118: }
                    119: 
1.1.1.4   root      120: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1       root      121: {
1.1.1.8   root      122:     special_mem |= S_READ;
1.1.1.11  root      123:     if (currprefs.illegal_mem) {
                    124:        if (illegal_count < 20) {
                    125:            illegal_count++;
                    126:            write_log ("Illegal bget at %08lx\n", addr);
                    127:        }
                    128:     }
1.1.1.4   root      129: 
1.1.1.9   root      130:     return 0xFF;
1.1       root      131: }
                    132: 
1.1.1.4   root      133: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1       root      134: {
1.1.1.8   root      135:     special_mem |= S_WRITE;
1.1.1.11  root      136:     if (currprefs.illegal_mem) {
                    137:        if (illegal_count < 20) {
                    138:            illegal_count++;
                    139:            write_log ("Illegal lput at %08lx\n", addr);
                    140:        }
                    141:     }
1.1.1.3   root      142: }
1.1.1.4   root      143: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      144: {
1.1.1.8   root      145:     special_mem |= S_WRITE;
1.1.1.11  root      146:     if (currprefs.illegal_mem) {
                    147:        if (illegal_count < 20) {
                    148:            illegal_count++;
                    149:            write_log ("Illegal wput at %08lx\n", addr);
                    150:        }
                    151:     }
1.1.1.3   root      152: }
1.1.1.4   root      153: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      154: {
1.1.1.8   root      155:     special_mem |= S_WRITE;
1.1.1.11  root      156:     if (currprefs.illegal_mem) {
                    157:        if (illegal_count < 20) {
                    158:            illegal_count++;
                    159:            write_log ("Illegal bput at %08lx\n", addr);
                    160:        }
                    161:     }
1.1       root      162: }
                    163: 
1.1.1.4   root      164: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1       root      165: {
1.1.1.9   root      166:     special_mem |= S_READ;
1.1.1.11  root      167:     if (currprefs.illegal_mem) {
                    168:        if (illegal_count < 20) {
                    169:            illegal_count++;
                    170:            write_log ("Illegal check at %08lx\n", addr);
                    171:        }
                    172:     }
1.1.1.4   root      173: 
1.1       root      174:     return 0;
                    175: }
                    176: 
1.1.1.3   root      177: /* A3000 "motherboard resources" bank.  */
1.1.1.4   root      178: static uae_u32 mbres_lget (uaecptr) REGPARAM;
                    179: static uae_u32 mbres_wget (uaecptr) REGPARAM;
                    180: static uae_u32 mbres_bget (uaecptr) REGPARAM;
                    181: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
                    182: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
                    183: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
                    184: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3   root      185: 
                    186: static int mbres_val = 0;
                    187: 
1.1.1.4   root      188: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3   root      189: {
1.1.1.8   root      190:     special_mem |= S_READ;
1.1.1.4   root      191:     if (currprefs.illegal_mem)
                    192:        write_log ("Illegal lget at %08lx\n", addr);
                    193: 
1.1       root      194:     return 0;
                    195: }
                    196: 
1.1.1.4   root      197: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1       root      198: {
1.1.1.8   root      199:     special_mem |= S_READ;
1.1.1.4   root      200:     if (currprefs.illegal_mem)
                    201:        write_log ("Illegal wget at %08lx\n", addr);
                    202: 
1.1       root      203:     return 0;
                    204: }
                    205: 
1.1.1.4   root      206: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3   root      207: {
1.1.1.8   root      208:     special_mem |= S_READ;
1.1.1.4   root      209:     if (currprefs.illegal_mem)
                    210:        write_log ("Illegal bget at %08lx\n", addr);
                    211: 
1.1.1.3   root      212:     return (addr & 0xFFFF) == 3 ? mbres_val : 0;
                    213: }
                    214: 
1.1.1.4   root      215: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1       root      216: {
1.1.1.8   root      217:     special_mem |= S_WRITE;
1.1.1.4   root      218:     if (currprefs.illegal_mem)
                    219:        write_log ("Illegal lput at %08lx\n", addr);
1.1       root      220: }
1.1.1.4   root      221: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1       root      222: {
1.1.1.8   root      223:     special_mem |= S_WRITE;
1.1.1.4   root      224:     if (currprefs.illegal_mem)
                    225:        write_log ("Illegal wput at %08lx\n", addr);
1.1       root      226: }
1.1.1.4   root      227: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1       root      228: {
1.1.1.8   root      229:     special_mem |= S_WRITE;
1.1.1.4   root      230:     if (currprefs.illegal_mem)
                    231:        write_log ("Illegal bput at %08lx\n", addr);
                    232: 
1.1.1.3   root      233:     if ((addr & 0xFFFF) == 3)
                    234:        mbres_val = b;
1.1       root      235: }
                    236: 
1.1.1.4   root      237: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1       root      238: {
1.1.1.4   root      239:     if (currprefs.illegal_mem)
                    240:        write_log ("Illegal check at %08lx\n", addr);
                    241: 
1.1       root      242:     return 0;
                    243: }
                    244: 
                    245: /* Chip memory */
                    246: 
1.1.1.3   root      247: uae_u8 *chipmemory;
1.1       root      248: 
1.1.1.4   root      249: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    250: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1       root      251: 
1.1.1.4   root      252: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1       root      253: {
1.1.1.3   root      254:     uae_u32 *m;
1.1.1.8   root      255: 
1.1       root      256:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      257:     addr &= chipmem_mask;
1.1.1.3   root      258:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      259:     return do_get_mem_long (m);
1.1       root      260: }
                    261: 
1.1.1.4   root      262: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1       root      263: {
1.1.1.3   root      264:     uae_u16 *m;
1.1.1.8   root      265: 
1.1       root      266:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      267:     addr &= chipmem_mask;
1.1.1.3   root      268:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      269:     return do_get_mem_word (m);
1.1       root      270: }
                    271: 
1.1.1.4   root      272: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1       root      273: {
                    274:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      275:     addr &= chipmem_mask;
1.1       root      276:     return chipmemory[addr];
                    277: }
                    278: 
1.1.1.4   root      279: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1       root      280: {
1.1.1.3   root      281:     uae_u32 *m;
1.1.1.8   root      282: 
1.1       root      283:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      284:     addr &= chipmem_mask;
1.1.1.3   root      285:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      286:     do_put_mem_long (m, l);
1.1       root      287: }
                    288: 
1.1.1.4   root      289: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1       root      290: {
1.1.1.3   root      291:     uae_u16 *m;
1.1.1.8   root      292: 
1.1       root      293:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      294:     addr &= chipmem_mask;
1.1.1.3   root      295:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      296:     do_put_mem_word (m, w);
1.1       root      297: }
                    298: 
1.1.1.4   root      299: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1       root      300: {
                    301:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      302:     addr &= chipmem_mask;
1.1       root      303:     chipmemory[addr] = b;
                    304: }
                    305: 
1.1.1.4   root      306: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1       root      307: {
                    308:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      309:     addr &= chipmem_mask;
1.1.1.4   root      310:     return (addr + size) <= allocated_chipmem;
1.1       root      311: }
                    312: 
1.1.1.4   root      313: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1       root      314: {
                    315:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      316:     addr &= chipmem_mask;
1.1       root      317:     return chipmemory + addr;
                    318: }
                    319: 
                    320: /* Slow memory */
                    321: 
1.1.1.3   root      322: static uae_u8 *bogomemory;
1.1       root      323: 
1.1.1.4   root      324: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
                    325: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
                    326: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
                    327: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
                    328: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
                    329: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
                    330: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    331: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1       root      332: 
1.1.1.4   root      333: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1       root      334: {
1.1.1.3   root      335:     uae_u32 *m;
1.1       root      336:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      337:     addr &= bogomem_mask;
1.1.1.3   root      338:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      339:     return do_get_mem_long (m);
1.1       root      340: }
                    341: 
1.1.1.4   root      342: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1       root      343: {
1.1.1.3   root      344:     uae_u16 *m;
1.1       root      345:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      346:     addr &= bogomem_mask;
1.1.1.3   root      347:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      348:     return do_get_mem_word (m);
1.1       root      349: }
                    350: 
1.1.1.4   root      351: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1       root      352: {
                    353:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      354:     addr &= bogomem_mask;
1.1       root      355:     return bogomemory[addr];
                    356: }
                    357: 
1.1.1.4   root      358: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1       root      359: {
1.1.1.3   root      360:     uae_u32 *m;
1.1       root      361:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      362:     addr &= bogomem_mask;
1.1.1.3   root      363:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      364:     do_put_mem_long (m, l);
1.1       root      365: }
                    366: 
1.1.1.4   root      367: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1       root      368: {
1.1.1.3   root      369:     uae_u16 *m;
1.1       root      370:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      371:     addr &= bogomem_mask;
1.1.1.3   root      372:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      373:     do_put_mem_word (m, w);
1.1       root      374: }
                    375: 
1.1.1.4   root      376: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1       root      377: {
                    378:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      379:     addr &= bogomem_mask;
1.1       root      380:     bogomemory[addr] = b;
                    381: }
                    382: 
1.1.1.4   root      383: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1       root      384: {
1.1.1.2   root      385:     addr -= bogomem_start & bogomem_mask;
                    386:     addr &= bogomem_mask;
1.1.1.4   root      387:     return (addr + size) <= allocated_bogomem;
1.1       root      388: }
                    389: 
1.1.1.4   root      390: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1       root      391: {
1.1.1.2   root      392:     addr -= bogomem_start & bogomem_mask;
                    393:     addr &= bogomem_mask;
1.1       root      394:     return bogomemory + addr;
                    395: }
                    396: 
1.1.1.3   root      397: /* A3000 motherboard fast memory */
                    398: 
                    399: static uae_u8 *a3000memory;
1.1       root      400: 
1.1.1.4   root      401: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
                    402: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
                    403: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
                    404: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
                    405: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
                    406: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
                    407: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    408: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      409: 
1.1.1.4   root      410: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3   root      411: {
                    412:     uae_u32 *m;
                    413:     addr -= a3000mem_start & a3000mem_mask;
                    414:     addr &= a3000mem_mask;
                    415:     m = (uae_u32 *)(a3000memory + addr);
1.1.1.5   root      416:     return do_get_mem_long (m);
1.1.1.3   root      417: }
1.1       root      418: 
1.1.1.4   root      419: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3   root      420: {
                    421:     uae_u16 *m;
                    422:     addr -= a3000mem_start & a3000mem_mask;
                    423:     addr &= a3000mem_mask;
                    424:     m = (uae_u16 *)(a3000memory + addr);
1.1.1.5   root      425:     return do_get_mem_word (m);
1.1.1.3   root      426: }
1.1       root      427: 
1.1.1.4   root      428: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1       root      429: {
1.1.1.3   root      430:     addr -= a3000mem_start & a3000mem_mask;
                    431:     addr &= a3000mem_mask;
                    432:     return a3000memory[addr];
1.1       root      433: }
                    434: 
1.1.1.4   root      435: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1       root      436: {
1.1.1.3   root      437:     uae_u32 *m;
                    438:     addr -= a3000mem_start & a3000mem_mask;
                    439:     addr &= a3000mem_mask;
                    440:     m = (uae_u32 *)(a3000memory + addr);
1.1.1.5   root      441:     do_put_mem_long (m, l);
1.1.1.3   root      442: }
                    443: 
1.1.1.4   root      444: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      445: {
                    446:     uae_u16 *m;
                    447:     addr -= a3000mem_start & a3000mem_mask;
                    448:     addr &= a3000mem_mask;
                    449:     m = (uae_u16 *)(a3000memory + addr);
1.1.1.5   root      450:     do_put_mem_word (m, w);
1.1.1.3   root      451: }
                    452: 
1.1.1.4   root      453: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      454: {
                    455:     addr -= a3000mem_start & a3000mem_mask;
                    456:     addr &= a3000mem_mask;
                    457:     a3000memory[addr] = b;
                    458: }
                    459: 
1.1.1.4   root      460: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3   root      461: {
                    462:     addr -= a3000mem_start & a3000mem_mask;
                    463:     addr &= a3000mem_mask;
1.1.1.4   root      464:     return (addr + size) <= allocated_a3000mem;
1.1       root      465: }
                    466: 
1.1.1.12  root      467: uae_u8 REGPARAM2 *a3000mem_xlate (uaecptr addr)
1.1.1.3   root      468: {
                    469:     addr -= a3000mem_start & a3000mem_mask;
                    470:     addr &= a3000mem_mask;
                    471:     return a3000memory + addr;
                    472: }
                    473: 
                    474: /* Kick memory */
                    475: 
                    476: uae_u8 *kickmemory;
                    477: 
1.1.1.12  root      478: /*
                    479:  * A1000 kickstart RAM handling
                    480:  *
                    481:  * RESET instruction unhides boot ROM and disables write protection
                    482:  * write access to boot ROM hides boot ROM and enables write protection
                    483:  *
                    484:  */
                    485: static int a1000_kickstart_mode;
                    486: static uae_u8 *a1000_bootrom;
                    487: static void a1000_handle_kickstart (int mode)
                    488: {
                    489:     if (mode == 0) {
                    490:        a1000_kickstart_mode = 0;
                    491:        memcpy (kickmemory, kickmemory + 262144, 262144);
                    492:     } else {
                    493:        a1000_kickstart_mode = 1;
                    494:        memset (kickmemory, 0, 262144);
                    495:        memcpy (kickmemory, a1000_bootrom, 8192);
                    496:        memcpy (kickmemory + 131072, a1000_bootrom, 8192);
                    497:     }
                    498: }
                    499: 
1.1.1.4   root      500: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
                    501: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
                    502: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
1.1.1.12  root      503: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
                    504: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
                    505: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
                    506: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.4   root      507: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      508: 
1.1.1.4   root      509: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1       root      510: {
1.1.1.3   root      511:     uae_u32 *m;
1.1       root      512:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      513:     addr &= kickmem_mask;
1.1.1.3   root      514:     m = (uae_u32 *)(kickmemory + addr);
1.1.1.5   root      515:     return do_get_mem_long (m);
1.1       root      516: }
                    517: 
1.1.1.4   root      518: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1       root      519: {
1.1.1.3   root      520:     uae_u16 *m;
1.1       root      521:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      522:     addr &= kickmem_mask;
1.1.1.3   root      523:     m = (uae_u16 *)(kickmemory + addr);
1.1.1.5   root      524:     return do_get_mem_word (m);
1.1       root      525: }
                    526: 
1.1.1.4   root      527: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1       root      528: {
                    529:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      530:     addr &= kickmem_mask;
1.1       root      531:     return kickmemory[addr];
                    532: }
                    533: 
1.1.1.4   root      534: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1       root      535: {
1.1.1.12  root      536:     uae_u32 *m;
                    537:     if (a1000_kickstart_mode) {
                    538:        if (addr >= 0xfc0000) {
                    539:            addr -= kickmem_start & kickmem_mask;
                    540:            addr &= kickmem_mask;
                    541:            m = (uae_u32 *)(kickmemory + addr);
                    542:            do_put_mem_long (m, b);
                    543:            return;
                    544:        } else
                    545:            a1000_handle_kickstart (0);
                    546:     } else if (currprefs.illegal_mem)
1.1.1.4   root      547:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      548: }
                    549: 
1.1.1.4   root      550: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1       root      551: {
1.1.1.12  root      552:     uae_u16 *m;
                    553:     if (a1000_kickstart_mode) {
                    554:        if (addr >= 0xfc0000) {
                    555:            addr -= kickmem_start & kickmem_mask;
                    556:            addr &= kickmem_mask;
                    557:            m = (uae_u16 *)(kickmemory + addr);
                    558:            do_put_mem_word (m, b);
                    559:            return;
                    560:        } else
                    561:            a1000_handle_kickstart (0);
                    562:     } else if (currprefs.illegal_mem)
1.1.1.4   root      563:        write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1       root      564: }
                    565: 
1.1.1.4   root      566: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1       root      567: {
1.1.1.12  root      568:     if (a1000_kickstart_mode) {
                    569:        if (addr >= 0xfc0000) {
                    570:            addr -= kickmem_start & kickmem_mask;
                    571:            addr &= kickmem_mask;
                    572:            kickmemory[addr] = b;
                    573:            return;
                    574:        } else
                    575:            a1000_handle_kickstart (0);
                    576:     } else if (currprefs.illegal_mem)
1.1.1.4   root      577:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      578: }
                    579: 
1.1.1.4   root      580: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1       root      581: {
1.1.1.2   root      582:     addr -= kickmem_start & kickmem_mask;
                    583:     addr &= kickmem_mask;
1.1.1.4   root      584:     return (addr + size) <= kickmem_size;
1.1       root      585: }
                    586: 
1.1.1.4   root      587: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1       root      588: {
1.1.1.2   root      589:     addr -= kickmem_start & kickmem_mask;
                    590:     addr &= kickmem_mask;
1.1       root      591:     return kickmemory + addr;
                    592: }
                    593: 
1.1.1.12  root      594: /* CD32/CDTV extended kick memory */
1.1.1.3   root      595: 
1.1.1.12  root      596: uae_u8 *extendedkickmemory;
                    597: static int extendedkickmem_size;
                    598: static uae_u32 extendedkickmem_start;
                    599: 
                    600: #define EXTENDED_ROM_CD32 1
                    601: #define EXTENDED_ROM_CDTV 2
                    602: 
                    603: static int extromtype (void)
                    604: {
                    605:     switch (extendedkickmem_size) {
                    606:     case 524288:
                    607:        return EXTENDED_ROM_CD32;
                    608:     case 262144:
                    609:        return EXTENDED_ROM_CDTV;
                    610:     }
1.1.1.3   root      611:     return 0;
                    612: }
                    613: 
1.1.1.12  root      614: static uae_u32 extendedkickmem_lget (uaecptr) REGPARAM;
                    615: static uae_u32 extendedkickmem_wget (uaecptr) REGPARAM;
                    616: static uae_u32 extendedkickmem_bget (uaecptr) REGPARAM;
                    617: static void extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
                    618: static void extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
                    619: static void extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
                    620: static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    621: static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM;
                    622: 
                    623: uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr)
1.1.1.3   root      624: {
1.1.1.12  root      625:     uae_u32 *m;
                    626:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    627:     addr &= extendedkickmem_mask;
                    628:     m = (uae_u32 *)(extendedkickmemory + addr);
                    629:     return do_get_mem_long (m);
1.1.1.3   root      630: }
                    631: 
1.1.1.12  root      632: uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr)
1.1       root      633: {
1.1.1.12  root      634:     uae_u16 *m;
                    635:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    636:     addr &= extendedkickmem_mask;
                    637:     m = (uae_u16 *)(extendedkickmemory + addr);
                    638:     return do_get_mem_word (m);
                    639: }
1.1.1.3   root      640: 
1.1.1.12  root      641: uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr)
                    642: {
                    643:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    644:     addr &= extendedkickmem_mask;
                    645:     return extendedkickmemory[addr];
                    646: }
1.1.1.3   root      647: 
1.1.1.12  root      648: void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
                    649: {
                    650:     if (currprefs.illegal_mem)
                    651:        write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
                    652: }
1.1.1.3   root      653: 
1.1.1.12  root      654: void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
                    655: {
                    656:     if (currprefs.illegal_mem)
                    657:        write_log ("Illegal extendedkickmem wput at %08lx\n", addr);
                    658: }
1.1.1.3   root      659: 
1.1.1.12  root      660: void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
                    661: {
                    662:     if (currprefs.illegal_mem)
                    663:        write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
                    664: }
1.1.1.3   root      665: 
1.1.1.12  root      666: int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size)
                    667: {
                    668:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    669:     addr &= extendedkickmem_mask;
                    670:     return (addr + size) <= extendedkickmem_size;
                    671: }
1.1.1.3   root      672: 
1.1.1.12  root      673: uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr)
                    674: {
                    675:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    676:     addr &= extendedkickmem_mask;
                    677:     return extendedkickmemory + addr;
                    678: }
1.1.1.2   root      679: 
1.1.1.12  root      680: /* Default memory access functions */
                    681: 
                    682: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
                    683: {
                    684:     return 0;
                    685: }
                    686: 
                    687: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
                    688: {
                    689:     write_log ("Your Amiga program just did something terribly stupid\n");
                    690:     uae_reset ();
                    691:     return kickmem_xlate (get_long (0xF80000));        /* So we don't crash. */
1.1       root      692: }
                    693: 
                    694: /* Address banks */
                    695: 
                    696: addrbank dummy_bank = {
                    697:     dummy_lget, dummy_wget, dummy_bget,
                    698:     dummy_lput, dummy_wput, dummy_bput,
1.1.1.9   root      699:     default_xlate, dummy_check, NULL
1.1       root      700: };
                    701: 
1.1.1.3   root      702: addrbank mbres_bank = {
                    703:     mbres_lget, mbres_wget, mbres_bget,
                    704:     mbres_lput, mbres_wput, mbres_bput,
1.1.1.9   root      705:     default_xlate, mbres_check, NULL
1.1.1.3   root      706: };
                    707: 
1.1       root      708: addrbank chipmem_bank = {
                    709:     chipmem_lget, chipmem_wget, chipmem_bget,
                    710:     chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.9   root      711:     chipmem_xlate, chipmem_check, NULL
1.1       root      712: };
                    713: 
                    714: addrbank bogomem_bank = {
                    715:     bogomem_lget, bogomem_wget, bogomem_bget,
                    716:     bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.9   root      717:     bogomem_xlate, bogomem_check, NULL
1.1       root      718: };
                    719: 
1.1.1.3   root      720: addrbank a3000mem_bank = {
                    721:     a3000mem_lget, a3000mem_wget, a3000mem_bget,
                    722:     a3000mem_lput, a3000mem_wput, a3000mem_bput,
1.1.1.9   root      723:     a3000mem_xlate, a3000mem_check, NULL
1.1.1.3   root      724: };
                    725: 
1.1       root      726: addrbank kickmem_bank = {
                    727:     kickmem_lget, kickmem_wget, kickmem_bget,
                    728:     kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.9   root      729:     kickmem_xlate, kickmem_check, NULL
1.1       root      730: };
                    731: 
1.1.1.12  root      732: addrbank extendedkickmem_bank = {
                    733:     extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
                    734:     extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
                    735:     extendedkickmem_xlate, extendedkickmem_check, NULL
                    736: };
                    737: 
                    738: static int decode_cloanto_rom (uae_u8 *mem, int size, int real_size)
                    739: {
                    740:     FILE *keyf;
                    741:     uae_u8 *p;
                    742:     long cnt, t;
                    743:     int keysize;
                    744: 
                    745:     if (strlen (currprefs.keyfile) == 0) {
                    746:        write_log ("No filename given for ROM key file and ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
                    747:        return 0;
                    748:     }
                    749:     keyf = zfile_open (currprefs.keyfile, "rb");
                    750:     if (keyf == 0) {
                    751:        write_log ("Could not find specified ROM key-file.\n");
                    752:        return 0;
                    753:     }
                    754: 
                    755:     p = (uae_u8 *) xmalloc (524288);
                    756:     keysize = fread (p, 1, 524288, keyf);
                    757:     for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize) {
                    758:        mem[cnt] ^= p[t];
                    759:        if (real_size == cnt + 1)
                    760:            t = keysize - 1;
                    761:     }
                    762:     fclose (keyf);
                    763:     free (p);
                    764:     return 1;
                    765: }
                    766: 
                    767: static int kickstart_checksum (uae_u8 *mem, int size)
                    768: {
                    769:     uae_u32 cksum = 0, prevck = 0;
                    770:     int i;
                    771:     for (i = 0; i < size; i += 4) {
                    772:        uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
                    773:        cksum += data;
                    774:        if (cksum < prevck)
                    775:            cksum++;
                    776:        prevck = cksum;
                    777:     }
                    778:     if (cksum != 0xFFFFFFFFul) {
                    779:        write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
                    780:     }
                    781:     return 0;
                    782: }
                    783: 
                    784: static int read_kickstart (FILE *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom)
                    785: {
                    786:     unsigned char buffer[20];
                    787:     int i, cr = 0;
                    788: 
                    789:     if (cloanto_rom)
                    790:        *cloanto_rom = 0;
                    791:     i = fread (buffer, 1, 11, f);
                    792:     if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) {
                    793:        fseek (f, 0, SEEK_SET);
                    794:     } else {
                    795:        cr = 1;
                    796:     }
                    797: 
                    798:     i = fread (mem, 1, size, f);
                    799:     if (i == 8192) {
                    800:        a1000_bootrom = malloc (8192);
                    801:        memcpy (a1000_bootrom, kickmemory, 8192);
                    802:        a1000_handle_kickstart (1);
                    803:     } else if (i == size / 2) {
                    804:        memcpy (mem + size / 2, mem, i);
                    805:     } else if (i != size) {
                    806:        write_log ("Error while reading Kickstart.\n");
                    807:        zfile_close (f);
                    808:        return 0;
                    809:     }
                    810:     zfile_close (f);
                    811: 
                    812:     if (cr)
                    813:        decode_cloanto_rom (mem, size, i);
                    814:     if (dochecksum && i >= 262144)
                    815:        kickstart_checksum (mem, size);
                    816:     if (cloanto_rom)
                    817:        *cloanto_rom = cr;
                    818:     return 1;
                    819: }
                    820: 
                    821: static int load_extendedkickstart (void)
                    822: {
                    823:     FILE *f;
                    824:     int size;
                    825: 
                    826:     if (strlen (currprefs.romextfile) == 0)
                    827:        return 0;
                    828:     f = zfile_open (currprefs.romextfile, "rb");
                    829:     if (!f) {
                    830:        write_log ("No extended Kickstart ROM found");
                    831:        return 0;
                    832:     }
                    833: 
                    834:     fseek (f, 0, SEEK_END);
                    835:     size = ftell (f);
                    836:     if (size > 300000)
                    837:        extendedkickmem_size = 524288;
                    838:     else
                    839:        extendedkickmem_size = 262144;
                    840:     fseek (f, 0, SEEK_SET);
                    841: 
                    842:     switch (extromtype ()) {
                    843:     case EXTENDED_ROM_CDTV:
                    844:        extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_f0");
                    845:        extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
                    846:        break;
                    847:     case EXTENDED_ROM_CD32:
                    848:        extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
                    849:        extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
                    850:        break;
                    851:     }
                    852:     read_kickstart (f, extendedkickmemory, 524288, 0, 0);
                    853:     fclose (f);
                    854:     return 1;
                    855: }
                    856: 
                    857: 
                    858: static int load_kickstart (void)
                    859: {
                    860:     FILE *f = zfile_open (currprefs.romfile, "rb");
                    861: 
                    862:     if (f == NULL) {
                    863: #if defined(AMIGA)||defined(__POS__)
                    864: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
                    865:        if (!getenv (USE_UAE_ERSATZ)) {
                    866:            write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
                    867:            memcpy (kickmemory, (char *) 0x1000000 - kickmem_size, kickmem_size);
                    868:            kickstart_checksum (kickmemory, kickmem_size);
                    869:            goto chk_sum;
                    870:        }
                    871: #endif
                    872:        return 0;
                    873:     }
                    874: 
                    875:     if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom))
                    876:        return 0;
                    877: 
                    878: #if defined(AMIGA)
                    879:   chk_sum:
                    880: #endif
                    881: 
                    882:     if (currprefs.kickshifter) {
                    883:        /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
                    884:           Changes 'lea $400,a0' to 'lea $2000,a0' for ShapeShifter compatability.
                    885:           NOTE: lea is 0x41f8, so we should do this better with a search for
                    886:           0x41f80400 --> 0x41f82000
                    887:        */
                    888:        if (kickmemory[0x24a] == 0x04 && kickmemory[0x24b] == 0x00) {   /* Kick 3.0 */
                    889:            kickmemory[0x24a] = 0x20;
                    890:            kickmemory[0x7ffea] -= 0x1c;
                    891:            write_log ("Kickstart KickShifted\n");
                    892:        } else if (kickmemory[0x26e] == 0x04 && kickmemory[0x26f] == 0x00) {    /* Kick 3.1 */
                    893:            kickmemory[0x26e] = 0x20;
                    894:            kickmemory[0x7ffea] -= 0x1c;
                    895:            write_log ("Kickstart KickShifted\n");
                    896:        } else if (kickmemory[0x24e] == 0x04 && kickmemory[0x24f] == 0x00) {    /* Kick 2.04 */
                    897:            kickmemory[0x24e] = 0x20;
                    898:            kickmemory[0x7ffea] -= 0x1c;
                    899:            write_log ("Kickstart KickShifted\n");
                    900:        }
                    901:     }
                    902:     return 1;
                    903: }
                    904: 
1.1       root      905: char *address_space, *good_address_map;
                    906: int good_address_fd;
1.1.1.4   root      907: 
1.1.1.9   root      908: #ifndef NATMEM_OFFSET
                    909: 
1.1.1.12  root      910: uae_u8 *mapped_malloc (size_t s, char *file)
1.1.1.4   root      911: {
1.1.1.13! root      912:     return calloc (s, 1);
1.1.1.4   root      913: }
                    914: 
1.1.1.9   root      915: void mapped_free (uae_u8 *p)
1.1       root      916: {
1.1.1.9   root      917:     free (p);
                    918: }
                    919: #else
1.1.1.3   root      920: 
1.1.1.9   root      921: #include <sys/ipc.h>
                    922: #include <sys/shm.h>
                    923: #include <unistd.h>
                    924: #include <sys/mman.h>
                    925: 
1.1.1.12  root      926: shmpiece *shm_start = NULL;
                    927: int canbang = 1;
1.1.1.9   root      928: 
1.1.1.12  root      929: static void dumplist (void)
1.1.1.9   root      930: {
1.1.1.12  root      931:     shmpiece *x = shm_start;
1.1.1.9   root      932:     printf ("Start Dump:\n");
                    933:     while (x) {
                    934:        printf ("  this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
1.1.1.12  root      935:                x, x->native_address, x->id, x->prev, x->next, x->size);
1.1.1.9   root      936:        x = x->next;
1.1.1.2   root      937:     }
1.1.1.9   root      938:     printf ("End Dump:\n");
                    939: }
1.1       root      940: 
1.1.1.9   root      941: static shmpiece *find_shmpiece (uae_u8 *base)
                    942: {
                    943:     shmpiece *x = shm_start;
1.1       root      944: 
1.1.1.9   root      945:     while (x && x->native_address != base)
                    946:        x = x->next;
                    947:     if (!x) {
1.1.1.12  root      948:        printf ("NATMEM: Failure to find mapping at %p\n", base);
                    949:        dumplist ();
1.1.1.9   root      950:        canbang = 0;
                    951:        return 0;
                    952:     }
                    953:     return x;
                    954: }
1.1.1.3   root      955: 
1.1.1.9   root      956: static void delete_shmmaps (uae_u32 start, uae_u32 size)
                    957: {
                    958:     if (!canbang)
                    959:        return;
                    960: 
                    961:     while (size) {
1.1.1.12  root      962:        uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1.1.1.9   root      963:        if (base) {
                    964:            shmpiece *x;
1.1.1.12  root      965:            base = ((uae_u8 *) NATMEM_OFFSET) + start;
1.1.1.9   root      966: 
                    967:            x = find_shmpiece (base);
1.1.1.12  root      968:            if (!x)
1.1.1.9   root      969:                return;
                    970: 
                    971:            if (x->size > size) {
1.1.1.12  root      972:                printf ("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n", start, x->size, size);
                    973:                dumplist ();
1.1.1.9   root      974:                canbang = 0;
                    975:                return;
                    976:            }
                    977:            shmdt (x->native_address);
                    978:            size -= x->size;
                    979:            start += x->size;
                    980:            if (x->next)
1.1.1.12  root      981:                x->next->prev = x->prev;        /* remove this one from the list */
1.1.1.9   root      982:            if (x->prev)
                    983:                x->prev->next = x->next;
                    984:            else
                    985:                shm_start = x->next;
1.1.1.12  root      986:            free (x);
1.1.1.9   root      987:        } else {
                    988:            size -= 0x10000;
                    989:            start += 0x10000;
                    990:        }
1.1.1.3   root      991:     }
1.1.1.9   root      992: }
1.1.1.12  root      993: 
1.1.1.9   root      994: static void add_shmmaps (uae_u32 start, addrbank *what)
                    995: {
                    996:     shmpiece *x = shm_start;
                    997:     shmpiece *y;
                    998:     uae_u8 *base = what->baseaddr;
                    999: 
                   1000:     if (!canbang)
                   1001:        return;
                   1002:     if (!base)
                   1003:        return;
                   1004: 
                   1005:     x = find_shmpiece (base);
1.1.1.12  root     1006:     if (!x)
1.1.1.9   root     1007:        return;
                   1008:     y = malloc (sizeof (shmpiece));
                   1009:     *y = *x;
1.1.1.12  root     1010:     base = ((uae_u8 *) NATMEM_OFFSET) + start;
                   1011:     y->native_address = shmat (y->id, base, 0);
                   1012:     if (y->native_address == (void *) -1) {
                   1013:        printf ("NATMEM: Failure to map existing at %08x(%p)\n", start, base);
                   1014:        perror ("shmat");
                   1015:        dumplist ();
1.1.1.9   root     1016:        canbang = 0;
                   1017:        return;
1.1.1.2   root     1018:     }
1.1.1.9   root     1019:     y->next = shm_start;
                   1020:     y->prev = NULL;
                   1021:     if (y->next)
                   1022:        y->next->prev = y;
                   1023:     shm_start = y;
                   1024: }
                   1025: 
                   1026: uae_u8 *mapped_malloc (size_t s, char *file)
                   1027: {
1.1.1.12  root     1028:     int id;
1.1.1.9   root     1029:     void *answer;
                   1030:     shmpiece *x;
                   1031: 
1.1.1.12  root     1032:     if (!canbang)
1.1.1.9   root     1033:        return malloc (s);
                   1034: 
1.1.1.12  root     1035:     id = shmget (IPC_PRIVATE, s, 0x1ff, file);
1.1.1.9   root     1036:     if (id == 1) {
                   1037:        canbang = 0;
                   1038:        return mapped_malloc (s, file);
                   1039:     }
1.1.1.12  root     1040:     answer = shmat (id, 0, 0);
                   1041:     shmctl (id, IPC_RMID, NULL);
                   1042:     if (answer != (void *) -1) {
                   1043:        x = malloc (sizeof (shmpiece));
1.1.1.9   root     1044:        x->native_address = answer;
                   1045:        x->id = id;
                   1046:        x->size = s;
                   1047:        x->next = shm_start;
                   1048:        x->prev = NULL;
                   1049:        if (x->next)
                   1050:            x->next->prev = x;
                   1051:        shm_start = x;
                   1052: 
                   1053:        return answer;
                   1054:     }
                   1055:     canbang = 0;
                   1056:     return mapped_malloc (s, file);
                   1057: }
                   1058: 
1.1.1.10  root     1059: void mapped_free (uae_u8 *base)
1.1.1.9   root     1060: {
                   1061:     shmpiece *x = find_shmpiece (base);
1.1.1.12  root     1062:     if (!x)
1.1.1.9   root     1063:        abort ();
                   1064:     shmdt (x->native_address);
                   1065: }
                   1066: 
1.1       root     1067: #endif
1.1.1.6   root     1068: 
1.1.1.9   root     1069: static void init_mem_banks (void)
                   1070: {
                   1071:     int i;
                   1072:     for (i = 0; i < 65536; i++)
                   1073:        put_mem_bank (i << 16, &dummy_bank, 0);
                   1074: }
                   1075: 
                   1076: static void allocate_memory (void)
                   1077: {
                   1078:     if (allocated_chipmem != currprefs.chipmem_size) {
                   1079:        if (chipmemory)
                   1080:            mapped_free (chipmemory);
                   1081:        chipmemory = 0;
                   1082: 
                   1083:        allocated_chipmem = currprefs.chipmem_size;
                   1084:        chipmem_mask = allocated_chipmem - 1;
                   1085: 
                   1086:        chipmemory = mapped_malloc (allocated_chipmem, "chip");
                   1087:        if (chipmemory == 0) {
                   1088:            write_log ("Fatal error: out of memory for chipmem.\n");
                   1089:            allocated_chipmem = 0;
                   1090:        } else
                   1091:            do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
                   1092:     }
                   1093: 
                   1094:     if (allocated_bogomem != currprefs.bogomem_size) {
                   1095:        if (bogomemory)
                   1096:            mapped_free (bogomemory);
                   1097:        bogomemory = 0;
                   1098: 
                   1099:        allocated_bogomem = currprefs.bogomem_size;
                   1100:        bogomem_mask = allocated_bogomem - 1;
                   1101: 
                   1102:        if (allocated_bogomem) {
                   1103:            bogomemory = mapped_malloc (allocated_bogomem, "bogo");
                   1104:            if (bogomemory == 0) {
                   1105:                write_log ("Out of memory for bogomem.\n");
                   1106:                allocated_bogomem = 0;
                   1107:            }
                   1108:        }
                   1109:     }
                   1110:     if (allocated_a3000mem != currprefs.a3000mem_size) {
                   1111:        if (a3000memory)
                   1112:            mapped_free (a3000memory);
                   1113:        a3000memory = 0;
                   1114: 
                   1115:        allocated_a3000mem = currprefs.a3000mem_size;
                   1116:        a3000mem_mask = allocated_a3000mem - 1;
                   1117: 
                   1118:        if (allocated_a3000mem) {
                   1119:            a3000memory = mapped_malloc (allocated_a3000mem, "a3000");
                   1120:            if (a3000memory == 0) {
                   1121:                write_log ("Out of memory for a3000mem.\n");
                   1122:                allocated_a3000mem = 0;
                   1123:            }
                   1124:        }
                   1125:     }
                   1126: 
                   1127:     if (savestate_state == STATE_RESTORE) {
                   1128:        fseek (savestate_file, chip_filepos, SEEK_SET);
                   1129:        fread (chipmemory, 1, allocated_chipmem, savestate_file);
                   1130:        if (allocated_bogomem > 0) {
                   1131:            fseek (savestate_file, bogo_filepos, SEEK_SET);
                   1132:            fread (bogomemory, 1, allocated_bogomem, savestate_file);
                   1133:        }
                   1134:     }
                   1135:     chipmem_bank.baseaddr = chipmemory;
                   1136:     bogomem_bank.baseaddr = bogomemory;
                   1137: }
                   1138: 
                   1139: void memory_reset (void)
                   1140: {
                   1141:     int i, custom_start;
                   1142: 
                   1143: #ifdef NATMEM_OFFSET
                   1144:     delete_shmmaps (0, 0xFFFF0000);
                   1145: #endif
1.1.1.4   root     1146:     init_mem_banks ();
1.1.1.3   root     1147: 
1.1.1.9   root     1148:     currprefs.chipmem_size = changed_prefs.chipmem_size;
                   1149:     currprefs.bogomem_size = changed_prefs.bogomem_size;
                   1150:     currprefs.a3000mem_size = changed_prefs.a3000mem_size;
                   1151: 
                   1152:     allocate_memory ();
                   1153: 
1.1.1.12  root     1154:     if (strcmp (currprefs.romfile, changed_prefs.romfile) != 0 || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0) {
1.1.1.10  root     1155:        ersatzkickfile = 0;
                   1156:        memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
                   1157:        memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
                   1158:        /* Clear out whatever data remains across a reset.  */
                   1159:        memset (chipmemory, 0, allocated_chipmem);
1.1.1.12  root     1160:        if (!load_kickstart ()) {
1.1.1.10  root     1161:            init_ersatz_rom (kickmemory);
                   1162:            ersatzkickfile = 1;
                   1163:        }
1.1.1.12  root     1164:     }
1.1.1.9   root     1165:     /* Map the chipmem into all of the lower 8MB */
                   1166:     i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
                   1167:     map_banks (&chipmem_bank, 0x00, i, allocated_chipmem);
                   1168: 
1.1.1.3   root     1169:     custom_start = 0xC0;
1.1       root     1170: 
1.1.1.9   root     1171:     map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0);
                   1172:     map_banks (&cia_bank, 0xA0, 32, 0);
                   1173:     map_banks (&clock_bank, 0xDC, 1, 0);
1.1.1.3   root     1174: 
                   1175:     /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
                   1176:      * range on an Amiga without expansion memory?  */
1.1.1.4   root     1177:     custom_start = allocated_chipmem >> 16;
1.1.1.3   root     1178:     if (custom_start < 0x20)
                   1179:        custom_start = 0x20;
1.1.1.9   root     1180:     map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
1.1.1.12  root     1181:     /*map_banks (&mbres_bank, 0xDE, 1); */
1.1.1.3   root     1182: 
1.1.1.9   root     1183:     if (bogomemory != 0) {
                   1184:        int t = allocated_bogomem >> 16;
                   1185:        if (t > 0x1C)
                   1186:            t = 0x1C;
                   1187:        map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
                   1188:     }
1.1.1.4   root     1189:     if (a3000memory != 0)
1.1.1.12  root     1190:        map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16, allocated_a3000mem);
1.1.1.9   root     1191: 
1.1.1.11  root     1192:     map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
1.1.1.9   root     1193: 
                   1194:     map_banks (&kickmem_bank, 0xF8, 8, 0);
1.1.1.12  root     1195:     if (a1000_bootrom)
                   1196:        a1000_handle_kickstart (1);
1.1.1.9   root     1197:     map_banks (&expamem_bank, 0xE8, 1, 0);
                   1198: 
1.1.1.12  root     1199:     switch (extromtype ()) {
                   1200:     case EXTENDED_ROM_CDTV:
                   1201:        map_banks (&extendedkickmem_bank, 0xF0, 4, 0);
                   1202:        break;
                   1203:     case EXTENDED_ROM_CD32:
                   1204:        map_banks (&extendedkickmem_bank, 0xE0, 8, 0);
                   1205:        break;
                   1206:     default:
                   1207:        if (cloanto_rom)
                   1208:            map_banks (&kickmem_bank, 0xE0, 8, 0);
                   1209:     }
1.1.1.9   root     1210: }
                   1211: 
                   1212: void memory_init (void)
                   1213: {
                   1214:     allocated_chipmem = 0;
                   1215:     allocated_bogomem = 0;
                   1216:     allocated_a3000mem = 0;
                   1217:     kickmemory = 0;
1.1.1.12  root     1218:     extendedkickmemory = 0;
1.1.1.9   root     1219:     chipmemory = 0;
                   1220:     a3000memory = 0;
                   1221:     bogomemory = 0;
                   1222: 
                   1223:     kickmemory = mapped_malloc (kickmem_size, "kick");
                   1224:     kickmem_bank.baseaddr = kickmemory;
1.1.1.3   root     1225: 
1.1.1.12  root     1226:     load_extendedkickstart ();
                   1227:     if (!load_kickstart ()) {
1.1.1.3   root     1228:        init_ersatz_rom (kickmemory);
1.1       root     1229:        ersatzkickfile = 1;
                   1230:     }
1.1.1.3   root     1231: 
1.1.1.9   root     1232:     init_mem_banks ();
                   1233:     memory_reset ();
1.1.1.4   root     1234: 
                   1235:     kickmem_mask = kickmem_size - 1;
1.1.1.12  root     1236:     extendedkickmem_mask = extendedkickmem_size - 1;
1.1       root     1237: }
                   1238: 
1.1.1.12  root     1239: void memory_cleanup (void)
1.1.1.10  root     1240: {
                   1241:     if (a3000memory)
                   1242:        mapped_free (a3000memory);
                   1243:     if (bogomemory)
                   1244:        mapped_free (bogomemory);
                   1245:     if (kickmemory)
                   1246:        mapped_free (kickmemory);
1.1.1.12  root     1247:     if (a1000_bootrom)
                   1248:        free (a1000_bootrom);
1.1.1.10  root     1249:     if (chipmemory)
                   1250:        mapped_free (chipmemory);
1.1.1.12  root     1251: 
1.1.1.10  root     1252:     a3000memory = 0;
                   1253:     bogomemory = 0;
                   1254:     kickmemory = 0;
1.1.1.12  root     1255:     a1000_bootrom = 0;
1.1.1.10  root     1256:     chipmemory = 0;
                   1257: }
                   1258: 
1.1.1.9   root     1259: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1       root     1260: {
                   1261:     int bnr;
1.1.1.3   root     1262:     unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.12  root     1263:     addrbank *orgbank = bank;
1.1.1.9   root     1264:     uae_u32 realstart = start;
1.1.1.12  root     1265: 
                   1266:     flush_icache (1);          /* Sure don't want to keep any old mappings around! */
1.1.1.9   root     1267: #ifdef NATMEM_OFFSET
                   1268:     delete_shmmaps (start << 16, size << 16);
                   1269: #endif
1.1.1.12  root     1270: 
1.1.1.9   root     1271:     if (!realsize)
                   1272:        realsize = size << 16;
                   1273: 
                   1274:     if ((size << 16) < realsize) {
1.1.1.11  root     1275:        write_log ("Please report to [email protected], and mention:\n");
1.1.1.12  root     1276:        write_log ("Broken mapping, size=%x, realsize=%x\n", size, realsize);
                   1277:        write_log ("Start is %x\n", start);
1.1.1.11  root     1278:        write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9   root     1279:        abort ();
                   1280:     }
1.1.1.3   root     1281: 
                   1282:     if (start >= 0x100) {
1.1.1.10  root     1283:        int real_left = 0;
1.1.1.9   root     1284:        for (bnr = start; bnr < start + size; bnr++) {
                   1285:            if (!real_left) {
                   1286:                realstart = bnr;
1.1.1.12  root     1287:                real_left = realsize >> 16;
1.1.1.9   root     1288: #ifdef NATMEM_OFFSET
                   1289:                add_shmmaps (realstart << 16, bank);
                   1290: #endif
                   1291:            }
1.1.1.12  root     1292:            put_mem_bank (bnr << 16, bank, realstart << 16);
1.1.1.9   root     1293:            real_left--;
                   1294:        }
1.1.1.3   root     1295:        return;
                   1296:     }
1.1.1.10  root     1297:     if (currprefs.address_space_24)
                   1298:        endhioffs = 0x10000;
1.1.1.9   root     1299:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10  root     1300:        int real_left = 0;
1.1.1.12  root     1301:        for (bnr = start; bnr < start + size; bnr++) {
1.1.1.9   root     1302:            if (!real_left) {
                   1303:                realstart = bnr + hioffs;
                   1304:                real_left = realsize >> 16;
                   1305: #ifdef NATMEM_OFFSET
                   1306:                add_shmmaps (realstart << 16, bank);
                   1307: #endif
                   1308:            }
1.1.1.12  root     1309:            put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1.1.1.9   root     1310:            real_left--;
                   1311:        }
                   1312:     }
                   1313: }
                   1314: 
                   1315: 
                   1316: /* memory save/restore code */
                   1317: 
                   1318: uae_u8 *save_cram (int *len)
                   1319: {
                   1320:     *len = allocated_chipmem;
                   1321:     return chipmemory;
                   1322: }
                   1323: 
                   1324: uae_u8 *save_bram (int *len)
                   1325: {
                   1326:     *len = allocated_bogomem;
                   1327:     return bogomemory;
                   1328: }
                   1329: 
                   1330: void restore_cram (int len, long filepos)
                   1331: {
                   1332:     chip_filepos = filepos;
                   1333:     changed_prefs.chipmem_size = len;
                   1334: }
                   1335: 
                   1336: void restore_bram (int len, long filepos)
                   1337: {
                   1338:     bogo_filepos = filepos;
                   1339:     changed_prefs.bogomem_size = len;
                   1340: }
                   1341: 
                   1342: uae_u8 *restore_rom (uae_u8 *src)
                   1343: {
                   1344:     restore_u32 ();
                   1345:     restore_u32 ();
                   1346:     restore_u32 ();
                   1347:     restore_u32 ();
                   1348:     restore_u32 ();
                   1349: 
                   1350:     return src;
                   1351: }
                   1352: 
                   1353: uae_u8 *save_rom (int first, int *len)
                   1354: {
                   1355:     static int count;
                   1356:     uae_u8 *dst, *dstbak;
                   1357:     uae_u8 *mem_real_start;
                   1358:     int mem_start, mem_size, mem_type, i, saverom;
                   1359: 
                   1360:     saverom = 0;
1.1.1.12  root     1361:     if (first)
                   1362:        count = 0;
1.1.1.9   root     1363:     for (;;) {
                   1364:        mem_type = count;
1.1.1.12  root     1365:        switch (count) {
                   1366:        case 0:         /* Kickstart ROM */
1.1.1.9   root     1367:            mem_start = 0xf80000;
                   1368:            mem_real_start = kickmemory;
                   1369:            mem_size = kickmem_size;
                   1370:            /* 256KB or 512KB ROM? */
1.1.1.12  root     1371:            for (i = 0; i < mem_size / 2 - 4; i++) {
                   1372:                if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
                   1373:                    break;
1.1.1.9   root     1374:            }
1.1.1.12  root     1375:            if (i == mem_size / 2 - 4) {
1.1.1.9   root     1376:                mem_size /= 2;
                   1377:                mem_start += 262144;
                   1378:            }
                   1379:            mem_type = 0;
                   1380:            break;
1.1.1.12  root     1381:        default:
1.1.1.9   root     1382:            return 0;
                   1383:        }
1.1.1.12  root     1384:        count++;
                   1385:        if (mem_size)
                   1386:            break;
1.1.1.9   root     1387:     }
                   1388:     dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
                   1389:     save_u32 (mem_start);
                   1390:     save_u32 (mem_size);
                   1391:     save_u32 (mem_type);
1.1.1.12  root     1392:     save_u32 (longget (mem_start + 12));       /* version+revision */
1.1.1.9   root     1393:     save_u32 (0);
1.1.1.12  root     1394:     sprintf (dst, "Kickstart %d.%d", wordget (mem_start + 12), wordget (mem_start + 14));
1.1.1.9   root     1395:     dst += strlen (dst) + 1;
                   1396:     if (saverom) {
1.1.1.12  root     1397:        for (i = 0; i < mem_size; i++)
                   1398:            *dst++ = byteget (mem_start + i);
1.1.1.9   root     1399:     }
                   1400:     *len = dst - dstbak;
                   1401:     return dstbak;
1.1       root     1402: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.