Show 64 and 80 bit floats in windows and qt debugger (issue #476)

This commit is contained in:
yz70s 2015-12-06 21:33:49 +01:00
parent 5f17636fdd
commit e76dc64868
5 changed files with 137 additions and 21 deletions

View File

@ -20,7 +20,7 @@
// GLOBAL VARIABLES // 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 } }, /* 0 bytes per chunk: */ { 0, { 0 } },
/* 1 byte per chunk: 00 11 22 33 44 55 66 77 */ { 3, { 0x04, 0x00, 0x80 } }, /* 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 } }, /* 5 bytes per chunk: */ { 0, { 0 } },
/* 6 bytes per chunk: */ { 0, { 0 } }, /* 6 bytes per chunk: */ { 0, { 0 } },
/* 7 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 } },
}; };
@ -219,6 +222,22 @@ INLINE float uint32_to_float(UINT32 value)
return v.f; return v.f;
} }
//-------------------------------------------------
// uint64_to_double - return a floating point number
// whose 64 bit representation is value
//-------------------------------------------------
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 // view_update - update the contents of the
// memory view // memory view
@ -233,7 +252,7 @@ void debug_view_memory::view_update()
recompute(); recompute();
// get positional data // 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 // loop over visible rows
for (UINT32 row = 0; row < m_visible.y; row++) for (UINT32 row = 0; row < m_visible.y; row++)
@ -278,9 +297,9 @@ void debug_view_memory::view_update()
int chunkindex = m_reverse_view ? (m_chunks_per_row - 1 - chunknum) : chunknum; int chunkindex = m_reverse_view ? (m_chunks_per_row - 1 - chunknum) : chunknum;
int spacing = posdata.m_spacing; int spacing = posdata.m_spacing;
UINT64 chunkdata;
bool ismapped = read(m_bytes_per_chunk, addrbyte + chunknum * m_bytes_per_chunk, chunkdata);
if (m_data_format <= 8) { 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; dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
for (int ch = 0; ch < posdata.m_spacing; ch++, dest++) for (int ch = 0; ch < posdata.m_spacing; ch++, dest++)
if (dest >= destmin && dest < destmax) if (dest >= destmin && dest < destmax)
@ -292,22 +311,41 @@ void debug_view_memory::view_update()
} }
else { else {
int ch; int ch;
char valuetext[20]; char valuetext[64];
UINT64 chunkdata;
floatx80 chunkdata80;
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);
spacing = 16;
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
if (ismapped) if (ismapped)
sprintf(valuetext, "%g", uint32_to_float((UINT32)chunkdata)); switch (m_data_format)
{
case 9:
sprintf(valuetext, "%g", uint32_to_float((UINT32)chunkdata));
break;
case 10:
sprintf(valuetext, "%g", uint64_to_double(chunkdata));
break;
case 11:
float64 f64 = floatx80_to_float64(chunkdata80);
sprintf(valuetext, "%g", uint64_to_double(f64));
break;
}
else { else {
valuetext[0] = '*'; valuetext[0] = '*';
valuetext[1] = 0; valuetext[1] = 0;
} }
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
// first copy the text // first copy the text
for (ch = 0; (ch < 16) && (valuetext[ch] != 0); ch++, dest++) for (ch = 0; (ch < spacing) && (valuetext[ch] != 0); ch++, dest++)
if (dest >= destmin && dest < destmax) if (dest >= destmin && dest < destmax)
dest->byte = valuetext[ch]; dest->byte = valuetext[ch];
// then fill with spaces // then fill with spaces
for (; ch < 16; ch++, dest++) for (; ch < spacing; ch++, dest++)
if (dest >= destmin && dest < destmax) if (dest >= destmin && dest < destmax)
dest->byte = ' '; dest->byte = ' ';
} }
@ -529,8 +567,11 @@ void debug_view_memory::recompute()
m_section[0].m_width = 1 + 8 + 1; m_section[0].m_width = 1 + 8 + 1;
if (m_data_format <= 8) if (m_data_format <= 8)
m_section[1].m_width = 1 + 3 * m_bytes_per_row + 1; m_section[1].m_width = 1 + 3 * m_bytes_per_row + 1;
else else {
m_section[1].m_width = 1 + 16 * m_chunks_per_row + 1; 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; m_section[2].m_width = m_ascii_view ? (1 + m_bytes_per_row + 1) : 0;
// compute the section positions // compute the section positions
@ -599,11 +640,11 @@ debug_view_memory::cursor_pos debug_view_memory::get_cursor_pos(const debug_view
{ {
// start with the base address for this row // start with the base address for this row
cursor_pos pos; 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; 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 // determine the X position within the middle section, clamping as necessary
if (m_data_format <= 8) { if (m_data_format <= 8) {
const memory_view_pos &posdata = s_memory_pos_table[m_bytes_per_chunk];
int xposition = cursor.x - m_section[1].m_pos - 1; int xposition = cursor.x - m_section[1].m_pos - 1;
if (xposition < 0) if (xposition < 0)
xposition = 0; xposition = 0;
@ -627,7 +668,7 @@ debug_view_memory::cursor_pos debug_view_memory::get_cursor_pos(const debug_view
// check for lower limit // check for lower limit
if (xposition < 0) if (xposition < 0)
xposition = 0; xposition = 0;
int chunknum = xposition / 16; int chunknum = xposition / posdata.m_spacing;
// check for upper limit // check for upper limit
if (chunknum >= m_chunks_per_row) if (chunknum >= m_chunks_per_row)
chunknum = m_chunks_per_row - 1; chunknum = m_chunks_per_row - 1;
@ -650,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) 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 // offset the address by the byte offset
if (pos.m_address < m_byte_offset) if (pos.m_address < m_byte_offset)
@ -675,7 +716,7 @@ void debug_view_memory::set_cursor_pos(cursor_pos pos)
m_cursor.x += m_section[1].m_pos + 1 + posdata.m_spacing * chunknum; m_cursor.x += m_section[1].m_pos + 1 + posdata.m_spacing * chunknum;
} }
else { else {
m_cursor.x = m_section[1].m_pos + 1 + 16 * chunknum; m_cursor.x = m_section[1].m_pos + 1 + posdata.m_spacing * chunknum;
} }
// clamp to the window bounds // clamp to the window bounds
@ -741,6 +782,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 // write - generic memory view data writer
//------------------------------------------------- //-------------------------------------------------
@ -837,7 +903,7 @@ void debug_view_memory::set_data_format(int format)
cursor_pos pos; cursor_pos pos;
// should never be // should never be
if (format <= 0) if ((format <= 0) || (format > 11))
return; return;
// no need to change // no need to change
if (format == m_data_format) if (format == m_data_format)
@ -869,7 +935,18 @@ void debug_view_memory::set_data_format(int format)
m_edit_enabled = false; m_edit_enabled = false;
m_cursor_visible = false; m_cursor_visible = false;
m_bytes_per_chunk = 4; 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; m_chunks_per_row = m_bytes_per_row / m_bytes_per_chunk;
pos.m_shift = 0; pos.m_shift = 0;

View File

@ -11,6 +11,9 @@
#ifndef __DVMEMORY_H__ #ifndef __DVMEMORY_H__
#define __DVMEMORY_H__ #define __DVMEMORY_H__
#include "softfloat/mamesf.h"
#include "softfloat/softfloat.h"
//************************************************************************** //**************************************************************************
// TYPE DEFINITIONS // TYPE DEFINITIONS
//************************************************************************** //**************************************************************************
@ -94,6 +97,7 @@ private:
// memory access // memory access
bool read(UINT8 size, offs_t offs, UINT64 &data); bool read(UINT8 size, offs_t offs, UINT64 &data);
void write(UINT8 size, offs_t offs, UINT64 data); void write(UINT8 size, offs_t offs, UINT64 data);
bool read(UINT8 size, offs_t offs, floatx80 &data);
// internal state // internal state
debug_view_expression m_expression; // expression describing the start address debug_view_expression m_expression; // expression describing the start address
@ -122,7 +126,7 @@ private:
UINT8 m_spacing; /* spacing between each entry */ UINT8 m_spacing; /* spacing between each entry */
UINT8 m_shift[24]; /* shift for each character */ UINT8 m_shift[24]; /* shift for each character */
}; };
static const memory_view_pos s_memory_pos_table[9]; // table for rendering at different chunk sizes static const memory_view_pos s_memory_pos_table[12]; // table for rendering at different data formats
// constants // constants
static const int MEM_MAX_LINE_WIDTH = 1024; static const int MEM_MAX_LINE_WIDTH = 1024;

