commodore64: add sprites (no collision or priority yet)
This commit is contained in:
parent
0907de61cc
commit
5fcf41ebbc
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue