diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 20263e435c7..b431bb88732 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -272,6 +272,11 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu m_console.register_command("fo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); m_console.register_command("findo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); + m_console.register_command("fill", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); + m_console.register_command("filld", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); + m_console.register_command("filli", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); + m_console.register_command("fillo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); + m_console.register_command("dasm", CMDFLAG_NONE, 0, 3, 5, std::bind(&debugger_commands::execute_dasm, this, _1, _2)); m_console.register_command("trace", CMDFLAG_NONE, 0, 1, 4, std::bind(&debugger_commands::execute_trace, this, _1, _2)); @@ -2909,6 +2914,113 @@ void debugger_commands::execute_find(int ref, const std::vector &pa } +//------------------------------------------------- +// execute_fill - execute the fill command +//------------------------------------------------- + +void debugger_commands::execute_fill(int ref, const std::vector ¶ms) +{ + u64 offset, length; + address_space *space; + + // validate parameters + if (!validate_number_parameter(params[0], offset)) + return; + if (!validate_number_parameter(params[1], length)) + return; + if (!validate_cpu_space_parameter(nullptr, ref, space)) + return; + + // further validation + offset = space->address_to_byte(offset & space->addrmask()); + int cur_data_size = space->addr_shift() > 0 ? 2 : 1 << -space->addr_shift(); + if (cur_data_size == 0) + cur_data_size = 1; + + // parse the data parameters + u64 fill_data[256]; + u8 fill_data_size[256]; + int data_count = 0; + for (int i = 2; i < params.size(); i++) + { + const char *pdata = params[i].c_str(); + size_t pdatalen = strlen(pdata) - 1; + + // check for a string + if (pdata[0] == '"' && pdata[pdatalen] == '"') + { + for (int j = 1; j < pdatalen; j++) + { + fill_data[data_count] = pdata[j]; + fill_data_size[data_count++] = 1; + } + } + + // otherwise, validate as a number + else + { + // check for a 'b','w','d',or 'q' prefix + fill_data_size[data_count] = cur_data_size; + if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 1; pdata += 2; } + if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 2; pdata += 2; } + if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 4; pdata += 2; } + if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 8; pdata += 2; } + + // validate as a number + if (!validate_number_parameter(pdata, fill_data[data_count++])) + return; + } + } + if (data_count == 0) + return; + + // now fill memory + device_memory_interface &memory = space->device().memory(); + auto dis = space->device().machine().disable_side_effects(); + u64 count = space->address_to_byte(length); + while (count != 0) + { + // write the entire string + for (int j = 0; j < data_count; j++) + { + offs_t address = space->byte_to_address(offset) & space->logaddrmask(); + if (!memory.translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, address)) + { + m_console.printf("Fill aborted due to page fault at %0*X\n", space->logaddrchars(), space->byte_to_address(offset) & space->logaddrmask()); + length = 0; + break; + } + switch (fill_data_size[j]) + { + case 1: + space->write_byte(address, fill_data[j]); + break; + + case 2: + space->write_word_unaligned(address, fill_data[j]); + break; + + case 4: + space->write_dword_unaligned(address, fill_data[j]); + break; + + case 8: + space->read_qword_unaligned(address, fill_data[j]); + break; + } + offset += fill_data_size[j]; + if (count <= fill_data_size[j]) + { + count = 0; + break; + } + else + count -= fill_data_size[j]; + } + } +} + + /*------------------------------------------------- execute_dasm - execute the dasm command -------------------------------------------------*/ diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index 04f54a4d75d..dad1979da39 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -152,6 +152,7 @@ private: void execute_cheatundo(int ref, const std::vector ¶ms); void execute_dasm(int ref, const std::vector ¶ms); void execute_find(int ref, const std::vector ¶ms); + void execute_fill(int ref, const std::vector ¶ms); void execute_trace(int ref, const std::vector ¶ms); void execute_traceover(int ref, const std::vector ¶ms); void execute_traceflush(int ref, const std::vector ¶ms); diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp index 014c574c586..88dcf85bda8 100644 --- a/src/emu/debug/debughlp.cpp +++ b/src/emu/debug/debughlp.cpp @@ -602,6 +602,23 @@ static const help_item static_help_list[] = " Searches the address range 0000-7fff for the string \"AAR\" followed by a dword-sized 0 " "followed by the string \"BEN\", followed by a word-sized 0.\n" }, + { + "fill", + "\n" + " fill[{d|i}]
,[,[,...]]\n" + "\n" + "The fill/filld/filli commands overwrite a block of memory with copies of the specified " + "sequence of data. 'fill' will fill program space memory, while 'filld' will fill data space " + "memory and 'filli' will fill I/O space memory.
indicates the address to begin " + "writing, and indicates how much memory to fill. can either be a quoted " + "string or a numeric value or expression. Non-string data is written by default in the " + "native word size of the CPU. To override the data size for non-strings, you can prefix " + "the value with b. to force byte-sized fill, w. for word-sized fill, d. for dword-sized, " + "and q. for qword-sized. Overrides are remembered, so if you want to fill with a series of " + "words, you need only to prefix the first value with a w. Note also that you can intermix " + "sizes in order to perform more complex fills. The fill operation may be truncated if a page " + "fault occurs or if part of the sequence or string would fall beyond
+-1.\n" + }, { "dump", "\n"