saturn - support loading bios. note that at the moment, the bios filename isn't in the firmware configuratorthingy. this marks the first change made to the yabause core itself (excepting the yui.cpp that we added); changing memory.h so that block loads don't do unnecessary fseek()

This commit is contained in:
goyuken 2013-05-02 20:47:56 +00:00
parent fdae009597
commit 149eeb5f33
9 changed files with 127 additions and 22 deletions

View File

@ -357,6 +357,7 @@
<Compile Include="Consoles\Sega\Genesis\Cart\RomHeader.cs" />
<Compile Include="Consoles\Sega\Genesis\Cart\SaveRAM.cs" />
<Compile Include="Consoles\Sega\Genesis\Input.cs" />
<Compile Include="Consoles\Sega\Saturn\FilePiping.cs" />
<Compile Include="Consoles\Sega\Saturn\LibYabause.cs" />
<Compile Include="Consoles\Sega\Saturn\Yabause.cs" />
<Compile Include="Consoles\Sega\SMS\MemoryMap.CodeMasters.cs" />

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Threading;
namespace BizHawk.Emulation.Consoles.Sega.Saturn
{
/// <summary>
/// helpers for moving files across named pipes
/// </summary>
public class FilePiping
{
public void Offer(byte[] data)
{
MemoryStream ms = new MemoryStream(data, false);
Offer(ms);
}
string PipeName;
Thread thr;
Exception e;
public string GetPipeName()
{
return PipeName;
}
public string GetPipeNameNative()
{
return @"\\.\pipe\" + PipeName;
}
public FilePiping()
{
PipeName = "BizHawk-" + Guid.NewGuid().ToString();
}
public void Offer(Stream s)
{
if (thr != null)
throw new Exception("Can only serve one thing at a time!");
if (e != null)
throw new Exception("Previous attempt failed!", e);
if (!s.CanRead)
throw new ArgumentException("Stream must be readable!");
thr = new Thread(delegate()
{
try
{
using (var srv = new NamedPipeServerStream(PipeName, PipeDirection.Out))
{
srv.WaitForConnection();
s.CopyTo(srv);
srv.WaitForPipeDrain();
}
}
catch (Exception ee)// might want to do something about this...
{
e = ee;
}
});
thr.Start();
}
public Exception GetResults()
{
if (thr == null)
throw new Exception("No pending!");
thr.Join();
thr = null;
Exception ret = e;
e = null;
return ret;
}
}
}

View File

