HMove updatealyosha-tas says:"You can merge it now, I have nothing more to add to it."

HMove update

alyosha-tas says:
"You can merge it now, I have nothing more to add to it."
This commit is contained in:
hegyak 2016-05-21 10:55:25 -07:00
commit dbc23a1f4d
10 changed files with 1363 additions and 2596 deletions

View File

@ -241,8 +241,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_mapper = new mUA();
break;
// Homebrew mappers
case "3E":
// Special Sega Mapper which has swapped banks
case "F8_sega":
_mapper = new mF8_sega();
break;
// Homebrew mappers
case "3E":
_mapper = new m3E();
break;
case "0840":

View File

@ -45,8 +45,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
game.AddOption("m", DetectMapper(rom));
}
Console.WriteLine("Game uses mapper " + game.GetOptionsDict()["m"]);
RebootCore();
if (Rom.HashSHA1() == "3A77DB43B6583E8689435F0F14AA04B9E57BDDED" ||
Rom.HashSHA1() == "E986E1818E747BEB9B33CE4DFF1CDC6B55BDB620")
{
game.RemoveOption("m");
game.AddOption("m", "F8_sega");
}
Console.WriteLine("Game uses mapper " + game.GetOptionsDict()["m"]);
Console.WriteLine(Rom.HashSHA1());
RebootCore();
SetupMemoryDomains();
Tracer = new TraceBuffer { Header = Cpu.TraceHeader };

View File

@ -74,13 +74,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
return Timer.Value;
}
// TODO: fix this to match real behaviour
// This is an undocumented instruction whose behaviour is more dynamic then indicated here
if ((registerAddr & 0x5) == 0x5)
{
// Read interrupt flag
if (Timer.InterruptEnabled && Timer.InterruptFlag)
if (Timer.InterruptFlag) //Timer.InterruptEnabled && )
{
return 0x80;
return 0xC0;
}
return 0x00;
@ -112,7 +113,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/1
Timer.PrescalerShift = 0;
Timer.Value = value;
Timer.PrescalerCount = 0;
Timer.PrescalerCount = 0;// 1 << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
else if (registerAddr == 0x05)
@ -120,7 +121,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/8
Timer.PrescalerShift = 3;
Timer.Value = value;
Timer.PrescalerCount = 0;
Timer.PrescalerCount = 0;// 1 << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
else if (registerAddr == 0x06)
@ -128,7 +129,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/64
Timer.PrescalerShift = 6;
Timer.Value = value;
Timer.PrescalerCount = 0;
Timer.PrescalerCount = 0;// 1 << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
else if (registerAddr == 0x07)
@ -136,7 +137,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Write to Timer/1024
Timer.PrescalerShift = 10;
Timer.Value = value;
Timer.PrescalerCount = 0;
Timer.PrescalerCount = 0;// 1 << Timer.PrescalerShift;
Timer.InterruptFlag = false;
}
}

View File

