]> localhost Git - WindEmu.git/commitdiff
series7: add stub sa-1100 CPU core
authorGeorge Wright <gw@gwright.org.uk>
Thu, 25 Jun 2026 01:43:35 +0000 (18:43 -0700)
committerGeorge Wright <gw@gwright.org.uk>
Fri, 26 Jun 2026 03:44:06 +0000 (20:44 -0700)
CMakeLists.txt
WindCore/series7/sa1100.cpp [new file with mode: 0644]
WindCore/series7/sa1100.h [new file with mode: 0644]
WindCore/series7/sa1100_memory.cpp [new file with mode: 0644]
WindCore/series7/series7_defs.h [new file with mode: 0644]

index b2170c12e21c455b7897e7fba30d70ca313b6485..be002264bc0df9d65b2a14e7a647e2f75abf44e6 100644 (file)
@@ -22,6 +22,8 @@ set(WIND_CORE_SOURCES
     WindCore/osaris/clps7600.cpp
     WindCore/series5mx/etna.cpp
     WindCore/series5mx/windermere.cpp
+    WindCore/series7/sa1100.cpp
+    WindCore/series7/sa1100_memory.cpp
 )
 
 add_library(WindCore STATIC ${WIND_CORE_SOURCES})
diff --git a/WindCore/series7/sa1100.cpp b/WindCore/series7/sa1100.cpp
new file mode 100644 (file)
index 0000000..ce3135b
--- /dev/null
@@ -0,0 +1,93 @@
+#include "sa1100.h"
+
+#include "common.h"
+
+#include <cstdint>
+
+namespace SA1100 {
+
+Emulator::Emulator() : EmuBase(false) {}
+
+uint32_t Emulator::getRTC() { return 0; }
+
+void Emulator::configure() {
+  if (configured)
+    return;
+
+  configured = true;
+  srand(1000);
+  nextTickAt = Series7::TICK_INTERVAL;
+  reset();
+}
+
+uint8_t* Emulator::getROMBuffer() { return ROM; }
+size_t Emulator::getROMSize() { return sizeof(ROM); }
+void Emulator::loadROM(uint8_t* buffer, size_t size) {
+  memcpy(ROM, buffer, size);
+}
+
+void Emulator::executeUntil(int64_t cycles) {
+  if (!configured)
+    configure();
+
+  while (!asleep && passedCycles < cycles) {
+    if (passedCycles >= nextTickAt) {
+      // increment RTCDIV
+      if ((pwrsr & 0x3F) == 0x3F) {
+        pwrsr &= ~0x3F;
+      } else {
+        pwrsr++;
+      }
+
+      nextTickAt += Series7::TICK_INTERVAL;
+    }
+
+    // what's running?
+    if (halted) {
+      // keep the clock moving
+      // when does the next earliest thing happen?
+      // this stops us from spinning needlessly
+      int64_t nextEvent = nextTickAt;
+      if (cycles < nextEvent)
+        nextEvent = cycles;
+      passedCycles = nextEvent;
+    } else {
+      if (auto v = virtToPhys(getGPR(15) - 0xC);
+          v.has_value() && instructionReady())
+        debugPC(v.value());
+      passedCycles += tick();
+    }
+  }
+}
+
+const char* Emulator::identifyObjectCon(uint32_t ptr) { return NULL; }
+
+void Emulator::fetchStr(uint32_t str, char* buf) {}
+
+void Emulator::fetchName(uint32_t obj, char* buf) {}
+
+void Emulator::fetchProcessFilename(uint32_t obj, char* buf) {}
+
+void Emulator::debugPC(uint32_t pc) {}
+
+const char* Emulator::getDeviceName() const { return "Series 7"; }
+int Emulator::getDigitiserWidth() const { return 783; }
+int Emulator::getDigitiserHeight() const { return 480; }
+int Emulator::getLCDOffsetX() const { return 71; }
+int Emulator::getLCDOffsetY() const { return 0; }
+int Emulator::getLCDWidth() const { return 640; }
+int Emulator::getLCDHeight() const { return 480; }
+
+void Emulator::readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const {}
+
+void Emulator::diffPorts(uint32_t oldval, uint32_t newval) {}
+
+void Emulator::diffInterrupts(uint16_t oldval, uint16_t newval) {}
+
+uint32_t Emulator::readKeyboard() {}
+
+void Emulator::setKeyboardKey(EpocKey key, bool value) {}
+
+void Emulator::updateTouchInput(int32_t x, int32_t y, bool down) {}
+
+} // namespace SA1100
diff --git a/WindCore/series7/sa1100.h b/WindCore/series7/sa1100.h
new file mode 100644 (file)
index 0000000..23d8e10
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef SA1100_H
+#define SA1100_H
+
+#include "emubase.h"
+#include "series7_defs.h"
+
+namespace SA1100 {
+
+// Relatively simple implementation of a StrongARM SA-1100 CPU
+//
+// The following resources are invaluable to determining how the SA-1100
+// operates:
+//
+// SA-1100 Technical documentation:
+//   https://courses.cs.washington.edu/courses/cse466/00au/sa1100dev.pdf
+// Address space layout:
+//   https://people.kth.se/~maguire/badge3/memorymap.html
+// ARMware emulator:
+//   https://github.com/Halajohn/ARMware
+// bookboot:
+//   https://web.archive.org/web/20060716045807/http://linux-7110.sourceforge.net/files/People/Klaasjan/netbook/
+
+class Emulator : public EmuBase {
+public:
+  // 16MB ROM
+  uint8_t ROM[0x1000000];
+  // 16MB RAM/bank0, mapped at base addr 0xC0000000
+  uint8_t MemoryBlockC0[0x1000000];
+  // 16MB RAM/bank1, mapped at base addr 0xC8000000
+  // On the netBook, the OS.img minus the 256-byte wrapper is copied to this RAM
+  // See the bookboot README file (linked above)
+  uint8_t MemoryBlockC8[0x1000000];
+  enum { MemoryBlockMask = 0x0FFFFFF };
+
+private:
+  uint32_t pwrsr = 0x00002000; // cold start flag
+  bool halted = false, asleep = false;
+  uint32_t getRTC();
+
+public:
+  MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) override;
+  bool writePhysical(uint32_t value, uint32_t physAddr,
+                     ValueSize valueSize) override;
+
+private:
+  uint8_t readPhysical8(uint32_t physAddr);
+  uint32_t readPhysical32(uint32_t physAddr);
+
+  bool writePhysical8(uint8_t value, uint32_t physAddr);
+  bool writePhysical32(uint32_t value, uint32_t physAddr);
+
+  uint8_t readPCM8(uint32_t physAddr);
+  uint32_t readPCM32(uint32_t physAddr);
+
+  uint8_t readSCM8(uint32_t physAddr);
+  uint32_t readSCM32(uint32_t physAddr);
+
+  bool writePCM8(uint8_t value, uint32_t physAddr);
+  bool writePCM32(uint32_t value, uint32_t physAddr);
+
+  bool writeSCM8(uint8_t value, uint32_t physAddr);
+  bool writeSCM32(uint32_t value, uint32_t physAddr);
+
+  bool configured = false;
+  void configure();
+
+  const char* identifyObjectCon(uint32_t ptr);
+  void fetchStr(uint32_t str, char* buf);
+  void fetchName(uint32_t obj, char* buf);
+  void fetchProcessFilename(uint32_t obj, char* buf);
+  void debugPC(uint32_t pc);
+  void diffPorts(uint32_t oldval, uint32_t newval);
+  void diffInterrupts(uint16_t oldval, uint16_t newval);
+  uint32_t readKeyboard();
+
+public:
+  Emulator();
+  uint8_t* getROMBuffer() override;
+  size_t getROMSize() override;
+  void loadROM(uint8_t* buffer, size_t size) override;
+  void executeUntil(int64_t cycles) override;
+  int32_t getClockSpeed() const override { return Series7::CLOCK_SPEED; }
+  const char* getDeviceName() const override;
+  int getDigitiserWidth() const override;
+  int getDigitiserHeight() const override;
+  int getLCDOffsetX() const override;
+  int getLCDOffsetY() const override;
+  int getLCDWidth() const override;
+  int getLCDHeight() const override;
+  void readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const override;
+  void setKeyboardKey(EpocKey key, bool value) override;
+  void updateTouchInput(int32_t x, int32_t y, bool down) override;
+};
+
+} // namespace SA1100
+
+#endif // SA1100_H
diff --git a/WindCore/series7/sa1100_memory.cpp b/WindCore/series7/sa1100_memory.cpp
new file mode 100644 (file)
index 0000000..fbb79da
--- /dev/null
@@ -0,0 +1,650 @@
+#include "sa1100.h"
+
+#include "common.h"
+
+namespace SA1100 {
+
+MaybeU32 Emulator::readPhysical(uint32_t physAddr, ValueSize valueSize) {
+  if (valueSize == V8) {
+    return readPhysical8(physAddr);
+  } else {
+    return readPhysical32(physAddr);
+  }
+}
+
+bool Emulator::writePhysical(uint32_t value, uint32_t physAddr,
+                             ValueSize valueSize) {
+  uint8_t region = (physAddr >> 24) & 0xFF;
+  if (valueSize == V8) {
+    return writePhysical8((uint8_t)value, physAddr);
+  } else {
+    return writePhysical32(value, physAddr);
+  }
+}
+
+uint8_t Emulator::readPCM8(uint32_t physAddr) {
+  // Peripheral Control Modules
+  return 0x0;
+}
+
+bool Emulator::writePCM8(uint8_t value, uint32_t physAddr) { return true; }
+
+uint32_t Emulator::readPCM32(uint32_t physAddr) {
+  // Peripheral Control Modules
+  return 0x0;
+}
+
+bool Emulator::writePCM32(uint32_t value, uint32_t physAddr) { return true; }
+
+uint8_t Emulator::readSCM8(uint32_t physAddr) {
+  // System Control Modules
+  return 0x0;
+}
+
+bool Emulator::writeSCM8(uint8_t value, uint32_t physAddr) { return true; }
+
+uint32_t Emulator::readSCM32(uint32_t physAddr) {
+  // System Control Modules
+  return 0x0;
+}
+
+bool Emulator::writeSCM32(uint32_t value, uint32_t physAddr) { return true; }
+
+uint8_t Emulator::readPhysical8(uint32_t physAddr) {
+  uint8_t region = (physAddr >> 24) & 0xFF;
+
+  switch (region) {
+  case 0x00:
+    return ROM[physAddr & 0xFFFFFF];
+  case 0x20:
+  case 0x21:
+  case 0x22:
+  case 0x23:
+  case 0x24:
+  case 0x25:
+  case 0x26:
+  case 0x27:
+  case 0x28:
+  case 0x29:
+  case 0x2A:
+  case 0x2B:
+  case 0x2C:
+  case 0x2D:
+  case 0x2E:
+  case 0x2F:
+    // PCMCIA slot 0
+    return 0x0;
+  case 0x30:
+  case 0x31:
+  case 0x32:
+  case 0x33:
+  case 0x34:
+  case 0x35:
+  case 0x36:
+  case 0x37:
+  case 0x38:
+  case 0x39:
+  case 0x3A:
+  case 0x3B:
+  case 0x3C:
+  case 0x3D:
+  case 0x3E:
+  case 0x3F:
+    // PCMCIA slot 1
+    return 0x0;
+  case 0x40:
+  case 0x41:
+  case 0x42:
+  case 0x43:
+  case 0x44:
+  case 0x45:
+  case 0x46:
+  case 0x47:
+  case 0x48:
+  case 0x49:
+  case 0x4A:
+  case 0x4B:
+  case 0x4C:
+  case 0x4D:
+  case 0x4E:
+  case 0x4F:
+  case 0x50:
+  case 0x51:
+  case 0x52:
+  case 0x53:
+  case 0x54:
+  case 0x55:
+  case 0x56:
+  case 0x57:
+  case 0x58:
+  case 0x59:
+  case 0x5A:
+  case 0x5B:
+  case 0x5C:
+  case 0x5D:
+  case 0x5E:
+  case 0x5F:
+  case 0x60:
+  case 0x61:
+  case 0x62:
+  case 0x63:
+  case 0x64:
+  case 0x65:
+  case 0x66:
+  case 0x67:
+  case 0x68:
+  case 0x69:
+  case 0x6A:
+  case 0x6B:
+  case 0x6C:
+  case 0x6D:
+  case 0x6E:
+  case 0x6F:
+  case 0x70:
+  case 0x71:
+  case 0x72:
+  case 0x73:
+  case 0x74:
+  case 0x75:
+  case 0x76:
+  case 0x77:
+  case 0x78:
+  case 0x79:
+  case 0x7A:
+  case 0x7B:
+  case 0x7C:
+  case 0x7D:
+  case 0x7E:
+  case 0x7F:
+    // Reserved, causes a data abort exception
+    return 0x0;
+  case 0x80:
+    // Peripheral Control Modules
+    return readPCM8(physAddr);
+  case 0x90:
+    // System Control Modules
+    return readSCM8(physAddr);
+  case 0xA0:
+    // Memory Control Registers
+    // Not valid in byte access
+    return 0x0;
+  case 0xB0:
+    // LCD/DMA Control Registers
+    return 0x0;
+  case 0xC0:
+  case 0xC1:
+  case 0xC2:
+  case 0xC3:
+  case 0xC4:
+  case 0xC5:
+  case 0xC6:
+  case 0xC7:
+    return MemoryBlockC0[physAddr & MemoryBlockMask];
+  case 0xC8:
+  case 0xC9:
+  case 0xCA:
+  case 0xCB:
+  case 0xCC:
+  case 0xCD:
+  case 0xCE:
+  case 0xCF:
+    return MemoryBlockC8[physAddr & MemoryBlockMask];
+  default:
+    return 0x0; // just throw accesses to unmapped RAM away
+  }
+}
+
+bool Emulator::writePhysical8(uint8_t value, uint32_t physAddr) {
+  uint8_t region = (physAddr >> 24) & 0xFF;
+
+  switch (region) {
+  case 0x00:
+    // Read-only
+    return false;
+    break;
+  case 0x20:
+  case 0x21:
+  case 0x22:
+  case 0x23:
+  case 0x24:
+  case 0x25:
+  case 0x26:
+  case 0x27:
+  case 0x28:
+  case 0x29:
+  case 0x2A:
+  case 0x2B:
+  case 0x2C:
+  case 0x2D:
+  case 0x2E:
+  case 0x2F:
+    // PCMCIA slot 0
+    return true;
+  case 0x30:
+  case 0x31:
+  case 0x32:
+  case 0x33:
+  case 0x34:
+  case 0x35:
+  case 0x36:
+  case 0x37:
+  case 0x38:
+  case 0x39:
+  case 0x3A:
+  case 0x3B:
+  case 0x3C:
+  case 0x3D:
+  case 0x3E:
+  case 0x3F:
+    // PCMCIA slot 1
+    return true;
+  case 0x40:
+  case 0x41:
+  case 0x42:
+  case 0x43:
+  case 0x44:
+  case 0x45:
+  case 0x46:
+  case 0x47:
+  case 0x48:
+  case 0x49:
+  case 0x4A:
+  case 0x4B:
+  case 0x4C:
+  case 0x4D:
+  case 0x4E:
+  case 0x4F:
+  case 0x50:
+  case 0x51:
+  case 0x52:
+  case 0x53:
+  case 0x54:
+  case 0x55:
+  case 0x56:
+  case 0x57:
+  case 0x58:
+  case 0x59:
+  case 0x5A:
+  case 0x5B:
+  case 0x5C:
+  case 0x5D:
+  case 0x5E:
+  case 0x5F:
+  case 0x60:
+  case 0x61:
+  case 0x62:
+  case 0x63:
+  case 0x64:
+  case 0x65:
+  case 0x66:
+  case 0x67:
+  case 0x68:
+  case 0x69:
+  case 0x6A:
+  case 0x6B:
+  case 0x6C:
+  case 0x6D:
+  case 0x6E:
+  case 0x6F:
+  case 0x70:
+  case 0x71:
+  case 0x72:
+  case 0x73:
+  case 0x74:
+  case 0x75:
+  case 0x76:
+  case 0x77:
+  case 0x78:
+  case 0x79:
+  case 0x7A:
+  case 0x7B:
+  case 0x7C:
+  case 0x7D:
+  case 0x7E:
+  case 0x7F:
+    // Reserved, causes a data abort exception
+    return false;
+  case 0x80:
+    // Peripheral Control Modules
+    return writePCM8(value, physAddr);
+  case 0x90:
+    // System Control Modules
+    return writeSCM8(value, physAddr);
+  case 0xA0:
+    // Memory Control Registers
+    // Invalid to write to with bytes
+    return false;
+  case 0xB0:
+    // LCD/DMA Control Registers
+    return true;
+  case 0xC0:
+  case 0xC1:
+  case 0xC2:
+  case 0xC3:
+  case 0xC4:
+  case 0xC5:
+  case 0xC6:
+  case 0xC7:
+    MemoryBlockC0[physAddr & MemoryBlockMask] = value;
+    return true;
+  case 0xC8:
+  case 0xC9:
+  case 0xCA:
+  case 0xCB:
+  case 0xCC:
+  case 0xCD:
+  case 0xCE:
+  case 0xCF:
+    MemoryBlockC8[physAddr & MemoryBlockMask] = value;
+    return true;
+  default:
+    // just throw accesses to unmapped RAM away
+    return true;
+  }
+}
+
+uint32_t Emulator::readPhysical32(uint32_t physAddr) {
+  uint8_t region = (physAddr >> 24) & 0xFF;
+  uint32_t result;
+
+  switch (region) {
+  case 0x00:
+    LOAD_32LE(result, physAddr & 0xFFFFFF, ROM);
+    break;
+  case 0x20:
+  case 0x21:
+  case 0x22:
+  case 0x23:
+  case 0x24:
+  case 0x25:
+  case 0x26:
+  case 0x27:
+  case 0x28:
+  case 0x29:
+  case 0x2A:
+  case 0x2B:
+  case 0x2C:
+  case 0x2D:
+  case 0x2E:
+  case 0x2F:
+    // PCMCIA slot 0
+    result = 0x0;
+    break;
+  case 0x30:
+  case 0x31:
+  case 0x32:
+  case 0x33:
+  case 0x34:
+  case 0x35:
+  case 0x36:
+  case 0x37:
+  case 0x38:
+  case 0x39:
+  case 0x3A:
+  case 0x3B:
+  case 0x3C:
+  case 0x3D:
+  case 0x3E:
+  case 0x3F:
+    // PCMCIA slot 1
+    result = 0x0;
+    break;
+  case 0x40:
+  case 0x41:
+  case 0x42:
+  case 0x43:
+  case 0x44:
+  case 0x45:
+  case 0x46:
+  case 0x47:
+  case 0x48:
+  case 0x49:
+  case 0x4A:
+  case 0x4B:
+  case 0x4C:
+  case 0x4D:
+  case 0x4E:
+  case 0x4F:
+  case 0x50:
+  case 0x51:
+  case 0x52:
+  case 0x53:
+  case 0x54:
+  case 0x55:
+  case 0x56:
+  case 0x57:
+  case 0x58:
+  case 0x59:
+  case 0x5A:
+  case 0x5B:
+  case 0x5C:
+  case 0x5D:
+  case 0x5E:
+  case 0x5F:
+  case 0x60:
+  case 0x61:
+  case 0x62:
+  case 0x63:
+  case 0x64:
+  case 0x65:
+  case 0x66:
+  case 0x67:
+  case 0x68:
+  case 0x69:
+  case 0x6A:
+  case 0x6B:
+  case 0x6C:
+  case 0x6D:
+  case 0x6E:
+  case 0x6F:
+  case 0x70:
+  case 0x71:
+  case 0x72:
+  case 0x73:
+  case 0x74:
+  case 0x75:
+  case 0x76:
+  case 0x77:
+  case 0x78:
+  case 0x79:
+  case 0x7A:
+  case 0x7B:
+  case 0x7C:
+  case 0x7D:
+  case 0x7E:
+  case 0x7F:
+    // Reserved, causes a data abort exception
+    result = 0x0;
+    break;
+  case 0x80:
+    // Peripheral Control Modules
+    result = readPCM32(physAddr);
+    break;
+  case 0x90:
+    // System Control Modules
+    result = readSCM32(physAddr);
+    break;
+  case 0xA0:
+    // Memory Control Registers
+    result = 0x0;
+    break;
+  case 0xB0:
+    // LCD/DMA Control Registers
+    result = 0x0;
+    break;
+  case 0xC0:
+  case 0xC1:
+  case 0xC2:
+  case 0xC3:
+  case 0xC4:
+  case 0xC5:
+  case 0xC6:
+  case 0xC7:
+    LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
+    break;
+  case 0xC8:
+  case 0xC9:
+  case 0xCA:
+  case 0xCB:
+  case 0xCC:
+  case 0xCD:
+  case 0xCE:
+  case 0xCF:
+    LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC8);
+    break;
+  default:
+    return 0x0; // just throw accesses to unmapped RAM away
+  }
+
+  return result;
+}
+
+bool Emulator::writePhysical32(uint32_t value, uint32_t physAddr) {
+  uint8_t region = (physAddr >> 24) & 0xFF;
+
+  switch (region) {
+  case 0x00:
+    // Read-only
+    return false;
+    break;
+  case 0x20:
+  case 0x21:
+  case 0x22:
+  case 0x23:
+  case 0x24:
+  case 0x25:
+  case 0x26:
+  case 0x27:
+  case 0x28:
+  case 0x29:
+  case 0x2A:
+  case 0x2B:
+  case 0x2C:
+  case 0x2D:
+  case 0x2E:
+  case 0x2F:
+    // PCMCIA slot 0
+    return true;
+  case 0x30:
+  case 0x31:
+  case 0x32:
+  case 0x33:
+  case 0x34:
+  case 0x35:
+  case 0x36:
+  case 0x37:
+  case 0x38:
+  case 0x39:
+  case 0x3A:
+  case 0x3B:
+  case 0x3C:
+  case 0x3D:
+  case 0x3E:
+  case 0x3F:
+    // PCMCIA slot 1
+    return true;
+  case 0x40:
+  case 0x41:
+  case 0x42:
+  case 0x43:
+  case 0x44:
+  case 0x45:
+  case 0x46:
+  case 0x47:
+  case 0x48:
+  case 0x49:
+  case 0x4A:
+  case 0x4B:
+  case 0x4C:
+  case 0x4D:
+  case 0x4E:
+  case 0x4F:
+  case 0x50:
+  case 0x51:
+  case 0x52:
+  case 0x53:
+  case 0x54:
+  case 0x55:
+  case 0x56:
+  case 0x57:
+  case 0x58:
+  case 0x59:
+  case 0x5A:
+  case 0x5B:
+  case 0x5C:
+  case 0x5D:
+  case 0x5E:
+  case 0x5F:
+  case 0x60:
+  case 0x61:
+  case 0x62:
+  case 0x63:
+  case 0x64:
+  case 0x65:
+  case 0x66:
+  case 0x67:
+  case 0x68:
+  case 0x69:
+  case 0x6A:
+  case 0x6B:
+  case 0x6C:
+  case 0x6D:
+  case 0x6E:
+  case 0x6F:
+  case 0x70:
+  case 0x71:
+  case 0x72:
+  case 0x73:
+  case 0x74:
+  case 0x75:
+  case 0x76:
+  case 0x77:
+  case 0x78:
+  case 0x79:
+  case 0x7A:
+  case 0x7B:
+  case 0x7C:
+  case 0x7D:
+  case 0x7E:
+  case 0x7F:
+    // Reserved, causes a data abort exception
+    return false;
+  case 0x80:
+    // Peripheral Control Modules
+    return writePCM32(value, physAddr);
+  case 0x90:
+    // System Control Modules
+    return writeSCM32(value, physAddr);
+  case 0xA0:
+    // Memory Control Registers
+    return false;
+  case 0xB0:
+    // LCD/DMA Control Registers
+    return true;
+  case 0xC0:
+  case 0xC1:
+  case 0xC2:
+  case 0xC3:
+  case 0xC4:
+  case 0xC5:
+  case 0xC6:
+  case 0xC7:
+    STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
+    return true;
+  case 0xC8:
+  case 0xC9:
+  case 0xCA:
+  case 0xCB:
+  case 0xCC:
+  case 0xCD:
+  case 0xCE:
+  case 0xCF:
+    STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC8);
+    return true;
+  default:
+    // just throw accesses to unmapped RAM away
+    return true;
+  }
+}
+
+} // namespace SA1100
diff --git a/WindCore/series7/series7_defs.h b/WindCore/series7/series7_defs.h
new file mode 100644 (file)
index 0000000..a32233c
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef PSION7_DEFS_H
+#define PSION7_DEFS_H
+
+namespace Series7 {
+
+enum {
+  CLOCK_SPEED = 132710000, // 132.71 MHz
+  TICKS_3_6864_MHZ = CLOCK_SPEED / 3686400,
+  TICKS_1_HZ = CLOCK_SPEED / 1,
+  TICK_INTERVAL = CLOCK_SPEED / 64
+};
+
+} // namespace Series7
+
+#endif // PSION7_DEFS_H