Merge pull request #638 from alyosha-tas/master

Initial PR for Compumate
This commit is contained in:
alyosha-tas 2016-05-31 09:27:14 -04:00
commit f56589ade1
4 changed files with 161 additions and 30 deletions

View File

@ -323,6 +323,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
Rom.HashSHA1(),
Rom.HashMD5(),
_mapper.GetType());
// as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves.
// some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532
// executing a reset sequence at power on, but it's needed so let's hard code it for now
Cpu.S = 0xFD;
}
private bool _pal;
@ -345,7 +351,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
M6532 = new M6532(this);
Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC
}
// as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves.
// some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532
// executing a reset sequence at power on, but it's needed so let's hard code it for now
Cpu.S = 0xFD;
}
public void FrameAdvance(bool render, bool rendersound)
{

View File

@ -9,6 +9,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public byte DDRa = 0x00;
public byte DDRb = 0x00;
public byte outputA = 0x00;
public TimerData Timer;
@ -35,9 +36,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
// Read Output reg A
// Combine readings from player 1 and player 2
var temp = (byte)(_core.ReadControls1(peek) & 0xF0 | ((_core.ReadControls2(peek) >> 4) & 0x0F));
temp = (byte)(temp & ~DDRa);
return temp;
// actually depends on setting in SWCHCNTA (aka DDRa)
var temp = (byte)(_core.ReadControls1(peek) & 0xF0 | ((_core.ReadControls2(peek) >> 4) & 0x0F));
temp = (byte)(temp & ~DDRa);
temp = (byte)(temp + (outputA & DDRa));
return temp;
}
if (registerAddr == 0x01)
@ -150,7 +155,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
if (registerAddr == 0x00)
{
// Write Output reg A
// Write Output reg A
outputA = value;
}
else if (registerAddr == 0x01)
{
@ -159,7 +165,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
else if (registerAddr == 0x02)
{
// Write Output reg B
// Write Output reg B
// But is read only
}
else if (registerAddr == 0x03)
{
@ -175,7 +182,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.BeginSection("M6532");
ser.Sync("ddra", ref DDRa);
ser.Sync("ddrb", ref DDRb);
Timer.SyncState(ser);
ser.Sync("OutputA", ref outputA);
Timer.SyncState(ser);
ser.EndSection();
}

View File

@ -1,5 +1,6 @@
using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
using System;
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
@ -183,6 +184,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private bool _disableRam = true;
private bool _writeMode = false;
private int _column = 0;
public bool _func_key = false;
public bool _shift_key = false;
public override void Dispose()
{
@ -197,8 +200,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_disableRam = true;
_writeMode = true;
_column = 0;
_func_key = false;
_shift_key = false;
base.HardReset();
}
public override void SyncState(Serializer ser)
@ -209,16 +216,62 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("column", ref _column);
ser.Sync("disableRam", ref _disableRam);
ser.Sync("writeMode", ref _writeMode);
ser.Sync("FuncKey", ref _func_key);
ser.Sync("ShiftKey", ref _shift_key);
base.SyncState(ser);
base.SyncState(ser);
}
public override byte ReadMemory(ushort addr)
private byte ReadMem(ushort addr, bool peek)
{
if (addr < 0x1000)
// 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
// so instead we bypass these cases here
if ((addr & 0x000F) == 8 && (addr & 0x1080)==0 && addr<1000)
{
// if func key pressed
if (_func_key == true)
{
return 0x80;
}
else
{
return 0;
}
}
else if ((addr & 0x000F) == 9 && (addr & 0x1080) == 0 && addr < 1000)
{
return 0x80;
}
else if ((addr & 0x000F) == 0xA && (addr & 0x1080) == 0 && addr < 1000)
{
return 0x80;
}
else if ((addr & 0x000F) == 0xB && (addr & 0x1080) == 0 && addr < 1000)
{
// if shift key pressed
if (_shift_key == true)
{
return 0x80;
}
else
{
return 0;
}
}
else if (addr < 0x1000)
{
return base.ReadMemory(addr);
}
return base.ReadMemory(addr);
}
// Lower 2K is always the first 2K of the ROM bank
// Upper 2K is also Rom if ram is enabled
@ -233,16 +286,22 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
return _ram[addr & 0x7FF];
}
// Attempting to read while in write mode
throw new NotTestedException();
// Attempting to read while in write mode
throw new NotTestedException();
}
public override byte PeekMemory(ushort addr)
public override byte ReadMemory(ushort addr)
{
return ReadMem(addr, false);
}
public override byte PeekMemory(ushort addr)
{
return ReadMemory(addr);
return ReadMem(addr,true);
}
public override void WriteMemory(ushort addr, byte value)
private void WriteMem(ushort addr, byte value, bool poke)
{
//Mimicking the 6532 logic for accesing port A, for testing
var isPortA = false;
@ -267,7 +326,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
if (registerAddr == 0x00)
{
if (addr != 640)
if (addr != 640 && addr>=0x280) // register addresses are only above 0x280
{
// Write Output reg A
isPortA = true;
@ -277,8 +336,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
}
//if (addr == 0x280) //Stella uses only 280
if (isPortA)
if (addr == 0x280 && !poke) //Stella uses only 280
//if (isPortA && !poke)
{
var bit5 = value.Bit(5);
var bit4 = value.Bit(4);
@ -292,9 +351,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_bank4K = value & 0x03;
//D6 = 1 -> increase key column (0 to 9)
//D5 = 1 -> reset key column to 0 (if D4 = 0)
if (bit5 && !bit4)
//D6 = 1 -> increase key column (0 to 9)
//D5 = 1 -> reset key column to 0 (if D4 = 0)
if (bit5 && !bit4)
{
_column = 0;
}
@ -312,8 +371,20 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_ram[addr & 0x7FF] = value;
}
}
base.WriteMemory(addr, value);
if (addr<0x1000) {
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);
}
}
}

View File

@ -1121,16 +1121,57 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
mask = 0x3f;
}
// inputs 0-3 are measured by a charging capacitor, these inputs are used with the paddles and the keyboard
// Changing the hard coded value will change the paddle position. The range seems to be roughly 0-56000 according to values from stella
// 6105 roughly centers the paddle in Breakout
if (maskedAddr == 0x08) // INPT0
{
// Changing the hard coded value will change the paddle position. The range seems to be roughly 0-56000 according to values from stella
// 6105 roughly centers the paddle in Breakout
if (_capCharging && _core.Cpu.TotalExecutedCycles - _capChargeStart >= 6105)
{
coll=0x80;
}
} else
{
coll = 0x00;
}
mask = 0x7f;
}
coll=0x00;
if (maskedAddr == 0x09) // INPT1
{
if (_capCharging && _core.Cpu.TotalExecutedCycles - _capChargeStart >= 6105)
{
coll = 0x80;
}
else
{
coll = 0x00;
}
mask = 0x7f;
}
if (maskedAddr == 0x0A) // INPT2
{
if (_capCharging && _core.Cpu.TotalExecutedCycles - _capChargeStart >= 6105)
{
coll = 0x80;
}
else
{
coll = 0x00;
}
mask = 0x7f;
}
if (maskedAddr == 0x0B) // INPT3
{
if (_capCharging && _core.Cpu.TotalExecutedCycles - _capChargeStart >= 6105)
{
coll = 0x80;
}
else
{
coll = 0x00;
}
mask = 0x7f;
}