summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/osx/disassemblyview.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/osx/disassemblyview.m')
-rw-r--r--src/osd/modules/debugger/osx/disassemblyview.m370
1 files changed, 370 insertions, 0 deletions
diff --git a/src/osd/modules/debugger/osx/disassemblyview.m b/src/osd/modules/debugger/osx/disassemblyview.m
new file mode 100644
index 00000000000..2592aeefdfc
--- /dev/null
+++ b/src/osd/modules/debugger/osx/disassemblyview.m
@@ -0,0 +1,370 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+//============================================================
+//
+// debugosxdisassemblyview.m - MacOS X Cocoa debug window handling
+//
+// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team.
+// Visit http://mamedev.org for licensing and usage restrictions.
+//
+//============================================================
+
+#import "disassemblyview.h"
+
+#include "debug/debugcon.h"
+#include "debug/debugcpu.h"
+#include "debug/debugvw.h"
+#include "debug/dvdisasm.h"
+
+
+@implementation MAMEDisassemblyView
+
+- (device_debug::breakpoint *)findBreakpointAtAddress:(offs_t)address inAddressSpace:(address_space &)space {
+ device_debug *cpuinfo = space.device().debug();
+ device_debug::breakpoint *bp;
+ for (bp = cpuinfo->breakpoint_first(); (bp != NULL) && (address != bp->address()); bp = bp->next()) {}
+ return bp;
+}
+
+- (void)createContextMenu {
+ NSMenu *contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Disassembly"];
+ NSMenuItem *item;
+
+ item = [contextMenu addItemWithTitle:@"Toggle Breakpoint"
+ action:@selector(debugToggleBreakpoint:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]];
+ [item setKeyEquivalentModifierMask:0];
+ [item setTarget:self];
+
+ item = [contextMenu addItemWithTitle:@"Disable Breakpoint"
+ action:@selector(debugToggleBreakpointEnable:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]];
+ [item setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [item setTarget:self];
+
+ [contextMenu addItem:[NSMenuItem separatorItem]];
+
+ item = [contextMenu addItemWithTitle:@"Run to Cursor"
+ action:@selector(debugRunToCursor:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]];
+ [item setKeyEquivalentModifierMask:0];
+ [item setTarget:self];
+
+ [contextMenu addItem:[NSMenuItem separatorItem]];
+
+ item = [contextMenu addItemWithTitle:@"Raw Opcodes"
+ action:@selector(showRightColumn:)
+ keyEquivalent:@"r"];
+ [item setTarget:self];
+ [item setTag:DASM_RIGHTCOL_RAW];
+
+ item = [contextMenu addItemWithTitle:@"Encrypted Opcodes"
+ action:@selector(showRightColumn:)
+ keyEquivalent:@"e"];
+ [item setTarget:self];
+ [item setTag:DASM_RIGHTCOL_ENCRYPTED];
+
+ item = [contextMenu addItemWithTitle:@"Comments"
+ action:@selector(showRightColumn:)
+ keyEquivalent:@"n"];
+ [item setTarget:self];
+ [item setTag:DASM_RIGHTCOL_COMMENTS];
+
+ [self setMenu:contextMenu];
+ [contextMenu release];
+}
+
+
+- (id)initWithFrame:(NSRect)f machine:(running_machine &)m useConsole:(BOOL)uc {
+ if (!(self = [super initWithFrame:f type:DVT_DISASSEMBLY machine:m]))
+ return nil;
+ useConsole = uc;
+ [self createContextMenu];
+ return self;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+
+- (BOOL)validateMenuItem:(NSMenuItem *)item {
+ SEL action = [item action];
+ BOOL inContextMenu = ([item menu] == [self menu]);
+ BOOL haveCursor = NO, isCurrent = NO;
+ device_debug::breakpoint *breakpoint = NULL;
+
+ if (view->cursor_visible()) {
+ if (debug_cpu_get_visible_cpu(*machine) == view->source()->device()) {
+ isCurrent = YES;
+ if (!useConsole || isCurrent) {
+ offs_t address = downcast<debug_view_disasm *>(view)->selected_address();
+ haveCursor = YES;
+ breakpoint = [self findBreakpointAtAddress:address inAddressSpace:downcast<const debug_view_disasm_source *>(view->source())->space()];
+ }
+ }
+ }
+
+ 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 if (action == @selector(debugRunToCursor:)) {
+ return isCurrent;
+ } else if (action == @selector(showRightColumn:)) {
+ [item setState:((downcast<debug_view_disasm *>(view)->right_column() == [item tag]) ? NSOnState : NSOffState)];
+ return YES;
+ } else {
+ return YES;
+ }
+}
+
+
+- (NSSize)maximumFrameSize {
+ debug_view_xy max;
+ device_t *curcpu = debug_cpu_get_visible_cpu(*machine);
+ const debug_view_source *source = view->source_for_device(curcpu);
+
+ max.x = max.y = 0;
+ for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next())
+ {
+ debug_view_xy current;
+ view->set_source(*source);
+ current = view->total_size();
+ if (current.x > max.x)
+ max.x = current.x;
+ if (current.y > max.y)
+ max.y = current.y;
+ }
+ view->set_source(*source);
+ return NSMakeSize(max.x * fontWidth, max.y * fontHeight);
+}
+
+
+- (NSString *)selectedSubviewName {
+ const debug_view_source *source = view->source();
+ if (source != NULL)
+ return [NSString stringWithUTF8String:source->name()];
+ else
+ return @"";
+}
+
+
+- (int)selectedSubviewIndex {
+ const debug_view_source *source = view->source();
+ if (source != NULL)
+ return view->source_list().indexof(*source);
+ else
+ return -1;
+}
+
+
+- (void)selectSubviewAtIndex:(int)index {
+ const int selected = view->source_list().indexof(*view->source());
+ if (selected != index) {
+ view->set_source(*view->source_list().find(index));
+ if ([[self window] firstResponder] != self)
+ view->set_cursor_visible(false);
+ }
+}
+
+
+- (void)selectSubviewForCPU:(device_t *)device {
+ const debug_view_source *selected = view->source();
+ const debug_view_source *source = view->source_for_device(device);
+ if ( selected != source ) {
+ view->set_source(*source);
+ if ([[self window] firstResponder] != self)
+ view->set_cursor_visible(false);
+ }
+}
+
+
+- (NSString *)expression {
+ return [NSString stringWithUTF8String:downcast<debug_view_disasm *>(view)->expression()];
+}
+
+
+- (void)setExpression:(NSString *)exp {
+ downcast<debug_view_disasm *>(view)->set_expression([exp UTF8String]);
+}
+
+
+- (IBAction)debugToggleBreakpoint:(id)sender {
+ if (view->cursor_visible()) {
+ address_space &space = downcast<const debug_view_disasm_source *>(view->source())->space();
+ if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &space.device())) {
+ offs_t address = downcast<debug_view_disasm *>(view)->selected_address();
+ device_debug::breakpoint *bp = [self findBreakpointAtAddress:address inAddressSpace:space];
+
+ // if it doesn't exist, add a new one
+ if (useConsole) {
+ NSString *command;
+ if (bp == NULL)
+ command = [NSString stringWithFormat:@"bpset %lX", (unsigned long)address];
+ else
+ command = [NSString stringWithFormat:@"bpclear %X", (unsigned)bp->index()];
+ debug_console_execute_command(*machine, [command UTF8String], 1);
+ } else {
+ if (bp == NULL)
+ space.device().debug()->breakpoint_set(address, NULL, NULL);
+ else
+ space.device().debug()->breakpoint_clear(bp->index());
+ }
+ }
+ }
+}
+
+
+- (IBAction)debugToggleBreakpointEnable:(id)sender {
+ if (view->cursor_visible()) {
+ address_space &space = downcast<const debug_view_disasm_source *>(view->source())->space();
+ if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &space.device())) {
+ offs_t address = downcast<debug_view_disasm *>(view)->selected_address();
+ device_debug::breakpoint *bp = [self findBreakpointAtAddress:address inAddressSpace:space];
+
+ if (bp != NULL) {
+ NSString *command;
+ if (useConsole) {
+ if (bp->enabled())
+ command = [NSString stringWithFormat:@"bpdisable %X", (unsigned)bp->index()];
+ else
+ command = [NSString stringWithFormat:@"bpenable %X", (unsigned)bp->index()];
+ debug_console_execute_command(*machine, [command UTF8String], 1);
+ } else {
+ space.device().debug()->breakpoint_enable(bp->index(), !bp->enabled());
+ }
+ }
+ }
+ }
+}
+
+
+- (IBAction)debugRunToCursor:(id)sender {
+ if (view->cursor_visible()) {
+ address_space &space = downcast<const debug_view_disasm_source *>(view->source())->space();
+ if (debug_cpu_get_visible_cpu(*machine) == &space.device()) {
+ offs_t address = downcast<debug_view_disasm *>(view)->selected_address();
+ if (useConsole) {
+ NSString *command = [NSString stringWithFormat:@"go 0x%lX", (unsigned long)address];
+ debug_console_execute_command(*machine, [command UTF8String], 1);
+ } else {
+ debug_cpu_get_visible_cpu(*machine)->debug()->go(address);
+ }
+ }
+ }
+}
+
+
+- (IBAction)showRightColumn:(id)sender {
+ downcast<debug_view_disasm *>(view)->set_right_column((disasm_right_column) [sender tag]);
+}
+
+
+- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index {
+ {
+ NSMenuItem *breakItem = [menu insertItemWithTitle:@"Toggle Breakpoint at Cursor"
+ action:@selector(debugToggleBreakpoint:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]
+ atIndex:index++];
+ [breakItem setKeyEquivalentModifierMask:0];
+ [breakItem setTarget:self];
+ }
+ {
+ NSMenuItem *disableItem = [menu insertItemWithTitle:@"Disable Breakpoint at Cursor"
+ action:@selector(debugToggleBreakpointEnable:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]
+ atIndex:index++];
+ [disableItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [disableItem setAlternate:YES];
+ [disableItem setTarget:self];
+ }
+ {
+ NSMenu *runMenu = [[menu itemWithTitle:@"Run"] submenu];
+ NSMenuItem *runItem;
+ if (runMenu != nil) {
+ runItem = [runMenu addItemWithTitle:@"to Cursor"
+ action:@selector(debugRunToCursor:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]];
+ } else {
+ runItem = [menu insertItemWithTitle:@"Run to Cursor"
+ action:@selector(debugRunToCursor:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]
+ atIndex:index++];
+ }
+ [runItem setKeyEquivalentModifierMask:0];
+ [runItem setTarget:self];
+ }
+ [menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
+ {
+ NSMenuItem *rawItem = [menu insertItemWithTitle:@"Show Raw Opcodes"
+ action:@selector(showRightColumn:)
+ keyEquivalent:@"r"
+ atIndex:index++];
+ [rawItem setTarget:self];
+ [rawItem setTag:DASM_RIGHTCOL_RAW];
+ }
+ {
+ NSMenuItem *encItem = [menu insertItemWithTitle:@"Show Encrypted Opcodes"
+ action:@selector(showRightColumn:)
+ keyEquivalent:@"e"
+ atIndex:index++];
+ [encItem setTarget:self];
+ [encItem setTag:DASM_RIGHTCOL_ENCRYPTED];
+ }
+ {
+ NSMenuItem *commentsItem = [menu insertItemWithTitle:@"Show Comments"
+ action:@selector(showRightColumn:)
+ keyEquivalent:@"n"
+ atIndex:index++];
+ [commentsItem setTarget:self];
+ [commentsItem setTag:DASM_RIGHTCOL_COMMENTS];
+ }
+ if (index < [menu numberOfItems])
+ [menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
+}
+
+
+- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index {
+ for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next())
+ {
+ [[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()]
+ action:NULL
+ keyEquivalent:@""
+ atIndex:index++] setTag:view->source_list().indexof(*source)];
+ }
+ if (index < [menu numberOfItems])
+ [menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
+}
+
+@end