/* * Castaway * (C) 1994 - 2002 Martin Doering, Joachim Hoenig * * $File$ - memory read/write * * This file is distributed under the GPL, version 2 or at your * option any later version. See doc/license.txt for details. * * revision history * 23.05.2002 JH FAST1.0.1 code import: KR -> ANSI, restructuring * 30.05.2002 JH Discontinued using mmap and mprotect, now using * Martin's memory access jump table. * 12.06.2002 JH Correct bus error/address error exception stack frame * 14.06.2002 JH LowRamSetX() functions improved. * 09.07.2002 JH Now loads any 192k ROM file * 10.07.2002 MAD Now loads any ROM file * 16.09.2002 JH Bugfix: Word access on unmapped I/O address stacked * two bus error stack frames. Fault address corrected. * 08.10.2002 JH Fixed integer types. * 27.10.2002 AG Trashed everything for more speed! mwuhahaha! */ #include #include #include #ifndef DREAMCAST #else #include #endif #include "config.h" #include "st.h" #include "mem.h" #include "m68k_intrf.h" #include "dcastaway.h" //int8 *membase=0; //int8 *rombase=0; static unsigned rombase_pos=0; char rom[80]; // = ROM; #ifdef DREAMCAST void reinit_sdcard(void); char rom_sd[24] = ROM_SD; #endif static int samvol[16]={0,0,0,1,1,1,2,3,5,7,11,17,25,38,57,85}; extern uint32 psg[26]; #define lastpsg psg[25] #define sampos psg[24] #define OPTIMIZE_VMEM 1 #ifdef OPTIMIZE_VMEM signed char videobuf[32768]; extern uint32 vid_mem; #endif char GetMemB(unsigned long address) { address &= MEMADDRMASK; if (address= vid_mem) && (address < (vid_mem+32768) ) ) { *((unsigned char *)(&videobuf[(address-vid_mem)^1])) = value; } #endif WriteB(address + membase, value); } /* Write byte to address */ void SetMemB (unsigned long address, unsigned char value) { address &= MEMADDRMASK; ON_WRITE(address, value); if (address=IOBASE && address= vid_mem) && (address < (vid_mem+32768) ) ) { *(unsigned short *)(&videobuf[address-vid_mem]) = value; } #endif WriteW(address + membase, value); } /* Write word, address may not be word-aligned */ void SetMemW(unsigned long address, unsigned short value) { #ifdef CHKADDRESSERR address &= MEMADDRMASK; if (address & 0x1){ ExceptionGroup0(ADDRESSERR, address, 1); return; } #else address &= MEMADDRMASKS; #endif ON_WRITE(address, value); if (address=IOBASE && address= vid_mem) && (address < (vid_mem+32768) ) ) { printf("vwlmem\n"); WriteL(&videobuf[address-vid_mem], value); } else #endif WriteL(address + membase, value); return; } if (address>=IOBASE && address>8)&15; uint32 value1=value&255; psg[psgctrl1]=value1; if (psgctrl1==lastpsg) sample[sampos++]=samvol[psg[8]]+samvol[psg[9]]+samvol[value1]; else if (psgctrl1==13 || psgctrl1==12) psg_epos=0; return; } address &= MEMADDRMASK; if (address>=IOBASE && address>8)); DoIOWB(address+2, (int8)value); return; } if (address>8)); WriteB(address+2, (int8)value); return; } } void SetMemPL(unsigned long address, unsigned long value) {// int8 psgctrl1,psgctrl2,value1,value2; if (address&0xffff03==0xff8800) { uint32 psgctrl1=(value>>24)&15; uint32 value1=(value>>16)&255; psg[psgctrl1]=value1; if (psgctrl1==lastpsg) sample[sampos++]=samvol[psg[8]]+samvol[psg[9]]+samvol[value1]; else if (psgctrl1==13 || psgctrl1==12) psg_epos=0; psgctrl1=(value>>8)&15; value1=value&255; if (psgctrl1==lastpsg) sample[sampos++]=samvol[psg[8]]+samvol[psg[9]]+samvol[value1]; else if (psgctrl1==13 || psgctrl1==12) psg_epos=0; return; } address &= MEMADDRMASK; if (address>=IOBASE && address>24)); DoIOWB(address+2, (int8)(value>>16)); DoIOWB(address+4, (int8)(value>>8)); DoIOWB(address+6, (int8)value); return; } if (address>24)); WriteB(address+2, (int8)(value>>16)); WriteB(address+4, (int8)(value>>8)); WriteB(address+6, (int8)value); return; } } #ifdef UNUSED static void *__rombase=NULL, *__membase=NULL; void MemQuit(void) { if (__membase) free(__membase); __membase=NULL; if (__rombase) free(__rombase); __rombase=NULL; } static void _set_dword(void *buf,unsigned dat) { unsigned short *b=(unsigned short *)buf; *b++=dat&0xffff; *b=dat>>16; } void MemClean(void) { membase=(int8*)__membase; memset(membase,0,MEMSIZE); //savestate_init(); memcpy (membase, ((int8*)__rombase)+rombase_pos, 8); _set_dword(membase+0x420,0x752019f3); _set_dword(membase+0x43a,0x237698aa); _set_dword(membase+0x51a,0x5555aaaa); #if MEMSIZE==0x00080000 _set_dword(membase+0x436,0x80000-0x8000); _set_dword(membase+0x42e,0x80000); WriteB(membase+0x425,1); WriteB(rombase+0xff8000,1); memconf=1; #else #if MEMSIZE==0x00100000 _set_dword(membase+0x436,0x100000-0x8000); _set_dword(membase+0x42e,0x100000); WriteB(membase+0x425,5); WriteB(rombase+0xff8000,5); memconf=5; #else #if MEMSIZE==0x00200000 _set_dword(membase+0x436,0x200000-0x8000); _set_dword(membase+0x42e,0x200000); WriteB(membase+0x425,2); WriteB(rombase+0xff8000,2); memconf=2; #else #if MEMSIZE==0x00400000 _set_dword(membase+0x436,0x400000-0x8000); _set_dword(membase+0x42e,0x400000); WriteB(membase+0x425,0xA); WriteB(rombase+0xff8000,0xA); memconf=0xA; #else #error DCaSTaway ERROR: MEMSIZE incorrect. #endif #endif #endif #endif _set_dword(membase+0x4c2,3); WriteW(membase+0x4a6,2); //if (TosCountry) // vid_syncmode=2; //else // vid_syncmode=0; } static unsigned actual_rom_crc=0; static unsigned rom_checksum(void) { int n; unsigned crc=0; for(n=ROMBASE2;n(MEMADDRSIZE-ROMBASE2)) len=(MEMADDRSIZE-ROMBASE2); if (len<=(192*1024)) rombase_pos=ROMBASE-ROMBASE2; else rombase_pos=0; if (!__rombase) __rombase = calloc(1,MEMADDRSIZE-ROMBASE2); rombase=(int8*)__rombase; for(n=0;n<(MEMADDRSIZE-ROMBASE2);n+=2) { rombase[n]=0x4e; rombase[n+1]=0x71; } if (len != fread(rombase+rombase_pos,1,len,roms)) { fclose(roms); return 2; } fclose (roms); #ifdef BYTES_SWAP for (n=0; n<(MEMADDRSIZE-ROMBASE2); n+=2) { val1 = rombase[n]; val2 = rombase[n+1]; rombase[n] = val2; rombase[n+1] =val1; } #endif /* precalculate rombase - now just address-adding happens later */ if (rombase_pos) { rombase -= ROMBASE2+rombase_pos-(ROMBASE-ROMBASE2); memcpy(rombase+ROMBASE2,rombase+ROMBASE,(MEMADDRSIZE-ROMBASE)); } else { rombase -= ROMBASE2; memcpy(rombase+ROMBASE,rombase+ROMBASE2,(MEMADDRSIZE-ROMBASE)); } TOS_FixRom((uint8 *)(((int8*)__rombase)+rombase_pos)); //Allocate and clear RAM if (!__membase) __membase = (int8*)calloc(1,MEMSIZE+0x10); MemClean(); actual_rom_crc=rom_checksum(); initialize_memmap(); return 0; } #endif