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

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 "options.h"
1.1.1.3   root       13: #include "uae.h"
1.1       root       14: #include "memory.h"
1.1.1.17  root       15: #include "romlist.h"
1.1       root       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.1.15  root       23: #include "crc32.h"
1.1.1.17  root       24: #include "gui.h"
1.1       root       25: 
1.1.1.2   root       26: #ifdef USE_MAPPED_MEMORY
1.1       root       27: #include <sys/mman.h>
                     28: #endif
                     29: 
                     30: int ersatzkickfile = 0;
                     31: 
1.1.1.4   root       32: uae_u32 allocated_chipmem;
                     33: uae_u32 allocated_fastmem;
                     34: uae_u32 allocated_bogomem;
                     35: uae_u32 allocated_gfxmem;
                     36: uae_u32 allocated_z3fastmem;
1.1.1.17  root       37: uae_u32 allocated_a3000lmem;
                     38: uae_u32 allocated_a3000hmem;
1.1.1.15  root       39: 
1.1.1.17  root       40: static long chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos;
1.1.1.15  root       41: 
1.1.1.17  root       42: /* Set if we notice during initialization that settings changed,
                     43:    and we must clear all memory to prevent bogus contents from confusing
                     44:    the Kickstart.  */
                     45: static int need_hardreset;
1.1.1.15  root       46: 
1.1.1.17  root       47: /* The address space setting used during the last reset.  */
                     48: static int last_address_space_24;
1.1.1.15  root       49: 
1.1.1.3   root       50: addrbank *mem_banks[65536];
1.1.1.9   root       51: 
                     52: /* This has two functions. It either holds a host address that, when added
                     53:    to the 68k address, gives the host address corresponding to that 68k
                     54:    address (in which case the value in this array is even), OR it holds the
                     55:    same value as mem_banks, for those banks that have baseaddr==0. In that
                     56:    case, bit 0 is set (the memory access routines will take care of it).  */
                     57: 
                     58: uae_u8 *baseaddr[65536];
1.1       root       59: 
1.1.1.2   root       60: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5   root       61: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2   root       62: {
1.1.1.5   root       63:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2   root       64: }
1.1.1.5   root       65: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2   root       66: {
1.1.1.5   root       67:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2   root       68: }
1.1.1.5   root       69: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2   root       70: {
1.1.1.5   root       71:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2   root       72: }
1.1.1.5   root       73: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2   root       74: {
1.1.1.5   root       75:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2   root       76: }
1.1.1.5   root       77: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2   root       78: {
1.1.1.5   root       79:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2   root       80: }
1.1.1.5   root       81: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2   root       82: {
1.1.1.5   root       83:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2   root       84: }
                     85: #endif
                     86: 
1.1.1.17  root       87: static uae_u32 chipmem_mask, chipmem_full_mask;
                     88: static uae_u32 kickmem_mask, extendedkickmem_mask, bogomem_mask;
                     89: static uae_u32 a3000lmem_mask, a3000hmem_mask;
1.1       root       90: 
1.1.1.11  root       91: static int illegal_count;
1.1.1.3   root       92: /* A dummy bank that only contains zeros */
                     93: 
1.1.1.4   root       94: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                     95: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                     96: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                     97: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                     98: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                     99: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                    100: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                    101: 
                    102: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                    103: {
1.1.1.11  root      104:     if (currprefs.illegal_mem) {
                    105:        if (illegal_count < 20) {
                    106:            illegal_count++;
                    107:            write_log ("Illegal lget at %08lx\n", addr);
                    108:        }
                    109:     }
1.1.1.4   root      110: 
1.1.1.9   root      111:     return 0xFFFFFFFF;
1.1       root      112: }
                    113: 
1.1.1.4   root      114: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1       root      115: {
1.1.1.11  root      116:     if (currprefs.illegal_mem) {
                    117:        if (illegal_count < 20) {
                    118:            illegal_count++;
                    119:            write_log ("Illegal wget at %08lx\n", addr);
                    120:        }
                    121:     }
1.1.1.12  root      122: 
1.1.1.9   root      123:     return 0xFFFF;
1.1       root      124: }
                    125: 
1.1.1.4   root      126: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1       root      127: {
1.1.1.11  root      128:     if (currprefs.illegal_mem) {
                    129:        if (illegal_count < 20) {
                    130:            illegal_count++;
                    131:            write_log ("Illegal bget at %08lx\n", addr);
                    132:        }
                    133:     }
1.1.1.4   root      134: 
1.1.1.9   root      135:     return 0xFF;
1.1       root      136: }
                    137: 
1.1.1.4   root      138: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1       root      139: {
1.1.1.11  root      140:     if (currprefs.illegal_mem) {
                    141:        if (illegal_count < 20) {
                    142:            illegal_count++;
                    143:            write_log ("Illegal lput at %08lx\n", addr);
                    144:        }
                    145:     }
1.1.1.3   root      146: }
1.1.1.17  root      147: 
1.1.1.4   root      148: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      149: {
1.1.1.11  root      150:     if (currprefs.illegal_mem) {
                    151:        if (illegal_count < 20) {
                    152:            illegal_count++;
                    153:            write_log ("Illegal wput at %08lx\n", addr);
                    154:        }
                    155:     }
1.1.1.3   root      156: }
1.1.1.17  root      157: 
1.1.1.4   root      158: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      159: {
1.1.1.11  root      160:     if (currprefs.illegal_mem) {
                    161:        if (illegal_count < 20) {
                    162:            illegal_count++;
                    163:            write_log ("Illegal bput at %08lx\n", addr);
                    164:        }
                    165:     }
1.1       root      166: }
                    167: 
1.1.1.4   root      168: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1       root      169: {
1.1.1.11  root      170:     if (currprefs.illegal_mem) {
                    171:        if (illegal_count < 20) {
                    172:            illegal_count++;
                    173:            write_log ("Illegal check at %08lx\n", addr);
                    174:        }
                    175:     }
1.1.1.4   root      176: 
1.1       root      177:     return 0;
                    178: }
                    179: 
                    180: /* Chip memory */
                    181: 
1.1.1.3   root      182: uae_u8 *chipmemory;
1.1       root      183: 
1.1.1.4   root      184: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    185: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1       root      186: 
1.1.1.4   root      187: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1       root      188: {
1.1.1.3   root      189:     uae_u32 *m;
1.1.1.8   root      190: 
1.1       root      191:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      192:     addr &= chipmem_mask;
1.1.1.3   root      193:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      194:     return do_get_mem_long (m);
1.1       root      195: }
                    196: 
1.1.1.4   root      197: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1       root      198: {
1.1.1.3   root      199:     uae_u16 *m;
1.1.1.8   root      200: 
1.1       root      201:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      202:     addr &= chipmem_mask;
1.1.1.3   root      203:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      204:     return do_get_mem_word (m);
1.1       root      205: }
                    206: 
1.1.1.4   root      207: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1       root      208: {
                    209:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      210:     addr &= chipmem_mask;
1.1       root      211:     return chipmemory[addr];
                    212: }
                    213: 
1.1.1.4   root      214: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1       root      215: {
1.1.1.3   root      216:     uae_u32 *m;
1.1.1.8   root      217: 
1.1       root      218:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      219:     addr &= chipmem_mask;
1.1.1.3   root      220:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      221:     do_put_mem_long (m, l);
1.1       root      222: }
                    223: 
1.1.1.4   root      224: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1       root      225: {
1.1.1.3   root      226:     uae_u16 *m;
1.1.1.8   root      227: 
1.1       root      228:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      229:     addr &= chipmem_mask;
1.1.1.3   root      230:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      231:     do_put_mem_word (m, w);
1.1       root      232: }
                    233: 
1.1.1.4   root      234: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1       root      235: {
                    236:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      237:     addr &= chipmem_mask;
1.1       root      238:     chipmemory[addr] = b;
                    239: }
                    240: 
1.1.1.17  root      241: uae_u32 REGPARAM2 chipmem_agnus_wget (uaecptr addr)
                    242: {
                    243:     uae_u16 *m;
                    244: 
                    245:     addr &= chipmem_full_mask;
                    246:     m = (uae_u16 *)(chipmemory + addr);
                    247:     return do_get_mem_word (m);
                    248: }
                    249: 
                    250: void REGPARAM2 chipmem_agnus_wput (uaecptr addr, uae_u32 w)
                    251: {
                    252:     uae_u16 *m;
                    253: 
                    254:     addr &= chipmem_full_mask;
                    255:     if (addr >= allocated_chipmem)
                    256:        return;
                    257:     m = (uae_u16 *)(chipmemory + addr);
                    258:     do_put_mem_word (m, w);
                    259: }
                    260: 
1.1.1.4   root      261: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1       root      262: {
                    263:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      264:     addr &= chipmem_mask;
1.1.1.4   root      265:     return (addr + size) <= allocated_chipmem;
1.1       root      266: }
                    267: 
1.1.1.4   root      268: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1       root      269: {
                    270:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      271:     addr &= chipmem_mask;
1.1       root      272:     return chipmemory + addr;
                    273: }
                    274: 
                    275: /* Slow memory */
                    276: 
1.1.1.3   root      277: static uae_u8 *bogomemory;
1.1       root      278: 
1.1.1.4   root      279: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
                    280: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
                    281: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
                    282: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
                    283: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
                    284: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
                    285: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    286: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1       root      287: 
