67 lines
2.2 KiB
C#
67 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);
|
|
|
|
// Audio Ports
|
|
if (lowerPort == 0x7E || lowerPort == 0x7F)
|
|
{
|
|
AudioProcessor.WritePort7F(value);
|
|
}
|
|
// Video Ports
|
|
else if (lowerPort == 0xBE)
|
|
{
|
|
VideoProcessor.WriteDataPort(value);
|
|
}
|
|
else if (lowerPort == 0xBF)
|
|
{
|
|
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!
|
|
}
|
|
}
|
|
}
|
|
} |