diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 6927ba9b4f3..02c5986d6ad 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -3390,6 +3390,8 @@ files { MAME_DIR .. "src/mame/video/rdpblend.h", MAME_DIR .. "src/mame/video/rdptpipe.cpp", MAME_DIR .. "src/mame/video/rdptpipe.h", + MAME_DIR .. "src/mame/video/pin64.cpp", + MAME_DIR .. "src/mame/video/pin64.h", MAME_DIR .. "src/mame/drivers/hanaawas.cpp", MAME_DIR .. "src/mame/includes/hanaawas.h", MAME_DIR .. "src/mame/video/hanaawas.cpp", diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 9c30f686d08..db5099da55a 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1172,6 +1172,8 @@ files { MAME_DIR .. "src/mame/video/rdpblend.h", MAME_DIR .. "src/mame/video/rdptpipe.cpp", MAME_DIR .. "src/mame/video/rdptpipe.h", + MAME_DIR .. "src/mame/video/pin64.cpp", + MAME_DIR .. "src/mame/video/pin64.h", MAME_DIR .. "src/mame/machine/megadriv.cpp", MAME_DIR .. "src/mame/drivers/naomi.cpp", MAME_DIR .. "src/mame/includes/naomi.h", diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp index 2c758ed1020..606d1ec74f0 100644 --- a/src/frontend/mame/cheat.cpp +++ b/src/frontend/mame/cheat.cpp @@ -73,13 +73,19 @@ ***************************************************************************/ #include "emu.h" -#include "emuopts.h" +#include "cheat.h" + #include "mame.h" #include "ui/ui.h" #include "ui/menu.h" -#include "cheat.h" -#include "debug/debugcpu.h" + #include "debugger.h" +#include "emuopts.h" +#include "debug/debugcpu.h" + +#include +#include +#include #include @@ -133,18 +139,18 @@ inline std::string number_and_format::format() const //------------------------------------------------- cheat_parameter::cheat_parameter(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const ¶mnode) - : m_value(0) + : m_minval(number_and_format(paramnode.get_attribute_int("min", 0), paramnode.get_attribute_int_format("min"))) + , m_maxval(number_and_format(paramnode.get_attribute_int("max", 0), paramnode.get_attribute_int_format("max"))) + , m_stepval(number_and_format(paramnode.get_attribute_int("step", 1), paramnode.get_attribute_int_format("step"))) + , m_value(0) + , m_curtext() + , m_itemlist() { - // read the core attributes - m_minval = number_and_format(paramnode.get_attribute_int("min", 0), paramnode.get_attribute_int_format("min")); - m_maxval = number_and_format(paramnode.get_attribute_int("max", 0), paramnode.get_attribute_int_format("max")); - m_stepval = number_and_format(paramnode.get_attribute_int("step", 1), paramnode.get_attribute_int_format("step")); - // iterate over items for (util::xml::data_node const *itemnode = paramnode.get_child("item"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("item")) { // check for nullptr text - if (itemnode->get_value() == nullptr || itemnode->get_value()[0] == 0) + if (!itemnode->get_value() || !itemnode->get_value()[0]) throw emu_fatalerror("%s.xml(%d): item is missing text\n", filename, itemnode->line); // check for non-existant value @@ -152,16 +158,14 @@ cheat_parameter::cheat_parameter(cheat_manager &manager, symbol_table &symbols, throw emu_fatalerror("%s.xml(%d): item is value\n", filename, itemnode->line); // extract the parameters - uint64_t const value = itemnode->get_attribute_int("value", 0); - util::xml::data_node::int_format const format = itemnode->get_attribute_int_format("value"); + uint64_t const value(itemnode->get_attribute_int("value", 0)); + util::xml::data_node::int_format const format(itemnode->get_attribute_int_format("value")); // allocate and append a new item - auto curitem = std::make_unique(itemnode->get_value(), value, format); + item &curitem(*m_itemlist.emplace(m_itemlist.end(), itemnode->get_value(), value, format)); // ensure the maximum expands to suit - m_maxval = std::max(m_maxval, curitem->value()); - - m_itemlist.push_back(std::move(curitem)); + m_maxval = std::max(m_maxval, curitem.value()); } // add a variable to the symbol table for our value @@ -178,18 +182,20 @@ const char *cheat_parameter::text() // are we a value cheat? if (!has_itemlist()) { - m_curtext = string_format("%d (0x%X)", uint32_t(m_value), uint32_t(m_value)); + m_curtext = string_format("%u (0x%X)", uint64_t(m_value), uint64_t(m_value)); } else { // if not, we're an item cheat - m_curtext = string_format("??? (%d)", uint32_t(m_value)); - for (auto &curitem : m_itemlist) - if (curitem->value() == m_value) + m_curtext = string_format("??? (%u)", uint64_t(m_value)); + for (item const &curitem : m_itemlist) + { + if (curitem.value() == m_value) { - m_curtext.assign(curitem->text()); + m_curtext = curitem.text(); break; } + } } return m_curtext.c_str(); } @@ -204,9 +210,9 @@ void cheat_parameter::save(emu_file &cheatfile) const // output the parameter tag cheatfile.printf("\t\t\n"); } - - // iterate over items else { + // iterate over items cheatfile.printf(">\n"); - for (auto &curitem : m_itemlist) - cheatfile.printf("\t\t\t%s\n", curitem->value().format().c_str(), curitem->text()); + for (item const &curitem : m_itemlist) + cheatfile.printf("\t\t\t%s\n", curitem.value().format().c_str(), curitem.text()); cheatfile.printf("\t\t\n"); } } @@ -233,12 +238,12 @@ void cheat_parameter::save(emu_file &cheatfile) const bool cheat_parameter::set_minimum_state() { - uint64_t origvalue = m_value; + uint64_t const origvalue(m_value); // set based on whether we have an item list - m_value = (!has_itemlist()) ? m_minval : m_itemlist.front()->value(); + m_value = !has_itemlist() ? m_minval : m_itemlist.front().value(); - return (m_value != origvalue); + return m_value != origvalue; } @@ -248,31 +253,26 @@ bool cheat_parameter::set_minimum_state() bool cheat_parameter::set_prev_state() { - uint64_t origvalue = m_value; + uint64_t const origvalue(m_value); - // are we a value cheat? if (!has_itemlist()) { - if (m_value < m_minval + m_stepval) + // are we a value cheat? + if (m_value < (m_minval + m_stepval)) m_value = m_minval; else m_value -= m_stepval; } - - // if not, we're an item cheat else { - item *previtem = nullptr; - for (auto &curitem : m_itemlist) { - if (curitem->value() == m_value) - break; - previtem = curitem.get(); - } - if (previtem != nullptr) - m_value = previtem->value(); + // if not, we're an item cheat + std::vector::const_iterator it; + for (it = m_itemlist.begin(); (m_itemlist.end() != it) && (it->value() != m_value); ++it) { } + if (m_itemlist.begin() != it) + m_value = std::prev(it)->value(); } - return (m_value != origvalue); + return m_value != origvalue; } @@ -282,29 +282,26 @@ bool cheat_parameter::set_prev_state() bool cheat_parameter::set_next_state() { - uint64_t origvalue = m_value; + uint64_t const origvalue(m_value); - // are we a value cheat? if (!has_itemlist()) { + // are we a value cheat? if (m_value > m_maxval - m_stepval) m_value = m_maxval; else m_value += m_stepval; } - - // if not, we're an item cheat else { - std::vector>::iterator it; - for (it = m_itemlist.begin(); it != m_itemlist.end(); ++it) - if (it->get()->value() == m_value) - break; - if (it != m_itemlist.end() && (++it != m_itemlist.end())) - m_value = it->get()->value(); + // if not, we're an item cheat + std::vector::const_iterator it; + for (it = m_itemlist.begin(); (m_itemlist.end() != it) && (it->value() != m_value); ++it) { } + if ((m_itemlist.end() != it) && (m_itemlist.end() != ++it)) + m_value = it->value(); } - return (m_value != origvalue); + return m_value != origvalue; } @@ -317,37 +314,33 @@ bool cheat_parameter::set_next_state() // cheat_script - constructor //------------------------------------------------- -cheat_script::cheat_script(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const &scriptnode) +cheat_script::cheat_script( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const &scriptnode) : m_state(SCRIPT_STATE_RUN) { // read the core attributes - const char *state = scriptnode.get_attribute_string("state", "run"); - if (strcmp(state, "on") == 0) + char const *const state(scriptnode.get_attribute_string("state", "run")); + if (!std::strcmp(state, "on")) m_state = SCRIPT_STATE_ON; - else if (strcmp(state, "off") == 0) + else if (!std::strcmp(state, "off")) m_state = SCRIPT_STATE_OFF; - else if (strcmp(state, "change") == 0) + else if (!std::strcmp(state, "change")) m_state = SCRIPT_STATE_CHANGE; - else if (strcmp(state, "run") != 0) + else if (std::strcmp(state, "run")) throw emu_fatalerror("%s.xml(%d): invalid script state '%s'\n", filename, scriptnode.line, state); // iterate over nodes within the script for (util::xml::data_node const *entrynode = scriptnode.get_first_child(); entrynode != nullptr; entrynode = entrynode->get_next_sibling()) { - // handle action nodes - if (strcmp(entrynode->get_name(), "action") == 0) + if (!std::strcmp(entrynode->get_name(), "action")) // handle action nodes m_entrylist.push_back(std::make_unique(manager, symbols, filename, *entrynode, true)); - - // handle output nodes - else if (strcmp(entrynode->get_name(), "output") == 0) + else if (!std::strcmp(entrynode->get_name(), "output")) // handle output nodes m_entrylist.push_back(std::make_unique(manager, symbols, filename, *entrynode, false)); - - // anything else is ignored - else - { + else // anything else is ignored osd_printf_warning("%s.xml(%d): unknown script item '%s' will be lost if saved\n", filename, entrynode->line, entrynode->get_name()); - continue; - } } } @@ -378,11 +371,11 @@ void cheat_script::save(emu_file &cheatfile) const cheatfile.printf("\t\t\n"); @@ -399,49 +392,54 @@ void cheat_script::save(emu_file &cheatfile) const // script_entry - constructor //------------------------------------------------- -cheat_script::script_entry::script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const &entrynode, bool isaction) - : m_condition(&symbols), - m_expression(&symbols) +cheat_script::script_entry::script_entry( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const &entrynode, + bool isaction) + : m_condition(&symbols) + , m_expression(&symbols) { - const char *expression = nullptr; + char const *expression(nullptr); try { // read the condition if present expression = entrynode.get_attribute_string("condition", nullptr); - if (expression != nullptr) + if (expression) m_condition.parse(expression); - // if this is an action, parse the expression if (isaction) { + // if this is an action, parse the expression expression = entrynode.get_value(); - if (expression == nullptr || expression[0] == 0) + if (!expression || !expression[0]) throw emu_fatalerror("%s.xml(%d): missing expression in action tag\n", filename, entrynode.line); m_expression.parse(expression); } - - // otherwise, parse the attributes and arguments else { + // otherwise, parse the attributes and arguments + // extract format - const char *format = entrynode.get_attribute_string("format", nullptr); - if (format == nullptr || format[0] == 0) + char const *const format(entrynode.get_attribute_string("format", nullptr)); + if (!format || !format[0]) throw emu_fatalerror("%s.xml(%d): missing format in output tag\n", filename, entrynode.line); - m_format.assign(format); + m_format = format; // extract other attributes m_line = entrynode.get_attribute_int("line", 0); m_justify = ui::text_layout::LEFT; - const char *align = entrynode.get_attribute_string("align", "left"); - if (strcmp(align, "center") == 0) + char const *const align(entrynode.get_attribute_string("align", "left")); + if (!std::strcmp(align, "center")) m_justify = ui::text_layout::CENTER; - else if (strcmp(align, "right") == 0) + else if (!std::strcmp(align, "right")) m_justify = ui::text_layout::RIGHT; - else if (strcmp(align, "left") != 0) + else if (std::strcmp(align, "left")) throw emu_fatalerror("%s.xml(%d): invalid alignment '%s' specified\n", filename, entrynode.line, align); // then parse arguments - int totalargs = 0; + int totalargs(0); for (util::xml::data_node const *argnode = entrynode.get_child("argument"); argnode != nullptr; argnode = argnode->get_next_sibling("argument")) { auto curarg = std::make_unique(manager, symbols, filename, *argnode); @@ -458,7 +456,7 @@ cheat_script::script_entry::script_entry(cheat_manager &manager, symbol_table &s validate_format(filename, entrynode.line); } } - catch (expression_error &err) + catch (expression_error const &err) { throw emu_fatalerror("%s.xml(%d): error parsing cheat expression \"%s\" (%s)\n", filename, entrynode.line, expression, err.code_string()); } @@ -476,11 +474,11 @@ void cheat_script::script_entry::execute(cheat_manager &manager, uint64_t &argin { try { - uint64_t result = m_condition.execute(); - if (result == 0) + uint64_t const result(m_condition.execute()); + if (!result) return; } - catch (expression_error &err) + catch (expression_error const &err) { osd_printf_warning("Error executing conditional expression \"%s\": %s\n", m_condition.original_string(), err.code_string()); return; @@ -511,14 +509,14 @@ void cheat_script::script_entry::execute(cheat_manager &manager, uint64_t &argin // generate the astring manager.get_output_string(m_line, m_justify) = string_format(m_format, - (uint32_t)params[0], (uint32_t)params[1], (uint32_t)params[2], (uint32_t)params[3], - (uint32_t)params[4], (uint32_t)params[5], (uint32_t)params[6], (uint32_t)params[7], - (uint32_t)params[8], (uint32_t)params[9], (uint32_t)params[10], (uint32_t)params[11], - (uint32_t)params[12], (uint32_t)params[13], (uint32_t)params[14], (uint32_t)params[15], - (uint32_t)params[16], (uint32_t)params[17], (uint32_t)params[18], (uint32_t)params[19], - (uint32_t)params[20], (uint32_t)params[21], (uint32_t)params[22], (uint32_t)params[23], - (uint32_t)params[24], (uint32_t)params[25], (uint32_t)params[26], (uint32_t)params[27], - (uint32_t)params[28], (uint32_t)params[29], (uint32_t)params[30], (uint32_t)params[31]); + params[0], params[1], params[2], params[3], + params[4], params[5], params[6], params[7], + params[8], params[9], params[10], params[11], + params[12], params[13], params[14], params[15], + params[16], params[17], params[18], params[19], + params[20], params[21], params[22], params[23], + params[24], params[25], params[26], params[27], + params[28], params[29], params[30], params[31]); } } @@ -529,33 +527,36 @@ void cheat_script::script_entry::execute(cheat_manager &manager, uint64_t &argin void cheat_script::script_entry::save(emu_file &cheatfile) const { - // output an action if (m_format.empty()) { + // output an action cheatfile.printf("\t\t\t%s\n", cheat_manager::quote_expression(m_expression).c_str()); } - - // output an output else { + // output an output cheatfile.printf("\t\t\t\n"); - // output arguments + if (m_arglist.size() == 0) + { + cheatfile.printf(" />\n"); + } else { + // output arguments cheatfile.printf(">\n"); for (auto &curarg : m_arglist) curarg->save(cheatfile); @@ -573,27 +574,20 @@ void cheat_script::script_entry::save(emu_file &cheatfile) const void cheat_script::script_entry::validate_format(const char *filename, int line) { // first count arguments - int argsprovided = 0; + int argsprovided(0); for (auto &curarg : m_arglist) argsprovided += curarg->count(); // now scan the string for valid argument usage - const char *p = strchr(m_format.c_str(), '%'); int argscounted = 0; - while (p != nullptr) + for (char const *p = strchr(m_format.c_str(), '%'); p; ++argscounted, p = strchr(p, '%')) { // skip past any valid attributes - p++; - while (strchr("lh0123456789.-+ #", *p) != nullptr) - p++; + for (++p; strchr("lh0123456789.-+ #", *p); ++p) { } // look for a valid type - if (strchr("cdiouxX", *p) == nullptr) + if (!strchr("cdiouxX", *p)) throw emu_fatalerror("%s.xml(%d): invalid format specification \"%s\"\n", filename, line, m_format.c_str()); - argscounted++; - - // look for the next one - p = strchr(p, '%'); } // did we match? @@ -608,16 +602,20 @@ void cheat_script::script_entry::validate_format(const char *filename, int line) // output_argument - constructor //------------------------------------------------- -cheat_script::script_entry::output_argument::output_argument(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const &argnode) - : m_expression(&symbols), - m_count(0) +cheat_script::script_entry::output_argument::output_argument( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const &argnode) + : m_expression(&symbols) + , m_count(0) { // first extract attributes m_count = argnode.get_attribute_int("count", 1); // read the expression - const char *expression = argnode.get_value(); - if (expression == nullptr || expression[0] == 0) + char const *const expression(argnode.get_value()); + if (!expression || !expression[0]) throw emu_fatalerror("%s.xml(%d): missing expression in argument tag\n", filename, argnode.line); // parse it @@ -625,7 +623,7 @@ cheat_script::script_entry::output_argument::output_argument(cheat_manager &mana { m_expression.parse(expression); } - catch (expression_error &err) + catch (expression_error const &err) { throw emu_fatalerror("%s.xml(%d): error parsing cheat expression \"%s\" (%s)\n", filename, argnode.line, expression, err.code_string()); } @@ -645,7 +643,7 @@ int cheat_script::script_entry::output_argument::values(uint64_t &argindex, uint { result[argindex] = m_expression.execute(); } - catch (expression_error &err) + catch (expression_error const &err) { osd_printf_warning("Error executing argument expression \"%s\": %s\n", m_expression.original_string(), err.code_string()); } @@ -662,7 +660,7 @@ void cheat_script::script_entry::output_argument::save(emu_file &cheatfile) cons { cheatfile.printf("\t\t\t\t%s\n", cheat_manager::quote_expression(m_expression).c_str()); } @@ -683,75 +681,64 @@ cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, cons , m_numtemp(DEFAULT_TEMP_VARIABLES) , m_argindex(0) { - // reset scripts - try + // pull the variable count out ahead of things + int const tempcount(cheatnode.get_attribute_int("tempvariables", DEFAULT_TEMP_VARIABLES)); + if (tempcount < 1) + throw emu_fatalerror("%s.xml(%d): invalid tempvariables attribute (%d)\n", filename, cheatnode.line, tempcount); + + // allocate memory for the cheat + m_numtemp = tempcount; + + // get the description + char const *const description(cheatnode.get_attribute_string("desc", nullptr)); + if (!description || !description[0]) + throw emu_fatalerror("%s.xml(%d): empty or missing desc attribute on cheat\n", filename, cheatnode.line); + m_description = description; + + // create the symbol table + m_symbols.add("argindex", symbol_table::READ_ONLY, &m_argindex); + for (int curtemp = 0; curtemp < tempcount; curtemp++) + m_symbols.add(string_format("temp%d", curtemp).c_str(), symbol_table::READ_WRITE); + + // read the first comment node + util::xml::data_node const *const commentnode(cheatnode.get_child("comment")); + if (commentnode != nullptr) { - // pull the variable count out ahead of things - int tempcount = cheatnode.get_attribute_int("tempvariables", DEFAULT_TEMP_VARIABLES); - if (tempcount < 1) - throw emu_fatalerror("%s.xml(%d): invalid tempvariables attribute (%d)\n", filename, cheatnode.line, tempcount); + // set the value if not nullptr + if (commentnode->get_value() && commentnode->get_value()[0]) + m_comment.assign(commentnode->get_value()); - // allocate memory for the cheat - m_numtemp = tempcount; - - // get the description - const char *description = cheatnode.get_attribute_string("desc", nullptr); - if (description == nullptr || description[0] == 0) - throw emu_fatalerror("%s.xml(%d): empty or missing desc attribute on cheat\n", filename, cheatnode.line); - m_description = description; - - // create the symbol table - m_symbols.add("argindex", symbol_table::READ_ONLY, &m_argindex); - for (int curtemp = 0; curtemp < tempcount; curtemp++) { - m_symbols.add(string_format("temp%d", curtemp).c_str(), symbol_table::READ_WRITE); - } - - // read the first comment node - util::xml::data_node const *commentnode = cheatnode.get_child("comment"); - if (commentnode != nullptr) - { - // set the value if not nullptr - if (commentnode->get_value() != nullptr && commentnode->get_value()[0] != 0) - m_comment.assign(commentnode->get_value()); - - // only one comment is kept - commentnode = commentnode->get_next_sibling("comment"); - if (commentnode != nullptr) - osd_printf_warning("%s.xml(%d): only one comment node is retained; ignoring additional nodes\n", filename, commentnode->line); - } - - // read the first parameter node - util::xml::data_node const *paramnode = cheatnode.get_child("parameter"); - if (paramnode != nullptr) - { - // load this parameter - m_parameter.reset(global_alloc(cheat_parameter(manager, m_symbols, filename, *paramnode))); - - // only one parameter allowed - paramnode = paramnode->get_next_sibling("parameter"); - if (paramnode != nullptr) - osd_printf_warning("%s.xml(%d): only one parameter node allowed; ignoring additional nodes\n", filename, paramnode->line); - } - - // read the script nodes - for (util::xml::data_node const *scriptnode = cheatnode.get_child("script"); scriptnode != nullptr; scriptnode = scriptnode->get_next_sibling("script")) - { - // load this entry - auto curscript = global_alloc(cheat_script(manager, m_symbols, filename, *scriptnode)); - - // if we have a script already for this slot, it is an error - std::unique_ptr &slot = script_for_state(curscript->state()); - if (slot != nullptr) - osd_printf_warning("%s.xml(%d): only one on script allowed; ignoring additional scripts\n", filename, scriptnode->line); - else - slot.reset(curscript); - } + // only one comment is kept + util::xml::data_node const *const nextcomment(commentnode->get_next_sibling("comment")); + if (nextcomment) + osd_printf_warning("%s.xml(%d): only one comment node is retained; ignoring additional nodes\n", filename, nextcomment->line); } - catch (emu_fatalerror &) + + // read the first parameter node + util::xml::data_node const *const paramnode(cheatnode.get_child("parameter")); + if (paramnode != nullptr) { - // call our destructor to clean up and re-throw - this->~cheat_entry(); - throw; + // load this parameter + m_parameter.reset(new cheat_parameter(manager, m_symbols, filename, *paramnode)); + + // only one parameter allowed + util::xml::data_node const *const nextparam(paramnode->get_next_sibling("parameter")); + if (nextparam) + osd_printf_warning("%s.xml(%d): only one parameter node allowed; ignoring additional nodes\n", filename, nextparam->line); + } + + // read the script nodes + for (util::xml::data_node const *scriptnode = cheatnode.get_child("script"); scriptnode != nullptr; scriptnode = scriptnode->get_next_sibling("script")) + { + // load this entry + std::unique_ptr curscript(new cheat_script(manager, m_symbols, filename, *scriptnode)); + + // if we have a script already for this slot, it is an error + std::unique_ptr &slot = script_for_state(curscript->state()); + if (slot) + osd_printf_warning("%s.xml(%d): only one on script allowed; ignoring additional scripts\n", filename, scriptnode->line); + else + slot = std::move(curscript); } } @@ -772,14 +759,17 @@ cheat_entry::~cheat_entry() void cheat_entry::save(emu_file &cheatfile) const { // determine if we have scripts - bool has_scripts = (m_off_script != nullptr || m_on_script != nullptr || m_run_script != nullptr || m_change_script != nullptr); + bool const has_scripts(m_off_script || m_on_script || m_run_script || m_change_script); // output the cheat tag cheatfile.printf("\t\n"); + } else { cheatfile.printf(">\n"); @@ -789,18 +779,13 @@ void cheat_entry::save(emu_file &cheatfile) const cheatfile.printf("\t\t\n", m_comment.c_str()); // output the parameter, if present - if (m_parameter != nullptr) - m_parameter->save(cheatfile); + if (m_parameter) m_parameter->save(cheatfile); // output the script nodes - if (m_on_script != nullptr) - m_on_script->save(cheatfile); - if (m_off_script != nullptr) - m_off_script->save(cheatfile); - if (m_change_script != nullptr) - m_change_script->save(cheatfile); - if (m_run_script != nullptr) - m_run_script->save(cheatfile); + if (m_on_script) m_on_script->save(cheatfile); + if (m_off_script) m_off_script->save(cheatfile); + if (m_change_script) m_change_script->save(cheatfile); + if (m_run_script) m_run_script->save(cheatfile); // close the cheat tag cheatfile.printf("\t\n"); @@ -814,23 +799,22 @@ void cheat_entry::save(emu_file &cheatfile) const bool cheat_entry::activate() { - bool changed = false; + bool changed(false); // if cheats have been toggled off no point in even trying to do anything if (!m_manager.enabled()) return changed; - // if we're a oneshot cheat, execute the "on" script and indicate change if (is_oneshot()) { + // if we're a oneshot cheat, execute the "on" script and indicate change execute_on_script(); changed = true; m_manager.machine().popmessage("Activated %s", m_description.c_str()); } - - // if we're a oneshot parameter cheat and we're active, execute the "state change" script and indicate change - else if (is_oneshot_parameter() && m_state != SCRIPT_STATE_OFF) + else if (is_oneshot_parameter() && (m_state != SCRIPT_STATE_OFF)) { + // if we're a oneshot parameter cheat and we're active, execute the "state change" script and indicate change execute_change_script(); changed = true; m_manager.machine().popmessage("Activated\n %s = %s", m_description.c_str(), m_parameter->text()); @@ -847,15 +831,17 @@ bool cheat_entry::activate() bool cheat_entry::select_default_state() { - bool changed = false; + bool changed(false); - // if we're a oneshot cheat, there is no default state if (is_oneshot()) - ; - - // all other types switch to the "off" state + { + // if we're a oneshot cheat, there is no default state + } else + { + // all other types switch to the "off" state changed = set_state(SCRIPT_STATE_OFF); + } return changed; } @@ -868,22 +854,26 @@ bool cheat_entry::select_default_state() bool cheat_entry::select_previous_state() { - bool changed = false; + bool changed(false); - // if we're a oneshot, there is no previous state if (is_oneshot()) - ; - - // if we're on/off, toggle to off + { + // if we're a oneshot, there is no previous state + } else if (is_onoff()) + { + // if we're on/off, toggle to off changed = set_state(SCRIPT_STATE_OFF); - - // if we have a parameter, set the previous state + } else if (m_parameter != nullptr) { + // if we have a parameter, set the previous state + // if we're at our minimum, turn off if (m_parameter->is_minimum()) + { changed = set_state(SCRIPT_STATE_OFF); + } else { // if we changed, ensure we are in the running state and signal state change @@ -896,6 +886,7 @@ bool cheat_entry::select_previous_state() } } } + return changed; } @@ -907,34 +898,37 @@ bool cheat_entry::select_previous_state() bool cheat_entry::select_next_state() { - bool changed = false; + bool changed(false); - // if we're a oneshot, there is no next state if (is_oneshot()) - ; - - // if we're on/off, toggle to running state + { + // if we're a oneshot, there is no next state + } else if (is_onoff()) + { + // if we're on/off, toggle to running state changed = set_state(SCRIPT_STATE_RUN); - - // if we have a parameter, set the next state + } else if (m_parameter != nullptr) { - // if we're off, switch on to the minimum state + // if we have a parameter, set the next state if (m_state == SCRIPT_STATE_OFF) { + // if we're off, switch on to the minimum state changed = set_state(SCRIPT_STATE_RUN); m_parameter->set_minimum_state(); } - - // otherwise, switch to the next state else + { + // otherwise, switch to the next state changed = m_parameter->set_next_state(); + } // if we changed, signal a state change if (changed && !is_oneshot_parameter()) execute_change_script(); } + return changed; } @@ -947,44 +941,43 @@ bool cheat_entry::select_next_state() void cheat_entry::menu_text(std::string &description, std::string &state, uint32_t &flags) { // description is standard - description.assign(m_description); + description = m_description; state.clear(); flags = 0; - // some cheat entries are just text for display if (is_text_only()) { + // some cheat entries are just text for display if (!description.empty()) { strtrimspace(description); if (description.empty()) - description.assign(MENU_SEPARATOR_ITEM); + description = MENU_SEPARATOR_ITEM; } flags = ui::menu::FLAG_DISABLE; } - - // if we have no parameter and no run or off script, it's a oneshot cheat else if (is_oneshot()) - state.assign("Set"); - - // if we have no parameter, it's just on/off + { + // if we have no parameter and no run or off script, it's a oneshot cheat + state = "Set"; + } else if (is_onoff()) { - state.assign((m_state == SCRIPT_STATE_RUN) ? "On" : "Off"); + // if we have no parameter, it's just on/off + state = (m_state == SCRIPT_STATE_RUN) ? "On" : "Off"; flags = (m_state != 0) ? ui::menu::FLAG_LEFT_ARROW : ui::menu::FLAG_RIGHT_ARROW; } - - // if we have a value parameter, compute it else if (m_parameter != nullptr) { + // if we have a value parameter, compute it if (m_state == SCRIPT_STATE_OFF) { - state.assign(is_oneshot_parameter() ? "Set" : "Off"); + state = is_oneshot_parameter() ? "Set" : "Off"; flags = ui::menu::FLAG_RIGHT_ARROW; } else { - state.assign(m_parameter->text()); + state = m_parameter->text(); flags = ui::menu::FLAG_LEFT_ARROW; if (!m_parameter->is_maximum()) flags |= ui::menu::FLAG_RIGHT_ARROW; @@ -1007,8 +1000,9 @@ bool cheat_entry::set_state(script_state newstate) m_state = newstate; if (newstate == SCRIPT_STATE_OFF) execute_off_script(); - else if (newstate == SCRIPT_STATE_ON || newstate == SCRIPT_STATE_RUN) + else if ((newstate == SCRIPT_STATE_ON) || (newstate == SCRIPT_STATE_RUN)) execute_on_script(); + return true; } @@ -1022,11 +1016,11 @@ std::unique_ptr &cheat_entry::script_for_state(script_state state) { switch (state) { - case SCRIPT_STATE_ON: return m_on_script; - case SCRIPT_STATE_OFF: return m_off_script; - case SCRIPT_STATE_CHANGE: return m_change_script; - default: - case SCRIPT_STATE_RUN: return m_run_script; + case SCRIPT_STATE_ON: return m_on_script; + case SCRIPT_STATE_OFF: return m_off_script; + case SCRIPT_STATE_CHANGE: return m_change_script; + default: + case SCRIPT_STATE_RUN: return m_run_script; } } @@ -1039,8 +1033,10 @@ std::unique_ptr &cheat_entry::script_for_state(script_state state) bool cheat_entry::is_duplicate() const { for (auto &scannode : manager().entries()) - if (strcmp(scannode->description(), description()) == 0) + { + if (!std::strcmp(scannode->description(), description())) return true; + } return false; } @@ -1049,7 +1045,7 @@ bool cheat_entry::is_duplicate() const // CHEAT MANAGER //************************************************************************** -const int cheat_manager::CHEAT_VERSION; +constexpr int cheat_manager::CHEAT_VERSION; //------------------------------------------------- @@ -1057,16 +1053,16 @@ const int cheat_manager::CHEAT_VERSION; //------------------------------------------------- cheat_manager::cheat_manager(running_machine &machine) - : m_machine(machine), - m_disabled(true), - m_symtable(&machine) + : m_machine(machine) + , m_disabled(true) + , m_symtable(&machine) { // if the cheat engine is disabled, we're done if (!machine.options().cheat()) return; - m_output.resize(UI_TARGET_FONT_ROWS*2); - m_justify.resize(UI_TARGET_FONT_ROWS*2); + m_output.resize(UI_TARGET_FONT_ROWS * 2); + m_justify.resize(UI_TARGET_FONT_ROWS * 2); // request a callback machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(&cheat_manager::frame_update, this)); @@ -1105,25 +1101,30 @@ void cheat_manager::set_enable(bool enable) if (!machine().options().cheat()) return; - // if we're enabled currently and we don't want to be, turn things off if (!m_disabled && !enable) { + // if we're enabled currently and we don't want to be, turn things off + // iterate over running cheats and execute any OFF Scripts for (auto &cheat : m_cheatlist) + { if (cheat->state() == SCRIPT_STATE_RUN) cheat->execute_off_script(); + } machine().popmessage("Cheats Disabled"); m_disabled = true; } - - // if we're disabled currently and we want to be enabled, turn things on else if (m_disabled && enable) { + // if we're disabled currently and we want to be enabled, turn things on + // iterate over running cheats and execute any ON Scripts m_disabled = false; for (auto &cheat : m_cheatlist) + { if (cheat->state() == SCRIPT_STATE_RUN) cheat->execute_on_script(); + } machine().popmessage("Cheats Enabled"); } } @@ -1152,6 +1153,7 @@ void cheat_manager::reload() // load the cheat file, if it's a system that has a software list then try softlist_name/shortname.xml first, // if it fails to load then try to load via crc32 - basename/crc32.xml ( eg. 01234567.xml ) for (device_image_interface &image : image_interface_iterator(machine().root_device())) + { if (image.exists()) { // if we are loading through a software list, try to load softlist_name/shortname.xml @@ -1173,9 +1175,10 @@ void cheat_manager::reload() } } } + } // if we haven't found the cheats yet, load by basename - if (m_cheatlist.size() == 0) + if (m_cheatlist.empty()) load_cheats(machine().basename()); // temporary: save the file back out as output.xml for comparison @@ -1193,7 +1196,7 @@ bool cheat_manager::save_all(const char *filename) { // open the file with the proper name emu_file cheatfile(machine().options().cheat_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = cheatfile.open(filename, ".xml"); + osd_file::error const filerr(cheatfile.open(filename, ".xml")); // if that failed, return nothing if (filerr != osd_file::error::NONE) @@ -1215,10 +1218,9 @@ bool cheat_manager::save_all(const char *filename) cheatfile.printf("\n"); return true; } - - // catch errors and cleanup - catch (emu_fatalerror &err) + catch (emu_fatalerror const &err) { + // catch errors and cleanup osd_printf_error("%s\n", err.string()); cheatfile.remove_on_close(); } @@ -1235,14 +1237,16 @@ void cheat_manager::render_text(mame_ui_manager &mui, render_container &containe { // render any text and free it along the way for (int linenum = 0; linenum < m_output.size(); linenum++) + { if (!m_output[linenum].empty()) { // output the text mui.draw_text_full(container, m_output[linenum].c_str(), - 0.0f, (float)linenum * mui.get_line_height(), 1.0f, + 0.0f, float(linenum) * mui.get_line_height(), 1.0f, m_justify[linenum], ui::text_layout::NEVER, mame_ui_manager::OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr); } + } } @@ -1256,17 +1260,16 @@ std::string &cheat_manager::get_output_string(int row, ui::text_layout::text_jus { // if the row is not specified, grab the next one if (row == 0) - row = (m_lastline >= 0) ? m_lastline + 1 : m_lastline - 1; + row = (m_lastline >= 0) ? (m_lastline + 1) : (m_lastline - 1); // remember the last request m_lastline = row; // invert if negative - row = (row < 0) ? m_numlines + row : row - 1; + row = (row < 0) ? (m_numlines + row) : (row - 1); // clamp within range - row = std::max(row, 0); - row = std::min(row, m_numlines - 1); + row = std::min(std::max(row, 0), m_numlines - 1); // return the appropriate string m_justify[row] = justify; @@ -1319,9 +1322,9 @@ std::string cheat_manager::quote_expression(const parsed_expression &expression) uint64_t cheat_manager::execute_frombcd(symbol_table &table, void *ref, int params, const uint64_t *param) { - uint64_t value = param[0]; - uint64_t multiplier = 1; - uint64_t result = 0; + uint64_t value(param[0]); + uint64_t multiplier(1); + uint64_t result(0); while (value != 0) { @@ -1339,9 +1342,9 @@ uint64_t cheat_manager::execute_frombcd(symbol_table &table, void *ref, int para uint64_t cheat_manager::execute_tobcd(symbol_table &table, void *ref, int params, const uint64_t *param) { - uint64_t value = param[0]; - uint64_t result = 0; - uint8_t shift = 0; + uint64_t value(param[0]); + uint64_t result(0); + uint8_t shift(0); while (value != 0) { @@ -1407,35 +1410,45 @@ void cheat_manager::load_cheats(const char *filename) throw emu_fatalerror("%s.xml(%d): error parsing XML (%s)\n", filename, error.error_line, error.error_message); // find the layout node - util::xml::data_node const *const mamecheatnode = rootnode->get_child("mamecheat"); + util::xml::data_node const *const mamecheatnode(rootnode->get_child("mamecheat")); if (mamecheatnode == nullptr) throw emu_fatalerror("%s.xml: missing mamecheatnode node", filename); // validate the config data version - int version = mamecheatnode->get_attribute_int("version", 0); + int const version(mamecheatnode->get_attribute_int("version", 0)); if (version != CHEAT_VERSION) throw emu_fatalerror("%s.xml(%d): Invalid cheat XML file: unsupported version", filename, mamecheatnode->line); // parse all the elements for (util::xml::data_node const *cheatnode = mamecheatnode->get_child("cheat"); cheatnode != nullptr; cheatnode = cheatnode->get_next_sibling("cheat")) { - // load this entry - auto curcheat = std::make_unique(*this, m_symtable, filename, *cheatnode); - - // make sure we're not a duplicate - if (REMOVE_DUPLICATE_CHEATS && curcheat->is_duplicate()) + try { - osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); + // load this entry + auto curcheat = std::make_unique(*this, m_symtable, filename, *cheatnode); + + // make sure we're not a duplicate + if (REMOVE_DUPLICATE_CHEATS && curcheat->is_duplicate()) + { + osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); + } + else + { + // add to the end of the list + m_cheatlist.push_back(std::move(curcheat)); + } + } + catch (emu_fatalerror const &err) + { + // just move on to the next cheat + osd_printf_error("%s\n", err.string()); } - else // add to the end of the list - m_cheatlist.push_back(std::move(curcheat)); } } } - - // handle errors cleanly - catch (emu_fatalerror &err) + catch (emu_fatalerror const &err) { + // handle errors cleanly osd_printf_error("%s\n", err.string()); m_cheatlist.clear(); } diff --git a/src/frontend/mame/cheat.h b/src/frontend/mame/cheat.h index eaba3650e7e..93b7d1ebfb8 100644 --- a/src/frontend/mame/cheat.h +++ b/src/frontend/mame/cheat.h @@ -8,10 +8,10 @@ ***************************************************************************/ -#pragma once +#ifndef MAME_FRONTEND_CHEAT_H +#define MAME_FRONTEND_CHEAT_H -#ifndef __CHEAT_H__ -#define __CHEAT_H__ +#pragma once #include "debug/express.h" #include "debug/debugcpu.h" @@ -50,12 +50,20 @@ class number_and_format { public: // construction/destruction - number_and_format(uint64_t value = 0, util::xml::data_node::int_format format = util::xml::data_node::int_format::DECIMAL) + constexpr number_and_format( + uint64_t value = 0, + util::xml::data_node::int_format format = util::xml::data_node::int_format::DECIMAL) : m_value(value) , m_format(format) { } + // copyable/movable + constexpr number_and_format(number_and_format const &) = default; + number_and_format(number_and_format &&) = default; + number_and_format &operator=(number_and_format const &) = default; + number_and_format &operator=(number_and_format &&) = default; + // pass-through to look like a regular number operator uint64_t &() { return m_value; } operator const uint64_t &() const { return m_value; } @@ -77,13 +85,17 @@ class cheat_parameter { public: // construction/destruction - cheat_parameter(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const ¶mnode); + cheat_parameter( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const ¶mnode); // queries - const char *text(); - bool has_itemlist() const { return (m_itemlist.size() != 0); } - bool is_minimum() const { return (m_value == ((m_itemlist.size() == 0) ? m_minval : m_itemlist.front()->value())); } - bool is_maximum() const { return (m_value == ((m_itemlist.size() == 0) ? m_maxval : m_itemlist.back()->value())); } + char const *text(); + bool has_itemlist() const { return !m_itemlist.empty(); } + bool is_minimum() const { return (m_itemlist.empty() ? m_minval : m_itemlist.front().value()) == m_value; } + bool is_maximum() const { return (m_itemlist.empty() ? m_maxval : m_itemlist.back().value()) == m_value; } // state setters bool set_minimum_state(); @@ -102,25 +114,32 @@ private: item(const char *text, uint64_t value, util::xml::data_node::int_format valformat) : m_text(text) , m_value(value, valformat) - { } + { + } + + // copyable/movable + item(item const &) = default; + item(item &&) = default; + item &operator=(item const &) = default; + item &operator=(item &&) = default; // getters - const number_and_format &value() const { return m_value; } - const char *text() const { return m_text.c_str(); } + number_and_format const &value() const { return m_value; } + char const *text() const { return m_text.c_str(); } private: // internal state - std::string m_text; // name of the item - number_and_format m_value; // value of the item + std::string m_text; // name of the item + number_and_format m_value; // value of the item }; // internal state - number_and_format m_minval; // minimum value - number_and_format m_maxval; // maximum value - number_and_format m_stepval; // step value - uint64_t m_value; // live value of the parameter - std::string m_curtext; // holding for a value string - std::vector> m_itemlist; // list of items + number_and_format m_minval; // minimum value + number_and_format m_maxval; // maximum value + number_and_format m_stepval; // step value + uint64_t m_value; // live value of the parameter + std::string m_curtext; // holding for a value string + std::vector m_itemlist; // list of items }; @@ -131,7 +150,11 @@ class cheat_script { public: // construction/destruction - cheat_script(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const &scriptnode); + cheat_script( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const &scriptnode); // getters script_state state() const { return m_state; } @@ -146,7 +169,12 @@ private: { public: // construction/destruction - script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const &entrynode, bool isaction); + script_entry( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const &entrynode, + bool isaction); // actions void execute(cheat_manager &manager, uint64_t &argindex); @@ -158,7 +186,11 @@ private: { public: // construction/destruction - output_argument(cheat_manager &manager, symbol_table &symbols, const char *filename, util::xml::data_node const &argnode); + output_argument( + cheat_manager &manager, + symbol_table &symbols, + char const *filename, + util::xml::data_node const &argnode); // getters int count() const { return m_count; } @@ -169,28 +201,28 @@ private: private: // internal state - parsed_expression m_expression; // expression for argument - uint64_t m_count; // number of repetitions + parsed_expression m_expression; // expression for argument + uint64_t m_count; // number of repetitions }; // internal helpers - void validate_format(const char *filename, int line); + void validate_format(char const *filename, int line); // internal state - parsed_expression m_condition; // condition under which this is executed - parsed_expression m_expression; // expression to execute - std::string m_format; // string format to print - std::vector> m_arglist; // list of arguments - int8_t m_line; // which line to print on - ui::text_layout::text_justify m_justify; // justification when printing + parsed_expression m_condition; // condition under which this is executed + parsed_expression m_expression; // expression to execute + std::string m_format; // string format to print + std::vector> m_arglist; // list of arguments + int8_t m_line; // which line to print on + ui::text_layout::text_justify m_justify; // justification when printing // constants - static const int MAX_ARGUMENTS = 32; + static constexpr int MAX_ARGUMENTS = 32; }; // internal state - std::vector> m_entrylist; // list of actions to perform - script_state m_state; // which state this script is for + std::vector> m_entrylist; // list of actions to perform + script_state m_state; // which state this script is for }; @@ -250,21 +282,21 @@ private: std::unique_ptr &script_for_state(script_state state); // internal state - cheat_manager & m_manager; // reference to our manager - std::string m_description; // string description/menu title - std::string m_comment; // comment data - std::unique_ptr m_parameter; // parameter - std::unique_ptr m_on_script; // script to run when turning on - std::unique_ptr m_off_script; // script to run when turning off - std::unique_ptr m_change_script; // script to run when value changes - std::unique_ptr m_run_script; // script to run each frame when on - symbol_table m_symbols; // symbol table for this cheat - script_state m_state; // current cheat state - uint32_t m_numtemp; // number of temporary variables - uint64_t m_argindex; // argument index variable + cheat_manager & m_manager; // reference to our manager + std::string m_description; // string description/menu title + std::string m_comment; // comment data + std::unique_ptr m_parameter; // parameter + std::unique_ptr m_on_script; // script to run when turning on + std::unique_ptr m_off_script; // script to run when turning off + std::unique_ptr m_change_script; // script to run when value changes + std::unique_ptr m_run_script; // script to run each frame when on + symbol_table m_symbols; // symbol table for this cheat + script_state m_state; // current cheat state + uint32_t m_numtemp; // number of temporary variables + uint64_t m_argindex; // argument index variable // constants - static const int DEFAULT_TEMP_VARIABLES = 10; + static constexpr int DEFAULT_TEMP_VARIABLES = 10; }; @@ -280,10 +312,10 @@ public: // getters running_machine &machine() const { return m_machine; } bool enabled() const { return !m_disabled; } - const std::vector> &entries() const { return m_cheatlist; } + std::vector> const &entries() const { return m_cheatlist; } // setters - void set_enable(bool enable = true); + void set_enable(bool enable); // actions void reload(); @@ -294,30 +326,30 @@ public: std::string &get_output_string(int row, ui::text_layout::text_justify justify); // global helpers - static std::string quote_expression(const parsed_expression &expression); - static uint64_t execute_frombcd(symbol_table &table, void *ref, int params, const uint64_t *param); - static uint64_t execute_tobcd(symbol_table &table, void *ref, int params, const uint64_t *param); + static std::string quote_expression(parsed_expression const &expression); + static uint64_t execute_frombcd(symbol_table &table, void *ref, int params, uint64_t const *param); + static uint64_t execute_tobcd(symbol_table &table, void *ref, int params, uint64_t const *param); private: // internal helpers void frame_update(); - void load_cheats(const char *filename); + void load_cheats(char const *filename); // internal state - running_machine & m_machine; // reference to our machine - std::vector> m_cheatlist; // cheat list - uint64_t m_framecount; // frame count - std::vector m_output; // array of output strings - std::vector m_justify; // justification for each string - uint8_t m_numlines; // number of lines available for output - int8_t m_lastline; // last line used for output - bool m_disabled; // true if the cheat engine is disabled - symbol_table m_symtable; // global symbol table - std::unique_ptr m_cpu; // debugger interface for cpus/memory + running_machine & m_machine; // reference to our machine + std::vector> m_cheatlist; // cheat list + uint64_t m_framecount; // frame count + std::vector m_output; // array of output strings + std::vector m_justify; // justification for each string + uint8_t m_numlines; // number of lines available for output + int8_t m_lastline; // last line used for output + bool m_disabled; // true if the cheat engine is disabled + symbol_table m_symtable; // global symbol table + std::unique_ptr m_cpu; // debugger interface for cpus/memory // constants static constexpr int CHEAT_VERSION = 1; }; -#endif /* __CHEAT_H__ */ +#endif /* MAME_FRONTEND_CHEAT_H */ diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp index 0db64344861..dc7c334b1bf 100644 --- a/src/lib/util/chd.cpp +++ b/src/lib/util/chd.cpp @@ -885,7 +885,7 @@ chd_error chd_file::read_hunk(uint32_t hunknum, void *buffer) // get a pointer to the map entry uint64_t blockoffs; uint32_t blocklen; - uint32_t blockcrc; + util::crc32_t blockcrc; uint8_t *rawmap; uint8_t *dest = reinterpret_cast(buffer); switch (m_version) @@ -2147,12 +2147,12 @@ void chd_file::decompress_v5_map() // read the reader uint8_t rawbuf[16]; file_read(m_mapoffset, rawbuf, sizeof(rawbuf)); - uint32_t mapbytes = be_read(&rawbuf[0], 4); - uint64_t firstoffs = be_read(&rawbuf[4], 6); - uint16_t mapcrc = be_read(&rawbuf[10], 2); - uint8_t lengthbits = rawbuf[12]; - uint8_t selfbits = rawbuf[13]; - uint8_t parentbits = rawbuf[14]; + uint32_t const mapbytes = be_read(&rawbuf[0], 4); + uint64_t const firstoffs = be_read(&rawbuf[4], 6); + util::crc16_t const mapcrc = be_read(&rawbuf[10], 2); + uint8_t const lengthbits = rawbuf[12]; + uint8_t const selfbits = rawbuf[13]; + uint8_t const parentbits = rawbuf[14]; // now read the map std::vector compressed(mapbytes); diff --git a/src/lib/util/hashing.h b/src/lib/util/hashing.h index 906bad047b4..5e9c9134c97 100644 --- a/src/lib/util/hashing.h +++ b/src/lib/util/hashing.h @@ -15,10 +15,12 @@ #include "osdcore.h" #include "corestr.h" -#include #include "md5.h" #include "sha1.h" +#include +#include + namespace util { //************************************************************************** @@ -132,13 +134,23 @@ protected: // final digest struct crc32_t { - bool operator==(const crc32_t &rhs) const { return m_raw == rhs.m_raw; } - bool operator!=(const crc32_t &rhs) const { return m_raw != rhs.m_raw; } + crc32_t() { } + constexpr crc32_t(const crc32_t &rhs) = default; + constexpr crc32_t(const uint32_t crc) : m_raw(crc) { } + + constexpr bool operator==(const crc32_t &rhs) const { return m_raw == rhs.m_raw; } + constexpr bool operator!=(const crc32_t &rhs) const { return m_raw != rhs.m_raw; } + + crc32_t &operator=(const crc32_t &rhs) = default; crc32_t &operator=(const uint32_t crc) { m_raw = crc; return *this; } - operator uint32_t() const { return m_raw; } + + constexpr operator uint32_t() const { return m_raw; } + bool from_string(const char *string, int length = -1); std::string as_string() const; + uint32_t m_raw; + static const crc32_t null; }; @@ -178,13 +190,23 @@ protected: // final digest struct crc16_t { - bool operator==(const crc16_t &rhs) const { return m_raw == rhs.m_raw; } - bool operator!=(const crc16_t &rhs) const { return m_raw != rhs.m_raw; } + crc16_t() { } + constexpr crc16_t(const crc16_t &rhs) = default; + constexpr crc16_t(const uint16_t crc) : m_raw(crc) { } + + constexpr bool operator==(const crc16_t &rhs) const { return m_raw == rhs.m_raw; } + constexpr bool operator!=(const crc16_t &rhs) const { return m_raw != rhs.m_raw; } + + crc16_t &operator=(const crc16_t &rhs) = default; crc16_t &operator=(const uint16_t crc) { m_raw = crc; return *this; } - operator uint16_t() const { return m_raw; } + + constexpr operator uint16_t() const { return m_raw; } + bool from_string(const char *string, int length = -1); std::string as_string() const; + uint16_t m_raw; + static const crc16_t null; }; @@ -220,4 +242,22 @@ protected: } // namespace util +namespace std { + +template <> struct hash<::util::crc32_t> +{ + typedef ::util::crc32_t argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const & s) const { return std::hash()(s); } +}; + +template <> struct hash<::util::crc16_t> +{ + typedef ::util::crc16_t argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const & s) const { return std::hash()(s); } +}; + +} // namespace std + #endif // __HASHING_H__ diff --git a/src/mame/drivers/aleisttl.cpp b/src/mame/drivers/aleisttl.cpp index df43a588445..51c2e64ff1a 100644 --- a/src/mame/drivers/aleisttl.cpp +++ b/src/mame/drivers/aleisttl.cpp @@ -7,7 +7,7 @@ Chase (aka Chase1) (1976) Deluxe Soccer (1973) Fire Power (1975) EG-1020-2 - Fütsball (1975) + Fötsball (1975) Galaxy Raider (1974) Hesitation (1974) AL-6500? Hockey, Soccer, Tennis (1974) diff --git a/src/mame/drivers/asteroid.cpp b/src/mame/drivers/asteroid.cpp index 574c420501e..08520d50cbd 100644 --- a/src/mame/drivers/asteroid.cpp +++ b/src/mame/drivers/asteroid.cpp @@ -323,7 +323,7 @@ static INPUT_PORTS_START( asteroid ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("dvg", dvg_device, done_r, nullptr) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CODE(KEYCODE_SPACE) PORT_CODE(JOYCODE_BUTTON3) /* hyperspace */ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(JOYCODE_BUTTON1) /* fire */ - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_TILT ) PORT_SERVICE( 0x80, IP_ACTIVE_HIGH ) @@ -416,7 +416,7 @@ static INPUT_PORTS_START( asterock ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, asteroid_state,clock_r, nullptr) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_CODE(KEYCODE_SPACE) PORT_CODE(JOYCODE_BUTTON3) /* hyperspace */ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(JOYCODE_BUTTON1) /* fire */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT ) PORT_SERVICE( 0x80, IP_ACTIVE_LOW ) @@ -457,7 +457,7 @@ static INPUT_PORTS_START( astdelux ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("dvg", dvg_device, done_r, nullptr) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CODE(KEYCODE_SPACE) PORT_CODE(JOYCODE_BUTTON3) /* hyperspace */ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(JOYCODE_BUTTON1) /* fire */ - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_TILT ) PORT_SERVICE( 0x80, IP_ACTIVE_HIGH ) @@ -542,7 +542,7 @@ static INPUT_PORTS_START( llander ) /* Of the rest, Bit 6 is the 3KHz source. 3,4 and 5 are unknown */ PORT_BIT( 0x38, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, asteroid_state,clock_r, nullptr) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) diff --git a/src/mame/drivers/bwidow.cpp b/src/mame/drivers/bwidow.cpp index 3eb06741e9e..e9d7c1c4629 100644 --- a/src/mame/drivers/bwidow.cpp +++ b/src/mame/drivers/bwidow.cpp @@ -447,7 +447,7 @@ static INPUT_PORTS_START( bwidow ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 ) // To fit "Coin A" Dip Switch PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_SERVICE( 0x10, IP_ACTIVE_LOW ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") /* bit 6 is the VG HALT bit. We set it to "low" */ /* per default (busy vector processor). */ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("avg", avg_device, done_r, nullptr) @@ -525,7 +525,7 @@ static INPUT_PORTS_START( gravitar ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 ) // To fit "Coin A" Dip Switch PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_SERVICE( 0x10, IP_ACTIVE_LOW ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") /* bit 6 is the VG HALT bit. We set it to "low" */ /* per default (busy vector processor). */ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("avg", avg_device, done_r, nullptr) @@ -633,7 +633,7 @@ static INPUT_PORTS_START( spacduel ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 ) // To fit "Coin A" Dip Switch PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_SERVICE( 0x10, IP_ACTIVE_LOW ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") /* bit 6 is the VG HALT bit. We set it to "low" */ /* per default (busy vector processor). */ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("avg", avg_device, done_r, nullptr) diff --git a/src/mame/drivers/bzone.cpp b/src/mame/drivers/bzone.cpp index f95bf75f3d7..2da43382822 100644 --- a/src/mame/drivers/bzone.cpp +++ b/src/mame/drivers/bzone.cpp @@ -355,7 +355,7 @@ ADDRESS_MAP_END PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )\ PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )\ PORT_SERVICE( 0x10, IP_ACTIVE_LOW )\ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1)\ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") \ /* bit 6 is the VG HALT bit. We set it to "low" */\ /* per default (busy vector processor). */\ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("avg", avg_bzone_device, done_r, nullptr)\ diff --git a/src/mame/drivers/dec0.cpp b/src/mame/drivers/dec0.cpp index 0c84483b3ad..a04f9106f89 100644 --- a/src/mame/drivers/dec0.cpp +++ b/src/mame/drivers/dec0.cpp @@ -51,7 +51,7 @@ ToDo: - Get rid of ROM patches in Sly Spy and Hippodrome; - background pen in Birdie Try is presumably wrong. - Pixel clock frequency isn't verified; -- Finally, get a proper decap of the MCUs used by Drangonninja and Birdie Try; +- Finally, get a proper decap of the MCUs used by Dragonninja and Birdie Try; Bad Dudes MCU dump came from an MCU that had been damaged during a misguided diff --git a/src/mame/drivers/firetrk.cpp b/src/mame/drivers/firetrk.cpp index 6faf9916048..7a465d04edd 100644 --- a/src/mame/drivers/firetrk.cpp +++ b/src/mame/drivers/firetrk.cpp @@ -434,7 +434,7 @@ static INPUT_PORTS_START( firetrk ) PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet )) PORT_DIPSETTING( 0x00, "Smokey Joe (1 Player)" ) PORT_DIPSETTING( 0x40, "Fire Truck (2 Players)" ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Diag Hold") PORT_CODE(KEYCODE_F6) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE2 ) PORT_NAME("Diag Hold") PORT_START("BIT_7") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) @@ -444,7 +444,7 @@ static INPUT_PORTS_START( firetrk ) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,crash_r, (void *)2) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Diag Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Diag Step") PORT_START("HORN") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Horn") PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,firetrk_horn_changed, 0) diff --git a/src/mame/drivers/lwriter.cpp b/src/mame/drivers/lwriter.cpp index c88b5220ea3..1034ecbad7e 100644 --- a/src/mame/drivers/lwriter.cpp +++ b/src/mame/drivers/lwriter.cpp @@ -4,13 +4,25 @@ Apple LaserWriter II NT driver + 0x000000 - 0x1fffff ???/ROM (switches based on overlay) + 0x200000 - 0x3fffff ROM + 0x400000 - 0x5fffff RAM + 0x600000 - 0x7fffff ??? more RAM? + 0x800000 - 0x9fffff LED/Printer Controls + 0xa00000 - 0xbfffff Zilog 8530 SCC (Serial Control Chip) Read + 0xc00000 - 0xdfffff Zilog 8530 SCC (Serial Control Chip) Write + 0xe00000 - 0xefffff Rockwell 6522 VIA + 0xf00000 - 0xffffef ??? (the ROM appears to be accessing here) + 0xfffff0 - 0xffffff ???Auto Vector?? + TODO: - Get the board to pass its self test, it fails long before it even bothers reading the dipswitches - - Hook up SCC and VIA interrupt pins to the 68k - Hook up the rest of the VIA pins to a canon printer HLE stub - Hook up ADB bitbang device to the VIA CB1, CB2 and PortA pins - Hook up VIA Port A, bits 5 and 6 to the SW1 and SW2 panel switches - Everything else + DONE: + - Hook up SCC and VIA interrupt pins to the 68k Future: - Let the board identify itself to a emulated mac driver so it displays the printer icon on the desktop @@ -100,7 +112,7 @@ public: { } DECLARE_READ16_MEMBER(bankedarea_r); DECLARE_WRITE16_MEMBER(bankedarea_w); - DECLARE_WRITE8_MEMBER(led_w); + DECLARE_WRITE8_MEMBER(led_out_w); DECLARE_READ8_MEMBER(via_pa_r); DECLARE_WRITE8_MEMBER(via_pa_w); DECLARE_WRITE_LINE_MEMBER(via_ca2_w); @@ -109,6 +121,7 @@ public: DECLARE_WRITE_LINE_MEMBER(via_cb1_w); DECLARE_WRITE_LINE_MEMBER(via_cb2_w); DECLARE_WRITE_LINE_MEMBER(via_int_w); + //DECLARE_WRITE_LINE_MEMBER(scc_int); virtual void machine_start () override; virtual void machine_reset () override; private: @@ -122,7 +135,7 @@ private: required_device m_via; #endif - // + uint16_t *m_ram_ptr, *m_rom_ptr; bool m_overlay; }; @@ -138,7 +151,8 @@ a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 0 0 A 0 1 0 * * * * * * * * * * * * * * * * * * R ROMEN3 0 0 A 0 1 1 * * * * * * * * * * * * * * * * * * R ROMEN4 0 0 A 1 x x x x x x x x x x x x x x x x x x x x OPEN BUS -0 1 * * * * * * * * * * * * * * * * * * * * * * RW DRAM +0 1 0 * * * * * * * * * * * * * * * * * * * * * RW DRAM +0 1 1 * * * * * * * * * * * * * * * * * * * * * RW ???? DRAM mirror? 1 0 0 ? ? ? x x x x x x x x x x x x x x x x x 1 W Status LEDs and mech 1 0 1 ? ? ? x x x x x x x x x x x x x x x * * 1 R 8530 SCC Read 1 1 0 ? ? ? x x x x x x x x x x x x x x x * * 0 W 8530 SCC Write @@ -153,7 +167,7 @@ map when overlay is set, i.e. A above is considered 'x': 000000-1fffff ROM (second half is open bus) 200000-3fffff ROM (second half is open bus) 400000-5fffff DRAM? -600000-7fffff unknown +600000-7fffff unknown, DRAM mirror? 800000-83ffff LEDs and status bits to printer mechanism 840000-9fffff unknown a00000-a3ffff SCC read @@ -169,7 +183,7 @@ map when overlay is clear, i.e. A above is considered '1': 000000-1fffff unknown, maybe RAM???? maybe eeprom goes here too? eeprom is specifically disabled when overlay is set 200000-3fffff ROM (second half is open bus) 400000-5fffff DRAM? -600000-7fffff unknown +600000-7fffff unknown, DRAM mirror? 800000-83ffff LEDs and status bits to printer mechanism 840000-9fffff unknown a00000-a3ffff SCC read @@ -189,8 +203,9 @@ static ADDRESS_MAP_START (maincpu_map, AS_PROGRAM, 16, lwriter_state) AM_RANGE(0x000000, 0x1fffff) AM_READWRITE(bankedarea_r, bankedarea_w) AM_RANGE(0x200000, 0x2fffff) AM_ROM AM_REGION("rom", 0) // 1MB ROM //AM_RANGE(0x300000, 0x3fffff) // open bus? - AM_RANGE(0x400000, 0x5fffff) AM_RAM AM_REGION("mainram", 0) AM_MIRROR(0x200000) // 2MB DRAM; the AM_MIRROR is probably wrong, but it gets the selftest to failing on test 08 instead of 0A - AM_RANGE(0x800000, 0x800001) AM_WRITE8(led_w, 0xff00) AM_MIRROR(0x1ffffe) // mirror is a guess given that the pals can only decode A18-A23 + AM_RANGE(0x400000, 0x5fffff) AM_RAM AM_REGION("mainram", 0) AM_MIRROR(0x200000) // 2MB DRAM + //AM_RANGE(0x600000, 0x600fff) AM_RAM AM_MIRROR(0x1ff000) // 4096 bytes SRAM???? + AM_RANGE(0x800000, 0x800001) AM_WRITE8(led_out_w, 0xff00) AM_MIRROR(0x1ffffe) // mirror is a guess given that the pals can only decode A18-A23 AM_RANGE(0xc00000, 0xc00001) AM_DEVWRITE8("scc", scc8530_device, ca_w, 0x00ff) AM_MIRROR(0x1ffff8) AM_RANGE(0xc00004, 0xc00005) AM_DEVWRITE8("scc", scc8530_device, da_w, 0x00ff) AM_MIRROR(0x1ffff8) AM_RANGE(0xa00000, 0xa00001) AM_DEVREAD8 ("scc", scc8530_device, ca_r, 0xff00) AM_MIRROR(0x1ffff8) @@ -214,6 +229,8 @@ INPUT_PORTS_END /* Start it up */ void lwriter_state::machine_start() { + m_rom_ptr = (uint16_t*)memregion("rom")->base(); + m_ram_ptr = (uint16_t*)memregion("mainram")->base(); // do stuff here later on like setting up printer mechanisms HLE timers etc } @@ -223,8 +240,29 @@ void lwriter_state::machine_reset() m_via->reset(); } +/* Overlay area */ +READ16_MEMBER(lwriter_state::bankedarea_r) +{ + if (m_overlay) + { + return m_rom_ptr[offset]; + } + // what actually maps here? dram? the sram and eeprom? + return 0xFFFF;//m_ram_ptr[offset]; +} + +WRITE16_MEMBER (lwriter_state::bankedarea_w) +{ + if (!m_overlay) + { + COMBINE_DATA(&m_ram_ptr[offset]); + } + else + fprintf(stderr, "Attempt to write data %04X to offset %08X IGNORED!\n", data, offset); +} + /* 4 diagnostic LEDs, plus 4 i/o lines for the printer */ -WRITE8_MEMBER(lwriter_state::led_w) +WRITE8_MEMBER(lwriter_state::led_out_w) { //popmessage("LED status: %02X\n", data&0xFF); logerror("LED status: %02X\n", data&0xFF); @@ -232,7 +270,6 @@ WRITE8_MEMBER(lwriter_state::led_w) } /* via stuff */ -// second via READ8_MEMBER(lwriter_state::via_pa_r) { logerror(" VIA: Port A read!\n"); @@ -258,6 +295,8 @@ READ8_MEMBER(lwriter_state::via_pb_r) WRITE8_MEMBER(lwriter_state::via_pb_w) { logerror(" VIA: Port B written with data of 0x%02x!\n", data); + /* Like early Mac models which had VIA A4 control overlaying, the + * LaserWriter II NT overlay is controlled by VIA B3 */ m_overlay = BIT(data,3); } @@ -274,31 +313,18 @@ WRITE_LINE_MEMBER(lwriter_state::via_cb2_w) WRITE_LINE_MEMBER(lwriter_state::via_int_w) { logerror(" VIA: INT output set to %d!\n", state); + //TODO: this is likely wrong, the VPA pin which controls whether autovector is enabled or not is controlled by PAL U8D, which is not dumped. + m_maincpu->set_input_line_and_vector(M68K_IRQ_1, (state ? ASSERT_LINE : CLEAR_LINE), M68K_INT_ACK_AUTOVECTOR); } -READ16_MEMBER(lwriter_state::bankedarea_r) +/* scc stuff */ +/* +WRITE_LINE_MEMBER(lwriter_state::scc_int) { - uint16_t *rom = (uint16_t *)(memregion("rom")->base()); - //uint16_t *ram = (uint16_t *)(memregion("mainram")->base()); - if (m_overlay == 1) - { - rom += (offset&0x1fffff); - return *rom; - } - else - { - // what actually maps here? the sram and eeprom? - //ram += (offset&0x1fffff); - //return *ram; - return 0xFFFF; /** TODO: fix me */ - } -} - -WRITE16_MEMBER (lwriter_state::bankedarea_w) -{ - uint16_t *ram = (uint16_t *)(memregion("mainram")->base()); - COMBINE_DATA(&ram[offset]); -} + logerror(" SCC: INT output set to %d!\n", state); + //m_via->set_input_line(VIA_CA1, state ? ASSERT_LINE : CLEAR_LINE); + m_via->write_ca1(state); +}*/ #define CPU_CLK (XTAL_22_3210MHz / 2) // Based on pictures form here: http://picclick.co.uk/Apple-Postscript-LaserWriter-IINT-Printer-640-4105-M6009-Mainboard-282160713108.html#&gid=1&pid=7 #define RXC_CLK ((CPU_CLK - (87 * 16 * 70)) / 3) // Tuned to get 9600 baud according to manual, needs rework based on real hardware @@ -315,6 +341,9 @@ static MACHINE_CONFIG_START( lwriter, lwriter_state ) MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE("rs232b", rs232_port_device, write_txd)) MCFG_Z80SCC_OUT_DTRB_CB(DEVWRITELINE("rs232b", rs232_port_device, write_dtr)) MCFG_Z80SCC_OUT_RTSB_CB(DEVWRITELINE("rs232b", rs232_port_device, write_rts)) + /* Interrupt */ + MCFG_Z80SCC_OUT_INT_CB(DEVWRITELINE("via", via6522_device, write_ca1)) + //MCFG_Z80SCC_OUT_INT_CB(WRITELINE(lwriter_state, scc_int)) MCFG_RS232_PORT_ADD ("rs232a", default_rs232_devices, "terminal") MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("scc", scc8530_device, rxa_w)) @@ -373,14 +402,14 @@ MACHINE_CONFIG_END ROM_START(lwriter) ROM_REGION16_BE (0x1000000, "rom", 0) - ROM_LOAD16_BYTE ("342-0545.l0", 0x000001, 0x20000, CRC (6431742d) SHA1 (040bd5b84b49b86f2b0fe9ece378bbc7a10a94ec)) - ROM_LOAD16_BYTE ("342-0546.h0", 0x000000, 0x20000, CRC (c592bfb7) SHA1 (b595ae225238f7fabd1566a3133ea6154e082e2d)) - ROM_LOAD16_BYTE ("342-0547.l1", 0x040001, 0x20000, CRC (205a5ea8) SHA1 (205fefbb5c67a07d57cb6184c69648321a34a8fe)) - ROM_LOAD16_BYTE ("342-0548.h1", 0x040000, 0x20000, CRC (f616e1c3) SHA1 (b9e2cd4d07990b2d1936be97b6e89ef21f06b462)) - ROM_LOAD16_BYTE ("342-0549.l2", 0x080001, 0x20000, CRC (0b0b051a) SHA1 (64a80085001570c3f99d9865031715bf49bd7698)) - ROM_LOAD16_BYTE ("342-0550.h2", 0x080000, 0x20000, CRC (82adcf85) SHA1 (e2ab728afdae802c0c67fc25c9ba278b9cb04e31)) - ROM_LOAD16_BYTE ("342-0551.l3", 0x0c0001, 0x20000, CRC (176b3346) SHA1 (eb8dfc7e44f2bc884097e51a47e2f10ee091c9e9)) - ROM_LOAD16_BYTE ("342-0552.h3", 0x0c0000, 0x20000, CRC (69b175c6) SHA1 (a84c82be1ec7e373bb097ee74b941920a3b091aa)) + ROM_LOAD16_BYTE ("342-0545.l0", 0x000001, 0x20000, CRC (6431742d) SHA1 (040bd5b84b49b86f2b0fe9ece378bbc7a10a94ec)) // Label: "342-0545-A JAPAN // TC531000CP-F700 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @L0 + ROM_LOAD16_BYTE ("342-0546.h0", 0x000000, 0x20000, CRC (c592bfb7) SHA1 (b595ae225238f7fabd1566a3133ea6154e082e2d)) // Label: "342-0546-A JAPAN // TC531000CP-F701 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @H0 + ROM_LOAD16_BYTE ("342-0547.l1", 0x040001, 0x20000, CRC (205a5ea8) SHA1 (205fefbb5c67a07d57cb6184c69648321a34a8fe)) // Label: "342-0547-A JAPAN // TC531000CP-F702 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @L1 + ROM_LOAD16_BYTE ("342-0548.h1", 0x040000, 0x20000, CRC (f616e1c3) SHA1 (b9e2cd4d07990b2d1936be97b6e89ef21f06b462)) // Label: "342-0548-A JAPAN // TC531000CP-F703 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @H1 + ROM_LOAD16_BYTE ("342-0549.l2", 0x080001, 0x20000, CRC (0b0b051a) SHA1 (64a80085001570c3f99d9865031715bf49bd7698)) // Label: "342-0549-A JAPAN // TC531000CP-F704 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @L2 + ROM_LOAD16_BYTE ("342-0550.h2", 0x080000, 0x20000, CRC (82adcf85) SHA1 (e2ab728afdae802c0c67fc25c9ba278b9cb04e31)) // Label: "342-0550-A JAPAN // TC531000CP-F705 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @H2 + ROM_LOAD16_BYTE ("342-0551.l3", 0x0c0001, 0x20000, CRC (176b3346) SHA1 (eb8dfc7e44f2bc884097e51a47e2f10ee091c9e9)) // Label: "342-0551-A JAPAN // TC531000CP-F706 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @L3 + ROM_LOAD16_BYTE ("342-0552.h3", 0x0c0000, 0x20000, CRC (69b175c6) SHA1 (a84c82be1ec7e373bb097ee74b941920a3b091aa)) // Label: "342-0552-A JAPAN // TC531000CP-F707 // (C) 87 APPLE 8940EAI // (C) 83-87 ADOBE V47.0 // (C) 81 LINOTYPE" TC531000 @H3 ROM_REGION( 0x200000, "mainram", ROMREGION_ERASEFF ) ROM_END diff --git a/src/mame/drivers/starwars.cpp b/src/mame/drivers/starwars.cpp index d3efae464cc..59320b60504 100644 --- a/src/mame/drivers/starwars.cpp +++ b/src/mame/drivers/starwars.cpp @@ -204,7 +204,7 @@ static INPUT_PORTS_START( starwars ) PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Diagnostic Step") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) diff --git a/src/mame/drivers/tempest.cpp b/src/mame/drivers/tempest.cpp index ed90b761427..52aa2e411b1 100644 --- a/src/mame/drivers/tempest.cpp +++ b/src/mame/drivers/tempest.cpp @@ -477,7 +477,7 @@ static INPUT_PORTS_START( tempest ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT ) PORT_SERVICE( 0x10, IP_ACTIVE_LOW ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Diagnostic Step") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Diagnostic Step") /* bit 6 is the VG HALT bit. We set it to "low" */ /* per default (busy vector processor). */ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("avg", avg_tempest_device, done_r, nullptr) diff --git a/src/mame/video/n64.cpp b/src/mame/video/n64.cpp index ac784a06431..66449ac7425 100644 --- a/src/mame/video/n64.cpp +++ b/src/mame/video/n64.cpp @@ -151,6 +151,8 @@ uint32_t n64_state::screen_update_n64(screen_device &screen, bitmap_rgb32 &bitma } */ + m_rdp->mark_frame(); + if (n64->vi_blank) { bitmap.fill(0, screen.visible_area()); @@ -168,6 +170,7 @@ void n64_state::screen_eof_n64(screen_device &screen, bool state) void n64_periphs::video_update(bitmap_rgb32 &bitmap) { + if(vi_control & 0x40) /* Interlace */ { field ^= 1; @@ -1095,15 +1098,15 @@ uint32_t n64_rdp::get_log2(uint32_t lod_clamp) /*****************************************************************************/ -uint32_t n64_rdp::read_data(uint32_t address) +uint64_t n64_rdp::read_data(uint32_t address) { if (m_status & 0x1) // XBUS_DMEM_DMA enabled { - return m_dmem[(address & 0xfff) / 4]; + return (uint64_t(m_dmem[(address & 0xfff) / 4]) << 32) | m_dmem[((address + 4) & 0xfff) / 4]; } else { - return m_rdram[((address & 0xffffff) / 4)]; + return (uint64_t(m_rdram[((address & 0xffffff) / 4)]) << 32) | m_rdram[(((address + 4) & 0xffffff) / 4)]; } } @@ -1192,39 +1195,38 @@ void n64_rdp::disassemble(char* buffer) char drdy[32], dgdy[32], dbdy[32], dady[32]; char drde[32], dgde[32], dbde[32], dade[32]; - uint32_t cmd[64]; + uint64_t cmd[32]; - const uint32_t length = m_cmd_ptr * 4; + const uint32_t length = m_cmd_ptr * 8; if (length < 8) { sprintf(buffer, "ERROR: length = %d\n", length); return; } - cmd[0] = m_cmd_data[m_cmd_cur+0]; - cmd[1] = m_cmd_data[m_cmd_cur+1]; + cmd[0] = m_cmd_data[m_cmd_cur]; - const int32_t tile = (cmd[1] >> 24) & 0x7; - sprintf(sl, "%4.2f", (float)((cmd[0] >> 12) & 0xfff) / 4.0f); - sprintf(tl, "%4.2f", (float)((cmd[0] >> 0) & 0xfff) / 4.0f); - sprintf(sh, "%4.2f", (float)((cmd[1] >> 12) & 0xfff) / 4.0f); - sprintf(th, "%4.2f", (float)((cmd[1] >> 0) & 0xfff) / 4.0f); + const int32_t tile = (cmd[0] >> 56) & 0x7; + sprintf(sl, "%4.2f", (float)((cmd[0] >> 44) & 0xfff) / 4.0f); + sprintf(tl, "%4.2f", (float)((cmd[0] >> 32) & 0xfff) / 4.0f); + sprintf(sh, "%4.2f", (float)((cmd[0] >> 12) & 0xfff) / 4.0f); + sprintf(th, "%4.2f", (float)((cmd[0] >> 0) & 0xfff) / 4.0f); - const char* format = s_image_format[(cmd[0] >> 21) & 0x7]; - const char* size = s_image_size[(cmd[0] >> 19) & 0x3]; + const char* format = s_image_format[(cmd[0] >> 53) & 0x7]; + const char* size = s_image_size[(cmd[0] >> 51) & 0x3]; - const uint32_t r = (cmd[1] >> 24) & 0xff; - const uint32_t g = (cmd[1] >> 16) & 0xff; - const uint32_t b = (cmd[1] >> 8) & 0xff; - const uint32_t a = (cmd[1] >> 0) & 0xff; + const uint32_t r = (cmd[0] >> 24) & 0xff; + const uint32_t g = (cmd[0] >> 16) & 0xff; + const uint32_t b = (cmd[0] >> 8) & 0xff; + const uint32_t a = (cmd[0] >> 0) & 0xff; - const uint32_t command = (cmd[0] >> 24) & 0x3f; + const uint32_t command = (cmd[0] >> 56) & 0x3f; switch (command) { case 0x00: sprintf(buffer, "No Op"); break; case 0x08: // Tri_NoShade { - const int32_t lft = (command >> 23) & 0x1; + const int32_t lft = (cmd[0] >> 55) & 0x1; if (length != s_rdp_command_length[command]) { @@ -1232,29 +1234,26 @@ void n64_rdp::disassemble(char* buffer) return; } + cmd[1] = m_cmd_data[m_cmd_cur+1]; cmd[2] = m_cmd_data[m_cmd_cur+2]; cmd[3] = m_cmd_data[m_cmd_cur+3]; - cmd[4] = m_cmd_data[m_cmd_cur+4]; - cmd[5] = m_cmd_data[m_cmd_cur+5]; - cmd[6] = m_cmd_data[m_cmd_cur+6]; - cmd[7] = m_cmd_data[m_cmd_cur+7]; - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)(cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)(cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)(cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)(cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)(cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)(cmd[7] / 65536.0f)); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); sprintf(buffer, "Tri_NoShade %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); break; } case 0x09: // Tri_NoShadeZ { - const int32_t lft = (command >> 23) & 0x1; + const int32_t lft = (cmd[0] >> 55) & 0x1; if (length != s_rdp_command_length[command]) { @@ -1262,29 +1261,26 @@ void n64_rdp::disassemble(char* buffer) return; } + cmd[1] = m_cmd_data[m_cmd_cur+1]; cmd[2] = m_cmd_data[m_cmd_cur+2]; cmd[3] = m_cmd_data[m_cmd_cur+3]; - cmd[4] = m_cmd_data[m_cmd_cur+4]; - cmd[5] = m_cmd_data[m_cmd_cur+5]; - cmd[6] = m_cmd_data[m_cmd_cur+6]; - cmd[7] = m_cmd_data[m_cmd_cur+7]; - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)(cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)(cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)(cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)(cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)(cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)(cmd[7] / 65536.0f)); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); sprintf(buffer, "Tri_NoShadeZ %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); break; } case 0x0a: // Tri_Tex { - const int32_t lft = (command >> 23) & 0x1; + const int32_t lft = (cmd[0] >> 55) & 0x1; if (length < s_rdp_command_length[command]) { @@ -1292,34 +1288,33 @@ void n64_rdp::disassemble(char* buffer) return; } - for (int32_t i = 2; i < 24; i++) + for (int32_t i = 1; i < 12; i++) { cmd[i] = m_cmd_data[m_cmd_cur+i]; } - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)((int32_t)cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)((int32_t)cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)((int32_t)cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)((int32_t)cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)((int32_t)cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)((int32_t)cmd[7] / 65536.0f)); - - sprintf(s, "%4.4f", (float)(int32_t)((cmd[ 8] & 0xffff0000) | ((cmd[12] >> 16) & 0xffff)) / 65536.0f); - sprintf(t, "%4.4f", (float)(int32_t)(((cmd[ 8] & 0xffff) << 16) | (cmd[12] & 0xffff)) / 65536.0f); - sprintf(w, "%4.4f", (float)(int32_t)((cmd[ 9] & 0xffff0000) | ((cmd[13] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdx, "%4.4f", (float)(int32_t)((cmd[10] & 0xffff0000) | ((cmd[14] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdx, "%4.4f", (float)(int32_t)(((cmd[10] & 0xffff) << 16) | (cmd[14] & 0xffff)) / 65536.0f); - sprintf(dwdx, "%4.4f", (float)(int32_t)((cmd[11] & 0xffff0000) | ((cmd[15] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsde, "%4.4f", (float)(int32_t)((cmd[16] & 0xffff0000) | ((cmd[20] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtde, "%4.4f", (float)(int32_t)(((cmd[16] & 0xffff) << 16) | (cmd[20] & 0xffff)) / 65536.0f); - sprintf(dwde, "%4.4f", (float)(int32_t)((cmd[17] & 0xffff0000) | ((cmd[21] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdy, "%4.4f", (float)(int32_t)((cmd[18] & 0xffff0000) | ((cmd[22] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdy, "%4.4f", (float)(int32_t)(((cmd[18] & 0xffff) << 16) | (cmd[22] & 0xffff)) / 65536.0f); - sprintf(dwdy, "%4.4f", (float)(int32_t)((cmd[19] & 0xffff0000) | ((cmd[23] >> 16) & 0xffff)) / 65536.0f); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); + sprintf(s, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(t, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(w, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); buffer+=sprintf(buffer, "Tri_Tex %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); buffer+=sprintf(buffer, " "); @@ -1334,7 +1329,7 @@ void n64_rdp::disassemble(char* buffer) } case 0x0b: // Tri_TexZ { - const int32_t lft = (command >> 23) & 0x1; + const int32_t lft = (cmd[0] >> 55) & 0x1; if (length < s_rdp_command_length[command]) { @@ -1342,34 +1337,33 @@ void n64_rdp::disassemble(char* buffer) return; } - for (int32_t i = 2; i < 24; i++) + for (int32_t i = 1; i < 12; i++) { cmd[i] = m_cmd_data[m_cmd_cur+i]; } - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)((int32_t)cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)((int32_t)cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)((int32_t)cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)((int32_t)cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)((int32_t)cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)((int32_t)cmd[7] / 65536.0f)); - - sprintf(s, "%4.4f", (float)(int32_t)((cmd[ 8] & 0xffff0000) | ((cmd[12] >> 16) & 0xffff)) / 65536.0f); - sprintf(t, "%4.4f", (float)(int32_t)(((cmd[ 8] & 0xffff) << 16) | (cmd[12] & 0xffff)) / 65536.0f); - sprintf(w, "%4.4f", (float)(int32_t)((cmd[ 9] & 0xffff0000) | ((cmd[13] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdx, "%4.4f", (float)(int32_t)((cmd[10] & 0xffff0000) | ((cmd[14] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdx, "%4.4f", (float)(int32_t)(((cmd[10] & 0xffff) << 16) | (cmd[14] & 0xffff)) / 65536.0f); - sprintf(dwdx, "%4.4f", (float)(int32_t)((cmd[11] & 0xffff0000) | ((cmd[15] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsde, "%4.4f", (float)(int32_t)((cmd[16] & 0xffff0000) | ((cmd[20] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtde, "%4.4f", (float)(int32_t)(((cmd[16] & 0xffff) << 16) | (cmd[20] & 0xffff)) / 65536.0f); - sprintf(dwde, "%4.4f", (float)(int32_t)((cmd[17] & 0xffff0000) | ((cmd[21] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdy, "%4.4f", (float)(int32_t)((cmd[18] & 0xffff0000) | ((cmd[22] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdy, "%4.4f", (float)(int32_t)(((cmd[18] & 0xffff) << 16) | (cmd[22] & 0xffff)) / 65536.0f); - sprintf(dwdy, "%4.4f", (float)(int32_t)((cmd[19] & 0xffff0000) | ((cmd[23] >> 16) & 0xffff)) / 65536.0f); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); + sprintf(s, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(t, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(w, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); buffer+=sprintf(buffer, "Tri_TexZ %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); buffer+=sprintf(buffer, " "); @@ -1392,36 +1386,37 @@ void n64_rdp::disassemble(char* buffer) return; } - for (int32_t i = 2; i < 24; i++) + for (int32_t i = 1; i < 12; i++) { cmd[i] = m_cmd_data[i]; } - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)((int32_t)cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)((int32_t)cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)((int32_t)cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)((int32_t)cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)((int32_t)cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)((int32_t)cmd[7] / 65536.0f)); - sprintf(rt, "%4.4f", (float)(int32_t)((cmd[8] & 0xffff0000) | ((cmd[12] >> 16) & 0xffff)) / 65536.0f); - sprintf(gt, "%4.4f", (float)(int32_t)(((cmd[8] & 0xffff) << 16) | (cmd[12] & 0xffff)) / 65536.0f); - sprintf(bt, "%4.4f", (float)(int32_t)((cmd[9] & 0xffff0000) | ((cmd[13] >> 16) & 0xffff)) / 65536.0f); - sprintf(at, "%4.4f", (float)(int32_t)(((cmd[9] & 0xffff) << 16) | (cmd[13] & 0xffff)) / 65536.0f); - sprintf(drdx, "%4.4f", (float)(int32_t)((cmd[10] & 0xffff0000) | ((cmd[14] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdx, "%4.4f", (float)(int32_t)(((cmd[10] & 0xffff) << 16) | (cmd[14] & 0xffff)) / 65536.0f); - sprintf(dbdx, "%4.4f", (float)(int32_t)((cmd[11] & 0xffff0000) | ((cmd[15] >> 16) & 0xffff)) / 65536.0f); - sprintf(dadx, "%4.4f", (float)(int32_t)(((cmd[11] & 0xffff) << 16) | (cmd[15] & 0xffff)) / 65536.0f); - sprintf(drde, "%4.4f", (float)(int32_t)((cmd[16] & 0xffff0000) | ((cmd[20] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgde, "%4.4f", (float)(int32_t)(((cmd[16] & 0xffff) << 16) | (cmd[20] & 0xffff)) / 65536.0f); - sprintf(dbde, "%4.4f", (float)(int32_t)((cmd[17] & 0xffff0000) | ((cmd[21] >> 16) & 0xffff)) / 65536.0f); - sprintf(dade, "%4.4f", (float)(int32_t)(((cmd[17] & 0xffff) << 16) | (cmd[21] & 0xffff)) / 65536.0f); - sprintf(drdy, "%4.4f", (float)(int32_t)((cmd[18] & 0xffff0000) | ((cmd[22] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdy, "%4.4f", (float)(int32_t)(((cmd[18] & 0xffff) << 16) | (cmd[22] & 0xffff)) / 65536.0f); - sprintf(dbdy, "%4.4f", (float)(int32_t)((cmd[19] & 0xffff0000) | ((cmd[23] >> 16) & 0xffff)) / 65536.0f); - sprintf(dady, "%4.4f", (float)(int32_t)(((cmd[19] & 0xffff) << 16) | (cmd[23] & 0xffff)) / 65536.0f); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); + + sprintf(rt, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(gt, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(bt, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(at, "%4.4f", (float)int32_t( ((cmd[4] & 0x0000ffff) << 16) | ( cmd[ 6] & 0xffff)) / 65536.0f); + sprintf(drdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dadx, "%4.4f", (float)int32_t( ((cmd[5] & 0x0000ffff) << 16) | ( cmd[ 7] & 0xffff)) / 65536.0f); + sprintf(drde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dade, "%4.4f", (float)int32_t( ((cmd[8] & 0x0000ffff) << 16) | ( cmd[10] & 0xffff)) / 65536.0f); + sprintf(drdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); + sprintf(dady, "%4.4f", (float)int32_t( ((cmd[9] & 0x0000ffff) << 16) | ( cmd[11] & 0xffff)) / 65536.0f); buffer+=sprintf(buffer, "Tri_Shade %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); buffer+=sprintf(buffer, " "); @@ -1444,36 +1439,37 @@ void n64_rdp::disassemble(char* buffer) return; } - for (int32_t i = 2; i < 24; i++) + for (int32_t i = 1; i < 12; i++) { cmd[i] = m_cmd_data[i]; } - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)((int32_t)cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)((int32_t)cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)((int32_t)cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)((int32_t)cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)((int32_t)cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)((int32_t)cmd[7] / 65536.0f)); - sprintf(rt, "%4.4f", (float)(int32_t)((cmd[8] & 0xffff0000) | ((cmd[12] >> 16) & 0xffff)) / 65536.0f); - sprintf(gt, "%4.4f", (float)(int32_t)(((cmd[8] & 0xffff) << 16) | (cmd[12] & 0xffff)) / 65536.0f); - sprintf(bt, "%4.4f", (float)(int32_t)((cmd[9] & 0xffff0000) | ((cmd[13] >> 16) & 0xffff)) / 65536.0f); - sprintf(at, "%4.4f", (float)(int32_t)(((cmd[9] & 0xffff) << 16) | (cmd[13] & 0xffff)) / 65536.0f); - sprintf(drdx, "%4.4f", (float)(int32_t)((cmd[10] & 0xffff0000) | ((cmd[14] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdx, "%4.4f", (float)(int32_t)(((cmd[10] & 0xffff) << 16) | (cmd[14] & 0xffff)) / 65536.0f); - sprintf(dbdx, "%4.4f", (float)(int32_t)((cmd[11] & 0xffff0000) | ((cmd[15] >> 16) & 0xffff)) / 65536.0f); - sprintf(dadx, "%4.4f", (float)(int32_t)(((cmd[11] & 0xffff) << 16) | (cmd[15] & 0xffff)) / 65536.0f); - sprintf(drde, "%4.4f", (float)(int32_t)((cmd[16] & 0xffff0000) | ((cmd[20] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgde, "%4.4f", (float)(int32_t)(((cmd[16] & 0xffff) << 16) | (cmd[20] & 0xffff)) / 65536.0f); - sprintf(dbde, "%4.4f", (float)(int32_t)((cmd[17] & 0xffff0000) | ((cmd[21] >> 16) & 0xffff)) / 65536.0f); - sprintf(dade, "%4.4f", (float)(int32_t)(((cmd[17] & 0xffff) << 16) | (cmd[21] & 0xffff)) / 65536.0f); - sprintf(drdy, "%4.4f", (float)(int32_t)((cmd[18] & 0xffff0000) | ((cmd[22] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdy, "%4.4f", (float)(int32_t)(((cmd[18] & 0xffff) << 16) | (cmd[22] & 0xffff)) / 65536.0f); - sprintf(dbdy, "%4.4f", (float)(int32_t)((cmd[19] & 0xffff0000) | ((cmd[23] >> 16) & 0xffff)) / 65536.0f); - sprintf(dady, "%4.4f", (float)(int32_t)(((cmd[19] & 0xffff) << 16) | (cmd[23] & 0xffff)) / 65536.0f); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); + + sprintf(rt, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(gt, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(bt, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(at, "%4.4f", (float)int32_t( ((cmd[4] & 0x0000ffff) << 16) | ( cmd[ 6] & 0xffff)) / 65536.0f); + sprintf(drdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dadx, "%4.4f", (float)int32_t( ((cmd[5] & 0x0000ffff) << 16) | ( cmd[ 7] & 0xffff)) / 65536.0f); + sprintf(drde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dade, "%4.4f", (float)int32_t( ((cmd[8] & 0x0000ffff) << 16) | ( cmd[10] & 0xffff)) / 65536.0f); + sprintf(drdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); + sprintf(dady, "%4.4f", (float)int32_t( ((cmd[9] & 0x0000ffff) << 16) | ( cmd[11] & 0xffff)) / 65536.0f); buffer+=sprintf(buffer, "Tri_ShadeZ %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); buffer+=sprintf(buffer, " "); @@ -1496,50 +1492,50 @@ void n64_rdp::disassemble(char* buffer) return; } - for (int32_t i = 2; i < 40; i++) + for (int32_t i = 1; i < 20; i++) { cmd[i] = m_cmd_data[m_cmd_cur+i]; } - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)((int32_t)cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)((int32_t)cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)((int32_t)cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)((int32_t)cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)((int32_t)cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)((int32_t)cmd[7] / 65536.0f)); - sprintf(rt, "%4.4f", (float)(int32_t)((cmd[8] & 0xffff0000) | ((cmd[12] >> 16) & 0xffff)) / 65536.0f); - sprintf(gt, "%4.4f", (float)(int32_t)(((cmd[8] & 0xffff) << 16) | (cmd[12] & 0xffff)) / 65536.0f); - sprintf(bt, "%4.4f", (float)(int32_t)((cmd[9] & 0xffff0000) | ((cmd[13] >> 16) & 0xffff)) / 65536.0f); - sprintf(at, "%4.4f", (float)(int32_t)(((cmd[9] & 0xffff) << 16) | (cmd[13] & 0xffff)) / 65536.0f); - sprintf(drdx, "%4.4f", (float)(int32_t)((cmd[10] & 0xffff0000) | ((cmd[14] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdx, "%4.4f", (float)(int32_t)(((cmd[10] & 0xffff) << 16) | (cmd[14] & 0xffff)) / 65536.0f); - sprintf(dbdx, "%4.4f", (float)(int32_t)((cmd[11] & 0xffff0000) | ((cmd[15] >> 16) & 0xffff)) / 65536.0f); - sprintf(dadx, "%4.4f", (float)(int32_t)(((cmd[11] & 0xffff) << 16) | (cmd[15] & 0xffff)) / 65536.0f); - sprintf(drde, "%4.4f", (float)(int32_t)((cmd[16] & 0xffff0000) | ((cmd[20] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgde, "%4.4f", (float)(int32_t)(((cmd[16] & 0xffff) << 16) | (cmd[20] & 0xffff)) / 65536.0f); - sprintf(dbde, "%4.4f", (float)(int32_t)((cmd[17] & 0xffff0000) | ((cmd[21] >> 16) & 0xffff)) / 65536.0f); - sprintf(dade, "%4.4f", (float)(int32_t)(((cmd[17] & 0xffff) << 16) | (cmd[21] & 0xffff)) / 65536.0f); - sprintf(drdy, "%4.4f", (float)(int32_t)((cmd[18] & 0xffff0000) | ((cmd[22] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdy, "%4.4f", (float)(int32_t)(((cmd[18] & 0xffff) << 16) | (cmd[22] & 0xffff)) / 65536.0f); - sprintf(dbdy, "%4.4f", (float)(int32_t)((cmd[19] & 0xffff0000) | ((cmd[23] >> 16) & 0xffff)) / 65536.0f); - sprintf(dady, "%4.4f", (float)(int32_t)(((cmd[19] & 0xffff) << 16) | (cmd[23] & 0xffff)) / 65536.0f); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); - sprintf(s, "%4.4f", (float)(int32_t)((cmd[24] & 0xffff0000) | ((cmd[28] >> 16) & 0xffff)) / 65536.0f); - sprintf(t, "%4.4f", (float)(int32_t)(((cmd[24] & 0xffff) << 16) | (cmd[28] & 0xffff)) / 65536.0f); - sprintf(w, "%4.4f", (float)(int32_t)((cmd[25] & 0xffff0000) | ((cmd[29] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdx, "%4.4f", (float)(int32_t)((cmd[26] & 0xffff0000) | ((cmd[30] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdx, "%4.4f", (float)(int32_t)(((cmd[26] & 0xffff) << 16) | (cmd[30] & 0xffff)) / 65536.0f); - sprintf(dwdx, "%4.4f", (float)(int32_t)((cmd[27] & 0xffff0000) | ((cmd[31] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsde, "%4.4f", (float)(int32_t)((cmd[32] & 0xffff0000) | ((cmd[36] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtde, "%4.4f", (float)(int32_t)(((cmd[32] & 0xffff) << 16) | (cmd[36] & 0xffff)) / 65536.0f); - sprintf(dwde, "%4.4f", (float)(int32_t)((cmd[33] & 0xffff0000) | ((cmd[37] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdy, "%4.4f", (float)(int32_t)((cmd[34] & 0xffff0000) | ((cmd[38] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdy, "%4.4f", (float)(int32_t)(((cmd[34] & 0xffff) << 16) | (cmd[38] & 0xffff)) / 65536.0f); - sprintf(dwdy, "%4.4f", (float)(int32_t)((cmd[35] & 0xffff0000) | ((cmd[39] >> 16) & 0xffff)) / 65536.0f); + sprintf(rt, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(gt, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(bt, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(at, "%4.4f", (float)int32_t( ((cmd[4] & 0x0000ffff) << 16) | ( cmd[ 6] & 0xffff)) / 65536.0f); + sprintf(drdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dadx, "%4.4f", (float)int32_t( ((cmd[5] & 0x0000ffff) << 16) | ( cmd[ 7] & 0xffff)) / 65536.0f); + sprintf(drde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dade, "%4.4f", (float)int32_t( ((cmd[8] & 0x0000ffff) << 16) | ( cmd[10] & 0xffff)) / 65536.0f); + sprintf(drdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); + sprintf(dady, "%4.4f", (float)int32_t( ((cmd[9] & 0x0000ffff) << 16) | ( cmd[11] & 0xffff)) / 65536.0f); + sprintf(s, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(t, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(w, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); buffer+=sprintf(buffer, "Tri_TexShade %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); buffer+=sprintf(buffer, " "); @@ -1571,50 +1567,50 @@ void n64_rdp::disassemble(char* buffer) return; } - for (int32_t i = 2; i < 40; i++) + for (int32_t i = 1; i < 20; i++) { cmd[i] = m_cmd_data[m_cmd_cur+i]; } - sprintf(yl, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); - sprintf(ym, "%4.4f", (float)((cmd[1] >> 16) & 0x1fff) / 4.0f); - sprintf(yh, "%4.4f", (float)((cmd[1] >> 0) & 0x1fff) / 4.0f); - sprintf(xl, "%4.4f", (float)((int32_t)cmd[2] / 65536.0f)); - sprintf(dxldy, "%4.4f", (float)((int32_t)cmd[3] / 65536.0f)); - sprintf(xh, "%4.4f", (float)((int32_t)cmd[4] / 65536.0f)); - sprintf(dxhdy, "%4.4f", (float)((int32_t)cmd[5] / 65536.0f)); - sprintf(xm, "%4.4f", (float)((int32_t)cmd[6] / 65536.0f)); - sprintf(dxmdy, "%4.4f", (float)((int32_t)cmd[7] / 65536.0f)); - sprintf(rt, "%4.4f", (float)(int32_t)((cmd[8] & 0xffff0000) | ((cmd[12] >> 16) & 0xffff)) / 65536.0f); - sprintf(gt, "%4.4f", (float)(int32_t)(((cmd[8] & 0xffff) << 16) | (cmd[12] & 0xffff)) / 65536.0f); - sprintf(bt, "%4.4f", (float)(int32_t)((cmd[9] & 0xffff0000) | ((cmd[13] >> 16) & 0xffff)) / 65536.0f); - sprintf(at, "%4.4f", (float)(int32_t)(((cmd[9] & 0xffff) << 16) | (cmd[13] & 0xffff)) / 65536.0f); - sprintf(drdx, "%4.4f", (float)(int32_t)((cmd[10] & 0xffff0000) | ((cmd[14] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdx, "%4.4f", (float)(int32_t)(((cmd[10] & 0xffff) << 16) | (cmd[14] & 0xffff)) / 65536.0f); - sprintf(dbdx, "%4.4f", (float)(int32_t)((cmd[11] & 0xffff0000) | ((cmd[15] >> 16) & 0xffff)) / 65536.0f); - sprintf(dadx, "%4.4f", (float)(int32_t)(((cmd[11] & 0xffff) << 16) | (cmd[15] & 0xffff)) / 65536.0f); - sprintf(drde, "%4.4f", (float)(int32_t)((cmd[16] & 0xffff0000) | ((cmd[20] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgde, "%4.4f", (float)(int32_t)(((cmd[16] & 0xffff) << 16) | (cmd[20] & 0xffff)) / 65536.0f); - sprintf(dbde, "%4.4f", (float)(int32_t)((cmd[17] & 0xffff0000) | ((cmd[21] >> 16) & 0xffff)) / 65536.0f); - sprintf(dade, "%4.4f", (float)(int32_t)(((cmd[17] & 0xffff) << 16) | (cmd[21] & 0xffff)) / 65536.0f); - sprintf(drdy, "%4.4f", (float)(int32_t)((cmd[18] & 0xffff0000) | ((cmd[22] >> 16) & 0xffff)) / 65536.0f); - sprintf(dgdy, "%4.4f", (float)(int32_t)(((cmd[18] & 0xffff) << 16) | (cmd[22] & 0xffff)) / 65536.0f); - sprintf(dbdy, "%4.4f", (float)(int32_t)((cmd[19] & 0xffff0000) | ((cmd[23] >> 16) & 0xffff)) / 65536.0f); - sprintf(dady, "%4.4f", (float)(int32_t)(((cmd[19] & 0xffff) << 16) | (cmd[23] & 0xffff)) / 65536.0f); + sprintf(yl, "%4.4f", (float)((cmd[0] >> 32) & 0x1fff) / 4.0f); + sprintf(ym, "%4.4f", (float)((cmd[0] >> 16) & 0x1fff) / 4.0f); + sprintf(yh, "%4.4f", (float)((cmd[0] >> 0) & 0x1fff) / 4.0f); + sprintf(xl, "%4.4f", (float)int32_t(cmd[1] >> 32) / 65536.0f); + sprintf(dxldy, "%4.4f", (float)int32_t(cmd[1]) / 65536.0f); + sprintf(xh, "%4.4f", (float)int32_t(cmd[2] >> 32) / 65536.0f); + sprintf(dxhdy, "%4.4f", (float)int32_t(cmd[2]) / 65536.0f); + sprintf(xm, "%4.4f", (float)int32_t(cmd[3] >> 32) / 65536.0f); + sprintf(dxmdy, "%4.4f", (float)int32_t(cmd[3]) / 65536.0f); - sprintf(s, "%4.4f", (float)(int32_t)((cmd[24] & 0xffff0000) | ((cmd[28] >> 16) & 0xffff)) / 65536.0f); - sprintf(t, "%4.4f", (float)(int32_t)(((cmd[24] & 0xffff) << 16) | (cmd[28] & 0xffff)) / 65536.0f); - sprintf(w, "%4.4f", (float)(int32_t)((cmd[25] & 0xffff0000) | ((cmd[29] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdx, "%4.4f", (float)(int32_t)((cmd[26] & 0xffff0000) | ((cmd[30] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdx, "%4.4f", (float)(int32_t)(((cmd[26] & 0xffff) << 16) | (cmd[30] & 0xffff)) / 65536.0f); - sprintf(dwdx, "%4.4f", (float)(int32_t)((cmd[27] & 0xffff0000) | ((cmd[31] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsde, "%4.4f", (float)(int32_t)((cmd[32] & 0xffff0000) | ((cmd[36] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtde, "%4.4f", (float)(int32_t)(((cmd[32] & 0xffff) << 16) | (cmd[36] & 0xffff)) / 65536.0f); - sprintf(dwde, "%4.4f", (float)(int32_t)((cmd[33] & 0xffff0000) | ((cmd[37] >> 16) & 0xffff)) / 65536.0f); - sprintf(dsdy, "%4.4f", (float)(int32_t)((cmd[34] & 0xffff0000) | ((cmd[38] >> 16) & 0xffff)) / 65536.0f); - sprintf(dtdy, "%4.4f", (float)(int32_t)(((cmd[34] & 0xffff) << 16) | (cmd[38] & 0xffff)) / 65536.0f); - sprintf(dwdy, "%4.4f", (float)(int32_t)((cmd[35] & 0xffff0000) | ((cmd[39] >> 16) & 0xffff)) / 65536.0f); + sprintf(rt, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(gt, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(bt, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(at, "%4.4f", (float)int32_t( ((cmd[4] & 0x0000ffff) << 16) | ( cmd[ 6] & 0xffff)) / 65536.0f); + sprintf(drdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dadx, "%4.4f", (float)int32_t( ((cmd[5] & 0x0000ffff) << 16) | ( cmd[ 7] & 0xffff)) / 65536.0f); + sprintf(drde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dade, "%4.4f", (float)int32_t( ((cmd[8] & 0x0000ffff) << 16) | ( cmd[10] & 0xffff)) / 65536.0f); + sprintf(drdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dgdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dbdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); + sprintf(dady, "%4.4f", (float)int32_t( ((cmd[9] & 0x0000ffff) << 16) | ( cmd[11] & 0xffff)) / 65536.0f); + sprintf(s, "%4.4f", (float)int32_t( ((cmd[4] >> 32) & 0xffff0000) | ((cmd[ 6] >> 48) & 0xffff)) / 65536.0f); + sprintf(t, "%4.4f", (float)int32_t((((cmd[4] >> 32) & 0x0000ffff) << 16) | ((cmd[ 6] >> 32) & 0xffff)) / 65536.0f); + sprintf(w, "%4.4f", (float)int32_t( (cmd[4] & 0xffff0000) | ((cmd[ 6] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdx, "%4.4f", (float)int32_t( ((cmd[5] >> 32) & 0xffff0000) | ((cmd[ 7] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdx, "%4.4f", (float)int32_t((((cmd[5] >> 32) & 0x0000ffff) << 16) | ((cmd[ 7] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdx, "%4.4f", (float)int32_t( (cmd[5] & 0xffff0000) | ((cmd[ 7] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsde, "%4.4f", (float)int32_t( ((cmd[8] >> 32) & 0xffff0000) | ((cmd[10] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtde, "%4.4f", (float)int32_t((((cmd[8] >> 32) & 0x0000ffff) << 16) | ((cmd[10] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwde, "%4.4f", (float)int32_t( (cmd[8] & 0xffff0000) | ((cmd[10] >> 16) & 0xffff)) / 65536.0f); + sprintf(dsdy, "%4.4f", (float)int32_t( ((cmd[9] >> 32) & 0xffff0000) | ((cmd[11] >> 48) & 0xffff)) / 65536.0f); + sprintf(dtdy, "%4.4f", (float)int32_t((((cmd[9] >> 32) & 0x0000ffff) << 16) | ((cmd[11] >> 32) & 0xffff)) / 65536.0f); + sprintf(dwdy, "%4.4f", (float)int32_t( (cmd[9] & 0xffff0000) | ((cmd[11] >> 16) & 0xffff)) / 65536.0f); buffer+=sprintf(buffer, "Tri_TexShadeZ %d, XL: %s, XM: %s, XH: %s, YL: %s, YM: %s, YH: %s\n", lft, xl,xm,xh,yl,ym,yh); buffer+=sprintf(buffer, " "); @@ -1644,12 +1640,12 @@ void n64_rdp::disassemble(char* buffer) sprintf(buffer, "ERROR: Texture_Rectangle length = %d\n", length); return; } - cmd[2] = m_cmd_data[m_cmd_cur+2]; - cmd[3] = m_cmd_data[m_cmd_cur+3]; - sprintf(s, "%4.4f", (float)(int16_t)((cmd[2] >> 16) & 0xffff) / 32.0f); - sprintf(t, "%4.4f", (float)(int16_t)((cmd[2] >> 0) & 0xffff) / 32.0f); - sprintf(dsdx, "%4.4f", (float)(int16_t)((cmd[3] >> 16) & 0xffff) / 1024.0f); - sprintf(dtdy, "%4.4f", (float)(int16_t)((cmd[3] >> 16) & 0xffff) / 1024.0f); + + cmd[1] = m_cmd_data[m_cmd_cur+1]; + sprintf(s, "%4.4f", (float)int16_t((cmd[1] >> 48) & 0xffff) / 32.0f); + sprintf(t, "%4.4f", (float)int16_t((cmd[1] >> 32) & 0xffff) / 32.0f); + sprintf(dsdx, "%4.4f", (float)int16_t((cmd[1] >> 16) & 0xffff) / 1024.0f); + sprintf(dtdy, "%4.4f", (float)int16_t((cmd[1] >> 0) & 0xffff) / 1024.0f); if (command == 0x24) sprintf(buffer, "Texture_Rectangle %d, %s, %s, %s, %s, %s, %s, %s, %s", tile, sh, th, sl, tl, s, t, dsdx, dtdy); @@ -1663,24 +1659,24 @@ void n64_rdp::disassemble(char* buffer) case 0x28: sprintf(buffer, "Sync_Tile"); break; case 0x29: sprintf(buffer, "Sync_Full"); break; case 0x2d: sprintf(buffer, "Set_Scissor %s, %s, %s, %s", sl, tl, sh, th); break; - case 0x2e: sprintf(buffer, "Set_Prim_Depth %04X, %04X", (cmd[1] >> 16) & 0xffff, cmd[1] & 0xffff); break; - case 0x2f: sprintf(buffer, "Set_Other_Modes %08X %08X", cmd[0], cmd[1]); break; + case 0x2e: sprintf(buffer, "Set_Prim_Depth %04X, %04X", uint32_t(cmd[0] >> 16) & 0xffff, (uint32_t)cmd[0] & 0xffff); break; + case 0x2f: sprintf(buffer, "Set_Other_Modes %08X %08X", uint32_t(cmd[0] >> 32), (uint32_t)cmd[0]); break; case 0x30: sprintf(buffer, "Load_TLUT %d, %s, %s, %s, %s", tile, sl, tl, sh, th); break; case 0x32: sprintf(buffer, "Set_Tile_Size %d, %s, %s, %s, %s", tile, sl, tl, sh, th); break; - case 0x33: sprintf(buffer, "Load_Block %d, %03X, %03X, %03X, %03X", tile, (cmd[0] >> 12) & 0xfff, cmd[0] & 0xfff, (cmd[1] >> 12) & 0xfff, cmd[1] & 0xfff); break; + case 0x33: sprintf(buffer, "Load_Block %d, %03X, %03X, %03X, %03X", tile, uint32_t(cmd[0] >> 44) & 0xfff, uint32_t(cmd[0] >> 32) & 0xfff, uint32_t(cmd[0] >> 12) & 0xfff, uint32_t(cmd[1]) & 0xfff); break; case 0x34: sprintf(buffer, "Load_Tile %d, %s, %s, %s, %s", tile, sl, tl, sh, th); break; - case 0x35: sprintf(buffer, "Set_Tile %d, %s, %s, %d, %04X", tile, format, size, ((cmd[0] >> 9) & 0x1ff) * 8, (cmd[0] & 0x1ff) * 8); break; + case 0x35: sprintf(buffer, "Set_Tile %d, %s, %s, %d, %04X", tile, format, size, (uint32_t(cmd[0] >> 41) & 0x1ff) * 8, (uint32_t(cmd[0] >> 32) & 0x1ff) * 8); break; case 0x36: sprintf(buffer, "Fill_Rectangle %s, %s, %s, %s", sh, th, sl, tl); break; case 0x37: sprintf(buffer, "Set_Fill_Color R: %d, G: %d, B: %d, A: %d", r, g, b, a); break; case 0x38: sprintf(buffer, "Set_Fog_Color R: %d, G: %d, B: %d, A: %d", r, g, b, a); break; case 0x39: sprintf(buffer, "Set_Blend_Color R: %d, G: %d, B: %d, A: %d", r, g, b, a); break; - case 0x3a: sprintf(buffer, "Set_Prim_Color %d, %d, R: %d, G: %d, B: %d, A: %d", (cmd[0] >> 8) & 0x1f, cmd[0] & 0xff, r, g, b, a); break; + case 0x3a: sprintf(buffer, "Set_Prim_Color %d, %d, R: %d, G: %d, B: %d, A: %d", uint32_t(cmd[0] >> 40) & 0x1f, uint32_t(cmd[0] >> 32) & 0xff, r, g, b, a); break; case 0x3b: sprintf(buffer, "Set_Env_Color R: %d, G: %d, B: %d, A: %d", r, g, b, a); break; - case 0x3c: sprintf(buffer, "Set_Combine %08X %08X", cmd[0], cmd[1]); break; - case 0x3d: sprintf(buffer, "Set_Texture_Image %s, %s, %d, %08X", format, size, (cmd[0] & 0x1ff)+1, cmd[1]); break; - case 0x3e: sprintf(buffer, "Set_Mask_Image %08X", cmd[1]); break; - case 0x3f: sprintf(buffer, "Set_Color_Image %s, %s, %d, %08X", format, size, (cmd[0] & 0x1ff)+1, cmd[1]); break; - default: sprintf(buffer, "Unknown (%08X %08X)", cmd[0], cmd[1]); break; + case 0x3c: sprintf(buffer, "Set_Combine %08X %08X", uint32_t(cmd[0] >> 32), (uint32_t)cmd[0]); break; + case 0x3d: sprintf(buffer, "Set_Texture_Image %s, %s, %d, %08X", format, size, (uint32_t(cmd[0] >> 32) & 0x1ff) + 1, (uint32_t)cmd[0]); break; + case 0x3e: sprintf(buffer, "Set_Mask_Image %08X", (uint32_t)cmd[0]); break; + case 0x3f: sprintf(buffer, "Set_Color_Image %s, %s, %d, %08X", format, size, (uint32_t(cmd[0] >> 32) & 0x1ff) + 1, (uint32_t)cmd[0]); break; + default: sprintf(buffer, "Unknown (%08X %08X)", uint32_t(cmd[0] >> 32), (uint32_t)cmd[0]); break; } } @@ -1865,16 +1861,17 @@ void n64_rdp::compute_cvg_flip(extent_t* spans, int32_t* majorx, int32_t* minorx } } +#define SIGN(x, numb) (((x) & ((1 << numb) - 1)) | -((x) & (1 << (numb - 1)))) + void n64_rdp::draw_triangle(bool shade, bool texture, bool zbuffer, bool rect) { - const uint32_t* cmd_data = rect ? m_temp_rect_data : m_cmd_data; + const uint64_t* cmd_data = rect ? m_temp_rect_data : m_cmd_data; const uint32_t fifo_index = rect ? 0 : m_cmd_cur; - const uint32_t w1 = cmd_data[fifo_index + 0]; - const uint32_t w2 = cmd_data[fifo_index + 1]; + const uint64_t w1 = cmd_data[fifo_index + 0]; - int32_t flip = (w1 & 0x00800000) ? 1 : 0; - m_misc_state.m_max_level = ((w1 >> 19) & 7); - int32_t tilenum = (w1 >> 16) & 0x7; + int32_t flip = int32_t(w1 >> 55) & 1; + m_misc_state.m_max_level = uint32_t(w1 >> 51) & 7; + int32_t tilenum = int32_t(w1 >> 48) & 0x7; int32_t dsdiff = 0, dtdiff = 0, dwdiff = 0, drdiff = 0, dgdiff = 0, dbdiff = 0, dadiff = 0, dzdiff = 0; int32_t dsdeh = 0, dtdeh = 0, dwdeh = 0, drdeh = 0, dgdeh = 0, dbdeh = 0, dadeh = 0, dzdeh = 0; @@ -1886,36 +1883,33 @@ void n64_rdp::draw_triangle(bool shade, bool texture, bool zbuffer, bool rect) int32_t maxxhx = 0; int32_t minxhx = 0; - int32_t shade_base = fifo_index + 8; - int32_t texture_base = fifo_index + 8; - int32_t zbuffer_base = fifo_index + 8; + int32_t shade_base = fifo_index + 4; + int32_t texture_base = fifo_index + 4; + int32_t zbuffer_base = fifo_index + 4; if(shade) { - texture_base += 16; - zbuffer_base += 16; + texture_base += 8; + zbuffer_base += 8; } if(texture) { - zbuffer_base += 16; + zbuffer_base += 8; } - uint32_t w3 = cmd_data[fifo_index + 2]; - uint32_t w4 = cmd_data[fifo_index + 3]; - uint32_t w5 = cmd_data[fifo_index + 4]; - uint32_t w6 = cmd_data[fifo_index + 5]; - uint32_t w7 = cmd_data[fifo_index + 6]; - uint32_t w8 = cmd_data[fifo_index + 7]; + uint64_t w2 = cmd_data[fifo_index + 1]; + uint64_t w3 = cmd_data[fifo_index + 2]; + uint64_t w4 = cmd_data[fifo_index + 3]; - int32_t yl = (w1 & 0x3fff); - int32_t ym = ((w2 >> 16) & 0x3fff); - int32_t yh = ((w2 >> 0) & 0x3fff); - int32_t xl = (int32_t)(w3 & 0x3fffffff); - int32_t xh = (int32_t)(w5 & 0x3fffffff); - int32_t xm = (int32_t)(w7 & 0x3fffffff); + int32_t yl = int32_t(w1 >> 32) & 0x3fff; + int32_t ym = int32_t(w1 >> 16) & 0x3fff; + int32_t yh = int32_t(w1 >> 0) & 0x3fff; + int32_t xl = (int32_t)(w2 >> 32) & 0x3fffffff; + int32_t xh = (int32_t)(w3 >> 32) & 0x3fffffff; + int32_t xm = (int32_t)(w4 >> 32) & 0x3fffffff; // Inverse slopes in 16.16 format - int32_t dxldy = (int32_t)(w4); - int32_t dxhdy = (int32_t)(w6); - int32_t dxmdy = (int32_t)(w8); + int32_t dxldy = (int32_t)w2; + int32_t dxhdy = (int32_t)w3; + int32_t dxmdy = (int32_t)w4; if (yl & 0x2000) yl |= 0xffffc000; if (ym & 0x2000) ym |= 0xffffc000; @@ -1925,38 +1919,40 @@ void n64_rdp::draw_triangle(bool shade, bool texture, bool zbuffer, bool rect) if (xm & 0x20000000) xm |= 0xc0000000; if (xh & 0x20000000) xh |= 0xc0000000; - int32_t r = (cmd_data[shade_base+0 ] & 0xffff0000) | ((cmd_data[shade_base+4 ] >> 16) & 0x0000ffff); - int32_t g = ((cmd_data[shade_base+0 ] << 16) & 0xffff0000) | (cmd_data[shade_base+4 ] & 0x0000ffff); - int32_t b = (cmd_data[shade_base+1 ] & 0xffff0000) | ((cmd_data[shade_base+5 ] >> 16) & 0x0000ffff); - int32_t a = ((cmd_data[shade_base+1 ] << 16) & 0xffff0000) | (cmd_data[shade_base+5 ] & 0x0000ffff); - const int32_t drdx = (cmd_data[shade_base+2 ] & 0xffff0000) | ((cmd_data[shade_base+6 ] >> 16) & 0x0000ffff); - const int32_t dgdx = ((cmd_data[shade_base+2 ] << 16) & 0xffff0000) | (cmd_data[shade_base+6 ] & 0x0000ffff); - const int32_t dbdx = (cmd_data[shade_base+3 ] & 0xffff0000) | ((cmd_data[shade_base+7 ] >> 16) & 0x0000ffff); - const int32_t dadx = ((cmd_data[shade_base+3 ] << 16) & 0xffff0000) | (cmd_data[shade_base+7 ] & 0x0000ffff); - const int32_t drde = (cmd_data[shade_base+8 ] & 0xffff0000) | ((cmd_data[shade_base+12] >> 16) & 0x0000ffff); - const int32_t dgde = ((cmd_data[shade_base+8 ] << 16) & 0xffff0000) | (cmd_data[shade_base+12] & 0x0000ffff); - const int32_t dbde = (cmd_data[shade_base+9 ] & 0xffff0000) | ((cmd_data[shade_base+13] >> 16) & 0x0000ffff); - const int32_t dade = ((cmd_data[shade_base+9 ] << 16) & 0xffff0000) | (cmd_data[shade_base+13] & 0x0000ffff); - const int32_t drdy = (cmd_data[shade_base+10] & 0xffff0000) | ((cmd_data[shade_base+14] >> 16) & 0x0000ffff); - const int32_t dgdy = ((cmd_data[shade_base+10] << 16) & 0xffff0000) | (cmd_data[shade_base+14] & 0x0000ffff); - const int32_t dbdy = (cmd_data[shade_base+11] & 0xffff0000) | ((cmd_data[shade_base+15] >> 16) & 0x0000ffff); - const int32_t dady = ((cmd_data[shade_base+11] << 16) & 0xffff0000) | (cmd_data[shade_base+15] & 0x0000ffff); - int32_t s = (cmd_data[texture_base+0 ] & 0xffff0000) | ((cmd_data[texture_base+4 ] >> 16) & 0x0000ffff); - int32_t t = ((cmd_data[texture_base+0 ] << 16) & 0xffff0000) | (cmd_data[texture_base+4 ] & 0x0000ffff); - int32_t w = (cmd_data[texture_base+1 ] & 0xffff0000) | ((cmd_data[texture_base+5 ] >> 16) & 0x0000ffff); - const int32_t dsdx = (cmd_data[texture_base+2 ] & 0xffff0000) | ((cmd_data[texture_base+6 ] >> 16) & 0x0000ffff); - const int32_t dtdx = ((cmd_data[texture_base+2 ] << 16) & 0xffff0000) | (cmd_data[texture_base+6 ] & 0x0000ffff); - const int32_t dwdx = (cmd_data[texture_base+3 ] & 0xffff0000) | ((cmd_data[texture_base+7 ] >> 16) & 0x0000ffff); - const int32_t dsde = (cmd_data[texture_base+8 ] & 0xffff0000) | ((cmd_data[texture_base+12] >> 16) & 0x0000ffff); - const int32_t dtde = ((cmd_data[texture_base+8 ] << 16) & 0xffff0000) | (cmd_data[texture_base+12] & 0x0000ffff); - const int32_t dwde = (cmd_data[texture_base+9 ] & 0xffff0000) | ((cmd_data[texture_base+13] >> 16) & 0x0000ffff); - const int32_t dsdy = (cmd_data[texture_base+10] & 0xffff0000) | ((cmd_data[texture_base+14] >> 16) & 0x0000ffff); - const int32_t dtdy = ((cmd_data[texture_base+10] << 16) & 0xffff0000) | (cmd_data[texture_base+14] & 0x0000ffff); - const int32_t dwdy = (cmd_data[texture_base+11] & 0xffff0000) | ((cmd_data[texture_base+15] >> 16) & 0x0000ffff); - int32_t z = cmd_data[zbuffer_base+0]; - const int32_t dzdx = cmd_data[zbuffer_base+1]; - const int32_t dzde = cmd_data[zbuffer_base+2]; - const int32_t dzdy = cmd_data[zbuffer_base+3]; + int32_t r = int32_t(((cmd_data[shade_base] >> 32) & 0xffff0000) | ((cmd_data[shade_base + 2] >> 48) & 0x0000ffff)); + int32_t g = int32_t(((cmd_data[shade_base] >> 16) & 0xffff0000) | ((cmd_data[shade_base + 2] >> 32) & 0x0000ffff)); + int32_t b = int32_t( (cmd_data[shade_base] & 0xffff0000) | ((cmd_data[shade_base + 2] >> 16) & 0x0000ffff)); + int32_t a = int32_t(((cmd_data[shade_base] << 16) & 0xffff0000) | (cmd_data[shade_base + 2] & 0x0000ffff)); + const int32_t drdx = int32_t(((cmd_data[shade_base + 1] >> 32) & 0xffff0000) | ((cmd_data[shade_base + 3] >> 48) & 0x0000ffff)); + const int32_t dgdx = int32_t(((cmd_data[shade_base + 1] >> 16) & 0xffff0000) | ((cmd_data[shade_base + 3] >> 32) & 0x0000ffff)); + const int32_t dbdx = int32_t( (cmd_data[shade_base + 1] & 0xffff0000) | ((cmd_data[shade_base + 3] >> 16) & 0x0000ffff)); + const int32_t dadx = int32_t(((cmd_data[shade_base + 1] << 16) & 0xffff0000) | (cmd_data[shade_base + 3] & 0x0000ffff)); + const int32_t drde = int32_t(((cmd_data[shade_base + 4] >> 32) & 0xffff0000) | ((cmd_data[shade_base + 6] >> 48) & 0x0000ffff)); + const int32_t dgde = int32_t(((cmd_data[shade_base + 4] >> 16) & 0xffff0000) | ((cmd_data[shade_base + 6] >> 32) & 0x0000ffff)); + const int32_t dbde = int32_t( (cmd_data[shade_base + 4] & 0xffff0000) | ((cmd_data[shade_base + 6] >> 16) & 0x0000ffff)); + const int32_t dade = int32_t(((cmd_data[shade_base + 4] << 16) & 0xffff0000) | (cmd_data[shade_base + 6] & 0x0000ffff)); + const int32_t drdy = int32_t(((cmd_data[shade_base + 5] >> 32) & 0xffff0000) | ((cmd_data[shade_base + 7] >> 48) & 0x0000ffff)); + const int32_t dgdy = int32_t(((cmd_data[shade_base + 5] >> 16) & 0xffff0000) | ((cmd_data[shade_base + 7] >> 32) & 0x0000ffff)); + const int32_t dbdy = int32_t( (cmd_data[shade_base + 5] & 0xffff0000) | ((cmd_data[shade_base + 7] >> 16) & 0x0000ffff)); + const int32_t dady = int32_t(((cmd_data[shade_base + 5] << 16) & 0xffff0000) | (cmd_data[shade_base + 7] & 0x0000ffff)); + + int32_t s = int32_t(((cmd_data[texture_base] >> 32) & 0xffff0000) | ((cmd_data[texture_base+ 2 ] >> 48) & 0x0000ffff)); + int32_t t = int32_t(((cmd_data[texture_base] >> 16) & 0xffff0000) | ((cmd_data[texture_base+ 2 ] >> 32) & 0x0000ffff)); + int32_t w = int32_t( (cmd_data[texture_base] & 0xffff0000) | ((cmd_data[texture_base+ 2 ] >> 16) & 0x0000ffff)); + const int32_t dsdx = int32_t(((cmd_data[texture_base + 1] >> 32) & 0xffff0000) | ((cmd_data[texture_base + 3] >> 48) & 0x0000ffff)); + const int32_t dtdx = int32_t(((cmd_data[texture_base + 1] >> 16) & 0xffff0000) | ((cmd_data[texture_base + 3] >> 32) & 0x0000ffff)); + const int32_t dwdx = int32_t( (cmd_data[texture_base + 1] & 0xffff0000) | ((cmd_data[texture_base + 3] >> 16) & 0x0000ffff)); + const int32_t dsde = int32_t(((cmd_data[texture_base + 4] >> 32) & 0xffff0000) | ((cmd_data[texture_base + 6] >> 48) & 0x0000ffff)); + const int32_t dtde = int32_t(((cmd_data[texture_base + 4] >> 16) & 0xffff0000) | ((cmd_data[texture_base + 6] >> 32) & 0x0000ffff)); + const int32_t dwde = int32_t( (cmd_data[texture_base + 4] & 0xffff0000) | ((cmd_data[texture_base + 6] >> 16) & 0x0000ffff)); + const int32_t dsdy = int32_t(((cmd_data[texture_base + 5] >> 32) & 0xffff0000) | ((cmd_data[texture_base + 7] >> 48) & 0x0000ffff)); + const int32_t dtdy = int32_t(((cmd_data[texture_base + 5] >> 16) & 0xffff0000) | ((cmd_data[texture_base + 7] >> 32) & 0x0000ffff)); + const int32_t dwdy = int32_t( (cmd_data[texture_base + 5] & 0xffff0000) | ((cmd_data[texture_base + 7] >> 16) & 0x0000ffff)); + + int32_t z = int32_t(cmd_data[zbuffer_base] >> 32); + const int32_t dzdx = int32_t(cmd_data[zbuffer_base]); + const int32_t dzde = int32_t(cmd_data[zbuffer_base+1] >> 32); + const int32_t dzdy = int32_t(cmd_data[zbuffer_base+1]); const int32_t dzdy_dz = (dzdy >> 16) & 0xffff; const int32_t dzdx_dz = (dzdx >> 16) & 0xffff; @@ -2215,207 +2211,180 @@ void n64_rdp::triangle(bool shade, bool texture, bool zbuffer) m_pipe_clean = false; } -void n64_rdp::cmd_triangle(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle(uint64_t w1) { triangle(false, false, false); } -void n64_rdp::cmd_triangle_z(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_z(uint64_t w1) { triangle(false, false, true); } -void n64_rdp::cmd_triangle_t(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_t(uint64_t w1) { triangle(false, true, false); } -void n64_rdp::cmd_triangle_tz(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_tz(uint64_t w1) { triangle(false, true, true); } -void n64_rdp::cmd_triangle_s(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_s(uint64_t w1) { triangle(true, false, false); } -void n64_rdp::cmd_triangle_sz(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_sz(uint64_t w1) { triangle(true, false, true); } -void n64_rdp::cmd_triangle_st(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_st(uint64_t w1) { triangle(true, true, false); } -void n64_rdp::cmd_triangle_stz(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_triangle_stz(uint64_t w1) { triangle(true, true, true); } -void n64_rdp::cmd_tex_rect(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_tex_rect(uint64_t w1) { - const uint32_t* data = m_cmd_data + m_cmd_cur; + const uint64_t* data = m_cmd_data + m_cmd_cur; - const uint32_t w3 = data[2]; - const uint32_t w4 = data[3]; + const uint64_t w2 = data[1]; - const int32_t tilenum = (w2 >> 24) & 0x7; - const int32_t xh = (w2 >> 12) & 0xfff; - const int32_t xl = (w1 >> 12) & 0xfff; - const int32_t yh = (w2 >> 0) & 0xfff; - int32_t yl = (w1 >> 0) & 0xfff; + const uint64_t tilenum = (w1 >> 24) & 0x7; + const uint64_t xh = (w1 >> 12) & 0xfff; + const uint64_t xl = (w1 >> 44) & 0xfff; + const uint64_t yh = (w1 >> 0) & 0xfff; + uint64_t yl = (w1 >> 32) & 0xfff; - const int32_t s = (w3 >> 16) & 0xffff; - const int32_t t = (w3 >> 0) & 0xffff; - const int32_t dsdx = SIGN16((w4 >> 16) & 0xffff); - const int32_t dtdy = SIGN16((w4 >> 0) & 0xffff); + const uint64_t s = (w2 >> 48) & 0xffff; + const uint64_t t = (w2 >> 32) & 0xffff; + const uint64_t dsdx = SIGN16((w2 >> 16) & 0xffff); + const uint64_t dtdy = SIGN16((w2 >> 0) & 0xffff); if (m_other_modes.cycle_type == CYCLE_TYPE_FILL || m_other_modes.cycle_type == CYCLE_TYPE_COPY) { yl |= 3; } - const int32_t xlint = (xl >> 2) & 0x3ff; - const int32_t xhint = (xh >> 2) & 0x3ff; + const uint64_t xlint = (xl >> 2) & 0x3ff; + const uint64_t xhint = (xh >> 2) & 0x3ff; - uint32_t* ewdata = m_temp_rect_data; - ewdata[0] = (0x24 << 24) | ((0x80 | tilenum) << 16) | yl; // command, flipped, tile, yl - ewdata[1] = (yl << 16) | yh; // ym, yh - ewdata[2] = (xlint << 16) | ((xl & 3) << 14); // xl, xl frac - // ewdata[3] = 0; dxldy, dxldy frac - ewdata[4] = (xhint << 16) | ((xh & 3) << 14); // xh, xh frac - // ewdata[5] = 0; dxhdy, dxhdy frac - ewdata[6] = (xlint << 16) | ((xl & 3) << 14); // xm, xm frac - //ewdata[7] = 0; dxmdy, dxmdy frac - memset(&ewdata[8], 0, 16 * sizeof(uint32_t)); // shade - ewdata[24] = (s << 16) | t; // s, t - // ewdata[25] = 0; w - ewdata[26] = ((dsdx >> 5) << 16); // dsdx, dtdx - // ewdata[27] = 0; dwdx - // ewdata[28] = 0; s frac, t frac - // ewdata[29] = 0; w frac - ewdata[30] = ((dsdx & 0x1f) << 11) << 16; // dsdx frac, dtdx frac - // ewdata[31] = 0; dwdx frac - ewdata[32] = (dtdy >> 5) & 0xffff; // dsde, dtde - // ewdata[33] = 0; dwde - ewdata[34] = (dtdy >> 5) & 0xffff; // dsdy, dtdy - // ewdata[35] = 0; dwdy - ewdata[36] = (dtdy & 0x1f) << 11; // dsde frac, dtde frac - // ewdata[37] = 0; dwde frac - ewdata[38] = (dtdy & 0x1f) << 11; // dsdy frac, dtdy frac - // ewdata[39] = 0; // dwdy frac + uint64_t* ewdata = m_temp_rect_data; + ewdata[0] = ((uint64_t)0x24 << 56) | ((0x80L | tilenum) << 48) | (yl << 32) | (yl << 16) | yh; // command, flipped, tile, yl + ewdata[1] = (xlint << 48) | ((xl & 3) << 46); // xl, xl frac, dxldy (0), dxldy frac (0) + ewdata[2] = (xhint << 48) | ((xh & 3) << 46); // xh, xh frac, dxhdy (0), dxhdy frac (0) + ewdata[3] = (xlint << 48) | ((xl & 3) << 46); // xm, xm frac, dxmdy (0), dxmdy frac (0) + memset(&ewdata[4], 0, 8 * sizeof(uint64_t)); // shade + ewdata[12] = (s << 48) | (t << 32); // s, t, w (0) + ewdata[13] = (dsdx >> 5) << 48; // dsdx, dtdx, dwdx (0) + ewdata[14] = 0; // s frac (0), t frac (0), w frac (0) + ewdata[15] = (dsdx & 0x1f) << 59; // dsdx frac, dtdx frac, dwdx frac (0) + ewdata[16] = ((dtdy >> 5) & 0xffff) << 32; // dsde, dtde, dwde (0) + ewdata[17] = ((dtdy >> 5) & 0xffff) << 32; // dsdy, dtdy, dwdy (0) + ewdata[18] = ((dtdy & 0x1f) << 11) << 32; // dsde frac, dtde frac, dwde frac (0) + ewdata[38] = ((dtdy & 0x1f) << 11) << 32; // dsdy frac, dtdy frac, dwdy frac (0) // ewdata[40-43] = 0; // depth draw_triangle(true, true, false, true); } -void n64_rdp::cmd_tex_rect_flip(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_tex_rect_flip(uint64_t w1) { - const uint32_t* data = m_cmd_data + m_cmd_cur; + const uint64_t* data = m_cmd_data + m_cmd_cur; - const uint32_t w3 = data[2]; - const uint32_t w4 = data[3]; + const uint64_t w2 = data[1]; - const int32_t tilenum = (w2 >> 24) & 0x7; - const int32_t xh = (w2 >> 12) & 0xfff; - const int32_t xl = (w1 >> 12) & 0xfff; - const int32_t yh = (w2 >> 0) & 0xfff; - int32_t yl = (w1 >> 0) & 0xfff; + const uint64_t tilenum = (w1 >> 56) & 0x7; + const uint64_t xh = (w1 >> 12) & 0xfff; + const uint64_t xl = (w1 >> 44) & 0xfff; + const uint64_t yh = (w1 >> 0) & 0xfff; + uint64_t yl = (w1 >> 32) & 0xfff; - const int32_t s = (w3 >> 16) & 0xffff; - const int32_t t = (w3 >> 0) & 0xffff; - const int32_t dsdx = SIGN16((w4 >> 16) & 0xffff); - const int32_t dtdy = SIGN16((w4 >> 0) & 0xffff); + const uint64_t s = (w2 >> 48) & 0xffff; + const uint64_t t = (w2 >> 32) & 0xffff; + const uint64_t dsdx = SIGN16((w2 >> 16) & 0xffff); + const uint64_t dtdy = SIGN16((w2 >> 0) & 0xffff); if (m_other_modes.cycle_type == CYCLE_TYPE_FILL || m_other_modes.cycle_type == CYCLE_TYPE_COPY) { yl |= 3; } - const int32_t xlint = (xl >> 2) & 0x3ff; - const int32_t xhint = (xh >> 2) & 0x3ff; + const uint64_t xlint = (xl >> 2) & 0x3ff; + const uint64_t xhint = (xh >> 2) & 0x3ff; - uint32_t* ewdata = m_temp_rect_data; - ewdata[0] = (0x25 << 24) | ((0x80 | tilenum) << 16) | yl; // command, flipped, tile, yl - ewdata[1] = (yl << 16) | yh; // ym, yh - ewdata[2] = (xlint << 16) | ((xl & 3) << 14); // xl, xl frac - // ewdata[3] = 0; dxldy, dxldy frac - ewdata[4] = (xhint << 16) | ((xh & 3) << 14); // xh, xh frac - // ewdata[5] = 0; dxhdy, dxhdy frac - ewdata[6] = (xlint << 16) | ((xl & 3) << 14); // xm, xm frac - // ewdata[7] = 0; dxmdy, dxmdy frac - memset(&ewdata[8], 0, 16 * sizeof(uint32_t)); // shade - ewdata[24] = (s << 16) | t; // s, t - // ewdata[25] = 0; // w - ewdata[26] = (dtdy >> 5) & 0xffff; // dsdx, dtdx - // ewdata[27] = 0; dwdx - // ewdata[28] = 0; s frac, t frac - // ewdata[29] = 0; w frac - ewdata[30] = ((dtdy & 0x1f) << 11); // dsdx frac, dtdx frac - // ewdata[31] = 0; dwdx frac - ewdata[32] = (dsdx >> 5) << 16; // dsde, dtde - // ewdata[33] = 0; dwde - ewdata[34] = (dsdx >> 5) << 16; // dsdy, dtdy - // ewdata[35] = 0; dwdy - ewdata[36] = (dsdx & 0x1f) << 27; // dsde frac, dtde frac - // ewdata[37] = 0; dwde frac - ewdata[38] = (dsdx & 0x1f) << 27; // dsdy frac, dtdy frac - // ewdata[39] = 0; // dwdy frac - // ewdata[40-43] = 0; // depth + uint64_t* ewdata = m_temp_rect_data; + ewdata[0] = ((uint64_t)0x25 << 56) | ((0x80L | tilenum) << 48) | (yl << 32) | (yl << 16) | yh; // command, flipped, tile, yl + ewdata[1] = (xlint << 48) | ((xl & 3) << 46); // xl, xl frac, dxldy (0), dxldy frac (0) + ewdata[2] = (xhint << 48) | ((xh & 3) << 46); // xh, xh frac, dxhdy (0), dxhdy frac (0) + ewdata[3] = (xlint << 48) | ((xl & 3) << 46); // xm, xm frac, dxmdy (0), dxmdy frac (0) + memset(&ewdata[4], 0, 8 * sizeof(uint64_t)); // shade + ewdata[12] = (s << 48) | (t << 32); // s, t, w (0) + ewdata[13] = ((dtdy >> 5) & 0xffff) << 32; // dsdx, dtdx, dwdx (0) + ewdata[14] = 0; // s frac (0), t frac (0), w frac (0) + ewdata[15] = ((dtdy & 0x1f) << 43); // dsdx frac, dtdx frac, dwdx frac (0) + ewdata[16] = (dsdx >> 5) << 48; // dsde, dtde, dwde (0) + ewdata[17] = (dsdx >> 5) << 48; // dsdy, dtdy, dwdy (0) + ewdata[18] = (dsdx & 0x1f) << 59; // dsde frac, dtde frac, dwde frac (0) + ewdata[19] = (dsdx & 0x1f) << 59; // dsdy frac, dtdy frac, dwdy frac (0) draw_triangle(true, true, false, true); } -void n64_rdp::cmd_sync_load(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_sync_load(uint64_t w1) { //wait("SyncLoad"); } -void n64_rdp::cmd_sync_pipe(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_sync_pipe(uint64_t w1) { //wait("SyncPipe"); } -void n64_rdp::cmd_sync_tile(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_sync_tile(uint64_t w1) { //wait("SyncTile"); } -void n64_rdp::cmd_sync_full(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_sync_full(uint64_t w1) { //wait("SyncFull"); dp_full_sync(*m_machine); } -void n64_rdp::cmd_set_key_gb(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_key_gb(uint64_t w1) { - m_key_scale.set_b(w2 & 0xff); - m_key_scale.set_g((w2 >> 16) & 0xff); + m_key_scale.set_b(uint32_t(w1 >> 0) & 0xff); + m_key_scale.set_g(uint32_t(w1 >> 16) & 0xff); } -void n64_rdp::cmd_set_key_r(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_key_r(uint64_t w1) { - m_key_scale.set_r(w2 & 0xff); + m_key_scale.set_r(uint32_t(w1 & 0xff)); } -void n64_rdp::cmd_set_fill_color32(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_fill_color32(uint64_t w1) { //wait("SetFillColor"); - m_fill_color = w2; + m_fill_color = (uint32_t)w1; } -void n64_rdp::cmd_set_convert(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_convert(uint64_t w1) { if(!m_pipe_clean) { m_pipe_clean = true; wait("SetConvert"); } - int32_t k0 = (w1 >> 13) & 0x1ff; - int32_t k1 = (w1 >> 4) & 0x1ff; - int32_t k2 = ((w1 & 0xf) << 5) | ((w2 >> 27) & 0x1f); - int32_t k3 = (w2 >> 18) & 0x1ff; - int32_t k4 = (w2 >> 9) & 0x1ff; - int32_t k5 = w2 & 0x1ff; + int32_t k0 = int32_t(w1 >> 45) & 0x1ff; + int32_t k1 = int32_t(w1 >> 36) & 0x1ff; + int32_t k2 = int32_t(w1 >> 27) & 0x1ff; + int32_t k3 = int32_t(w1 >> 18) & 0x1ff; + int32_t k4 = int32_t(w1 >> 9) & 0x1ff; + int32_t k5 = int32_t(w1 >> 0) & 0x1ff; k0 = (SIGN9(k0) << 1) + 1; k1 = (SIGN9(k1) << 1) + 1; @@ -2425,81 +2394,83 @@ void n64_rdp::cmd_set_convert(uint32_t w1, uint32_t w2) set_yuv_factors(rgbaint_t(0, k0, k2, k3), rgbaint_t(0, 0, k1, 0), rgbaint_t(k4, k4, k4, k4), rgbaint_t(k5, k5, k5, k5)); } -void n64_rdp::cmd_set_scissor(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_scissor(uint64_t w1) { - m_scissor.m_xh = ((w1 >> 12) & 0xfff) >> 2; - m_scissor.m_yh = ((w1 >> 0) & 0xfff) >> 2; - m_scissor.m_xl = ((w2 >> 12) & 0xfff) >> 2; - m_scissor.m_yl = ((w2 >> 0) & 0xfff) >> 2; + m_scissor.m_xh = ((w1 >> 44) & 0xfff) >> 2; + m_scissor.m_yh = ((w1 >> 32) & 0xfff) >> 2; + m_scissor.m_xl = ((w1 >> 12) & 0xfff) >> 2; + m_scissor.m_yl = ((w1 >> 0) & 0xfff) >> 2; // TODO: handle f & o? } -void n64_rdp::cmd_set_prim_depth(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_prim_depth(uint64_t w1) { - m_misc_state.m_primitive_z = w2 & 0x7fff0000; - m_misc_state.m_primitive_dz = (uint16_t)(w1); + m_misc_state.m_primitive_z = (uint32_t)(w1 & 0x7fff0000); + m_misc_state.m_primitive_dz = (uint16_t)(w1 >> 32); } -void n64_rdp::cmd_set_other_modes(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_other_modes(uint64_t w1) { //wait("SetOtherModes"); - m_other_modes.cycle_type = (w1 >> 20) & 0x3; // 01 - m_other_modes.persp_tex_en = (w1 & 0x80000) ? 1 : 0; // 1 - m_other_modes.detail_tex_en = (w1 & 0x40000) ? 1 : 0; // 0 - m_other_modes.sharpen_tex_en = (w1 & 0x20000) ? 1 : 0; // 0 - m_other_modes.tex_lod_en = (w1 & 0x10000) ? 1 : 0; // 0 - m_other_modes.en_tlut = (w1 & 0x08000) ? 1 : 0; // 0 - m_other_modes.tlut_type = (w1 & 0x04000) ? 1 : 0; // 0 - m_other_modes.sample_type = (w1 & 0x02000) ? 1 : 0; // 1 - m_other_modes.mid_texel = (w1 & 0x01000) ? 1 : 0; // 0 - m_other_modes.bi_lerp0 = (w1 & 0x00800) ? 1 : 0; // 1 - m_other_modes.bi_lerp1 = (w1 & 0x00400) ? 1 : 0; // 1 - m_other_modes.convert_one = (w1 & 0x00200) ? 1 : 0; // 0 - m_other_modes.key_en = (w1 & 0x00100) ? 1 : 0; // 0 - m_other_modes.rgb_dither_sel = (w1 >> 6) & 0x3; // 00 - m_other_modes.alpha_dither_sel = (w1 >> 4) & 0x3; // 01 - m_other_modes.blend_m1a_0 = (w2 >> 30) & 0x3; // 11 - m_other_modes.blend_m1a_1 = (w2 >> 28) & 0x3; // 00 - m_other_modes.blend_m1b_0 = (w2 >> 26) & 0x3; // 10 - m_other_modes.blend_m1b_1 = (w2 >> 24) & 0x3; // 00 - m_other_modes.blend_m2a_0 = (w2 >> 22) & 0x3; // 00 - m_other_modes.blend_m2a_1 = (w2 >> 20) & 0x3; // 01 - m_other_modes.blend_m2b_0 = (w2 >> 18) & 0x3; // 00 - m_other_modes.blend_m2b_1 = (w2 >> 16) & 0x3; // 01 - m_other_modes.force_blend = (w2 >> 14) & 1; // 0 - m_other_modes.blend_shift = m_other_modes.force_blend ? 5 : 2; - m_other_modes.alpha_cvg_select = (w2 >> 13) & 1; // 1 - m_other_modes.cvg_times_alpha = (w2 >> 12) & 1; // 0 - m_other_modes.z_mode = (w2 >> 10) & 0x3; // 00 - m_other_modes.cvg_dest = (w2 >> 8) & 0x3; // 00 - m_other_modes.color_on_cvg = (w2 >> 7) & 1; // 0 - m_other_modes.image_read_en = (w2 >> 6) & 1; // 1 - m_other_modes.z_update_en = (w2 >> 5) & 1; // 1 - m_other_modes.z_compare_en = (w2 >> 4) & 1; // 1 - m_other_modes.antialias_en = (w2 >> 3) & 1; // 1 - m_other_modes.z_source_sel = (w2 >> 2) & 1; // 0 - m_other_modes.dither_alpha_en = (w2 >> 1) & 1; // 0 - m_other_modes.alpha_compare_en = (w2) & 1; // 0 + m_other_modes.cycle_type = (w1 >> 52) & 0x3; // 01 + m_other_modes.persp_tex_en = (w1 >> 51) & 1; // 1 + m_other_modes.detail_tex_en = (w1 >> 50) & 1; // 0 + m_other_modes.sharpen_tex_en = (w1 >> 49) & 1; // 0 + m_other_modes.tex_lod_en = (w1 >> 48) & 1; // 0 + m_other_modes.en_tlut = (w1 >> 47) & 1; // 0 + m_other_modes.tlut_type = (w1 >> 46) & 1; // 0 + m_other_modes.sample_type = (w1 >> 45) & 1; // 1 + m_other_modes.mid_texel = (w1 >> 44) & 1; // 0 + m_other_modes.bi_lerp0 = (w1 >> 43) & 1; // 1 + m_other_modes.bi_lerp1 = (w1 >> 42) & 1; // 1 + m_other_modes.convert_one = (w1 >> 41) & 1; // 0 + m_other_modes.key_en = (w1 >> 40) & 1; // 0 + m_other_modes.rgb_dither_sel = (w1 >> 38) & 0x3; // 00 + m_other_modes.alpha_dither_sel = (w1 >> 36) & 0x3; // 01 + m_other_modes.blend_m1a_0 = (w1 >> 30) & 0x3; // 11 + m_other_modes.blend_m1a_1 = (w1 >> 28) & 0x3; // 00 + m_other_modes.blend_m1b_0 = (w1 >> 26) & 0x3; // 10 + m_other_modes.blend_m1b_1 = (w1 >> 24) & 0x3; // 00 + m_other_modes.blend_m2a_0 = (w1 >> 22) & 0x3; // 00 + m_other_modes.blend_m2a_1 = (w1 >> 20) & 0x3; // 01 + m_other_modes.blend_m2b_0 = (w1 >> 18) & 0x3; // 00 + m_other_modes.blend_m2b_1 = (w1 >> 16) & 0x3; // 01 + m_other_modes.force_blend = (w1 >> 14) & 1; // 0 + m_other_modes.blend_shift = m_other_modes.force_blend ? 5 : 2; + m_other_modes.alpha_cvg_select = (w1 >> 13) & 1; // 1 + m_other_modes.cvg_times_alpha = (w1 >> 12) & 1; // 0 + m_other_modes.z_mode = (w1 >> 10) & 0x3; // 00 + m_other_modes.cvg_dest = (w1 >> 8) & 0x3; // 00 + m_other_modes.color_on_cvg = (w1 >> 7) & 1; // 0 + m_other_modes.image_read_en = (w1 >> 6) & 1; // 1 + m_other_modes.z_update_en = (w1 >> 5) & 1; // 1 + m_other_modes.z_compare_en = (w1 >> 4) & 1; // 1 + m_other_modes.antialias_en = (w1 >> 3) & 1; // 1 + m_other_modes.z_source_sel = (w1 >> 2) & 1; // 0 + m_other_modes.dither_alpha_en = (w1 >> 1) & 1; // 0 + m_other_modes.alpha_compare_en = (w1 >> 0) & 1; // 0 m_other_modes.alpha_dither_mode = (m_other_modes.alpha_compare_en << 1) | m_other_modes.dither_alpha_en; } -void n64_rdp::cmd_load_tlut(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_load_tlut(uint64_t w1) { //wait("LoadTLUT"); n64_tile_t* tile = m_tiles; - const int32_t tilenum = (w2 >> 24) & 0x7; - const int32_t sl = tile[tilenum].sl = ((w1 >> 12) & 0xfff); - const int32_t tl = tile[tilenum].tl = w1 & 0xfff; - const int32_t sh = tile[tilenum].sh = ((w2 >> 12) & 0xfff); - const int32_t th = tile[tilenum].th = w2 & 0xfff; + const int32_t tilenum = (w1 >> 24) & 0x7; + const int32_t sl = tile[tilenum].sl = int32_t(w1 >> 44) & 0xfff; + const int32_t tl = tile[tilenum].tl = int32_t(w1 >> 32) & 0xfff; + const int32_t sh = tile[tilenum].sh = int32_t(w1 >> 12) & 0xfff; + const int32_t th = tile[tilenum].th = int32_t(w1 >> 0) & 0xfff; if (tl != th) { fatalerror("Load tlut: tl=%d, th=%d\n",tl,th); } + m_capture.data_begin(); + const int32_t count = ((sh >> 2) - (sl >> 2) + 1) << 2; switch (m_misc_state.m_ti_size) @@ -2519,6 +2490,7 @@ void n64_rdp::cmd_load_tlut(uint32_t w1, uint32_t w2) if (dststart < 2048) { dst[dststart] = U_RREADIDX16(srcstart); + m_capture.data_block()->put16(dst[dststart]); dst[dststart + 1] = dst[dststart]; dst[dststart + 2] = dst[dststart]; dst[dststart + 3] = dst[dststart]; @@ -2531,37 +2503,39 @@ void n64_rdp::cmd_load_tlut(uint32_t w1, uint32_t w2) default: fatalerror("RDP: load_tlut: size = %d\n", m_misc_state.m_ti_size); } + m_capture.data_end(); + m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th); m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl); } -void n64_rdp::cmd_set_tile_size(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_tile_size(uint64_t w1) { //wait("SetTileSize"); - const int32_t tilenum = (w2 >> 24) & 0x7; + const int32_t tilenum = int32_t(w1 >> 24) & 0x7; - m_tiles[tilenum].sl = (w1 >> 12) & 0xfff; - m_tiles[tilenum].tl = (w1 >> 0) & 0xfff; - m_tiles[tilenum].sh = (w2 >> 12) & 0xfff; - m_tiles[tilenum].th = (w2 >> 0) & 0xfff; + m_tiles[tilenum].sl = int32_t(w1 >> 44) & 0xfff; + m_tiles[tilenum].tl = int32_t(w1 >> 32) & 0xfff; + m_tiles[tilenum].sh = int32_t(w1 >> 12) & 0xfff; + m_tiles[tilenum].th = int32_t(w1 >> 0) & 0xfff; m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th); m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl); } -void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_load_block(uint64_t w1) { //wait("LoadBlock"); n64_tile_t* tile = m_tiles; - const int32_t tilenum = (w2 >> 24) & 0x7; + const int32_t tilenum = int32_t(w1 >> 24) & 0x7; uint16_t* tc = get_tmem16(); - int32_t sl = tile[tilenum].sl = ((w1 >> 12) & 0xfff); - int32_t tl = tile[tilenum].tl = ((w1 >> 0) & 0xfff); - int32_t sh = tile[tilenum].sh = ((w2 >> 12) & 0xfff); - const int32_t dxt = ((w2 >> 0) & 0xfff); + int32_t sl = tile[tilenum].sl = int32_t(w1 >> 44) & 0xfff; + int32_t tl = tile[tilenum].tl = int32_t(w1 >> 32) & 0xfff; + int32_t sh = tile[tilenum].sh = int32_t(w1 >> 12) & 0xfff; + const int32_t dxt = int32_t(w1 >> 0) & 0xfff; if (sh < sl) { @@ -2584,6 +2558,8 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) const uint32_t src = (m_misc_state.m_ti_address >> 1) + (tl * tiwinwords) + slinwords; + m_capture.data_begin(); + if (dxt != 0) { int32_t j = 0; @@ -2608,6 +2584,12 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) tc[((ptr + 1) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 1); tc[((ptr + 2) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 2); tc[((ptr + 3) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 3); + + m_capture.data_block()->put16(U_RREADIDX16(srcptr)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+1)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+2)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+3)); + j += dxt; } } @@ -2636,6 +2618,10 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) tc[ptr] = ((first >> 8) << 8) | (sec >> 8); tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff); + m_capture.data_block()->put16(U_RREADIDX16(srcptr)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+1)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+2)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+3)); j += dxt; } } @@ -2657,6 +2643,11 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) tc[ptr] = U_RREADIDX16(srcptr + 2); tc[ptr | 0x400] = U_RREADIDX16(srcptr + 3); + m_capture.data_block()->put16(U_RREADIDX16(srcptr)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+1)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+2)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+3)); + j += dxt; } } @@ -2674,6 +2665,11 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) tc[((ptr + 1) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 1); tc[((ptr + 2) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 2); tc[((ptr + 3) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 3); + + m_capture.data_block()->put16(U_RREADIDX16(srcptr)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+1)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+2)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+3)); } } else if (tile[tilenum].format == FORMAT_YUV) @@ -2692,6 +2688,11 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) sec = U_RREADIDX16(srcptr + 3); tc[ptr] = ((first >> 8) << 8) | (sec >> 8); tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff); + + m_capture.data_block()->put16(U_RREADIDX16(srcptr)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+1)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+2)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+3)); } } else @@ -2706,25 +2707,32 @@ void n64_rdp::cmd_load_block(uint32_t w1, uint32_t w2) ptr = ((tb + (i << 1) + 1) ^ WORD_ADDR_XOR) & 0x3ff; tc[ptr] = U_RREADIDX16(srcptr + 2); tc[ptr | 0x400] = U_RREADIDX16(srcptr + 3); + + m_capture.data_block()->put16(U_RREADIDX16(srcptr)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+1)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+2)); + m_capture.data_block()->put16(U_RREADIDX16(srcptr+3)); } } tile[tilenum].th = tl; } + m_capture.data_end(); + m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th); m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl); } -void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_load_tile(uint64_t w1) { //wait("LoadTile"); n64_tile_t* tile = m_tiles; - const int32_t tilenum = (w2 >> 24) & 0x7; + const int32_t tilenum = int32_t(w1 >> 24) & 0x7; - tile[tilenum].sl = ((w1 >> 12) & 0xfff); - tile[tilenum].tl = ((w1 >> 0) & 0xfff); - tile[tilenum].sh = ((w2 >> 12) & 0xfff); - tile[tilenum].th = ((w2 >> 0) & 0xfff); + tile[tilenum].sl = int32_t(w1 >> 44) & 0xfff; + tile[tilenum].tl = int32_t(w1 >> 32) & 0xfff; + tile[tilenum].sh = int32_t(w1 >> 12) & 0xfff; + tile[tilenum].th = int32_t(w1 >> 0) & 0xfff; const int32_t sl = tile[tilenum].sl >> 2; const int32_t tl = tile[tilenum].tl >> 2; @@ -2746,6 +2754,8 @@ void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) topad = 0; // ???? */ + m_capture.data_begin(); + switch (m_misc_state.m_ti_size) { case PIXEL_SIZE_8BIT: @@ -2762,7 +2772,9 @@ void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) for (int32_t i = 0; i < width; i++) { - tc[((tline + i) ^ xorval8) & 0xfff] = U_RREADADDR8(src + s + i); + const uint8_t data = U_RREADADDR8(src + s + i); + m_capture.data_block()->put8(data); + tc[((tline + i) ^ xorval8) & 0xfff] = data; } } break; @@ -2783,8 +2795,10 @@ void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) for (int32_t i = 0; i < width; i++) { - uint32_t taddr = (tline + i) ^ xorval16; - tc[taddr & 0x7ff] = U_RREADIDX16(src + s + i); + const uint32_t taddr = (tline + i) ^ xorval16; + const uint16_t data = U_RREADIDX16(src + s + i); + m_capture.data_block()->put16(data); + tc[taddr & 0x7ff] = data; } } } @@ -2801,6 +2815,7 @@ void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) { uint32_t taddr = ((tline + i) ^ xorval8) & 0x7ff; uint16_t yuvword = U_RREADIDX16(src + s + i); + m_capture.data_block()->put16(yuvword); get_tmem8()[taddr] = yuvword >> 8; get_tmem8()[taddr | 0x800] = yuvword & 0xff; } @@ -2823,6 +2838,7 @@ void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) for (int32_t i = 0; i < width; i++) { uint32_t c = U_RREADIDX32(src + s + i); + m_capture.data_block()->put32(c); uint32_t ptr = ((tline + i) ^ xorval32cur) & 0x3ff; tc16[ptr] = c >> 16; tc16[ptr | 0x400] = c & 0xffff; @@ -2834,29 +2850,31 @@ void n64_rdp::cmd_load_tile(uint32_t w1, uint32_t w2) default: fatalerror("RDP: load_tile: size = %d\n", m_misc_state.m_ti_size); } + m_capture.data_end(); + m_tiles[tilenum].sth = rgbaint_t(m_tiles[tilenum].sh, m_tiles[tilenum].sh, m_tiles[tilenum].th, m_tiles[tilenum].th); m_tiles[tilenum].stl = rgbaint_t(m_tiles[tilenum].sl, m_tiles[tilenum].sl, m_tiles[tilenum].tl, m_tiles[tilenum].tl); } -void n64_rdp::cmd_set_tile(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_tile(uint64_t w1) { //wait("SetTile"); - const int32_t tilenum = (w2 >> 24) & 0x7; + const int32_t tilenum = int32_t(w1 >> 24) & 0x7; n64_tile_t* tex_tile = &m_tiles[tilenum]; - tex_tile->format = (w1 >> 21) & 0x7; - tex_tile->size = (w1 >> 19) & 0x3; - tex_tile->line = (w1 >> 9) & 0x1ff; - tex_tile->tmem = (w1 >> 0) & 0x1ff; - tex_tile->palette = (w2 >> 20) & 0xf; - tex_tile->ct = (w2 >> 19) & 0x1; - tex_tile->mt = (w2 >> 18) & 0x1; - tex_tile->mask_t = (w2 >> 14) & 0xf; - tex_tile->shift_t = (w2 >> 10) & 0xf; - tex_tile->cs = (w2 >> 9) & 0x1; - tex_tile->ms = (w2 >> 8) & 0x1; - tex_tile->mask_s = (w2 >> 4) & 0xf; - tex_tile->shift_s = (w2 >> 0) & 0xf; + tex_tile->format = int32_t(w1 >> 53) & 0x7; + tex_tile->size = int32_t(w1 >> 51) & 0x3; + tex_tile->line = int32_t(w1 >> 41) & 0x1ff; + tex_tile->tmem = int32_t(w1 >> 32) & 0x1ff; + tex_tile->palette = int32_t(w1 >> 20) & 0xf; + tex_tile->ct = int32_t(w1 >> 19) & 0x1; + tex_tile->mt = int32_t(w1 >> 18) & 0x1; + tex_tile->mask_t = int32_t(w1 >> 14) & 0xf; + tex_tile->shift_t = int32_t(w1 >> 10) & 0xf; + tex_tile->cs = int32_t(w1 >> 9) & 0x1; + tex_tile->ms = int32_t(w1 >> 8) & 0x1; + tex_tile->mask_s = int32_t(w1 >> 4) & 0xf; + tex_tile->shift_s = int32_t(w1 >> 0) & 0xf; tex_tile->lshift_s = (tex_tile->shift_s >= 11) ? (16 - tex_tile->shift_s) : 0; tex_tile->rshift_s = (tex_tile->shift_s < 11) ? tex_tile->shift_s : 0; @@ -2892,106 +2910,104 @@ void n64_rdp::cmd_set_tile(uint32_t w1, uint32_t w2) //m_pending_mode_block = true; } -void n64_rdp::cmd_fill_rect(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_fill_rect(uint64_t w1) { //if(m_pending_mode_block) { wait("Block on pending mode-change"); m_pending_mode_block = false; } - const uint32_t xh = (w2 >> 12) & 0xfff; - const uint32_t xl = (w1 >> 12) & 0xfff; - const uint32_t yh = (w2 >> 0) & 0xfff; - uint32_t yl = (w1 >> 0) & 0xfff; + const uint64_t xh = (w1 >> 12) & 0xfff; + const uint64_t xl = (w1 >> 44) & 0xfff; + const uint64_t yh = (w1 >> 0) & 0xfff; + uint64_t yl = (w1 >> 32) & 0xfff; if (m_other_modes.cycle_type == CYCLE_TYPE_FILL || m_other_modes.cycle_type == CYCLE_TYPE_COPY) { yl |= 3; } - const uint32_t xlint = (xl >> 2) & 0x3ff; - const uint32_t xhint = (xh >> 2) & 0x3ff; + const uint64_t xlint = (xl >> 2) & 0x3ff; + const uint64_t xhint = (xh >> 2) & 0x3ff; - uint32_t* ewdata = m_temp_rect_data; - ewdata[0] = (0x3680 << 16) | yl;//command, flipped, tile, yl - ewdata[1] = (yl << 16) | yh;//ym, yh - ewdata[2] = (xlint << 16) | ((xl & 3) << 14);//xl, xl frac - ewdata[3] = 0;//dxldy, dxldy frac - ewdata[4] = (xhint << 16) | ((xh & 3) << 14);//xh, xh frac - ewdata[5] = 0;//dxhdy, dxhdy frac - ewdata[6] = (xlint << 16) | ((xl & 3) << 14);//xm, xm frac - ewdata[7] = 0;//dxmdy, dxmdy frac - memset(&ewdata[8], 0, 36 * sizeof(uint32_t));//shade, texture, depth + uint64_t* ewdata = m_temp_rect_data; + ewdata[0] = ((uint64_t)0x3680 << 48) | (yl << 32) | (yl << 16) | yh; // command, flipped, tile, yl, ym, yh + ewdata[1] = (xlint << 48) | ((xl & 3) << 46); // xl, xl frac, dxldy (0), dxldy frac (0) + ewdata[2] = (xhint << 48) | ((xh & 3) << 46); // xh, xh frac, dxhdy (0), dxhdy frac (0) + ewdata[3] = (xlint << 48) | ((xl & 3) << 46); // xm, xm frac, dxmdy (0), dxmdy frac (0) + memset(&ewdata[4], 0, 18 * sizeof(uint64_t));//shade, texture, depth draw_triangle(false, false, false, true); } -void n64_rdp::cmd_set_fog_color(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_fog_color(uint64_t w1) { - m_fog_color.set(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff); + m_fog_color.set(uint8_t(w1), uint8_t(w1 >> 24), uint8_t(w1 >> 16), uint8_t(w1 >> 8)); } -void n64_rdp::cmd_set_blend_color(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_blend_color(uint64_t w1) { - m_blend_color.set(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff); + m_blend_color.set(uint8_t(w1), uint8_t(w1 >> 24), uint8_t(w1 >> 16), uint8_t(w1 >> 8)); } -void n64_rdp::cmd_set_prim_color(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_prim_color(uint64_t w1) { - m_misc_state.m_min_level = (w1 >> 8) & 0x1f; - const uint8_t prim_lod_fraction = w1 & 0xff; + m_misc_state.m_min_level = uint32_t(w1 >> 40) & 0x1f; + const uint8_t prim_lod_fraction(w1 >> 32); m_prim_lod_fraction.set(prim_lod_fraction, prim_lod_fraction, prim_lod_fraction, prim_lod_fraction); - m_prim_color.set(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff); - m_prim_alpha.set(w2 & 0xff, w2 & 0xff, w2 & 0xff, w2 & 0xff); + const uint8_t alpha(w1); + m_prim_color.set(alpha, uint8_t(w1 >> 24), uint8_t(w1 >> 16), uint8_t(w1 >> 8)); + m_prim_alpha.set(alpha, alpha, alpha, alpha); } -void n64_rdp::cmd_set_env_color(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_env_color(uint64_t w1) { - m_env_color.set(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff); - m_env_alpha.set(w2 & 0xff, w2 & 0xff, w2 & 0xff, w2 & 0xff); + const uint8_t alpha(w1); + m_env_color.set(alpha, uint8_t(w1 >> 24), uint8_t(w1 >> 16), uint8_t(w1 >> 8)); + m_env_alpha.set(alpha, alpha, alpha, alpha); } -void n64_rdp::cmd_set_combine(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_combine(uint64_t w1) { - m_combine.sub_a_rgb0 = (w1 >> 20) & 0xf; - m_combine.mul_rgb0 = (w1 >> 15) & 0x1f; - m_combine.sub_a_a0 = (w1 >> 12) & 0x7; - m_combine.mul_a0 = (w1 >> 9) & 0x7; - m_combine.sub_a_rgb1 = (w1 >> 5) & 0xf; - m_combine.mul_rgb1 = (w1 >> 0) & 0x1f; + m_combine.sub_a_rgb0 = uint32_t(w1 >> 52) & 0xf; + m_combine.mul_rgb0 = uint32_t(w1 >> 47) & 0x1f; + m_combine.sub_a_a0 = uint32_t(w1 >> 44) & 0x7; + m_combine.mul_a0 = uint32_t(w1 >> 41) & 0x7; + m_combine.sub_a_rgb1 = uint32_t(w1 >> 37) & 0xf; + m_combine.mul_rgb1 = uint32_t(w1 >> 32) & 0x1f; - m_combine.sub_b_rgb0 = (w2 >> 28) & 0xf; - m_combine.sub_b_rgb1 = (w2 >> 24) & 0xf; - m_combine.sub_a_a1 = (w2 >> 21) & 0x7; - m_combine.mul_a1 = (w2 >> 18) & 0x7; - m_combine.add_rgb0 = (w2 >> 15) & 0x7; - m_combine.sub_b_a0 = (w2 >> 12) & 0x7; - m_combine.add_a0 = (w2 >> 9) & 0x7; - m_combine.add_rgb1 = (w2 >> 6) & 0x7; - m_combine.sub_b_a1 = (w2 >> 3) & 0x7; - m_combine.add_a1 = (w2 >> 0) & 0x7; + m_combine.sub_b_rgb0 = uint32_t(w1 >> 28) & 0xf; + m_combine.sub_b_rgb1 = uint32_t(w1 >> 24) & 0xf; + m_combine.sub_a_a1 = uint32_t(w1 >> 21) & 0x7; + m_combine.mul_a1 = uint32_t(w1 >> 18) & 0x7; + m_combine.add_rgb0 = uint32_t(w1 >> 15) & 0x7; + m_combine.sub_b_a0 = uint32_t(w1 >> 12) & 0x7; + m_combine.add_a0 = uint32_t(w1 >> 9) & 0x7; + m_combine.add_rgb1 = uint32_t(w1 >> 6) & 0x7; + m_combine.sub_b_a1 = uint32_t(w1 >> 3) & 0x7; + m_combine.add_a1 = uint32_t(w1 >> 0) & 0x7; } -void n64_rdp::cmd_set_texture_image(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_texture_image(uint64_t w1) { - m_misc_state.m_ti_format = (w1 >> 21) & 0x7; - m_misc_state.m_ti_size = (w1 >> 19) & 0x3; - m_misc_state.m_ti_width = (w1 & 0x3ff) + 1; - m_misc_state.m_ti_address = w2 & 0x01ffffff; + m_misc_state.m_ti_format = uint32_t(w1 >> 53) & 0x7; + m_misc_state.m_ti_size = uint32_t(w1 >> 51) & 0x3; + m_misc_state.m_ti_width = (uint32_t(w1 >> 32) & 0x3ff) + 1; + m_misc_state.m_ti_address = uint32_t(w1) & 0x01ffffff; } -void n64_rdp::cmd_set_mask_image(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_mask_image(uint64_t w1) { //wait("SetMaskImage"); - m_misc_state.m_zb_address = w2 & 0x01ffffff; + m_misc_state.m_zb_address = uint32_t(w1) & 0x01ffffff; } -void n64_rdp::cmd_set_color_image(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_set_color_image(uint64_t w1) { //wait("SetColorImage"); - m_misc_state.m_fb_format = (w1 >> 21) & 0x7; - m_misc_state.m_fb_size = (w1 >> 19) & 0x3; - m_misc_state.m_fb_width = (w1 & 0x3ff) + 1; - m_misc_state.m_fb_address = w2 & 0x01ffffff; + m_misc_state.m_fb_format = uint32_t(w1 >> 53) & 0x7; + m_misc_state.m_fb_size = uint32_t(w1 >> 51) & 0x3; + m_misc_state.m_fb_width = (uint32_t(w1 >> 32) & 0x3ff) + 1; + m_misc_state.m_fb_address = uint32_t(w1) & 0x01ffffff; if (m_misc_state.m_fb_format < 2 || m_misc_state.m_fb_format > 32) // Jet Force Gemini sets the format to 4, Intensity. Protection? { @@ -3001,12 +3017,12 @@ void n64_rdp::cmd_set_color_image(uint32_t w1, uint32_t w2) /*****************************************************************************/ -void n64_rdp::cmd_invalid(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_invalid(uint64_t w1) { - fatalerror("n64_rdp::Invalid: %d, %08x %08x\n", (w1 >> 24) & 0x3f, w1, w2); + fatalerror("n64_rdp::Invalid: %d, %08x %08x\n", uint32_t(w1 >> 56) & 0x3f, uint32_t(w1 >> 32), (uint32_t)w1); } -void n64_rdp::cmd_noop(uint32_t w1, uint32_t w2) +void n64_rdp::cmd_noop(uint64_t w1) { // Do nothing } @@ -3023,15 +3039,15 @@ void n64_rdp::process_command_list() } // load command data - for(int32_t i = 0; i < length; i += 4) + for(int32_t i = 0; i < length; i += 8) { m_cmd_data[m_cmd_ptr++] = read_data((m_current & 0x1fffffff) + i); } m_current = m_end; - uint32_t cmd = (m_cmd_data[0] >> 24) & 0x3f; - uint32_t cmd_length = (m_cmd_ptr + 1) * 4; + uint32_t cmd = (m_cmd_data[0] >> 56) & 0x3f; + uint32_t cmd_length = uint32_t(m_cmd_ptr + 1) * 8; set_status(get_status() &~ DP_STATUS_FREEZE); @@ -3043,78 +3059,79 @@ void n64_rdp::process_command_list() while (m_cmd_cur < m_cmd_ptr) { - cmd = (m_cmd_data[m_cmd_cur] >> 24) & 0x3f; + cmd = (m_cmd_data[m_cmd_cur] >> 56) & 0x3f; - if (((m_cmd_ptr - m_cmd_cur) * 4) < s_rdp_command_length[cmd]) + if (((m_cmd_ptr - m_cmd_cur) * 8) < s_rdp_command_length[cmd]) { return; //fatalerror("rdp_process_list: not enough rdp command data: cur = %d, ptr = %d, expected = %d\n", m_cmd_cur, m_cmd_ptr, s_rdp_command_length[cmd]); } + m_capture.command(&m_cmd_data[m_cmd_cur], s_rdp_command_length[cmd] / 8); + if (LOG_RDP_EXECUTION) { char string[4000]; disassemble(string); - fprintf(rdp_exec, "%08X: %08X %08X %s\n", m_start+(m_cmd_cur * 4), m_cmd_data[m_cmd_cur+0], m_cmd_data[m_cmd_cur+1], string); + fprintf(rdp_exec, "%08X: %08X%08X %s\n", m_start+(m_cmd_cur * 8), uint32_t(m_cmd_data[m_cmd_cur] >> 32), (uint32_t)m_cmd_data[m_cmd_cur], string); fflush(rdp_exec); } // execute the command - uint32_t w1 = m_cmd_data[m_cmd_cur+0]; - uint32_t w2 = m_cmd_data[m_cmd_cur+1]; + uint64_t w = m_cmd_data[m_cmd_cur]; switch(cmd) { - case 0x00: cmd_noop(w1, w2); break; + case 0x00: cmd_noop(w); break; - case 0x08: cmd_triangle(w1, w2); break; - case 0x09: cmd_triangle_z(w1, w2); break; - case 0x0a: cmd_triangle_t(w1, w2); break; - case 0x0b: cmd_triangle_tz(w1, w2); break; - case 0x0c: cmd_triangle_s(w1, w2); break; - case 0x0d: cmd_triangle_sz(w1, w2); break; - case 0x0e: cmd_triangle_st(w1, w2); break; - case 0x0f: cmd_triangle_stz(w1, w2); break; + case 0x08: cmd_triangle(w); break; + case 0x09: cmd_triangle_z(w); break; + case 0x0a: cmd_triangle_t(w); break; + case 0x0b: cmd_triangle_tz(w); break; + case 0x0c: cmd_triangle_s(w); break; + case 0x0d: cmd_triangle_sz(w); break; + case 0x0e: cmd_triangle_st(w); break; + case 0x0f: cmd_triangle_stz(w); break; - case 0x24: cmd_tex_rect(w1, w2); break; - case 0x25: cmd_tex_rect_flip(w1, w2); break; + case 0x24: cmd_tex_rect(w); break; + case 0x25: cmd_tex_rect_flip(w); break; - case 0x26: cmd_sync_load(w1, w2); break; - case 0x27: cmd_sync_pipe(w1, w2); break; - case 0x28: cmd_sync_tile(w1, w2); break; - case 0x29: cmd_sync_full(w1, w2); break; + case 0x26: cmd_sync_load(w); break; + case 0x27: cmd_sync_pipe(w); break; + case 0x28: cmd_sync_tile(w); break; + case 0x29: cmd_sync_full(w); break; - case 0x2a: cmd_set_key_gb(w1, w2); break; - case 0x2b: cmd_set_key_r(w1, w2); break; + case 0x2a: cmd_set_key_gb(w); break; + case 0x2b: cmd_set_key_r(w); break; - case 0x2c: cmd_set_convert(w1, w2); break; - case 0x3c: cmd_set_combine(w1, w2); break; - case 0x2d: cmd_set_scissor(w1, w2); break; - case 0x2e: cmd_set_prim_depth(w1, w2); break; - case 0x2f: cmd_set_other_modes(w1, w2); break; + case 0x2c: cmd_set_convert(w); break; + case 0x3c: cmd_set_combine(w); break; + case 0x2d: cmd_set_scissor(w); break; + case 0x2e: cmd_set_prim_depth(w); break; + case 0x2f: cmd_set_other_modes(w);break; - case 0x30: cmd_load_tlut(w1, w2); break; - case 0x33: cmd_load_block(w1, w2); break; - case 0x34: cmd_load_tile(w1, w2); break; + case 0x30: cmd_load_tlut(w); break; + case 0x33: cmd_load_block(w); break; + case 0x34: cmd_load_tile(w); break; - case 0x32: cmd_set_tile_size(w1, w2); break; - case 0x35: cmd_set_tile(w1, w2); break; + case 0x32: cmd_set_tile_size(w); break; + case 0x35: cmd_set_tile(w); break; - case 0x36: cmd_fill_rect(w1, w2); break; + case 0x36: cmd_fill_rect(w); break; - case 0x37: cmd_set_fill_color32(w1, w2); break; - case 0x38: cmd_set_fog_color(w1, w2); break; - case 0x39: cmd_set_blend_color(w1, w2); break; - case 0x3a: cmd_set_prim_color(w1, w2); break; - case 0x3b: cmd_set_env_color(w1, w2); break; + case 0x37: cmd_set_fill_color32(w); break; + case 0x38: cmd_set_fog_color(w); break; + case 0x39: cmd_set_blend_color(w);break; + case 0x3a: cmd_set_prim_color(w); break; + case 0x3b: cmd_set_env_color(w); break; - case 0x3d: cmd_set_texture_image(w1, w2); break; - case 0x3e: cmd_set_mask_image(w1, w2); break; - case 0x3f: cmd_set_color_image(w1, w2); break; + case 0x3d: cmd_set_texture_image(w); break; + case 0x3e: cmd_set_mask_image(w); break; + case 0x3f: cmd_set_color_image(w); break; } - m_cmd_cur += s_rdp_command_length[cmd] / 4; + m_cmd_cur += s_rdp_command_length[cmd] / 8; }; m_cmd_ptr = 0; m_cmd_cur = 0; diff --git a/src/mame/video/n64.h b/src/mame/video/n64.h index e1b0dd983ca..20eeab81fe2 100644 --- a/src/mame/video/n64.h +++ b/src/mame/video/n64.h @@ -6,6 +6,7 @@ #include "emu.h" #include "includes/n64.h" #include "video/poly.h" +#include "pin64.h" /*****************************************************************************/ @@ -128,7 +129,7 @@ class n64_rdp; #include "video/rdpblend.h" #include "video/rdptpipe.h" -typedef void (*rdp_command_t)(uint32_t w1, uint32_t w2); +typedef void (*rdp_command_t)(uint64_t w1); class n64_rdp : public poly_manager { @@ -163,7 +164,7 @@ public: } void process_command_list(); - uint32_t read_data(uint32_t address); + uint64_t read_data(uint32_t address); void disassemble(char* buffer); void set_machine(running_machine& machine) { m_machine = &machine; } @@ -224,43 +225,43 @@ public: bool z_compare(uint32_t zcurpixel, uint32_t dzcurpixel, uint32_t sz, uint16_t dzpix, rdp_span_aux* userdata, const rdp_poly_state &object); // Commands - void cmd_invalid(uint32_t w1, uint32_t w2); - void cmd_noop(uint32_t w1, uint32_t w2); - void cmd_triangle(uint32_t w1, uint32_t w2); - void cmd_triangle_z(uint32_t w1, uint32_t w2); - void cmd_triangle_t(uint32_t w1, uint32_t w2); - void cmd_triangle_tz(uint32_t w1, uint32_t w2); - void cmd_triangle_s(uint32_t w1, uint32_t w2); - void cmd_triangle_sz(uint32_t w1, uint32_t w2); - void cmd_triangle_st(uint32_t w1, uint32_t w2); - void cmd_triangle_stz(uint32_t w1, uint32_t w2); - void cmd_tex_rect(uint32_t w1, uint32_t w2); - void cmd_tex_rect_flip(uint32_t w1, uint32_t w2); - void cmd_sync_load(uint32_t w1, uint32_t w2); - void cmd_sync_pipe(uint32_t w1, uint32_t w2); - void cmd_sync_tile(uint32_t w1, uint32_t w2); - void cmd_sync_full(uint32_t w1, uint32_t w2); - void cmd_set_key_gb(uint32_t w1, uint32_t w2); - void cmd_set_key_r(uint32_t w1, uint32_t w2); - void cmd_set_fill_color32(uint32_t w1, uint32_t w2); - void cmd_set_convert(uint32_t w1, uint32_t w2); - void cmd_set_scissor(uint32_t w1, uint32_t w2); - void cmd_set_prim_depth(uint32_t w1, uint32_t w2); - void cmd_set_other_modes(uint32_t w1, uint32_t w2); - void cmd_load_tlut(uint32_t w1, uint32_t w2); - void cmd_set_tile_size(uint32_t w1, uint32_t w2); - void cmd_load_block(uint32_t w1, uint32_t w2); - void cmd_load_tile(uint32_t w1, uint32_t w2); - void cmd_fill_rect(uint32_t w1, uint32_t w2); - void cmd_set_tile(uint32_t w1, uint32_t w2); - void cmd_set_fog_color(uint32_t w1, uint32_t w2); - void cmd_set_blend_color(uint32_t w1, uint32_t w2); - void cmd_set_prim_color(uint32_t w1, uint32_t w2); - void cmd_set_env_color(uint32_t w1, uint32_t w2); - void cmd_set_combine(uint32_t w1, uint32_t w2); - void cmd_set_texture_image(uint32_t w1, uint32_t w2); - void cmd_set_mask_image(uint32_t w1, uint32_t w2); - void cmd_set_color_image(uint32_t w1, uint32_t w2); + void cmd_invalid(uint64_t w1); + void cmd_noop(uint64_t w1); + void cmd_triangle(uint64_t w1); + void cmd_triangle_z(uint64_t w1); + void cmd_triangle_t(uint64_t w1); + void cmd_triangle_tz(uint64_t w1); + void cmd_triangle_s(uint64_t w1); + void cmd_triangle_sz(uint64_t w1); + void cmd_triangle_st(uint64_t w1); + void cmd_triangle_stz(uint64_t w1); + void cmd_tex_rect(uint64_t w1); + void cmd_tex_rect_flip(uint64_t w1); + void cmd_sync_load(uint64_t w1); + void cmd_sync_pipe(uint64_t w1); + void cmd_sync_tile(uint64_t w1); + void cmd_sync_full(uint64_t w1); + void cmd_set_key_gb(uint64_t w1); + void cmd_set_key_r(uint64_t w1); + void cmd_set_fill_color32(uint64_t w1); + void cmd_set_convert(uint64_t w1); + void cmd_set_scissor(uint64_t w1); + void cmd_set_prim_depth(uint64_t w1); + void cmd_set_other_modes(uint64_t w1); + void cmd_load_tlut(uint64_t w1); + void cmd_set_tile_size(uint64_t w1); + void cmd_load_block(uint64_t w1); + void cmd_load_tile(uint64_t w1); + void cmd_fill_rect(uint64_t w1); + void cmd_set_tile(uint64_t w1); + void cmd_set_fog_color(uint64_t w1); + void cmd_set_blend_color(uint64_t w1); + void cmd_set_prim_color(uint64_t w1); + void cmd_set_env_color(uint64_t w1); + void cmd_set_combine(uint64_t w1); + void cmd_set_texture_image(uint64_t w1); + void cmd_set_mask_image(uint64_t w1); + void cmd_set_color_image(uint64_t w1); void rgbaz_clip(int32_t sr, int32_t sg, int32_t sb, int32_t sa, int32_t* sz, rdp_span_aux* userdata); void rgbaz_correct_triangle(int32_t offx, int32_t offy, int32_t* r, int32_t* g, int32_t* b, int32_t* a, int32_t* z, rdp_span_aux* userdata, const rdp_poly_state &object); @@ -272,6 +273,8 @@ public: uint16_t decompress_cvmask_frombyte(uint8_t x); void lookup_cvmask_derivatives(uint32_t mask, uint8_t* offx, uint8_t* offy, rdp_span_aux* userdata); + void mark_frame() { m_capture.mark_frame(*m_machine); } + misc_state_t m_misc_state; // Color constants @@ -344,8 +347,8 @@ private: uint32_t m_z_complete_dec_table[0x4000]; //the same for decompressed z values, 14b uint8_t m_compressed_cvmasks[0x10000]; //16bit cvmask -> to byte - uint32_t m_cmd_data[0x1000]; - uint32_t m_temp_rect_data[0x1000]; + uint64_t m_cmd_data[0x800]; + uint64_t m_temp_rect_data[0x800]; int32_t m_cmd_ptr; int32_t m_cmd_cur; @@ -367,6 +370,8 @@ private: int32_t m_norm_point_rom[64]; int32_t m_norm_slope_rom[64]; + pin64_t m_capture; + static uint32_t s_special_9bit_clamptable[512]; static const z_decompress_entry_t m_z_dec_table[8]; diff --git a/src/mame/video/pin64.cpp b/src/mame/video/pin64.cpp new file mode 100644 index 00000000000..9e40abc8360 --- /dev/null +++ b/src/mame/video/pin64.cpp @@ -0,0 +1,508 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz + +#include "pin64.h" + +#define CAP_NAME "pin64_%d.cap" + +// pin64_fileutil_t members + +void pin64_fileutil_t::write(FILE* file, uint32_t data) { + if (!file) + return; + + uint8_t temp(data >> 24); + fwrite(&temp, 1, 1, file); + + temp = (uint8_t)(data >> 16); + fwrite(&temp, 1, 1, file); + + temp = (uint8_t)(data >> 8); + fwrite(&temp, 1, 1, file); + + temp = (uint8_t)data; + fwrite(&temp, 1, 1, file); +} + +void pin64_fileutil_t::write(FILE* file, const uint8_t* data, uint32_t size) { + if (!file) + return; + + fwrite(data, 1, size, file); +} + + + +// pin64_data_t members + +void pin64_data_t::put8(uint8_t data) { + m_data.push_back(data); + m_offset++; +} + +void pin64_data_t::put16(uint16_t data) { + put8((uint8_t)(data >> 8)); + put8((uint8_t)data); +} + +void pin64_data_t::put32(uint32_t data) { + put16((uint16_t)(data >> 16)); + put16((uint16_t)data); +} + +void pin64_data_t::put64(uint64_t data) { + put32((uint32_t)(data >> 32)); + put32((uint32_t)data); +} + +uint8_t pin64_data_t::get8() { + if (m_offset >= m_data.size()) + fatalerror("PIN64: Call to pin64_data_t::get8() at end of block (requested offset %x, size %x)\n", m_offset, (uint32_t)m_data.size()); + + uint8_t ret = m_data[m_offset]; + m_offset++; + + return ret; +} + +uint16_t pin64_data_t::get16() { + uint16_t ret = (uint16_t)get8() << 8; + return ret | get8(); +} + +uint32_t pin64_data_t::get32() { + uint32_t ret = (uint32_t)get16() << 16; + return ret | get16(); +} + +uint64_t pin64_data_t::get64() { + uint64_t ret = (uint64_t)get32() << 32; + return ret | get32(); +} + +uint8_t pin64_data_t::get8(uint32_t offset, bool temp_access) { + update_offset(offset, temp_access); + + uint8_t ret = get8(); + m_offset = m_old_offset; + return ret; +} + +uint16_t pin64_data_t::get16(uint32_t offset, bool temp_access) { + update_offset(offset, temp_access); + + uint16_t ret = get16(); + m_offset = m_old_offset; + return ret; +} + +uint32_t pin64_data_t::get32(uint32_t offset, bool temp_access) { + update_offset(offset, temp_access); + + uint32_t ret = get32(); + m_offset = m_old_offset; + return ret; +} + +uint64_t pin64_data_t::get64(uint32_t offset, bool temp_access) { + update_offset(offset, temp_access); + + uint32_t ret = get64(); + m_offset = m_old_offset; + return ret; +} + +void pin64_data_t::reset() { + m_old_offset = 0; + m_offset = 0; +} + +void pin64_data_t::clear() { + reset(); + m_data.clear(); +} + +void pin64_data_t::update_offset(uint32_t offset, bool update_current) { + m_old_offset = (update_current ? offset : m_offset); + m_offset = offset; +} + + + +// pin64_printer_t members + +void pin64_printer_t::print_data(pin64_block_t* block) { + pin64_data_t* data = block->data(); + + printf(" CRC32: %08x\n", (uint32_t)block->crc32()); fflush(stdout); + printf(" Data Size: %08x\n", (uint32_t)data->size()); fflush(stdout); + printf(" Data: "); fflush(stdout); + + const uint32_t data_size = data->size(); + const uint32_t row_count = (data_size + 31) / 32; + const uint8_t* bytes = data->bytes(); + for (uint32_t row = 0; row < row_count; row++) { + const uint32_t row_index = row * 32; + const uint32_t data_remaining = data_size - row_index; + const uint32_t col_count = (data_remaining > 32 ? 32 : data_remaining); + for (uint32_t col = 0; col < col_count; col++) + { + printf("%02x ", bytes[row_index + col]); fflush(stdout); + } + + if (row == (row_count - 1)) { + printf("\n"); fflush(stdout); + } else { + printf("\n "); fflush(stdout); + } + } + + printf("\n"); fflush(stdout); +} + +void pin64_printer_t::print_command(int cmd_start, int cmd, std::unordered_map& blocks, std::vector& commands) { + pin64_block_t* block = blocks[commands[cmd]]; + pin64_data_t* data = block->data(); + + printf(" Command %d:\n", cmd - cmd_start); fflush(stdout); + const uint32_t cmd_size(data->get32()); + printf(" CRC32: %08x\n", (uint32_t)commands[cmd]); fflush(stdout); + printf(" Packet Data Size: %d words\n", cmd_size); fflush(stdout); + printf(" Packet Data: "); fflush(stdout); + + bool load_command = false; + for (int i = 0; i < cmd_size; i++) { + const uint64_t cmd_entry(data->get64()); + if (i == 0) { + const uint8_t top_byte = uint8_t(cmd_entry >> 56) & 0x3f; + if (top_byte == 0x30 || top_byte == 0x33 || top_byte == 0x34) + load_command = true; + } + printf("%08x%08x\n", uint32_t(cmd_entry >> 32), (uint32_t)cmd_entry); fflush(stdout); + + if (i < (cmd_size - 1)) + printf(" "); fflush(stdout); + } + + printf(" Data Block Present: %s\n", load_command ? "Yes" : "No"); fflush(stdout); + + if (load_command) { + printf(" Data Block CRC32: %08x\n", data->get32()); fflush(stdout); + } + + data->reset(); +}; + + + +// pin64_block_t members + +void pin64_block_t::finalize() { + if (m_data.size() > 0) + m_crc32 = util::crc32_creator::simple(m_data.bytes(), m_data.size()); + else + m_crc32 = ~0; + m_data.reset(); +} + +void pin64_block_t::clear() { + m_crc32 = 0; + m_data.clear(); +} + +void pin64_block_t::write(FILE* file) { + pin64_fileutil_t::write(file, m_crc32); + pin64_fileutil_t::write(file, m_data.size()); + if (m_data.size() > 0) + pin64_fileutil_t::write(file, m_data.bytes(), m_data.size()); +} + +uint32_t pin64_block_t::size() { + return sizeof(uint32_t) // data CRC32 + + sizeof(uint32_t) // data size + + m_data.size(); // data +} + + + +// pin64_t members + +const uint8_t pin64_t::CAP_ID[8] = { 'P', 'I', 'N', '6', '4', 'C', 'A', 'P' }; + +pin64_t::~pin64_t() { + if (m_capture_file) + finish(); + + clear(); +} + +void pin64_t::start(int frames) +{ + if (m_capture_index == ~0) + init_capture_index(); + + if (m_capture_file) + fatalerror("PIN64: Call to start() while already capturing\n"); + + char name_buf[256]; + sprintf(name_buf, CAP_NAME, m_capture_index); + m_capture_index++; + + m_capture_file = fopen(name_buf, "wb"); + + m_capture_frames = frames; + + m_frames.push_back(0); +} + +void pin64_t::finish() { + if (!m_capture_file) + return; + + finalize(); + print(); + + write(m_capture_file); + fclose(m_capture_file); + m_capture_file = nullptr; + + clear(); +} + +void pin64_t::finalize() { + finish_command(); + data_end(); +} + +void pin64_t::play(int index) { +} + +void pin64_t::mark_frame(running_machine& machine) { + if (m_capture_file) { + if (m_frames.size() == m_capture_frames && m_capture_frames > 0) { + printf("\n"); + finish(); + machine.popmessage("Done recording."); + } else { + printf("%d ", (uint32_t)m_commands.size()); + m_frames.push_back((uint32_t)m_commands.size()); + } + } + +#if PIN64_ENABLE_CAPTURE + if (machine.input().code_pressed_once(KEYCODE_N) && !m_capture_file) { + start(1); + machine.popmessage("Capturing PIN64 snapshot to pin64_%d.cap", m_capture_index - 1); + } else if (machine.input().code_pressed_once(KEYCODE_M)) { + if (m_capture_file) { + finish(); + machine.popmessage("Done recording."); + } else { + start(); + machine.popmessage("Recording PIN64 movie to pin64_%d.cap", m_capture_index - 1); + } + } +#endif +} + +void pin64_t::command(uint64_t* cmd_data, uint32_t size) { + if (!capturing()) + return; + + finish_command(); + + m_current_command = new pin64_block_t(); + m_current_command->data()->put32(size); + + for (uint32_t i = 0 ; i < size; i++) + m_current_command->data()->put64(cmd_data[i]); +} + +void pin64_t::finish_command() { + if (!m_current_command) + return; + + m_current_command->finalize(); + if (m_blocks.find(m_current_command->crc32()) == m_blocks.end()) + m_blocks[m_current_command->crc32()] = m_current_command; + + m_commands.push_back(m_current_command->crc32()); +} + +void pin64_t::data_begin() { + if (!capturing()) + return; + + if (m_current_data) + data_end(); + + m_current_data = new pin64_block_t(); +} + +pin64_data_t* pin64_t::data_block() { + if (!capturing() || !m_current_data) + return &m_dummy_data; + + return m_current_data->data(); +} + +void pin64_t::data_end() { + if (!capturing() || !m_current_data) + return; + + m_current_data->finalize(); + m_current_command->data()->put32(m_current_data->crc32()); + finish_command(); + + if (m_blocks.find(m_current_data->crc32()) == m_blocks.end()) + m_blocks[m_current_data->crc32()] = m_current_data; + + m_current_data = nullptr; +} + +size_t pin64_t::size() { + return header_size() + block_directory_size() + cmdlist_directory_size() + cmdlist_size(); +} + +size_t pin64_t::header_size() { + return sizeof(uint8_t) * 8 // "PIN64CAP" + + sizeof(uint32_t) // total file size + + sizeof(uint32_t) // start of block directory data + + sizeof(uint32_t) // start of command-list directory data + + sizeof(uint32_t) // start of blocks + + sizeof(uint32_t); // start of commands +} + +size_t pin64_t::block_directory_size() { + return (m_blocks.size() + 1) * sizeof(uint32_t); +} + +size_t pin64_t::cmdlist_directory_size() { + return (m_frames.size() + 1) * sizeof(uint16_t); +} + +size_t pin64_t::blocks_size() { + size_t block_size = 0; + for (std::pair block_pair : m_blocks) + block_size += (block_pair.second)->size(); + + return block_size; +} + +size_t pin64_t::cmdlist_size() { + return (m_commands.size() + 1) * sizeof(uint32_t); +} + +void pin64_t::print() +{ + printf("Total Size: %9x bytes\n", (uint32_t)size()); fflush(stdout); + printf("Header Size: %9x bytes\n", (uint32_t)header_size()); fflush(stdout); + printf("Block Dir Size: %9x bytes\n", (uint32_t)block_directory_size()); fflush(stdout); + printf("Cmdlist Dir Size: %9x bytes\n", (uint32_t)cmdlist_directory_size()); fflush(stdout); + printf("Blocks Size: %9x bytes\n", (uint32_t)blocks_size()); fflush(stdout); + printf("Cmdlist Size: %9x bytes\n", (uint32_t)cmdlist_size()); fflush(stdout); + + printf("Command-List Count: %d\n", (uint32_t)m_frames.size()); fflush(stdout); + for (int i = 0; i < m_frames.size(); i++) { + printf(" List %d:\n", i); fflush(stdout); + + const int next_start = ((i == (m_frames.size() - 1)) ? m_commands.size() : m_frames[i+1]); + for (int cmd = m_frames[i]; cmd < next_start; cmd++) { + pin64_printer_t::print_command(m_frames[i], cmd, m_blocks, m_commands); + } + if (i == (m_frames.size() - 1)) + { + printf("\n"); fflush(stdout); + } + } + + printf("\nData Block Count: %d\n", (uint32_t)m_blocks.size()); fflush(stdout); + int i = 0; + for (std::pair block_pair : m_blocks) { + printf(" Block %d:\n", i); fflush(stdout); + + pin64_printer_t::print_data((block_pair.second)); + if (i == (m_blocks.size() - 1)) + { + printf("\n"); fflush(stdout); + } + i++; + } +} + +void pin64_t::write(FILE* file) { + const uint32_t size_total = size(); + const uint32_t size_header = header_size(); + const uint32_t size_block_dir = block_directory_size(); + const uint32_t size_cmdlist_dir = cmdlist_directory_size(); + const uint32_t size_blocks_dir = blocks_size(); + + pin64_fileutil_t::write(file, CAP_ID, 8); + pin64_fileutil_t::write(file, size_total); + pin64_fileutil_t::write(file, size_header); + pin64_fileutil_t::write(file, size_header + size_block_dir); + pin64_fileutil_t::write(file, size_header + size_block_dir + size_cmdlist_dir); + pin64_fileutil_t::write(file, size_header + size_block_dir + size_cmdlist_dir + size_blocks_dir); + + write_data_directory(file); + write_cmdlist_directory(file); + + for (std::pair block_pair : m_blocks) + (block_pair.second)->write(file); + + pin64_fileutil_t::write(file, m_commands.size()); + for (util::crc32_t crc : m_commands) + pin64_fileutil_t::write(file, crc); +} + +void pin64_t::write_data_directory(FILE* file) { + pin64_fileutil_t::write(file, m_blocks.size()); + size_t offset(header_size()); + for (std::pair block_pair : m_blocks) { + pin64_fileutil_t::write(file, offset); + offset += (block_pair.second)->size(); + } +} + +void pin64_t::write_cmdlist_directory(FILE* file) { + pin64_fileutil_t::write(file, m_frames.size()); + for (uint32_t frame : m_frames) + pin64_fileutil_t::write(file, frame); +} + +void pin64_t::clear() { + if (m_capture_file != nullptr) { + fclose(m_capture_file); + m_capture_file = nullptr; + } + + for (std::pair block_pair : m_blocks) + delete block_pair.second; + + m_blocks.clear(); + m_commands.clear(); + m_frames.clear(); + + m_current_data = nullptr; + m_current_command = nullptr; +} + +void pin64_t::init_capture_index() +{ + char name_buf[256]; + bool found = true; + + m_capture_index = 0; + + do { + sprintf(name_buf, CAP_NAME, m_capture_index); + + FILE* temp = fopen(name_buf, "rb"); + if (temp == nullptr) { + break; + } else { + fclose(temp); + m_capture_index++; + } + } while(found); +} diff --git a/src/mame/video/pin64.h b/src/mame/video/pin64.h new file mode 100644 index 00000000000..d8e82395f25 --- /dev/null +++ b/src/mame/video/pin64.h @@ -0,0 +1,180 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +#pragma once + +#ifndef PIN64_H +#define PIN64_H + +#include +#include +#include + +#define PIN64_ENABLE_CAPTURE (0) + +#include "emu.h" + +class pin64_fileutil_t { +public: + static void write(FILE* file, uint32_t data); + static void write(FILE* file, const uint8_t* data, uint32_t size); +}; + +class pin64_command_t { +public: + std::vector data; +}; + +class pin64_data_t { +public: + pin64_data_t() + : m_offset(0) + , m_old_offset(0) { } + + void reset(); + void clear(); + + // setters + virtual void put8(uint8_t data); + virtual void put16(uint16_t data); + virtual void put32(uint32_t data); + virtual void put64(uint64_t data); + + // getters + virtual uint8_t get8(); + virtual uint8_t get8(uint32_t offset, bool temp_access = false); + virtual uint16_t get16(); + virtual uint16_t get16(uint32_t offset, bool temp_access = false); + virtual uint32_t get32(); + virtual uint32_t get32(uint32_t offset, bool temp_access = false); + virtual uint64_t get64(); + virtual uint64_t get64(uint32_t offset, bool temp_access = false); + virtual uint32_t offset() { return m_offset; } + uint8_t* bytes() { return (m_data.size() > 0) ? &m_data[0] : nullptr; } + uint32_t size() { return m_data.size(); } + +private: + void update_offset(uint32_t offset, bool temp_access = false); + +protected: + std::vector m_data; + + uint32_t m_offset; + uint32_t m_old_offset; +}; + +class pin64_dummy_data_t : public pin64_data_t { +public: + void put8(uint8_t data) override { } + void put16(uint16_t data) override { } + void put32(uint32_t data) override { } + void put64(uint64_t data) override { } + + uint8_t get8() override { return 0; } + uint8_t get8(uint32_t offset, bool update_current = true) override { return 0; } + uint16_t get16() override { return 0; } + uint16_t get16(uint32_t offset, bool update_current = true) override { return 0; } + uint32_t get32() override { return 0; } + uint32_t get32(uint32_t offset, bool update_current = true) override { return 0; } + uint64_t get64() override { return 0; } + uint64_t get64(uint32_t offset, bool update_current = true) override { return 0; } + + uint32_t offset() override { return 0; } +}; + +class pin64_block_t { +public: + pin64_block_t() + : m_crc32{0} { } + virtual ~pin64_block_t() { } + + void finalize(); + void clear(); + + void write(FILE* file); + + // getters + uint32_t size(); + pin64_data_t* data() { return &m_data; } + util::crc32_t crc32() const { return m_crc32; } + +protected: + util::crc32_t m_crc32; + pin64_data_t m_data; +}; + +class pin64_printer_t { +public: + static void print_data(pin64_block_t* block); + static void print_command(int cmd_start, int cmd, std::unordered_map& blocks, std::vector& commands); +}; + +class pin64_t +{ +public: + pin64_t() + : m_capture_file(nullptr) + , m_capture_index(~0) + , m_capture_frames(0) + , m_current_data(nullptr) + , m_current_command(nullptr) + , m_playing(false) + { } + ~pin64_t(); + + void start(int frames = 0); + void finish(); + void clear(); + void print(); + + void mark_frame(running_machine& machine); + void play(int index); + + void command(uint64_t* cmd_data, uint32_t size); + + void data_begin(); + pin64_data_t* data_block(); + pin64_block_t& block() { return *m_current_data; } + void data_end(); + + bool capturing() const { return m_capture_file != nullptr; } + bool playing() const { return m_playing; } + + size_t size(); + +private: + void start_command_block(); + + void write(FILE* file); + + size_t header_size(); + size_t block_directory_size(); + size_t cmdlist_directory_size(); + size_t blocks_size(); + size_t cmdlist_size(); + + void finish_command(); + + void write_data_directory(FILE* file); + void write_cmdlist_directory(FILE* file); + void init_capture_index(); + + void finalize(); + + FILE *m_capture_file; + int32_t m_capture_index; + int m_capture_frames; + + pin64_block_t* m_current_data; + pin64_block_t* m_current_command; + std::unordered_map m_blocks; + + std::vector m_commands; + std::vector m_frames; + + bool m_playing; + + pin64_dummy_data_t m_dummy_data; + static const uint8_t CAP_ID[8]; +}; + +#endif // PIN64_H \ No newline at end of file