ROMDB提交,Mapper修復

This commit is contained in:
ALIENJACK\alien 2024-08-06 13:49:24 +08:00
parent c7f32874ae
commit e4da00136d
31 changed files with 22702 additions and 1450 deletions

3
.gitignore vendored
View File

@ -14,3 +14,6 @@
/AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset /AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset
/AxibugEmuOnline.Client/Logs /AxibugEmuOnline.Client/Logs
/virtuanessrc097-master/save /virtuanessrc097-master/save
/virtuanessrc097-master/.vs
/virtuanessrc097-master/Debug
/virtuanessrc097-master/VirtualNES.ini

File diff suppressed because it is too large Load Diff

View File

@ -3,45 +3,50 @@ using System.Diagnostics;
using UnityEngine; using UnityEngine;
using VirtualNes.Core; using VirtualNes.Core;
public class AudioProvider : MonoBehaviour namespace AxibugEmuOnline.Client
{ {
[SerializeField]
private AudioSource m_as;
private SoundBuffer _buffer = new SoundBuffer(4096); public class AudioProvider : MonoBehaviour
public void Initialize()
{ {
var dummy = AudioClip.Create("dummy", 1, 1, AudioSettings.outputSampleRate, false); [SerializeField]
private AudioSource m_as;
dummy.SetData(new float[] { 1 }, 0); private SoundBuffer _buffer = new SoundBuffer(4096);
m_as.clip = dummy; //just to let unity play the audiosource
m_as.loop = true;
m_as.spatialBlend = 1;
m_as.Play();
}
void OnAudioFilterRead(float[] data, int channels) public void Initialize()
{
int step = channels;
var bufferCount = _buffer.Available();
for (int i = 0; i < data.Length; i += step)
{ {
float rawFloat = 0; var dummy = AudioClip.Create("dummy", 1, 1, AudioSettings.outputSampleRate, false);
if (_buffer.TryRead(out byte rawData))
rawFloat = rawData / 255f;
data[i] = rawFloat; dummy.SetData(new float[] { 1 }, 0);
for (int fill = 1; fill < step; fill++) m_as.clip = dummy; //just to let unity play the audiosource
data[i + fill] = rawFloat; m_as.loop = true;
m_as.spatialBlend = 1;
m_as.Play();
}
void OnAudioFilterRead(float[] data, int channels)
{
int step = channels;
var bufferCount = _buffer.Available();
for (int i = 0; i < data.Length; i += step)
{
float rawFloat = 0;
if (_buffer.TryRead(out byte rawData))
rawFloat = rawData / 255f;
data[i] = rawFloat;
for (int fill = 1; fill < step; fill++)
data[i + fill] = rawFloat;
}
}
public void ProcessSound(NES nes)
{
nes.apu.Process(_buffer, (uint)(Supporter.Config.sound.nRate * Time.deltaTime));
} }
} }
public void ProcessSound(NES nes) }
{
nes.apu.Process(_buffer, (uint)(Supporter.Config.sound.nRate * Time.deltaTime));
}
}

View File

@ -17,7 +17,7 @@ namespace AxibugEmuOnline.Client
private void Start() private void Start()
{ {
Application.targetFrameRate = 60; Application.targetFrameRate = 60;
StartGame("tstd2.nes"); StartGame("ff1.nes");
} }
public void StartGame(string romName) public void StartGame(string romName)
@ -44,7 +44,6 @@ namespace AxibugEmuOnline.Client
m_nesIns = null; m_nesIns = null;
} }
private void Update() private void Update()
{ {
if (m_nesIns != null) if (m_nesIns != null)

View File

@ -30,7 +30,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 4232056521131536011} m_Father: {fileID: 4232056521131536011}
m_RootOrder: 1 m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9003897287163669553 --- !u!114 &9003897287163669553
MonoBehaviour: MonoBehaviour:
@ -141,6 +141,78 @@ AudioSource:
m_PreInfinity: 2 m_PreInfinity: 2
m_PostInfinity: 2 m_PostInfinity: 2
m_RotationOrder: 4 m_RotationOrder: 4
--- !u!1 &3545890545112170401
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1038087993597378172}
- component: {fileID: 3032498056073774270}
- component: {fileID: 634277252673086327}
m_Layer: 5
m_Name: Viewer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1038087993597378172
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3545890545112170401}
m_LocalRotation: {x: 1, y: 0, z: 0, w: 0}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 4232056520494431727}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 128, y: 256}
m_Pivot: {x: 0, y: 0}
--- !u!222 &3032498056073774270
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3545890545112170401}
m_CullTransparentMesh: 1
--- !u!114 &634277252673086327
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3545890545112170401}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 8400000, guid: ffe34aaf87e4b9942b4c2ac05943d444, type: 2}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!1 &4232056520112715746 --- !u!1 &4232056520112715746
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -168,8 +240,7 @@ Transform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: m_Children: []
- {fileID: 4232056520494431727}
m_Father: {fileID: 4232056521131536011} m_Father: {fileID: 4232056521131536011}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -217,8 +288,9 @@ RectTransform:
m_LocalScale: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0, y: 0, z: 0}
m_Children: m_Children:
- {fileID: 4232056521759880275} - {fileID: 4232056521759880275}
m_Father: {fileID: 4232056520112715745} - {fileID: 1038087993597378172}
m_RootOrder: 0 m_Father: {fileID: 4232056521131536011}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
@ -315,7 +387,9 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: m_Children:
- {fileID: 4232056520112715745} - {fileID: 4232056520112715745}
- {fileID: 393435831810118449}
- {fileID: 4785916497946256520} - {fileID: 4785916497946256520}
- {fileID: 4232056520494431727}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -405,3 +479,47 @@ MonoBehaviour:
y: 0 y: 0
width: 1 width: 1
height: 1 height: 1
--- !u!1 &7856060136050839404
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 393435831810118449}
- component: {fileID: 499856625911497759}
m_Layer: 0
m_Name: PatternViewer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &393435831810118449
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7856060136050839404}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 4232056521131536011}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &499856625911497759
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7856060136050839404}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c7a50c189f5be5b4ea54de444f8488a0, type: 3}
m_Name:
m_EditorClassIdentifier:
img: {fileID: 634277252673086327}

