2013-02-07 01:05:47 +00:00
|
|
|
#include "defs.h"
|
|
|
|
#include "fmem.h"
|
|
|
|
#include "CpuModule.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
/* Illegal read / write fault information */
|
|
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
BOOLE memory_fault_read = FALSE; /* TRUE - read / FALSE - write */
|
|
|
|
ULO memory_fault_address = 0;
|
|
|
|
|
|
|
|
/*==============================================================================
|
|
|
|
Raises exception 3 when a word or long is accessing an odd address
|
|
|
|
and the CPU is < 020
|
|
|
|
==============================================================================*/
|
|
|
|
|
|
|
|
static void memoryOddRead(ULO address)
|
|
|
|
{
|
|
|
|
if (address & 1)
|
|
|
|
{
|
|
|
|
if (cpuGetModelMajor() < 2)
|
|
|
|
{
|
|
|
|
memory_fault_read = TRUE;
|
|
|
|
memory_fault_address = address;
|
|
|
|
cpuThrowAddressErrorException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void memoryOddWrite(ULO address)
|
|
|
|
{
|
|
|
|
if (address & 1)
|
|
|
|
{
|
|
|
|
if (cpuGetModelMajor() < 2)
|
|
|
|
{
|
|
|
|
memory_fault_read = FALSE;
|
|
|
|
memory_fault_address = address;
|
|
|
|
cpuThrowAddressErrorException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// new memory functions.
|
|
|
|
|
|
|
|
static uint8_t *Memory = NULL;
|
|
|
|
static uint32_t MemorySize = 0;
|
2013-02-10 01:06:30 +00:00
|
|
|
static uint32_t MemoryGlobalLog = 0;
|
2013-02-07 01:05:47 +00:00
|
|
|
|
2013-07-02 22:48:40 +00:00
|
|
|
static memoryLoggingFunc MemoryLoggingFunc = NULL;
|
|
|
|
|
|
|
|
void memorySetLoggingFunc(memoryLoggingFunc func)
|
|
|
|
{
|
|
|
|
MemoryLoggingFunc = func;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
void memorySetMemory(uint8_t *memory, uint32_t size)
|
|
|
|
{
|
|
|
|
Memory = memory;
|
|
|
|
MemorySize = size;
|
|
|
|
}
|
|
|
|
|
2013-02-10 01:06:30 +00:00
|
|
|
void memorySetGlobalLog(uint32_t globalLog)
|
|
|
|
{
|
|
|
|
MemoryGlobalLog = globalLog;
|
|
|
|
}
|
|
|
|
|
2013-02-11 01:19:01 +00:00
|
|
|
|
|
|
|
uint8_t *memoryPointer(uint32_t address)
|
|
|
|
{
|
|
|
|
return Memory + address;
|
|
|
|
}
|
|
|
|
|
2013-02-16 04:47:48 +00:00
|
|
|
// memory read of 0xffffffff not handled correctly
|
|
|
|
// since the unsigned compare overflows.
|
2013-02-07 01:05:47 +00:00
|
|
|
UBY memoryReadByte(ULO address)
|
|
|
|
{
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-07-02 22:48:40 +00:00
|
|
|
if (MemoryLoggingFunc)
|
|
|
|
MemoryLoggingFunc(address, 1, 0, 0);
|
|
|
|
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
// hmmm... 32-bit clean addresses?
|
|
|
|
if (address < MemorySize)
|
|
|
|
return Memory[address];
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
UWO memoryReadWord(ULO address)
|
|
|
|
{
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-07-02 22:48:40 +00:00
|
|
|
if (MemoryLoggingFunc)
|
|
|
|
MemoryLoggingFunc(address, 2, 0, 0);
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
if (address & 0x01) memoryOddRead(address);
|
|
|
|
|
|
|
|
if (address + 1 < MemorySize)
|
|
|
|
return (Memory[address++] << 8)
|
|
|
|
| (Memory[address++] << 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ULO memoryReadLong(ULO address)
|
|
|
|
{
|
2013-07-02 22:48:40 +00:00
|
|
|
|
|
|
|
if (MemoryLoggingFunc)
|
|
|
|
MemoryLoggingFunc(address, 4, 0, 0);
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
if (address & 0x01) memoryOddRead(address);
|
|
|
|
|
2013-02-21 04:10:00 +00:00
|
|
|
if (address + 3 < MemorySize)
|
2013-02-07 01:05:47 +00:00
|
|
|
return (Memory[address++] << 24)
|
|
|
|
| (Memory[address++] << 16)
|
|
|
|
| (Memory[address++] << 8)
|
|
|
|
| (Memory[address++] << 0);
|
|
|
|
|
|
|
|
return 0;
|
2013-02-21 04:10:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t memoryReadLongLong(ULO address)
|
|
|
|
{
|
|
|
|
uint64_t tmp;
|
2013-02-07 01:05:47 +00:00
|
|
|
|
2013-02-21 04:10:00 +00:00
|
|
|
tmp = memoryReadLong(address);
|
|
|
|
tmp <<= 32;
|
|
|
|
tmp |= memoryReadLong(address + 4);
|
|
|
|
|
|
|
|
return tmp;
|
2013-02-07 01:05:47 +00:00
|
|
|
}
|
2013-02-21 04:10:00 +00:00
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
void memoryWriteByte(UBY data, ULO address)
|
|
|
|
{
|
2013-07-02 22:48:40 +00:00
|
|
|
|
|
|
|
if (MemoryLoggingFunc)
|
|
|
|
MemoryLoggingFunc(address, 1, 1, data);
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
if (address < MemorySize)
|
|
|
|
{
|
|
|
|
Memory[address] = data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void memoryWriteWord(UWO data, ULO address)
|
|
|
|
{
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-07-02 22:48:40 +00:00
|
|
|
if (MemoryLoggingFunc)
|
|
|
|
MemoryLoggingFunc(address, 2, 1, data);
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
if (address & 0x01) memoryOddWrite(address);
|
|
|
|
|
|
|
|
if (address + 1 < MemorySize)
|
|
|
|
{
|
|
|
|
Memory[address++] = data >> 8;
|
|
|
|
Memory[address++] = data >> 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void memoryWriteLong(ULO data, ULO address)
|
|
|
|
{
|
2013-02-08 04:44:26 +00:00
|
|
|
|
2013-07-02 22:48:40 +00:00
|
|
|
if (MemoryLoggingFunc)
|
|
|
|
MemoryLoggingFunc(address, 4, 1, data);
|
2013-02-08 04:44:26 +00:00
|
|
|
|
|
|
|
|
2013-02-07 01:05:47 +00:00
|
|
|
if (address & 0x01) memoryOddWrite(address);
|
|
|
|
|
|
|
|
if (address + 3 < MemorySize)
|
|
|
|
{
|
|
|
|
Memory[address++] = data >> 24;
|
|
|
|
Memory[address++] = data >> 16;
|
|
|
|
Memory[address++] = data >> 8;
|
|
|
|
Memory[address++] = data >> 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-21 04:10:00 +00:00
|
|
|
void memoryWriteLongLong(uint64_t data, ULO address)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (address & 0x01) memoryOddWrite(address);
|
|
|
|
|
|
|
|
if (address + 7 < MemorySize)
|
|
|
|
{
|
|
|
|
Memory[address++] = data >> 56;
|
|
|
|
Memory[address++] = data >> 48;
|
|
|
|
Memory[address++] = data >> 40;
|
|
|
|
Memory[address++] = data >> 32;
|
|
|
|
Memory[address++] = data >> 24;
|
|
|
|
Memory[address++] = data >> 16;
|
|
|
|
Memory[address++] = data >> 8;
|
|
|
|
Memory[address++] = data >> 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|