DSP asm/disasm: Lots of cleanup, mostly. I may have broken the DSP debugger a bit. will fix it properly later..
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2968 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
0c65e2fe11
commit
d25d6b5f98
|
@ -23,50 +23,34 @@
|
||||||
#include "assemble.h"
|
#include "assemble.h"
|
||||||
#include "disassemble.h"
|
#include "disassemble.h"
|
||||||
|
|
||||||
DSPAssembler::DSPAssembler()
|
|
||||||
: include_dir(0),
|
|
||||||
current_param(0),
|
|
||||||
cur_addr(0),
|
|
||||||
labels_count(0),
|
|
||||||
cur_pass(0)
|
|
||||||
{
|
|
||||||
include_dir = 0;
|
|
||||||
current_param = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DSPAssembler::~DSPAssembler()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Assemble(const char *text, std::vector<u16> *code)
|
bool Assemble(const char *text, std::vector<u16> *code)
|
||||||
{
|
{
|
||||||
const char *fname = "tmp.asm";
|
const char *fname = "tmp.asm";
|
||||||
gd_globals_t gdg;
|
AssemblerSettings settings;
|
||||||
memset(&gdg, 0, sizeof(gdg));
|
memset(&settings, 0, sizeof(settings));
|
||||||
gdg.pc = 0;
|
settings.pc = 0;
|
||||||
// gdg.decode_registers = false;
|
// settings.decode_registers = false;
|
||||||
// gdg.decode_names = false;
|
// settings.decode_names = false;
|
||||||
gdg.print_tabs = false;
|
settings.print_tabs = false;
|
||||||
gdg.ext_separator = '\'';
|
settings.ext_separator = '\'';
|
||||||
gdg.buffer = 0;
|
settings.buffer = 0;
|
||||||
|
|
||||||
if (!File::WriteStringToFile(true, text, fname))
|
if (!File::WriteStringToFile(true, text, fname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: fix the terrible api of the assembler.
|
// TODO: fix the terrible api of the assembler.
|
||||||
DSPAssembler assembler;
|
DSPAssembler assembler(settings);
|
||||||
assembler.gd_ass_init_pass(1);
|
assembler.gd_ass_init_pass(1);
|
||||||
if (!assembler.gd_ass_file(&gdg, fname, 1))
|
if (!assembler.gd_ass_file(fname, 1))
|
||||||
return false;
|
return false;
|
||||||
assembler.gd_ass_init_pass(2);
|
assembler.gd_ass_init_pass(2);
|
||||||
if (!assembler.gd_ass_file(&gdg, fname, 2))
|
if (!assembler.gd_ass_file(fname, 2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
code->resize(gdg.buffer_size);
|
code->resize(assembler.gdg_buffer_size);
|
||||||
for (int i = 0; i < gdg.buffer_size; i++) {
|
for (int i = 0; i < assembler.gdg_buffer_size; i++) {
|
||||||
(*code)[i] = *(u16 *)(gdg.buffer + i * 2);
|
(*code)[i] = *(u16 *)(assembler.gdg_buffer + i * 2);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -86,18 +70,17 @@ bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string *t
|
||||||
FILE* t = fopen(tmp2, "w");
|
FILE* t = fopen(tmp2, "w");
|
||||||
if (t != NULL)
|
if (t != NULL)
|
||||||
{
|
{
|
||||||
gd_globals_t gdg;
|
AssemblerSettings settings;
|
||||||
memset(&gdg, 0, sizeof(gdg));
|
|
||||||
|
|
||||||
// These two prevent roundtripping.
|
// These two prevent roundtripping.
|
||||||
gdg.show_hex = false;
|
settings.show_hex = false;
|
||||||
gdg.show_pc = line_numbers;
|
settings.show_pc = line_numbers;
|
||||||
gdg.ext_separator = '\'';
|
settings.ext_separator = '\'';
|
||||||
gdg.decode_names = false;
|
settings.decode_names = false;
|
||||||
gdg.decode_registers = true;
|
settings.decode_registers = true;
|
||||||
|
|
||||||
DSPDisassembler disasm;
|
DSPDisassembler disasm(settings);
|
||||||
bool success = disasm.gd_dis_file(&gdg, tmp1, t);
|
bool success = disasm.gd_dis_file(tmp1, t);
|
||||||
fclose(t);
|
fclose(t);
|
||||||
|
|
||||||
File::ReadFileToString(true, tmp2, text);
|
File::ReadFileToString(true, tmp2, text);
|
||||||
|
|
|
@ -234,11 +234,11 @@ const DSPOPCTemplate opcodes[] =
|
||||||
|
|
||||||
|
|
||||||
{"INCM", 0x7400, 0xfeff, DSPInterpreter::incm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"INCM", 0x7400, 0xfeff, DSPInterpreter::incm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"INC", 0x7600, 0xfeff, DSPInterpreter::inc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"INC", 0x7600, 0xfeff, DSPInterpreter::inc, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"DECM", 0x7800, 0xfeff, DSPInterpreter::decm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"DECM", 0x7800, 0xfeff, DSPInterpreter::decm, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"DEC", 0x7a00, 0xfeff, DSPInterpreter::dec, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"DEC", 0x7a00, 0xfeff, DSPInterpreter::dec, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"NEG", 0x7c00, 0xfeff, DSPInterpreter::neg, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"NEG", 0x7c00, 0xfeff, DSPInterpreter::neg, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MOVNP", 0x7e00, 0xfeff, DSPInterpreter::movnp, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MOVNP", 0x7e00, 0xfeff, DSPInterpreter::movnp, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
|
||||||
|
|
||||||
{"TST", 0xb100, 0xf7ff, DSPInterpreter::tst, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"TST", 0xb100, 0xf7ff, DSPInterpreter::tst, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
@ -278,19 +278,19 @@ const DSPOPCTemplate opcodes[] =
|
||||||
{"ORC", 0x3E00, 0xfeff, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
|
{"ORC", 0x3E00, 0xfeff, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this
|
||||||
|
|
||||||
{"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULXAC", 0xa400, 0xe6ff, DSPInterpreter::mulxac, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULXAC", 0xa400, 0xe6ff, DSPInterpreter::mulxac, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULXMV", 0xa600, 0xe6ff, DSPInterpreter::mulxmv, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULXMV", 0xa600, 0xe6ff, DSPInterpreter::mulxmv, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
|
||||||
{"MUL", 0x9000, 0xf7ff, DSPInterpreter::mul, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MUL", 0x9000, 0xf7ff, DSPInterpreter::mul, nop, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULMVZ", 0x9200, 0xf6ff, DSPInterpreter::mulmvz, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULMVZ", 0x9200, 0xf6ff, DSPInterpreter::mulmvz, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULAC", 0x9400, 0xf6ff, DSPInterpreter::mulac, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULAC", 0x9400, 0xf6ff, DSPInterpreter::mulac, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULMV", 0x9600, 0xf6ff, DSPInterpreter::mulmv, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULMV", 0x9600, 0xf6ff, DSPInterpreter::mulmv, nop, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
|
||||||
{"MULC", 0xc000, 0xe7ff, DSPInterpreter::mulc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULC", 0xc000, 0xe7ff, DSPInterpreter::mulc, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULCMVZ", 0xc200, 0xe6ff, DSPInterpreter::mulcmvz, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULCMVZ", 0xc200, 0xe6ff, DSPInterpreter::mulcmvz, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULCAC", 0xc400, 0xe6ff, DSPInterpreter::mulcac, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULCAC", 0xc400, 0xe6ff, DSPInterpreter::mulcac, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"MULCMV", 0xc600, 0xe6ff, DSPInterpreter::mulcmv, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"MULCMV", 0xc600, 0xe6ff, DSPInterpreter::mulcmv, nop, 1 | P_EXT, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
|
||||||
{"ADDR", 0x4000, 0xf8ff, DSPInterpreter::addr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"ADDR", 0x4000, 0xf8ff, DSPInterpreter::addr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
{"ADDAX", 0x4800, 0xfcff, DSPInterpreter::addax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
{"ADDAX", 0x4800, 0xfcff, DSPInterpreter::addax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
|
||||||
|
@ -316,7 +316,6 @@ const DSPOPCTemplate cw =
|
||||||
|
|
||||||
const DSPOPCTemplate opcodes_ext[] =
|
const DSPOPCTemplate opcodes_ext[] =
|
||||||
{
|
{
|
||||||
|
|
||||||
// FIXME: guessing this is cr need checking
|
// FIXME: guessing this is cr need checking
|
||||||
{"CR", 0x0000, 0x00fc, DSPInterpreter::Ext::cr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
{"CR", 0x0000, 0x00fc, DSPInterpreter::Ext::cr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
||||||
{"DR", 0x0004, 0x00fc, DSPInterpreter::Ext::dr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
{"DR", 0x0004, 0x00fc, DSPInterpreter::Ext::dr, nop, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, NULL, NULL,},
|
||||||
|
@ -410,10 +409,10 @@ const pdlabel_t regnames[] =
|
||||||
{0x01, "AR1", "Addr Reg 01",},
|
{0x01, "AR1", "Addr Reg 01",},
|
||||||
{0x02, "AR2", "Addr Reg 02",},
|
{0x02, "AR2", "Addr Reg 02",},
|
||||||
{0x03, "AR3", "Addr Reg 03",},
|
{0x03, "AR3", "Addr Reg 03",},
|
||||||
{0x04, "IX0", "Index Reg 1(04)",},
|
{0x04, "IX0", "Index Reg 0(04)",},
|
||||||
{0x05, "IX1", "Index Reg 2(05)",},
|
{0x05, "IX1", "Index Reg 1(05)",},
|
||||||
{0x06, "IX2", "Index Reg 3(06)",},
|
{0x06, "IX2", "Index Reg 2(06)",},
|
||||||
{0x07, "IX3", "Indec Reg 4(07)",},
|
{0x07, "IX3", "Indec Reg 3(07)",},
|
||||||
{0x08, "R08", "Register 08",},
|
{0x08, "R08", "Register 08",},
|
||||||
{0x09, "R09", "Register 09",},
|
{0x09, "R09", "Register 09",},
|
||||||
{0x0a, "R10", "Register 10",},
|
{0x0a, "R10", "Register 10",},
|
||||||
|
@ -422,7 +421,7 @@ const pdlabel_t regnames[] =
|
||||||
{0x0d, "ST1", "Data stack",},
|
{0x0d, "ST1", "Data stack",},
|
||||||
{0x0e, "ST2", "Loop addr stack",},
|
{0x0e, "ST2", "Loop addr stack",},
|
||||||
{0x0f, "ST3", "Loop counter",},
|
{0x0f, "ST3", "Loop counter",},
|
||||||
{0x00, "AC0.H", "Accu High 0",},
|
{0x10, "AC0.H", "Accu High 0",},
|
||||||
{0x11, "AC1.H", "Accu High 1",},
|
{0x11, "AC1.H", "Accu High 1",},
|
||||||
{0x12, "CR", "Config Register",},
|
{0x12, "CR", "Config Register",},
|
||||||
{0x13, "SR", "Special Register",},
|
{0x13, "SR", "Special Register",},
|
||||||
|
@ -439,7 +438,7 @@ const pdlabel_t regnames[] =
|
||||||
{0x1e, "AC0.M", "Accu Mid 0",},
|
{0x1e, "AC0.M", "Accu Mid 0",},
|
||||||
{0x1f, "AC1.M", "Accu Mid 1",},
|
{0x1f, "AC1.M", "Accu Mid 1",},
|
||||||
|
|
||||||
// To resolve special names.
|
// To resolve combined register names.
|
||||||
{0x20, "ACC0", "Accu Full 0",},
|
{0x20, "ACC0", "Accu Full 0",},
|
||||||
{0x21, "ACC1", "Accu Full 1",},
|
{0x21, "ACC1", "Accu Full 1",},
|
||||||
{0x22, "AX0", "Extra Accu 0",},
|
{0x22, "AX0", "Extra Accu 0",},
|
||||||
|
@ -451,7 +450,6 @@ dspInstFunc opTable[OPTABLE_SIZE];
|
||||||
dspInstFunc prologueTable[OPTABLE_SIZE];
|
dspInstFunc prologueTable[OPTABLE_SIZE];
|
||||||
dspInstFunc epilogueTable[OPTABLE_SIZE];
|
dspInstFunc epilogueTable[OPTABLE_SIZE];
|
||||||
|
|
||||||
|
|
||||||
const char* pdname(u16 val)
|
const char* pdname(u16 val)
|
||||||
{
|
{
|
||||||
static char tmpstr[12]; // nasty
|
static char tmpstr[12]; // nasty
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
|
|
||||||
// The ones that end with _D are the opposite one - if the bit specify
|
// The ones that end with _D are the opposite one - if the bit specify
|
||||||
// ACC0, then ACC_D will be ACC1.
|
// ACC0, then ACC_D will be ACC1.
|
||||||
|
|
||||||
|
// The values of these are very important.
|
||||||
|
// For the reg ones, the value >> 8 is the base register.
|
||||||
|
// & 0x80 means it's a "D".
|
||||||
|
|
||||||
enum partype_t
|
enum partype_t
|
||||||
{
|
{
|
||||||
P_NONE = 0x0000,
|
P_NONE = 0x0000,
|
||||||
|
@ -37,15 +42,15 @@ enum partype_t
|
||||||
P_REGM18 = P_REG | 0x1810, // used in multiply instructions
|
P_REGM18 = P_REG | 0x1810, // used in multiply instructions
|
||||||
P_REG19 = P_REG | 0x1900,
|
P_REG19 = P_REG | 0x1900,
|
||||||
P_REGM19 = P_REG | 0x1910, // used in multiply instructions
|
P_REGM19 = P_REG | 0x1910, // used in multiply instructions
|
||||||
P_REG1A = P_REG | 0x1a00,
|
P_REG1A = P_REG | 0x1a80,
|
||||||
P_REG1C = P_REG | 0x1c00,
|
P_REG1C = P_REG | 0x1c00,
|
||||||
// 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_ACC_D = P_REG | 0x1c80,
|
P_ACC_D = P_REG | 0x1c80,
|
||||||
P_ACCL = P_REG | 0x1c00, // used for mid accum
|
P_ACCL = P_REG | 0x1c00, // used for low part of accum
|
||||||
P_ACCM = P_REG | 0x1e00, // used for mid accum
|
P_ACCM = P_REG | 0x1e00, // 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 | 0x1e80,
|
||||||
P_ACC = P_REG | 0x2000, // used for global accum.
|
P_ACC = P_REG | 0x2000, // used for full accum.
|
||||||
P_AX = P_REG | 0x2200,
|
P_AX = P_REG | 0x2200,
|
||||||
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,
|
||||||
|
|
|
@ -76,14 +76,30 @@ static const char *err_string[] =
|
||||||
"Number out of range"
|
"Number out of range"
|
||||||
};
|
};
|
||||||
|
|
||||||
void DSPAssembler::parse_error(err_t err_code, fass_t *fa, const char *extra_info)
|
DSPAssembler::DSPAssembler(const AssemblerSettings &settings)
|
||||||
|
: current_param(0),
|
||||||
|
cur_addr(0),
|
||||||
|
cur_pass(0),
|
||||||
|
settings_(settings)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%i : %s\n", fa->code_line, cur_line);
|
gdg_buffer = NULL;
|
||||||
fa->failed = true;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DSPAssembler::~DSPAssembler()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPAssembler::parse_error(err_t err_code, const char *extra_info)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%i : %s\n", code_line, cur_line);
|
||||||
|
failed = true;
|
||||||
if (!extra_info)
|
if (!extra_info)
|
||||||
extra_info = "-";
|
extra_info = "-";
|
||||||
if (fa->fsrc)
|
if (fsrc)
|
||||||
fclose(fa->fsrc);
|
fclose(fsrc);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: %s : %s\n", err_string[err_code], extra_info);
|
fprintf(stderr, "ERROR: %s : %s\n", err_string[err_code], extra_info);
|
||||||
|
@ -92,10 +108,10 @@ void DSPAssembler::parse_error(err_t err_code, fass_t *fa, const char *extra_inf
|
||||||
// modified by Hermes
|
// modified by Hermes
|
||||||
|
|
||||||
if (current_param == 0)
|
if (current_param == 0)
|
||||||
fprintf(stderr, "ERROR: %s Line: %d : %s\n", err_string[err_code], fa->code_line, extra_info);
|
fprintf(stderr, "ERROR: %s Line: %d : %s\n", err_string[err_code], code_line, extra_info);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "ERROR: %s Line: %d Param: %d : %s\n",
|
fprintf(stderr, "ERROR: %s Line: %d Param: %d : %s\n",
|
||||||
err_string[err_code], fa->code_line, current_param, extra_info);
|
err_string[err_code], code_line, current_param, extra_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *skip_spaces(char *ptr)
|
char *skip_spaces(char *ptr)
|
||||||
|
@ -114,19 +130,12 @@ const char *skip_spaces(const char *ptr)
|
||||||
|
|
||||||
void DSPAssembler::gd_ass_register_label(const char *label, u16 lval)
|
void DSPAssembler::gd_ass_register_label(const char *label, u16 lval)
|
||||||
{
|
{
|
||||||
labels[labels_count].label = (char *)malloc(strlen(label) + 1);
|
labels.push_back(label_t(label, lval));
|
||||||
strcpy(labels[labels_count].label, label);
|
|
||||||
labels[labels_count].addr = lval;
|
|
||||||
labels_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPAssembler::gd_ass_clear_labels()
|
void DSPAssembler::gd_ass_clear_labels()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < labels_count; i++)
|
labels.clear();
|
||||||
{
|
|
||||||
free(labels[i].label);
|
|
||||||
}
|
|
||||||
labels_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a standalone value - it can be a number in one of several formats or a label.
|
// Parse a standalone value - it can be a number in one of several formats or a label.
|
||||||
|
@ -156,7 +165,7 @@ s32 DSPAssembler::strtoval(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
|
||||||
parse_error(ERR_INCORRECT_DEC, cur_fa, str);
|
parse_error(ERR_INCORRECT_DEC, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -172,9 +181,9 @@ s32 DSPAssembler::strtoval(const char *str)
|
||||||
else if (ptr[i] >= 'A' && ptr[i] <= 'F')
|
else if (ptr[i] >= 'A' && ptr[i] <= 'F')
|
||||||
val += (ptr[i]-'A'+10);
|
val += (ptr[i]-'A'+10);
|
||||||
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
|
||||||
parse_error(ERR_INCORRECT_HEX, cur_fa, str);
|
parse_error(ERR_INCORRECT_HEX, str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\'': // binary
|
case '\'': // binary
|
||||||
|
@ -184,7 +193,7 @@ s32 DSPAssembler::strtoval(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
|
||||||
parse_error(ERR_INCORRECT_BIN, cur_fa, str);
|
parse_error(ERR_INCORRECT_BIN, str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -205,19 +214,19 @@ s32 DSPAssembler::strtoval(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
|
||||||
parse_error(ERR_INCORRECT_DEC, cur_fa, str);
|
parse_error(ERR_INCORRECT_DEC, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Everything else is a label.
|
else // Everything else is a label.
|
||||||
{
|
{
|
||||||
// Lookup label
|
// Lookup label
|
||||||
for (int i = 0; i < labels_count; i++)
|
for (int i = 0; i < labels.size(); i++)
|
||||||
{
|
{
|
||||||
if (strcmp(labels[i].label, ptr) == 0)
|
if (strcmp(labels[i].label.c_str(), ptr) == 0)
|
||||||
return labels[i].addr;
|
return labels[i].addr;
|
||||||
}
|
}
|
||||||
if (cur_pass == 2)
|
if (cur_pass == 2)
|
||||||
parse_error(ERR_UNKNOWN_LABEL, cur_fa, str);
|
parse_error(ERR_UNKNOWN_LABEL, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (negative)
|
if (negative)
|
||||||
|
@ -270,7 +279,7 @@ char *DSPAssembler::find_brackets(char *src, char *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count)
|
if (count)
|
||||||
parse_error(ERR_NO_MATCHING_BRACKETS, cur_fa);
|
parse_error(ERR_NO_MATCHING_BRACKETS);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,8 +342,7 @@ u32 DSPAssembler::parse_exp(const char *ptr)
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
{
|
{
|
||||||
val = 0x10000 + (val & 0xffff); // ATTENTION: avoid a terrible bug!!! number cannot write with '-' in sprintf
|
val = 0x10000 + (val & 0xffff); // ATTENTION: avoid a terrible bug!!! number cannot write with '-' in sprintf
|
||||||
if(cur_fa)
|
fprintf(stderr, "WARNING: Number Underflow at Line: %d \n", code_line);
|
||||||
fprintf(stderr, "WARNING: Number Underflow at Line: %d \n", cur_fa->code_line);
|
|
||||||
}
|
}
|
||||||
sprintf(d_buffer, "%d", val);
|
sprintf(d_buffer, "%d", val);
|
||||||
}
|
}
|
||||||
|
@ -373,14 +381,13 @@ u32 DSPAssembler::parse_exp(const char *ptr)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 DSPAssembler::parse_exp_f(const char *ptr, fass_t *fa)
|
u32 DSPAssembler::parse_exp_f(const char *ptr)
|
||||||
{
|
{
|
||||||
cur_fa = fa;
|
|
||||||
return parse_exp(ptr);
|
return parse_exp(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroys parstr
|
// Destroys parstr
|
||||||
u32 DSPAssembler::get_params(char *parstr, param_t *par, fass_t *fa)
|
u32 DSPAssembler::get_params(char *parstr, param_t *par)
|
||||||
{
|
{
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
char *tmpstr = skip_spaces(parstr);
|
char *tmpstr = skip_spaces(parstr);
|
||||||
|
@ -405,27 +412,27 @@ u32 DSPAssembler::get_params(char *parstr, param_t *par, fass_t *fa)
|
||||||
par[i].type = P_STR;
|
par[i].type = P_STR;
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
par[i].val = parse_exp_f(tmpstr + 1, fa);
|
par[i].val = parse_exp_f(tmpstr + 1);
|
||||||
par[i].type = P_IMM;
|
par[i].type = P_IMM;
|
||||||
break;
|
break;
|
||||||
case '@':
|
case '@':
|
||||||
if (tmpstr[1] == '$')
|
if (tmpstr[1] == '$')
|
||||||
{
|
{
|
||||||
par[i].val = parse_exp_f(tmpstr + 2, fa);
|
par[i].val = parse_exp_f(tmpstr + 2);
|
||||||
par[i].type = P_PRG;
|
par[i].type = P_PRG;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
par[i].val = parse_exp_f(tmpstr + 1, fa);
|
par[i].val = parse_exp_f(tmpstr + 1);
|
||||||
par[i].type = P_MEM;
|
par[i].type = P_MEM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
par[i].val = parse_exp_f(tmpstr + 1, fa);
|
par[i].val = parse_exp_f(tmpstr + 1);
|
||||||
par[i].type = P_REG;
|
par[i].type = P_REG;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
par[i].val = parse_exp_f(tmpstr, fa);
|
par[i].val = parse_exp_f(tmpstr);
|
||||||
par[i].type = P_VAL;
|
par[i].type = P_VAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -434,7 +441,7 @@ u32 DSPAssembler::get_params(char *parstr, param_t *par, fass_t *fa)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
const opc_t *DSPAssembler::find_opcode(const char *opcode, u32 par_count, const opc_t * const opcod, u32 opcod_size, DSPAssembler::fass_t *fa)
|
const opc_t *DSPAssembler::find_opcode(const char *opcode, u32 par_count, const opc_t * const opcod, int opcod_size)
|
||||||
{
|
{
|
||||||
if (opcode[0] == 'C' && opcode[1] == 'W')
|
if (opcode[0] == 'C' && opcode[1] == 'W')
|
||||||
return &cw;
|
return &cw;
|
||||||
|
@ -449,16 +456,16 @@ const opc_t *DSPAssembler::find_opcode(const char *opcode, u32 par_count, const
|
||||||
{
|
{
|
||||||
if (par_count < opc->param_count)
|
if (par_count < opc->param_count)
|
||||||
{
|
{
|
||||||
parse_error(ERR_NOT_ENOUGH_PARAMETERS, fa);
|
parse_error(ERR_NOT_ENOUGH_PARAMETERS);
|
||||||
}
|
}
|
||||||
if (par_count > opc->param_count)
|
if (par_count > opc->param_count)
|
||||||
{
|
{
|
||||||
parse_error(ERR_TOO_MANY_PARAMETERS, fa);
|
parse_error(ERR_TOO_MANY_PARAMETERS);
|
||||||
}
|
}
|
||||||
return opc;
|
return opc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parse_error(ERR_UNKNOWN_OPCODE, fa);
|
parse_error(ERR_UNKNOWN_OPCODE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,81 +477,93 @@ u16 get_mask_shifted_down(u16 mask)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, u32 count, fass_t *fa)
|
bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, int count, bool ext)
|
||||||
{
|
{
|
||||||
int value;
|
for (int i = 0; i < count; i++)
|
||||||
unsigned int valueu;
|
|
||||||
for (u32 i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
current_param = i+1;
|
const int current_param = i + 1; // just for display.
|
||||||
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 ((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 ((unsigned)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:
|
|
||||||
value = (opc->params[i].type >> 8) & 31;
|
value = (opc->params[i].type >> 8) & 31;
|
||||||
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))
|
||||||
{
|
{
|
||||||
parse_error(ERR_INVALID_REGISTER, fa);
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
|
fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
|
||||||
|
parse_error(ERR_INVALID_REGISTER);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_PRG:
|
case P_PRG:
|
||||||
if ((int)par[i].val < 0 || (int)par[i].val > 0x3)
|
if ((int)par[i].val < 0 || (int)par[i].val > 0x3)
|
||||||
{
|
{
|
||||||
parse_error(ERR_INVALID_REGISTER, fa);
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
|
fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
|
||||||
|
parse_error(ERR_INVALID_REGISTER);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_ACC:
|
case P_ACC:
|
||||||
if ((int)par[i].val < 0x20 || (int)par[i].val > 0x21)
|
if ((int)par[i].val < 0x20 || (int)par[i].val > 0x21)
|
||||||
{
|
{
|
||||||
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
||||||
fprintf(stderr, "WARNING: $ACM%d register used instead $ACC%d register Line: %d Param: %d\n",
|
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACC%d register Line: %d Param: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), fa->code_line, current_param);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param, ext);
|
||||||
else if (par[i].val >= 0x1c && par[i].val <= 0x1d)
|
else if (par[i].val >= 0x1c && par[i].val <= 0x1d)
|
||||||
fprintf(stderr, "WARNING: $ACL%d register used instead $ACC%d register Line: %d Param: %d\n",
|
fprintf(stderr, "WARNING: $ACL%d register used instead of $ACC%d register Line: %d Param: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), fa->code_line, current_param);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
else
|
else
|
||||||
parse_error(ERR_WRONG_PARAMETER_ACC, fa);
|
parse_error(ERR_WRONG_PARAMETER_ACC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_ACCM:
|
case P_ACCM:
|
||||||
if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
|
if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
|
||||||
{
|
{
|
||||||
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
if (par[i].val >= 0x1c && par[i].val <= 0x1d)
|
if (par[i].val >= 0x1c && par[i].val <= 0x1d)
|
||||||
fprintf(stderr, "WARNING: $ACL%d register used instead $ACM%d register Line: %d Param: %d\n",
|
fprintf(stderr, "WARNING: $ACL%d register used instead of $ACM%d register Line: %d Param: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), fa->code_line, current_param);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
|
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
|
||||||
fprintf(stderr, "WARNING: $ACC%d register used instead $ACM%d register Line: %d Param: %d\n",
|
fprintf(stderr, "WARNING: $ACC%d register used instead of $ACM%d register Line: %d Param: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), fa->code_line, current_param);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
else
|
else
|
||||||
parse_error(ERR_WRONG_PARAMETER_ACC, fa);
|
parse_error(ERR_WRONG_PARAMETER_ACC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_ACCL:
|
case P_ACCL:
|
||||||
if ((int)par[i].val < 0x1c || (int)par[i].val > 0x1d)
|
if ((int)par[i].val < 0x1c || (int)par[i].val > 0x1d)
|
||||||
{
|
{
|
||||||
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
||||||
fprintf(stderr, "WARNING: $ACM%d register used instead $ACL%d register Line: %d Param: %d\n",
|
{
|
||||||
(par[i].val & 1), (par[i].val & 1), fa->code_line, current_param);
|
fprintf(stderr, "%s", cur_line.c_str());
|
||||||
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
|
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %d\n",
|
||||||
fprintf(stderr, "WARNING: $ACC%d register used instead $ACL%d register Line: %d Param: %d\n",
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
(par[i].val & 1), (par[i].val & 1), fa->code_line, current_param);
|
}
|
||||||
|
else if (par[i].val >= 0x20 && par[i].val <= 0x21) {
|
||||||
|
fprintf(stderr, "%s", cur_line.c_str());
|
||||||
|
fprintf(stderr, "WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %d\n",
|
||||||
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
parse_error(ERR_WRONG_PARAMETER_ACC, fa);
|
parse_error(ERR_WRONG_PARAMETER_ACC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* case P_ACCM_D: //P_ACC_MID:
|
/* case P_ACCM_D: //P_ACC_MID:
|
||||||
if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
|
if ((int)par[i].val < 0x1e || (int)par[i].val > 0x1f)
|
||||||
{
|
{
|
||||||
parse_error(ERR_WRONG_PARAMETER_MID_ACC, fa);
|
parse_error(ERR_WRONG_PARAMETER_MID_ACC);
|
||||||
}
|
}
|
||||||
break;*/
|
break;*/
|
||||||
}
|
}
|
||||||
|
@ -554,42 +573,45 @@ bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, u32 count, fass
|
||||||
switch (par[i].type & (P_REG | P_VAL | P_MEM | P_IMM))
|
switch (par[i].type & (P_REG | P_VAL | P_MEM | P_IMM))
|
||||||
{
|
{
|
||||||
case P_REG:
|
case P_REG:
|
||||||
parse_error(ERR_EXPECTED_PARAM_REG, fa);
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
|
parse_error(ERR_EXPECTED_PARAM_REG);
|
||||||
break;
|
break;
|
||||||
case P_MEM:
|
case P_MEM:
|
||||||
parse_error(ERR_EXPECTED_PARAM_MEM, fa);
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
|
parse_error(ERR_EXPECTED_PARAM_MEM);
|
||||||
break;
|
break;
|
||||||
case P_VAL:
|
case P_VAL:
|
||||||
parse_error(ERR_EXPECTED_PARAM_VAL, fa);
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
|
parse_error(ERR_EXPECTED_PARAM_VAL);
|
||||||
break;
|
break;
|
||||||
case P_IMM:
|
case P_IMM:
|
||||||
parse_error(ERR_EXPECTED_PARAM_IMM, fa);
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
|
parse_error(ERR_EXPECTED_PARAM_IMM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parse_error(ERR_WRONG_PARAMETER, fa);
|
parse_error(ERR_WRONG_PARAMETER);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((opc->params[i].type & 3) != 0 && (par[i].type & 3) != 0)
|
else if ((opc->params[i].type & 3) != 0 && (par[i].type & 3) != 0)
|
||||||
{
|
{
|
||||||
// modified by Hermes: test NUMBER range
|
// modified by Hermes: test NUMBER range
|
||||||
value = get_mask_shifted_down(opc->params[i].mask);
|
int value = get_mask_shifted_down(opc->params[i].mask);
|
||||||
|
unsigned int valueu = 0xffff & ~(value >> 1);
|
||||||
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 por sbclr/sbset
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Value must be from 0x0 to 0x%x\n", value);
|
fprintf(stderr,"Value must be from 0x0 to 0x%x\n", value);
|
||||||
parse_error(ERR_OUT_RANGE_NUMBER, fa);
|
parse_error(ERR_OUT_RANGE_NUMBER);
|
||||||
}
|
}
|
||||||
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));
|
fprintf(stderr, "Address value must be from 0x%x to 0x%x\n",valueu, (value>>1));
|
||||||
else
|
else
|
||||||
fprintf(stderr,"Address value must be from 0x0 to 0x%x\n", value);
|
fprintf(stderr, "Address value must be from 0x0 to 0x%x\n", value);
|
||||||
|
|
||||||
parse_error(ERR_OUT_RANGE_NUMBER, fa);
|
parse_error(ERR_OUT_RANGE_NUMBER);
|
||||||
}
|
}
|
||||||
else if ((int)par[i].val < -((value >> 1) + 1))
|
else if ((int)par[i].val < -((value >> 1) + 1))
|
||||||
{
|
{
|
||||||
|
@ -600,7 +622,7 @@ bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, u32 count, fass
|
||||||
fprintf(stderr, "Value must be from -0x%x to 0x%x or 0x0 to 0x%x, is %i\n",
|
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);
|
(value >> 1) + 1, value >> 1, value, par[i].val);
|
||||||
|
|
||||||
parse_error(ERR_OUT_RANGE_NUMBER, fa);
|
parse_error(ERR_OUT_RANGE_NUMBER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -610,7 +632,7 @@ bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, u32 count, fass
|
||||||
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);
|
fprintf(stderr,"Value must be from 0x%x to 0x%x, is %i\n",valueu, value, par[i].val);
|
||||||
parse_error(ERR_OUT_RANGE_NUMBER, fa);
|
parse_error(ERR_OUT_RANGE_NUMBER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (opc->params[i].type == P_MEM)
|
else if (opc->params[i].type == P_MEM)
|
||||||
|
@ -624,7 +646,7 @@ bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, u32 count, fass
|
||||||
fprintf(stderr,"Address value must be from 0x%x to 0x%x, is %04x\n", valueu, value, par[i].val);
|
fprintf(stderr,"Address value must be from 0x%x to 0x%x, is %04x\n", valueu, value, par[i].val);
|
||||||
else
|
else
|
||||||
fprintf(stderr,"Address value must be minor of 0x%x\n", value+1);
|
fprintf(stderr,"Address value must be minor of 0x%x\n", value+1);
|
||||||
parse_error(ERR_OUT_RANGE_NUMBER, fa);
|
parse_error(ERR_OUT_RANGE_NUMBER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -637,7 +659,7 @@ bool DSPAssembler::verify_params(const opc_t *opc, param_t *par, u32 count, fass
|
||||||
fprintf(stderr,"Value must be from -0x%x to 0x%x, is %i\n", (value + 1), value, par[i].val);
|
fprintf(stderr,"Value must be from -0x%x to 0x%x, is %i\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);
|
fprintf(stderr,"Value must be minor of 0x%x, is %i\n", value + 1, par[i].val);
|
||||||
parse_error(ERR_OUT_RANGE_NUMBER, fa);
|
parse_error(ERR_OUT_RANGE_NUMBER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,6 +694,7 @@ void DSPAssembler::build_code(const opc_t *opc, param_t *par, u32 par_count, u16
|
||||||
|
|
||||||
void DSPAssembler::gd_ass_init_pass(int pass)
|
void DSPAssembler::gd_ass_init_pass(int pass)
|
||||||
{
|
{
|
||||||
|
failed = false;
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
// Reset label table. Pre-populate with hw addresses and registers.
|
// Reset label table. Pre-populate with hw addresses and registers.
|
||||||
|
@ -680,7 +703,7 @@ void DSPAssembler::gd_ass_init_pass(int pass)
|
||||||
{
|
{
|
||||||
gd_ass_register_label(regnames[i].name, regnames[i].addr);
|
gd_ass_register_label(regnames[i].name, regnames[i].addr);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < pdlabels_size; i++)
|
for (int i = 0; i < (int)pdlabels_size; i++)
|
||||||
{
|
{
|
||||||
gd_ass_register_label(pdlabels[i].name, pdlabels[i].addr);
|
gd_ass_register_label(pdlabels[i].name, pdlabels[i].addr);
|
||||||
}
|
}
|
||||||
|
@ -696,40 +719,37 @@ void DSPAssembler::gd_ass_init_pass(int pass)
|
||||||
segment_addr[SEGMENT_OVERLAY] = 0;
|
segment_addr[SEGMENT_OVERLAY] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
bool DSPAssembler::gd_ass_file(const char *fname, int pass)
|
||||||
{
|
{
|
||||||
fass_t fa;
|
|
||||||
int disable_text = 0; // modified by Hermes
|
int disable_text = 0; // modified by Hermes
|
||||||
|
|
||||||
param_t params[10] = {0};
|
fsrc = fopen(fname, "r");
|
||||||
param_t params_ext[10] = {0};
|
if (fsrc == NULL)
|
||||||
u32 params_count = 0;
|
|
||||||
u32 params_count_ext = 0;
|
|
||||||
|
|
||||||
fa.failed = false;
|
|
||||||
fa.fsrc = fopen(fname, "r");
|
|
||||||
if (fa.fsrc == NULL)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot open %s file\n", fname);
|
fprintf(stderr, "Cannot open %s file\n", fname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(fa.fsrc, 0, SEEK_SET);
|
fseek(fsrc, 0, SEEK_SET);
|
||||||
|
|
||||||
printf("Pass %d\n", pass);
|
printf("Pass %d\n", pass);
|
||||||
fa.code_line = 0;
|
code_line = 0;
|
||||||
cur_pass = pass;
|
cur_pass = pass;
|
||||||
|
|
||||||
#define LINEBUF_SIZE 4096
|
#define LINEBUF_SIZE 1024
|
||||||
char linebuffer[LINEBUF_SIZE];
|
char linebuffer[LINEBUF_SIZE];
|
||||||
while (!feof(fa.fsrc) && !fa.failed)
|
while (!feof(fsrc) && !failed)
|
||||||
{
|
{
|
||||||
int opcode_size = 0;
|
int opcode_size = 0;
|
||||||
memset(linebuffer, 0, LINEBUF_SIZE);
|
memset(linebuffer, 0, LINEBUF_SIZE);
|
||||||
if (!fgets(linebuffer, LINEBUF_SIZE, fa.fsrc))
|
if (!fgets(linebuffer, LINEBUF_SIZE, fsrc))
|
||||||
break;
|
break;
|
||||||
strcpy(cur_line, linebuffer);
|
cur_line = linebuffer;
|
||||||
//printf("A: %s", linebuffer);
|
//printf("A: %s", linebuffer);
|
||||||
fa.code_line++;
|
code_line++;
|
||||||
|
|
||||||
|
param_t params[10] = {0};
|
||||||
|
param_t params_ext[10] = {0};
|
||||||
|
|
||||||
for (int i = 0; i < LINEBUF_SIZE; i++)
|
for (int i = 0; i < LINEBUF_SIZE; i++)
|
||||||
{
|
{
|
||||||
|
@ -744,7 +764,7 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
c = 0x00;
|
c = 0x00;
|
||||||
else if (linebuffer[i+1] == '*')
|
else if (linebuffer[i+1] == '*')
|
||||||
{
|
{
|
||||||
// wtf is this?
|
// toggle comment mode.
|
||||||
disable_text = !disable_text;
|
disable_text = !disable_text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -759,8 +779,8 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// turn text into spaces if disable_text is on (in a comment).
|
||||||
if(disable_text && ((unsigned char )c)>32) c=32;
|
if (disable_text && ((unsigned char)c) > 32) c = 32;
|
||||||
|
|
||||||
if (c == 0x0a || c == 0x0d || c == ';')
|
if (c == 0x0a || c == 0x0d || c == ';')
|
||||||
c = 0x00;
|
c = 0x00;
|
||||||
|
@ -802,9 +822,8 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
opcode = strtok(ptr, " ");
|
opcode = strtok(ptr, " ");
|
||||||
char *opcode_ext = NULL;
|
char *opcode_ext = NULL;
|
||||||
|
|
||||||
char *paramstr;
|
u32 params_count = 0;
|
||||||
char *paramstr_ext;
|
u32 params_count_ext = 0;
|
||||||
|
|
||||||
if (opcode)
|
if (opcode)
|
||||||
{
|
{
|
||||||
if ((opcode_ext = strstr(opcode, "'")) != NULL)
|
if ((opcode_ext = strstr(opcode, "'")) != NULL)
|
||||||
|
@ -819,11 +838,10 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
params_count = 0;
|
params_count = 0;
|
||||||
params_count_ext = 0;
|
params_count_ext = 0;
|
||||||
|
|
||||||
paramstr = paramstr_ext = 0;
|
char *paramstr = strtok(NULL, "\0");
|
||||||
|
char *paramstr_ext = 0;
|
||||||
// there is valid opcode so probably we have parameters
|
// there is valid opcode so probably we have parameters
|
||||||
|
|
||||||
paramstr = strtok(NULL, "\0");
|
|
||||||
|
|
||||||
if (paramstr)
|
if (paramstr)
|
||||||
{
|
{
|
||||||
if ((paramstr_ext = strstr(paramstr, ":")) != NULL)
|
if ((paramstr_ext = strstr(paramstr, ":")) != NULL)
|
||||||
|
@ -834,9 +852,9 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paramstr)
|
if (paramstr)
|
||||||
params_count = get_params(paramstr, params, &fa);
|
params_count = get_params(paramstr, params);
|
||||||
if (paramstr_ext)
|
if (paramstr_ext)
|
||||||
params_count_ext = get_params(paramstr_ext, params_ext, &fa);
|
params_count_ext = get_params(paramstr_ext, params_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label)
|
if (label)
|
||||||
|
@ -852,10 +870,8 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
|
||||||
gd_ass_register_label(label, lval);
|
gd_ass_register_label(label, lval);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (opcode == NULL)
|
if (opcode == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -866,34 +882,30 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
if (params[0].type == P_STR)
|
if (params[0].type == P_STR)
|
||||||
{
|
{
|
||||||
char *tmpstr;
|
char *tmpstr;
|
||||||
if (include_dir)
|
if (include_dir.size())
|
||||||
{
|
{
|
||||||
tmpstr = (char *)malloc(strlen(include_dir) + strlen(params[0].str) + 2);
|
tmpstr = (char *)malloc(include_dir.size() + strlen(params[0].str) + 2);
|
||||||
sprintf(tmpstr, "%s/%s", include_dir, params[0].str);
|
sprintf(tmpstr, "%s/%s", include_dir.c_str(), params[0].str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmpstr = (char *)malloc(strlen(params[0].str) + 1);
|
tmpstr = (char *)malloc(strlen(params[0].str) + 1);
|
||||||
strcpy(tmpstr, params[0].str);
|
strcpy(tmpstr, params[0].str);
|
||||||
}
|
}
|
||||||
gd_ass_file(gdg, tmpstr, pass);
|
gd_ass_file(tmpstr, pass);
|
||||||
free(tmpstr);
|
free(tmpstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
parse_error(ERR_EXPECTED_PARAM_STR, &fa);
|
parse_error(ERR_EXPECTED_PARAM_STR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("INCDIR", opcode) == 0)
|
if (strcmp("INCDIR", opcode) == 0)
|
||||||
{
|
{
|
||||||
if (params[0].type == P_STR)
|
if (params[0].type == P_STR)
|
||||||
{
|
include_dir = params[0].str;
|
||||||
if (include_dir) free(include_dir);
|
|
||||||
include_dir = (char *)malloc(strlen(params[0].str) + 1);
|
|
||||||
strcpy(include_dir, params[0].str);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
parse_error(ERR_EXPECTED_PARAM_STR, &fa);
|
parse_error(ERR_EXPECTED_PARAM_STR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,13 +914,13 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
if (params[0].type == P_VAL)
|
if (params[0].type == P_VAL)
|
||||||
cur_addr = params[0].val;
|
cur_addr = params[0].val;
|
||||||
else
|
else
|
||||||
parse_error(ERR_EXPECTED_PARAM_VAL, &fa);
|
parse_error(ERR_EXPECTED_PARAM_VAL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("SEGMENT", opcode) == 0)
|
if (strcmp("SEGMENT", opcode) == 0)
|
||||||
{
|
{
|
||||||
if(params[0].type == P_STR)
|
if (params[0].type == P_STR)
|
||||||
{
|
{
|
||||||
segment_addr[cur_segment] = cur_addr;
|
segment_addr[cur_segment] = cur_addr;
|
||||||
if (strcmp("DATA", params[0].str) == 0)
|
if (strcmp("DATA", params[0].str) == 0)
|
||||||
|
@ -918,17 +930,17 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
cur_addr = segment_addr[cur_segment];
|
cur_addr = segment_addr[cur_segment];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
parse_error(ERR_EXPECTED_PARAM_STR, &fa);
|
parse_error(ERR_EXPECTED_PARAM_STR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const opc_t *opc = find_opcode(opcode, params_count, opcodes, opcodes_size, &fa);
|
const opc_t *opc = find_opcode(opcode, params_count, opcodes, opcodes_size);
|
||||||
if (!opc)
|
if (!opc)
|
||||||
opc = &cw;
|
opc = &cw;
|
||||||
|
|
||||||
opcode_size = opc->size & ~P_EXT;
|
opcode_size = opc->size & ~P_EXT;
|
||||||
|
|
||||||
verify_params(opc, params, params_count, &fa);
|
verify_params(opc, params, params_count);
|
||||||
|
|
||||||
const opc_t *opc_ext = NULL;
|
const opc_t *opc_ext = NULL;
|
||||||
// Check for opcode extensions.
|
// Check for opcode extensions.
|
||||||
|
@ -936,37 +948,37 @@ bool DSPAssembler::gd_ass_file(gd_globals_t *gdg, const char *fname, int pass)
|
||||||
{
|
{
|
||||||
if (opcode_ext)
|
if (opcode_ext)
|
||||||
{
|
{
|
||||||
opc_ext = find_opcode(opcode_ext, params_count_ext, opcodes_ext, opcodes_ext_size, &fa);
|
opc_ext = find_opcode(opcode_ext, params_count_ext, opcodes_ext, opcodes_ext_size);
|
||||||
verify_params(opc_ext, params_ext, params_count_ext, &fa);
|
verify_params(opc_ext, params_ext, params_count_ext, true);
|
||||||
}
|
}
|
||||||
else if (params_count_ext)
|
else if (params_count_ext)
|
||||||
parse_error(ERR_EXT_PAR_NOT_EXT, &fa);
|
parse_error(ERR_EXT_PAR_NOT_EXT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (opcode_ext)
|
if (opcode_ext)
|
||||||
parse_error(ERR_EXT_CANT_EXTEND_OPCODE, &fa);
|
parse_error(ERR_EXT_CANT_EXTEND_OPCODE);
|
||||||
if (params_count_ext)
|
if (params_count_ext)
|
||||||
parse_error(ERR_EXT_PAR_NOT_EXT, &fa);
|
parse_error(ERR_EXT_PAR_NOT_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass == 2)
|
if (pass == 2)
|
||||||
{
|
{
|
||||||
// generate binary
|
// generate binary
|
||||||
((u16 *)gdg->buffer)[cur_addr] = 0x0000;
|
((u16 *)gdg_buffer)[cur_addr] = 0x0000;
|
||||||
build_code(opc, params, params_count, (u16 *)gdg->buffer);
|
build_code(opc, params, params_count, (u16 *)gdg_buffer);
|
||||||
if (opc_ext)
|
if (opc_ext)
|
||||||
build_code(opc_ext, params_ext, params_count_ext, (u16 *)gdg->buffer);
|
build_code(opc_ext, params_ext, params_count_ext, (u16 *)gdg_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_addr += opcode_size;
|
cur_addr += opcode_size;
|
||||||
};
|
};
|
||||||
if (gdg->buffer == NULL)
|
if (gdg_buffer == NULL)
|
||||||
{
|
{
|
||||||
gdg->buffer_size = cur_addr;
|
gdg_buffer_size = cur_addr;
|
||||||
gdg->buffer = (char *)malloc(gdg->buffer_size * sizeof(u16) + 4);
|
gdg_buffer = (char *)malloc(gdg_buffer_size * sizeof(u16) + 4);
|
||||||
memset(gdg->buffer, 0, gdg->buffer_size * sizeof(u16));
|
memset(gdg_buffer, 0, gdg_buffer_size * sizeof(u16));
|
||||||
}
|
}
|
||||||
fclose(fa.fsrc);
|
fclose(fsrc);
|
||||||
return !fa.failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,21 +64,15 @@ enum err_t
|
||||||
class DSPAssembler
|
class DSPAssembler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSPAssembler();
|
DSPAssembler(const AssemblerSettings &settings);
|
||||||
~DSPAssembler();
|
~DSPAssembler();
|
||||||
|
|
||||||
void Assemble(const char *text, std::vector<u16> *code);
|
void Assemble(const char *text, std::vector<u16> *code);
|
||||||
|
|
||||||
typedef struct fass_t
|
|
||||||
{
|
|
||||||
FILE *fsrc;
|
|
||||||
u32 code_line;
|
|
||||||
bool failed;
|
|
||||||
} fass_t;
|
|
||||||
|
|
||||||
struct label_t
|
struct label_t
|
||||||
{
|
{
|
||||||
char *label;
|
label_t(const char *lbl, s32 address) : label(lbl), addr(address) {}
|
||||||
|
std::string label;
|
||||||
s32 addr;
|
s32 addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,39 +91,42 @@ public:
|
||||||
SEGMENT_MAX
|
SEGMENT_MAX
|
||||||
};
|
};
|
||||||
void gd_ass_init_pass(int pass);
|
void gd_ass_init_pass(int pass);
|
||||||
bool gd_ass_file(gd_globals_t *gdg, const char *fname, int pass);
|
bool gd_ass_file(const char *fname, int pass);
|
||||||
|
|
||||||
|
char *gdg_buffer;
|
||||||
|
int gdg_buffer_size;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parse_error(err_t err_code, fass_t *fa, const char *extra_info = NULL);
|
void parse_error(err_t err_code, const char *extra_info = NULL);
|
||||||
void gd_ass_register_label(const char *label, u16 lval);
|
void gd_ass_register_label(const char *label, u16 lval);
|
||||||
void gd_ass_clear_labels();
|
void gd_ass_clear_labels();
|
||||||
s32 strtoval(const char *str);
|
s32 strtoval(const char *str);
|
||||||
char *find_brackets(char *src, char *dst);
|
char *find_brackets(char *src, char *dst);
|
||||||
u32 parse_exp(const char *ptr);
|
u32 parse_exp(const char *ptr);
|
||||||
u32 parse_exp_f(const char *ptr, fass_t *fa);
|
u32 parse_exp_f(const char *ptr);
|
||||||
u32 get_params(char *parstr, param_t *par, fass_t *fa);
|
u32 get_params(char *parstr, param_t *par);
|
||||||
const opc_t *find_opcode(const char *opcode, u32 par_count, const opc_t * const opcod, u32 opcod_size, fass_t *fa);
|
const opc_t *find_opcode(const char *opcode, u32 par_count, const opc_t * const opcod, int opcod_size);
|
||||||
bool verify_params(const opc_t *opc, param_t *par, u32 count, fass_t *fa);
|
bool verify_params(const opc_t *opc, param_t *par, int count, bool ext = false);
|
||||||
void build_code(const opc_t *opc, param_t *par, u32 par_count, u16 *outbuf);
|
void build_code(const opc_t *opc, param_t *par, u32 par_count, u16 *outbuf);
|
||||||
|
|
||||||
char *include_dir;
|
std::string include_dir;
|
||||||
|
std::vector<label_t> labels;
|
||||||
label_t labels[10000];
|
std::string cur_line;
|
||||||
int labels_count;
|
|
||||||
|
|
||||||
char cur_line[4096];
|
|
||||||
|
|
||||||
u32 cur_addr;
|
u32 cur_addr;
|
||||||
u8 cur_pass;
|
u8 cur_pass;
|
||||||
fass_t *cur_fa;
|
|
||||||
|
FILE *fsrc;
|
||||||
|
u32 code_line;
|
||||||
|
bool failed;
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> AliasMap;
|
typedef std::map<std::string, std::string> AliasMap;
|
||||||
AliasMap aliases;
|
AliasMap aliases;
|
||||||
|
|
||||||
segment_t cur_segment;
|
segment_t cur_segment;
|
||||||
u32 segment_addr[SEGMENT_MAX];
|
u32 segment_addr[SEGMENT_MAX];
|
||||||
|
|
||||||
int current_param;
|
int current_param;
|
||||||
|
const AssemblerSettings settings_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _DSP_ASSEMBLE_H
|
#endif // _DSP_ASSEMBLE_H
|
|
@ -34,25 +34,23 @@
|
||||||
#pragma warning(disable:4996)
|
#pragma warning(disable:4996)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u32 unk_opcodes[0x10000];
|
|
||||||
|
|
||||||
extern void nop(const UDSPInstruction& opc);
|
extern void nop(const UDSPInstruction& opc);
|
||||||
|
|
||||||
DSPDisassembler::DSPDisassembler()
|
DSPDisassembler::DSPDisassembler(const AssemblerSettings &settings)
|
||||||
|
: settings_(settings)
|
||||||
{
|
{
|
||||||
|
memset(unk_opcodes, 0, sizeof(unk_opcodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
char* DSPDisassembler::gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* opc,
|
char *DSPDisassembler::gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2, char *strbuf)
|
||||||
u16 op1, u16 op2, char* strbuf)
|
|
||||||
{
|
{
|
||||||
char* buf = strbuf;
|
char *buf = strbuf;
|
||||||
u32 val;
|
|
||||||
|
|
||||||
for (int j = 0; j < opc->param_count; j++)
|
for (int j = 0; j < opc->param_count; j++)
|
||||||
{
|
{
|
||||||
if (j > 0)
|
if (j > 0)
|
||||||
buf += sprintf(buf, ", ");
|
buf += sprintf(buf, ", ");
|
||||||
|
|
||||||
|
u32 val;
|
||||||
if (opc->params[j].loc >= 1)
|
if (opc->params[j].loc >= 1)
|
||||||
val = op2;
|
val = op2;
|
||||||
else
|
else
|
||||||
|
@ -83,21 +81,21 @@ char* DSPDisassembler::gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* op
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case P_REG:
|
case P_REG:
|
||||||
if (gdg->decode_registers)
|
if (settings_.decode_registers)
|
||||||
sprintf(buf, "$%s", pdregname(val));
|
sprintf(buf, "$%s", pdregname(val));
|
||||||
else
|
else
|
||||||
sprintf(buf, "$%d", val);
|
sprintf(buf, "$%d", val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_PRG:
|
case P_PRG:
|
||||||
if (gdg->decode_registers)
|
if (settings_.decode_registers)
|
||||||
sprintf(buf, "@$%s", pdregname(val));
|
sprintf(buf, "@$%s", pdregname(val));
|
||||||
else
|
else
|
||||||
sprintf(buf, "@$%d", val);
|
sprintf(buf, "@$%d", val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_VAL:
|
case P_VAL:
|
||||||
if (gdg->decode_names)
|
if (settings_.decode_names)
|
||||||
sprintf(buf, "%s", pdname(val));
|
sprintf(buf, "%s", pdname(val));
|
||||||
else
|
else
|
||||||
sprintf(buf, "0x%04x", val);
|
sprintf(buf, "0x%04x", val);
|
||||||
|
@ -119,7 +117,7 @@ char* DSPDisassembler::gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* op
|
||||||
if (opc->params[j].size != 2)
|
if (opc->params[j].size != 2)
|
||||||
val = (u16)(s8)val;
|
val = (u16)(s8)val;
|
||||||
|
|
||||||
if (gdg->decode_names)
|
if (settings_.decode_names)
|
||||||
sprintf(buf, "@%s", pdname(val));
|
sprintf(buf, "@%s", pdname(val));
|
||||||
else
|
else
|
||||||
sprintf(buf, "@0x%04x", val);
|
sprintf(buf, "@0x%04x", val);
|
||||||
|
@ -127,7 +125,6 @@ char* DSPDisassembler::gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* op
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(DSPLLE, "Unknown parameter type: %x", opc->params[j].type);
|
ERROR_LOG(DSPLLE, "Unknown parameter type: %x", opc->params[j].type);
|
||||||
// exit(-1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +134,7 @@ char* DSPDisassembler::gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* op
|
||||||
return strbuf;
|
return strbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
|
u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
|
||||||
{
|
{
|
||||||
const DSPOPCTemplate* opc = 0;
|
const DSPOPCTemplate* opc = 0;
|
||||||
|
@ -168,7 +166,6 @@ u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
|
||||||
if (!opc)
|
if (!opc)
|
||||||
{
|
{
|
||||||
ERROR_LOG(DSPLLE, "get_opcode_size ARGH");
|
ERROR_LOG(DSPLLE, "get_opcode_size ARGH");
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opc->size & P_EXT && op1 & 0x00ff)
|
if (opc->size & P_EXT && op1 & 0x00ff)
|
||||||
|
@ -197,28 +194,27 @@ u16 gd_dis_get_opcode_size(gd_globals_t* gdg)
|
||||||
|
|
||||||
return opc->size & ~P_EXT;
|
return opc->size & ~P_EXT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
void DSPDisassembler::gd_dis_opcode(const u16 *binbuf, u16 *pc, std::string *dest)
|
||||||
{
|
{
|
||||||
u32 op2;
|
u32 op2;
|
||||||
char *buf = gdg->buffer;
|
char buffer[256];
|
||||||
|
char *buf = buffer;
|
||||||
u16 pc = gdg->pc;
|
|
||||||
|
|
||||||
// Start with a space.
|
// Start with a space.
|
||||||
buf[0] = ' ';
|
buf[0] = ' ';
|
||||||
buf[1] = '\0';
|
buf[1] = '\0';
|
||||||
buf++;
|
buf++;
|
||||||
|
|
||||||
if ((pc & 0x7fff) >= 0x1000)
|
if ((*pc & 0x7fff) >= 0x1000)
|
||||||
{
|
{
|
||||||
gdg->pc++;
|
*pc++;
|
||||||
return gdg->buffer;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pc &= 0x0fff;
|
*pc &= 0x0fff;
|
||||||
u32 op1 = gdg->binbuf[pc];
|
const u32 op1 = binbuf[*pc];
|
||||||
|
|
||||||
const DSPOPCTemplate *opc = NULL;
|
const DSPOPCTemplate *opc = NULL;
|
||||||
const DSPOPCTemplate *opc_ext = NULL;
|
const DSPOPCTemplate *opc_ext = NULL;
|
||||||
|
@ -239,7 +235,6 @@ char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const DSPOPCTemplate fake_op = {"CW", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, NULL, NULL,};
|
const DSPOPCTemplate fake_op = {"CW", 0x0000, 0x0000, nop, nop, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, NULL, NULL,};
|
||||||
if (!opc)
|
if (!opc)
|
||||||
opc = &fake_op;
|
opc = &fake_op;
|
||||||
|
@ -266,23 +261,22 @@ char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
||||||
|
|
||||||
// printing
|
// printing
|
||||||
|
|
||||||
if (gdg->show_pc)
|
if (settings_.show_pc)
|
||||||
sprintf(buf, "%04x ", gdg->pc);
|
sprintf(buf, "%04x ", *pc);
|
||||||
|
|
||||||
buf += strlen(buf);
|
buf += strlen(buf);
|
||||||
|
|
||||||
if ((opc->size & ~P_EXT) == 2)
|
if ((opc->size & ~P_EXT) == 2)
|
||||||
{
|
{
|
||||||
op2 = gdg->binbuf[pc + 1];
|
op2 = binbuf[*pc + 1];
|
||||||
|
if (settings_.show_hex)
|
||||||
if (gdg->show_hex)
|
|
||||||
sprintf(buf, "%04x %04x ", op1, op2);
|
sprintf(buf, "%04x %04x ", op1, op2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
op2 = 0;
|
op2 = 0;
|
||||||
|
|
||||||
if (gdg->show_hex)
|
if (settings_.show_hex)
|
||||||
sprintf(buf, "%04x ", op1);
|
sprintf(buf, "%04x ", op1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,11 +285,11 @@ char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
||||||
char tmpbuf[20];
|
char tmpbuf[20];
|
||||||
|
|
||||||
if (extended)
|
if (extended)
|
||||||
sprintf(tmpbuf, "%s%c%s", opc->name, gdg->ext_separator, opc_ext->name);
|
sprintf(tmpbuf, "%s%c%s", opc->name, settings_.ext_separator, opc_ext->name);
|
||||||
else
|
else
|
||||||
sprintf(tmpbuf, "%s", opc->name);
|
sprintf(tmpbuf, "%s", opc->name);
|
||||||
|
|
||||||
if (gdg->print_tabs)
|
if (settings_.print_tabs)
|
||||||
sprintf(buf, "%s\t", tmpbuf);
|
sprintf(buf, "%s\t", tmpbuf);
|
||||||
else
|
else
|
||||||
sprintf(buf, "%-12s", tmpbuf);
|
sprintf(buf, "%-12s", tmpbuf);
|
||||||
|
@ -303,7 +297,7 @@ char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
||||||
buf += strlen(buf);
|
buf += strlen(buf);
|
||||||
|
|
||||||
if (opc->param_count > 0)
|
if (opc->param_count > 0)
|
||||||
gd_dis_params(gdg, opc, op1, op2, buf);
|
gd_dis_params(opc, op1, op2, buf);
|
||||||
|
|
||||||
buf += strlen(buf);
|
buf += strlen(buf);
|
||||||
|
|
||||||
|
@ -318,7 +312,7 @@ char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
||||||
buf += strlen(buf);
|
buf += strlen(buf);
|
||||||
|
|
||||||
if (opc_ext->param_count > 0)
|
if (opc_ext->param_count > 0)
|
||||||
gd_dis_params(gdg, opc_ext, op1, op2, buf);
|
gd_dis_params(opc_ext, op1, op2, buf);
|
||||||
|
|
||||||
buf += strlen(buf);
|
buf += strlen(buf);
|
||||||
}
|
}
|
||||||
|
@ -331,14 +325,14 @@ char* DSPDisassembler::gd_dis_opcode(gd_globals_t* gdg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extended)
|
if (extended)
|
||||||
gdg->pc += opc_ext->size;
|
*pc += opc_ext->size;
|
||||||
else
|
else
|
||||||
gdg->pc += opc->size & ~P_EXT;
|
*pc += opc->size & ~P_EXT;
|
||||||
|
|
||||||
return gdg->buffer;
|
dest->append(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPDisassembler::gd_dis_file(gd_globals_t* gdg, const char* name, FILE* output)
|
bool DSPDisassembler::gd_dis_file(const char* name, FILE* output)
|
||||||
{
|
{
|
||||||
gd_dis_open_unkop();
|
gd_dis_open_unkop();
|
||||||
|
|
||||||
|
@ -354,23 +348,20 @@ bool DSPDisassembler::gd_dis_file(gd_globals_t* gdg, const char* name, FILE* out
|
||||||
fseek(in, 0, SEEK_END);
|
fseek(in, 0, SEEK_END);
|
||||||
size = (int)ftell(in);
|
size = (int)ftell(in);
|
||||||
fseek(in, 0, SEEK_SET);
|
fseek(in, 0, SEEK_SET);
|
||||||
gdg->binbuf = (u16*)malloc(size);
|
|
||||||
fread(gdg->binbuf, 1, size, in);
|
|
||||||
|
|
||||||
gdg->buffer = (char*)malloc(256);
|
u16 *binbuf = (u16*)malloc(size);
|
||||||
gdg->buffer_size = 256;
|
fread(binbuf, 1, size, in);
|
||||||
|
|
||||||
for (gdg->pc = 0; gdg->pc < (size / 2);)
|
for (u16 pc = 0; pc < (size / 2);)
|
||||||
fprintf(output, "%s\n", gd_dis_opcode(gdg));
|
{
|
||||||
|
std::string str;
|
||||||
|
gd_dis_opcode(binbuf, &pc, &str);
|
||||||
|
fprintf(output, "%s\n", str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
free(gdg->binbuf);
|
free(binbuf);
|
||||||
gdg->binbuf = NULL;
|
|
||||||
|
|
||||||
free(gdg->buffer);
|
|
||||||
gdg->buffer = NULL;
|
|
||||||
gdg->buffer_size = 0;
|
|
||||||
|
|
||||||
gd_dis_close_unkop();
|
gd_dis_close_unkop();
|
||||||
|
|
||||||
|
|
|
@ -28,40 +28,55 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "DSPTables.h"
|
#include "DSPTables.h"
|
||||||
|
|
||||||
struct gd_globals_t
|
struct AssemblerSettings
|
||||||
{
|
{
|
||||||
|
AssemblerSettings()
|
||||||
|
: print_tabs(false),
|
||||||
|
show_hex(false),
|
||||||
|
show_pc(false),
|
||||||
|
decode_names(true),
|
||||||
|
decode_registers(true),
|
||||||
|
ext_separator('\'')
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool print_tabs;
|
bool print_tabs;
|
||||||
bool show_hex;
|
bool show_hex;
|
||||||
bool show_pc;
|
bool show_pc;
|
||||||
bool decode_names;
|
bool decode_names;
|
||||||
bool decode_registers;
|
bool decode_registers;
|
||||||
|
bool lower_case_ops;
|
||||||
|
char ext_separator;
|
||||||
|
|
||||||
u16* binbuf;
|
u16 *binbuf;
|
||||||
u16 pc;
|
u16 pc;
|
||||||
char* buffer;
|
char* buffer;
|
||||||
u16 buffer_size;
|
u16 buffer_size;
|
||||||
char ext_separator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DSPDisassembler
|
class DSPDisassembler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSPDisassembler();
|
DSPDisassembler(const AssemblerSettings &settings);
|
||||||
~DSPDisassembler() {}
|
~DSPDisassembler() {}
|
||||||
|
|
||||||
char* gd_dis_opcode(gd_globals_t* gdg);
|
// Moves PC forward and writes the result to dest.
|
||||||
bool gd_dis_file(gd_globals_t* gdg, const char* name, FILE* output);
|
void gd_dis_opcode(const u16 *binbuf, u16 *pc, std::string *dest);
|
||||||
|
bool gd_dis_file(const char* name, FILE *output);
|
||||||
|
|
||||||
void gd_dis_close_unkop();
|
void gd_dis_close_unkop();
|
||||||
void gd_dis_open_unkop();
|
void gd_dis_open_unkop();
|
||||||
const char* gd_dis_get_reg_name(u16 reg);
|
const char* gd_dis_get_reg_name(u16 reg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* gd_dis_params(gd_globals_t* gdg, const DSPOPCTemplate* opc, u16 op1, u16 op2, char* strbuf);
|
char* gd_dis_params(const DSPOPCTemplate* opc, u16 op1, u16 op2, char* strbuf);
|
||||||
|
u32 unk_opcodes[0x10000];
|
||||||
|
|
||||||
|
const AssemblerSettings settings_;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *gd_get_reg_name(u16 reg);
|
const char *gd_get_reg_name(u16 reg);
|
||||||
u16 gd_dis_get_opcode_size(gd_globals_t* gdg);
|
//u16 gd_dis_get_opcode_size(gd_globals_t* gdg);
|
||||||
|
|
||||||
#endif // _DSP_DISASSEMBLE_H
|
#endif // _DSP_DISASSEMBLE_H
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,6 @@ void RunAsmTests()
|
||||||
#define CHK(a) if (!SuperTrip(a)) printf("FAIL\n%s\n", a), fail = true;
|
#define CHK(a) if (!SuperTrip(a)) printf("FAIL\n%s\n", a), fail = true;
|
||||||
|
|
||||||
// Let's start out easy - a trivial instruction..
|
// Let's start out easy - a trivial instruction..
|
||||||
#if 0
|
|
||||||
CHK(" NOP\n");
|
CHK(" NOP\n");
|
||||||
|
|
||||||
// Now let's do several.
|
// Now let's do several.
|
||||||
|
@ -114,26 +113,30 @@ void RunAsmTests()
|
||||||
" si @0xfffd, #0xbeef\n"
|
" si @0xfffd, #0xbeef\n"
|
||||||
" si @DIRQ, #0x0001\n");
|
" si @DIRQ, #0x0001\n");
|
||||||
|
|
||||||
|
// Let's try some messy extended instructions.
|
||||||
|
//CHK(" MULMV'SN $AX0.L, $AX0.H, $ACC0 : @$AR2, $AC1.M\n");
|
||||||
|
|
||||||
|
//" ADDAXL'MV $ACC1, $AX1.L : $AX1.H, $AC1.M\n");
|
||||||
// Let's get brutal. We generate random code bytes and make sure that they can
|
// Let's get brutal. We generate random code bytes and make sure that they can
|
||||||
// be roundtripped. We don't expect it to always succeed but it'll be sure to generate
|
// be roundtripped. We don't expect it to always succeed but it'll be sure to generate
|
||||||
// interesting test cases.
|
// interesting test cases.
|
||||||
|
/*
|
||||||
puts("Insane Random Code Test\n");
|
puts("Insane Random Code Test\n");
|
||||||
std::vector<u16> rand_code;
|
std::vector<u16> rand_code;
|
||||||
GenRandomCode(21, &rand_code);
|
GenRandomCode(31, &rand_code);
|
||||||
std::string rand_code_text;
|
std::string rand_code_text;
|
||||||
Disassemble(rand_code, &rand_code_text);
|
Disassemble(rand_code, true, &rand_code_text);
|
||||||
printf("%s", rand_code_text.c_str());
|
printf("%s", rand_code_text.c_str());
|
||||||
RoundTrip(rand_code);
|
RoundTrip(rand_code);
|
||||||
#endif
|
*/
|
||||||
|
|
||||||
std::string dsp_test;
|
std::string dsp_test;
|
||||||
//File::ReadStringFromFile(true, "C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test);
|
|
||||||
|
|
||||||
File::ReadFileToString(true, "C:/devkitPro/trunk/libogc/libasnd/dsp_mixer/dsp_mixer.s", &dsp_test);
|
if (File::ReadFileToString(true, "C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test))
|
||||||
// This is CLOSE to working. Sorry about the local path btw. This is preliminary code.
|
|
||||||
SuperTrip(dsp_test.c_str());
|
SuperTrip(dsp_test.c_str());
|
||||||
|
|
||||||
|
//.File::ReadFileToString(true, "C:/devkitPro/trunk/libogc/libasnd/dsp_mixer/dsp_mixer.s", &dsp_test);
|
||||||
|
// This is CLOSE to working. Sorry about the local path btw. This is preliminary code.
|
||||||
|
|
||||||
if (!fail)
|
if (!fail)
|
||||||
printf("All passed!\n");
|
printf("All passed!\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,26 +190,27 @@ void DSPDebuggerLLE::RebuildDisAsmListView()
|
||||||
m_Disasm->DeleteAllItems();
|
m_Disasm->DeleteAllItems();
|
||||||
|
|
||||||
char Buffer[256];
|
char Buffer[256];
|
||||||
gd_globals_t gdg;
|
AssemblerSettings settings;
|
||||||
|
|
||||||
|
const u16 *binbuf;
|
||||||
if (g_dsp.pc & 0x8000)
|
if (g_dsp.pc & 0x8000)
|
||||||
gdg.binbuf = g_dsp.irom;
|
binbuf = g_dsp.irom;
|
||||||
else
|
else
|
||||||
gdg.binbuf = g_dsp.iram;
|
binbuf = g_dsp.iram;
|
||||||
|
|
||||||
gdg.buffer = Buffer;
|
settings.buffer = Buffer;
|
||||||
gdg.buffer_size = 256;
|
settings.buffer_size = 256;
|
||||||
gdg.ext_separator = (char)0xff;
|
settings.ext_separator = (char)0xff;
|
||||||
|
|
||||||
gdg.show_pc = false;
|
settings.show_pc = false;
|
||||||
gdg.show_hex = false;
|
settings.show_hex = false;
|
||||||
gdg.print_tabs = true;
|
settings.print_tabs = true;
|
||||||
gdg.decode_names = true;
|
settings.decode_names = true;
|
||||||
gdg.decode_registers = true;
|
settings.decode_registers = true;
|
||||||
|
|
||||||
for (gdg.pc = 0; gdg.pc < DSP_IROM_SIZE;)
|
for (settings.pc = 0; settings.pc < DSP_IROM_SIZE;)
|
||||||
{
|
{
|
||||||
u16 CurrentPC = gdg.pc;
|
u16 CurrentPC = settings.pc;
|
||||||
|
|
||||||
if (g_dsp.pc & 0x8000)
|
if (g_dsp.pc & 0x8000)
|
||||||
CurrentPC |= 0x8000;
|
CurrentPC |= 0x8000;
|
||||||
|
@ -220,13 +221,16 @@ void DSPDebuggerLLE::RebuildDisAsmListView()
|
||||||
char Temp2[256];
|
char Temp2[256];
|
||||||
sprintf(Temp2, "0x%04x", dsp_imem_read(CurrentPC));
|
sprintf(Temp2, "0x%04x", dsp_imem_read(CurrentPC));
|
||||||
|
|
||||||
DSPDisassembler disasm;
|
AssemblerSettings settings;
|
||||||
char* pOpcode = disasm.gd_dis_opcode(&gdg);
|
DSPDisassembler disasm(settings);
|
||||||
|
std::string op_str;
|
||||||
|
disasm.gd_dis_opcode(binbuf,&settings.pc, &op_str);
|
||||||
const char* pParameter = NULL;
|
const char* pParameter = NULL;
|
||||||
const char* pExtension = NULL;
|
const char* pExtension = NULL;
|
||||||
|
|
||||||
size_t WholeString = strlen(pOpcode);
|
size_t WholeString = op_str.size();
|
||||||
|
|
||||||
|
/*
|
||||||
for (size_t i = 0; i < WholeString; i++)
|
for (size_t i = 0; i < WholeString; i++)
|
||||||
{
|
{
|
||||||
if (pOpcode[i] == (char)0xff)
|
if (pOpcode[i] == (char)0xff)
|
||||||
|
@ -240,7 +244,7 @@ void DSPDebuggerLLE::RebuildDisAsmListView()
|
||||||
pOpcode[i] = 0x00;
|
pOpcode[i] = 0x00;
|
||||||
pParameter = &pOpcode[i + 1];
|
pParameter = &pOpcode[i + 1];
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const char* pFunctionName = NULL;
|
const char* pFunctionName = NULL;
|
||||||
|
|
||||||
|
@ -249,15 +253,15 @@ void DSPDebuggerLLE::RebuildDisAsmListView()
|
||||||
pFunctionName = m_SymbolMap[CurrentPC].Name.c_str();
|
pFunctionName = m_SymbolMap[CurrentPC].Name.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Item = m_Disasm->InsertItem(gdg.pc, wxEmptyString);
|
int Item = m_Disasm->InsertItem(settings.pc, wxEmptyString);
|
||||||
m_Disasm->SetItem(Item, COLUMN_BP, wxEmptyString);
|
m_Disasm->SetItem(Item, COLUMN_BP, wxEmptyString);
|
||||||
m_Disasm->SetItem(Item, COLUMN_FUNCTION, wxString::FromAscii(pFunctionName));
|
m_Disasm->SetItem(Item, COLUMN_FUNCTION, wxString::FromAscii(pFunctionName));
|
||||||
m_Disasm->SetItem(Item, COLUMN_ADDRESS, wxString::FromAscii(Temp));
|
m_Disasm->SetItem(Item, COLUMN_ADDRESS, wxString::FromAscii(Temp));
|
||||||
m_Disasm->SetItem(Item, COLUMN_MNEMONIC, wxString::FromAscii(Temp2));
|
m_Disasm->SetItem(Item, COLUMN_MNEMONIC, wxString::FromAscii(Temp2));
|
||||||
m_Disasm->SetItem(Item, COLUMN_OPCODE, wxString::FromAscii(pOpcode));
|
m_Disasm->SetItem(Item, COLUMN_OPCODE, wxString::FromAscii(op_str.c_str()));
|
||||||
m_Disasm->SetItem(Item, COLUMN_EXT, wxString::FromAscii(pExtension));
|
m_Disasm->SetItem(Item, COLUMN_EXT, wxString::FromAscii(pExtension));
|
||||||
|
|
||||||
if (!strcasecmp(pOpcode, "CALL"))
|
if (!strcasecmp(op_str.c_str(), "CALL"))
|
||||||
{
|
{
|
||||||
u32 FunctionAddress = -1;
|
u32 FunctionAddress = -1;
|
||||||
sscanf(pParameter, "0x%04x", &FunctionAddress);
|
sscanf(pParameter, "0x%04x", &FunctionAddress);
|
||||||
|
|
|
@ -60,15 +60,15 @@ bool DisasmUCodeDump(u32 crc)
|
||||||
FILE* t = fopen(txtFile, "wb");
|
FILE* t = fopen(txtFile, "wb");
|
||||||
if (t != NULL)
|
if (t != NULL)
|
||||||
{
|
{
|
||||||
gd_globals_t gdg;
|
AssemblerSettings settings;
|
||||||
memset(&gdg, 0, sizeof(gdg));
|
memset(&settings, 0, sizeof(settings));
|
||||||
gdg.show_hex = true;
|
settings.show_hex = true;
|
||||||
gdg.show_pc = true;
|
settings.show_pc = true;
|
||||||
gdg.ext_separator = '\t';
|
settings.ext_separator = '\t';
|
||||||
gdg.decode_names = true;
|
settings.decode_names = true;
|
||||||
gdg.decode_registers = true;
|
settings.decode_registers = true;
|
||||||
DSPDisassembler disasm;
|
DSPDisassembler disasm(settings);
|
||||||
disasm.gd_dis_file(&gdg, binFile, t);
|
disasm.gd_dis_file(binFile, t);
|
||||||
fclose(t);
|
fclose(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue