Partially implemented the M6532's timer capabilities

Sketchy implementation of the TIA. But hey, it kind of renders pitfall!
This commit is contained in:
pjgat09 2012-03-10 00:26:54 +00:00
parent 65282a366e
commit 781ab15e1e
4 changed files with 182 additions and 11 deletions

View File

@ -75,7 +75,7 @@ namespace BizHawk
// ROM data
else
{
Console.WriteLine("ROM read");
//Console.WriteLine("ROM read");
return rom[maskedAddr & 0x0FFF];
}
}
@ -110,7 +110,7 @@ namespace BizHawk
cpu.WriteMemory = WriteMemory;
// Setup TIA
tia = new TIA(cpu);
tia = new TIA(cpu, frameBuffer);
// Setup 6532
m6532 = new M6532(cpu, ram);
@ -124,10 +124,11 @@ namespace BizHawk
{
Frame++;
//cpu.Execute(228);
cpu.Execute(1);
cpu.Execute(2000);
//clear the framebuffer (hack code)
if (render == false) return;
for (int i = 0; i < 256 * 192; i++)
/*
for (int i = 0; i < 160 * 192; i++)
{
if (i < 64*256)
frameBuffer[i] = i % 256; //black
@ -136,7 +137,7 @@ namespace BizHawk
if (i >= 128*256)
frameBuffer[i] = (i % 256) << 16; //black
}
*/
//run one frame's worth of cpu cyclees (i.e. do the emulation!)
//this should generate the framebuffer as it goes.

View File

@ -8,7 +8,7 @@ namespace BizHawk
{
public string SystemId { get { return "A26"; } }
private int[] frameBuffer = new int[256 * 192];
private int[] frameBuffer = new int[320 * 192];
public CoreInputComm CoreInputComm { get; set; }
public CoreOutputComm CoreOutputComm { get; private set; }
public IVideoProvider VideoProvider { get { return this; } }
@ -68,7 +68,7 @@ namespace BizHawk
return ms.ToArray();
}
public int[] GetVideoBuffer() { return frameBuffer; }
public int BufferWidth { get { return 256; } }
public int BufferWidth { get { return 320; } }
public int BufferHeight { get { return 192; } }
public int BackgroundColor { get { return 0; } }
public void GetSamples(short[] samples) { }

View File

@ -10,11 +10,18 @@ namespace BizHawk.Emulation.Consoles.Atari
{
MOS6502 Cpu;
public byte[] ram;
public int timerStartValue;
public int timerFinishedCycles;
public int timerShift;
public M6532(MOS6502 cpu, byte[] ram)
{
Cpu = cpu;
this.ram = ram;
// Apparently this will break for some games (Solaris and H.E.R.O.). We shall see
timerFinishedCycles = 0;
}
public byte ReadMemory(ushort addr)
@ -30,7 +37,28 @@ namespace BizHawk.Emulation.Consoles.Atari
else
{
maskedAddr = (ushort)(addr & 0x0007);
Console.WriteLine("6532 register read: " + maskedAddr.ToString("x"));
if (maskedAddr == 0x04 || maskedAddr == 0x06)
{
Console.WriteLine("6532 timer read: " + maskedAddr.ToString("x"));
// Calculate the current value on the timer
int timerCurrentValue = timerFinishedCycles - Cpu.TotalExecutedCycles;
// If the timer has not finished, shift the value down for the game
if (Cpu.TotalExecutedCycles < timerFinishedCycles)
{
return (byte)(((timerCurrentValue) >> timerShift) & 0xFF);
}
// Other wise, return the last 8 bits from how long ago it triggered
else
{
return (byte)(timerCurrentValue & 0xFF);
}
}
else
{
Console.WriteLine("6532 register read: " + maskedAddr.ToString("x"));
}
}
return 0x3A;
@ -49,7 +77,23 @@ namespace BizHawk.Emulation.Consoles.Atari
else
{
maskedAddr = (ushort)(addr & 0x0007);
Console.WriteLine("6532 register write: " + maskedAddr.ToString("x"));
if ((addr & 0x14) == 0x14)
{
int[] shift = new int[] {0,3,6,10};
timerShift = shift[addr & 0x03];
// Store the number of cycles for the timer
timerStartValue = value << timerShift;
// Calculate when the timer will be finished
timerFinishedCycles = timerStartValue + Cpu.TotalExecutedCycles;
Console.WriteLine("6532 timer write: " + maskedAddr.ToString("x"));
}
else
{
Console.WriteLine("6532 register write: " + maskedAddr.ToString("x"));
}
}
}
}

View File

