dev_4VirtualNes #18
@ -62,5 +62,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
romName = Path.GetFileNameWithoutExtension(romName);
|
romName = Path.GetFileNameWithoutExtension(romName);
|
||||||
File.WriteAllBytes($"{diskFileDirectoryPath}/{romName}.dsv", diskFileContent);
|
File.WriteAllBytes($"{diskFileDirectoryPath}/{romName}.dsv", diskFileContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EmulatorConfig Config { get; private set; } = new EmulatorConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
StartGame("Kirby.nes");
|
||||||
//StartGame("Kirby.nes");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartGame(string romName)
|
public void StartGame(string romName)
|
||||||
|
@ -10,6 +10,12 @@ namespace VirtualNes.Core
|
|||||||
private NES nes;
|
private NES nes;
|
||||||
private byte exsound_select;
|
private byte exsound_select;
|
||||||
private APU_INTERNAL @internal = new APU_INTERNAL();
|
private APU_INTERNAL @internal = new APU_INTERNAL();
|
||||||
|
private APU_VRC6 vrc6 = new APU_VRC6();
|
||||||
|
private APU_VRC7 vrc7 = new APU_VRC7();
|
||||||
|
private APU_MMC5 mmc5 = new APU_MMC5();
|
||||||
|
private APU_FDS fds = new APU_FDS();
|
||||||
|
private APU_N106 n106 = new APU_N106();
|
||||||
|
private APU_FME7 fme7 = new APU_FME7();
|
||||||
private int last_data;
|
private int last_data;
|
||||||
private int last_diff;
|
private int last_diff;
|
||||||
protected short[] m_SoundBuffer = new short[256];
|
protected short[] m_SoundBuffer = new short[256];
|
||||||
@ -17,6 +23,7 @@ namespace VirtualNes.Core
|
|||||||
protected QUEUE queue = new QUEUE();
|
protected QUEUE queue = new QUEUE();
|
||||||
protected QUEUE exqueue = new QUEUE();
|
protected QUEUE exqueue = new QUEUE();
|
||||||
protected bool[] m_bMute = new bool[16];
|
protected bool[] m_bMute = new bool[16];
|
||||||
|
protected double elapsed_time;
|
||||||
|
|
||||||
public APU(NES parent)
|
public APU(NES parent)
|
||||||
{
|
{
|
||||||
@ -90,6 +97,81 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SoundSetup()
|
||||||
|
{
|
||||||
|
float fClock = nes.nescfg.CpuClock;
|
||||||
|
int nRate = Supporter.Config.sound.nRate;
|
||||||
|
|
||||||
|
@internal.Setup(fClock, nRate);
|
||||||
|
vrc6.Setup(fClock, nRate);
|
||||||
|
vrc7.Setup(fClock, nRate);
|
||||||
|
mmc5.Setup(fClock, nRate);
|
||||||
|
fds.Setup(fClock, nRate);
|
||||||
|
n106.Setup(fClock, nRate);
|
||||||
|
fme7.Setup(fClock, nRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SelectExSound(byte data)
|
||||||
|
{
|
||||||
|
exsound_select = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Reset()
|
||||||
|
{
|
||||||
|
queue = new QUEUE();
|
||||||
|
exqueue = new QUEUE();
|
||||||
|
|
||||||
|
elapsed_time = 0;
|
||||||
|
|
||||||
|
float fClock = nes.nescfg.CpuClock;
|
||||||
|
int nRate = Supporter.Config.sound.nRate;
|
||||||
|
|
||||||
|
@internal.Reset(fClock, nRate);
|
||||||
|
vrc6.Reset(fClock, nRate);
|
||||||
|
vrc7.Reset(fClock, nRate);
|
||||||
|
mmc5.Reset(fClock, nRate);
|
||||||
|
fds.Reset(fClock, nRate);
|
||||||
|
n106.Reset(fClock, nRate);
|
||||||
|
fme7.Reset(fClock, nRate);
|
||||||
|
|
||||||
|
SoundSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ExWrite(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
SetExQueue(nes.cpu.GetTotalCycles(), addr, data);
|
||||||
|
|
||||||
|
if ((exsound_select & 0x04) != 0)
|
||||||
|
{
|
||||||
|
if (addr >= 0x4040 && addr < 0x4100)
|
||||||
|
{
|
||||||
|
fds.SyncWrite(addr, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((exsound_select & 0x08) != 0)
|
||||||
|
{
|
||||||
|
if (addr >= 0x5000 && addr <= 0x5015)
|
||||||
|
{
|
||||||
|
mmc5.SyncWrite(addr, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetExQueue(int writetime, ushort addr, byte data)
|
||||||
|
{
|
||||||
|
exqueue.data[exqueue.wrptr].time = writetime;
|
||||||
|
exqueue.data[exqueue.wrptr].addr = addr;
|
||||||
|
exqueue.data[exqueue.wrptr].data = data;
|
||||||
|
exqueue.wrptr++;
|
||||||
|
var temp = QUEUE_LENGTH - 1;
|
||||||
|
exqueue.wrptr = (int)(exqueue.wrptr & temp);
|
||||||
|
if (exqueue.wrptr == exqueue.rdptr)
|
||||||
|
{
|
||||||
|
Debuger.LogError("exqueue overflow.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct QUEUEDATA
|
public struct QUEUEDATA
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class APU_FDS : APU_INTERFACE
|
||||||
|
{
|
||||||
|
private FDSSOUND fds = new FDSSOUND();
|
||||||
|
private FDSSOUND fds_sync = new FDSSOUND();
|
||||||
|
|
||||||
|
public override void Reset(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Process(int channel)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SyncWrite(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
WriteSub(addr, data, fds_sync, 1789772.5d);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WriteSub(ushort addr, byte data, FDSSOUND ch, double rate)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FDSSOUND
|
||||||
|
{
|
||||||
|
//todo : 实现
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5e16912525198924a860e53ab4ef0c81
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class APU_FME7 : APU_INTERFACE
|
||||||
|
{
|
||||||
|
public override void Reset(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Process(int channel)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 03e0258857a7134438a497aec27ea607
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,13 +1,11 @@
|
|||||||
using System;
|
namespace VirtualNes.Core
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
|
||||||
{
|
{
|
||||||
public abstract class APU_INTERFACE
|
public abstract class APU_INTERFACE
|
||||||
{
|
{
|
||||||
|
public const float APU_CLOCK = 1789772.5f;
|
||||||
|
|
||||||
|
public virtual void Dispose() { }
|
||||||
|
|
||||||
public abstract void Reset(float fClock, int nRate);
|
public abstract void Reset(float fClock, int nRate);
|
||||||
public abstract void Setup(float fClock, int nRate);
|
public abstract void Setup(float fClock, int nRate);
|
||||||
public abstract void Write(ushort addr, byte data);
|
public abstract void Write(ushort addr, byte data);
|
||||||
@ -24,5 +22,15 @@ namespace VirtualNes.Core
|
|||||||
public virtual int GetStateSize() { return 0; }
|
public virtual int GetStateSize() { return 0; }
|
||||||
public virtual void SaveState(byte[] p) { }
|
public virtual void SaveState(byte[] p) { }
|
||||||
public virtual void LoadState(byte[] p) { }
|
public virtual void LoadState(byte[] p) { }
|
||||||
|
|
||||||
|
public static int INT2FIX(int x)
|
||||||
|
{
|
||||||
|
return x << 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int FIX2INT(int x)
|
||||||
|
{
|
||||||
|
return x >> 16;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public class APU_INTERNAL : APU_INTERFACE
|
public class APU_INTERNAL : APU_INTERFACE
|
||||||
@ -63,8 +61,43 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
private bool SyncUpdateDPCM(int cycles)
|
private bool SyncUpdateDPCM(int cycles)
|
||||||
{
|
{
|
||||||
//TODO : 实现
|
bool bIRQ = false;
|
||||||
return false;
|
|
||||||
|
if (ch4.sync_enable != 0)
|
||||||
|
{
|
||||||
|
ch4.sync_cycles -= cycles;
|
||||||
|
while (ch4.sync_cycles < 0)
|
||||||
|
{
|
||||||
|
ch4.sync_cycles += ch4.sync_cache_cycles;
|
||||||
|
if (ch4.sync_dmalength != 0)
|
||||||
|
{
|
||||||
|
// if( !(--ch4.sync_dmalength) ) {
|
||||||
|
if (--ch4.sync_dmalength < 2)
|
||||||
|
{
|
||||||
|
if (ch4.sync_looping != 0)
|
||||||
|
{
|
||||||
|
ch4.sync_dmalength = ch4.sync_cache_dmalength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch4.sync_dmalength = 0;
|
||||||
|
|
||||||
|
if (ch4.sync_irq_gen != 0)
|
||||||
|
{
|
||||||
|
ch4.sync_irq_enable = 0xFF;
|
||||||
|
nes.cpu.SetIRQ(CPU.IRQ_DPCM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ch4.sync_irq_enable != 0)
|
||||||
|
{
|
||||||
|
bIRQ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bIRQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFrame()
|
private void UpdateFrame()
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class APU_MMC5 : APU_INTERFACE
|
||||||
|
{
|
||||||
|
public override void Reset(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Process(int channel)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SyncWrite(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 15b983a12234c3c47baefb9fa2751351
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,25 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class APU_N106 : APU_INTERFACE
|
||||||
|
{
|
||||||
|
public override void Reset(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Process(int channel)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6a47ed257e942d4478215338d8fe4c35
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
310
AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_VRC6.cs
Normal file
310
AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_VRC6.cs
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class APU_VRC6 : APU_INTERFACE
|
||||||
|
{
|
||||||
|
public const int RECTANGLE_VOL_SHIFT = 8;
|
||||||
|
public const int SAWTOOTH_VOL_SHIFT = 6;
|
||||||
|
|
||||||
|
private RECTANGLE ch0 = new RECTANGLE();
|
||||||
|
private RECTANGLE ch1 = new RECTANGLE();
|
||||||
|
private SAWTOOTH ch2 = new SAWTOOTH();
|
||||||
|
|
||||||
|
private int cycle_rate;
|
||||||
|
private float cpu_clock;
|
||||||
|
|
||||||
|
public APU_VRC6()
|
||||||
|
{
|
||||||
|
Reset(APU_CLOCK, 22050);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
ch0.ZeroMemory();
|
||||||
|
ch1.ZeroMemory();
|
||||||
|
ch2.ZeroMemory();
|
||||||
|
|
||||||
|
Setup(fClock, nRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
cpu_clock = fClock;
|
||||||
|
cycle_rate = (int)(fClock * 65536.0f / nRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
// VRC6 CH0 rectangle
|
||||||
|
case 0x9000:
|
||||||
|
ch0.reg[0] = data;
|
||||||
|
ch0.gate = (byte)(data & 0x80);
|
||||||
|
ch0.volume = (byte)(data & 0x0F);
|
||||||
|
ch0.duty_pos = (byte)((data >> 4) & 0x07);
|
||||||
|
break;
|
||||||
|
case 0x9001:
|
||||||
|
ch0.reg[1] = data;
|
||||||
|
ch0.freq = INT2FIX((((ch0.reg[2] & 0x0F) << 8) | data) + 1);
|
||||||
|
break;
|
||||||
|
case 0x9002:
|
||||||
|
ch0.reg[2] = data;
|
||||||
|
ch0.enable = (byte)(data & 0x80);
|
||||||
|
ch0.freq = INT2FIX((((data & 0x0F) << 8) | ch0.reg[1]) + 1);
|
||||||
|
break;
|
||||||
|
// VRC6 CH1 rectangle
|
||||||
|
case 0xA000:
|
||||||
|
ch1.reg[0] = data;
|
||||||
|
ch1.gate = (byte)(data & 0x80);
|
||||||
|
ch1.volume = (byte)(data & 0x0F);
|
||||||
|
ch1.duty_pos = (byte)((data >> 4) & 0x07);
|
||||||
|
break;
|
||||||
|
case 0xA001:
|
||||||
|
ch1.reg[1] = data;
|
||||||
|
ch1.freq = INT2FIX((((ch1.reg[2] & 0x0F) << 8) | data) + 1);
|
||||||
|
break;
|
||||||
|
case 0xA002:
|
||||||
|
ch1.reg[2] = data;
|
||||||
|
ch1.enable = (byte)(data & 0x80);
|
||||||
|
ch1.freq = INT2FIX((((data & 0x0F) << 8) | ch1.reg[1]) + 1);
|
||||||
|
break;
|
||||||
|
// VRC6 CH2 sawtooth
|
||||||
|
case 0xB000:
|
||||||
|
ch2.reg[1] = data;
|
||||||
|
ch2.phaseaccum = (byte)(data & 0x3F);
|
||||||
|
break;
|
||||||
|
case 0xB001:
|
||||||
|
ch2.reg[1] = data;
|
||||||
|
ch2.freq = INT2FIX((((ch2.reg[2] & 0x0F) << 8) | data) + 1);
|
||||||
|
break;
|
||||||
|
case 0xB002:
|
||||||
|
ch2.reg[2] = data;
|
||||||
|
ch2.enable = (byte)(data & 0x80);
|
||||||
|
ch2.freq = INT2FIX((((data & 0x0F) << 8) | ch2.reg[1]) + 1);
|
||||||
|
// ch2.adder = 0; // 僋儕傾偡傞偲僲僀僘偺尨場偵側傞
|
||||||
|
// ch2.accum = 0; // 僋儕傾偡傞偲僲僀僘偺尨場偵側傞
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Process(int channel)
|
||||||
|
{
|
||||||
|
switch (channel)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return RectangleRender(ch0);
|
||||||
|
case 1:
|
||||||
|
return RectangleRender(ch1);
|
||||||
|
case 2:
|
||||||
|
return SawtoothRender(ch2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetFreq(int channel)
|
||||||
|
{
|
||||||
|
if (channel == 0 || channel == 1)
|
||||||
|
{
|
||||||
|
RECTANGLE ch = null;
|
||||||
|
if (channel == 0) ch = ch0;
|
||||||
|
else ch = ch1;
|
||||||
|
if (ch.enable == 0 || ch.gate != 0 || ch.volume == 0)
|
||||||
|
return 0;
|
||||||
|
if (ch.freq < INT2FIX(8))
|
||||||
|
return 0;
|
||||||
|
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 16.0f));
|
||||||
|
}
|
||||||
|
if (channel == 2)
|
||||||
|
{
|
||||||
|
SAWTOOTH ch = ch2;
|
||||||
|
if (ch.enable == 0 || ch.phaseaccum == 0)
|
||||||
|
return 0;
|
||||||
|
if (ch.freq < INT2FIX(8))
|
||||||
|
return 0;
|
||||||
|
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 14.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int RectangleRender(RECTANGLE ch)
|
||||||
|
{
|
||||||
|
// Enable?
|
||||||
|
if (ch.enable == 0)
|
||||||
|
{
|
||||||
|
ch.output_vol = 0;
|
||||||
|
ch.adder = 0;
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Digitized output
|
||||||
|
if (ch.gate != 0)
|
||||||
|
{
|
||||||
|
ch.output_vol = ch.volume << RECTANGLE_VOL_SHIFT;
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 堦掕埲忋偺廃攇悢偼張棟偟側偄(柍懯)
|
||||||
|
if (ch.freq < INT2FIX(8))
|
||||||
|
{
|
||||||
|
ch.output_vol = 0;
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch.phaseacc -= cycle_rate;
|
||||||
|
if (ch.phaseacc >= 0)
|
||||||
|
return ch.output_vol;
|
||||||
|
|
||||||
|
int output = ch.volume << RECTANGLE_VOL_SHIFT;
|
||||||
|
|
||||||
|
if (ch.freq > cycle_rate)
|
||||||
|
{
|
||||||
|
// add 1 step
|
||||||
|
ch.phaseacc += ch.freq;
|
||||||
|
ch.adder = (byte)((ch.adder + 1) & 0x0F);
|
||||||
|
if (ch.adder <= ch.duty_pos)
|
||||||
|
ch.output_vol = output;
|
||||||
|
else
|
||||||
|
ch.output_vol = -output;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// average calculate
|
||||||
|
int num_times, total;
|
||||||
|
num_times = total = 0;
|
||||||
|
while (ch.phaseacc < 0)
|
||||||
|
{
|
||||||
|
ch.phaseacc += ch.freq;
|
||||||
|
ch.adder = (byte)((ch.adder + 1) & 0x0F);
|
||||||
|
if (ch.adder <= ch.duty_pos)
|
||||||
|
total += output;
|
||||||
|
else
|
||||||
|
total += -output;
|
||||||
|
num_times++;
|
||||||
|
}
|
||||||
|
ch.output_vol = total / num_times;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int SawtoothRender(SAWTOOTH ch)
|
||||||
|
{
|
||||||
|
// Digitized output
|
||||||
|
if (ch.enable == 0)
|
||||||
|
{
|
||||||
|
ch.output_vol = 0;
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 堦掕埲忋偺廃攇悢偼張棟偟側偄(柍懯)
|
||||||
|
if (ch.freq < INT2FIX(9))
|
||||||
|
{
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch.phaseacc -= cycle_rate / 2;
|
||||||
|
if (ch.phaseacc >= 0)
|
||||||
|
return ch.output_vol;
|
||||||
|
|
||||||
|
if (ch.freq > cycle_rate / 2)
|
||||||
|
{
|
||||||
|
// add 1 step
|
||||||
|
ch.phaseacc += ch.freq;
|
||||||
|
if (++ch.adder >= 7)
|
||||||
|
{
|
||||||
|
ch.adder = 0;
|
||||||
|
ch.accum = 0;
|
||||||
|
}
|
||||||
|
ch.accum += ch.phaseaccum;
|
||||||
|
ch.output_vol = ch.accum << SAWTOOTH_VOL_SHIFT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// average calculate
|
||||||
|
int num_times, total;
|
||||||
|
num_times = total = 0;
|
||||||
|
while (ch.phaseacc < 0)
|
||||||
|
{
|
||||||
|
ch.phaseacc += ch.freq;
|
||||||
|
if (++ch.adder >= 7)
|
||||||
|
{
|
||||||
|
ch.adder = 0;
|
||||||
|
ch.accum = 0;
|
||||||
|
}
|
||||||
|
ch.accum += ch.phaseaccum;
|
||||||
|
total += ch.accum << SAWTOOTH_VOL_SHIFT;
|
||||||
|
num_times++;
|
||||||
|
}
|
||||||
|
ch.output_vol = (total / num_times);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch.output_vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RECTANGLE
|
||||||
|
{
|
||||||
|
public byte[] reg = new byte[3];
|
||||||
|
|
||||||
|
public byte enable;
|
||||||
|
public byte gate;
|
||||||
|
public byte volume;
|
||||||
|
|
||||||
|
public int phaseacc;
|
||||||
|
public int freq;
|
||||||
|
public int output_vol;
|
||||||
|
|
||||||
|
public byte adder;
|
||||||
|
public byte duty_pos;
|
||||||
|
|
||||||
|
public void ZeroMemory()
|
||||||
|
{
|
||||||
|
Array.Clear(reg, 0, reg.Length);
|
||||||
|
enable = default;
|
||||||
|
gate = default;
|
||||||
|
volume = default;
|
||||||
|
|
||||||
|
phaseacc = default;
|
||||||
|
freq = default;
|
||||||
|
output_vol = default;
|
||||||
|
|
||||||
|
adder = default;
|
||||||
|
duty_pos = default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SAWTOOTH
|
||||||
|
{
|
||||||
|
public byte[] reg = new byte[3];
|
||||||
|
|
||||||
|
public byte enable;
|
||||||
|
public byte volume;
|
||||||
|
|
||||||
|
public int phaseacc;
|
||||||
|
public int freq;
|
||||||
|
public int output_vol;
|
||||||
|
|
||||||
|
public byte adder;
|
||||||
|
public byte accum;
|
||||||
|
public byte phaseaccum;
|
||||||
|
|
||||||
|
public void ZeroMemory()
|
||||||
|
{
|
||||||
|
Array.Clear(reg, 0, reg.Length);
|
||||||
|
enable = default;
|
||||||
|
volume = default;
|
||||||
|
|
||||||
|
phaseacc = default;
|
||||||
|
freq = default;
|
||||||
|
output_vol = default;
|
||||||
|
|
||||||
|
adder = default;
|
||||||
|
accum = default;
|
||||||
|
phaseaccum = default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 190f3271accd30f4eb5b13590417d265
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,25 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class APU_VRC7 : APU_INTERFACE
|
||||||
|
{
|
||||||
|
public override void Reset(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(float fClock, int nRate)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Process(int channel)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 180a87918f9d49e4fad978014f1d594f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,11 +1,4 @@
|
|||||||
using Codice.CM.Client.Differences;
|
namespace VirtualNes.Core
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
|
||||||
{
|
{
|
||||||
public class DPCM
|
public class DPCM
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace VirtualNes.Core
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
|
||||||
{
|
{
|
||||||
public class NOISE
|
public class NOISE
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -47,5 +43,43 @@ namespace VirtualNes.Core
|
|||||||
public byte sync_holdnote;
|
public byte sync_holdnote;
|
||||||
public byte dummy2;
|
public byte dummy2;
|
||||||
public int sync_len_count;
|
public int sync_len_count;
|
||||||
|
|
||||||
|
public void ZeroMemory()
|
||||||
|
{
|
||||||
|
Array.Clear(reg, 0, reg.Length);
|
||||||
|
enable = 0;
|
||||||
|
holdnote = 0;
|
||||||
|
volume = 0;
|
||||||
|
complement = 0;
|
||||||
|
|
||||||
|
phaseacc = 0;
|
||||||
|
freq = 0;
|
||||||
|
freqlimit = 0;
|
||||||
|
adder = 0;
|
||||||
|
duty = 0;
|
||||||
|
len_count = 0;
|
||||||
|
|
||||||
|
nowvolume = 0;
|
||||||
|
|
||||||
|
env_fixed = 0;
|
||||||
|
env_decay = 0;
|
||||||
|
env_count = 0;
|
||||||
|
dummy0 = 0;
|
||||||
|
env_vol = 0;
|
||||||
|
|
||||||
|
swp_on = 0;
|
||||||
|
swp_inc = 0;
|
||||||
|
swp_shift = 0;
|
||||||
|
swp_decay = 0;
|
||||||
|
swp_count = 0;
|
||||||
|
Array.Clear(dummy1, 0, dummy1.Length);
|
||||||
|
|
||||||
|
Array.Clear(sync_reg, 0, sync_reg.Length);
|
||||||
|
sync_output_enable = 0;
|
||||||
|
sync_enable = 0;
|
||||||
|
sync_holdnote = 0;
|
||||||
|
dummy2 = 0;
|
||||||
|
sync_len_count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
20
AxibugEmuOnline.Client/Assets/VirtualNes.Core/Cheat.cs
Normal file
20
AxibugEmuOnline.Client/Assets/VirtualNes.Core/Cheat.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CHEATCODE
|
||||||
|
{
|
||||||
|
public byte enable;
|
||||||
|
public byte type;
|
||||||
|
public byte length;
|
||||||
|
public ushort address;
|
||||||
|
public uint data;
|
||||||
|
|
||||||
|
public string comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GENIECODE
|
||||||
|
{
|
||||||
|
public ushort address;
|
||||||
|
public byte data;
|
||||||
|
public byte cmp;
|
||||||
|
};
|
||||||
|
}
|
@ -1,22 +1,17 @@
|
|||||||
using Codice.CM.Client.Differences;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Unity.VisualScripting.Antlr3.Runtime.Tree;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public static class CRC
|
public static class CRC
|
||||||
{
|
{
|
||||||
const int CHAR_BIT = 8;
|
const int CHAR_BIT = 8;
|
||||||
const ulong CRCPOLY1 = 0x04C11DB7UL;
|
const uint CRCPOLY1 = 0x04C11DB7U;
|
||||||
const ulong CRCPOLY2 = 0xEDB88320UL;
|
const uint CRCPOLY2 = 0xEDB88320U;
|
||||||
|
|
||||||
static bool m_Init;
|
static bool m_Init;
|
||||||
static bool m_InitRev;
|
static bool m_InitRev;
|
||||||
static ulong[] m_CrcTable = new ulong[byte.MaxValue + 1];
|
static uint[] m_CrcTable = new uint[byte.MaxValue + 1];
|
||||||
static ulong[] m_CrcTableRev = new ulong[byte.MaxValue + 1];
|
static uint[] m_CrcTableRev = new uint[byte.MaxValue + 1];
|
||||||
|
|
||||||
public static ulong Crc(int size, Span<byte> c)
|
public static ulong Crc(int size, Span<byte> c)
|
||||||
{
|
{
|
||||||
@ -35,7 +30,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
return ~r & 0xFFFFFFFFUL;
|
return ~r & 0xFFFFFFFFUL;
|
||||||
}
|
}
|
||||||
public static ulong CrcRev(int size, Span<byte> c)
|
public static uint CrcRev(int size, Span<byte> c)
|
||||||
{
|
{
|
||||||
if (!m_InitRev)
|
if (!m_InitRev)
|
||||||
{
|
{
|
||||||
@ -43,41 +38,41 @@ namespace VirtualNes.Core
|
|||||||
m_InitRev = true;
|
m_InitRev = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong r = 0xFFFFFFFFUL;
|
uint r = 0xFFFFFFFFU;
|
||||||
int step = 0;
|
int step = 0;
|
||||||
while (--size >= 0)
|
while (--size >= 0)
|
||||||
{
|
{
|
||||||
r = (r >> CHAR_BIT) ^ m_CrcTableRev[(byte)r ^ c[step]];
|
r = (r >> CHAR_BIT) ^ m_CrcTableRev[(byte)r ^ c[step]];
|
||||||
step++;
|
step++;
|
||||||
}
|
}
|
||||||
return r ^ 0xFFFFFFFFUL;
|
return r ^ 0xFFFFFFFFU;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MakeTable()
|
static void MakeTable()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
ulong r;
|
uint r;
|
||||||
|
|
||||||
for (i = 0; i <= byte.MaxValue; i++)
|
for (i = 0; i <= byte.MaxValue; i++)
|
||||||
{
|
{
|
||||||
r = (ulong)i << (32 - CHAR_BIT);
|
r = (uint)i << (32 - CHAR_BIT);
|
||||||
for (j = 0; j < CHAR_BIT; j++)
|
for (j = 0; j < CHAR_BIT; j++)
|
||||||
{
|
{
|
||||||
if ((r & 0x80000000UL) > 0) r = (r << 1) ^ CRCPOLY1;
|
if ((r & 0x80000000UL) > 0) r = (r << 1) ^ CRCPOLY1;
|
||||||
else r <<= 1;
|
else r <<= 1;
|
||||||
}
|
}
|
||||||
m_CrcTable[i] = r & 0xFFFFFFFFUL;
|
m_CrcTable[i] = r & 0xFFFFFFFFU;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
static void MakeTableRev()
|
static void MakeTableRev()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
ulong r;
|
uint r;
|
||||||
|
|
||||||
for (i = 0; i <= byte.MaxValue; i++)
|
for (i = 0; i <= byte.MaxValue; i++)
|
||||||
{
|
{
|
||||||
r = (ulong)i;
|
r = (uint)i;
|
||||||
for (j = 0; j < CHAR_BIT; j++)
|
for (j = 0; j < CHAR_BIT; j++)
|
||||||
{
|
{
|
||||||
if ((r & 1) > 0) r = (r >> 1) ^ CRCPOLY2;
|
if ((r & 1) > 0) r = (r >> 1) ^ CRCPOLY2;
|
||||||
|
@ -0,0 +1,145 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class OPLL_PATCH
|
||||||
|
{
|
||||||
|
public uint TL, FB, EG, ML, AR, DR, SL, RR, KR, KL, AM, PM, WF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OPLL_SLOT
|
||||||
|
{
|
||||||
|
public OPLL_PATCH patch;
|
||||||
|
|
||||||
|
public int type; /* 0 : modulator 1 : carrier */
|
||||||
|
|
||||||
|
/* OUTPUT */
|
||||||
|
public Int32 feedback;
|
||||||
|
public Int32[] output = new Int32[5]; /* Output value of slot */
|
||||||
|
|
||||||
|
/* for Phase Generator (PG) */
|
||||||
|
public UInt32 sintbl; /* Wavetable */
|
||||||
|
public UInt32 phase; /* Phase */
|
||||||
|
public UInt32 dphase; /* Phase increment amount */
|
||||||
|
public UInt32 pgout; /* output */
|
||||||
|
|
||||||
|
/* for Envelope Generator (EG) */
|
||||||
|
public int fnum; /* F-Number */
|
||||||
|
public int block; /* Block */
|
||||||
|
public int volume; /* Current volume */
|
||||||
|
public int sustine; /* Sustine 1 = ON, 0 = OFF */
|
||||||
|
public UInt32 tll; /* Total Level + Key scale level*/
|
||||||
|
public UInt32 rks; /* Key scale offset (Rks) */
|
||||||
|
public int eg_mode; /* Current state */
|
||||||
|
public UInt32 eg_phase; /* Phase */
|
||||||
|
public UInt32 eg_dphase; /* Phase increment amount */
|
||||||
|
public UInt32 egout; /* output */
|
||||||
|
|
||||||
|
|
||||||
|
/* refer to opll-> */
|
||||||
|
public UInt32 plfo_pm;
|
||||||
|
public UInt32 plfo_am;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OPLL_CH
|
||||||
|
{
|
||||||
|
public int patch_number;
|
||||||
|
public int key_status;
|
||||||
|
public OPLL_SLOT mod;
|
||||||
|
public OPLL_SLOT car;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OPLL
|
||||||
|
{
|
||||||
|
public UInt32 adr;
|
||||||
|
public Int32[] output = new Int32[2];
|
||||||
|
|
||||||
|
/* Register */
|
||||||
|
public byte[] reg = new byte[0x40];
|
||||||
|
public int[] slot_on_flag = new int[18];
|
||||||
|
|
||||||
|
/* Rythm Mode : 0 = OFF, 1 = ON */
|
||||||
|
public int rythm_mode;
|
||||||
|
|
||||||
|
/* Pitch Modulator */
|
||||||
|
public UInt32 pm_phase;
|
||||||
|
public Int32 lfo_pm;
|
||||||
|
|
||||||
|
/* Amp Modulator */
|
||||||
|
public Int32 am_phase;
|
||||||
|
public Int32 lfo_am;
|
||||||
|
|
||||||
|
/* Noise Generator */
|
||||||
|
public UInt32 noise_seed;
|
||||||
|
public UInt32 whitenoise;
|
||||||
|
public UInt32 noiseA;
|
||||||
|
public UInt32 noiseB;
|
||||||
|
public UInt32 noiseA_phase;
|
||||||
|
public UInt32 noiseB_phase;
|
||||||
|
public UInt32 noiseA_idx;
|
||||||
|
public UInt32 noiseB_idx;
|
||||||
|
public UInt32 noiseA_dphase;
|
||||||
|
public UInt32 noiseB_dphase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Emu2413API
|
||||||
|
{
|
||||||
|
public static void OPLL_init(UInt32 c, UInt32 r)
|
||||||
|
{
|
||||||
|
makePmTable();
|
||||||
|
makeAmTable();
|
||||||
|
makeDB2LinTable();
|
||||||
|
makeAdjustTable();
|
||||||
|
makeTllTable();
|
||||||
|
makeRksTable();
|
||||||
|
makeSinTable();
|
||||||
|
makeDefaultPatch();
|
||||||
|
OPLL_setClock(c, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OPLL_setClock(uint c, uint r)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeDefaultPatch()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeSinTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeRksTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeTllTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeAdjustTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeDB2LinTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeAmTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makePmTable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f5ecddbb6b69204478d799a484d8c47c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace VirtualNes.Core
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
|
||||||
{
|
{
|
||||||
// 昤夋曽幃
|
// 昤夋曽幃
|
||||||
public enum EnumRenderMethod
|
public enum EnumRenderMethod
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public static class MemoryUtility
|
||||||
|
{
|
||||||
|
public static void ZEROMEMORY(byte[] array, uint length)
|
||||||
|
{
|
||||||
|
memset(array, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void memset(byte[] array, byte value, uint length)
|
||||||
|
{
|
||||||
|
Unsafe.InitBlock(ref array[0], value, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8586eb710dc81124593eb5adfa08d73b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,11 +1,11 @@
|
|||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public struct NesConfig
|
public class NesConfig
|
||||||
{
|
{
|
||||||
public float BaseClock; // NTSC:21477270.0 PAL:21281364.0
|
public float BaseClock; // NTSC:21477270.0 PAL:21281364.0
|
||||||
public float CpuClock; // NTSC: 1789772.5 PAL: 1773447.0
|
public float CpuClock; // NTSC: 1789772.5 PAL: 1773447.0
|
||||||
|
|
||||||
public int TotalScanLines; // NTSC: 262 PAL: 312
|
public int TotalScanlines; // NTSC: 262 PAL: 312
|
||||||
|
|
||||||
public int ScanlineCycles; // NTSC:1364 PAL:1362
|
public int ScanlineCycles; // NTSC:1364 PAL:1362
|
||||||
|
|
||||||
@ -19,40 +19,33 @@
|
|||||||
public int FrameRate; // NTSC:60(59.94) PAL:50
|
public int FrameRate; // NTSC:60(59.94) PAL:50
|
||||||
public float FramePeriod; // NTSC:16.683 PAL:20.0
|
public float FramePeriod; // NTSC:16.683 PAL:20.0
|
||||||
|
|
||||||
public static NesConfig GetNTSC()
|
public static NesConfig NESCONFIG_NTSC = new NesConfig
|
||||||
{
|
{
|
||||||
return new NesConfig
|
BaseClock = 21477270.0f,
|
||||||
{
|
CpuClock = 1789772.5f,
|
||||||
BaseClock = 21477270.0f,
|
TotalScanlines = 262,
|
||||||
CpuClock = 1789772.5f,
|
ScanlineCycles = 1364,
|
||||||
TotalScanLines = 262,
|
HDrawCycles = 1024,
|
||||||
ScanlineCycles = 1364,
|
HBlankCycles = 340,
|
||||||
HDrawCycles = 1024,
|
ScanlineEndCycles = 4,
|
||||||
HBlankCycles = 340,
|
FrameCycles = 1364 * 262,
|
||||||
ScanlineEndCycles = 4,
|
FrameIrqCycles = 29830,
|
||||||
FrameCycles = 1364 * 262,
|
FrameRate = 60,
|
||||||
FrameIrqCycles = 29830,
|
FramePeriod = 1000.0f / 60.0f
|
||||||
FrameRate = 60,
|
};
|
||||||
FramePeriod = 1000.0f / 60.0f
|
public static NesConfig NESCONFIG_PAL = new NesConfig
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NesConfig GetPAL()
|
|
||||||
{
|
{
|
||||||
return new NesConfig
|
BaseClock = 26601714.0f,
|
||||||
{
|
CpuClock = 1662607.125f,
|
||||||
BaseClock = 26601714.0f,
|
TotalScanlines = 312,
|
||||||
CpuClock = 1662607.125f,
|
ScanlineCycles = 1278,
|
||||||
TotalScanLines = 312,
|
HDrawCycles = 960,
|
||||||
ScanlineCycles = 1278,
|
HBlankCycles = 318,
|
||||||
HDrawCycles = 960,
|
ScanlineEndCycles = 2,
|
||||||
HBlankCycles = 318,
|
FrameCycles = 1278 * 312,
|
||||||
ScanlineEndCycles = 2,
|
FrameIrqCycles = 33252,
|
||||||
FrameCycles = 1278 * 312,
|
FrameRate = 50,
|
||||||
FrameIrqCycles = 33252,
|
FramePeriod = 1000.0f / 50.0f
|
||||||
FrameRate = 50,
|
};
|
||||||
FramePeriod = 1000.0f / 50.0f
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -27,7 +24,7 @@ namespace VirtualNes.Core
|
|||||||
NSF
|
NSF
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct NSFHEADER
|
public class NSFHEADER
|
||||||
{
|
{
|
||||||
byte[] ID;
|
byte[] ID;
|
||||||
byte Version;
|
byte Version;
|
||||||
@ -43,7 +40,7 @@ namespace VirtualNes.Core
|
|||||||
byte[] BankSwitch;
|
byte[] BankSwitch;
|
||||||
ushort SpeedPAL;
|
ushort SpeedPAL;
|
||||||
byte NTSC_PALbits;
|
byte NTSC_PALbits;
|
||||||
byte ExtraChipSelect;
|
public byte ExtraChipSelect;
|
||||||
byte[] Expansion; // must be 0
|
byte[] Expansion; // must be 0
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +62,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct NESHEADER
|
public class NESHEADER
|
||||||
{
|
{
|
||||||
public byte[] ID;
|
public byte[] ID;
|
||||||
public byte PRG_PAGE_SIZE;
|
public byte PRG_PAGE_SIZE;
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.Remoting.Messaging;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public static class RomPatch
|
public static class RomPatch
|
||||||
{
|
{
|
||||||
public static void DoPatch(ref ulong crc, ref byte[] lpPRG, ref byte[] lpCHR, ref int mapper, ref NESHEADER header)
|
public static void DoPatch(ref uint crc, ref byte[] lpPRG, ref byte[] lpCHR, ref int mapper, ref NESHEADER header)
|
||||||
{
|
{
|
||||||
// Mapper 000
|
// Mapper 000
|
||||||
if (crc == 0x57970078)
|
if (crc == 0x57970078)
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using Codice.CM.Client.Differences;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
using Codice.CM.Client.Differences;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes
|
namespace VirtualNes
|
||||||
{
|
{
|
||||||
public static class MMU
|
public static class MMU
|
||||||
{
|
{
|
||||||
// CPU 儊儌儕僶儞僋
|
// CPU 儊儌儕僶儞僋
|
||||||
public static byte[][] CPU_MEM_BANK = new byte[8][]; // 8K扨埵
|
public static Memory<byte>[] CPU_MEM_BANK = new Memory<byte>[8]; // 8K扨埵
|
||||||
|
public static byte[] CPU_MEM_TYPE = new byte[8];
|
||||||
|
public static int[] CPU_MEM_PAGE = new int[8]; // 僗僥乕僩僙乕僽梡
|
||||||
// PPU 儊儌儕僶儞僋
|
// PPU 儊儌儕僶儞僋
|
||||||
public static byte[][] PPU_MEM_BANK = new byte[12][]; // 1K扨埵
|
public static Memory<byte>[] PPU_MEM_BANK = new Memory<byte>[12]; // 1K扨埵
|
||||||
public static byte[] PPU_MEM_TYPE = new byte[12];
|
public static byte[] PPU_MEM_TYPE = new byte[12];
|
||||||
public static int[] PPU_MEM_PAGE = new int[12]; // 僗僥乕僩僙乕僽梡
|
public static int[] PPU_MEM_PAGE = new int[12]; // 僗僥乕僩僙乕僽梡
|
||||||
public static byte[] CRAM_USED = new byte[16]; // 僗僥乕僩僙乕僽梡
|
public static byte[] CRAM_USED = new byte[16]; // 僗僥乕僩僙乕僽梡
|
||||||
|
|
||||||
// NES儊儌儕
|
// NES儊儌儕
|
||||||
public static byte[] RAM = new byte[8 * 1024]; // NES撪憻RAM
|
public static byte[] RAM = new byte[8 * 1024]; // NES撪憻RAM
|
||||||
public static byte[] WARM = new byte[128 * 1024]; // 儚乕僋/僶僢僋傾僢僾RAM
|
public static byte[] WRAM = new byte[128 * 1024]; // 儚乕僋/僶僢僋傾僢僾RAM
|
||||||
public static byte[] DRAM = new byte[40 * 1024]; // 僨傿僗僋僔僗僥儉RAM
|
public static byte[] DRAM = new byte[40 * 1024]; // 僨傿僗僋僔僗僥儉RAM
|
||||||
public static byte[] XRAM = new byte[8 * 1024]; // 僟儈乕僶儞僋
|
public static byte[] XRAM = new byte[8 * 1024]; // 僟儈乕僶儞僋
|
||||||
public static byte[] ERAM = new byte[32 * 1024]; // 奼挘婡婍梡RAM
|
public static byte[] ERAM = new byte[32 * 1024]; // 奼挘婡婍梡RAM
|
||||||
@ -42,6 +38,17 @@ namespace VirtualNes
|
|||||||
public static ushort loopy_v; // same as $2005/$2006
|
public static ushort loopy_v; // same as $2005/$2006
|
||||||
public static ushort loopy_x; // tile x offset
|
public static ushort loopy_x; // tile x offset
|
||||||
|
|
||||||
|
// ROM僨乕僞億僀儞僞
|
||||||
|
public static byte[] PROM; // PROM ptr
|
||||||
|
public static byte[] VROM; // VROM ptr
|
||||||
|
|
||||||
|
// For dis...
|
||||||
|
public static byte PROM_ACCESS;
|
||||||
|
|
||||||
|
// ROM 僶儞僋僒僀僘
|
||||||
|
public static int PROM_8K_SIZE, PROM_16K_SIZE, PROM_32K_SIZE;
|
||||||
|
public static int VROM_1K_SIZE, VROM_2K_SIZE, VROM_4K_SIZE, VROM_8K_SIZE;
|
||||||
|
|
||||||
// 儊儌儕僞僀僾
|
// 儊儌儕僞僀僾
|
||||||
// For PROM (CPU)
|
// For PROM (CPU)
|
||||||
public const byte BANKTYPE_ROM = 0x00;
|
public const byte BANKTYPE_ROM = 0x00;
|
||||||
@ -60,5 +67,170 @@ namespace VirtualNes
|
|||||||
public const byte VRAM_MIRROR4L = 0x03; // PA10 L屌掕 $2000-$23FF偺儈儔乕
|
public const byte VRAM_MIRROR4L = 0x03; // PA10 L屌掕 $2000-$23FF偺儈儔乕
|
||||||
public const byte VRAM_MIRROR4H = 0x04; // PA10 H屌掕 $2400-$27FF偺儈儔乕
|
public const byte VRAM_MIRROR4H = 0x04; // PA10 H屌掕 $2400-$27FF偺儈儔乕
|
||||||
|
|
||||||
|
internal static void SetPROM_Bank(byte page, Memory<byte> ptr, byte type)
|
||||||
|
{
|
||||||
|
CPU_MEM_BANK[page] = ptr;
|
||||||
|
CPU_MEM_TYPE[page] = type;
|
||||||
|
CPU_MEM_PAGE[page] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetPROM_8K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
bank %= PROM_8K_SIZE;
|
||||||
|
CPU_MEM_BANK[page] = new Memory<byte>(MMU.PROM, 0x2000 * bank, MMU.PROM.Length - 0x2000 * bank);
|
||||||
|
CPU_MEM_TYPE[page] = BANKTYPE_ROM;
|
||||||
|
CPU_MEM_PAGE[page] = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetPROM_16K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
SetPROM_8K_Bank((byte)(page + 0), bank * 2 + 0);
|
||||||
|
SetPROM_8K_Bank((byte)(page + 1), bank * 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetPROM_32K_Bank(int bank)
|
||||||
|
{
|
||||||
|
SetPROM_8K_Bank(4, bank * 4 + 0);
|
||||||
|
SetPROM_8K_Bank(5, bank * 4 + 1);
|
||||||
|
SetPROM_8K_Bank(6, bank * 4 + 2);
|
||||||
|
SetPROM_8K_Bank(7, bank * 4 + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetPROM_32K_Bank(int bank0, int bank1, int bank2, int bank3)
|
||||||
|
{
|
||||||
|
SetPROM_8K_Bank(4, bank0);
|
||||||
|
SetPROM_8K_Bank(5, bank1);
|
||||||
|
SetPROM_8K_Bank(6, bank2);
|
||||||
|
SetPROM_8K_Bank(7, bank3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPU VROM bank
|
||||||
|
internal static void SetVROM_Bank(byte page, Memory<byte> ptr, byte type)
|
||||||
|
{
|
||||||
|
PPU_MEM_BANK[page] = ptr;
|
||||||
|
PPU_MEM_TYPE[page] = type;
|
||||||
|
PPU_MEM_PAGE[page] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVROM_1K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
bank %= VROM_1K_SIZE;
|
||||||
|
PPU_MEM_BANK[page] = new Memory<byte>(VROM, 0x0400 * bank, VROM.Length - (0x0400 * bank));
|
||||||
|
PPU_MEM_TYPE[page] = BANKTYPE_VROM;
|
||||||
|
PPU_MEM_PAGE[page] = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVROM_2K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
SetVROM_1K_Bank((byte)(page + 0), bank * 2 + 0);
|
||||||
|
SetVROM_1K_Bank((byte)(page + 1), bank * 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVROM_4K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
SetVROM_1K_Bank((byte)(page + 0), bank * 4 + 0);
|
||||||
|
SetVROM_1K_Bank((byte)(page + 1), bank * 4 + 1);
|
||||||
|
SetVROM_1K_Bank((byte)(page + 2), bank * 4 + 2);
|
||||||
|
SetVROM_1K_Bank((byte)(page + 3), bank * 4 + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVROM_8K_Bank(int bank)
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
SetVROM_1K_Bank(i, bank * 8 + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVROM_8K_Bank(int bank0, int bank1, int bank2, int bank3,
|
||||||
|
int bank4, int bank5, int bank6, int bank7)
|
||||||
|
{
|
||||||
|
SetVROM_1K_Bank(0, bank0);
|
||||||
|
SetVROM_1K_Bank(1, bank1);
|
||||||
|
SetVROM_1K_Bank(2, bank2);
|
||||||
|
SetVROM_1K_Bank(3, bank3);
|
||||||
|
SetVROM_1K_Bank(4, bank4);
|
||||||
|
SetVROM_1K_Bank(5, bank5);
|
||||||
|
SetVROM_1K_Bank(6, bank6);
|
||||||
|
SetVROM_1K_Bank(7, bank7);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetCRAM_1K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
bank &= 0x1F;
|
||||||
|
PPU_MEM_BANK[page] = new Memory<byte>(MMU.CRAM, 0x0400 * bank, MMU.CRAM.Length - 0x0400 * bank);
|
||||||
|
PPU_MEM_TYPE[page] = BANKTYPE_CRAM;
|
||||||
|
PPU_MEM_PAGE[page] = bank;
|
||||||
|
|
||||||
|
CRAM_USED[bank >> 2] = 0xFF; // CRAM巊梡僼儔僌
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetCRAM_2K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
SetCRAM_1K_Bank((byte)(page + 0), bank * 2 + 0);
|
||||||
|
SetCRAM_1K_Bank((byte)(page + 1), bank * 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetCRAM_4K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
SetCRAM_1K_Bank((byte)(page + 0), bank * 4 + 0);
|
||||||
|
SetCRAM_1K_Bank((byte)(page + 1), bank * 4 + 1);
|
||||||
|
SetCRAM_1K_Bank((byte)(page + 2), bank * 4 + 2);
|
||||||
|
SetCRAM_1K_Bank((byte)(page + 3), bank * 4 + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetCRAM_8K_Bank(int bank)
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
SetCRAM_1K_Bank(i, bank * 8 + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVRAM_1K_Bank(byte page, int bank)
|
||||||
|
{
|
||||||
|
bank &= 3;
|
||||||
|
PPU_MEM_BANK[page] = new Memory<byte>(VRAM, 0x0400 * bank, VRAM.Length - 0x0400 * bank);
|
||||||
|
PPU_MEM_TYPE[page] = BANKTYPE_VRAM;
|
||||||
|
PPU_MEM_PAGE[page] = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVRAM_Bank(int bank0, int bank1, int bank2, int bank3)
|
||||||
|
{
|
||||||
|
SetVRAM_1K_Bank(8, bank0);
|
||||||
|
SetVRAM_1K_Bank(9, bank1);
|
||||||
|
SetVRAM_1K_Bank(10, bank2);
|
||||||
|
SetVRAM_1K_Bank(11, bank3);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVRAM_Mirror(int type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case VRAM_HMIRROR:
|
||||||
|
SetVRAM_Bank(0, 0, 1, 1);
|
||||||
|
break;
|
||||||
|
case VRAM_VMIRROR:
|
||||||
|
SetVRAM_Bank(0, 1, 0, 1);
|
||||||
|
break;
|
||||||
|
case VRAM_MIRROR4L:
|
||||||
|
SetVRAM_Bank(0, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case VRAM_MIRROR4H:
|
||||||
|
SetVRAM_Bank(1, 1, 1, 1);
|
||||||
|
break;
|
||||||
|
case VRAM_MIRROR4:
|
||||||
|
SetVRAM_Bank(0, 1, 2, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetVRAM_Mirror(int bank0, int bank1, int bank2, int bank3)
|
||||||
|
{
|
||||||
|
SetVRAM_1K_Bank(8, bank0);
|
||||||
|
SetVRAM_1K_Bank(9, bank1);
|
||||||
|
SetVRAM_1K_Bank(10, bank2);
|
||||||
|
SetVRAM_1K_Bank(11, bank3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using Codice.CM.Client.Differences;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -30,7 +25,7 @@ namespace VirtualNes.Core
|
|||||||
// $6000-$7FFF WRAM
|
// $6000-$7FFF WRAM
|
||||||
if (addr >= 0x6000 && addr <= 0x7FFF)
|
if (addr >= 0x6000 && addr <= 0x7FFF)
|
||||||
{
|
{
|
||||||
return MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF];
|
return MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (byte)(addr >> 8);
|
return (byte)(addr >> 8);
|
||||||
@ -39,7 +34,7 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
if (addr >= 0x6000 && addr <= 0x7FFF)
|
if (addr >= 0x6000 && addr <= 0x7FFF)
|
||||||
{
|
{
|
||||||
MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
|
MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
using Codice.CM.Client.Differences;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -18,10 +17,14 @@ namespace VirtualNes.Core
|
|||||||
public NesConfig nescfg;
|
public NesConfig nescfg;
|
||||||
|
|
||||||
private List<CHEATCODE> m_CheatCode = new List<CHEATCODE>();
|
private List<CHEATCODE> m_CheatCode = new List<CHEATCODE>();
|
||||||
|
private List<GENIECODE> m_GenieCode = new List<GENIECODE>();
|
||||||
private bool m_bDiskThrottle;
|
private bool m_bDiskThrottle;
|
||||||
private int m_CommandRequest;
|
private int m_CommandRequest;
|
||||||
private int m_nSnapNo;
|
private int m_nSnapNo;
|
||||||
private bool m_bNsfPlaying;
|
private bool m_bNsfPlaying;
|
||||||
|
private bool m_bNsfInit;
|
||||||
|
private int m_nNsfSongNo;
|
||||||
|
private int m_nNsfSongMode;
|
||||||
private bool m_bMoviePlay;
|
private bool m_bMoviePlay;
|
||||||
private bool m_bMovieRec;
|
private bool m_bMovieRec;
|
||||||
private Stream m_fpMovie;
|
private Stream m_fpMovie;
|
||||||
@ -96,7 +99,7 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
bVideoMode = false;
|
bVideoMode = false;
|
||||||
|
|
||||||
nescfg = NesConfig.GetNTSC();
|
nescfg = NesConfig.NESCONFIG_NTSC;
|
||||||
|
|
||||||
CheatInitial();
|
CheatInitial();
|
||||||
|
|
||||||
@ -203,18 +206,203 @@ namespace VirtualNes.Core
|
|||||||
SaveDISK();
|
SaveDISK();
|
||||||
SaveTurboFile();
|
SaveTurboFile();
|
||||||
|
|
||||||
//todo : ʵÏÖ
|
// RAM Clear
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.RAM, (uint)MMU.RAM.Length);
|
||||||
|
if (rom.GetPROM_CRC() == 0x29401686)
|
||||||
|
{ // Minna no Taabou no Nakayoshi Dai Sakusen(J)
|
||||||
|
MemoryUtility.memset(MMU.RAM, 0xFF, (uint)MMU.RAM.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAM set
|
||||||
|
if (!rom.IsSAVERAM() && rom.GetMapperNo() != 20)
|
||||||
|
{
|
||||||
|
MemoryUtility.memset(MMU.WRAM, 0xFF, (uint)MMU.WRAM.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.CRAM, (uint)MMU.CRAM.Length);
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.VRAM, (uint)MMU.VRAM.Length);
|
||||||
|
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.SPRAM, (uint)MMU.SPRAM.Length);
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.BGPAL, (uint)MMU.BGPAL.Length);
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.SPPAL, (uint)MMU.SPPAL.Length);
|
||||||
|
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.CPUREG, (uint)MMU.CPUREG.Length);
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.PPUREG, (uint)MMU.PPUREG.Length);
|
||||||
|
|
||||||
|
m_bDiskThrottle = false;
|
||||||
|
|
||||||
|
SetRenderMethod(EnumRenderMethod.PRE_RENDER);
|
||||||
|
|
||||||
|
if (rom.IsPAL())
|
||||||
|
{
|
||||||
|
SetVideoMode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
MMU.PROM = rom.GetPROM();
|
||||||
|
MMU.VROM = rom.GetVROM();
|
||||||
|
|
||||||
|
MMU.PROM_8K_SIZE = rom.GetPROM_SIZE() * 2;
|
||||||
|
MMU.PROM_16K_SIZE = rom.GetPROM_SIZE();
|
||||||
|
MMU.PROM_32K_SIZE = rom.GetPROM_SIZE() / 2;
|
||||||
|
|
||||||
|
MMU.VROM_1K_SIZE = rom.GetVROM_SIZE() * 8;
|
||||||
|
MMU.VROM_2K_SIZE = rom.GetVROM_SIZE() * 4;
|
||||||
|
MMU.VROM_4K_SIZE = rom.GetVROM_SIZE() * 2;
|
||||||
|
MMU.VROM_8K_SIZE = rom.GetVROM_SIZE();
|
||||||
|
|
||||||
|
// デフォルトバンク
|
||||||
|
if (MMU.VROM_8K_SIZE != 0)
|
||||||
|
{
|
||||||
|
MMU.SetVROM_8K_Bank(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.SetCRAM_8K_Bank(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ミラー
|
||||||
|
if (rom.Is4SCREEN())
|
||||||
|
{
|
||||||
|
MMU.SetVRAM_Mirror(MMU.VRAM_MIRROR4);
|
||||||
|
}
|
||||||
|
else if (rom.IsVMIRROR())
|
||||||
|
{
|
||||||
|
MMU.SetVRAM_Mirror(MMU.VRAM_VMIRROR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.SetVRAM_Mirror(MMU.VRAM_HMIRROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
apu.SelectExSound(0);
|
||||||
|
|
||||||
|
ppu.Reset();
|
||||||
|
mapper.Reset();
|
||||||
|
|
||||||
|
// Trainer
|
||||||
|
if (rom.IsTRAINER())
|
||||||
|
{
|
||||||
|
Array.Copy(rom.GetTRAINER(), 0, MMU.WRAM, 0x1000, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
pad.Reset();
|
||||||
|
cpu.Reset();
|
||||||
|
apu.Reset();
|
||||||
|
|
||||||
|
if (rom.IsNSF())
|
||||||
|
{
|
||||||
|
mapper.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
base_cycles = emul_cycles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetVideoMode(bool bMode)
|
||||||
|
{
|
||||||
|
bVideoMode = bMode;
|
||||||
|
if (!bVideoMode)
|
||||||
|
{
|
||||||
|
nescfg = NesConfig.NESCONFIG_NTSC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nescfg = NesConfig.NESCONFIG_PAL;
|
||||||
|
}
|
||||||
|
apu.SoundSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRenderMethod(EnumRenderMethod type)
|
||||||
|
{
|
||||||
|
RenderMethod = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SoftReset()
|
internal void SoftReset()
|
||||||
{
|
{
|
||||||
//todo : ʵÏÖ
|
pad.Reset();
|
||||||
|
cpu.Reset();
|
||||||
|
apu.Reset();
|
||||||
|
|
||||||
|
if (rom.IsNSF())
|
||||||
|
{
|
||||||
|
mapper.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bDiskThrottle = false;
|
||||||
|
|
||||||
|
base_cycles = emul_cycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EmulateNSF()
|
internal void EmulateNSF()
|
||||||
{
|
{
|
||||||
//todo : ʵÏÖNSFÄ£Äâ
|
R6502 reg = null;
|
||||||
throw new NotImplementedException("EmulateNSF");
|
|
||||||
|
ppu.Reset();
|
||||||
|
mapper.VSync();
|
||||||
|
|
||||||
|
//DEBUGOUT( "Frame\n" );
|
||||||
|
|
||||||
|
if (m_bNsfPlaying)
|
||||||
|
{
|
||||||
|
if (m_bNsfInit)
|
||||||
|
{
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.RAM, (uint)MMU.RAM.Length);
|
||||||
|
if ((rom.GetNsfHeader().ExtraChipSelect & 0x04) == 0)
|
||||||
|
{
|
||||||
|
MemoryUtility.ZEROMEMORY(MMU.RAM, 0x2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
apu.Reset();
|
||||||
|
apu.Write(0x4015, 0x0F);
|
||||||
|
apu.Write(0x4017, 0xC0);
|
||||||
|
apu.ExWrite(0x4080, 0x80); // FDS Volume 0
|
||||||
|
apu.ExWrite(0x408A, 0xE8); // FDS Envelope Speed
|
||||||
|
|
||||||
|
cpu.GetContext(ref reg);
|
||||||
|
reg.PC = 0x4710; // Init Address
|
||||||
|
reg.A = (byte)m_nNsfSongNo;
|
||||||
|
reg.X = (byte)m_nNsfSongMode;
|
||||||
|
reg.Y = 0;
|
||||||
|
reg.S = 0xFF;
|
||||||
|
reg.P = CPU.Z_FLAG | CPU.R_FLAG | CPU.I_FLAG;
|
||||||
|
|
||||||
|
// 安全対策を兼ねてあえてループに(1秒分)
|
||||||
|
for (int i = 0; i < nescfg.TotalScanlines * 60; i++)
|
||||||
|
{
|
||||||
|
EmulationCPU(nescfg.ScanlineCycles);
|
||||||
|
cpu.GetContext(ref reg);
|
||||||
|
|
||||||
|
// 無限ループに入ったことを確認したら抜ける
|
||||||
|
if (reg.PC == 0x4700)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bNsfInit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu.GetContext(ref reg);
|
||||||
|
// 無限ループに入っていたら再設定する
|
||||||
|
if (reg.PC == 0x4700)
|
||||||
|
{
|
||||||
|
reg.PC = 0x4720; // Play Address
|
||||||
|
reg.A = 0;
|
||||||
|
reg.S = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nescfg.TotalScanlines; i++)
|
||||||
|
{
|
||||||
|
EmulationCPU(nescfg.ScanlineCycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpu.GetContext(ref reg);
|
||||||
|
reg.PC = 0x4700; // 無限ループ
|
||||||
|
reg.S = 0xFF;
|
||||||
|
|
||||||
|
EmulationCPU(nescfg.ScanlineCycles * nescfg.TotalScanlines);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CheatCodeProcess()
|
internal void CheatCodeProcess()
|
||||||
@ -239,7 +427,7 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
for (i = 0; i < SAVERAM_SIZE; i++)
|
for (i = 0; i < SAVERAM_SIZE; i++)
|
||||||
{
|
{
|
||||||
if (MMU.WARM[i] != 0x00)
|
if (MMU.WRAM[i] != 0x00)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +437,7 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
Debuger.Log($"Saving SAVERAM...[{romName}]");
|
Debuger.Log($"Saving SAVERAM...[{romName}]");
|
||||||
|
|
||||||
Supporter.SaveSRAMToFile(MMU.WARM, romName);
|
Supporter.SaveSRAMToFile(MMU.WRAM, romName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +570,7 @@ namespace VirtualNes.Core
|
|||||||
case 0x05: // $A000-$BFFF
|
case 0x05: // $A000-$BFFF
|
||||||
case 0x06: // $C000-$DFFF
|
case 0x06: // $C000-$DFFF
|
||||||
case 0x07: // $E000-$FFFF
|
case 0x07: // $E000-$FFFF
|
||||||
return MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF];
|
return MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00; // Warning—\–h
|
return 0x00; // Warning—\–h
|
||||||
@ -508,23 +696,47 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mapper->WriteLow(addr, data);
|
mapper.WriteLow(addr, data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x03: // $6000-$7FFF
|
case 0x03: // $6000-$7FFF
|
||||||
mapper->WriteLow(addr, data);
|
mapper.WriteLow(addr, data);
|
||||||
break;
|
break;
|
||||||
case 0x04: // $8000-$9FFF
|
case 0x04: // $8000-$9FFF
|
||||||
case 0x05: // $A000-$BFFF
|
case 0x05: // $A000-$BFFF
|
||||||
case 0x06: // $C000-$DFFF
|
case 0x06: // $C000-$DFFF
|
||||||
case 0x07: // $E000-$FFFF
|
case 0x07: // $E000-$FFFF
|
||||||
mapper->Write(addr, data);
|
mapper.Write(addr, data);
|
||||||
|
|
||||||
GenieCodeProcess();
|
GenieCodeProcess();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GenieCodeProcess()
|
||||||
|
{
|
||||||
|
ushort addr;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_GenieCode.Count; i++)
|
||||||
|
{
|
||||||
|
addr = m_GenieCode[i].address;
|
||||||
|
if ((addr & 0x8000) != 0)
|
||||||
|
{
|
||||||
|
// 8character codes
|
||||||
|
if (MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF] == m_GenieCode[i].cmp)
|
||||||
|
{
|
||||||
|
MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF] = m_GenieCode[i].data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 6character codes
|
||||||
|
addr |= 0x8000;
|
||||||
|
MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF] = m_GenieCode[i].data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void WriteReg(ushort addr, byte data)
|
private void WriteReg(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
switch (addr & 0xFF)
|
switch (addr & 0xFF)
|
||||||
@ -561,20 +773,20 @@ namespace VirtualNes.Core
|
|||||||
case 0x16:
|
case 0x16:
|
||||||
mapper.ExWrite(addr, data); // For VS-Unisystem
|
mapper.ExWrite(addr, data); // For VS-Unisystem
|
||||||
pad.Write(addr, data);
|
pad.Write(addr, data);
|
||||||
CPUREG[addr & 0xFF] = data;
|
MMU.CPUREG[addr & 0xFF] = data;
|
||||||
m_TapeIn = data;
|
m_TapeIn = data;
|
||||||
break;
|
break;
|
||||||
case 0x17:
|
case 0x17:
|
||||||
CPUREG[addr & 0xFF] = data;
|
MMU.CPUREG[addr & 0xFF] = data;
|
||||||
pad->Write(addr, data);
|
pad.Write(addr, data);
|
||||||
apu->Write(addr, data);
|
apu.Write(addr, data);
|
||||||
break;
|
break;
|
||||||
// VirtuaNESŒÅ—Lƒ|<7C>[ƒg
|
// VirtuaNESŒÅ—Lƒ|<7C>[ƒg
|
||||||
case 0x18:
|
case 0x18:
|
||||||
apu->Write(addr, data);
|
apu.Write(addr, data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mapper->ExWrite(addr, data);
|
mapper.ExWrite(addr, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Codice.CM.Client.Differences;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -17,6 +18,10 @@ namespace VirtualNes.Core
|
|||||||
private byte[] padbitsync = new byte[4];
|
private byte[] padbitsync = new byte[4];
|
||||||
private byte micbitsync;
|
private byte micbitsync;
|
||||||
private bool bBarcodeWorld;
|
private bool bBarcodeWorld;
|
||||||
|
private int[][] padcnt = new int[4][]
|
||||||
|
{
|
||||||
|
new int[2],new int[2],new int[2],new int[2],
|
||||||
|
};
|
||||||
|
|
||||||
public uint pad1bit, pad2bit, pad3bit, pad4bit;
|
public uint pad1bit, pad2bit, pad3bit, pad4bit;
|
||||||
|
|
||||||
@ -79,6 +84,326 @@ namespace VirtualNes.Core
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
|
|
||||||
|
internal void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
if (addr == 0x4016)
|
||||||
|
{
|
||||||
|
if ((data & 0x01) != 0)
|
||||||
|
{
|
||||||
|
bStrobe = true;
|
||||||
|
}
|
||||||
|
else if (bStrobe)
|
||||||
|
{
|
||||||
|
bStrobe = false;
|
||||||
|
|
||||||
|
Strobe();
|
||||||
|
if (expad != null)
|
||||||
|
{
|
||||||
|
expad.Strobe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expad != null)
|
||||||
|
{
|
||||||
|
expad.Write4016(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addr == 0x4017)
|
||||||
|
{
|
||||||
|
if (expad != null)
|
||||||
|
{
|
||||||
|
expad.Write4017(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Strobe()
|
||||||
|
{
|
||||||
|
// For VS-Unisystem
|
||||||
|
if (nes.rom.IsVSUNISYSTEM())
|
||||||
|
{
|
||||||
|
uint pad1 = (uint)(padbitsync[0] & 0xF3);
|
||||||
|
uint pad2 = (uint)(padbitsync[1] & 0xF3);
|
||||||
|
uint st1 = (uint)(padbitsync[0] & 0x08) >> 3;
|
||||||
|
uint st2 = (uint)(padbitsync[1] & 0x08) >> 3;
|
||||||
|
|
||||||
|
switch (nVSSwapType)
|
||||||
|
{
|
||||||
|
case VSType.VS_TYPE0:
|
||||||
|
pad1bit = pad1 | (st1 << 2);
|
||||||
|
pad2bit = pad2 | (st2 << 2);
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPE1:
|
||||||
|
pad1bit = pad2 | (st1 << 2);
|
||||||
|
pad2bit = pad1 | (st2 << 2);
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPE2:
|
||||||
|
pad1bit = pad1 | (st1 << 2) | (st2 << 3);
|
||||||
|
pad2bit = pad2;
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPE3:
|
||||||
|
pad1bit = pad2 | (st1 << 2) | (st2 << 3);
|
||||||
|
pad2bit = pad1;
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPE4:
|
||||||
|
pad1bit = pad1 | (st1 << 2) | 0x08; // 0x08=Start Protect
|
||||||
|
pad2bit = pad2 | (st2 << 2) | 0x08; // 0x08=Start Protect
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPE5:
|
||||||
|
pad1bit = pad2 | (st1 << 2) | 0x08; // 0x08=Start Protect
|
||||||
|
pad2bit = pad1 | (st2 << 2) | 0x08; // 0x08=Start Protect
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPE6:
|
||||||
|
pad1bit = pad1 | (st1 << 2) | (((uint)padbitsync[0] & 0x04) << 1);
|
||||||
|
pad2bit = pad2 | (st2 << 2) | (((uint)padbitsync[1] & 0x04) << 1);
|
||||||
|
break;
|
||||||
|
case VSType.VS_TYPEZ:
|
||||||
|
pad1bit = 0;
|
||||||
|
pad2bit = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coin 2偲旐傞堊偵徚偡
|
||||||
|
micbit = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Supporter.Config.emulator.bFourPlayer)
|
||||||
|
{
|
||||||
|
// NES type
|
||||||
|
pad1bit = padbitsync[0] | ((uint)padbitsync[2] << 8) | 0x00080000;
|
||||||
|
pad2bit = padbitsync[1] | ((uint)padbitsync[3] << 8) | 0x00040000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Famicom type
|
||||||
|
pad1bit = padbitsync[0];
|
||||||
|
pad2bit = padbitsync[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pad3bit = padbitsync[2];
|
||||||
|
pad4bit = padbitsync[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Reset()
|
||||||
|
{
|
||||||
|
pad1bit = pad2bit = 0;
|
||||||
|
bStrobe = false;
|
||||||
|
|
||||||
|
bBarcodeWorld = false;
|
||||||
|
|
||||||
|
for (int x = 0; x < 4; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < 2; y++)
|
||||||
|
{
|
||||||
|
padcnt[x][y] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select Extension Devices
|
||||||
|
uint crc = nes.rom.GetPROM_CRC();
|
||||||
|
|
||||||
|
if (crc == 0xfbfc6a6c // Adventures of Bayou Billy, The(E)
|
||||||
|
|| crc == 0xcb275051 // Adventures of Bayou Billy, The(U)
|
||||||
|
|| crc == 0xfb69c131 // Baby Boomer(Unl)(U)
|
||||||
|
|| crc == 0xf2641ad0 // Barker Bill's Trick Shooting(U)
|
||||||
|
|| crc == 0xbc1dce96 // Chiller (Unl)(U)
|
||||||
|
|| crc == 0x90ca616d // Duck Hunt(JUE)
|
||||||
|
|| crc == 0x59e3343f // Freedom Force(U)
|
||||||
|
|| crc == 0x242a270c // Gotcha!(U)
|
||||||
|
|| crc == 0x7b5bd2de // Gumshoe(UE)
|
||||||
|
|| crc == 0x255b129c // Gun Sight(J)
|
||||||
|
|| crc == 0x8963ae6e // Hogan's Alley(JU)
|
||||||
|
|| crc == 0x51d2112f // Laser Invasion(U)
|
||||||
|
|| crc == 0x0a866c94 // Lone Ranger, The(U)
|
||||||
|
// || crc == 0xe4c04eea // Mad City(J)
|
||||||
|
|| crc == 0x9eef47aa // Mechanized Attack(U)
|
||||||
|
|| crc == 0xc2db7551 // Shooting Range(U)
|
||||||
|
|| crc == 0x163e86c0 // To The Earth(U)
|
||||||
|
|| crc == 0x42d893e4 // Operation Wolf(J)
|
||||||
|
|| crc == 0x1388aeb9 // Operation Wolf(U)
|
||||||
|
|| crc == 0x0d3cf705 // Wild Gunman(J)
|
||||||
|
|| crc == 0x389960db)
|
||||||
|
{ // Wild Gunman(JUE)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_ZAPPER);
|
||||||
|
}
|
||||||
|
if (crc == 0x35893b67 // Arkanoid(J)
|
||||||
|
|| crc == 0x6267fbd1)
|
||||||
|
{ // Arkanoid 2(J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_PADDLE);
|
||||||
|
}
|
||||||
|
if (crc == 0xff6621ce // Hyper Olympic(J)
|
||||||
|
|| crc == 0xdb9418e8 // Hyper Olympic(Tonosama Ban)(J)
|
||||||
|
|| crc == 0xac98cd70)
|
||||||
|
{ // Hyper Sports(J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_HYPERSHOT);
|
||||||
|
}
|
||||||
|
if (crc == 0xf9def527 // Family BASIC(Ver2.0)
|
||||||
|
|| crc == 0xde34526e // Family BASIC(Ver2.1a)
|
||||||
|
|| crc == 0xf050b611 // Family BASIC(Ver3)
|
||||||
|
|| crc == 0x3aaeed3f // Family BASIC(Ver3)(Alt)
|
||||||
|
|| crc == 0x868FCD89 // Family BASIC(Ver1.0)
|
||||||
|
|| crc == 0x2D6B7E5A // PLAYBOX BASIC(J) (Prototype_v0.0)
|
||||||
|
|| crc == 0xDA03D908)
|
||||||
|
{ // PLAYBOX BASIC (J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_KEYBOARD);
|
||||||
|
}
|
||||||
|
if (crc == 0x589b6b0d // Supor Computer V3.0
|
||||||
|
|| crc == 0x8b265862 // Supor English
|
||||||
|
|| crc == 0x41401c6d // Supor Computer V4.0
|
||||||
|
|| crc == 0x82F1Fb96 // Supor Computer(Russia) V1.0
|
||||||
|
|| crc == 0xd5d6eac4)
|
||||||
|
{ // EDU(C) Computer
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_SUPOR_KEYBOARD);
|
||||||
|
nes.SetVideoMode(true);
|
||||||
|
}
|
||||||
|
if (crc == 0xc68363f6 // Crazy Climber(J)
|
||||||
|
|| crc == 0x2989ead6 // Smash TV(U) [!]
|
||||||
|
|| crc == 0x0b8f8128)
|
||||||
|
{ // Smash TV(E) [!]
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_CRAZYCLIMBER);
|
||||||
|
}
|
||||||
|
if (crc == 0x20d22251)
|
||||||
|
{ // Top rider(J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_TOPRIDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x0cd00488)
|
||||||
|
{ // Space Shadow(J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_SPACESHADOWGUN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0x8c8fa83b // Family Trainer - Athletic World (J)
|
||||||
|
|| crc == 0x7e704a14 // Family Trainer - Jogging Race (J)
|
||||||
|
|| crc == 0x2330a5d3)
|
||||||
|
{ // Family Trainer - Rairai Kyonshiizu (J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_FAMILYTRAINER_A);
|
||||||
|
}
|
||||||
|
if (crc == 0xf8da2506 // Family Trainer - Aerobics Studio (J)
|
||||||
|
|| crc == 0xca26a0f1 // Family Trainer - Dai Undoukai (J)
|
||||||
|
|| crc == 0x28068b8c // Family Trainer - Fuuun Takeshi Jou 2 (J)
|
||||||
|
|| crc == 0x10bb8f9a // Family Trainer - Manhattan Police (J)
|
||||||
|
|| crc == 0xad3df455 // Family Trainer - Meiro Dai Sakusen (J)
|
||||||
|
|| crc == 0x8a5b72c0 // Family Trainer - Running Stadium (J)
|
||||||
|
|| crc == 0x59794f2d)
|
||||||
|
{ // Family Trainer - Totsugeki Fuuun Takeshi Jou (J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_FAMILYTRAINER_B);
|
||||||
|
}
|
||||||
|
if (crc == 0x9fae4d46 // Ide Yousuke Meijin no Jissen Mahjong (J)
|
||||||
|
|| crc == 0x7b44fb2a)
|
||||||
|
{ // Ide Yousuke Meijin no Jissen Mahjong 2 (J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_MAHJANG);
|
||||||
|
}
|
||||||
|
if (crc == 0x786148b6)
|
||||||
|
{ // Exciting Boxing (J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_EXCITINGBOXING);
|
||||||
|
}
|
||||||
|
if (crc == 0xc3c0811d // Oeka Kids - Anpanman no Hiragana Daisuki (J)
|
||||||
|
|| crc == 0x9d048ea4)
|
||||||
|
{ // Oeka Kids - Anpanman to Oekaki Shiyou!! (J)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_OEKAKIDS_TABLET);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0x67898319)
|
||||||
|
{ // Barcode World (J)
|
||||||
|
bBarcodeWorld = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VS-Unisystem
|
||||||
|
if (nes.rom.IsVSUNISYSTEM())
|
||||||
|
{
|
||||||
|
if (crc == 0xff5135a3 // VS Hogan's Alley
|
||||||
|
|| crc == 0xed588f00 // VS Duck Hunt
|
||||||
|
|| crc == 0x17ae56be)
|
||||||
|
{ // VS Freedom Force
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_VSZAPPER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_VSUNISYSTEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0x21b099f3)
|
||||||
|
{ // Gyromite (JUE)
|
||||||
|
SetExController(EXCONTROLLER.EXCONTROLLER_GYROMITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetExController(EXCONTROLLER type)
|
||||||
|
{
|
||||||
|
excontroller_select = (int)type;
|
||||||
|
|
||||||
|
expad?.Dispose();
|
||||||
|
expad = null;
|
||||||
|
|
||||||
|
bZapperMode = false;
|
||||||
|
|
||||||
|
// ExPad Instance create
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_ZAPPER:
|
||||||
|
expad = new EXPAD_Zapper(nes);
|
||||||
|
bZapperMode = true;
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_PADDLE:
|
||||||
|
expad = new EXPAD_Paddle(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_HYPERSHOT:
|
||||||
|
expad = new EXPAD_HyperShot(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_KEYBOARD:
|
||||||
|
expad = new EXPAD_Keyboard(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_SUPOR_KEYBOARD:
|
||||||
|
expad = new EXPAD_Supor_Keyboard(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_CRAZYCLIMBER:
|
||||||
|
expad = new EXPAD_CrazyClimber(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_TOPRIDER:
|
||||||
|
expad = new EXPAD_Toprider(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_SPACESHADOWGUN:
|
||||||
|
expad = new EXPAD_SpaceShadowGun(nes);
|
||||||
|
bZapperMode = true;
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_FAMILYTRAINER_A:
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_FAMILYTRAINER_B:
|
||||||
|
expad = new EXPAD_FamlyTrainer(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_EXCITINGBOXING:
|
||||||
|
expad = new EXPAD_ExcitingBoxing(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_MAHJANG:
|
||||||
|
expad = new EXPAD_Mahjang(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_OEKAKIDS_TABLET:
|
||||||
|
expad = new EXPAD_OekakidsTablet(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_TURBOFILE:
|
||||||
|
expad = new EXPAD_TurboFile(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_VSUNISYSTEM:
|
||||||
|
expad = new EXPAD_VSUnisystem(nes);
|
||||||
|
break;
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_VSZAPPER:
|
||||||
|
expad = new EXPAD_VSZapper(nes);
|
||||||
|
bZapperMode = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXCONTROLLER.EXCONTROLLER_GYROMITE:
|
||||||
|
expad = new EXPAD_Gyromite(nes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expad != null)
|
||||||
|
{
|
||||||
|
expad.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VSType
|
public enum VSType
|
||||||
@ -92,4 +417,31 @@ namespace VirtualNes.Core
|
|||||||
VS_TYPE6, // SELECT1P=START1P/SELECT2P=START2P 1P/2P Reverse (For Golf)
|
VS_TYPE6, // SELECT1P=START1P/SELECT2P=START2P 1P/2P Reverse (For Golf)
|
||||||
VS_TYPEZ, // ZAPPER
|
VS_TYPEZ, // ZAPPER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum EXCONTROLLER
|
||||||
|
{
|
||||||
|
EXCONTROLLER_NONE = 0,
|
||||||
|
EXCONTROLLER_PADDLE,
|
||||||
|
EXCONTROLLER_HYPERSHOT,
|
||||||
|
EXCONTROLLER_ZAPPER,
|
||||||
|
EXCONTROLLER_KEYBOARD,
|
||||||
|
EXCONTROLLER_CRAZYCLIMBER,
|
||||||
|
EXCONTROLLER_TOPRIDER,
|
||||||
|
EXCONTROLLER_SPACESHADOWGUN,
|
||||||
|
|
||||||
|
EXCONTROLLER_FAMILYTRAINER_A,
|
||||||
|
EXCONTROLLER_FAMILYTRAINER_B,
|
||||||
|
EXCONTROLLER_EXCITINGBOXING,
|
||||||
|
EXCONTROLLER_MAHJANG,
|
||||||
|
EXCONTROLLER_OEKAKIDS_TABLET,
|
||||||
|
EXCONTROLLER_TURBOFILE,
|
||||||
|
|
||||||
|
EXCONTROLLER_VSUNISYSTEM,
|
||||||
|
EXCONTROLLER_VSZAPPER,
|
||||||
|
|
||||||
|
EXCONTROLLER_GYROMITE,
|
||||||
|
EXCONTROLLER_STACKUP,
|
||||||
|
|
||||||
|
EXCONTROLLER_SUPOR_KEYBOARD,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,15 +95,26 @@ namespace VirtualNes.Core
|
|||||||
public const byte SP_COLOR_BIT = 0x03;
|
public const byte SP_COLOR_BIT = 0x03;
|
||||||
|
|
||||||
private NES nes;
|
private NES nes;
|
||||||
|
|
||||||
|
private bool bExtLatch; // For MMC5
|
||||||
|
private bool bChrLatch; // For MMC2/MMC4
|
||||||
|
private bool bExtNameTable; // For Super Monkey no Dai Bouken
|
||||||
|
private bool bExtMono; // For Final Fantasy
|
||||||
|
|
||||||
|
private ushort loopy_y;
|
||||||
|
private ushort loopy_shift;
|
||||||
|
|
||||||
private byte[] lpScreen;
|
private byte[] lpScreen;
|
||||||
|
/// <summary> 作为lpScreen数组的索引 </summary>
|
||||||
|
private int lpScanline;
|
||||||
|
private int ScanlineNo;
|
||||||
private byte[] lpColormode;
|
private byte[] lpColormode;
|
||||||
|
|
||||||
private bool bVSMode;
|
private bool bVSMode;
|
||||||
private int nVSColorMap;
|
private int nVSColorMap;
|
||||||
private byte VSSecurityData;
|
private byte VSSecurityData;
|
||||||
private byte[] Bit2Rev = new byte[256];
|
private byte[] Bit2Rev = new byte[256];
|
||||||
private int ScanlineNo;
|
|
||||||
/// <summary> 作为lpScreen数组的索引 </summary>
|
|
||||||
private int lpScanline;
|
|
||||||
|
|
||||||
public PPU(NES nes)
|
public PPU(NES nes)
|
||||||
{
|
{
|
||||||
@ -128,9 +139,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal byte Read(ushort addr)
|
internal byte Read(ushort addr)
|
||||||
{
|
{
|
||||||
@ -178,7 +187,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
addr &= 0xEFFF;
|
addr &= 0xEFFF;
|
||||||
}
|
}
|
||||||
MMU.PPU7_Temp = MMU.PPU_MEM_BANK[addr >> 10][addr & 0x03FF];
|
MMU.PPU7_Temp = MMU.PPU_MEM_BANK[addr >> 10].Span[addr & 0x03FF];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +323,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
if (MMU.PPU_MEM_TYPE[vaddr >> 10] != MMU.BANKTYPE_VROM)
|
if (MMU.PPU_MEM_TYPE[vaddr >> 10] != MMU.BANKTYPE_VROM)
|
||||||
{
|
{
|
||||||
MMU.PPU_MEM_BANK[vaddr >> 10][vaddr & 0x03FF] = data;
|
MMU.PPU_MEM_BANK[vaddr >> 10].Span[vaddr & 0x03FF] = data;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -330,6 +339,30 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void Reset()
|
||||||
|
{
|
||||||
|
bExtLatch = false;
|
||||||
|
bChrLatch = false;
|
||||||
|
bExtNameTable = false;
|
||||||
|
bExtMono = false;
|
||||||
|
|
||||||
|
MMU.PPUREG[0] = MMU.PPUREG[1] = 0;
|
||||||
|
|
||||||
|
MMU.PPU56Toggle = 0;
|
||||||
|
|
||||||
|
MMU.PPU7_Temp = 0xFF; // VS Excitebike偱偍偐偟偔側傞($2006傪撉傒偵峴偔僶僌偑偁傞)
|
||||||
|
// PPU7_Temp = 0;
|
||||||
|
|
||||||
|
MMU.loopy_v = MMU.loopy_t = 0;
|
||||||
|
MMU.loopy_x = loopy_y = 0;
|
||||||
|
loopy_shift = 0;
|
||||||
|
|
||||||
|
if (lpScreen != null)
|
||||||
|
MemoryUtility.memset(lpScreen, 0x3F, (int)(Screen.SCREEN_WIDTH) * (int)(Screen.SCREEN_HEIGHT));
|
||||||
|
if (lpColormode != null)
|
||||||
|
MemoryUtility.memset(lpColormode, 0, (int)(Screen.SCREEN_HEIGHT));
|
||||||
|
}
|
||||||
|
|
||||||
private enum Screen
|
private enum Screen
|
||||||
{
|
{
|
||||||
SCREEN_WIDTH = 256 + 16,
|
SCREEN_WIDTH = 256 + 16,
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public class EXPAD
|
public class EXPAD
|
||||||
@ -23,7 +18,7 @@ namespace VirtualNes.Core
|
|||||||
public virtual void Write4016(byte data) { }
|
public virtual void Write4016(byte data) { }
|
||||||
public virtual void Write4017(byte data) { }
|
public virtual void Write4017(byte data) { }
|
||||||
public virtual void Sync() { }
|
public virtual void Sync() { }
|
||||||
public virtual void SetSyncData(int type,int data) { }
|
public virtual void SetSyncData(int type, int data) { }
|
||||||
public virtual int GetSyncData(int type) { return 0x00; }
|
public virtual int GetSyncData(int type) { return 0x00; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_CrazyClimber : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_CrazyClimber(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2d7ac655210edb74ea198ad8802cb545
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_ExcitingBoxing : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_ExcitingBoxing(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2ac6f1c51a9c1b64e970bc5fe5e00b9a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_FamlyTrainer : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_FamlyTrainer(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5a2cfbbbe2b90bd4ba754bc9a8f014af
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_Gyromite : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Gyromite(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c49edbe29e34f0245b621a7920d4981e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_HyperShot : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_HyperShot(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ac43bf6e282394c46b8ea717595d8664
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_Keyboard : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Keyboard(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1f56b9a9d01afad4b967b5d606f7ef11
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_Mahjang : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Mahjang(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 146c88b5d0fab5b43ba7e570f0ff116b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_OekakidsTablet : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_OekakidsTablet(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 47337ac29c001d047a911c028e305b43
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class EXPAD_Paddle : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Paddle(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8e48f82e9b202e64fa7ebe3816804ae9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_SpaceShadowGun : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_SpaceShadowGun(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 01ac1bc69454b414cb5a9db1d12f1aac
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_Supor_Keyboard : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Supor_Keyboard(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5adc370589ec4bf42b7ea0c20acb2a48
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_Toprider : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Toprider(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b0b1053511d6f224a840b0e9df4f9889
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_TurboFile : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_TurboFile(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7b6b41e81a80079489f60eaa5be220cd
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_VSUnisystem : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_VSUnisystem(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d343a07cca05ea642be6db80607ea23a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
internal class EXPAD_VSZapper : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_VSZapper(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6803ff5b7be6edc49ba2b71256aa16a3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 光枪
|
||||||
|
/// </summary>
|
||||||
|
public class EXPAD_Zapper : EXPAD
|
||||||
|
{
|
||||||
|
public EXPAD_Zapper(NES parent) : base(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c378fd8c53bb8084f979b05d2405bb9c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,9 +1,6 @@
|
|||||||
using Codice.CM.Client.Differences;
|
using System;
|
||||||
using System;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using VirtualNes.Core.Debug;
|
using VirtualNes.Core.Debug;
|
||||||
using static UnityEditor.PlayerSettings;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -22,13 +19,13 @@ namespace VirtualNes.Core
|
|||||||
protected byte[] lpTrainer;
|
protected byte[] lpTrainer;
|
||||||
protected byte[] lpDiskBios;
|
protected byte[] lpDiskBios;
|
||||||
protected byte[] lpDisk;
|
protected byte[] lpDisk;
|
||||||
protected ulong crc;
|
protected uint crc;
|
||||||
protected ulong crcall;
|
protected uint crcall;
|
||||||
protected ulong crcvrom;
|
protected uint crcvrom;
|
||||||
protected int mapper;
|
protected int mapper;
|
||||||
protected int diskno;
|
protected int diskno;
|
||||||
protected ulong fdsmakerID;
|
protected uint fdsmakerID;
|
||||||
protected ulong fdsgameID;
|
protected uint fdsgameID;
|
||||||
|
|
||||||
public ROM(string fname)
|
public ROM(string fname)
|
||||||
{
|
{
|
||||||
@ -256,7 +253,7 @@ namespace VirtualNes.Core
|
|||||||
crc = crcall = crcvrom = 0;
|
crc = crcall = crcvrom = 0;
|
||||||
|
|
||||||
fdsmakerID = lpPRG[0x1F];
|
fdsmakerID = lpPRG[0x1F];
|
||||||
fdsgameID = (ulong)((lpPRG[0x20] << 24) | (lpPRG[0x21] << 16) | (lpPRG[0x22] << 8) | (lpPRG[0x23] << 0));
|
fdsgameID = (uint)((lpPRG[0x20] << 24) | (lpPRG[0x21] << 16) | (lpPRG[0x22] << 8) | (lpPRG[0x23] << 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //NSF
|
else //NSF
|
||||||
@ -301,6 +298,10 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
return bNSF;
|
return bNSF;
|
||||||
}
|
}
|
||||||
|
public bool IsPAL()
|
||||||
|
{
|
||||||
|
return bPAL;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsSAVERAM()
|
public bool IsSAVERAM()
|
||||||
{
|
{
|
||||||
@ -331,6 +332,11 @@ namespace VirtualNes.Core
|
|||||||
return lpPRG;
|
return lpPRG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal byte[] GetVROM()
|
||||||
|
{
|
||||||
|
return lpCHR;
|
||||||
|
}
|
||||||
|
|
||||||
internal byte[] GetDISK()
|
internal byte[] GetDISK()
|
||||||
{
|
{
|
||||||
return lpDisk;
|
return lpDisk;
|
||||||
@ -355,6 +361,41 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
return (header.control2 & (byte)EnumRomControlByte2.ROM_VSUNISYSTEM) != 0;
|
return (header.control2 & (byte)EnumRomControlByte2.ROM_VSUNISYSTEM) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal uint GetPROM_CRC()
|
||||||
|
{
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal byte GetPROM_SIZE()
|
||||||
|
{
|
||||||
|
return header.PRG_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal byte GetVROM_SIZE()
|
||||||
|
{
|
||||||
|
return header.CHR_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool Is4SCREEN()
|
||||||
|
{
|
||||||
|
return (header.control1 & (byte)EnumRomControlByte1.ROM_4SCREEN) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool IsVMIRROR()
|
||||||
|
{
|
||||||
|
return (header.control1 & (byte)EnumRomControlByte1.ROM_VMIRROR) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal byte[] GetTRAINER()
|
||||||
|
{
|
||||||
|
return lpTrainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal NSFHEADER GetNsfHeader()
|
||||||
|
{
|
||||||
|
return nsfheader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fd0714f580724604da063207fe69e274
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgController
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3328948cdc73baa4fb90c995f39f454f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,18 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgEmulator
|
||||||
|
{
|
||||||
|
public bool bIllegalOp { get; set; } = false;
|
||||||
|
public bool bAutoFrameSkip { get; set; } = true;
|
||||||
|
public bool bThrottle { get; set; } = true;
|
||||||
|
public int nThrottleFPS { get; set; } = 120;
|
||||||
|
public bool bBackground { get; set; } = false;
|
||||||
|
public int nPriority { get; set; } = 3;
|
||||||
|
public bool bFourPlayer { get; set; } = true;
|
||||||
|
public bool bCrcCheck { get; set; } = true;
|
||||||
|
public bool bDiskThrottle { get; set; } = true;
|
||||||
|
public bool bLoadFullscreen { get; set; } = false;
|
||||||
|
public bool bPNGsnapshot { get; set; } = false;
|
||||||
|
public bool bAutoIPS { get; set; } = false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aae682cf38878ae40a449ab1a13fc7fc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgExtraSound
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c707e4c8c38fa2e40a884047d0582b7e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,6 +1,7 @@
|
|||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public class CHEATCODE
|
public class CfgGeneral
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 797171ffbac5b8748923ba914141781d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgGraphics
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c5d72263cee06c74e94d67af00befbdf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgLanguage
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c23af0b4dd8a4e04a89d1a380c54688f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgLauncher
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a033c816849b204c8cda167cd1fddb0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgMovie
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fdbdc9850f494ad44a16ec1ec82157cc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgNetPlay
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6a81c95a03cbc4f4298e034f2b5cab7c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgPath
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c9368c1964e431040a469e2fb7b1c710
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgShortCut
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4bc2f955a549544e9f03a73b98455fb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,19 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class CfgSound
|
||||||
|
{
|
||||||
|
public bool bEnable { get; set; } = true;
|
||||||
|
public int nRate { get; set; } = 22050;
|
||||||
|
public int nBits { get; set; } = 8;
|
||||||
|
public int nBufferSize { get; set; } = 4;
|
||||||
|
public int nFilterType { get; set; } = 0;
|
||||||
|
public bool bChangeTone { get; set; } = false;
|
||||||
|
public bool bDisableVolumeEffect { get; set; } = false;
|
||||||
|
public bool bExtraSoundEnable { get; set; } = true;
|
||||||
|
public short[] nVolume { get; set; } = new short[16]
|
||||||
|
{
|
||||||
|
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f13850718ff124445ad8696ef491313d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,20 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class EmulatorConfig
|
||||||
|
{
|
||||||
|
private bool m_bKeyboardDisable;
|
||||||
|
|
||||||
|
public CfgGeneral general { get; private set; } = new CfgGeneral();
|
||||||
|
public CfgPath path { get; private set; } = new CfgPath();
|
||||||
|
public CfgEmulator emulator { get; private set; } = new CfgEmulator();
|
||||||
|
public CfgGraphics graphics { get; private set; } = new CfgGraphics();
|
||||||
|
public CfgSound sound { get; private set; } = new CfgSound();
|
||||||
|
public CfgShortCut shortcut { get; private set; } = new CfgShortCut();
|
||||||
|
public CfgLanguage language { get; private set; } = new CfgLanguage();
|
||||||
|
public CfgController controller { get; private set; } = new CfgController();
|
||||||
|
public CfgMovie movie { get; private set; } = new CfgMovie();
|
||||||
|
public CfgLauncher launcher { get; private set; } = new CfgLauncher();
|
||||||
|
public CfgExtraSound extsound { get; private set; } = new CfgExtraSound();
|
||||||
|
public CfgNetPlay netplay { get; private set; } = new CfgNetPlay();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8e0eb25b08646f64eaf7930288788c68
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,7 +1,4 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -37,6 +34,8 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
s_support.SaveDISKToFile(diskFileContent, romName);
|
s_support.SaveDISKToFile(diskFileContent, romName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EmulatorConfig Config => s_support.Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ISupporterImpl
|
public interface ISupporterImpl
|
||||||
@ -46,5 +45,6 @@ namespace VirtualNes.Core
|
|||||||
Stream OpenFile_DISKSYS();
|
Stream OpenFile_DISKSYS();
|
||||||
void SaveSRAMToFile(byte[] sramContent, string romName);
|
void SaveSRAMToFile(byte[] sramContent, string romName);
|
||||||
void SaveDISKToFile(byte[] diskFileContent, string romName);
|
void SaveDISKToFile(byte[] diskFileContent, string romName);
|
||||||
|
EmulatorConfig Config { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user