Annotation of frontvm/cpu/memory.c, revision 1.1.1.1

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator - CPU core
                      3:   *
                      4:   * Memory management
                      5:   *
                      6:   * (c) 1995 Bernd Schmidt
                      7:   *
                      8:   * Adaptation to Hatari by Thomas Huth
                      9:   *
                     10:   * This file is distributed under the GNU Public License, version 2 or at
                     11:   * your option any later version. Read the file gpl.txt for details.
                     12:   */
                     13: static char rcsid[] = "Hatari $Id: memory.c,v 1.12 2003/04/05 22:25:03 thothy Exp $";
                     14: 
                     15: #include "sysdeps.h"
                     16: #include "hatari-glue.h"
                     17: #include "maccess.h"
                     18: #include "memory.h"
                     19: #include "../hardware/main.h"
                     20: #include "../hardware/reset.h"
                     21: #include "../hardware/decode.h"
                     22: #include "../hardware/m68000.h"
                     23: #include "newcpu.h"
                     24: 
                     25: 
                     26: uae_u32 STmem_size;
                     27: 
                     28: #define STmem_start  0x00000000
                     29: 
                     30: #define STmem_mask  0x00ffffff
                     31: 
                     32: 
                     33: #ifdef SAVE_MEMORY_BANKS
                     34: addrbank *mem_banks[65536];
                     35: #else
                     36: addrbank mem_banks[65536];
                     37: #endif
                     38: 
                     39: #ifdef NO_INLINE_MEMORY_ACCESS
                     40: __inline__ uae_u32 longget (uaecptr addr)
                     41: {
                     42:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
                     43: }
                     44: __inline__ uae_u32 wordget (uaecptr addr)
                     45: {
                     46:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
                     47: }
                     48: __inline__ uae_u32 byteget (uaecptr addr)
                     49: {
                     50:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
                     51: }
                     52: __inline__ void longput (uaecptr addr, uae_u32 l)
                     53: {
                     54:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
                     55: }
                     56: __inline__ void wordput (uaecptr addr, uae_u32 w)
                     57: {
                     58:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
                     59: }
                     60: __inline__ void byteput (uaecptr addr, uae_u32 b)
                     61: {
                     62:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
                     63: }
                     64: #endif
                     65: 
                     66: 
                     67: /* Some prototypes: */
                     68: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                     69: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
                     70: 
                     71: 
                     72: /* A dummy bank that only contains zeros */
                     73: 
                     74: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                     75: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                     76: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                     77: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                     78: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                     79: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                     80: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                     81: 
                     82: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                     83: {
                     84:     if (illegal_mem)
                     85:        write_log ("Illegal lget at %08lx\n", (long)addr);
                     86: 
                     87:     return 0;
                     88: }
                     89: 
                     90: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
                     91: {
                     92:     if (illegal_mem)
                     93:        write_log ("Illegal wget at %08lx\n", (long)addr);
                     94: 
                     95:     return 0;
                     96: }
                     97: 
                     98: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
                     99: {
                    100:     if (illegal_mem)
                    101:        write_log ("Illegal bget at %08lx\n", (long)addr);
                    102: 
                    103:     return 0;
                    104: }
                    105: 
                    106: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
                    107: {
                    108:     if (illegal_mem)
                    109:        write_log ("Illegal lput at %08lx\n", (long)addr);
                    110: }
                    111: 
                    112: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
                    113: {
                    114:     if (illegal_mem)
                    115:        write_log ("Illegal wput at %08lx\n", (long)addr);
                    116: }
                    117: 
                    118: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
                    119: {
                    120:     if (illegal_mem)
                    121:        write_log ("Illegal bput at %08lx\n", (long)addr);
                    122: }
                    123: 
                    124: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
                    125: {
                    126:     if (illegal_mem)
                    127:        write_log ("Illegal check at %08lx\n", (long)addr);
                    128: 
                    129:     return 0;
                    130: }
                    131: 
                    132: uae_u8 REGPARAM2 *dummy_xlate (uaecptr addr)
                    133: {
                    134:     write_log("Your Atari program just did something terribly stupid:"
                    135:               " dummy_xlate($%x)\n", addr);
                    136:     /*Reset_Warm();*/
                    137:     return STmem_xlate(addr);  /* So we don't crash. */
                    138: }
                    139: 
                    140: 
                    141: /* **** This memory bank only generates bus errors **** */
                    142: 
                    143: uae_u32 REGPARAM2 BusErrMem_lget(uaecptr addr)
                    144: {
                    145:     if (illegal_mem)
                    146:        write_log ("Bus error lget at %08lx\n", (long)addr);
                    147: 
                    148:     M68000_Crash (2);
                    149:     return 0;
                    150: }
                    151: 
                    152: uae_u32 REGPARAM2 BusErrMem_wget(uaecptr addr)
                    153: {
                    154:     if (illegal_mem)
                    155:        write_log ("Bus error wget at %08lx\n", (long)addr);
                    156: 
                    157:     M68000_Crash (2);
                    158:     return 0;
                    159: }
                    160: 
                    161: uae_u32 REGPARAM2 BusErrMem_bget(uaecptr addr)
                    162: {
                    163:     if (illegal_mem)
                    164:        write_log ("Bus error bget at %08lx\n", (long)addr);
                    165: 
                    166:     M68000_Crash (2);
                    167:     return 0;
                    168: }
                    169: 
                    170: void REGPARAM2 BusErrMem_lput(uaecptr addr, uae_u32 l)
                    171: {
                    172:     if (illegal_mem)
                    173:        write_log ("Bus error lput at %08lx\n", (long)addr);
                    174: 
                    175:     M68000_Crash (2);
                    176: }
                    177: 
                    178: void REGPARAM2 BusErrMem_wput(uaecptr addr, uae_u32 w)
                    179: {
                    180:     if (illegal_mem)
                    181:        write_log ("Bus error wput at %08lx\n", (long)addr);
                    182: 
                    183:     M68000_Crash (2);
                    184: }
                    185: 
                    186: void REGPARAM2 BusErrMem_bput(uaecptr addr, uae_u32 b)
                    187: {
                    188:     if (illegal_mem)
                    189:        write_log ("Bus error bput at %08lx\n", (long)addr);
                    190: 
                    191:     M68000_Crash (2);
                    192: }
                    193: 
                    194: int REGPARAM2 BusErrMem_check(uaecptr addr, uae_u32 size)
                    195: {
                    196:     if (illegal_mem)
                    197:        write_log ("Bus error check at %08lx\n", (long)addr);
                    198: 
                    199:     return 0;
                    200: }
                    201: 
                    202: uae_u8 REGPARAM2 *BusErrMem_xlate (uaecptr addr)
                    203: {
                    204:     write_log("Your Atari program just did something terribly stupid:"
                    205:               " BusErrMem_xlate($%x)\n", addr);
                    206: 
                    207:     /*M68000_Crash (2);*/
                    208:     return STmem_xlate(addr);  /* So we don't crash. */
                    209: }
                    210: 
                    211: 
                    212: /* **** ST RAM memory **** */
                    213: 
                    214: uae_u8 *STmemory;
                    215: 
                    216: uae_u32 REGPARAM2 STmem_lget (uaecptr addr)
                    217: {
                    218:     uae_u32 *m;
                    219: 
                    220:     addr -= STmem_start & STmem_mask;
                    221:     addr &= STmem_mask;
                    222:     m = (uae_u32 *)(STmemory + addr);
                    223:     return do_get_mem_long (m);
                    224: }
                    225: 
                    226: uae_u32 REGPARAM2 STmem_wget (uaecptr addr)
                    227: {
                    228:     uae_u16 *m;
                    229: 
                    230:     addr -= STmem_start & STmem_mask;
                    231:     addr &= STmem_mask;
                    232:     m = (uae_u16 *)(STmemory + addr);
                    233:     return do_get_mem_word (m);
                    234: }
                    235: 
                    236: uae_u32 REGPARAM2 STmem_bget (uaecptr addr)
                    237: {
                    238:     addr -= STmem_start & STmem_mask;
                    239:     addr &= STmem_mask;
                    240:     return STmemory[addr];
                    241: }
                    242: 
                    243: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l)
                    244: {
                    245:     uae_u32 *m;
                    246: 
                    247:     addr -= STmem_start & STmem_mask;
                    248:     addr &= STmem_mask;
                    249:     m = (uae_u32 *)(STmemory + addr);
                    250:     do_put_mem_long (m, l);
                    251: }
                    252: 
                    253: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w)
                    254: {
                    255:     uae_u16 *m;
                    256: 
                    257:     addr -= STmem_start & STmem_mask;
                    258:     addr &= STmem_mask;
                    259:     m = (uae_u16 *)(STmemory + addr);
                    260:     do_put_mem_word (m, w);
                    261: }
                    262: 
                    263: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b)
                    264: {
                    265:     addr -= STmem_start & STmem_mask;
                    266:     addr &= STmem_mask;
                    267:     STmemory[addr] = b;
                    268: }
                    269: 
                    270: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size)
                    271: {
                    272:     addr -= STmem_start & STmem_mask;
                    273:     addr &= STmem_mask;
                    274:     return (addr + size) <= STmem_size;
                    275: }
                    276: 
                    277: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr)
                    278: {
                    279:     addr -= STmem_start & STmem_mask;
                    280:     addr &= STmem_mask;
                    281:     return STmemory + addr;
                    282: }
                    283: 
                    284: 
                    285: /*
                    286:  * **** ST RAM system memory ****
                    287:  * We need a separate mem bank for this region since the first 0x800 bytes on
                    288:  * the ST can only be accessed in supervisor mode. Note that the very first
                    289:  * 8 bytes of the ST memory are also a mirror of the TOS ROM, so they are write
                    290:  * protected!
                    291:  */
                    292: uae_u32 REGPARAM2 SysMem_lget(uaecptr addr)
                    293: {
                    294:     uae_u32 *m;
                    295: 
                    296:     addr -= STmem_start & STmem_mask;
                    297:     addr &= STmem_mask;
                    298:     m = (uae_u32 *)(STmemory + addr);
                    299:     return do_get_mem_long (m);
                    300: }
                    301: 
                    302: uae_u32 REGPARAM2 SysMem_wget(uaecptr addr)
                    303: {
                    304:     uae_u16 *m;
                    305: 
                    306:     addr -= STmem_start & STmem_mask;
                    307:     addr &= STmem_mask;
                    308:     m = (uae_u16 *)(STmemory + addr);
                    309:     return do_get_mem_word (m);
                    310: }
                    311: 
                    312: uae_u32 REGPARAM2 SysMem_bget(uaecptr addr)
                    313: {
                    314:     addr -= STmem_start & STmem_mask;
                    315:     addr &= STmem_mask;
                    316:     return STmemory[addr];
                    317: }
                    318: 
                    319: void REGPARAM2 SysMem_lput(uaecptr addr, uae_u32 l)
                    320: {
                    321:     uae_u32 *m;
                    322: 
                    323:     addr -= STmem_start & STmem_mask;
                    324:     addr &= STmem_mask;
                    325:     m = (uae_u32 *)(STmemory + addr);
                    326:     do_put_mem_long (m, l);
                    327: }
                    328: 
                    329: void REGPARAM2 SysMem_wput(uaecptr addr, uae_u32 w)
                    330: {
                    331:     uae_u16 *m;
                    332: 
                    333:     addr -= STmem_start & STmem_mask;
                    334:     addr &= STmem_mask;
                    335:     m = (uae_u16 *)(STmemory + addr);
                    336:     do_put_mem_word (m, w);
                    337: }
                    338: 
                    339: void REGPARAM2 SysMem_bput(uaecptr addr, uae_u32 b)
                    340: {
                    341:     addr -= STmem_start & STmem_mask;
                    342:     addr &= STmem_mask;
                    343:     STmemory[addr] = b;
                    344: }
                    345: 
                    346: 
                    347: /*
                    348:  * **** Void memory ****
                    349:  * Between the ST-RAM end and the 4 MB barrier, there is a void memory space:
                    350:  * Reading always returns the same value and writing does nothing at all.
                    351:  */
                    352: 
                    353: uae_u32 REGPARAM2 VoidMem_lget(uaecptr addr)
                    354: {
                    355:     return 0;
                    356: }
                    357: 
                    358: uae_u32 REGPARAM2 VoidMem_wget(uaecptr addr)
                    359: {
                    360:     return 0;
                    361: }
                    362: 
                    363: uae_u32 REGPARAM2 VoidMem_bget(uaecptr addr)
                    364: {
                    365:     return 0;
                    366: }
                    367: 
                    368: void REGPARAM2 VoidMem_lput(uaecptr addr, uae_u32 l)
                    369: {
                    370: }
                    371: 
                    372: void REGPARAM2 VoidMem_wput(uaecptr addr, uae_u32 w)
                    373: {
                    374: }
                    375: 
                    376: void REGPARAM2 VoidMem_bput (uaecptr addr, uae_u32 b)
                    377: {
                    378: }
                    379: 
                    380: int REGPARAM2 VoidMem_check(uaecptr addr, uae_u32 size)
                    381: {
                    382:     if (illegal_mem)
                    383:        write_log ("Void memory check at %08lx\n", (long)addr);
                    384: 
                    385:     return 0;
                    386: }
                    387: 
                    388: uae_u8 REGPARAM2 *VoidMem_xlate (uaecptr addr)
                    389: {
                    390:     write_log("Your Atari program just did something terribly stupid:"
                    391:               " VoidMem_xlate($%x)\n", addr);
                    392: 
                    393:     return STmem_xlate(addr);  /* So we don't crash. */
                    394: }
                    395: 
                    396: 
                    397: /* **** Address banks **** */
                    398: 
                    399: addrbank dummy_bank = {
                    400:     dummy_lget, dummy_wget, dummy_bget,
                    401:     dummy_lput, dummy_wput, dummy_bput,
                    402:     dummy_xlate, dummy_check
                    403: };
                    404: 
                    405: addrbank BusErrMem_bank = {
                    406:     BusErrMem_lget, BusErrMem_wget, BusErrMem_bget,
                    407:     BusErrMem_lput, BusErrMem_wput, BusErrMem_bput,
                    408:     BusErrMem_xlate, BusErrMem_check
                    409: };
                    410: 
                    411: addrbank STmem_bank = {
                    412:     STmem_lget, STmem_wget, STmem_bget,
                    413:     STmem_lput, STmem_wput, STmem_bput,
                    414:     STmem_xlate, STmem_check
                    415: };
                    416: 
                    417: addrbank SysMem_bank = {
                    418:     SysMem_lget, SysMem_wget, SysMem_bget,
                    419:     SysMem_lput, SysMem_wput, SysMem_bput,
                    420:     STmem_xlate, STmem_check
                    421: };
                    422: 
                    423: addrbank VoidMem_bank = {
                    424:     VoidMem_lget, VoidMem_wget, VoidMem_bget,
                    425:     VoidMem_lput, VoidMem_wput, VoidMem_bput,
                    426:     VoidMem_xlate, VoidMem_check
                    427: };
                    428: 
                    429: 
                    430: char *address_space, *good_address_map;
                    431: int good_address_fd;
                    432: 
                    433: 
                    434: static void init_mem_banks (void)
                    435: {
                    436:     int i;
                    437:     for (i = 0; i < 65536; i++)
                    438:        put_mem_bank (i<<16, &dummy_bank);
                    439: }
                    440: 
                    441: 
                    442: /*
                    443:  * Initialize the memory banks
                    444:  */
                    445: void memory_init(uae_u32 f_STMemSize, uae_u32 f_TTMemSize, uae_u32 f_RomMemStart)
                    446: {
                    447:     STmem_size = (f_STMemSize + 65535) & 0xFFFF0000;
                    448: 
                    449:     /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
                    450:               STmem_size, TTmem_size, f_RomMemStart);*/
                    451: 
                    452:     STmemory = STRam;
                    453: /*
                    454:     while (! STmemory && STmem_size > 512*1024) {
                    455:        STmem_size >>= 1;
                    456:        STmemory = (uae_u8 *)malloc (STmem_size);
                    457:        if (STmemory)
                    458:            fprintf (stderr, "Reducing STmem size to %dkb\n", STmem_size >> 10);
                    459:     }
                    460:     if (! STmemory) {
                    461:        write_log ("virtual memory exhausted (STmemory)!\n");
                    462:        abort ();
                    463:     }
                    464: */
                    465: 
                    466:     init_mem_banks();
                    467: 
                    468:     /* Map the ST RAM: */
                    469:     map_banks(&SysMem_bank, 0x00, 1);
                    470:     map_banks(&VoidMem_bank, 0x08, 0x38);  /* Between STRamEnd and 4MB barrier, there is void space! */
                    471:     map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1);
                    472: 
                    473:     /* Illegal memory regions cause a bus error on the ST: */
                    474:     map_banks(&BusErrMem_bank, 0x200000 >> 16, 0xbf); /* Everything above 2mb */
                    475: }
                    476: 
                    477: 
                    478: /*
                    479:  * Uninitialize the memory banks.
                    480:  */
                    481: void memory_uninit (void)
                    482: {
                    483:     /* Here, we free allocated memory from memory_init */
                    484: }
                    485: 
                    486: 
                    487: void map_banks (addrbank *bank, int start, int size)
                    488: {
                    489:     int bnr;
                    490:     unsigned long int hioffs = 0, endhioffs = 0x100;
                    491: 
                    492:     if (start >= 0x100) {
                    493:        for (bnr = start; bnr < start + size; bnr++)
                    494:            put_mem_bank (bnr << 16, bank);
                    495:        return;
                    496:     }
                    497:     /* Some ROMs apparently require a 24 bit address space... */
                    498:     if (address_space_24)
                    499:        endhioffs = 0x10000;
                    500:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
                    501:        for (bnr = start; bnr < start+size; bnr++)
                    502:            put_mem_bank ((bnr + hioffs) << 16, bank);
                    503: }

unix.superglobalmegacorp.com