commodore64: add sprites (no collision or priority yet)

This commit is contained in:
saxxonpike 2012-12-02 23:57:10 +00:00
parent 0907de61cc
commit 5fcf41ebbc
2 changed files with 120 additions and 33 deletions

View File

@ -641,15 +641,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public byte Peek(int addr)
{
return 0;
return ReadRegister((ushort)(addr & 0x1F));
}
public void Poke(int addr, byte val)
{
WriteRegister((ushort)(addr & 0x1F), val);
}
public byte Read(ushort addr)
{
addr &= 0x1F;
byte result = 0x00;
switch (addr)
{
@ -694,60 +696,75 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
(envelopes[0].Release)
);
break;
case 0x07: result = (byte)voices[0].FrequencyLo; break;
case 0x08: result = (byte)voices[0].FrequencyHi; break;
case 0x09: result = (byte)voices[0].PulseWidthLo; break;
case 0x0A: result = (byte)voices[0].PulseWidthHi; break;
case 0x07: result = (byte)voices[1].FrequencyLo; break;
case 0x08: result = (byte)voices[1].FrequencyHi; break;
case 0x09: result = (byte)voices[1].PulseWidthLo; break;
case 0x0A: result = (byte)voices[1].PulseWidthHi; break;
case 0x0B:
result = (byte)(
(envelopes[0].Gate ? 0x01 : 0x00) |
(voices[0].Sync ? 0x02 : 0x00) |
(voices[0].RingMod ? 0x04 : 0x00) |
(voices[0].Test ? 0x08 : 0x00) |
(byte)(voices[0].Waveform << 4)
(envelopes[1].Gate ? 0x01 : 0x00) |
(voices[1].Sync ? 0x02 : 0x00) |
(voices[1].RingMod ? 0x04 : 0x00) |
(voices[1].Test ? 0x08 : 0x00) |
(byte)(voices[1].Waveform << 4)
);
break;
case 0x0C:
result = (byte)(
(envelopes[0].Attack << 4) |
(envelopes[0].Decay)
(envelopes[1].Attack << 4) |
(envelopes[1].Decay)
);
break;
case 0x0D:
result = (byte)(
(envelopes[0].Sustain << 4) |
(envelopes[0].Release)
(envelopes[1].Sustain << 4) |
(envelopes[1].Release)
);
break;
case 0x0E: result = (byte)voices[0].FrequencyLo; break;
case 0x0F: result = (byte)voices[0].FrequencyHi; break;
case 0x10: result = (byte)voices[0].PulseWidthLo; break;
case 0x11: result = (byte)voices[0].PulseWidthHi; break;
case 0x0E: result = (byte)voices[2].FrequencyLo; break;
case 0x0F: result = (byte)voices[2].FrequencyHi; break;
case 0x10: result = (byte)voices[2].PulseWidthLo; break;
case 0x11: result = (byte)voices[2].PulseWidthHi; break;
case 0x12:
result = (byte)(
(envelopes[0].Gate ? 0x01 : 0x00) |
(voices[0].Sync ? 0x02 : 0x00) |
(voices[0].RingMod ? 0x04 : 0x00) |
(voices[0].Test ? 0x08 : 0x00) |
(byte)(voices[0].Waveform << 4)
(envelopes[2].Gate ? 0x01 : 0x00) |
(voices[2].Sync ? 0x02 : 0x00) |
(voices[2].RingMod ? 0x04 : 0x00) |
(voices[2].Test ? 0x08 : 0x00) |
(byte)(voices[2].Waveform << 4)
);
break;
case 0x13:
result = (byte)(
(envelopes[0].Attack << 4) |
(envelopes[0].Decay)
(envelopes[2].Attack << 4) |
(envelopes[2].Decay)
);
break;
case 0x14:
result = (byte)(
(envelopes[0].Sustain << 4) |
(envelopes[0].Release)
(envelopes[2].Sustain << 4) |
(envelopes[2].Release)
);
break;
case 0x15: result = (byte)(filterFrequency & 0x7); break;
case 0x16: result = (byte)((filterFrequency >> 3) & 0xFF); break;
case 0x17:
result = (byte)(
(filterEnable[0] ? 0x01 : 0x00) |
(filterEnable[1] ? 0x02 : 0x00) |
(filterEnable[2] ? 0x04 : 0x00) |
(byte)(filterResonance << 4)
);
break;
case 0x18:
result = (byte)(
(byte)volume |
(filterSelectLoPass ? 0x10 : 0x00) |
(filterSelectBandPass ? 0x20 : 0x00) |
(filterSelectHiPass ? 0x40 : 0x00) |
(disableVoice3 ? 0x80 : 0x00)
);
break;
case 0x15: break;
case 0x16: break;
case 0x17: break;
case 0x18: break;
case 0x19: result = (byte)potX; break;
case 0x1A: result = (byte)potY; break;
case 0x1B: result = (byte)(voices[2].Oscillator >> 4); break;
@ -759,6 +776,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void Write(ushort addr, byte val)
{
addr &= 0x1F;
switch (addr)
{
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x1E:
case 0x1F:
// can't write to these
break;
default:
WriteRegister(addr, val);
break;
}
}
private void WriteRegister(ushort addr, byte val)

View File

@ -20,10 +20,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public uint mc;
public uint mcbase;
public bool multicolor;
public bool multicolorCrunch;
public uint pointer;
public bool priority;
public bool shiftEnable;
public uint sr;
public uint x;
public bool xCrunch;
public bool xExpand;
public uint y;
public bool yCrunch;
@ -42,8 +45,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
multicolor = false;
pointer = 0;
priority = false;
shiftEnable = false;
sr = 0;
x = 0;
xCrunch = false;
xExpand = false;
y = 0;
yCrunch = false;
@ -455,9 +460,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
case 0x00:
// fetch P
addr = (ushort)(0x1F8 | (pointerVM << 10) | cycleFetchSpriteIndex);
addr = (ushort)(0x3F8 | (pointerVM << 10) | cycleFetchSpriteIndex);
bus = chips.pla.ReadVic(addr);
sprites[cycleFetchSpriteIndex].pointer = bus;
sprites[cycleFetchSpriteIndex].shiftEnable = false;
break;
case 0x10:
case 0x20:
@ -510,6 +516,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
Sprite spr = sprites[i];
if (spr.yCrunch)
spr.mcbase += 2;
spr.shiftEnable = false;
spr.xCrunch = !spr.xExpand;
}
}
if ((act & pipelineChkSprDisp) != 0)
@ -607,8 +615,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
borderOnMain = true;
}
// render visible pixel
// recall pixel from buffer
pixel = pixelBuffer[pixelBufferIndex];
buf[bufOffset] = palette[pixel];
bufOffset++;
if (bufOffset == bufLength)
@ -617,10 +626,55 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
// put the pixel from the background buffer into the main buffer
pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex];
// render sprite
uint pixelOwner = 8;
for (uint j = 0; j < 8; j++)
{
uint sprData;
uint sprPixel = pixel;
Sprite spr = sprites[j];
if (spr.x == rasterX)
spr.shiftEnable = true;
if (spr.shiftEnable)
{
if (spr.multicolor)
{
sprData = (spr.sr & 0xC00000) >> 22;
if (spr.multicolorCrunch && spr.xCrunch)
spr.sr <<= 2;
spr.multicolorCrunch ^= spr.xCrunch;
}
else
{
sprData = (spr.sr & 0x800000) >> 22;
if (spr.xCrunch)
spr.sr <<= 1;
}
spr.xCrunch ^= spr.xExpand;
switch (sprData)
{
case 1: sprPixel = spriteMulticolor0; break;
case 2: sprPixel = spr.color; break;
case 3: sprPixel = spriteMulticolor1; break;
}
if (sprData != 0 && pixelOwner >= 8)
{
pixel = sprPixel;
pixelOwner = j;
}
if (spr.sr == 0)
spr.shiftEnable = false; //optimization
}
}
// border doesn't work with the background buffer
if (borderOnMain || borderOnVertical)
pixel = borderColor;
// store pixel in buffer
pixelBuffer[pixelBufferIndex] = pixel;
// fill shift register