Merge pull request #506 from Kabuto/master
C64 core: tape loading added, lots of bugfixes and improvements
This commit is contained in:
commit
3ca25ccb69
|
@ -672,7 +672,7 @@ namespace BizHawk.Client.Common
|
|||
nextEmulator = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
|
||||
break;
|
||||
case "C64":
|
||||
var c64 = new C64(nextComm, game, rom.RomData, rom.Extension);
|
||||
var c64 = new C64(nextComm, game, rom.RomData, rom.Extension, GetCoreSettings<C64>(), GetCoreSyncSettings<C64>());
|
||||
nextEmulator = c64;
|
||||
break;
|
||||
case "GBA":
|
||||
|
|
|
@ -8,6 +8,12 @@ namespace BizHawk.Client.Common
|
|||
// these are political numbers, designed to be in accord with tasvideos.org tradition. theyre not necessarily mathematical factualities (although they may be in some cases)
|
||||
// it would be nice if we could turn this into a rational expression natively, and also, to write some comments about the derivation and ideal valees (since this seems to be where theyre all collected)
|
||||
// are we collecting them anywhere else? for avi-writing code perhaps?
|
||||
|
||||
// just some constants, according to specs
|
||||
private static readonly double PAL_CARRIER = 15625 * 283.75 + 25; // 4.43361875 MHz
|
||||
private static readonly double NTSC_CARRIER = 4500000 * 227.5 / 286; // 3.579545454... MHz
|
||||
private static readonly double PAL_N_CARRIER = 15625 * 229.25 + 25; // 3.58205625 MHz
|
||||
|
||||
private static readonly Dictionary<string, double> _rates = new Dictionary<string, double>
|
||||
{
|
||||
{ "NES", 60.098813897440515532 }, // discussion here: http://forums.nesdev.com/viewtopic.php?t=492 ; a rational expression would be (19687500 / 11) / ((341*262-0.529780.5)/3) -> (118125000 / 1965513) -> 60.098813897440515529533511098629 (so our chosen number is very close)
|
||||
|
@ -48,6 +54,11 @@ namespace BizHawk.Client.Common
|
|||
{"PSX", 44100.0*768*11/7/263/3413}, //59.292862562
|
||||
{"PSX_PAL", 44100.0*768*11/7/314/3406}, //49.7645593576
|
||||
|
||||
{"C64_PAL", PAL_CARRIER*2/9/312/63},
|
||||
{"C64_NTSC", NTSC_CARRIER*2/7/263/65},
|
||||
{"C64_NTSC_OLD", NTSC_CARRIER*2/7/262/64},
|
||||
{"C64_DREAN", PAL_N_CARRIER*2/7/312/65},
|
||||
|
||||
//according to ryphecha, using
|
||||
//clocks[2] = { 53.693182e06, 53.203425e06 }; //ntsc console, pal console
|
||||
//lpf[2][2] = { { 263, 262.5 }, { 314, 312.5 } }; //ntsc,pal; noninterlaced, interlaced
|
||||
|
|
|
@ -1965,7 +1965,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (VersionInfo.DeveloperBuild)
|
||||
{
|
||||
return FormatFilter(
|
||||
"Rom Files", "*.nes;*.fds;*unf;*.sms;*.gg;*.sg;*.pce;*.sgx;*.bin;*.smd;*.rom;*.a26;*.a78;*.lnx;*.m3u;*.cue;*.ccd;*.exe;*.gb;*.gbc;*.gba;*.gen;*.md;*.col;.int;*.smc;*.sfc;*.prg;*.d64;*.g64;*.crt;*.sgb;*.xml;*.z64;*.v64;*.n64;*.ws;*.wsc;*.dsk;*.do;*.po;*.psf;*.minipsf;*.nsf;%ARCH%",
|
||||
"Rom Files", "*.nes;*.fds;*unf;*.sms;*.gg;*.sg;*.pce;*.sgx;*.bin;*.smd;*.rom;*.a26;*.a78;*.lnx;*.m3u;*.cue;*.ccd;*.exe;*.gb;*.gbc;*.gba;*.gen;*.md;*.col;.int;*.smc;*.sfc;*.prg;*.d64;*.g64;*.crt;*.tap;*.sgb;*.xml;*.z64;*.v64;*.n64;*.ws;*.wsc;*.dsk;*.do;*.po;*.psf;*.minipsf;*.nsf;%ARCH%",
|
||||
"Music Files", "*.psf;*.minipsf;*.sid;*.nsf",
|
||||
"Disc Images", "*.cue;*.ccd;*.m3u",
|
||||
"NES", "*.nes;*.fds;*.unf;*.nsf;%ARCH%",
|
||||
|
@ -1986,7 +1986,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
"PlayStation", "*.cue;*.ccd;*.m3u",
|
||||
"PSX Executables (experimental)", "*.exe",
|
||||
"PSF Playstation Sound File", "*.psf;*.minipsf",
|
||||
"Commodore 64 (experimental)", "*.prg; *.d64, *.g64; *.crt;%ARCH%",
|
||||
"Commodore 64 (experimental)", "*.prg; *.d64, *.g64; *.crt; *.tap;%ARCH%",
|
||||
"SID Commodore 64 Music File", "*.sid;%ARCH%",
|
||||
"Nintendo 64", "*.z64;*.v64;*.n64",
|
||||
"WonderSwan", "*.ws;*.wsc;%ARCH%",
|
||||
|
|
|
@ -315,6 +315,7 @@ namespace BizHawk.Emulation.Common
|
|||
case ".T64":
|
||||
case ".G64":
|
||||
case ".CRT":
|
||||
case ".TAP":
|
||||
game.System = "C64";
|
||||
break;
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
<Compile Include="Computers\Commodore64\C64.IDebuggable.cs">
|
||||
<DependentUpon>C64.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\Commodore64\C64.IDisassemblable.cs" />
|
||||
<Compile Include="Computers\Commodore64\C64.IDriveLight.cs">
|
||||
<DependentUpon>C64.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -160,6 +161,7 @@
|
|||
<Compile Include="Computers\Commodore64\C64.IMemoryDomains.cs">
|
||||
<DependentUpon>C64.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Computers\Commodore64\C64.ISettable.cs" />
|
||||
<Compile Include="Computers\Commodore64\C64.IStatable.cs">
|
||||
<DependentUpon>C64.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -176,14 +178,15 @@
|
|||
<Compile Include="Computers\Commodore64\Cartridge\Mapper0013.cs" />
|
||||
<Compile Include="Computers\Commodore64\Cartridge\Mapper0020.cs" />
|
||||
<Compile Include="Computers\Commodore64\CassettePort\CassettePortDevice.cs" />
|
||||
<Compile Include="Computers\Commodore64\CassettePort\Tape.cs" />
|
||||
<Compile Include="Computers\Commodore64\InputFileInfo.cs" />
|
||||
<Compile Include="Computers\Commodore64\Media\PRG.cs" />
|
||||
<Compile Include="Computers\Commodore64\Cartridge\Cart.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\CartridgePort.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\CassettePort.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\Chip2114.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\Chip23XX.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\Chip4864.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6567R56A.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6510.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6522.cs" />
|
||||
<Compile Include="Computers\Commodore64\Media\D64.cs" />
|
||||
|
@ -193,7 +196,8 @@
|
|||
<Compile Include="Computers\Commodore64\MOS\MOS6526-2.Interface.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6526-2.PortIO.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6526.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6567.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6567R8.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6572.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6581.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOS6569.cs" />
|
||||
<Compile Include="Computers\Commodore64\MOS\MOSPLA.cs" />
|
||||
|
|
|
@ -2931,5 +2931,10 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
if (!rdy_freeze)
|
||||
mi++;
|
||||
} //ExecuteOne
|
||||
|
||||
public bool AtInstructionStart()
|
||||
{
|
||||
return Microcode[opcode][mi] >= Uop.End;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,15 +51,110 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
}
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks
|
||||
public bool CanStep(StepType type)
|
||||
{
|
||||
[FeatureNotImplemented]
|
||||
get { throw new NotImplementedException(); }
|
||||
switch (type)
|
||||
{
|
||||
case StepType.Into:
|
||||
case StepType.Over:
|
||||
case StepType.Out:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void Step(StepType type) { throw new NotImplementedException(); }
|
||||
|
||||
public bool CanStep(StepType type) { return false; }
|
||||
public void Step(StepType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case StepType.Into:
|
||||
StepInto();
|
||||
break;
|
||||
case StepType.Out:
|
||||
StepOut();
|
||||
break;
|
||||
case StepType.Over:
|
||||
StepOver();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void StepInto()
|
||||
{
|
||||
while (board.cpu.AtInstructionStart())
|
||||
{
|
||||
DoCycle();
|
||||
}
|
||||
while (!board.cpu.AtInstructionStart())
|
||||
{
|
||||
DoCycle();
|
||||
}
|
||||
}
|
||||
|
||||
private void StepOver()
|
||||
{
|
||||
var instruction = board.cpu.Peek(board.cpu.PC);
|
||||
|
||||
if (instruction == JSR)
|
||||
{
|
||||
var destination = board.cpu.PC + JSRSize;
|
||||
while (board.cpu.PC != destination)
|
||||
{
|
||||
StepInto();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StepInto();
|
||||
}
|
||||
}
|
||||
|
||||
private void StepOut()
|
||||
{
|
||||
var instr = board.cpu.Peek(board.cpu.PC);
|
||||
|
||||
JSRCount = instr == JSR ? 1 : 0;
|
||||
|
||||
var bailOutFrame = Frame + 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
StepInto();
|
||||
instr = board.cpu.Peek(board.cpu.PC);
|
||||
if (instr == JSR)
|
||||
{
|
||||
JSRCount++;
|
||||
}
|
||||
else if ((instr == RTS || instr == RTI) && JSRCount <= 0)
|
||||
{
|
||||
StepInto();
|
||||
JSRCount = 0;
|
||||
break;
|
||||
}
|
||||
else if (instr == RTS || instr == RTI)
|
||||
{
|
||||
JSRCount--;
|
||||
}
|
||||
else //Emergency Bailout Logic
|
||||
{
|
||||
if (Frame == bailOutFrame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int JSRCount = 0;
|
||||
|
||||
private const byte JSR = 0x20;
|
||||
private const byte RTI = 0x40;
|
||||
private const byte RTS = 0x60;
|
||||
|
||||
private const byte JSRSize = 3;
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||
{
|
||||
public partial class C64 : IDisassemblable
|
||||
{
|
||||
public string Cpu
|
||||
{
|
||||
get { return "6510"; } set { }
|
||||
}
|
||||
|
||||
public string PCRegisterName
|
||||
{
|
||||
get { return "PC"; }
|
||||
}
|
||||
|
||||
public IEnumerable<string> AvailableCpus
|
||||
{
|
||||
get { yield return "6510"; }
|
||||
}
|
||||
|
||||
public string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
return Components.M6502.MOS6502X.Disassemble((ushort)addr, out length, (a) => m.PeekByte(a));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||
{
|
||||
public partial class C64 : ISettable<C64.C64Settings, C64.C64SyncSettings>
|
||||
{
|
||||
public C64Settings GetSettings()
|
||||
{
|
||||
return Settings.Clone();
|
||||
}
|
||||
|
||||
public C64SyncSettings GetSyncSettings()
|
||||
{
|
||||
return SyncSettings.Clone();
|
||||
}
|
||||
|
||||
public bool PutSettings(C64Settings o)
|
||||
{
|
||||
Settings = o;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PutSyncSettings(C64SyncSettings o)
|
||||
{
|
||||
SyncSettings = o;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal C64Settings Settings { get; private set; }
|
||||
internal C64SyncSettings SyncSettings { get; private set; }
|
||||
|
||||
public class C64Settings
|
||||
{
|
||||
public C64Settings Clone()
|
||||
{
|
||||
return (C64Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public C64Settings()
|
||||
{
|
||||
BizHawk.Common.SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class C64SyncSettings
|
||||
{
|
||||
[DisplayName("VIC type")]
|
||||
[Description("Set the type of video chip to use")]
|
||||
[DefaultValue(VicType.PAL)]
|
||||
public VicType vicType { get; set; }
|
||||
|
||||
public C64SyncSettings Clone()
|
||||
{
|
||||
return (C64SyncSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public C64SyncSettings()
|
||||
{
|
||||
BizHawk.Common.SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
}
|
||||
|
||||
public enum VicType
|
||||
{
|
||||
PAL, NTSC, NTSC_OLD, DREAN
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,25 +42,48 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
|
||||
private C64 _c64;
|
||||
|
||||
public Motherboard(C64 c64, Region initRegion)
|
||||
public Motherboard(C64 c64, C64.VicType initRegion)
|
||||
{
|
||||
// note: roms need to be added on their own externally
|
||||
_c64 = c64;
|
||||
|
||||
int clockNum, clockDen, mainsFrq;
|
||||
switch (initRegion)
|
||||
{
|
||||
case C64.VicType.PAL:
|
||||
clockNum = 17734475;
|
||||
clockDen = 18;
|
||||
mainsFrq = 50;
|
||||
break;
|
||||
case C64.VicType.NTSC:
|
||||
case C64.VicType.NTSC_OLD:
|
||||
clockNum = 11250000;
|
||||
clockDen = 11;
|
||||
mainsFrq = 60;
|
||||
break;
|
||||
case C64.VicType.DREAN:
|
||||
clockNum = 14328225;
|
||||
clockDen = 14;
|
||||
mainsFrq = 50;
|
||||
break;
|
||||
default:
|
||||
throw new System.Exception();
|
||||
}
|
||||
cartPort = new CartridgePort();
|
||||
cassPort = new CassettePortDevice();
|
||||
cia0 = new MOS6526(initRegion);
|
||||
cia1 = new MOS6526(initRegion);
|
||||
cia0 = new MOS6526(clockNum, clockDen*mainsFrq);
|
||||
cia1 = new MOS6526(clockNum, clockDen*mainsFrq);
|
||||
colorRam = new Chip2114();
|
||||
cpu = new MOS6510();
|
||||
pla = new MOSPLA();
|
||||
ram = new Chip4864();
|
||||
serPort = new SerialPort();
|
||||
sid = MOS6581.Create(44100, initRegion);
|
||||
sid = MOS6581.Create(44100, clockNum, clockDen);
|
||||
switch (initRegion)
|
||||
{
|
||||
case Region.NTSC: vic = MOS6567.Create(); break;
|
||||
case Region.PAL: vic = MOS6569.Create(); break;
|
||||
case C64.VicType.NTSC: vic = MOS6567R8.Create(); break;
|
||||
case C64.VicType.PAL: vic = MOS6569.Create(); break;
|
||||
case C64.VicType.NTSC_OLD: vic = MOS6567R56A.Create(); break;
|
||||
case C64.VicType.DREAN: vic = MOS6572.Create(); break;
|
||||
}
|
||||
userPort = new UserPortDevice();
|
||||
}
|
||||
|
@ -102,6 +125,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
sid.HardReset();
|
||||
vic.HardReset();
|
||||
userPort.HardReset();
|
||||
cassPort.HardReset();
|
||||
|
||||
// because of how mapping works, the cpu needs to be hard reset twice
|
||||
cpu.HardReset();
|
||||
|
|
|
@ -4,28 +4,25 @@ using System.IO;
|
|||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Computers.Commodore64.MOS;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||
{
|
||||
// TODO: use the EMulation.Common Region enum
|
||||
public enum Region
|
||||
{
|
||||
NTSC,
|
||||
PAL
|
||||
}
|
||||
|
||||
[CoreAttributes(
|
||||
"C64Hawk",
|
||||
"SaxxonPIke",
|
||||
isPorted: false,
|
||||
isReleased: false
|
||||
)]
|
||||
[ServiceNotApplicable(typeof(IRegionable), typeof(ISettable<,>))]
|
||||
sealed public partial class C64 : IEmulator, IStatable, IInputPollable, IDriveLight, IDebuggable
|
||||
[ServiceNotApplicable(typeof(ISettable<,>))]
|
||||
sealed public partial class C64 : IEmulator, IStatable, IInputPollable, IDriveLight, IDebuggable, IDisassemblable, IRegionable, ISettable<C64.C64Settings, C64.C64SyncSettings>
|
||||
{
|
||||
// framework
|
||||
public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension)
|
||||
public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension, object Settings, object SyncSettings)
|
||||
{
|
||||
PutSyncSettings((C64SyncSettings)SyncSettings ?? new C64SyncSettings());
|
||||
PutSettings((C64Settings)Settings ?? new C64Settings());
|
||||
|
||||
ServiceProvider = new BasicServiceProvider(this);
|
||||
InputCallbacks = new InputCallbackSystem();
|
||||
|
||||
|
@ -33,14 +30,37 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
inputFileInfo.Data = rom;
|
||||
inputFileInfo.Extension = romextension;
|
||||
CoreComm = comm;
|
||||
Init(Region.PAL);
|
||||
Init(this.SyncSettings.vicType);
|
||||
cyclesPerFrame = board.vic.CyclesPerFrame;
|
||||
SetupMemoryDomains();
|
||||
MemoryCallbacks = new MemoryCallbackSystem();
|
||||
HardReset();
|
||||
|
||||
(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(board.vic);
|
||||
}
|
||||
|
||||
|
||||
/*private DisplayType queryUserForRegion()
|
||||
{
|
||||
Form prompt = new Form() { Width = 160, Height = 120, FormBorderStyle = FormBorderStyle.FixedDialog, Text = "Region selector", StartPosition = FormStartPosition.CenterScreen };
|
||||
Label textLabel = new Label() { Left = 10, Top = 10, Width = 260, Text = "Please choose a region:" };
|
||||
RadioButton palButton = new RadioButton() { Left = 10, Top = 30, Width = 70, Text = "PAL", Checked = true };
|
||||
RadioButton ntscButton = new RadioButton() { Left = 80, Top = 30, Width = 70, Text = "NTSC" };
|
||||
Button confirmation = new Button() { Text = "Ok", Left = 40, Width = 80, Top = 60, DialogResult = DialogResult.OK };
|
||||
confirmation.Click += (sender, e) => { prompt.Close(); };
|
||||
prompt.Controls.Add(textLabel);
|
||||
prompt.Controls.Add(palButton);
|
||||
prompt.Controls.Add(ntscButton);
|
||||
prompt.Controls.Add(confirmation);
|
||||
prompt.AcceptButton = confirmation;
|
||||
|
||||
if (prompt.ShowDialog() != DialogResult.OK || !palButton.Checked && !ntscButton.Checked)
|
||||
{
|
||||
throw new Exception("Can't construct new C64 because you didn't choose anything");
|
||||
}
|
||||
return palButton.Checked ? DisplayType.PAL : DisplayType.NTSC;
|
||||
}*/
|
||||
|
||||
// internal variables
|
||||
private int _frame = 0;
|
||||
private int cyclesPerFrame;
|
||||
|
@ -63,6 +83,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
_frame = 0;
|
||||
_lagcount = 0;
|
||||
_islag = false;
|
||||
frameCycles = 0;
|
||||
}
|
||||
|
||||
// audio/video
|
||||
|
@ -92,6 +113,12 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
|
||||
public IEmulatorServiceProvider ServiceProvider { get; private set; }
|
||||
|
||||
public DisplayType Region
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (board.sid != null)
|
||||
|
@ -101,76 +128,66 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
}
|
||||
}
|
||||
|
||||
int frameCycles;
|
||||
|
||||
// process frame
|
||||
public void FrameAdvance(bool render, bool rendersound)
|
||||
{
|
||||
board.inputRead = false;
|
||||
board.PollInput();
|
||||
board.cpu.LagCycles = 0;
|
||||
|
||||
for (int count = 0; count < cyclesPerFrame; count++)
|
||||
do
|
||||
{
|
||||
//disk.Execute();
|
||||
board.Execute();
|
||||
DoCycle();
|
||||
}
|
||||
while (frameCycles != 0);
|
||||
}
|
||||
|
||||
#if false
|
||||
if (board.cpu.PC == 0xE16F && (board.cpu.ReadPort() & 0x7) == 7)
|
||||
private void DoCycle()
|
||||
{
|
||||
if (frameCycles == 0) {
|
||||
board.inputRead = false;
|
||||
board.PollInput();
|
||||
board.cpu.LagCycles = 0;
|
||||
}
|
||||
|
||||
//disk.Execute();
|
||||
board.Execute();
|
||||
frameCycles++;
|
||||
|
||||
// load PRG file if needed
|
||||
if (loadPrg)
|
||||
{
|
||||
// check to see if cpu PC is at the BASIC warm start vector
|
||||
if (board.cpu.PC == ((board.ram.Peek(0x0303) << 8) | board.ram.Peek(0x0302)))
|
||||
{
|
||||
// HUGE kernal hack to load files
|
||||
// the only purpose for this is to be able to run the Lorenz
|
||||
// test suite!
|
||||
//board.ram.Poke(0x0302, 0xAE);
|
||||
//board.ram.Poke(0x0303, 0xA7);
|
||||
////board.ram.Poke(0x0302, board.ram.Peek(0x0308));
|
||||
////board.ram.Poke(0x0303, board.ram.Peek(0x0309));
|
||||
|
||||
int fileNameLength = board.ram.Peek(0xB7);
|
||||
int fileNameOffset = board.ram.Peek(0xBB) | ((int)board.ram.Peek(0xBC) << 8);
|
||||
byte[] fileNameRaw = new byte[fileNameLength];
|
||||
for (int i = 0; i < fileNameLength; i++)
|
||||
{
|
||||
fileNameRaw[i] = board.ram.Peek(fileNameOffset + i);
|
||||
}
|
||||
var enc = System.Text.Encoding.ASCII;
|
||||
string fileName = enc.GetString(fileNameRaw);
|
||||
string filePath = Path.Combine(@"E:\Programming\Visual Studio 2013\Vice\testprogs\general\Lorenz-2.15\src\", fileName + ".prg");
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
PRG.Load(board.pla, File.ReadAllBytes(filePath));
|
||||
}
|
||||
board.cpu.PC = 0xE1B5;
|
||||
}
|
||||
#endif
|
||||
|
||||
// load PRG file if needed
|
||||
if (loadPrg)
|
||||
{
|
||||
// check to see if cpu PC is at the BASIC warm start vector
|
||||
if (board.cpu.PC == ((board.ram.Peek(0x0303) << 8) | board.ram.Peek(0x0302)))
|
||||
{
|
||||
//board.ram.Poke(0x0302, 0xAE);
|
||||
//board.ram.Poke(0x0303, 0xA7);
|
||||
////board.ram.Poke(0x0302, board.ram.Peek(0x0308));
|
||||
////board.ram.Poke(0x0303, board.ram.Peek(0x0309));
|
||||
|
||||
//if (inputFileInfo.Data.Length >= 6)
|
||||
//{
|
||||
// board.ram.Poke(0x0039, inputFileInfo.Data[4]);
|
||||
// board.ram.Poke(0x003A, inputFileInfo.Data[5]);
|
||||
//}
|
||||
PRG.Load(board.pla, inputFileInfo.Data);
|
||||
loadPrg = false;
|
||||
}
|
||||
//if (inputFileInfo.Data.Length >= 6)
|
||||
//{
|
||||
// board.ram.Poke(0x0039, inputFileInfo.Data[4]);
|
||||
// board.ram.Poke(0x003A, inputFileInfo.Data[5]);
|
||||
//}
|
||||
PRG.Load(board.pla, inputFileInfo.Data);
|
||||
loadPrg = false;
|
||||
}
|
||||
}
|
||||
|
||||
board.Flush();
|
||||
_islag = !board.inputRead;
|
||||
if (frameCycles == cyclesPerFrame)
|
||||
{
|
||||
board.Flush();
|
||||
_islag = !board.inputRead;
|
||||
|
||||
if (_islag)
|
||||
_lagcount++;
|
||||
_frame++;
|
||||
if (_islag)
|
||||
_lagcount++;
|
||||
frameCycles -= cyclesPerFrame;
|
||||
_frame++;
|
||||
|
||||
//Console.WriteLine("CPUPC: " + C64Util.ToHex(board.cpu.PC, 4) + " 1541PC: " + C64Util.ToHex(disk.PC, 4));
|
||||
//Console.WriteLine("CPUPC: " + C64Util.ToHex(board.cpu.PC, 4) + " 1541PC: " + C64Util.ToHex(disk.PC, 4));
|
||||
|
||||
int test = board.cpu.LagCycles;
|
||||
DriveLightOn = DriveLED;
|
||||
int test = board.cpu.LagCycles;
|
||||
DriveLightOn = DriveLED;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleFirmwareError(string file)
|
||||
|
@ -190,7 +207,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
return result;
|
||||
}
|
||||
|
||||
private void Init(Region initRegion)
|
||||
private void Init(VicType initRegion)
|
||||
{
|
||||
board = new Motherboard(this, initRegion);
|
||||
InitRoms();
|
||||
|
@ -213,6 +230,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
board.cartPort.Connect(cart);
|
||||
}
|
||||
break;
|
||||
case @".TAP":
|
||||
CassettePort.Tape tape = CassettePort.Tape.Load(inputFileInfo.Data);
|
||||
if (tape != null)
|
||||
{
|
||||
board.cassPort.Connect(tape);
|
||||
}
|
||||
break;
|
||||
case @".PRG":
|
||||
if (inputFileInfo.Data.Length > 2)
|
||||
loadPrg = true;
|
||||
|
|
|
@ -11,24 +11,31 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.CassettePort
|
|||
{
|
||||
public Func<bool> ReadDataOutput;
|
||||
public Func<bool> ReadMotor;
|
||||
Commodore64.CassettePort.Tape tape;
|
||||
|
||||
public void HardReset()
|
||||
{
|
||||
if (tape != null) tape.rewind();
|
||||
}
|
||||
|
||||
virtual public bool ReadDataInputBuffer()
|
||||
{
|
||||
return true;
|
||||
return tape != null && !ReadMotor() ? tape.read() : true;
|
||||
}
|
||||
|
||||
virtual public bool ReadSenseBuffer()
|
||||
{
|
||||
return true;
|
||||
return tape == null; // Just assume that "play" is constantly pressed as long as a tape is inserted
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
SaveState.SyncObject(ser, this);
|
||||
}
|
||||
|
||||
internal void Connect(Tape tape)
|
||||
{
|
||||
this.tape = tape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64.CassettePort
|
||||
{
|
||||
/**
|
||||
* This class represents a tape. Only TAP-style tapes are supported for now.
|
||||
*/
|
||||
class Tape
|
||||
{
|
||||
private readonly byte[] tapeData;
|
||||
private readonly byte version;
|
||||
private uint pos, cycle;
|
||||
private readonly uint start, end;
|
||||
|
||||
public Tape(byte version, byte[] tapeData, uint start, uint end)
|
||||
{
|
||||
this.version = version;
|
||||
this.tapeData = tapeData;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
rewind();
|
||||
}
|
||||
|
||||
// Rewinds the tape back to start
|
||||
public void rewind()
|
||||
{
|
||||
pos = start;
|
||||
cycle = 0;
|
||||
}
|
||||
|
||||
// Reads from tape, this will tell the caller if the flag pin should be raised
|
||||
public bool read()
|
||||
{
|
||||
if (cycle == 0)
|
||||
{
|
||||
if (pos >= end)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycle = ((uint)tapeData[pos++])*8;
|
||||
if (cycle == 0)
|
||||
{
|
||||
if (version == 0)
|
||||
{
|
||||
cycle = 256 * 8; // unspecified overflow condition
|
||||
}
|
||||
else
|
||||
{
|
||||
cycle = BitConverter.ToUInt32(tapeData, (int)pos-1)>>8;
|
||||
pos += 3;
|
||||
if (cycle == 0)
|
||||
{
|
||||
throw new Exception("Bad tape data");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send a single negative pulse at the end of a cycle
|
||||
return --cycle != 0;
|
||||
}
|
||||
|
||||
// Try to construct a tape file from file data. Returns null if not a tape file, throws exceptions for bad tape files.
|
||||
// (Note that some error conditions aren't caught right here.)
|
||||
static public Tape Load(byte[] tapeFile)
|
||||
{
|
||||
Tape result = null;
|
||||
|
||||
if (System.Text.Encoding.ASCII.GetString(tapeFile, 0, 12) == "C64-TAPE-RAW")
|
||||
{
|
||||
byte version = tapeFile[12];
|
||||
if (version > 1) throw new Exception("This tape has an unsupported version");
|
||||
uint size = BitConverter.ToUInt32(tapeFile, 16);
|
||||
if (size + 20 != tapeFile.Length)
|
||||
{
|
||||
throw new Exception("Tape file header specifies a length that doesn't match the file size");
|
||||
}
|
||||
result = new Tape(version, tapeFile, 20, (uint)tapeFile.Length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("tape");
|
||||
ser.Sync("pos", ref pos);
|
||||
ser.Sync("cycle", ref cycle);
|
||||
ser.EndSection();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
using System;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
||||
{
|
||||
public class CassettePort
|
||||
{
|
||||
public Func<bool> ReadDataOutput;
|
||||
public Func<bool> ReadMotor;
|
||||
|
||||
public void HardReset()
|
||||
{
|
||||
}
|
||||
|
||||
virtual public bool ReadDataInputBuffer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual public bool ReadSenseBuffer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
SaveState.SyncObject(ser, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,9 +99,14 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
}
|
||||
set
|
||||
{
|
||||
lagCycles = value;
|
||||
}
|
||||
}
|
||||
lagCycles = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool AtInstructionStart()
|
||||
{
|
||||
return cpu.AtInstructionStart();
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
LatchedPort portA;
|
||||
LatchedPort portB;
|
||||
|
||||
public MOS6526_2(Region region)
|
||||
public MOS6526_2(Common.DisplayType region)
|
||||
{
|
||||
a = new CiaTimer(serialPortA, underFlowA);
|
||||
b = new CiaTimer(serialPortB, underFlowB);
|
||||
|
@ -241,10 +241,10 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
portB = new LatchedPort();
|
||||
switch (region)
|
||||
{
|
||||
case Region.NTSC:
|
||||
case Common.DisplayType.NTSC:
|
||||
tod_period = 14318181 / 140;
|
||||
break;
|
||||
case Region.PAL:
|
||||
case Common.DisplayType.PAL:
|
||||
tod_period = 17734472 / 180;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
// ------------------------------------
|
||||
|
||||
bool alarmSelect;
|
||||
Region chipRegion;
|
||||
bool cntPos;
|
||||
bool enableIntAlarm;
|
||||
bool enableIntFlag;
|
||||
|
@ -77,16 +76,22 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
byte[] todAlarm;
|
||||
bool todAlarmPM;
|
||||
int todCounter;
|
||||
int todCounterLatch;
|
||||
bool todIn;
|
||||
bool todPM;
|
||||
|
||||
bool oldFlag;
|
||||
// ------------------------------------
|
||||
|
||||
public MOS6526(Region region)
|
||||
int todStepsNum;
|
||||
int todStepsDen;
|
||||
|
||||
// todStepsNum/todStepsDen is the number of clock cycles it takes the external clock source to advance one cycle
|
||||
// (50 or 60 Hz depending on AC frequency in use).
|
||||
// By default the CIA assumes 60 Hz and will thus count incorrectly when fed with 50 Hz.
|
||||
public MOS6526(int todStepsNum, int todStepsDen)
|
||||
{
|
||||
chipRegion = region;
|
||||
enableIntTimer = new bool[2];
|
||||
this.todStepsNum = todStepsNum;
|
||||
this.todStepsDen = todStepsDen;
|
||||
enableIntTimer = new bool[2];
|
||||
intTimer = new bool[2];
|
||||
timerDelay = new int[2];
|
||||
timerInMode = new InMode[2];
|
||||
|
@ -96,7 +101,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
timerRunMode = new RunMode[2];
|
||||
tod = new byte[4];
|
||||
todAlarm = new byte[4];
|
||||
SetTodIn(chipRegion);
|
||||
|
||||
portA = new LatchedPort();
|
||||
portB = new LatchedPort();
|
||||
|
@ -161,6 +165,10 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
cntPos = false;
|
||||
underflow[0] = false;
|
||||
underflow[1] = false;
|
||||
|
||||
bool newFlag = ReadFlag();
|
||||
intFlag |= oldFlag && !newFlag;
|
||||
oldFlag = newFlag;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,29 +211,14 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
todAlarm[1] = 0;
|
||||
todAlarm[2] = 0;
|
||||
todAlarm[3] = 0;
|
||||
todCounter = todCounterLatch;
|
||||
todIn = (chipRegion == Region.PAL);
|
||||
todCounter = 0;
|
||||
todIn = false;
|
||||
todPM = false;
|
||||
|
||||
pinCnt = false;
|
||||
pinPC = true;
|
||||
}
|
||||
|
||||
private void SetTodIn(Region region)
|
||||
{
|
||||
switch (region)
|
||||
{
|
||||
case Region.NTSC:
|
||||
todCounterLatch = 14318181 / 140;
|
||||
todIn = false;
|
||||
break;
|
||||
case Region.PAL:
|
||||
todCounterLatch = 17734472 / 180;
|
||||
todIn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
private byte BCDAdd(byte i, byte j, out bool overflow)
|
||||
|
@ -338,9 +331,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
{
|
||||
bool todV;
|
||||
|
||||
if (todCounter == 0)
|
||||
if (todCounter <= 0)
|
||||
{
|
||||
todCounter = todCounterLatch;
|
||||
todCounter += todStepsNum*(todIn ? 6 : 5);
|
||||
tod[0] = BCDAdd(tod[0], 1, out todV);
|
||||
if (tod[0] >= 10)
|
||||
{
|
||||
|
@ -366,7 +359,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
}
|
||||
}
|
||||
}
|
||||
todCounter--;
|
||||
todCounter -= todStepsDen;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
||||
{
|
||||
// vic ntsc old
|
||||
// TODO is everything right? it's mostly a copy from the other NTSC chip with tweaks wherever it was neccessary to fix something
|
||||
static public class MOS6567R56A
|
||||
{
|
||||
static int cycles = 64;
|
||||
static int scanwidth = cycles * 8;
|
||||
static int lines = 262;
|
||||
static int vblankstart = 0x00D % lines;
|
||||
static int vblankend = 0x018 % lines;
|
||||
static int hblankoffset = 20;
|
||||
static int hblankstart = (0x18C + hblankoffset) % scanwidth;
|
||||
static int hblankend = (0x1F0 + hblankoffset) % scanwidth;
|
||||
|
||||
static int[] timing = Vic.TimingBuilder_XRaster(0x19C, 0x200, scanwidth, -1, -1);
|
||||
static int[] fetch = Vic.TimingBuilder_Fetch(timing, 0x174);
|
||||
static int[] ba = Vic.TimingBuilder_BA(fetch);
|
||||
static int[] act = Vic.TimingBuilder_Act(timing, 0x004, 0x14C, hblankstart, hblankend);
|
||||
|
||||
static int[][] pipeline = new int[][]
|
||||
{
|
||||
timing,
|
||||
fetch,
|
||||
ba,
|
||||
act
|
||||
};
|
||||
|
||||
static public Vic Create()
|
||||
{
|
||||
return new Vic(
|
||||
cycles, lines,
|
||||
pipeline,
|
||||
14318181 / 14,
|
||||
hblankstart, hblankend,
|
||||
vblankstart, vblankend
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +1,41 @@
|
|||
using System.Drawing;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
||||
{
|
||||
// vic ntsc
|
||||
static public class MOS6567
|
||||
{
|
||||
static int cycles = 65;
|
||||
static int scanwidth = cycles * 8;
|
||||
static int lines = 263;
|
||||
static int vblankstart = 0x00D % lines;
|
||||
static int vblankend = 0x018 % lines;
|
||||
static int hblankoffset = 20;
|
||||
static int hblankstart = (0x18C + hblankoffset) % scanwidth;
|
||||
static int hblankend = (0x1F0 + hblankoffset) % scanwidth;
|
||||
|
||||
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, hblankstart, hblankend);
|
||||
|
||||
static int[][] pipeline = new int[][]
|
||||
{
|
||||
timing,
|
||||
fetch,
|
||||
ba,
|
||||
act
|
||||
};
|
||||
|
||||
static public Vic Create()
|
||||
{
|
||||
return new Vic(
|
||||
cycles, lines,
|
||||
pipeline,
|
||||
14318181 / 14,
|
||||
hblankstart, hblankend,
|
||||
vblankstart, vblankend
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Drawing;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
||||
{
|
||||
// vic ntsc
|
||||
static public class MOS6567R8
|
||||
{
|
||||
static int cycles = 65;
|
||||
static int scanwidth = cycles * 8;
|
||||
static int lines = 263;
|
||||
static int vblankstart = 0x00D % lines;
|
||||
static int vblankend = 0x018 % lines;
|
||||
static int hblankoffset = 20;
|
||||
static int hblankstart = (0x18C + hblankoffset) % scanwidth - 8; // -8 because the VIC repeats internal pixel cycles around 0x18C
|
||||
static int hblankend = (0x1F0 + hblankoffset) % scanwidth - 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, hblankstart, hblankend);
|
||||
|
||||
static int[][] pipeline = new int[][]
|
||||
{
|
||||
timing,
|
||||
fetch,
|
||||
ba,
|
||||
act
|
||||
};
|
||||
|
||||
static public Vic Create()
|
||||
{
|
||||
return new Vic(
|
||||
cycles, lines,
|
||||
pipeline,
|
||||
14318181 / 14,
|
||||
hblankstart, hblankend,
|
||||
vblankstart, vblankend
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
||||
{
|
||||
// pal n / drean - TODO correct?
|
||||
class MOS6572
|
||||
{
|
||||
static int cycles = 65;
|
||||
static int scanwidth = cycles * 8;
|
||||
static int lines = 312;
|
||||
static int vblankstart = 0x12C % lines;
|
||||
static int vblankend = 0x00F % lines;
|
||||
static int hblankoffset = 20;
|
||||
static int hblankstart = (0x18C + hblankoffset) % scanwidth - 8; // -8 because the VIC repeats internal pixel cycles around 0x18C
|
||||
static int hblankend = (0x1F0 + hblankoffset) % scanwidth - 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, hblankstart, hblankend);
|
||||
|
||||
static int[][] pipeline = new int[][]
|
||||
{
|
||||
timing,
|
||||
fetch,
|
||||
ba,
|
||||
act
|
||||
};
|
||||
|
||||
static public Vic Create()
|
||||
{
|
||||
return new Vic(
|
||||
cycles, lines,
|
||||
pipeline,
|
||||
14328225 / 14,
|
||||
hblankstart, hblankend,
|
||||
vblankstart, vblankend
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4119,9 +4119,9 @@
|
|||
}
|
||||
};
|
||||
|
||||
static public Sid Create(int newSampleRate, Region newRegion)
|
||||
static public Sid Create(int newSampleRate, int clockFrqNum, int clockFrqDen)
|
||||
{
|
||||
return new Sid(waveTable, newSampleRate, newRegion);
|
||||
return new Sid(waveTable, (uint)newSampleRate, (uint)clockFrqNum, (uint)clockFrqDen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,20 +42,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
public Func<byte> ReadPotX;
|
||||
public Func<byte> ReadPotY;
|
||||
|
||||
public Sid(int[][] newWaveformTable, int newSampleRate, Region newRegion)
|
||||
public Sid(int[][] newWaveformTable, uint sampleRate, uint cyclesNum, uint cyclesDen)
|
||||
{
|
||||
uint cyclesPerSec = 0;
|
||||
uint cyclesNum;
|
||||
uint cyclesDen;
|
||||
uint sampleRate = 44100;
|
||||
|
||||
switch (newRegion)
|
||||
{
|
||||
case Region.NTSC: cyclesNum = 14318181; cyclesDen = 14; break;
|
||||
case Region.PAL: cyclesNum = 17734472; cyclesDen = 18; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
waveformTable = newWaveformTable;
|
||||
|
||||
envelopes = new Envelope[3];
|
||||
|
|
|
@ -145,8 +145,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
}
|
||||
else if (parseba == 0x1000)
|
||||
{
|
||||
pinBA = !badline;
|
||||
}
|
||||
pinBA = !badline;
|
||||
}
|
||||
else
|
||||
{
|
||||
parsecycleBAsprite0 = (parseba & 0x000F);
|
||||
|
|
|
@ -75,6 +75,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
}
|
||||
|
||||
// display enable compare
|
||||
if (rasterLine == 0)
|
||||
badlineEnable = false;
|
||||
|
||||
if (rasterLine == 0x030)
|
||||
badlineEnable |= displayEnable;
|
||||
|
||||
|
|
Loading…
Reference in New Issue