First commit for issue #476

"byte per chunk" is sostituted by "data format"
  data formats lesser than 9 work as before, data format 9 is 32 but floating point
  in the debug_view_memory class method bytes_per_chunk is substituted by get_data_format, set_bytes_per_chunk is substituted by set_data_format
  floating point values cannot be edited
  currently floating point values are available only in the windows debugger, next commit will add them to the qt debugger, osx i won't be able to do it
  afterwards 64 and 80 bit formats will be added
This commit is contained in:
yz70s 2015-11-29 18:02:43 +01:00
parent 60083f5094
commit b052dcb402
8 changed files with 193 additions and 77 deletions

View File

@ -94,9 +94,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)
@ -190,6 +192,9 @@ 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 (m_bytes_per_chunk > 8)
m_bytes_per_chunk = 8;
m_data_format = m_bytes_per_chunk;
if (source.m_space != NULL)
m_expression.set_context(&source.m_space->device().debug()->symtable());
else
@ -198,6 +203,22 @@ void debug_view_memory::view_notify(debug_view_notification type)
}
//-------------------------------------------------
// uint32_to_float - return a floating point number
// whose 32 bit representation is value
//-------------------------------------------------
INLINE float uint32_to_float(UINT32 value)
{
union {
float f;
UINT32 i;
} v;
v.i = value;
return v.f;
}
//-------------------------------------------------
// view_update - update the contents of the
// memory view
@ -255,17 +276,41 @@ 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;
int spacing = posdata.m_spacing;
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] : '*';
if (m_data_format <= 8) {
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[20];
spacing = 16;
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
if (ismapped)
sprintf(valuetext, "%g", uint32_to_float((UINT32)chunkdata));
else {
valuetext[0] = '*';
valuetext[1] = 0;
}
// first copy the text
for (ch = 0; (ch < 16) && (valuetext[ch] != 0); ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = valuetext[ch];
// then fill with spaces
for (; ch < 16; ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = ' ';
}
}
// generate the ASCII data
@ -295,6 +340,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)
{
@ -478,7 +527,10 @@ 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
m_section[1].m_width = 1 + 16 * m_chunks_per_row + 1;
m_section[2].m_width = m_ascii_view ? (1 + m_bytes_per_row + 1) : 0;
// compute the section positions
@ -550,24 +602,43 @@ debug_view_memory::cursor_pos debug_view_memory::get_cursor_pos(const debug_view
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;
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;
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;
// 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;
// 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 / 16;
// 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;
}
@ -594,13 +665,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 + 16 * chunknum;
}
// clamp to the window bounds
m_cursor.x = MIN(m_cursor.x, m_total.x);
@ -734,32 +810,6 @@ void debug_view_memory::set_expression(const char *expression)
}
//-------------------------------------------------
// set_bytes_per_chunk - specify the number of
// bytes displayed per chunk
//-------------------------------------------------
void debug_view_memory::set_bytes_per_chunk(UINT8 chunkbytes)
{
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
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_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
@ -777,6 +827,59 @@ void debug_view_memory::set_chunks_per_row(UINT32 rowchunks)
}
//-------------------------------------------------
// set_data_format - specify what kind of values
// are shown, 1-8 8-64 bits, 9 32bit floating point
//-------------------------------------------------
void debug_view_memory::set_data_format(int format)
{
cursor_pos pos;
// should never be
if (format <= 0)
return;
// no need to change
if (format == m_data_format)
return;
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;
m_bytes_per_chunk = 4;
}
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

View File

@ -50,7 +50,7 @@ class debug_view_memory : public debug_view
public:
// getters
const char *expression() { return m_expression.string(); }
UINT8 bytes_per_chunk() { flush_updates(); return m_bytes_per_chunk; }
int get_data_format() { flush_updates(); return m_data_format; }
UINT32 chunks_per_row() { flush_updates(); return m_chunks_per_row; }
bool reverse() const { return m_reverse_view; }
bool ascii() const { return m_ascii_view; }
@ -59,8 +59,8 @@ public:
// setters
void set_expression(const char *expression);
void set_bytes_per_chunk(UINT8 chunkbytes);
void set_chunks_per_row(UINT32 rowchunks);
void set_data_format(int format); // 1-8 current values 9 32bit floating point
void set_reverse(bool reverse);
void set_ascii(bool reverse);
void set_physical(bool physical);
@ -99,9 +99,11 @@ private:
debug_view_expression m_expression; // expression describing the start address
UINT32 m_chunks_per_row; // number of chunks displayed per line
UINT8 m_bytes_per_chunk; // bytes per chunk
int m_data_format; // 1-8 current values 9 32bit floating point
bool m_reverse_view; // reverse-endian view?
bool m_ascii_view; // display ASCII characters?
bool m_no_translation; // don't run addresses through the cpu translation hook
bool m_edit_enabled; // can modify contents ?
offs_t m_maxaddr; // (derived) maximum address to display
UINT32 m_bytes_per_row; // (derived) number of bytes displayed per line
UINT32 m_byte_offset; // (derived) offset of starting visible byte

View File