@ -83,9 +83,10 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn
///
/// </summary>
/// <param name="intf">cd interface. struct need not persist after call, but the function pointers better</param>
/// <param name="biosfn">path to bios, pass null to use built in bios emulation</param>
/// <returns></returns>
[DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool libyabause_init(ref CDInterface intf);
public static extern bool libyabause_init(ref CDInterface intf, string biosfn);
public struct CDInterface
{

View File

@ -33,16 +33,16 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn
LibYabause.CDInterface.ReadSectorFAD ReadSectorFADH;
LibYabause.CDInterface.ReadAheadFAD ReadAheadFADH;
public Yabause(CoreComm CoreComm, DiscSystem.Disc CD)
public Yabause(CoreComm CoreComm, DiscSystem.Disc CD, byte[] bios)
{
CoreComm.RomStatusDetails = "Yeh";
this.CoreComm = CoreComm;
this.CD = CD;
ResetFrameCounter();
Init();
Init(bios);
}
void Init()
void Init(byte[] bios)
{
if (AttachedCore != null)
{
@ -60,9 +60,17 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn
CDInt.ReadSectorFADFunc = ReadSectorFADH = new LibYabause.CDInterface.ReadSectorFAD(CD_ReadSectorFAD);
CDInt.ReadAheadFADFunc = ReadAheadFADH = new LibYabause.CDInterface.ReadAheadFAD(CD_ReadAheadFAD);
if (!LibYabause.libyabause_init(ref CDInt))
var fp = new FilePiping();
string BiosPipe = fp.GetPipeNameNative();
fp.Offer(bios);
if (!LibYabause.libyabause_init(ref CDInt, BiosPipe))
throw new Exception("libyabause_init() failed!");
var e = fp.GetResults();
if (e != null)
throw e;
LibYabause.libyabause_setvidbuff(VideoHandle.AddrOfPinnedObject());
LibYabause.libyabause_setsndbuff(SoundHandle.AddrOfPinnedObject());
AttachedCore = this;

View File

@ -256,6 +256,7 @@ namespace BizHawk.MultiClient
public string FilenameA78PALBios = "7800PALBIOS.bin";
public string FilenameA78HSCBios = "7800highscore.bin";
public string FilenameINTVEROM = "erom.bin";
public string FilenameSaturnBios = "Sega Saturn BIOS v1.01 (JAP).bin";
public string FFMpegPath = "%exe%/dll/ffmpeg.exe";

View File

@ -2082,8 +2082,16 @@ namespace BizHawk.MultiClient
switch (game.System)
{
case "SAT":
var saturn = new Emulation.Consoles.Sega.Saturn.Yabause(nextComm, disc);
nextEmulator = saturn;
{
string biosPath = PathManager.StandardFirmwareName(Global.Config.FilenameSaturnBios);
if (!File.Exists(biosPath))
{
MessageBox.Show("Saturn BIOS not found. Please check firmware configurations.");
return false;
}
var saturn = new Emulation.Consoles.Sega.Saturn.Yabause(nextComm, disc, File.ReadAllBytes(biosPath));
nextEmulator = saturn;
}
break;
case "PSX":

View File

@ -201,7 +201,7 @@ extern "C" __declspec(dllexport) void libyabause_setpads(u8 p11, u8 p12, u8 p21,
ctrl2->padbits[1] = p22;
}
extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD)
extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD, const char *biosfn)
{
FECD.DeInit = _CD->DeInit;
FECD.GetStatus = _CD->GetStatus;
@ -227,7 +227,7 @@ extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD)
yinit.m68kcoretype = M68KCORE_C68K;
yinit.cartpath = CART_NONE;
yinit.regionid = REGION_AUTODETECT;
yinit.biospath = NULL;
yinit.biospath = biosfn;
yinit.cdpath = "Saturnus"; //NULL;
yinit.buppath = NULL;
yinit.mpegpath = NULL;

View File

@ -194,7 +194,7 @@ static INLINE void T3WriteLong(T3Memory * mem, u32 addr, u32 val)
static INLINE int T123Load(void * mem, u32 size, int type, const char *filename)
{
FILE *fp;
u32 filesize, filesizecheck;
u32 filesizecheck;
u8 *buffer;
u32 i;
@ -205,41 +205,47 @@ static INLINE int T123Load(void * mem, u32 size, int type, const char *filename)
return -1;
// Calculate file size
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET);
//fseek(fp, 0, SEEK_END);
//filesize = ftell(fp);
//fseek(fp, 0, SEEK_SET);
if (filesize > size)
return -1;
//if (filesize > size)
// return -1;
if ((buffer = (u8 *)malloc(filesize)) == NULL)
if ((buffer = (u8 *)malloc(size)) == NULL)
{
fclose(fp);
return -1;
}
filesizecheck = (u32)fread((void *)buffer, 1, filesize, fp);
fclose(fp);
filesizecheck = (u32)fread((void *)buffer, 1, size, fp);
// make sure there are no bytes left in the file
if (filesizecheck != size || fgetc(fp) != EOF)
{
free(buffer);
fclose(fp);
return -1;
}
if (filesizecheck != filesize) return -1;
fclose(fp);
switch (type)
{
case 1:
{
for (i = 0; i < filesize; i++)
for (i = 0; i < size; i++)
T1WriteByte((u8 *) mem, i, buffer[i]);
break;
}
case 2:
{
for (i = 0; i < filesize; i++)
for (i = 0; i < size; i++)
T2WriteByte((u8 *) mem, i, buffer[i]);
break;
}
case 3:
{
for (i = 0; i < filesize; i++)
for (i = 0; i < size; i++)
T3WriteByte((T3Memory *) mem, i, buffer[i]);
break;
}