summaryrefslogtreecommitdiff
path: root/io.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'io.cpp')
-rw-r--r--io.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/io.cpp b/io.cpp
new file mode 100644
index 0000000..e46feab
--- /dev/null
+++ b/io.cpp
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: Unlicense
+ */
+
+#include "io.hpp"
+
+#include <cstdio>
+
+uint32_t IO::Read(const uint32_t offset, const enum bitness bitness)
+{
+ uint32_t ret{};
+ if (bitness == BITNESS_32) {
+ ret = (read(offset + 3) << 24) |
+ (read(offset + 2) << 16) |
+ (read(offset + 1) << 8) |
+ read(offset + 0);
+ } else if (bitness == BITNESS_16) {
+ ret = (read(offset + 1) << 8) | read(offset + 0);
+ } else if (bitness == BITNESS_8) {
+ ret = read(offset);
+ }
+ if (DEBUG_TRACE_IO_ACCESS) {
+ printf(
+ "IO r%d%s @0x%08x 0x%0*x\n",
+ bitness * 8,
+ (bitness <= 1 ? " " : ""),
+ base_address + offset,
+ bitness * 2,
+ ret);
+ }
+ return ret;
+}
+
+void IO::Write(const uint32_t offset, const enum bitness bitness, const uint32_t value)
+{
+ if (DEBUG_TRACE_IO_ACCESS) {
+ printf(
+ "IO w%d%s @0x%08x 0x%0*x\n",
+ bitness * 8,
+ (bitness <= 1 ? " " : ""),
+ base_address + offset,
+ bitness * 2,
+ value);
+ }
+ if (bitness == BITNESS_32) {
+ write(offset + 3, value & 0xff);
+ write(offset + 2, (value >> 8) & 0xff);
+ write(offset + 1, (value >> 16) & 0xff);
+ write(offset + 0, (value >> 24) & 0xff);
+ } else if (bitness == BITNESS_16) {
+ write(offset + 0, (value >> 8) & 0xff);
+ write(offset + 1, value & 0xff);
+ } else if (bitness == BITNESS_8) {
+ write(offset, value & 0xff);
+ }
+}
+
+uint32_t IO::read(const uint32_t offset)
+{
+ switch (offset) {
+ case kData1Offset: return _data1;
+ case kData2Offset: return _data2;
+ case kData3Offset: return _data3;
+ case kControl1Offset: return _control1;
+ case kControl2Offset: return _control2;
+ case kControl3Offset: return _control3;
+ case kTx1Offset: return _tx1;
+ case kRx1Offset: return _rx1;
+ case kStatus1Offset: return _status1;
+ case kTx2Offset: return _tx2;
+ case kRx2Offset: return _rx2;
+ case kStatus2Offset: return _status2;
+ case kRx3Offset: return _tx3;
+ case kTx3Offset: return _rx3;
+ case kStatus3Offset: return _status3;
+ case kZ80BusReq: return !_z80_busreq;
+ case kZ80Reset: return 0;
+ }
+ return 0;
+}
+
+void IO::write(const uint32_t offset, const uint8_t value)
+{
+ switch (offset) {
+ case kData1Offset: _data1 = value; break;
+ case kData2Offset: _data2 = value; break;
+ case kData3Offset: _data3 = value; break;
+ case kControl1Offset: _control1 = value; break;
+ case kControl2Offset: _control2 = value; break;
+ case kControl3Offset: _control3 = value; break;
+ case kTx1Offset: _tx1 = value; break;
+ case kRx1Offset: _rx1 = value; break;
+ case kStatus1Offset: _status1 = value; break;
+ case kTx2Offset: _tx2 = value; break;
+ case kRx2Offset: _rx2 = value; break;
+ case kStatus2Offset: _status2 = value; break;
+ case kRx3Offset: _tx3 = value; break;
+ case kTx3Offset: _rx3 = value; break;
+ case kStatus3Offset: _status3 = value; break;
+ case kZ80BusReq: _z80_busreq = value & 0x1; break;
+ case kZ80Reset: _z80_reset = value & 0x1; break;
+ }
+}