Skip to content

Commit

Permalink
feature: Create/Delete Address Breakpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Maximilien Noal <noal.maximilien@gmail.com>
  • Loading branch information
maximilien-noal committed Oct 1, 2024
1 parent e7e60df commit 3e58dd8
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/Spice86/Messages/StatusMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Spice86.Messages;

public record StatusMessage(DateTime Time, object Origin, string Message);
3 changes: 3 additions & 0 deletions src/Spice86/Models/Debugging/CpuInstructionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ namespace Spice86.Models.Debugging;

using Iced.Intel;

using Spice86.Core.Emulator.VM.Breakpoint;

public partial class CpuInstructionInfo : ObservableObject {
[ObservableProperty] private string? _stringRepresentation;
[ObservableProperty] private bool _hasBreakpoint;
[ObservableProperty] private BreakPoint? _breakPoint;
[ObservableProperty] private bool _isCsIp;
[ObservableProperty] private uint _address;
[ObservableProperty] private string? _segmentedAddress;
Expand Down
4 changes: 4 additions & 0 deletions src/Spice86/ViewModels/DebugWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public partial class DebugWindowViewModel : ViewModelBase,
[ObservableProperty]
private CfgCpuViewModel _cfgCpuViewModel;

[ObservableProperty]
private StatusMessageViewModel _statusMessageViewModel;

private readonly IPauseHandler _pauseHandler;

public DebugWindowViewModel(IInstructionExecutor cpu, State cpuState, IMemory memory, Midi externalMidiDevice,
Expand All @@ -65,6 +68,7 @@ public DebugWindowViewModel(IInstructionExecutor cpu, State cpuState, IMemory me
messenger.Register<RemoveViewModelMessage<DisassemblyViewModel>>(this);
messenger.Register<RemoveViewModelMessage<MemoryViewModel>>(this);
_messenger = messenger;
StatusMessageViewModel = new(_messenger);
_pauseHandler = pauseHandler;
IsPaused = pauseHandler.IsPaused;
pauseHandler.Pausing += () => uiDispatcher.Post(() => IsPaused = true);
Expand Down
25 changes: 18 additions & 7 deletions src/Spice86/ViewModels/DisassemblyViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,30 @@ private List<CpuInstructionInfo> DecodeInstructions(State state, IMemory memory,
return instructions;
}

/// <summary>
/// Handles a breakpoint being hit.
/// </summary>
/// <param name="breakPoint">The <see cref="BreakPoint"/> object representing the breakpoint that was hit.</param>
private void OnBreakPointReached(BreakPoint breakPoint) =>
_pauseHandler.RequestPause($"breakpoint {breakPoint.BreakPointType} hit");
private void OnBreakPointReached(BreakPoint breakPoint) {
string message = $"{breakPoint.BreakPointType} breakpoint was reached.";
_pauseHandler.RequestPause(message);
_messenger.Send(new StatusMessage(DateTime.Now, this, message));
}

[RelayCommand]
private void RemoveAddressBreakpointHere() {
if (SelectedInstruction?.BreakPoint is null) {
return;
}
_emulatorBreakpointsManager.ToggleBreakPoint(SelectedInstruction.BreakPoint, false);
SelectedInstruction.BreakPoint = null;
SelectedInstruction.HasBreakpoint = false;
}

[RelayCommand]
private void CreateAddressBreakpointHere() {
if (SelectedInstruction is null) {
return;
}
AddressBreakPoint breakPoint = new(BreakPointType.EXECUTION, SelectedInstruction.Address, OnBreakPointReached, false);
AddressBreakPoint breakPoint = new(BreakPointType.EXECUTION, SelectedInstruction.Address, OnBreakPointReached,
isRemovedOnTrigger: false);
SelectedInstruction.BreakPoint = breakPoint;
_emulatorBreakpointsManager.ToggleBreakPoint(breakPoint, true);
SelectedInstruction.HasBreakpoint = true;
}
Expand Down
25 changes: 25 additions & 0 deletions src/Spice86/ViewModels/StatusMessageViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Spice86.ViewModels;

using Avalonia.Collections;

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;

using Spice86.Messages;

public partial class StatusMessageViewModel : ViewModelBase, IRecipient<StatusMessage> {
[ObservableProperty]
private AvaloniaList<StatusMessage> _previousMessages = new();

[ObservableProperty]
private StatusMessage? _message;

public StatusMessageViewModel(IMessenger messenger) => messenger.Register(this);

public void Receive(StatusMessage message) {
PreviousMessages.Add(message);
Message = message;
if (PreviousMessages.Count > 50)
PreviousMessages.RemoveAt(0);
}
}
4 changes: 3 additions & 1 deletion src/Spice86/Views/DebugWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
xmlns:local="clr-namespace:Spice86"
xmlns:fluent="clr-namespace:FluentIcons.Avalonia.Fluent;assembly=FluentIcons.Avalonia.Fluent"
xmlns:controls="clr-namespace:Spice86.Controls"
xmlns:views="clr-namespace:Spice86.Views"
x:CompileBindings="True"
x:DataType="vm:DebugWindowViewModel"
WindowStartupLocation="CenterOwner"
Expand All @@ -26,7 +27,7 @@
<Window.DataTemplates>
<local:ViewLocator />
</Window.DataTemplates>
<Grid RowDefinitions="Auto,*">
<Grid RowDefinitions="Auto,*,Auto">
<StackPanel Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Top" Orientation="Horizontal">
<Button
Margin="5,0,0,0"
Expand Down Expand Up @@ -80,5 +81,6 @@
</TabControl>
</controls:HotKeyTabItem>
</TabControl>
<views:StatusMessageView Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" DataContext="{Binding StatusMessageViewModel}" />
</Grid>
</Window>
3 changes: 2 additions & 1 deletion src/Spice86/Views/DisassemblyView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Copy line" Command="{Binding CopyLineCommand}" />
<MenuItem Header="Address BreakPoint here" Command="{Binding CreateAddressBreakpointHereCommand}" />
<MenuItem Header="Create address BreakPoint here" IsVisible="{Binding !SelectedInstruction.HasBreakpoint, FallbackValue=False}" Command="{Binding CreateAddressBreakpointHereCommand}" />
<MenuItem Header="Remove address BreakPoint here" IsVisible="{Binding SelectedInstruction.HasBreakpoint, FallbackValue=False}" Command="{Binding RemoveAddressBreakpointHereCommand}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
Expand Down
1 change: 0 additions & 1 deletion src/Spice86/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ namespace Spice86.Views;
using Avalonia.Controls;
using Avalonia.Input;

using Spice86.Shared.Interfaces;
using Spice86.ViewModels;

using System;
Expand Down
29 changes: 29 additions & 0 deletions src/Spice86/Views/StatusMessageView.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Spice86.ViewModels"
xmlns:controls="clr-namespace:Spice86.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Spice86.Views.StatusMessageView"
x:DataType="viewModels:StatusMessageViewModel">
<controls:StatusBar>
<controls:StatusBarItem>
<StackPanel Orientation="Horizontal">
<ComboBox SelectedItem="{Binding Message, Mode=TwoWay}" ItemsSource="{Binding PreviousMessages}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Time}" />
<Run Text=": " />
<Run Text="{Binding Origin}" />
<Run Text=" - " />
<Run Text="{Binding Message}" />
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</controls:StatusBarItem>
</controls:StatusBar>
</UserControl>
11 changes: 11 additions & 0 deletions src/Spice86/Views/StatusMessageView.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace Spice86.Views;

public partial class StatusMessageView : UserControl {
public StatusMessageView() {
InitializeComponent();
}
}

0 comments on commit 3e58dd8

Please sign in to comment.