Add files via upload
This commit is contained in:
parent
12c46db790
commit
fc0a251040
|
@ -12,36 +12,36 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
{
|
||||
return new Dictionary<string, RegisterValue>
|
||||
{
|
||||
["A"] = Cpu.RegisterA,
|
||||
["AF"] = Cpu.RegisterAF,
|
||||
["B"] = Cpu.RegisterB,
|
||||
["BC"] = Cpu.RegisterBC,
|
||||
["C"] = Cpu.RegisterC,
|
||||
["D"] = Cpu.RegisterD,
|
||||
["DE"] = Cpu.RegisterDE,
|
||||
["E"] = Cpu.RegisterE,
|
||||
["F"] = Cpu.RegisterF,
|
||||
["H"] = Cpu.RegisterH,
|
||||
["HL"] = Cpu.RegisterHL,
|
||||
["I"] = Cpu.RegisterI,
|
||||
["IX"] = Cpu.RegisterIX,
|
||||
["IY"] = Cpu.RegisterIY,
|
||||
["L"] = Cpu.RegisterL,
|
||||
["PC"] = Cpu.RegisterPC,
|
||||
["R"] = Cpu.RegisterR,
|
||||
["Shadow AF"] = Cpu.RegisterShadowAF,
|
||||
["Shadow BC"] = Cpu.RegisterShadowBC,
|
||||
["Shadow DE"] = Cpu.RegisterShadowDE,
|
||||
["Shadow HL"] = Cpu.RegisterShadowHL,
|
||||
["SP"] = Cpu.RegisterSP,
|
||||
["Flag C"] = Cpu.RegisterF.Bit(0),
|
||||
["Flag N"] = Cpu.RegisterF.Bit(1),
|
||||
["Flag P/V"] = Cpu.RegisterF.Bit(2),
|
||||
["Flag 3rd"] = Cpu.RegisterF.Bit(3),
|
||||
["Flag H"] = Cpu.RegisterF.Bit(4),
|
||||
["Flag 5th"] = Cpu.RegisterF.Bit(5),
|
||||
["Flag Z"] = Cpu.RegisterF.Bit(6),
|
||||
["Flag S"] = Cpu.RegisterF.Bit(7)
|
||||
["A"] = Cpu.Regs[Cpu.A],
|
||||
["AF"] = Cpu.Regs[Cpu.F] + (Cpu.Regs[Cpu.A] << 8),
|
||||
["B"] = Cpu.Regs[Cpu.B],
|
||||
["BC"] = Cpu.Regs[Cpu.C] + (Cpu.Regs[Cpu.B] << 8),
|
||||
["C"] = Cpu.Regs[Cpu.C],
|
||||
["D"] = Cpu.Regs[Cpu.D],
|
||||
["DE"] = Cpu.Regs[Cpu.E] + (Cpu.Regs[Cpu.D] << 8),
|
||||
["E"] = Cpu.Regs[Cpu.E],
|
||||
["F"] = Cpu.Regs[Cpu.F],
|
||||
["H"] = Cpu.Regs[Cpu.H],
|
||||
["HL"] = Cpu.Regs[Cpu.L] + (Cpu.Regs[Cpu.H] << 8),
|
||||
["I"] = Cpu.Regs[Cpu.I],
|
||||
["IX"] = Cpu.Regs[Cpu.Ixl] + (Cpu.Regs[Cpu.Ixh] << 8),
|
||||
["IY"] = Cpu.Regs[Cpu.Iyl] + (Cpu.Regs[Cpu.Iyh] << 8),
|
||||
["L"] = Cpu.Regs[Cpu.L],
|
||||
["PC"] = Cpu.Regs[Cpu.PCl] + (Cpu.Regs[Cpu.PCh] << 8),
|
||||
["R"] = Cpu.Regs[Cpu.R],
|
||||
["Shadow AF"] = Cpu.Regs[Cpu.F_s] + (Cpu.Regs[Cpu.A_s] << 8),
|
||||
["Shadow BC"] = Cpu.Regs[Cpu.C_s] + (Cpu.Regs[Cpu.B_s] << 8),
|
||||
["Shadow DE"] = Cpu.Regs[Cpu.E_s] + (Cpu.Regs[Cpu.D_s] << 8),
|
||||
["Shadow HL"] = Cpu.Regs[Cpu.L_s] + (Cpu.Regs[Cpu.H_s] << 8),
|
||||
["SP"] = Cpu.Regs[Cpu.Iyl] + (Cpu.Regs[Cpu.Iyh] << 8),
|
||||
["Flag C"] = Cpu.FlagC,
|
||||
["Flag N"] = Cpu.FlagN,
|
||||
["Flag P/V"] = Cpu.FlagP,
|
||||
["Flag 3rd"] = Cpu.Flag3,
|
||||
["Flag H"] = Cpu.FlagH,
|
||||
["Flag 5th"] = Cpu.Flag5,
|
||||
["Flag Z"] = Cpu.FlagZ,
|
||||
["Flag S"] = Cpu.FlagS
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,70 +52,82 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
default:
|
||||
throw new InvalidOperationException();
|
||||
case "A":
|
||||
Cpu.RegisterA = (byte)value;
|
||||
Cpu.Regs[Cpu.A] = (ushort)value;
|
||||
break;
|
||||
case "AF":
|
||||
Cpu.RegisterAF = (byte)value;
|
||||
Cpu.Regs[Cpu.F] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.A] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "B":
|
||||
Cpu.RegisterB = (byte)value;
|
||||
Cpu.Regs[Cpu.B] = (ushort)value;
|
||||
break;
|
||||
case "BC":
|
||||
Cpu.RegisterBC = (byte)value;
|
||||
Cpu.Regs[Cpu.C] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.B] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "C":
|
||||
Cpu.RegisterC = (byte)value;
|
||||
Cpu.Regs[Cpu.C] = (ushort)value;
|
||||
break;
|
||||
case "D":
|
||||
Cpu.RegisterD = (byte)value;
|
||||
Cpu.Regs[Cpu.D] = (ushort)value;
|
||||
break;
|
||||
case "DE":
|
||||
Cpu.RegisterDE = (byte)value;
|
||||
Cpu.Regs[Cpu.E] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.D] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "E":
|
||||
Cpu.RegisterE = (byte)value;
|
||||
Cpu.Regs[Cpu.E] = (ushort)value;
|
||||
break;
|
||||
case "F":
|
||||
Cpu.RegisterF = (byte)value;
|
||||
Cpu.Regs[Cpu.F] = (ushort)value;
|
||||
break;
|
||||
case "H":
|
||||
Cpu.RegisterH = (byte)value;
|
||||
Cpu.Regs[Cpu.H] = (ushort)value;
|
||||
break;
|
||||
case "HL":
|
||||
Cpu.RegisterHL = (byte)value;
|
||||
Cpu.Regs[Cpu.L] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.H] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "I":
|
||||
Cpu.RegisterI = (byte)value;
|
||||
Cpu.Regs[Cpu.I] = (ushort)value;
|
||||
break;
|
||||
case "IX":
|
||||
Cpu.RegisterIX = (byte)value;
|
||||
Cpu.Regs[Cpu.Ixl] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.Ixh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "IY":
|
||||
Cpu.RegisterIY = (byte)value;
|
||||
Cpu.Regs[Cpu.Iyl] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.Iyh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "L":
|
||||
Cpu.RegisterL = (byte)value;
|
||||
Cpu.Regs[Cpu.L] = (ushort)value;
|
||||
break;
|
||||
case "PC":
|
||||
Cpu.RegisterPC = (ushort)value;
|
||||
Cpu.Regs[Cpu.PCl] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.PCh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "R":
|
||||
Cpu.RegisterR = (byte)value;
|
||||
Cpu.Regs[Cpu.R] = (ushort)value;
|
||||
break;
|
||||
case "Shadow AF":
|
||||
Cpu.RegisterShadowAF = (byte)value;
|
||||
Cpu.Regs[Cpu.F_s] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.A_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow BC":
|
||||
Cpu.RegisterShadowBC = (byte)value;
|
||||
Cpu.Regs[Cpu.C_s] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.B_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow DE":
|
||||
Cpu.RegisterShadowDE = (byte)value;
|
||||
Cpu.Regs[Cpu.E_s] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.D_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow HL":
|
||||
Cpu.RegisterShadowHL = (byte)value;
|
||||
Cpu.Regs[Cpu.L_s] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.H_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "SP":
|
||||
Cpu.RegisterSP = (byte)value;
|
||||
Cpu.Regs[Cpu.SPl] = (ushort)(value & 0xFF);
|
||||
Cpu.Regs[Cpu.SPh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,15 +36,19 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
_lagged = true;
|
||||
_frame++;
|
||||
PSG.BeginFrame(Cpu.TotalExecutedCycles);
|
||||
Cpu.Debug = Tracer.Enabled;
|
||||
|
||||
if (!IsGameGear)
|
||||
{
|
||||
PSG.StereoPanning = Settings.ForceStereoSeparation ? ForceStereoByte : (byte)0xFF;
|
||||
}
|
||||
|
||||
if (Cpu.Debug && Cpu.Logger == null) // TODO, lets not do this on each frame. But lets refactor CoreComm/CoreComm first
|
||||
{
|
||||
Cpu.Logger = s => Tracer.Put(s);
|
||||
}
|
||||
|
||||
if (Tracer.Enabled)
|
||||
{
|
||||
Cpu.TraceCallback = s => Tracer.Put(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cpu.TraceCallback = null;
|
||||
}
|
||||
|
||||
if (IsGameGear == false)
|
||||
|
|
|
@ -1,106 +1,100 @@
|
|||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public sealed partial class SMS : IStatable
|
||||
{
|
||||
public bool BinarySaveStatesPreferred
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
SyncState(Serializer.CreateBinaryWriter(bw));
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
SyncState(Serializer.CreateBinaryReader(br));
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter tw)
|
||||
{
|
||||
SyncState(Serializer.CreateTextWriter(tw));
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader tr)
|
||||
{
|
||||
SyncState(Serializer.CreateTextReader(tr));
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
if (_stateBuffer == null)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new BinaryWriter(stream);
|
||||
SaveStateBinary(writer);
|
||||
_stateBuffer = stream.ToArray();
|
||||
writer.Close();
|
||||
return _stateBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
var stream = new MemoryStream(_stateBuffer);
|
||||
var writer = new BinaryWriter(stream);
|
||||
SaveStateBinary(writer);
|
||||
writer.Close();
|
||||
return _stateBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] _stateBuffer;
|
||||
|
||||
private void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("SMS");
|
||||
Cpu.SyncState(ser);
|
||||
Vdp.SyncState(ser);
|
||||
PSG.SyncState(ser);
|
||||
ser.Sync("RAM", ref SystemRam, false);
|
||||
ser.Sync("RomBank0", ref RomBank0);
|
||||
ser.Sync("RomBank1", ref RomBank1);
|
||||
ser.Sync("RomBank2", ref RomBank2);
|
||||
ser.Sync("RomBank3", ref RomBank3);
|
||||
ser.Sync("Port01", ref Port01);
|
||||
ser.Sync("Port02", ref Port02);
|
||||
ser.Sync("Port3E", ref Port3E);
|
||||
ser.Sync("Port3F", ref Port3F);
|
||||
ser.Sync("Paddle1High", ref Paddle1High);
|
||||
ser.Sync("Paddle2High", ref Paddle2High);
|
||||
ser.Sync("LatchLightPhaser", ref LatchLightPhaser);
|
||||
|
||||
if (SaveRAM != null)
|
||||
{
|
||||
ser.Sync("SaveRAM", ref SaveRAM, false);
|
||||
ser.Sync("SaveRamBank", ref SaveRamBank);
|
||||
}
|
||||
|
||||
if (ExtRam != null)
|
||||
{
|
||||
ser.Sync("ExtRAM", ref ExtRam, true);
|
||||
}
|
||||
|
||||
if (HasYM2413)
|
||||
{
|
||||
YM2413.SyncState(ser);
|
||||
}
|
||||
|
||||
ser.Sync("Frame", ref _frame);
|
||||
ser.Sync("LagCount", ref _lagCount);
|
||||
ser.Sync("IsLag", ref _isLag);
|
||||
|
||||
ser.EndSection();
|
||||
|
||||
if (ser.IsReader)
|
||||
{
|
||||
SyncAllByteArrayDomains();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public sealed partial class SMS : IStatable
|
||||
{
|
||||
public bool BinarySaveStatesPreferred
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
SyncState(new Serializer(writer));
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
SyncState(new Serializer(reader));
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
SyncState(new Serializer(bw));
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
SyncState(new Serializer(br));
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter bw = new BinaryWriter(ms);
|
||||
SaveStateBinary(bw);
|
||||
bw.Flush();
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private void SyncState(Serializer ser)
|
||||
{
|
||||
byte[] core = null;
|
||||
if (ser.IsWriter)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
ms.Close();
|
||||
core = ms.ToArray();
|
||||
}
|
||||
Cpu.SyncState(ser);
|
||||
|
||||
ser.BeginSection("SMS");
|
||||
Vdp.SyncState(ser);
|
||||
PSG.SyncState(ser);
|
||||
ser.Sync("RAM", ref SystemRam, false);
|
||||
ser.Sync("RomBank0", ref RomBank0);
|
||||
ser.Sync("RomBank1", ref RomBank1);
|
||||
ser.Sync("RomBank2", ref RomBank2);
|
||||
ser.Sync("RomBank3", ref RomBank3);
|
||||
ser.Sync("Port01", ref Port01);
|
||||
ser.Sync("Port02", ref Port02);
|
||||
ser.Sync("Port3E", ref Port3E);
|
||||
ser.Sync("Port3F", ref Port3F);
|
||||
ser.Sync("Paddle1High", ref Paddle1High);
|
||||
ser.Sync("Paddle2High", ref Paddle2High);
|
||||
ser.Sync("LatchLightPhaser", ref LatchLightPhaser);
|
||||
|
||||
if (SaveRAM != null)
|
||||
{
|
||||
ser.Sync("SaveRAM", ref SaveRAM, false);
|
||||
ser.Sync("SaveRamBank", ref SaveRamBank);
|
||||
}
|
||||
|
||||
if (ExtRam != null)
|
||||
{
|
||||
ser.Sync("ExtRAM", ref ExtRam, true);
|
||||
}
|
||||
|
||||
if (HasYM2413)
|
||||
{
|
||||
YM2413.SyncState(ser);
|
||||
}
|
||||
|
||||
ser.Sync("Frame", ref _frame);
|
||||
ser.Sync("LagCount", ref _lagCount);
|
||||
ser.Sync("IsLag", ref _isLag);
|
||||
|
||||
ser.EndSection();
|
||||
|
||||
if (ser.IsReader)
|
||||
{
|
||||
SyncAllByteArrayDomains();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ using BizHawk.Common.StringExtensions;
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.Components;
|
||||
using BizHawk.Emulation.Cores.Components;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using BizHawk.Emulation.Common.Components.Z80A;
|
||||
|
||||
/*****************************************************
|
||||
TODO:
|
||||
|
@ -75,11 +75,12 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
HasYM2413 = true;
|
||||
}
|
||||
|
||||
Cpu = new Z80A
|
||||
Cpu = new Z80A()
|
||||
{
|
||||
RegisterSP = 0xDFF0,
|
||||
ReadHardware = ReadPort,
|
||||
WriteHardware = WritePort,
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
MemoryCallbacks = MemoryCallbacks
|
||||
};
|
||||
|
||||
|
@ -160,7 +161,10 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
}
|
||||
|
||||
if (game["SRAM"])
|
||||
{
|
||||
SaveRAM = new byte[int.Parse(game.OptionValue("SRAM"))];
|
||||
Console.WriteLine(SaveRAM.Length);
|
||||
}
|
||||
else if (game.NotInDatabase)
|
||||
SaveRAM = new byte[0x8000];
|
||||
|
||||
|
@ -175,8 +179,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
|
||||
var serviceProvider = ServiceProvider as BasicServiceProvider;
|
||||
serviceProvider.Register<ITraceable>(Tracer);
|
||||
serviceProvider.Register<IDisassemblable>(new Disassembler());
|
||||
serviceProvider.Register<IDisassemblable>(Cpu);
|
||||
Vdp.ProcessOverscan();
|
||||
|
||||
Cpu.ReadMemory = ReadMemory;
|
||||
Cpu.WriteMemory = WriteMemory;
|
||||
}
|
||||
|
||||
// Constants
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.IO;
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using BizHawk.Emulation.Common.Components.Z80A;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
|
@ -113,7 +113,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
StatusByte &= 0x1F;
|
||||
HIntPending = false;
|
||||
VIntPending = false;
|
||||
Cpu.Interrupt = false;
|
||||
Cpu.FlagI = false;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
@ -291,13 +291,13 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
{
|
||||
case 0: // Mode Control Register 1
|
||||
CheckVideoMode();
|
||||
Cpu.Interrupt = (EnableLineInterrupts && HIntPending);
|
||||
Cpu.Interrupt |= (EnableFrameInterrupts && VIntPending);
|
||||
Cpu.FlagI = (EnableLineInterrupts && HIntPending);
|
||||
Cpu.FlagI |= (EnableFrameInterrupts && VIntPending);
|
||||
break;
|
||||
case 1: // Mode Control Register 2
|
||||
CheckVideoMode();
|
||||
Cpu.Interrupt = (EnableFrameInterrupts && VIntPending);
|
||||
Cpu.Interrupt |= (EnableLineInterrupts && HIntPending);
|
||||
Cpu.FlagI = (EnableFrameInterrupts && VIntPending);
|
||||
Cpu.FlagI |= (EnableLineInterrupts && HIntPending);
|
||||
break;
|
||||
case 2: // Name Table Base Address
|
||||
NameTableBase = CalcNameTableBase();
|
||||
|
@ -347,7 +347,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
|
||||
if (VIntPending && EnableFrameInterrupts)
|
||||
{
|
||||
Cpu.Interrupt = true;
|
||||
Cpu.FlagI = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
HIntPending = true;
|
||||
if (EnableLineInterrupts)
|
||||
{;
|
||||
Cpu.Interrupt = true;
|
||||
Cpu.FlagI = true;
|
||||
}
|
||||
lineIntLinesRemaining = Registers[0x0A];
|
||||
}
|
||||
|
@ -383,7 +383,14 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
ProcessLineInterrupt();
|
||||
Sms.ProcessLineControls();
|
||||
|
||||
Cpu.ExecuteCycles(IPeriod);
|
||||
//Console.Write(Cpu.cur_instr.Length);
|
||||
//Console.Write(" ");
|
||||
//Console.WriteLine(Cpu.instr_pntr);
|
||||
for (int j = 0; j < IPeriod; j++)
|
||||
{
|
||||
Cpu.ExecuteOne();
|
||||
}
|
||||
|
||||
|
||||
if (ScanLine == scanlinesPerFrame - 1)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue