diff --git a/Core/Core.csproj b/Core/Core.csproj
index 7be6fbe..6886036 100644
--- a/Core/Core.csproj
+++ b/Core/Core.csproj
@@ -9,9 +9,7 @@
-
-
diff --git a/Core/Interfaces/IAudioDevice.cs b/Core/Interfaces/IAudioDevice.cs
new file mode 100644
index 0000000..98d2426
--- /dev/null
+++ b/Core/Interfaces/IAudioDevice.cs
@@ -0,0 +1,8 @@
+namespace Core.Interfaces
+{
+ public interface IAudioDevice
+ {
+ // Now accepts the Beeper state + 3 AY frequencies + 3 AY volumes
+ void AddSample(bool isHigh, float freqA, float volA, float freqB, float volB, float freqC, float volC);
+ }
+}
\ No newline at end of file
diff --git a/Core/Interfaces/IIoBus.cs b/Core/Interfaces/IIoBus.cs
new file mode 100644
index 0000000..c28821e
--- /dev/null
+++ b/Core/Interfaces/IIoBus.cs
@@ -0,0 +1,8 @@
+namespace Core.Interfaces
+{
+ public interface IIoBus
+ {
+ byte Read(ushort port);
+ void Write(ushort port, byte value);
+ }
+}
diff --git a/Core/Interfaces/IMemory.cs b/Core/Interfaces/IMemory.cs
new file mode 100644
index 0000000..cd84d64
--- /dev/null
+++ b/Core/Interfaces/IMemory.cs
@@ -0,0 +1,9 @@
+namespace Core.Interfaces
+{
+ public interface IMemory
+ {
+ byte Read(ushort address);
+ void Write(ushort address, byte value);
+ void CleanRAMData();
+ }
+}
diff --git a/Core/Memory/SmsMemoryBus.cs b/Core/Memory/SmsMemoryBus.cs
new file mode 100644
index 0000000..dbcd319
--- /dev/null
+++ b/Core/Memory/SmsMemoryBus.cs
@@ -0,0 +1,109 @@
+using Core.Interfaces;
+using System;
+
+namespace Core.Memory
+{
+ public class SmsMemoryBus : IMemory
+ {
+ // SMS has 8KB of internal Work RAM
+ private readonly byte[] _workRam = new byte[0x2000];
+
+ // The entire game cartridge loaded into one big array
+ private byte[] _cartridgeRom = Array.Empty();
+
+ // The Paging Registers (Which 16KB chunk is in which slot?)
+ // Default startup state: Bank 0, 1, and 2 in order.
+ private int _romBank0 = 0;
+ private int _romBank1 = 1;
+ private int _romBank2 = 2;
+
+ // A flag to handle cartridges that don't use paging (like early 32KB games)
+ private bool _isCartridgeLoaded = false;
+
+ public void LoadCartridge(byte[] romData)
+ {
+ _cartridgeRom = romData;
+ _isCartridgeLoaded = true;
+
+ // Reset the mapper on boot
+ _romBank0 = 0;
+ _romBank1 = 1;
+ _romBank2 = 2;
+
+ // Clean the RAM
+ CleanRAMData();
+ }
+
+ public byte Read(ushort address)
+ {
+ if (address < 0x4000) // ROM Slot 0 (0x0000 - 0x3FFF)
+ {
+ // SMS Hardware Quirk: The first 1KB (0x0000 - 0x03FF) is NEVER paged.
+ // It is hardwired to Bank 0 so the interrupt handlers don't crash.
+ if (address < 0x0400) return ReadFromCartridge(0, address);
+
+ return ReadFromCartridge(_romBank0, address);
+ }
+ if (address < 0x8000) // ROM Slot 1 (0x4000 - 0x7FFF)
+ {
+ return ReadFromCartridge(_romBank1, address & 0x3FFF);
+ }
+ if (address < 0xC000) // ROM Slot 2 (0x8000 - 0xBFFF)
+ {
+ return ReadFromCartridge(_romBank2, address & 0x3FFF);
+ }
+
+ // If we are here, we are in System RAM (0xC000 - 0xFFFF)
+ // The & 0x1FFF handles the 8KB mirroring automatically!
+ return _workRam[address & 0x1FFF];
+ }
+
+ public void Write(ushort address, byte value)
+ {
+ if (address < 0xC000)
+ {
+ // You cannot write to a ROM cartridge!
+ return;
+ }
+
+ // Write to System RAM
+ _workRam[address & 0x1FFF] = value;
+
+ // --- THE SEGA MAPPER ---
+ // If the CPU wrote to the very top of memory, it is commanding a bank swap!
+ if (address == 0xFFFD)
+ {
+ _romBank0 = value;
+ }
+ else if (address == 0xFFFE)
+ {
+ _romBank1 = value;
+ }
+ else if (address == 0xFFFF)
+ {
+ _romBank2 = value;
+ }
+ }
+
+ private byte ReadFromCartridge(int bankIndex, int offset)
+ {
+ if (!_isCartridgeLoaded) return 0xFF; // Floating bus if no game
+
+ int absoluteAddress = (bankIndex * 0x4000) + offset;
+
+ // Safety check in case a game asks for a bank outside its file size
+ if (absoluteAddress >= _cartridgeRom.Length)
+ {
+ // Wrap around (mirrors the ROM if it's smaller than the requested bank)
+ absoluteAddress %= _cartridgeRom.Length;
+ }
+
+ return _cartridgeRom[absoluteAddress];
+ }
+
+ public void CleanRAMData()
+ {
+ Array.Clear(_workRam, 0, _workRam.Length);
+ }
+ }
+}
\ No newline at end of file