View File

@ -68,21 +68,29 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
QAction* formatActFour = new QAction("4-byte chunks", this); QAction* formatActFour = new QAction("4-byte chunks", this);
QAction* formatActEight = new QAction("8-byte chunks", this); QAction* formatActEight = new QAction("8-byte chunks", this);
QAction* formatAct32bitFloat = new QAction("32 bit floating point", this); QAction* formatAct32bitFloat = new QAction("32 bit floating point", this);
QAction* formatAct64bitFloat = new QAction("64 bit floating point", this);
QAction* formatAct80bitFloat = new QAction("80 bit floating point", this);
formatActOne->setObjectName("formatActOne"); formatActOne->setObjectName("formatActOne");
formatActTwo->setObjectName("formatActTwo"); formatActTwo->setObjectName("formatActTwo");
formatActFour->setObjectName("formatActFour"); formatActFour->setObjectName("formatActFour");
formatActEight->setObjectName("formatActEight"); formatActEight->setObjectName("formatActEight");
formatAct32bitFloat->setObjectName("formatAct32bitFloat"); formatAct32bitFloat->setObjectName("formatAct32bitFloat");
formatAct64bitFloat->setObjectName("formatAct64bitFloat");
formatAct80bitFloat->setObjectName("formatAct80bitFloat");
formatActOne->setCheckable(true); formatActOne->setCheckable(true);
formatActTwo->setCheckable(true); formatActTwo->setCheckable(true);
formatActFour->setCheckable(true); formatActFour->setCheckable(true);
formatActEight->setCheckable(true); formatActEight->setCheckable(true);
formatAct32bitFloat->setCheckable(true); formatAct32bitFloat->setCheckable(true);
formatAct64bitFloat->setCheckable(true);
formatAct80bitFloat->setCheckable(true);
formatActOne->setActionGroup(dataFormat); formatActOne->setActionGroup(dataFormat);
formatActTwo->setActionGroup(dataFormat); formatActTwo->setActionGroup(dataFormat);
formatActFour->setActionGroup(dataFormat); formatActFour->setActionGroup(dataFormat);
formatActEight->setActionGroup(dataFormat); formatActEight->setActionGroup(dataFormat);
formatAct32bitFloat->setActionGroup(dataFormat); formatAct32bitFloat->setActionGroup(dataFormat);
formatAct64bitFloat->setActionGroup(dataFormat);
formatAct80bitFloat->setActionGroup(dataFormat);
formatActOne->setShortcut(QKeySequence("Ctrl+1")); formatActOne->setShortcut(QKeySequence("Ctrl+1"));
formatActTwo->setShortcut(QKeySequence("Ctrl+2")); formatActTwo->setShortcut(QKeySequence("Ctrl+2"));
formatActFour->setShortcut(QKeySequence("Ctrl+4")); formatActFour->setShortcut(QKeySequence("Ctrl+4"));
@ -90,7 +98,6 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
formatAct32bitFloat->setShortcut(QKeySequence("Ctrl+9")); formatAct32bitFloat->setShortcut(QKeySequence("Ctrl+9"));
formatActOne->setChecked(true); formatActOne->setChecked(true);
connect(dataFormat, SIGNAL(triggered(QAction*)), this, SLOT(formatChanged(QAction*))); connect(dataFormat, SIGNAL(triggered(QAction*)), this, SLOT(formatChanged(QAction*)));
// Create a address display group // Create a address display group
QActionGroup* addressGroup = new QActionGroup(this); QActionGroup* addressGroup = new QActionGroup(this);
addressGroup->setObjectName("addressgroup"); addressGroup->setObjectName("addressgroup");
@ -161,6 +168,8 @@ void MemoryWindow::memoryRegionChanged(int index)
case 4: dataFormatMenuItem("formatActFour")->setChecked(true); break; case 4: dataFormatMenuItem("formatActFour")->setChecked(true); break;
case 8: dataFormatMenuItem("formatActEight")->setChecked(true); break; case 8: dataFormatMenuItem("formatActEight")->setChecked(true); break;
case 9: dataFormatMenuItem("formatAct32bitFloat")->setChecked(true); break; case 9: dataFormatMenuItem("formatAct32bitFloat")->setChecked(true); break;
case 10: dataFormatMenuItem("formatAct64bitFloat")->setChecked(true); break;
case 11: dataFormatMenuItem("formatAct80bitFloat")->setChecked(true); break;
default: break; default: break;
} }
} }
@ -207,6 +216,14 @@ void MemoryWindow::formatChanged(QAction* changedTo)
{ {
memView->set_data_format(9); memView->set_data_format(9);
} }
else if (changedTo->text() == "64 bit floating point")
{
memView->set_data_format(10);
}
else if (changedTo->text() == "80 bit floating point")
{
memView->set_data_format(11);
}
m_memTable->viewport()->update(); m_memTable->viewport()->update();
} }
@ -381,6 +398,10 @@ void MemoryWindowQtConfig::buildFromQWidget(QWidget* widget)
m_dataFormat = 3; m_dataFormat = 3;
else if (dataFormat->checkedAction()->text() == "32 bit floating point") else if (dataFormat->checkedAction()->text() == "32 bit floating point")
m_dataFormat = 4; m_dataFormat = 4;
else if (dataFormat->checkedAction()->text() == "64 bit floating point")
m_dataFormat = 5;
else if (dataFormat->checkedAction()->text() == "80 bit floating point")
m_dataFormat = 6;
} }

