summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/debugcmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/debugcmd.cpp')
-rw-r--r--src/emu/debug/debugcmd.cpp366
1 files changed, 224 insertions, 142 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index c1e96054164..0c7715b523b 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -14,6 +14,7 @@
#include "debugcmd.h"
#include "debugcon.h"
#include "debugcpu.h"
+#include "debugbuf.h"
#include "express.h"
#include "debughlp.h"
#include "debugvw.h"
@@ -1644,7 +1645,6 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa
u64 offset, endoffset, length;
address_space *space;
FILE *f;
- u64 i;
/* validate parameters */
if (!validate_number_parameter(params[1], offset))
@@ -1655,8 +1655,9 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa
return;
/* determine the addresses to write */
- endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
- offset = space->address_to_byte(offset) & space->bytemask();
+ endoffset = (offset + length - 1) & space->addrmask();
+ offset = offset & space->addrmask();
+ endoffset ++;
/* open the file */
f = fopen(params[0].c_str(), "wb");
@@ -1667,10 +1668,46 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa
}
/* now write the data out */
- for (i = offset; i <= endoffset; i++)
+ auto dis = space->machine().disable_side_effect();
+ switch (space->addrbus_shift())
{
- u8 byte = m_cpu.read_byte(*space, i, true);
- fwrite(&byte, 1, 1, f);
+ case -3:
+ for (offs_t i = offset; i != endoffset; i++)
+ {
+ u64 data = space->read_qword(i);
+ fwrite(&data, 8, 1, f);
+ }
+ break;
+ case -2:
+ for (offs_t i = offset; i != endoffset; i++)
+ {
+ u32 data = space->read_dword(i);
+ fwrite(&data, 4, 1, f);
+ }
+ break;
+ case -1:
+ for (offs_t i = offset; i != endoffset; i++)
+ {
+ u16 byte = space->read_word(i);
+ fwrite(&byte, 2, 1, f);
+ }
+ break;
+ case 0:
+ for (offs_t i = offset; i != endoffset; i++)
+ {
+ u8 byte = space->read_byte(i);
+ fwrite(&byte, 1, 1, f);
+ }
+ break;
+ case 3:
+ offset &= ~15;
+ endoffset &= ~15;
+ for (offs_t i = offset; i != endoffset; i+=16)
+ {
+ u16 byte = space->read_word(i >> 4);
+ fwrite(&byte, 2, 1, f);
+ }
+ break;
}
/* close the file */
@@ -1687,7 +1724,6 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa
{
u64 offset, endoffset, length = 0;
address_space *space;
- u64 i;
// validate parameters
if (!validate_number_parameter(params[1], offset))
@@ -1712,19 +1748,66 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa
f.seekg(0, std::ios::end);
length = f.tellg();
f.seekg(0);
+ if (space->addrbus_shift() < 0)
+ length >>= -space->addrbus_shift();
+ else if (space->addrbus_shift() > 0)
+ length <<= space->addrbus_shift();
}
// determine the addresses to read
- endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
- offset = space->address_to_byte(offset) & space->bytemask();
-
+ endoffset = (offset + length - 1) & space->addrmask();
+ offset = offset & space->addrmask();
+ offs_t i = 0;
// now read the data in, ignore endoffset and load entire file if length has been set to zero (offset-1)
- for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++)
+ switch (space->addrbus_shift())
{
- char byte;
- f.read(&byte, 1);
- if (f)
- m_cpu.write_byte(*space, i, byte, true);
+ case -3:
+ for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++)
+ {
+ u64 data;
+ f.read((char *)&data, 8);
+ if (f)
+ space->write_qword(i, data);
+ }
+ break;
+ case -2:
+ for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++)
+ {
+ u32 data;
+ f.read((char *)&data, 4);
+ if (f)
+ space->write_dword(i, data);
+ }
+ break;
+ case -1:
+ for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++)
+ {
+ u16 data;
+ f.read((char *)&data, 2);
+ if (f)
+ space->write_word(i, data);
+ }
+ break;
+ case 0:
+ for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++)
+ {
+ u8 data;
+ f.read((char *)&data, 1);
+ if (f)
+ space->write_byte(i, data);
+ }
+ break;
+ case 3:
+ offset &= ~15;
+ endoffset &= ~15;
+ for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 16); i+=16)
+ {
+ u16 data;
+ f.read((char *)&data, 2);
+ if (f)
+ space->write_word(i >> 4, data);
+ }
+ break;
}
if (!f.good())
@@ -1767,6 +1850,9 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa
if (!validate_cpu_space_parameter((params.size() > 6) ? params[6].c_str() : nullptr, ref, space))
return;
+ int shift = space->addrbus_shift();
+ u64 granularity = shift > 0 ? 2 : 1 << -shift;
+
/* further validation */
if (width == 0)
width = space->data_width() / 8;
@@ -1777,14 +1863,19 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa
m_console.printf("Invalid width! (must be 1,2,4 or 8)\n");
return;
}
+ if (width < granularity)
+ {
+ m_console.printf("Invalid width! (must be at least %d)\n", granularity);
+ return;
+ }
if (rowsize == 0 || (rowsize % width) != 0)
{
m_console.printf("Invalid row size! (must be a positive multiple of %d)\n", width);
return;
}
- u64 endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
- offset = space->address_to_byte(offset) & space->bytemask();
+ u64 endoffset = (offset + length - 1) & space->addrmask();
+ offset = offset & space->addrmask();
/* open the file */
FILE* f = fopen(params[0].c_str(), "w");
@@ -1797,13 +1888,22 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa
/* now write the data out */
util::ovectorstream output;
output.reserve(200);
- for (u64 i = offset; i <= endoffset; i += rowsize)
+
+ if (shift > 0)
+ width <<= shift;
+ else if(shift < 0)
+ width >>= -shift;
+
+ auto dis = space->machine().disable_side_effect();
+ bool be = space->endianness() == ENDIANNESS_BIG;
+
+ for (offs_t i = offset; i <= endoffset; i += rowsize)
{
output.clear();
output.rdbuf()->clear();
/* print the address */
- util::stream_format(output, "%0*X: ", space->logaddrchars(), u32(space->byte_to_address(i)));
+ util::stream_format(output, "%0*X: ", space->logaddrchars(), i);
/* print the bytes */
for (u64 j = 0; j < rowsize; j += width)
@@ -1813,8 +1913,21 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa
offs_t curaddr = i + j;
if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr))
{
- u64 value = m_cpu.read_memory(*space, i + j, width, true);
- util::stream_format(output, " %0*X", width * 2, value);
+ switch (width)
+ {
+ case 8:
+ util::stream_format(output, " %016X", space->read_qword(i+j));
+ break;
+ case 4:
+ util::stream_format(output, " %08X", space->read_dword(i+j));
+ break;
+ case 2:
+ util::stream_format(output, " %04X", space->read_word(i+j));
+ break;
+ case 1:
+ util::stream_format(output, " %02X", space->read_byte(i+j));
+ break;
+ }
}
else
{
@@ -1834,8 +1947,26 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa
offs_t curaddr = i + j;
if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr))
{
- u8 byte = m_cpu.read_byte(*space, i + j, true);
- util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.');
+ u64 data = 0;
+ switch (width)
+ {
+ case 8:
+ data = space->read_qword(i+j);
+ break;
+ case 4:
+ data = space->read_dword(i+j);
+ break;
+ case 2:
+ data = space->read_word(i+j);
+ break;
+ case 1:
+ data = space->read_byte(i+j);
+ break;
+ }
+ for (unsigned int b = 0; b != width; b++) {
+ u8 byte = data >> (8 * (be ? (width-i-b) : b));
+ util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.');
+ }
}
else
{
@@ -1920,8 +2051,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string
{
for (address_map_entry &entry : space->map()->m_entrylist)
{
- cheat_region[region_count].offset = space->address_to_byte(entry.m_addrstart) & space->bytemask();
- cheat_region[region_count].endoffset = space->address_to_byte(entry.m_addrend) & space->bytemask();
+ cheat_region[region_count].offset = entry.m_addrstart & space->addrmask();
+ cheat_region[region_count].endoffset = entry.m_addrend & space->addrmask();
cheat_region[region_count].share = entry.m_share;
cheat_region[region_count].disabled = (entry.m_write.m_type == AMH_RAM) ? false : true;
@@ -1944,8 +2075,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string
return;
/* force region to the specified range */
- cheat_region[region_count].offset = space->address_to_byte(offset) & space->bytemask();
- cheat_region[region_count].endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
+ cheat_region[region_count].offset = offset & space->addrmask();
+ cheat_region[region_count].endoffset = (offset + length - 1) & space->addrmask();
cheat_region[region_count].share = nullptr;
cheat_region[region_count].disabled = false;
region_count++;
@@ -2320,9 +2451,9 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa
return;
/* further validation */
- endoffset = space->address_to_byte(offset + length - 1) & space->bytemask();
- offset = space->address_to_byte(offset) & space->bytemask();
- cur_data_size = space->address_to_byte(1);
+ endoffset = (offset + length - 1) & space->addrmask();
+ offset = offset & space->addrmask();
+ cur_data_size = space->addrbus_shift() > 0 ? 2 : 1 << -space->addrbus_shift();
if (cur_data_size == 0)
cur_data_size = 1;
@@ -2403,10 +2534,7 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa
void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &params)
{
u64 offset, length, bytes = 1;
- int minbytes, maxbytes, byteswidth;
- address_space *space, *decrypted_space;
- FILE *f;
- int j;
+ address_space *space;
/* validate parameters */
if (!validate_number_parameter(params[1], offset))
@@ -2417,10 +2545,6 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa
return;
if (!validate_cpu_space_parameter(params.size() > 4 ? params[4].c_str() : nullptr, AS_PROGRAM, space))
return;
- if (space->device().memory().has_space(AS_OPCODES))
- decrypted_space = &space->device().memory().space(AS_OPCODES);
- else
- decrypted_space = space;
/* determine the width of the bytes */
device_disasm_interface *dasmintf;
@@ -2429,104 +2553,72 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa
m_console.printf("No disassembler available for %s\n", space->device().name());
return;
}
- minbytes = dasmintf->min_opcode_bytes();
- maxbytes = dasmintf->max_opcode_bytes();
- byteswidth = 0;
- if (bytes)
- {
- byteswidth = (maxbytes + (minbytes - 1)) / minbytes;
- byteswidth *= (2 * minbytes) + 1;
- }
- /* open the file */
- f = fopen(params[0].c_str(), "w");
- if (!f)
- {
- m_console.printf("Error opening file '%s'\n", params[0].c_str());
- return;
- }
+ /* build the data, check the maximum size of the opcodes and disasm */
+ std::vector<offs_t> pcs;
+ std::vector<std::string> instructions;
+ std::vector<std::string> tpc;
+ std::vector<std::string> topcodes;
+ int max_opcodes_size = 0;
+ int max_disasm_size = 0;
+
+ debug_disasm_buffer buffer(space->device());
- /* now write the data out */
- util::ovectorstream output;
- util::ovectorstream disasm;
- output.reserve(512);
for (u64 i = 0; i < length; )
{
- int pcbyte = space->address_to_byte(offset + i) & space->bytemask();
- const char *comment;
- offs_t tempaddr;
- int numbytes = 0;
- output.clear();
- output.rdbuf()->clear();
- disasm.clear();
- disasm.seekp(0);
+ std::string instruction;
+ offs_t next_offset;
+ offs_t size;
+ u32 info;
+ buffer.disassemble(offset, instruction, next_offset, size, info);
+ pcs.push_back(offset);
+ instructions.emplace_back(instruction);
+ tpc.emplace_back(buffer.pc_to_string(offset));
+ topcodes.emplace_back(buffer.data_to_string(offset, size, true));
- /* print the address */
- stream_format(output, "%0*X: ", space->logaddrchars(), u32(space->byte_to_address(pcbyte)));
+ int osize = topcodes.back().size();
+ if(osize > max_opcodes_size)
+ max_opcodes_size = osize;
- /* make sure we can translate the address */
- tempaddr = pcbyte;
- if (space->device().memory().translate(space->spacenum(), TRANSLATE_FETCH_DEBUG, tempaddr))
- {
- {
- u8 opbuf[64], argbuf[64];
+ int dsize = instructions.back().size();
+ if(dsize > max_disasm_size)
+ max_disasm_size = dsize;
- /* fetch the bytes up to the maximum */
- for (numbytes = 0; numbytes < maxbytes; numbytes++)
- {
- opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1);
- }
+ i += size;
+ offset = next_offset;
+ }
- /* disassemble the result */
- i += numbytes = dasmintf->disassemble(disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
- }
+ /* write the data */
+ std::ofstream f(params[0]);
+ if (!f.good())
+ {
+ m_console.printf("Error opening file '%s'\n", params[0]);
+ return;
+ }
- /* print the bytes */
- if (bytes)
- {
- auto const startdex = output.tellp();
- numbytes = space->address_to_byte(numbytes);
- for (j = 0; j < numbytes; j += minbytes)
- stream_format(output, "%0*X ", minbytes * 2, m_cpu.read_opcode(*decrypted_space, pcbyte + j, minbytes));
- if ((output.tellp() - startdex) < byteswidth)
- stream_format(output, "%*s", byteswidth - (output.tellp() - startdex), "");
- stream_format(output, " ");
- }
- }
- else
+ if (bytes)
+ {
+ for(unsigned int i=0; i != pcs.size(); i++)
{
- disasm << "<unmapped>";
- i += minbytes;
+ const char *comment = space->device().debug()->comment_text(pcs[i]);
+ if (comment)
+ util::stream_format(f, "%s: %-*s %-*s // %s\n", tpc[i], max_opcodes_size, topcodes[i], max_disasm_size, instructions[i], comment);
+ else
+ util::stream_format(f, "%s: %-*s %s\n", tpc[i], max_opcodes_size, topcodes[i], instructions[i]);
}
-
- /* add the disassembly */
- disasm.put('\0');
- stream_format(output, "%s", &disasm.vec()[0]);
-
- /* attempt to add the comment */
- comment = space->device().debug()->comment_text(tempaddr);
- if (comment != nullptr)
+ }
+ else
+ {
+ for(unsigned int i=0; i != pcs.size(); i++)
{
- /* somewhat arbitrary guess as to how long most disassembly lines will be [column 60] */
- if (output.tellp() < 60)
- {
- /* pad the comment space out to 60 characters and null-terminate */
- while (output.tellp() < 60) output.put(' ');
-
- stream_format(output, "// %s", comment);
- }
+ const char *comment = space->device().debug()->comment_text(pcs[i]);
+ if (comment)
+ util::stream_format(f, "%s: %-*s // %s\n", tpc[i], max_disasm_size, instructions[i], comment);
else
- stream_format(output, "\t// %s", comment);
+ util::stream_format(f, "%s: %s\n", tpc[i], instructions[i]);
}
-
- /* output the result */
- auto const &text(output.vec());
- fprintf(f, "%.*s\n", int(unsigned(text.size())), &text[0]);
}
- /* close the file */
- fclose(f);
m_console.printf("Data dumped successfully\n");
}
@@ -2640,13 +2732,9 @@ void debugger_commands::execute_traceflush(int ref, const std::vector<std::strin
void debugger_commands::execute_history(int ref, const std::vector<std::string> &params)
{
/* validate parameters */
- address_space *space, *decrypted_space;
+ address_space *space;
if (!validate_cpu_space_parameter(!params.empty() ? params[0].c_str() : nullptr, AS_PROGRAM, space))
return;
- if (space->device().memory().has_space(AS_OPCODES))
- decrypted_space = &space->device().memory().space(AS_OPCODES);
- else
- decrypted_space = space;
u64 count = device_debug::HISTORY_SIZE;
if (params.size() > 1 && !validate_number_parameter(params[1], count))
@@ -2665,25 +2753,19 @@ void debugger_commands::execute_history(int ref, const std::vector<std::string>
m_console.printf("No disassembler available for %s\n", space->device().name());
return;
}
- int maxbytes = dasmintf->max_opcode_bytes();
+
+ debug_disasm_buffer buffer(space->device());
+
for (int index = 0; index < (int) count; index++)
{
offs_t pc = debug->history_pc(-index);
+ std::string instruction;
+ offs_t next_offset;
+ offs_t size;
+ u32 info;
+ buffer.disassemble(pc, instruction, next_offset, size, info);
- /* fetch the bytes up to the maximum */
- offs_t pcbyte = space->address_to_byte(pc) & space->bytemask();
- u8 opbuf[64], argbuf[64];
- for (int numbytes = 0; numbytes < maxbytes; numbytes++)
- {
- opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1);
- }
-
- util::ovectorstream buffer;
- dasmintf->disassemble(buffer, pc, opbuf, argbuf);
- buffer.put('\0');
-
- m_console.printf("%0*X: %s\n", space->logaddrchars(), pc, &buffer.vec()[0]);
+ m_console.printf("%s: %s\n", buffer.pc_to_string(pc), instruction);
}
}
@@ -2882,7 +2964,7 @@ void debugger_commands::execute_map(int ref, const std::vector<std::string> &par
for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++)
{
static const char *const intnames[] = { "Read", "Write", "Fetch" };
- taddress = space->address_to_byte(address) & space->bytemask();
+ taddress = address & space->addrmask();
if (space->device().memory().translate(space->spacenum(), intention, taddress))
{
const char *mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress);
@@ -2890,7 +2972,7 @@ void debugger_commands::execute_map(int ref, const std::vector<std::string> &par
"%7s: %0*X logical == %0*X physical -> %s\n",
intnames[intention & 3],
space->logaddrchars(), address,
- space->addrchars(), space->byte_to_address(taddress),
+ space->addrchars(), taddress,
mapname);
}
else