@ -33,7 +33,7 @@
if (action == @selector(showChunkSize:))
{
[item setState:((tag == memview->bytes_per_chunk()) ? NSOnState : NSOffState)];
[item setState:((tag == memview->get_data_format()) ? NSOnState : NSOffState)];
return YES;
}
else if (action == @selector(showPhysicalAddresses:))
@ -171,7 +171,7 @@
- (IBAction)showChunkSize:(id)sender {
downcast<debug_view_memory *>(view)->set_bytes_per_chunk([sender tag]);
downcast<debug_view_memory *>(view)->set_data_format([sender tag]);
}

View File

@ -143,7 +143,7 @@ void MemoryWindow::memoryRegionChanged(int index)
// Update the chunk size radio buttons to the memory region's default
debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
switch(memView->bytes_per_chunk())
switch(memView->get_data_format())
{
case 1: chunkSizeMenuItem("chunkActOne")->setChecked(true); break;
case 2: chunkSizeMenuItem("chunkActTwo")->setChecked(true); break;
@ -176,15 +176,15 @@ void MemoryWindow::chunkChanged(QAction* changedTo)
debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
if (changedTo->text() == "1-byte chunks")
{
memView->set_bytes_per_chunk(1);
memView->set_data_format(1);
}
else if (changedTo->text() == "2-byte chunks")
{
memView->set_bytes_per_chunk(2);
memView->set_data_format(2);
}
else if (changedTo->text() == "4-byte chunks")
{
memView->set_bytes_per_chunk(4);
memView->set_data_format(4);
}
m_memTable->viewport()->update();
}

View File

@ -82,6 +82,7 @@ protected:
ID_2_BYTE_CHUNKS,
ID_4_BYTE_CHUNKS,
ID_8_BYTE_CHUNKS,
ID_FLOATING_POINT_32BIT,
ID_LOGICAL_ADDRESSES,
ID_PHYSICAL_ADDRESSES,
ID_REVERSE_VIEW,

View File

@ -22,9 +22,9 @@ memoryview_info::~memoryview_info()
}
UINT8 memoryview_info::bytes_per_chunk() const
UINT8 memoryview_info::data_format() const
{
return view<debug_view_memory>()->bytes_per_chunk();
return view<debug_view_memory>()->get_data_format();
}
@ -51,9 +51,9 @@ void memoryview_info::set_expression(char const *string)
view<debug_view_memory>()->set_expression(string);
}
void memoryview_info::set_bytes_per_chunk(UINT8 chunkbytes)
void memoryview_info::set_data_format(UINT8 dataformat)
{
view<debug_view_memory>()->set_bytes_per_chunk(chunkbytes);
view<debug_view_memory>()->set_data_format(dataformat);
}
void memoryview_info::set_chunks_per_row(UINT32 rowchunks)

View File

@ -20,14 +20,14 @@ public:
memoryview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent);
virtual ~memoryview_info();
UINT8 bytes_per_chunk() const;
UINT8 data_format() const;
UINT32 chunks_per_row() const;
bool reverse() const;
bool ascii() const;
bool physical() const;
void set_expression(char const *string);
void set_bytes_per_chunk(UINT8 chunkbytes);
void set_data_format(UINT8 dataformat);
void set_chunks_per_row(UINT32 rowchunks);
void set_reverse(bool reverse);
void set_physical(bool physical);

View File

@ -35,6 +35,7 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS, TEXT("2-byte chunks\tCtrl+2"));
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_FLOATING_POINT_32BIT, TEXT("32 bit floating point\tCtrl+9"));
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_PHYSICAL_ADDRESSES, TEXT("Physical Addresses\tCtrl+Y"));
@ -97,6 +98,10 @@ bool memorywin_info::handle_key(WPARAM wparam, LPARAM lparam)
SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS, 0);
return true;
case '9':
SendMessage(window(), WM_COMMAND, ID_FLOATING_POINT_32BIT, 0);
return true;
case 'L':
SendMessage(window(), WM_COMMAND, ID_LOGICAL_ADDRESSES, 0);
return true;
@ -172,10 +177,11 @@ void memorywin_info::update_menu()
memoryview_info *const memview = downcast<memoryview_info *>(m_views[0].get());
HMENU const menu = GetMenu(window());
CheckMenuItem(menu, ID_1_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 1 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_2_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 2 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 4 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->bytes_per_chunk() == 8 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_1_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 1 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_2_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 2 ? 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_FLOATING_POINT_32BIT, MF_BYCOMMAND | (memview->data_format() == 9 ? MF_CHECKED : MF_UNCHECKED));
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_REVERSE_VIEW, MF_BYCOMMAND | (memview->reverse() ? MF_CHECKED : MF_UNCHECKED));
@ -209,19 +215,23 @@ bool memorywin_info::handle_command(WPARAM wparam, LPARAM lparam)
switch (LOWORD(wparam))
{
case ID_1_BYTE_CHUNKS:
memview->set_bytes_per_chunk(1);
memview->set_data_format(1);
return true;
case ID_2_BYTE_CHUNKS:
memview->set_bytes_per_chunk(2);
memview->set_data_format(2);
return true;
case ID_4_BYTE_CHUNKS:
memview->set_bytes_per_chunk(4);
memview->set_data_format(4);
return true;
case ID_8_BYTE_CHUNKS:
memview->set_bytes_per_chunk(8);
memview->set_data_format(8);
return true;
case ID_FLOATING_POINT_32BIT:
memview->set_data_format(9);
return true;
case ID_LOGICAL_ADDRESSES: