summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/osx/disassemblyviewer.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/osx/disassemblyviewer.mm')
-rw-r--r--src/osd/modules/debugger/osx/disassemblyviewer.mm293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm
new file mode 100644
index 00000000000..d50bb34262e
--- /dev/null
+++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm
@@ -0,0 +1,293 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+//============================================================
+//
+// disassemblyviewer.m - MacOS X Cocoa debug window handling
+//
+//============================================================
+
+#import "disassemblyviewer.h"
+
+#import "debugconsole.h"
+#import "debugview.h"
+#import "disassemblyview.h"
+
+#include "debugger.h"
+#include "debug/debugcon.h"
+#include "debug/debugcpu.h"
+
+
+@implementation MAMEDisassemblyViewer
+
+- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c {
+ NSScrollView *dasmScroll;
+ NSView *expressionContainer;
+ NSPopUpButton *actionButton;
+ NSRect expressionFrame;
+
+ if (!(self = [super initWithMachine:m title:@"Disassembly" console:c]))
+ return nil;
+ NSRect const contentBounds = [[window contentView] bounds];
+ NSFont *const defaultFont = [[MAMEDebugView class] defaultFontForMachine:m];
+
+ // create the expression field
+ expressionField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)];
+ [expressionField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin)];
+ [expressionField setFont:defaultFont];
+ [expressionField setFocusRingType:NSFocusRingTypeNone];
+ [expressionField setTarget:self];
+ [expressionField setAction:@selector(doExpression:)];
+ [expressionField setDelegate:self];
+ [expressionField sizeToFit];
+
+ // create the subview popup
+ subviewButton = [[NSPopUpButton alloc] initWithFrame:NSOffsetRect(expressionFrame,
+ expressionFrame.size.width,
+ 0)];
+ [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)];
+ [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle];
+ [subviewButton setFocusRingType:NSFocusRingTypeNone];
+ [subviewButton setFont:defaultFont];
+ [subviewButton setTarget:self];
+ [subviewButton setAction:@selector(changeSubview:)];
+ [[subviewButton cell] setArrowPosition:NSPopUpArrowAtBottom];
+ [subviewButton sizeToFit];
+
+ // adjust sizes to make it fit nicely
+ expressionFrame = [expressionField frame];
+ expressionFrame.size.height = MAX(expressionFrame.size.height, [subviewButton frame].size.height);
+ expressionFrame.size.width = (contentBounds.size.width - expressionFrame.size.height) / 2;
+ [expressionField setFrame:expressionFrame];
+ expressionFrame.origin.x = expressionFrame.size.width;
+ expressionFrame.size.width = contentBounds.size.width - expressionFrame.size.height - expressionFrame.origin.x;
+ [subviewButton setFrame:expressionFrame];
+
+ // create a container for the expression field and subview popup
+ expressionFrame = NSMakeRect(expressionFrame.size.height,
+ contentBounds.size.height - expressionFrame.size.height,
+ contentBounds.size.width - expressionFrame.size.height,
+ expressionFrame.size.height);
+ expressionContainer = [[NSView alloc] initWithFrame:expressionFrame];
+ [expressionContainer setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
+ [expressionContainer addSubview:expressionField];
+ [expressionField release];
+ [expressionContainer addSubview:subviewButton];
+ [subviewButton release];
+ [[window contentView] addSubview:expressionContainer];
+ [expressionContainer release];
+
+ // create the disassembly view
+ dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine];
+ [dasmView insertSubviewItemsInMenu:[subviewButton menu] atIndex:0];
+ dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,
+ 0,
+ contentBounds.size.width,
+ expressionFrame.origin.y)];
+ [dasmScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
+ [dasmScroll setHasHorizontalScroller:YES];
+ [dasmScroll setHasVerticalScroller:YES];
+ [dasmScroll setAutohidesScrollers:YES];
+ [dasmScroll setBorderType:NSNoBorder];
+ [dasmScroll setDocumentView:dasmView];
+ [dasmView release];
+ [[window contentView] addSubview:dasmScroll];
+ [dasmScroll release];
+
+ // create the action popup
+ actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0,
+ expressionFrame.origin.y,
+ expressionFrame.size.height,
+ expressionFrame.size.height)];
+ [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)];
+ [actionButton setFont:[NSFont systemFontOfSize:[defaultFont pointSize]]];
+ [dasmView insertActionItemsInMenu:[actionButton menu] atIndex:1];
+ [[window contentView] addSubview:actionButton];
+ [actionButton release];
+
+ // set default state
+ [dasmView selectSubviewForDevice:debug_cpu_get_visible_cpu(*machine)];
+ [dasmView setExpression:@"curpc"];
+ [expressionField setStringValue:@"curpc"];
+ [expressionField selectText:self];
+ [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[dasmView selectedSubviewIndex]]];
+ [window makeFirstResponder:expressionField];
+ [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]];
+
+ // calculate the optimal size for everything
+ NSSize const desired = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize]
+ hasHorizontalScroller:YES
+ hasVerticalScroller:YES
+ borderType:[dasmScroll borderType]];
+ [self cascadeWindowWithDesiredSize:desired forView:dasmScroll];
+
+ // don't forget the result
+ return self;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+
+- (id <MAMEDebugViewExpressionSupport>)documentView {
+ return dasmView;
+}
+
+
+- (IBAction)debugNewMemoryWindow:(id)sender {
+ debug_view_disasm_source const *source = [dasmView source];
+ [console debugNewMemoryWindowForSpace:&source->space()
+ device:&source->device()
+ expression:nil];
+}
+
+
+- (IBAction)debugNewDisassemblyWindow:(id)sender {
+ debug_view_disasm_source const *source = [dasmView source];
+ [console debugNewDisassemblyWindowForSpace:&source->space()
+ device:&source->device()
+ expression:[dasmView expression]];
+}
+
+
+- (BOOL)selectSubviewForDevice:(device_t *)device {
+ BOOL const result = [dasmView selectSubviewForDevice:device];
+ [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[dasmView selectedSubviewIndex]]];
+ [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]];
+ return result;
+}
+
+
+- (BOOL)selectSubviewForSpace:(address_space *)space {
+ BOOL const result = [dasmView selectSubviewForSpace:space];
+ [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[dasmView selectedSubviewIndex]]];
+ [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]];
+ return result;
+}
+
+
+- (IBAction)debugToggleBreakpoint:(id)sender {
+ if ([dasmView cursorVisible])
+ {
+ device_t &device = [dasmView source]->device();
+ offs_t const address = [dasmView selectedAddress];
+ device_debug::breakpoint *bp = [[self class] findBreakpointAtAddress:address forDevice:device];
+
+ // if it doesn't exist, add a new one
+ if (bp == NULL)
+ {
+ UINT32 const bpnum = device.debug()->breakpoint_set(address, NULL, NULL);
+ debug_console_printf(*machine, "Breakpoint %X set\n", bpnum);
+ }
+ else
+ {
+ int const bpnum = bp->index();
+ device.debug()->breakpoint_clear(bpnum);
+ debug_console_printf(*machine, "Breakpoint %X cleared\n", (UINT32)bpnum);
+ }
+
+ // fail to do this and the display doesn't update
+ machine->debug_view().update_all();
+ debugger_refresh_display(*machine);
+ }
+}
+
+
+- (IBAction)debugToggleBreakpointEnable:(id)sender {
+ if ([dasmView cursorVisible])
+ {
+ device_t &device = [dasmView source]->device();
+ offs_t const address = [dasmView selectedAddress];
+ device_debug::breakpoint *bp = [[self class] findBreakpointAtAddress:address forDevice:device];
+ if (bp != NULL)
+ {
+ device.debug()->breakpoint_enable(bp->index(), !bp->enabled());
+ debug_console_printf(*machine,
+ "Breakpoint %X %s\n",
+ (UINT32)bp->index(),
+ bp->enabled() ? "enabled" : "disabled");
+ machine->debug_view().update_all();
+ debugger_refresh_display(*machine);
+ }
+ }
+}
+
+
+- (IBAction)debugRunToCursor:(id)sender {
+ if ([dasmView cursorVisible])
+ [dasmView source]->device().debug()->go([dasmView selectedAddress]);
+}
+
+
+- (IBAction)changeSubview:(id)sender {
+ [dasmView selectSubviewAtIndex:[[sender selectedItem] tag]];
+ [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]];
+}
+
+
+- (BOOL)validateMenuItem:(NSMenuItem *)item {
+ SEL const action = [item action];
+ BOOL const inContextMenu = ([item menu] == [dasmView menu]);
+ BOOL const haveCursor = [dasmView cursorVisible];
+
+ device_debug::breakpoint *breakpoint = NULL;
+ if (haveCursor)
+ {
+ breakpoint = [[self class] findBreakpointAtAddress:[dasmView selectedAddress]
+ forDevice:[dasmView source]->device()];
+ }
+
+ if (action == @selector(debugToggleBreakpoint:))
+ {
+ if (haveCursor)
+ {
+ if (breakpoint != NULL)
+ {
+ if (inContextMenu)
+ [item setTitle:@"Clear Breakpoint"];
+ else
+ [item setTitle:@"Clear Breakpoint at Cursor"];
+ }
+ else
+ {
+ if (inContextMenu)
+ [item setTitle:@"Set Breakpoint"];
+ else
+ [item setTitle:@"Set Breakpoint at Cursor"];
+ }
+ }
+ else
+ {
+ if (inContextMenu)
+ [item setTitle:@"Toggle Breakpoint"];
+ else
+ [item setTitle:@"Toggle Breakpoint at Cursor"];
+ }
+ return haveCursor;
+ }
+ else if (action == @selector(debugToggleBreakpointEnable:))
+ {
+ if ((breakpoint != NULL) && !breakpoint->enabled())
+ {
+ if (inContextMenu)
+ [item setTitle:@"Enable Breakpoint"];
+ else
+ [item setTitle:@"Enable Breakpoint at Cursor"];
+ }
+ else
+ {
+ if (inContextMenu)
+ [item setTitle:@"Disable Breakpoint"];
+ else
+ [item setTitle:@"Disable Breakpoint at Cursor"];
+ }
+ return breakpoint != NULL;
+ }
+ else
+ {
+ return YES;
+ }
+}
+
+@end