Commodore64: Border unit implemented fully, timing is much better now and works for both PAL and NTSC.
This commit is contained in:
parent
dde1169325
commit
1c18da52b3
|
@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
PAL
|
||||
}
|
||||
|
||||
public partial class C64 : IEmulator
|
||||
sealed public partial class C64 : IEmulator
|
||||
{
|
||||
private Motherboard board;
|
||||
private bool loadPrg;
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
/// <summary>
|
||||
/// Contains the onboard chipset and glue.
|
||||
/// </summary>
|
||||
public partial class Motherboard
|
||||
sealed public partial class Motherboard
|
||||
{
|
||||
// chips
|
||||
public Chip23XX basicRom;
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Text;
|
|||
|
||||
namespace BizHawk.Emulation.Computers.Commodore64
|
||||
{
|
||||
public partial class Motherboard
|
||||
sealed public partial class Motherboard
|
||||
{
|
||||
bool CassPort_ReadDataOutput()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace BizHawk.Emulation.Computers.Commodore64
|
||||
{
|
||||
public partial class C64 : IEmulator
|
||||
sealed public partial class C64 : IEmulator
|
||||
{
|
||||
public void ClearSaveRam()
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.IO;
|
|||
|
||||
namespace BizHawk.Emulation.Computers.Commodore64
|
||||
{
|
||||
public partial class C64 : IEmulator
|
||||
sealed public partial class C64 : IEmulator
|
||||
{
|
||||
// internal variables
|
||||
private bool _islag = true;
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||
using System.Drawing;
|
||||
|
||||
namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||
{
|
||||
// vic ntsc
|
||||
static public class MOS6567
|
||||
{
|
||||
static int[] timing = Vic.TimingBuilder_XRaster(0x19C, 0x200, 0x208, 0x18C, 8);
|
||||
static int cycles = 65;
|
||||
static int lines = 263;
|
||||
static int vblankstart = 0x00D;
|
||||
static int vblankend = 0x018;
|
||||
static int hblankstart = 0x18C;
|
||||
static int hblankend = 0x1F0;
|
||||
static int scanwidth = cycles * 8;
|
||||
|
||||
static int[] timing = Vic.TimingBuilder_XRaster(0x19C, 0x200, scanwidth, 0x18C, 8);
|
||||
static int[] fetch = Vic.TimingBuilder_Fetch(timing, 0x174);
|
||||
static int[] ba = Vic.TimingBuilder_BA(fetch);
|
||||
static int[] act = Vic.TimingBuilder_Act(timing, 0x004, 0x14C);
|
||||
static int[] act = Vic.TimingBuilder_Act(timing, 0x004, 0x14C, hblankstart, hblankend);
|
||||
|
||||
static int[][] pipeline = new int[][]
|
||||
{
|
||||
|
@ -18,7 +28,13 @@
|
|||
|
||||
static public Vic Create()
|
||||
{
|
||||
return new Vic(65, 263, pipeline, 14318181 / 14);
|
||||
return new Vic(
|
||||
cycles, lines,
|
||||
pipeline,
|
||||
14318181 / 14,
|
||||
hblankstart, hblankend,
|
||||
vblankstart, vblankend
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||
using System.Drawing;
|
||||
|
||||
namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
||||
{
|
||||
// vic pal
|
||||
static public class MOS6569
|
||||
{
|
||||
static int[] timing = Vic.TimingBuilder_XRaster(0x194, 0x1F8, 0x1F8, -1, -1);
|
||||
static int cycles = 63;
|
||||
static int lines = 312;
|
||||
static int vblankstart = 0x12C;
|
||||
static int vblankend = 0x00F;
|
||||
static int hblankstart = 0x17C;
|
||||
static int hblankend = 0x1E0;
|
||||
static int scanwidth = cycles * 8;
|
||||
|
||||
static int[] timing = Vic.TimingBuilder_XRaster(0x194, 0x1F8, scanwidth, -1, -1);
|
||||
static int[] fetch = Vic.TimingBuilder_Fetch(timing, 0x164);
|
||||
static int[] ba = Vic.TimingBuilder_BA(fetch);
|
||||
static int[] act = Vic.TimingBuilder_Act(timing, 0x004, 0x14C);
|
||||
static int[] act = Vic.TimingBuilder_Act(timing, 0x004, 0x14C, hblankstart, hblankend);
|
||||
|
||||
static int[][] pipeline = new int[][]
|
||||
{
|
||||
|
@ -18,7 +28,13 @@
|
|||
|
||||
static public Vic Create()
|
||||
{
|
||||
return new Vic(63, 312, pipeline, 17734472 / 18);
|
||||
return new Vic(
|
||||
cycles, lines,
|
||||
pipeline,
|
||||
17734472 / 18,
|
||||
hblankstart, hblankend,
|
||||
vblankstart, vblankend
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -613,11 +613,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
public Sid(int[][] newWaveformTable, int newSampleRate, Region newRegion)
|
||||
{
|
||||
uint cyclesPerSec = 0;
|
||||
uint cyclesNum;
|
||||
uint cyclesDen;
|
||||
uint sampleRate = 44100;
|
||||
|
||||
switch (newRegion)
|
||||
{
|
||||
case Region.NTSC: cyclesPerSec = 14318181 / 14; break;
|
||||
case Region.PAL: cyclesPerSec = 17734472 / 18; break;
|
||||
case Region.NTSC: cyclesNum = 14318181; cyclesDen = 14; break;
|
||||
case Region.PAL: cyclesNum = 17734472; cyclesDen = 18; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
waveformTable = newWaveformTable;
|
||||
|
@ -636,7 +640,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
for (int i = 0; i < 3; i++)
|
||||
filterEnable[i] = false;
|
||||
|
||||
resampler = new Sound.Utilities.SpeexResampler(0, cyclesPerSec, 44100, cyclesPerSec, 44100, null, null);
|
||||
resampler = new Sound.Utilities.SpeexResampler(0, cyclesNum, sampleRate * cyclesDen, cyclesNum, sampleRate * cyclesDen, null, null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -19,6 +19,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
public const int pipelineChkBrdR1 = 256;
|
||||
public const int pipelineChkSprDisp = 512;
|
||||
public const int pipelineUpdateRc = 1024;
|
||||
public const int pipelineHBlankL = 0x10000000;
|
||||
public const int pipelineHBlankR = 0x20000000;
|
||||
public const int pipelineHoldX = 0x40000000;
|
||||
public const int rasterIrqLine0Cycle = 1;
|
||||
public const int rasterIrqLineXCycle = 0;
|
||||
|
@ -43,6 +45,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
// apply X location
|
||||
rasterX = pipeline[0][cycleIndex];
|
||||
rasterXHold = ((parseact & pipelineHoldX) != 0);
|
||||
|
||||
// perform fetch
|
||||
parsefetchType = parsefetch & 0xFF00;
|
||||
|
@ -158,7 +161,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
// perform actions
|
||||
borderCheckLEnable = ((parseact & (pipelineChkBrdL0 | pipelineChkBrdL1)) != 0);
|
||||
borderCheckREnable = ((parseact & (pipelineChkBrdR0 | pipelineChkBrdR1)) != 0);
|
||||
rasterXHold = ((parseact & pipelineHoldX) != 0);
|
||||
hblankCheckEnableL = ((parseact & pipelineHBlankL) != 0);
|
||||
hblankCheckEnableR = ((parseact & pipelineHBlankR) != 0);
|
||||
|
||||
if (parseact != 0)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
{
|
||||
sealed public partial class Vic
|
||||
{
|
||||
int borderSR;
|
||||
int ecmPixel;
|
||||
int pixel;
|
||||
int[] pixelBackgroundBuffer;
|
||||
|
@ -33,47 +34,52 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
private void Render()
|
||||
{
|
||||
renderEnabled = bufRect.Contains(bufPoint);
|
||||
if (hblankCheckEnableL)
|
||||
{
|
||||
if (rasterX == hblankEnd)
|
||||
hblank = false;
|
||||
}
|
||||
else if (hblankCheckEnableR)
|
||||
{
|
||||
if (rasterX == hblankStart)
|
||||
hblank = true;
|
||||
}
|
||||
renderEnabled = !hblank && !vblank; //bufRect.Contains(bufPoint);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (borderCheckLEnable)
|
||||
if (borderCheckLEnable && (rasterX == borderL))
|
||||
{
|
||||
if (rasterX == borderL)
|
||||
{
|
||||
if (rasterLine == borderB)
|
||||
borderOnVertical = true;
|
||||
if (rasterLine == borderT && displayEnable)
|
||||
borderOnVertical = false;
|
||||
if (!borderOnVertical)
|
||||
borderOnMain = false;
|
||||
}
|
||||
}
|
||||
if (borderCheckREnable)
|
||||
{
|
||||
if (rasterX == borderR)
|
||||
borderOnMain = true;
|
||||
if (rasterLine == borderB)
|
||||
borderOnVertical = true;
|
||||
if (rasterLine == borderT && displayEnable)
|
||||
borderOnVertical = false;
|
||||
if (!borderOnVertical)
|
||||
borderOnMain = false;
|
||||
}
|
||||
|
||||
if (borderCheckREnable && (rasterX == borderR))
|
||||
borderOnMain = true;
|
||||
|
||||
// recall pixel from buffer
|
||||
pixel = pixelBuffer[pixelBufferIndex];
|
||||
|
||||
// border doesn't work with the background buffer
|
||||
borderSR <<= 1;
|
||||
if (borderOnMain || borderOnVertical)
|
||||
borderSR |= 1;
|
||||
if ((borderSR & 0x100) != 0)
|
||||
pixel = borderColor;
|
||||
|
||||
// plot pixel if within viewing area
|
||||
if (renderEnabled)
|
||||
{
|
||||
|
||||
buf[bufOffset] = palette[pixel];
|
||||
bufOffset++;
|
||||
if (bufOffset == bufLength)
|
||||
bufOffset = 0;
|
||||
}
|
||||
bufPoint.X++;
|
||||
if (bufPoint.X == bufWidth)
|
||||
{
|
||||
bufPoint.X = 0;
|
||||
bufPoint.Y++;
|
||||
if (bufPoint.Y == bufHeight)
|
||||
bufPoint.Y = 0;
|
||||
}
|
||||
|
||||
// put the pixel from the background buffer into the main buffer
|
||||
pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex];
|
||||
|
@ -143,10 +149,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
}
|
||||
}
|
||||
|
||||
// border doesn't work with the background buffer
|
||||
if (borderOnMain || borderOnVertical)
|
||||
pixel = borderColor;
|
||||
|
||||
// store pixel in buffer
|
||||
pixelBuffer[pixelBufferIndex] = pixel;
|
||||
|
||||
|
|
|
@ -42,11 +42,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
bool enableIntSpriteCollision;
|
||||
bool enableIntSpriteDataCollision;
|
||||
bool extraColorMode;
|
||||
bool hblank;
|
||||
bool idle;
|
||||
bool intLightPen;
|
||||
bool intRaster;
|
||||
bool intSpriteCollision;
|
||||
bool intSpriteDataCollision;
|
||||
int hblankEnd;
|
||||
int hblankStart;
|
||||
bool hblankCheckEnableL;
|
||||
bool hblankCheckEnableR;
|
||||
int lastRasterLine;
|
||||
int lightPenX;
|
||||
int lightPenY;
|
||||
|
@ -69,6 +74,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
int spriteMulticolor1;
|
||||
Sprite[] sprites;
|
||||
int sr;
|
||||
bool vblank;
|
||||
int vblankEnd;
|
||||
int vblankStart;
|
||||
int vc;
|
||||
int vcbase;
|
||||
int vmli;
|
||||
|
@ -105,6 +113,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
enableIntSpriteCollision = false;
|
||||
enableIntSpriteDataCollision = false;
|
||||
extraColorMode = false;
|
||||
hblank = true;
|
||||
idle = true;
|
||||
intLightPen = false;
|
||||
intRaster = false;
|
||||
|
@ -127,6 +136,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
spriteMulticolor0 = 0;
|
||||
spriteMulticolor1 = 0;
|
||||
sr = 0;
|
||||
vblank = true;
|
||||
vc = 0;
|
||||
vcbase = 0;
|
||||
vmli = 0;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
pipelineChkSprDisp, pipelineUpdateRc
|
||||
};
|
||||
|
||||
static public int[] TimingBuilder_Act(int[] timing, int cycle14, int cycle55)
|
||||
static public int[] TimingBuilder_Act(int[] timing, int cycle14, int cycle55, int hblankStart, int hblankEnd)
|
||||
{
|
||||
List<int> result = new List<int>();
|
||||
|
||||
|
@ -39,6 +39,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
result.Add(0);
|
||||
}
|
||||
|
||||
bool hBlankL = false;
|
||||
bool hBlankR = false;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
// pipeline raster X delay
|
||||
|
@ -54,6 +56,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
result[i] |= pipelineChkBrdR0;
|
||||
if (timing[i] == 0x15C)
|
||||
result[i] |= pipelineChkBrdR1;
|
||||
if (timing[i] == (hblankStart & 0xFFD))
|
||||
result[i] |= pipelineHBlankR;
|
||||
if (timing[i] == (hblankEnd & 0xFFD))
|
||||
result[i] |= pipelineHBlankL;
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
|
@ -196,6 +202,34 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
return result.ToArray();
|
||||
}
|
||||
|
||||
static public int TimingBuilder_ScreenHeight(int vblankStart, int vblankEnd, int lines)
|
||||
{
|
||||
int offset = vblankEnd;
|
||||
int result = 0;
|
||||
while (true)
|
||||
{
|
||||
if (offset >= lines)
|
||||
offset -= lines;
|
||||
if (offset == vblankStart)
|
||||
return result;
|
||||
offset++;
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static public int TimingBuilder_ScreenWidth(int[] timing, int hblankStart, int hblankEnd)
|
||||
{
|
||||
int length = timing.Length;
|
||||
int result = 0;
|
||||
int offset = 0;
|
||||
|
||||
while (timing[offset] != hblankEnd) { offset = (offset + 1) % length; }
|
||||
while (timing[offset] != hblankStart) { offset = (offset + 1) % length; result++; }
|
||||
//while (timing[offset] == hblankStart) { offset = (offset + 1) % length; result++; }
|
||||
|
||||
return (result * 4);
|
||||
}
|
||||
|
||||
static public int[] TimingBuilder_XRaster(int start, int width, int count, int delayOffset, int delayAmount)
|
||||
{
|
||||
List<int> result = new List<int>();
|
||||
|
|
|
@ -8,8 +8,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
int bufHeight;
|
||||
int bufLength;
|
||||
int bufOffset;
|
||||
Point bufPoint;
|
||||
Rectangle bufRect;
|
||||
int bufWidth;
|
||||
|
||||
// palette
|
||||
|
@ -40,12 +38,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
public int BufferHeight
|
||||
{
|
||||
get { return bufRect.Height; }
|
||||
get { return bufHeight; }
|
||||
}
|
||||
|
||||
public int BufferWidth
|
||||
{
|
||||
get { return bufRect.Width; }
|
||||
get { return bufWidth; }
|
||||
}
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
|
@ -55,7 +53,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
public int VirtualWidth
|
||||
{
|
||||
get { return bufRect.Width; }
|
||||
get { return bufWidth; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
int totalCycles;
|
||||
int totalLines;
|
||||
|
||||
public Vic(int newCycles, int newLines, int[][] newPipeline, int newCyclesPerSec)
|
||||
public Vic(int newCycles, int newLines, int[][] newPipeline, int newCyclesPerSec, int hblankStart, int hblankEnd, int vblankStart, int vblankEnd)
|
||||
{
|
||||
|
||||
{
|
||||
debugScreen = false;
|
||||
|
||||
this.hblankStart = hblankStart;
|
||||
this.hblankEnd = hblankEnd;
|
||||
this.vblankStart = vblankStart;
|
||||
this.vblankEnd = vblankEnd;
|
||||
|
||||
totalCycles = newCycles;
|
||||
totalLines = newLines;
|
||||
pipeline = newPipeline;
|
||||
|
@ -31,19 +35,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
pixelBufferDelay = 12;
|
||||
pixelBackgroundBufferDelay = 4;
|
||||
|
||||
if (debugScreen)
|
||||
{
|
||||
bufRect = new Rectangle(0, 0, totalCycles * 8, totalLines);
|
||||
}
|
||||
else
|
||||
{
|
||||
bufRect = new Rectangle(136 - 24, 51 - 24, 320 + 48, 200 + 48);
|
||||
}
|
||||
bufWidth = TimingBuilder_ScreenWidth(pipeline[0], hblankStart, hblankEnd);
|
||||
bufHeight = TimingBuilder_ScreenHeight(vblankStart, vblankEnd, newLines);
|
||||
|
||||
buf = new int[bufRect.Width * bufRect.Height];
|
||||
buf = new int[bufWidth * bufHeight];
|
||||
bufLength = buf.Length;
|
||||
bufWidth = (totalCycles * 8);
|
||||
bufHeight = (totalLines);
|
||||
|
||||
sprites = new Sprite[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
|
@ -145,6 +141,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
if (rasterLine == borderT && displayEnable)
|
||||
borderOnVertical = false;
|
||||
|
||||
if (rasterLine == vblankStart)
|
||||
vblank = true;
|
||||
if (rasterLine == vblankEnd)
|
||||
vblank = false;
|
||||
|
||||
cycleIndex = 0;
|
||||
cycle = 0;
|
||||
rasterLine++;
|
||||
|
|
|
@ -24,7 +24,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
IntBuffer refIntBuffer;
|
||||
Int32 refPointX;
|
||||
Int32 refPointY;
|
||||
Rectangle refRect;
|
||||
SByte refSByte;
|
||||
UInt16 refUInt16;
|
||||
UInt32 refUInt32;
|
||||
|
|
Loading…
Reference in New Issue