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

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.9   root      912:     return malloc (s);
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.