1.1.1.4   root      288: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1       root      289: {
1.1.1.3   root      290:     uae_u32 *m;
1.1       root      291:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      292:     addr &= bogomem_mask;
1.1.1.3   root      293:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      294:     return do_get_mem_long (m);
1.1       root      295: }
                    296: 
1.1.1.4   root      297: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1       root      298: {
1.1.1.3   root      299:     uae_u16 *m;
1.1       root      300:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      301:     addr &= bogomem_mask;
1.1.1.3   root      302:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      303:     return do_get_mem_word (m);
1.1       root      304: }
                    305: 
1.1.1.4   root      306: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1       root      307: {
                    308:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      309:     addr &= bogomem_mask;
1.1       root      310:     return bogomemory[addr];
                    311: }
                    312: 
1.1.1.4   root      313: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1       root      314: {
1.1.1.3   root      315:     uae_u32 *m;
1.1       root      316:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      317:     addr &= bogomem_mask;
1.1.1.3   root      318:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      319:     do_put_mem_long (m, l);
1.1       root      320: }
                    321: 
1.1.1.4   root      322: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1       root      323: {
1.1.1.3   root      324:     uae_u16 *m;
1.1       root      325:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      326:     addr &= bogomem_mask;
1.1.1.3   root      327:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      328:     do_put_mem_word (m, w);
1.1       root      329: }
                    330: 
1.1.1.4   root      331: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1       root      332: {
                    333:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      334:     addr &= bogomem_mask;
1.1       root      335:     bogomemory[addr] = b;
                    336: }
                    337: 
1.1.1.4   root      338: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1       root      339: {
1.1.1.2   root      340:     addr -= bogomem_start & bogomem_mask;
                    341:     addr &= bogomem_mask;
1.1.1.4   root      342:     return (addr + size) <= allocated_bogomem;
1.1       root      343: }
                    344: 
1.1.1.4   root      345: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1       root      346: {
1.1.1.2   root      347:     addr -= bogomem_start & bogomem_mask;
                    348:     addr &= bogomem_mask;
1.1       root      349:     return bogomemory + addr;
                    350: }
                    351: 
1.1.1.17  root      352: /* A3000 motherboard fastmemory.  */
                    353: static uae_u8 *a3000lmemory, *a3000hmemory;
                    354: uae_u32 a3000lmem_start, a3000hmem_start;
                    355: 
                    356: static uae_u32 a3000lmem_lget (uaecptr) REGPARAM;
                    357: static uae_u32 a3000lmem_wget (uaecptr) REGPARAM;
                    358: static uae_u32 a3000lmem_bget (uaecptr) REGPARAM;
                    359: static void a3000lmem_lput (uaecptr, uae_u32) REGPARAM;
                    360: static void a3000lmem_wput (uaecptr, uae_u32) REGPARAM;
                    361: static void a3000lmem_bput (uaecptr, uae_u32) REGPARAM;
                    362: static int a3000lmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3   root      363: 
1.1.1.17  root      364: static uae_u32 REGPARAM2 a3000lmem_lget (uaecptr addr)
                    365: {
                    366:     uae_u32 *m;
                    367:     addr &= a3000lmem_mask;
                    368:     m = (uae_u32 *)(a3000lmemory + addr);
                    369:     return do_get_mem_long (m);
                    370: }
                    371: 
                    372: static uae_u32 REGPARAM2 a3000lmem_wget (uaecptr addr)
                    373: {
                    374:     uae_u16 *m;
                    375:     addr &= a3000lmem_mask;
                    376:     m = (uae_u16 *)(a3000lmemory + addr);
                    377:     return do_get_mem_word (m);
                    378: }
1.1       root      379: 
1.1.1.17  root      380: static uae_u32 REGPARAM2 a3000lmem_bget (uaecptr addr)
                    381: {
                    382:     addr &= a3000lmem_mask;
                    383:     return a3000lmemory[addr];
                    384: }
1.1.1.3   root      385: 
1.1.1.17  root      386: static void REGPARAM2 a3000lmem_lput (uaecptr addr, uae_u32 l)
1.1.1.3   root      387: {
                    388:     uae_u32 *m;
1.1.1.17  root      389:     addr &= a3000lmem_mask;
                    390:     m = (uae_u32 *)(a3000lmemory + addr);
                    391:     do_put_mem_long (m, l);
                    392: }
                    393: 
                    394: static void REGPARAM2 a3000lmem_wput (uaecptr addr, uae_u32 w)
                    395: {
                    396:     uae_u16 *m;
                    397:     addr &= a3000lmem_mask;
                    398:     m = (uae_u16 *)(a3000lmemory + addr);
                    399:     do_put_mem_word (m, w);
                    400: }
                    401: 
                    402: static void REGPARAM2 a3000lmem_bput (uaecptr addr, uae_u32 b)
                    403: {
                    404:     addr &= a3000lmem_mask;
                    405:     a3000lmemory[addr] = b;
                    406: }
                    407: 
                    408: static int REGPARAM2 a3000lmem_check (uaecptr addr, uae_u32 size)
                    409: {
                    410:     addr &= a3000lmem_mask;
                    411:     return (addr + size) <= allocated_a3000lmem;
                    412: }
                    413: 
                    414: static uae_u8 *REGPARAM2 a3000lmem_xlate (uaecptr addr)
                    415: {
                    416:     addr &= a3000lmem_mask;
                    417:     return a3000lmemory + addr;
                    418: }
                    419: 
                    420: static uae_u32 a3000hmem_lget (uaecptr) REGPARAM;
                    421: static uae_u32 a3000hmem_wget (uaecptr) REGPARAM;
                    422: static uae_u32 a3000hmem_bget (uaecptr) REGPARAM;
                    423: static void a3000hmem_lput (uaecptr, uae_u32) REGPARAM;
                    424: static void a3000hmem_wput (uaecptr, uae_u32) REGPARAM;
                    425: static void a3000hmem_bput (uaecptr, uae_u32) REGPARAM;
                    426: static int a3000hmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    427: static uae_u8 *a3000hmem_xlate (uaecptr addr) REGPARAM;
                    428: 
                    429: static uae_u32 REGPARAM2 a3000hmem_lget (uaecptr addr)
                    430: {
                    431:     uae_u32 *m;
                    432:     addr &= a3000hmem_mask;
                    433:     m = (uae_u32 *)(a3000hmemory + addr);
1.1.1.5   root      434:     return do_get_mem_long (m);
1.1.1.3   root      435: }
1.1       root      436: 
1.1.1.17  root      437: static uae_u32 REGPARAM2 a3000hmem_wget (uaecptr addr)
1.1.1.3   root      438: {
                    439:     uae_u16 *m;
1.1.1.17  root      440:     addr &= a3000hmem_mask;
                    441:     m = (uae_u16 *)(a3000hmemory + addr);
1.1.1.5   root      442:     return do_get_mem_word (m);
1.1.1.3   root      443: }
1.1       root      444: 
1.1.1.17  root      445: static uae_u32 REGPARAM2 a3000hmem_bget (uaecptr addr)
1.1       root      446: {
1.1.1.17  root      447:     addr &= a3000hmem_mask;
                    448:     return a3000hmemory[addr];
1.1       root      449: }
                    450: 
1.1.1.17  root      451: static void REGPARAM2 a3000hmem_lput (uaecptr addr, uae_u32 l)
1.1       root      452: {
1.1.1.3   root      453:     uae_u32 *m;
1.1.1.17  root      454:     addr &= a3000hmem_mask;
                    455:     m = (uae_u32 *)(a3000hmemory + addr);
1.1.1.5   root      456:     do_put_mem_long (m, l);
1.1.1.3   root      457: }
                    458: 
1.1.1.17  root      459: static void REGPARAM2 a3000hmem_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      460: {
                    461:     uae_u16 *m;
1.1.1.17  root      462:     addr &= a3000hmem_mask;
                    463:     m = (uae_u16 *)(a3000hmemory + addr);
1.1.1.5   root      464:     do_put_mem_word (m, w);
1.1.1.3   root      465: }
                    466: 
1.1.1.17  root      467: static void REGPARAM2 a3000hmem_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      468: {
1.1.1.17  root      469:     addr &= a3000hmem_mask;
                    470:     a3000hmemory[addr] = b;
1.1.1.3   root      471: }
                    472: 
1.1.1.17  root      473: static int REGPARAM2 a3000hmem_check (uaecptr addr, uae_u32 size)
1.1.1.3   root      474: {
1.1.1.17  root      475:     addr &= a3000hmem_mask;
                    476:     return (addr + size) <= allocated_a3000hmem;
1.1       root      477: }
                    478: 
1.1.1.17  root      479: static uae_u8 *REGPARAM2 a3000hmem_xlate (uaecptr addr)
1.1.1.3   root      480: {
1.1.1.17  root      481:     addr &= a3000hmem_mask;
                    482:     return a3000hmemory + addr;
1.1.1.3   root      483: }
                    484: 
                    485: /* Kick memory */
                    486: 
                    487: uae_u8 *kickmemory;