View File

@ -83,6 +83,8 @@ protected:
ID_4_BYTE_CHUNKS, ID_4_BYTE_CHUNKS,
ID_8_BYTE_CHUNKS, ID_8_BYTE_CHUNKS,
ID_FLOATING_POINT_32BIT, ID_FLOATING_POINT_32BIT,
ID_FLOATING_POINT_64BIT,
ID_FLOATING_POINT_80BIT,
ID_LOGICAL_ADDRESSES, ID_LOGICAL_ADDRESSES,
ID_PHYSICAL_ADDRESSES, ID_PHYSICAL_ADDRESSES,
ID_REVERSE_VIEW, ID_REVERSE_VIEW,

View File

@ -36,6 +36,8 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS, TEXT("4-byte chunks\tCtrl+4")); AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS, TEXT("4-byte chunks\tCtrl+4"));
AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS, TEXT("8-byte chunks\tCtrl+8")); AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS, TEXT("8-byte chunks\tCtrl+8"));
AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_32BIT, TEXT("32 bit floating point\tCtrl+9")); AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_32BIT, TEXT("32 bit floating point\tCtrl+9"));
AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_64BIT, TEXT("64 bit floating point"));
AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_80BIT, TEXT("80 bit floating point"));
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT("")); AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
AppendMenu(optionsmenu, MF_ENABLED, ID_LOGICAL_ADDRESSES, TEXT("Logical Addresses\tCtrl+L")); AppendMenu(optionsmenu, MF_ENABLED, ID_LOGICAL_ADDRESSES, TEXT("Logical Addresses\tCtrl+L"));
AppendMenu(optionsmenu, MF_ENABLED, ID_PHYSICAL_ADDRESSES, TEXT("Physical Addresses\tCtrl+Y")); AppendMenu(optionsmenu, MF_ENABLED, ID_PHYSICAL_ADDRESSES, TEXT("Physical Addresses\tCtrl+Y"));
@ -182,6 +184,8 @@ void memorywin_info::update_menu()
CheckMenuItem(menu, ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 4 ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 4 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 8 ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 8 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_FLOATING_POINT_32BIT, MF_BYCOMMAND | (memview->data_format() == 9 ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_FLOATING_POINT_32BIT, MF_BYCOMMAND | (memview->data_format() == 9 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_FLOATING_POINT_64BIT, MF_BYCOMMAND | (memview->data_format() == 10 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_FLOATING_POINT_80BIT, MF_BYCOMMAND | (memview->data_format() == 11 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_LOGICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_UNCHECKED : MF_CHECKED)); CheckMenuItem(menu, ID_LOGICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_UNCHECKED : MF_CHECKED));
CheckMenuItem(menu, ID_PHYSICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_PHYSICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_REVERSE_VIEW, MF_BYCOMMAND | (memview->reverse() ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_REVERSE_VIEW, MF_BYCOMMAND | (memview->reverse() ? MF_CHECKED : MF_UNCHECKED));
@ -234,6 +238,14 @@ bool memorywin_info::handle_command(WPARAM wparam, LPARAM lparam)
memview->set_data_format(9); memview->set_data_format(9);
return true; return true;
case ID_FLOATING_POINT_64BIT:
memview->set_data_format(10);
return true;
case ID_FLOATING_POINT_80BIT:
memview->set_data_format(11);
return true;
case ID_LOGICAL_ADDRESSES: case ID_LOGICAL_ADDRESSES:
memview->set_physical(false); memview->set_physical(false);
return true; return true;