TIA: Added score graphics. Added support for collisions, and added responses for some collisions. Added support for controller button input. Added another copying mode (0x01: 2 copies close). Fixed a color issue with Pacman.

This commit is contained in:
pjgat09 2012-03-14 20:28:10 +00:00
parent 4c47676c02
commit e686660a7c
2 changed files with 108 additions and 11 deletions

View File

@ -109,7 +109,7 @@ namespace BizHawk
cpu.WriteMemory = WriteMemory; cpu.WriteMemory = WriteMemory;
// Setup TIA // Setup TIA
tia = new TIA(cpu, frameBuffer); tia = new TIA(this, frameBuffer);
// Setup 6532 // Setup 6532
m6532 = new M6532(cpu, ram, this); m6532 = new M6532(cpu, ram, this);
@ -169,6 +169,7 @@ namespace BizHawk
if (Controller["P1 Down"]) value &= 0xDF; if (Controller["P1 Down"]) value &= 0xDF;
if (Controller["P1 Left"]) value &= 0xBF; if (Controller["P1 Left"]) value &= 0xBF;
if (Controller["P1 Right"]) value &= 0x7F; if (Controller["P1 Right"]) value &= 0x7F;
if (Controller["P1 Button"]) value &= 0xF7;
return value; return value;
} }
} }

View File