1.1.1.17  root      488: uae_u16 kickstart_version;
1.1.1.3   root      489: 
1.1.1.12  root      490: /*
                    491:  * A1000 kickstart RAM handling
                    492:  *
                    493:  * RESET instruction unhides boot ROM and disables write protection
                    494:  * write access to boot ROM hides boot ROM and enables write protection
                    495:  *
                    496:  */
                    497: static int a1000_kickstart_mode;
                    498: static uae_u8 *a1000_bootrom;
                    499: static void a1000_handle_kickstart (int mode)
                    500: {
1.1.1.17  root      501:     if (!a1000_bootrom)
                    502:        return;
1.1.1.12  root      503:     if (mode == 0) {
                    504:        a1000_kickstart_mode = 0;
                    505:        memcpy (kickmemory, kickmemory + 262144, 262144);
1.1.1.17  root      506:        kickstart_version = (kickmemory[262144 + 12] << 8) | kickmemory[262144 + 13];
1.1.1.12  root      507:     } else {
                    508:        a1000_kickstart_mode = 1;
1.1.1.17  root      509:        memcpy (kickmemory, a1000_bootrom, 262144);
                    510:        kickstart_version = 0;
1.1.1.12  root      511:     }
                    512: }
                    513: 
1.1.1.17  root      514: void a1000_reset (void)
                    515: {
                    516:     a1000_handle_kickstart (1);
                    517: }
                    518: 
1.1.1.4   root      519: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
                    520: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
                    521: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
1.1.1.12  root      522: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
                    523: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
                    524: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
                    525: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.4   root      526: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      527: 
1.1.1.4   root      528: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1       root      529: {
1.1.1.3   root      530:     uae_u32 *m;
1.1       root      531:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      532:     addr &= kickmem_mask;
1.1.1.3   root      533:     m = (uae_u32 *)(kickmemory + addr);
1.1.1.5   root      534:     return do_get_mem_long (m);
1.1       root      535: }
                    536: 
1.1.1.4   root      537: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1       root      538: {
1.1.1.3   root      539:     uae_u16 *m;
1.1       root      540:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      541:     addr &= kickmem_mask;
1.1.1.3   root      542:     m = (uae_u16 *)(kickmemory + addr);
1.1.1.5   root      543:     return do_get_mem_word (m);
1.1       root      544: }
                    545: 
1.1.1.4   root      546: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1       root      547: {
                    548:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      549:     addr &= kickmem_mask;
1.1       root      550:     return kickmemory[addr];
                    551: }
                    552: 
1.1.1.4   root      553: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1       root      554: {
1.1.1.12  root      555:     uae_u32 *m;
                    556:     if (a1000_kickstart_mode) {
                    557:        if (addr >= 0xfc0000) {
                    558:            addr -= kickmem_start & kickmem_mask;
                    559:            addr &= kickmem_mask;
                    560:            m = (uae_u32 *)(kickmemory + addr);
                    561:            do_put_mem_long (m, b);
                    562:            return;
                    563:        } else
                    564:            a1000_handle_kickstart (0);
                    565:     } else if (currprefs.illegal_mem)
1.1.1.4   root      566:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      567: }
                    568: 
1.1.1.4   root      569: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1       root      570: {
1.1.1.12  root      571:     uae_u16 *m;
                    572:     if (a1000_kickstart_mode) {
                    573:        if (addr >= 0xfc0000) {
                    574:            addr -= kickmem_start & kickmem_mask;
                    575:            addr &= kickmem_mask;
                    576:            m = (uae_u16 *)(kickmemory + addr);
                    577:            do_put_mem_word (m, b);
                    578:            return;
                    579:        } else
                    580:            a1000_handle_kickstart (0);
                    581:     } else if (currprefs.illegal_mem)
1.1.1.4   root      582:        write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1       root      583: }
                    584: 
1.1.1.4   root      585: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1       root      586: {
1.1.1.12  root      587:     if (a1000_kickstart_mode) {
                    588:        if (addr >= 0xfc0000) {
                    589:            addr -= kickmem_start & kickmem_mask;
                    590:            addr &= kickmem_mask;
                    591:            kickmemory[addr] = b;
                    592:            return;
                    593:        } else
                    594:            a1000_handle_kickstart (0);
                    595:     } else if (currprefs.illegal_mem)
1.1.1.4   root      596:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      597: }
                    598: 
1.1.1.4   root      599: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1       root      600: {
1.1.1.2   root      601:     addr -= kickmem_start & kickmem_mask;
                    602:     addr &= kickmem_mask;
1.1.1.4   root      603:     return (addr + size) <= kickmem_size;
1.1       root      604: }
                    605: 
1.1.1.4   root      606: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1       root      607: {
1.1.1.2   root      608:     addr -= kickmem_start & kickmem_mask;
                    609:     addr &= kickmem_mask;
1.1       root      610:     return kickmemory + addr;
                    611: }
                    612: 
1.1.1.12  root      613: /* CD32/CDTV extended kick memory */
1.1.1.3   root      614: 
1.1.1.12  root      615: uae_u8 *extendedkickmemory;
1.1.1.18! root      616: static uae_u32 extendedkickmem_size;
1.1.1.12  root      617: static uae_u32 extendedkickmem_start;
                    618: 
                    619: #define EXTENDED_ROM_CD32 1
                    620: #define EXTENDED_ROM_CDTV 2
                    621: 
                    622: static int extromtype (void)
                    623: {
                    624:     switch (extendedkickmem_size) {
                    625:     case 524288:
                    626:        return EXTENDED_ROM_CD32;
                    627:     case 262144:
                    628:        return EXTENDED_ROM_CDTV;
                    629:     }
1.1.1.3   root      630:     return 0;
                    631: }
                    632: 
1.1.1.12  root      633: static uae_u32 extendedkickmem_lget (uaecptr) REGPARAM;
                    634: static uae_u32 extendedkickmem_wget (uaecptr) REGPARAM;
                    635: static uae_u32 extendedkickmem_bget (uaecptr) REGPARAM;
                    636: static void extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
                    637: static void extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
                    638: static void extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
                    639: static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    640: static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM;
                    641: 
1.1.1.17  root      642: static uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr)
1.1.1.3   root      643: {
1.1.1.12  root      644:     uae_u32 *m;
                    645:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    646:     addr &= extendedkickmem_mask;
                    647:     m = (uae_u32 *)(extendedkickmemory + addr);
                    648:     return do_get_mem_long (m);
1.1.1.3   root      649: }
                    650: 
1.1.1.17  root      651: static uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr)
1.1       root      652: {
1.1.1.12  root      653:     uae_u16 *m;
                    654:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    655:     addr &= extendedkickmem_mask;
                    656:     m = (uae_u16 *)(extendedkickmemory + addr);
                    657:     return do_get_mem_word (m);
                    658: }
1.1.1.3   root      659: 
1.1.1.17  root      660: static uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr)
1.1.1.12  root      661: {
                    662:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    663:     addr &= extendedkickmem_mask;
                    664:     return extendedkickmemory[addr];
                    665: }
1.1.1.3   root      666: 
1.1.1.17  root      667: static void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
1.1.1.12  root      668: {
                    669:     if (currprefs.illegal_mem)
                    670:        write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
                    671: }
1.1.1.3   root      672: 
1.1.1.17  root      673: static void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
1.1.1.12  root      674: {
                    675:     if (currprefs.illegal_mem)
                    676:        write_log ("Illegal extendedkickmem wput at %08lx\n", addr);
                    677: }
1.1.1.3   root      678: 
1.1.1.17  root      679: static void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
1.1.1.12  root      680: {
                    681:     if (currprefs.illegal_mem)
                    682:        write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
                    683: }
1.1.1.3   root      684: 
1.1.1.17  root      685: static int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size)
1.1.1.12  root      686: {
                    687:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    688:     addr &= extendedkickmem_mask;
                    689:     return (addr + size) <= extendedkickmem_size;
                    690: }
1.1.1.3   root      691: 
1.1.1.17  root      692: static uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr)
1.1.1.12  root      693: {
                    694:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    695:     addr &= extendedkickmem_mask;
                    696:     return extendedkickmemory + addr;
                    697: }
1.1.1.2   root      698: 
1.1.1.12  root      699: /* Default memory access functions */
                    700: 
                    701: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
                    702: {
                    703:     return 0;
                    704: }
                    705: 
                    706: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
                    707: {
                    708:     write_log ("Your Amiga program just did something terribly stupid\n");
1.1.1.15  root      709:     uae_reset (1);
1.1.1.17  root      710: 
                    711:     set_special (SPCFLAG_RESTORE_SANITY);
                    712:     /* rtarea_bank has an infinite loop in m68k space, which we use to avoid a
                    713:      * crash. */
                    714:     return rtarea_bank.xlateaddr (0xF0FFC0);
1.1       root      715: }
                    716: 
                    717: /* Address banks */
                    718: 
                    719: addrbank dummy_bank = {
                    720:     dummy_lget, dummy_wget, dummy_bget,
                    721:     dummy_lput, dummy_wput, dummy_bput,
1.1.1.17  root      722:     default_xlate, dummy_check, NULL, NULL
1.1.1.3   root      723: };
                    724: 
1.1       root      725: addrbank chipmem_bank = {
                    726:     chipmem_lget, chipmem_wget, chipmem_bget,
                    727:     chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.17  root      728:     chipmem_xlate, chipmem_check, NULL, "Chip memory"
1.1       root      729: };
                    730: 
                    731: addrbank bogomem_bank = {
                    732:     bogomem_lget, bogomem_wget, bogomem_bget,
                    733:     bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.17  root      734:     bogomem_xlate, bogomem_check, NULL, "Slow memory"
1.1       root      735: };
                    736: 
