?? memory.c
字號:
/***************************************************************************** XCopilotThis code is part of XCopilot, a port of copilot Portions of this code are Copyright (C) 1997 Ivan A. Curtis icurtis@radlogic.com.auThe original MS-Windows95 copilot emulator was written by Greg Hewgill.The following copyright notice appeared on the original copilot sources: Copyright (c) 1996 Greg Hewgill MC68000 Emulation code is from Bernd Schmidt's Unix Amiga Emulator. The following copyright notice appeared in those files: Original UAE code Copyright (c) 1995 Bernd SchmidtThis code must not be distributed without these copyright notices intact.**************************************************************************************************************************************************************Filename: memory.cDescription: Copilot Memory managementUpdate History: (most recent first) Ian Goldberg 26-Jun-98 12:40 -- generalized memory mappings Ian Goldberg 11-Sep-97 09:48 -- added bus error support Brian Grossman 14-Jul-97 15:00 -- $XCOPILOTRAM is now a filename Ian Goldberg 18-Apr-97 11:13 -- can now have multiple RAM files Ian Goldberg 10-Apr-97 16:43 -- support for Palm Pilot ROM I. Curtis 5-Mar-97 21:47 -- mmapped scratchmemory and pilotram rom_wput() routine now actually does something I. Curtis 26-Feb-97 14:59 -- modified from win95 version******************************************************************************/#include <config.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/ipc.h>#include <sys/shm.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <netinet/in.h>#include "sysdeps.h"#include "shared.h"#include "memory.h"#if 0#define RANGE_BEGIN 0x1001e3c4#define RANGE_END (RANGE_BEGIN+4)#define _ALIGN(a, s) ((a) & ~((s) - 1))#define CHECK_WATCH(a, s, v) \ if (_ALIGN(a, s) >= _ALIGN(RANGE_BEGIN, s) && \ _ALIGN(a, s) < _ALIGN(RANGE_END, s)) { \ fprintf(stderr, "RANGE violation at PC=0x%x addr=0x%x, value=0x%x size=0x%x\n\r",\ MC68000_getpc(), a, v, s); \ } else#else#define CHECK_WATCH(addr, size, v)#endifint ram_size;int ram_size_mask;int rom_size;extern shared_img *Shptr;extern int exectrace;extern unsigned long text_offset;extern unsigned long data_offset;extern unsigned long bss_offset;int sram_protect = 1;int buserr = 0;addrbank *membanks;/* Default memory access functions */int default_check(CPTR a, ULONG b){ return 0;}UWORD *default_xlate(CPTR a){/* fprintf(stderr, "Your Pilot program just did something terribly stupid\n"); */ return 0;}/* A dummy bank that only contains zeros */static ULONG dummy_lget(CPTR);static UWORD dummy_wget(CPTR);static UBYTE dummy_bget(CPTR);static void dummy_lput(CPTR, ULONG);static void dummy_wput(CPTR, UWORD);static void dummy_bput(CPTR, UBYTE);static int dummy_check(CPTR addr, ULONG size);static UWORD *dummy_xlate(CPTR addr);ULONG dummy_lget(CPTR addr){ fprintf(stderr, "Bus error: read a long from undefined memory address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; return 0;}UWORD dummy_wget(CPTR addr){ if ((addr & 0xFF000000) != 0x10000000) { fprintf(stderr, "Bus error: read a word from undefined memory address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } return 0;}UBYTE dummy_bget(CPTR addr){ fprintf(stderr, "Bus error: read a byte from undefined memory address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; return 0;}void dummy_lput(CPTR addr, ULONG l){ fprintf(stderr, "Bus error: wrote a long to undefined memory address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1;}void dummy_wput(CPTR addr, UWORD w){ if ((addr & 0xFF000000) != 0x10000000) { fprintf(stderr, "Bus error: wrote a word to undefined memory address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; }}void dummy_bput(CPTR addr, UBYTE b){ fprintf(stderr, "Bus error: wrote a byte to undefined memory address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1;}int dummy_check(CPTR addr, ULONG size){ return 0;}UWORD *dummy_xlate(CPTR addr){ return NULL;}/* RAM */UWORD *rammemory;static ULONG ram_lget(CPTR);static UWORD ram_wget(CPTR);static UBYTE ram_bget(CPTR);static void ram_lput(CPTR, ULONG);static void ram_wput(CPTR, UWORD);static void ram_bput(CPTR, UBYTE);static int ram_check(CPTR addr, ULONG size);static UWORD *ram_xlate(CPTR addr);ULONG ram_lget(CPTR addr){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; return ((ULONG)rammemory[addr >> 1] << 16) | rammemory[(addr >> 1)+1];}UWORD ram_wget(CPTR addr){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; return rammemory[addr >> 1];}UBYTE ram_bget(CPTR addr){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; if (addr & 1) return rammemory[addr >> 1]; else return rammemory[addr >> 1] >> 8;}void ram_lput(CPTR addr, ULONG l){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; rammemory[addr >> 1] = l >> 16; rammemory[(addr >> 1)+1] = (UWORD)l;}void sram_lput(CPTR addr, ULONG l){ if (sram_protect) { fprintf(stderr, "Bus error: wrote a long to database RAM address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } else { ram_lput(addr, l); }}void ram_wput(CPTR addr, UWORD w){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; rammemory[addr >> 1] = w;}void sram_wput(CPTR addr, UWORD w){ if (sram_protect) { fprintf(stderr, "Bus error: wrote a word to database RAM address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } else { ram_wput(addr, w); }}void ram_bput(CPTR addr, UBYTE b){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; if (!(addr & 1)) { rammemory[addr>>1] = (rammemory[addr>>1] & 0xff) | (((UWORD)b) << 8); } else { rammemory[addr>>1] = (rammemory[addr>>1] & 0xff00) | b; }}void sram_bput(CPTR addr, UBYTE b){ if (sram_protect) { fprintf(stderr, "Bus error: wrote a byte to database RAM address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } else { ram_bput(addr, b); }}int ram_check(CPTR addr, ULONG size){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; return (addr + size) <= (ULONG)ram_size;}UWORD *ram_xlate(CPTR addr){ addr -= ram_start & (ram_size_mask); addr &= ram_size_mask; return rammemory + (addr >> 1);}/* ROM */static UWORD *rommemory;static ULONG rom_lget(CPTR);static UWORD rom_wget(CPTR);static UBYTE rom_bget(CPTR);static void rom_lput(CPTR, ULONG);static void rom_wput(CPTR, UWORD);static void rom_bput(CPTR, UBYTE);static int rom_check(CPTR addr, ULONG size);static UWORD *rom_xlate(CPTR addr);ULONG rom_lget(CPTR addr){ addr -= rom_start & (rom_size-1); addr &= rom_size-1; return ((ULONG)rommemory[addr >> 1] << 16) | rommemory[(addr >> 1)+1];}UWORD rom_wget(CPTR addr){ addr -= rom_start & (rom_size-1); addr &= rom_size-1; return rommemory[addr >> 1];}UBYTE rom_bget(CPTR addr){ addr -= rom_start & (rom_size-1); addr &= rom_size-1; return rommemory[addr >> 1] >> (addr & 1 ? 0 : 8);}void rom_lput(CPTR addr, ULONG b){ fprintf(stderr, "Bus error: wrote a long to ROM address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1;}void rom_wput(CPTR addr, UWORD w){ if (Shptr->allowromwrites) { addr -= rom_start & (rom_size - 1); addr &= rom_size - 1; rommemory[addr >> 1] = w; } else { fprintf(stderr, "Bus error: wrote a word to ROM address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; }}void rom_bput(CPTR addr, UBYTE b){ fprintf(stderr, "Bus error: wrote a byte to ROM address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1;}int rom_check(CPTR addr, ULONG size){ addr -= rom_start & (rom_size-1); addr &= rom_size-1; return (addr + size) <= rom_size;}UWORD *rom_xlate(CPTR addr){ addr -= rom_start & (rom_size-1); addr &= rom_size-1; return rommemory + (addr >> 1);}static intverify_entrypoint(const void *rom){ const unsigned char _bootsign[] = { 0x4e, 0xfa, 0x00, 0x00, 'b', 'o', 'o', 't', 0x27, 0x10, 0xff }; const unsigned char _bootmask[] = { 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; const unsigned char *bootsign = _bootsign, *bootmask = _bootmask; while ((*bootsign & *bootmask) == *bootsign) if ((*((char *)rom)++ & *bootmask++) != *bootsign++) return 0; return 1;}static const char *find_entrypoint(const char *rom){ const char *entry = rom; while (entry - rom < rom_size) { if (verify_entrypoint(entry)) return entry; else entry += 2; /* Instructions must be word aligned */ } return NULL;}/* This routine replaces the win_load_rom routine *//* It was grabbed from copilot-linux sources */static int load_rom(const char *dir, const char *romfile, int nocheck){ int i; char *rombuf; char *resetv; int f; struct stat st; if (romfile[0] != '/' && dir) { rombuf = alloca(strlen(dir)+strlen(romfile)+2); if (!rombuf) { return PILOTCPU_ERROR_LOADING_ROM; } sprintf(rombuf, "%s/%s", dir, romfile); romfile = rombuf; } f = open(romfile, O_RDONLY);fprintf(stderr, "load %s\n", romfile); if (f == -1) {fprintf(stderr, "%s,%d\n", __FILE__, __LINE__); return PILOTCPU_ROM_NOT_FOUND; } if (fstat(f, &st)) { close(f);fprintf(stderr, "%s,%d\n", __FILE__, __LINE__); return PILOTCPU_ROM_NOT_FOUND; } rom_size = st.st_size; /* Round up to the next power of two */ if (rom_size & (rom_size-1)) { /* It is not already a power of two */ int pow_of_2; for(pow_of_2 = 1; pow_of_2 < rom_size; pow_of_2 <<= 1) ; rom_size = pow_of_2; } #if 1 rommemory = malloc(rom_size + 4096);fprintf(stderr, "%s,%d - 0x%x\n", __FILE__, __LINE__, rommemory); if (rommemory == (UWORD *)0) {fprintf(stderr, "%s,%d\n", __FILE__, __LINE__); return PILOTCPU_ERROR_LOADING_ROM; } memset(rommemory, 0, rom_size); read(f, rommemory, rom_size); // rommemory = (char *) ((((unsigned long) rommemory) + 4095) & ~4095);#else rommemory = (UWORD*)mmap(0, rom_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, f, 0); if (rommemory == (UWORD *)-1) {fprintf(stderr, "%s,%d\n", __FILE__, __LINE__); return PILOTCPU_ERROR_LOADING_ROM; }#endif if (!nocheck) { /* Check if the reset vector looks plausible */ resetv = (char *)rommemory + (ntohl(*(CPTR *)(((char *)rommemory)+4)) - rom_start); if (!verify_entrypoint(resetv)) { int offset; int pageoffset; void *newrom; /* It didn't - we need to find it */ if (1 != ntohs(*(UWORD *)(((char *)rommemory)+0x0c))) { offset = ntohl(*(CPTR *)(((char *)rommemory)+0x68)) + sram_start - rom_start; } else { offset = resetv - find_entrypoint((char *)rommemory); } /* Did we find it? If not, lets go with the original. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -