68 lines
2.3 KiB
C#
68 lines
2.3 KiB
C#
using Core.Interfaces;
|
|
using Core.Video;
|
|
|
|
namespace Core.Io
|
|
{
|
|
public class SmsIoBus : IIoBus
|
|
{
|
|
public SmsVdp VideoProcessor { get; set; }
|
|
// public Psg AudioProcessor { get; set; }
|
|
|
|
// Joypad State (0xFF means no buttons pressed - the SMS uses Active-Low logic!)
|
|
public byte Joypad1State { get; set; } = 0xFF;
|
|
public byte Joypad2State { get; set; } = 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)
|
|
{
|
|
// Port 0xDC: Player 1 (Up, Down, Left, Right, 1, 2) + Player 2 (Up, Down)
|
|
return Joypad1State;
|
|
}
|
|
if (lowerPort == 0xDD)
|
|
{
|
|
// Port 0xDD: Player 2 (Left, Right, 1, 2) + Reset Button
|
|
return Joypad2State;
|
|
}
|
|
|
|
return 0xFF; // Floating bus
|
|
}
|
|
|
|
public void WritePort(ushort port, byte value)
|
|
{
|
|
byte lowerPort = (byte)(port & 0xFF);
|
|
|
|
if (lowerPort >= 0x40 && lowerPort <= 0x7F)
|
|
{
|
|
// PSG Audio Write (Usually written exactly to 0x7F)
|
|
// AudioProcessor.WriteData(value);
|
|
}
|
|
else if (lowerPort >= 0x80 && lowerPort <= 0xBF)
|
|
{
|
|
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!
|
|
}
|
|
}
|
|
}
|
|
} |