Atari 2600 - some progress on the AR mapper (Super charger), but still doesn't work

This commit is contained in:
adelikat 2014-04-19 16:28:03 +00:00
parent 09daa3f939
commit dba0d25a5c
2 changed files with 240 additions and 83 deletions

View File

@ -18,16 +18,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public M6532 M6532 { get; private set; }
public int LastAddress;
public int NumberOfDistinctAddresses;
public int DistinctAccessCount;
public byte BaseReadMemory(ushort addr)
{
if (addr != LastAddress)
{
NumberOfDistinctAddresses++;
LastAddress = addr;
}
addr = (ushort)(addr & 0x1FFF);
if ((addr & 0x1080) == 0)
{
@ -62,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
if (addr != LastAddress)
{
NumberOfDistinctAddresses++;
DistinctAccessCount++;
LastAddress = addr;
}
@ -83,6 +77,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public byte ReadMemory(ushort addr)
{
if (addr != LastAddress)
{
DistinctAccessCount++;
LastAddress = addr;
}
_mapper.Bit13 = addr.Bit(13);
var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF));
CoreComm.MemoryCallbackSystem.CallRead(addr);
@ -99,6 +99,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public void WriteMemory(ushort addr, byte value)
{
if (addr != LastAddress)
{
DistinctAccessCount++;
LastAddress = addr;
}
_mapper.WriteMemory((ushort)(addr & 0x1FFF), value);
CoreComm.MemoryCallbackSystem.CallWrite(addr);

View File

@ -1,4 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using BizHawk.Common;
/**
This is the cartridge class for Arcadia (aka Starpath) Supercharger
@ -36,28 +40,50 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// TODO: var names, savestates, hard reset, dispose, cart ram
public mAR(Atari2600 core)
{
// TODO: clean this stuff up
/*****************************************/
int size = core.Rom.Length;
mySize = core.Rom.Length < 8448 ? 8448 : core.Rom.Length; //8448 or Rom size, whichever is bigger
myNumberOfLoadImages = (byte)(mySize / 8448);
// TODO: why are we making a redundant copy?
myLoadedImages = new ByteBuffer(mySize);
for (int i = 0; i < size; i++)
{
myLoadedImages[i] = core.Rom[i];
}
if (size < 8448)
{
for (int i = size; i < mySize; i++)
{
myLoadedImages[i] = DefaultHeader[i];
}
}
/*****************************************/
Core = core;
InitializeRom();
BankConfiguration(0);
}
private int _bank2k;
//private ByteBuffer _ram = new ByteBuffer(6144);
ByteBuffer myImage = new ByteBuffer(8192);
private IntBuffer _imageOffsets = new IntBuffer(2);
private bool _writePending = false;
int myNumberOfDistinctAccesses = 0;
bool myWriteEnabled = false;
byte myDataHoldRegister;
// Indicates if the ROM's power is on or off
private bool myPower;
// Indicates when the power was last turned on
int myPowerRomCycle;
private ByteBuffer myImage = new ByteBuffer(8192);
private IntBuffer myImageOffsets = new IntBuffer(2);
private bool myWritePending = false;
private int myNumberOfDistinctAccesses = 0;
private bool myWriteEnabled = false;
private byte myDataHoldRegister;
private byte myNumberOfLoadImages;
private ByteBuffer myLoadedImages;
private byte[] myHeader = new byte[256];
private bool myPower; // Indicates if the ROM's power is on or off
private int myPowerRomCycle; // Indicates when the power was last turned on
private int mySize;
private ulong _elapsedCycles;
#region SuperCharger Data
private readonly byte[] DummyRomCode = {
0xa5, 0xfa, 0x85, 0x80, 0x4c, 0x18, 0xf8, 0xff,
0xff, 0xff, 0x78, 0xd8, 0xa0, 0x00, 0xa2, 0x00,
@ -133,6 +159,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
};
#endregion
public override void ClockCpu()
{
_elapsedCycles++;
@ -141,68 +169,62 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private byte ReadMem(ushort addr, bool peek)
{
if (!peek)
if (addr < 0x1000) { if (peek) { return base.PeekMemory(addr); } else { return base.ReadMemory(addr); } }
/*---------------------------*/
if (addr == 0x1850 && myImageOffsets[1] == (3 << 11))
{
Address(addr);
LoadIntoRam(Core.MemoryDomains["System Bus"].PeekByte(0x80)); // Get load that's being accessed (BIOS places load number at 0x80) // TODO: a better way to do this
return myImage[(addr & 0x7FF) + myImageOffsets[1]];
}
if (addr < 0x1000)
if (myWritePending && // Cancel any pending write if more than 5 distinct accesses have occurred // TODO: Modify to handle when the distinct counter wraps around...
(Core.DistinctAccessCount > myNumberOfDistinctAccesses + 5))
{
return base.ReadMemory(addr);
myWritePending = false;
}
if (addr == 0x1850 && _imageOffsets[1] == (3 << 11))
{
/// TODO: weird stuff goes here
///
return myImage[(addr & 0x7FF) + _imageOffsets[1]];
}
/*---------------------------*/
// Cancel any pending write if more than 5 distinct accesses have occurred
// TODO: Modify to handle when the distinct counter wraps around...
if (_writePending &&
(Core.NumberOfDistinctAddresses > myNumberOfDistinctAccesses + 5))
{
_writePending = false;
}
if (!((addr & 0x0F00) > 0) && (!myWriteEnabled || !_writePending))
if (!((addr & 0x0F00) > 0) && (!myWriteEnabled || !myWritePending))
{
myDataHoldRegister = (byte)addr;
myNumberOfDistinctAccesses = Core.NumberOfDistinctAddresses;
_writePending = true;
addrThatChangedDataHoldRegister = addr;
myNumberOfDistinctAccesses = Core.DistinctAccessCount;
myWritePending = true;
}
// Is the bank configuration hotspot being accessed?
else if (addr == 0x1FF8)
else if ((addr & 0x1FFF) == 0x1FF8) // Is the bank configuration hotspot being accessed?
{
// Yes, so handle the bank configuration
_writePending = false;
myWritePending = false;
BankConfiguration(myDataHoldRegister);
}
else if (myWriteEnabled &&
_writePending &&
Core.NumberOfDistinctAddresses == (myNumberOfDistinctAccesses + 5))
else if (myWriteEnabled && myWritePending &&
Core.DistinctAccessCount == (myNumberOfDistinctAccesses + 5))
{
if ((addr & 0x800) == 0)
{
// TODO
var test1 = addr & 0x07FF;
myImage[(addr & 0x07FF) + myImage[0]] = myDataHoldRegister;
}
else if (_imageOffsets[1] != (3 << 11)) // Don't poke Rom
else if (myImageOffsets[1] != (3 << 11)) // Don't poke Rom
{
// TODO
var test2 = addr & 0x07FF;
myImage[(addr & 0x07FF) + myImageOffsets[1]] = myDataHoldRegister;
}
_writePending = false;
myWritePending = false;
}
var tempVal = (addr & 0x07FF) + _imageOffsets[((addr & 0x800) > 0) ? 1 : 0];
return myImage[(addr & 0x07FF) + _imageOffsets[((addr & 0x800) > 0) ? 1 : 0]];
/*---------------------------*/
return myImage[(addr & 0x07FF) + myImageOffsets[((addr & 0x800) > 0) ? 1 : 0]];
}
// Temp hacks
bool written = false;
ushort addrThatChangedDataHoldRegister;
public override byte ReadMemory(ushort addr)
{
@ -214,15 +236,54 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
return ReadMem(addr, true);
}
private void Address(ushort addr)
public override void WriteMemory(ushort addr, byte value)
{
if (addr == 0x1FF8)
if (myWritePending && (Core.DistinctAccessCount > myNumberOfDistinctAccesses + 5))
{
_bank2k = 0;
int xxxx = 0;
}
else if (addr == 0x1FF9)
if (addr < 0x1000)
{
_bank2k = 1;
base.WriteMemory(addr, value);
return;
}
if (myWritePending && (Core.DistinctAccessCount > myNumberOfDistinctAccesses + 5))
{
myWritePending = false;
}
// Is the data hold register being set?
if (!((addr & 0x0F00) > 0) && (!myWriteEnabled || !myWritePending))
{
myDataHoldRegister = (byte)addr;
myNumberOfDistinctAccesses = Core.DistinctAccessCount;
myWritePending = true;
}
// Is the bank configuration hotspot being accessed?
else if ((addr & 0x1FFF) == 0x1FF8)
{
// Yes, so handle bank configuration
myWritePending = false;
BankConfiguration(myDataHoldRegister);
}
// Handle poke if writing enabled
else if (myWriteEnabled && myWritePending &&
(Core.DistinctAccessCount == (myNumberOfDistinctAccesses + 5)))
{
if ((addr & 0x0800) == 0)
{
myImage[(addr & 0x07FF) + myImageOffsets[0]] = myDataHoldRegister;
}
else if (myImageOffsets[1] != (3 << 11)) // Can't poke to ROM
{
myImage[(addr & 0x07FF) + myImageOffsets[1]] = myDataHoldRegister;
}
myWritePending = false;
}
}
@ -282,48 +343,138 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
// 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.
_bank2k = configuration & 0x1F; // remember for the bank() method
//_bank2k = configuration & 0x1F; // remember for the bank() method
myPower = !((configuration & 0x01) > 0);
if (myPower)
{
myPowerRomCycle = (int)_elapsedCycles;
}
myWriteEnabled = (configuration & 0x02) > 0;
switch ((configuration >> 2) & 0x07)
{
case 0x00:
_imageOffsets[0] = 2 << 11;
_imageOffsets[1] = 3 << 11;
myImageOffsets[0] = 2 << 11;
myImageOffsets[1] = 3 << 11;
break;
case 0x01:
_imageOffsets[0] = 0;
_imageOffsets[1] = 3 << 11;
myImageOffsets[0] = 0;
myImageOffsets[1] = 3 << 11;
break;
case 0x02:
_imageOffsets[0] = 2 << 11;
_imageOffsets[1] = 0;
myImageOffsets[0] = 2 << 11;
myImageOffsets[1] = 0;
break;
case 0x03:
_imageOffsets[0] = 0;
_imageOffsets[1] = 2 << 11;
myImageOffsets[0] = 0;
myImageOffsets[1] = 2 << 11;
break;
case 0x04:
_imageOffsets[0] = 2 << 11;
_imageOffsets[1] = 3 << 11;
myImageOffsets[0] = 2 << 11;
myImageOffsets[1] = 3 << 11;
break;
case 0x05:
_imageOffsets[0] = 1 << 11;
_imageOffsets[1] = 3 << 11;
myImageOffsets[0] = 1 << 11;
myImageOffsets[1] = 3 << 11;
break;
case 0x06:
_imageOffsets[0] = 2 << 11;
_imageOffsets[1] = 1 << 11;
myImageOffsets[0] = 2 << 11;
myImageOffsets[1] = 1 << 11;
break;
case 0x07:
_imageOffsets[0] = 1 << 11;
_imageOffsets[1] = 2 << 11;
myImageOffsets[0] = 1 << 11;
myImageOffsets[1] = 2 << 11;
break;
}
}
private void LoadIntoRam(byte load)
{
ushort image;
for (image = 0; image < myNumberOfLoadImages; image++)
{
if (myLoadedImages[(image * 8448) + 8192 + 5] == load)
{
for (int i = 0; i < 256; i++)
{
myHeader[i] = myLoadedImages[(image * 8448) + 8192 + i];
}
if (Checksum(myHeader.Take(8).ToArray()) != 0x55)
{
Console.WriteLine("WARNING: The Supercharger header checksum is invalid...");
}
// TODO: verify the load's header
// Load all of the pages from the load
bool invalidPageChecksumSeen = false;
for (int j = 0; j < myHeader[3]; j++)
{
int bank = myHeader[16 + j] & 0x03;
int page = (myHeader[16 + j] >> 2) & 0x07;
var src = myLoadedImages.Arr.Skip((image * 8448) + (j * 256)).Take(256).ToArray();
byte sum = (byte)(Checksum(src) + myHeader[16 + j] + myHeader[64 + j]);
if (!invalidPageChecksumSeen && (sum != 0x55))
{
Console.WriteLine("WARNING: Some Supercharger page checksums are invalid...");
invalidPageChecksumSeen = true;
}
if (bank < 3)
{
for (int k = 0; k < src.Length; k++)
{
myImage[(bank * 2048) + (page * 256) + k] = src[k];
}
}
}
// TODO: is this the correct Write to do?
base.WriteMemory(0xFE, myHeader[0]);
base.WriteMemory(0xFF, myHeader[1]);
base.WriteMemory(0x80, myHeader[2]);
}
}
}
private void WriteToFile() // TODO: Delete me
{
// A hack for now, because this byte is different than in stella
if (myImage[6426] != 85)
{
myImage[6425] = 85;
}
if (!written)
{
var sb = new StringBuilder();
for (int i = 0; i < myImage.Len; i++)
{
sb.Append(((int)(myImage[i])).ToString()).AppendLine();
}
File.WriteAllText("C:\\Repos\\bizlog.log", sb.ToString());
written = true;
}
}
private byte Checksum(byte[] s)
{
byte sum = 0;
for (int i = 0; i < s.Count(); i++)
{
sum += s[i];
}
return sum;
}
}
}