summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/dvmemory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/dvmemory.cpp')
-rw-r--r--src/emu/debug/dvmemory.cpp334
1 files changed, 257 insertions, 77 deletions
diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp
index 1e2e0648326..2327d7284cc 100644
--- a/src/emu/debug/dvmemory.cpp
+++ b/src/emu/debug/dvmemory.cpp
@@ -20,7 +20,7 @@
// GLOBAL VARIABLES
//**************************************************************************
-const debug_view_memory::memory_view_pos debug_view_memory::s_memory_pos_table[9] =
+const debug_view_memory::memory_view_pos debug_view_memory::s_memory_pos_table[12] =
{
/* 0 bytes per chunk: */ { 0, { 0 } },
/* 1 byte per chunk: 00 11 22 33 44 55 66 77 */ { 3, { 0x04, 0x00, 0x80 } },
@@ -30,7 +30,10 @@ const debug_view_memory::memory_view_pos debug_view_memory::s_memory_pos_table[9
/* 5 bytes per chunk: */ { 0, { 0 } },
/* 6 bytes per chunk: */ { 0, { 0 } },
/* 7 bytes per chunk: */ { 0, { 0 } },
- /* 8 bytes per chunk: 0011223344556677 */ { 24, { 0xbc, 0xbc, 0xbc, 0xbc, 0x3c, 0x38, 0x34, 0x30, 0x2c, 0x28, 0x24, 0x20, 0x1c, 0x18, 0x14, 0x10, 0x0c, 0x08, 0x04, 0x00, 0x80, 0x80, 0x80, 0x80 } }
+ /* 8 bytes per chunk: 0011223344556677 */ { 24, { 0xbc, 0xbc, 0xbc, 0xbc, 0x3c, 0x38, 0x34, 0x30, 0x2c, 0x28, 0x24, 0x20, 0x1c, 0x18, 0x14, 0x10, 0x0c, 0x08, 0x04, 0x00, 0x80, 0x80, 0x80, 0x80 } },
+ /* 32 bit floating point: */ { 16, { 0 } },
+ /* 64 bit floating point: */ { 32, { 0 } },
+ /* 80 bit floating point: */ { 32, { 0 } },
};
@@ -47,7 +50,7 @@ debug_view_memory_source::debug_view_memory_source(const char *name, address_spa
: debug_view_source(name, &space.device()),
m_space(&space),
m_memintf(dynamic_cast<device_memory_interface *>(&space.device())),
- m_base(NULL),
+ m_base(nullptr),
m_length(0),
m_offsetxor(0),
m_endianness(space.endianness()),
@@ -57,8 +60,8 @@ debug_view_memory_source::debug_view_memory_source(const char *name, address_spa
debug_view_memory_source::debug_view_memory_source(const char *name, memory_region &region)
: debug_view_source(name),
- m_space(NULL),
- m_memintf(NULL),
+ m_space(nullptr),
+ m_memintf(nullptr),
m_base(region.base()),
m_length(region.bytes()),
m_offsetxor(ENDIAN_VALUE_NE_NNE(region.endianness(), 0, region.bytewidth() - 1)),
@@ -69,8 +72,8 @@ debug_view_memory_source::debug_view_memory_source(const char *name, memory_regi
debug_view_memory_source::debug_view_memory_source(const char *name, void *base, int element_size, int num_elements)
: debug_view_source(name),
- m_space(NULL),
- m_memintf(NULL),
+ m_space(nullptr),
+ m_memintf(nullptr),
m_base(base),
m_length(element_size * num_elements),
m_offsetxor(0),
@@ -94,9 +97,11 @@ debug_view_memory::debug_view_memory(running_machine &machine, debug_view_osd_up
m_expression(machine),
m_chunks_per_row(16),
m_bytes_per_chunk(1),
+ m_data_format(1),
m_reverse_view(false),
m_ascii_view(true),
m_no_translation(false),
+ m_edit_enabled(true),
m_maxaddr(0),
m_bytes_per_row(16),
m_byte_offset(0)
@@ -131,7 +136,7 @@ void debug_view_memory::enumerate_sources()
// first add all the devices' address spaces
memory_interface_iterator iter(machine().root_device());
- for (device_memory_interface *memintf = iter.first(); memintf != NULL; memintf = iter.next())
+ for (device_memory_interface *memintf = iter.first(); memintf != nullptr; memintf = iter.next())
if (&memintf->device() != &machine().root_device())
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; ++spacenum)
if (memintf->has_space(spacenum))
@@ -142,7 +147,7 @@ void debug_view_memory::enumerate_sources()
}
// then add all the memory regions
- for (memory_region *region = machine().memory().first_region(); region != NULL; region = region->next())
+ for (memory_region *region = machine().memory().first_region(); region != nullptr; region = region->next())
{
strprintf(name, "Region '%s'", region->name());
m_source_list.append(*global_alloc(debug_view_memory_source(name.c_str(), *region)));
@@ -155,7 +160,7 @@ void debug_view_memory::enumerate_sources()
UINT32 valsize, valcount;
void *base;
const char *itemname = machine().save().indexed_item(itemnum, base, valsize, valcount);
- if (itemname == NULL)
+ if (itemname == nullptr)
break;
// add pretty much anything that's not a timer (we may wish to cull other items later)
@@ -190,15 +195,50 @@ void debug_view_memory::view_notify(debug_view_notification type)
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
m_chunks_per_row = m_bytes_per_chunk * m_chunks_per_row / source.m_prefsize;
m_bytes_per_chunk = source.m_prefsize;
- if (source.m_space != NULL)
+ if (m_bytes_per_chunk > 8)
+ m_bytes_per_chunk = 8;
+ m_data_format = m_bytes_per_chunk;
+ if (source.m_space != nullptr)
m_expression.set_context(&source.m_space->device().debug()->symtable());
else
- m_expression.set_context(NULL);
+ m_expression.set_context(nullptr);
}
}
//-------------------------------------------------
+// uint32_to_float - return a floating point number
+// whose 32 bit representation is value
+//-------------------------------------------------
+
+static inline float uint32_to_float(UINT32 value)
+{
+ union {
+ float f;
+ UINT32 i;
+ } v;
+
+ v.i = value;
+ return v.f;
+}
+
+//-------------------------------------------------
+// uint64_to_double - return a floating point number
+// whose 64 bit representation is value
+//-------------------------------------------------
+
+static inline float uint64_to_double(UINT64 value)
+{
+ union {
+ double f;
+ UINT64 i;
+ } v;
+
+ v.i = value;
+ return v.f;
+}
+
+//-------------------------------------------------
// view_update - update the contents of the
// memory view
//-------------------------------------------------
@@ -212,7 +252,7 @@ void debug_view_memory::view_update()
recompute();
// get positional data
- const memory_view_pos &posdata = s_memory_pos_table[m_bytes_per_chunk];
+ const memory_view_pos &posdata = s_memory_pos_table[m_data_format];
// loop over visible rows
for (UINT32 row = 0; row < m_visible.y; row++)
@@ -241,7 +281,7 @@ void debug_view_memory::view_update()
if (effrow < m_total.y)
{
offs_t addrbyte = m_byte_offset + effrow * m_bytes_per_row;
- offs_t address = (source.m_space != NULL) ? source.m_space->byte_to_address(addrbyte) : addrbyte;
+ offs_t address = (source.m_space != nullptr) ? source.m_space->byte_to_address(addrbyte) : addrbyte;
char addrtext[20];
// generate the address
@@ -255,17 +295,60 @@ void debug_view_memory::view_update()
for (int chunknum = 0; chunknum < m_chunks_per_row; chunknum++)
{
int chunkindex = m_reverse_view ? (m_chunks_per_row - 1 - chunknum) : chunknum;
-
- UINT64 chunkdata;
- bool ismapped = read(m_bytes_per_chunk, addrbyte + chunknum * m_bytes_per_chunk, chunkdata);
- dest = destrow + m_section[1].m_pos + 1 + chunkindex * posdata.m_spacing;
- for (int ch = 0; ch < posdata.m_spacing; ch++, dest++)
- if (dest >= destmin && dest < destmax)
- {
- UINT8 shift = posdata.m_shift[ch];
- if (shift < 64)
- dest->byte = ismapped ? "0123456789ABCDEF"[(chunkdata >> shift) & 0x0f] : '*';
+ int spacing = posdata.m_spacing;
+
+ if (m_data_format <= 8) {
+ UINT64 chunkdata;
+ bool ismapped = read(m_bytes_per_chunk, addrbyte + chunknum * m_bytes_per_chunk, chunkdata);
+ dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
+ for (int ch = 0; ch < posdata.m_spacing; ch++, dest++)
+ if (dest >= destmin && dest < destmax)
+ {
+ UINT8 shift = posdata.m_shift[ch];
+ if (shift < 64)
+ dest->byte = ismapped ? "0123456789ABCDEF"[(chunkdata >> shift) & 0x0f] : '*';
+ }
+ }
+ else {
+ int ch;
+ char valuetext[64];
+ UINT64 chunkdata = 0;
+ floatx80 chunkdata80 = { 0, 0 };
+ bool ismapped;
+
+ if (m_data_format != 11)
+ ismapped = read(m_bytes_per_chunk, addrbyte + chunknum * m_bytes_per_chunk, chunkdata);
+ else
+ ismapped = read(m_bytes_per_chunk, addrbyte + chunknum * m_bytes_per_chunk, chunkdata80);
+
+ if (ismapped)
+ switch (m_data_format)
+ {
+ case 9:
+ sprintf(valuetext, "%.8g", uint32_to_float((UINT32)chunkdata));
+ break;
+ case 10:
+ sprintf(valuetext, "%.24g", uint64_to_double(chunkdata));
+ break;
+ case 11:
+ float64 f64 = floatx80_to_float64(chunkdata80);
+ sprintf(valuetext, "%.24g", uint64_to_double(f64));
+ break;
+ }
+ else {
+ valuetext[0] = '*';
+ valuetext[1] = 0;
}
+ dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
+ // first copy the text
+ for (ch = 0; (ch < spacing) && (valuetext[ch] != 0); ch++, dest++)
+ if (dest >= destmin && dest < destmax)
+ dest->byte = valuetext[ch];
+ // then fill with spaces
+ for (; ch < spacing; ch++, dest++)
+ if (dest >= destmin && dest < destmax)
+ dest->byte = ' ';
+ }
}
// generate the ASCII data
@@ -295,6 +378,10 @@ void debug_view_memory::view_char(int chval)
// get the position
cursor_pos pos = get_cursor_pos(m_cursor);
+ // editing is not supported when showing floating point values
+ if (m_edit_enabled == false)
+ return;
+
// handle the incoming key
switch (chval)
{
@@ -360,7 +447,7 @@ void debug_view_memory::view_char(int chval)
{
static const char hexvals[] = "0123456789abcdef";
char *hexchar = (char *)strchr(hexvals, tolower(chval));
- if (hexchar == NULL)
+ if (hexchar == nullptr)
break;
UINT64 data;
@@ -443,7 +530,7 @@ void debug_view_memory::recompute()
// determine the maximum address and address format string from the raw information
int addrchars;
- if (source.m_space != NULL)
+ if (source.m_space != nullptr)
{
m_maxaddr = m_no_translation ? source.m_space->bytemask() : source.m_space->logbytemask();
addrchars = m_no_translation ? source.m_space->addrchars() : source.m_space->logaddrchars();
@@ -461,7 +548,7 @@ void debug_view_memory::recompute()
strprintf(m_addrformat, "%%0%dX%*s", addrchars, 8 - addrchars, "");
// if we are viewing a space with a minimum chunk size, clamp the bytes per chunk
- if (source.m_space != NULL && source.m_space->byte_to_address(1) > 1)
+ if (source.m_space != nullptr && source.m_space->byte_to_address(1) > 1)
{
UINT32 min_bytes_per_chunk = source.m_space->byte_to_address(1);
while (m_bytes_per_chunk < min_bytes_per_chunk)
@@ -478,7 +565,13 @@ void debug_view_memory::recompute()
// compute the section widths
m_section[0].m_width = 1 + 8 + 1;
- m_section[1].m_width = 1 + 3 * m_bytes_per_row + 1;
+ if (m_data_format <= 8)
+ m_section[1].m_width = 1 + 3 * m_bytes_per_row + 1;
+ else {
+ const memory_view_pos &posdata = s_memory_pos_table[m_data_format];
+
+ m_section[1].m_width = 1 + posdata.m_spacing * m_chunks_per_row + 1;
+ }
m_section[2].m_width = m_ascii_view ? (1 + m_bytes_per_row + 1) : 0;
// compute the section positions
@@ -524,7 +617,7 @@ bool debug_view_memory::needs_recompute()
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
offs_t resultbyte;
- if (source.m_space != NULL)
+ if (source.m_space != nullptr)
resultbyte = source.m_space->address_to_byte(m_expression.value()) & source.m_space->logbytemask();
else
resultbyte = m_expression.value();
@@ -547,27 +640,46 @@ debug_view_memory::cursor_pos debug_view_memory::get_cursor_pos(const debug_view
{
// start with the base address for this row
cursor_pos pos;
+ const memory_view_pos &posdata = s_memory_pos_table[m_data_format];
pos.m_address = m_byte_offset + cursor.y * m_bytes_per_chunk * m_chunks_per_row;
// determine the X position within the middle section, clamping as necessary
- const memory_view_pos &posdata = s_memory_pos_table[m_bytes_per_chunk];
- int xposition = cursor.x - m_section[1].m_pos - 1;
- if (xposition < 0)
- xposition = 0;
- else if (xposition >= posdata.m_spacing * m_chunks_per_row)
- xposition = posdata.m_spacing * m_chunks_per_row - 1;
-
- // compute chunk number and offset within that chunk
- int chunknum = xposition / posdata.m_spacing;
- int chunkoffs = xposition % posdata.m_spacing;
-
- // reverse the chunknum if we're reversed
- if (m_reverse_view)
- chunknum = m_chunks_per_row - 1 - chunknum;
+ if (m_data_format <= 8) {
+ int xposition = cursor.x - m_section[1].m_pos - 1;
+ if (xposition < 0)
+ xposition = 0;
+ else if (xposition >= posdata.m_spacing * m_chunks_per_row)
+ xposition = posdata.m_spacing * m_chunks_per_row - 1;
+
+ // compute chunk number and offset within that chunk
+ int chunknum = xposition / posdata.m_spacing;
+ int chunkoffs = xposition % posdata.m_spacing;
+
+ // reverse the chunknum if we're reversed
+ if (m_reverse_view)
+ chunknum = m_chunks_per_row - 1 - chunknum;
+
+ // compute the address and shift
+ pos.m_address += chunknum * m_bytes_per_chunk;
+ pos.m_shift = posdata.m_shift[chunkoffs] & 0x7f;
+ }
+ else {
+ int xposition = cursor.x - m_section[1].m_pos - 1;
+ // check for lower limit
+ if (xposition < 0)
+ xposition = 0;
+ int chunknum = xposition / posdata.m_spacing;
+ // check for upper limit
+ if (chunknum >= m_chunks_per_row)
+ chunknum = m_chunks_per_row - 1;
+ // reverse the chunknum if we're reversed
+ if (m_reverse_view)
+ chunknum = m_chunks_per_row - 1 - chunknum;
+ // compute the address
+ pos.m_address += chunknum * m_bytes_per_chunk;
+ pos.m_shift = 0;
+ }
- // compute the address and shift
- pos.m_address += chunknum * m_bytes_per_chunk;
- pos.m_shift = posdata.m_shift[chunkoffs] & 0x7f;
return pos;
}
@@ -579,7 +691,7 @@ debug_view_memory::cursor_pos debug_view_memory::get_cursor_pos(const debug_view
void debug_view_memory::set_cursor_pos(cursor_pos pos)
{
- const memory_view_pos &posdata = s_memory_pos_table[m_bytes_per_chunk];
+ const memory_view_pos &posdata = s_memory_pos_table[m_data_format];
// offset the address by the byte offset
if (pos.m_address < m_byte_offset)
@@ -594,13 +706,18 @@ void debug_view_memory::set_cursor_pos(cursor_pos pos)
if (m_reverse_view)
chunknum = m_chunks_per_row - 1 - chunknum;
- // scan within the chunk to find the shift
- for (m_cursor.x = 0; m_cursor.x < posdata.m_spacing; m_cursor.x++)
- if (posdata.m_shift[m_cursor.x] == pos.m_shift)
- break;
+ if (m_data_format <= 8) {
+ // scan within the chunk to find the shift
+ for (m_cursor.x = 0; m_cursor.x < posdata.m_spacing; m_cursor.x++)
+ if (posdata.m_shift[m_cursor.x] == pos.m_shift)
+ break;
- // add in the chunk offset and shift to the right of divider1
- m_cursor.x += m_section[1].m_pos + 1 + posdata.m_spacing * chunknum;
+ // add in the chunk offset and shift to the right of divider1
+ m_cursor.x += m_section[1].m_pos + 1 + posdata.m_spacing * chunknum;
+ }
+ else {
+ m_cursor.x = m_section[1].m_pos + 1 + posdata.m_spacing * chunknum;
+ }
// clamp to the window bounds
m_cursor.x = MIN(m_cursor.x, m_total.x);
@@ -621,7 +738,7 @@ bool debug_view_memory::read(UINT8 size, offs_t offs, UINT64 &data)
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
// if no raw data, just use the standard debug routines
- if (source.m_space != NULL)
+ if (source.m_space != nullptr)
{
offs_t dummyaddr = offs;
@@ -666,6 +783,31 @@ bool debug_view_memory::read(UINT8 size, offs_t offs, UINT64 &data)
//-------------------------------------------------
+// read - read a 80 bit value
+//-------------------------------------------------
+
+bool debug_view_memory::read(UINT8 size, offs_t offs, floatx80 &data)
+{
+ UINT64 t;
+ bool mappedhi, mappedlo;
+ const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
+
+ if (source.m_endianness == ENDIANNESS_LITTLE) {
+ mappedlo = read(8, offs, data.low);
+ mappedhi = read(2, offs+8, t);
+ data.high = (bits16)t;
+ }
+ else {
+ mappedhi = read(2, offs, t);
+ data.high = (bits16)t;
+ mappedlo = read(8, offs + 2, data.low);
+ }
+
+ return mappedhi && mappedlo;
+}
+
+
+//-------------------------------------------------
// write - generic memory view data writer
//-------------------------------------------------
@@ -674,7 +816,7 @@ void debug_view_memory::write(UINT8 size, offs_t offs, UINT64 data)
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
// if no raw data, just use the standard debug routines
- if (source.m_space != NULL)
+ if (source.m_space != nullptr)
{
switch (size)
{
@@ -735,48 +877,86 @@ void debug_view_memory::set_expression(const char *expression)
//-------------------------------------------------
-// set_bytes_per_chunk - specify the number of
-// bytes displayed per chunk
+// set_chunks_per_row - specify the number of
+// chunks displayed across a row
//-------------------------------------------------
-void debug_view_memory::set_bytes_per_chunk(UINT8 chunkbytes)
+void debug_view_memory::set_chunks_per_row(UINT32 rowchunks)
{
- const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
+ if (rowchunks < 1)
+ return;
cursor_pos pos = begin_update_and_get_cursor_pos();
- pos.m_address += (pos.m_shift / 8) ^ ((source.m_endianness == ENDIANNESS_LITTLE) ? 0 : (m_bytes_per_chunk - 1));
- pos.m_shift %= 8;
-
- m_bytes_per_chunk = chunkbytes;
- m_chunks_per_row = m_bytes_per_row / chunkbytes;
- if (m_chunks_per_row < 1)
- m_chunks_per_row = 1;
+ m_chunks_per_row = rowchunks;
m_recompute = m_update_pending = true;
-
- pos.m_shift += 8 * ((pos.m_address % m_bytes_per_chunk) ^ ((source.m_endianness == ENDIANNESS_LITTLE) ? 0 : (m_bytes_per_chunk - 1)));
- pos.m_address -= pos.m_address % m_bytes_per_chunk;
-
end_update_and_set_cursor_pos(pos);
}
//-------------------------------------------------
-// set_chunks_per_row - specify the number of
-// chunks displayed across a row
+// set_data_format - specify what kind of values
+// are shown, 1-8 8-64 bits, 9 32bit floating point
//-------------------------------------------------
-void debug_view_memory::set_chunks_per_row(UINT32 rowchunks)
+void debug_view_memory::set_data_format(int format)
{
- if (rowchunks < 1)
+ cursor_pos pos;
+
+ // should never be
+ if ((format <= 0) || (format > 11))
+ return;
+ // no need to change
+ if (format == m_data_format)
return;
- cursor_pos pos = begin_update_and_get_cursor_pos();
- m_chunks_per_row = rowchunks;
+ pos = begin_update_and_get_cursor_pos();
+ if ((format <= 8) && (m_data_format <= 8)) {
+ const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
+
+ pos.m_address += (pos.m_shift / 8) ^ ((source.m_endianness == ENDIANNESS_LITTLE) ? 0 : (m_bytes_per_chunk - 1));
+ pos.m_shift %= 8;
+
+ m_bytes_per_chunk = format;
+ m_chunks_per_row = m_bytes_per_row / format;
+ if (m_chunks_per_row < 1)
+ m_chunks_per_row = 1;
+
+ pos.m_shift += 8 * ((pos.m_address % m_bytes_per_chunk) ^ ((source.m_endianness == ENDIANNESS_LITTLE) ? 0 : (m_bytes_per_chunk - 1)));
+ pos.m_address -= pos.m_address % m_bytes_per_chunk;
+ } else {
+ if (format <= 8) {
+ m_supports_cursor = true;
+ m_edit_enabled = true;
+
+ m_bytes_per_chunk = format;
+ }
+ else {
+ m_supports_cursor = false;
+ m_edit_enabled = false;
+ m_cursor_visible = false;
+
+ switch (format)
+ {
+ case 9:
+ m_bytes_per_chunk = 4;
+ break;
+ case 10:
+ m_bytes_per_chunk = 8;
+ break;
+ case 11:
+ m_bytes_per_chunk = 10;
+ break;
+ }
+ }
+ m_chunks_per_row = m_bytes_per_row / m_bytes_per_chunk;
+ pos.m_shift = 0;
+ pos.m_address -= pos.m_address % m_bytes_per_chunk;
+ }
m_recompute = m_update_pending = true;
+ m_data_format = format;
end_update_and_set_cursor_pos(pos);
}
-
//-------------------------------------------------
// set_reverse - specify true if the memory view
// is displayed reverse