/** ** Supermodel ** A Sega Model 3 Arcade Emulator. ** Copyright 2011 Bart Trzynadlowski, Nik Henson ** ** This file is part of Supermodel. ** ** Supermodel is free software: you can redistribute it and/or modify it under ** the terms of the GNU General Public License as published by the Free ** Software Foundation, either version 3 of the License, or (at your option) ** any later version. ** ** Supermodel is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ** more details. ** ** You should have received a copy of the GNU General Public License along ** with Supermodel. If not, see . **/ /* * AddressTable.h */ #ifdef SUPERMODEL_DEBUGGER #ifndef INCLUDED_ADDRESSTABLE_H #define INCLUDED_ADDRESSTABLE_H #include "Types.h" #include #include using namespace std; #define TABLE_WIDTH 16 #define TABLE_SIZE (1 << TABLE_WIDTH) #define TABLE_MASK (TABLE_SIZE - 1) #define INDEX_SHIFT TABLE_WIDTH #define NUM_TABLES (0x100000000ULL / TABLE_SIZE) namespace Debugger { class CCPUDebug; /* * Base class for objects that reference an address, such as a label or a comment. */ class CAddressRef { protected: CAddressRef(CCPUDebug *refCPU, UINT32 refAddr, UINT32 refSize = 1); public: CCPUDebug *cpu; const UINT32 addr; const UINT32 size; const UINT32 addrEnd; bool CheckAddr(UINT32 loc); // TODO - implement operators }; /* * Class that holds a table of address references. It does so in an a memory-expensive manner but with the result that it * performs better (hopefully!) as lookups are constant-time. */ class CAddressTable { private: int m_count; CAddressRef **m_tables[NUM_TABLES]; CAddressRef **GetTableNoCreate(UINT32 addr, int &tableIndex, unsigned &indexInTable); CAddressRef **GetTableCreate(UINT32 addr, int &tableIndex, unsigned &indexInTable); void CheckAndReleaseTable(int tableIndex); public: CAddressTable(); ~CAddressTable(); bool IsEmpty(); void Clear(); CAddressRef *Get(UINT32 addr); CAddressRef *Get(UINT32 addr, UINT32 size); void Add(CAddressRef *value); bool Remove(CAddressRef *value); }; // // Inlined methods // inline bool CAddressRef::CheckAddr(UINT32 loc) { return addr <= loc && loc <= addrEnd; } inline CAddressRef **CAddressTable::GetTableNoCreate(UINT32 addr, int &tableIndex, unsigned &indexInTable) { tableIndex = addr >> INDEX_SHIFT; if (m_tables[tableIndex] == NULL) return NULL; indexInTable = addr & TABLE_MASK; return m_tables[tableIndex]; } inline CAddressRef *CAddressTable::Get(UINT32 addr) { int tableIndex; unsigned indexInTable; CAddressRef **table = GetTableNoCreate(addr, tableIndex, indexInTable); if (table == NULL) return NULL; return table[indexInTable]; } inline CAddressRef *CAddressTable::Get(UINT32 addr, UINT32 size) { int tableIndex; unsigned indexInTable; CAddressRef **table = GetTableNoCreate(addr, tableIndex, indexInTable); for (UINT32 i = 0; i < size; i++) { if (table != NULL) { CAddressRef *ref = table[indexInTable]; if (ref != NULL) return ref; addr++; if (indexInTable >= TABLE_SIZE - 1) table = GetTableNoCreate(addr, tableIndex, indexInTable); else indexInTable++; } else { addr++; table = GetTableNoCreate(addr, tableIndex, indexInTable); } } return NULL; } } #endif // INCLUDED_ADDRESSTABLE_H #endif // SUPERMODEL_DEBUGGER