diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MMC3.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MMC3.cs
new file mode 100644
index 00000000..3ffdd6ae
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MMC3.cs
@@ -0,0 +1,401 @@
+//MMC3.h
+
+
+////////////////////////////////////////////////////////////////////////////
+//// Nintendo MMC3 //
+////////////////////////////////////////////////////////////////////////////
+//class MMC3 : public Mapper
+//{
+//public:
+// MMC3( NES* parent );
+// //virtual ~MMC3();
+
+// // For state save
+// BOOL IsStateSave() { return TRUE; }
+// void SaveState( LPBYTE p );
+// void LoadState( LPBYTE p );
+
+
+// void Reset();
+
+// void Write( WORD addr, BYTE data );
+// void HSync( INT scanline );
+
+// //////////////////////////////////////////////////////////////////////////
+// // MMC3
+// //////////////////////////////////////////////////////////////////////////
+// unsigned int count;
+// unsigned int latch;
+// unsigned int reload;
+// unsigned int enabled;
+
+// unsigned int ctrl0;
+// unsigned int ctrl1;
+
+// unsigned int chr[8];
+// unsigned int prg[4];
+
+// //Memory Write 8000~FFFF
+// //void Mmc3_MemoryWrite(uint32 address, uint8 data);
+// void Poke_Mmc3_8000(uint32 address,uint8 data);
+// void Poke_Mmc3_8001(uint32 address,uint8 data);
+// void Poke_Mmc3_A000(uint32 address,uint8 data);
+// void Poke_Mmc3_A001(uint32 address,uint8 data);
+// void Poke_Mmc3_C000(uint32 address,uint8 data);
+// void Poke_Mmc3_C001(uint32 address,uint8 data);
+// void Poke_Mmc3_E000(uint32 address,uint8 data);
+// void Poke_Mmc3_E001(uint32 address,uint8 data);
+// void Poke_Nop(uint32,uint8);
+
+// //³õʼ»¯Mmc3º¯ÊýÖ¸Õë
+// //void Mmc3_Init();
+// //void Mmc3_Reset();
+// void Mmc3_UpdatePrg();
+// void Mmc3_UpdateChr();
+// void Mmc3_UpdatePrg2p(unsigned int addr,unsigned int bank);
+// void Mmc3_UpdateChr2p(unsigned int addr,unsigned int bank);
+// unsigned int Mmc3_GetChrSource(unsigned int);
+// void Mmc3_HSync(uint32 scanline);
+
+// void Mmc3_SwapChr1K(uint8 page,uint32 bank);
+// void Mmc3_SwapChr2K(uint8 page,uint32 bank);
+
+// void (MMC3::*UpdateChr)(unsigned int,unsigned int);
+// void (MMC3::*UpdatePrg)(unsigned int,unsigned int);
+// unsigned int (MMC3::*GetChrSource)(unsigned int);
+
+// void (MMC3::*Poke_8000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_8001)(uint32 address,uint8 data);
+// void (MMC3::*Poke_A000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_A001)(uint32 address,uint8 data);
+// void (MMC3::*Poke_C000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_C001)(uint32 address,uint8 data);
+// void (MMC3::*Poke_E000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_E001)(uint32 address,uint8 data);
+//};//////////////////////////////////////////////////////////////////////////
+//// Nintendo MMC3 //
+////////////////////////////////////////////////////////////////////////////
+//class MMC3 : public Mapper
+//{
+//public:
+// MMC3( NES* parent );
+// //virtual ~MMC3();
+
+// // For state save
+// BOOL IsStateSave() { return TRUE; }
+// void SaveState( LPBYTE p );
+// void LoadState( LPBYTE p );
+
+
+// void Reset();
+
+// void Write( WORD addr, BYTE data );
+// void HSync( INT scanline );
+
+// //////////////////////////////////////////////////////////////////////////
+// // MMC3
+// //////////////////////////////////////////////////////////////////////////
+// unsigned int count;
+// unsigned int latch;
+// unsigned int reload;
+// unsigned int enabled;
+
+// unsigned int ctrl0;
+// unsigned int ctrl1;
+
+// unsigned int chr[8];
+// unsigned int prg[4];
+
+// //Memory Write 8000~FFFF
+// //void Mmc3_MemoryWrite(uint32 address, uint8 data);
+// void Poke_Mmc3_8000(uint32 address,uint8 data);
+// void Poke_Mmc3_8001(uint32 address,uint8 data);
+// void Poke_Mmc3_A000(uint32 address,uint8 data);
+// void Poke_Mmc3_A001(uint32 address,uint8 data);
+// void Poke_Mmc3_C000(uint32 address,uint8 data);
+// void Poke_Mmc3_C001(uint32 address,uint8 data);
+// void Poke_Mmc3_E000(uint32 address,uint8 data);
+// void Poke_Mmc3_E001(uint32 address,uint8 data);
+// void Poke_Nop(uint32,uint8);
+
+// //³õʼ»¯Mmc3º¯ÊýÖ¸Õë
+// //void Mmc3_Init();
+// //void Mmc3_Reset();
+// void Mmc3_UpdatePrg();
+// void Mmc3_UpdateChr();
+// void Mmc3_UpdatePrg2p(unsigned int addr,unsigned int bank);
+// void Mmc3_UpdateChr2p(unsigned int addr,unsigned int bank);
+// unsigned int Mmc3_GetChrSource(unsigned int);
+// void Mmc3_HSync(uint32 scanline);
+
+// void Mmc3_SwapChr1K(uint8 page,uint32 bank);
+// void Mmc3_SwapChr2K(uint8 page,uint32 bank);
+
+// void (MMC3::*UpdateChr)(unsigned int,unsigned int);
+// void (MMC3::*UpdatePrg)(unsigned int,unsigned int);
+// unsigned int (MMC3::*GetChrSource)(unsigned int);
+
+// void (MMC3::*Poke_8000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_8001)(uint32 address,uint8 data);
+// void (MMC3::*Poke_A000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_A001)(uint32 address,uint8 data);
+// void (MMC3::*Poke_C000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_C001)(uint32 address,uint8 data);
+// void (MMC3::*Poke_E000)(uint32 address,uint8 data);
+// void (MMC3::*Poke_E001)(uint32 address,uint8 data);
+//};
+
+
+
+
+//MMC3.cpp
+
+
+////////////////////////////////////////////////////////////////////////////
+//// Nintendo MMC3 //
+////////////////////////////////////////////////////////////////////////////
+//using System.Net;
+//using System;
+//using Unity.Android.Gradle.Manifest;
+//using VirtualNes.Core;
+
+//MMC3::MMC3(NES * parent) : Mapper(parent)
+//{
+// UpdateChr = &MMC3::Mmc3_UpdateChr2p;
+// UpdatePrg = &MMC3::Mmc3_UpdatePrg2p;
+// GetChrSource = &MMC3::Mmc3_GetChrSource;
+
+// Poke_8000 = &MMC3::Poke_Mmc3_8000;
+// Poke_8001 = &MMC3::Poke_Mmc3_8001;
+// Poke_A000 = &MMC3::Poke_Mmc3_A000;
+// Poke_A001 = &MMC3::Poke_Mmc3_A001;
+// Poke_C000 = &MMC3::Poke_Mmc3_C000;
+// Poke_C001 = &MMC3::Poke_Mmc3_C001;
+// Poke_E000 = &MMC3::Poke_Mmc3_E000;
+// Poke_E001 = &MMC3::Poke_Mmc3_E001;
+//}
+
+//void MMC3::Reset()
+//{
+// int i;
+
+// ctrl0 = 0;
+// ctrl1 = 0;
+
+// for (i = 0; i < 8; ++i)
+// chr[i] = i;
+
+// prg[0] = 0x00;
+// prg[1] = 0x01;
+// prg[2] = 0x3E;
+// prg[3] = 0x3F;
+
+// count = 0;
+// latch = 0;
+// reload = 0;
+// enabled = 0;
+
+// Mmc3_UpdatePrg();
+// Mmc3_UpdateChr();
+//}
+
+//void MMC3::Write(WORD A, BYTE V)
+//{
+// switch (A & 0xE001)
+// {
+// case 0x8000: (this->* Poke_8000)(A, V); break;
+// case 0x8001: (this->* Poke_8001)(A, V); break;
+// case 0xA000: (this->* Poke_A000)(A, V); break;
+// case 0xA001: (this->* Poke_A001)(A, V); break;
+// case 0xC000: (this->* Poke_C000)(A, V); break;
+// case 0xC001: (this->* Poke_C001)(A, V); break;
+// case 0xE000: (this->* Poke_E000)(A, V); break;
+// case 0xE001: (this->* Poke_E001)(A, V); break;
+// }
+//}
+
+//void MMC3::Poke_Mmc3_8000(uint32 address, uint8 data)
+//{
+// const unsigned int diff = ctrl0 ^ data;
+// ctrl0 = data;
+
+// if (diff & 0x40)
+// {
+// const unsigned int v[2] =
+// {
+// prg[(data >> 5 & 0x2) ^ 0],
+// prg[(data >> 5 & 0x2) ^ 2]
+// };
+
+// (this->* UpdatePrg)(0x0000, v[0]);
+// (this->* UpdatePrg)(0x4000, v[1]);
+// }
+
+// if (diff & 0x80)
+// Mmc3_UpdateChr();
+//}
+//void MMC3::Poke_Mmc3_8001(uint32 address, uint8 data)
+//{
+// unsigned int addr = ctrl0 & 0x7;
+
+// if (addr < 6)
+// {
+// unsigned int base = ctrl0 << 5 & 0x1000;
+
+// if (addr < 2)
+// {
+// addr <<= 1;
+// base |= addr << 10;
+// (this->* UpdateChr)(base | 0x0000, (chr[addr + 0] = data & 0xFE));
+// (this->* UpdateChr)(base | 0x0400, (chr[addr + 1] = data | 0x01));
+// }
+// else
+// {
+// (this->* UpdateChr)((base ^ 0x1000) | (addr - 2) << 10, (chr[addr + 2] = data));
+// }
+// }
+// else
+// {
+// (this->* UpdatePrg)((addr == 6) ? (ctrl0 << 8 & 0x4000) : 0x2000, (prg[addr - 6] = data & 0x3F));
+// }
+//}
+//void MMC3::Poke_Mmc3_A000(uint32 address, uint8 data)
+//{
+// if (!nes->rom->Is4SCREEN())
+// {
+// if (data & 0x01)
+// SetVRAM_Mirror(VRAM_HMIRROR);
+// else
+// SetVRAM_Mirror(VRAM_VMIRROR);
+// }
+//}
+
+//void MMC3::Poke_Mmc3_A001(uint32 address, uint8 data)
+//{
+// ctrl1 = data;
+//}
+
+////////////////////////////////////////////////////////////////////////////
+//// MMC3 IRQ
+////////////////////////////////////////////////////////////////////////////
+//void MMC3::Poke_Mmc3_C000(uint32 address, uint8 data)
+//{
+// count = data;
+// reload = 0;
+//}
+//void MMC3::Poke_Mmc3_C001(uint32 address, uint8 data)
+//{
+// latch = data;
+// reload = 0;
+//}
+//void MMC3::Poke_Mmc3_E000(uint32 address, uint8 data)
+//{
+//enabled = 0;
+//reload = 0;
+// nes->cpu->ClrIRQ(IRQ_MAPPER);
+//}
+//void MMC3::Poke_Mmc3_E001(uint32 address, uint8 data)
+//{
+// enabled = 1;
+// reload = 0;
+//}
+
+//void MMC3::HSync(int scanline)
+////void MMC3::Mmc3_HSync(uint32 scanline)
+//{
+// if ((scanline >= 0 && scanline <= 239))
+// {
+// if (nes->ppu->IsDispON())
+// {
+// if (enabled && !reload)
+// {
+// if (scanline == 0)
+// {
+// if (count)
+// {
+// count -= 1;
+// }
+// }
+// if (!(count))
+// {
+// reload = 0xFF;
+// count = latch;
+// nes->cpu->SetIRQ(IRQ_MAPPER);
+// }
+// count--;
+// }
+// }
+// }
+//}
+
+//void MMC3::Poke_Nop(uint32 addr, uint8 data)
+//{
+// return;
+//}
+
+
+
+//void MMC3::Mmc3_SwapChr1K(uint8 page, uint32 bank)
+//{
+// if ((this->* GetChrSource)(bank))
+// {
+// SetCRAM_1K_Bank(page, bank);
+// }
+// else
+// {
+// SetVROM_1K_Bank(page, bank);
+// }
+//}
+
+//void MMC3::Mmc3_SwapChr2K(uint8 page, uint32 bank)
+//{
+// if ((this->* GetChrSource)(bank))
+// {
+// SetCRAM_2K_Bank(page, bank);
+// }
+// else
+// {
+// SetVROM_2K_Bank(page, bank);
+// }
+//}
+
+//void MMC3::Mmc3_UpdatePrg2p(unsigned int addr, unsigned int bank)
+//{
+// SetPROM_8K_Bank((addr >> 13) + 4, bank);
+//}
+
+//void MMC3::Mmc3_UpdateChr2p(unsigned int addr, unsigned int bank)
+//{
+// Mmc3_SwapChr1K(addr >> 10, bank);
+//}
+
+
+//void MMC3::Mmc3_UpdatePrg()
+//{
+// const unsigned int x = ctrl0 >> 5 & 0x2;
+
+// (this->* UpdatePrg)(0x0000, prg[0 ^ x]);
+// (this->* UpdatePrg)(0x2000, prg[1 ^ 0]);
+// (this->* UpdatePrg)(0x4000, prg[2 ^ x]);
+// (this->* UpdatePrg)(0x6000, prg[3 ^ 0]);
+//}
+
+//void MMC3::Mmc3_UpdateChr()
+//{
+// const unsigned int x = ctrl0 >> 5 & 0x4;
+// unsigned int i = 0;
+// for (i = 0; i < 8; ++i)
+// (this->* UpdateChr)(i * 0x400, chr[i ^ x]);
+//}
+
+//unsigned int MMC3::Mmc3_GetChrSource(unsigned int dummy){return 0;}
+
+
+//void MMC3::SaveState(LPBYTE p)
+//{
+// //ûдºÃ
+//}
+//void MMC3::LoadState(LPBYTE p)
+//{
+// //ûдºÃ
+//}
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MMC3.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MMC3.cs.meta
new file mode 100644
index 00000000..fa3a7c52
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MMC3.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 0e50dbc25281282468ee112d349c4127
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs
index d0b32b40..8ab66d0a 100644
--- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs
@@ -234,8 +234,9 @@ namespace VirtualNes.Core
case 246: return new Mapper246(parent);
case 248: return new Mapper248(parent);
case 249: return new Mapper249(parent);
- case 251: return new Mapper251(parent);
+ case 251: return new Mapper251(parent);
case 252: return new Mapper252(parent);
+ case 253: return new Mapper253(parent);
case 254: return new Mapper254(parent);
case 255: return new Mapper255(parent);
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper020.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper020.cs
new file mode 100644
index 00000000..f6e09986
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper020.cs
@@ -0,0 +1,98 @@
+//TODO VirituaNes097 / NES / Mapper / MapperFDS.cpp
+
+////////////////////////////////////////////////////////////////////////////
+//// Mapper020 Nintendo Disk System(FDS) //
+////////////////////////////////////////////////////////////////////////////
+//using System;
+//using Unity.Android.Gradle;
+//using static VirtualNes.Core.CPU;
+//using static VirtualNes.MMU;
+//using BYTE = System.Byte;
+//using INT = System.Int32;
+
+
+//namespace VirtualNes.Core
+//{
+// public class Mapper020 : Mapper
+// {
+// enum enum_1
+// {
+// BLOCK_READY = 0,
+// BLOCK_VOLUME_LABEL,
+// BLOCK_FILE_AMOUNT,
+// BLOCK_FILE_HEADER,
+// BLOCK_FILE_DATA,
+// };
+// enum enum_2
+// {
+// SIZE_VOLUME_LABEL = 56,
+// SIZE_FILE_AMOUNT = 2,
+// SIZE_FILE_HEADER = 16,
+// };
+// enum enum_3
+// {
+// OFFSET_VOLUME_LABEL = 0,
+// OFFSET_FILE_AMOUNT = 56,
+// OFFSET_FILE_HEADER = 58,
+// OFFSET_FILE_DATA = 74,
+// };
+
+// enum enum_4
+// {
+// MECHANICAL_SOUND_BOOT = 0,
+// MECHANICAL_SOUND_SEEKEND,
+// MECHANICAL_SOUND_MOTOR_ON,
+// MECHANICAL_SOUND_MOTOR_OFF,
+// MECHANICAL_SOUND_ALLSTOP,
+// };
+
+// bool bDiskThrottle;
+// bool DiskThrottleTime;
+
+// LPBYTE disk;
+// LPBYTE disk_w;
+
+// INT irq_counter, irq_latch; // $4020-$4021
+// BYTE irq_enable, irq_repeat; // $4022
+// BYTE irq_occur; // IRQ発生時に0以外になる
+// BYTE irq_transfer; // 割り込み転送フラグ
+
+// BYTE disk_enable; // Disk I/O enable
+// BYTE sound_enable; // Sound I/O enable
+// BYTE RW_start; // 読み書き可能になったらIRQ発生
+// BYTE RW_mode; // 読み書きモード
+// BYTE disk_motor_mode; // ディスクモーター
+// BYTE disk_eject; // ディスクカードの挿入/非挿入
+// BYTE drive_ready; // 読み書き中かどうか
+// BYTE drive_reset; // ドライブリセット状態
+
+// INT block_point;
+// INT block_mode;
+// INT size_file_data;
+// INT file_amount;
+// INT point;
+// BYTE first_access;
+
+// BYTE disk_side;
+// BYTE disk_mount_count;
+
+// BYTE irq_type;
+
+// // For mechanical sound
+// BYTE sound_startup_flag;
+// INT sound_startup_timer;
+// INT sound_seekend_timer;
+// public Mapper020(NES parent) : base(parent)
+// {
+
+
+// }
+
+// public override bool IsStateSave()
+// {
+// return true;
+// }
+
+// override ma
+// }
+//}
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper020.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper020.cs.meta
new file mode 100644
index 00000000..4cd56df1
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper020.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 18bba5ba2502bfd4394ce01de2fb331c
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper191.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper191.cs
index f7686981..8c6cd882 100644
--- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper191.cs
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper191.cs
@@ -1,8 +1,4 @@
-//////////////////////////////////////////////////////////////////////////
-// Mapper191 SACHEN Super Cartridge Xin1 (Ver.1-9) //
-// SACHEN Q-BOY Support //
-//////////////////////////////////////////////////////////////////////////
-using static VirtualNes.MMU;
+using static VirtualNes.MMU;
using BYTE = System.Byte;
using INT = System.Int32;
@@ -13,95 +9,19 @@ namespace VirtualNes.Core
{
BYTE[] reg = new BYTE[8];
BYTE prg0, prg1;
- BYTE chr0, chr1, chr2, chr3;
- BYTE highbank;
+ BYTE[] chr = new BYTE[8];
+ BYTE we_sram;
+
+ BYTE irq_type;
+ BYTE irq_enable;
+ BYTE irq_counter;
+ BYTE irq_latch;
+ BYTE irq_request;
+
+ BYTE patch;
public Mapper191(NES parent) : base(parent)
{
- }
- public override void Reset()
-
- {
- for (INT i = 0; i < 8; i++)
- {
- reg[i] = 0x00;
- }
-
- prg0 = 0;
- // prg1 = 1;
- SetBank_CPU();
-
- chr0 = 0;
- chr1 = 0;
- chr2 = 0;
- chr3 = 0;
- highbank = 0;
- SetBank_PPU();
- }
-
- //void Mapper191::WriteLow(WORD addr, BYTE data)
- public override void WriteLow(ushort addr, byte data)
- {
- switch (addr)
- {
- case 0x4100:
- reg[0] = data;
- break;
- case 0x4101:
- reg[1] = data;
- switch (reg[0])
- {
- case 0:
- chr0 = (byte)(data & 7);
- SetBank_PPU();
- break;
- case 1:
- chr1 = (byte)(data & 7);
- SetBank_PPU();
- break;
- case 2:
- chr2 = (byte)(data & 7);
- SetBank_PPU();
- break;
- case 3:
- chr3 = (byte)(data & 7);
- SetBank_PPU();
- break;
- case 4:
- highbank = (byte)(data & 7);
- SetBank_PPU();
- break;
- case 5:
- prg0 = (byte)(data & 7);
- SetBank_CPU();
- break;
- case 7:
- if ((data & 0x02) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
- else SetVRAM_Mirror(VRAM_VMIRROR);
- break;
- }
- break;
- }
- }
-
- void SetBank_CPU()
- {
- SetPROM_32K_Bank(prg0);
- }
-
- void SetBank_PPU()
- {
- if (VROM_1K_SIZE != 0)
- {
- SetVROM_1K_Bank(0, (((highbank << 3) + chr0) << 2) + 0);
- SetVROM_1K_Bank(1, (((highbank << 3) + chr0) << 2) + 1);
- SetVROM_1K_Bank(2, (((highbank << 3) + chr1) << 2) + 2);
- SetVROM_1K_Bank(3, (((highbank << 3) + chr1) << 2) + 3);
- SetVROM_1K_Bank(4, (((highbank << 3) + chr2) << 2) + 0);
- SetVROM_1K_Bank(5, (((highbank << 3) + chr2) << 2) + 1);
- SetVROM_1K_Bank(6, (((highbank << 3) + chr3) << 2) + 2);
- SetVROM_1K_Bank(7, (((highbank << 3) + chr3) << 2) + 3);
- }
}
public override bool IsStateSave()
@@ -109,28 +29,396 @@ namespace VirtualNes.Core
return true;
}
+ public override void Reset()
+ {
+ for (INT i = 0; i < 8; i++)
+ {
+ reg[i] = 0x00;
+ }
+ prg0 = 0;
+ prg1 = 1;
+ SetBank_CPU();
+ chr[0] = 0;
+ chr[2] = 2;
+ chr[4] = 4;
+ chr[5] = 5;
+ chr[6] = 6;
+ chr[7] = 7;
+ SetBank_PPU();
+
+ we_sram = 0; // Disable
+ irq_enable = 0; // Disable
+ irq_counter = 0;
+ irq_latch = 0;
+ irq_request = 0;
+ }
+
+
+ //BYTE Mapper191::ReadLow(WORD addr)
+ public override byte ReadLow(ushort addr)
+ {
+ if (addr >= 0x5000 && addr <= 0x5FFF)
+ {
+ return XRAM[addr - 0x4000];
+ }
+ else
+ {
+ return base.ReadLow(addr);
+ }
+ }
+
+ //void Mapper191::WriteLow(WORD addr, BYTE data)
+ public override void WriteLow(ushort addr, byte data)
+ {
+ if (addr >= 0x5000 && addr <= 0x5FFF)
+ {
+ XRAM[addr - 0x4000] = data;
+ }
+ else
+ {
+ base.WriteLow(addr, data);
+ }
+ }
+
+ //void Mapper191::Write(WORD addr, BYTE data)
+ public override void Write(ushort addr, byte data)
+ {
+ switch (addr & 0xE001)
+ {
+ case 0x8000:
+ reg[0] = data;
+ SetBank_CPU();
+ SetBank_PPU();
+ break;
+ case 0x8001:
+ reg[1] = data;
+
+ switch (reg[0] & 0x07)
+ {
+ case 0x00:
+ chr[0] = (byte)(data & 0xFE);
+ SetBank_PPU();
+ break;
+ case 0x01:
+ chr[2] = (byte)(data & 0xFE);
+ SetBank_PPU();
+ break;
+ case 0x02:
+ chr[4] = data;
+ SetBank_PPU();
+ break;
+ case 0x03:
+ chr[5] = data;
+ SetBank_PPU();
+ break;
+ case 0x04:
+ chr[6] = data;
+ SetBank_PPU();
+ break;
+ case 0x05:
+ chr[7] = data;
+ SetBank_PPU();
+ break;
+ case 0x06:
+ prg0 = data;
+ SetBank_CPU();
+ break;
+ case 0x07:
+ prg1 = data;
+ SetBank_CPU();
+ break;
+ }
+ break;
+ case 0xA000:
+ reg[2] = data;
+ if (!nes.rom.Is4SCREEN())
+ {
+ if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
+ else SetVRAM_Mirror(VRAM_VMIRROR);
+ }
+ break;
+ case 0xA001:
+ reg[3] = data;
+ break;
+ case 0xC000:
+ reg[4] = data;
+ irq_counter = data;
+ irq_request = 0;
+ break;
+ case 0xC001:
+ reg[5] = data;
+ irq_latch = data;
+ irq_request = 0;
+ break;
+ case 0xE000:
+ reg[6] = data;
+ irq_enable = 0;
+ irq_request = 0;
+ nes.cpu.ClrIRQ(CPU.IRQ_MAPPER);
+ break;
+ case 0xE001:
+ reg[7] = data;
+ irq_enable = 1;
+ irq_request = 0;
+ break;
+ }
+
+ }
+
+ //void Mapper191::HSync(INT scanline)
+ public override void HSync(int scanline)
+ {
+ if ((scanline >= 0 && scanline <= 239))
+ {
+ if (nes.ppu.IsDispON())
+ {
+ if (irq_enable != 0 && irq_request == 0)
+ {
+ if (scanline == 0)
+ {
+ if (irq_counter != 0)
+ {
+ irq_counter--;
+ }
+ }
+ if ((irq_counter--) == 0)
+ {
+ irq_request = 0xFF;
+ irq_counter = irq_latch;
+ nes.cpu.SetIRQ(CPU.IRQ_MAPPER);
+ }
+ }
+ }
+ }
+ }
+
+ //void Mapper191::SetBank_CPU()
+
+ private void SetBank_CPU()
+ {
+ if ((reg[0] & 0x40) != 0)
+ {
+ SetPROM_32K_Bank(PROM_8K_SIZE - 2, prg1, prg0, PROM_8K_SIZE - 1);
+ }
+ else
+ {
+ SetPROM_32K_Bank(prg0, prg1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
+ }
+ }
+
+ //void Mapper191::SetBank_PPU()
+ private void SetBank_PPU()
+ {
+ chr[1] = (byte)(chr[0] + 1);
+ chr[3] = (byte)(chr[2] + 1);
+
+ if ((reg[0] & 0x80) != 0)
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ SetBank_PPUSUB(i, chr[(i + 4) & 7], (chr[(i + 4) & 7] & 0x80) != 0);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ SetBank_PPUSUB(i, chr[i], (chr[i] & 0x80) != 0);
+ }
+ }
+ }
+
+ //void Mapper191::SetBank_PPUSUB(int bank, int page, BOOL bRAM)
+ private void SetBank_PPUSUB(int bank, int page, bool bRAM)
+ {
+ if (bRAM)
+ {
+ SetCRAM_1K_Bank((BYTE)bank, page & 7);
+ }
+ else
+ {
+ SetVROM_1K_Bank((BYTE)bank, page);
+ }
+ }
//void Mapper191::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
- p[0] = prg0;
- p[1] = chr0;
- p[2] = chr1;
- p[3] = chr2;
- p[4] = chr3;
- p[5] = highbank;
+ for (INT i = 0; i < 8; i++)
+ {
+ p[i] = reg[i];
+ }
+ p[8] = prg0;
+ p[9] = prg1;
+ p[10] = chr[0];
+ p[11] = chr[2];
+ p[12] = chr[4];
+ p[13] = chr[5];
+ p[14] = chr[6];
+ p[15] = chr[7];
+ p[16] = irq_enable;
+ p[17] = irq_counter;
+ p[18] = irq_latch;
+ p[19] = irq_request;
}
//void Mapper191::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
- prg0 = p[0];
- chr0 = p[1];
- chr1 = p[2];
- chr2 = p[3];
- chr3 = p[4];
- highbank = p[5];
+ for (INT i = 0; i < 8; i++)
+ {
+ reg[i] = p[i];
+ }
+ prg0 = p[8];
+ prg1 = p[9];
+ chr[0] = p[10];
+ chr[2] = p[11];
+ chr[4] = p[12];
+ chr[5] = p[13];
+ chr[6] = p[14];
+ chr[7] = p[15];
+ irq_enable = p[16];
+ irq_counter = p[17];
+ irq_latch = p[18];
+ irq_request = p[19];
}
}
}
+
+////////////////////////////////////////////////////////////////////////////
+//// Mapper191 SACHEN Super Cartridge Xin1 (Ver.1-9) //
+//// SACHEN Q-BOY Support //
+////////////////////////////////////////////////////////////////////////////
+//using static VirtualNes.MMU;
+//using BYTE = System.Byte;
+//using INT = System.Int32;
+
+
+//namespace VirtualNes.Core
+//{
+// public class Mapper191 : Mapper
+// {
+// BYTE[] reg = new BYTE[8];
+// BYTE prg0, prg1;
+// BYTE chr0, chr1, chr2, chr3;
+// BYTE highbank;
+// public Mapper191(NES parent) : base(parent)
+// {
+// }
+
+// public override void Reset()
+
+// {
+// for (INT i = 0; i < 8; i++)
+// {
+// reg[i] = 0x00;
+// }
+
+// prg0 = 0;
+// // prg1 = 1;
+// SetBank_CPU();
+
+// chr0 = 0;
+// chr1 = 0;
+// chr2 = 0;
+// chr3 = 0;
+// highbank = 0;
+// SetBank_PPU();
+// }
+
+// //void Mapper191::WriteLow(WORD addr, BYTE data)
+// public override void WriteLow(ushort addr, byte data)
+// {
+// switch (addr)
+// {
+// case 0x4100:
+// reg[0] = data;
+// break;
+// case 0x4101:
+// reg[1] = data;
+// switch (reg[0])
+// {
+// case 0:
+// chr0 = (byte)(data & 7);
+// SetBank_PPU();
+// break;
+// case 1:
+// chr1 = (byte)(data & 7);
+// SetBank_PPU();
+// break;
+// case 2:
+// chr2 = (byte)(data & 7);
+// SetBank_PPU();
+// break;
+// case 3:
+// chr3 = (byte)(data & 7);
+// SetBank_PPU();
+// break;
+// case 4:
+// highbank = (byte)(data & 7);
+// SetBank_PPU();
+// break;
+// case 5:
+// prg0 = (byte)(data & 7);
+// SetBank_CPU();
+// break;
+// case 7:
+// if ((data & 0x02) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
+// else SetVRAM_Mirror(VRAM_VMIRROR);
+// break;
+// }
+// break;
+// }
+// }
+
+// void SetBank_CPU()
+// {
+// SetPROM_32K_Bank(prg0);
+// }
+
+// void SetBank_PPU()
+// {
+// if (VROM_1K_SIZE != 0)
+// {
+// SetVROM_1K_Bank(0, (((highbank << 3) + chr0) << 2) + 0);
+// SetVROM_1K_Bank(1, (((highbank << 3) + chr0) << 2) + 1);
+// SetVROM_1K_Bank(2, (((highbank << 3) + chr1) << 2) + 2);
+// SetVROM_1K_Bank(3, (((highbank << 3) + chr1) << 2) + 3);
+// SetVROM_1K_Bank(4, (((highbank << 3) + chr2) << 2) + 0);
+// SetVROM_1K_Bank(5, (((highbank << 3) + chr2) << 2) + 1);
+// SetVROM_1K_Bank(6, (((highbank << 3) + chr3) << 2) + 2);
+// SetVROM_1K_Bank(7, (((highbank << 3) + chr3) << 2) + 3);
+// }
+// }
+
+// public override bool IsStateSave()
+// {
+// return true;
+// }
+
+
+
+// //void Mapper191::SaveState(LPBYTE p)
+// public override void SaveState(byte[] p)
+// {
+// p[0] = prg0;
+// p[1] = chr0;
+// p[2] = chr1;
+// p[3] = chr2;
+// p[4] = chr3;
+// p[5] = highbank;
+// }
+
+// //void Mapper191::LoadState(LPBYTE p)
+// public override void LoadState(byte[] p)
+// {
+// prg0 = p[0];
+// chr0 = p[1];
+// chr1 = p[2];
+// chr2 = p[3];
+// chr3 = p[4];
+// highbank = p[5];
+// }
+// }
+//}
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper253.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper253.cs
new file mode 100644
index 00000000..95d086b7
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper253.cs
@@ -0,0 +1,246 @@
+//////////////////////////////////////////////////////////////////////////
+// Mapper253 WaiXing LongZhu CN //
+//////////////////////////////////////////////////////////////////////////
+using System;
+using static VirtualNes.Core.CPU;
+using static VirtualNes.MMU;
+using BYTE = System.Byte;
+using INT = System.Int32;
+
+namespace VirtualNes.Core
+{
+ public class Mapper253 : Mapper
+ {
+ BYTE VRAM_switch;
+ BYTE rom_type;
+ BYTE[] reg = new BYTE[9];
+ BYTE irq_enable;
+ BYTE irq_counter;
+ BYTE irq_latch;
+ INT irq_clock;
+ public Mapper253(NES parent) : base(parent)
+ {
+ }
+
+ public override bool IsStateSave()
+ {
+ return true;
+ }
+
+ //void Mapper253::Reset()
+ public override void Reset()
+ {
+ // nes.ppu.SetVromWrite(1);
+ for (INT i = 0; i < 8; i++)
+ {
+ reg[i] = (byte)i;
+ }
+ reg[8] = 0;
+
+ irq_enable = 0;
+ irq_counter = 0;
+ irq_latch = 0;
+ irq_clock = 0;
+ VRAM_switch = 0;
+ rom_type = 0;
+ SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
+ SetVROM_8K_Bank(0);
+
+ uint crc = nes.rom.GetPROM_CRC();
+ if (crc == 0x0530b26e)
+ { //[HengGe] Shen Hua Jian Yun III (C)
+ rom_type = 1;
+ }
+ }
+
+ //void Mapper253::Write(WORD addr, BYTE data)
+ public override void Write(ushort addr, byte data)
+ {
+ Debug.Debuger.Log($"Address={addr & 0xFFFF} Data={data & 0xFF}");
+
+ if (addr == 0x8010)
+ {
+ SetPROM_8K_Bank(4, data);
+ return;
+ }
+ if (addr == 0xA010)
+ {
+ SetPROM_8K_Bank(5, data);
+ return;
+ }
+ if (addr == 0x9400)
+ {
+ data &= 0x03;
+ if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
+ else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
+ else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L);
+ else SetVRAM_Mirror(VRAM_MIRROR4H);
+ }
+ switch (addr & 0xF00C)
+ {
+ case 0xB000:
+ reg[0] = (byte)((reg[0] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(0, reg[0]);
+ break;
+ case 0xB004:
+ reg[0] = (byte)((reg[0] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(0, reg[0] + ((data >> 4) * 0x100));
+ break;
+ case 0xB008:
+ reg[1] = (byte)((reg[1] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(1, reg[1]);
+ break;
+ case 0xB00C:
+ reg[1] = (byte)((reg[1] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(1, reg[1] + ((data >> 4) * 0x100));
+ break;
+ case 0xC000:
+ reg[2] = (byte)((reg[2] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(2, reg[2]);
+ break;
+ case 0xC004:
+ reg[2] = (byte)((reg[2] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(2, reg[2] + ((data >> 4) * 0x100));
+ break;
+ case 0xC008:
+ reg[3] = (byte)((reg[3] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(3, reg[3]);
+ break;
+ case 0xC00C:
+ reg[3] = (byte)((reg[3] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(3, reg[3] + ((data >> 4) * 0x100));
+ break;
+ case 0xD000:
+ reg[4] = (byte)((reg[4] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(4, reg[4]);
+ break;
+ case 0xD004:
+ reg[4] = (byte)((reg[4] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(4, reg[4] + ((data >> 4) * 0x100));
+ break;
+ case 0xD008:
+ reg[5] = (byte)((reg[5] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(5, reg[5]);
+ break;
+ case 0xD00C:
+ reg[5] = (byte)((reg[5] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(5, reg[5] + ((data >> 4) * 0x100));
+ break;
+ case 0xE000:
+ reg[6] = (byte)((reg[6] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(6, reg[6]);
+ break;
+ case 0xE004:
+ reg[6] = (byte)((reg[6] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(6, reg[6] + ((data >> 4) * 0x100));
+ break;
+ case 0xE008:
+ reg[7] = (byte)((reg[7] & 0xF0) | (data & 0x0F));
+ SetBank_PPUSUB(7, reg[7]);
+ break;
+ case 0xE00C:
+ reg[7] = (byte)((reg[7] & 0x0F) | ((data & 0x0F) << 4));
+ SetBank_PPUSUB(7, reg[7] + ((data >> 4) * 0x100));
+ break;
+ case 0xF000:
+ irq_latch = (byte)((irq_latch & 0xF0) | (data & 0x0F));
+ break;
+ case 0xF004:
+ irq_latch = (byte)((irq_latch & 0x0F) | ((data & 0x0F) << 4));
+ break;
+ case 0xF008:
+ irq_enable = (byte)(data & 0x03);
+ if ((irq_enable & 0x02) != null)
+ {
+ irq_counter = irq_latch;
+ irq_clock = 0;
+ }
+ nes.cpu.ClrIRQ(IRQ_MAPPER);
+ break;
+ }
+ }
+
+ //void Mapper253::SetBank_PPUSUB(int bank, int page)
+ private void SetBank_PPUSUB(int bank, int page)
+ {
+ if (rom_type == 1)
+ {
+ if (page == 0x88)
+ {
+ VRAM_switch = 0;
+ return;
+ }
+ else if (page == 0xc8)
+ {
+ VRAM_switch = 1;
+ return;
+ }
+ }
+ if ((page == 4) || (page == 5))
+ {
+ if ((VRAM_switch == 0) && (rom_type == 1))
+ {
+ SetVROM_1K_Bank((byte)bank, page);
+ }
+ else
+ {
+ SetCRAM_1K_Bank((byte)bank, page);
+ }
+ }
+ else
+ {
+ SetVROM_1K_Bank((byte)bank, page);
+ }
+ }
+
+ //void Mapper253::Clock(INT cycles)
+ public override void Clock(int cycles)
+ {
+ if ((irq_enable & 0x02)!= null)
+ {
+ if ((irq_clock += cycles) >= 0x72)
+ {
+ irq_clock -= 0x72;
+ if (irq_counter == 0xFF)
+ {
+ irq_counter = irq_latch;
+ irq_enable = (BYTE)((irq_enable & 0x01) * 3);
+ nes.cpu.SetIRQ(IRQ_MAPPER);
+ }
+ else
+ {
+ irq_counter++;
+ }
+ }
+ }
+ }
+
+ //void Mapper253::SaveState(LPBYTE p)
+ public override void SaveState(byte[] p)
+ {
+ for (INT i = 0; i < 9; i++)
+ {
+ p[i] = reg[i];
+ }
+ p[9] = irq_enable;
+ p[10] = irq_counter;
+ p[11] = irq_latch;
+ //*(INT*)&p[12] = irq_clock;
+ p[12] = (byte)irq_clock;
+ }
+
+ //void Mapper253::LoadState(LPBYTE p)
+ public override void LoadState(byte[] p)
+ {
+ for (INT i = 0; i < 9; i++)
+ {
+ reg[i] = p[i];
+ }
+ irq_enable = p[9];
+ irq_counter = p[10];
+ irq_latch = p[11];
+ //irq_clock = *(INT*)&p[12];
+ irq_clock = p[12];
+ }
+ }
+}
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper253.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper253.cs.meta
new file mode 100644
index 00000000..eaf47d3c
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper253.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 18997986769512340ba3766e5a555b22
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MapperFk23c.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MapperFk23c.cs
new file mode 100644
index 00000000..5ffce8c2
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MapperFk23c.cs
@@ -0,0 +1,282 @@
+//using System;
+//using VirtualNes.Core;
+
+//------------------------------.h-------------------------------
+
+// //////////////////////////////////////////////////////////////////////////
+// // MapperFk23c WaiXing San Guo Zhi - Xiong Ba Tian Xia (C) //
+// //////////////////////////////////////////////////////////////////////////
+//class MapperFk23c : public MMC3
+//{
+//public:
+// MapperFk23c(NES * parent);
+
+
+//void Reset();
+//void Write(WORD addr, BYTE data);
+//void WriteLow(WORD addr, BYTE data);
+
+//// For state save
+//BOOL IsStateSave() { return TRUE; }
+//void SaveState(LPBYTE p);
+//void LoadState(LPBYTE p);
+
+//protected:
+// BYTE exRegs[8];
+//BYTE unromChr, mode;
+
+//private:
+// void fk23c_UpdatePrg2p(unsigned int addr, unsigned int bank);
+//void fk23c_UpdateChr2p(unsigned int addr, unsigned int bank);
+//virtual void fk23c_UpdatePrg();
+//void fk23c_UpdateChr();
+//};
+
+//class MapperFk23ca : public MapperFk23c
+//{
+//public:
+// MapperFk23ca(NES * parent);
+//void Reset();
+
+//private:
+// void fk23c_UpdatePrg();
+//};
+
+//-----------------------------CPP-------------------------------
+
+////////////////////////////////////////////////////////////////////////////
+//// MapperFk23c WaiXing San Guo Zhi - Xiong Ba Tian Xia (C) //
+////////////////////////////////////////////////////////////////////////////
+
+//using System;
+//using VirtualNes.Core;
+
+//MapperFk23c::MapperFk23c(NES * parent) : MMC3(parent)
+//{
+// UpdateChr = (void(__thiscall MMC3::* )(unsigned int, unsigned int)) & MapperFk23c::fk23c_UpdateChr2p;
+// UpdatePrg = (void(__thiscall MMC3::* )(unsigned int, unsigned int)) & MapperFk23c::fk23c_UpdatePrg2p;
+//}
+
+//void MapperFk23c::Reset()
+//{
+// uint8 i;
+// for (i = 0; i < 8; ++i)
+// exRegs[i] = 0xFF;
+
+// if (PROM_16K_SIZE <= 32)
+// {
+// for (i = 0; i < 4; ++i)
+// exRegs[i] = 0x00;
+// }
+
+// unromChr = 0x0;
+// mode = 0;
+
+// MMC3::Reset();
+// Mmc3_UpdatePrg();
+// Mmc3_UpdateChr();
+//}
+
+//void MapperFk23c::WriteLow(WORD A, BYTE V)
+//{
+// if ((A >= 0x5000) && (A <= 0x5fff))
+// {
+// if (A & (1U << (mode + 4)))
+// {
+// exRegs[A & 0x3] = V;
+
+// fk23c_UpdatePrg();
+// fk23c_UpdateChr();
+// }
+// }
+// else
+// Mapper::WriteLow(A, V);
+//}
+
+
+//void MapperFk23c::Write(WORD A, BYTE V)
+//{
+// if (exRegs[0] & 0x40U)
+// {
+// unromChr = (exRegs[0] & 0x30U) ? 0x0 : V & 0x3;
+// fk23c_UpdateChr();
+// }
+// else switch (A & 0xE001)
+// {
+// case 0x8000: Poke_Mmc3_8000(A, V); break;
+// case 0x8001:
+
+// if (exRegs[3] << 2 & (ctrl0 & 0x8))
+// {
+// exRegs[4 | (ctrl0 & 0x3)] = V;
+
+// fk23c_UpdatePrg();
+// fk23c_UpdateChr();
+// }
+// else
+// {
+// Poke_Mmc3_8001(A, V);
+// }
+// break;
+
+// case 0xA000:
+// if (V)
+// SetVRAM_Mirror(VRAM_HMIRROR);
+// else
+// SetVRAM_Mirror(VRAM_VMIRROR);
+// break;
+// case 0xA001: Poke_Mmc3_A001(A, V); break;
+// case 0xC000: Poke_Mmc3_C000(A, V); break;
+// case 0xC001: Poke_Mmc3_C001(A, V); break;
+// case 0xE000: Poke_Mmc3_E000(A, V); break;
+// case 0xE001: Poke_Mmc3_E001(A, V); break;
+
+// default:;
+// }
+//}
+
+
+//void MapperFk23c::fk23c_UpdatePrg2p(unsigned int A, unsigned int V)
+//{
+// if ((exRegs[0] & 0x7U) - 3 > 1 && (!(exRegs[3] & 0x2U) || A < 0x4000))
+// {
+// if (exRegs[0] & 0x3U)
+// V = (V & (0x3FU >> (exRegs[0] & 0x3U))) | (exRegs[1] << 1);
+
+// SetPROM_8K_Bank((A >> 13) + 4, V);
+// }
+//}
+
+//void MapperFk23c::fk23c_UpdateChr2p(unsigned int A, unsigned int V)
+//{
+// if (VROM_1K_SIZE == 0) return;//ÔÝʱûÓкõĽâ¾ö·½·¨
+
+// if (!(exRegs[0] & 0x40U) && (!(exRegs[3] & 0x2U) || (A != 0x400 && A != 0xC00)))
+// SetVROM_1K_Bank(A >> 10, (exRegs[2] & 0x7FU) << 3 | V);
+//}
+
+
+//void MapperFk23c::fk23c_UpdatePrg()
+//{
+// if ((exRegs[0] & 0x7U) == 4)
+// {
+// SetPROM_32K_Bank(exRegs[1] >> 1);
+// }
+// else if ((exRegs[0] & 0x7U) == 3)
+// {
+// SetPROM_16K_Bank(4, exRegs[1]);
+// SetPROM_16K_Bank(6, exRegs[1]);
+// }
+// else
+// {
+// if (exRegs[3] & 0x2U)
+// {
+// SetPROM_8K_Bank(6, exRegs[4]);
+// SetPROM_8K_Bank(7, exRegs[5]);
+// }
+
+// Mmc3_UpdatePrg();
+// }
+//}
+
+//void MapperFk23c::fk23c_UpdateChr()
+//{
+// if (exRegs[0] & 0x40U)
+// {
+// SetVROM_8K_Bank(exRegs[2] | unromChr);
+// }
+// else
+// {
+// if (exRegs[3] & 0x2U)
+// {
+// const unsigned int base = (exRegs[2] & 0x7FU) << 3;
+
+// SetVROM_1K_Bank(1, base | exRegs[6]);
+// SetVROM_1K_Bank(3, base | exRegs[7]);
+// }
+
+// Mmc3_UpdateChr();
+// }
+//}
+
+//void MapperFk23c::SaveState(LPBYTE p)
+//{/*
+// for( INT i = 0; i < 8; i++ ) {
+// p[i] = reg[i];
+// p[10+i] = chr[i];
+// }
+
+// p[ 8] = prg[0];
+// p[ 9] = prg[1];
+// p[18] = irq_enable;
+// p[19] = irq_counter;
+// p[20] = irq_latch;
+// p[21] = irq_request;
+// p[22] = prg[2];
+// p[23] = prg[3];
+// */
+//}
+
+//void MapperFk23c::LoadState(LPBYTE p)
+//{
+// /*for( INT i = 0; i < 8; i++ ) {
+// reg[i] = p[i];
+// chr[i] = p[10+i];
+// }
+// prg[0] = p[ 8];
+// prg[1] = p[ 9];
+// irq_enable = p[18];
+// irq_counter = p[19];
+// irq_latch = p[20];
+// irq_request = p[21];
+// prg[2] = p[ 22];
+// prg[3] = p[ 23];*/
+//}
+
+
+
+//MapperFk23ca::MapperFk23ca(NES * parent) : MapperFk23c(parent)
+//{
+//}
+
+//void MapperFk23ca::Reset()
+//{
+// uint8 i;
+// for (i = 0; i < 8; ++i)
+// MapperFk23c::exRegs[i] = 0xFF;
+
+// for (i = 0; i < 4; ++i)
+// exRegs[i] = 0x00;
+
+// MapperFk23c::unromChr = 0x0;
+// MapperFk23c::mode = 0;
+
+// MMC3::Reset();
+// Mmc3_UpdatePrg();
+// Mmc3_UpdateChr();
+//}
+
+//void MapperFk23ca::fk23c_UpdatePrg()
+//{
+// uint32 bank = (exRegs[1] & 0x1F);
+// uint32 block = (exRegs[1] & 0x60);
+// uint32 extra = (exRegs[3] & 2);
+
+// if ((exRegs[0] & 0x7U) == 4)
+// {
+// SetPROM_32K_Bank((bank + block) >> 1);
+// }
+// else if ((exRegs[0] & 0x7U) == 3)
+// {
+// SetPROM_16K_Bank(4, (bank + block));
+// SetPROM_16K_Bank(6, (bank + block));
+// }
+// else
+// {
+// if (extra)
+// {
+// SetPROM_8K_Bank(6, exRegs[4]);
+// SetPROM_8K_Bank(7, exRegs[5]);
+// }
+// }
+//}
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MapperFk23c.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MapperFk23c.cs.meta
new file mode 100644
index 00000000..44c968cb
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/MapperFk23c.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: ec2612a9819d1f34cb86820bc16cbcc8
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/UnifMapper.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/UnifMapper.cs
new file mode 100644
index 00000000..c5c1d57c
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/UnifMapper.cs
@@ -0,0 +1,253 @@
+//using System;
+//using Unity.Android.Gradle;
+//using Unity.Android.Gradle.Manifest;
+//using VirtualNes.Core;
+
+//namespace VirtualNes.Core
+//{
+
+// public class map0_3208cn : Mapper
+// {
+// public map0_3208cn(NES parent) : base(parent) { }
+// //void map0_3208cn::Reset()
+// public override void Reset()
+// {
+// SetPROM_32K_Bank(0);
+// }
+
+
+// //void map0_3208cn::Write(WORD addr, BYTE data)
+// public override void Write(ushort addr, byte data)
+// {
+// //addr = 0x8000,Çл» PROM
+// if (addr == 0x8032)
+// SetPROM_32K_Bank(data);
+// if (addr == 0x8416)
+// SetPROM_16K_Bank(4, data);
+// if (addr == 0x8616)
+// SetPROM_16K_Bank(6, data);
+// if (addr == 0x8408)
+// SetPROM_8K_Bank(4, data);
+// if (addr == 0x8508)
+// SetPROM_8K_Bank(5, data);
+// if (addr == 0x8608)
+// SetPROM_8K_Bank(6, data);
+// if (addr == 0x8708)
+// SetPROM_8K_Bank(7, data);
+
+// //addr = 0x8001,Çл» VROM
+// if (addr == 0x9008)
+// SetVROM_8K_Bank(data);
+// if (addr == 0x9004)
+// SetVROM_4K_Bank(0, data);
+// if (addr == 0x9404)
+// SetVROM_4K_Bank(4, data);
+// if (addr == 0x9001)
+// SetVROM_1K_Bank(0, data);
+// if (addr == 0x9101)
+// SetVROM_1K_Bank(1, data);
+// if (addr == 0x9201)
+// SetVROM_1K_Bank(2, data);
+// if (addr == 0x9301)
+// SetVROM_1K_Bank(3, data);
+// if (addr == 0x9401)
+// SetVROM_1K_Bank(4, data);
+// if (addr == 0x9501)
+// SetVROM_1K_Bank(5, data);
+// if (addr == 0x9601)
+// SetVROM_1K_Bank(6, data);
+// if (addr == 0x9701)
+// SetVROM_1K_Bank(7, data);
+// }
+// }
+
+// public class GeniusMerioBros : Mapper
+// {
+
+// public GeniusMerioBros(NES parent) : base(parent) { }
+// //void GeniusMerioBros::Reset()
+// public override void Reset()
+// {
+// SetPROM_32K_Bank(0);
+// memcpy(WRAM, PROM + 0x2000 * 4, 0x800);
+// }
+
+// //BYTE GeniusMerioBros::ReadLow(WORD A)
+// public override byte ReadLow(ushort addr)
+// {
+// if (A >= 0x6000 && A <= 0x6FFF)
+// {
+// return CPU_MEM_BANK[0][A & 0x7FF];
+// }
+// else if (A >= 0x7000 && A <= 0x7FFF)
+// {
+// return XRAM[A & 0x7FF];
+// }
+// else
+// return (BYTE)(A >> 8);
+
+// }
+// //void GeniusMerioBros::WriteLow(WORD A, BYTE V)
+// public override void WriteLow(ushort addr, byte data)
+// {
+// if (A >= 0x7000 && A <= 0x7FFF)
+// {
+// XRAM[A & 0x7FF] = V;
+// }
+// else
+// if (A >= 0x6000 && A <= 0x6FFF)
+// {
+// CPU_MEM_BANK[A >> 13][A & 0x1FFF] = V;
+// }
+// }
+// }
+
+// public class smb2j : Mapper
+// {
+
+// BYTE prg, IRQa;
+// WORD IRQCount;
+// public smb2j(NES parent) : base(parent) { }
+// //Super Mario Bros. 2j (Unl) [U][!]
+// //void smb2j::Reset()
+// public override void Reset()
+// {
+// prg = 0;
+
+// memcpy(MRAM, &PROMPTR[1][0x1000], 0x1000);
+// SetPrg8r(1, 0x6000, 1);
+// SetPROM_32K_Bank(prg);
+// SetVROM_8K_Bank(0);
+// SetVRAM_Mirror(VRAM_VMIRROR);
+// IRQa = 0;
+// IRQCount = 0;
+// }
+
+// //void smb2j::Write(WORD A, BYTE V)// (0x4020,0xffff)
+// public override void Write(ushort addr, byte data)
+// {
+// if (A == 0x4022)
+// {
+// prg = V & 1;
+// SetPROM_32K_Bank(prg);
+// }
+// if (A == 0x4122)
+// {
+// IRQa = V;
+// IRQCount = 0;
+// nes->cpu->ClrIRQ(IRQ_MAPPER);
+// }
+// }
+
+// //void smb2j::WriteLow(WORD A, BYTE V)
+// public override void WriteLow(ushort addr, byte data)
+// {
+// Write(A, V);
+// }
+
+// //void smb2j::Clock(INT a)
+// public override void Clock(int cycles)
+// {
+// if (IRQa)
+// {
+// IRQCount += a * 3;
+// if ((IRQCount >> 12) == IRQa)
+// nes->cpu->SetIRQ(IRQ_MAPPER);
+// }
+// }
+
+// //BYTE smb2j::ReadLow(WORD A)
+// public override byte ReadLow(ushort addr)
+// {
+// if ((A >= 0x5000) && (A < 0x6000))
+// return MRAM[A - 0x5000];
+// return Mapper::ReadLow(A);
+// }
+// }
+
+// //public class smb2j : Mapper
+// //{
+
+// // WORD cmdreg;
+// // BYTE invalid_data;
+// // public smb2j(NES parent) : base(parent) { }
+
+// // void Reset();
+// // void SoftReset();
+// // void Write(WORD addr, BYTE data);
+// // BYTE Read(WORD addr);
+// // void Sync(void);
+// //}
+
+
+// //void Mapper8157::SoftReset()
+// // {
+// // cmdreg = 0x200;
+// // invalid_data ^= 1;
+// // Sync();
+// // }
+
+// // void Mapper8157::Sync(void)
+// // {
+// // SetPrg16r((cmdreg & 0x060) >> 5, 0x8000, (cmdreg & 0x01C) >> 2);
+// // SetPrg16r((cmdreg & 0x060) >> 5, 0xC000, (cmdreg & 0x200) ? (PROM_16K_SIZE / 4 - 1) : 0);
+// // SetVRAM_Mirror(((cmdreg & 2) >> 1) ^ 1);
+// // }
+
+// // BYTE Mapper8157::Read(WORD A)
+// // {
+// // if (invalid_data && cmdreg & 0x100)
+// // return 0xFF;
+// // else
+// // return Mapper::Read(A);
+// // }
+
+// // void Mapper8157::Write(WORD A, BYTE V)
+// // {
+// // cmdreg = A;
+// // Sync();
+// // }
+
+
+
+
+// public class MapperT262 : Mapper
+// {
+
+// uint16 addrreg;
+// uint8 datareg;
+// uint8 busy;
+// public MapperT262(NES parent) : base(parent) { }
+
+// //void MapperT262::Reset()
+// public override void Reset()
+// {
+// SetVROM_8K_Bank(0);
+// busy = 0;
+// addrreg = 0;
+// datareg = 0;
+
+// uint16 base = ((addrreg & 0x60) >> 2) | ((addrreg & 0x100) >> 3);
+// SetPROM_16K_Bank(0x8000 >> 13, (datareg & 7) | base);
+// SetPROM_16K_Bank(0xC000 >> 13, 7 | base);
+// SetVRAM_Mirror(((addrreg & 2) >> 1) ^ 1);
+// }
+// //void MapperT262::Write(WORD A, BYTE V)
+// public override void Write(ushort addr, byte data)
+// {
+// if (busy || (A == 0x8000))
+// datareg = V;
+// else
+// {
+// addrreg = A;
+// busy = 1;
+// }
+
+// uint16 base = ((addrreg & 0x60) >> 2) | ((addrreg & 0x100) >> 3);
+// SetPROM_16K_Bank(0x8000 >> 13, (datareg & 7) | base);
+// SetPROM_16K_Bank(0xC000 >> 13, 7 | base);
+// SetVRAM_Mirror(((addrreg & 2) >> 1) ^ 1);
+// }
+// }
+//}
+
diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/UnifMapper.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/UnifMapper.cs.meta
new file mode 100644
index 00000000..650adba1
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/UnifMapper.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: c022787531a02234dacffb16e9788d5f
\ No newline at end of file
diff --git a/AxibugEmuOnline.Server/Manager/SavDataManager.cs b/AxibugEmuOnline.Server/Manager/SavDataManager.cs
index bebdabd4..3c6a5195 100644
--- a/AxibugEmuOnline.Server/Manager/SavDataManager.cs
+++ b/AxibugEmuOnline.Server/Manager/SavDataManager.cs
@@ -231,7 +231,7 @@ namespace AxibugEmuOnline.Server.Manager
}
public void GetNewRomPath(long uid, RomPlatformType ptype, int romid, int stateIdx, string filename, out string path)
{
- path = Path.Combine(uid.ToString(), ptype.ToString(), romid.ToString(), stateIdx.ToString(), filename);
+ path = Path.Combine("UserSav", uid.ToString(), ptype.ToString(), romid.ToString(), stateIdx.ToString(), filename);
}
public bool FileDelete(string path)
{
diff --git a/AxibugEmuOnline.Server/Properties/PublishProfiles/FolderProfile1.pubxml.user b/AxibugEmuOnline.Server/Properties/PublishProfiles/FolderProfile1.pubxml.user
index b6eb66ef..9f1f3a0d 100644
--- a/AxibugEmuOnline.Server/Properties/PublishProfiles/FolderProfile1.pubxml.user
+++ b/AxibugEmuOnline.Server/Properties/PublishProfiles/FolderProfile1.pubxml.user
@@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
- True|2025-01-09T07:02:05.2160606Z||;True|2025-01-09T14:48:42.5299550+08:00||;False|2025-01-09T14:48:02.6306184+08:00||;True|2025-01-09T14:17:00.2185117+08:00||;True|2025-01-08T23:13:47.7309044+08:00||;True|2025-01-08T13:32:52.0590130+08:00||;True|2025-01-08T13:31:56.8589678+08:00||;True|2025-01-07T13:54:02.0272718+08:00||;True|2025-01-07T10:47:36.6196477+08:00||;True|2025-01-07T01:21:34.5863249+08:00||;False|2025-01-07T01:20:39.5344134+08:00||;True|2025-01-07T00:21:47.4863058+08:00||;True|2025-01-07T00:16:42.7998249+08:00||;False|2025-01-07T00:16:02.8107509+08:00||;False|2025-01-02T15:36:18.1906464+08:00||;False|2025-01-02T15:36:06.5622643+08:00||;True|2024-12-27T18:24:49.7554320+08:00||;
+ True|2025-01-13T08:07:43.4441316Z||;True|2025-01-09T15:02:05.2160606+08:00||;True|2025-01-09T14:48:42.5299550+08:00||;False|2025-01-09T14:48:02.6306184+08:00||;True|2025-01-09T14:17:00.2185117+08:00||;True|2025-01-08T23:13:47.7309044+08:00||;True|2025-01-08T13:32:52.0590130+08:00||;True|2025-01-08T13:31:56.8589678+08:00||;True|2025-01-07T13:54:02.0272718+08:00||;True|2025-01-07T10:47:36.6196477+08:00||;True|2025-01-07T01:21:34.5863249+08:00||;False|2025-01-07T01:20:39.5344134+08:00||;True|2025-01-07T00:21:47.4863058+08:00||;True|2025-01-07T00:16:42.7998249+08:00||;False|2025-01-07T00:16:02.8107509+08:00||;False|2025-01-02T15:36:18.1906464+08:00||;False|2025-01-02T15:36:06.5622643+08:00||;True|2024-12-27T18:24:49.7554320+08:00||;
\ No newline at end of file
diff --git a/AxibugEmuOnline.Web/Common/Config.cs b/AxibugEmuOnline.Web/Common/Config.cs
index 139d4041..6aa9b06f 100644
--- a/AxibugEmuOnline.Web/Common/Config.cs
+++ b/AxibugEmuOnline.Web/Common/Config.cs
@@ -21,6 +21,8 @@ namespace AxibugEmuOnline.Web.Common
public string ClientVersion { get; set; }
public string AesKey { get; set; }
public string AesIv { get; set; }
+ public string downLoadUrl { get; set; }
+ public string downLoadSavUrl { get; set; }
}
diff --git a/AxibugEmuOnline.Web/Controllers/ApiController.cs b/AxibugEmuOnline.Web/Controllers/ApiController.cs
index 05111f43..4d1a940d 100644
--- a/AxibugEmuOnline.Web/Controllers/ApiController.cs
+++ b/AxibugEmuOnline.Web/Controllers/ApiController.cs
@@ -46,7 +46,8 @@ namespace AxibugEmuOnline.Web.Controllers
clientVersion = Config.cfg.ClientVersion,
serverIp = Config.cfg.ServerIp,
serverPort = Config.cfg.ServerPort,
- downLoadUrl = ""
+ downLoadUrl = Config.cfg.downLoadUrl,
+ downLoadSavUrl = Config.cfg.downLoadSavUrl,
};
return new JsonResult(resp);
}
@@ -361,6 +362,7 @@ LIMIT ?offset, ?pageSize;";
public ushort serverPort { get; set; }
public string clientVersion { get; set; }
public string downLoadUrl { get; set; }
+ public string downLoadSavUrl { get; set; }
}
diff --git a/AxibugEmuOnline.Web/Properties/PublishProfiles/FolderProfile.pubxml.user b/AxibugEmuOnline.Web/Properties/PublishProfiles/FolderProfile.pubxml.user
index 2bf65348..df8a9f26 100644
--- a/AxibugEmuOnline.Web/Properties/PublishProfiles/FolderProfile.pubxml.user
+++ b/AxibugEmuOnline.Web/Properties/PublishProfiles/FolderProfile.pubxml.user
@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<_PublishTargetUrl>G:\Sin365\AxibugEmuOnline\AxibugEmuOnline.Web\bin\Release\net8.0\publish\
- True|2025-01-08T05:35:26.6793825Z||;True|2025-01-07T10:37:18.6461694+08:00||;True|2024-09-12T14:18:38.6992653+08:00||;True|2024-09-12T14:08:58.4526827+08:00||;True|2024-08-22T14:13:06.3067002+08:00||;True|2024-08-14T10:33:10.9180984+08:00||;True|2024-08-13T18:28:27.5050523+08:00||;True|2024-08-13T18:25:47.6591234+08:00||;True|2024-08-13T18:25:17.5344107+08:00||;True|2024-08-13T17:46:23.4523329+08:00||;
+ True|2025-01-13T07:57:42.8554189Z||;True|2025-01-13T15:56:16.9992929+08:00||;True|2025-01-09T15:00:13.8691822+08:00||;True|2025-01-09T14:47:16.4993283+08:00||;True|2025-01-09T14:47:09.3814423+08:00||;True|2025-01-09T14:38:36.2730244+08:00||;True|2025-01-08T13:35:26.6793825+08:00||;True|2025-01-07T10:37:18.6461694+08:00||;True|2024-09-12T14:18:38.6992653+08:00||;True|2024-09-12T14:08:58.4526827+08:00||;True|2024-08-22T14:13:06.3067002+08:00||;True|2024-08-14T10:33:10.9180984+08:00||;True|2024-08-13T18:28:27.5050523+08:00||;True|2024-08-13T18:25:47.6591234+08:00||;True|2024-08-13T18:25:17.5344107+08:00||;True|2024-08-13T17:46:23.4523329+08:00||;
\ No newline at end of file
diff --git a/README.md b/README.md
index 8f9ebe87..6be5ce82 100644
--- a/README.md
+++ b/README.md
@@ -118,6 +118,8 @@ Mapper支持越多,通俗讲就是支持更多卡带。
后续补充二次,修正 Mapper163 175 176 178 192 199 参照叶枫VirtuaNESex_src(20191105)
+后续补充第三次,修正Mapper 191 支持madcell大字汉化的《热血时代剧》《热血物语》《快打旋风》《双截龙3》, 添加Mapper253 支持外星《龙珠 中文》 (参照VirtuaNES Plus 翻译代码)
+
### 街机模拟器核心 CPS1 / NEOGEO / PGM / Taito(b) / Tehkan / or other MAME platform