@ -9,11 +9,16 @@ namespace BizHawk.Emulation.Consoles.Atari
// Emulates the TIA // Emulates the TIA
public partial class TIA public partial class TIA
{ {
MOS6507 Cpu; Atari2600 core;
UInt32 PF; // PlayField data UInt32 PF; // PlayField data
byte BKcolor, PFcolor; byte BKcolor, PFcolor;
bool PFpriority = false; bool PFpriority = false;
bool PFreflect = false; bool PFreflect = false;
bool PFscore = false;
bool inpt_latching = false;
bool inpt4 = false;
bool hmoveHappened = false; bool hmoveHappened = false;
@ -50,6 +55,18 @@ namespace BizHawk.Emulation.Consoles.Atari
byte player1copy1 = 0; byte player1copy1 = 0;
byte player1copy2 = 0; byte player1copy2 = 0;
byte P0_collisions = 0;
byte P1_collisions = 0;
byte M0_collisions = 0;
byte M1_collisions = 0;
byte BL_collisions = 0;
const byte COLP0 = 0x01;
const byte COLP1 = 0x02;
const byte COLM0 = 0x04;
const byte COLM1 = 0x08;
const byte COLPF = 0x10;
const byte COLBL = 0x20;
bool vblankEnabled = false; bool vblankEnabled = false;
@ -98,9 +115,9 @@ namespace BizHawk.Emulation.Consoles.Atari
0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0 0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0
}; };
public TIA(MOS6507 cpu, int[] frameBuffer) public TIA(Atari2600 core, int[] frameBuffer)
{ {
Cpu = cpu; this.core = core;
BKcolor = 0x00; BKcolor = 0x00;
this.frameBuffer = frameBuffer; this.frameBuffer = frameBuffer;
scanlinePos = 0; scanlinePos = 0;
@ -142,17 +159,30 @@ namespace BizHawk.Emulation.Consoles.Atari
UInt32 color; UInt32 color;
color = palette[BKcolor]; color = palette[BKcolor];
byte collisions = 0;
if ((PF & PFmask) != 0) if ((PF & PFmask) != 0)
{ {
color = palette[PFcolor]; color = palette[PFcolor];
if (PFscore)
{
if (pixelPos < 80)
{
color = palette[player0.color];
}
else
{
color = palette[player1.color];
}
}
collisions |= COLPF;
} }
// Ball // Ball
if (ball.enabled && pixelPos >= ball.pos && pixelPos < (ball.pos + (1 << ball.size))) if (ball.enabled && pixelPos >= ball.pos && pixelPos < (ball.pos + (1 << ball.size)))
{ {
color = palette[PFcolor]; color = palette[PFcolor];
collisions |= COLBL;
} }
// Player 1 // Player 1
@ -167,6 +197,7 @@ namespace BizHawk.Emulation.Consoles.Atari
if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay)) if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay))
{ {
color = palette[player1.color]; color = palette[player1.color];
collisions |= COLP1;
} }
} }
@ -183,6 +214,7 @@ namespace BizHawk.Emulation.Consoles.Atari
if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay)) if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay))
{ {
color = palette[player1.color]; color = palette[player1.color];
collisions |= COLP1;
} }
} }
@ -199,6 +231,7 @@ namespace BizHawk.Emulation.Consoles.Atari
if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay)) if (((player1.grp & mask) != 0 && !player1.delay) || ((player1.dgrp & mask) != 0 && player1.delay))
{ {
color = palette[player1.color]; color = palette[player1.color];
collisions |= COLP1;
} }
} }
@ -213,6 +246,7 @@ namespace BizHawk.Emulation.Consoles.Atari
if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay)) if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay))
{ {
color = palette[player0.color]; color = palette[player0.color];
collisions |= COLP0;
} }
} }
@ -229,6 +263,7 @@ namespace BizHawk.Emulation.Consoles.Atari
if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay)) if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay))
{ {
color = palette[player0.color]; color = palette[player0.color];
collisions |= COLP0;
} }
} }
@ -245,12 +280,25 @@ namespace BizHawk.Emulation.Consoles.Atari
if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay)) if (((player0.grp & mask) != 0 && !player0.delay) || ((player0.dgrp & mask) != 0 && player0.delay))
{ {
color = palette[player0.color]; color = palette[player0.color];
collisions |= COLP0;
} }
} }
if ((PF & PFmask) != 0 && PFpriority == true) if ((PF & PFmask) != 0 && PFpriority == true)
{ {
color = palette[PFcolor]; color = palette[PFcolor];
if (PFscore)
{
if (pixelPos < 80)
{
color = palette[player0.color];
}
else
{
color = palette[player1.color];
}
}
collisions |= COLPF;
} }
if (vblankEnabled) if (vblankEnabled)
@ -258,6 +306,12 @@ namespace BizHawk.Emulation.Consoles.Atari
color = 0x000000; color = 0x000000;
} }
P0_collisions |= (((collisions & COLP0) != 0) ? collisions : P0_collisions);
P1_collisions |= (((collisions & COLP1) != 0) ? collisions : P1_collisions);
M0_collisions |= (((collisions & COLM0) != 0) ? collisions : M0_collisions);
M1_collisions |= (((collisions & COLM1) != 0) ? collisions : M1_collisions);
BL_collisions |= (((collisions & COLBL) != 0) ? collisions : BL_collisions);
if (hmoveHappened && pixelPos >= 0 && pixelPos < 8) if (hmoveHappened && pixelPos >= 0 && pixelPos < 8)
{ {
color = 0x000000; color = 0x000000;
@ -298,10 +352,34 @@ namespace BizHawk.Emulation.Consoles.Atari
public byte ReadMemory(ushort addr) public byte ReadMemory(ushort addr)
{ {
ushort maskedAddr = (ushort)(addr & 0x3f); ushort maskedAddr = (ushort)(addr & 0x000F);
Console.WriteLine("TIA read: " + maskedAddr.ToString("x")); Console.WriteLine("TIA read: " + maskedAddr.ToString("x"));
if (maskedAddr == 0x02) // CXP0FB
{
return (byte)((((P0_collisions & COLPF) != 0) ? 0x80 : 0x00) | (((P0_collisions & COLBL) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x07) // CXPPMM
{
return (byte)((((P0_collisions & COLP1) != 0) ? 0x80 : 0x00) | (((M0_collisions & COLM1) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x0C) // INPT4
{
if (inpt_latching)
{
if (inpt4 == true)
{
inpt4 = ((core.ReadControls1() & 0x08) != 0);
}
}
else
{
inpt4 = ((core.ReadControls1() & 0x08) != 0);
}
return (byte)(inpt4 ? 0x80 : 0x00);
return 0x3A; }
return 0x80;
} }
public void WriteMemory(ushort addr, byte value) public void WriteMemory(ushort addr, byte value)
@ -336,6 +414,7 @@ namespace BizHawk.Emulation.Consoles.Atari
{ {
Console.WriteLine("TIA Vblank Off"); Console.WriteLine("TIA Vblank Off");
} }
inpt_latching = (value & 0x40) != 0;
} }
else if (maskedAddr == 0x02) // WSYNC else if (maskedAddr == 0x02) // WSYNC
{ {
@ -353,6 +432,10 @@ namespace BizHawk.Emulation.Consoles.Atari
case 0x00: case 0x00:
player0copies = 0; player0copies = 0;
break; break;
case 0x01:
player0copies = 1;
player0copy1 = 16;
break;
case 0x02: case 0x02:
player0copies = 1; player0copies = 1;
player0copy1 = 32; player0copy1 = 32;
@ -372,6 +455,10 @@ namespace BizHawk.Emulation.Consoles.Atari
case 0x00: case 0x00:
player1copies = 0; player1copies = 0;
break; break;
case 0x01:
player1copies = 1;
player1copy1 = 16;
break;
case 0x02: case 0x02:
player1copies = 1; player1copies = 1;
player1copy1 = 32; player1copy1 = 32;
@ -385,24 +472,25 @@ namespace BizHawk.Emulation.Consoles.Atari
} }
else if (maskedAddr == 0x06) // COLUP0 else if (maskedAddr == 0x06) // COLUP0
{ {
player0.color = value; player0.color = (byte)(value & 0xFE);
} }
else if (maskedAddr == 0x07) // COLUP1 else if (maskedAddr == 0x07) // COLUP1
{ {
player1.color = value; player1.color = (byte)(value & 0xFE);
} }
else if (maskedAddr == 0x08) // COLUPF else if (maskedAddr == 0x08) // COLUPF
{ {
PFcolor = value; PFcolor = (byte)(value & 0xFE);
} }
else if (maskedAddr == 0x09) // COLUBK else if (maskedAddr == 0x09) // COLUBK
{ {
BKcolor = value; BKcolor = (byte)(value & 0xFE);
} }
else if (maskedAddr == 0x0A) // CTRLPF else if (maskedAddr == 0x0A) // CTRLPF
{ {
PFpriority = (value & 0x04) != 0; PFpriority = (value & 0x04) != 0;
PFreflect = (value & 0x01) != 0; PFreflect = (value & 0x01) != 0;
PFscore = (value & 0x02) != 0;
ball.size = (byte)((value & 0x30) >> 4); ball.size = (byte)((value & 0x30) >> 4);
} }
@ -484,6 +572,14 @@ namespace BizHawk.Emulation.Consoles.Atari
hmoveHappened = true; hmoveHappened = true;
} }
else if (maskedAddr == 0x2C) // CXCLR
{
P0_collisions = 0;
P1_collisions = 0;
M0_collisions = 0;
M1_collisions = 0;
BL_collisions = 0;
}
} }
public byte reverseBits(byte value) public byte reverseBits(byte value)