@ -0,0 +1,98 @@
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
/*
F8 (Atari style 8K)
-----
This is the fairly standard way 8K of cartridge ROM was implemented. There are two
4K ROM banks, which get mapped into the 4K of cartridge space. Accessing 1FF8 or
1FF9 selects one of the two 4K banks. When one of these two addresses are accessed,
the banks switch spontaniously.
ANY kind of access will trigger the switching- reading or writing. Usually games use
LDA or BIT on 1FF8/1FF9 to perform the switch.
When the switch occurs, the entire 4K ROM bank switches, including the code that is
reading the 1FF8/1FF9 location. Usually, games put a small stub of code in BOTH banks
so when the switch occurs, the code won't crash.
*/
internal class mF8_sega : MapperBase
{
private int _bank4K=1;
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("bank_4k", ref _bank4K);
}
public override void HardReset()
{
_bank4K = 1;
base.HardReset();
}
private byte ReadMem(ushort addr, bool peek)
{
if (!peek)
{
Address(addr);
}
if (addr < 0x1000)
{
return base.ReadMemory(addr);
}
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
}
public override byte ReadMemory(ushort addr)
{
return ReadMem(addr, false);
}
public override byte PeekMemory(ushort addr)
{
return ReadMem(addr, true);
}
private void WriteMem(ushort addr, byte value, bool poke)
{
if (!poke)
{
Address(addr);
}
if (addr < 0x1000)
{
base.WriteMemory(addr, value);
}
}
public override void WriteMemory(ushort addr, byte value)
{
WriteMem(addr, value, poke: false);
}
public override void PokeMemory(ushort addr, byte value)
{
WriteMem(addr, value, poke: true);
}
private void Address(ushort addr)
{
if (addr == 0x1FF8)
{
_bank4K = 0;
}
else if (addr == 0x1FF9)
{
_bank4K = 1;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private struct HMoveData
{
public bool HMoveEnabled;
public bool HMoveJustStarted;
public bool LateHBlankReset;
public bool DecCntEnabled;
@ -20,7 +19,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public byte HMoveDelayCnt;
public byte HMoveCnt;
public byte Player0Cnt;
public int test_count_p0;
public int test_count_p1;
public int test_count_m0;
public int test_count_m1;
public int test_count_b;
public byte Player0Cnt;
public byte Player1Cnt;
public byte Missile0Cnt;
public byte Missile1Cnt;
@ -30,7 +35,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
ser.BeginSection("HMove");
ser.Sync("hmoveEnabled", ref HMoveEnabled);
ser.Sync("hmoveJustStarted", ref HMoveJustStarted);
ser.Sync("lateHBlankReset", ref LateHBlankReset);
ser.Sync("decCntEnabled", ref DecCntEnabled);
ser.Sync("player0Latch", ref Player0Latch);
@ -44,8 +48,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("player1Cnt", ref Player1Cnt);
ser.Sync("missile0Cnt", ref Missile0Cnt);
ser.Sync("missile1Cnt", ref Missile1Cnt);
ser.Sync("ballCnt", ref BallCnt);
ser.EndSection();
ser.Sync("Test_count_p0", ref test_count_p0);
ser.Sync("Test_count_p1", ref test_count_p1);
ser.Sync("Test_count_m0", ref test_count_m0);
ser.Sync("Test_count_m1", ref test_count_m1);
ser.Sync("Test_count_b", ref test_count_b);
ser.Sync("ballCnt", ref BallCnt);
ser.EndSection();
}
}
}

View File

