118 lines
2.9 KiB
C#
118 lines
2.9 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace Iris.GBA
|
|
{
|
|
internal sealed class BIOS : IDisposable
|
|
{
|
|
private const int KB = 1024;
|
|
private const int BIOS_Size = 16 * KB;
|
|
private readonly IntPtr _bios = Marshal.AllocHGlobal(BIOS_Size);
|
|
|
|
private const UInt32 BIOS_StartAddress = 0x0000_0000;
|
|
private const UInt32 BIOS_EndAddress = 0x0000_4000;
|
|
|
|
private CPU.CPU_Core _cpu;
|
|
private bool _disposed;
|
|
|
|
internal BIOS()
|
|
{
|
|
Byte[] data;
|
|
|
|
try
|
|
{
|
|
data = File.ReadAllBytes("gba_bios.bin");
|
|
}
|
|
catch (FileNotFoundException)
|
|
{
|
|
throw new Exception("Iris.GBA.BIOS: Could not find BIOS");
|
|
}
|
|
catch
|
|
{
|
|
throw new Exception("Iris.GBA.BIOS: Could not read BIOS");
|
|
}
|
|
|
|
if (data.Length != BIOS_Size)
|
|
throw new Exception("Iris.GBA.BIOS: Wrong BIOS size");
|
|
|
|
Marshal.Copy(data, 0, _bios, BIOS_Size);
|
|
}
|
|
|
|
~BIOS()
|
|
{
|
|
Dispose();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
|
|
Marshal.FreeHGlobal(_bios);
|
|
|
|
GC.SuppressFinalize(this);
|
|
_disposed = true;
|
|
}
|
|
|
|
internal void Initialize(CPU.CPU_Core cpu, Memory memory)
|
|
{
|
|
_cpu = cpu;
|
|
|
|
memory.Map(_bios, BIOS_Size, BIOS_StartAddress, BIOS_EndAddress, Memory.Flag.AllRead);
|
|
}
|
|
|
|
internal void Reset(bool skipIntro)
|
|
{
|
|
if (skipIntro)
|
|
{
|
|
_cpu.Reg[CPU.CPU_Core.SP] = 0x300_7f00;
|
|
_cpu.Reg[CPU.CPU_Core.LR] = 0x800_0000;
|
|
|
|
_cpu.CPSR = 0x1f;
|
|
|
|
_cpu.Reg13_svc = 0x300_7fe0;
|
|
_cpu.Reg13_irq = 0x300_7fa0;
|
|
|
|
_cpu.NextInstructionAddress = 0x800_0000;
|
|
}
|
|
else
|
|
{
|
|
_cpu.CPSR = 0xd3;
|
|
_cpu.NextInstructionAddress = 0;
|
|
}
|
|
}
|
|
|
|
internal Byte Read8(UInt32 address)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
internal UInt16 Read16(UInt32 address)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
internal UInt32 Read32(UInt32 address)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
internal UInt64 HandleSWI()
|
|
{
|
|
_cpu.Reg14_svc = _cpu.NextInstructionAddress;
|
|
_cpu.SPSR_svc = _cpu.CPSR;
|
|
_cpu.SetCPSR((_cpu.CPSR & ~0xbfu) | 0x93u);
|
|
_cpu.NextInstructionAddress = 0x08;
|
|
return 3;
|
|
}
|
|
|
|
internal UInt64 HandleIRQ()
|
|
{
|
|
_cpu.Reg14_irq = _cpu.NextInstructionAddress + 4;
|
|
_cpu.SPSR_irq = _cpu.CPSR;
|
|
_cpu.SetCPSR((_cpu.CPSR & ~0xbfu) | 0x92u);
|
|
_cpu.NextInstructionAddress = 0x18;
|
|
return 3;
|
|
}
|
|
}
|
|
}
|