View File

@ -7,10 +7,18 @@ using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using VirtualNes.Core; using VirtualNes.Core;
namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator namespace AxibugEmuOnline.Client
{ {
public static class PaletteDefine public static class PaletteDefine
{ {
public struct RGBQUAD
{
public byte rgbBlue;
public byte rgbGreen;
public byte rgbRed;
public byte rgbReserved;
}
public class PALBUF public class PALBUF
{ {
public byte r; public byte r;
@ -108,6 +116,33 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
new PALBUF(0x00, 0x00, 0x00), new PALBUF(0x00, 0x00, 0x00),
}; };
#region 256
// Color
public static RGBQUAD[][] m_cpPalette = new RGBQUAD[8][]
{
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
};
// Monochrome
public static RGBQUAD[][] m_mpPalette = new RGBQUAD[8][]
{
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
};
#endregion
#region #region
// Color // Color
public static uint[][] m_cnPalette = new uint[8][] public static uint[][] m_cnPalette = new uint[8][]
@ -161,6 +196,18 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
}; };
#endregion #endregion
public static RGBQUAD[] GetPaletteData()
{
RGBQUAD[] rgb = new RGBQUAD[256];
for (int i = 0; i < 64; i++)
{
rgb[i] = m_cpPalette[0][i];
rgb[i + 0x40] = m_mpPalette[0][i];
}
return rgb;
}
static PaletteDefine() static PaletteDefine()
{ {
int Rbit = 0, Gbit = 0, Bbit = 0; int Rbit = 0, Gbit = 0, Bbit = 0;
@ -186,6 +233,13 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
Gs = (uint)(PalConvTbl[j][1] * m_PaletteBuf[i].g * m_nScanlineColor / 100.0f); Gs = (uint)(PalConvTbl[j][1] * m_PaletteBuf[i].g * m_nScanlineColor / 100.0f);
Bs = (uint)(PalConvTbl[j][2] * m_PaletteBuf[i].b * m_nScanlineColor / 100.0f); Bs = (uint)(PalConvTbl[j][2] * m_PaletteBuf[i].b * m_nScanlineColor / 100.0f);
m_cpPalette[j][i + 0x00].rgbRed = (byte)Rn;
m_cpPalette[j][i + 0x00].rgbGreen = (byte)Gn;
m_cpPalette[j][i + 0x00].rgbBlue = (byte)Bn;
m_cpPalette[j][i + 0x40].rgbRed = (byte)Rs;
m_cpPalette[j][i + 0x40].rgbGreen = (byte)Gs;
m_cpPalette[j][i + 0x40].rgbBlue = (byte)Bs;
m_cnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft); m_cnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft);
m_csPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft); m_csPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft);
@ -216,6 +270,13 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
if (Gs > 0xFF) Gs = 0xFF; if (Gs > 0xFF) Gs = 0xFF;
if (Bs > 0xFF) Bs = 0xFF; if (Bs > 0xFF) Bs = 0xFF;
m_mpPalette[j][i + 0x00].rgbRed = (byte)Rn;
m_mpPalette[j][i + 0x00].rgbGreen = (byte)Gn;
m_mpPalette[j][i + 0x00].rgbBlue = (byte)Bn;
m_mpPalette[j][i + 0x40].rgbRed = (byte)Rs;
m_mpPalette[j][i + 0x40].rgbGreen = (byte)Gs;
m_mpPalette[j][i + 0x40].rgbBlue = (byte)Bs;
m_mnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft); m_mnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft);
m_msPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft); m_msPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft);
} }

View File

@ -0,0 +1,75 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using VirtualNes;
using static AxibugEmuOnline.Client.PaletteDefine;
namespace AxibugEmuOnline.Client
{
public class PatternViewer : MonoBehaviour
{
public RawImage img;
private Color32[] m_lpPattern = new Color32[128 * 256];
private Texture2D m_texture;
private Dictionary<byte, RGBQUAD> colors = new Dictionary<byte, RGBQUAD>();
private void Awake()
{
m_texture = new Texture2D(128, 256);
}
private void Update()
{
Paint();
}
public void Paint()
{
img.texture = m_texture;
var pal = MMU.SPPAL;
var palette = PaletteDefine.GetPaletteData();
colors[0] = palette[pal[0]];
colors[1] = palette[pal[1]];
colors[2] = palette[pal[2]];
colors[3] = palette[pal[3]];
for (int i = 0; i < 8; i++)
{
var Ptn = MMU.PPU_MEM_BANK[i];
int lpPtn = 0;
for (int p = 0; p < 64; p++)
{
int lpScn = i * 32 * 128 + (p & 15) * 8 + (p / 16) * 8 * 128;
for (int y = 0; y < 8; y++)
{
byte chr_l = Ptn[lpPtn + y];
byte chr_h = Ptn[lpPtn + y + 8];
m_lpPattern[lpScn + 0] = ToColor32(colors, (((chr_h >> 6) & 2) | ((chr_l >> 7) & 1)));
m_lpPattern[lpScn + 4] = ToColor32(colors, (((chr_h >> 2) & 2) | ((chr_l >> 3) & 1)));
m_lpPattern[lpScn + 1] = ToColor32(colors, (((chr_h >> 5) & 2) | ((chr_l >> 6) & 1)));
m_lpPattern[lpScn + 5] = ToColor32(colors, (((chr_h >> 1) & 2) | ((chr_l >> 2) & 1)));
m_lpPattern[lpScn + 2] = ToColor32(colors, (((chr_h >> 4) & 2) | ((chr_l >> 5) & 1)));
m_lpPattern[lpScn + 6] = ToColor32(colors, (((chr_h >> 0) & 2) | ((chr_l >> 1) & 1)));
m_lpPattern[lpScn + 3] = ToColor32(colors, (((chr_h >> 3) & 2) | ((chr_l >> 4) & 1)));
m_lpPattern[lpScn + 7] = ToColor32(colors, (((chr_h << 1) & 2) | ((chr_l >> 0) & 1)));
// Next line
lpScn += 128;
}
// Next pattern
lpPtn += 16;
}
}
m_texture.SetPixels32(m_lpPattern);
m_texture.Apply();
}
private Color32 ToColor32(Dictionary<byte, RGBQUAD> map, int v)
{
var raw = map[(byte)v];
return new Color32(raw.rgbRed, raw.rgbGreen, raw.rgbBlue, 255);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7a50c189f5be5b4ea54de444f8488a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,9 +1,7 @@
using AxibugEmuOnline.Client.Assets.Script.NesEmulator;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using VirtualNes.Core;
namespace AxibugEmuOnline.Client namespace AxibugEmuOnline.Client
{ {

View File

@ -34,6 +34,13 @@ namespace VirtualNes.Core
m_length = length; m_length = length;
} }
public void SetArray(byte[] array, int offset)
{
m_rawArray = array;
m_offset = offset;
m_length = array.Length - offset;
}
public byte this[int index] public byte this[int index]
{ {
get get

View File

@ -78,6 +78,13 @@ namespace VirtualNes
CPU_MEM_PAGE[page] = 0; CPU_MEM_PAGE[page] = 0;
} }
internal static void SetPROM_Bank(byte page, ByteArrayRef 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) internal static void SetPROM_8K_Bank(byte page, int bank)
{ {
bank %= PROM_8K_SIZE; bank %= PROM_8K_SIZE;

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c57bc13f96a8d064a885b65c6aebc351
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -8,404 +8,409 @@ using BYTE = System.Byte;
using Codice.CM.Client.Differences; using Codice.CM.Client.Differences;
namespace VirtualNes.Core namespace VirtualNes.Core
{ {
public class Mapper001 : Mapper public class Mapper001 : Mapper
{ {
uint last_addr; uint last_addr;
BYTE patch; BYTE patch;
BYTE wram_patch; BYTE wram_patch;
BYTE wram_bank; BYTE wram_bank;
BYTE wram_count; BYTE wram_count;
BYTE[] reg = new byte[4]; BYTE[] reg = new byte[4];
BYTE shift, regbuf; BYTE shift, regbuf;
public Mapper001(NES parent) : base(parent) { } public Mapper001(NES parent) : base(parent) { }
public override void Reset() public override void Reset()
{ {
reg[0] = 0x0C; // D3=1,D2=1 reg[0] = 0x0C; // D3=1,D2=1
reg[1] = reg[2] = reg[3] = 0; reg[1] = reg[2] = reg[3] = 0;
shift = regbuf = 0; shift = regbuf = 0;
patch = 0; patch = 0;
wram_patch = 0; wram_patch = 0;
if (PROM_16K_SIZE < 32) if (PROM_16K_SIZE < 32)
{ {
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1); SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
} }
else else
{ {
// For 512K/1M byte Cartridge // For 512K/1M byte Cartridge
SetPROM_16K_Bank(4, 0); SetPROM_16K_Bank(4, 0);
SetPROM_16K_Bank(6, 16 - 1); SetPROM_16K_Bank(6, 16 - 1);
patch = 1; patch = 1;
} }
if (VROM_8K_SIZE != 0) if (VROM_8K_SIZE != 0)
{ {
// SetVROM_8K_Bank( 0 ); // SetVROM_8K_Bank( 0 );
} }
uint crc = nes.rom.GetPROM_CRC(); uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xb8e16bd0) if (crc == 0xb8e16bd0)
{ // Snow Bros.(J) { // Snow Bros.(J)
patch = 2; patch = 2;
} }
// if( crc == 0x9b565541 ) { // Triathron, The(J) // if( crc == 0x9b565541 ) { // Triathron, The(J)
// nes.SetFrameIRQmode( FALSE ); // nes.SetFrameIRQmode( FALSE );
// } // }
if (crc == 0xc96c6f04) if (crc == 0xc96c6f04)
{ // Venus Senki(J) { // Venus Senki(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER); nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
} }
// if( crc == 0x5e3f7004 ) { // Softball Tengoku(J) // if( crc == 0x5e3f7004 ) { // Softball Tengoku(J)
// } // }
if (crc == 0x4d2edf70) if (crc == 0x4d2edf70)
{ // Night Rider(J) { // Night Rider(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER); nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
} }
if (crc == 0xcd2a73f0) if (crc == 0xcd2a73f0)
{ // Pirates!(U) { // Pirates!(U)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER); nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
patch = 2; patch = 2;
} }
// if( crc == 0x09efe54b ) { // Majaventure - Mahjong Senki(J) // if( crc == 0x09efe54b ) { // Majaventure - Mahjong Senki(J)
// nes.SetFrameIRQmode( FALSE ); // nes.SetFrameIRQmode( FALSE );
// } // }
if (crc == 0x11469ce3) if (crc == 0x11469ce3)
{ // Viva! Las Vegas(J) { // Viva! Las Vegas(J)
} }
if (crc == 0xd878ebf5) if (crc == 0xd878ebf5)
{ // Ninja Ryukenden(J) { // Ninja Ryukenden(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER); nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
} }
// if( crc == 0x7bd7b849 ) { // Nekketsu Koukou - Dodgeball Bu(J) // if( crc == 0x7bd7b849 ) { // Nekketsu Koukou - Dodgeball Bu(J)
// } // }
if (crc == 0x466efdc2) if (crc == 0x466efdc2)
{ // Final Fantasy(J) { // Final Fantasy(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER); nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
nes.ppu.SetExtMonoMode(true); nes.ppu.SetExtMonoMode(true);
} }
if (crc == 0xc9556b36) if (crc == 0xc9556b36)
{ // Final Fantasy I&II(J) { // Final Fantasy I&II(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER); nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
nes.ppu.SetExtMonoMode(true); nes.ppu.SetExtMonoMode(true);
nes.SetSAVERAM_SIZE(16 * 1024); nes.SetSAVERAM_SIZE(16 * 1024);
wram_patch = 2; wram_patch = 2;
} }
if (crc == 0x717e1169) if (crc == 0x717e1169)
{ // Cosmic Wars(J) { // Cosmic Wars(J)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER); nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
} }
if (crc == 0xC05D2034) if (crc == 0xC05D2034)
{ // Snake's Revenge(U) { // Snake's Revenge(U)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER); nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
} }
if (crc == 0xb8747abf // Best Play - Pro Yakyuu Special(J) if (crc == 0xb8747abf // Best Play - Pro Yakyuu Special(J)
|| crc == 0x29449ba9 // Nobunaga no Yabou - Zenkoku Ban(J) || crc == 0x29449ba9 // Nobunaga no Yabou - Zenkoku Ban(J)
|| crc == 0x2b11e0b0 // Nobunaga no Yabou - Zenkoku Ban(J)(alt) || crc == 0x2b11e0b0 // Nobunaga no Yabou - Zenkoku Ban(J)(alt)
|| crc == 0x4642dda6 // Nobunaga's Ambition(U) || crc == 0x4642dda6 // Nobunaga's Ambition(U)
|| crc == 0xfb69743a // Aoki Ookami to Shiroki Mejika - Genghis Khan(J) || crc == 0xfb69743a // Aoki Ookami to Shiroki Mejika - Genghis Khan(J)
|| crc == 0x2225c20f // Genghis Khan(U) || crc == 0x2225c20f // Genghis Khan(U)
|| crc == 0xabbf7217 // Sangokushi(J) || crc == 0xabbf7217 // Sangokushi(J)
) )
{ {
nes.SetSAVERAM_SIZE(16 * 1024); nes.SetSAVERAM_SIZE(16 * 1024);
wram_patch = 1; wram_patch = 1;
wram_bank = 0; wram_bank = 0;
wram_count = 0; wram_count = 0;
} }
} }
//void Mapper001::Write(WORD addr, BYTE data) private ByteArrayRef _PROM_BANK = new ByteArrayRef();
public override void Write(ushort addr, byte data) //void Mapper001::Write(WORD addr, BYTE data)
{ public override void Write(ushort addr, byte data)
// DEBUGOUT( "MMC1 %04X=%02X\n", addr&0xFFFF,data&0xFF ); {
// DEBUGOUT( "MMC1 %04X=%02X\n", addr&0xFFFF,data&0xFF );
if (wram_patch == 1 && addr == 0xBFFF)
{ if (wram_patch == 1 && addr == 0xBFFF)
wram_count++; {
wram_bank += (byte)(data & 0x01); wram_count++;
if (wram_count == 5) wram_bank += (byte)(data & 0x01);
{ if (wram_count == 5)
if (wram_bank != 0) {
{ if (wram_bank != 0)
SetPROM_Bank(3, &WRAM[0x2000], BANKTYPE_RAM); {
} _PROM_BANK.SetArray(WRAM, 0x2000);
else SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
{ }
SetPROM_Bank(3, &WRAM[0x0000], BANKTYPE_RAM); else
} {
wram_bank = wram_count = 0; _PROM_BANK.SetArray(WRAM, 0x0000);
} SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
} }
wram_bank = wram_count = 0;
if (patch != 1) }
{ }
if ((addr & 0x6000) != (last_addr & 0x6000))
{ if (patch != 1)
shift = regbuf = 0; {
} if ((addr & 0x6000) != (last_addr & 0x6000))
last_addr = addr; {
} shift = regbuf = 0;
}
if ((data & 0x80) != 0) last_addr = addr;
{ }
shift = regbuf = 0;
// reg[0] = 0x0C; // D3=1,D2=1 if ((data & 0x80) != 0)
reg[0] |= 0x0C; // D3=1,D2=1 残りはリセットされない {
return; shift = regbuf = 0;
} // reg[0] = 0x0C; // D3=1,D2=1
reg[0] |= 0x0C; // D3=1,D2=1 残りはリセットされない
if ((data & 0x01) != 0) regbuf |= (byte)(1 << shift); return;
if (++shift < 5) }
return;
addr = (ushort)((addr & 0x7FFF) >> 13); if ((data & 0x01) != 0) regbuf |= (byte)(1 << shift);
reg[addr] = regbuf; if (++shift < 5)
return;
// DEBUGOUT( "MMC1 %d=%02X\n", addr&0xFFFF,regbuf&0xFF ); addr = (ushort)((addr & 0x7FFF) >> 13);
reg[addr] = regbuf;
regbuf = 0;
shift = 0; // DEBUGOUT( "MMC1 %d=%02X\n", addr&0xFFFF,regbuf&0xFF );
if (patch != 1) regbuf = 0;
{ shift = 0;
// For Normal Cartridge
switch (addr) if (patch != 1)
{ {
case 0: // For Normal Cartridge
if ((reg[0] & 0x02) != 0) switch (addr)
{ {
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR); case 0:
else SetVRAM_Mirror(VRAM_VMIRROR); if ((reg[0] & 0x02) != 0)
} {
else if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
{ else SetVRAM_Mirror(VRAM_VMIRROR);
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_MIRROR4H); }
else SetVRAM_Mirror(VRAM_MIRROR4L); else
} {
break; if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
case 1: else SetVRAM_Mirror(VRAM_MIRROR4L);
// Register #1 }
if (VROM_1K_SIZE != 0) break;
{ case 1:
if ((reg[0] & 0x10) != 0) // Register #1
{ if (VROM_1K_SIZE != 0)
// CHR 4K bank lower($0000-$0FFF) {
SetVROM_4K_Bank(0, reg[1]); if ((reg[0] & 0x10) != 0)
// CHR 4K bank higher($1000-$1FFF) {
SetVROM_4K_Bank(4, reg[2]); // CHR 4K bank lower($0000-$0FFF)
} SetVROM_4K_Bank(0, reg[1]);
else // CHR 4K bank higher($1000-$1FFF)
{ SetVROM_4K_Bank(4, reg[2]);
// CHR 8K bank($0000-$1FFF) }
SetVROM_8K_Bank(reg[1] >> 1); else
} {
} // CHR 8K bank($0000-$1FFF)
else SetVROM_8K_Bank(reg[1] >> 1);
{ }
// For Romancia }
if ((reg[0] & 0x10) != 0) else
{ {
SetCRAM_4K_Bank(0, reg[1]); // For Romancia
} if ((reg[0] & 0x10) != 0)
} {
break; SetCRAM_4K_Bank(0, reg[1]);
case 2: }
// Register #2 }
if (VROM_1K_SIZE != 0) break;
{ case 2:
if ((reg[0] & 0x10) != 0) // Register #2
{ if (VROM_1K_SIZE != 0)
// CHR 4K bank lower($0000-$0FFF) {
SetVROM_4K_Bank(0, reg[1]); if ((reg[0] & 0x10) != 0)
// CHR 4K bank higher($1000-$1FFF) {
SetVROM_4K_Bank(4, reg[2]); // CHR 4K bank lower($0000-$0FFF)
} SetVROM_4K_Bank(0, reg[1]);
else // CHR 4K bank higher($1000-$1FFF)
{ SetVROM_4K_Bank(4, reg[2]);
// CHR 8K bank($0000-$1FFF) }
SetVROM_8K_Bank(reg[1] >> 1); else
} {
} // CHR 8K bank($0000-$1FFF)
else SetVROM_8K_Bank(reg[1] >> 1);
{ }
// For Romancia }
if ((reg[0] & 0x10) != 0) else
{ {
SetCRAM_4K_Bank(4, reg[2]); // For Romancia
} if ((reg[0] & 0x10) != 0)
} {
break; SetCRAM_4K_Bank(4, reg[2]);
case 3: }
if (!((reg[0] & 0x08) != 0)) }
{ break;
// PRG 32K bank ($8000-$FFFF) case 3:
SetPROM_32K_Bank(reg[3] >> 1); if (!((reg[0] & 0x08) != 0))
} {
else // PRG 32K bank ($8000-$FFFF)
{ SetPROM_32K_Bank(reg[3] >> 1);
if ((reg[0] & 0x04) != 0) }
{ else
// PRG 16K bank ($8000-$BFFF) {
SetPROM_16K_Bank(4, reg[3]); if ((reg[0] & 0x04) != 0)
SetPROM_16K_Bank(6, PROM_16K_SIZE - 1); {
} // PRG 16K bank ($8000-$BFFF)
else SetPROM_16K_Bank(4, reg[3]);
{ SetPROM_16K_Bank(6, PROM_16K_SIZE - 1);
// PRG 16K bank ($C000-$FFFF) }
SetPROM_16K_Bank(6, reg[3]); else
SetPROM_16K_Bank(4, 0); {
} // PRG 16K bank ($C000-$FFFF)
} SetPROM_16K_Bank(6, reg[3]);
break; SetPROM_16K_Bank(4, 0);
} }
} }
else break;
{ }
// For 512K/1M byte Cartridge }
INT PROM_BASE = 0; else
if (PROM_16K_SIZE >= 32) {
{ // For 512K/1M byte Cartridge
PROM_BASE = reg[1] & 0x10; INT PROM_BASE = 0;
} if (PROM_16K_SIZE >= 32)
{
// For FinalFantasy I&II PROM_BASE = reg[1] & 0x10;
if (wram_patch == 2) }
{
if (((reg[1] & 0x18) == 0)) // For FinalFantasy I&II
{ if (wram_patch == 2)
SetPROM_Bank(3, &WRAM[0x0000], BANKTYPE_RAM); {
} if (((reg[1] & 0x18) == 0))
else {
{ _PROM_BANK.SetArray(WRAM, 0x0000);
SetPROM_Bank(3, &WRAM[0x2000], BANKTYPE_RAM); SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
} }
} else
{
// Register #0 _PROM_BANK.SetArray(WRAM, 0x2000);
if (addr == 0) SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
{ }
if ((reg[0] & 0x02) != 0) }
{
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR); // Register #0
else SetVRAM_Mirror(VRAM_VMIRROR); if (addr == 0)
} {
else if ((reg[0] & 0x02) != 0)
{ {
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_MIRROR4H); if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_MIRROR4L); else SetVRAM_Mirror(VRAM_VMIRROR);
} }
} else
// Register #1 {
if (VROM_1K_SIZE != 0) if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
{ else SetVRAM_Mirror(VRAM_MIRROR4L);
if ((reg[0] & 0x10) != 0) }
{ }
// CHR 4K bank lower($0000-$0FFF) // Register #1
SetVROM_4K_Bank(0, reg[1]); if (VROM_1K_SIZE != 0)
} {
else if ((reg[0] & 0x10) != 0)
{ {
// CHR 8K bank($0000-$1FFF) // CHR 4K bank lower($0000-$0FFF)
SetVROM_8K_Bank(reg[1] >> 1); SetVROM_4K_Bank(0, reg[1]);
} }
} else
else {
{ // CHR 8K bank($0000-$1FFF)
// For Romancia SetVROM_8K_Bank(reg[1] >> 1);
if ((reg[0] & 0x10) != 0) }
{ }
SetCRAM_4K_Bank(0, reg[1]); else
} {
} // For Romancia
// Register #2 if ((reg[0] & 0x10) != 0)
if (VROM_1K_SIZE != 0) {
{ SetCRAM_4K_Bank(0, reg[1]);
if ((reg[0] & 0x10) != 0) }
{ }
// CHR 4K bank higher($1000-$1FFF) // Register #2
SetVROM_4K_Bank(4, reg[2]); if (VROM_1K_SIZE != 0)
} {
} if ((reg[0] & 0x10) != 0)
else {
{ // CHR 4K bank higher($1000-$1FFF)
// For Romancia SetVROM_4K_Bank(4, reg[2]);
if ((reg[0] & 0x10) != 0) }
{ }
SetCRAM_4K_Bank(4, reg[2]); else
} {
} // For Romancia
// Register #3 if ((reg[0] & 0x10) != 0)
if (((reg[0] & 0x08) == 0)) {
{ SetCRAM_4K_Bank(4, reg[2]);
// PRG 32K bank ($8000-$FFFF) }
SetPROM_32K_Bank((reg[3] & (0xF + PROM_BASE)) >> 1); }
} // Register #3
else if (((reg[0] & 0x08) == 0))
{ {
if ((reg[0] & 0x04) != 0) // PRG 32K bank ($8000-$FFFF)
{ SetPROM_32K_Bank((reg[3] & (0xF + PROM_BASE)) >> 1);
// PRG 16K bank ($8000-$BFFF) }
SetPROM_16K_Bank(4, PROM_BASE + (reg[3] & 0x0F)); else
if (PROM_16K_SIZE >= 32) SetPROM_16K_Bank(6, PROM_BASE + 16 - 1); {
} if ((reg[0] & 0x04) != 0)
else {
{ // PRG 16K bank ($8000-$BFFF)
// PRG 16K bank ($C000-$FFFF) SetPROM_16K_Bank(4, PROM_BASE + (reg[3] & 0x0F));
SetPROM_16K_Bank(6, PROM_BASE + (reg[3] & 0x0F)); if (PROM_16K_SIZE >= 32) SetPROM_16K_Bank(6, PROM_BASE + 16 - 1);
if (PROM_16K_SIZE >= 32) SetPROM_16K_Bank(4, PROM_BASE); }
} else
} {
} // PRG 16K bank ($C000-$FFFF)
} SetPROM_16K_Bank(6, PROM_BASE + (reg[3] & 0x0F));
if (PROM_16K_SIZE >= 32) SetPROM_16K_Bank(4, PROM_BASE);
//void Mapper001::SaveState(LPBYTE p) }
public override void SaveState(byte[] p) }
{ }
p[0] = reg[0]; }
p[1] = reg[1];
p[2] = reg[2]; //void Mapper001::SaveState(LPBYTE p)
p[3] = reg[3]; public override void SaveState(byte[] p)
p[4] = shift; {
p[5] = regbuf; p[0] = reg[0];
p[1] = reg[1];
p[6] = wram_bank; p[2] = reg[2];
p[7] = wram_count; p[3] = reg[3];
} p[4] = shift;
p[5] = regbuf;
//void Mapper001::LoadState(LPBYTE p)
public override void LoadState(byte[] p) p[6] = wram_bank;
{ p[7] = wram_count;
reg[0] = p[0]; }
reg[1] = p[1];
reg[2] = p[2]; //void Mapper001::LoadState(LPBYTE p)
reg[3] = p[3]; public override void LoadState(byte[] p)
shift = p[4]; {
regbuf = p[5]; reg[0] = p[0];
reg[1] = p[1];
wram_bank = p[6]; reg[2] = p[2];
wram_count = p[7]; reg[3] = p[3];
} shift = p[4];
regbuf = p[5];
public override bool IsStateSave()
{ wram_bank = p[6];
return true; wram_count = p[7];
} }
}
public override bool IsStateSave()
{
return true;
}
}
} }

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c921e7f594a988845856d30f6a925157
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb072eff593853c41974a6d3b8bc1f93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -12,33 +12,33 @@ namespace VirtualNes.Core
public class Mapper003 : Mapper public class Mapper003 : Mapper
{ {
public Mapper003(NES parent) : base(parent) { } public Mapper003(NES parent) : base(parent) { }
public override void Reset() public override void Reset()
{ {
switch (PROM_16K_SIZE) switch (PROM_16K_SIZE)
{ {
case 1: // 16K only case 1: // 16K only
SetPROM_16K_Bank(4, 0); SetPROM_16K_Bank(4, 0);
SetPROM_16K_Bank(6, 0); SetPROM_16K_Bank(6, 0);
break; break;
case 2: // 32K case 2: // 32K
SetPROM_32K_Bank(0); SetPROM_32K_Bank(0);
break; break;
} }
// nes.SetRenderMethod( NES::TILE_RENDER ); // nes.SetRenderMethod( NES::TILE_RENDER );
uint crc = nes.rom.GetPROM_CRC(); uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x2b72fe7e) if (crc == 0x2b72fe7e)
{ // Ganso Saiyuuki - Super Monkey Dai Bouken(J) { // Ganso Saiyuuki - Super Monkey Dai Bouken(J)
nes.SetRenderMethod( EnumRenderMethod.TILE_RENDER); nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
nes.ppu.SetExtNameTableMode(true); nes.ppu.SetExtNameTableMode(true);
} }
// if( crc == 0xE44D95B5 ) { // ひみつw // if( crc == 0xE44D95B5 ) { // ひみつw
// } // }
} }
#if FALSE//0 #if FALSE//0
void Mapper003::WriteLow( WORD addr, BYTE data ) void Mapper003::WriteLow( WORD addr, BYTE data )
{ {
@ -55,12 +55,12 @@ void Mapper003::WriteLow( WORD addr, BYTE data )
} }
} }
#endif #endif
//void Mapper003::Write(WORD addr, BYTE data) //void Mapper003::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data) public override void Write(ushort addr, byte data)
{ {
SetVROM_8K_Bank(data); SetVROM_8K_Bank(data);
} }
} }
} }

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d63147469fd9c5540882a5a89799462b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26977049b3ea7ad4fa3b5c35a325ae48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0672fe1374d484f4ab1c824d0882bfdd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 063872d968d91234a9a22755e3db7aab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e39136ad8af00f4c95499cab3a0aa45
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60942642eeee2e04fbe2fad967c2400d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0beeffcb64a5c124c9ef8d2b428f723e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d46cb68121988e498159e8a53b0cb90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0d9dccfbd35bbf458c8f5d100e2f89b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 660200e3200da7d4eb9925d2b63afef5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a00ec8072aa26648bcd7bef203e9a39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -22,6 +22,7 @@ namespace VirtualNes.Core
BYTE irq_latch; BYTE irq_latch;
BYTE irq_request; BYTE irq_request;
int MMC4prg, MMC4chr; int MMC4prg, MMC4chr;
public Mapper245(NES parent) : base(parent) public Mapper245(NES parent) : base(parent)
{ {
} }
@ -30,92 +31,92 @@ namespace VirtualNes.Core
//void Mapper245::Reset() //void Mapper245::Reset()
public override void Reset() public override void Reset()
{ {
for (INT i = 0; i < 8; i++) for (INT i = 0; i < 8; i++)
{ {
reg[i] = 0x00; reg[i] = 0x00;
} }
prg0 = 0; prg0 = 0;
prg1 = 1; prg1 = 1;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1); SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0) if (VROM_1K_SIZE != 0)
{ {
SetVROM_8K_Bank(0); SetVROM_8K_Bank(0);
} }
we_sram = 0; // Disable we_sram = 0; // Disable
irq_enable = 0; // Disable irq_enable = 0; // Disable
irq_counter = 0; irq_counter = 0;
irq_latch = 0; irq_latch = 0;
irq_request = 0; irq_request = 0;
nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK); nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK);
} }
//void Mapper245::Write(WORD addr, BYTE data) //void Mapper245::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data) public override void Write(ushort addr, byte data)
{ {
switch (addr & 0xF7FF) switch (addr & 0xF7FF)
{ {
case 0x8000: case 0x8000:
reg[0] = data; reg[0] = data;
break; break;
case 0x8001: case 0x8001:
reg[1] = data; reg[1] = data;
switch (reg[0]) switch (reg[0])
{ {
case 0x00: case 0x00:
reg[3] = (byte)((data & 2) << 5); reg[3] = (byte)((data & 2) << 5);
SetPROM_8K_Bank(6, 0x3E | reg[3]); SetPROM_8K_Bank(6, 0x3E | reg[3]);
SetPROM_8K_Bank(7, 0x3F | reg[3]); SetPROM_8K_Bank(7, 0x3F | reg[3]);
break; break;
case 0x06: case 0x06:
prg0 = data; prg0 = data;
break; break;
case 0x07: case 0x07:
prg1 = data; prg1 = data;
break; break;
} }
SetPROM_8K_Bank(4, prg0 | reg[3]); SetPROM_8K_Bank(4, prg0 | reg[3]);
SetPROM_8K_Bank(5, prg1 | reg[3]); SetPROM_8K_Bank(5, prg1 | reg[3]);
break; break;
case 0xA000: case 0xA000:
reg[2] = data; reg[2] = data;
if (!nes.rom.Is4SCREEN()) if (!nes.rom.Is4SCREEN())
{ {
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR); if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR); else SetVRAM_Mirror(VRAM_VMIRROR);
} }
break; break;
case 0xA001: case 0xA001:
break; break;
case 0xC000: case 0xC000:
reg[4] = data; reg[4] = data;
irq_counter = data; irq_counter = data;
irq_request = 0; irq_request = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER); nes.cpu.ClrIRQ(IRQ_MAPPER);
break; break;
case 0xC001: case 0xC001:
reg[5] = data; reg[5] = data;
irq_latch = data; irq_latch = data;
irq_request = 0; irq_request = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER); nes.cpu.ClrIRQ(IRQ_MAPPER);
break; break;
case 0xE000: case 0xE000:
reg[6] = data; reg[6] = data;
irq_enable = 0; irq_enable = 0;
irq_request = 0; irq_request = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER); nes.cpu.ClrIRQ(IRQ_MAPPER);
break; break;
case 0xE001: case 0xE001:
reg[7] = data; reg[7] = data;
irq_enable = 1; irq_enable = 1;
irq_request = 0; irq_request = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER); nes.cpu.ClrIRQ(IRQ_MAPPER);
break; break;
} }
} }
@ -130,27 +131,27 @@ namespace VirtualNes.Core
//void Mapper245::HSync(INT scanline) //void Mapper245::HSync(INT scanline)
public override void HSync(int scanline) public override void HSync(int scanline)
{ {
if ((scanline >= 0 && scanline <= 239)) if ((scanline >= 0 && scanline <= 239))
{ {
if (nes.ppu.IsDispON()) if (nes.ppu.IsDispON())
{ {
if (irq_enable != 0 && irq_request == 0) if (irq_enable != 0 && irq_request == 0)
{ {
if (scanline == 0) if (scanline == 0)
{ {
if (irq_counter != 0) if (irq_counter != 0)
{ {
irq_counter--; irq_counter--;
} }
} }
if ((irq_counter--) == 0) if ((irq_counter--) == 0)
{ {
irq_request = 0xFF; irq_request = 0xFF;
irq_counter = irq_latch; irq_counter = irq_latch;
nes.cpu.SetIRQ(IRQ_MAPPER); nes.cpu.SetIRQ(IRQ_MAPPER);
} }
} }
} }
} }
// if( irq_request && (nes.GetIrqType() == NES::IRQ_HSYNC) ) { // if( irq_request && (nes.GetIrqType() == NES::IRQ_HSYNC) ) {
// nes.cpu.IRQ_NotPending(); // nes.cpu.IRQ_NotPending();
@ -164,43 +165,43 @@ namespace VirtualNes.Core
void SetBank_PPU() void SetBank_PPU()
{ {
if ((VROM_1K_SIZE) != 0) if (VROM_1K_SIZE != 0)
{ {
if (((reg[0] & 0x80)! + 0) != 0) if ((reg[0] & 0x80) != 0)
{ {
SetVROM_8K_Bank(chr4, chr5, chr6, chr7, SetVROM_8K_Bank(chr4, chr5, chr6, chr7,
chr23 + 1, chr23, chr01 + 1, chr01); chr23 + 1, chr23, chr01 + 1, chr01);
} }
else else
{ {
SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1, SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1,
chr4, chr5, chr6, chr7); chr4, chr5, chr6, chr7);
} }
} }
else else
{ {
if ((reg[0] & 0x80) != 0) if ((reg[0] & 0x80) != 0)
{ {
SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07); SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07);
SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07); SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07);
SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07); SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07);
SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07); SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07);
SetCRAM_1K_Bank(0, chr4 & 0x07); SetCRAM_1K_Bank(0, chr4 & 0x07);
SetCRAM_1K_Bank(1, chr5 & 0x07); SetCRAM_1K_Bank(1, chr5 & 0x07);
SetCRAM_1K_Bank(2, chr6 & 0x07); SetCRAM_1K_Bank(2, chr6 & 0x07);
SetCRAM_1K_Bank(3, chr7 & 0x07); SetCRAM_1K_Bank(3, chr7 & 0x07);
} }
else else
{ {
SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07); SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07);
SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07); SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07);
SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07); SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07);
SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07); SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07);
SetCRAM_1K_Bank(4, chr4 & 0x07); SetCRAM_1K_Bank(4, chr4 & 0x07);
SetCRAM_1K_Bank(5, chr5 & 0x07); SetCRAM_1K_Bank(5, chr5 & 0x07);
SetCRAM_1K_Bank(6, chr6 & 0x07); SetCRAM_1K_Bank(6, chr6 & 0x07);
SetCRAM_1K_Bank(7, chr7 & 0x07); SetCRAM_1K_Bank(7, chr7 & 0x07);
} }
} }
} }

View File

@ -1147,6 +1147,16 @@ namespace VirtualNes.Core
bChrLatch = bMode; bChrLatch = bMode;
} }
internal void SetExtNameTableMode(bool bMode)
{
bExtNameTable = bMode;
}
internal void SetExtMonoMode(bool bMode)
{
bExtMono = bMode;
}
public struct Sprite public struct Sprite
{ {
public byte y public byte y