@ -9,17 +9,59 @@ namespace BizHawk.Emulation.Consoles.Atari
public partial class TIA
{
MOS6502 Cpu;
UInt32 PF; // PlayField data
byte background;
byte scanline;
UInt32 BKcolor, PFcolor;
int[] frameBuffer;
UInt32[] palette = new UInt32[]{
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0,
0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0,
0xbbbb35, 0, 0xd2d240, 0, 0xe8e84a, 0, 0xfcfc54, 0,
0x7c2c00, 0, 0x904811, 0, 0xa26221, 0, 0xb47a30, 0,
0xc3903d, 0, 0xd2a44a, 0, 0xdfb755, 0, 0xecc860, 0,
0x901c00, 0, 0xa33915, 0, 0xb55328, 0, 0xc66c3a, 0,
0xd5824a, 0, 0xe39759, 0, 0xf0aa67, 0, 0xfcbc74, 0,
0x940000, 0, 0xa71a1a, 0, 0xb83232, 0, 0xc84848, 0,
0xd65c5c, 0, 0xe46f6f, 0, 0xf08080, 0, 0xfc9090, 0,
0x840064, 0, 0x97197a, 0, 0xa8308f, 0, 0xb846a2, 0,
0xc659b3, 0, 0xd46cc3, 0, 0xe07cd2, 0, 0xec8ce0, 0,
0x500084, 0, 0x68199a, 0, 0x7d30ad, 0, 0x9246c0, 0,
0xa459d0, 0, 0xb56ce0, 0, 0xc57cee, 0, 0xd48cfc, 0,
0x140090, 0, 0x331aa3, 0, 0x4e32b5, 0, 0x6848c6, 0,
0x7f5cd5, 0, 0x956fe3, 0, 0xa980f0, 0, 0xbc90fc, 0,
0x000094, 0, 0x181aa7, 0, 0x2d32b8, 0, 0x4248c8, 0,
0x545cd6, 0, 0x656fe4, 0, 0x7580f0, 0, 0x8490fc, 0,
0x001c88, 0, 0x183b9d, 0, 0x2d57b0, 0, 0x4272c2, 0,
0x548ad2, 0, 0x65a0e1, 0, 0x75b5ef, 0, 0x84c8fc, 0,
0x003064, 0, 0x185080, 0, 0x2d6d98, 0, 0x4288b0, 0,
0x54a0c5, 0, 0x65b7d9, 0, 0x75cceb, 0, 0x84e0fc, 0,
0x004030, 0, 0x18624e, 0, 0x2d8169, 0, 0x429e82, 0,
0x54b899, 0, 0x65d1ae, 0, 0x75e7c2, 0, 0x84fcd4, 0,
0x004400, 0, 0x1a661a, 0, 0x328432, 0, 0x48a048, 0,
0x5cba5c, 0, 0x6fd26f, 0, 0x80e880, 0, 0x90fc90, 0,
0x143c00, 0, 0x355f18, 0, 0x527e2d, 0, 0x6e9c42, 0,
0x87b754, 0, 0x9ed065, 0, 0xb4e775, 0, 0xc8fc84, 0,
0x303800, 0, 0x505916, 0, 0x6d762b, 0, 0x88923e, 0,
0xa0ab4f, 0, 0xb7c25f, 0, 0xccd86e, 0, 0xe0ec7c, 0,
0x482c00, 0, 0x694d14, 0, 0x866a26, 0, 0xa28638, 0,
0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0
};
public TIA(MOS6502 cpu)
public TIA(MOS6502 cpu, int[] frameBuffer)
{
Cpu = cpu;
scanline = 0;
BKcolor = 0x00;
this.frameBuffer = frameBuffer;
}
public byte ReadMemory(ushort addr)
{
ushort maskedAddr = (ushort)(addr & 0x3f);
Console.WriteLine("TIA read: " + maskedAddr.ToString("x"));
return 0x3A;
}
@ -27,6 +69,90 @@ namespace BizHawk.Emulation.Consoles.Atari
{
ushort maskedAddr = (ushort)(addr & 0x3f);
Console.WriteLine("TIA write: " + maskedAddr.ToString("x"));
if (maskedAddr == 0x00)
{
if ((value & 0x02) != 0)
{
Console.WriteLine("TIA VSYNC On");
}
else
{
Console.WriteLine("TIA VSYNC Off");
}
}
else if (maskedAddr == 0x01)
{
if ((value & 0x02) != 0)
{
Console.WriteLine("TIA Vblank On");
scanline = 0;
}
else
{
Console.WriteLine("TIA Vblank Off");
}
}
else if (maskedAddr == 0x02) // WSYNC
{
for (int i = 0; i < 320; i++)
{
UInt32 PFmask;
if (i < 160)
{
PFmask = (UInt32)(1 << (20 - (byte)((i % 160) / 8)));
}
else
{
PFmask = (UInt32)(1 << ((byte)((i % 160) / 8)));
}
UInt32 color;
if ((PF & PFmask) != 0)
{
color = palette[PFcolor];
}
else
{
color = palette[BKcolor];
}
frameBuffer[scanline * 320 + i] = (int)color;
}
scanline++;
if (scanline >= 192) { scanline = 0; }
Console.WriteLine("TIA WSYNC");
}
else if (maskedAddr == 0x0D) // PF0
{
PF = (UInt32)((PF & 0x0FFFF) + ((reverseBits(value) & 0x0F) << 16));
}
else if (maskedAddr == 0x0E) // PF1
{
PF = (UInt32)((PF & 0xF00FF) + (value << 8));
}
else if (maskedAddr == 0x0F) // PF2
{
PF = (UInt32)((PF & 0xFFF00) + reverseBits(value));
}
else if (maskedAddr == 0x08) // COLUPF
{
PFcolor = (UInt32)(value);
}
else if (maskedAddr == 0x09) // COLUBK
{
BKcolor = (UInt32)(value);
}
}
public byte reverseBits(byte value)
{
byte result = 0x00;
for (int i = 0; i < 8; i++)
{
result = (byte)(result | (((value >> i) & 0x01 ) << (7-i)));
}
return result;
}
}
}