1.1.1.17  root      737: addrbank a3000lmem_bank = {
                    738:     a3000lmem_lget, a3000lmem_wget, a3000lmem_bget,
                    739:     a3000lmem_lput, a3000lmem_wput, a3000lmem_bput,
                    740:     a3000lmem_xlate, a3000lmem_check, NULL, "RAMSEY memory (low)"
                    741: };
                    742: 
                    743: addrbank a3000hmem_bank = {
                    744:     a3000hmem_lget, a3000hmem_wget, a3000hmem_bget,
                    745:     a3000hmem_lput, a3000hmem_wput, a3000hmem_bput,
                    746:     a3000hmem_xlate, a3000hmem_check, NULL, "RAMSEY memory (high)"
1.1.1.3   root      747: };
                    748: 
1.1       root      749: addrbank kickmem_bank = {
                    750:     kickmem_lget, kickmem_wget, kickmem_bget,
                    751:     kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.17  root      752:     kickmem_xlate, kickmem_check, NULL, "Kickstart ROM"
1.1       root      753: };
                    754: 
1.1.1.12  root      755: addrbank extendedkickmem_bank = {
                    756:     extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
                    757:     extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
1.1.1.17  root      758:     extendedkickmem_xlate, extendedkickmem_check, NULL, "Extended Kickstart ROM"
1.1.1.12  root      759: };
                    760: 
                    761: static int kickstart_checksum (uae_u8 *mem, int size)
                    762: {
                    763:     uae_u32 cksum = 0, prevck = 0;
                    764:     int i;
                    765:     for (i = 0; i < size; i += 4) {
                    766:        uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
                    767:        cksum += data;
                    768:        if (cksum < prevck)
                    769:            cksum++;
                    770:        prevck = cksum;
                    771:     }
                    772:     if (cksum != 0xFFFFFFFFul) {
                    773:        write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
                    774:     }
                    775:     return 0;
                    776: }
                    777: 
1.1.1.17  root      778: static const char kickstring[] = "exec.library";
                    779: 
                    780: static int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom)
1.1.1.12  root      781: {
                    782:     unsigned char buffer[20];
1.1.1.17  root      783:     int i, j, cr = 0;
1.1.1.12  root      784: 
                    785:     if (cloanto_rom)
                    786:        *cloanto_rom = 0;
1.1.1.17  root      787:     i = zfile_fread (buffer, 1, 11, f);
1.1.1.12  root      788:     if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) {
1.1.1.17  root      789:        zfile_fseek (f, 0, SEEK_SET);
1.1.1.12  root      790:     } else {
                    791:        cr = 1;
                    792:     }
                    793: 
1.1.1.17  root      794:     if (cloanto_rom)
                    795:        *cloanto_rom = cr;
                    796: 
                    797:     i = zfile_fread (mem, 1, size, f);
                    798: 
                    799:     if (i != 8192 && i != 65536 && i != 131072 && i != 262144 && i != 524288 && i != 524288 * 2 && i != 524288 * 4) {
                    800:        gui_message ("Error while reading Kickstart ROM file.");
1.1.1.12  root      801:        return 0;
                    802:     }
1.1.1.17  root      803:     if (i == size / 2)
                    804:        memcpy (mem + size / 2, mem, size / 2);
                    805: 
                    806:     if (cr) {
                    807:        if (!decode_cloanto_rom (mem, size, i, 0))
                    808:            return 0;
                    809:     }
                    810:     if (currprefs.cs_a1000ram) {
                    811:        int off = 0;
                    812:        a1000_bootrom = xcalloc (262144, 1);
                    813:        while (off + i < 262144) {
                    814:            memcpy (a1000_bootrom + off, kickmemory, i);
                    815:            off += i;
                    816:        }
                    817:        memset (kickmemory, 0, kickmem_size);
                    818:        a1000_handle_kickstart (1);
                    819:        dochecksum = 0;
                    820:        i = 524288;
                    821:     }
                    822: 
                    823:     zfile_fclose (f);
                    824: 
                    825:     for (j = 0; j < 256 && i >= 262144; j++) {
                    826:        if (!memcmp (mem + j, kickstring, strlen (kickstring) + 1))
                    827:            break;
                    828:     }
1.1.1.12  root      829: 
1.1.1.17  root      830:     if (j == 256 || i < 262144)
                    831:        dochecksum = 0;
                    832:     if (dochecksum)
1.1.1.12  root      833:        kickstart_checksum (mem, size);
1.1.1.17  root      834: 
1.1.1.12  root      835:     return 1;
                    836: }
                    837: 
                    838: static int load_extendedkickstart (void)
                    839: {
1.1.1.17  root      840:     struct zfile *f;
1.1.1.12  root      841:     int size;
                    842: 
                    843:     if (strlen (currprefs.romextfile) == 0)
                    844:        return 0;
                    845:     f = zfile_open (currprefs.romextfile, "rb");
                    846:     if (!f) {
                    847:        write_log ("No extended Kickstart ROM found");
                    848:        return 0;
                    849:     }
                    850: 
1.1.1.17  root      851:     zfile_fseek (f, 0, SEEK_END);
                    852:     size = zfile_ftell (f);
1.1.1.12  root      853:     if (size > 300000)
                    854:        extendedkickmem_size = 524288;
                    855:     else
                    856:        extendedkickmem_size = 262144;
1.1.1.17  root      857:     zfile_fseek (f, 0, SEEK_SET);
1.1.1.12  root      858: 
                    859:     switch (extromtype ()) {
                    860:     case EXTENDED_ROM_CDTV:
                    861:        extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_f0");
                    862:        extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
                    863:        break;
                    864:     case EXTENDED_ROM_CD32:
                    865:        extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
                    866:        extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
                    867:        break;
                    868:     }
                    869:     read_kickstart (f, extendedkickmemory, 524288, 0, 0);
                    870:     return 1;
                    871: }
                    872: 
                    873: 
1.1.1.17  root      874: static void kickstart_fix_checksum (uae_u8 *mem, int size)
                    875: {
                    876:     uae_u32 cksum = 0, prevck = 0;
                    877:     int i, ch = size == 524288 ? 0x7ffe8 : 0x3e;
                    878: 
                    879:     mem[ch] = 0;
                    880:     mem[ch + 1] = 0;
                    881:     mem[ch + 2] = 0;
                    882:     mem[ch + 3] = 0;
                    883:     for (i = 0; i < size; i+=4) {
                    884:        uae_u32 data = (mem[i] << 24) | (mem[i + 1] << 16) | (mem[i + 2] << 8) | mem[i + 3];
                    885:        cksum += data;
                    886:        if (cksum < prevck)
                    887:            cksum++;
                    888:        prevck = cksum;
                    889:     }
                    890:     cksum ^= 0xffffffff;
                    891:     mem[ch++] = cksum >> 24;
                    892:     mem[ch++] = cksum >> 16;
                    893:     mem[ch++] = cksum >> 8;
                    894:     mem[ch++] = cksum >> 0;
                    895: }
                    896: 
                    897: static int patch_shapeshifter (uae_u8 *kickmemory)
                    898: {
                    899:     /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
                    900:      * Changes 'lea $400,a0' and 'lea $1000,a0' to 'lea $3000,a0' for
                    901:      * ShapeShifter compatability.
                    902:     */
                    903:     int i, patched = 0;
                    904:     uae_u8 kickshift1[] = { 0x41, 0xf8, 0x04, 0x00 };
                    905:     uae_u8 kickshift2[] = { 0x41, 0xf8, 0x10, 0x00 };
                    906:     uae_u8 kickshift3[] = { 0x43, 0xf8, 0x04, 0x00 };
                    907: 
                    908:     for (i = 0x200; i < 0x300; i++) {
                    909:        if (!memcmp (kickmemory + i, kickshift1, sizeof (kickshift1)) ||
                    910:        !memcmp (kickmemory + i, kickshift2, sizeof (kickshift2)) ||
                    911:        !memcmp (kickmemory + i, kickshift3, sizeof (kickshift3))) {
                    912:            kickmemory[i + 2] = 0x30;
                    913:            write_log ("Kickstart KickShifted @%04.4X\n", i);
                    914:            patched++;
                    915:        }
                    916:     }
                    917:     return patched;
                    918: }
                    919: 
                    920: /* disable incompatible drivers */
                    921: static int patch_residents (uae_u8 *kickmemory, int size)
                    922: {
                    923:     int i, j, patched = 0;
                    924:     char *residents[] = {
                    925:        "NCR scsi.device", 
                    926:        "scsi.device", "carddisk.device", "card.resource",
                    927:        NULL
                    928:     };
                    929:     uaecptr base = size == 524288 ? 0xf80000 : 0xfc0000;
                    930: 
                    931:     for (i = 0; i < size - 100; i++) {
                    932:        if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
                    933:            uaecptr addr;
                    934:            addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0);
                    935:            if (addr != i + base)
                    936:                continue;
                    937:            addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0);
                    938:            if (addr >= base && addr < base + size) {
                    939:                j = 0;
                    940:                while (residents[j]) {
                    941:                    if (!memcmp (residents[j], kickmemory + addr - base, strlen (residents[j]) + 1)) {
                    942:                        write_log ("KSPatcher: '%s' at %08.8X disabled\n", residents[j], i + base);
                    943:                        kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */
                    944:                        patched++;
                    945:                        break;
                    946:                    }
                    947:                    j++;
                    948:                }
                    949:            }
                    950:        }
                    951:     }
                    952:     return patched;
                    953: }
                    954: 
