Added Golden Axe Warrior. Added Debugger.
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Audio\" />
|
||||
<Folder Include="Cpu\" />
|
||||
<Folder Include="Io\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -53,12 +53,12 @@ namespace Core.Cpu
|
||||
|
||||
// The Memory Bus
|
||||
private readonly IMemory _memory;
|
||||
private readonly IO_Bus _simpleIoBus;
|
||||
private readonly IIoBus _simpleIoBus;
|
||||
|
||||
//External Timing interface
|
||||
public Func<ushort, long, int>? WaitStateCallback { get; set; }
|
||||
|
||||
public Z80(IMemory memory, IO_Bus ioBus)
|
||||
public Z80(IMemory memory, IIoBus ioBus)
|
||||
{
|
||||
_memory = memory;
|
||||
_simpleIoBus = ioBus;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
public interface IIoBus
|
||||
{
|
||||
byte Read(ushort port);
|
||||
void Write(ushort port, byte value);
|
||||
byte ReadPort(ushort port);
|
||||
void WritePort(ushort port, byte value);
|
||||
}
|
||||
}
|
||||
|
||||
62
Core/Io/SmsIoBus.cs
Normal file
62
Core/Io/SmsIoBus.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Core.Interfaces;
|
||||
|
||||
namespace Core.Io
|
||||
{
|
||||
public class SmsIoBus : IIoBus
|
||||
{
|
||||
// We will wire these up in the next phases!
|
||||
// public Vdp 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 >= 0x80 && lowerPort <= 0xBF)
|
||||
{
|
||||
// VDP Read (Usually 0xBE for VRAM Data, 0xBF for Status Flags)
|
||||
// return VideoProcessor.ReadPort(lowerPort);
|
||||
return 0x00;
|
||||
}
|
||||
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)
|
||||
{
|
||||
// VDP Write (Usually 0xBE for VRAM Data, 0xBF for Control Registers)
|
||||
// VideoProcessor.WritePort(lowerPort, 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!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Core/SmsMachine.cs
Normal file
61
Core/SmsMachine.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Core.Cpu;
|
||||
using Core.Io;
|
||||
using Core.Memory;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
public class SmsMachine
|
||||
{
|
||||
public Z80 Cpu { get; private set; }
|
||||
public SmsMemoryBus MemoryBus { get; private set; }
|
||||
public SmsIoBus IoBus { get; private set; }
|
||||
public ushort? Breakpoint { get; set; } = null;
|
||||
|
||||
// NTSC SMS T-States per frame
|
||||
public const int TStatesPerFrame = 59736;
|
||||
public long TotalFrameCount { get; private set; } = 0;
|
||||
public double FramesPerSecond { get; private set; } = 0;
|
||||
public double FrameTime { get; private set; } = 0;
|
||||
|
||||
public SmsMachine()
|
||||
{
|
||||
MemoryBus = new SmsMemoryBus();
|
||||
IoBus = new SmsIoBus();
|
||||
Cpu = new Z80(MemoryBus, IoBus);
|
||||
}
|
||||
|
||||
public void LoadCartridge(byte[] romData)
|
||||
{
|
||||
MemoryBus.LoadCartridge(romData);
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
MemoryBus.CleanRAMData();
|
||||
Cpu.Reset();
|
||||
|
||||
// We will reset the VDP and PSG here later!
|
||||
}
|
||||
|
||||
public void RunFrame()
|
||||
{
|
||||
long currentFrameTStates = 0;
|
||||
|
||||
while (currentFrameTStates < TStatesPerFrame)
|
||||
{
|
||||
int tStates = Cpu.Step();
|
||||
currentFrameTStates += tStates;
|
||||
|
||||
// --- FUTURE EXPANSION ---
|
||||
// VideoProcessor.Update(tStates);
|
||||
// AudioProcessor.Update(tStates);
|
||||
|
||||
// if (VideoProcessor.IsVBlanking && VideoProcessor.InterruptsEnabled)
|
||||
// {
|
||||
// Cpu.RequestInterrupt();
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user