AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Runtime/Core/Cartridge.cs
2024-06-28 18:08:25 +08:00

67 lines
2.0 KiB
C#

using System;
namespace AxibugEmuOnline.Client.UNES
{
public class Cartridge
{
public readonly byte[] Raw;
public readonly int PRGROMSize;
public readonly int CHRROMSize;
public readonly int PRGRAMSize;
public readonly int PRGROMOffset;
public readonly int MapperNumber;
public readonly byte[] PRGROM;
public readonly byte[] CHRROM;
public VRAMMirroringMode MirroringMode;
public enum VRAMMirroringMode
{
Horizontal, Vertical, All, Upper, Lower
}
public Cartridge(byte[] bytes)
{
Raw = bytes;
var header = BitConverter.ToInt32(Raw, 0);
if (header != 0x1A53454E) // "NES<EOF>"
{
throw new FormatException("unexpected header value " + header.ToString("X"));
}
PRGROMSize = Raw[4] * 0x4000; // 16kb units
CHRROMSize = Raw[5] * 0x2000; // 8kb units
PRGRAMSize = Raw[8] * 0x2000;
var hasTrainer = (Raw[6] & 0b100) > 0;
PRGROMOffset = 16 + (hasTrainer ? 512 : 0);
MirroringMode = (Raw[6] & 0x1) > 0 ? VRAMMirroringMode.Vertical : VRAMMirroringMode.Horizontal;
if ((Raw[6] & 0x8) > 0)
{
MirroringMode = VRAMMirroringMode.All;
}
MapperNumber = (Raw[6] >> 4) | (Raw[7] & 0xF0);
PRGROM = new byte[PRGROMSize];
Array.Copy(Raw, PRGROMOffset, PRGROM, 0, PRGROMSize);
if (CHRROMSize == 0)
{
CHRROM = new byte[0x2000];
}
else
{
CHRROM = new byte[CHRROMSize];
Array.Copy(Raw, PRGROMOffset + PRGROMSize, CHRROM, 0, CHRROMSize);
}
}
public override string ToString()
{
return $"Cartridge{{PRGROMSize={PRGROMSize}, CHRROMSize={CHRROMSize}, PRGROMOffset={PRGROMOffset}, MapperNumber={MapperNumber}}}";
}
}
}