核心低版本C#修改
This commit is contained in:
parent
51336a4976
commit
45f904172d
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Iris.CPU
|
namespace Iris.CPU
|
||||||
{
|
{
|
||||||
@ -93,17 +93,43 @@ namespace Iris.CPU
|
|||||||
N = 31
|
N = 31
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe readonly struct InstructionListEntry<T>(T mask, T expected, delegate*<CPU_Core, T, UInt64> handler, List<Model> modelList)
|
//internal unsafe readonly struct InstructionListEntry1<T>(T mask, T expected, delegate*<CPU_Core, T, UInt64> handler, List<Model> modelList)
|
||||||
|
//{
|
||||||
|
// internal readonly T _mask = mask;
|
||||||
|
// internal readonly T _expected = expected;
|
||||||
|
// internal unsafe readonly delegate*<CPU_Core, T, UInt64> _handler = handler;
|
||||||
|
// internal readonly List<Model> _modelList = modelList;
|
||||||
|
//}
|
||||||
|
|
||||||
|
internal unsafe readonly struct InstructionListEntry<T>
|
||||||
{
|
{
|
||||||
internal readonly T _mask = mask;
|
internal InstructionListEntry(T mask, T expected, delegate*<CPU_Core, T, UInt64> handler, List<Model> modelList)
|
||||||
internal readonly T _expected = expected;
|
{
|
||||||
internal unsafe readonly delegate*<CPU_Core, T, UInt64> _handler = handler;
|
_mask = mask;
|
||||||
internal readonly List<Model> _modelList = modelList;
|
_expected = expected;
|
||||||
|
_handler = handler;
|
||||||
|
_modelList = modelList;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal readonly T _mask;
|
||||||
|
internal readonly T _expected;
|
||||||
|
internal unsafe readonly delegate*<CPU_Core, T, UInt64> _handler;
|
||||||
|
internal readonly List<Model> _modelList;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe readonly struct InstructionLUTEntry<T>(delegate*<CPU_Core, T, UInt64> handler)
|
//internal unsafe readonly struct InstructionLUTEntry<T>(delegate*<CPU_Core, T, UInt64> handler)
|
||||||
|
//{
|
||||||
|
// internal unsafe readonly delegate*<CPU_Core, T, UInt64> _handler = handler;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
internal unsafe readonly struct InstructionLUTEntry<T>
|
||||||
{
|
{
|
||||||
internal unsafe readonly delegate*<CPU_Core, T, UInt64> _handler = handler;
|
internal InstructionLUTEntry(delegate*<CPU_Core, T, UInt64> handler)
|
||||||
|
{
|
||||||
|
_handler = handler;
|
||||||
|
}
|
||||||
|
internal unsafe readonly delegate*<CPU_Core, T, UInt64> _handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal const UInt32 ModeMask = 0b1_1111;
|
internal const UInt32 ModeMask = 0b1_1111;
|
||||||
@ -307,10 +333,9 @@ namespace Iris.CPU
|
|||||||
UInt32 newMode = value & ModeMask;
|
UInt32 newMode = value & ModeMask;
|
||||||
|
|
||||||
CPSR = value | 0b1_0000;
|
CPSR = value | 0b1_0000;
|
||||||
|
|
||||||
if (previousMode != newMode)
|
if (previousMode != newMode)
|
||||||
{
|
{
|
||||||
ref UInt32 regDataRef = ref MemoryMarshal.GetArrayDataReference(Reg);
|
ref UInt32 regDataRef = ref MyUnSafeCommon.GetArrayDataReference(Reg);
|
||||||
ref UInt32 reg8 = ref Unsafe.Add(ref regDataRef, 8);
|
ref UInt32 reg8 = ref Unsafe.Add(ref regDataRef, 8);
|
||||||
ref UInt32 reg9 = ref Unsafe.Add(ref regDataRef, 9);
|
ref UInt32 reg9 = ref Unsafe.Add(ref regDataRef, 9);
|
||||||
ref UInt32 reg10 = ref Unsafe.Add(ref regDataRef, 10);
|
ref UInt32 reg10 = ref Unsafe.Add(ref regDataRef, 10);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Iris.Common
|
namespace Iris.Common
|
||||||
{
|
{
|
||||||
public sealed class Scheduler(int taskListSize, int scheduledTaskListSize)
|
public sealed class Scheduler
|
||||||
{
|
{
|
||||||
|
public Scheduler(int taskListSize, int scheduledTaskListSize)
|
||||||
|
{
|
||||||
|
_taskList = new Task_Delegate[taskListSize];
|
||||||
|
_scheduledTaskList = new ScheduledTaskListEntry[scheduledTaskListSize];
|
||||||
|
}
|
||||||
public delegate void Task_Delegate(UInt64 cycleCountDelay);
|
public delegate void Task_Delegate(UInt64 cycleCountDelay);
|
||||||
private readonly Task_Delegate[] _taskList = new Task_Delegate[taskListSize];
|
private readonly Task_Delegate[] _taskList;
|
||||||
|
//private readonly Task_Delegate[] _taskList = new Task_Delegate[taskListSize];
|
||||||
|
|
||||||
private struct ScheduledTaskListEntry
|
private struct ScheduledTaskListEntry
|
||||||
{
|
{
|
||||||
@ -15,7 +22,7 @@ namespace Iris.Common
|
|||||||
internal UInt64 _cycleCount;
|
internal UInt64 _cycleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ScheduledTaskListEntry[] _scheduledTaskList = new ScheduledTaskListEntry[scheduledTaskListSize]; // sorted by _cycleCount from smallest to largest
|
private readonly ScheduledTaskListEntry[] _scheduledTaskList; // sorted by _cycleCount from smallest to largest
|
||||||
private int _scheduledTaskCount;
|
private int _scheduledTaskCount;
|
||||||
|
|
||||||
private UInt64 _cycleCounter;
|
private UInt64 _cycleCounter;
|
||||||
@ -60,9 +67,14 @@ namespace Iris.Common
|
|||||||
{
|
{
|
||||||
_cycleCounter += cycleCount;
|
_cycleCounter += cycleCount;
|
||||||
|
|
||||||
|
|
||||||
// process tasks
|
// process tasks
|
||||||
ref readonly ScheduledTaskListEntry firstEntry = ref MemoryMarshal.GetArrayDataReference(_scheduledTaskList);
|
|
||||||
ref Task_Delegate taskListDataRef = ref MemoryMarshal.GetArrayDataReference(_taskList);
|
//ref readonly ScheduledTaskListEntry firstEntry = ref UnSafeCommon.GetArrayDataReference(_scheduledTaskList);
|
||||||
|
//ref Task_Delegate taskListDataRef = ref UnSafeCommon.GetArrayDataReference(_taskList);
|
||||||
|
|
||||||
|
ref readonly ScheduledTaskListEntry firstEntry = ref MyUnSafeCommon.GetArrayDataReference(_scheduledTaskList);
|
||||||
|
ref Task_Delegate taskListDataRef = ref MyUnSafeCommon.GetArrayDataReference(_taskList);
|
||||||
|
|
||||||
while ((_scheduledTaskCount > 0) && (firstEntry._cycleCount <= _cycleCounter))
|
while ((_scheduledTaskCount > 0) && (firstEntry._cycleCount <= _cycleCounter))
|
||||||
{
|
{
|
||||||
@ -93,7 +105,8 @@ namespace Iris.Common
|
|||||||
// get the position and reference of the new task
|
// get the position and reference of the new task
|
||||||
// (searching is done backward because a new task is more likely to be inserted towards the end)
|
// (searching is done backward because a new task is more likely to be inserted towards the end)
|
||||||
int index = _scheduledTaskCount;
|
int index = _scheduledTaskCount;
|
||||||
ref ScheduledTaskListEntry entry = ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_scheduledTaskList), _scheduledTaskCount - 1);
|
//ref ScheduledTaskListEntry entry = ref Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_scheduledTaskList), _scheduledTaskCount - 1);
|
||||||
|
ref ScheduledTaskListEntry entry = ref Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_scheduledTaskList), _scheduledTaskCount - 1);
|
||||||
|
|
||||||
while ((index > 0) && (entry._cycleCount > cycleCount))
|
while ((index > 0) && (entry._cycleCount > cycleCount))
|
||||||
{
|
{
|
||||||
@ -116,7 +129,8 @@ namespace Iris.Common
|
|||||||
public void CancelTask(int id)
|
public void CancelTask(int id)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
ref ScheduledTaskListEntry entry = ref MemoryMarshal.GetArrayDataReference(_scheduledTaskList);
|
//ref ScheduledTaskListEntry entry = ref MyUnSafeCommon.GetArrayDataReference(_scheduledTaskList);
|
||||||
|
ref ScheduledTaskListEntry entry = ref MyUnSafeCommon.GetArrayDataReference(_scheduledTaskList);
|
||||||
|
|
||||||
while (index < _scheduledTaskCount)
|
while (index < _scheduledTaskCount)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace Iris.Common
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Iris.Common
|
||||||
{
|
{
|
||||||
public abstract class System : IDisposable
|
public abstract class System : IDisposable
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace Iris.GBA
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
internal sealed class Communication
|
internal sealed class Communication
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
@ -414,10 +416,15 @@ namespace Iris.GBA
|
|||||||
const int DataUnitSize = 2;
|
const int DataUnitSize = 2;
|
||||||
|
|
||||||
int sourceIncrement = GetSourceIncrement(DataUnitSize);
|
int sourceIncrement = GetSourceIncrement(DataUnitSize);
|
||||||
(int destinationIncrement, reloadDestination) = GetDestinationIncrement(DataUnitSize);
|
//(int destinationIncrement, reloadDestination) = GetDestinationIncrement(DataUnitSize);
|
||||||
|
|
||||||
|
var v2 = GetDestinationIncrement(DataUnitSize);
|
||||||
|
int destinationIncrement = v2.destinationIncrement;
|
||||||
|
reloadDestination = v2.reloadDestination;
|
||||||
|
|
||||||
for (; channel._length > 0; --channel._length)
|
for (; channel._length > 0; --channel._length)
|
||||||
{
|
{
|
||||||
|
//_memory.Write16(channel._destination, _memory.Read16(channel._source));
|
||||||
_memory.Write16(channel._destination, _memory.Read16(channel._source));
|
_memory.Write16(channel._destination, _memory.Read16(channel._source));
|
||||||
|
|
||||||
channel._source = (UInt32)(channel._source + sourceIncrement);
|
channel._source = (UInt32)(channel._source + sourceIncrement);
|
||||||
@ -433,7 +440,10 @@ namespace Iris.GBA
|
|||||||
const int DataUnitSize = 4;
|
const int DataUnitSize = 4;
|
||||||
|
|
||||||
int sourceIncrement = GetSourceIncrement(DataUnitSize);
|
int sourceIncrement = GetSourceIncrement(DataUnitSize);
|
||||||
(int destinationIncrement, reloadDestination) = GetDestinationIncrement(DataUnitSize);
|
//(int destinationIncrement, reloadDestination) = GetDestinationIncrement(DataUnitSize);
|
||||||
|
var v2 = GetDestinationIncrement(DataUnitSize);
|
||||||
|
int destinationIncrement = v2.destinationIncrement;
|
||||||
|
reloadDestination = v2.reloadDestination;
|
||||||
|
|
||||||
for (; channel._length > 0; --channel._length)
|
for (; channel._length > 0; --channel._length)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Security.Cryptography;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
@ -226,7 +229,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
address &= 0x0fff_ffff;
|
address &= 0x0fff_ffff;
|
||||||
|
|
||||||
IntPtr page = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_read8PageTable), address >> 10);
|
IntPtr page = Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_read8PageTable), (int)(address >> 10));
|
||||||
|
|
||||||
if (page != IntPtr.Zero)
|
if (page != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@ -507,7 +510,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
address &= 0x0fff_fffe;
|
address &= 0x0fff_fffe;
|
||||||
|
|
||||||
IntPtr page = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_read16PageTable), address >> 10);
|
IntPtr page = Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_read16PageTable), (int)(address >> 10));
|
||||||
|
|
||||||
if (page != IntPtr.Zero)
|
if (page != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@ -655,7 +658,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
address &= 0x0fff_fffc;
|
address &= 0x0fff_fffc;
|
||||||
|
|
||||||
IntPtr page = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_read32PageTable), address >> 10);
|
IntPtr page = Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_read32PageTable), (int)(address >> 10));
|
||||||
|
|
||||||
if (page != IntPtr.Zero)
|
if (page != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@ -778,7 +781,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
address &= 0x0fff_ffff;
|
address &= 0x0fff_ffff;
|
||||||
|
|
||||||
IntPtr page = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_write8PageTable), address >> 10);
|
IntPtr page = Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_write8PageTable), (int)(address >> 10));
|
||||||
|
|
||||||
if (page != IntPtr.Zero)
|
if (page != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@ -1499,7 +1502,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
address &= 0x0fff_fffe;
|
address &= 0x0fff_fffe;
|
||||||
|
|
||||||
IntPtr page = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_write16PageTable), address >> 10);
|
IntPtr page = Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_write16PageTable), (int)(address >> 10));
|
||||||
|
|
||||||
if (page != IntPtr.Zero)
|
if (page != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@ -1883,7 +1886,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
address &= 0x0fff_fffc;
|
address &= 0x0fff_fffc;
|
||||||
|
|
||||||
IntPtr page = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(_write32PageTable), address >> 10);
|
IntPtr page = Unsafe.Add(ref MyUnSafeCommon.GetArrayDataReference(_write32PageTable), (int)(address >> 10));
|
||||||
|
|
||||||
if (page != IntPtr.Zero)
|
if (page != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace Iris.GBA
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
internal sealed class Sound
|
internal sealed class Sound
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace Iris.GBA
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
internal sealed class SystemControl
|
internal sealed class SystemControl
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using static UnityEditor.Experimental.AssetDatabaseExperimental.AssetDatabaseCounters;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
{
|
{
|
||||||
@ -23,17 +26,43 @@ namespace Iris.GBA
|
|||||||
|
|
||||||
private InterruptControl _interruptControl;
|
private InterruptControl _interruptControl;
|
||||||
|
|
||||||
private struct Channel(GBA_System.TaskId startTaskId, GBA_System.TaskId handleOverflowTaskId, InterruptControl.Interrupt interrupt)
|
//private struct Channel(GBA_System.TaskId startTaskId, GBA_System.TaskId handleOverflowTaskId, InterruptControl.Interrupt interrupt)
|
||||||
|
//{
|
||||||
|
// internal UInt16 _counter;
|
||||||
|
// internal UInt16 _reload;
|
||||||
|
// internal UInt16 _control;
|
||||||
|
// internal UInt64 _cycleCount; // only used in non-cascading mode
|
||||||
|
// internal bool _running;
|
||||||
|
|
||||||
|
// internal readonly GBA_System.TaskId _startTaskId = startTaskId;
|
||||||
|
// internal readonly GBA_System.TaskId _handleOverflowTaskId = handleOverflowTaskId;
|
||||||
|
// internal readonly InterruptControl.Interrupt _interrupt = interrupt;
|
||||||
|
//}
|
||||||
|
|
||||||
|
private struct Channel
|
||||||
{
|
{
|
||||||
|
internal Channel(GBA_System.TaskId startTaskId, GBA_System.TaskId handleOverflowTaskId, InterruptControl.Interrupt interrupt)
|
||||||
|
{
|
||||||
|
_startTaskId = startTaskId;
|
||||||
|
_handleOverflowTaskId = handleOverflowTaskId;
|
||||||
|
_interrupt = interrupt;
|
||||||
|
|
||||||
|
_counter = 0;
|
||||||
|
_reload = 0;
|
||||||
|
_control = 0;
|
||||||
|
_cycleCount = 0;
|
||||||
|
_running = false;
|
||||||
|
|
||||||
|
}
|
||||||
internal UInt16 _counter;
|
internal UInt16 _counter;
|
||||||
internal UInt16 _reload;
|
internal UInt16 _reload;
|
||||||
internal UInt16 _control;
|
internal UInt16 _control;
|
||||||
internal UInt64 _cycleCount; // only used in non-cascading mode
|
internal UInt64 _cycleCount; // only used in non-cascading mode
|
||||||
internal bool _running;
|
internal bool _running;
|
||||||
|
|
||||||
internal readonly GBA_System.TaskId _startTaskId = startTaskId;
|
internal readonly GBA_System.TaskId _startTaskId;
|
||||||
internal readonly GBA_System.TaskId _handleOverflowTaskId = handleOverflowTaskId;
|
internal readonly GBA_System.TaskId _handleOverflowTaskId;
|
||||||
internal readonly InterruptControl.Interrupt _interrupt = interrupt;
|
internal readonly InterruptControl.Interrupt _interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Channel[] _channels;
|
private readonly Channel[] _channels;
|
||||||
@ -42,13 +71,13 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
_scheduler = scheduler;
|
_scheduler = scheduler;
|
||||||
|
|
||||||
_channels =
|
_channels = new Channel[]
|
||||||
[
|
{
|
||||||
new(GBA_System.TaskId.StartTimer_Channel0, GBA_System.TaskId.HandleTimerOverflow_Channel0, InterruptControl.Interrupt.Timer0),
|
new Channel(GBA_System.TaskId.StartTimer_Channel0, GBA_System.TaskId.HandleTimerOverflow_Channel0, InterruptControl.Interrupt.Timer0),
|
||||||
new(GBA_System.TaskId.StartTimer_Channel1, GBA_System.TaskId.HandleTimerOverflow_Channel1, InterruptControl.Interrupt.Timer1),
|
new Channel(GBA_System.TaskId.StartTimer_Channel1, GBA_System.TaskId.HandleTimerOverflow_Channel1, InterruptControl.Interrupt.Timer1),
|
||||||
new(GBA_System.TaskId.StartTimer_Channel2, GBA_System.TaskId.HandleTimerOverflow_Channel2, InterruptControl.Interrupt.Timer2),
|
new Channel(GBA_System.TaskId.StartTimer_Channel2, GBA_System.TaskId.HandleTimerOverflow_Channel2, InterruptControl.Interrupt.Timer2),
|
||||||
new(GBA_System.TaskId.StartTimer_Channel3, GBA_System.TaskId.HandleTimerOverflow_Channel3, InterruptControl.Interrupt.Timer3)
|
new Channel(GBA_System.TaskId.StartTimer_Channel3, GBA_System.TaskId.HandleTimerOverflow_Channel3, InterruptControl.Interrupt.Timer3)
|
||||||
];
|
};
|
||||||
|
|
||||||
for (int channelIndex = 0; channelIndex < 4; ++channelIndex)
|
for (int channelIndex = 0; channelIndex < 4; ++channelIndex)
|
||||||
{
|
{
|
||||||
@ -333,7 +362,8 @@ namespace Iris.GBA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UInt64 ComputeCycleCountUntilOverflow(ref readonly Channel channel)
|
//private static UInt64 ComputeCycleCountUntilOverflow(ref readonly Channel channel)
|
||||||
|
private static UInt64 ComputeCycleCountUntilOverflow(ref Channel channel)
|
||||||
{
|
{
|
||||||
return (0x1_0000u - channel._counter) * GetPrescaler(channel._control);
|
return (0x1_0000u - channel._counter) * GetPrescaler(channel._control);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Iris.GBA
|
namespace Iris.GBA
|
||||||
@ -265,7 +267,7 @@ namespace Iris.GBA
|
|||||||
|
|
||||||
_scheduler.ScheduleTask((int)GBA_System.TaskId.StartHBlank, HDrawCycleCount);
|
_scheduler.ScheduleTask((int)GBA_System.TaskId.StartHBlank, HDrawCycleCount);
|
||||||
|
|
||||||
Array.Clear(_displayFrameBuffer);
|
Array.Clear(_displayFrameBuffer,0, _displayFrameBuffer.Length);
|
||||||
|
|
||||||
_currentBG2X = 0;
|
_currentBG2X = 0;
|
||||||
_currentBG2Y = 0;
|
_currentBG2Y = 0;
|
||||||
@ -674,7 +676,8 @@ namespace Iris.GBA
|
|||||||
_dma.PerformVideoTransfer(false);
|
_dma.PerformVideoTransfer(false);
|
||||||
|
|
||||||
_presentFrameCallback(_displayFrameBuffer);
|
_presentFrameCallback(_displayFrameBuffer);
|
||||||
Array.Clear(_displayFrameBuffer);
|
//Array.Clear(_displayFrameBuffer);
|
||||||
|
Array.Clear(_displayFrameBuffer,0, _displayFrameBuffer.Length);
|
||||||
|
|
||||||
_currentBG2X = ((_BG2X_H << 20) | (_BG2X_L << 4)) >> 4;
|
_currentBG2X = ((_BG2X_H << 20) | (_BG2X_L << 4)) >> 4;
|
||||||
_currentBG2Y = ((_BG2Y_H << 20) | (_BG2Y_L << 4)) >> 4;
|
_currentBG2Y = ((_BG2Y_H << 20) | (_BG2Y_L << 4)) >> 4;
|
||||||
@ -859,7 +862,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
if ((_DISPCNT & 0x0400) == 0x0400)
|
if ((_DISPCNT & 0x0400) == 0x0400)
|
||||||
{
|
{
|
||||||
ref UInt16 displayFrameBufferDataRef = ref MemoryMarshal.GetArrayDataReference(_displayFrameBuffer);
|
ref UInt16 displayFrameBufferDataRef = ref MyUnSafeCommon.GetArrayDataReference(_displayFrameBuffer);
|
||||||
|
|
||||||
int pixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
int pixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
||||||
int pixelNumberEnd = pixelNumberBegin + DisplayScreenWidth;
|
int pixelNumberEnd = pixelNumberBegin + DisplayScreenWidth;
|
||||||
@ -886,7 +889,7 @@ namespace Iris.GBA
|
|||||||
{
|
{
|
||||||
if ((_DISPCNT & 0x0400) == 0x0400)
|
if ((_DISPCNT & 0x0400) == 0x0400)
|
||||||
{
|
{
|
||||||
ref UInt16 displayFrameBufferDataRef = ref MemoryMarshal.GetArrayDataReference(_displayFrameBuffer);
|
ref UInt16 displayFrameBufferDataRef = ref MyUnSafeCommon.GetArrayDataReference(_displayFrameBuffer);
|
||||||
|
|
||||||
int pixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
int pixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
||||||
int pixelNumberEnd = pixelNumberBegin + DisplayScreenWidth;
|
int pixelNumberEnd = pixelNumberBegin + DisplayScreenWidth;
|
||||||
@ -921,7 +924,7 @@ namespace Iris.GBA
|
|||||||
|
|
||||||
if (_VCOUNT < VRAM_FrameBufferHeight)
|
if (_VCOUNT < VRAM_FrameBufferHeight)
|
||||||
{
|
{
|
||||||
ref UInt16 displayFrameBufferDataRef = ref MemoryMarshal.GetArrayDataReference(_displayFrameBuffer);
|
ref UInt16 displayFrameBufferDataRef = ref MyUnSafeCommon.GetArrayDataReference(_displayFrameBuffer);
|
||||||
|
|
||||||
int vramPixelNumberBegin = _VCOUNT * VRAM_FrameBufferWidth;
|
int vramPixelNumberBegin = _VCOUNT * VRAM_FrameBufferWidth;
|
||||||
int vramPixelNumberEnd = vramPixelNumberBegin + VRAM_FrameBufferWidth;
|
int vramPixelNumberEnd = vramPixelNumberBegin + VRAM_FrameBufferWidth;
|
||||||
@ -950,7 +953,7 @@ namespace Iris.GBA
|
|||||||
|
|
||||||
private void RenderTextBackground(UInt16 cnt, UInt16 hofs, UInt16 vofs, bool isFirst)
|
private void RenderTextBackground(UInt16 cnt, UInt16 hofs, UInt16 vofs, bool isFirst)
|
||||||
{
|
{
|
||||||
ref UInt16 displayFrameBufferDataRef = ref MemoryMarshal.GetArrayDataReference(_displayFrameBuffer);
|
ref UInt16 displayFrameBufferDataRef = ref MyUnSafeCommon.GetArrayDataReference(_displayFrameBuffer);
|
||||||
|
|
||||||
int displayPixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
int displayPixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
||||||
|
|
||||||
@ -1068,7 +1071,7 @@ namespace Iris.GBA
|
|||||||
|
|
||||||
private void RenderRotationScalingBackground(UInt16 cnt, Int32 x, Int32 y, UInt16 pa, UInt16 pc, bool isFirst)
|
private void RenderRotationScalingBackground(UInt16 cnt, Int32 x, Int32 y, UInt16 pa, UInt16 pc, bool isFirst)
|
||||||
{
|
{
|
||||||
ref UInt16 displayFrameBufferDataRef = ref MemoryMarshal.GetArrayDataReference(_displayFrameBuffer);
|
ref UInt16 displayFrameBufferDataRef = ref MyUnSafeCommon.GetArrayDataReference(_displayFrameBuffer);
|
||||||
|
|
||||||
int displayPixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
int displayPixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
||||||
|
|
||||||
@ -1144,7 +1147,7 @@ namespace Iris.GBA
|
|||||||
|
|
||||||
private void RenderObjects(UInt16 bgPriority)
|
private void RenderObjects(UInt16 bgPriority)
|
||||||
{
|
{
|
||||||
ref UInt16 displayFrameBufferDataRef = ref MemoryMarshal.GetArrayDataReference(_displayFrameBuffer);
|
ref UInt16 displayFrameBufferDataRef = ref MyUnSafeCommon.GetArrayDataReference(_displayFrameBuffer);
|
||||||
|
|
||||||
int displayPixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
int displayPixelNumberBegin = _VCOUNT * DisplayScreenWidth;
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Iris.NDS
|
using System;
|
||||||
|
|
||||||
|
namespace Iris.NDS
|
||||||
{
|
{
|
||||||
public sealed partial class NDS_System
|
public sealed partial class NDS_System
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace Iris.NDS
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Iris.NDS
|
||||||
{
|
{
|
||||||
public sealed partial class NDS_System
|
public sealed partial class NDS_System
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
namespace Iris.NDS
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Iris.NDS
|
||||||
{
|
{
|
||||||
public sealed partial class NDS_System : Common.System
|
public sealed partial class NDS_System : Common.System
|
||||||
{
|
{
|
||||||
|
91
Assets/MyUnSafeCommon.cs
Normal file
91
Assets/MyUnSafeCommon.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
public static class MyUnSafeCommon
|
||||||
|
{
|
||||||
|
public static ref T GetArrayDataReference<T>(T[] array)
|
||||||
|
{
|
||||||
|
if (array == null) throw new ArgumentNullException(nameof(array));
|
||||||
|
if (array.Length == 0) throw new ArgumentException("Array cannot be empty", nameof(array));
|
||||||
|
return ref array[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//public unsafe static ref T GetArrayDataReference<T>(T[] array) where T : struct
|
||||||
|
//{
|
||||||
|
// fixed (T* ptr = array)
|
||||||
|
// {
|
||||||
|
// return ref ArrayElementAsRef<T>(ptr, 0);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public unsafe static ref T ArrayElementAsRef<T>(void* ptr, int index) where T : struct
|
||||||
|
//{
|
||||||
|
// return ref Unity.Collections.LowLevel.Unsafe.UnsafeUtility.ArrayElementAsRef<T>(ptr, index);
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class MyBitOperations
|
||||||
|
{
|
||||||
|
// 计算一个整数的位计数(也称为汉明重量)
|
||||||
|
public static int PopCount(uint value)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
while (value != 0)
|
||||||
|
{
|
||||||
|
value &= value - 1; // 清除最低位的1
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果需要处理long或int等其他类型,可以添加重载
|
||||||
|
public static int PopCount(int value)
|
||||||
|
{
|
||||||
|
return PopCount((uint)value); // 对于int,简单地将其视为无符号的uint来处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于long,你可能需要更复杂的处理或额外的迭代,但基本思想相同
|
||||||
|
public static int PopCount(long value)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
value = value - ((value >> 1) & 0x5555555555555555L); // 每两位一组求和
|
||||||
|
value = (value & 0x3333333333333333L) + ((value >> 2) & 0x3333333333333333L); // 每四位一组求和
|
||||||
|
value = (value + (value >> 4)) & 0x0f0f0f0f0f0f0f0fL; // 每八位一组求和
|
||||||
|
count = (int)((value * 0x0101010101010101L) >> 56); // 计算总和
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向右旋转指定数量的位(等效于BitOperations.RotateRight)
|
||||||
|
public static uint RotateRight(uint value, int count)
|
||||||
|
{
|
||||||
|
// 确保旋转位数在有效范围内(对于uint,0到31)
|
||||||
|
count &= 31;
|
||||||
|
|
||||||
|
// 使用位移和位或操作来实现旋转
|
||||||
|
// 先右移count位
|
||||||
|
uint rightShifted = value >> count;
|
||||||
|
|
||||||
|
// 然后左移(32 - count)位,并将结果与右移的结果进行位或操作
|
||||||
|
// 注意:由于uint是无符号的,所以左移不会导致符号扩展
|
||||||
|
uint leftShifted = (value << (32 - count)) & 0xFFFFFFFF; // 实际上,对于uint,& 0xFFFFFFFF是多余的,但在这里为了清晰性而保留
|
||||||
|
|
||||||
|
// 组合结果
|
||||||
|
return rightShifted | leftShifted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果需要处理ulong,可以添加类似的重载
|
||||||
|
public static ulong RotateRight(ulong value, int count)
|
||||||
|
{
|
||||||
|
// 确保旋转位数在有效范围内(对于ulong,0到63)
|
||||||
|
count &= 63;
|
||||||
|
|
||||||
|
// 使用位移和位或操作来实现旋转
|
||||||
|
// 注意:ulong需要64位操作
|
||||||
|
ulong rightShifted = value >> count;
|
||||||
|
ulong leftShifted = (value << (64 - count)) & 0xFFFFFFFFFFFFFFFF; // 同样,对于ulong,& 0xFFFFFFFFFFFFFFFF是多余的,但保留以增加清晰性
|
||||||
|
|
||||||
|
// 组合结果
|
||||||
|
return rightShifted | leftShifted;
|
||||||
|
}
|
||||||
|
}
|
11
Assets/MyUnSafeCommon.cs.meta
Normal file
11
Assets/MyUnSafeCommon.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d82a940594010314bbfb9de2d3865d64
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/Plugins.meta
Normal file
8
Assets/Plugins.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2a9692e254d34f34aa83151367615810
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/System.Buffers.dll
Normal file
BIN
Assets/Plugins/System.Buffers.dll
Normal file
Binary file not shown.
33
Assets/Plugins/System.Buffers.dll.meta
Normal file
33
Assets/Plugins/System.Buffers.dll.meta
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1cb7f59fb73e5f74cb7d6d787eadcbd1
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/System.Memory.dll
Normal file
BIN
Assets/Plugins/System.Memory.dll
Normal file
Binary file not shown.
33
Assets/Plugins/System.Memory.dll.meta
Normal file
33
Assets/Plugins/System.Memory.dll.meta
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b70ee69b176c61f4eb6db50741d13b0b
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/System.Numerics.Vectors.dll
Normal file
BIN
Assets/Plugins/System.Numerics.Vectors.dll
Normal file
Binary file not shown.
33
Assets/Plugins/System.Numerics.Vectors.dll.meta
Normal file
33
Assets/Plugins/System.Numerics.Vectors.dll.meta
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d58c54bd61da7884f97da0f6bea3e4f5
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll
Normal file
BIN
Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll
Normal file
Binary file not shown.
@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b26dd54a0d93ba0469d1f9307e0e4b43
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user