mame/src/osd/modules/debugger/osx/memoryview.mm
Vas Crabb b6d7d31d49 * Save/restore more Cocoa debugger state
* Fix some Cocoa debugger desync issues
 - Scroll to selection on gaining focus by keyboard (e.g. tab) only
 - Fixes jump on clicking a memory or disasm view that you've scrolled
2017-07-21 01:17:52 +10:00

314 lines
8.8 KiB
Plaintext

// license:BSD-3-Clause
// copyright-holders:Vas Crabb
//============================================================
//
// memoryview.m - MacOS X Cocoa debug window handling
//
//============================================================
#include "emu.h"
#import "memoryview.h"
#include "debug/debugcpu.h"
#include "debug/debugvw.h"
#include "util/xmlfile.h"
@implementation MAMEMemoryView
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m {
if (!(self = [super initWithFrame:f type:DVT_MEMORY machine:m wholeLineScroll:NO]))
return nil;
return self;
}
- (void)dealloc {
[super dealloc];
}
- (BOOL)validateMenuItem:(NSMenuItem *)item {
SEL action = [item action];
NSInteger tag = [item tag];
debug_view_memory *memview = downcast<debug_view_memory *>(view);
if (action == @selector(showChunkSize:))
{
[item setState:((tag == memview->get_data_format()) ? NSOnState : NSOffState)];
return YES;
}
else if (action == @selector(showPhysicalAddresses:))
{
[item setState:((tag == memview->physical()) ? NSOnState : NSOffState)];
return YES;
}
else if (action == @selector(showReverseView:))
{
[item setState:((tag == memview->reverse()) ? NSOnState : NSOffState)];
return YES;
}
else if (action == @selector(showReverseViewToggle:))
{
[item setState:(memview->reverse() ? NSOnState : NSOffState)];
return YES;
}
else if (action == @selector(changeBytesPerLine:))
{
return (memview->chunks_per_row() + [item tag]) > 0;
}
else
{
return [super validateMenuItem:item];
}
}
- (NSSize)maximumFrameSize {
debug_view_xy max(0, 0);
debug_view_source const *source = view->source();
for (debug_view_source const *source = view->first_source(); source != nullptr; source = source->next())
{
view->set_source(*source);
debug_view_xy const current = view->total_size();
max.x = std::max(max.x, current.x);
max.y = std::max(max.y, current.y);
}
view->set_source(*source);
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]];
}
- (NSString *)selectedSubviewName {
debug_view_source const *source = view->source();
if (source != nullptr)
return [NSString stringWithUTF8String:source->name()];
else
return @"";
}
- (int)selectedSubviewIndex {
debug_view_source const *source = view->source();
if (source != nullptr)
return view->source_list().indexof(*source);
else
return -1;
}
- (void)selectSubviewAtIndex:(int)index {
int const 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);
}
}
- (BOOL)selectSubviewForDevice:(device_t *)device {
debug_view_source const *const source = view->source_for_device(device);
if (source != nullptr)
{
if (view->source() != source)
{
view->set_source(*source);
if ([[self window] firstResponder] != self)
view->set_cursor_visible(false);
}
return YES;
}
else
{
return NO;
}
}
- (BOOL)selectSubviewForSpace:(address_space *)space {
if (space == nullptr) return NO;
debug_view_memory_source const *source = downcast<debug_view_memory_source const *>(view->first_source());
while ((source != nullptr) && (source->space() != space))
source = downcast<debug_view_memory_source *>(source->next());
if (source != nullptr)
{
if (view->source() != source)
{
view->set_source(*source);
if ([[self window] firstResponder] != self)
view->set_cursor_visible(false);
}
return YES;
}
else
{
return NO;
}
}
- (NSString *)expression {
return [NSString stringWithUTF8String:downcast<debug_view_memory *>(view)->expression()];
}
- (void)setExpression:(NSString *)exp {
downcast<debug_view_memory *>(view)->set_expression([exp UTF8String]);
}
- (debug_view_memory_source const *)source {
return downcast<debug_view_memory_source const *>(view->source());
}
- (IBAction)showChunkSize:(id)sender {
downcast<debug_view_memory *>(view)->set_data_format([sender tag]);
}
- (IBAction)showPhysicalAddresses:(id)sender {
downcast<debug_view_memory *>(view)->set_physical([sender tag]);
}
- (IBAction)showReverseView:(id)sender {
downcast<debug_view_memory *>(view)->set_reverse([sender tag]);
}
- (IBAction)showReverseViewToggle:(id)sender {
downcast<debug_view_memory *>(view)->set_reverse(!downcast<debug_view_memory *>(view)->reverse());
}
- (IBAction)changeBytesPerLine:(id)sender {
debug_view_memory *const memView = downcast<debug_view_memory *>(view);
memView->set_chunks_per_row(memView->chunks_per_row() + [sender tag]);
}
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
debug_view_memory *const memView = downcast<debug_view_memory *>(view);
node->set_attribute_int("reverse", memView->reverse() ? 1 : 0);
node->set_attribute_int("addressmode", memView->physical() ? 1 : 0);
node->set_attribute_int("dataformat", memView->get_data_format());
node->set_attribute_int("rowchunks", memView->chunks_per_row());
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
debug_view_memory *const memView = downcast<debug_view_memory *>(view);
memView->set_reverse(0 != node->get_attribute_int("reverse", memView->reverse() ? 1 : 0));
memView->set_physical(0 != node->get_attribute_int("addressmode", memView->physical() ? 1 : 0));
memView->set_data_format(node->get_attribute_int("dataformat", memView->get_data_format()));
memView->set_chunks_per_row(node->get_attribute_int("rowchunks", memView->chunks_per_row()));
}
- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index {
NSInteger tag;
for (tag = 1; tag <= 8; tag <<= 1) {
NSString *title = [NSString stringWithFormat:@"%ld-byte Chunks", (long)tag];
NSMenuItem *chunkItem = [menu insertItemWithTitle:title
action:@selector(showChunkSize:)
keyEquivalent:[NSString stringWithFormat:@"%ld", (long)tag]
atIndex:index++];
[chunkItem setTarget:self];
[chunkItem setTag:tag];
}
NSMenuItem *chunkItem = [menu insertItemWithTitle:@"32-bit floats"
action:@selector(showChunkSize:)
keyEquivalent:@"F"
atIndex:index++];
[chunkItem setTarget:self];
[chunkItem setTag:9];
NSMenuItem *chunkItem2 = [menu insertItemWithTitle:@"64-bit floats"
action:@selector(showChunkSize:)
keyEquivalent:@"D"
atIndex:index++];
[chunkItem2 setTarget:self];
[chunkItem2 setTag:10];
NSMenuItem *chunkItem3 = [menu insertItemWithTitle:@"80-bit floats"
action:@selector(showChunkSize:)
keyEquivalent:@"E"
atIndex:index++];
[chunkItem3 setTarget:self];
[chunkItem3 setTag:11];
[menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
NSMenuItem *logicalItem = [menu insertItemWithTitle:@"Logical Addresses"
action:@selector(showPhysicalAddresses:)
keyEquivalent:@"v"
atIndex:index++];
[logicalItem setTarget:self];
[logicalItem setTag:FALSE];
NSMenuItem *physicalItem = [menu insertItemWithTitle:@"Physical Addresses"
action:@selector(showPhysicalAddresses:)
keyEquivalent:@"y"
atIndex:index++];
[physicalItem setTarget:self];
[physicalItem setTag:TRUE];
[menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
NSMenuItem *reverseItem = [menu insertItemWithTitle:@"Reverse View"
action:@selector(showReverseViewToggle:)
keyEquivalent:@"r"
atIndex:index++];
[reverseItem setTarget:self];
[menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
NSMenuItem *increaseItem = [menu insertItemWithTitle:@"Increase Bytes Per Line"
action:@selector(changeBytesPerLine:)
keyEquivalent:@"p"
atIndex:index++];
[increaseItem setTarget:self];
[increaseItem setTag:1];
NSMenuItem *decreaseItem = [menu insertItemWithTitle:@"Decrease Bytes Per Line"
action:@selector(changeBytesPerLine:)
keyEquivalent:@"o"
atIndex:index++];
[decreaseItem setTarget:self];
[decreaseItem setTag:-1];
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 != nullptr; 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