home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Memory management
- *
- * (c) 1995 Bernd Schmidt
- */
-
- #include "sysconfig.h"
- #include "sysdeps.h"
-
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "cia.h"
- #include "ersatz.h"
- #include "zfile.h"
-
- int ersatzkickfile = 0;
-
- int buserr;
- addrbank membanks[65536];
-
- /* Default memory access functions */
-
- int default_check(CPTR a, ULONG b)
- {
- return 0;
- }
-
- UWORD *default_xlate(CPTR a)
- {
- fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
- return 0;
- }
-
- /* A dummy bank that only contains zeros */
-
- static ULONG dummy_lget(CPTR) REGPARAM;
- static UWORD dummy_wget(CPTR) REGPARAM;
- static UBYTE dummy_bget(CPTR) REGPARAM;
- static void dummy_lput(CPTR, ULONG) REGPARAM;
- static void dummy_wput(CPTR, UWORD) REGPARAM;
- static void dummy_bput(CPTR, UBYTE) REGPARAM;
- static int dummy_check(CPTR addr, ULONG size) REGPARAM;
- static UWORD *dummy_xlate(CPTR addr) REGPARAM;
-
- ULONG dummy_lget(CPTR addr)
- {
- return 0;
- }
-
- UWORD dummy_wget(CPTR addr)
- {
- return 0;
- }
-
- UBYTE dummy_bget(CPTR addr)
- {
- return 0;
- }
-
- void dummy_lput(CPTR addr, ULONG l) { }
- void dummy_wput(CPTR addr, UWORD w) { }
- void dummy_bput(CPTR addr, UBYTE b) { }
-
- int dummy_check(CPTR addr, ULONG size)
- {
- return 0;
- }
-
- UWORD *dummy_xlate(CPTR addr)
- {
- return NULL;
- }
-
- /* Chip memory */
-
- UWORD *chipmemory;
-
- static ULONG chipmem_lget(CPTR) REGPARAM;
- static UWORD chipmem_wget(CPTR) REGPARAM;
- static UBYTE chipmem_bget(CPTR) REGPARAM;
- static void chipmem_lput(CPTR, ULONG) REGPARAM;
- static void chipmem_wput(CPTR, UWORD) REGPARAM;
- static void chipmem_bput(CPTR, UBYTE) REGPARAM;
- static int chipmem_check(CPTR addr, ULONG size) REGPARAM;
- static UWORD *chipmem_xlate(CPTR addr) REGPARAM;
-
- ULONG chipmem_lget(CPTR addr)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
- }
-
- UWORD chipmem_wget(CPTR addr)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- return chipmemory[addr >> 1];
- }
-
- UBYTE chipmem_bget(CPTR addr)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- if (addr & 1)
- return chipmemory[addr >> 1];
- else
- return chipmemory[addr >> 1] >> 8;
- }
-
- void chipmem_lput(CPTR addr, ULONG l)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- chipmemory[addr >> 1] = l >> 16;
- chipmemory[(addr >> 1)+1] = (UWORD)l;
- }
-
- void chipmem_wput(CPTR addr, UWORD w)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- chipmemory[addr >> 1] = w;
- }
-
- void chipmem_bput(CPTR addr, UBYTE b)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- if (!(addr & 1)) {
- chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
- } else {
- chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
- }
- }
-
- int chipmem_check(CPTR addr, ULONG size)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- return (addr + size) < chipmem_size;
- }
-
- UWORD *chipmem_xlate(CPTR addr)
- {
- addr -= chipmem_start & (chipmem_size-1);
- addr &= chipmem_size-1;
- return chipmemory + (addr >> 1);
- }
-
- /* Slow memory */
-
- static UWORD *bogomemory;
-
- static ULONG bogomem_lget(CPTR) REGPARAM;
- static UWORD bogomem_wget(CPTR) REGPARAM;
- static UBYTE bogomem_bget(CPTR) REGPARAM;
- static void bogomem_lput(CPTR, ULONG) REGPARAM;
- static void bogomem_wput(CPTR, UWORD) REGPARAM;
- static void bogomem_bput(CPTR, UBYTE) REGPARAM;
- static int bogomem_check(CPTR addr, ULONG size) REGPARAM;
- static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
-
- ULONG bogomem_lget(CPTR addr)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
- }
-
- UWORD bogomem_wget(CPTR addr)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- return bogomemory[addr >> 1];
- }
-
- UBYTE bogomem_bget(CPTR addr)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- if (addr & 1)
- return bogomemory[addr >> 1];
- else
- return bogomemory[addr >> 1] >> 8;
- }
-
- void bogomem_lput(CPTR addr, ULONG l)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- bogomemory[addr >> 1] = l >> 16;
- bogomemory[(addr >> 1)+1] = (UWORD)l;
- }
-
- void bogomem_wput(CPTR addr, UWORD w)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- bogomemory[addr >> 1] = w;
- }
-
- void bogomem_bput(CPTR addr, UBYTE b)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- if (!(addr & 1)) {
- bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
- } else {
- bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
- }
- }
-
- int bogomem_check(CPTR addr, ULONG size)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- return (addr + size) < bogomem_size;
- }
-
- UWORD *bogomem_xlate(CPTR addr)
- {
- addr -= bogomem_start & (bogomem_size-1);
- addr &= bogomem_size-1;
- return bogomemory + (addr >> 1);
- }
-
- /* Kick memory */
-
- static int zkickfile = 0;
- static UWORD kickmemory[kickmem_size/2];
-
- static ULONG kickmem_lget(CPTR) REGPARAM;
- static UWORD kickmem_wget(CPTR) REGPARAM;
- static UBYTE kickmem_bget(CPTR) REGPARAM;
- static void kickmem_lput(CPTR, ULONG) REGPARAM;
- static void kickmem_wput(CPTR, UWORD) REGPARAM;
- static void kickmem_bput(CPTR, UBYTE) REGPARAM;
- static int kickmem_check(CPTR addr, ULONG size) REGPARAM;
- static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
-
- ULONG kickmem_lget(CPTR addr)
- {
- addr -= kickmem_start & (kickmem_size-1);
- addr &= kickmem_size-1;
- return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
- }
-
- UWORD kickmem_wget(CPTR addr)
- {
- addr -= kickmem_start & (kickmem_size-1);
- addr &= kickmem_size-1;
- return kickmemory[addr >> 1];
- }
-
- UBYTE kickmem_bget(CPTR addr)
- {
- addr -= kickmem_start & (kickmem_size-1);
- addr &= kickmem_size-1;
- return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
- }
-
- void kickmem_lput(CPTR a, ULONG b)
- {
- }
-
- void kickmem_wput(CPTR a, UWORD b)
- {
- }
-
- void kickmem_bput(CPTR a, UBYTE b)
- {
- }
-
- int kickmem_check(CPTR addr, ULONG size)
- {
- addr -= kickmem_start & (kickmem_size-1);
- addr &= kickmem_size-1;
- return (addr + size) < kickmem_size;
- }
-
- UWORD *kickmem_xlate(CPTR addr)
- {
- addr -= kickmem_start & (kickmem_size-1);
- addr &= kickmem_size-1;
- return kickmemory + (addr >> 1);
- }
-
- static int load_kickstart(void)
- {
- int i;
- ULONG cksum = 0, prevck = 0;
- unsigned char buffer[8];
-
- FILE *f = zfile_open(romfile, "rb");
-
- if (f == NULL) {
- fprintf(stderr, "No Kickstart ROM found.\n");
- return 0;
- }
-
- fread(buffer, 1, 8, f);
- if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
- fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n");
- zkickfile = 1;
- } else
- fseek(f, 0, SEEK_SET);
-
- i = fread(kickmemory, 1, kickmem_size, f);
- if (i == kickmem_size/2) {
- fprintf(stderr, "Warning: Kickstart is only 256K.\n");
- memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2);
- } else if (i != kickmem_size) {
- fprintf(stderr, "Error while reading Kickstart.\n");
- return 0;
- }
- zfile_close (f);
-
- for (i = 0; i < kickmem_size/2; i++) {
- UWORD *p = kickmemory + i;
- UBYTE *bp = (UBYTE *)p;
- *p = (*bp << 8) | *(bp+1);
- }
-
- for (i = 0; i < kickmem_size/4; i++) {
- ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1];
- cksum += data;
- if (cksum < prevck)
- cksum++;
- prevck = cksum;
- }
- if (cksum != 0xFFFFFFFF) {
- fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
- }
- return 1;
- }
-
- /* Address banks */
-
- addrbank dummy_bank = {
- dummy_lget, dummy_wget, dummy_bget,
- dummy_lput, dummy_wput, dummy_bput,
- dummy_xlate, dummy_check
- };
-
- addrbank chipmem_bank = {
- chipmem_lget, chipmem_wget, chipmem_bget,
- chipmem_lput, chipmem_wput, chipmem_bput,
- chipmem_xlate, chipmem_check
- };
-
- addrbank bogomem_bank = {
- bogomem_lget, bogomem_wget, bogomem_bget,
- bogomem_lput, bogomem_wput, bogomem_bput,
- bogomem_xlate, bogomem_check
- };
-
- addrbank kickmem_bank = {
- kickmem_lget, kickmem_wget, kickmem_bget,
- kickmem_lput, kickmem_wput, kickmem_bput,
- kickmem_xlate, kickmem_check
- };
-
- void memory_init(void)
- {
- int i;
- buserr = 0;
-
- chipmemory = (UWORD *)malloc(chipmem_size);
- if(!chipmemory) {
- fprintf(stderr,"virtual memory exhausted !\n");
- abort();
- }
- memset(chipmemory, 0, sizeof chipmemory);
-
- for(i = 0; i < 65536; i++)
- membanks[i] = dummy_bank;
-
- /* Map the chipmem into all of the lower 16MB */
- map_banks(chipmem_bank, 0x00, 256);
- map_banks(custom_bank, 0xC0, 0x20);
- map_banks(cia_bank, 0xA0, 32);
- map_banks(clock_bank, 0xDC, 1);
-
- if (bogomem_size > 0) {
- bogomemory = (UWORD *)malloc (bogomem_size);
- if(!bogomemory) {
- fprintf(stderr,"virtual memory exhausted !\n");
- abort();
- }
- map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
- }
-
- map_banks(rtarea_bank, 0xF0, 1);
- rtarea_init ();
- if (!load_kickstart()) {
- init_ersatz_rom(kickmemory);
- ersatzkickfile = 1;
- }
- if (zkickfile)
- map_banks(kickmem_bank, 0x20, 8);
-
- map_banks(kickmem_bank, 0xF8, 8);
- if (!zkickfile)
- map_banks(expamem_bank, 0xE8, 1);
- }
-
- void map_banks(addrbank bank, int start, int size)
- {
- int bnr;
- int hioffs = 0;
- #if CPU_LEVEL < 2
- for (hioffs = 0; hioffs < 256; hioffs++)
- #endif
- for (bnr = start; bnr < start+size; bnr++)
- membanks[bnr + hioffs * 256] = bank;
- }
-