@ -2,89 +2,159 @@
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
public partial class TIA
{
private struct MissileData
{
public bool Enabled;
public bool ResetToPlayer;
public byte HPosCnt;
public byte Size;
public byte Number;
public byte Hm;
public byte Collisions;
public partial class TIA
{
private struct MissileData
{
public bool Enabled;
public bool ResetToPlayer;
public byte HPosCnt;
public byte Size;
public byte Number;
public byte Hm;
public byte Collisions;
// Resp commands do not trigger start signals for main copies. We need to model this
public int Draw_To;
public byte ScanCnt;
public bool ScanCntInit;
public int Start_Signal;
public int Signal_Reached;
public bool Tick()
{
var result = false;
{
var result = false;
if (ScanCntInit==true)
{
if (ScanCnt < (1 << Size) && Enabled && !ResetToPlayer)
{
result = true;
ScanCnt++;
} else
{
ScanCntInit = false;
}
}
/*
// At hPosCnt == 0, start drawing the missile, if enabled
if (HPosCnt < (1 << Size))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
if ((Number & 0x07) == 0x01 || ((Number & 0x07) == 0x03))
{
if (HPosCnt >= 16 && HPosCnt <= (16 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
}
if ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06))
{
if (HPosCnt >= 32 && HPosCnt <= (32 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
}
if ((Number & 0x07) == 0x04 || (Number & 0x07) == 0x06)
{
if (HPosCnt >= 64 && HPosCnt <= (64 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
}*/
if (Start_Signal == 160)
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
ScanCnt = 0;
Start_Signal++;
ScanCntInit = true;
}
if ((Number & 0x07) == 0x01 || ((Number & 0x07) == 0x03))
if (Start_Signal == 16 && ((Number & 0x07) == 0x01 || ((Number & 0x07) == 0x03)))
{
if (HPosCnt >= 16 && HPosCnt <= (16 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
ScanCnt = 0;
Start_Signal++;
ScanCntInit = true;
}
if ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06))
if (Start_Signal == 32 && ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06)))
{
if (HPosCnt >= 32 && HPosCnt <= (32 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
ScanCnt = 0;
Start_Signal++;
ScanCntInit = true;
}
if ((Number & 0x07) == 0x04 || (Number & 0x07) == 0x06)
if (Start_Signal == 64 && ((Number & 0x07) == 0x04 || ((Number & 0x07) == 0x06)))
{
if (HPosCnt >= 64 && HPosCnt <= (64 + (1 << Size) - 1))
{
if (Enabled && !ResetToPlayer)
{
// Draw the missile
result = true;
}
}
ScanCnt = 0;
Start_Signal++;
ScanCntInit = true;
}
// Increment the counter
HPosCnt++;
// Counter loops at 160
HPosCnt %= 160;
// Counter loops at 160
HPosCnt %= 160;
//our goal here is to send a start signal 4 clocks before drawing begins. The properly emulates
//drawing on a real TIA
if (HPosCnt == 156 || HPosCnt == 12 || HPosCnt == 28 || HPosCnt == 60)
{
Start_Signal = HPosCnt;
Signal_Reached = HPosCnt + 5;
}
if (Start_Signal < Signal_Reached)
{
Start_Signal++;
}
return result;
}
}
public void SyncState(Serializer ser)
{
ser.BeginSection("Missile");
ser.Sync("enabled", ref Enabled);
ser.Sync("resetToPlayer", ref ResetToPlayer);
ser.Sync("hPosCnt", ref HPosCnt);
ser.Sync("size", ref Size);
ser.Sync("number", ref Number);
ser.Sync("HM", ref Hm);
ser.Sync("collisions", ref Collisions);
public void SyncState(Serializer ser)
{
ser.BeginSection("Missile");
ser.Sync("enabled", ref Enabled);
ser.Sync("resetToPlayer", ref ResetToPlayer);
ser.Sync("hPosCnt", ref HPosCnt);
ser.Sync("size", ref Size);
ser.Sync("number", ref Number);
ser.Sync("HM", ref Hm);
ser.Sync("collisions", ref Collisions);
ser.Sync("start_signal", ref Start_Signal);
ser.Sync("signal_reached", ref Signal_Reached);
ser.Sync("draw_to", ref Draw_To);
ser.Sync("scanCnt", ref ScanCnt);
ser.Sync("scanCntInit", ref ScanCntInit);
ser.EndSection();
}
}
}
}
}
}
}

View File

