📄 dsmmusub.cpp
字号:
u16 dsMMUsub::rdH_MMIO(u32 a){ return mmioPages[MMIO_PAGE_INDEX].rdH(a); }u32 dsMMUsub::rdW_MMIO(u32 a){ return mmioPages[MMIO_PAGE_INDEX].rdW(a); }void dsMMUsub::wrB_MMIO(u32 a, u8 d) { mmioPages[MMIO_PAGE_INDEX].wrB(a,d); }void dsMMUsub::wrH_MMIO(u32 a, u16 d){ mmioPages[MMIO_PAGE_INDEX].wrH(a,d); }void dsMMUsub::wrW_MMIO(u32 a, u32 d){ mmioPages[MMIO_PAGE_INDEX].wrW(a,d); }// Since there's no other real place to keep the BIOS interrupt flags,// they're here in the MMU, along with their accessor functions.u8 dsMMUsub::rdB_INT(u32 a) { return interruptIO[(a&15)>>2].b[a&3]; }u16 dsMMUsub::rdH_INT(u32 a){ return interruptIO[(a&15)>>2].h[(a&2)>>1]; }u32 dsMMUsub::rdW_INT(u32 a){ return interruptIO[(a&15)>>2].w; }void dsMMUsub::wrB_INT(u32 a, u8 d){ interruptIO[(a&15)>>2].b[a&3]=d; switch(a&15) { case 4: waitstates((interruptIO[1].b[1]<<8)|d); break; case 5: waitstates(interruptIO[1].b[0]|(d<<8)); break; }}void dsMMUsub::wrH_INT(u32 a, u16 d){ interruptIO[(a&15)>>2].h[(a&2)>>1]=d; if((a&14)==4) waitstates(d); }void dsMMUsub::wrW_INT(u32 a, u32 d){ interruptIO[(a&15)>>2].w=d; waitstates(d&65535); }// If the MMU is to be informed of events, this is where they come in.// At present, this merely wraps the DMA event handler.void dsMMUsub::event(int type, void *data){ switch(type) { case MMU_EVENT_SETEWRAM: EWRAM =(u8 *)data; EWRAMh=(u16*)data; EWRAMw=(u32*)data; for(int i=0;i<16;i++) rangeReg(0x20+i, rdB_EWRAM, rdH_EWRAM, rdW_EWRAM, wrB_EWRAM, wrH_EWRAM, wrW_EWRAM); break; case MMU_EVENT_SETSWRAM: SWRAM =(u8 *)data; SWRAMh=(u16*)data; SWRAMw=(u32*)data; rangeReg(0x37, rdB_SWRAM, rdH_SWRAM, rdW_SWRAM, wrB_SWRAM, wrH_SWRAM, wrW_SWRAM); break; default: dma->check(type); break; }}// Initialise plugin// Parameters: name - FQPN of plugin as listed in INI file// req - Pointer to PluginRequest API function// unreq - Pointer to PluginUnrequest API functiondsMMUsub::dsMMUsub(std::string name, REQPTR req, UNREQPTR unreq){ pName = std::string(name); pClass = pName.substr(0, pName.find(".")+1); pRequest = req; pUnrequest = unreq; pluginName = std::string(pName); ROMfile = std::string(""); if(!GUI) GUI = (GUIPlugin*)pRequest("UI"); dmpbuffer = new u32[360*128]; dmpwinID = GUI->subwinCreate(360,128, "Sub Memory Viewer", dmpbuffer); // Blank out the page table for(int i=0; i<256; ++i) { pagetable[i].rdB=rdB_BAD; pagetable[i].rdH=rdH_BAD; pagetable[i].rdW=rdW_BAD; pagetable[i].wrB=wrB_BAD; pagetable[i].wrH=wrH_BAD; pagetable[i].wrW=wrW_BAD; pagetable[i].set=0; mmioPages[i].rdB=rdB_BAD; mmioPages[i].rdH=rdH_BAD; mmioPages[i].rdW=rdW_BAD; mmioPages[i].wrB=wrB_BAD; mmioPages[i].wrH=wrH_BAD; mmioPages[i].wrW=wrW_BAD; mmioPages[i].set=0; } // Make all memory pointers null EWRAM=NULL; EWRAMh=NULL; EWRAMw=NULL; IWRAM=NULL; IWRAMh=NULL; IWRAMw=NULL; SWRAM=NULL; SWRAMh=NULL; SWRAMw=NULL; BIOS =NULL; BIOSh =NULL; BIOSw =NULL; ROM =NULL; ROMh =NULL; ROMw =NULL; // Allocate RAMs /* EWRAM = new u8[256*1024]; if(!EWRAM) throw Exception(ERR_MMU_INIT, pName, "Allocation of EWRAM failed."); EWRAMh = (u16*)EWRAM; EWRAMw = (u32*)EWRAM; Logger::log(pName) << "256KB of EWRAM allocated."; */ IWRAM = new u8[64*1024]; if(!IWRAM) throw Exception(ERR_MMU_INIT, pName, "Allocation of IWRAM failed."); IWRAMh = (u16*)IWRAM; IWRAMw = (u32*)IWRAM; Logger::log(pName) << "64KB of IWRAM allocated."; // Register regions with pagetable for(int i=0; i<16; ++i) { rangeReg(0x00+i, rdB_BIOS , rdH_BIOS , rdW_BIOS , wrB_BAD , wrH_BAD , wrW_BAD ); } for(int i=0; i<8; i++) { rangeReg(0x38+i, rdB_IWRAM, rdH_IWRAM, rdW_IWRAM, wrB_IWRAM, wrH_IWRAM, wrW_IWRAM); rangeReg(0x40+i, rdB_MMIO, rdH_MMIO, rdW_MMIO, wrB_MMIO, wrH_MMIO, wrW_MMIO ); } // Register the interrupt flag I/O space with the MMIO pagetable mmioReg(0x20, rdB_INT, rdH_INT, rdW_INT, wrB_INT, wrH_INT, wrW_INT); for(int i=0; i<4; ++i) interruptIO[i].w=0; waitstates(0); // All done. Logger::log(pName) << "Initialised.";}// Plugin cleanupdsMMUsub::~dsMMUsub(){ //if(EWRAM != NULL) { delete EWRAM; EWRAM=NULL; EWRAMh=NULL; EWRAMw=NULL; } if(IWRAM != NULL) { delete IWRAM; IWRAM=NULL; IWRAMh=NULL; IWRAMw=NULL; } if(ROM != NULL) { delete ROM; ROM =NULL; ROMh =NULL; ROMw =NULL; } if(dma) { delete dma; dma=NULL; } if(dmpbuffer) { delete dmpbuffer; dmpbuffer=NULL; } pUnrequest("UI", 0); GUI = NULL; Logger::log(pName) << "Shutdown.";}void dsMMUsub::setCPU(CPUPlugin *c){ if(c) CPU = (ARM7TDMI*)c;}// Reset plugin statevoid dsMMUsub::reset(){ // Clear out memory memset(IWRAM, 0, 64*1024); if(ROMfile.length()) load(ROMfile); memset(dmpbuffer, 0, 360*128*4); if(!dma) dma = new DMA(this); dma->reset(); // Since the BIOS file may change between resets, loading of the BIOS // is done here in reset as opposed to the constructor if(BIOS != NULL) { delete BIOS; BIOS =NULL; BIOSh =NULL; BIOSw =NULL; } Config ini; ini.read("dsmmusub.ini"); if(!ini.exists("BIOS")) ini["BIOS"] = "bioshack.img"; std::ifstream input(ini["BIOS"].c_str(), std::ios::binary); input.seekg(0, std::ios::end); BIOSsize = input.tellg(); input.seekg(0, std::ios::beg); BIOS = new u8[nlpo2(BIOSsize)]; if(!BIOS) throw Exception(ERR_MMU_INIT, pName, "Allocation of BIOS space failed."); BIOSh=(u16*)BIOS; BIOSw=(u32*)BIOS; input.read((char*)BIOS, BIOSsize); input.close(); BIOSsize = nlpo2(BIOSsize)-1; Logger::log(pName) << ini["BIOS"] << " (" << BIOSsize+1 <<" bytes) loaded as BIOS."; // Refresh the dump window status(0x04000000, 1); // We're done. Logger::log(pName) << "Reset.";}// Provide status information: fill the memorydump framebuffervoid dsMMUsub::status(int addr=0x04000000, int mode=1){ Font5x7 prn(dmpbuffer, 360,128); char str[256]; for(int i=0; i<16; ++i) { sprintf(str, "%08X | ", addr+i*16); switch(mode) { case 0: for(int j=0; j<16; ++j) sprintf(str, "%s%02X ", str, rdB(addr+i*16+j)); break; case 1: for(int j=0; j<16; j+=2) sprintf(str, "%s%04X ", str, rdH(addr+i*16+j)); break; case 2: for(int j=0; j<16; j+=4) sprintf(str, "%s%08X ", str, rdW(addr+i*16+j)); break; } prn.print(str,0,i*8,0x00FFFFFF); } GUI->subwinRefresh(dmpwinID);}// Information about what this MMU supports// Returns: bits set in a u8u8 dsMMUsub::getCaps(){ return PLGMMU_CAPS_32B | PLGMMU_CAPS_LSBEND;}// Next Largest Power of 2 (32-bit)// This is used by the allocators to get nice chunks of memory, and make// our masking life easy.// ACK: Parallel Computing Aggregate, Kentucky U (nlpo2)inline unsigned intdsMMUsub::nlpo2(unsigned int x){ if(x&(x-1)) { // If we're not already a power of 2 x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return(x+1); // Return next power up } return x; // Otherwise, stick with what we have}//---Plugin architecture support-------------------------------------------// Retrieve Plugin class from outside// Parameters: plg - Address of a pointer to a Plugin class to 'new'// name - FQPN of plugin as listed in INI file// req - Pointer to PluginRequest API function// unreq - Pointer to PluginUnrequest API functionEXPORTFUNC void getPlugin(Plugin **plg, std::string name, REQPTR req, UNREQPTR unreq){ *plg = new dsMMUsub(name, req, unreq);}// Provide plugin version informationPLUGININFO *dsMMUsub::getinfo(){ return &pInfo;}// Release plugin from outsidevoid dsMMUsub::release(){ // Delete the Test plugin that was 'new'd in getPlugin. delete this;}/*** EOF: gbammu.cpp *****************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -