lynx: controllers and frame timing fix

This commit is contained in:
goyuken 2014-09-16 00:40:15 +00:00
parent dec35ed67c
commit bacbaa2bec
6 changed files with 63 additions and 23 deletions

View File

@ -22,6 +22,20 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
public static extern void Reset(IntPtr s);
[DllImport(dllname, CallingConvention = cc)]
public static extern void Advance(IntPtr s, int buttons, int[] vbuff, short[] sbuff, ref int sbuffsize);
public static extern void Advance(IntPtr s, Buttons buttons, int[] vbuff, short[] sbuff, ref int sbuffsize);
[Flags]
public enum Buttons : ushort
{
Up = 0x0080,
Down = 0x0040,
Left = 0x0010,
Right = 0x0020,
Option_1 = 0x008,
Option_2 = 0x004,
B = 0x002,
A = 0x001,
Pause = 0x100,
}
}
}

View File

@ -80,10 +80,12 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
case 0x80000: pagesize0 = 0x800; break;
case 0x30000: pagesize0 = 0x200; pagesize1 = 0x100; break;
case 0x50000: pagesize0 = 0x400; pagesize1 = 0x100; break;
case 0x60000: pagesize0 = 0x400; pagesize1 = 0x200; break;
case 0x90000: pagesize0 = 0x800; pagesize1 = 0x100; break;
case 0xa0000: pagesize0 = 0x800; pagesize1 = 0x200; break;
case 0xc0000: pagesize0 = 0x800; pagesize1 = 0x400; break;
case 0x100000: pagesize0 = 0x800; pagesize1 = 0x800; break;
}
Console.WriteLine("Auto-guessed banking options {0} {1}", pagesize0, pagesize1);
}
@ -91,7 +93,8 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
Core = LibLynx.Create(realfile, realfile.Length, bios, bios.Length, pagesize0, pagesize1, false);
try
{
// ...
CoreComm.VsyncNum = 16000000; // 16.00 mhz refclock
CoreComm.VsyncDen = 16 * 105 * 159;
}
catch
{
@ -103,14 +106,12 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
public void FrameAdvance(bool render, bool rendersound = true)
{
Frame++;
if (Controller["Power"])
LibLynx.Reset(Core);
int samples = soundbuff.Length;
LibLynx.Advance(Core, 0, videobuff, soundbuff, ref samples);
numsamp = samples;
Console.WriteLine(numsamp);
LibLynx.Advance(Core, GetButtons(), videobuff, soundbuff, ref samples);
numsamp = samples / 2; // sound provider wants number of sample pairs
}
public int Frame { get; private set; }
@ -156,9 +157,31 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
#region Controller
public ControllerDefinition ControllerDefinition { get { return NullEmulator.NullController; } }
private static readonly ControllerDefinition LynxTroller = new ControllerDefinition
{
Name = "Lynx Controller",
BoolButtons = { "Up", "Down", "Left", "Right", "A", "B", "Option 1", "Option 2", "Pause", "Power" },
};
public ControllerDefinition ControllerDefinition { get { return LynxTroller; } }
public IController Controller { get; set; }
LibLynx.Buttons GetButtons()
{
LibLynx.Buttons ret = 0;
if (Controller["A"]) ret |= LibLynx.Buttons.A;
if (Controller["B"]) ret |= LibLynx.Buttons.B;
if (Controller["Up"]) ret |= LibLynx.Buttons.Up;
if (Controller["Down"]) ret |= LibLynx.Buttons.Down;
if (Controller["Left"]) ret |= LibLynx.Buttons.Left;
if (Controller["Right"]) ret |= LibLynx.Buttons.Right;
if (Controller["Pause"]) ret |= LibLynx.Buttons.Pause;
if (Controller["Option 1"]) ret |= LibLynx.Buttons.Option_1;
if (Controller["Option 2"]) ret |= LibLynx.Buttons.Option_2;
return ret;
}
#endregion
#region savestates
@ -239,7 +262,7 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
#region SoundProvider
short[] soundbuff = new short[1000000]; // todo: make this smaller once frame loop is resolved
short[] soundbuff = new short[2048];
int numsamp;
public ISoundProvider SoundProvider { get { return null; } }

View File

@ -406,7 +406,6 @@ uint32 CMikie::DisplayRenderLine()
{
uint32 work_done=0;
if(!mpDisplayCurrent) return 0;
if(!mDISPCTL_DMAEnable) return 0;
// if(mLynxLine&0x80000000) return 0;

View File

@ -158,27 +158,31 @@ void CSystem::Advance(int buttons, uint32 *vbuff, int16 *sbuff, int &sbuffsize)
// this check needs to occur at least once every 250 million cycles or better
mMikie->CheckWrap();
SetButtonData(buttons);
uint32 start = gSystemCycleCount;
// nominal timer values are div16 for prescalar, 158 for line timer, and 104 for frame timer
// reloads are actually +1 due to the way the hardware works
// so this is a frame, theoretically
uint32 target = gSystemCycleCount + 16 * 105 * 159 - frameoverflow;
// audio start frame
mMikie->startTS = start;
mMikie->mpDisplayCurrent = vbuff;
// go to next frame end, or no more than 200,000 cycles to avoid exploding the output buffer (was set at 60ms limit)
while (mMikie->mpDisplayCurrent && gSystemCycleCount - start < 200000)
// while (gSystemCycleCount - start < 700000) // what's the magic significance?
while (gSystemCycleCount < target)
//while (mMikie->mpDisplayCurrent && gSystemCycleCount - start < 800000)
{
Update();
Update(target);
}
// total cycles executed is now gSystemCycleCount - start
mMikie->mikbuf.end_frame((gSystemCycleCount - start) >> 2);
sbuffsize = mMikie->mikbuf.read_samples(sbuff, sbuffsize) / 2;
frameoverflow = gSystemCycleCount - target;
mMikie->mikbuf.end_frame((gSystemCycleCount - start) >> 2);
sbuffsize = mMikie->mikbuf.read_samples(sbuff, sbuffsize);
}

View File

@ -121,10 +121,10 @@ public:
public:
void Reset() MDFN_COLD;
inline void Update()
inline void Update(uint32 targetclock)
{
// Only update if there is a predicted timer event
if(gSystemCycleCount>=gNextTimerEvent)
if(gSystemCycleCount >= gNextTimerEvent)
{
mMikie->Update();
}
@ -135,7 +135,7 @@ public:
// If the CPU is asleep then skip to the next timer event
if(gSystemCPUSleep)
{
gSystemCycleCount=gNextTimerEvent;
gSystemCycleCount = std::min(gNextTimerEvent, targetclock);
}
}
@ -192,11 +192,9 @@ public:
// Miscellaneous
void SetButtonData(uint32 data) {mSusie->SetButtonData(data);};
uint32 GetButtonData() {return mSusie->GetButtonData();};
void SetCycleBreakpoint(uint32 breakpoint) {mCycleCountBreakpoint=breakpoint;};
uint8* GetRamPointer() {return mRam->GetRamPointer();};
public:
uint32 mCycleCountBreakpoint;
CLynxBase *mMemoryHandlers[SYSTEM_SIZE];
CCart *mCart;
CRom *mRom;
@ -210,11 +208,13 @@ public:
uint32 gSuzieDoneTime;
uint32 gSystemCycleCount;
uint32 gNextTimerEvent;
//uint32 gCPUBootAddress;
uint32 gSystemIRQ;
uint32 gSystemNMI;
uint32 gSystemCPUSleep;
uint32 gSystemHalt;
// frame overflow detection
int frameoverflow;
};
#endif

Binary file not shown.