mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
Merge pull request #135 from cuavas/master
Another round of debugger improvements
This commit is contained in:
commit
1d8c6fb922
@ -12,10 +12,9 @@
|
||||
|
||||
// TODO:
|
||||
// * Automatic scrolling for console and log views
|
||||
// * Keyboard shortcuts in error log and devices windows
|
||||
// * Keyboard shortcuts in error log and device windows
|
||||
// * Don't accept keyboard input while the game is running
|
||||
// * Interior focus rings - standard/exterior focus rings look really ugly here
|
||||
// * Improve automatic window sizing - it isn't working all that well
|
||||
// * Updates causing debug views' widths to change are sometimes obscured by the scroll views' opaque backgrounds
|
||||
// * Scroll views with content narrower than clipping area are flaky under Tiger - nothing I can do about this
|
||||
|
||||
|
@ -37,6 +37,10 @@
|
||||
|
||||
- (IBAction)doCommand:(id)sender;
|
||||
|
||||
- (IBAction)debugToggleBreakpoint:(id)sender;
|
||||
- (IBAction)debugToggleBreakpointEnable:(id)sender;
|
||||
- (IBAction)debugRunToCursor:(id)sender;
|
||||
|
||||
- (IBAction)debugNewMemoryWindow:(id)sender;
|
||||
- (IBAction)debugNewDisassemblyWindow:(id)sender;
|
||||
- (IBAction)debugNewErrorLogWindow:(id)sender;
|
||||
@ -45,6 +49,7 @@
|
||||
|
||||
- (void)debugNewMemoryWindowForSpace:(address_space *)space device:(device_t *)device expression:(NSString *)expression;
|
||||
- (void)debugNewDisassemblyWindowForSpace:(address_space *)space device:(device_t *)device expression:(NSString *)expression;
|
||||
- (void)debugNewInfoWindowForDevice:(device_t &)device;
|
||||
|
||||
- (void)showDebugger:(NSNotification *)notification;
|
||||
- (void)auxiliaryWindowWillClose:(NSNotification *)notification;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#import "debugcommandhistory.h"
|
||||
#import "consoleview.h"
|
||||
#import "debugview.h"
|
||||
#import "deviceinfoviewer.h"
|
||||
#import "devicesviewer.h"
|
||||
#import "disassemblyview.h"
|
||||
#import "disassemblyviewer.h"
|
||||
@ -53,9 +54,7 @@
|
||||
[regView release];
|
||||
|
||||
// create the disassembly view
|
||||
dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
|
||||
machine:*machine
|
||||
useConsole:YES];
|
||||
dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine];
|
||||
[dasmView setExpression:@"curpc"];
|
||||
dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
|
||||
[dasmScroll setDrawsBackground:YES];
|
||||
@ -215,10 +214,13 @@
|
||||
|
||||
- (IBAction)doCommand:(id)sender {
|
||||
NSString *command = [sender stringValue];
|
||||
if ([command length] == 0) {
|
||||
if ([command length] == 0)
|
||||
{
|
||||
debug_cpu_get_visible_cpu(*machine)->debug()->single_step();
|
||||
[history reset];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_console_execute_command(*machine, [command UTF8String], 1);
|
||||
[history add:command];
|
||||
[history edit];
|
||||
@ -227,6 +229,54 @@
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)debugToggleBreakpoint:(id)sender {
|
||||
device_t &device = [dasmView source]->device();
|
||||
if ([dasmView cursorVisible] && (debug_cpu_get_visible_cpu(*machine) == &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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)debugToggleBreakpointEnable:(id)sender {
|
||||
device_t &device = [dasmView source]->device();
|
||||
if ([dasmView cursorVisible] && (debug_cpu_get_visible_cpu(*machine) == &device))
|
||||
{
|
||||
device_debug::breakpoint *bp = [[self class] findBreakpointAtAddress:[dasmView selectedAddress]
|
||||
forDevice:device];
|
||||
if (bp != NULL)
|
||||
{
|
||||
NSString *command;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)debugRunToCursor:(id)sender {
|
||||
device_t &device = [dasmView source]->device();
|
||||
if ([dasmView cursorVisible] && (debug_cpu_get_visible_cpu(*machine) == &device))
|
||||
{
|
||||
NSString *command = [NSString stringWithFormat:@"go 0x%lX", (unsigned long)[dasmView selectedAddress]];
|
||||
debug_console_execute_command(*machine, [command UTF8String], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)debugNewMemoryWindow:(id)sender {
|
||||
MAMEMemoryViewer *win = [[MAMEMemoryViewer alloc] initWithMachine:*machine console:self];
|
||||
[auxiliaryWindows addObject:win];
|
||||
@ -301,6 +351,16 @@
|
||||
}
|
||||
|
||||
|
||||
- (void)debugNewInfoWindowForDevice:(device_t &)device {
|
||||
MAMEDeviceInfoViewer *win = [[MAMEDeviceInfoViewer alloc] initWithDevice:device
|
||||
machine:*machine
|
||||
console:self];
|
||||
[auxiliaryWindows addObject:win];
|
||||
[win release];
|
||||
[win activate];
|
||||
}
|
||||
|
||||
|
||||
- (void)showDebugger:(NSNotification *)notification {
|
||||
device_t *device = (device_t * )[[[notification userInfo] objectForKey:@"MAMEDebugDevice"] pointerValue];
|
||||
if (&device->machine() == machine)
|
||||
@ -419,4 +479,74 @@
|
||||
[[[sender subviews] objectAtIndex:1] setFrame:second];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item {
|
||||
SEL const action = [item action];
|
||||
BOOL const inContextMenu = ([item menu] == [dasmView menu]);
|
||||
BOOL const haveCursor = [dasmView cursorVisible];
|
||||
BOOL const isCurrent = (debug_cpu_get_visible_cpu(*machine) == &[dasmView source]->device());
|
||||
|
||||
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 && isCurrent;
|
||||
}
|
||||
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) && isCurrent;
|
||||
}
|
||||
else if (action == @selector(debugRunToCursor:))
|
||||
{
|
||||
return isCurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -44,9 +44,18 @@
|
||||
- (NSFont *)font;
|
||||
- (void)setFont:(NSFont *)f;
|
||||
|
||||
- (BOOL)cursorSupported;
|
||||
- (BOOL)cursorVisible;
|
||||
- (debug_view_xy)cursorPosition;
|
||||
|
||||
- (IBAction)copyVisible:(id)sender;
|
||||
- (IBAction)paste:(id)sender;
|
||||
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification;
|
||||
- (void)windowDidResignKey:(NSNotification *)notification;
|
||||
|
||||
- (void)addContextMenuItemsToMenu:(NSMenu *)menu;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -224,6 +224,11 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
|
||||
[self setFont:[[self class] defaultFont]];
|
||||
|
||||
NSMenu *contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Context"];
|
||||
[self addContextMenuItemsToMenu:contextMenu];
|
||||
[self setMenu:contextMenu];
|
||||
[contextMenu release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -264,8 +269,8 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
|
||||
- (NSSize)maximumFrameSize {
|
||||
debug_view_xy const max = view->total_size();
|
||||
return NSMakeSize((max.x * fontWidth) + (2 * [textContainer lineFragmentPadding]),
|
||||
max.y * fontHeight);
|
||||
return NSMakeSize(ceil((max.x * fontWidth) + (2 * [textContainer lineFragmentPadding])),
|
||||
ceil(max.y * fontHeight));
|
||||
}
|
||||
|
||||
|
||||
@ -286,6 +291,90 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)cursorSupported {
|
||||
return view->cursor_supported();
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)cursorVisible {
|
||||
return view->cursor_visible();
|
||||
}
|
||||
|
||||
|
||||
- (debug_view_xy)cursorPosition {
|
||||
return view->cursor_position();
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)copyVisible:(id)sender {
|
||||
debug_view_xy const size = view->visible_size();
|
||||
debug_view_char const *data = view->viewdata();
|
||||
if (!data)
|
||||
{
|
||||
NSBeep();
|
||||
return;
|
||||
}
|
||||
|
||||
for (UINT32 row = 0; row < size.y; row++, data += size.x)
|
||||
{
|
||||
int attr = -1;
|
||||
NSUInteger start = [text length], length = 0;
|
||||
for (UINT32 col = 0; col < size.x; col++)
|
||||
{
|
||||
[[text mutableString] appendFormat:@"%c", data[col].byte];
|
||||
if ((start < length) && (attr != (data[col].attrib & ~DCA_SELECTED)))
|
||||
{
|
||||
NSRange const run = NSMakeRange(start, length - start);
|
||||
[text addAttribute:NSForegroundColorAttributeName
|
||||
value:[self foregroundForAttribute:attr]
|
||||
range:run];
|
||||
[text addAttribute:NSBackgroundColorAttributeName
|
||||
value:[self backgroundForAttribute:attr]
|
||||
range:run];
|
||||
start = length;
|
||||
}
|
||||
attr = data[col].attrib & ~DCA_SELECTED;
|
||||
length = [text length];
|
||||
}
|
||||
if (start < length)
|
||||
{
|
||||
NSRange const run = NSMakeRange(start, length - start);
|
||||
[text addAttribute:NSForegroundColorAttributeName
|
||||
value:[self foregroundForAttribute:attr]
|
||||
range:run];
|
||||
[text addAttribute:NSBackgroundColorAttributeName
|
||||
value:[self backgroundForAttribute:attr]
|
||||
range:run];
|
||||
}
|
||||
[[text mutableString] appendString:@"\n"];
|
||||
}
|
||||
|
||||
NSRange const run = NSMakeRange(0, [text length]);
|
||||
[text addAttribute:NSFontAttributeName value:font range:run];
|
||||
NSPasteboard *const board = [NSPasteboard generalPasteboard];
|
||||
[board declareTypes:[NSArray arrayWithObject:NSRTFPboardType] owner:nil];
|
||||
[board setData:[text RTFFromRange:run documentAttributes:nil] forType:NSRTFPboardType];
|
||||
[text deleteCharactersInRange:run];
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)paste:(id)sender {
|
||||
NSPasteboard *const board = [NSPasteboard generalPasteboard];
|
||||
NSString *const avail = [board availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]];
|
||||
if (avail == nil)
|
||||
{
|
||||
NSBeep();
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *const data = [[board stringForType:avail] dataUsingEncoding:NSASCIIStringEncoding
|
||||
allowLossyConversion:YES];
|
||||
char const *const bytes = (char const *)[data bytes];
|
||||
for (NSUInteger i = 0, l = [data length]; i < l; i++)
|
||||
view->process_char(bytes[i]);
|
||||
}
|
||||
|
||||
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
||||
NSWindow *win = [notification object];
|
||||
if ((win == [self window]) && ([win firstResponder] == self) && view->cursor_supported())
|
||||
@ -300,6 +389,21 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
}
|
||||
|
||||
|
||||
- (void)addContextMenuItemsToMenu:(NSMenu *)menu {
|
||||
NSMenuItem *item;
|
||||
|
||||
item = [menu addItemWithTitle:@"Copy Visible"
|
||||
action:@selector(copyVisible:)
|
||||
keyEquivalent:@""];
|
||||
[item setTarget:self];
|
||||
|
||||
item = [menu addItemWithTitle:@"Paste"
|
||||
action:@selector(paste:)
|
||||
keyEquivalent:@""];
|
||||
[item setTarget:self];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)acceptsFirstResponder {
|
||||
return view->cursor_supported();
|
||||
}
|
||||
@ -432,7 +536,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
- (void)mouseDown:(NSEvent *)event {
|
||||
NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||
NSUInteger const modifiers = [event modifierFlags];
|
||||
view->process_click((modifiers & NSCommandKeyMask) ? DCK_RIGHT_CLICK
|
||||
view->process_click(((modifiers & NSCommandKeyMask) && [[self window] isMainWindow]) ? DCK_RIGHT_CLICK
|
||||
: (modifiers & NSAlternateKeyMask) ? DCK_MIDDLE_CLICK
|
||||
: DCK_LEFT_CLICK,
|
||||
[self convertLocation:location]);
|
||||
@ -440,6 +544,21 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
}
|
||||
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)event {
|
||||
[self autoscroll:event];
|
||||
NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||
NSUInteger const modifiers = [event modifierFlags];
|
||||
if (view->cursor_supported()
|
||||
&& !(modifiers & NSAlternateKeyMask)
|
||||
&& (!(modifiers & NSCommandKeyMask) || ![[self window] isMainWindow]))
|
||||
{
|
||||
view->set_cursor_position([self convertLocation:location]);
|
||||
view->set_cursor_visible(true);
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)rightMouseDown:(NSEvent *)event {
|
||||
NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||
if (view->cursor_supported())
|
||||
@ -556,4 +675,19 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item {
|
||||
SEL action = [item action];
|
||||
|
||||
if (action == @selector(paste:))
|
||||
{
|
||||
NSPasteboard *const board = [NSPasteboard generalPasteboard];
|
||||
return [board availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]] != nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -12,6 +12,7 @@
|
||||
#import "debugosx.h"
|
||||
|
||||
#include "emu.h"
|
||||
#include "debug/debugcpu.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@ -34,6 +35,8 @@ extern NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification;
|
||||
+ (void)addCommonActionItems:(NSMenu *)menu;
|
||||
+ (NSPopUpButton *)newActionButtonWithFrame:(NSRect)frame;
|
||||
|
||||
+ (device_debug::breakpoint *)findBreakpointAtAddress:(offs_t)address forDevice:(device_t &)device;
|
||||
|
||||
- (id)initWithMachine:(running_machine &)m title:(NSString *)t;
|
||||
|
||||
- (void)activate;
|
||||
|
@ -14,8 +14,6 @@
|
||||
#import "debugcommandhistory.h"
|
||||
#import "debugview.h"
|
||||
|
||||
#include "debug/debugcpu.h"
|
||||
|
||||
|
||||
//============================================================
|
||||
// NOTIFICATIONS
|
||||
@ -128,6 +126,14 @@ NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryD
|
||||
}
|
||||
|
||||
|
||||
+ (device_debug::breakpoint *)findBreakpointAtAddress:(offs_t)address forDevice:(device_t &)device {
|
||||
device_debug *const cpuinfo = device.debug();
|
||||
device_debug::breakpoint *bp = cpuinfo->breakpoint_first();
|
||||
while ((bp != NULL) && (address != bp->address())) bp = bp->next();
|
||||
return bp;
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithMachine:(running_machine &)m title:(NSString *)t {
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
@ -421,4 +427,4 @@ NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryD
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
30
src/osd/modules/debugger/osx/deviceinfoviewer.h
Normal file
30
src/osd/modules/debugger/osx/deviceinfoviewer.h
Normal file
@ -0,0 +1,30 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
//============================================================
|
||||
//
|
||||
// deviceinfoviewer.h - 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 "debugosx.h"
|
||||
|
||||
#import "debugwindowhandler.h"
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@class MAMEDebugConsole, MAMEDeviceWrapper;
|
||||
|
||||
@interface MAMEDeviceInfoViewer : MAMEAuxiliaryDebugWindowHandler
|
||||
{
|
||||
device_t *device;
|
||||
}
|
||||
|
||||
- (id)initWithDevice:(device_t &)d machine:(running_machine &)m console:(MAMEDebugConsole *)c;
|
||||
|
||||
@end
|
236
src/osd/modules/debugger/osx/deviceinfoviewer.m
Normal file
236
src/osd/modules/debugger/osx/deviceinfoviewer.m
Normal file
@ -0,0 +1,236 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
//============================================================
|
||||
//
|
||||
// deviceinfoviewer.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 "deviceinfoviewer.h"
|
||||
|
||||
|
||||
@interface MAMEDeviceInfoView : NSView
|
||||
{
|
||||
CGFloat minWidth;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame;
|
||||
|
||||
- (void)setMinWidth:(CGFloat)aWidth;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MAMEDeviceInfoView
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame {
|
||||
if (!(self = [super initWithFrame:frame]))
|
||||
return nil;
|
||||
minWidth = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setMinWidth:(CGFloat)aWidth {
|
||||
minWidth = aWidth;
|
||||
}
|
||||
|
||||
- (BOOL)isFlipped {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize {
|
||||
NSSize const newBoundsSize = [[self superview] bounds].size;
|
||||
[self setFrameSize:NSMakeSize(MAX(newBoundsSize.width, minWidth), [self frame].size.height)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MAMEDeviceInfoViewer
|
||||
|
||||
- (NSTextField *)makeLabel:(NSString *)text {
|
||||
NSTextField *const result = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 14)];
|
||||
[result setAutoresizingMask:(NSViewMaxYMargin | NSViewMaxXMargin)];
|
||||
[[result cell] setControlSize:NSSmallControlSize];
|
||||
[result setEditable:NO];
|
||||
[result setSelectable:NO];
|
||||
[result setBezeled:NO];
|
||||
[result setBordered:NO];
|
||||
[result setDrawsBackground:NO];
|
||||
[result setAlignment:NSRightTextAlignment];
|
||||
[result setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
|
||||
[result setStringValue:text];
|
||||
[result sizeToFit];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (NSTextField *)makeField:(NSString *)text {
|
||||
NSTextField *const result = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 14)];
|
||||
[result setAutoresizingMask:(NSViewWidthSizable | NSViewMaxYMargin)];
|
||||
[[result cell] setControlSize:NSSmallControlSize];
|
||||
[result setEditable:NO];
|
||||
[result setSelectable:YES];
|
||||
[result setBezeled:NO];
|
||||
[result setBordered:NO];
|
||||
[result setDrawsBackground:NO];
|
||||
[result setAlignment:NSLeftTextAlignment];
|
||||
[result setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
|
||||
[result setStringValue:text];
|
||||
[result sizeToFit];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (NSBox *)makeBox:(NSString *)t toFit:(NSView *)v {
|
||||
NSBox *const result = [[NSBox alloc] initWithFrame:NSMakeRect(0, 0, [v frame].size.width - 34, 32)];
|
||||
[result setAutoresizingMask:(NSViewWidthSizable | NSViewMaxYMargin)];
|
||||
[result setTitle:t];
|
||||
[result setBoxType:NSBoxPrimary];
|
||||
[result setBorderType:NSLineBorder];
|
||||
[result setContentViewMargins:NSMakeSize(0, 0)];
|
||||
[result setAutoresizesSubviews:YES];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (void)addLabel:(NSString *)l withWidth:(CGFloat)w andField:(NSString *)f toView:(NSView *)v {
|
||||
NSTextField *const label = [self makeLabel:l];
|
||||
NSTextField *const field = [self makeField:f];
|
||||
CGFloat const height = MAX([label frame].size.height, [field frame].size.height);
|
||||
NSSize space = [v bounds].size;
|
||||
space.width = MAX(space.width, [field frame].size.width + w + 52);
|
||||
space.height += height + 8;
|
||||
[label setFrame:NSMakeRect(25, space.height - height - 20, w, height)];
|
||||
[field setFrame:NSMakeRect(w + 27, space.height - height - 20, space.width - w - 52, height)];
|
||||
[v setFrameSize:space];
|
||||
[v addSubview:label];
|
||||
[v addSubview:field];
|
||||
[label release];
|
||||
[field release];
|
||||
}
|
||||
|
||||
|
||||
- (void)addField:(NSString *)f toBox:(NSBox *)b {
|
||||
NSTextField *const field = [self makeField:f];
|
||||
[field setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
|
||||
NSSize space = [b frame].size;
|
||||
space.width = MAX(space.width, [field frame].size.width + 32);
|
||||
space.height += [field frame].size.height + 8;
|
||||
[field setFrame:NSMakeRect(15, 14, space.width - 32, [field frame].size.height)];
|
||||
[b setFrameSize:space];
|
||||
[[b contentView] addSubview:field];
|
||||
[field release];
|
||||
}
|
||||
|
||||
|
||||
- (void)addBox:(NSBox *)b toView:(NSView *)v {
|
||||
NSSize space = [v frame].size;
|
||||
space.width = MAX(space.width, [b frame].size.width + 34);
|
||||
space.height += [b frame].size.height + 4;
|
||||
[b setFrameOrigin:NSMakePoint(17, space.height - [b frame].size.height - 16)];
|
||||
[v setFrameSize:space];
|
||||
[v addSubview:b];
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithDevice:(device_t &)d machine:(running_machine &)m console:(MAMEDebugConsole *)c {
|
||||
MAMEDeviceInfoView *contentView;
|
||||
NSScrollView *contentScroll;
|
||||
|
||||
if (!(self = [super initWithMachine:m
|
||||
title:[NSString stringWithFormat:@"Device %s", d.tag()]
|
||||
console:c]))
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
device = &d;
|
||||
|
||||
// Create a view to hold everything
|
||||
contentView = [[MAMEDeviceInfoView alloc] initWithFrame:NSMakeRect(0, 0, 320, 32)];
|
||||
[contentView setAutoresizesSubviews:YES];
|
||||
|
||||
// add the stuff that's always present
|
||||
[self addLabel:@"Tag:"
|
||||
withWidth:100
|
||||
andField:[NSString stringWithUTF8String:device->tag()]
|
||||
toView:contentView];
|
||||
[self addLabel:@"Name:"
|
||||
withWidth:100
|
||||
andField:[NSString stringWithUTF8String:device->name()]
|
||||
toView:contentView];
|
||||
[self addLabel:@"Shortname:"
|
||||
withWidth:100
|
||||
andField:[NSString stringWithUTF8String:device->shortname()]
|
||||
toView:contentView];
|
||||
|
||||
// add interfaces if present
|
||||
device_interface *interface = device->first_interface();
|
||||
if (interface != NULL)
|
||||
{
|
||||
NSBox *const interfacesBox = [self makeBox:@"Interfaces" toFit:contentView];
|
||||
while (interface != NULL)
|
||||
{
|
||||
[self addField:[NSString stringWithUTF8String:interface->interface_type()]
|
||||
toBox:interfacesBox];
|
||||
interface = interface->interface_next();
|
||||
}
|
||||
[self addBox:interfacesBox toView:contentView];
|
||||
[interfacesBox release];
|
||||
}
|
||||
|
||||
// add memory maps if present
|
||||
device_memory_interface *memory;
|
||||
if (device->interface(memory))
|
||||
{
|
||||
NSBox *memoryBox = nil;
|
||||
for (address_spacenum i = AS_0; i < ADDRESS_SPACES; i++)
|
||||
{
|
||||
if (memory->has_space(i))
|
||||
{
|
||||
if (memoryBox == nil)
|
||||
memoryBox = [self makeBox:@"Memory maps" toFit:contentView];
|
||||
[self addField:[NSString stringWithUTF8String:memory->space_config(i)->name()]
|
||||
toBox:memoryBox];
|
||||
}
|
||||
}
|
||||
if (memoryBox != nil)
|
||||
{
|
||||
[self addBox:memoryBox toView:contentView];
|
||||
[memoryBox release];
|
||||
}
|
||||
}
|
||||
|
||||
// lock minimum content size
|
||||
[contentView setMinWidth:[contentView frame].size.width];
|
||||
[contentView setAutoresizingMask:NSViewWidthSizable];
|
||||
|
||||
// create a scroll view for holding everything
|
||||
NSSize desired = [NSScrollView frameSizeForContentSize:[contentView frame].size
|
||||
hasHorizontalScroller:YES
|
||||
hasVerticalScroller:YES
|
||||
borderType:NSNoBorder];
|
||||
[window setContentSize:desired];
|
||||
contentScroll = [[NSScrollView alloc] initWithFrame:[[window contentView] bounds]];
|
||||
[contentScroll setDrawsBackground:NO];
|
||||
[contentScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||
[contentScroll setHasHorizontalScroller:YES];
|
||||
[contentScroll setHasVerticalScroller:YES];
|
||||
[contentScroll setAutohidesScrollers:YES];
|
||||
[contentScroll setBorderType:NSNoBorder];
|
||||
[contentScroll setDocumentView:contentView];
|
||||
[contentView release];
|
||||
[[window contentView] addSubview:contentScroll];
|
||||
[contentScroll release];
|
||||
|
||||
// calculate the optimal size for everything
|
||||
[self cascadeWindowWithDesiredSize:[contentScroll frame].size forView:contentScroll];
|
||||
|
||||
// don't forget the result
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
@ -28,4 +28,6 @@
|
||||
|
||||
- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c;
|
||||
|
||||
- (IBAction)showDeviceDetail:(id)sender;
|
||||
|
||||
@end
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#import "devicesviewer.h"
|
||||
|
||||
#import "debugconsole.h"
|
||||
|
||||
|
||||
@interface MAMEDeviceWrapper : NSObject
|
||||
{
|
||||
@ -138,9 +140,9 @@
|
||||
[nameColumn release];
|
||||
[devicesView setOutlineTableColumn:tagColumn];
|
||||
[devicesView setAutoresizesOutlineColumn:YES];
|
||||
[devicesView setDoubleAction:@selector(showDeviceDetail:)];
|
||||
[devicesView setDataSource:self];
|
||||
devicesScroll = [[NSScrollView alloc] initWithFrame:[[window contentView] bounds]];
|
||||
[devicesScroll setDrawsBackground:YES];
|
||||
[devicesScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||
[devicesScroll setHasHorizontalScroller:YES];
|
||||
[devicesScroll setHasVerticalScroller:YES];
|
||||
@ -175,6 +177,11 @@
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)showDeviceDetail:(id)sender {
|
||||
[console debugNewInfoWindowForDevice:[(MAMEDeviceWrapper *)[sender itemAtRow:[sender clickedRow]] device]];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
|
||||
return [(MAMEDeviceWrapper *)item children] > 0;
|
||||
}
|
||||
|
@ -21,10 +21,9 @@
|
||||
|
||||
@interface MAMEDisassemblyView : MAMEDebugView <MAMEDebugViewSubviewSupport, MAMEDebugViewExpressionSupport>
|
||||
{
|
||||
BOOL useConsole;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m useConsole:(BOOL)uc;
|
||||
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m;
|
||||
|
||||
- (NSSize)maximumFrameSize;
|
||||
|
||||
@ -38,10 +37,7 @@
|
||||
- (void)setExpression:(NSString *)exp;
|
||||
|
||||
- (debug_view_disasm_source const *)source;
|
||||
|
||||
- (IBAction)debugToggleBreakpoint:(id)sender;
|
||||
- (IBAction)debugToggleBreakpointEnable:(id)sender;
|
||||
- (IBAction)debugRunToCursor:(id)sender;
|
||||
- (offs_t)selectedAddress;
|
||||
|
||||
- (IBAction)showRightColumn:(id)sender;
|
||||
|
||||
|
@ -11,75 +11,14 @@
|
||||
|
||||
#import "disassemblyview.h"
|
||||
|
||||
#include "debugger.h"
|
||||
#include "debug/debugcon.h"
|
||||
#include "debug/debugcpu.h"
|
||||
#include "debug/debugvw.h"
|
||||
|
||||
|
||||
@implementation MAMEDisassemblyView
|
||||
|
||||
- (device_debug::breakpoint *)findBreakpointAtAddress:(offs_t)address forDevice:(device_t &)device {
|
||||
device_debug *cpuinfo = 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 {
|
||||
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m {
|
||||
if (!(self = [super initWithFrame:f type:DVT_DISASSEMBLY machine:m]))
|
||||
return nil;
|
||||
useConsole = uc;
|
||||
[self createContextMenu];
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -91,95 +30,79 @@
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item {
|
||||
SEL const action = [item action];
|
||||
BOOL const inContextMenu = ([item menu] == [self menu]);
|
||||
BOOL haveCursor = view->cursor_visible();
|
||||
BOOL const isCurrent = (debug_cpu_get_visible_cpu(*machine) == view->source()->device());
|
||||
|
||||
device_debug::breakpoint *breakpoint = NULL;
|
||||
if (haveCursor)
|
||||
{
|
||||
offs_t const address = downcast<debug_view_disasm *>(view)->selected_address();
|
||||
breakpoint = [self findBreakpointAtAddress:address forDevice:[self 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 && (!useConsole || isCurrent);
|
||||
}
|
||||
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) && (!useConsole || isCurrent);
|
||||
}
|
||||
else if (action == @selector(debugRunToCursor:))
|
||||
{
|
||||
return !useConsole || isCurrent;
|
||||
}
|
||||
else if (action == @selector(showRightColumn:))
|
||||
if (action == @selector(showRightColumn:))
|
||||
{
|
||||
[item setState:((downcast<debug_view_disasm *>(view)->right_column() == [item tag]) ? NSOnState : NSOffState)];
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
return YES;
|
||||
return [super validateMenuItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (NSSize)maximumFrameSize {
|
||||
debug_view_xy max(0, 0);
|
||||
const debug_view_source *source = view->source();
|
||||
|
||||
for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next())
|
||||
debug_view_source const *source = view->source();
|
||||
for (debug_view_source const *source = view->first_source(); 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;
|
||||
debug_view_xy const current = view->total_size();
|
||||
max.x = MAX(max.x, current.x);
|
||||
max.y = MAX(max.y, current.y);
|
||||
}
|
||||
view->set_source(*source);
|
||||
return NSMakeSize(max.x * fontWidth, max.y * fontHeight);
|
||||
return NSMakeSize(ceil((max.x * fontWidth) + (2 * [textContainer lineFragmentPadding])),
|
||||
ceil(max.y * fontHeight));
|
||||
}
|
||||
|
||||
|
||||
- (void)addContextMenuItemsToMenu:(NSMenu *)menu {
|
||||
NSMenuItem *item;
|
||||
|
||||
[super addContextMenuItemsToMenu:menu];
|
||||
|
||||
if ([menu numberOfItems] > 0)
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
item = [menu addItemWithTitle:@"Toggle Breakpoint"
|
||||
action:@selector(debugToggleBreakpoint:)
|
||||
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]];
|
||||
[item setKeyEquivalentModifierMask:0];
|
||||
|
||||
item = [menu addItemWithTitle:@"Disable Breakpoint"
|
||||
action:@selector(debugToggleBreakpointEnable:)
|
||||
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]];
|
||||
[item setKeyEquivalentModifierMask:NSShiftKeyMask];
|
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
item = [menu addItemWithTitle:@"Run to Cursor"
|
||||
action:@selector(debugRunToCursor:)
|
||||
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]];
|
||||
[item setKeyEquivalentModifierMask:0];
|
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
item = [menu addItemWithTitle:@"Raw Opcodes"
|
||||
action:@selector(showRightColumn:)
|
||||
keyEquivalent:@"r"];
|
||||
[item setTarget:self];
|
||||
[item setTag:DASM_RIGHTCOL_RAW];
|
||||
|
||||
item = [menu addItemWithTitle:@"Encrypted Opcodes"
|
||||
action:@selector(showRightColumn:)
|
||||
keyEquivalent:@"e"];
|
||||
[item setTarget:self];
|
||||
[item setTag:DASM_RIGHTCOL_ENCRYPTED];
|
||||
|
||||
item = [menu addItemWithTitle:@"Comments"
|
||||
action:@selector(showRightColumn:)
|
||||
keyEquivalent:@"n"];
|
||||
[item setTarget:self];
|
||||
[item setTag:DASM_RIGHTCOL_COMMENTS];
|
||||
}
|
||||
|
||||
|
||||
@ -267,101 +190,8 @@
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)debugToggleBreakpoint:(id)sender {
|
||||
if (view->cursor_visible())
|
||||
{
|
||||
device_t &device = [self source]->device();
|
||||
if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &device))
|
||||
{
|
||||
offs_t const address = downcast<debug_view_disasm *>(view)->selected_address();
|
||||
device_debug::breakpoint *bp = [self findBreakpointAtAddress:address forDevice:device];
|
||||
|
||||
// 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)
|
||||
{
|
||||
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 (view->cursor_visible())
|
||||
{
|
||||
device_t &device = [self source]->device();
|
||||
if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &device))
|
||||
{
|
||||
offs_t const address = downcast<debug_view_disasm *>(view)->selected_address();
|
||||
device_debug::breakpoint *bp = [self findBreakpointAtAddress:address forDevice:device];
|
||||
if (bp != NULL)
|
||||
{
|
||||
if (useConsole)
|
||||
{
|
||||
NSString *command;
|
||||
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
|
||||
{
|
||||
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 (view->cursor_visible())
|
||||
{
|
||||
device_t &device = [self source]->device();
|
||||
if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &device))
|
||||
{
|
||||
offs_t const 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
|
||||
{
|
||||
device.debug()->go(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
- (offs_t)selectedAddress {
|
||||
return downcast<debug_view_disasm *>(view)->selected_address();
|
||||
}
|
||||
|
||||
|
||||
@ -371,64 +201,55 @@
|
||||
|
||||
|
||||
- (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];
|
||||
NSMenuItem *breakItem = [menu insertItemWithTitle:@"Toggle Breakpoint at Cursor"
|
||||
action:@selector(debugToggleBreakpoint:)
|
||||
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]
|
||||
atIndex:index++];
|
||||
[breakItem setKeyEquivalentModifierMask:0];
|
||||
|
||||
NSMenuItem *disableItem = [menu insertItemWithTitle:@"Disable Breakpoint at Cursor"
|
||||
action:@selector(debugToggleBreakpointEnable:)
|
||||
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]
|
||||
atIndex:index++];
|
||||
[disableItem setKeyEquivalentModifierMask:NSShiftKeyMask];
|
||||
|
||||
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];
|
||||
|
||||
[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];
|
||||
}
|
||||
|
||||
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++];
|
||||
}
|
||||
|
@ -31,6 +31,10 @@
|
||||
- (BOOL)selectSubviewForDevice:(device_t *)device;
|
||||
- (BOOL)selectSubviewForSpace:(address_space *)space;
|
||||
|
||||
- (IBAction)debugToggleBreakpoint:(id)sender;
|
||||
- (IBAction)debugToggleBreakpointEnable:(id)sender;
|
||||
- (IBAction)debugRunToCursor:(id)sender;
|
||||
|
||||
- (IBAction)changeSubview:(id)sender;
|
||||
|
||||
@end
|
||||
|
@ -15,6 +15,8 @@
|
||||
#import "debugview.h"
|
||||
#import "disassemblyview.h"
|
||||
|
||||
#include "debugger.h"
|
||||
#include "debug/debugcon.h"
|
||||
#include "debug/debugcpu.h"
|
||||
|
||||
|
||||
@ -69,9 +71,7 @@
|
||||
[expressionContainer release];
|
||||
|
||||
// create the disassembly view
|
||||
dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
|
||||
machine:*machine
|
||||
useConsole:NO];
|
||||
dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine];
|
||||
[dasmView insertSubviewItemsInMenu:[subviewButton menu] atIndex:0];
|
||||
dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,
|
||||
0,
|
||||
@ -161,9 +161,127 @@
|
||||
}
|
||||
|
||||
|
||||
- (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
|
||||
|
@ -18,16 +18,8 @@
|
||||
@implementation MAMEMemoryView
|
||||
|
||||
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m {
|
||||
NSMenu *contextMenu;
|
||||
|
||||
if (!(self = [super initWithFrame:f type:DVT_MEMORY machine:m]))
|
||||
return nil;
|
||||
|
||||
contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Memory"];
|
||||
[self insertActionItemsInMenu:contextMenu atIndex:0];
|
||||
[self setMenu:contextMenu];
|
||||
[contextMenu release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -42,39 +34,47 @@
|
||||
NSInteger tag = [item tag];
|
||||
debug_view_memory *memview = downcast<debug_view_memory *>(view);
|
||||
|
||||
if (action == @selector(showChunkSize:)) {
|
||||
if (action == @selector(showChunkSize:))
|
||||
{
|
||||
[item setState:((tag == memview->bytes_per_chunk()) ? NSOnState : NSOffState)];
|
||||
} else if (action == @selector(showPhysicalAddresses:)) {
|
||||
}
|
||||
else if (action == @selector(showPhysicalAddresses:))
|
||||
{
|
||||
[item setState:((tag == memview->physical()) ? NSOnState : NSOffState)];
|
||||
} else if (action == @selector(showReverseView:)) {
|
||||
}
|
||||
else if (action == @selector(showReverseView:))
|
||||
{
|
||||
[item setState:((tag == memview->reverse()) ? NSOnState : NSOffState)];
|
||||
} else if (action == @selector(showReverseViewToggle:)) {
|
||||
}
|
||||
else if (action == @selector(showReverseViewToggle:))
|
||||
{
|
||||
[item setState:(memview->reverse() ? NSOnState : NSOffState)];
|
||||
}
|
||||
return YES;
|
||||
return [super validateMenuItem:item];
|
||||
}
|
||||
|
||||
|
||||
- (NSSize)maximumFrameSize {
|
||||
debug_view_xy max;
|
||||
device_t *curcpu = debug_cpu_get_visible_cpu(*machine);
|
||||
debug_view_source const *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 max(0, 0);
|
||||
debug_view_source const *source = view->source();
|
||||
for (debug_view_source const *source = view->first_source(); 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;
|
||||
debug_view_xy const current = view->total_size();
|
||||
max.x = MAX(max.x, current.x);
|
||||
max.y = MAX(max.y, current.y);
|
||||
}
|
||||
view->set_source(*source);
|
||||
return NSMakeSize(max.x * fontWidth, max.y * fontHeight);
|
||||
return NSMakeSize(ceil((max.x * fontWidth) + (2 * [textContainer lineFragmentPadding])),
|
||||
ceil(max.y * fontHeight));
|
||||
}
|
||||
|
||||
|
||||
- (void)addContextMenuItemsToMenu:(NSMenu *)menu {
|
||||
[super addContextMenuItemsToMenu:menu];
|
||||
if ([menu numberOfItems] > 0)
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[self insertActionItemsInMenu:menu atIndex:[menu numberOfItems]];
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,25 +128,26 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
|
||||
{
|
||||
if (m_dasmView->view()->cursor_visible())
|
||||
{
|
||||
if (debug_cpu_get_visible_cpu(*m_machine) == m_dasmView->view()->source()->device())
|
||||
offs_t address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
|
||||
device_t *device = m_dasmView->view()->source()->device();
|
||||
device_debug *cpuinfo = device->debug();
|
||||
|
||||
// Find an existing breakpoint at this address
|
||||
INT32 bpindex = -1;
|
||||
for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first();
|
||||
bp != NULL;
|
||||
bp = bp->next())
|
||||
{
|
||||
offs_t address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
|
||||
device_debug *cpuinfo = m_dasmView->view()->source()->device()->debug();
|
||||
|
||||
// Find an existing breakpoint at this address
|
||||
INT32 bpindex = -1;
|
||||
for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first();
|
||||
bp != NULL;
|
||||
bp = bp->next())
|
||||
if (address == bp->address())
|
||||
{
|
||||
if (address == bp->address())
|
||||
{
|
||||
bpindex = bp->index();
|
||||
break;
|
||||
}
|
||||
bpindex = bp->index();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If none exists, add a new one
|
||||
// If none exists, add a new one
|
||||
if (debug_cpu_get_visible_cpu(*m_machine) == device)
|
||||
{
|
||||
astring command;
|
||||
if (bpindex == -1)
|
||||
{
|
||||
@ -158,6 +159,21 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
|
||||
}
|
||||
debug_console_execute_command(*m_machine, command, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bpindex == -1)
|
||||
{
|
||||
bpindex = cpuinfo->breakpoint_set(address, NULL, NULL);
|
||||
debug_console_printf(*m_machine, "Breakpoint %X set\n", bpindex);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuinfo->breakpoint_clear(bpindex);
|
||||
debug_console_printf(*m_machine, "Breakpoint %X cleared\n", bpindex);
|
||||
}
|
||||
m_machine->debug_view().update_all();
|
||||
debugger_refresh_display(*m_machine);
|
||||
}
|
||||
}
|
||||
|
||||
refreshAll();
|
||||
@ -168,13 +184,19 @@ void DasmWindow::runToCursor(bool changedTo)
|
||||
{
|
||||
if (m_dasmView->view()->cursor_visible())
|
||||
{
|
||||
if (debug_cpu_get_visible_cpu(*m_machine) == m_dasmView->view()->source()->device())
|
||||
offs_t address = downcast<debug_view_disasm*>(m_dasmView->view())->selected_address();
|
||||
device_t *device = m_dasmView->view()->source()->device();
|
||||
|
||||
if (debug_cpu_get_visible_cpu(*m_machine) == device)
|
||||
{
|
||||
offs_t address = downcast<debug_view_disasm*>(m_dasmView->view())->selected_address();
|
||||
astring command;
|
||||
command.printf("go 0x%X", address);
|
||||
debug_console_execute_command(*m_machine, command, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
device->debug()->go(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,6 +295,7 @@ DEBUGOBJS = \
|
||||
$(OSDOBJ)/modules/debugger/osx/debugconsole.o \
|
||||
$(OSDOBJ)/modules/debugger/osx/debugview.o \
|
||||
$(OSDOBJ)/modules/debugger/osx/debugwindowhandler.o \
|
||||
$(OSDOBJ)/modules/debugger/osx/deviceinfoviewer.o \
|
||||
$(OSDOBJ)/modules/debugger/osx/devicesviewer.o \
|
||||
$(OSDOBJ)/modules/debugger/osx/disassemblyview.o \
|
||||
$(OSDOBJ)/modules/debugger/osx/disassemblyviewer.o \
|
||||
|
Loading…
Reference in New Issue
Block a user