?? memory.c
字號(hào):
if ((char *)offset != resetv) { /* It may not always be page aligned... */ pageoffset = ((offset-1) & ~(getpagesize() - 1)) + getpagesize(); if ((st.st_size + offset) > rom_size) rom_size <<= 1;fprintf(stderr, "%s,%d remap\n", __FILE__, __LINE__); rommemory = (UWORD *)mmap((void*)(rommemory + pageoffset), rom_size - pageoffset, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE | MAP_FIXED, f, 0); if (rommemory == (UWORD *)-1) {fprintf(stderr, "%s,%d\n", __FILE__, __LINE__); return PILOTCPU_ERROR_LOADING_ROM; } memcpy(((char *)rommemory) - offset, rommemory, 256); ((char *)rommemory) -= offset; } } }#ifndef WORDS_BIGENDIAN#if 1 for (i = 0; i < rom_size/2; i++) { UWORD *p; UBYTE *bp; p = rommemory + i; bp = (UBYTE *)p; *p = (*bp << 8) | *(bp + 1); }#else for (i = 0; i < rom_size; i += 2) { char *p = rommemory + i, tmp; tmp = p[0]; p[0] = p[1]; p[1] = tmp; }#endif#endif close(f); return 0;}/* Scratch area */UBYTE *scratchmemory = NULL;static ULONG scratch_lget(CPTR);static UWORD scratch_wget(CPTR);static UBYTE scratch_bget(CPTR);static void scratch_lput(CPTR, ULONG);static void scratch_wput(CPTR, UWORD);static void scratch_bput(CPTR, UBYTE);static int scratch_check(CPTR addr, ULONG size);static UWORD *scratch_xlate(CPTR addr);ULONG scratch_lget(CPTR addr){ if (scratchmemory == NULL) return dummy_lget(addr); addr -= scratch_start; return ((ULONG)scratchmemory[addr] << 24) | ((ULONG)scratchmemory[addr+1] << 16) | ((ULONG)scratchmemory[addr+2] << 8) | scratchmemory[addr+3];}UWORD scratch_wget(CPTR addr){ if (scratchmemory == NULL) return dummy_wget(addr); addr -= scratch_start; return ((UWORD)scratchmemory[addr] << 8) | scratchmemory[addr+1];}UBYTE scratch_bget(CPTR addr){ if (scratchmemory == NULL) return dummy_lget(addr); addr -= scratch_start; return scratchmemory[addr];}void scratch_lput(CPTR addr, ULONG l){ if (scratchmemory == NULL) return; addr -= scratch_start; scratchmemory[addr] = l >> 24; scratchmemory[addr+1] = l >> 16; scratchmemory[addr+2] = l >> 8; scratchmemory[addr+3] = l;}void scratch_wput(CPTR addr, UWORD w){ if (scratchmemory == NULL) return; addr -= scratch_start; scratchmemory[addr] = w >> 8; scratchmemory[addr+1] = w;}void scratch_bput(CPTR addr, UBYTE b){ if (scratchmemory == NULL) return; addr -= scratch_start; scratchmemory[addr] = b;}int scratch_check(CPTR addr, ULONG size){ if (scratchmemory == NULL) return 0; return 1;}UWORD *scratch_xlate(CPTR addr){ return NULL; /* anything that calls this will assume swapped byte order! */}/* Address banks */addrbank dummy_bank = { dummy_lget, dummy_wget, dummy_bget, dummy_lput, dummy_wput, dummy_bput, dummy_xlate, dummy_check};addrbank ram_bank = { ram_lget, ram_wget, ram_bget, ram_lput, ram_wput, ram_bput, ram_xlate, ram_check};addrbank sram_bank = { ram_lget, ram_wget, ram_bget, sram_lput, sram_wput, sram_bput, ram_xlate, ram_check};addrbank rom_bank = { rom_lget, rom_wget, rom_bget, rom_lput, rom_wput, rom_bput, rom_xlate, rom_check};addrbank scratch_bank = { scratch_lget, scratch_wget, scratch_bget, scratch_lput, scratch_wput, scratch_bput, scratch_xlate, scratch_check};void map_banks(addrbank bank, int start, int size){ int bnr; for (bnr = start; bnr < start+size; bnr++) membanks[bnr] = bank;}#ifdef NEED_FTRUNCATE/* -*-Mode: C;-*- * * MODULE: ftruncate.c * * AUTHORS: HO Harry Ohlsen harryo@ise.com.au * RF Rick Flower rick.flower@trw.com * * PURPOSE: Supplementary library function for ftruncate(); * * USAGE: * * This routine is used to augment systems which don't have access * to the ftruncate() system library function (such as SunOS). * This routine tries to mimic as closely as possible the regular * behavior that the standard library function performs, including * the same return error codes where applicable. * * This routine will return zero on success and non-zero (-1) on * failure. If it fails, it will also set errno appropriately. * * HISTORY: * * This routine was snitched from some code originally written by * Harry Ohlsen (see Authors above) and adapted by Rick Flower * for this specific purpose. */#include <sys/types.h>#include <unistd.h>#include <errno.h>int ftruncate(int fd, off_t createSize){ int bytesToGo = createSize; char *crap; /* We will get problems when we try to write stuff * to the memory segment (it won't end up on disk, * since mmap()-ed things don't extend). */ crap = (char *)malloc(createSize); errno = 0; /* Reset errno value */ (void)memset(crap, 0x00, createSize); while (bytesToGo > 0) { int bytesToWrite; if (bytesToGo < createSize) bytesToWrite = bytesToGo; else bytesToWrite = createSize; if (write(fd, crap, bytesToWrite) != bytesToWrite) { free(crap); /* Free buffer space used up.. */ errno = EIO; /* Set error to indicate I/O error */ return(-1); /* Return bad status to caller */ } bytesToGo -= bytesToWrite; } free(crap); /* Free buffer space used up.. */ return(0); /* Return valid status to caller */}#endif/* * This routine replaces the original memory_init * It was taken from copilot-linux sources with minor changes */int memory_init(int ramsize, const char *dir, const char *romfile, const char *ramfile, const char *scratchfile, int reset, int check_entrypoint){ int i; int f; int res; char *rambuf, *scratchbuf; buserr = 0; if (ramsize & (ramsize-1)) { return PILOTCPU_ERROR_LOADING_RAM; } ram_size = ramsize * 1024; ram_size_mask = ram_size - 1; if (ramfile[0] != '/' && dir) { rambuf = alloca(strlen(dir)+strlen(ramfile)+2); if (!rambuf) { return PILOTCPU_ERROR_LOADING_RAM; } sprintf(rambuf, "%s/%s", dir, ramfile); ramfile = rambuf; } if (reset) f = open(ramfile, O_RDWR|O_CREAT|O_TRUNC, 0666); else f = open(ramfile, O_RDWR|O_CREAT, 0666); if (f == -1) { return PILOTCPU_ERROR_LOADING_RAM; } ftruncate(f, ram_size); rammemory = (UWORD*)mmap(0, ram_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, f, 0); if (rammemory == (UWORD*)-1) { return PILOTCPU_ERROR_LOADING_RAM; } close(f); if (scratchfile[0] != '/' && dir) { scratchbuf = alloca(strlen(dir)+strlen(scratchfile)+2); if (!scratchbuf) { return PILOTCPU_ERROR_LOADING_RAM; } sprintf(scratchbuf, "%s/%s", dir, scratchfile); scratchfile = scratchbuf; } f = open(scratchfile, O_RDWR|O_CREAT|O_TRUNC,0666); if (f == -1) { return PILOTCPU_ERROR_LOADING_RAM; } ftruncate(f, SCRATCH_SIZE); scratchmemory = (unsigned char*)mmap(0, SCRATCH_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, f, 0); close(f); /* f = open("cpustate", O_RDWR|O_CREAT|O_TRUNC,0666); *//* if (f == -1) { *//* return PILOTCPU_ERROR_LOADING_RAM; *//* } *//* ftruncate(f, state_size); */ /* statememory = (char*)mmap(0, state_size, PROT_READ|PROT_WRITE, *//* MAP_FILE|MAP_SHARED, f, 0); *//* close(f); */ /* sharedstate = (struct state*)statememory; */ /* CpuState = (int*)(sharedstate+1); *//* ExceptionFlags = (int*)(CpuState+1); */ membanks = (addrbank *)malloc(65536 * sizeof(addrbank)); if (membanks == NULL) { perror("memory_init"); exit(1); } for(i = 0; i < 65536; i++) { membanks[i] = dummy_bank; }#define NUM_BANKS(s) ((s)>>16 + (((s)&0xFFFF) ? 1 : 0)) map_banks(ram_bank, ram_start>>16, NUM_BANKS(ram_size) /*16*/); map_banks(sram_bank, sram_start>>16, NUM_BANKS(ram_size)); map_banks(scratch_bank, scratch_start>>16, NUM_BANKS(SCRATCH_SIZE)); map_banks(custom_bank, custom_start>>16, 1); res = load_rom(dir, romfile, check_entrypoint); map_banks(rom_bank, rom_start>>16, NUM_BANKS(rom_size)); return res;}void mem_setscratchaddr(UBYTE *addr){ scratchmemory = addr;}unsigned int bankindex(CPTR a){ return a>>16;}ULONG longget(CPTR addr){ return membanks[bankindex(addr)].lget(addr);}UWORD wordget(CPTR addr){ return membanks[bankindex(addr)].wget(addr);}UBYTE byteget(CPTR addr) { return membanks[bankindex(addr)].bget(addr);}void longput(CPTR addr, ULONG l){ membanks[bankindex(addr)].lput(addr, l);}void wordput(CPTR addr, UWORD w){ membanks[bankindex(addr)].wput(addr, w);}void byteput(CPTR addr, UBYTE b){ membanks[bankindex(addr)].bput(addr, b);}int check_addr(CPTR a){#ifdef NO_EXCEPTION_3 return 1;#else return (a & 1) == 0;#endif}ULONG get_long(CPTR addr) { if (check_addr(addr)) return longget(addr); fprintf(stderr, "Bus error: read a long from odd address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; return 0;}UWORD get_word(CPTR addr) { if (check_addr(addr)) return wordget(addr); fprintf(stderr, "Bus error: read a word from odd address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; return 0;}UBYTE get_byte(CPTR addr) { return byteget(addr); }void put_long(CPTR addr, ULONG l) { CHECK_WATCH(addr, 4, l); if ((addr & 0xfffffff0) == 0xdeadbee0) { switch (addr & 0xf) { case 0: fprintf(stderr, "PTR value is 0x%x\n\r", l); return; default: puts("Barf!"); exit(0); } } if (!check_addr(addr)) { fprintf(stderr, "Bus error: wrote a long to odd address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } longput(addr, l);}void put_word(CPTR addr, UWORD w) { CHECK_WATCH(addr, 2, w); if ((addr & 0xfffffff0) == 0xdeadbee0) { switch (addr & 0xf) { case 0: fprintf(stderr, "At line %d\n\r", w); return; default: puts("Barf!"); exit(0); } } if (!check_addr(addr)) { fprintf(stderr, "Bus error: wrote a word to odd address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } wordput(addr, w);}void put_byte(CPTR addr, UBYTE b) { CHECK_WATCH(addr, 1, b); if ((addr & 0xfffffff0) == 0xdeadbee0) { switch (addr & 0xf) { case 0: text_offset = (Shptr->regs).d[0]; data_offset = (Shptr->regs).d[1]; bss_offset = (Shptr->regs).d[2];{int i; for (i=0;i<8;i++) fprintf(stderr,"A%d[%.8x]",i,(Shptr->regs).a[i]);fprintf(stderr,"\n\r");for (i=0;i<8;i++) fprintf(stderr,"D%d[%.8x]",i,(Shptr->regs).d[i]);fprintf(stderr,"\n\r");fflush(stderr);} exectrace = 1; return; default: puts("Barf!"); exit(0); } } byteput(addr, b);}UWORD *get_real_address(CPTR addr){ if (!check_addr(addr)) { fprintf(stderr, "Bus error: attempted translation of odd address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } return membanks[bankindex(addr)].xlateaddr(addr);}int valid_address(CPTR addr, ULONG size){ if (!check_addr(addr)) { fprintf(stderr, "Bus error: attempted validation of odd address 0x%08lx\n", addr); fprintf(stderr, "PC=0x%08lx\n", MC68000_getpc()); buserr = 1; } return membanks[bankindex(addr)].check(addr, size);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -