cleanup Atari2600 mapper code
This commit is contained in:
parent
a61230e4ab
commit
8f860adf51
|
@ -2,9 +2,6 @@
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||
{
|
||||
/*
|
||||
Mapper used for multi-cart 2K games
|
||||
*/
|
||||
internal class Multicart2K : MapperBase
|
||||
{
|
||||
private int _gameTotal;
|
||||
|
@ -28,15 +25,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
IncrementGame();
|
||||
}
|
||||
|
||||
private void IncrementGame()
|
||||
{
|
||||
_currentGame++;
|
||||
if (_currentGame >= _gameTotal)
|
||||
{
|
||||
_currentGame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
|
@ -49,5 +37,14 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
/*
|
||||
Mapper used for multi-cart 4K games
|
||||
*/
|
||||
internal class Multicart4K : MapperBase
|
||||
{
|
||||
private int _gameTotal;
|
||||
|
@ -28,15 +25,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
IncrementGame();
|
||||
}
|
||||
|
||||
private void IncrementGame()
|
||||
{
|
||||
_currentGame++;
|
||||
if (_currentGame >= _gameTotal)
|
||||
{
|
||||
_currentGame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
|
@ -49,5 +37,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
/*
|
||||
Mapper used for multi-cart 8K games
|
||||
*/
|
||||
internal class Multicart8K : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
|
@ -33,6 +30,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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()
|
||||
{
|
||||
_currentGame++;
|
||||
|
@ -57,16 +64,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF8)
|
||||
|
|
|
@ -15,20 +15,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
0 1xxx xBxx xxxx
|
||||
|
||||
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).
|
||||
|
||||
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.
|
||||
*/
|
||||
internal class m0840 : MapperBase
|
||||
internal class m0840 : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
|
||||
public m0840(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _bank4K;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
|
@ -41,6 +41,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -56,16 +66,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
|
||||
private void WriteMem(ushort addr, byte value, bool poke)
|
||||
{
|
||||
if (!poke)
|
||||
|
@ -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)
|
||||
{
|
||||
switch (addr & 0x1840)
|
||||
_bank4K = (addr & 0x1840) switch
|
||||
{
|
||||
case 0x0800:
|
||||
_bank4K = 0;
|
||||
break;
|
||||
case 0x0840:
|
||||
_bank4K = 1;
|
||||
break;
|
||||
}
|
||||
0x0800 => 0,
|
||||
0x0840 => 1,
|
||||
_ => _bank4K
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
1400-17FF is the write port.
|
||||
*/
|
||||
|
@ -26,8 +26,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
}
|
||||
|
||||
private int _lowbank2K;
|
||||
private int _rambank1K;
|
||||
private int _lowBank2K;
|
||||
private int _ramBank1K;
|
||||
private bool _hasRam;
|
||||
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)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("lowbank_2k", ref _lowbank2K);
|
||||
ser.Sync("rambank_1k", ref _rambank1K);
|
||||
ser.Sync("lowbank_2k", ref _lowBank2K);
|
||||
ser.Sync("rambank_1k", ref _ramBank1K);
|
||||
ser.Sync("cart_ram", ref _ram, false);
|
||||
ser.Sync("hasRam", ref _hasRam);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_lowbank2K = 0;
|
||||
_rambank1K = 0;
|
||||
_lowBank2K = 0;
|
||||
_ramBank1K = 0;
|
||||
_hasRam = false;
|
||||
_ram = new byte[256 * 1024];
|
||||
base.HardReset();
|
||||
|
@ -64,27 +64,30 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
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
|
||||
{
|
||||
return Core.Rom[(Core.Rom.Length - 0x800) + (addr & 0x07FF)];
|
||||
return Core.Rom[Core.Rom.Length - 0x800 + (addr & 0x07FF)];
|
||||
}
|
||||
|
||||
return base.ReadMemory(addr);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMemory(addr);
|
||||
}
|
||||
public override byte PeekMemory(ushort addr) => 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)
|
||||
{
|
||||
|
@ -93,18 +96,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
if (addr == 0x003E)
|
||||
{
|
||||
_hasRam = true;
|
||||
_rambank1K = value;
|
||||
_ramBank1K = value;
|
||||
}
|
||||
else if (addr == 0x003F)
|
||||
{
|
||||
_hasRam = false;
|
||||
if (value << 11 < Core.Rom.Length)
|
||||
{
|
||||
_lowbank2K = value;
|
||||
_lowBank2K = value;
|
||||
}
|
||||
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
|
||||
{
|
||||
_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,11 +3,11 @@
|
|||
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
|
||||
there's two 2K pages in the 4K of address space. The upper bank is fixed to the last 2K
|
||||
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
|
||||
of the ROM.
|
||||
|
||||
The first 2K is selectable by writing to any location between 0000 and 003F. Yes, this
|
||||
|
@ -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
|
||||
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.
|
||||
*/
|
||||
|
||||
internal class m3F : MapperBase
|
||||
{
|
||||
private int _lowBank2K;
|
||||
|
||||
public m3F(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _lowbank2K;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("lowbank_2k", ref _lowbank2K);
|
||||
ser.Sync("lowbank_2k", ref _lowBank2K);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_lowbank2K = 0;
|
||||
_lowBank2K = 0;
|
||||
base.HardReset();
|
||||
}
|
||||
|
||||
|
@ -50,21 +49,24 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
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
|
||||
{
|
||||
return Core.Rom[(Core.Rom.Length - 2048) + (addr & 0x07FF)];
|
||||
return Core.Rom[Core.Rom.Length - 2048 + (addr & 0x07FF)];
|
||||
}
|
||||
|
||||
return base.ReadMemory(addr);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMemory(addr);
|
||||
}
|
||||
public override byte PeekMemory(ushort addr) => 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)
|
||||
{
|
||||
|
@ -74,26 +76,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
if ((value << 11) < Core.Rom.Length)
|
||||
{
|
||||
_lowbank2K = value;
|
||||
_lowBank2K = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lowbank2K = value & (Core.Rom.Length >> 11);
|
||||
_lowBank2K = value & (Core.Rom.Length >> 11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
/* From Kebtris docs
|
||||
/* From Kevtris docs
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
and M2 (clock) to be able to properly do most of the things it's doing.
|
||||
*/
|
||||
|
||||
/* 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.
|
||||
|
||||
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
|
||||
{
|
||||
public m4A50(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private byte[] _ram = new byte[32768];
|
||||
|
||||
private byte _lastData = 0xFF;
|
||||
|
@ -61,6 +57,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
private int _sliceMiddle;
|
||||
|
||||
private byte[] _romImage;
|
||||
|
||||
public m4A50(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private byte[] RomImage
|
||||
{
|
||||
get
|
||||
|
@ -129,6 +130,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
byte val = 0;
|
||||
|
@ -142,27 +153,31 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
else if (addr < 0x1800) // 2K region from 0x1000 - 0x17ff
|
||||
{
|
||||
val = _isRomLow ? RomImage[(addr & 0x7ff) + _sliceLow]
|
||||
: _ram[(addr & 0x7ff) + _sliceLow];
|
||||
val = _isRomLow
|
||||
? RomImage[(addr & 0x7ff) + _sliceLow]
|
||||
: _ram[(addr & 0x7ff) + _sliceLow];
|
||||
}
|
||||
else if (addr < 0x1E00) // 1.5K region from 0x1800 - 0x1dff
|
||||
{
|
||||
val = _isRomMiddle ? RomImage[(addr & 0x7ff) + _sliceMiddle + 0x10000]
|
||||
: _ram[(addr & 0x7ff) + _sliceMiddle];
|
||||
val = _isRomMiddle
|
||||
? RomImage[(addr & 0x7ff) + _sliceMiddle + 0x10000]
|
||||
: _ram[(addr & 0x7ff) + _sliceMiddle];
|
||||
}
|
||||
else if (addr < 0x1F00) // 256B region from 0x1e00 - 0x1eff
|
||||
{
|
||||
val = _isRomHigh ? RomImage[(addr & 0xff) + _sliceHigh + 0x10000]
|
||||
: _ram[(addr & 0xff) + _sliceHigh];
|
||||
val = _isRomHigh
|
||||
? RomImage[(addr & 0xff) + _sliceHigh + 0x10000]
|
||||
: _ram[(addr & 0xff) + _sliceHigh];
|
||||
}
|
||||
else if (addr < 0x2000) // 256B region from 0x1f00 - 0x1fff
|
||||
{
|
||||
val = RomImage[(addr & 0xff) + (RomImage.Length - 256)];
|
||||
if ((_lastData & 0xe0) == 0x60 && (_lastAddress >= 0x1000 ||
|
||||
_lastAddress < 0x200) && !peek)
|
||||
if ((_lastData & 0xe0) == 0x60 && (_lastAddress >= 0x1000
|
||||
|| _lastAddress < 0x200) && !peek)
|
||||
{
|
||||
_sliceHigh = (_sliceHigh & 0xf0ff) | ((addr & 0x8) << 8) |
|
||||
((addr & 0x70) << 4);
|
||||
_sliceHigh = (_sliceHigh & 0xf0ff)
|
||||
| ((addr & 0x8) << 8)
|
||||
| ((addr & 0x70) << 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,16 +190,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
if (((_lastData & 0xe0) == 0x60) &&
|
||||
(_lastAddress >= 0x1000 || (_lastAddress < 0x200)) && !poke)
|
||||
if ((_lastData & 0xe0) == 0x60
|
||||
&& (_lastAddress >= 0x1000 || _lastAddress < 0x200))
|
||||
{
|
||||
_sliceHigh = (_sliceHigh & 0xf0ff) | ((addr & 0x8) << 8) |
|
||||
((addr & 0x70) << 4);
|
||||
_sliceHigh = (_sliceHigh & 0xf0ff)
|
||||
| ((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)
|
||||
{
|
||||
if (((_lastData & 0xe0) == 0x60) && // Switch lower/middle/upper bank
|
||||
((_lastAddress >= 0x1000) || (_lastAddress < 0x200)))
|
||||
if ((_lastData & 0xe0) == 0x60 // Switch lower/middle/upper bank
|
||||
&& (_lastAddress >= 0x1000 || _lastAddress < 0x200))
|
||||
{
|
||||
if ((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff
|
||||
{
|
||||
|
@ -280,19 +276,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
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
|
||||
{
|
||||
_sliceLow = _sliceLow ^ 0x1000;
|
||||
_sliceLow ^= 0x1000;
|
||||
}
|
||||
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
|
||||
{
|
||||
_sliceMiddle = _sliceMiddle ^ 0x1000;
|
||||
_sliceMiddle ^= 0x1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,87 +1,38 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
/*
|
||||
This is the cartridge class for Arcadia (aka Starpath) Supercharger
|
||||
games. Christopher Salomon provided most of the technical details
|
||||
used in creating this class. A good description of the Supercharger
|
||||
is provided in the Cuttle Cart's manual.
|
||||
|
||||
The Supercharger has four 2K banks. There are three banks of RAM
|
||||
and one bank of ROM. All 6K of the RAM can be read and written.
|
||||
|
||||
D7-D5 of this byte: Write Pulse Delay (n/a for emulator)
|
||||
|
||||
D4-D0: RAM/ROM configuration:
|
||||
$F000-F7FF $F800-FFFF Address range that banks map into
|
||||
000wp 2 ROM
|
||||
001wp 0 ROM
|
||||
010wp 2 0 as used in Commie Mutants and many others
|
||||
011wp 0 2 as used in Suicide Mission
|
||||
100wp 2 ROM
|
||||
101wp 1 ROM
|
||||
110wp 2 1 as used in Killer Satellites
|
||||
111wp 1 2 as we use for 2k/4k ROM cloning
|
||||
|
||||
w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
|
||||
to happen. 0 = disabled, and the cart acts like ROM.)
|
||||
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.
|
||||
*/
|
||||
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
|
||||
used in creating this class. A good description of the Supercharger
|
||||
is provided in the Cuttle Cart's manual.
|
||||
|
||||
The Supercharger has four 2K banks. There are three banks of RAM
|
||||
and one bank of ROM. All 6K of the RAM can be read and written.
|
||||
|
||||
D7-D5 of this byte: Write Pulse Delay (n/a for emulator)
|
||||
|
||||
D4-D0: RAM/ROM configuration:
|
||||
$F000-F7FF $F800-FFFF Address range that banks map into
|
||||
000wp 2 ROM
|
||||
001wp 0 ROM
|
||||
010wp 2 0 as used in Commie Mutants and many others
|
||||
011wp 0 2 as used in Suicide Mission
|
||||
100wp 2 ROM
|
||||
101wp 1 ROM
|
||||
110wp 2 1 as used in Killer Satellites
|
||||
111wp 1 2 as we use for 2k/4k ROM cloning
|
||||
|
||||
w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
|
||||
to happen. 0 = disabled, and the cart acts like ROM.)
|
||||
p = ROM Power (0 = enabled, 1 = off.) Only power the ROM if you're
|
||||
wanting to access the ROM for multi-loads. Otherwise set to 1.
|
||||
*/
|
||||
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
|
||||
|
||||
private readonly byte[] _dummyRomCode =
|
||||
|
@ -163,6 +114,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
#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 void HardReset()
|
||||
|
@ -215,6 +185,46 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_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)
|
||||
{
|
||||
if (addr < 0x1000)
|
||||
|
@ -274,16 +284,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
/* 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
|
||||
// to happen. 0 = disabled, and the cart acts like ROM.)
|
||||
// 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
|
||||
_powerIndicator = !((configuration & 0x01) > 0);
|
||||
|
@ -468,7 +458,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
int bank = _header[16 + j] & 0x03;
|
||||
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]);
|
||||
|
||||
if (!invalidPageChecksumSeen && (sum != 0x55))
|
||||
|
@ -498,7 +492,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
byte sum = 0;
|
||||
|
||||
for (int i = 0; i < s.Count(); i++)
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
sum += s[i];
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ using BizHawk.Common.NumberExtensions;
|
|||
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.
|
||||
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)
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -104,8 +104,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
|
||||
/*
|
||||
* Spectravideo Compumate Add-on Stella Documentation
|
||||
Cartridge class used for SpectraVideo CompuMate bankswitched games.
|
||||
* SpectraVideo Compumate Add-on Stella Documentation
|
||||
Cartridge class used for SpectraVideo Compumate bankswitched games.
|
||||
|
||||
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
|
||||
|
@ -129,12 +129,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
D1 = bank select high bit
|
||||
D0 = bank select low bit
|
||||
|
||||
INPT0: D7 = FUNC key input (0 on startup / 1 = key pressed)
|
||||
INPT1: D7 = always HIGH input (pulled high thru 20K resistor)
|
||||
INPT2: D7 = always HIGH input (pulled high thru 20K resistor)
|
||||
INPT3: D7 = SHIFT key input (0 on startup / 1 = key pressed)
|
||||
INPT4: D7 = keyboard row 0 input (0 = key pressed)
|
||||
INPT5: D7 = keyboard row 2 input (0 = key pressed)
|
||||
INPUT0: D7 = FUNC key input (0 on startup / 1 = key pressed)
|
||||
INPUT1: D7 = always HIGH input (pulled high thru 20K resistor)
|
||||
INPUT2: D7 = always HIGH input (pulled high thru 20K resistor)
|
||||
INPUT3: D7 = SHIFT key input (0 on startup / 1 = key pressed)
|
||||
INPUT4: D7 = keyboard row 0 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. 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
|
||||
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
|
||||
|
||||
|
@ -218,11 +218,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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
|
||||
// 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
|
||||
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");
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
public override byte PeekMemory(ushort addr) => ReadMemory(addr);
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return 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 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?
|
||||
|
||||
if ((addr & 0x0200) == 0) // If the RS bit is not set, this is a ram write
|
||||
|
@ -321,7 +318,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
|
||||
if (addr == 0x280 && !poke) // Stella uses only 280
|
||||
////if (isPortA && !poke)
|
||||
////if (isPortA && !poke)
|
||||
{
|
||||
var bit5 = value.Bit(5);
|
||||
var bit4 = value.Bit(4);
|
||||
|
@ -361,15 +358,5 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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
|
||||
{
|
||||
private byte[] _ram = new byte[1024];
|
||||
|
||||
public mCV(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private byte[] _ram = new byte[1024];
|
||||
|
||||
public override byte[] CartRam => _ram;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
|
@ -51,16 +51,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
if (addr >= 0x1800 && addr < 0x2000)
|
||||
{
|
||||
return Core.Rom[(addr & 0x7FF)];
|
||||
return Core.Rom[addr & 0x7FF];
|
||||
}
|
||||
|
||||
return base.ReadMemory(addr);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMemory(addr);
|
||||
}
|
||||
public override byte PeekMemory(ushort addr) => 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)
|
||||
{
|
||||
|
@ -70,18 +73,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
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").
|
||||
|
||||
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
|
||||
passthrough. Apparently, Activision thought that people wouldn't like this, or
|
||||
pass-through cartridge into your 2600, then plug the game cartridge into the
|
||||
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
|
||||
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.
|
||||
|
||||
OK, enough background. Now onto the meat:
|
||||
|
@ -139,7 +139,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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
|
||||
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
|
||||
so. The value read at 1004-1007 is the instantanious value generated by the fetchers and
|
||||
mixing hardware.
|
||||
|
||||
*/
|
||||
internal class mDPC : MapperBase
|
||||
{
|
||||
public mDPC(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
// Table for computing the input bit of the random number generator's
|
||||
// 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 };
|
||||
|
@ -245,6 +240,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
private float _fractionalClocks; // Fractional DPC music OSC clocks unused during the last update
|
||||
|
||||
private byte[] _dspData;
|
||||
|
||||
public mDPC(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
public byte[] DspData => _dspData ??= Core.Rom.Skip(8192).Take(2048).ToArray();
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
|
@ -285,6 +285,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_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)
|
||||
{
|
||||
if (addr < 0x1000)
|
||||
|
@ -385,16 +395,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
|
||||
private void WriteMem(ushort addr, byte value, bool poke)
|
||||
{
|
||||
if (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)
|
||||
{
|
||||
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
|
||||
// bit for the shift register
|
||||
var bit = _randomInputBits[((_currentRandomVal >> 3) & 0x07) |
|
||||
((_currentRandomVal & 0x80) > 0 ? 0x08 : 0x00)];
|
||||
var bit = _randomInputBits[((_currentRandomVal >> 3) & 0x07)
|
||||
| ((_currentRandomVal & 0x80) > 0 ? 0x08 : 0x00)];
|
||||
|
||||
// Update the shift register
|
||||
_currentRandomVal = (byte)((_currentRandomVal << 1) | bit);
|
||||
|
|
|
@ -11,11 +11,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
internal class mDPCPlus : MapperBase
|
||||
{
|
||||
// TODO: PokeMem, and everything else
|
||||
public mDPCPlus(Atari2600 core) : base(core)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// Table for computing the input bit of the random number generator's
|
||||
// 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 int[] _counters = new int[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 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
|
||||
// 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 };
|
||||
// TODO: PokeMem, and everything else
|
||||
public mDPCPlus(Atari2600 core) : base(core)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public byte[] DspData => _dspData ??= Core.Rom.Skip(8192).Take(2048).ToArray();
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
|
@ -73,6 +74,83 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_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)
|
||||
{
|
||||
if (addr < 0x1000)
|
||||
|
@ -173,89 +251,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (addr == 0x1FF6)
|
||||
|
|
|
@ -22,17 +22,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
Example Games:
|
||||
Frogger II - Threedeep! (1983) (Parker Bros)
|
||||
*/
|
||||
|
||||
internal class mE0 : MapperBase
|
||||
{
|
||||
public mE0(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _toggle1;
|
||||
private int _toggle2;
|
||||
private int _toggle3;
|
||||
|
||||
public mE0(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
|
@ -49,6 +48,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
|
||||
private void WriteMem(ushort addr, byte value, bool poke)
|
||||
{
|
||||
if (!poke)
|
||||
|
@ -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)
|
||||
{
|
||||
switch (addr)
|
||||
|
|
|
@ -21,17 +21,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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
|
||||
banks making a total of 1K accessable here.
|
||||
Only 256 bytes of RAM is accessible at time, but there are four different 256 byte
|
||||
banks making a total of 1K accessible here.
|
||||
|
||||
Accessing 1FE8 through 1FEB select which 256 byte bank shows up.
|
||||
*/
|
||||
|
||||
internal class mE7 : MapperBase
|
||||
{
|
||||
private const int RamBank1Offset = 1024;
|
||||
private int _rombank1K;
|
||||
private int _rambank1Toggle;
|
||||
private int _romBank1K;
|
||||
private int _ramBank1Toggle;
|
||||
private byte[] _ram = new byte[2048];
|
||||
|
||||
private bool _enableRam0;
|
||||
|
@ -43,16 +42,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("toggle", ref _rombank1K);
|
||||
ser.Sync("toggle", ref _romBank1K);
|
||||
ser.Sync("ram", ref _ram, false);
|
||||
ser.Sync("EnableRam0", ref _enableRam0);
|
||||
ser.Sync("rambank1_toggle", ref _rambank1Toggle);
|
||||
ser.Sync("rambank1_toggle", ref _ramBank1Toggle);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_rombank1K = 0;
|
||||
_rambank1Toggle = 0;
|
||||
_romBank1K = 0;
|
||||
_ramBank1Toggle = 0;
|
||||
_ram = new byte[2048];
|
||||
_enableRam0 = false;
|
||||
base.HardReset();
|
||||
|
@ -60,6 +59,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
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)
|
||||
{
|
||||
if (addr < 0x1000)
|
||||
|
@ -84,17 +87,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
return _ram[RamBank1Offset + (_rambank1Toggle * 0x100) + (addr & 0xFF)];
|
||||
return _ram[RamBank1Offset + (_ramBank1Toggle * 0x100) + (addr & 0xFF)];
|
||||
}
|
||||
|
||||
if (addr < 0x2000)
|
||||
|
@ -108,15 +111,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return base.ReadMemory(addr);
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
=> WriteMem(addr, value, false);
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -135,61 +134,51 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
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)
|
||||
{
|
||||
_enableRam0 = false;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1FE0:
|
||||
_rombank1K = 0;
|
||||
_romBank1K = 0;
|
||||
break;
|
||||
case 0x1FE1:
|
||||
_rombank1K = 1;
|
||||
_romBank1K = 1;
|
||||
break;
|
||||
case 0x1FE2:
|
||||
_rombank1K = 2;
|
||||
_romBank1K = 2;
|
||||
break;
|
||||
case 0x1FE3:
|
||||
_rombank1K = 3;
|
||||
_romBank1K = 3;
|
||||
break;
|
||||
case 0x1FE4:
|
||||
_rombank1K = 4;
|
||||
_romBank1K = 4;
|
||||
break;
|
||||
case 0x1FE5:
|
||||
_rombank1K = 5;
|
||||
_romBank1K = 5;
|
||||
break;
|
||||
case 0x1FE6:
|
||||
_rombank1K = 6;
|
||||
_romBank1K = 6;
|
||||
break;
|
||||
case 0x1FE7:
|
||||
_rombank1K = 7;
|
||||
_romBank1K = 7;
|
||||
_enableRam0 = true;
|
||||
break;
|
||||
case 0x1FE8:
|
||||
_rambank1Toggle = 0;
|
||||
_ramBank1Toggle = 0;
|
||||
break;
|
||||
case 0x1FE9:
|
||||
_rambank1Toggle = 1;
|
||||
_ramBank1Toggle = 1;
|
||||
break;
|
||||
case 0x1FEA:
|
||||
_rambank1Toggle = 2;
|
||||
_ramBank1Toggle = 2;
|
||||
break;
|
||||
case 0x1FEB:
|
||||
_rambank1Toggle = 3;
|
||||
_ramBank1Toggle = 3;
|
||||
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,
|
||||
1FE1 = bank 1, etc.
|
||||
*/
|
||||
|
||||
internal class mEF : MapperBase
|
||||
{
|
||||
private int _toggle;
|
||||
|
@ -32,6 +31,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -47,16 +56,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FE0) _toggle = 0;
|
||||
if (addr == 0x1FE1) _toggle = 1;
|
||||
if (addr == 0x1FE2) _toggle = 2;
|
||||
if (addr == 0x1FE3) _toggle = 3;
|
||||
if (addr == 0x1FE4) _toggle = 4;
|
||||
if (addr == 0x1FE5) _toggle = 5;
|
||||
if (addr == 0x1FE6) _toggle = 6;
|
||||
if (addr == 0x1FE7) _toggle = 7;
|
||||
if (addr == 0x1FE8) _toggle = 8;
|
||||
if (addr == 0x1FE9) _toggle = 9;
|
||||
if (addr == 0x1FEA) _toggle = 10;
|
||||
if (addr == 0x1FEB) _toggle = 11;
|
||||
if (addr == 0x1FEC) _toggle = 12;
|
||||
if (addr == 0x1FED) _toggle = 13;
|
||||
if (addr == 0x1FEE) _toggle = 14;
|
||||
if (addr == 0x1FEF) _toggle = 15;
|
||||
_toggle = addr switch
|
||||
{
|
||||
0x1FE0 => 0,
|
||||
0x1FE1 => 1,
|
||||
0x1FE2 => 2,
|
||||
0x1FE3 => 3,
|
||||
0x1FE4 => 4,
|
||||
0x1FE5 => 5,
|
||||
0x1FE6 => 6,
|
||||
0x1FE7 => 7,
|
||||
0x1FE8 => 8,
|
||||
0x1FE9 => 9,
|
||||
0x1FEA => 10,
|
||||
0x1FEB => 11,
|
||||
0x1FEC => 12,
|
||||
0x1FED => 13,
|
||||
0x1FEE => 14,
|
||||
0x1FEF => 15,
|
||||
_ => _toggle
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,29 +9,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
internal class mEFSC : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public mEFSC(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _bank4k;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public override byte[] CartRam => _ram;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("bank4k", ref _bank4k);
|
||||
ser.Sync("bank4k", ref _bank4K);
|
||||
ser.Sync("auxRam", ref _ram, false);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_bank4k = 0;
|
||||
_bank4K = 0;
|
||||
_ram = new byte[128];
|
||||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -52,20 +62,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
if (addr < 0x1100)
|
||||
{
|
||||
return _ram[(addr & 0x7F)];
|
||||
return _ram[addr & 0x7F];
|
||||
}
|
||||
|
||||
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);
|
||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FE0) _bank4k = 0;
|
||||
if (addr == 0x1FE1) _bank4k = 1;
|
||||
if (addr == 0x1FE2) _bank4k = 2;
|
||||
if (addr == 0x1FE3) _bank4k = 3;
|
||||
if (addr == 0x1FE4) _bank4k = 4;
|
||||
if (addr == 0x1FE5) _bank4k = 5;
|
||||
if (addr == 0x1FE6) _bank4k = 6;
|
||||
if (addr == 0x1FE7) _bank4k = 7;
|
||||
if (addr == 0x1FE8) _bank4k = 8;
|
||||
if (addr == 0x1FE9) _bank4k = 9;
|
||||
if (addr == 0x1FEA) _bank4k = 10;
|
||||
if (addr == 0x1FEB) _bank4k = 11;
|
||||
if (addr == 0x1FEC) _bank4k = 12;
|
||||
if (addr == 0x1FED) _bank4k = 13;
|
||||
if (addr == 0x1FEE) _bank4k = 14;
|
||||
if (addr == 0x1FEF) _bank4k = 15;
|
||||
_bank4K = addr switch
|
||||
{
|
||||
0x1FE0 => 0,
|
||||
0x1FE1 => 1,
|
||||
0x1FE2 => 2,
|
||||
0x1FE3 => 3,
|
||||
0x1FE4 => 4,
|
||||
0x1FE5 => 5,
|
||||
0x1FE6 => 6,
|
||||
0x1FE7 => 7,
|
||||
0x1FE8 => 8,
|
||||
0x1FE9 => 9,
|
||||
0x1FEA => 10,
|
||||
0x1FEB => 11,
|
||||
0x1FEC => 12,
|
||||
0x1FED => 13,
|
||||
0x1FEE => 14,
|
||||
0x1FEF => 15,
|
||||
_ => _bank4K
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
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
|
||||
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
|
||||
1FF0 until the bank it is looking for comes up.
|
||||
*/
|
||||
|
||||
internal class mF0 : MapperBase
|
||||
{
|
||||
private int _bank;
|
||||
|
@ -38,6 +37,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -56,16 +65,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
_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
|
||||
by accessing 1FF4 through 1FFB.
|
||||
*/
|
||||
|
||||
internal class mF4 :MapperBase
|
||||
{
|
||||
private int _toggle;
|
||||
|
@ -30,6 +29,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -45,16 +54,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF4) _toggle = 0;
|
||||
if (addr == 0x1FF5) _toggle = 1;
|
||||
if (addr == 0x1FF6) _toggle = 2;
|
||||
if (addr == 0x1FF7) _toggle = 3;
|
||||
if (addr == 0x1FF8) _toggle = 4;
|
||||
if (addr == 0x1FF9) _toggle = 5;
|
||||
if (addr == 0x1FF9) _toggle = 5;
|
||||
if (addr == 0x1FFA) _toggle = 6;
|
||||
if (addr == 0x1FFB) _toggle = 7;
|
||||
_toggle = addr switch
|
||||
{
|
||||
0x1FF4 => 0,
|
||||
0x1FF5 => 1,
|
||||
0x1FF6 => 2,
|
||||
0x1FF7 => 3,
|
||||
0x1FF8 => 4,
|
||||
0x1FF9 => 5,
|
||||
0x1FFA => 6,
|
||||
0x1FFB => 7,
|
||||
_ => _toggle
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
internal class mF4SC : MapperBase
|
||||
{
|
||||
private int _bank4k;
|
||||
private int _bank4K;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public mF4SC(Atari2600 core) : base(core)
|
||||
|
@ -20,17 +20,27 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("toggle", ref _bank4k);
|
||||
ser.Sync("toggle", ref _bank4K);
|
||||
ser.Sync("auxRam", ref _ram, false);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_bank4k = 0;
|
||||
_bank4K = 0;
|
||||
_ram = new byte[128];
|
||||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -45,26 +55,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
if (addr < 0x1100)
|
||||
{
|
||||
return _ram[(addr & 0x7F)];
|
||||
return _ram[addr & 0x7F];
|
||||
}
|
||||
|
||||
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);
|
||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF4) _bank4k = 0;
|
||||
if (addr == 0x1FF5) _bank4k = 1;
|
||||
if (addr == 0x1FF6) _bank4k = 2;
|
||||
if (addr == 0x1FF7) _bank4k = 3;
|
||||
if (addr == 0x1FF8) _bank4k = 4;
|
||||
if (addr == 0x1FF9) _bank4k = 5;
|
||||
if (addr == 0x1FF9) _bank4k = 5;
|
||||
if (addr == 0x1FFA) _bank4k = 6;
|
||||
if (addr == 0x1FFB) _bank4k = 7;
|
||||
_bank4K = addr switch
|
||||
{
|
||||
0x1FF4 => 0,
|
||||
0x1FF5 => 1,
|
||||
0x1FF6 => 2,
|
||||
0x1FF7 => 3,
|
||||
0x1FF8 => 4,
|
||||
0x1FF9 => 5,
|
||||
0x1FFA => 6,
|
||||
0x1FFB => 7,
|
||||
_ => _bank4K
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,12 +13,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
internal class mF6 : MapperBase
|
||||
{
|
||||
private int _toggle;
|
||||
|
||||
public mF6(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _toggle;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
|
@ -46,15 +46,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return Core.Rom[(_toggle << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
public override byte ReadMemory(ushort addr) => ReadMem(addr, false);
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
public override byte PeekMemory(ushort addr) => ReadMem(addr, true);
|
||||
|
||||
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)
|
||||
{
|
||||
WriteMem(addr, value, poke: false);
|
||||
}
|
||||
=> WriteMem(addr, value, false);
|
||||
|
||||
public override void PokeMemory(ushort addr, byte value)
|
||||
{
|
||||
WriteMem(addr, value, poke: true);
|
||||
}
|
||||
=> WriteMem(addr, value, true);
|
||||
|
||||
private void Address(ushort addr)
|
||||
{
|
||||
if (addr == 0x1FF6) _toggle = 0;
|
||||
if (addr == 0x1FF7) _toggle = 1;
|
||||
if (addr == 0x1FF8) _toggle = 2;
|
||||
if (addr == 0x1FF9) _toggle = 3;
|
||||
_toggle = addr switch
|
||||
{
|
||||
0x1FF6 => 0,
|
||||
0x1FF7 => 1,
|
||||
0x1FF8 => 2,
|
||||
0x1FF9 => 3,
|
||||
_ => _toggle
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,29 +8,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
internal class mF6SC : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public mF6SC(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _bank4k;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public override byte[] CartRam => _ram;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("bank_4k", ref _bank4k);
|
||||
ser.Sync("bank_4k", ref _bank4K);
|
||||
ser.Sync("auxRam", ref _ram, false);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_bank4k = 0;
|
||||
_bank4K = 0;
|
||||
_ram = new byte[128];
|
||||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -54,17 +64,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return _ram[(addr & 0x7F)];
|
||||
}
|
||||
|
||||
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);
|
||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF6) _bank4k = 0;
|
||||
if (addr == 0x1FF7) _bank4k = 1;
|
||||
if (addr == 0x1FF8) _bank4k = 2;
|
||||
if (addr == 0x1FF9) _bank4k = 3;
|
||||
_bank4K = addr switch
|
||||
{
|
||||
0x1FF6 => 0,
|
||||
0x1FF7 => 1,
|
||||
0x1FF8 => 2,
|
||||
0x1FF9 => 3,
|
||||
_ => _bank4K
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -54,16 +64,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
|
||||
private void WriteMem(ushort addr, byte value, bool poke)
|
||||
{
|
||||
if (!poke)
|
||||
|
@ -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)
|
||||
{
|
||||
if (addr == 0x1FF8)
|
||||
|
|
|
@ -8,22 +8,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
internal class mF8SC : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public mF8SC(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _bank_4K;
|
||||
private byte[] _ram = new byte[128];
|
||||
|
||||
public override byte[] CartRam => _ram;
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_bank_4K = 0;
|
||||
_bank4K = 0;
|
||||
_ram = new byte[128];
|
||||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -44,20 +61,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
if (addr < 0x1100)
|
||||
{
|
||||
return _ram[(addr & 0x7F)];
|
||||
return _ram[addr & 0x7F];
|
||||
}
|
||||
|
||||
return Core.Rom[(_bank_4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF8)
|
||||
{
|
||||
_bank_4K = 0;
|
||||
_bank4K = 0;
|
||||
}
|
||||
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.
|
||||
*/
|
||||
|
||||
internal class mF8_sega : MapperBase
|
||||
{
|
||||
private int _bank4K = 1;
|
||||
|
@ -29,6 +28,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -44,16 +53,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
|
||||
private void WriteMem(ushort addr, byte value, bool poke)
|
||||
{
|
||||
if (!poke)
|
||||
|
@ -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)
|
||||
{
|
||||
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.
|
||||
The write port is at 1000-10FF, and the read port is 1100-11FF.
|
||||
*/
|
||||
|
||||
internal class mFA : MapperBase
|
||||
{
|
||||
private int _toggle;
|
||||
|
@ -37,6 +36,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -62,16 +71,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF8) _toggle = 0;
|
||||
if (addr == 0x1FF9) _toggle = 1;
|
||||
if (addr == 0x1FFA) _toggle = 2;
|
||||
_toggle = addr switch
|
||||
{
|
||||
0x1FF8 => 0,
|
||||
0x1FF9 => 1,
|
||||
0x1FFA => 2,
|
||||
_ => _toggle
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||
{
|
||||
/**
|
||||
/*
|
||||
This is an extended version of the CBS RAM Plus bankswitching scheme
|
||||
supported by the Harmony cartridge.
|
||||
|
||||
|
@ -10,29 +10,39 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
*/
|
||||
internal class mFA2 : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
private byte[] _ram = new byte[256];
|
||||
|
||||
public mFA2(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _bank4k;
|
||||
private byte[] _ram = new byte[256];
|
||||
|
||||
public override byte[] CartRam => _ram;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("bank4k", ref _bank4k);
|
||||
ser.Sync("bank4k", ref _bank4K);
|
||||
ser.Sync("auxRam", ref _ram, false);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_bank4k = 0;
|
||||
_bank4K = 0;
|
||||
_ram = new byte[256];
|
||||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -55,17 +65,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return _ram[addr & 0xFF];
|
||||
}
|
||||
|
||||
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);
|
||||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (addr == 0x1FF5) _bank4k = 0;
|
||||
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 = addr switch
|
||||
{
|
||||
_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
|
||||
{
|
||||
/*
|
||||
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.
|
||||
|
||||
|
@ -33,11 +33,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
says:
|
||||
|
||||
"
|
||||
Megacart Specification, Rev1.1
|
||||
MegaCart Specification, Rev1.1
|
||||
(c) 1997 Chris Wilkson
|
||||
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,
|
||||
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
|
||||
|
@ -58,7 +58,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
address bus. An actual system doesn't have that luxury, unfortunately, so it must
|
||||
disregard accesses to 3C-3F instead.
|
||||
*/
|
||||
|
||||
internal class mMC : MapperBase
|
||||
{
|
||||
public mMC(Atari2600 core) : base(core)
|
||||
|
|
|
@ -9,12 +9,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
internal class mSB : MapperBase
|
||||
{
|
||||
private int _bank4K;
|
||||
private int myStartBank => (Core.Rom.Length >> 12) - 1;
|
||||
|
||||
public mSB(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int MyStartBank => (Core.Rom.Length >> 12) - 1;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
|
@ -27,6 +28,18 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -42,16 +55,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return Core.Rom[(_bank4K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, false);
|
||||
}
|
||||
|
||||
public override byte PeekMemory(ushort addr)
|
||||
{
|
||||
return ReadMem(addr, true);
|
||||
}
|
||||
|
||||
private void WriteMem(ushort addr, byte value, bool poke)
|
||||
{
|
||||
if (!poke)
|
||||
|
@ -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)
|
||||
{
|
||||
var temp = addr & (0x17FF + (Core.Rom.Length >> 12));
|
||||
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.
|
||||
*/
|
||||
|
||||
internal class mUA : MapperBase
|
||||
{
|
||||
private int _toggle;
|
||||
|
||||
public mUA(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _toggle;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
|
@ -32,6 +31,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -47,16 +56,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (addr == 0x0220)
|
||||
|
|
|
@ -35,24 +35,34 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
internal class mX07 : MapperBase
|
||||
{
|
||||
private int _romBank2K;
|
||||
|
||||
public mX07(Atari2600 core) : base(core)
|
||||
{
|
||||
}
|
||||
|
||||
private int _rombank2K;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("rombank_2k", ref _rombank2K);
|
||||
ser.Sync("rombank_2k", ref _romBank2K);
|
||||
}
|
||||
|
||||
public override void HardReset()
|
||||
{
|
||||
_rombank2K = 0;
|
||||
_romBank2K = 0;
|
||||
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)
|
||||
{
|
||||
if (!peek)
|
||||
|
@ -65,17 +75,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
return base.ReadMemory(addr);
|
||||
}
|
||||
|
||||
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);
|
||||
return Core.Rom[(_romBank2K << 12) + (addr & 0xFFF)];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if ((addr & 0x180F) == 0x080D)
|
||||
|
@ -109,16 +99,16 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
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)
|
||||
{
|
||||
_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/=aaaaaaaa/@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/=Activision/@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/=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/=assy/@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/=Attrib/@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/=backcolor/@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/=bankswitching/@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/=Colecovision/@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/=Compumate/@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/=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/=Dupped/@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/=endianess/@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/=Fairchild/@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/=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/=FFFFFFFF/@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/=Frameskipping/@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/=Frugalizers/@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/=keepalives/@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/=Kopi/@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/=LFSR/@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/=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/=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/=Magicard/@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/=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/=passthru/@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/=PCSX/@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/=RLCA/@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/=samplerate/@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/=Screenshot/@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/=speccy/@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/=tasvideos/@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/=toolform/@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/=WSWAN/@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/=Xjin/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xploder/@EntryIndexedValue">True</s:Boolean>
|
||||
|
|
Loading…
Reference in New Issue