Annotation of hatari/src/uae-cpu/memory.c, revision 1.1.1.3

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Memory management
                      5:   *
                      6:   * (c) 1995 Bernd Schmidt
1.1.1.2   root        7:   *
                      8:   * Adaptation to Hatari by Thomas Huth
1.1       root        9:   */
                     10: 
                     11: /*#include "sysconfig.h"*/
                     12: #include "sysdeps.h"
                     13: #include "hatari-glue.h"
                     14: #include "maccess.h"
                     15: #include "memory.h"
                     16: #include "../includes/tos.h"
1.1.1.3 ! root       17: #include "../includes/intercept.h"
        !            18: #include "../includes/reset.h"
        !            19: 
1.1       root       20: #ifdef USE_MAPPED_MEMORY
                     21: #include <sys/mman.h>
                     22: #endif
                     23: 
                     24: 
                     25: extern   unsigned char STRam[16*1024*1024];  /* See hatari.c */
                     26: 
                     27: 
                     28: /* Set by each memory handler that does not simply access real memory.  */
                     29: int special_mem;
                     30: 
                     31: uae_u32 allocated_STmem;
                     32: uae_u32 allocated_TTmem;
                     33: 
                     34: uae_u32 STmem_mask, ROMmem_mask, IOmem_mask, TTmem_mask;
                     35: 
                     36: 
                     37: #ifdef SAVE_MEMORY_BANKS
                     38: addrbank *mem_banks[65536];
                     39: #else
                     40: addrbank mem_banks[65536];
                     41: #endif
                     42: 
                     43: #ifdef NO_INLINE_MEMORY_ACCESS
                     44: __inline__ uae_u32 longget (uaecptr addr)
                     45: {
                     46:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
                     47: }
                     48: __inline__ uae_u32 wordget (uaecptr addr)
                     49: {
                     50:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
                     51: }
                     52: __inline__ uae_u32 byteget (uaecptr addr)
                     53: {
                     54:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
                     55: }
                     56: __inline__ void longput (uaecptr addr, uae_u32 l)
                     57: {
                     58:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
                     59: }
                     60: __inline__ void wordput (uaecptr addr, uae_u32 w)
                     61: {
                     62:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
                     63: }
                     64: __inline__ void byteput (uaecptr addr, uae_u32 b)
                     65: {
                     66:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
                     67: }
                     68: #endif
                     69: 
                     70: 
                     71: /* A dummy bank that only contains zeros */
                     72: 
                     73: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                     74: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                     75: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                     76: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                     77: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                     78: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                     79: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                     80: 
                     81: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                     82: {
                     83:     special_mem |= S_READ;
                     84:     if (illegal_mem)
1.1.1.3 ! root       85:        write_log ("Illegal lget at %08lx\n", (long)addr);
1.1       root       86: 
                     87:     return 0;
                     88: }
                     89: 
                     90: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
                     91: {
                     92:     special_mem |= S_READ;
                     93:     if (illegal_mem)
1.1.1.3 ! root       94:        write_log ("Illegal wget at %08lx\n", (long)addr);
1.1       root       95: 
                     96:     return 0;
                     97: }
                     98: 
                     99: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
                    100: {
                    101:     special_mem |= S_READ;
                    102:     if (illegal_mem)
1.1.1.3 ! root      103:        write_log ("Illegal bget at %08lx\n", (long)addr);
1.1       root      104: 
                    105:     return 0;
                    106: }
                    107: 
                    108: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
                    109: {
                    110:     special_mem |= S_WRITE;
                    111:     if (illegal_mem)
1.1.1.3 ! root      112:        write_log ("Illegal lput at %08lx\n", (long)addr);
1.1       root      113: }
                    114: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
                    115: {
                    116:     special_mem |= S_WRITE;
                    117:     if (illegal_mem)
1.1.1.3 ! root      118:        write_log ("Illegal wput at %08lx\n", (long)addr);
1.1       root      119: }
                    120: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
                    121: {
                    122:     special_mem |= S_WRITE;
                    123:     if (illegal_mem)
1.1.1.3 ! root      124:        write_log ("Illegal bput at %08lx\n", (long)addr);
1.1       root      125: }
                    126: 
                    127: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
                    128: {
                    129:     if (illegal_mem)
1.1.1.3 ! root      130:        write_log ("Illegal check at %08lx\n", (long)addr);
1.1       root      131: 
                    132:     return 0;
                    133: }
                    134: 
                    135: 
                    136: /* ST RAM memory */
                    137: 
                    138: uae_u8 *STmemory;
                    139: 
                    140: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    141: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
                    142: 
                    143: uae_u32 REGPARAM2 STmem_lget (uaecptr addr)
                    144: {
                    145:     uae_u32 *m;
                    146: 
                    147:     addr -= STmem_start & STmem_mask;
                    148:     addr &= STmem_mask;
                    149:     m = (uae_u32 *)(STmemory + addr);
                    150:     return do_get_mem_long (m);
                    151: }
                    152: 
                    153: uae_u32 REGPARAM2 STmem_wget (uaecptr addr)
                    154: {
                    155:     uae_u16 *m;
                    156: 
                    157:     addr -= STmem_start & STmem_mask;
                    158:     addr &= STmem_mask;
                    159:     m = (uae_u16 *)(STmemory + addr);
                    160:     return do_get_mem_word (m);
                    161: }
                    162: 
                    163: uae_u32 REGPARAM2 STmem_bget (uaecptr addr)
                    164: {
                    165:     addr -= STmem_start & STmem_mask;
                    166:     addr &= STmem_mask;
                    167:     return STmemory[addr];
                    168: }
                    169: 
                    170: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l)
                    171: {
                    172:     uae_u32 *m;
                    173: 
                    174:     addr -= STmem_start & STmem_mask;
                    175:     addr &= STmem_mask;
                    176:     m = (uae_u32 *)(STmemory + addr);
                    177:     do_put_mem_long (m, l);
                    178: }
                    179: 
                    180: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w)
                    181: {
                    182:     uae_u16 *m;
                    183: 
                    184:     addr -= STmem_start & STmem_mask;
                    185:     addr &= STmem_mask;
                    186:     m = (uae_u16 *)(STmemory + addr);
                    187:     do_put_mem_word (m, w);
                    188: }
                    189: 
                    190: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b)
                    191: {
                    192:     addr -= STmem_start & STmem_mask;
                    193:     addr &= STmem_mask;
                    194:     STmemory[addr] = b;
                    195: }
                    196: 
                    197: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size)
                    198: {
                    199:     addr -= STmem_start & STmem_mask;
                    200:     addr &= STmem_mask;
                    201:     return (addr + size) <= allocated_STmem;
                    202: }
                    203: 
                    204: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr)
                    205: {
                    206:     addr -= STmem_start & STmem_mask;
                    207:     addr &= STmem_mask;
                    208:     return STmemory + addr;
                    209: }
                    210: 
                    211: 
                    212: /* TT fast memory */
                    213: 
                    214: static uae_u8 *TTmemory;
                    215: 
                    216: static uae_u32 TTmem_lget (uaecptr) REGPARAM;
                    217: static uae_u32 TTmem_wget (uaecptr) REGPARAM;
                    218: static uae_u32 TTmem_bget (uaecptr) REGPARAM;
                    219: static void TTmem_lput (uaecptr, uae_u32) REGPARAM;
                    220: static void TTmem_wput (uaecptr, uae_u32) REGPARAM;
                    221: static void TTmem_bput (uaecptr, uae_u32) REGPARAM;
                    222: static int TTmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    223: static uae_u8 *TTmem_xlate (uaecptr addr) REGPARAM;
                    224: 
                    225: uae_u32 REGPARAM2 TTmem_lget (uaecptr addr)
                    226: {
                    227:     uae_u32 *m;
                    228:     addr -= TTmem_start & TTmem_mask;
                    229:     addr &= TTmem_mask;
                    230:     m = (uae_u32 *)(TTmemory + addr);
                    231:     return do_get_mem_long (m);
                    232: }
                    233: 
                    234: uae_u32 REGPARAM2 TTmem_wget (uaecptr addr)
                    235: {
                    236:     uae_u16 *m;
                    237:     addr -= TTmem_start & TTmem_mask;
                    238:     addr &= TTmem_mask;
                    239:     m = (uae_u16 *)(TTmemory + addr);
                    240:     return do_get_mem_word (m);
                    241: }
                    242: 
                    243: uae_u32 REGPARAM2 TTmem_bget (uaecptr addr)
                    244: {
                    245:     addr -= TTmem_start & TTmem_mask;
                    246:     addr &= TTmem_mask;
                    247:     return TTmemory[addr];
                    248: }
                    249: 
                    250: void REGPARAM2 TTmem_lput (uaecptr addr, uae_u32 l)
                    251: {
                    252:     uae_u32 *m;
                    253:     addr -= TTmem_start & TTmem_mask;
                    254:     addr &= TTmem_mask;
                    255:     m = (uae_u32 *)(TTmemory + addr);
                    256:     do_put_mem_long (m, l);
                    257: }
                    258: 
                    259: void REGPARAM2 TTmem_wput (uaecptr addr, uae_u32 w)
                    260: {
                    261:     uae_u16 *m;
                    262:     addr -= TTmem_start & TTmem_mask;
                    263:     addr &= TTmem_mask;
                    264:     m = (uae_u16 *)(TTmemory + addr);
                    265:     do_put_mem_word (m, w);
                    266: }
                    267: 
                    268: void REGPARAM2 TTmem_bput (uaecptr addr, uae_u32 b)
                    269: {
                    270:     addr -= TTmem_start & TTmem_mask;
                    271:     addr &= TTmem_mask;
                    272:     TTmemory[addr] = b;
                    273: }
                    274: 
                    275: int REGPARAM2 TTmem_check (uaecptr addr, uae_u32 size)
                    276: {
                    277:     addr -= TTmem_start & TTmem_mask;
                    278:     addr &= TTmem_mask;
                    279:     return (addr + size) <= allocated_TTmem;
                    280: }
                    281: 
                    282: uae_u8 REGPARAM2 *TTmem_xlate(uaecptr addr)
                    283: {
                    284:     addr -= TTmem_start & TTmem_mask;
                    285:     addr &= TTmem_mask;
                    286:     return TTmemory + addr;
                    287: }
                    288: 
                    289: /* ROM memory */
                    290: 
                    291: uae_u8 *ROMmemory;
                    292: 
                    293: static uae_u32 ROMmem_lget (uaecptr) REGPARAM;
                    294: static uae_u32 ROMmem_wget (uaecptr) REGPARAM;
                    295: static uae_u32 ROMmem_bget (uaecptr) REGPARAM;
                    296: static void  ROMmem_lput (uaecptr, uae_u32) REGPARAM;
                    297: static void  ROMmem_wput (uaecptr, uae_u32) REGPARAM;
                    298: static void  ROMmem_bput (uaecptr, uae_u32) REGPARAM;
                    299: static int  ROMmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    300: static uae_u8 *ROMmem_xlate (uaecptr addr) REGPARAM;
                    301: 
                    302: uae_u32 REGPARAM2 ROMmem_lget (uaecptr addr)
                    303: {
                    304:     uae_u32 *m;
                    305:     addr -= ROMmem_start & ROMmem_mask;
                    306:     addr &= ROMmem_mask;
                    307:     m = (uae_u32 *)(ROMmemory + addr);
                    308:     return do_get_mem_long (m);
                    309: }
                    310: 
                    311: uae_u32 REGPARAM2 ROMmem_wget (uaecptr addr)
                    312: {
                    313:     uae_u16 *m;
                    314:     addr -= ROMmem_start & ROMmem_mask;
                    315:     addr &= ROMmem_mask;
                    316:     m = (uae_u16 *)(ROMmemory + addr);
                    317:     return do_get_mem_word (m);
                    318: }
                    319: 
                    320: uae_u32 REGPARAM2 ROMmem_bget (uaecptr addr)
                    321: {
                    322:     addr -= ROMmem_start & ROMmem_mask;
                    323:     addr &= ROMmem_mask;
                    324:     return ROMmemory[addr];
                    325: }
                    326: 
                    327: void REGPARAM2 ROMmem_lput (uaecptr addr, uae_u32 b)
                    328: {
                    329:     if (illegal_mem)
1.1.1.3 ! root      330:        write_log ("Illegal ROMmem lput at %08lx\n", (long)addr);
1.1       root      331: }
                    332: 
                    333: void REGPARAM2 ROMmem_wput (uaecptr addr, uae_u32 b)
                    334: {
                    335:     if (illegal_mem)
1.1.1.3 ! root      336:        write_log ("Illegal ROMmem wput at %08lx\n", (long)addr);
1.1       root      337: }
                    338: 
                    339: void REGPARAM2 ROMmem_bput (uaecptr addr, uae_u32 b)
                    340: {
                    341:     if (illegal_mem)
1.1.1.3 ! root      342:        write_log ("Illegal ROMmem lput at %08lx\n", (long)addr);
1.1       root      343: }
                    344: 
                    345: int REGPARAM2 ROMmem_check (uaecptr addr, uae_u32 size)
                    346: {
                    347:     addr -= ROMmem_start & ROMmem_mask;
                    348:     addr &= ROMmem_mask;
                    349:     return (addr + size) <= ROMmem_size;
                    350: }
                    351: 
                    352: uae_u8 REGPARAM2 *ROMmem_xlate (uaecptr addr)
                    353: {
                    354:     addr -= ROMmem_start & ROMmem_mask;
                    355:     addr &= ROMmem_mask;
                    356:     return ROMmemory + addr;
                    357: }
                    358: 
                    359: 
                    360: /* Hardware IO memory */
                    361: /* see also intercept.c */
                    362: 
                    363: uae_u8 *IOmemory;
                    364: 
                    365: static int  IOmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    366: static uae_u8 *IOmem_xlate (uaecptr addr) REGPARAM;
                    367: 
                    368: int REGPARAM2 IOmem_check (uaecptr addr, uae_u32 size)
                    369: {
                    370:     addr -= IOmem_start & IOmem_mask;
                    371:     addr &= IOmem_mask;
                    372:     return (addr + size) <= IOmem_size;
                    373: }
                    374: 
                    375: uae_u8 REGPARAM2 *IOmem_xlate (uaecptr addr)
                    376: {
                    377:     addr -= IOmem_start & IOmem_mask;
                    378:     addr &= IOmem_mask;
                    379:     return IOmemory + addr;
                    380: }
                    381: 
                    382: 
                    383: 
                    384: /* Default memory access functions */
                    385: 
                    386: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
                    387: {
                    388:     return 0;
                    389: }
                    390: 
                    391: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
                    392: {
                    393:     write_log ("Your Atari program just did something terribly stupid\n");
                    394:     Reset_Warm();
                    395:     return ROMmem_xlate (get_long (0xFC0000)); /* So we don't crash. */
                    396: }
                    397: 
                    398: 
                    399: /* Address banks */
                    400: 
                    401: addrbank dummy_bank = {
                    402:     dummy_lget, dummy_wget, dummy_bget,
                    403:     dummy_lput, dummy_wput, dummy_bput,
                    404:     default_xlate, dummy_check
                    405: };
                    406: 
                    407: addrbank STmem_bank = {
                    408:     STmem_lget, STmem_wget, STmem_bget,
                    409:     STmem_lput, STmem_wput, STmem_bput,
                    410:     STmem_xlate, STmem_check
                    411: };
                    412: 
                    413: addrbank TTmem_bank = {
                    414:     TTmem_lget, TTmem_wget, TTmem_bget,
                    415:     TTmem_lput, TTmem_wput, TTmem_bput,
                    416:     TTmem_xlate, TTmem_check
                    417: };
                    418: 
                    419: addrbank ROMmem_bank = {
                    420:     ROMmem_lget, ROMmem_wget, ROMmem_bget,
                    421:     ROMmem_lput, ROMmem_wput, ROMmem_bput,
                    422:     ROMmem_xlate, ROMmem_check
                    423: };
                    424: 
                    425: addrbank IOmem_bank = {
                    426:     Intercept_ReadLong, Intercept_ReadWord, Intercept_ReadByte,
                    427:     Intercept_WriteLong, Intercept_WriteWord, Intercept_WriteByte,
                    428:     IOmem_xlate, IOmem_check
                    429: };
                    430: 
                    431: 
                    432: char *address_space, *good_address_map;
                    433: int good_address_fd;
                    434: 
                    435: static void init_mem_banks (void)
                    436: {
                    437:     int i;
                    438:     for (i = 0; i < 65536; i++)
                    439:        put_mem_bank (i<<16, &dummy_bank);
                    440: }
                    441: 
                    442: #define MAKE_USER_PROGRAMS_BEHAVE 1
                    443: void memory_init (void)
                    444: {
1.1.1.3 ! root      445: /*
1.1       root      446:     char buffer[4096];
                    447:     char *nam;
                    448:     int i, fd;
1.1.1.3 ! root      449: */
1.1       root      450: 
                    451:     allocated_STmem = STmem_size;
                    452:     allocated_TTmem = TTmem_size;
                    453: 
                    454: #ifdef USE_MAPPED_MEMORY
                    455: #error So nicht
                    456:     fd = open ("/dev/zero", O_RDWR);
                    457:     good_address_map = mmap (NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
                    458:     /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon
                    459:      * as a decrunch routine tries to do color register hacks. */
                    460:     address_space = mmap (NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0);
                    461:     if ((int)address_space < 0 || (int)good_address_map < 0) {
                    462:        write_log ("Your system does not have enough virtual memory - increase swap.\n");
                    463:        abort ();
                    464:     }
                    465: #ifdef MAKE_USER_PROGRAMS_BEHAVE
                    466:     memset (address_space + 0xDFF180, 0xFF, 32*2);
                    467: #else
                    468:     /* Likewise. This is mostly for mouse button checks. */
                    469:     if (USER_PROGRAMS_BEHAVE)
                    470:        memset (address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000);
                    471: #endif
                    472:     STmemory = mmap (address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
1.1.1.2   root      473:     ROMmemory = mmap (address_space + ROMmem_start, ROMmem_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
1.1       root      474: 
                    475:     close(fd);
                    476: 
                    477:     good_address_fd = open (nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600);
                    478:     memset (buffer, 1, sizeof(buffer));
                    479:     write (good_address_fd, buffer, sizeof buffer);
                    480:     unlink (nam);
                    481: 
                    482:     for (i = 0; i < allocated_STmem; i += 4096)
                    483:        mmap (good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
                    484:              good_address_fd, 0);
                    485:     for (i = 0; i < ROMmem_size; i += 4096)
                    486:        mmap (good_address_map + i + 0x1000000 - ROMmem_size, 4096, PROT_READ,
                    487:              MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
                    488: #else
1.1.1.2   root      489:     ROMmemory = STRam+ROMmem_start;  /*(uae_u8 *)malloc (ROMmem_size)*/;
1.1       root      490:     STmemory = STRam; /*(uae_u8 *)malloc (allocated_STmem);*/
                    491: /*
                    492:     while (! STmemory && allocated_STmem > 512*1024) {
                    493:        allocated_STmem >>= 1;
                    494:        STmemory = (uae_u8 *)malloc (allocated_STmem);
                    495:        if (STmemory)
                    496:            fprintf (stderr, "Reducing STmem size to %dkb\n", allocated_STmem >> 10);
                    497:     }
                    498:     if (! STmemory) {
                    499:        write_log ("virtual memory exhausted (STmemory)!\n");
                    500:        abort ();
                    501:     }
                    502: */
                    503: #endif
                    504: 
                    505:     init_mem_banks ();
                    506: 
                    507:     /* Map the STmem into all of the lower 16MB */
                    508:     map_banks (&STmem_bank, 0x00, 256);
                    509: 
                    510:     if (allocated_TTmem > 0)
                    511:        TTmemory = (uae_u8 *)malloc (allocated_TTmem);
                    512:     if (TTmemory != 0)
                    513:        map_banks (&TTmem_bank, TTmem_start >> 16, allocated_TTmem >> 16);
                    514:     else
                    515:        allocated_TTmem = 0;
                    516: 
                    517:     map_banks(&ROMmem_bank, ROMmem_start >> 16, ROMmem_size/65536);
                    518: /*    map_banks(&ROMmem_bank, 0xFFFC, 4);*/
                    519: 
                    520:     map_banks(&IOmem_bank, IOmem_start>>16, 1);
                    521: 
1.1.1.2   root      522:     STmem_mask = 0x00ffffff;
                    523:     ROMmem_mask = 0x00ffffff;
1.1       root      524:     TTmem_mask = allocated_TTmem - 1;
                    525:     IOmem_mask = IOmem_size - 1;
                    526: }
                    527: 
                    528: void map_banks (addrbank *bank, int start, int size)
                    529: {
                    530:     int bnr;
                    531:     unsigned long int hioffs = 0, endhioffs = 0x100;
                    532: 
                    533:     if (start >= 0x100) {
                    534:        for (bnr = start; bnr < start + size; bnr++)
                    535:            put_mem_bank (bnr << 16, bank);
                    536:        return;
                    537:     }
                    538:     /* Some ROMs apparently require a 24 bit address space... */
                    539:     if (address_space_24)
                    540:        endhioffs = 0x10000;
                    541:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
                    542:        for (bnr = start; bnr < start+size; bnr++)
                    543:            put_mem_bank ((bnr + hioffs) << 16, bank);
                    544: }

unix.superglobalmegacorp.com

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