mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 15:49:25 +01:00
Merge pull request #10694 from Pokechu22/dsp-assembler-error-messages-etc
DSPAssembler: Rework errors and warnings, and related cleanup
This commit is contained in:
commit
3dbc18060b
@ -22,9 +22,46 @@
|
|||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
|
#include "Core/DSP/DSPCore.h"
|
||||||
#include "Core/DSP/DSPDisassembler.h"
|
#include "Core/DSP/DSPDisassembler.h"
|
||||||
#include "Core/DSP/DSPTables.h"
|
#include "Core/DSP/DSPTables.h"
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fmt::formatter<DSP::DSPAssembler::LocationContext>
|
||||||
|
{
|
||||||
|
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const DSP::DSPAssembler::LocationContext& loc, FormatContext& ctx) const
|
||||||
|
{
|
||||||
|
// Trim trailing newlines
|
||||||
|
// TODO: Ideally, we shouldn't be getting any newlines at all here, but
|
||||||
|
// DSPTool uses File::ReadFileToString, which opens the file in binary mode,
|
||||||
|
// so we get \r endings on Windows. This leads to bad results when printing the string.
|
||||||
|
std::string trimmed_line = loc.line_text;
|
||||||
|
// while (trimmed_line.ends_with('\r') || trimmed_line.ends_with('\n'))
|
||||||
|
while (!trimmed_line.empty() && (trimmed_line.back() == '\r' || trimmed_line.back() == '\n'))
|
||||||
|
trimmed_line.pop_back();
|
||||||
|
|
||||||
|
auto out = fmt::format_to(ctx.out(), "At line {}", loc.line_num);
|
||||||
|
|
||||||
|
if (loc.included_file_path.has_value())
|
||||||
|
out = fmt::format_to(out, " of included file {}", loc.included_file_path.value());
|
||||||
|
|
||||||
|
if (loc.opcode_type.has_value())
|
||||||
|
{
|
||||||
|
if (loc.opcode_type.value() == DSP::DSPAssembler::OpcodeType::Primary)
|
||||||
|
out = fmt::format_to(out, ", main opcode");
|
||||||
|
else if (loc.opcode_type.value() == DSP::DSPAssembler::OpcodeType::Extension)
|
||||||
|
out = fmt::format_to(out, ", extension opcode");
|
||||||
|
|
||||||
|
if (loc.opcode_param_number.has_value())
|
||||||
|
out = fmt::format_to(out, " parameter {}", loc.opcode_param_number.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format_to(out, ":\n{}", trimmed_line);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace DSP
|
namespace DSP
|
||||||
{
|
{
|
||||||
static const char* err_string[] = {"",
|
static const char* err_string[] = {"",
|
||||||
@ -87,31 +124,39 @@ bool DSPAssembler::Assemble(const std::string& text, std::vector<u16>& code,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPAssembler::ShowError(AssemblerError err_code, const char* extra_info)
|
void DSPAssembler::ShowError(AssemblerError err_code)
|
||||||
{
|
{
|
||||||
if (!m_settings.force)
|
if (!m_settings.force)
|
||||||
m_failed = true;
|
m_failed = true;
|
||||||
|
|
||||||
std::string error = fmt::format("{} : {} ", m_code_line, m_cur_line);
|
m_last_error_str =
|
||||||
if (!extra_info)
|
fmt::format("{}\nERROR: {}\n\n", m_location, err_string[static_cast<size_t>(err_code)]);
|
||||||
extra_info = "-";
|
fmt::print(stderr, "{}", m_last_error_str);
|
||||||
|
|
||||||
const char* const error_string = err_string[static_cast<size_t>(err_code)];
|
|
||||||
|
|
||||||
if (m_current_param == 0)
|
|
||||||
{
|
|
||||||
error += fmt::format("ERROR: {} Line: {} : {}\n", error_string, m_code_line, extra_info);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error += fmt::format("ERROR: {} Line: {} Param: {} : {}\n", error_string, m_code_line,
|
|
||||||
m_current_param, extra_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_last_error_str = std::move(error);
|
|
||||||
m_last_error = err_code;
|
m_last_error = err_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void DSPAssembler::ShowError(AssemblerError err_code, fmt::format_string<Args...> format,
|
||||||
|
Args&&... args)
|
||||||
|
{
|
||||||
|
if (!m_settings.force)
|
||||||
|
m_failed = true;
|
||||||
|
|
||||||
|
const auto msg = fmt::format(format, std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
m_last_error_str = fmt::format("{}\nERROR: {}: {}\n\n", m_location,
|
||||||
|
err_string[static_cast<size_t>(err_code)], msg);
|
||||||
|
fmt::print(stderr, "{}", m_last_error_str);
|
||||||
|
m_last_error = err_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void DSPAssembler::ShowWarning(fmt::format_string<Args...> format, Args&&... args)
|
||||||
|
{
|
||||||
|
const auto msg = fmt::format(format, std::forward<Args>(args)...);
|
||||||
|
fmt::print(stderr, "{}\nWARNING: {}\n\n", m_location, msg);
|
||||||
|
}
|
||||||
|
|
||||||
static char* skip_spaces(char* ptr)
|
static char* skip_spaces(char* ptr)
|
||||||
{
|
{
|
||||||
while (*ptr == ' ')
|
while (*ptr == ' ')
|
||||||
@ -146,7 +191,7 @@ s32 DSPAssembler::ParseValue(const char* str)
|
|||||||
if (ptr[i] >= '0' && ptr[i] <= '9')
|
if (ptr[i] >= '0' && ptr[i] <= '9')
|
||||||
val += ptr[i] - '0';
|
val += ptr[i] - '0';
|
||||||
else
|
else
|
||||||
ShowError(AssemblerError::IncorrectDecimal, str);
|
ShowError(AssemblerError::IncorrectDecimal, "{}", str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -164,7 +209,7 @@ s32 DSPAssembler::ParseValue(const char* str)
|
|||||||
else if (ptr[i] >= '0' && ptr[i] <= '9')
|
else if (ptr[i] >= '0' && ptr[i] <= '9')
|
||||||
val += (ptr[i] - '0');
|
val += (ptr[i] - '0');
|
||||||
else
|
else
|
||||||
ShowError(AssemblerError::IncorrectHex, str);
|
ShowError(AssemblerError::IncorrectHex, "{}", str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\'': // binary
|
case '\'': // binary
|
||||||
@ -174,7 +219,7 @@ s32 DSPAssembler::ParseValue(const char* str)
|
|||||||
if (ptr[i] >= '0' && ptr[i] <= '1')
|
if (ptr[i] >= '0' && ptr[i] <= '1')
|
||||||
val += ptr[i] - '0';
|
val += ptr[i] - '0';
|
||||||
else
|
else
|
||||||
ShowError(AssemblerError::IncorrectBinary, str);
|
ShowError(AssemblerError::IncorrectBinary, "{}", str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -195,7 +240,7 @@ s32 DSPAssembler::ParseValue(const char* str)
|
|||||||
if (ptr[i] >= '0' && ptr[i] <= '9')
|
if (ptr[i] >= '0' && ptr[i] <= '9')
|
||||||
val += ptr[i] - '0';
|
val += ptr[i] - '0';
|
||||||
else
|
else
|
||||||
ShowError(AssemblerError::IncorrectDecimal, str);
|
ShowError(AssemblerError::IncorrectDecimal, "{}", str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Everything else is a label.
|
else // Everything else is a label.
|
||||||
@ -205,7 +250,7 @@ s32 DSPAssembler::ParseValue(const char* str)
|
|||||||
return *value;
|
return *value;
|
||||||
|
|
||||||
if (m_cur_pass == 2)
|
if (m_cur_pass == 2)
|
||||||
ShowError(AssemblerError::UnknownLabel, str);
|
ShowError(AssemblerError::UnknownLabel, "{}", str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (negative)
|
if (negative)
|
||||||
@ -331,10 +376,10 @@ u32 DSPAssembler::ParseExpression(const char* ptr)
|
|||||||
val = ParseExpression(d_buffer) - ParseExpression(pbuf + 1);
|
val = ParseExpression(d_buffer) - ParseExpression(pbuf + 1);
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
{
|
{
|
||||||
|
ShowWarning("Number Underflow: {}", val);
|
||||||
val = 0x10000 +
|
val = 0x10000 +
|
||||||
(val &
|
(val &
|
||||||
0xffff); // ATTENTION: avoid a terrible bug!!! number cannot write with '-' in sprintf
|
0xffff); // ATTENTION: avoid a terrible bug!!! number cannot write with '-' in sprintf
|
||||||
fprintf(stderr, "WARNING: Number Underflow at Line: %d \n", m_code_line);
|
|
||||||
}
|
}
|
||||||
sprintf(d_buffer, "%d", val);
|
sprintf(d_buffer, "%d", val);
|
||||||
}
|
}
|
||||||
@ -471,7 +516,7 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < count; i++)
|
for (size_t i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
const size_t current_param = i + 1; // just for display.
|
m_location.opcode_param_number = i + 1;
|
||||||
if (opc->params[i].type != par[i].type || (par[i].type & P_REG))
|
if (opc->params[i].type != par[i].type || (par[i].type & P_REG))
|
||||||
{
|
{
|
||||||
if (par[i].type == P_VAL &&
|
if (par[i].type == P_VAL &&
|
||||||
@ -483,58 +528,38 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
|
|
||||||
if ((opc->params[i].type & P_REG) && (par[i].type & P_REG))
|
if ((opc->params[i].type & P_REG) && (par[i].type & P_REG))
|
||||||
{
|
{
|
||||||
// Just a temp. Should be replaced with more purposeful vars.
|
|
||||||
int value;
|
|
||||||
|
|
||||||
// modified by Hermes: test the register range
|
// modified by Hermes: test the register range
|
||||||
switch ((unsigned)opc->params[i].type)
|
switch (opc->params[i].type)
|
||||||
{
|
{
|
||||||
case P_REG18:
|
case P_REG18:
|
||||||
case P_REG19:
|
case P_REG19:
|
||||||
case P_REG1A:
|
case P_REG1A:
|
||||||
case P_REG1C:
|
case P_REG1C:
|
||||||
value = (opc->params[i].type >> 8) & 31;
|
{
|
||||||
|
int value = (opc->params[i].type >> 8) & 0x1f;
|
||||||
if ((int)par[i].val < value ||
|
if ((int)par[i].val < value ||
|
||||||
(int)par[i].val > value + get_mask_shifted_down(opc->params[i].mask))
|
(int)par[i].val > value + get_mask_shifted_down(opc->params[i].mask))
|
||||||
{
|
{
|
||||||
if (type == OpcodeType::Extension)
|
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
|
|
||||||
fprintf(stderr, "%s (param %zu)", m_cur_line.c_str(), current_param);
|
|
||||||
ShowError(AssemblerError::InvalidRegister);
|
ShowError(AssemblerError::InvalidRegister);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case P_PRG:
|
case P_PRG:
|
||||||
if ((int)par[i].val < 0 || (int)par[i].val > 0x3)
|
if ((int)par[i].val < DSP_REG_AR0 || (int)par[i].val > DSP_REG_AR3)
|
||||||
{
|
{
|
||||||
if (type == OpcodeType::Extension)
|
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
|
|
||||||
fprintf(stderr, "%s (param %zu)", m_cur_line.c_str(), current_param);
|
|
||||||
ShowError(AssemblerError::InvalidRegister);
|
ShowError(AssemblerError::InvalidRegister);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_ACC:
|
case P_ACC:
|
||||||
if ((int)par[i].val < 0x20 || (int)par[i].val > 0x21)
|
if ((int)par[i].val < DSP_REG_ACC0_FULL || (int)par[i].val > DSP_REG_ACC1_FULL)
|
||||||
{
|
{
|
||||||
if (type == OpcodeType::Extension)
|
if (par[i].val >= DSP_REG_ACM0 && par[i].val <= DSP_REG_ACM1)
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
|
|
||||||
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%i : %s ", m_code_line, m_cur_line.c_str());
|
ShowWarning("$ACM{0} register used instead of $ACC{0} register", (par[i].val & 1));
|
||||||
fprintf(stderr,
|
|
||||||
"WARNING: $ACM%d register used instead of $ACC%d register Line: %d "
|
|
||||||
"Param: %zu Ext: %d\n",
|
|
||||||
(par[i].val & 1), (par[i].val & 1), m_code_line, current_param,
|
|
||||||
static_cast<int>(type));
|
|
||||||
}
|
}
|
||||||
else if (par[i].val >= 0x1c && par[i].val <= 0x1d)
|
else if (par[i].val >= DSP_REG_ACL0 && par[i].val <= DSP_REG_ACL1)
|
||||||
{
|
{
|
||||||
fprintf(
|
ShowWarning("$ACL{0} register used instead of $ACC{0} register", (par[i].val & 1));
|
||||||
stderr,
|
|
||||||
"WARNING: $ACL%d register used instead of $ACC%d register Line: %d Param: %zu\n",
|
|
||||||
(par[i].val & 1), (par[i].val & 1), m_code_line, current_param);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -543,24 +568,15 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_ACCM:
|
case P_ACCM:
|
||||||
if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
|
if ((int)par[i].val < DSP_REG_ACM0 || (int)par[i].val > DSP_REG_ACM1)
|
||||||
{
|
{
|
||||||
if (type == OpcodeType::Extension)
|
if (par[i].val >= DSP_REG_ACL0 && par[i].val <= DSP_REG_ACL1)
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
|
|
||||||
if (par[i].val >= 0x1c && par[i].val <= 0x1d)
|
|
||||||
{
|
{
|
||||||
fprintf(
|
ShowWarning("$ACL{0} register used instead of $ACCM{0} register", (par[i].val & 1));
|
||||||
stderr,
|
|
||||||
"WARNING: $ACL%d register used instead of $ACM%d register Line: %d Param: %zu\n",
|
|
||||||
(par[i].val & 1), (par[i].val & 1), m_code_line, current_param);
|
|
||||||
}
|
}
|
||||||
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
|
else if (par[i].val >= DSP_REG_ACC0_FULL && par[i].val <= DSP_REG_ACC1_FULL)
|
||||||
{
|
{
|
||||||
fprintf(
|
ShowWarning("$ACC{0} register used instead of $ACM{0} register", (par[i].val & 1));
|
||||||
stderr,
|
|
||||||
"WARNING: $ACC%d register used instead of $ACM%d register Line: %d Param: %zu\n",
|
|
||||||
(par[i].val & 1), (par[i].val & 1), m_code_line, current_param);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -570,26 +586,15 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case P_ACCL:
|
case P_ACCL:
|
||||||
if ((int)par[i].val < 0x1c || (int)par[i].val > 0x1d)
|
if ((int)par[i].val < DSP_REG_ACL0 || (int)par[i].val > DSP_REG_ACL1)
|
||||||
{
|
{
|
||||||
if (type == OpcodeType::Extension)
|
if (par[i].val >= DSP_REG_ACM0 && par[i].val <= DSP_REG_ACM1)
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
|
|
||||||
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s ", m_cur_line.c_str());
|
ShowWarning("$ACM{0} register used instead of $ACL{0} register", (par[i].val & 1));
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %zu\n",
|
|
||||||
(par[i].val & 1), (par[i].val & 1), m_code_line, current_param);
|
|
||||||
}
|
}
|
||||||
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
|
else if (par[i].val >= DSP_REG_ACC0_FULL && par[i].val <= DSP_REG_ACC1_FULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s ", m_cur_line.c_str());
|
ShowWarning("$ACC{0} register used instead of $ACL{0} register", (par[i].val & 1));
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %zu\n",
|
|
||||||
(par[i].val & 1), (par[i].val & 1), m_code_line, current_param);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -604,23 +609,15 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
switch (par[i].type & (P_REG | 7))
|
switch (par[i].type & (P_REG | 7))
|
||||||
{
|
{
|
||||||
case P_REG:
|
case P_REG:
|
||||||
if (type == OpcodeType::Extension)
|
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
ShowError(AssemblerError::ExpectedParamReg);
|
ShowError(AssemblerError::ExpectedParamReg);
|
||||||
break;
|
break;
|
||||||
case P_MEM:
|
case P_MEM:
|
||||||
if (type == OpcodeType::Extension)
|
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
ShowError(AssemblerError::ExpectedParamMem);
|
ShowError(AssemblerError::ExpectedParamMem);
|
||||||
break;
|
break;
|
||||||
case P_VAL:
|
case P_VAL:
|
||||||
if (type == OpcodeType::Extension)
|
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
ShowError(AssemblerError::ExpectedParamVal);
|
ShowError(AssemblerError::ExpectedParamVal);
|
||||||
break;
|
break;
|
||||||
case P_IMM:
|
case P_IMM:
|
||||||
if (type == OpcodeType::Extension)
|
|
||||||
fprintf(stderr, "(ext) ");
|
|
||||||
ShowError(AssemblerError::ExpectedParamImm);
|
ShowError(AssemblerError::ExpectedParamImm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -634,40 +631,49 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
unsigned int valueu = 0xffff & ~(value >> 1);
|
unsigned int valueu = 0xffff & ~(value >> 1);
|
||||||
if ((int)par[i].val < 0)
|
if ((int)par[i].val < 0)
|
||||||
{
|
{
|
||||||
if (value == 7) // value 7 por sbclr/sbset
|
if (value == 7) // value 7 for sbclr/sbset
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Value must be from 0x0 to 0x%x\n", value);
|
ShowError(AssemblerError::NumberOutOfRange, "Value must be from 0x0 to {:#x}, was {:#x}",
|
||||||
ShowError(AssemblerError::NumberOutOfRange);
|
value, (int)par[i].val);
|
||||||
}
|
}
|
||||||
else if (opc->params[i].type == P_MEM)
|
else if (opc->params[i].type == P_MEM)
|
||||||
{
|
{
|
||||||
if (value < 256)
|
if (value < 256)
|
||||||
fprintf(stderr, "Address value must be from 0x%x to 0x%x\n", valueu, (value >> 1));
|
{
|
||||||
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Address value must be from {:#x} to {:#x}, was {:#x}", valueu, (value >> 1),
|
||||||
|
(int)par[i].val);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Address value must be from 0x0 to 0x%x\n", value);
|
{
|
||||||
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
ShowError(AssemblerError::NumberOutOfRange);
|
"Address value must be from 0x0 to {:#x}, was {:#x}", value, (int)par[i].val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ((int)par[i].val < -((value >> 1) + 1))
|
else if ((int)par[i].val < -((value >> 1) + 1))
|
||||||
{
|
{
|
||||||
if (value < 128)
|
if (value < 128)
|
||||||
fprintf(stderr, "Value must be from -0x%x to 0x%x, is %i\n", (value >> 1) + 1,
|
{
|
||||||
value >> 1, par[i].val);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Value must be from {:#x} to {:#x}, was {:#x}", -((value >> 1) + 1),
|
||||||
|
value >> 1, (int)par[i].val);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Value must be from -0x%x to 0x%x or 0x0 to 0x%x, is %i\n",
|
{
|
||||||
(value >> 1) + 1, value >> 1, value, par[i].val);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Value must be from {:#x} to {:#x} or 0x0 to {:#x}, was {:#x}",
|
||||||
ShowError(AssemblerError::NumberOutOfRange);
|
-((value >> 1) + 1), value >> 1, value, (int)par[i].val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (value == 7) // value 7 por sbclr/sbset
|
if (value == 7) // value 7 for sbclr/sbset
|
||||||
{
|
{
|
||||||
if (par[i].val > (unsigned)value)
|
if (par[i].val > (unsigned)value)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Value must be from 0x%x to 0x%x, is %i\n", valueu, value, par[i].val);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
ShowError(AssemblerError::NumberOutOfRange);
|
"Value must be from {:#x} to {:#x}, was {:#x}\n", valueu, value, par[i].val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (opc->params[i].type == P_MEM)
|
else if (opc->params[i].type == P_MEM)
|
||||||
@ -678,11 +684,17 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
(par[i].val < valueu || par[i].val > (unsigned)0xffff))
|
(par[i].val < valueu || par[i].val > (unsigned)0xffff))
|
||||||
{
|
{
|
||||||
if (value < 256)
|
if (value < 256)
|
||||||
fprintf(stderr, "Address value must be from 0x%x to 0x%x, is %04x\n", valueu, value,
|
{
|
||||||
par[i].val);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Address value must be from {:#x} to {:#x}, was {:04x}\n", valueu, value,
|
||||||
|
par[i].val);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Address value must be minor of 0x%x\n", value + 1);
|
{
|
||||||
ShowError(AssemblerError::NumberOutOfRange);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Address value must be less than {:#x}, was {:04x}\n", value + 1,
|
||||||
|
par[i].val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -692,18 +704,23 @@ bool DSPAssembler::VerifyParams(const DSPOPCTemplate* opc, param_t* par, size_t
|
|||||||
if (par[i].val > (unsigned)value)
|
if (par[i].val > (unsigned)value)
|
||||||
{
|
{
|
||||||
if (value < 64)
|
if (value < 64)
|
||||||
fprintf(stderr, "Value must be from -0x%x to 0x%x, is %i\n", (value + 1), value,
|
{
|
||||||
par[i].val);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Value must be from {:#x} to {:#x}, was {:#x}\n", -(value + 1), value,
|
||||||
|
par[i].val);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Value must be minor of 0x%x, is %i\n", value + 1, par[i].val);
|
{
|
||||||
ShowError(AssemblerError::NumberOutOfRange);
|
ShowError(AssemblerError::NumberOutOfRange,
|
||||||
|
"Value must be less than {:#x}, was {:#x}\n", value + 1, par[i].val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_current_param = 0;
|
m_location.opcode_param_number = std::nullopt;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,11 +768,11 @@ void DSPAssembler::InitPass(int pass)
|
|||||||
|
|
||||||
bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
||||||
{
|
{
|
||||||
int disable_text = 0; // modified by Hermes
|
bool disable_text = false; // modified by Hermes
|
||||||
|
|
||||||
std::istringstream fsrc(text);
|
std::istringstream fsrc(text);
|
||||||
|
|
||||||
m_code_line = 0;
|
m_location.line_num = 0;
|
||||||
m_cur_pass = pass;
|
m_cur_pass = pass;
|
||||||
|
|
||||||
#define LINEBUF_SIZE 1024
|
#define LINEBUF_SIZE 1024
|
||||||
@ -767,8 +784,8 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
if (fsrc.fail())
|
if (fsrc.fail())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
m_cur_line = line;
|
m_location.line_text = line;
|
||||||
m_code_line++;
|
m_location.line_num++;
|
||||||
|
|
||||||
param_t params[10] = {{0, P_NONE, nullptr}};
|
param_t params[10] = {{0, P_NONE, nullptr}};
|
||||||
param_t params_ext[10] = {{0, P_NONE, nullptr}};
|
param_t params_ext[10] = {{0, P_NONE, nullptr}};
|
||||||
@ -781,10 +798,10 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
// modified by Hermes : added // and /* */ for long commentaries
|
// modified by Hermes : added // and /* */ for long commentaries
|
||||||
if (c == '/')
|
if (c == '/')
|
||||||
{
|
{
|
||||||
if (i < 1023)
|
if (i + 1 < LINEBUF_SIZE)
|
||||||
{
|
{
|
||||||
if (line[i + 1] == '/')
|
if (line[i + 1] == '/')
|
||||||
c = 0x00;
|
c = '\0';
|
||||||
else if (line[i + 1] == '*')
|
else if (line[i + 1] == '*')
|
||||||
{
|
{
|
||||||
// toggle comment mode.
|
// toggle comment mode.
|
||||||
@ -794,28 +811,28 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
}
|
}
|
||||||
else if (c == '*')
|
else if (c == '*')
|
||||||
{
|
{
|
||||||
if (i < 1023 && line[i + 1] == '/' && disable_text)
|
if (i + 1 < LINEBUF_SIZE && line[i + 1] == '/' && disable_text)
|
||||||
{
|
{
|
||||||
disable_text = 0;
|
disable_text = false;
|
||||||
c = 32;
|
c = ' ';
|
||||||
line[i + 1] = 32;
|
line[i + 1] = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn text into spaces if disable_text is on (in a comment).
|
// turn text into spaces if disable_text is on (in a comment).
|
||||||
if (disable_text && ((unsigned char)c) > 32)
|
if (disable_text && ((unsigned char)c) > ' ')
|
||||||
c = 32;
|
c = ' ';
|
||||||
|
|
||||||
if (c == 0x0a || c == 0x0d || c == ';')
|
if (c == '\r' || c == '\n' || c == ';')
|
||||||
c = 0x00;
|
c = '\0';
|
||||||
if (c == 0x09) // tabs to spaces
|
if (c == '\t') // tabs to spaces
|
||||||
c = ' ';
|
c = ' ';
|
||||||
if (c == '"')
|
if (c == '"')
|
||||||
upper = !upper;
|
upper = !upper;
|
||||||
if (upper && c >= 'a' && c <= 'z') // convert to uppercase
|
if (upper && c >= 'a' && c <= 'z') // convert to uppercase
|
||||||
c = c - 'a' + 'A';
|
c = c - 'a' + 'A';
|
||||||
line[i] = c;
|
line[i] = c;
|
||||||
if (c == 0)
|
if (c == '\0')
|
||||||
break; // modified by Hermes
|
break; // modified by Hermes
|
||||||
}
|
}
|
||||||
char* ptr = line;
|
char* ptr = line;
|
||||||
@ -905,23 +922,22 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
{
|
{
|
||||||
if (params[0].type == P_STR)
|
if (params[0].type == P_STR)
|
||||||
{
|
{
|
||||||
std::string include_file_path;
|
const auto old_location = m_location;
|
||||||
const u32 this_code_line = m_code_line;
|
|
||||||
|
|
||||||
if (m_include_dir.empty())
|
if (m_include_dir.empty())
|
||||||
{
|
{
|
||||||
include_file_path = params[0].str;
|
m_location.included_file_path = params[0].str;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
include_file_path = m_include_dir + '/' + params[0].str;
|
m_location.included_file_path = m_include_dir + '/' + params[0].str;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string included_text;
|
std::string included_text;
|
||||||
File::ReadFileToString(include_file_path, included_text);
|
File::ReadFileToString(m_location.included_file_path.value(), included_text);
|
||||||
AssemblePass(included_text, pass);
|
AssemblePass(included_text, pass);
|
||||||
|
|
||||||
m_code_line = this_code_line;
|
m_location = old_location;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -959,9 +975,8 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
{
|
{
|
||||||
if (m_cur_addr > params[0].val)
|
if (m_cur_addr > params[0].val)
|
||||||
{
|
{
|
||||||
const std::string msg = fmt::format("WARNPC at 0x{:04x}, expected 0x{:04x} or less",
|
ShowError(AssemblerError::PCOutOfRange, "WARNPC at 0x{:04x}, expected 0x{:04x} or less",
|
||||||
m_cur_addr, params[0].val);
|
m_cur_addr, params[0].val);
|
||||||
ShowError(AssemblerError::PCOutOfRange, msg.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -987,6 +1002,7 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_location.opcode_type = OpcodeType::Primary;
|
||||||
const DSPOPCTemplate* opc = FindOpcode(opcode, params_count, OpcodeType::Primary);
|
const DSPOPCTemplate* opc = FindOpcode(opcode, params_count, OpcodeType::Primary);
|
||||||
if (!opc)
|
if (!opc)
|
||||||
opc = &cw;
|
opc = &cw;
|
||||||
@ -997,6 +1013,7 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
|
|
||||||
const DSPOPCTemplate* opc_ext = nullptr;
|
const DSPOPCTemplate* opc_ext = nullptr;
|
||||||
// Check for opcode extensions.
|
// Check for opcode extensions.
|
||||||
|
m_location.opcode_type = OpcodeType::Extension;
|
||||||
if (opc->extended)
|
if (opc->extended)
|
||||||
{
|
{
|
||||||
if (opcode_ext)
|
if (opcode_ext)
|
||||||
@ -1016,6 +1033,7 @@ bool DSPAssembler::AssemblePass(const std::string& text, int pass)
|
|||||||
if (params_count_ext)
|
if (params_count_ext)
|
||||||
ShowError(AssemblerError::ExtensionParamsOnNonExtendableOpcode);
|
ShowError(AssemblerError::ExtensionParamsOnNonExtendableOpcode);
|
||||||
}
|
}
|
||||||
|
m_location.opcode_type = std::nullopt;
|
||||||
|
|
||||||
if (pass == 2)
|
if (pass == 2)
|
||||||
{
|
{
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
#include "Core/DSP/DSPDisassembler.h"
|
#include "Core/DSP/DSPDisassembler.h"
|
||||||
@ -85,6 +89,17 @@ private:
|
|||||||
Extension
|
Extension
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LocationContext
|
||||||
|
{
|
||||||
|
u32 line_num = 0;
|
||||||
|
std::string line_text;
|
||||||
|
std::optional<OpcodeType> opcode_type;
|
||||||
|
std::optional<size_t> opcode_param_number;
|
||||||
|
std::optional<std::string> included_file_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
friend struct ::fmt::formatter<DSP::DSPAssembler::LocationContext>;
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
s32 ParseValue(const char* str);
|
s32 ParseValue(const char* str);
|
||||||
u32 ParseExpression(const char* ptr);
|
u32 ParseExpression(const char* ptr);
|
||||||
@ -94,7 +109,11 @@ private:
|
|||||||
void InitPass(int pass);
|
void InitPass(int pass);
|
||||||
bool AssemblePass(const std::string& text, int pass);
|
bool AssemblePass(const std::string& text, int pass);
|
||||||
|
|
||||||
void ShowError(AssemblerError err_code, const char* extra_info = nullptr);
|
void ShowError(AssemblerError err_code);
|
||||||
|
template <typename... Args>
|
||||||
|
void ShowError(AssemblerError err_code, fmt::format_string<Args...> format, Args&&... args);
|
||||||
|
template <typename... Args>
|
||||||
|
void ShowWarning(fmt::format_string<Args...> format, Args&&... args);
|
||||||
|
|
||||||
char* FindBrackets(char* src, char* dst);
|
char* FindBrackets(char* src, char* dst);
|
||||||
const DSPOPCTemplate* FindOpcode(std::string name, size_t par_count, OpcodeType type);
|
const DSPOPCTemplate* FindOpcode(std::string name, size_t par_count, OpcodeType type);
|
||||||
@ -104,7 +123,6 @@ private:
|
|||||||
std::vector<u16> m_output_buffer;
|
std::vector<u16> m_output_buffer;
|
||||||
|
|
||||||
std::string m_include_dir;
|
std::string m_include_dir;
|
||||||
std::string m_cur_line;
|
|
||||||
|
|
||||||
u32 m_cur_addr = 0;
|
u32 m_cur_addr = 0;
|
||||||
int m_total_size = 0;
|
int m_total_size = 0;
|
||||||
@ -112,7 +130,6 @@ private:
|
|||||||
|
|
||||||
LabelMap m_labels;
|
LabelMap m_labels;
|
||||||
|
|
||||||
u32 m_code_line = 0;
|
|
||||||
bool m_failed = false;
|
bool m_failed = false;
|
||||||
std::string m_last_error_str;
|
std::string m_last_error_str;
|
||||||
AssemblerError m_last_error = AssemblerError::OK;
|
AssemblerError m_last_error = AssemblerError::OK;
|
||||||
@ -122,7 +139,8 @@ private:
|
|||||||
|
|
||||||
segment_t m_cur_segment = SEGMENT_CODE;
|
segment_t m_cur_segment = SEGMENT_CODE;
|
||||||
u32 m_segment_addr[SEGMENT_MAX] = {};
|
u32 m_segment_addr[SEGMENT_MAX] = {};
|
||||||
int m_current_param = 0;
|
|
||||||
const AssemblerSettings m_settings;
|
const AssemblerSettings m_settings;
|
||||||
|
|
||||||
|
LocationContext m_location;
|
||||||
};
|
};
|
||||||
} // namespace DSP
|
} // namespace DSP
|
||||||
|
@ -35,13 +35,7 @@ bool Assemble(const std::string& text, std::vector<u16>& code, bool force)
|
|||||||
|
|
||||||
// TODO: fix the terrible api of the assembler.
|
// TODO: fix the terrible api of the assembler.
|
||||||
DSPAssembler assembler(settings);
|
DSPAssembler assembler(settings);
|
||||||
if (!assembler.Assemble(text, code))
|
return assembler.Assemble(text, code);
|
||||||
{
|
|
||||||
std::cerr << assembler.GetErrorString() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Disassemble(const std::vector<u16>& code, bool line_numbers, std::string& text)
|
bool Disassemble(const std::vector<u16>& code, bool line_numbers, std::string& text)
|
||||||
|
@ -122,15 +122,23 @@ enum : int
|
|||||||
DSP_REG_AXH1 = 0x1b,
|
DSP_REG_AXH1 = 0x1b,
|
||||||
|
|
||||||
// Accumulator (global)
|
// Accumulator (global)
|
||||||
DSP_REG_ACC0 = 0x1c,
|
|
||||||
DSP_REG_ACC1 = 0x1d,
|
|
||||||
|
|
||||||
DSP_REG_ACL0 = 0x1c, // Low accumulator
|
DSP_REG_ACL0 = 0x1c, // Low accumulator
|
||||||
DSP_REG_ACL1 = 0x1d,
|
DSP_REG_ACL1 = 0x1d,
|
||||||
DSP_REG_ACM0 = 0x1e, // Mid accumulator
|
DSP_REG_ACM0 = 0x1e, // Mid accumulator
|
||||||
DSP_REG_ACM1 = 0x1f,
|
DSP_REG_ACM1 = 0x1f,
|
||||||
DSP_REG_ACH0 = 0x10, // Sign extended 8 bit register 0
|
DSP_REG_ACH0 = 0x10, // Sign extended 8 bit register 0
|
||||||
DSP_REG_ACH1 = 0x11 // Sign extended 8 bit register 1
|
DSP_REG_ACH1 = 0x11, // Sign extended 8 bit register 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum : int
|
||||||
|
{
|
||||||
|
// Magic values used by DSPTables.h
|
||||||
|
// These do not correspond to real registers like above, but instead combined versions of the
|
||||||
|
// registers.
|
||||||
|
DSP_REG_ACC0_FULL = 0x20,
|
||||||
|
DSP_REG_ACC1_FULL = 0x21,
|
||||||
|
DSP_REG_AX0_FULL = 0x22,
|
||||||
|
DSP_REG_AX1_FULL = 0x23,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hardware registers address
|
// Hardware registers address
|
||||||
|
@ -152,10 +152,8 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, u16* pc, std::string&
|
|||||||
|
|
||||||
// Find main opcode
|
// Find main opcode
|
||||||
const DSPOPCTemplate* opc = FindOpInfoByOpcode(op1);
|
const DSPOPCTemplate* opc = FindOpInfoByOpcode(op1);
|
||||||
const DSPOPCTemplate fake_op = {"CW", 0x0000, 0x0000, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},
|
|
||||||
false, false, false, false, false};
|
|
||||||
if (!opc)
|
if (!opc)
|
||||||
opc = &fake_op;
|
opc = &cw;
|
||||||
|
|
||||||
bool is_extended = false;
|
bool is_extended = false;
|
||||||
bool is_only_7_bit_ext = false;
|
bool is_only_7_bit_ext = false;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
#include "Core/DSP/Interpreter/DSPIntTables.h"
|
#include "Core/DSP/DSPCore.h"
|
||||||
|
|
||||||
namespace DSP
|
namespace DSP
|
||||||
{
|
{
|
||||||
@ -39,10 +39,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"RETZ", 0x02d5, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if zero
|
{"RETZ", 0x02d5, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if zero
|
||||||
{"RETNC", 0x02d6, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if not carry
|
{"RETNC", 0x02d6, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if not carry
|
||||||
{"RETC", 0x02d7, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if carry
|
{"RETC", 0x02d7, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if carry
|
||||||
{"RETx8", 0x02d8, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
{"RETX8", 0x02d8, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
||||||
{"RETx9", 0x02d9, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
{"RETX9", 0x02d9, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
||||||
{"RETxA", 0x02da, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
{"RETXA", 0x02da, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
||||||
{"RETxB", 0x02db, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
{"RETXB", 0x02db, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if TODO
|
||||||
{"RETLNZ", 0x02dc, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if logic not zero
|
{"RETLNZ", 0x02dc, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if logic not zero
|
||||||
{"RETLZ", 0x02dd, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if logic zero
|
{"RETLZ", 0x02dd, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if logic zero
|
||||||
{"RETO", 0x02de, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if overflow
|
{"RETO", 0x02de, 0xffff, 1, 0, {}, false, true, false, true, false}, // return if overflow
|
||||||
@ -56,10 +56,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"RTIZ", 0x02f5, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if zero
|
{"RTIZ", 0x02f5, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if zero
|
||||||
{"RTINC", 0x02f6, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if not carry
|
{"RTINC", 0x02f6, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if not carry
|
||||||
{"RTIC", 0x02f7, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if carry
|
{"RTIC", 0x02f7, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if carry
|
||||||
{"RTIx8", 0x02f8, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
{"RTIX8", 0x02f8, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
||||||
{"RTIx9", 0x02f9, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
{"RTIX9", 0x02f9, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
||||||
{"RTIxA", 0x02fa, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
{"RTIXA", 0x02fa, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
||||||
{"RTIxB", 0x02fb, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
{"RTIXB", 0x02fb, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if TODO
|
||||||
{"RTILNZ", 0x02fc, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if logic not zero
|
{"RTILNZ", 0x02fc, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if logic not zero
|
||||||
{"RTILZ", 0x02fd, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if logic zero
|
{"RTILZ", 0x02fd, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if logic zero
|
||||||
{"RTIO", 0x02fe, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if overflow
|
{"RTIO", 0x02fe, 0xffff, 1, 0, {}, false, true, false, true, false}, // return from interrupt if overflow
|
||||||
@ -73,10 +73,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"CALLZ", 0x02b5, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if zero
|
{"CALLZ", 0x02b5, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if zero
|
||||||
{"CALLNC", 0x02b6, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if not carry
|
{"CALLNC", 0x02b6, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if not carry
|
||||||
{"CALLC", 0x02b7, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if carry
|
{"CALLC", 0x02b7, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if carry
|
||||||
{"CALLx8", 0x02b8, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
{"CALLX8", 0x02b8, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
||||||
{"CALLx9", 0x02b9, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
{"CALLX9", 0x02b9, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
||||||
{"CALLxA", 0x02ba, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
{"CALLXA", 0x02ba, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
||||||
{"CALLxB", 0x02bb, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
{"CALLXB", 0x02bb, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if TODO
|
||||||
{"CALLLNZ", 0x02bc, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if logic not zero
|
{"CALLLNZ", 0x02bc, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if logic not zero
|
||||||
{"CALLLZ", 0x02bd, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if logic zero
|
{"CALLLZ", 0x02bd, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if logic zero
|
||||||
{"CALLO", 0x02be, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if overflow
|
{"CALLO", 0x02be, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // call if overflow
|
||||||
@ -90,10 +90,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"IFZ", 0x0275, 0xffff, 1, 0, {}, false, true, false, true, false}, // if zero
|
{"IFZ", 0x0275, 0xffff, 1, 0, {}, false, true, false, true, false}, // if zero
|
||||||
{"IFNC", 0x0276, 0xffff, 1, 0, {}, false, true, false, true, false}, // if not carry
|
{"IFNC", 0x0276, 0xffff, 1, 0, {}, false, true, false, true, false}, // if not carry
|
||||||
{"IFC", 0x0277, 0xffff, 1, 0, {}, false, true, false, true, false}, // if carry
|
{"IFC", 0x0277, 0xffff, 1, 0, {}, false, true, false, true, false}, // if carry
|
||||||
{"IFx8", 0x0278, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
{"IFX8", 0x0278, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
||||||
{"IFx9", 0x0279, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
{"IFX9", 0x0279, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
||||||
{"IFxA", 0x027a, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
{"IFXA", 0x027a, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
||||||
{"IFxB", 0x027b, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
{"IFXB", 0x027b, 0xffff, 1, 0, {}, false, true, false, true, false}, // if TODO
|
||||||
{"IFLNZ", 0x027c, 0xffff, 1, 0, {}, false, true, false, true, false}, // if logic not zero
|
{"IFLNZ", 0x027c, 0xffff, 1, 0, {}, false, true, false, true, false}, // if logic not zero
|
||||||
{"IFLZ", 0x027d, 0xffff, 1, 0, {}, false, true, false, true, false}, // if logic zero
|
{"IFLZ", 0x027d, 0xffff, 1, 0, {}, false, true, false, true, false}, // if logic zero
|
||||||
{"IFO", 0x027e, 0xffff, 1, 0, {}, false, true, false, true, false}, // if overflow
|
{"IFO", 0x027e, 0xffff, 1, 0, {}, false, true, false, true, false}, // if overflow
|
||||||
@ -107,10 +107,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"JZ", 0x0295, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if zero
|
{"JZ", 0x0295, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if zero
|
||||||
{"JNC", 0x0296, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if not carry
|
{"JNC", 0x0296, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if not carry
|
||||||
{"JC", 0x0297, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if carry
|
{"JC", 0x0297, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if carry
|
||||||
{"JMPx8", 0x0298, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
{"JMPX8", 0x0298, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
||||||
{"JMPx9", 0x0299, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
{"JMPX9", 0x0299, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
||||||
{"JMPxA", 0x029a, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
{"JMPXA", 0x029a, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
||||||
{"JMPxB", 0x029b, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
{"JMPXB", 0x029b, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if TODO
|
||||||
{"JLNZ", 0x029c, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if logic not zero
|
{"JLNZ", 0x029c, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if logic not zero
|
||||||
{"JLZ", 0x029d, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if logic zero
|
{"JLZ", 0x029d, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if logic zero
|
||||||
{"JO", 0x029e, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if overflow
|
{"JO", 0x029e, 0xffff, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false}, // jump if overflow
|
||||||
@ -124,10 +124,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"JRZ", 0x1705, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if zero
|
{"JRZ", 0x1705, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if zero
|
||||||
{"JRNC", 0x1706, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if not carry
|
{"JRNC", 0x1706, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if not carry
|
||||||
{"JRC", 0x1707, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if carry
|
{"JRC", 0x1707, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if carry
|
||||||
{"JMPRx8", 0x1708, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
{"JMPRX8", 0x1708, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
||||||
{"JMPRx9", 0x1709, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
{"JMPRX9", 0x1709, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
||||||
{"JMPRxA", 0x170a, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
{"JMPRXA", 0x170a, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
||||||
{"JMPRxB", 0x170b, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
{"JMPRXB", 0x170b, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if TODO
|
||||||
{"JRLNZ", 0x170c, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if logic not zero
|
{"JRLNZ", 0x170c, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if logic not zero
|
||||||
{"JRLZ", 0x170d, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if logic zero
|
{"JRLZ", 0x170d, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if logic zero
|
||||||
{"JRO", 0x170e, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if overflow
|
{"JRO", 0x170e, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false, false}, // jump to $R if overflow
|
||||||
@ -141,10 +141,10 @@ const std::array<DSPOPCTemplate, 230> s_opcodes =
|
|||||||
{"CALLRZ", 0x1715, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if zero
|
{"CALLRZ", 0x1715, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if zero
|
||||||
{"CALLRNC", 0x1716, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if not carry
|
{"CALLRNC", 0x1716, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if not carry
|
||||||
{"CALLRC", 0x1717, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if carry
|
{"CALLRC", 0x1717, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if carry
|
||||||
{"CALLRx8", 0x1718, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
{"CALLRX8", 0x1718, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
||||||
{"CALLRx9", 0x1719, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
{"CALLRX9", 0x1719, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
||||||
{"CALLRxA", 0x171a, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
{"CALLRXA", 0x171a, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
||||||
{"CALLRxB", 0x171b, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
{"CALLRXB", 0x171b, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if TODO
|
||||||
{"CALLRLNZ", 0x171c, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if logic not zero
|
{"CALLRLNZ", 0x171c, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if logic not zero
|
||||||
{"CALLRLZ", 0x171d, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if logic zero
|
{"CALLRLZ", 0x171d, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if logic zero
|
||||||
{"CALLRO", 0x171e, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if overflow
|
{"CALLRO", 0x171e, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, true, false}, // call $R if overflow
|
||||||
@ -451,44 +451,44 @@ const std::array<pdlabel_t, 96> pdlabels =
|
|||||||
|
|
||||||
const std::array<pdlabel_t, 36> regnames =
|
const std::array<pdlabel_t, 36> regnames =
|
||||||
{{
|
{{
|
||||||
{0x00, "AR0", "Addr Reg 00",},
|
{DSP_REG_AR0, "AR0", "Addr Reg 00",},
|
||||||
{0x01, "AR1", "Addr Reg 01",},
|
{DSP_REG_AR1, "AR1", "Addr Reg 01",},
|
||||||
{0x02, "AR2", "Addr Reg 02",},
|
{DSP_REG_AR2, "AR2", "Addr Reg 02",},
|
||||||
{0x03, "AR3", "Addr Reg 03",},
|
{DSP_REG_AR3, "AR3", "Addr Reg 03",},
|
||||||
{0x04, "IX0", "Index Reg 0",},
|
{DSP_REG_IX0, "IX0", "Index Reg 0",},
|
||||||
{0x05, "IX1", "Index Reg 1",},
|
{DSP_REG_IX1, "IX1", "Index Reg 1",},
|
||||||
{0x06, "IX2", "Index Reg 2",},
|
{DSP_REG_IX2, "IX2", "Index Reg 2",},
|
||||||
{0x07, "IX3", "Index Reg 3",},
|
{DSP_REG_IX3, "IX3", "Index Reg 3",},
|
||||||
{0x08, "WR0", "Wrapping Register 0",},
|
{DSP_REG_WR0, "WR0", "Wrapping Register 0",},
|
||||||
{0x09, "WR1", "Wrapping Register 1",},
|
{DSP_REG_WR1, "WR1", "Wrapping Register 1",},
|
||||||
{0x0a, "WR2", "Wrapping Register 2",},
|
{DSP_REG_WR2, "WR2", "Wrapping Register 2",},
|
||||||
{0x0b, "WR3", "Wrapping Register 3",},
|
{DSP_REG_WR3, "WR3", "Wrapping Register 3",},
|
||||||
{0x0c, "ST0", "Call stack",},
|
{DSP_REG_ST0, "ST0", "Call stack",},
|
||||||
{0x0d, "ST1", "Data stack",},
|
{DSP_REG_ST1, "ST1", "Data stack",},
|
||||||
{0x0e, "ST2", "Loop addr stack",},
|
{DSP_REG_ST2, "ST2", "Loop addr stack",},
|
||||||
{0x0f, "ST3", "Loop counter stack",},
|
{DSP_REG_ST3, "ST3", "Loop counter stack",},
|
||||||
{0x10, "AC0.H", "Accu High 0",},
|
{DSP_REG_ACH0, "AC0.H", "Accu High 0",},
|
||||||
{0x11, "AC1.H", "Accu High 1",},
|
{DSP_REG_ACH1, "AC1.H", "Accu High 1",},
|
||||||
{0x12, "CR", "Config Register",},
|
{DSP_REG_CR, "CR", "Config Register",},
|
||||||
{0x13, "SR", "Special Register",},
|
{DSP_REG_SR, "SR", "Special Register",},
|
||||||
{0x14, "PROD.L", "Prod L",},
|
{DSP_REG_PRODL, "PROD.L", "Prod L",},
|
||||||
{0x15, "PROD.M1", "Prod M1",},
|
{DSP_REG_PRODM, "PROD.M1", "Prod M1",},
|
||||||
{0x16, "PROD.H", "Prod H",},
|
{DSP_REG_PRODH, "PROD.H", "Prod H",},
|
||||||
{0x17, "PROD.M2", "Prod M2",},
|
{DSP_REG_PRODM2, "PROD.M2", "Prod M2",},
|
||||||
{0x18, "AX0.L", "Extra Accu L 0",},
|
{DSP_REG_AXL0, "AX0.L", "Extra Accu L 0",},
|
||||||
{0x19, "AX1.L", "Extra Accu L 1",},
|
{DSP_REG_AXL1, "AX1.L", "Extra Accu L 1",},
|
||||||
{0x1a, "AX0.H", "Extra Accu H 0",},
|
{DSP_REG_AXH0, "AX0.H", "Extra Accu H 0",},
|
||||||
{0x1b, "AX1.H", "Extra Accu H 1",},
|
{DSP_REG_AXH1, "AX1.H", "Extra Accu H 1",},
|
||||||
{0x1c, "AC0.L", "Accu Low 0",},
|
{DSP_REG_ACL0, "AC0.L", "Accu Low 0",},
|
||||||
{0x1d, "AC1.L", "Accu Low 1",},
|
{DSP_REG_ACL1, "AC1.L", "Accu Low 1",},
|
||||||
{0x1e, "AC0.M", "Accu Mid 0",},
|
{DSP_REG_ACM0, "AC0.M", "Accu Mid 0",},
|
||||||
{0x1f, "AC1.M", "Accu Mid 1",},
|
{DSP_REG_ACM1, "AC1.M", "Accu Mid 1",},
|
||||||
|
|
||||||
// To resolve combined register names.
|
// To resolve combined register names.
|
||||||
{0x20, "ACC0", "Accu Full 0",},
|
{DSP_REG_ACC0_FULL, "ACC0", "Accu Full 0",},
|
||||||
{0x21, "ACC1", "Accu Full 1",},
|
{DSP_REG_ACC1_FULL, "ACC1", "Accu Full 1",},
|
||||||
{0x22, "AX0", "Extra Accu 0",},
|
{DSP_REG_AX0_FULL, "AX0", "Extra Accu 0",},
|
||||||
{0x23, "AX1", "Extra Accu 1",},
|
{DSP_REG_AX1_FULL, "AX1", "Extra Accu 1",},
|
||||||
}};
|
}};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include "Core/DSP/DSPCommon.h"
|
#include "Core/DSP/DSPCommon.h"
|
||||||
|
#include "Core/DSP/DSPCore.h"
|
||||||
|
|
||||||
namespace DSP
|
namespace DSP
|
||||||
{
|
{
|
||||||
@ -31,23 +32,23 @@ enum partype_t
|
|||||||
P_ADDR_I = 0x0005,
|
P_ADDR_I = 0x0005,
|
||||||
P_ADDR_D = 0x0006,
|
P_ADDR_D = 0x0006,
|
||||||
P_REG = 0x8000,
|
P_REG = 0x8000,
|
||||||
P_REG04 = P_REG | 0x0400, // IX
|
P_REG04 = P_REG | DSP_REG_IX0 << 8,
|
||||||
P_REG08 = P_REG | 0x0800,
|
P_REG08 = P_REG | DSP_REG_WR0 << 8,
|
||||||
P_REG18 = P_REG | 0x1800,
|
P_REG18 = P_REG | DSP_REG_AXL0 << 8,
|
||||||
P_REGM18 = P_REG | 0x1810, // used in multiply instructions
|
P_REGM18 = P_REG | DSP_REG_AXL0 << 8 | 0x10, // used in multiply instructions
|
||||||
P_REG19 = P_REG | 0x1900,
|
P_REG19 = P_REG | DSP_REG_AXL1 << 8,
|
||||||
P_REGM19 = P_REG | 0x1910, // used in multiply instructions
|
P_REGM19 = P_REG | DSP_REG_AXL1 << 8 | 0x10, // used in multiply instructions
|
||||||
P_REG1A = P_REG | 0x1a80,
|
P_REG1A = P_REG | DSP_REG_AXH0 << 8 | 0x80,
|
||||||
// P_ACC = P_REG | 0x1c10, // used for global accum (gcdsptool's value)
|
// P_ACC = P_REG | 0x1c10, // used for global accum (gcdsptool's value)
|
||||||
P_ACCL = P_REG | 0x1c00, // used for low part of accum
|
P_ACCL = P_REG | DSP_REG_ACL0 << 8, // used for low part of accum
|
||||||
P_REG1C = P_REG | 0x1c10, // gcdsptool calls this P_ACCLM
|
P_REG1C = P_REG | DSP_REG_ACL0 << 8 | 0x10, // gcdsptool calls this P_ACCLM
|
||||||
P_ACCM = P_REG | 0x1e00, // used for mid part of accum
|
P_ACCM = P_REG | DSP_REG_ACM0 << 8, // used for mid part of accum
|
||||||
// The following are not in gcdsptool
|
// The following are not in gcdsptool
|
||||||
P_ACCM_D = P_REG | 0x1e80,
|
P_ACCM_D = P_REG | DSP_REG_ACM0 << 8 | 0x80,
|
||||||
P_ACC = P_REG | 0x2000, // used for full accum.
|
P_ACC = P_REG | DSP_REG_ACC0_FULL << 8, // used for full accum.
|
||||||
P_ACCH = P_REG | 0x1000, // used for high part of accum
|
P_ACCH = P_REG | DSP_REG_ACH0 << 8, // used for high part of accum
|
||||||
P_ACC_D = P_REG | 0x2080,
|
P_ACC_D = P_REG | DSP_REG_ACC0_FULL << 8 | 0x80,
|
||||||
P_AX = P_REG | 0x2200,
|
P_AX = P_REG | DSP_REG_AX0_FULL << 8,
|
||||||
P_REGS_MASK = 0x03f80, // gcdsptool's value = 0x01f80
|
P_REGS_MASK = 0x03f80, // gcdsptool's value = 0x01f80
|
||||||
P_REF = P_REG | 0x4000,
|
P_REF = P_REG | 0x4000,
|
||||||
P_PRG = P_REF | P_REG,
|
P_PRG = P_REF | P_REG,
|
||||||
|
@ -138,3 +138,6 @@ sub $acc1, $acc0
|
|||||||
set16
|
set16
|
||||||
|
|
||||||
call send_back ; 20
|
call send_back ; 20
|
||||||
|
|
||||||
|
; We're done, DO NOT DELETE THIS LINE
|
||||||
|
jmp end_of_test
|
||||||
|
@ -213,19 +213,19 @@ test_cond:
|
|||||||
ADDARN $AR0, $IX0
|
ADDARN $AR0, $IX0
|
||||||
|
|
||||||
LRI $IX0, #0x0100
|
LRI $IX0, #0x0100
|
||||||
CW 0x0278 ; IFx8
|
IFx8
|
||||||
ADDARN $AR0, $IX0
|
ADDARN $AR0, $IX0
|
||||||
|
|
||||||
LRI $IX0, #0x0200
|
LRI $IX0, #0x0200
|
||||||
CW 0x0279 ; IFx9
|
IFx9
|
||||||
ADDARN $AR0, $IX0
|
ADDARN $AR0, $IX0
|
||||||
|
|
||||||
LRI $IX0, #0x0400
|
LRI $IX0, #0x0400
|
||||||
CW 0x027A ; IFxA
|
IFxA
|
||||||
ADDARN $AR0, $IX0
|
ADDARN $AR0, $IX0
|
||||||
|
|
||||||
LRI $IX0, #0x0800
|
LRI $IX0, #0x0800
|
||||||
CW 0x027B ; IFxB
|
IFxB
|
||||||
ADDARN $AR0, $IX0
|
ADDARN $AR0, $IX0
|
||||||
|
|
||||||
LRI $IX0, #0x1000
|
LRI $IX0, #0x1000
|
||||||
|
@ -244,5 +244,5 @@ lri $AX1.L, #0x13
|
|||||||
nx'ldnm : $AX0.L, $AX1.L, @$AR0
|
nx'ldnm : $AX0.L, $AX1.L, @$AR0
|
||||||
call send_back ; 20
|
call send_back ; 20
|
||||||
|
|
||||||
|
; We're done, DO NOT DELETE THIS LINE
|
||||||
|
jmp end_of_test
|
||||||
|
@ -114,4 +114,5 @@ neg $ACC0
|
|||||||
set40
|
set40
|
||||||
call send_back ; 18
|
call send_back ; 18
|
||||||
|
|
||||||
|
; We're done, DO NOT DELETE THIS LINE
|
||||||
|
jmp end_of_test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user