@ -18,11 +18,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public bool Reflect;
public bool Delay;
public byte Nusiz;
public bool Reset;
public byte ResetCnt;
public byte Collisions;
public bool Tick()
// Resp commands do not trigger start signals for main copies. We need to model this
public int Start_Signal;
public int Signal_Reached;
public bool Tick()
{
var result = false;
if (ScanCnt < 8)
@ -112,9 +114,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// At counter position 0 we should initalize the scan counter.
// Note that for double and quad sized players that the scan counter is not started immediately.
if (HPosCnt == 0 && !Reset)
{
if (Start_Signal==160)
{
ScanCnt = 0;
Start_Signal++;
if ((Nusiz & 0x07) == 0x05)
{
ScanCntInit = true;
@ -129,23 +132,23 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
}
if (HPosCnt == 16 && ((Nusiz & 0x07) == 0x01 || ((Nusiz & 0x07) == 0x03)))
if (Start_Signal == 16 && ((Nusiz & 0x07) == 0x01 || ((Nusiz & 0x07) == 0x03)))
{
ScanCnt = 0;
}
Start_Signal++;
}
if (HPosCnt == 32 && ((Nusiz & 0x07) == 0x02 || ((Nusiz & 0x07) == 0x03) || ((Nusiz & 0x07) == 0x06)))
if (Start_Signal == 32 && ((Nusiz & 0x07) == 0x02 || ((Nusiz & 0x07) == 0x03) || ((Nusiz & 0x07) == 0x06)))
{
ScanCnt = 0;
}
Start_Signal++;
}
if (HPosCnt == 64 && ((Nusiz & 0x07) == 0x04 || ((Nusiz & 0x07) == 0x06)))
if (Start_Signal == 64 && ((Nusiz & 0x07) == 0x04 || ((Nusiz & 0x07) == 0x06)))
{
ScanCnt = 0;
}
// Reset is no longer in effect
Reset = false;
Start_Signal++;
}
// Increment the counter
HPosCnt++;
@ -153,18 +156,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// Counter loops at 160
HPosCnt %= 160;
if (ResetCnt < 4)
{
ResetCnt++;
}
if (ResetCnt == 4)
{
HPosCnt = 0;
Reset = true;
ResetCnt++;
}
//our goal here is to send a start signal 4 clocks before drawing begins. This properly emulates
//drawing on a real TIA
if (HPosCnt==156 || HPosCnt==12 || HPosCnt==28 || HPosCnt==60)
{
Start_Signal = HPosCnt-1;
Signal_Reached = HPosCnt + 5;
}
if (Start_Signal<Signal_Reached)
{
Start_Signal++;
}
return result;
}
@ -181,10 +184,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("reflect", ref Reflect);
ser.Sync("delay", ref Delay);
ser.Sync("nusiz", ref Nusiz);
ser.Sync("reset", ref Reset);
ser.Sync("resetCnt", ref ResetCnt);
ser.Sync("collisions", ref Collisions);
}
ser.Sync("start_signal", ref Start_Signal);
ser.Sync("signal_reached", ref Signal_Reached);
}
}
}
}

View File

@ -284,12 +284,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
//PAL:
//0 15 30 45 60 -> 12 27 42 57 -> 9 24 39 54 -> 6 21 36 51 -> 3 18 33 48 -> 0
//sequence of ppu clocks per cpu clock: 4,3,3,3,3
//sequence of ppu clocks per cpu clock: 3,3,3,3,4
//at least it should be, but something is off with that (start up time?) so it is 3,3,3,4,3 for now
//NTSC:
//sequence of ppu clocks per cpu clock: 3
ByteBuffer cpu_sequence;
static ByteBuffer cpu_sequence_NTSC = new ByteBuffer(new byte[]{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3});
static ByteBuffer cpu_sequence_PAL = new ByteBuffer(new byte[]{4,3,3,3,3,4,3,3,3,3,4,3,3,3,3,4,3,3,3,3,4,3,3,3,3,4,3,3,3,3,4,3,3,3,3,4,3,3,3,3});
static ByteBuffer cpu_sequence_NTSC = new ByteBuffer(new byte[]{3,3,3,3,3});
static ByteBuffer cpu_sequence_PAL = new ByteBuffer(new byte[]{3,3,3,4,3});
public int cpu_step, cpu_stepcounter, cpu_deadcounter;
#if VS2012
@ -301,7 +302,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (cpu_stepcounter == cpu_sequence[cpu_step])
{
cpu_step++;
cpu_step &= 31;
if(cpu_step == 5) cpu_step=0;
cpu_stepcounter = 0;
if (sprdma_countdown > 0)
@ -309,9 +310,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
sprdma_countdown--;
if (sprdma_countdown == 0)
{
//its weird that this is 514.. normally itd be 512 (and people would say its wrong) or 513 (and people would say its right)
//but 514 passes test 4-irq_and_dma
cpu_deadcounter += 514;
//its weird that this is 514.. normally itd be 512 (and people would say its wrong) or 513 (and people would say its right)
//but 514 passes test 4-irq_and_dma
// according to nesdev wiki, http://wiki.nesdev.com/w/index.php/PPU_OAM this is 513 on even cycles and 514 on odd cycles
// TODO: Implement that
cpu_deadcounter += 514;
}
}

1535
TIA.cs

File diff suppressed because it is too large Load Diff