Meteor - break up into separate files

This commit is contained in:
adelikat 2015-01-17 19:32:45 +00:00
parent 0a9b07ac32
commit 4f956779fe
7 changed files with 319 additions and 259 deletions

View File

@ -323,25 +323,25 @@
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.IDebuggable.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.IInputPollable.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.IMemoryDomains.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.ISaveRam.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.ISettable.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.IStatable.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.IVideoProvider.cs">
<DependentUpon>GambatteLink.cs</DependentUpon>
<DependentUpon>GambatteLink.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\GBColors.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\GBDisassembler.cs" />
@ -351,6 +351,21 @@
<Compile Include="Consoles\Nintendo\GBA\LibMeteor.cs" />
<Compile Include="Consoles\Nintendo\GBA\LibVBANext.cs" />
<Compile Include="Consoles\Nintendo\GBA\Meteor.cs" />
<Compile Include="Consoles\Nintendo\GBA\Meteor.IGBAGPUViewable.cs">
<DependentUpon>Meteor.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBA\Meteor.IMemoryDomains.cs">
<DependentUpon>Meteor.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBA\Meteor.ISaveRam.cs">
<DependentUpon>Meteor.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBA\Meteor.IStatable.cs">
<DependentUpon>Meteor.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBA\Meteor.IVideoProvider.cs">
<DependentUpon>Meteor.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\GBA\VBANext.cs" />
<Compile Include="Consoles\Nintendo\GBA\VBARegisterHelper.cs" />
<Compile Include="Consoles\Nintendo\N64\N64.IDebuggable.cs">

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
public partial class GBA : IGBAGPUViewable
{
public GBAGPUMemoryAreas GetMemoryAreas()
{
IntPtr _vram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.vram);
IntPtr _palram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.palram);
IntPtr _oam = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.oam);
IntPtr _mmio = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.io);
if (_vram == IntPtr.Zero || _palram == IntPtr.Zero || _oam == IntPtr.Zero || _mmio == IntPtr.Zero)
throw new Exception("libmeteor_getmemoryarea() failed!");
return new GBAGPUMemoryAreas
{
vram = _vram,
palram = _palram,
oam = _oam,
mmio = _mmio
};
}
public void SetScanlineCallback(Action callback, int scanline)
{
if (scanline < 0 || scanline > 227)
{
throw new ArgumentOutOfRangeException("Scanline must be in [0, 227]!");
}
if (callback == null)
{
scanlinecb = null;
LibMeteor.libmeteor_setscanlinecallback(null, 0);
}
else
{
scanlinecb = new LibMeteor.ScanlineCallback(callback);
LibMeteor.libmeteor_setscanlinecallback(scanlinecb, scanline);
}
}
private LibMeteor.ScanlineCallback scanlinecb = null;
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
public partial class GBA
{
private List<MemoryDomain> _domainList = new List<MemoryDomain>();
private IMemoryDomains _memoryDomains;
private void AddMemoryDomain(LibMeteor.MemoryArea which, int size, string name)
{
IntPtr data = LibMeteor.libmeteor_getmemoryarea(which);
if (data == IntPtr.Zero)
throw new Exception("libmeteor_getmemoryarea() returned NULL??");
MemoryDomain md = MemoryDomain.FromIntPtr(name, size, MemoryDomain.Endian.Little, data);
_domainList.Add(md);
}
private void SetUpMemoryDomains()
{
_domainList.Clear();
// this must be first to coincide with "main memory"
// note that ewram could also be considered main memory depending on which hairs you split
AddMemoryDomain(LibMeteor.MemoryArea.iwram, 32 * 1024, "IWRAM");
AddMemoryDomain(LibMeteor.MemoryArea.ewram, 256 * 1024, "EWRAM");
AddMemoryDomain(LibMeteor.MemoryArea.bios, 16 * 1024, "BIOS");
AddMemoryDomain(LibMeteor.MemoryArea.palram, 1024, "PALRAM");
AddMemoryDomain(LibMeteor.MemoryArea.vram, 96 * 1024, "VRAM");
AddMemoryDomain(LibMeteor.MemoryArea.oam, 1024, "OAM");
// even if the rom is less than 32MB, the whole is still valid in meteor
AddMemoryDomain(LibMeteor.MemoryArea.rom, 32 * 1024 * 1024, "ROM");
// special domain for system bus
{
MemoryDomain sb = new MemoryDomain("System Bus", 1 << 28, MemoryDomain.Endian.Little,
delegate(int addr)
{
if (addr < 0 || addr >= 0x10000000)
throw new IndexOutOfRangeException();
return LibMeteor.libmeteor_peekbus((uint)addr);
},
delegate(int addr, byte val)
{
if (addr < 0 || addr >= 0x10000000)
throw new IndexOutOfRangeException();
LibMeteor.libmeteor_writebus((uint)addr, val);
});
_domainList.Add(sb);
}
// special combined ram memory domain
{
var ew = _domainList[1];
var iw = _domainList[0];
MemoryDomain cr = new MemoryDomain("Combined WRAM", (256 + 32) * 1024, MemoryDomain.Endian.Little,
delegate(int addr)
{
if (addr < 0 || addr >= (256 + 32) * 1024)
throw new IndexOutOfRangeException();
if (addr >= 256 * 1024)
return iw.PeekByte(addr & 32767);
else
return ew.PeekByte(addr);
},
delegate(int addr, byte val)
{
if (addr < 0 || addr >= (256 + 32) * 1024)
throw new IndexOutOfRangeException();
if (addr >= 256 * 1024)
iw.PokeByte(addr & 32767, val);
else
ew.PokeByte(addr, val);
});
_domainList.Add(cr);
}
_memoryDomains = new MemoryDomainList(_domainList);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(_memoryDomains);
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
public partial class GBA : ISaveRam
{
public bool SaveRamModified
{
get
{
if (disposed)
throw new ObjectDisposedException(this.GetType().ToString());
return LibMeteor.libmeteor_hassaveram();
}
}
public byte[] CloneSaveRam()
{
throw new Exception("This needs to be fixed to match the VBANext Core!");
#if false
if (disposed)
throw new ObjectDisposedException(this.GetType().ToString());
if (!LibMeteor.libmeteor_hassaveram())
return null;
IntPtr data = IntPtr.Zero;
uint size = 0;
if (!LibMeteor.libmeteor_savesaveram(ref data, ref size))
throw new Exception("libmeteor_savesaveram() returned false!");
byte[] ret = new byte[size];
Marshal.Copy(data, ret, 0, (int)size);
LibMeteor.libmeteor_savesaveram_destroy(data);
return ret;
#endif
}
public void StoreSaveRam(byte[] data)
{
throw new Exception("This needs to be fixed to match the VBANext Core!");
#if false
if (disposed)
throw new ObjectDisposedException(this.GetType().ToString());
if (!LibMeteor.libmeteor_loadsaveram(data, (uint)data.Length))
throw new Exception("libmeteor_loadsaveram() returned false!");
#endif
}
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
public partial class GBA : IStatable
{
public bool BinarySaveStatesPreferred { get { return true; } }
public void SaveStateText(System.IO.TextWriter writer)
{
var temp = SaveStateBinary();
temp.SaveAsHex(writer);
// write extra copy of stuff we don't use
writer.WriteLine("Frame {0}", Frame);
}
public void LoadStateText(System.IO.TextReader reader)
{
string hex = reader.ReadLine();
byte[] state = new byte[hex.Length / 2];
state.ReadFromHex(hex);
LoadStateBinary(new BinaryReader(new MemoryStream(state)));
}
public void SaveStateBinary(System.IO.BinaryWriter writer)
{
byte[] data = SaveCoreBinary();
writer.Write(data.Length);
writer.Write(data);
// other variables
writer.Write(IsLagFrame);
writer.Write(LagCount);
writer.Write(Frame);
}
public void LoadStateBinary(System.IO.BinaryReader reader)
{
int length = reader.ReadInt32();
byte[] data = reader.ReadBytes(length);
LoadCoreBinary(data);
// other variables
IsLagFrame = reader.ReadBoolean();
LagCount = reader.ReadInt32();
Frame = reader.ReadInt32();
}
public byte[] SaveStateBinary()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
return ms.ToArray();
}
private byte[] SaveCoreBinary()
{
IntPtr ndata = IntPtr.Zero;
uint nsize = 0;
if (!LibMeteor.libmeteor_savestate(ref ndata, ref nsize))
throw new Exception("libmeteor_savestate() failed!");
if (ndata == IntPtr.Zero || nsize == 0)
throw new Exception("libmeteor_savestate() returned bad!");
byte[] ret = new byte[nsize];
Marshal.Copy(ndata, ret, 0, (int)nsize);
LibMeteor.libmeteor_savestate_destroy(ndata);
return ret;
}
private void LoadCoreBinary(byte[] data)
{
if (!LibMeteor.libmeteor_loadstate(data, (uint)data.Length))
throw new Exception("libmeteor_loadstate() failed!");
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
public partial class GBA : IVideoProvider
{
public int VirtualWidth { get { return 240; } }
public int VirtualHeight { get { return 160; } }
public int BufferWidth { get { return 240; } }
public int BufferHeight { get { return 160; } }
public int BackgroundColor
{
get { return unchecked((int)0xff000000); }
}
public int[] GetVideoBuffer()
{
return videobuffer;
}
private int[] videobuffer;
private GCHandle videohandle;
}
}

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
isReleased: false
)]
[ServiceNotApplicable(typeof(IDriveLight))]
public class GBA : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable, ISaveRam, IStatable, IInputPollable
public partial class GBA : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable, ISaveRam, IStatable, IInputPollable
{
[CoreConstructor("GBA")]
public GBA(CoreComm comm, byte[] file)
@ -112,202 +112,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
IsLagFrame = false;
}
#region saveram
public byte[] CloneSaveRam()
{
throw new Exception("This needs to be fixed to match the VBANext Core!");
#if false
if (disposed)
throw new ObjectDisposedException(this.GetType().ToString());
if (!LibMeteor.libmeteor_hassaveram())
return null;
IntPtr data = IntPtr.Zero;
uint size = 0;
if (!LibMeteor.libmeteor_savesaveram(ref data, ref size))
throw new Exception("libmeteor_savesaveram() returned false!");
byte[] ret = new byte[size];
Marshal.Copy(data, ret, 0, (int)size);
LibMeteor.libmeteor_savesaveram_destroy(data);
return ret;
#endif
}
public void StoreSaveRam(byte[] data)
{
throw new Exception("This needs to be fixed to match the VBANext Core!");
#if false
if (disposed)
throw new ObjectDisposedException(this.GetType().ToString());
if (!LibMeteor.libmeteor_loadsaveram(data, (uint)data.Length))
throw new Exception("libmeteor_loadsaveram() returned false!");
#endif
}
public bool SaveRamModified
{
get
{
if (disposed)
throw new ObjectDisposedException(this.GetType().ToString());
return LibMeteor.libmeteor_hassaveram();
}
}
#endregion
#region savestates
byte[] SaveCoreBinary()
{
IntPtr ndata = IntPtr.Zero;
uint nsize = 0;
if (!LibMeteor.libmeteor_savestate(ref ndata, ref nsize))
throw new Exception("libmeteor_savestate() failed!");
if (ndata == IntPtr.Zero || nsize == 0)
throw new Exception("libmeteor_savestate() returned bad!");
byte[] ret = new byte[nsize];
Marshal.Copy(ndata, ret, 0, (int)nsize);
LibMeteor.libmeteor_savestate_destroy(ndata);
return ret;
}
void LoadCoreBinary(byte[] data)
{
if (!LibMeteor.libmeteor_loadstate(data, (uint)data.Length))
throw new Exception("libmeteor_loadstate() failed!");
}
public void SaveStateText(System.IO.TextWriter writer)
{
var temp = SaveStateBinary();
temp.SaveAsHex(writer);
// write extra copy of stuff we don't use
writer.WriteLine("Frame {0}", Frame);
}
public void LoadStateText(System.IO.TextReader reader)
{
string hex = reader.ReadLine();
byte[] state = new byte[hex.Length / 2];
state.ReadFromHex(hex);
LoadStateBinary(new BinaryReader(new MemoryStream(state)));
}
public void SaveStateBinary(System.IO.BinaryWriter writer)
{
byte[] data = SaveCoreBinary();
writer.Write(data.Length);
writer.Write(data);
// other variables
writer.Write(IsLagFrame);
writer.Write(LagCount);
writer.Write(Frame);
}
public void LoadStateBinary(System.IO.BinaryReader reader)
{
int length = reader.ReadInt32();
byte[] data = reader.ReadBytes(length);
LoadCoreBinary(data);
// other variables
IsLagFrame = reader.ReadBoolean();
LagCount = reader.ReadInt32();
Frame = reader.ReadInt32();
}
public byte[] SaveStateBinary()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
return ms.ToArray();
}
public bool BinarySaveStatesPreferred { get { return true; } }
#endregion
public CoreComm CoreComm { get; private set; }
#region memorydomains
List<MemoryDomain> _MemoryDomains = new List<MemoryDomain>();
private IMemoryDomains _memoryDomains;
void AddMemoryDomain(LibMeteor.MemoryArea which, int size, string name)
{
IntPtr data = LibMeteor.libmeteor_getmemoryarea(which);
if (data == IntPtr.Zero)
throw new Exception("libmeteor_getmemoryarea() returned NULL??");
MemoryDomain md = MemoryDomain.FromIntPtr(name, size, MemoryDomain.Endian.Little, data);
_MemoryDomains.Add(md);
}
void SetUpMemoryDomains()
{
_MemoryDomains.Clear();
// this must be first to coincide with "main memory"
// note that ewram could also be considered main memory depending on which hairs you split
AddMemoryDomain(LibMeteor.MemoryArea.iwram, 32 * 1024, "IWRAM");
AddMemoryDomain(LibMeteor.MemoryArea.ewram, 256 * 1024, "EWRAM");
AddMemoryDomain(LibMeteor.MemoryArea.bios, 16 * 1024, "BIOS");
AddMemoryDomain(LibMeteor.MemoryArea.palram, 1024, "PALRAM");
AddMemoryDomain(LibMeteor.MemoryArea.vram, 96 * 1024, "VRAM");
AddMemoryDomain(LibMeteor.MemoryArea.oam, 1024, "OAM");
// even if the rom is less than 32MB, the whole is still valid in meteor
AddMemoryDomain(LibMeteor.MemoryArea.rom, 32 * 1024 * 1024, "ROM");
// special domain for system bus
{
MemoryDomain sb = new MemoryDomain("System Bus", 1 << 28, MemoryDomain.Endian.Little,
delegate(int addr)
{
if (addr < 0 || addr >= 0x10000000)
throw new IndexOutOfRangeException();
return LibMeteor.libmeteor_peekbus((uint)addr);
},
delegate(int addr, byte val)
{
if (addr < 0 || addr >= 0x10000000)
throw new IndexOutOfRangeException();
LibMeteor.libmeteor_writebus((uint)addr, val);
});
_MemoryDomains.Add(sb);
}
// special combined ram memory domain
{
var ew = _MemoryDomains[1];
var iw = _MemoryDomains[0];
MemoryDomain cr = new MemoryDomain("Combined WRAM", (256 + 32) * 1024, MemoryDomain.Endian.Little,
delegate(int addr)
{
if (addr < 0 || addr >= (256 + 32) * 1024)
throw new IndexOutOfRangeException();
if (addr >= 256 * 1024)
return iw.PeekByte(addr & 32767);
else
return ew.PeekByte(addr);
},
delegate(int addr, byte val)
{
if (addr < 0 || addr >= (256 + 32) * 1024)
throw new IndexOutOfRangeException();
if (addr >= 256 * 1024)
iw.PokeByte(addr & 32767, val);
else
ew.PokeByte(addr, val);
});
_MemoryDomains.Add(cr);
}
_memoryDomains = new MemoryDomainList(_MemoryDomains);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(_memoryDomains);
}
#endregion
/// <summary>like libsnes, the library is single-instance</summary>
static GBA attachedcore;
@ -423,46 +228,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
Tracer.Put(msg);
}
GBAGPUMemoryAreas IGBAGPUViewable.GetMemoryAreas()
{
IntPtr _vram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.vram);
IntPtr _palram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.palram);
IntPtr _oam = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.oam);
IntPtr _mmio = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.io);
if (_vram == IntPtr.Zero || _palram == IntPtr.Zero || _oam == IntPtr.Zero || _mmio == IntPtr.Zero)
throw new Exception("libmeteor_getmemoryarea() failed!");
return new GBAGPUMemoryAreas
{
vram = _vram,
palram = _palram,
oam = _oam,
mmio = _mmio
};
}
void IGBAGPUViewable.SetScanlineCallback(Action callback, int scanline)
{
if (scanline < 0 || scanline > 227)
{
throw new ArgumentOutOfRangeException("Scanline must be in [0, 227]!");
}
if (callback == null)
{
scanlinecb = null;
LibMeteor.libmeteor_setscanlinecallback(null, 0);
}
else
{
scanlinecb = new LibMeteor.ScanlineCallback(callback);
LibMeteor.libmeteor_setscanlinecallback(scanlinecb, scanline);
}
}
LibMeteor.ScanlineCallback scanlinecb = null;
void Init()
private void Init()
{
if (attachedcore != null)
attachedcore.Dispose();
@ -487,7 +253,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
attachedcore = this;
}
bool disposed = false;
private bool disposed = false;
public void Dispose()
{
if (!disposed)
@ -503,24 +269,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
LibMeteor.libmeteor_setmessagecallback(messagecallback);
LibMeteor.libmeteor_setkeycallback(inputcallback);
LibMeteor.libmeteor_settracecallback(tracecallback);
_MemoryDomains.Clear();
_domainList.Clear();
}
}
#region IVideoProvider
int[] videobuffer;
GCHandle videohandle;
public int[] GetVideoBuffer() { return videobuffer; }
public int VirtualWidth { get { return 240; } }
public int VirtualHeight { get { return 160; } }
public int BufferWidth { get { return 240; } }
public int BufferHeight { get { return 160; } }
public int BackgroundColor { get { return unchecked((int)0xff000000); } }
#endregion
#region ISoundProvider
short[] soundbuffer;