diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/debug/debugcmd.cpp | 180 | ||||
-rw-r--r-- | src/emu/debug/debugcmd.h | 1 | ||||
-rw-r--r-- | src/emu/debug/debughlp.cpp | 22 |
3 files changed, 203 insertions, 0 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 9b33eac7b45..a5856a9b794 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -251,6 +251,11 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu m_console.register_command("dumpi", CMDFLAG_NONE, AS_IO, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); m_console.register_command("dumpo", CMDFLAG_NONE, AS_OPCODES, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); + m_console.register_command("strdump", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); + m_console.register_command("strdumpd", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); + m_console.register_command("strdumpi", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); + m_console.register_command("strdumpo", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); + m_console.register_command("cheatinit", CMDFLAG_NONE, 0, 0, 4, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); m_console.register_command("ci", CMDFLAG_NONE, 0, 0, 4, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); @@ -2391,6 +2396,181 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa } +//------------------------------------------------- +// execute_strdump - execute the strdump command +//------------------------------------------------- + +void debugger_commands::execute_strdump(int ref, const std::vector<std::string> ¶ms) +{ + // validate parameters + u64 offset; + if (!validate_number_parameter(params[1], offset)) + return; + + u64 length; + if (!validate_number_parameter(params[2], length)) + return; + + u64 term = 0; + if (params.size() > 3 && !validate_number_parameter(params[3], term)) + return; + + address_space *space; + if (!validate_cpu_space_parameter((params.size() > 4) ? params[4].c_str() : nullptr, ref, space)) + return; + + // further validation + if (term >= 0x100 && term != u64(-0x80)) + { + m_console.printf("Invalid termination character\n"); + return; + } + + // open the file + FILE *f = fopen(params[0].c_str(), "w"); + if (!f) + { + m_console.printf("Error opening file '%s'\n", params[0].c_str()); + return; + } + + const int shift = space->addr_shift(); + const unsigned delta = (shift >= 0) ? (1 << shift) : 1; + const unsigned width = (shift >= 0) ? 1 : (1 << -shift); + const bool be = space->endianness() == ENDIANNESS_BIG; + + offset = offset & space->addrmask(); + if (shift > 0) + length >>= shift; + + // now write the data out + util::ovectorstream output; + output.reserve(200); + + auto dis = space->device().machine().disable_side_effects(); + + bool terminated = true; + while (length-- != 0) + { + if (terminated) + { + terminated = false; + output.clear(); + output.rdbuf()->clear(); + + // print the address + util::stream_format(output, "%0*X: \"", space->logaddrchars(), offset); + } + + // get the character data + u64 data = 0; + offs_t curaddr = offset; + if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) + { + switch (width) + { + case 1: + data = space->read_byte(curaddr); + break; + + case 2: + data = space->read_word(curaddr); + if (be) + data = swapendian_int16(data); + break; + + case 4: + data = space->read_dword(curaddr); + if (be) + data = swapendian_int32(data); + break; + + case 8: + data = space->read_qword(curaddr); + if (be) + data = swapendian_int64(data); + break; + } + } + + // print the characters + for (int n = 0; n < width; n++) + { + // check for termination within word + if (terminated) + { + terminated = false; + + // output the result + auto const &text = output.vec(); + fprintf(f, "%.*s\"\n", int(unsigned(text.size())), &text[0]); + output.clear(); + output.rdbuf()->clear(); + + // print the address + util::stream_format(output, "%0*X.%d: \"", space->logaddrchars(), offset, n); + } + + u8 ch = data & 0xff; + data >>= 8; + + // check for termination + if (term == u64(-0x80)) + { + if (BIT(ch, 7)) + { + terminated = true; + ch &= 0x7f; + } + } + else if (ch == term) + { + terminated = true; + continue; + } + + // check for non-ASCII characters + if (ch < 0x20 || ch >= 0x7f) + { + // use special or octal escape + if (ch >= 0x07 && ch <= 0x0d) + util::stream_format(output, "\\%c", "abtnvfr"[ch - 0x07]); + else + util::stream_format(output, "\\%03o", ch); + } + else + { + if (ch == '"' || ch == '\\') + output << '\\'; + output << char(ch); + } + } + + if (terminated) + { + // output the result + auto const &text = output.vec(); + fprintf(f, "%.*s\"\n", int(unsigned(text.size())), &text[0]); + output.clear(); + output.rdbuf()->clear(); + } + + offset += delta; + } + + if (!terminated) + { + // 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"); +} + + /*------------------------------------------------- execute_cheatinit - initialize the cheat system -------------------------------------------------*/ diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index e2ebec7e2fc..0fad46d7009 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -151,6 +151,7 @@ private: void execute_load(int ref, const std::vector<std::string> ¶ms); void execute_loadregion(int ref, const std::vector<std::string> ¶ms); void execute_dump(int ref, const std::vector<std::string> ¶ms); + void execute_strdump(int ref, const std::vector<std::string> ¶ms); void execute_cheatinit(int ref, const std::vector<std::string> ¶ms); void execute_cheatnext(int ref, const std::vector<std::string> ¶ms); void execute_cheatlist(int ref, const std::vector<std::string> ¶ms); diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp index 55e3524f7ef..dc6c204f03f 100644 --- a/src/emu/debug/debughlp.cpp +++ b/src/emu/debug/debughlp.cpp @@ -112,10 +112,17 @@ static const help_item static_help_list[] = " f[ind] <address>,<length>[,<data>[,...]] -- search program memory for data\n" " f[ind]d <address>,<length>[,<data>[,...]] -- search data memory for data\n" " f[ind]i <address>,<length>[,<data>[,...]] -- search I/O memory for data\n" + " fill <address>,<length>[,<data>[,...]] -- fill program memory with data\n" + " filld <address>,<length>[,<data>[,...]] -- fill data memory with data\n" + " filli <address>,<length>[,<data>[,...][ -- fill I/O memory with data\n" " dump <filename>,<address>,<length>[,<size>[,<ascii>[,<rowsize>[,<CPU>]]]] -- dump program memory as text\n" " dumpd <filename>,<address>,<length>[,<size>[,<ascii>[,<rowsize>[,<CPU>]]]] -- dump data memory as text\n" " dumpi <filename>,<address>,<length>[,<size>[,<ascii>[,<rowsize>[,<CPU>]]]] -- dump I/O memory as text\n" " dumpo <filename>,<address>,<length>[,<size>[,<ascii>[,<rowsize>[,<CPU>]]]] -- dump opcodes memory as text\n" + " strdump <filename>,<address>,<length>[,<term>[,<CPU>]] -- dump ASCII strings from program memory\n" + " strdumpd <filename>,<address>,<length>[,<term>[,<CPU>]] -- dump ASCII strings from data memory\n" + " strdumpi <filename>,<address>,<length>[,<term>[,<CPU>]] -- dump ASCII strings from I/O memory\n" + " strdumpo <filename>,<address>,<length>[,<term>[,<CPU>]] -- dump ASCII strings from opcodes memory\n" " save <filename>,<address>,<length>[,<CPU>] -- save binary program memory to the given file\n" " saved <filename>,<address>,<length>[,<CPU>] -- save binary data memory to the given file\n" " savei <filename>,<address>,<length>[,<CPU>] -- save binary I/O memory to the given file\n" @@ -646,6 +653,21 @@ static const help_item static_help_list[] = "to the file 'harddriv.dmp'.\n" }, { + "strdump", + "\n" + " strdump[{d|i}] <filename>,<address>,<length>[,<term>[,<CPU>]]\n" + "\n" + "The strdump/strdumpd/strdumpi/strdumpo commands dump memory to the text file specified in the " + "<filename> parameter. 'strdump' will dump program space memory, while 'strdumpd' will dump data " + "space memory, 'strdumpi' will dump I/O space memory and 'strdumpo' will dump opcodes memory. " + "<address> indicates the address of the start of dumping, and <length> indicates how much memory " + "to dump. The range <address> through <address>+<length>-1 inclusive will be output to the file. " + "By default, the data will be interpreted as a series of null-terminated strings, and the dump " + "will have one string on each line and C-style escapes for non-ASCII characters. The optional " + "<term> parameter can be used to specify a different character as the string terminator. Finally, " + "you can dump memory from another CPU by specifying the <CPU> parameter.\n" + }, + { "save", "\n" " save[{d|i}] <filename>,<address>,<length>[,<CPU>]\n" |