cleanup Atari2600 mapper code
This commit is contained in:
parent
a61230e4ab
commit
8f860adf51
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
Mapper used for multi-cart 2K games
|
|
||||||
*/
|
|
||||||
internal class Multicart2K : MapperBase
|
internal class Multicart2K : MapperBase
|
||||||
{
|
{
|
||||||
private int _gameTotal;
|
private int _gameTotal;
|
||||||
|
@ -29,15 +26,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
IncrementGame();
|
IncrementGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncrementGame()
|
|
||||||
{
|
|
||||||
_currentGame++;
|
|
||||||
if (_currentGame >= _gameTotal)
|
|
||||||
{
|
|
||||||
_currentGame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override byte ReadMemory(ushort addr)
|
public override byte ReadMemory(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -49,5 +37,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||||
|
|
||||||
|
private void IncrementGame()
|
||||||
|
{
|
||||||
|
_currentGame++;
|
||||||
|
if (_currentGame >= _gameTotal)
|
||||||
|
{
|
||||||
|
_currentGame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
Mapper used for multi-cart 4K games
|
|
||||||
*/
|
|
||||||
internal class Multicart4K : MapperBase
|
internal class Multicart4K : MapperBase
|
||||||
{
|
{
|
||||||
private int _gameTotal;
|
private int _gameTotal;
|
||||||
|
@ -29,15 +26,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
IncrementGame();
|
IncrementGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncrementGame()
|
|
||||||
{
|
|
||||||
_currentGame++;
|
|
||||||
if (_currentGame >= _gameTotal)
|
|
||||||
{
|
|
||||||
_currentGame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override byte ReadMemory(ushort addr)
|
public override byte ReadMemory(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -49,5 +37,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||||
|
|
||||||
|
private void IncrementGame()
|
||||||
|
{
|
||||||
|
_currentGame++;
|
||||||
|
if (_currentGame >= _gameTotal)
|
||||||
|
{
|
||||||
|
_currentGame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
Mapper used for multi-cart 8K games
|
|
||||||
*/
|
|
||||||
internal class Multicart8K : MapperBase
|
internal class Multicart8K : MapperBase
|
||||||
{
|
{
|
||||||
private int _bank4K;
|
private int _bank4K;
|
||||||
|
@ -33,6 +30,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
IncrementGame();
|
IncrementGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private void IncrementGame()
|
private void IncrementGame()
|
||||||
{
|
{
|
||||||
_currentGame++;
|
_currentGame++;
|
||||||
|
@ -57,16 +64,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF) + (_currentGame * 8192)];
|
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF) + (_currentGame * 8192)];
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -80,16 +77,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF8)
|
if (addr == 0x1FF8)
|
||||||
|
|
|
@ -15,20 +15,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
0 1xxx xBxx xxxx
|
0 1xxx xBxx xxxx
|
||||||
|
|
||||||
Each bit corresponds to one of the 13 address lines. a 0 or 1 means that bit must be
|
Each bit corresponds to one of the 13 address lines. a 0 or 1 means that bit must be
|
||||||
0 or 1 to trigger the bankswitch. x is a bit that is not concidered (it can be either
|
0 or 1 to trigger the bankswitch. x is a bit that is not considered (it can be either
|
||||||
0 or 1 and is thus a "don't care" bit).
|
0 or 1 and is thus a "don't care" bit).
|
||||||
|
|
||||||
B is the bank we will select. sooo, accessing 0800 will select bank 0, and 0840
|
B is the bank we will select. So, accessing 0800 will select bank 0, and 0840
|
||||||
will select bank 1.
|
will select bank 1.
|
||||||
*/
|
*/
|
||||||
internal class m0840 : MapperBase
|
internal class m0840 : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _bank4K;
|
||||||
|
|
||||||
public m0840(Atari2600 core) : base(core)
|
public m0840(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _bank4K;
|
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
|
@ -41,6 +41,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -56,16 +66,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -79,27 +79,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
switch (addr & 0x1840)
|
_bank4K = (addr & 0x1840) switch
|
||||||
{
|
{
|
||||||
case 0x0800:
|
0x0800 => 0,
|
||||||
_bank4K = 0;
|
0x0840 => 1,
|
||||||
break;
|
_ => _bank4K
|
||||||
case 0x0840:
|
};
|
||||||
_bank4K = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
3E (Boulderdash
|
3E (Boulderdash
|
||||||
-----
|
-----
|
||||||
|
|
||||||
This works similar to 3F (Tigervision) above, except RAM has been added. The range of
|
This works similar to 3F (TigerVision) above, except RAM has been added. The range of
|
||||||
addresses has been restricted, too. Only 3E and 3F can be written to now.
|
addresses has been restricted, too. Only 3E and 3F can be written to now.
|
||||||
|
|
||||||
1000-17FF - this bank is selectable
|
1000-17FF - this bank is selectable
|
||||||
|
@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
8 bits, there's enough for 256 2K banks, or a maximum of 512K of ROM.
|
8 bits, there's enough for 256 2K banks, or a maximum of 512K of ROM.
|
||||||
|
|
||||||
Writing to 3E, however, is what's new. Writing here selects a 1K RAM bank into
|
Writing to 3E, however, is what's new. Writing here selects a 1K RAM bank into
|
||||||
1000-17FF. The example (Boulderdash) uses 16K of RAM, however there's theoretically
|
1000-17FF. The example (BoulderDash) uses 16K of RAM, however there's theoretically
|
||||||
enough space for 256K of RAM. When RAM is selected, 1000-13FF is the read port while
|
enough space for 256K of RAM. When RAM is selected, 1000-13FF is the read port while
|
||||||
1400-17FF is the write port.
|
1400-17FF is the write port.
|
||||||
*/
|
*/
|
||||||
|
@ -26,8 +26,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _lowbank2K;
|
private int _lowBank2K;
|
||||||
private int _rambank1K;
|
private int _ramBank1K;
|
||||||
private bool _hasRam;
|
private bool _hasRam;
|
||||||
private byte[] _ram = new byte[256 * 1024]; // Up to 256k
|
private byte[] _ram = new byte[256 * 1024]; // Up to 256k
|
||||||
|
|
||||||
|
@ -36,16 +36,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("lowbank_2k", ref _lowbank2K);
|
ser.Sync("lowbank_2k", ref _lowBank2K);
|
||||||
ser.Sync("rambank_1k", ref _rambank1K);
|
ser.Sync("rambank_1k", ref _ramBank1K);
|
||||||
ser.Sync("cart_ram", ref _ram, false);
|
ser.Sync("cart_ram", ref _ram, false);
|
||||||
ser.Sync("hasRam", ref _hasRam);
|
ser.Sync("hasRam", ref _hasRam);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_lowbank2K = 0;
|
_lowBank2K = 0;
|
||||||
_rambank1K = 0;
|
_ramBank1K = 0;
|
||||||
_hasRam = false;
|
_hasRam = false;
|
||||||
_ram = new byte[256 * 1024];
|
_ram = new byte[256 * 1024];
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
|
@ -64,27 +64,30 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
if (addr < 0x1400)
|
if (addr < 0x1400)
|
||||||
{
|
{
|
||||||
return _ram[(addr & 0x03FF) + (_rambank1K << 10)];
|
return _ram[(addr & 0x03FF) + (_ramBank1K << 10)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return _ram[(addr & 0x03FF) + (_rambank1K << 10)] = 0xFF; // Reading from the write port triggers an unwanted write
|
return _ram[(addr & 0x03FF) + (_ramBank1K << 10)] = 0xFF; // Reading from the write port triggers an unwanted write
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_lowbank2K << 11) + (addr & 0x07FF)];
|
return Core.Rom[(_lowBank2K << 11) + (addr & 0x07FF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0x2000) // High bank fixed to last 2k of ROM
|
if (addr < 0x2000) // High bank fixed to last 2k of ROM
|
||||||
{
|
{
|
||||||
return Core.Rom[(Core.Rom.Length - 0x800) + (addr & 0x07FF)];
|
return Core.Rom[Core.Rom.Length - 0x800 + (addr & 0x07FF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ReadMemory(addr);
|
return base.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr)
|
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||||
{
|
|
||||||
return ReadMemory(addr);
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
}
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private void WriteMem(ushort addr, byte value, bool poke)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
|
@ -93,18 +96,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
if (addr == 0x003E)
|
if (addr == 0x003E)
|
||||||
{
|
{
|
||||||
_hasRam = true;
|
_hasRam = true;
|
||||||
_rambank1K = value;
|
_ramBank1K = value;
|
||||||
}
|
}
|
||||||
else if (addr == 0x003F)
|
else if (addr == 0x003F)
|
||||||
{
|
{
|
||||||
_hasRam = false;
|
_hasRam = false;
|
||||||
if (value << 11 < Core.Rom.Length)
|
if (value << 11 < Core.Rom.Length)
|
||||||
{
|
{
|
||||||
_lowbank2K = value;
|
_lowBank2K = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_lowbank2K = value & (Core.Rom.Length >> 11);
|
_lowBank2K = value & (Core.Rom.Length >> 11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,18 +122,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if (addr < 0x1800) // Write port
|
else if (addr < 0x1800) // Write port
|
||||||
{
|
{
|
||||||
_ram[(_rambank1K << 10) + (addr & 0x3FF)] = value;
|
_ram[(_ramBank1K << 10) + (addr & 0x3FF)] = 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
3F (Tigervision)
|
3F (TigerVision)
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Traditionally, this method was used on the Tigervision games. The ROMs were all 8K, and
|
Traditionally, this method was used on the TigerVision games. The ROMs were all 8K, and
|
||||||
there's two 2K pages in the 4K of address space. The upper bank is fixed to the last 2K
|
there's two 2K pages in the 4K of address space. The upper bank is fixed to the last 2K
|
||||||
of the ROM.
|
of the ROM.
|
||||||
|
|
||||||
|
@ -17,27 +17,26 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
The homebrew community has decided that if 8K is good, more ROM is better! This mapper
|
The homebrew community has decided that if 8K is good, more ROM is better! This mapper
|
||||||
can support up to 512K bytes of ROM just by implementing all 8 bits on the mapper
|
can support up to 512K bytes of ROM just by implementing all 8 bits on the mapper
|
||||||
register, and this has been done... however I do not think 512K ROMs have been made just
|
register, and this has been done... however do not think 512K ROMs have been made just
|
||||||
yet.
|
yet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class m3F : MapperBase
|
internal class m3F : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _lowBank2K;
|
||||||
|
|
||||||
public m3F(Atari2600 core) : base(core)
|
public m3F(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _lowbank2K;
|
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("lowbank_2k", ref _lowbank2K);
|
ser.Sync("lowbank_2k", ref _lowBank2K);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_lowbank2K = 0;
|
_lowBank2K = 0;
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,21 +49,24 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
if (addr < 0x1800) // Low 2k Bank
|
if (addr < 0x1800) // Low 2k Bank
|
||||||
{
|
{
|
||||||
return Core.Rom[(_lowbank2K << 11) + (addr & 0x07FF)];
|
return Core.Rom[(_lowBank2K << 11) + (addr & 0x07FF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0x2000) // High bank fixed to last 2k of ROM
|
if (addr < 0x2000) // High bank fixed to last 2k of ROM
|
||||||
{
|
{
|
||||||
return Core.Rom[(Core.Rom.Length - 2048) + (addr & 0x07FF)];
|
return Core.Rom[Core.Rom.Length - 2048 + (addr & 0x07FF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ReadMemory(addr);
|
return base.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr)
|
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||||
{
|
|
||||||
return ReadMemory(addr);
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
}
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private void WriteMem(ushort addr, byte value, bool poke)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
|
@ -74,26 +76,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
if ((value << 11) < Core.Rom.Length)
|
if ((value << 11) < Core.Rom.Length)
|
||||||
{
|
{
|
||||||
_lowbank2K = value;
|
_lowBank2K = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_lowbank2K = value & (Core.Rom.Length >> 11);
|
_lowBank2K = value & (Core.Rom.Length >> 11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.WriteMemory(addr, value);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using BizHawk.Common;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/* From Kebtris docs
|
/* From Kevtris docs
|
||||||
4A50 (no name)
|
4A50 (no name)
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
One major problem is that it specifies that memory can be read and written
|
One major problem is that it specifies that memory can be read and written
|
||||||
to at the same address, but this is nearly impossible to detect on a 2600
|
to at the same address, but this is nearly impossible to detect on a 2600
|
||||||
cartridge. You'd almost have to try and figure out what opcodes are being
|
cartridge. You'd almost have to try and figure out what OpCodes are being
|
||||||
run, and what cycle it's on somehow, all just by watching address and
|
run, and what cycle it's on somehow, all just by watching address and
|
||||||
data bus state. Not very practical.
|
data bus state. Not very practical.
|
||||||
|
|
||||||
|
@ -23,13 +23,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
There's just tons and tons of unnecessary things like attempting to detect
|
There's just tons and tons of unnecessary things like attempting to detect
|
||||||
BIT instructions, handling page wraps and other silly things.
|
BIT instructions, handling page wraps and other silly things.
|
||||||
|
|
||||||
This all supposidly fit into a Xilinx XC9536XL but I am not sure how the
|
This all supposedly fit into a Xilinx XC9536XL but I am not sure how the
|
||||||
chip could handle the RAM issue above at all. It almost needs to see R/W
|
chip could handle the RAM issue above at all. It almost needs to see R/W
|
||||||
and M2 (clock) to be able to properly do most of the things it's doing.
|
and M2 (clock) to be able to properly do most of the things it's doing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* From Stella docs
|
/* From Stella docs
|
||||||
Bankswitching method as defined/created by John Payson (aka Supercat),
|
Bankswitching method as defined/created by John Payson (aka SuperCat),
|
||||||
documented at http://www.casperkitty.com/stella/cartfmt.htm.
|
documented at http://www.casperkitty.com/stella/cartfmt.htm.
|
||||||
|
|
||||||
In this bankswitching scheme the 2600's 4K cartridge address space
|
In this bankswitching scheme the 2600's 4K cartridge address space
|
||||||
|
@ -43,10 +43,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
internal class m4A50 : MapperBase
|
internal class m4A50 : MapperBase
|
||||||
{
|
{
|
||||||
public m4A50(Atari2600 core) : base(core)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] _ram = new byte[32768];
|
private byte[] _ram = new byte[32768];
|
||||||
|
|
||||||
private byte _lastData = 0xFF;
|
private byte _lastData = 0xFF;
|
||||||
|
@ -61,6 +57,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
private int _sliceMiddle;
|
private int _sliceMiddle;
|
||||||
|
|
||||||
private byte[] _romImage;
|
private byte[] _romImage;
|
||||||
|
|
||||||
|
public m4A50(Atari2600 core) : base(core)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] RomImage
|
private byte[] RomImage
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -129,6 +130,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
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 byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
byte val = 0;
|
byte val = 0;
|
||||||
|
@ -142,27 +153,31 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if (addr < 0x1800) // 2K region from 0x1000 - 0x17ff
|
else if (addr < 0x1800) // 2K region from 0x1000 - 0x17ff
|
||||||
{
|
{
|
||||||
val = _isRomLow ? RomImage[(addr & 0x7ff) + _sliceLow]
|
val = _isRomLow
|
||||||
|
? RomImage[(addr & 0x7ff) + _sliceLow]
|
||||||
: _ram[(addr & 0x7ff) + _sliceLow];
|
: _ram[(addr & 0x7ff) + _sliceLow];
|
||||||
}
|
}
|
||||||
else if (addr < 0x1E00) // 1.5K region from 0x1800 - 0x1dff
|
else if (addr < 0x1E00) // 1.5K region from 0x1800 - 0x1dff
|
||||||
{
|
{
|
||||||
val = _isRomMiddle ? RomImage[(addr & 0x7ff) + _sliceMiddle + 0x10000]
|
val = _isRomMiddle
|
||||||
|
? RomImage[(addr & 0x7ff) + _sliceMiddle + 0x10000]
|
||||||
: _ram[(addr & 0x7ff) + _sliceMiddle];
|
: _ram[(addr & 0x7ff) + _sliceMiddle];
|
||||||
}
|
}
|
||||||
else if (addr < 0x1F00) // 256B region from 0x1e00 - 0x1eff
|
else if (addr < 0x1F00) // 256B region from 0x1e00 - 0x1eff
|
||||||
{
|
{
|
||||||
val = _isRomHigh ? RomImage[(addr & 0xff) + _sliceHigh + 0x10000]
|
val = _isRomHigh
|
||||||
|
? RomImage[(addr & 0xff) + _sliceHigh + 0x10000]
|
||||||
: _ram[(addr & 0xff) + _sliceHigh];
|
: _ram[(addr & 0xff) + _sliceHigh];
|
||||||
}
|
}
|
||||||
else if (addr < 0x2000) // 256B region from 0x1f00 - 0x1fff
|
else if (addr < 0x2000) // 256B region from 0x1f00 - 0x1fff
|
||||||
{
|
{
|
||||||
val = RomImage[(addr & 0xff) + (RomImage.Length - 256)];
|
val = RomImage[(addr & 0xff) + (RomImage.Length - 256)];
|
||||||
if ((_lastData & 0xe0) == 0x60 && (_lastAddress >= 0x1000 ||
|
if ((_lastData & 0xe0) == 0x60 && (_lastAddress >= 0x1000
|
||||||
_lastAddress < 0x200) && !peek)
|
|| _lastAddress < 0x200) && !peek)
|
||||||
{
|
{
|
||||||
_sliceHigh = (_sliceHigh & 0xf0ff) | ((addr & 0x8) << 8) |
|
_sliceHigh = (_sliceHigh & 0xf0ff)
|
||||||
((addr & 0x70) << 4);
|
| ((addr & 0x8) << 8)
|
||||||
|
| ((addr & 0x70) << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,16 +190,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000) // Hotspots below 0x1000
|
if (addr < 0x1000) // Hotspots below 0x1000
|
||||||
|
@ -218,11 +223,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if (addr < 0x2000 && !poke) // 256B region at 0x1f00 - 0x1fff
|
else if (addr < 0x2000 && !poke) // 256B region at 0x1f00 - 0x1fff
|
||||||
{
|
{
|
||||||
if (((_lastData & 0xe0) == 0x60) &&
|
if ((_lastData & 0xe0) == 0x60
|
||||||
(_lastAddress >= 0x1000 || (_lastAddress < 0x200)) && !poke)
|
&& (_lastAddress >= 0x1000 || _lastAddress < 0x200))
|
||||||
{
|
{
|
||||||
_sliceHigh = (_sliceHigh & 0xf0ff) | ((addr & 0x8) << 8) |
|
_sliceHigh = (_sliceHigh & 0xf0ff)
|
||||||
((addr & 0x70) << 4);
|
| ((addr & 0x8) << 8)
|
||||||
|
| ((addr & 0x70) << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,20 +239,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 CheckBankSwitch(ushort address, byte value)
|
private void CheckBankSwitch(ushort address, byte value)
|
||||||
{
|
{
|
||||||
if (((_lastData & 0xe0) == 0x60) && // Switch lower/middle/upper bank
|
if ((_lastData & 0xe0) == 0x60 // Switch lower/middle/upper bank
|
||||||
((_lastAddress >= 0x1000) || (_lastAddress < 0x200)))
|
&& (_lastAddress >= 0x1000 || _lastAddress < 0x200))
|
||||||
{
|
{
|
||||||
if ((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff
|
if ((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff
|
||||||
{
|
{
|
||||||
|
@ -280,19 +276,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if ((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address
|
else if ((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address
|
||||||
{
|
{
|
||||||
_sliceLow = _sliceLow ^ 0x800;
|
_sliceLow ^= 0x800;
|
||||||
}
|
}
|
||||||
else if ((address & 0x0f00) == 0x0500) // Toggle bit A12 of lower block address
|
else if ((address & 0x0f00) == 0x0500) // Toggle bit A12 of lower block address
|
||||||
{
|
{
|
||||||
_sliceLow = _sliceLow ^ 0x1000;
|
_sliceLow ^= 0x1000;
|
||||||
}
|
}
|
||||||
else if ((address & 0x0f00) == 0x0800) // Toggle bit A11 of middle block address
|
else if ((address & 0x0f00) == 0x0800) // Toggle bit A11 of middle block address
|
||||||
{
|
{
|
||||||
_sliceMiddle = _sliceMiddle ^ 0x800;
|
_sliceMiddle ^= 0x800;
|
||||||
}
|
}
|
||||||
else if ((address & 0x0f00) == 0x0900) // Toggle bit A12 of middle block address
|
else if ((address & 0x0f00) == 0x0900) // Toggle bit A12 of middle block address
|
||||||
{
|
{
|
||||||
_sliceMiddle = _sliceMiddle ^ 0x1000;
|
_sliceMiddle ^= 0x1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using BizHawk.Common;
|
using BizHawk.Common;
|
||||||
/*
|
|
||||||
This is the cartridge class for Arcadia (aka Starpath) Supercharger
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This is the cartridge class for Arcadia (aka StarPath) Supercharger
|
||||||
games. Christopher Salomon provided most of the technical details
|
games. Christopher Salomon provided most of the technical details
|
||||||
used in creating this class. A good description of the Supercharger
|
used in creating this class. A good description of the Supercharger
|
||||||
is provided in the Cuttle Cart's manual.
|
is provided in the Cuttle Cart's manual.
|
||||||
|
@ -27,61 +29,10 @@ using BizHawk.Common;
|
||||||
w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
|
w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
|
||||||
to happen. 0 = disabled, and the cart acts like ROM.)
|
to happen. 0 = disabled, and the cart acts like ROM.)
|
||||||
p = ROM Power (0 = enabled, 1 = off.) Only power the ROM if you're
|
p = ROM Power (0 = enabled, 1 = off.) Only power the ROM if you're
|
||||||
wanting to access the ROM for multiloads. Otherwise set to 1.
|
wanting to access the ROM for multi-loads. Otherwise set to 1.
|
||||||
*/
|
*/
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|
||||||
{
|
|
||||||
internal class mAR : MapperBase
|
internal class mAR : MapperBase
|
||||||
{
|
{
|
||||||
public mAR(Atari2600 core) : base(core)
|
|
||||||
{
|
|
||||||
InitializeSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] _superChargerImage = new byte[8192];
|
|
||||||
private int[] _imageOffsets = new int[2];
|
|
||||||
private bool _writePending;
|
|
||||||
private int _distinctAccesses;
|
|
||||||
private bool _writeEnabled;
|
|
||||||
private byte _dataHoldRegister;
|
|
||||||
private byte _numberOfLoadImages;
|
|
||||||
private byte[] _loadedImages;
|
|
||||||
private byte[] _header = new byte[256];
|
|
||||||
private bool _powerIndicator; // Indicates if the ROM's power is on or off
|
|
||||||
private int _powerRomCycle; // Indicates when the power was last turned on
|
|
||||||
private int _size;
|
|
||||||
private ulong _elapsedCycles;
|
|
||||||
|
|
||||||
private void InitializeSettings()
|
|
||||||
{
|
|
||||||
// TODO: clean this stuff up
|
|
||||||
/*****************************************/
|
|
||||||
int size = Core.Rom.Length;
|
|
||||||
_size = Core.Rom.Length < 8448 ? 8448 : Core.Rom.Length; // 8448 or Rom size, whichever is bigger
|
|
||||||
|
|
||||||
_numberOfLoadImages = (byte)(_size / 8448);
|
|
||||||
|
|
||||||
// TODO: why are we making a redundant copy?
|
|
||||||
_loadedImages = new byte[_size];
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
_loadedImages[i] = Core.Rom[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < 8448)
|
|
||||||
{
|
|
||||||
for (int i = size; i < _size; i++)
|
|
||||||
{
|
|
||||||
_loadedImages[i] = _defaultHeader[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************/
|
|
||||||
|
|
||||||
InitializeRom();
|
|
||||||
BankConfiguration(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region SuperCharger Data
|
#region SuperCharger Data
|
||||||
|
|
||||||
private readonly byte[] _dummyRomCode =
|
private readonly byte[] _dummyRomCode =
|
||||||
|
@ -163,6 +114,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private byte[] _superChargerImage = new byte[8192];
|
||||||
|
private int[] _imageOffsets = new int[2];
|
||||||
|
private bool _writePending;
|
||||||
|
private int _distinctAccesses;
|
||||||
|
private bool _writeEnabled;
|
||||||
|
private byte _dataHoldRegister;
|
||||||
|
private byte _numberOfLoadImages;
|
||||||
|
private byte[] _loadedImages;
|
||||||
|
private byte[] _header = new byte[256];
|
||||||
|
private bool _powerIndicator; // Indicates if the ROM's power is on or off
|
||||||
|
private int _powerRomCycle; // Indicates when the power was last turned on
|
||||||
|
private int _size;
|
||||||
|
private ulong _elapsedCycles;
|
||||||
|
|
||||||
|
public mAR(Atari2600 core) : base(core)
|
||||||
|
{
|
||||||
|
InitializeSettings();
|
||||||
|
}
|
||||||
|
|
||||||
public override byte[] CartRam => _superChargerImage;
|
public override byte[] CartRam => _superChargerImage;
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
|
@ -215,6 +185,46 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
_elapsedCycles++;
|
_elapsedCycles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
|
private void InitializeSettings()
|
||||||
|
{
|
||||||
|
// TODO: clean this stuff up
|
||||||
|
/*****************************************/
|
||||||
|
int size = Core.Rom.Length;
|
||||||
|
_size = Core.Rom.Length < 8448 ? 8448 : Core.Rom.Length; // 8448 or Rom size, whichever is bigger
|
||||||
|
|
||||||
|
_numberOfLoadImages = (byte)(_size / 8448);
|
||||||
|
|
||||||
|
// TODO: why are we making a redundant copy?
|
||||||
|
_loadedImages = new byte[_size];
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
_loadedImages[i] = Core.Rom[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 8448)
|
||||||
|
{
|
||||||
|
for (int i = size; i < _size; i++)
|
||||||
|
{
|
||||||
|
_loadedImages[i] = _defaultHeader[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
|
||||||
|
InitializeRom();
|
||||||
|
BankConfiguration(0);
|
||||||
|
}
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -274,16 +284,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return _superChargerImage[(addr & 0x07FF) + _imageOffsets[((addr & 0x800) > 0) ? 1 : 0]];
|
return _superChargerImage[(addr & 0x07FF) + _imageOffsets[((addr & 0x800) > 0) ? 1 : 0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -330,16 +330,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 InitializeRom()
|
private void InitializeRom()
|
||||||
{
|
{
|
||||||
/* scrom.asm data borrowed from Stella:
|
/* scrom.asm data borrowed from Stella:
|
||||||
|
@ -394,7 +384,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
// w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
|
// w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
|
||||||
// to happen. 0 = disabled, and the cart acts like ROM.)
|
// to happen. 0 = disabled, and the cart acts like ROM.)
|
||||||
// p = ROM Power (0 = enabled, 1 = off.) Only power the ROM if you're
|
// p = ROM Power (0 = enabled, 1 = off.) Only power the ROM if you're
|
||||||
// wanting to access the ROM for multiloads. Otherwise set to 1.
|
// wanting to access the ROM for multi-loads. Otherwise set to 1.
|
||||||
|
|
||||||
//_bank2k = configuration & 0x1F; // remember for the bank() method
|
//_bank2k = configuration & 0x1F; // remember for the bank() method
|
||||||
_powerIndicator = !((configuration & 0x01) > 0);
|
_powerIndicator = !((configuration & 0x01) > 0);
|
||||||
|
@ -468,7 +458,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
int bank = _header[16 + j] & 0x03;
|
int bank = _header[16 + j] & 0x03;
|
||||||
int page = (_header[16 + j] >> 2) & 0x07;
|
int page = (_header[16 + j] >> 2) & 0x07;
|
||||||
var src = _loadedImages.Skip((image * 8448) + (j * 256)).Take(256).ToArray();
|
var src = _loadedImages
|
||||||
|
.Skip((image * 8448) + (j * 256))
|
||||||
|
.Take(256)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
byte sum = (byte)(Checksum(src) + _header[16 + j] + _header[64 + j]);
|
byte sum = (byte)(Checksum(src) + _header[16 + j] + _header[64 + j]);
|
||||||
|
|
||||||
if (!invalidPageChecksumSeen && (sum != 0x55))
|
if (!invalidPageChecksumSeen && (sum != 0x55))
|
||||||
|
@ -498,7 +492,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
byte sum = 0;
|
byte sum = 0;
|
||||||
|
|
||||||
for (int i = 0; i < s.Count(); i++)
|
for (int i = 0; i < s.Length; i++)
|
||||||
{
|
{
|
||||||
sum += s[i];
|
sum += s[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ using BizHawk.Common.NumberExtensions;
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Spectravideo Compumate Add-on Kevtris Documentation
|
Spectra-video Compumate Add-on Kevtris Documentation
|
||||||
|
|
||||||
This is more than just a cartridge mapper- it's also a "computer" add-on.
|
This is more than just a cartridge mapper- it's also a "computer" add-on.
|
||||||
There's two 8K EPROMs soldered on top of each other. There's two short
|
There's two 8K EPROMs soldered on top of each other. There's two short
|
||||||
|
@ -47,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
1000-1FFF : selectable 4K ROM bank (selected by D0, D1 on portA)
|
1000-1FFF : selectable 4K ROM bank (selected by D0, D1 on portA)
|
||||||
|
|
||||||
On powerup, the port is all 1's, so the last bank of ROM is enabled, RAM is
|
On power up, the port is all 1's, so the last bank of ROM is enabled, RAM is
|
||||||
disabled.
|
disabled.
|
||||||
|
|
||||||
when RAM is enabled:
|
when RAM is enabled:
|
||||||
|
@ -70,7 +70,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
Bit 6 of portA clocks the 4017. Each rising edge advances the column one
|
Bit 6 of portA clocks the 4017. Each rising edge advances the column one
|
||||||
count.
|
count.
|
||||||
|
|
||||||
There's 10 columns labelled 0-9, and 4 rows, labelled 0-3.
|
There's 10 columns labeled 0-9, and 4 rows, labeled 0-3.
|
||||||
|
|
||||||
Column
|
Column
|
||||||
|
|
||||||
|
@ -104,8 +104,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spectravideo Compumate Add-on Stella Documentation
|
* SpectraVideo Compumate Add-on Stella Documentation
|
||||||
Cartridge class used for SpectraVideo CompuMate bankswitched games.
|
Cartridge class used for SpectraVideo Compumate bankswitched games.
|
||||||
|
|
||||||
This is more than just a cartridge mapper - it's also a "computer" add-on.
|
This is more than just a cartridge mapper - it's also a "computer" add-on.
|
||||||
There's two 8K EPROMs soldered on top of each other. There's two short
|
There's two 8K EPROMs soldered on top of each other. There's two short
|
||||||
|
@ -129,12 +129,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
D1 = bank select high bit
|
D1 = bank select high bit
|
||||||
D0 = bank select low bit
|
D0 = bank select low bit
|
||||||
|
|
||||||
INPT0: D7 = FUNC key input (0 on startup / 1 = key pressed)
|
INPUT0: D7 = FUNC key input (0 on startup / 1 = key pressed)
|
||||||
INPT1: D7 = always HIGH input (pulled high thru 20K resistor)
|
INPUT1: D7 = always HIGH input (pulled high thru 20K resistor)
|
||||||
INPT2: D7 = always HIGH input (pulled high thru 20K resistor)
|
INPUT2: D7 = always HIGH input (pulled high thru 20K resistor)
|
||||||
INPT3: D7 = SHIFT key input (0 on startup / 1 = key pressed)
|
INPUT3: D7 = SHIFT key input (0 on startup / 1 = key pressed)
|
||||||
INPT4: D7 = keyboard row 0 input (0 = key pressed)
|
INPUT4: D7 = keyboard row 0 input (0 = key pressed)
|
||||||
INPT5: D7 = keyboard row 2 input (0 = key pressed)
|
INPUT5: D7 = keyboard row 2 input (0 = key pressed)
|
||||||
|
|
||||||
The keyboard's composed of a 4017 1 of 10 counter, driving the 10 columns of
|
The keyboard's composed of a 4017 1 of 10 counter, driving the 10 columns of
|
||||||
the keyboard. It has 4 rows. The 4 row outputs are buffered by inverters.
|
the keyboard. It has 4 rows. The 4 row outputs are buffered by inverters.
|
||||||
|
@ -145,7 +145,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
Bit 6 of portA clocks the 4017. Each rising edge advances the column one
|
Bit 6 of portA clocks the 4017. Each rising edge advances the column one
|
||||||
count.
|
count.
|
||||||
|
|
||||||
There's 10 columns labelled 0-9, and 4 rows, labelled 0-3.
|
There's 10 columns labeled 0-9, and 4 rows, labeled 0-3.
|
||||||
|
|
||||||
Column
|
Column
|
||||||
|
|
||||||
|
@ -218,11 +218,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
public override byte ReadMemory(ushort addr)
|
||||||
{
|
{
|
||||||
// A unique feature of the keyboard is that it changes the operation of inputs 0-3
|
// A unique feature of the keyboard is that it changes the operation of inputs 0-3
|
||||||
// by holding them high in the no-button-pressed state.
|
// by holding them high in the no-button-pressed state.
|
||||||
// However exposing this behaviour to the rest of the system would be overly cunmbersome
|
// However exposing this behaviour to the rest of the system would be overly cumbersome
|
||||||
// so instead we bypass these cases here
|
// so instead we bypass these cases here
|
||||||
if ((addr & 0x000F) == 8 && (addr & 0x1080) == 0 && addr < 1000)
|
if ((addr & 0x000F) == 8 && (addr & 0x1080) == 0 && addr < 1000)
|
||||||
{
|
{
|
||||||
|
@ -278,19 +278,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
throw new Exception("this hasn't been tested");
|
throw new Exception("this hasn't been tested");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte ReadMemory(ushort addr)
|
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||||
{
|
|
||||||
return ReadMem(addr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr)
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
{
|
=> WriteMem(addr, value, false);
|
||||||
return ReadMem(addr,true);
|
|
||||||
}
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private void WriteMem(ushort addr, byte value, bool poke)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
// Mimicking the 6532 logic for accessing port A, for testing
|
|
||||||
////var isPortA = false; // adelikat: Commented out this variable to remove a warning. Should this be deleted or is this supposed to be actually used?
|
////var isPortA = false; // adelikat: Commented out this variable to remove a warning. Should this be deleted or is this supposed to be actually used?
|
||||||
|
|
||||||
if ((addr & 0x0200) == 0) // If the RS bit is not set, this is a ram write
|
if ((addr & 0x0200) == 0) // If the RS bit is not set, this is a ram write
|
||||||
|
@ -361,15 +358,5 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.WriteMemory(addr, value);
|
base.WriteMemory(addr, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteMemory(ushort addr, byte value)
|
|
||||||
{
|
|
||||||
WriteMem(addr, value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PokeMemory(ushort addr, byte value)
|
|
||||||
{
|
|
||||||
WriteMem(addr, value, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mCV : MapperBase
|
internal class mCV : MapperBase
|
||||||
{
|
{
|
||||||
|
private byte[] _ram = new byte[1024];
|
||||||
|
|
||||||
public mCV(Atari2600 core) : base(core)
|
public mCV(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] _ram = new byte[1024];
|
|
||||||
|
|
||||||
public override byte[] CartRam => _ram;
|
public override byte[] CartRam => _ram;
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
|
@ -51,16 +51,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
if (addr >= 0x1800 && addr < 0x2000)
|
if (addr >= 0x1800 && addr < 0x2000)
|
||||||
{
|
{
|
||||||
return Core.Rom[(addr & 0x7FF)];
|
return Core.Rom[addr & 0x7FF];
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ReadMemory(addr);
|
return base.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr)
|
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||||
{
|
|
||||||
return ReadMemory(addr);
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
}
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private void WriteMem(ushort addr, byte value, bool poke)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
|
@ -70,18 +73,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if (addr >= 0x1400 && addr < 0x1800)
|
else if (addr >= 0x1400 && addr < 0x1800)
|
||||||
{
|
{
|
||||||
_ram[(addr & 0x3FF)] = value;
|
_ram[addr & 0x3FF] = 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
lots of the internal workings of the chip (number 4644495, "video memory system").
|
lots of the internal workings of the chip (number 4644495, "video memory system").
|
||||||
|
|
||||||
Interestingly, the patent shows the DPC as a *separate* device. You plug a
|
Interestingly, the patent shows the DPC as a *separate* device. You plug a
|
||||||
passthrough cartridge into your 2600, then plug the game cartridge into the
|
pass-through cartridge into your 2600, then plug the game cartridge into the
|
||||||
passthrough. Apparently, Activision thought that people wouldn't like this, or
|
pass-through. Apparently, Activision thought that people wouldn't like this, or
|
||||||
there was some other reasoning behind it and they ditched that idea and went with
|
there was some other reasoning behind it and they ditched that idea and went with
|
||||||
the DPC inside the cartridge.
|
the DPC inside the cartridge.
|
||||||
|
|
||||||
Unfortunately for Activision, it was filed in January of 1984, during the height of
|
Unfortunately for ActiVision, it was filed in January of 1984, during the height of
|
||||||
the crash. The inventor is listed as David Crane.
|
the crash. The inventor is listed as David Crane.
|
||||||
|
|
||||||
OK, enough background. Now onto the meat:
|
OK, enough background. Now onto the meat:
|
||||||
|
@ -139,7 +139,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
Masking the data:
|
Masking the data:
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
1038-103F is the readback for the mask value
|
1038-103F is the read back for the mask value
|
||||||
1040-1047 is the start count
|
1040-1047 is the start count
|
||||||
1048-104F is the end count
|
1048-104F is the end count
|
||||||
|
|
||||||
|
@ -221,14 +221,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
Pitfall 2 just reads this location and stuffs it into the audio register every scanline or
|
Pitfall 2 just reads this location and stuffs it into the audio register every scanline or
|
||||||
so. The value read at 1004-1007 is the instantanious value generated by the fetchers and
|
so. The value read at 1004-1007 is the instantanious value generated by the fetchers and
|
||||||
mixing hardware.
|
mixing hardware.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
internal class mDPC : MapperBase
|
internal class mDPC : MapperBase
|
||||||
{
|
{
|
||||||
public mDPC(Atari2600 core) : base(core)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table for computing the input bit of the random number generator's
|
// Table for computing the input bit of the random number generator's
|
||||||
// shift register (it's the NOT of the EOR of four bits)
|
// shift register (it's the NOT of the EOR of four bits)
|
||||||
private readonly byte[] _randomInputBits = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
|
private readonly byte[] _randomInputBits = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
|
||||||
|
@ -245,6 +240,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
private float _fractionalClocks; // Fractional DPC music OSC clocks unused during the last update
|
private float _fractionalClocks; // Fractional DPC music OSC clocks unused during the last update
|
||||||
|
|
||||||
private byte[] _dspData;
|
private byte[] _dspData;
|
||||||
|
|
||||||
|
public mDPC(Atari2600 core) : base(core)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] DspData => _dspData ??= Core.Rom.Skip(8192).Take(2048).ToArray();
|
public byte[] DspData => _dspData ??= Core.Rom.Skip(8192).Take(2048).ToArray();
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
|
@ -285,6 +285,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
_elapsedCycles++;
|
_elapsedCycles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -385,16 +395,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -470,16 +470,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF8)
|
if (addr == 0x1FF8)
|
||||||
|
@ -496,8 +486,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
// Using bits 7, 5, 4, & 3 of the shift register compute the input
|
// Using bits 7, 5, 4, & 3 of the shift register compute the input
|
||||||
// bit for the shift register
|
// bit for the shift register
|
||||||
var bit = _randomInputBits[((_currentRandomVal >> 3) & 0x07) |
|
var bit = _randomInputBits[((_currentRandomVal >> 3) & 0x07)
|
||||||
((_currentRandomVal & 0x80) > 0 ? 0x08 : 0x00)];
|
| ((_currentRandomVal & 0x80) > 0 ? 0x08 : 0x00)];
|
||||||
|
|
||||||
// Update the shift register
|
// Update the shift register
|
||||||
_currentRandomVal = (byte)((_currentRandomVal << 1) | bit);
|
_currentRandomVal = (byte)((_currentRandomVal << 1) | bit);
|
||||||
|
|
|
@ -11,11 +11,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mDPCPlus : MapperBase
|
internal class mDPCPlus : MapperBase
|
||||||
{
|
{
|
||||||
// TODO: PokeMem, and everything else
|
// Table for computing the input bit of the random number generator's
|
||||||
public mDPCPlus(Atari2600 core) : base(core)
|
// shift register (it's the NOT of the EOR of four bits)
|
||||||
{
|
private readonly byte[] _randomInputBits = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int[] _counters = new int[8];
|
private int[] _counters = new int[8];
|
||||||
private byte[] _tops = new byte[8];
|
private byte[] _tops = new byte[8];
|
||||||
|
@ -29,11 +27,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
private float _fractionalClocks; // Fractional DPC music OSC clocks unused during the last update
|
private float _fractionalClocks; // Fractional DPC music OSC clocks unused during the last update
|
||||||
|
|
||||||
private byte[] _dspData;
|
private byte[] _dspData;
|
||||||
public byte[] DspData => _dspData ??= Core.Rom.Skip(8192).Take(2048).ToArray();
|
|
||||||
|
|
||||||
// Table for computing the input bit of the random number generator's
|
// TODO: PokeMem, and everything else
|
||||||
// shift register (it's the NOT of the EOR of four bits)
|
public mDPCPlus(Atari2600 core) : base(core)
|
||||||
private readonly byte[] _randomInputBits = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] DspData => _dspData ??= Core.Rom.Skip(8192).Take(2048).ToArray();
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
|
@ -73,6 +74,83 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
_elapsedCycles++;
|
_elapsedCycles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
{
|
||||||
|
if (addr < 0x1000)
|
||||||
|
{
|
||||||
|
base.WriteMemory(addr, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address(addr);
|
||||||
|
ClockRandomNumberGenerator();
|
||||||
|
|
||||||
|
if (addr >= 0x1040 && addr < 0x1080)
|
||||||
|
{
|
||||||
|
var index = addr & 0x07;
|
||||||
|
var function = (addr >> 3) & 0x07;
|
||||||
|
|
||||||
|
switch (function)
|
||||||
|
{
|
||||||
|
// DFx top count
|
||||||
|
case 0x00:
|
||||||
|
_tops[index] = value;
|
||||||
|
_flags[index] = 0x00;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DFx bottom count
|
||||||
|
case 0x01:
|
||||||
|
_bottoms[index] = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DFx counter low
|
||||||
|
case 0x02:
|
||||||
|
if (index >= 5 && _musicModes[index - 5])
|
||||||
|
{
|
||||||
|
// Data fetcher is in music mode so its low counter value
|
||||||
|
// should be loaded from the top register not the poked value
|
||||||
|
_counters[index] = (_counters[index] & 0x0700) |
|
||||||
|
_tops[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Data fetcher is either not a music mode data fetcher or it
|
||||||
|
// isn't in music mode so it's low counter value should be loaded
|
||||||
|
// with the poked value
|
||||||
|
_counters[index] = (_counters[index] & 0x0700) | value;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DFx counter high
|
||||||
|
case 0x03:
|
||||||
|
_counters[index] = (ushort)(((value & 0x07) << 8)
|
||||||
|
| (_counters[index] & 0x00ff));
|
||||||
|
|
||||||
|
// Execute special code for music mode data fetchers
|
||||||
|
if (index >= 5)
|
||||||
|
{
|
||||||
|
_musicModes[index - 5] = (value & 0x10) > 0;
|
||||||
|
|
||||||
|
// NOTE: We are not handling the clock source input for
|
||||||
|
// the music mode data fetchers. We're going to assume
|
||||||
|
// they always use the OSC input.
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Random Number Generator Reset
|
||||||
|
case 0x06:
|
||||||
|
_currentRandomVal = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -173,89 +251,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteMemory(ushort addr, byte value)
|
|
||||||
{
|
|
||||||
if (addr < 0x1000)
|
|
||||||
{
|
|
||||||
base.WriteMemory(addr, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Address(addr);
|
|
||||||
ClockRandomNumberGenerator();
|
|
||||||
|
|
||||||
if (addr >= 0x1040 && addr < 0x1080)
|
|
||||||
{
|
|
||||||
var index = addr & 0x07;
|
|
||||||
var function = (addr >> 3) & 0x07;
|
|
||||||
|
|
||||||
switch (function)
|
|
||||||
{
|
|
||||||
// DFx top count
|
|
||||||
case 0x00:
|
|
||||||
_tops[index] = value;
|
|
||||||
_flags[index] = 0x00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DFx bottom count
|
|
||||||
case 0x01:
|
|
||||||
_bottoms[index] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DFx counter low
|
|
||||||
case 0x02:
|
|
||||||
if ((index >= 5) && _musicModes[index - 5])
|
|
||||||
{
|
|
||||||
// Data fetcher is in music mode so its low counter value
|
|
||||||
// should be loaded from the top register not the poked value
|
|
||||||
_counters[index] = (_counters[index] & 0x0700) |
|
|
||||||
_tops[index];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Data fetcher is either not a music mode data fetcher or it
|
|
||||||
// isn't in music mode so it's low counter value should be loaded
|
|
||||||
// with the poked value
|
|
||||||
_counters[index] = (_counters[index] & 0x0700) | value;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DFx counter high
|
|
||||||
case 0x03:
|
|
||||||
_counters[index] = (ushort)(((value & 0x07) << 8) |
|
|
||||||
(_counters[index] & 0x00ff));
|
|
||||||
|
|
||||||
// Execute special code for music mode data fetchers
|
|
||||||
if (index >= 5)
|
|
||||||
{
|
|
||||||
_musicModes[index - 5] = (value & 0x10) > 0;
|
|
||||||
|
|
||||||
// NOTE: We are not handling the clock source input for
|
|
||||||
// the music mode data fetchers. We're going to assume
|
|
||||||
// they always use the OSC input.
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Random Number Generator Reset
|
|
||||||
case 0x06:
|
|
||||||
_currentRandomVal = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Address(ushort addr)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF6)
|
if (addr == 0x1FF6)
|
||||||
|
|
|
@ -22,17 +22,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
Example Games:
|
Example Games:
|
||||||
Frogger II - Threedeep! (1983) (Parker Bros)
|
Frogger II - Threedeep! (1983) (Parker Bros)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mE0 : MapperBase
|
internal class mE0 : MapperBase
|
||||||
{
|
{
|
||||||
public mE0(Atari2600 core) : base(core)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private int _toggle1;
|
private int _toggle1;
|
||||||
private int _toggle2;
|
private int _toggle2;
|
||||||
private int _toggle3;
|
private int _toggle3;
|
||||||
|
|
||||||
|
public mE0(Atari2600 core) : base(core)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
|
@ -49,6 +48,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
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 byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -79,16 +88,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(7 * 1024) + (addr & 0x3FF)]; // 7 because final bank is always set to last
|
return Core.Rom[(7 * 1024) + (addr & 0x3FF)]; // 7 because final bank is always set to last
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -102,16 +101,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
|
|
|
@ -21,17 +21,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
is the read port.
|
is the read port.
|
||||||
|
|
||||||
1800-19FF also holds RAM. 1800-18FF is the write port, 1900-19FF is the read port.
|
1800-19FF also holds RAM. 1800-18FF is the write port, 1900-19FF is the read port.
|
||||||
Only 256 bytes of RAM is accessable at time, but there are four different 256 byte
|
Only 256 bytes of RAM is accessible at time, but there are four different 256 byte
|
||||||
banks making a total of 1K accessable here.
|
banks making a total of 1K accessible here.
|
||||||
|
|
||||||
Accessing 1FE8 through 1FEB select which 256 byte bank shows up.
|
Accessing 1FE8 through 1FEB select which 256 byte bank shows up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mE7 : MapperBase
|
internal class mE7 : MapperBase
|
||||||
{
|
{
|
||||||
private const int RamBank1Offset = 1024;
|
private const int RamBank1Offset = 1024;
|
||||||
private int _rombank1K;
|
private int _romBank1K;
|
||||||
private int _rambank1Toggle;
|
private int _ramBank1Toggle;
|
||||||
private byte[] _ram = new byte[2048];
|
private byte[] _ram = new byte[2048];
|
||||||
|
|
||||||
private bool _enableRam0;
|
private bool _enableRam0;
|
||||||
|
@ -43,16 +42,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("toggle", ref _rombank1K);
|
ser.Sync("toggle", ref _romBank1K);
|
||||||
ser.Sync("ram", ref _ram, false);
|
ser.Sync("ram", ref _ram, false);
|
||||||
ser.Sync("EnableRam0", ref _enableRam0);
|
ser.Sync("EnableRam0", ref _enableRam0);
|
||||||
ser.Sync("rambank1_toggle", ref _rambank1Toggle);
|
ser.Sync("rambank1_toggle", ref _ramBank1Toggle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_rombank1K = 0;
|
_romBank1K = 0;
|
||||||
_rambank1Toggle = 0;
|
_ramBank1Toggle = 0;
|
||||||
_ram = new byte[2048];
|
_ram = new byte[2048];
|
||||||
_enableRam0 = false;
|
_enableRam0 = false;
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
|
@ -60,6 +59,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
public override byte[] CartRam => _ram;
|
public override byte[] CartRam => _ram;
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -84,17 +87,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return _ram[addr & 0x3FF];
|
return _ram[addr & 0x3FF];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_rombank1K * 0x800) + (addr & 0x7FF)];
|
return Core.Rom[(_romBank1K * 0x800) + (addr & 0x7FF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0x1900) // Ram 1 Write port
|
if (addr < 0x1900) // Ram 1 Write port
|
||||||
{
|
{
|
||||||
return _ram[RamBank1Offset + (_rambank1Toggle * 0x100) + (addr & 0xFF)] = 0xFF; // Reading from the 256b write port @1800 riggers an unwanted write
|
return _ram[RamBank1Offset + (_ramBank1Toggle * 0x100) + (addr & 0xFF)] = 0xFF; // Reading from the 256b write port @1800 riggers an unwanted write
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0x1A00) // Ram 1 Read port
|
if (addr < 0x1A00) // Ram 1 Read port
|
||||||
{
|
{
|
||||||
return _ram[RamBank1Offset + (_rambank1Toggle * 0x100) + (addr & 0xFF)];
|
return _ram[RamBank1Offset + (_ramBank1Toggle * 0x100) + (addr & 0xFF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0x2000)
|
if (addr < 0x2000)
|
||||||
|
@ -108,15 +111,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return base.ReadMemory(addr);
|
return base.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte ReadMemory(ushort addr)
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
{
|
=> WriteMem(addr, value, false);
|
||||||
return ReadMem(addr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr)
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
{
|
=> WriteMem(addr, value, true);
|
||||||
return ReadMem(addr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteMem(ushort addr, byte value, bool poke)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
|
@ -135,61 +134,51 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if (addr >= 0x1800 && addr < 0x1900)
|
else if (addr >= 0x1800 && addr < 0x1900)
|
||||||
{
|
{
|
||||||
_ram[RamBank1Offset + (addr & 0xFF) + (_rambank1Toggle * 0x100)] = value;
|
_ram[RamBank1Offset + (addr & 0xFF) + (_ramBank1Toggle * 0x100)] = 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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
_enableRam0 = false;
|
_enableRam0 = false;
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x1FE0:
|
case 0x1FE0:
|
||||||
_rombank1K = 0;
|
_romBank1K = 0;
|
||||||
break;
|
break;
|
||||||
case 0x1FE1:
|
case 0x1FE1:
|
||||||
_rombank1K = 1;
|
_romBank1K = 1;
|
||||||
break;
|
break;
|
||||||
case 0x1FE2:
|
case 0x1FE2:
|
||||||
_rombank1K = 2;
|
_romBank1K = 2;
|
||||||
break;
|
break;
|
||||||
case 0x1FE3:
|
case 0x1FE3:
|
||||||
_rombank1K = 3;
|
_romBank1K = 3;
|
||||||
break;
|
break;
|
||||||
case 0x1FE4:
|
case 0x1FE4:
|
||||||
_rombank1K = 4;
|
_romBank1K = 4;
|
||||||
break;
|
break;
|
||||||
case 0x1FE5:
|
case 0x1FE5:
|
||||||
_rombank1K = 5;
|
_romBank1K = 5;
|
||||||
break;
|
break;
|
||||||
case 0x1FE6:
|
case 0x1FE6:
|
||||||
_rombank1K = 6;
|
_romBank1K = 6;
|
||||||
break;
|
break;
|
||||||
case 0x1FE7:
|
case 0x1FE7:
|
||||||
_rombank1K = 7;
|
_romBank1K = 7;
|
||||||
_enableRam0 = true;
|
_enableRam0 = true;
|
||||||
break;
|
break;
|
||||||
case 0x1FE8:
|
case 0x1FE8:
|
||||||
_rambank1Toggle = 0;
|
_ramBank1Toggle = 0;
|
||||||
break;
|
break;
|
||||||
case 0x1FE9:
|
case 0x1FE9:
|
||||||
_rambank1Toggle = 1;
|
_ramBank1Toggle = 1;
|
||||||
break;
|
break;
|
||||||
case 0x1FEA:
|
case 0x1FEA:
|
||||||
_rambank1Toggle = 2;
|
_ramBank1Toggle = 2;
|
||||||
break;
|
break;
|
||||||
case 0x1FEB:
|
case 0x1FEB:
|
||||||
_rambank1Toggle = 3;
|
_ramBank1Toggle = 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
1FE0-1FEF. Accessing one of these will select the desired bank. 1FE0 = bank 0,
|
1FE0-1FEF. Accessing one of these will select the desired bank. 1FE0 = bank 0,
|
||||||
1FE1 = bank 1, etc.
|
1FE1 = bank 1, etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mEF : MapperBase
|
internal class mEF : MapperBase
|
||||||
{
|
{
|
||||||
private int _toggle;
|
private int _toggle;
|
||||||
|
@ -32,6 +31,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -47,16 +56,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_toggle << 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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -70,34 +69,28 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FE0) _toggle = 0;
|
_toggle = addr switch
|
||||||
if (addr == 0x1FE1) _toggle = 1;
|
{
|
||||||
if (addr == 0x1FE2) _toggle = 2;
|
0x1FE0 => 0,
|
||||||
if (addr == 0x1FE3) _toggle = 3;
|
0x1FE1 => 1,
|
||||||
if (addr == 0x1FE4) _toggle = 4;
|
0x1FE2 => 2,
|
||||||
if (addr == 0x1FE5) _toggle = 5;
|
0x1FE3 => 3,
|
||||||
if (addr == 0x1FE6) _toggle = 6;
|
0x1FE4 => 4,
|
||||||
if (addr == 0x1FE7) _toggle = 7;
|
0x1FE5 => 5,
|
||||||
if (addr == 0x1FE8) _toggle = 8;
|
0x1FE6 => 6,
|
||||||
if (addr == 0x1FE9) _toggle = 9;
|
0x1FE7 => 7,
|
||||||
if (addr == 0x1FEA) _toggle = 10;
|
0x1FE8 => 8,
|
||||||
if (addr == 0x1FEB) _toggle = 11;
|
0x1FE9 => 9,
|
||||||
if (addr == 0x1FEC) _toggle = 12;
|
0x1FEA => 10,
|
||||||
if (addr == 0x1FED) _toggle = 13;
|
0x1FEB => 11,
|
||||||
if (addr == 0x1FEE) _toggle = 14;
|
0x1FEC => 12,
|
||||||
if (addr == 0x1FEF) _toggle = 15;
|
0x1FED => 13,
|
||||||
|
0x1FEE => 14,
|
||||||
|
0x1FEF => 15,
|
||||||
|
_ => _toggle
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,29 +9,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mEFSC : MapperBase
|
internal class mEFSC : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _bank4K;
|
||||||
|
private byte[] _ram = new byte[128];
|
||||||
|
|
||||||
public mEFSC(Atari2600 core) : base(core)
|
public mEFSC(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _bank4k;
|
|
||||||
private byte[] _ram = new byte[128];
|
|
||||||
|
|
||||||
public override byte[] CartRam => _ram;
|
public override byte[] CartRam => _ram;
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("bank4k", ref _bank4k);
|
ser.Sync("bank4k", ref _bank4K);
|
||||||
ser.Sync("auxRam", ref _ram, false);
|
ser.Sync("auxRam", ref _ram, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_bank4k = 0;
|
_bank4K = 0;
|
||||||
_ram = new byte[128];
|
_ram = new byte[128];
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -52,20 +62,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
if (addr < 0x1100)
|
if (addr < 0x1100)
|
||||||
{
|
{
|
||||||
return _ram[(addr & 0x7F)];
|
return _ram[addr & 0x7F];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
|
@ -85,34 +85,28 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FE0) _bank4k = 0;
|
_bank4K = addr switch
|
||||||
if (addr == 0x1FE1) _bank4k = 1;
|
{
|
||||||
if (addr == 0x1FE2) _bank4k = 2;
|
0x1FE0 => 0,
|
||||||
if (addr == 0x1FE3) _bank4k = 3;
|
0x1FE1 => 1,
|
||||||
if (addr == 0x1FE4) _bank4k = 4;
|
0x1FE2 => 2,
|
||||||
if (addr == 0x1FE5) _bank4k = 5;
|
0x1FE3 => 3,
|
||||||
if (addr == 0x1FE6) _bank4k = 6;
|
0x1FE4 => 4,
|
||||||
if (addr == 0x1FE7) _bank4k = 7;
|
0x1FE5 => 5,
|
||||||
if (addr == 0x1FE8) _bank4k = 8;
|
0x1FE6 => 6,
|
||||||
if (addr == 0x1FE9) _bank4k = 9;
|
0x1FE7 => 7,
|
||||||
if (addr == 0x1FEA) _bank4k = 10;
|
0x1FE8 => 8,
|
||||||
if (addr == 0x1FEB) _bank4k = 11;
|
0x1FE9 => 9,
|
||||||
if (addr == 0x1FEC) _bank4k = 12;
|
0x1FEA => 10,
|
||||||
if (addr == 0x1FED) _bank4k = 13;
|
0x1FEB => 11,
|
||||||
if (addr == 0x1FEE) _bank4k = 14;
|
0x1FEC => 12,
|
||||||
if (addr == 0x1FEF) _bank4k = 15;
|
0x1FED => 13,
|
||||||
|
0x1FEE => 14,
|
||||||
|
0x1FEF => 15,
|
||||||
|
_ => _bank4K
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
F0 (Megaboy)
|
F0 (MegaBoy)
|
||||||
-----
|
-----
|
||||||
|
|
||||||
This was used on one game, "megaboy".. Some kind of educational cartridge. It supports
|
This was used on one game, "MegaBoy".. Some kind of educational cartridge. It supports
|
||||||
64K of ROM making it the biggest single production game made during the original run
|
64K of ROM making it the biggest single production game made during the original run
|
||||||
of the 2600.
|
of the 2600.
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
bank is numbered by means of one of the ROM locations, and the code simply keeps accessing
|
bank is numbered by means of one of the ROM locations, and the code simply keeps accessing
|
||||||
1FF0 until the bank it is looking for comes up.
|
1FF0 until the bank it is looking for comes up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mF0 : MapperBase
|
internal class mF0 : MapperBase
|
||||||
{
|
{
|
||||||
private int _bank;
|
private int _bank;
|
||||||
|
@ -38,6 +37,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -56,16 +65,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_bank << 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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (addr < 0x1000)
|
if (addr < 0x1000)
|
||||||
|
@ -78,16 +77,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 Increment()
|
private void Increment()
|
||||||
{
|
{
|
||||||
_bank++;
|
_bank++;
|
||||||
|
|
|
@ -9,7 +9,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
Again, this works like F8 and F6 except now there's 8 4K banks. Selection is performed
|
Again, this works like F8 and F6 except now there's 8 4K banks. Selection is performed
|
||||||
by accessing 1FF4 through 1FFB.
|
by accessing 1FF4 through 1FFB.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mF4 :MapperBase
|
internal class mF4 :MapperBase
|
||||||
{
|
{
|
||||||
private int _toggle;
|
private int _toggle;
|
||||||
|
@ -30,6 +29,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -45,16 +54,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_toggle << 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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -68,27 +67,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF4) _toggle = 0;
|
_toggle = addr switch
|
||||||
if (addr == 0x1FF5) _toggle = 1;
|
{
|
||||||
if (addr == 0x1FF6) _toggle = 2;
|
0x1FF4 => 0,
|
||||||
if (addr == 0x1FF7) _toggle = 3;
|
0x1FF5 => 1,
|
||||||
if (addr == 0x1FF8) _toggle = 4;
|
0x1FF6 => 2,
|
||||||
if (addr == 0x1FF9) _toggle = 5;
|
0x1FF7 => 3,
|
||||||
if (addr == 0x1FF9) _toggle = 5;
|
0x1FF8 => 4,
|
||||||
if (addr == 0x1FFA) _toggle = 6;
|
0x1FF9 => 5,
|
||||||
if (addr == 0x1FFB) _toggle = 7;
|
0x1FFA => 6,
|
||||||
|
0x1FFB => 7,
|
||||||
|
_ => _toggle
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mF4SC : MapperBase
|
internal class mF4SC : MapperBase
|
||||||
{
|
{
|
||||||
private int _bank4k;
|
private int _bank4K;
|
||||||
private byte[] _ram = new byte[128];
|
private byte[] _ram = new byte[128];
|
||||||
|
|
||||||
public mF4SC(Atari2600 core) : base(core)
|
public mF4SC(Atari2600 core) : base(core)
|
||||||
|
@ -20,17 +20,27 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("toggle", ref _bank4k);
|
ser.Sync("toggle", ref _bank4K);
|
||||||
ser.Sync("auxRam", ref _ram, false);
|
ser.Sync("auxRam", ref _ram, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_bank4k = 0;
|
_bank4K = 0;
|
||||||
_ram = new byte[128];
|
_ram = new byte[128];
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -45,26 +55,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
if (addr < 0x1080)
|
if (addr < 0x1080)
|
||||||
{
|
{
|
||||||
_ram[(addr & 0x7F)] = 0xFF; // Reading from the write port triggers an unwanted write of open bus
|
_ram[addr & 0x7F] = 0xFF; // Reading from the write port triggers an unwanted write of open bus
|
||||||
return 0xFF; // 0xFF is used for deterministic emulation, in reality it would be a random value based on pins being high or low
|
return 0xFF; // 0xFF is used for deterministic emulation, in reality it would be a random value based on pins being high or low
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0x1100)
|
if (addr < 0x1100)
|
||||||
{
|
{
|
||||||
return _ram[(addr & 0x7F)];
|
return _ram[addr & 0x7F];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
|
@ -84,27 +84,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF4) _bank4k = 0;
|
_bank4K = addr switch
|
||||||
if (addr == 0x1FF5) _bank4k = 1;
|
{
|
||||||
if (addr == 0x1FF6) _bank4k = 2;
|
0x1FF4 => 0,
|
||||||
if (addr == 0x1FF7) _bank4k = 3;
|
0x1FF5 => 1,
|
||||||
if (addr == 0x1FF8) _bank4k = 4;
|
0x1FF6 => 2,
|
||||||
if (addr == 0x1FF9) _bank4k = 5;
|
0x1FF7 => 3,
|
||||||
if (addr == 0x1FF9) _bank4k = 5;
|
0x1FF8 => 4,
|
||||||
if (addr == 0x1FFA) _bank4k = 6;
|
0x1FF9 => 5,
|
||||||
if (addr == 0x1FFB) _bank4k = 7;
|
0x1FFA => 6,
|
||||||
|
0x1FFB => 7,
|
||||||
|
_ => _bank4K
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,12 +13,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
internal class mF6 : MapperBase
|
internal class mF6 : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _toggle;
|
||||||
|
|
||||||
public mF6(Atari2600 core) : base(core)
|
public mF6(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _toggle;
|
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
|
@ -46,15 +46,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte ReadMemory(ushort addr)
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
{
|
|
||||||
return ReadMem(addr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override byte PeekMemory(ushort addr)
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
{
|
|
||||||
return ReadMem(addr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteMem(ushort addr, byte value, bool poke)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
|
@ -70,21 +64,21 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteMemory(ushort addr, byte value)
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
{
|
=> WriteMem(addr, value, false);
|
||||||
WriteMem(addr, value, poke: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PokeMemory(ushort addr, byte value)
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
{
|
=> WriteMem(addr, value, true);
|
||||||
WriteMem(addr, value, poke: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Address(ushort addr)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF6) _toggle = 0;
|
_toggle = addr switch
|
||||||
if (addr == 0x1FF7) _toggle = 1;
|
{
|
||||||
if (addr == 0x1FF8) _toggle = 2;
|
0x1FF6 => 0,
|
||||||
if (addr == 0x1FF9) _toggle = 3;
|
0x1FF7 => 1,
|
||||||
|
0x1FF8 => 2,
|
||||||
|
0x1FF9 => 3,
|
||||||
|
_ => _toggle
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,29 +8,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mF6SC : MapperBase
|
internal class mF6SC : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _bank4K;
|
||||||
|
private byte[] _ram = new byte[128];
|
||||||
|
|
||||||
public mF6SC(Atari2600 core) : base(core)
|
public mF6SC(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _bank4k;
|
|
||||||
private byte[] _ram = new byte[128];
|
|
||||||
|
|
||||||
public override byte[] CartRam => _ram;
|
public override byte[] CartRam => _ram;
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("bank_4k", ref _bank4k);
|
ser.Sync("bank_4k", ref _bank4K);
|
||||||
ser.Sync("auxRam", ref _ram, false);
|
ser.Sync("auxRam", ref _ram, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_bank4k = 0;
|
_bank4K = 0;
|
||||||
_ram = new byte[128];
|
_ram = new byte[128];
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -54,17 +64,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return _ram[(addr & 0x7F)];
|
return _ram[(addr & 0x7F)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
|
@ -84,22 +84,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF6) _bank4k = 0;
|
_bank4K = addr switch
|
||||||
if (addr == 0x1FF7) _bank4k = 1;
|
{
|
||||||
if (addr == 0x1FF8) _bank4k = 2;
|
0x1FF6 => 0,
|
||||||
if (addr == 0x1FF9) _bank4k = 3;
|
0x1FF7 => 1,
|
||||||
|
0x1FF8 => 2,
|
||||||
|
0x1FF9 => 3,
|
||||||
|
_ => _bank4K
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,6 +39,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -54,16 +64,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -77,16 +77,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF8)
|
if (addr == 0x1FF8)
|
||||||
|
|
|
@ -8,22 +8,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mF8SC : MapperBase
|
internal class mF8SC : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _bank4K;
|
||||||
|
private byte[] _ram = new byte[128];
|
||||||
|
|
||||||
public mF8SC(Atari2600 core) : base(core)
|
public mF8SC(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _bank_4K;
|
|
||||||
private byte[] _ram = new byte[128];
|
|
||||||
|
|
||||||
public override byte[] CartRam => _ram;
|
public override byte[] CartRam => _ram;
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_bank_4K = 0;
|
_bank4K = 0;
|
||||||
_ram = new byte[128];
|
_ram = new byte[128];
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void SyncState(Serializer ser)
|
||||||
|
{
|
||||||
|
base.SyncState(ser);
|
||||||
|
ser.Sync("bank_4k", ref _bank4K);
|
||||||
|
ser.Sync("auxRam", ref _ram, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -44,20 +61,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
if (addr < 0x1100)
|
if (addr < 0x1100)
|
||||||
{
|
{
|
||||||
return _ram[(addr & 0x7F)];
|
return _ram[addr & 0x7F];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_bank_4K << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
|
@ -77,32 +84,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
|
||||||
{
|
|
||||||
base.SyncState(ser);
|
|
||||||
ser.Sync("bank_4k", ref _bank_4K);
|
|
||||||
ser.Sync("auxRam", ref _ram, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Address(ushort addr)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF8)
|
if (addr == 0x1FF8)
|
||||||
{
|
{
|
||||||
_bank_4K = 0;
|
_bank4K = 0;
|
||||||
}
|
}
|
||||||
else if (addr == 0x1FF9)
|
else if (addr == 0x1FF9)
|
||||||
{
|
{
|
||||||
_bank_4K = 1;
|
_bank4K = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
Apparently some of Sega's games have banks that are physically flipped, so even though this game uses a common mapper, the initial bank that gets pointed to is incorrect.
|
Apparently some of Sega's games have banks that are physically flipped, so even though this game uses a common mapper, the initial bank that gets pointed to is incorrect.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mF8_sega : MapperBase
|
internal class mF8_sega : MapperBase
|
||||||
{
|
{
|
||||||
private int _bank4K = 1;
|
private int _bank4K = 1;
|
||||||
|
@ -29,6 +28,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -44,16 +53,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -67,16 +66,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF8)
|
if (addr == 0x1FF8)
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
accessing 1FF8, 1FF9, and 1FFA. There's also 256 bytes of RAM mapped into 1000-11FF.
|
accessing 1FF8, 1FF9, and 1FFA. There's also 256 bytes of RAM mapped into 1000-11FF.
|
||||||
The write port is at 1000-10FF, and the read port is 1100-11FF.
|
The write port is at 1000-10FF, and the read port is 1100-11FF.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mFA : MapperBase
|
internal class mFA : MapperBase
|
||||||
{
|
{
|
||||||
private int _toggle;
|
private int _toggle;
|
||||||
|
@ -37,6 +36,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -62,16 +71,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_toggle << 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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -89,21 +88,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF8) _toggle = 0;
|
_toggle = addr switch
|
||||||
if (addr == 0x1FF9) _toggle = 1;
|
{
|
||||||
if (addr == 0x1FFA) _toggle = 2;
|
0x1FF8 => 0,
|
||||||
|
0x1FF9 => 1,
|
||||||
|
0x1FFA => 2,
|
||||||
|
_ => _toggle
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/**
|
/*
|
||||||
This is an extended version of the CBS RAM Plus bankswitching scheme
|
This is an extended version of the CBS RAM Plus bankswitching scheme
|
||||||
supported by the Harmony cartridge.
|
supported by the Harmony cartridge.
|
||||||
|
|
||||||
|
@ -10,29 +10,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
*/
|
*/
|
||||||
internal class mFA2 : MapperBase
|
internal class mFA2 : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _bank4K;
|
||||||
|
private byte[] _ram = new byte[256];
|
||||||
|
|
||||||
public mFA2(Atari2600 core) : base(core)
|
public mFA2(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _bank4k;
|
|
||||||
private byte[] _ram = new byte[256];
|
|
||||||
|
|
||||||
public override byte[] CartRam => _ram;
|
public override byte[] CartRam => _ram;
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("bank4k", ref _bank4k);
|
ser.Sync("bank4k", ref _bank4K);
|
||||||
ser.Sync("auxRam", ref _ram, false);
|
ser.Sync("auxRam", ref _ram, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_bank4k = 0;
|
_bank4K = 0;
|
||||||
_ram = new byte[256];
|
_ram = new byte[256];
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -55,17 +65,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return _ram[addr & 0xFF];
|
return _ram[addr & 0xFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_bank4k << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
|
@ -85,28 +85,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x1FF5) _bank4k = 0;
|
_bank4K = addr switch
|
||||||
if (addr == 0x1FF6) _bank4k = 1;
|
|
||||||
if (addr == 0x1FF7) _bank4k = 2;
|
|
||||||
if (addr == 0x1FF8) _bank4k = 3;
|
|
||||||
if (addr == 0x1FF9) _bank4k = 4;
|
|
||||||
if (addr == 0x1FFA) _bank4k = 5;
|
|
||||||
if (addr == 0x1FFB && Core.Rom.Length == 28 * 1024) // Only available on 28k Roms
|
|
||||||
{
|
{
|
||||||
_bank4k = 6;
|
0x1FF5 => 0,
|
||||||
}
|
0x1FF6 => 1,
|
||||||
|
0x1FF7 => 2,
|
||||||
|
0x1FF8 => 3,
|
||||||
|
0x1FF9 => 4,
|
||||||
|
0x1FFA => 5,
|
||||||
|
0x1FFB when Core.Rom.Length == 28 * 1024 => 6,
|
||||||
|
_ => _bank4K
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
MC (Megacart)
|
MC (MegaCart)
|
||||||
-----
|
-----
|
||||||
|
|
||||||
This is the mapper for the "Chris Wilkson's Megacart".
|
This is the mapper for the "Chris Wilkson's MegaCart".
|
||||||
|
|
||||||
Only four addresses are used to bankswitch on this one.
|
Only four addresses are used to bankswitch on this one.
|
||||||
|
|
||||||
|
@ -33,11 +33,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
says:
|
says:
|
||||||
|
|
||||||
"
|
"
|
||||||
Megacart Specification, Rev1.1
|
MegaCart Specification, Rev1.1
|
||||||
(c) 1997 Chris Wilkson
|
(c) 1997 Chris Wilkson
|
||||||
cwilkson@mit.edu
|
cwilkson@mit.edu
|
||||||
|
|
||||||
Because the console's memory is randomized at powerup, there is no way to
|
Because the console's memory is randomized at power up, there is no way to
|
||||||
predict the data initially contained in the "hot addresses". Therefore,
|
predict the data initially contained in the "hot addresses". Therefore,
|
||||||
hardware will force slot 3 to always point to ROM block $FF immediately
|
hardware will force slot 3 to always point to ROM block $FF immediately
|
||||||
after any read or write to the RESET vector at $FFFC-$FFFD. Block $FF
|
after any read or write to the RESET vector at $FFFC-$FFFD. Block $FF
|
||||||
|
@ -58,7 +58,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
address bus. An actual system doesn't have that luxury, unfortunately, so it must
|
address bus. An actual system doesn't have that luxury, unfortunately, so it must
|
||||||
disregard accesses to 3C-3F instead.
|
disregard accesses to 3C-3F instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mMC : MapperBase
|
internal class mMC : MapperBase
|
||||||
{
|
{
|
||||||
public mMC(Atari2600 core) : base(core)
|
public mMC(Atari2600 core) : base(core)
|
||||||
|
|
|
@ -9,12 +9,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
internal class mSB : MapperBase
|
internal class mSB : MapperBase
|
||||||
{
|
{
|
||||||
private int _bank4K;
|
private int _bank4K;
|
||||||
private int myStartBank => (Core.Rom.Length >> 12) - 1;
|
|
||||||
|
|
||||||
public mSB(Atari2600 core) : base(core)
|
public mSB(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int MyStartBank => (Core.Rom.Length >> 12) - 1;
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
|
@ -27,6 +28,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr)
|
||||||
|
=> ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr)
|
||||||
|
=> ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -42,16 +55,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -65,22 +68,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
var temp = addr & (0x17FF + (Core.Rom.Length >> 12));
|
var temp = addr & (0x17FF + (Core.Rom.Length >> 12));
|
||||||
if ((temp & 0x1800) == 0x800)
|
if ((temp & 0x1800) == 0x800)
|
||||||
{
|
{
|
||||||
_bank4K = temp & myStartBank;
|
_bank4K = temp & MyStartBank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
Accessing 0220 will select the first bank, and accessing 0240 will select the second.
|
Accessing 0220 will select the first bank, and accessing 0240 will select the second.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class mUA : MapperBase
|
internal class mUA : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _toggle;
|
||||||
|
|
||||||
public mUA(Atari2600 core) : base(core)
|
public mUA(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _toggle;
|
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
|
@ -32,6 +31,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -47,16 +56,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_toggle << 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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
{
|
{
|
||||||
if (!poke)
|
if (!poke)
|
||||||
|
@ -70,16 +69,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if (addr == 0x0220)
|
if (addr == 0x0220)
|
||||||
|
|
|
@ -35,24 +35,34 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
|
|
||||||
internal class mX07 : MapperBase
|
internal class mX07 : MapperBase
|
||||||
{
|
{
|
||||||
|
private int _romBank2K;
|
||||||
|
|
||||||
public mX07(Atari2600 core) : base(core)
|
public mX07(Atari2600 core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _rombank2K;
|
|
||||||
|
|
||||||
public override void SyncState(Serializer ser)
|
public override void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
base.SyncState(ser);
|
base.SyncState(ser);
|
||||||
ser.Sync("rombank_2k", ref _rombank2K);
|
ser.Sync("rombank_2k", ref _romBank2K);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HardReset()
|
public override void HardReset()
|
||||||
{
|
{
|
||||||
_rombank2K = 0;
|
_romBank2K = 0;
|
||||||
base.HardReset();
|
base.HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||||
|
|
||||||
|
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||||
|
|
||||||
|
public override void WriteMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, false);
|
||||||
|
|
||||||
|
public override void PokeMemory(ushort addr, byte value)
|
||||||
|
=> WriteMem(addr, value, true);
|
||||||
|
|
||||||
private byte ReadMem(ushort addr, bool peek)
|
private byte ReadMem(ushort addr, bool peek)
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
|
@ -65,17 +75,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
return base.ReadMemory(addr);
|
return base.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Core.Rom[(_rombank2K << 12) + (addr & 0xFFF)];
|
return Core.Rom[(_romBank2K << 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)
|
private void WriteMem(ushort addr, byte value, bool poke)
|
||||||
|
@ -91,16 +91,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private void Address(ushort addr)
|
||||||
{
|
{
|
||||||
if ((addr & 0x180F) == 0x080D)
|
if ((addr & 0x180F) == 0x080D)
|
||||||
|
@ -109,16 +99,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||||
}
|
}
|
||||||
else if ((addr & 0x1880) == 0)
|
else if ((addr & 0x1880) == 0)
|
||||||
{
|
{
|
||||||
if ((_rombank2K & 0xE) == 0xE)
|
if ((_romBank2K & 0xE) == 0xE)
|
||||||
{
|
{
|
||||||
Bank(((addr & 0x40) >> 6) | (_rombank2K & 0xE));
|
Bank(((addr & 0x40) >> 6) | (_romBank2K & 0xE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Bank(int bank)
|
private void Bank(int bank)
|
||||||
{
|
{
|
||||||
_rombank2K = bank & 0x0F;
|
_romBank2K = bank & 0x0F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,9 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=aaaaaaa/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=aaaaaaa/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=aaaaaaaa/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=aaaaaaaa/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=AARRGGBB/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=AARRGGBB/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ABCDEFGH/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=accum/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=accum/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Activision/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=addr/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=addr/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=adelikat/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=adelikat/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ADPCM/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ADPCM/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -198,6 +200,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Arkanoid/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Arkanoid/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=assy/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=assy/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=assys/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=assys/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Atariage/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=atten/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=atten/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Attrib/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Attrib/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Attribs/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Attribs/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -214,6 +217,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=backbuffer/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=backbuffer/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=backcolor/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=backcolor/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bandai/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bandai/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitch/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitched/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitched/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitching/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bankswitching/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bezier/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bezier/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -252,7 +256,9 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coleco/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coleco/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Colecovision/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Colecovision/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=colesced/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=colesced/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Commavid/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Compositing/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Compositing/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Compumate/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Conout/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Conout/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coroutine/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coroutine/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cpus/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cpus/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -289,14 +295,18 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dontfire/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dontfire/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dupped/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dupped/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ejin/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ejin/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=emucore/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Endian/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Endian/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=endianess/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=endianess/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=endrift/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=endrift/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=EPRO/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Faaaaaaa/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Faaaaaaa/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fairchild/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fairchild/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Famicom/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Famicom/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Famtasia/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Famtasia/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=FCEU/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=FCEU/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFC/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFF/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFE/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFE/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFFFF/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFFFF/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ffmpeg/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ffmpeg/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -317,6 +327,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frameskip/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frameskip/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frameskipping/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frameskipping/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=framestart/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=framestart/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frogger/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frugalizer/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frugalizer/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frugalizers/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frugalizers/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=gambatte/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=gambatte/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -351,10 +362,12 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Justifier/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Justifier/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=keepalives/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=keepalives/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kernings/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kernings/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kevtris/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=KEYMENU/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=KEYMENU/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kopi/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kopi/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=leadout/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=leadout/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Letterboxing/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Letterboxing/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=LFSR/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Libretro/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Libretro/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Libsnes/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Libsnes/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=libspeexdsp/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=libspeexdsp/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -373,6 +386,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=luaf/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=luaf/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=luases/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=luases/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lua_0027s/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lua_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Magicard/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mainform/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mainform/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mainmemory/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mainmemory/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mame/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mame/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -421,6 +435,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Palletize/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Palletize/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=passthru/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=passthru/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pathing/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pathing/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Payson/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCFX/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCFX/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCSX/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=PCSX/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=performant/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=performant/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -459,6 +474,8 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=riffmaster/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=riffmaster/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=RLCA/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=RLCA/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Roms/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Roms/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ROM_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Salomon/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=samp/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=samp/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=samplerate/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=samplerate/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Saturnus/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Saturnus/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -470,6 +487,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=scanlines/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=scanlines/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Screenshot/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Screenshot/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Screensize/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Screensize/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=scrom/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=shaders/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=shaders/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=speccy/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=speccy/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Speedruns/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Speedruns/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -500,6 +518,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tastudio/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tastudio/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tasvideos/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tasvideos/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tempfile/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tempfile/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Threedeep/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tkey/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tkey/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=toolform/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=toolform/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trollers/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trollers/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
@ -549,6 +568,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=WRAM/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=WRAM/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=WSWAN/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=WSWAN/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=XBOX/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=XBOX/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xilinx/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=xinput/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=xinput/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xjin/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xjin/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xploder/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xploder/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Reference in New Issue