2006-06-15 04:19:30 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "MemoryMap.h"
|
|
|
|
|
|
|
|
CMemoryMap::~CMemoryMap()
|
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
|
2007-11-22 19:49:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMemoryMap::InsertReadMap(uint32 nStart, uint32 nEnd, void* pPointer, unsigned char nKey)
|
|
|
|
{
|
2008-06-15 19:55:28 +00:00
|
|
|
InsertMap(m_readMap, nStart, nEnd, pPointer, nKey);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2007-11-22 19:49:28 +00:00
|
|
|
void CMemoryMap::InsertReadMap(uint32 start, uint32 end, const MemoryMapHandlerType& handler, unsigned char key)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
InsertMap(m_readMap, start, end, handler, key);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2007-11-22 19:49:28 +00:00
|
|
|
void CMemoryMap::InsertWriteMap(uint32 nStart, uint32 nEnd, void* pPointer, unsigned char nKey)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2008-06-15 19:55:28 +00:00
|
|
|
InsertMap(m_writeMap, nStart, nEnd, pPointer, nKey);
|
2007-11-22 19:49:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMemoryMap::InsertWriteMap(uint32 start, uint32 end, const MemoryMapHandlerType& handler, unsigned char key)
|
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
InsertMap(m_writeMap, start, end, handler, key);
|
2008-06-15 19:55:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMemoryMap::InsertInstructionMap(uint32 start, uint32 end, void* pointer, unsigned char key)
|
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
InsertMap(m_instructionMap, start, end, pointer, key);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2012-01-08 06:04:48 +00:00
|
|
|
const CMemoryMap::MEMORYMAPELEMENT* CMemoryMap::GetReadMap(uint32 address) const
|
2008-07-20 17:26:08 +00:00
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
return GetMap(m_readMap, address);
|
2008-07-20 17:26:08 +00:00
|
|
|
}
|
|
|
|
|
2012-01-08 06:04:48 +00:00
|
|
|
const CMemoryMap::MEMORYMAPELEMENT* CMemoryMap::GetWriteMap(uint32 address) const
|
2008-07-20 17:26:08 +00:00
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
return GetMap(m_writeMap, address);
|
2008-07-20 17:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMemoryMap::SetWriteNotifyHandler(const WriteNotifyHandlerType& WriteNotifyHandler)
|
2006-12-26 05:43:34 +00:00
|
|
|
{
|
|
|
|
m_WriteNotifyHandler = WriteNotifyHandler;
|
|
|
|
}
|
|
|
|
|
2007-11-22 19:49:28 +00:00
|
|
|
void CMemoryMap::InsertMap(MemoryMapListType& memoryMap, uint32 start, uint32 end, void* pointer, unsigned char key)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
MEMORYMAPELEMENT element;
|
2012-06-25 18:49:17 +00:00
|
|
|
element.nStart = start;
|
|
|
|
element.nEnd = end;
|
|
|
|
element.pPointer = pointer;
|
|
|
|
element.nType = MEMORYMAP_TYPE_MEMORY;
|
2012-01-08 06:04:48 +00:00
|
|
|
memoryMap.push_back(element);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2007-11-22 19:49:28 +00:00
|
|
|
void CMemoryMap::InsertMap(MemoryMapListType& memoryMap, uint32 start, uint32 end, const MemoryMapHandlerType& handler, unsigned char key)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
MEMORYMAPELEMENT element;
|
2012-06-25 18:49:17 +00:00
|
|
|
element.nStart = start;
|
|
|
|
element.nEnd = end;
|
|
|
|
element.handler = handler;
|
|
|
|
element.pPointer = NULL;
|
|
|
|
element.nType = MEMORYMAP_TYPE_FUNCTION;
|
2012-01-08 06:04:48 +00:00
|
|
|
memoryMap.push_back(element);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2012-01-08 06:04:48 +00:00
|
|
|
const CMemoryMap::MEMORYMAPELEMENT* CMemoryMap::GetMap(const MemoryMapListType& memoryMap, uint32 nAddress)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
for(MemoryMapListType::const_iterator element(memoryMap.begin());
|
|
|
|
memoryMap.end() != element; element++)
|
|
|
|
{
|
|
|
|
const MEMORYMAPELEMENT& mapElement(*element);
|
2007-11-22 19:49:28 +00:00
|
|
|
if(nAddress <= mapElement.nEnd)
|
|
|
|
{
|
|
|
|
if(!(nAddress >= mapElement.nStart)) return NULL;
|
|
|
|
return &mapElement;
|
|
|
|
}
|
2012-01-08 06:04:48 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8 CMemoryMap::GetByte(uint32 nAddress)
|
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_readMap, nAddress);
|
2006-06-15 04:19:30 +00:00
|
|
|
if(e == NULL) return 0xCC;
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
|
|
|
return *(uint8*)&((uint8*)e->pPointer)[nAddress - e->nStart];
|
|
|
|
break;
|
2008-07-17 22:59:58 +00:00
|
|
|
case MEMORYMAP_TYPE_FUNCTION:
|
2012-06-25 18:49:17 +00:00
|
|
|
return static_cast<uint8>(e->handler(nAddress, 0));
|
2008-07-17 22:59:58 +00:00
|
|
|
break;
|
2006-06-15 04:19:30 +00:00
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
return 0xCC;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMemoryMap::SetByte(uint32 nAddress, uint8 nValue)
|
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_writeMap, nAddress);
|
2006-06-15 04:19:30 +00:00
|
|
|
if(e == NULL)
|
|
|
|
{
|
|
|
|
printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, 0x%0.4X).\r\n", nAddress, nValue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
|
|
|
*(uint8*)&((uint8*)e->pPointer)[nAddress - e->nStart] = nValue;
|
|
|
|
break;
|
|
|
|
case MEMORYMAP_TYPE_FUNCTION:
|
2012-06-25 18:49:17 +00:00
|
|
|
e->handler(nAddress, nValue);
|
2006-06-15 04:19:30 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
break;
|
|
|
|
}
|
2006-12-26 05:43:34 +00:00
|
|
|
|
|
|
|
if(m_WriteNotifyHandler)
|
|
|
|
{
|
|
|
|
m_WriteNotifyHandler(nAddress);
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
//LSB First Memory Map Implementation
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
uint16 CMemoryMap_LSBF::GetHalf(uint32 nAddress)
|
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
assert((nAddress & 0x01) == 0);
|
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_readMap, nAddress);
|
2006-06-15 04:19:30 +00:00
|
|
|
if(e == NULL) return 0xCCCC;
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
|
|
|
return *(uint16*)&((uint8*)e->pPointer)[nAddress - e->nStart];
|
|
|
|
break;
|
|
|
|
default:
|
2012-06-25 18:49:17 +00:00
|
|
|
return static_cast<uint16>(e->handler(nAddress, 0));
|
2006-06-15 04:19:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CMemoryMap_LSBF::GetWord(uint32 nAddress)
|
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
assert((nAddress & 0x03) == 0);
|
2012-01-08 06:04:48 +00:00
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_readMap, nAddress);
|
2006-06-15 04:19:30 +00:00
|
|
|
if(e == NULL) return 0xCCCCCCCC;
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
|
|
|
return *(uint32*)&((uint8*)e->pPointer)[nAddress - e->nStart];
|
|
|
|
break;
|
|
|
|
case MEMORYMAP_TYPE_FUNCTION:
|
2012-06-25 18:49:17 +00:00
|
|
|
return e->handler(nAddress, 0);
|
2006-06-15 04:19:30 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
return 0xCCCCCCCC;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-15 19:55:28 +00:00
|
|
|
uint32 CMemoryMap_LSBF::GetInstruction(uint32 address)
|
|
|
|
{
|
2012-06-25 18:49:17 +00:00
|
|
|
assert((address & 0x03) == 0);
|
2012-01-08 06:04:48 +00:00
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_instructionMap, address);
|
2008-06-15 19:55:28 +00:00
|
|
|
if(e == NULL) return 0xCCCCCCCC;
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
|
|
|
return *reinterpret_cast<uint32*>(&reinterpret_cast<uint8*>(e->pPointer)[address - e->nStart]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
return 0xCCCCCCCC;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
void CMemoryMap_LSBF::SetHalf(uint32 nAddress, uint16 nValue)
|
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
assert((nAddress & 0x01) == 0);
|
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_writeMap, nAddress);
|
2006-06-15 04:19:30 +00:00
|
|
|
if(e == NULL)
|
|
|
|
{
|
|
|
|
printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, 0x%0.4X).\r\n", nAddress, nValue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
2008-05-16 21:32:21 +00:00
|
|
|
*reinterpret_cast<uint16*>(&reinterpret_cast<uint8*>(e->pPointer)[nAddress - e->nStart]) = nValue;
|
|
|
|
break;
|
|
|
|
case MEMORYMAP_TYPE_FUNCTION:
|
|
|
|
e->handler(nAddress, nValue);
|
2006-06-15 04:19:30 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
break;
|
|
|
|
}
|
2006-12-26 05:43:34 +00:00
|
|
|
|
|
|
|
if(m_WriteNotifyHandler)
|
|
|
|
{
|
|
|
|
m_WriteNotifyHandler(nAddress);
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMemoryMap_LSBF::SetWord(uint32 nAddress, uint32 nValue)
|
|
|
|
{
|
2012-01-08 06:04:48 +00:00
|
|
|
assert((nAddress & 0x03) == 0);
|
|
|
|
const MEMORYMAPELEMENT* e = GetMap(m_writeMap, nAddress);
|
2006-06-15 04:19:30 +00:00
|
|
|
if(e == NULL)
|
|
|
|
{
|
|
|
|
printf("MemoryMap: Wrote to unmapped memory (0x%0.8X, 0x%0.8X).\r\n", nAddress, nValue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch(e->nType)
|
|
|
|
{
|
|
|
|
case MEMORYMAP_TYPE_MEMORY:
|
|
|
|
*(uint32*)&((uint8*)e->pPointer)[nAddress - e->nStart] = nValue;
|
|
|
|
break;
|
|
|
|
case MEMORYMAP_TYPE_FUNCTION:
|
2012-06-25 18:49:17 +00:00
|
|
|
e->handler(nAddress, nValue);
|
2006-06-15 04:19:30 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
break;
|
|
|
|
}
|
2006-12-26 05:43:34 +00:00
|
|
|
|
|
|
|
if(m_WriteNotifyHandler)
|
|
|
|
{
|
|
|
|
m_WriteNotifyHandler(nAddress);
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|