Switched over to using the 6507 to allow for some modifications to the CPU

MOS6507: now executes instructions on the last cycle. This corrects a syncing issue with the TIA
TIA: added ball data, partially implemented HMOVE, implemented VBLANK
This commit is contained in:
pjgat09 2012-03-11 03:22:44 +00:00
parent bc2e7995cc
commit 84a11eacdf
5 changed files with 129 additions and 22 deletions

View File

@ -38,7 +38,9 @@ namespace BizHawk.Emulation.CPUs.M6507
if(debug) Console.WriteLine(State());
ushort this_pc = PC;
byte opcode = ReadMemory(PC++);
byte opcode = ReadMemory(PC);
if (PendingCycles < CycTable[opcode]) { break; }
PC++;
switch (opcode)
{
case 0x00: // BRK

View File

@ -237,5 +237,27 @@ namespace BizHawk.Emulation.CPUs.M6507
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
};
// Cycles count for the MOS6507 opcodes, borrowed from FCEUX
// TODO: Confirm these are correct
public static byte[] CycTable = new byte[]
{
/*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
/*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
/*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
/*0x30*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
/*0x40*/ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,
/*0x50*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
/*0x60*/ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,
/*0x70*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
/*0x80*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
/*0x90*/ 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,
/*0xA0*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
/*0xB0*/ 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,
/*0xC0*/ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
/*0xD0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
/*0xE0*/ 2,6,3,8,3,3,5,5,2,2,2,2,4,4,6,6,
/*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
};
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using BizHawk.Emulation.CPUs.M6502;
using BizHawk.Emulation.CPUs.M6507;
using BizHawk.Emulation.Consoles.Atari;
namespace BizHawk
@ -9,7 +9,7 @@ namespace BizHawk
partial class Atari2600
{
public byte[] rom;
public MOS6502 cpu;
public MOS6507 cpu;
public M6532 m6532;
public TIA tia;
@ -104,7 +104,7 @@ namespace BizHawk
public void HardReset()
{
cpu = new Emulation.CPUs.M6502.MOS6502();
cpu = new MOS6507();
cpu.debug = true;
cpu.ReadMemory = ReadMemory;
cpu.WriteMemory = WriteMemory;
@ -134,6 +134,11 @@ namespace BizHawk
tia.execute(1);
cpu.Execute(1);
if (cpu.PendingCycles <= 0)
{
Console.WriteLine("Tia clocks: " + tia.scanlinePos + " CPU pending: " + cpu.PendingCycles);
}
}
//clear the framebuffer (hack code)
if (render == false) return;

View File

@ -1,20 +1,20 @@
using System;
using System.Globalization;
using System.IO;
using BizHawk.Emulation.CPUs.M6502;
using BizHawk.Emulation.CPUs.M6507;
namespace BizHawk.Emulation.Consoles.Atari
{
// Emulates the M6532 RIOT Chip
public partial class M6532
{
MOS6502 Cpu;
MOS6507 Cpu;
public byte[] ram;
public int timerStartValue;
public int timerFinishedCycles;
public int timerShift;
public M6532(MOS6502 cpu, byte[] ram)
public M6532(MOS6507 cpu, byte[] ram)
{
Cpu = cpu;
this.ram = ram;

View File

@ -1,7 +1,7 @@
using System;
using System.Globalization;
using System.IO;
using BizHawk.Emulation.CPUs.M6502;
using BizHawk.Emulation.CPUs.M6507;
using System.Collections.Generic;
namespace BizHawk.Emulation.Consoles.Atari
@ -9,10 +9,11 @@ namespace BizHawk.Emulation.Consoles.Atari
// Emulates the TIA
public partial class TIA
{
MOS6502 Cpu;
MOS6507 Cpu;
UInt32 PF; // PlayField data
byte BKcolor, PFcolor;
bool PFpriority = false;
struct playerData
{
public byte grp;
@ -23,17 +24,32 @@ namespace BizHawk.Emulation.Consoles.Atari
public bool delay;
public byte nusiz;
};
struct ballMissileData
{
public bool enabled;
public byte pos;
public byte HM;
public byte size;
public bool reset;
public bool delay;
};
ballMissileData ball;
playerData player0;
playerData player1;
bool vblankEnabled = false;
int[] frameBuffer;
public bool frameComplete;
List<uint[]> scanlinesBuffer = new List<uint[]> ();
uint[] scanline = new uint[160];
int scanlinePos;
public int scanlinePos;
int[] hmove = new int[] { 0,-1,-2,-3,-4,-5,-6,-7,-8,7,6,5,4,3,2,1 };
UInt32[] palette = new UInt32[]{
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
@ -70,7 +86,7 @@ namespace BizHawk.Emulation.Consoles.Atari
0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0
};
public TIA(MOS6502 cpu, int[] frameBuffer)
public TIA(MOS6507 cpu, int[] frameBuffer)
{
Cpu = cpu;
BKcolor = 0x00;
@ -112,8 +128,28 @@ namespace BizHawk.Emulation.Consoles.Atari
{
color = palette[PFcolor];
}
// Ball
if (ball.enabled && pixelPos >= ball.pos && pixelPos < (ball.pos + (1 << ball.size)))
{
color = palette[PFcolor];
}
// Player 1
if (pixelPos >= player1.pos && pixelPos < (player1.pos + 8))
{
byte mask = (byte)(0x80 >> (pixelPos - player1.pos));
if (player1.reflect)
{
mask = reverseBits(mask);
}
if ((player1.grp & mask) != 0)
{
color = palette[player1.color];
}
}
// Player 0
if (pixelPos >= player0.pos && pixelPos < (player0.pos + 8))
{
byte mask = (byte)(0x80 >> (pixelPos - player0.pos));
@ -132,6 +168,10 @@ namespace BizHawk.Emulation.Consoles.Atari
color = palette[PFcolor];
}
if (vblankEnabled)
{
color = 0x000000;
}
scanline[pixelPos] = color;
scanlinePos++;
@ -193,13 +233,13 @@ namespace BizHawk.Emulation.Consoles.Atari
}
else if (maskedAddr == 0x01)
{
vblankEnabled = (value & 0x02) != 0;
if ((value & 0x02) != 0)
{
Console.WriteLine("TIA Vblank On");
}
else
{
// With this, the electon beam will turn back on and scan lines will start again
Console.WriteLine("TIA Vblank Off");
}
}
@ -215,6 +255,10 @@ namespace BizHawk.Emulation.Consoles.Atari
{
player0.color = value;
}
else if (maskedAddr == 0x07) // COLUP1
{
player1.color = value;
}
else if (maskedAddr == 0x08) // COLUPF
{
PFcolor = value;
@ -225,19 +269,18 @@ namespace BizHawk.Emulation.Consoles.Atari
}
else if (maskedAddr == 0x0A) // CTRLPF
{
if ((value & 0x04) != 0)
{
PFpriority = true;
}
else
{
PFpriority = false;
}
PFpriority = (value & 0x04) != 0;
ball.size = (byte)((value & 0x30) >> 4);
}
else if (maskedAddr == 0x0B) // REFP0
{
player0.reflect = ((value & 0x04) != 0);
}
else if (maskedAddr == 0x0C) // REFP1
{
player1.reflect = ((value & 0x04) != 0);
}
else if (maskedAddr == 0x0D) // PF0
{
PF = (UInt32)((PF & 0x0FFFF) + ((reverseBits(value) & 0x0F) << 16));
@ -252,7 +295,15 @@ namespace BizHawk.Emulation.Consoles.Atari
}
else if (maskedAddr == 0x10) // RESP0
{
player0.pos = (byte)(scanlinePos - 68);
player0.pos = (byte)(scanlinePos - 68 + 5);
}
else if (maskedAddr == 0x11) // RESP1
{
player1.pos = (byte)(scanlinePos - 68 + 5);
}
else if (maskedAddr == 0x14) // RESBL
{
ball.pos = (byte)(scanlinePos - 68 + 4);
}
else if (maskedAddr == 0x1B) // GRP0
{
@ -262,6 +313,33 @@ namespace BizHawk.Emulation.Consoles.Atari
{
player1.grp = value;
}
else if (maskedAddr == 0x1F) // ENABL
{
ball.enabled = (value & 0x02) != 0;
}
else if (maskedAddr == 0x20) // HMP0
{
player0.HM = (byte)((value & 0xF0) >> 4);
}
else if (maskedAddr == 0x21) // HMP1
{
player1.HM = (byte)((value & 0xF0) >> 4);
}
else if (maskedAddr == 0x24) // HMBL
{
ball.HM = (byte)((value & 0xF0) >> 4);
}
else if (maskedAddr == 0x2A) // HMOVE
{
player0.pos = (byte)(player0.pos + hmove[player0.HM]);
player1.pos = (byte)(player1.pos + hmove[player1.HM]);
ball.pos = (byte)(ball.pos + hmove[ball.HM]);
player0.HM = 0;
player1.HM = 0;
ball.HM = 0;
}
}
public byte reverseBits(byte value)