Automatic code walking with timer. Improved memory interface.
This commit is contained in:
parent
65ba2ce0d5
commit
971a01d968
5 changed files with 295 additions and 92 deletions
|
@ -27,6 +27,16 @@
|
|||
<Path Data="F1 M 38,22.1667L 58.5832,37.6043L 58.5832,38.7918L 38,53.8333L 38,22.1667 Z M 33.25,22.1667L 33.25,53.8333L 26.9167,53.8333L 26.9167,22.1667L 33.25,22.1667 Z "/>
|
||||
</Button>
|
||||
<Separator />
|
||||
<Button ToolTip="Start" Command="{Binding Path=StartCommand}">
|
||||
<Path Data="F1 M 30.0833,22.1667L 50.6665,37.6043L 50.6665,38.7918L 30.0833,53.8333L 30.0833,22.1667 Z "/>
|
||||
</Button>
|
||||
<Button ToolTip="Start Slow" Command="{Binding Path=StartSlowCommand}">
|
||||
<Path Data="F1 M 44.3333,45.9167L 53.8333,54.625L 44.3333,63.3333L 44.3333,45.9167 Z M 52.25,39.5833C 52.25,42.2298 51.6007,44.7245 50.4528,46.917L 47.3572,44.2084C 47.762,43.2521 48.0451,42.2317 48.187,41.1667L 44.3333,41.1667L 44.3333,38L 48.187,38C 47.4819,32.7082 43.2918,28.5181 38,27.813L 38,31.6667L 34.8333,31.6667L 34.8333,27.813C 29.5415,28.5181 25.3513,32.7082 24.6463,38L 28.5,38.0001L 28.5,41.1667L 24.6463,41.1667C 25.3513,46.4585 29.5415,50.6487 34.8333,51.3537L 34.8333,47.5L 38,47.5L 38,51.3537C 39.1115,51.2056 40.5703,50.9038 41.5625,50.4702L 41.5625,54.6918C 40.063,55.1628 38.0716,55.4167 36.4167,55.4167C 27.6721,55.4167 20.5833,48.3279 20.5833,39.5833C 20.5833,31.3732 26.8322,24.6226 34.8333,23.8282L 34.8333,22.1667L 30.0833,22.1667L 30.0833,17.4167L 42.75,17.4167L 42.75,22.1667L 38,22.1667L 38,23.8282C 41.1844,24.1444 44.0913,25.404 46.4371,27.3237L 47.5796,26.1813L 45.3404,23.9421L 48.6991,20.5833L 55.4167,27.3009L 52.0579,30.6596L 49.8187,28.4204L 48.6763,29.5629C 50.9099,32.2923 52.25,35.7813 52.25,39.5833 Z M 36.4166,36.4167C 38.1655,36.4167 39.5833,37.8345 39.5833,39.5834C 39.5833,41.3323 38.1655,42.75 36.4166,42.75L 30.0833,47.5L 33.2499,39.5834C 33.2499,37.8345 34.6677,36.4167 36.4166,36.4167 Z "/>
|
||||
</Button>
|
||||
<Button ToolTip="Stop" Command="{Binding Path=StopCommand}">
|
||||
<Path Data="F1 M 26.9167,23.75L 33.25,23.75L 33.25,52.25L 26.9167,52.25L 26.9167,23.75 Z M 42.75,23.75L 49.0833,23.75L 49.0833,52.25L 42.75,52.25L 42.75,23.75 Z "/>
|
||||
</Button>
|
||||
<Separator />
|
||||
<Button ToolTip="Reset" Command="{Binding Path=ResetCommand}">
|
||||
<Path Data="F1 M 52,24L 52,52L 47,52L 47,43C 47,38.0295 42.9706,34 38,34L 37,34L 37,30L 30.25,36.5L 37,43L 37,39L 38,39C 40.2091,39 42,40.7909 42,43L 42,52L 24,52L 24,24L 52,24 Z "/>
|
||||
</Button>
|
||||
|
@ -35,91 +45,106 @@
|
|||
</Button>
|
||||
</ToolBar>
|
||||
<DockPanel>
|
||||
<Grid DockPanel.Dock="Right" Width="200">
|
||||
<TabControl>
|
||||
<TabItem Header="CPU State">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TabControl DockPanel.Dock="Right" Width="235">
|
||||
<TabItem Header="CPU State">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.Resources>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="Stack Pointer" />
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=StackPointer, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="Base Pointer" />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=BasePointer, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="Code Pointer" />
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=CodePointer, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="Flags" />
|
||||
<Grid Grid.Row="3" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.Resources>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="Stack Pointer" />
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=StackPointer, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="Base Pointer" />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=BasePointer, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="Code Pointer" />
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=CodePointer, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="Flags" />
|
||||
<Grid Grid.Row="3" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox Grid.Column="0" IsChecked="{Binding Path=FlagZ}" Content="Z"/>
|
||||
<CheckBox Grid.Column="1" IsChecked="{Binding Path=FlagN}" Content="N"/>
|
||||
</Grid>
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="0" Content="Stack:" />
|
||||
<ScrollViewer Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2">
|
||||
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding Path=Stack}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<DataTemplate.Resources>
|
||||
<Style TargetType="TextBlock" >
|
||||
<Setter Property="Margin" Value="4,2" />
|
||||
</Style>
|
||||
</DataTemplate.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
|
||||
<ColumnDefinition Width="1" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding Path=Index}" />
|
||||
<Border Grid.Column="1" Background="Black" />
|
||||
<TextBox Grid.Column="2" HorizontalContentAlignment="Right" Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<CheckBox Grid.Column="0" IsChecked="{Binding Path=FlagZ}" Content="Z"/>
|
||||
<CheckBox Grid.Column="1" IsChecked="{Binding Path=FlagN}" Content="N"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Output">
|
||||
<TextBox VerticalContentAlignment="Top" Text="{Binding Path=Output}"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="0" Content="Stack:" />
|
||||
<ScrollViewer Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2">
|
||||
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding Path=Stack}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<DataTemplate.Resources>
|
||||
<Style TargetType="TextBlock" >
|
||||
<Setter Property="Margin" Value="4,2" />
|
||||
</Style>
|
||||
</DataTemplate.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
|
||||
<ColumnDefinition Width="1" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding Path=Index}" />
|
||||
<Border Grid.Column="1" Background="Black" />
|
||||
<TextBox Grid.Column="2" HorizontalContentAlignment="Right" Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Output">
|
||||
<TextBox VerticalContentAlignment="Top" Text="{Binding Path=Output}"/>
|
||||
</TabItem>
|
||||
<TabItem Header="Memory" Grid.IsSharedSizeScope="True">
|
||||
<DockPanel>
|
||||
<DataGrid ItemsSource="{Binding Path=Memory}" AutoGenerateColumns="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="+0" Binding="{Binding Path=D0}" />
|
||||
<DataGridTextColumn Header="+1" Binding="{Binding Path=D1}" />
|
||||
<DataGridTextColumn Header="+2" Binding="{Binding Path=D2}" />
|
||||
<DataGridTextColumn Header="+3" Binding="{Binding Path=D3}" />
|
||||
<DataGridTextColumn Header="+4" Binding="{Binding Path=D4}" />
|
||||
<DataGridTextColumn Header="+5" Binding="{Binding Path=D5}" />
|
||||
<DataGridTextColumn Header="+6" Binding="{Binding Path=D6}" />
|
||||
<DataGridTextColumn Header="+7" Binding="{Binding Path=D7}" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<TabControl>
|
||||
<TabItem Header="Assembler">
|
||||
<local:CodeEditor
|
||||
x:Name="codeEditor"
|
||||
ShowLineNumbers="True"
|
||||
FontFamily="Consolas"
|
||||
Code="{Binding Path=Source, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</TabItem>
|
||||
<TabItem Header="Code">
|
||||
|
|
|
@ -5,6 +5,8 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using SuperVM.Assembler;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
|
||||
namespace SuperVM.VisualDebugger
|
||||
{
|
||||
|
@ -14,31 +16,69 @@ namespace SuperVM.VisualDebugger
|
|||
|
||||
private Process process;
|
||||
private VMAssembly assembly;
|
||||
private Memory memory;
|
||||
private readonly Timer timer;
|
||||
|
||||
public VirtualMachineModel()
|
||||
{
|
||||
this.memory = new Memory(1024);
|
||||
this.memory.LoadString("Hallo Welt!", 33);
|
||||
|
||||
this.process = new Process()
|
||||
{
|
||||
Memory = new Memory(1024),
|
||||
Memory = this.memory,
|
||||
};
|
||||
this.process.SysCall += Process_SysCall;
|
||||
|
||||
this.Source = "\tpush 12\n\tpush 30\n\tadd\n\tdrop";
|
||||
|
||||
this.Recompile();
|
||||
|
||||
this.Reset();
|
||||
this.Source = "\tcpget\n\tjmp @main\n\tsyscall[ci: 0]\n; Here your code!\nmain:";
|
||||
|
||||
this.StepCommand = new RelayCommand(this.Step);
|
||||
this.ResetCommand = new RelayCommand(this.Reset);
|
||||
this.RecompileCommand = new RelayCommand(this.Recompile);
|
||||
this.StartCommand = new RelayCommand(this.Start);
|
||||
this.StartSlowCommand = new RelayCommand(this.StartSlow);
|
||||
this.StopCommand = new RelayCommand(this.Stop);
|
||||
|
||||
this.timer = new Timer();
|
||||
this.timer.Elapsed += Timer_Elapsed;
|
||||
|
||||
this.Recompile();
|
||||
|
||||
this.Reset();
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
this.Step();
|
||||
}
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
this.timer.Stop();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
this.timer.Interval = 10.0;
|
||||
this.timer.Start();
|
||||
}
|
||||
|
||||
private void StartSlow()
|
||||
{
|
||||
this.timer.Interval = 100.0;
|
||||
this.timer.Start();
|
||||
}
|
||||
|
||||
private void Process_SysCall(object sender, Process.CommandExecutionEnvironment e)
|
||||
{
|
||||
switch(e.Additional)
|
||||
switch (e.Additional)
|
||||
{
|
||||
case 1:
|
||||
case 0: // Stop execution
|
||||
{
|
||||
this.Stop();
|
||||
break;
|
||||
}
|
||||
case 1: // Print char
|
||||
{
|
||||
this.Output += Encoding.ASCII.GetString(new[] { (byte)e.Input0 });
|
||||
this.OnPropertyChanged(nameof(Output));
|
||||
|
@ -49,22 +89,37 @@ namespace SuperVM.VisualDebugger
|
|||
|
||||
public void Recompile()
|
||||
{
|
||||
this.assembly = Assembler.Assembler.Assemble(this.Source);
|
||||
|
||||
this.process.Module = assembly.CreateModule();
|
||||
|
||||
this.Stop();
|
||||
try
|
||||
{
|
||||
this.assembly = Assembler.Assembler.Assemble(this.Source);
|
||||
this.process.Module = assembly.CreateModule();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "SuperVM Assembler", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
this.Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
this.timer.Stop();
|
||||
this.process.Reset();
|
||||
this.OnVmChanged();
|
||||
}
|
||||
|
||||
public void Step()
|
||||
{
|
||||
this.process.Step();
|
||||
try
|
||||
{
|
||||
this.process.Step();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Stop();
|
||||
MessageBox.Show(ex.Message, "SuperVM", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
this.OnVmChanged();
|
||||
}
|
||||
|
||||
|
@ -121,15 +176,21 @@ namespace SuperVM.VisualDebugger
|
|||
.Select(i => new StackItem(i, this.process))
|
||||
.ToArray();
|
||||
|
||||
public MemoryProxy[] Memory => Enumerable
|
||||
.Range(0, this.memory.Size / 8)
|
||||
.Select(i => new MemoryProxy(this.memory, (uint)(8 * i)))
|
||||
.ToArray();
|
||||
|
||||
public string Source { get; set; }
|
||||
|
||||
public string Output { get; set; }
|
||||
|
||||
public ICommand StepCommand { get; private set; }
|
||||
|
||||
public ICommand ResetCommand { get; private set; }
|
||||
|
||||
public ICommand RecompileCommand { get; private set; }
|
||||
public ICommand StartCommand { get; private set; }
|
||||
public ICommand StopCommand { get; private set; }
|
||||
public ICommand StartSlowCommand { get; private set; }
|
||||
}
|
||||
|
||||
public class StackItem
|
||||
|
@ -150,4 +211,78 @@ namespace SuperVM.VisualDebugger
|
|||
set { this.process.Stack[this.Index] = (uint)value; }
|
||||
}
|
||||
}
|
||||
|
||||
public class MemoryProxy : INotifyPropertyChanged
|
||||
{
|
||||
private readonly Memory mem;
|
||||
private readonly uint offset;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public MemoryProxy(Memory mem, uint offset)
|
||||
{
|
||||
this.mem = mem;
|
||||
this.offset = offset;
|
||||
|
||||
this.mem.Changed += Mem_Changed;
|
||||
}
|
||||
|
||||
private void Mem_Changed(object sender, MemoryChangedEventArgs e)
|
||||
{
|
||||
var upper = this.offset + 7;
|
||||
if (e.Address >= this.offset && (e.Address + e.Length) <= upper)
|
||||
{
|
||||
var idx = (e.Address - offset) % 8;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("D" + idx));
|
||||
}
|
||||
}
|
||||
|
||||
public byte D0
|
||||
{
|
||||
get { return this.mem[this.offset + 0]; }
|
||||
set { this.mem[this.offset + 0] = value; }
|
||||
}
|
||||
|
||||
public byte D1
|
||||
{
|
||||
get { return this.mem[this.offset + 1]; }
|
||||
set { this.mem[this.offset + 1] = value; }
|
||||
}
|
||||
|
||||
public byte D2
|
||||
{
|
||||
get { return this.mem[this.offset + 2]; }
|
||||
set { this.mem[this.offset + 2] = value; }
|
||||
}
|
||||
|
||||
public byte D3
|
||||
{
|
||||
get { return this.mem[this.offset + 3]; }
|
||||
set { this.mem[this.offset + 3] = value; }
|
||||
}
|
||||
|
||||
public byte D4
|
||||
{
|
||||
get { return this.mem[this.offset + 4]; }
|
||||
set { this.mem[this.offset + 4] = value; }
|
||||
}
|
||||
|
||||
public byte D5
|
||||
{
|
||||
get { return this.mem[this.offset + 5]; }
|
||||
set { this.mem[this.offset + 5] = value; }
|
||||
}
|
||||
|
||||
public byte D6
|
||||
{
|
||||
get { return this.mem[this.offset + 6]; }
|
||||
set { this.mem[this.offset + 6] = value; }
|
||||
}
|
||||
|
||||
public byte D7
|
||||
{
|
||||
get { return this.mem[this.offset + 7]; }
|
||||
set { this.mem[this.offset + 7] = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace SuperVM
|
||||
{
|
||||
|
@ -6,6 +7,8 @@ namespace SuperVM
|
|||
{
|
||||
private readonly byte[] data;
|
||||
|
||||
public event EventHandler<MemoryChangedEventArgs> Changed;
|
||||
|
||||
public Memory(int size)
|
||||
{
|
||||
this.data = new byte[size];
|
||||
|
@ -29,6 +32,7 @@ namespace SuperVM
|
|||
public void SetUInt8(uint address, byte value)
|
||||
{
|
||||
this.data[address] = value;
|
||||
this.Changed?.Invoke(this, new MemoryChangedEventArgs(address, 1));
|
||||
}
|
||||
|
||||
public void SetUInt16(uint address, UInt16 value)
|
||||
|
@ -37,6 +41,7 @@ namespace SuperVM
|
|||
BitConverter.GetBytes(value), 0,
|
||||
this.data, address,
|
||||
2);
|
||||
this.Changed?.Invoke(this, new MemoryChangedEventArgs(address, 2));
|
||||
}
|
||||
|
||||
public void SetUint32(uint address, UInt32 value)
|
||||
|
@ -45,12 +50,27 @@ namespace SuperVM
|
|||
BitConverter.GetBytes(value), 0,
|
||||
this.data, address,
|
||||
4);
|
||||
this.Changed?.Invoke(this, new MemoryChangedEventArgs(address, 4));
|
||||
}
|
||||
|
||||
public void LoadString(string text, int start)
|
||||
{
|
||||
var bits = Encoding.ASCII.GetBytes(text);
|
||||
for (int i = 0; i < bits.Length; i++)
|
||||
{
|
||||
this.data[start + i] = bits[i];
|
||||
}
|
||||
this.Changed?.Invoke(this, new MemoryChangedEventArgs((uint)start, (uint)bits.Length));
|
||||
}
|
||||
|
||||
public byte this[uint address]
|
||||
{
|
||||
get { return this.data[address]; }
|
||||
set { this.data[address] = value; }
|
||||
set
|
||||
{
|
||||
this.data[address] = value;
|
||||
this.Changed?.Invoke(this, new MemoryChangedEventArgs(address, 1));
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Raw => this.data;
|
||||
|
|
22
SuperVM/MemoryChangedEventArgs.cs
Normal file
22
SuperVM/MemoryChangedEventArgs.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace SuperVM
|
||||
{
|
||||
public sealed class MemoryChangedEventArgs : EventArgs
|
||||
{
|
||||
public MemoryChangedEventArgs(uint address) :
|
||||
this(address, 1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MemoryChangedEventArgs(uint address, uint length)
|
||||
{
|
||||
this.Address = address;
|
||||
this.Length = length;
|
||||
}
|
||||
|
||||
public uint Address { get; private set; }
|
||||
public uint Length { get; private set; }
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@
|
|||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="Instruction.cs" />
|
||||
<Compile Include="Memory.cs" />
|
||||
<Compile Include="MemoryChangedEventArgs.cs" />
|
||||
<Compile Include="Module.cs" />
|
||||
<Compile Include="Process.Commands.cs" />
|
||||
<Compile Include="Process.cs" />
|
||||
|
|
Loading…
Reference in a new issue