--- /dev/null
+// ARMware - an ARM emulator
+// Copyright (C) <2007> Wei Hu <wei.hu.tw@gmail.com>
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "memory_controller.h"
+
+#include "logger.h"
+
+namespace SA1100 {
+
+void MemoryController::initRegisters() {
+ mMDCNFG = 0;
+ mMDCAS00 = 0;
+ mMDCAS01 = 0;
+ mMDCAS02 = 0;
+ mMSC0 = 0;
+ mMSC1 = 0;
+ mMECR = 0;
+ mMDREFR = 0;
+ mMDCAS20 = 0;
+ mMDCAS21 = 0;
+ mMDCAS22 = 0;
+ mMSC2 = 0;
+ mSMCNFG = 0;
+}
+
+void MemoryController::reset() {
+ // :NOTE: Wei 2004-Jan-18:
+ //
+ // Bits 0, 1, 16, 17 will reset to 0 when reset.
+ mMDCNFG &= ~((1 << 0) | (1 << 1) | (1 << 16) | (1 << 17));
+
+ // :NOTE: Wei 2003-Dec-11:
+ //
+ // I assume all of the bits which have unknown values when reset have value 0.
+ mMDREFR =
+ static_cast<uint32_t>((1 << 31) | (1 << 26) | (1 << 22) | (1 << 18));
+
+ // :NOTE: Wei 2003-Dec-11:
+ //
+ // I assume all of the bits which have unknown values when reset have value 0.
+ mMDCAS00 = (1 << 10) | (1 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) |
+ (1 << 2) | (1 << 1) | 1;
+ mMDCAS01 = mMDCAS00;
+ mMDCAS02 = mMDCAS00;
+ mMDCAS20 = mMDCAS00;
+ mMDCAS21 = mMDCAS00;
+ mMDCAS22 = mMDCAS00;
+
+ // :NOTE: Wei 2003-Dec-11:
+ //
+ // I assume all of the bits which have unknown values when reset have value 0.
+ //
+ // :SA-1110 Developer's Manual: p.141: Wei 2004-Jun-09:
+ //
+ // On iPaq H3600, RBW0 have to be 0 to indicate 32-bit 'ROM bus width'.
+ mMSC0 = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 12) | (1 << 11) |
+ (1 << 10) | (1 << 9) | (1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) |
+ (1 << 4) | (1 << 3);
+
+ // :NOTE: Wei 2003-Dec-11:
+ //
+ // I assume all of the bits which have unknown values when reset have value 0.
+ mSMCNFG = (1 << 15) | (1 << 14) | (1 << 6);
+}
+
+uint32_t MemoryController::read32(const uint32_t address) const {
+ switch (address) {
+ case MDCNFG:
+ LOG_REG_R("MemoryController MDCNFG", address, mMDCNFG);
+ return mMDCNFG;
+ case MDCAS00:
+ LOG_REG_R("MemoryController MDCAS00", address, mMDCAS00);
+ return mMDCAS00;
+ case MDCAS01:
+ LOG_REG_R("MemoryController MDCAS01", address, mMDCAS01);
+ return mMDCAS01;
+ case MDCAS02:
+ LOG_REG_R("MemoryController MDCAS02", address, mMDCAS02);
+ return mMDCAS02;
+ case MSC0:
+ LOG_REG_R("MemoryController MSC0", address, mMSC0);
+ return mMSC0;
+ case MSC1:
+ LOG_REG_R("MemoryController MSC1", address, mMSC1);
+ return mMSC1;
+ case MECR:
+ LOG_REG_R("MemoryController MECR", address, mMECR);
+ return mMECR;
+ case MDREFR:
+ LOG_REG_R("MemoryController MDREFR", address, mMDREFR);
+ return mMDREFR;
+ case MDCAS20:
+ LOG_REG_R("MemoryController MDCAS20", address, mMDCAS20);
+ return mMDCAS20;
+ case MDCAS21:
+ LOG_REG_R("MemoryController MDCAS21", address, mMDCAS21);
+ return mMDCAS21;
+ case MDCAS22:
+ LOG_REG_R("MemoryController MDCAS22", address, mMDCAS22);
+ return mMDCAS22;
+ case MSC2:
+ LOG_REG_R("MemoryController MSC2", address, mMSC2);
+ return mMSC2;
+ case SMCNFG:
+ LOG_REG_R("MemoryController SMCNFG", address, mSMCNFG);
+ return mSMCNFG;
+ default:
+ LOG_REG_R("MemoryController Unknown", address, 0);
+ return 0;
+ }
+}
+
+void MemoryController::write32(const uint32_t address, const uint32_t value) {
+ switch (address) {
+ case MDCNFG:
+ LOG_REG_W("MemoryController MDCNFG", address, value);
+ mMDCNFG = value;
+ break;
+ case MDCAS00:
+ LOG_REG_W("MemoryController MDCAS00", address, value);
+ mMDCAS00 = value;
+ break;
+ case MDCAS01:
+ LOG_REG_W("MemoryController MDCAS01", address, value);
+ mMDCAS01 = value;
+ break;
+ case MDCAS02:
+ LOG_REG_W("MemoryController MDCAS02", address, value);
+ mMDCAS02 = value;
+ break;
+ case MSC0:
+ LOG_REG_W("MemoryController MSC0", address, value);
+ mMSC0 = value;
+ break;
+ case MSC1:
+ LOG_REG_W("MemoryController MSC1", address, value);
+ mMSC1 = value;
+ break;
+ case MECR:
+ LOG_REG_W("MemoryController MECR", address, value);
+ mMECR = value;
+ break;
+ case MDREFR:
+ LOG_REG_W("MemoryController MDREFR", address, value);
+ mMDREFR = value;
+ break;
+ case MDCAS20:
+ LOG_REG_W("MemoryController MDCAS20", address, value);
+ mMDCAS20 = value;
+ break;
+ case MDCAS21:
+ LOG_REG_W("MemoryController MDCAS21", address, value);
+ mMDCAS21 = value;
+ break;
+ case MDCAS22:
+ LOG_REG_W("MemoryController MDCAS22", address, value);
+ mMDCAS22 = value;
+ break;
+ case MSC2:
+ LOG_REG_W("MemoryController MSC2", address, value);
+ mMSC2 = value;
+ break;
+ case SMCNFG:
+ LOG_REG_W("MemoryController SMCNFG", address, value);
+ mSMCNFG = value;
+ break;
+ default:
+ LOG_REG_W("MemoryController Unknown", address, value);
+ break;
+ }
+}
+
+} // namespace SA1100
--- /dev/null
+// ARMware - an ARM emulator
+// Copyright (C) <2007> Wei Hu <wei.hu.tw@gmail.com>
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef MEMORY_CONTROLLER_H
+#define MEMORY_CONTROLLER_H
+
+#include <cstdint>
+
+namespace SA1100 {
+
+class MemoryController {
+public:
+ MemoryController() { initRegisters(); }
+
+ void reset();
+
+ uint32_t read32(const uint32_t address) const;
+ void write32(const uint32_t address, const uint32_t value);
+
+private:
+ void initRegisters();
+
+ enum {
+ MDCNFG = 0xA0000000,
+ MDCAS00 = 0xA0000004,
+ MDCAS01 = 0xA0000008,
+ MDCAS02 = 0xA000000C,
+ MSC0 = 0xA0000010,
+ MSC1 = 0xA0000014,
+ MECR = 0xA0000018,
+ MDREFR = 0xA000001C,
+ MDCAS20 = 0xA0000020,
+ MDCAS21 = 0xA0000024,
+ MDCAS22 = 0xA0000028,
+ MSC2 = 0xA000002C,
+ SMCNFG = 0xA0000030
+ };
+
+ uint32_t mMDCNFG; // DRAM Configuration register
+ uint32_t mMDCAS00; // CAS waveform rotate register 0 for DRAM bank pair 0/1
+ uint32_t mMDCAS01; // CAS waveform rotate register 1 for DRAM bank pair 0/1
+ uint32_t mMDCAS02; // CAS waveform rotate register 2 for DRAM bank pair 0/1
+ uint32_t mMSC0; // Static memory control register 0
+ uint32_t mMSC1; // Static memory control register 1
+ uint32_t mMECR; // Expansion memory (PC-Card) bus configuration register
+ uint32_t mMDREFR; // DRAM refresh control register
+ uint32_t mMDCAS20; // CAS waveform rotate register 0 for DRAM bank pair 2/3
+ uint32_t mMDCAS21; // CAS waveform rotate register 1 for DRAM bank pair 2/3
+ uint32_t mMDCAS22; // CAS waveform rotate register 2 for DRAM bank pair 2/3
+ uint32_t mMSC2; // Static memory control register 2
+ uint32_t mSMCNFG; // SMROM configuration register
+};
+
+} // namespace SA1100
+
+#endif // MEMORY_CONTROLLER_H