1.1.1.18! root      955: static void patch_kick (void)
1.1.1.17  root      956: {
                    957:     int patched = 0;
                    958:     if (kickmem_size >= 524288 && currprefs.kickshifter)
                    959:        patched += patch_shapeshifter (kickmemory);
                    960:     patched += patch_residents (kickmemory, kickmem_size);
                    961:     if (extendedkickmemory) {
                    962:        patched += patch_residents (extendedkickmemory, extendedkickmem_size);
                    963:        if (patched)
                    964:            kickstart_fix_checksum (extendedkickmemory, extendedkickmem_size);
                    965:     }
                    966:     if (patched)
                    967:        kickstart_fix_checksum (kickmemory, kickmem_size);
                    968: }
                    969: 
1.1.1.12  root      970: static int load_kickstart (void)
                    971: {
1.1.1.17  root      972:     struct zfile *f = NULL;
                    973:     int i;
                    974: 
                    975:     if (currprefs.rom_crc32) {
                    976:        for (i = 0;; i++) {
                    977:            struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1);
                    978:            if (!rl)
                    979:                break;
                    980:            if (rl->rd->crc32 == currprefs.rom_crc32) {
                    981:                f = zfile_open (rl->path, "rb");
                    982:                break;
                    983:            }
                    984:        }
                    985:     } else
                    986:        f = zfile_open (currprefs.romfile, "rb");
1.1.1.12  root      987: 
                    988:     if (f == NULL) {
1.1.1.17  root      989: #if defined (AMIGA)
1.1.1.12  root      990: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
                    991:        if (!getenv (USE_UAE_ERSATZ)) {
                    992:            write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
                    993:            memcpy (kickmemory, (char *) 0x1000000 - kickmem_size, kickmem_size);
                    994:            kickstart_checksum (kickmemory, kickmem_size);
                    995:            goto chk_sum;
                    996:        }
                    997: #endif
                    998:        return 0;
                    999:     }
                   1000: 
                   1001:     if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom))
                   1002:        return 0;
                   1003: 
1.1.1.17  root     1004: #if defined (AMIGA)
1.1.1.12  root     1005:   chk_sum:
                   1006: #endif
1.1.1.17  root     1007:     kickstart_version = (kickmemory[12] << 8) | kickmemory[13];
1.1.1.12  root     1008: 
                   1009:     return 1;
                   1010: }
                   1011: 
1.1       root     1012: char *address_space, *good_address_map;
                   1013: int good_address_fd;
1.1.1.4   root     1014: 
1.1.1.9   root     1015: #ifndef NATMEM_OFFSET
                   1016: 
1.1.1.12  root     1017: uae_u8 *mapped_malloc (size_t s, char *file)
1.1.1.4   root     1018: {
1.1.1.13  root     1019:     return calloc (s, 1);
1.1.1.4   root     1020: }
                   1021: 
1.1.1.9   root     1022: void mapped_free (uae_u8 *p)
1.1       root     1023: {
1.1.1.9   root     1024:     free (p);
                   1025: }
                   1026: #else
1.1.1.3   root     1027: 
1.1.1.9   root     1028: #include <sys/ipc.h>
                   1029: #include <sys/shm.h>
                   1030: #include <unistd.h>
                   1031: #include <sys/mman.h>
                   1032: 
1.1.1.12  root     1033: shmpiece *shm_start = NULL;
                   1034: int canbang = 1;
1.1.1.9   root     1035: 
1.1.1.12  root     1036: static void dumplist (void)
1.1.1.9   root     1037: {
1.1.1.12  root     1038:     shmpiece *x = shm_start;
1.1.1.9   root     1039:     printf ("Start Dump:\n");
                   1040:     while (x) {
                   1041:        printf ("  this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
1.1.1.12  root     1042:                x, x->native_address, x->id, x->prev, x->next, x->size);
1.1.1.9   root     1043:        x = x->next;
1.1.1.2   root     1044:     }
1.1.1.9   root     1045:     printf ("End Dump:\n");
                   1046: }
1.1       root     1047: 
1.1.1.9   root     1048: static shmpiece *find_shmpiece (uae_u8 *base)
                   1049: {
                   1050:     shmpiece *x = shm_start;
1.1       root     1051: 
1.1.1.9   root     1052:     while (x && x->native_address != base)
                   1053:        x = x->next;
                   1054:     if (!x) {
1.1.1.12  root     1055:        printf ("NATMEM: Failure to find mapping at %p\n", base);
                   1056:        dumplist ();
1.1.1.9   root     1057:        canbang = 0;
                   1058:        return 0;
                   1059:     }
                   1060:     return x;
                   1061: }
1.1.1.3   root     1062: 
1.1.1.9   root     1063: static void delete_shmmaps (uae_u32 start, uae_u32 size)
                   1064: {
                   1065:     if (!canbang)
                   1066:        return;
                   1067: 
                   1068:     while (size) {
1.1.1.12  root     1069:        uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1.1.1.9   root     1070:        if (base) {
                   1071:            shmpiece *x;
1.1.1.12  root     1072:            base = ((uae_u8 *) NATMEM_OFFSET) + start;
1.1.1.9   root     1073: 
                   1074:            x = find_shmpiece (base);
1.1.1.12  root     1075:            if (!x)
1.1.1.9   root     1076:                return;
                   1077: 
                   1078:            if (x->size > size) {
1.1.1.17  root     1079:                printf ("NATMEM: Failure to delete mapping at %08x (size %08x, delsize %08x)\n", start, x->size, size);
1.1.1.12  root     1080:                dumplist ();
1.1.1.9   root     1081:                canbang = 0;
                   1082:                return;
                   1083:            }
                   1084:            shmdt (x->native_address);
                   1085:            size -= x->size;
                   1086:            start += x->size;
                   1087:            if (x->next)
1.1.1.12  root     1088:                x->next->prev = x->prev;        /* remove this one from the list */
1.1.1.9   root     1089:            if (x->prev)
                   1090:                x->prev->next = x->next;
                   1091:            else
                   1092:                shm_start = x->next;
1.1.1.12  root     1093:            free (x);
1.1.1.9   root     1094:        } else {
                   1095:            size -= 0x10000;
                   1096:            start += 0x10000;
                   1097:        }
1.1.1.3   root     1098:     }
1.1.1.9   root     1099: }
1.1.1.12  root     1100: 
1.1.1.9   root     1101: static void add_shmmaps (uae_u32 start, addrbank *what)
                   1102: {
                   1103:     shmpiece *x = shm_start;
                   1104:     shmpiece *y;
                   1105:     uae_u8 *base = what->baseaddr;
                   1106: 
                   1107:     if (!canbang)
                   1108:        return;
                   1109:     if (!base)
                   1110:        return;
                   1111: 
                   1112:     x = find_shmpiece (base);
1.1.1.12  root     1113:     if (!x)
1.1.1.9   root     1114:        return;
                   1115:     y = malloc (sizeof (shmpiece));
                   1116:     *y = *x;
1.1.1.12  root     1117:     base = ((uae_u8 *) NATMEM_OFFSET) + start;
                   1118:     y->native_address = shmat (y->id, base, 0);
                   1119:     if (y->native_address == (void *) -1) {
1.1.1.17  root     1120:        printf ("NATMEM: Failure to map existing at %08x (%p)\n", start, base);
1.1.1.12  root     1121:        perror ("shmat");
                   1122:        dumplist ();
1.1.1.9   root     1123:        canbang = 0;
                   1124:        return;
1.1.1.2   root     1125:     }
1.1.1.9   root     1126:     y->next = shm_start;
                   1127:     y->prev = NULL;
                   1128:     if (y->next)
                   1129:        y->next->prev = y;
                   1130:     shm_start = y;
                   1131: }
                   1132: 
                   1133: uae_u8 *mapped_malloc (size_t s, char *file)
                   1134: {
1.1.1.12  root     1135:     int id;
1.1.1.9   root     1136:     void *answer;
                   1137:     shmpiece *x;
                   1138: 
1.1.1.12  root     1139:     if (!canbang)
1.1.1.9   root     1140:        return malloc (s);
                   1141: 
1.1.1.12  root     1142:     id = shmget (IPC_PRIVATE, s, 0x1ff, file);
1.1.1.9   root     1143:     if (id == 1) {
                   1144:        canbang = 0;
                   1145:        return mapped_malloc (s, file);
                   1146:     }
1.1.1.12  root     1147:     answer = shmat (id, 0, 0);
                   1148:     shmctl (id, IPC_RMID, NULL);
                   1149:     if (answer != (void *) -1) {
                   1150:        x = malloc (sizeof (shmpiece));
1.1.1.9   root     1151:        x->native_address = answer;
                   1152:        x->id = id;
                   1153:        x->size = s;
                   1154:        x->next = shm_start;
                   1155:        x->prev = NULL;
                   1156:        if (x->next)
                   1157:            x->next->prev = x;
                   1158:        shm_start = x;
                   1159: 
                   1160:        return answer;
                   1161:     }
                   1162:     canbang = 0;
                   1163:     return mapped_malloc (s, file);
                   1164: }
                   1165: 
1.1.1.10  root     1166: void mapped_free (uae_u8 *base)
1.1.1.9   root     1167: {
                   1168:     shmpiece *x = find_shmpiece (base);
1.1.1.12  root     1169:     if (!x)
1.1.1.9   root     1170:        abort ();
                   1171:     shmdt (x->native_address);
                   1172: }
                   1173: 
