mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Add 'fill' command to debugger. Syntax and operation are similar to 'find' command.
This commit is contained in:
parent
85a91ce999
commit
5c210560e8
@ -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<std::string> &pa
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// execute_fill - execute the fill command
|
||||
//-------------------------------------------------
|
||||
|
||||
void debugger_commands::execute_fill(int ref, const std::vector<std::string> ¶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
|
||||
-------------------------------------------------*/
|
||||
|
@ -152,6 +152,7 @@ private:
|
||||
void execute_cheatundo(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_dasm(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_find(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_fill(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_trace(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_traceover(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_traceflush(int ref, const std::vector<std::string> ¶ms);
|
||||
|
@ -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}] <address>,<length>[,<data>[,...]]\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. <address> indicates the address to begin "
|
||||
"writing, and <length> indicates how much memory to fill. <data> 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 <address>+<length>-1.\n"
|
||||
},
|
||||
{
|
||||
"dump",
|
||||
"\n"
|
||||
|
Loading…
Reference in New Issue
Block a user