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); public static extern void Reset(IntPtr s);
[DllImport(dllname, CallingConvention = cc)] [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 0x80000: pagesize0 = 0x800; break;
case 0x30000: pagesize0 = 0x200; pagesize1 = 0x100; break; case 0x30000: pagesize0 = 0x200; pagesize1 = 0x100; break;
case 0x50000: pagesize0 = 0x400; pagesize1 = 0x100; break;
case 0x60000: pagesize0 = 0x400; pagesize1 = 0x200; 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 0xc0000: pagesize0 = 0x800; pagesize1 = 0x400; break;
case 0x100000: pagesize0 = 0x800; pagesize1 = 0x800; break; case 0x100000: pagesize0 = 0x800; pagesize1 = 0x800; break;
} }
Console.WriteLine("Auto-guessed banking options {0} {1}", pagesize0, pagesize1); 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); Core = LibLynx.Create(realfile, realfile.Length, bios, bios.Length, pagesize0, pagesize1, false);
try try
{ {
// ... CoreComm.VsyncNum = 16000000; // 16.00 mhz refclock
CoreComm.VsyncDen = 16 * 105 * 159;
} }
catch catch
{ {
@ -103,14 +106,12 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
public void FrameAdvance(bool render, bool rendersound = true) public void FrameAdvance(bool render, bool rendersound = true)
{ {
Frame++; Frame++;
if (Controller["Power"]) if (Controller["Power"])
LibLynx.Reset(Core); LibLynx.Reset(Core);
int samples = soundbuff.Length; int samples = soundbuff.Length;
LibLynx.Advance(Core, 0, videobuff, soundbuff, ref samples); LibLynx.Advance(Core, GetButtons(), videobuff, soundbuff, ref samples);
numsamp = samples; numsamp = samples / 2; // sound provider wants number of sample pairs
Console.WriteLine(numsamp);
} }
public int Frame { get; private set; } public int Frame { get; private set; }
@ -156,9 +157,31 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
#region Controller #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; } 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 #endregion
#region savestates #region savestates
@ -239,7 +262,7 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
#region SoundProvider #region SoundProvider
short[] soundbuff = new short[1000000]; // todo: make this smaller once frame loop is resolved short[] soundbuff = new short[2048];
int numsamp; int numsamp;
public ISoundProvider SoundProvider { get { return null; } } public ISoundProvider SoundProvider { get { return null; } }

View File

@ -406,7 +406,6 @@ uint32 CMikie::DisplayRenderLine()
{ {
uint32 work_done=0; uint32 work_done=0;
if(!mpDisplayCurrent) return 0;
if(!mDISPCTL_DMAEnable) return 0; if(!mDISPCTL_DMAEnable) return 0;
// if(mLynxLine&0x80000000) 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 // this check needs to occur at least once every 250 million cycles or better
mMikie->CheckWrap(); mMikie->CheckWrap();
SetButtonData(buttons); SetButtonData(buttons);
uint32 start = gSystemCycleCount; 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 // audio start frame
mMikie->startTS = start; mMikie->startTS = start;
mMikie->mpDisplayCurrent = vbuff; 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 (gSystemCycleCount < target)
while (mMikie->mpDisplayCurrent && gSystemCycleCount - start < 200000) //while (mMikie->mpDisplayCurrent && gSystemCycleCount - start < 800000)
// while (gSystemCycleCount - start < 700000) // what's the magic significance?
{ {
Update(); Update(target);
} }
// total cycles executed is now gSystemCycleCount - start // total cycles executed is now gSystemCycleCount - start
mMikie->mikbuf.end_frame((gSystemCycleCount - start) >> 2); frameoverflow = gSystemCycleCount - target;
sbuffsize = mMikie->mikbuf.read_samples(sbuff, sbuffsize) / 2;
mMikie->mikbuf.end_frame((gSystemCycleCount - start) >> 2);
sbuffsize = mMikie->mikbuf.read_samples(sbuff, sbuffsize);
} }

View File

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

Binary file not shown.