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)
|
public byte Peek(int addr)
|
||||||
{
|
{
|
||||||
return 0;
|
return ReadRegister((ushort)(addr & 0x1F));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Poke(int addr, byte val)
|
public void Poke(int addr, byte val)
|
||||||
{
|
{
|
||||||
|
WriteRegister((ushort)(addr & 0x1F), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte Read(ushort addr)
|
public byte Read(ushort addr)
|
||||||
{
|
{
|
||||||
|
addr &= 0x1F;
|
||||||
byte result = 0x00;
|
byte result = 0x00;
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
@ -694,60 +696,75 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
(envelopes[0].Release)
|
(envelopes[0].Release)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 0x07: result = (byte)voices[0].FrequencyLo; break;
|
case 0x07: result = (byte)voices[1].FrequencyLo; break;
|
||||||
case 0x08: result = (byte)voices[0].FrequencyHi; break;
|
case 0x08: result = (byte)voices[1].FrequencyHi; break;
|
||||||
case 0x09: result = (byte)voices[0].PulseWidthLo; break;
|
case 0x09: result = (byte)voices[1].PulseWidthLo; break;
|
||||||
case 0x0A: result = (byte)voices[0].PulseWidthHi; break;
|
case 0x0A: result = (byte)voices[1].PulseWidthHi; break;
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
result = (byte)(
|
result = (byte)(
|
||||||
(envelopes[0].Gate ? 0x01 : 0x00) |
|
(envelopes[1].Gate ? 0x01 : 0x00) |
|
||||||
(voices[0].Sync ? 0x02 : 0x00) |
|
(voices[1].Sync ? 0x02 : 0x00) |
|
||||||
(voices[0].RingMod ? 0x04 : 0x00) |
|
(voices[1].RingMod ? 0x04 : 0x00) |
|
||||||
(voices[0].Test ? 0x08 : 0x00) |
|
(voices[1].Test ? 0x08 : 0x00) |
|
||||||
(byte)(voices[0].Waveform << 4)
|
(byte)(voices[1].Waveform << 4)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
result = (byte)(
|
result = (byte)(
|
||||||
(envelopes[0].Attack << 4) |
|
(envelopes[1].Attack << 4) |
|
||||||
(envelopes[0].Decay)
|
(envelopes[1].Decay)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
result = (byte)(
|
result = (byte)(
|
||||||
(envelopes[0].Sustain << 4) |
|
(envelopes[1].Sustain << 4) |
|
||||||
(envelopes[0].Release)
|
(envelopes[1].Release)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 0x0E: result = (byte)voices[0].FrequencyLo; break;
|
case 0x0E: result = (byte)voices[2].FrequencyLo; break;
|
||||||
case 0x0F: result = (byte)voices[0].FrequencyHi; break;
|
case 0x0F: result = (byte)voices[2].FrequencyHi; break;
|
||||||
case 0x10: result = (byte)voices[0].PulseWidthLo; break;
|
case 0x10: result = (byte)voices[2].PulseWidthLo; break;
|
||||||
case 0x11: result = (byte)voices[0].PulseWidthHi; break;
|
case 0x11: result = (byte)voices[2].PulseWidthHi; break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
result = (byte)(
|
result = (byte)(
|
||||||
(envelopes[0].Gate ? 0x01 : 0x00) |
|
(envelopes[2].Gate ? 0x01 : 0x00) |
|
||||||
(voices[0].Sync ? 0x02 : 0x00) |
|
(voices[2].Sync ? 0x02 : 0x00) |
|
||||||
(voices[0].RingMod ? 0x04 : 0x00) |
|
(voices[2].RingMod ? 0x04 : 0x00) |
|
||||||
(voices[0].Test ? 0x08 : 0x00) |
|
(voices[2].Test ? 0x08 : 0x00) |
|
||||||
(byte)(voices[0].Waveform << 4)
|
(byte)(voices[2].Waveform << 4)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 0x13:
|
case 0x13:
|
||||||
result = (byte)(
|
result = (byte)(
|
||||||
(envelopes[0].Attack << 4) |
|
(envelopes[2].Attack << 4) |
|
||||||
(envelopes[0].Decay)
|
(envelopes[2].Decay)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
result = (byte)(
|
result = (byte)(
|
||||||
(envelopes[0].Sustain << 4) |
|
(envelopes[2].Sustain << 4) |
|
||||||
(envelopes[0].Release)
|
(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;
|
break;
|
||||||
case 0x15: break;
|
|
||||||
case 0x16: break;
|
|
||||||
case 0x17: break;
|
|
||||||
case 0x18: break;
|
|
||||||
case 0x19: result = (byte)potX; break;
|
case 0x19: result = (byte)potX; break;
|
||||||
case 0x1A: result = (byte)potY; break;
|
case 0x1A: result = (byte)potY; break;
|
||||||
case 0x1B: result = (byte)(voices[2].Oscillator >> 4); 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)
|
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)
|
private void WriteRegister(ushort addr, byte val)
|
||||||
|
|
|
@ -20,10 +20,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
public uint mc;
|
public uint mc;
|
||||||
public uint mcbase;
|
public uint mcbase;
|
||||||
public bool multicolor;
|
public bool multicolor;
|
||||||
|
public bool multicolorCrunch;
|
||||||
public uint pointer;
|
public uint pointer;
|
||||||
public bool priority;
|
public bool priority;
|
||||||
|
public bool shiftEnable;
|
||||||
public uint sr;
|
public uint sr;
|
||||||
public uint x;
|
public uint x;
|
||||||
|
public bool xCrunch;
|
||||||
public bool xExpand;
|
public bool xExpand;
|
||||||
public uint y;
|
public uint y;
|
||||||
public bool yCrunch;
|
public bool yCrunch;
|
||||||
|
@ -42,8 +45,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
multicolor = false;
|
multicolor = false;
|
||||||
pointer = 0;
|
pointer = 0;
|
||||||
priority = false;
|
priority = false;
|
||||||
|
shiftEnable = false;
|
||||||
sr = 0;
|
sr = 0;
|
||||||
x = 0;
|
x = 0;
|
||||||
|
xCrunch = false;
|
||||||
xExpand = false;
|
xExpand = false;
|
||||||
y = 0;
|
y = 0;
|
||||||
yCrunch = false;
|
yCrunch = false;
|
||||||
|
@ -455,9 +460,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
// fetch P
|
// fetch P
|
||||||
addr = (ushort)(0x1F8 | (pointerVM << 10) | cycleFetchSpriteIndex);
|
addr = (ushort)(0x3F8 | (pointerVM << 10) | cycleFetchSpriteIndex);
|
||||||
bus = chips.pla.ReadVic(addr);
|
bus = chips.pla.ReadVic(addr);
|
||||||
sprites[cycleFetchSpriteIndex].pointer = bus;
|
sprites[cycleFetchSpriteIndex].pointer = bus;
|
||||||
|
sprites[cycleFetchSpriteIndex].shiftEnable = false;
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
case 0x20:
|
case 0x20:
|
||||||
|
@ -510,6 +516,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
Sprite spr = sprites[i];
|
Sprite spr = sprites[i];
|
||||||
if (spr.yCrunch)
|
if (spr.yCrunch)
|
||||||
spr.mcbase += 2;
|
spr.mcbase += 2;
|
||||||
|
spr.shiftEnable = false;
|
||||||
|
spr.xCrunch = !spr.xExpand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((act & pipelineChkSprDisp) != 0)
|
if ((act & pipelineChkSprDisp) != 0)
|
||||||
|
@ -607,8 +615,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
borderOnMain = true;
|
borderOnMain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// render visible pixel
|
// recall pixel from buffer
|
||||||
pixel = pixelBuffer[pixelBufferIndex];
|
pixel = pixelBuffer[pixelBufferIndex];
|
||||||
|
|
||||||
buf[bufOffset] = palette[pixel];
|
buf[bufOffset] = palette[pixel];
|
||||||
bufOffset++;
|
bufOffset++;
|
||||||
if (bufOffset == bufLength)
|
if (bufOffset == bufLength)
|
||||||
|
@ -617,10 +626,55 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||||
// put the pixel from the background buffer into the main buffer
|
// put the pixel from the background buffer into the main buffer
|
||||||
pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex];
|
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
|
// border doesn't work with the background buffer
|
||||||
if (borderOnMain || borderOnVertical)
|
if (borderOnMain || borderOnVertical)
|
||||||
pixel = borderColor;
|
pixel = borderColor;
|
||||||
|
|
||||||
|
// store pixel in buffer
|
||||||
pixelBuffer[pixelBufferIndex] = pixel;
|
pixelBuffer[pixelBufferIndex] = pixel;
|
||||||
|
|
||||||
// fill shift register
|
// fill shift register
|
||||||
|
|
Loading…
Reference in New Issue