1.1       root     1174: #endif
1.1.1.6   root     1175: 
1.1.1.9   root     1176: static void init_mem_banks (void)
                   1177: {
                   1178:     int i;
                   1179:     for (i = 0; i < 65536; i++)
                   1180:        put_mem_bank (i << 16, &dummy_bank, 0);
                   1181: }
                   1182: 
                   1183: static void allocate_memory (void)
                   1184: {
                   1185:     if (allocated_chipmem != currprefs.chipmem_size) {
1.1.1.18! root     1186:        uae_u32 memsize;
1.1.1.9   root     1187:        if (chipmemory)
                   1188:            mapped_free (chipmemory);
                   1189:        chipmemory = 0;
                   1190: 
1.1.1.17  root     1191:        memsize = allocated_chipmem = currprefs.chipmem_size;
1.1.1.9   root     1192:        chipmem_mask = allocated_chipmem - 1;
                   1193: 
1.1.1.17  root     1194:        if (memsize < 0x100000)
                   1195:            memsize = 0x100000;
                   1196:        chipmemory = mapped_malloc (memsize, "chip");
1.1.1.9   root     1197:        if (chipmemory == 0) {
                   1198:            write_log ("Fatal error: out of memory for chipmem.\n");
                   1199:            allocated_chipmem = 0;
1.1.1.17  root     1200:        } else {
                   1201:            need_hardreset = 1;
                   1202:            if (memsize != allocated_chipmem)
                   1203:                memset (chipmemory + allocated_chipmem, 0xff, memsize - allocated_chipmem);
                   1204:        }
1.1.1.9   root     1205:     }
                   1206: 
1.1.1.17  root     1207:     chipmem_full_mask = allocated_chipmem - 1;
                   1208:     if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && allocated_chipmem < 0x100000)
                   1209:        chipmem_full_mask = 0x100000 - 1;
                   1210: 
1.1.1.9   root     1211:     if (allocated_bogomem != currprefs.bogomem_size) {
                   1212:        if (bogomemory)
                   1213:            mapped_free (bogomemory);
                   1214:        bogomemory = 0;
                   1215: 
                   1216:        allocated_bogomem = currprefs.bogomem_size;
                   1217:        bogomem_mask = allocated_bogomem - 1;
                   1218: 
                   1219:        if (allocated_bogomem) {
                   1220:            bogomemory = mapped_malloc (allocated_bogomem, "bogo");
                   1221:            if (bogomemory == 0) {
                   1222:                write_log ("Out of memory for bogomem.\n");
                   1223:                allocated_bogomem = 0;
                   1224:            }
                   1225:        }
1.1.1.17  root     1226:        need_hardreset = 1;
1.1.1.9   root     1227:     }
1.1.1.17  root     1228: 
                   1229:     if (allocated_a3000lmem != currprefs.mbresmem_low_size) {
                   1230:        if (a3000lmemory)
                   1231:            mapped_free (a3000lmemory);
                   1232:        a3000lmemory = 0;
                   1233: 
                   1234:        allocated_a3000lmem = currprefs.mbresmem_low_size;
                   1235:        a3000lmem_mask = allocated_a3000lmem - 1;
                   1236:        a3000lmem_start = 0x08000000 - allocated_a3000lmem;
                   1237:        if (allocated_a3000lmem) {
                   1238:            a3000lmemory = mapped_malloc (allocated_a3000lmem, "ramsey_low");
                   1239:            if (a3000lmemory == 0) {
                   1240:                write_log ("Out of memory for a3000lowmem.\n");
                   1241:                allocated_a3000lmem = 0;
                   1242:            }
                   1243:        }
                   1244:        need_hardreset = 1;
                   1245:     }
                   1246: 
                   1247:     if (allocated_a3000hmem != currprefs.mbresmem_high_size) {
                   1248:        if (a3000hmemory)
                   1249:            mapped_free (a3000hmemory);
                   1250:        a3000hmemory = 0;
                   1251: 
                   1252:        allocated_a3000hmem = currprefs.mbresmem_high_size;
                   1253:        a3000hmem_mask = allocated_a3000hmem - 1;
                   1254:        a3000hmem_start = 0x08000000;
                   1255:        if (allocated_a3000hmem) {
                   1256:            a3000hmemory = mapped_malloc (allocated_a3000hmem, "ramsey_high");
                   1257:            if (a3000hmemory == 0) {
                   1258:                write_log ("Out of memory for a3000highmem.\n");
                   1259:                allocated_a3000hmem = 0;
1.1.1.9   root     1260:            }
                   1261:        }
1.1.1.17  root     1262:        need_hardreset = 1;
1.1.1.9   root     1263:     }
                   1264: 
                   1265:     if (savestate_state == STATE_RESTORE) {
1.1.1.17  root     1266:        restore_ram (chip_filepos, chipmemory);
1.1.1.9   root     1267:        if (allocated_bogomem > 0) {
1.1.1.17  root     1268:            restore_ram (bogo_filepos, bogomemory);
1.1.1.9   root     1269:        }
1.1.1.17  root     1270:        if (allocated_a3000lmem > 0)
                   1271:            restore_ram (a3000lmem_filepos, a3000lmemory);
                   1272:        if (allocated_a3000hmem > 0)
                   1273:            restore_ram (a3000hmem_filepos, a3000hmemory);
1.1.1.9   root     1274:     }
                   1275:     chipmem_bank.baseaddr = chipmemory;
                   1276:     bogomem_bank.baseaddr = bogomemory;
