#include "defs.h" #include "fmem.h" #include "CpuModule.h" /*============================================================================*/ /* Illegal read / write fault information */ /*============================================================================*/ BOOLE memory_fault_read = FALSE; /* TRUE - read / FALSE - write */ uint32_t 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(uint32_t address) { if (address & 1) { if (cpuGetModelMajor() < 2) { memory_fault_read = TRUE; memory_fault_address = address; cpuThrowAddressErrorException(); } } } static void memoryOddWrite(uint32_t 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; static uint32_t MemoryGlobalLog = 0; static memoryLoggingFunc MemoryLoggingFunc = NULL; void memorySetLoggingFunc(memoryLoggingFunc func) { MemoryLoggingFunc = func; } void memorySetMemory(uint8_t *memory, uint32_t size) { Memory = memory; MemorySize = size; } void memorySetGlobalLog(uint32_t globalLog) { MemoryGlobalLog = globalLog; } uint8_t *memoryPointer(uint32_t address) { return Memory + address; } // memory read of 0xffffffff not handled correctly // since the unsigned compare overflows. uint8_t memoryReadByte(uint32_t address) { if (MemoryLoggingFunc) MemoryLoggingFunc(address, 1, 0, 0); // hmmm... 32-bit clean addresses? if (address < MemorySize) return Memory[address]; return 0; } uint16_t memoryReadWord(uint32_t address) { if (MemoryLoggingFunc) MemoryLoggingFunc(address, 2, 0, 0); if (address & 0x01) memoryOddRead(address); if (address + 1 < MemorySize) return (Memory[address + 0] << 8) | (Memory[address + 1] << 0); return 0; } uint32_t memoryReadLong(uint32_t address) { if (MemoryLoggingFunc) MemoryLoggingFunc(address, 4, 0, 0); if (address & 0x01) memoryOddRead(address); if (address + 3 < MemorySize) return (Memory[address + 0] << 24) | (Memory[address + 1] << 16) | (Memory[address + 2] << 8) | (Memory[address + 3] << 0); return 0; } uint64_t memoryReadLongLong(uint32_t address) { uint64_t tmp; tmp = memoryReadLong(address); tmp <<= 32; tmp |= memoryReadLong(address + 4); return tmp; } void memoryWriteByte(uint8_t data, uint32_t address) { if (MemoryLoggingFunc) MemoryLoggingFunc(address, 1, 1, data); if (address < MemorySize) { Memory[address] = data; } } void memoryWriteWord(uint16_t data, uint32_t address) { if (MemoryLoggingFunc) MemoryLoggingFunc(address, 2, 1, data); if (address & 0x01) memoryOddWrite(address); if (address + 1 < MemorySize) { Memory[address++] = data >> 8; Memory[address++] = data >> 0; } } void memoryWriteLong(uint32_t data, uint32_t address) { if (MemoryLoggingFunc) MemoryLoggingFunc(address, 4, 1, data); 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; } } void memoryWriteLongLong(uint64_t data, uint32_t 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; } }