Files
ParsonsMasterSystem2026/Core/Io/SmsIoBus.cs

64 lines
2.2 KiB
C#

using Core.Audio;
using Core.Interfaces;
using Core.Video;
namespace Core.Io
{
public class SmsIoBus : IIoBus
{
public SmsVdp VideoProcessor { get; set; }
public SmsApu AudioProcessor { get; set; }
// Joypad State (0xFF means no buttons pressed - the SMS uses Active-Low logic!)
public byte Joypad1Keyboard = 0xFF;
public byte Joypad1Gamepad = 0xFF;
public byte Joypad2State = 0xFF;
public byte ReadPort(ushort port)
{
// The Z80 can output 16-bit port addresses, but the Master System
// hardware only physically wires up the bottom 8 bits.
byte lowerPort = (byte)(port & 0xFF);
if (lowerPort == 0x7E)
{
// VDP V-Counter (Vertical Scanline Position)
return VideoProcessor.ReadVCounter();
}
if (lowerPort >= 0x80 && lowerPort <= 0xBF)
{
// Even ports (like 0xBE) are Data. Odd ports (like 0xBF) are Control.
if ((lowerPort & 0x01) == 0) return VideoProcessor.ReadDataPort();
else return VideoProcessor.ReadControlPort();
}
if (lowerPort == 0xDC) return (byte)(Joypad1Keyboard & Joypad1Gamepad);
if (lowerPort == 0xDD) return Joypad2State;
return 0xFF; // Floating bus
}
public void WritePort(ushort port, byte value)
{
byte lowerPort = (byte)(port & 0xFF);
if (lowerPort == 0x7E || lowerPort == 0x7F)
{
AudioProcessor.WritePort7F(value);
}
// THE FIX: Video Ports are mirrored across the entire 0x80 to 0xBF range!
else if (lowerPort >= 0x80 && lowerPort <= 0xBF)
{
// Even ports are Data, Odd ports are Control
if ((lowerPort & 0x01) == 0) VideoProcessor.WriteDataPort(value);
else VideoProcessor.WriteControlPort(value);
}
else if (lowerPort <= 0x3F)
{
// Port 0x3E is used by the BIOS to enable/disable the cartridge slot
// We can usually ignore this if we are just directly booting game ROMs!
}
}
}
}