1.1.1.17  root     1277:     a3000lmem_bank.baseaddr = a3000lmemory;
                   1278:     a3000hmem_bank.baseaddr = a3000hmemory;
                   1279: }
                   1280: 
                   1281: void map_overlay (int chip)
                   1282: {
                   1283:     int i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
                   1284:     addrbank *cb;
                   1285: 
                   1286:     cb = &chipmem_bank;
                   1287:     if (chip)
                   1288:        map_banks (cb, 0, i, allocated_chipmem);
                   1289:     else
                   1290:        map_banks (&kickmem_bank, 0, i, 0x80000);
                   1291:     if (savestate_state != STATE_RESTORE)
                   1292:        m68k_setpc (m68k_getpc ());
1.1.1.9   root     1293: }
                   1294: 
                   1295: void memory_reset (void)
                   1296: {
1.1.1.17  root     1297:     int bnk, bnk_end;
1.1.1.9   root     1298: 
                   1299: #ifdef NATMEM_OFFSET
                   1300:     delete_shmmaps (0, 0xFFFF0000);
                   1301: #endif
1.1.1.4   root     1302:     init_mem_banks ();
1.1.1.3   root     1303: 
1.1.1.9   root     1304:     currprefs.chipmem_size = changed_prefs.chipmem_size;
                   1305:     currprefs.bogomem_size = changed_prefs.bogomem_size;
1.1.1.17  root     1306:     currprefs.mbresmem_low_size = changed_prefs.mbresmem_low_size;
                   1307:     currprefs.mbresmem_high_size = changed_prefs.mbresmem_high_size;
                   1308:     currprefs.chipset_mask = changed_prefs.chipset_mask;
                   1309:     currprefs.cs_a1000ram = changed_prefs.cs_a1000ram;
                   1310:     currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev;
                   1311:     currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev;
                   1312:     currprefs.cs_ide = changed_prefs.cs_ide;
                   1313:     currprefs.bootrom = changed_prefs.bootrom;
                   1314: 
                   1315:     need_hardreset = 0;
                   1316:     /* Use changed_prefs, as m68k_reset is called later.  */
                   1317:     if (last_address_space_24 != changed_prefs.address_space_24)
                   1318:        need_hardreset = 1;
1.1.1.9   root     1319: 
1.1.1.17  root     1320:     last_address_space_24 = changed_prefs.address_space_24;
1.1.1.9   root     1321:     allocate_memory ();
                   1322: 
1.1.1.17  root     1323:     if (currprefs.rom_crc32 != changed_prefs.rom_crc32
                   1324:        || strcmp (currprefs.romfile, changed_prefs.romfile) != 0
                   1325:        || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0)
                   1326:     {
1.1.1.10  root     1327:        ersatzkickfile = 0;
1.1.1.17  root     1328:        a1000_handle_kickstart (0);
                   1329:        free (a1000_bootrom);
                   1330:        a1000_bootrom = 0;
                   1331:        a1000_kickstart_mode = 0;
                   1332: 
                   1333:        currprefs.rom_crc32 = changed_prefs.rom_crc32;
1.1.1.10  root     1334:        memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
                   1335:        memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
1.1.1.17  root     1336:        need_hardreset = 1;
1.1.1.12  root     1337:        if (!load_kickstart ()) {
1.1.1.10  root     1338:            init_ersatz_rom (kickmemory);
                   1339:            ersatzkickfile = 1;
                   1340:        }
1.1.1.17  root     1341:        patch_kick ();
1.1.1.12  root     1342:     }
1.1       root     1343: 
1.1.1.17  root     1344:     map_banks (&custom_bank, 0xC0, 0xE0 - 0xC0, 0);
1.1.1.9   root     1345:     map_banks (&cia_bank, 0xA0, 32, 0);
1.1.1.17  root     1346:     if (!currprefs.cs_a1000ram)
                   1347:        /* D80000 - DDFFFF not mapped (A1000 = custom chips) */
                   1348:        map_banks (&dummy_bank, 0xD8, 6, 0);
                   1349: 
                   1350:     /* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if PCMCIA or AGA) */
                   1351:     bnk = allocated_chipmem >> 16;
                   1352:     if (bnk < 0x20)
                   1353:        bnk = 0x20;
                   1354:     bnk_end = (currprefs.chipset_mask & CSMASK_AGA) ? 0xBF : 0xA0;
                   1355:     map_banks (&dummy_bank, bnk, bnk_end - bnk, 0);
                   1356:     if (currprefs.chipset_mask & CSMASK_AGA)
                   1357:        map_banks (&dummy_bank, 0xc0, 0xd8 - 0xc0, 0);
1.1.1.3   root     1358: 
1.1.1.9   root     1359:     if (bogomemory != 0) {
                   1360:        int t = allocated_bogomem >> 16;
                   1361:        if (t > 0x1C)
                   1362:            t = 0x1C;
1.1.1.17  root     1363:        if (t > 0x10 && ((currprefs.chipset_mask & CSMASK_AGA) || currprefs.cpu_model >= 68020))
                   1364:            t = 0x10;
1.1.1.9   root     1365:        map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
                   1366:     }
1.1.1.17  root     1367:     if (currprefs.cs_ide) {
                   1368:        if (currprefs.cs_ide == 1) {
                   1369:            map_banks (&gayle_bank, 0xD8, 6, 0);
                   1370:            map_banks (&gayle2_bank, 0xDD, 2, 0);
                   1371:            // map_banks (&gayle_attr_bank, 0xA0, 8, 0); only if PCMCIA card inserted */
                   1372:        }
                   1373:        if (currprefs.cs_ide == 2) {
                   1374:            map_banks (&gayle_bank, 0xDD, 1, 0);
                   1375:        }
                   1376:        if (currprefs.cs_ide < 0) {
                   1377:            map_banks (&gayle_bank, 0xD8, 6, 0);
                   1378:            map_banks (&gayle_bank, 0xDD, 1, 0);
                   1379:        }
                   1380:     }
                   1381:     if (currprefs.cs_rtc)
                   1382:        map_banks (&clock_bank, 0xDC, 1, 0);
                   1383:     if (currprefs.cs_fatgaryrev >= 0 || currprefs.cs_ramseyrev >= 0)
                   1384:        map_banks (&mbres_bank, 0xDE, 1, 0);
                   1385: 
                   1386:     if (a3000lmemory != 0)
                   1387:        map_banks (&a3000lmem_bank, a3000lmem_start >> 16, allocated_a3000lmem >> 16, 0);
                   1388:     if (a3000hmemory != 0)
                   1389:        map_banks (&a3000hmem_bank, a3000hmem_start >> 16, allocated_a3000hmem >> 16, 0);
                   1390: 
                   1391:     if (currprefs.bootrom) {
                   1392:        uae_boot_rom = 1;
                   1393:        map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
                   1394:     } else
                   1395:        uae_boot_rom = 0;
1.1.1.9   root     1396: 
                   1397:     map_banks (&kickmem_bank, 0xF8, 8, 0);
1.1.1.17  root     1398: 
                   1399:     a1000_reset ();
1.1.1.9   root     1400:     map_banks (&expamem_bank, 0xE8, 1, 0);
                   1401: 
1.1.1.17  root     1402:     /* Map the chipmem into all of the lower 8MB */
                   1403:     map_overlay (1);
                   1404: 
1.1.1.12  root     1405:     switch (extromtype ()) {
                   1406:     case EXTENDED_ROM_CDTV:
                   1407:        map_banks (&extendedkickmem_bank, 0xF0, 4, 0);
                   1408:        break;
                   1409:     case EXTENDED_ROM_CD32:
                   1410:        map_banks (&extendedkickmem_bank, 0xE0, 8, 0);
                   1411:        break;
                   1412:     default:
                   1413:        if (cloanto_rom)
                   1414:            map_banks (&kickmem_bank, 0xE0, 8, 0);
                   1415:     }
1.1.1.17  root     1416: 
                   1417:     if (need_hardreset)
                   1418:        memory_hardreset ();
1.1.1.9   root     1419: }
                   1420: 
                   1421: void memory_init (void)
                   1422: {
                   1423:     allocated_chipmem = 0;
                   1424:     allocated_bogomem = 0;
                   1425:     kickmemory = 0;
1.1.1.12  root     1426:     extendedkickmemory = 0;
1.1.1.9   root     1427:     chipmemory = 0;
1.1.1.17  root     1428:     allocated_a3000lmem = allocated_a3000hmem = 0;
                   1429:     a3000lmemory = a3000hmemory = 0;
1.1.1.9   root     1430:     bogomemory = 0;
                   1431: 
                   1432:     kickmemory = mapped_malloc (kickmem_size, "kick");
                   1433:     kickmem_bank.baseaddr = kickmemory;
1.1.1.3   root     1434: 
1.1.1.12  root     1435:     load_extendedkickstart ();
                   1436:     if (!load_kickstart ()) {
1.1.1.3   root     1437:        init_ersatz_rom (kickmemory);
1.1       root     1438:        ersatzkickfile = 1;
                   1439:     }
1.1.1.3   root     1440: 
1.1.1.9   root     1441:     init_mem_banks ();
                   1442:     memory_reset ();
1.1.1.4   root     1443: 
                   1444:     kickmem_mask = kickmem_size - 1;
1.1.1.12  root     1445:     extendedkickmem_mask = extendedkickmem_size - 1;
1.1       root     1446: }
                   1447: 
1.1.1.12  root     1448: void memory_cleanup (void)
1.1.1.10  root     1449: {
1.1.1.17  root     1450:     if (a3000lmemory)
                   1451:        mapped_free (a3000lmemory);
                   1452:     if (a3000hmemory)
                   1453:        mapped_free (a3000hmemory);
1.1.1.10  root     1454:     if (bogomemory)
                   1455:        mapped_free (bogomemory);
                   1456:     if (kickmemory)
                   1457:        mapped_free (kickmemory);
1.1.1.12  root     1458:     if (a1000_bootrom)
                   1459:        free (a1000_bootrom);
1.1.1.10  root     1460:     if (chipmemory)
                   1461:        mapped_free (chipmemory);
1.1.1.12  root     1462: 
1.1.1.17  root     1463:     a3000lmemory = a3000hmemory = 0;
1.1.1.10  root     1464:     bogomemory = 0;
                   1465:     kickmemory = 0;
1.1.1.12  root     1466:     a1000_bootrom = 0;
1.1.1.10  root     1467:     chipmemory = 0;
                   1468: }
                   1469: 
1.1.1.17  root     1470: void memory_hardreset (void)
                   1471: {
                   1472:     if (savestate_state == STATE_RESTORE)
                   1473:        return;
                   1474:     if (chipmemory)
                   1475:        memset (chipmemory, 0, allocated_chipmem);
                   1476:     if (bogomemory)
                   1477:        memset (bogomemory, 0, allocated_bogomem);
                   1478:     if (a3000lmemory)
                   1479:        memset (a3000lmemory, 0, allocated_a3000lmem);
                   1480:     if (a3000hmemory)
                   1481:        memset (a3000hmemory, 0, allocated_a3000hmem);
                   1482:     expansion_clear ();
                   1483: }
                   1484: 
1.1.1.9   root     1485: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1       root     1486: {
                   1487:     int bnr;
1.1.1.3   root     1488:     unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.12  root     1489:     addrbank *orgbank = bank;
1.1.1.9   root     1490:     uae_u32 realstart = start;
1.1.1.12  root     1491: 
                   1492:     flush_icache (1);          /* Sure don't want to keep any old mappings around! */
1.1.1.9   root     1493: #ifdef NATMEM_OFFSET
                   1494:     delete_shmmaps (start << 16, size << 16);
                   1495: #endif
1.1.1.12  root     1496: 
1.1.1.9   root     1497:     if (!realsize)
                   1498:        realsize = size << 16;
                   1499: 
                   1500:     if ((size << 16) < realsize) {
1.1.1.11  root     1501:        write_log ("Please report to [email protected], and mention:\n");
1.1.1.12  root     1502:        write_log ("Broken mapping, size=%x, realsize=%x\n", size, realsize);
                   1503:        write_log ("Start is %x\n", start);
1.1.1.11  root     1504:        write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9   root     1505:        abort ();
                   1506:     }
1.1.1.3   root     1507: 
                   1508:     if (start >= 0x100) {
1.1.1.10  root     1509:        int real_left = 0;
1.1.1.9   root     1510:        for (bnr = start; bnr < start + size; bnr++) {
                   1511:            if (!real_left) {
                   1512:                realstart = bnr;
1.1.1.12  root     1513:                real_left = realsize >> 16;
1.1.1.9   root     1514: #ifdef NATMEM_OFFSET
                   1515:                add_shmmaps (realstart << 16, bank);
                   1516: #endif
                   1517:            }
1.1.1.12  root     1518:            put_mem_bank (bnr << 16, bank, realstart << 16);
1.1.1.9   root     1519:            real_left--;
                   1520:        }
1.1.1.3   root     1521:        return;
                   1522:     }
1.1.1.17  root     1523:     /* Already in currprefs, since we get called after m68k_reset.  */
                   1524:     if (last_address_space_24)
1.1.1.10  root     1525:        endhioffs = 0x10000;
1.1.1.9   root     1526:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10  root     1527:        int real_left = 0;
1.1.1.12  root     1528:        for (bnr = start; bnr < start + size; bnr++) {
1.1.1.9   root     1529:            if (!real_left) {
                   1530:                realstart = bnr + hioffs;
                   1531:                real_left = realsize >> 16;
                   1532: #ifdef NATMEM_OFFSET
                   1533:                add_shmmaps (realstart << 16, bank);
                   1534: #endif
                   1535:            }
1.1.1.12  root     1536:            put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1.1.1.9   root     1537:            real_left--;
                   1538:        }
                   1539:     }
                   1540: }
                   1541: 
                   1542: 
                   1543: /* memory save/restore code */
                   1544: 
                   1545: uae_u8 *save_cram (int *len)
                   1546: {
                   1547:     *len = allocated_chipmem;
                   1548:     return chipmemory;
                   1549: }
                   1550: 
                   1551: uae_u8 *save_bram (int *len)
                   1552: {
                   1553:     *len = allocated_bogomem;
                   1554:     return bogomemory;
                   1555: }
                   1556: 
