Merge pull request #636 from alyosha-tas/master

More Bug Fixes
This commit is contained in:
hegyak 2016-05-28 06:17:21 -07:00
commit 3ef327e748
4 changed files with 163 additions and 112 deletions

View File

@ -36,10 +36,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
if ((addr & 0x1080) == 0x0080)
{
return M6532.ReadMemory(addr, false);
_tia.bus_state = M6532.ReadMemory(addr, false);
return M6532.ReadMemory(addr, false);
}
return Rom[addr & 0x0FFF];
_tia.bus_state = Rom[addr & 0x0FFF];
return Rom[addr & 0x0FFF];
}
internal byte BasePeekMemory(ushort addr)
@ -52,15 +54,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
if ((addr & 0x1080) == 0x0080)
{
return M6532.ReadMemory(addr, true);
return M6532.ReadMemory(addr, true);
}
return Rom[addr & 0x0FFF];
return Rom[addr & 0x0FFF];
}
internal void BaseWriteMemory(ushort addr, byte value)
{
if (addr != LastAddress)
_tia.bus_state = value;
if (addr != LastAddress)
{
DistinctAccessCount++;
LastAddress = addr;
@ -69,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
addr = (ushort)(addr & 0x1FFF);
if ((addr & 0x1080) == 0)
{
_tia.WriteMemory(addr, value);
_tia.WriteMemory(addr, value, false);
}
else if ((addr & 0x1080) == 0x0080)
{
@ -83,10 +85,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
internal void BasePokeMemory(ushort addr, byte value)
{
addr = (ushort)(addr & 0x1FFF);
addr = (ushort)(addr & 0x1FFF);
if ((addr & 0x1080) == 0)
{
_tia.WriteMemory(addr, value);
_tia.WriteMemory(addr, value, true);
}
else if ((addr & 0x1080) == 0x0080)
{
@ -108,6 +110,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_mapper.Bit13 = addr.Bit(13);
var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF));
_tia.bus_state = temp;
MemoryCallbacks.CallReads(addr);
return temp;
@ -115,8 +118,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
internal byte PeekMemory(ushort addr)
{
var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF));
var temp = _mapper.PeekMemory((ushort)(addr & 0x1FFF));
return temp;
}

View File

@ -20,7 +20,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
16,
MemoryDomain.Endian.Little,
addr => _tia.ReadMemory((ushort)addr, true),
(addr, value) => this._tia.WriteMemory((ushort)addr, value), 1),
(addr, value) => this._tia.WriteMemory((ushort)addr, value, true), 1),
new MemoryDomainDelegate(
"PIA",
1024,

View File

@ -170,15 +170,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
val = RomImage[(addr & 0xff) + (RomImage.Length - 256)];
if (((_lastData & 0xe0) == 0x60) && ((_lastAddress >= 0x1000) ||
(_lastAddress < 0x200)))
(_lastAddress < 0x200)) && !peek)
{
_sliceHigh = (_sliceHigh & 0xf0ff) | ((addr & 0x8) << 8) |
((addr & 0x70) << 4);
}
}
_lastData = val;
_lastAddress = (ushort)(addr & 0x1fff);
if (!peek)
{
_lastData = val;
_lastAddress = (ushort)(addr & 0x1fff);
}
return val;
}
@ -226,7 +228,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
else if (addr < 0x2000 && !poke) // 256B region at 0x1f00 - 0x1fff
{
if (((_lastData & 0xe0) == 0x60) &&
((_lastAddress >= 0x1000) || (_lastAddress < 0x200)))
((_lastAddress >= 0x1000) || (_lastAddress < 0x200)) && !poke)
{
_sliceHigh = (_sliceHigh & 0xf0ff) | ((addr & 0x8) << 8) |
((addr & 0x70) << 4);
@ -252,96 +254,95 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private void CheckBankSwitch(ushort address, byte value)
{
if (((_lastData & 0xe0) == 0x60) && // Switch lower/middle/upper bank
((_lastAddress >= 0x1000) || (_lastAddress < 0x200)))
if (((_lastData & 0xe0) == 0x60) && // Switch lower/middle/upper bank
((_lastAddress >= 0x1000) || (_lastAddress < 0x200)))
{
if ((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff
{
_isRomHigh = true;
_sliceHigh = (address & 0xff) << 8;
}
else if ((address & 0x0f00) == 0x0d00) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
_isRomHigh = false;
_sliceHigh = (address & 0x7f) << 8;
}
else if ((address & 0x0f40) == 0x0e00) // Enable 2K of ROM at 0x1000 - 0x17ff
{
_isRomLow = true;
_sliceLow = (address & 0x1f) << 11;
}
else if ((address & 0x0f40) == 0x0e40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
_isRomLow = false;
_sliceLow = (address & 0xf) << 11;
}
else if ((address & 0x0f40) == 0x0f00) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
_isRomMiddle = true;
_sliceMiddle = (address & 0x1f) << 11;
}
else if ((address & 0x0f50) == 0x0f40) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
_isRomMiddle = false;
_sliceMiddle = (address & 0xf) << 11;
}
else if ((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address
{
_sliceLow = _sliceLow ^ 0x800;
}
else if ((address & 0x0f00) == 0x0500) // Toggle bit A12 of lower block address
{
_sliceLow = _sliceLow ^ 0x1000;
}
else if ((address & 0x0f00) == 0x0800) // Toggle bit A11 of middle block address
{
_sliceMiddle = _sliceMiddle ^ 0x800;
}
else if ((address & 0x0f00) == 0x0900) // Toggle bit A12 of middle block address
{
_sliceMiddle = _sliceMiddle ^ 0x1000;
}
}
// Zero-page hotspots for upper page
// 0xf4, 0xf6, 0xfc, 0xfe for ROM
// 0xf5, 0xf7, 0xfd, 0xff for RAM
// 0x74 - 0x7f (0x80 bytes lower)
if ((address & 0xf75) == 0x74) // Enable 256B of ROM at 0x1e00 - 0x1eff
{
if ((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff
{
_isRomHigh = true;
_sliceHigh = (address & 0xff) << 8;
}
else if ((address & 0x0f00) == 0x0d00) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
_isRomHigh = false;
_sliceHigh = (address & 0x7f) << 8;
}
else if ((address & 0x0f40) == 0x0e00) // Enable 2K of ROM at 0x1000 - 0x17ff
_isRomHigh = true;
_sliceHigh = value << 8;
}
else if ((address & 0xf75) == 0x75) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
_isRomHigh = false;
_sliceHigh = (value & 0x7f) << 8;
}
// Zero-page hotspots for lower and middle blocks
// 0xf8, 0xf9, 0xfa, 0xfb
// 0x78, 0x79, 0x7a, 0x7b (0x80 bytes lower)
else if ((address & 0xf7c) == 0x78)
{
if ((value & 0xf0) == 0) // Enable 2K of ROM at 0x1000 - 0x17ff
{
_isRomLow = true;
_sliceLow = (address & 0x1f) << 11;
_sliceLow = (value & 0xf) << 11;
}
else if ((address & 0x0f40) == 0x0e40) // Enable 2K of RAM at 0x1000 - 0x17ff
else if ((value & 0xf0) == 0x40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
_isRomLow = false;
_sliceLow = (address & 0xf) << 11;
_sliceLow = (value & 0xf) << 11;
}
else if ((address & 0x0f40) == 0x0f00) // Enable 1.5K of ROM at 0x1800 - 0x1dff
else if ((value & 0xf0) == 0x90) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
_isRomMiddle = true;
_sliceMiddle = (address & 0x1f) << 11;
_sliceMiddle = ((value & 0xf) | 0x10) << 11;
}
else if ((address & 0x0f50) == 0x0f40) // Enable 1.5K of RAM at 0x1800 - 0x1dff
else if ((value & 0xf0) == 0xc0) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
_isRomMiddle = false;
_sliceMiddle = (address & 0xf) << 11;
}
else if ((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address
{
_sliceLow = _sliceLow ^ 0x800;
}
else if ((address & 0x0f00) == 0x0500) // Toggle bit A12 of lower block address
{
_sliceLow = _sliceLow ^ 0x1000;
}
else if ((address & 0x0f00) == 0x0800) // Toggle bit A11 of middle block address
{
_sliceMiddle = _sliceMiddle ^ 0x800;
}
else if ((address & 0x0f00) == 0x0900) // Toggle bit A12 of middle block address
{
_sliceMiddle = _sliceMiddle ^ 0x1000;
}
// Zero-page hotspots for upper page
// 0xf4, 0xf6, 0xfc, 0xfe for ROM
// 0xf5, 0xf7, 0xfd, 0xff for RAM
// 0x74 - 0x7f (0x80 bytes lower)
if ((address & 0xf75) == 0x74) // Enable 256B of ROM at 0x1e00 - 0x1eff
{
_isRomHigh = true;
_sliceHigh = value << 8;
}
else if ((address & 0xf75) == 0x75) // Enable 256B of RAM at 0x1e00 - 0x1eff
{
_isRomHigh = false;
_sliceHigh = (value & 0x7f) << 8;
}
// Zero-page hotspots for lower and middle blocks
// 0xf8, 0xf9, 0xfa, 0xfb
// 0x78, 0x79, 0x7a, 0x7b (0x80 bytes lower)
else if ((address & 0xf7c) == 0x78)
{
if ((value & 0xf0) == 0) // Enable 2K of ROM at 0x1000 - 0x17ff
{
_isRomLow = true;
_sliceLow = (value & 0xf) << 11;
}
else if ((value & 0xf0) == 0x40) // Enable 2K of RAM at 0x1000 - 0x17ff
{
_isRomLow = false;
_sliceLow = (value & 0xf) << 11;
}
else if ((value & 0xf0) == 0x90) // Enable 1.5K of ROM at 0x1800 - 0x1dff
{
_isRomMiddle = true;
_sliceMiddle = ((value & 0xf) | 0x10) << 11;
}
else if ((value & 0xf0) == 0xc0) // Enable 1.5K of RAM at 0x1800 - 0x1dff
{
_isRomMiddle = false;
_sliceMiddle = (value & 0xf) << 11;
}
_sliceMiddle = (value & 0xf) << 11;
}
}
}

View File

@ -269,6 +269,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private int[] _palette;
public int bus_state;
private byte pf0_update;
private byte pf1_update;
private byte pf2_update;
@ -289,6 +291,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private bool enam1_val;
private bool enamb_val;
private int vblank_delay;
private byte vblank_value;
private bool p0_stuff;
private bool p1_stuff;
private bool m0_stuff;
@ -415,10 +420,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_capChargeStart = 0;
_capCharging = false;
_vblankEnabled = false;
vblank_delay = 0;
vblank_value = 0;
_vsyncEnabled = false;
_CurrentScanLine = 0;
_audioClocks = 0;
bus_state = 0;
pf0_update = 0;
pf1_update = 0;
pf2_update = 0;
@ -472,6 +481,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
// Still ignoring cycles...
// delay vblank latch
if (vblank_delay > 0)
{
vblank_delay++;
if (vblank_delay==3)
{
_vblankEnabled = (vblank_value & 0x02) != 0;
vblank_delay = 0;
}
}
//delay latch to new playfield register
if (pf0_updater == true)
{
@ -716,7 +739,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
}
if (_playField.Score && !_playField.Priority && (collisions & CXPF) != 0 && _core.Settings.ShowPlayfield)
if (_playField.Score && !_playField.Priority && ((collisions & CXPF) != 0) && _core.Settings.ShowPlayfield)
{
pixelColor = !rightSide ? _palette[_player0.Color] : _palette[_player1.Color];
}
@ -1047,44 +1070,55 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public byte ReadMemory(ushort addr, bool peek)
{
var maskedAddr = (ushort)(addr & 0x000F);
byte coll = 0;
int mask = 0;
if (maskedAddr == 0x00) // CXM0P
{
return (byte)((((_player0.Missile.Collisions & CXP1) != 0) ? 0x80 : 0x00) | (((_player0.Missile.Collisions & CXP0) != 0) ? 0x40 : 0x00));
coll=(byte)((((_player0.Missile.Collisions & CXP1) != 0) ? 0x80 : 0x00) | (((_player0.Missile.Collisions & CXP0) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x01) // CXM1P
{
return (byte)((((_player1.Missile.Collisions & CXP0) != 0) ? 0x80 : 0x00) | (((_player1.Missile.Collisions & CXP1) != 0) ? 0x40 : 0x00));
coll = (byte)((((_player1.Missile.Collisions & CXP0) != 0) ? 0x80 : 0x00) | (((_player1.Missile.Collisions & CXP1) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x02) // CXP0FB
{
return (byte)((((_player0.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player0.Collisions & CXBL) != 0) ? 0x40 : 0x00));
coll = (byte)((((_player0.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player0.Collisions & CXBL) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x03) // CXP1FB
{
return (byte)((((_player1.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player1.Collisions & CXBL) != 0) ? 0x40 : 0x00));
coll = (byte)((((_player1.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player1.Collisions & CXBL) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x04) // CXM0FB
{
return (byte)((((_player0.Missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player0.Missile.Collisions & CXBL) != 0) ? 0x40 : 0x00));
coll = (byte)((((_player0.Missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player0.Missile.Collisions & CXBL) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x05) // CXM1FB
{
return (byte)((((_player1.Missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player1.Missile.Collisions & CXBL) != 0) ? 0x40 : 0x00));
coll = (byte)((((_player1.Missile.Collisions & CXPF) != 0) ? 0x80 : 0x00) | (((_player1.Missile.Collisions & CXBL) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x06) // CXBLPF
{
return (byte)(((_ball.Collisions & CXPF) != 0) ? 0x80 : 0x00);
coll = (byte)(((_ball.Collisions & CXPF) != 0) ? 0x80 : 0x00);
mask = 0x7f;
}
if (maskedAddr == 0x07) // CXPPMM
{
return (byte)((((_player0.Collisions & CXP1) != 0) ? 0x80 : 0x00) | (((_player0.Missile.Collisions & CXM1) != 0) ? 0x40 : 0x00));
coll = (byte)((((_player0.Collisions & CXP1) != 0) ? 0x80 : 0x00) | (((_player0.Missile.Collisions & CXM1) != 0) ? 0x40 : 0x00));
mask = 0x3f;
}
if (maskedAddr == 0x08) // INPT0
@ -1093,28 +1127,38 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// 6105 roughly centers the paddle in Breakout
if (_capCharging && _core.Cpu.TotalExecutedCycles - _capChargeStart >= 6105)
{
return 0x80;
coll=0x80;
}
return 0x00;
coll=0x00;
mask = 0x7f;
}
if (maskedAddr == 0x0C) // INPT4
{
return (byte)((_core.ReadControls1(peek) & 0x08) != 0 ? 0x80 : 0x00);
coll = (byte)((_core.ReadControls1(peek) & 0x08) != 0 ? 0x80 : 0x00);
mask = 0x7f;
}
if (maskedAddr == 0x0D) // INPT5
{
return (byte)((_core.ReadControls2(peek) & 0x08) != 0 ? 0x80 : 0x00);
coll = (byte)((_core.ReadControls2(peek) & 0x08) != 0 ? 0x80 : 0x00);
mask = 0x7f;
}
return 0x00;
//some bits of the databus will be undriven when a read call is made. Our goal here is to sort out what
// happens to the undriven pins. Most of the time, they will be in whatever state they were when previously
//assigned in some other bus access, so let's go with that.
coll+=(byte)(mask & bus_state);
if (!peek) bus_state = (int)coll;
return coll;
}
public void WriteMemory(ushort addr, byte value)
public void WriteMemory(ushort addr, byte value, bool poke)
{
var maskedAddr = (ushort)(addr & 0x3f);
if (!poke) bus_state = value;
if (maskedAddr == 0x00) // VSYNC
{
@ -1145,7 +1189,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (maskedAddr == 0x01) // VBLANK
{
_vblankEnabled = (value & 0x02) != 0;
vblank_delay = 1;
vblank_value = value;
_capCharging = (value & 0x80) == 0;
if ((value & 0x80) == 0)
{
@ -1575,6 +1620,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("hsyncCnt", ref _hsyncCnt);
// add everything to the state
ser.Sync("Bus_State", ref bus_state);
ser.Sync("PF0_up",ref pf0_update);
ser.Sync("PF1_up", ref pf1_update);
ser.Sync("PF2_up", ref pf2_update);
@ -1613,7 +1660,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("Ticks", ref do_ticks);
ser.Sync("VBlankDelay", ref vblank_delay);
ser.Sync("VBlankValue", ref vblank_value);
// some of these things weren't in the state because they weren't needed if
// states were always taken at frame boundaries