1.1.1.17  root     1557: uae_u8 *save_a3000lram (int *len)
                   1558: {
                   1559:     *len = allocated_a3000lmem;
                   1560:     return a3000lmemory;
                   1561: }
                   1562: 
                   1563: uae_u8 *save_a3000hram (int *len)
                   1564: {
                   1565:     *len = allocated_a3000hmem;
                   1566:     return a3000hmemory;
                   1567: }
                   1568: 
1.1.1.9   root     1569: void restore_cram (int len, long filepos)
                   1570: {
                   1571:     chip_filepos = filepos;
                   1572:     changed_prefs.chipmem_size = len;
                   1573: }
                   1574: 
                   1575: void restore_bram (int len, long filepos)
                   1576: {
                   1577:     bogo_filepos = filepos;
                   1578:     changed_prefs.bogomem_size = len;
                   1579: }
                   1580: 
1.1.1.17  root     1581: void restore_a3000lram (int len, size_t filepos)
                   1582: {
                   1583:     a3000lmem_filepos = filepos;
                   1584:     changed_prefs.mbresmem_low_size = len;
                   1585: }
                   1586: 
                   1587: void restore_a3000hram (int len, size_t filepos)
                   1588: {
                   1589:     a3000hmem_filepos = filepos;
                   1590:     changed_prefs.mbresmem_high_size = len;
                   1591: }
                   1592: 
1.1.1.16  root     1593: const uae_u8 *restore_rom (const uae_u8 *src)
1.1.1.9   root     1594: {
1.1.1.17  root     1595:     struct romdata *rom;
1.1.1.15  root     1596:     uae_u32 crc32;
1.1.1.17  root     1597:     char *romname;
1.1.1.15  root     1598:     int i;
                   1599: 
1.1.1.9   root     1600:     restore_u32 ();
                   1601:     restore_u32 ();
                   1602:     restore_u32 ();
                   1603:     restore_u32 ();
1.1.1.15  root     1604:     crc32 = restore_u32 ();
                   1605: 
1.1.1.17  root     1606:     rom = getromdatabycrc (crc32);
                   1607:     if (rom)
                   1608:        changed_prefs.rom_crc32 = crc32;
1.1.1.9   root     1609: 
                   1610:     return src;
                   1611: }
                   1612: 
1.1.1.15  root     1613: uae_u8 *save_rom (int first, int *len, uae_u8 *dstptr)
1.1.1.9   root     1614: {
                   1615:     static int count;
                   1616:     uae_u8 *dst, *dstbak;
                   1617:     uae_u8 *mem_real_start;
                   1618:     int mem_start, mem_size, mem_type, i, saverom;
                   1619: 
                   1620:     saverom = 0;
1.1.1.12  root     1621:     if (first)
                   1622:        count = 0;
1.1.1.9   root     1623:     for (;;) {
                   1624:        mem_type = count;
1.1.1.12  root     1625:        switch (count) {
                   1626:        case 0:         /* Kickstart ROM */
1.1.1.9   root     1627:            mem_start = 0xf80000;
                   1628:            mem_real_start = kickmemory;
                   1629:            mem_size = kickmem_size;
                   1630:            /* 256KB or 512KB ROM? */
1.1.1.12  root     1631:            for (i = 0; i < mem_size / 2 - 4; i++) {
                   1632:                if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
                   1633:                    break;
1.1.1.9   root     1634:            }
1.1.1.12  root     1635:            if (i == mem_size / 2 - 4) {
1.1.1.9   root     1636:                mem_size /= 2;
                   1637:                mem_start += 262144;
                   1638:            }
                   1639:            mem_type = 0;
                   1640:            break;
1.1.1.12  root     1641:        default:
1.1.1.9   root     1642:            return 0;
                   1643:        }
1.1.1.12  root     1644:        count++;
                   1645:        if (mem_size)
                   1646:            break;
1.1.1.9   root     1647:     }
1.1.1.15  root     1648:     if (dstptr)
                   1649:        dstbak = dst = dstptr;
                   1650:     else
                   1651:        dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
1.1.1.9   root     1652:     save_u32 (mem_start);
                   1653:     save_u32 (mem_size);
                   1654:     save_u32 (mem_type);
1.1.1.12  root     1655:     save_u32 (longget (mem_start + 12));       /* version+revision */
1.1.1.15  root     1656:     save_u32 (get_crc32 (kickmemory, mem_size));
1.1.1.12  root     1657:     sprintf (dst, "Kickstart %d.%d", wordget (mem_start + 12), wordget (mem_start + 14));
1.1.1.9   root     1658:     dst += strlen (dst) + 1;
                   1659:     if (saverom) {
1.1.1.12  root     1660:        for (i = 0; i < mem_size; i++)
                   1661:            *dst++ = byteget (mem_start + i);
1.1.1.9   root     1662:     }
                   1663:     *len = dst - dstbak;
                   1664:     return dstbak;
1.1       root     1665: }
1.1.1.17  root     1666: 
                   1667: /* memory helpers */
                   1668: 
                   1669: static int addr_valid (char *txt, uaecptr addr, uae_u32 len)
                   1670: {
                   1671:     addrbank *ab = &get_mem_bank (addr);
                   1672:     if (ab == 0 || addr < 0x100
                   1673:        || len < 0 || len > 16777215 || !valid_address (addr, len)) {
                   1674:        write_log ("corrupt %s pointer %x (%d) detected!\n", txt, addr, len);
                   1675:        return 0;
                   1676:     }
                   1677:     return 1;
                   1678: }
                   1679: 
                   1680: void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size)
                   1681: {
                   1682:     if (!addr_valid ("memcpyha", dst, size))
                   1683:        return;
                   1684:     while (size--)
                   1685:        put_byte (dst++, *src++);
                   1686: }
                   1687: 
                   1688: void memcpyha (uaecptr dst, const uae_u8 *src, int size)
                   1689: {
                   1690:     while (size--)
                   1691:        put_byte (dst++, *src++);
                   1692: }
                   1693: 
                   1694: void memcpyah_safe (uae_u8 *dst, uaecptr src, int size)
                   1695: {
                   1696:     if (!addr_valid ("memcpyah", src, size))
                   1697:        return;
                   1698:     while (size--)
                   1699:        *dst++ = get_byte (src++);
                   1700: }
                   1701: 
                   1702: void memcpyah (uae_u8 *dst, uaecptr src, int size)
                   1703: {
                   1704:     while (size--)
                   1705:        *dst++ = get_byte (src++);
                   1706: }
                   1707: 
                   1708: char *strcpyah_safe (char *dst, uaecptr src)
                   1709: {
                   1710:     char *res = dst;
                   1711:     uae_u8 b;
                   1712:     do {
                   1713:        if (!addr_valid ("strcpyah", src, 1))
                   1714:            return res;
                   1715:        b = get_byte (src++);
                   1716:        *dst++ = b;
                   1717:     } while (b);
                   1718:     return res;
                   1719: }
                   1720: 
                   1721: uaecptr strcpyha_safe (uaecptr dst, const char *src)
                   1722: {
                   1723:     uaecptr res = dst;
                   1724:     uae_u8 b;
                   1725:     do {
                   1726:        if (!addr_valid ("strcpyha", dst, 1))
                   1727:            return res;
                   1728:        b = *src++;
                   1729:        put_byte (dst++, b);
                   1730:     } while (b);
                   1731:     return res;
                   1732: }
                   1733: 
1.1.1.18! root     1734: #if 0
1.1.1.17  root     1735: uae_u32 strncpyha (uae_u32 dst, const char *src, int size)
                   1736: {
                   1737:     uae_u32 res = dst;
                   1738:     while (size--) {
                   1739:        put_byte (dst++, *src);
                   1740:        if (!*src++)
                   1741:            return res;
                   1742:     }
                   1743:     return res;
                   1744: }
1.1.1.18! root     1745: #endif
1.1.1.17  root     1746: 
                   1747: uae_u32 strncpyha_safe (uae_u32 dst, const char *src, int size)
                   1748: {
                   1749:     uae_u32 res = dst;
                   1750:     while (size--) {
                   1751:        if (!addr_valid ("strcpyha", dst, 1))
                   1752:            return res;
                   1753:        put_byte (dst++, *src);
                   1754:        if (!*src++)
                   1755:            return res;
                   1756:     }
                   1757:     return res;
                   1758: }

unix.superglobalmegacorp.com

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