From 1580b6e6276197cf2630856a5e8cda4453f2d7bd Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Fri, 19 May 2017 17:07:26 -0700 Subject: [PATCH 1/4] DSPTool: make existing tests pass Disassemble code without the additional text for humans, like the current PC and opcode hex values, so that it can be reassembled. I'm not updating any commented-out tests here. --- Source/DSPTool/DSPTool.cpp | 21 +- Source/DSPTool/Testdata/dsp_test.S | 390 ++++++++++++++--------------- 2 files changed, 214 insertions(+), 197 deletions(-) diff --git a/Source/DSPTool/DSPTool.cpp b/Source/DSPTool/DSPTool.cpp index c0d34dc152..ed6863365e 100644 --- a/Source/DSPTool/DSPTool.cpp +++ b/Source/DSPTool/DSPTool.cpp @@ -6,6 +6,7 @@ #include "Common/FileUtil.h" #include "Common/StringUtil.h" #include "Core/DSP/DSPCodeUtil.h" +#include "Core/DSP/DSPDisassembler.h" #include "Core/DSP/DSPHost.h" #include "Core/DSP/DSPTables.h" @@ -38,13 +39,27 @@ void DSP::Host::UpdateDebugger() { } +static bool RoundTrippableDissassemble(const std::vector& code, std::string& text) +{ + DSP::AssemblerSettings settings; + settings.ext_separator = '\''; + settings.decode_names = true; + settings.decode_registers = true; + // These two prevent roundtripping. + settings.show_hex = false; + settings.show_pc = false; + DSP::DSPDisassembler disasm(settings); + + return disasm.Disassemble(0x0000, code, 0x0000, text); +} + // This test goes from text ASM to binary to text ASM and once again back to binary. // Then the two binaries are compared. static bool RoundTrip(const std::vector& code1) { std::vector code2; std::string text; - if (!DSP::Disassemble(code1, false, text)) + if (!RoundTrippableDissassemble(code1, text)) { printf("RoundTrip: Disassembly failed.\n"); return false; @@ -74,7 +89,8 @@ static bool SuperTrip(const char* asm_code) return false; } printf("First assembly: %i words\n", (int)code1.size()); - if (!DSP::Disassemble(code1, false, text)) + + if (!RoundTrippableDissassemble(code1, text)) { printf("SuperTrip: Disassembly failed\n"); return false; @@ -84,6 +100,7 @@ static bool SuperTrip(const char* asm_code) printf("Disass:\n"); printf("%s", text.c_str()); } + if (!DSP::Assemble(text, code2)) { printf("SuperTrip: Second assembly failed\n"); diff --git a/Source/DSPTool/Testdata/dsp_test.S b/Source/DSPTool/Testdata/dsp_test.S index 9a177c4d4e..2c4f4f4d56 100644 --- a/Source/DSPTool/Testdata/dsp_test.S +++ b/Source/DSPTool/Testdata/dsp_test.S @@ -76,7 +76,7 @@ MEM_LO: equ 0x0f7F jmp irq5 jmp irq6 jmp irq7 - + ; Main code at 0x10 CW 0x1302 CW 0x1303 @@ -86,11 +86,11 @@ MEM_LO: equ 0x0f7F s40 lri $r12, #0x00ff - + main: cw 0x8900 - cw 0x8100 + cw 0x8100 ; get address of memory dump and copy it @@ -177,8 +177,8 @@ main: nop - - + + cw 0x8600 call send_back @@ -188,223 +188,223 @@ main: ; call dump_memory ; call send_back - - -; 0x041e -; - cw 0x00de - cw 0x03f1 + +; 0x041e +; + + cw 0x00de + cw 0x03f1 call send_back - - cw 0x0200 - cw 0x0a60 + + cw 0x0200 + cw 0x0a60 call send_back - - cw 0x1c7e + + cw 0x1c7e call send_back - - cw 0x8100 + + cw 0x8100 call send_back - - cw 0x8900 + + cw 0x8900 call send_back - - cw 0x009f - cw 0x00a0 + + cw 0x009f + cw 0x00a0 call send_back - - cw 0x00de - cw 0x03f1 + + cw 0x00de + cw 0x03f1 call send_back - - cw 0x5d00 + + cw 0x5d00 call send_back - - cw 0x0e50 + + cw 0x0e50 call send_back - - cw 0x0750 + + cw 0x0750 call send_back - - cw 0x0270 + + cw 0x0270 call send_back - - cw 0x5d00 + + cw 0x5d00 call send_back - - cw 0x00da - cw 0x03f2 + + cw 0x00da + cw 0x03f2 call send_back - - cw 0x8600 + + cw 0x8600 call send_back - - JNS g_0c4d -; cw 0x0290 -; cw 0x0c4d + + JGE g_0c4d +; cw 0x0290 +; cw 0x0c4d ; call send_back JX0 - - cw 0x00de - cw 0x03f3 + + cw 0x00de + cw 0x03f3 call send_back - - cw 0x5c00 + + cw 0x5c00 call send_back - - JLE g_0c38 -; cw 0x0293 + + JLE g_0c38 +; cw 0x0293 ; cw 0x0c38 JX3 ; call send_back - + JMP g_0c52 - -; cw 0x029f -; cw 0x0c52 -; call send_back + +; cw 0x029f +; cw 0x0c52 +; call send_back g_0c38: - cw 0x00db - cw 0x03f7 + cw 0x00db + cw 0x03f7 call send_back - - cw 0x009e - cw 0x8000 + + cw 0x009e + cw 0x8000 call send_back - - cw 0x4600 + + cw 0x4600 call send_back - + JMP g_0c44 -; cw 0x029f -; cw 0x0c44 +; cw 0x029f +; cw 0x0c44 ; call send_back - -g_0c3f: - cw 0x00db - cw 0x03f7 + +g_0c3f: + cw 0x00db + cw 0x03f7 call send_back - - cw 0x009e - cw 0x8000 + + cw 0x009e + cw 0x8000 call send_back - - cw 0x5600 + + cw 0x5600 call send_back - -g_0c44: - cw 0x00fe - cw 0x03f5 + +g_0c44: + cw 0x00fe + cw 0x03f5 call send_back - - cw 0x1fda + + cw 0x1fda call send_back - - cw 0x7c00 + + cw 0x7c00 call send_back - - cw 0x1f5e + + cw 0x1f5e call send_back - - cw 0x00fe - cw 0x03f2 + + cw 0x00fe + cw 0x03f2 call send_back - - JMP g_0c52 -; cw 0x029f -; cw 0x0c52 + + JMP g_0c52 +; cw 0x029f +; cw 0x0c52 ; call send_back g_0c4d: - - cw 0x00de - cw 0x03f4 + + cw 0x00de + cw 0x03f4 call send_back - - cw 0x5d00 + + cw 0x5d00 call send_back - - JLE g_0c3f -; cw 0x0293 -; cw 0x0c3f + + JLE g_0c3f +; cw 0x0293 +; cw 0x0c3f ; call send_back - -g_0c52: - cw 0x8900 + +g_0c52: + cw 0x8900 call send_back - - cw 0x00dd - cw 0x03f5 + + cw 0x00dd + cw 0x03f5 call send_back - - cw 0x1501 + + cw 0x1501 call send_back - - cw 0x8100 + + cw 0x8100 call send_back - - cw 0x00dc - cw 0x03f6 + + cw 0x00dc + cw 0x03f6 call send_back - - cw 0x008b - cw 0x009f + + cw 0x008b + cw 0x009f call send_back - - cw 0x0080 - cw 0x0a00 + + cw 0x0080 + cw 0x0a00 call send_back - - cw 0x0900 + + cw 0x0900 call send_back - + BLOOPI #0x50, g_0c65 -; cw 0x1150 -; cw 0x0c65 +; cw 0x1150 +; cw 0x0c65 ; call send_back - cw 0x1878 + cw 0x1878 call send_back - - cw 0x4c00 + + cw 0x4c00 call send_back - - cw 0x1cfe + + cw 0x1cfe call send_back - - cw 0x001f + + cw 0x001f call send_back - - cw 0x1fd9 + + cw 0x1fd9 call send_back g_0c65: - cw 0x1b18 + cw 0x1b18 call send_back - - cw 0x009f - cw 0x0a60 + + cw 0x009f + cw 0x0a60 call send_back - - cw 0x1fc3 + + cw 0x1fc3 call send_back - - cw 0x5c00 + + cw 0x5c00 call send_back - - cw 0x00fe - cw 0x03f1 + + cw 0x00fe + cw 0x03f1 call send_back - - cw 0x00fc - cw 0x03f6 + + cw 0x00fc + cw 0x03f6 call send_back - - cw 0x008b - cw 0xffff + + cw 0x008b + cw 0xffff call send_back - - + + ende: @@ -415,9 +415,9 @@ ende: nop nop nop - - - + + + dead_loop: jmp dead_loop @@ -445,7 +445,7 @@ wait_for_cpu_mbox: andcf $acl1, #0x8000 jlnz wait_for_cpu_mbox ret - + irq0: lri $acl0, #0x0000 jmp irq @@ -455,7 +455,7 @@ irq1: irq2: lri $acl0, #0x0002 jmp irq - + irq3: lri $acl0, #0x0003 jmp irq @@ -477,7 +477,7 @@ irq5: nop nop rti - + lri $acl0, #0x0005 jmp irq irq6: @@ -486,20 +486,20 @@ irq6: irq7: lri $acl0, #0x0007 jmp irq - + irq: lrs $ACL1, @DMBH andcf $acl1, #0x8000 jlz irq si @DMBH, #0x8BAD sr @DMBL, $r0b -;sr @DMBL, $acl0 +;sr @DMBL, $acl0 si @DIRQ, #0x0001 halt - - - - + + + + send_back: ; store registers to reg table @@ -536,7 +536,7 @@ send_back: srri @$r00, $r1d srri @$r00, $r1e srri @$r00, $r1f - + lri $r18, #0x0000 lri $r19, #1 ;(DSP_CR_IMEM | DSP_CR_TO_CPU) @@ -545,7 +545,7 @@ send_back: lr $r1e, @MEM_LO lri $r01, #8+8 - + bloop $r01, dma_copy call do_dma addi $r1e, #0x200 @@ -555,19 +555,19 @@ send_back: nop dma_copy: nop - + call wait_for_dsp_mbox si @DMBH, #0x8888 si @DMBL, #0xfeeb si @DIRQ, #0x0001 - -; wait for answer before we execute the next op + +; wait for answer before we execute the next op call wait_for_cpu_mbox lrs $ACL0, @CMBL andi $acl1, #0x7fff - - + + lri $r00, #REGS_BASE+1 lrri $r01, @$r00 lrri $r02, @$r00 @@ -601,39 +601,39 @@ dma_copy: lrri $r1e, @$r00 lrri $r1f, @$r00 lr $r00, @REGS_BASE - - ret - -send_back_16: - - cw 0x8e00 - call send_back - cw 0x8f00 - + ret - - + +send_back_16: + + cw 0x8e00 + call send_back + cw 0x8f00 + + ret + + dump_memory: lri $r02, #0x0000 lri $acl0, #0x1000 - - lri $r01, #0x1000 - bloop $r01, _fill_loop2 - + + lri $r01, #0x1000 + bloop $r01, _fill_loop2 + mrr $r03, $acl0 cw 0x80f0 - + mrr $r1f, $r00 mrr $r00, $r02 srri @$r00, $r1b mrr $r02, $r00 mrr $r00, $r1f - - addis $acc0, #0x1 - + + addis $AC0.M, #0x1 + _fill_loop2: nop - -ret + +ret From 80710984dc9d0d9ad381277e0894b970604edfa8 Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Fri, 19 May 2017 17:36:04 -0700 Subject: [PATCH 2/4] DSPTool: extract tests into a DSPAssemblyTest - Moves all test code from DSPTool into UnitTests/Core/DSPAssemblyTest. - Converts test files (which could only be loaded if they were in the shell's working directory, so basically never) into C++ values. - Enables most of the commented-out tests. - Removes non-deterministic random code test. --- Source/DSPTool/DSPTool.cpp | 192 ------------------ Source/DSPTool/Testdata/dsp_test.bin | Bin 1072 -> 0 bytes Source/DSPTool/Testdata/hermes.bin | Bin 1472 -> 0 bytes Source/UnitTests/Core/CMakeLists.txt | 7 + Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp | 155 ++++++++++++++ Source/UnitTests/Core/DSP/DSPTestBinary.cpp | 52 +++++ Source/UnitTests/Core/DSP/DSPTestBinary.h | 11 + .../Core/DSP/DSPTestText.cpp} | 7 + Source/UnitTests/Core/DSP/DSPTestText.h | 9 + Source/UnitTests/Core/DSP/HermesBinary.cpp | 69 +++++++ Source/UnitTests/Core/DSP/HermesBinary.h | 11 + .../Testdata => UnitTests/Core/DSP}/hermes.s | 0 Source/UnitTests/UnitTests.vcxproj | 1 + 13 files changed, 322 insertions(+), 192 deletions(-) delete mode 100644 Source/DSPTool/Testdata/dsp_test.bin delete mode 100644 Source/DSPTool/Testdata/hermes.bin create mode 100644 Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp create mode 100644 Source/UnitTests/Core/DSP/DSPTestBinary.cpp create mode 100644 Source/UnitTests/Core/DSP/DSPTestBinary.h rename Source/{DSPTool/Testdata/dsp_test.S => UnitTests/Core/DSP/DSPTestText.cpp} (97%) create mode 100644 Source/UnitTests/Core/DSP/DSPTestText.h create mode 100644 Source/UnitTests/Core/DSP/HermesBinary.cpp create mode 100644 Source/UnitTests/Core/DSP/HermesBinary.h rename Source/{DSPTool/Testdata => UnitTests/Core/DSP}/hermes.s (100%) diff --git a/Source/DSPTool/DSPTool.cpp b/Source/DSPTool/DSPTool.cpp index ed6863365e..de400f88dd 100644 --- a/Source/DSPTool/DSPTool.cpp +++ b/Source/DSPTool/DSPTool.cpp @@ -39,192 +39,7 @@ void DSP::Host::UpdateDebugger() { } -static bool RoundTrippableDissassemble(const std::vector& code, std::string& text) -{ - DSP::AssemblerSettings settings; - settings.ext_separator = '\''; - settings.decode_names = true; - settings.decode_registers = true; - // These two prevent roundtripping. - settings.show_hex = false; - settings.show_pc = false; - DSP::DSPDisassembler disasm(settings); - - return disasm.Disassemble(0x0000, code, 0x0000, text); -} - -// This test goes from text ASM to binary to text ASM and once again back to binary. -// Then the two binaries are compared. -static bool RoundTrip(const std::vector& code1) -{ - std::vector code2; - std::string text; - if (!RoundTrippableDissassemble(code1, text)) - { - printf("RoundTrip: Disassembly failed.\n"); - return false; - } - if (!DSP::Assemble(text, code2)) - { - printf("RoundTrip: Assembly failed.\n"); - return false; - } - if (!DSP::Compare(code1, code2)) - { - DSP::Disassemble(code1, true, text); - printf("%s", text.c_str()); - } - return true; -} - -// This test goes from text ASM to binary to text ASM and once again back to binary. -// Very convenient for testing. Then the two binaries are compared. -static bool SuperTrip(const char* asm_code) -{ - std::vector code1, code2; - std::string text; - if (!DSP::Assemble(asm_code, code1)) - { - printf("SuperTrip: First assembly failed\n"); - return false; - } - printf("First assembly: %i words\n", (int)code1.size()); - - if (!RoundTrippableDissassemble(code1, text)) - { - printf("SuperTrip: Disassembly failed\n"); - return false; - } - else - { - printf("Disass:\n"); - printf("%s", text.c_str()); - } - - if (!DSP::Assemble(text, code2)) - { - printf("SuperTrip: Second assembly failed\n"); - return false; - } - /* - std::string text2; - Disassemble(code1, true, &text1); - Disassemble(code2, true, &text2); - File::WriteStringToFile(text1, "code1.txt"); - File::WriteStringToFile(text2, "code2.txt"); - */ - return true; -} - -static void RunAsmTests() -{ - bool fail = false; -#define CHK(a) \ - if (!SuperTrip(a)) \ - printf("FAIL\n%s\n", a), fail = true; - - // Let's start out easy - a trivial instruction.. - CHK(" NOP\n"); - - // Now let's do several. - CHK(" NOP\n" - " NOP\n" - " NOP\n"); - - // Turning it up a notch. - CHK(" SET16\n" - " SET40\n" - " CLR15\n" - " M0\n" - " M2\n"); - - // Time to try labels and parameters, and comments. - CHK("DIRQ_TEST: equ 0xfffb ; DSP Irq Request\n" - " si @0xfffc, #0x8888\n" - " si @0xfffd, #0xbeef\n" - " si @DIRQ_TEST, #0x0001\n"); - - // Let's see if registers roundtrip. Also try predefined labels. - CHK(" si @0xfffc, #0x8888\n" - " si @0xfffd, #0xbeef\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 - // be roundtripped. We don't expect it to always succeed but it'll be sure to generate - - // interesting test cases. - /* - std::vector hermes; - if (!LoadBinary("testdata/hermes.bin", &hermes)) - PanicAlert("Failed to load hermes rom"); - RoundTrip(hermes); - */ - /* - std::vector code; - std::string text_orig; - File::ReadFileToString("testdata/dsp_test.S", &text_orig); - if (!Assemble(text_orig.c_str(), &code)) - { - printf("SuperTrip: First assembly failed\n"); - return; - }*/ - - /* - { - std::vector code; - code.clear(); - for (int i = 0; i < sizeof(dsp_test)/4; i++) - { - code.push_back(dsp_test[i] >> 16); - code.push_back(dsp_test[i] & 0xFFFF); - } - - SaveBinary(code, "dsp_test2.bin"); - RoundTrip(code); - }*/ - // if (Compare(code, hermes)) - // printf("Successs\n"); - /* - { - std::vector code; - std::string text; - LoadBinary("testdata/dsp_test.bin", &code); - Disassemble(code, true, &text); - Assemble(text.c_str(), &code); - Disassemble(code, true, &text); - printf("%s", text.c_str()); - }*/ - /* - puts("Insane Random Code Test\n"); - std::vector rand_code; - GenRandomCode(30, &rand_code); - std::string rand_code_text; - Disassemble(rand_code, true, &rand_code_text); - printf("%s", rand_code_text.c_str()); - RoundTrip(rand_code); - - - if (File::ReadFileToString("C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test)) - SuperTrip(dsp_test.c_str()); - - //.File::ReadFileToString("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. -*/ - - std::string dsp_test; - if (File::ReadFileToString("Testdata/dsp_test.s", dsp_test)) - fail = fail || !SuperTrip(dsp_test.c_str()); - if (!fail) - printf("All passed!\n"); -} - // Usage: -// Run internal tests: -// dsptool test // Disassemble a file: // dsptool -d -o asdf.txt asdf.bin // Disassemble a file, output to standard output: @@ -235,7 +50,6 @@ static void RunAsmTests() // dsptool [-f] -h asdf.h asdf.txt // Print results from DSPSpy register dump // dsptool -p dsp_dump0.bin -// So far, all this binary can do is test partially that itself works correctly. int main(int argc, const char* argv[]) { if (argc == 1 || (argc == 2 && (!strcmp(argv[1], "--help") || (!strcmp(argv[1], "-?"))))) @@ -258,12 +72,6 @@ int main(int argc, const char* argv[]) return 0; } - if (argc == 2 && !strcmp(argv[1], "test")) - { - RunAsmTests(); - return 0; - } - std::string input_name; std::string output_header_name; std::string output_name; diff --git a/Source/DSPTool/Testdata/dsp_test.bin b/Source/DSPTool/Testdata/dsp_test.bin deleted file mode 100644 index 4726300d235280f467ea19f7805636c5bf9cd38f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1072 zcmb_bOHUL*5U%dt2P}_SSa#W>W@)|1Kk#PYWMX0h7rgi+9z1x^qXz@C#+W5UG|EAV zF#ZAl0YMT^#DEtsBJOhYz(IVYF4I=`%pxK2<|I{L_t#ZjkLi-3I4?tSndK_WHJ0lv zH&_Cey9HTLy{SUFkeLN|1ZEnlAYX{lQnOYo?bnw|zd`VR{De^>QwEGT36VDiPXOR4 z%lt8bE#~Up6k84d^<4S*FHbLsJs~*k34vEdff5y_FpU|^VjH$&4m+?DyRaKQ%wrGs zVgdWGh$ZaDG9nHjp^p_DL=CHabMoD@HOz5+C!wxBxi#djSo9~Yb~VmTJ1Yp`x#e1x z7aiL@X1T1>@}^zKJZ!4Zc9%qW2p`z*i)Ai2KlvDzWeB_QPW`YfEC!B09iN8q=IF^e zcLI_6X6^N+)wdm|FS#3{IHJ3?uD)6>&V^&GB{jT{y^Ho=CDp-}`tJN^Aaoey+^y|S z_l${3`IhC+y1gGc8*R0IYc-V}6UKehFYPX_k#luDg=Q;)G0wKteuv!sQ_wUU5SiDo zXV&4TS%Y8Z)zF$+g_K+nXJlijsaCl^3u2Vlky}3#-&d;OT(V?j$*5X0LTB$j+1UqKmzEe03+x&X?4U!;9ic*xO3}vZ}+9^jJ z)Ja{`O&;Z`hkB_%eN?0p^;4OU28hU~3JsD@=0d={JeUg}s60%F4erpe1POXiaX_tY zzRV?)7VR9Fm;W*kvN7xa?gQYS-r<0Yd4MX*ge>}#!LHu+B_}`P>y+SZ8UTL)kTM=| diff --git a/Source/DSPTool/Testdata/hermes.bin b/Source/DSPTool/Testdata/hermes.bin deleted file mode 100644 index 0f6f9dd42ad20d3243a902b0dff9750a0dc7c439..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1472 zcmZ`(U2Kz87=F(CmC@=2W&3DX_LbAE+p71wApz6GOC`aCgv1RrF)dF-(#2AeiR_S_t&ev8t32ol-mjN_}#oS&y|r(U8?Q_nfR^icoi_-$`fpK|<-MJ zenJvI!$TQcoGcs%>IZMs>F`E_$XjF{DVddC<`m;T;uj#FsdRlejI*8JIq|#|uZp|q z!~zn*p17YeOaV)1r)7s_sol@vdFTovh#a%uFAv-C6)C9g!@%!k*3c1V-PG>pmrllt ztmJh$j+;o~7P^_$61LK3*A(=_aaL2^ki#73Ff7r|9S7k~yOmcV{-}}D>Im}G1$9h( zcFKFm`{;V9bH_XDSrZM`iB=Y~U&c1pML&tTi@Va_jU(QMKe%R~c}JrAEP7i{;77QJ zVQZmFa)xW)%JDj%nanjUER(rE(&uQ{mKOG4{UKs~fI zvg@|S)NOh-G31=#P5IERxRZKB4_P!Z#LTix`y)5pKnC?-urioPom-h`(YJv{KNiv3@_-Gpwroh(TJ+|w|yJfHG-;HYu@32*-tdX^G@-$ zbbER48=hz{u|8s*#1hH<$q`~b#L~oK#NyO1P`?;-o9)+mgya|YN)IJX>812Z88!1g zBi_S(vxvV<5f!tLDF*CWIU?mu)tP5E%<}yzXKKOx3-P6_C)^L*4R}zujxAy!wt!TB zk#`_O_9={GfUG;Nkt{Z`@6QS_;O&ne3T#%*y{Bx>S)2GFG3)=f2Bs!&`tY`mL88pI Z%B + +static bool RoundTrippableDissassemble(const std::vector& code, std::string& text) +{ + DSP::AssemblerSettings settings; + settings.ext_separator = '\''; + settings.decode_names = true; + settings.decode_registers = true; + // These two prevent roundtripping. + settings.show_hex = false; + settings.show_pc = false; + DSP::DSPDisassembler disasm(settings); + + return disasm.Disassemble(0x0000, code, 0x0000, text); +} + +// This test goes from text ASM to binary to text ASM and once again back to binary. +// Then the two binaries are compared. +static bool RoundTrip(const std::vector& code1) +{ + std::vector code2; + std::string text; + if (!RoundTrippableDissassemble(code1, text)) + { + printf("RoundTrip: Disassembly failed.\n"); + return false; + } + if (!DSP::Assemble(text, code2)) + { + printf("RoundTrip: Assembly failed.\n"); + return false; + } + if (!DSP::Compare(code1, code2)) + { + DSP::Disassemble(code1, true, text); + printf("%s", text.c_str()); + } + return true; +} + +// This test goes from text ASM to binary to text ASM and once again back to binary. +// Very convenient for testing. Then the two binaries are compared. +static bool SuperTrip(const char* asm_code) +{ + std::vector code1, code2; + std::string text; + if (!DSP::Assemble(asm_code, code1)) + { + printf("SuperTrip: First assembly failed\n"); + return false; + } + printf("First assembly: %i words\n", (int)code1.size()); + + if (!RoundTrippableDissassemble(code1, text)) + { + printf("SuperTrip: Disassembly failed\n"); + return false; + } + else + { + printf("Disassembly:\n"); + printf("%s", text.c_str()); + } + + if (!DSP::Assemble(text, code2)) + { + printf("SuperTrip: Second assembly failed\n"); + return false; + } + return true; +} + +// Let's start out easy - a trivial instruction.. +TEST(DSPAssembly, TrivialInstruction) +{ + ASSERT_TRUE(SuperTrip(" NOP\n")); +} + +// Now let's do several. +TEST(DSPAssembly, SeveralTrivialInstructions) +{ + ASSERT_TRUE(SuperTrip(" NOP\n" + " NOP\n" + " NOP\n")); +} + +// Turning it up a notch. +TEST(DSPAssembly, SeveralNoParameterInstructions) +{ + ASSERT_TRUE(SuperTrip(" SET16\n" + " SET40\n" + " CLR15\n" + " M0\n" + " M2\n")); +} + +// Time to try labels and parameters, and comments. +TEST(DSPAssembly, LabelsParametersAndComments) +{ + ASSERT_TRUE(SuperTrip("DIRQ_TEST: equ 0xfffb ; DSP Irq Request\n" + " si @0xfffc, #0x8888\n" + " si @0xfffd, #0xbeef\n" + " si @DIRQ_TEST, #0x0001\n")); +} + +// Let's see if registers roundtrip. Also try predefined labels. +TEST(DSPAssembly, RegistersAndPredefinedLabels) +{ + ASSERT_TRUE(SuperTrip(" si @0xfffc, #0x8888\n" + " si @0xfffd, #0xbeef\n" + " si @DIRQ, #0x0001\n")); +} + +// Let's try some messy extended instructions. +TEST(DSPAssembly, ExtendedInstructions) +{ + ASSERT_TRUE(SuperTrip(" MULMV'SN $AX0.L, $AX0.H, $ACC0 : @$AR2, $AC1.M\n" + " ADDAXL'MV $ACC1, $AX1.L : $AX1.H, $AC1.M\n")); +} + +TEST(DSPAssembly, HermesBinary) +{ + ASSERT_TRUE(RoundTrip(s_hermes_bin)); +} + +TEST(DSPAssembly, DSPTestText) +{ + ASSERT_TRUE(SuperTrip(s_dsp_test_text)); +} + +TEST(DSPAssembly, DSPTestBinary) +{ + ASSERT_TRUE(RoundTrip(s_dsp_test_bin)); +} + +/* + +if (File::ReadFileToString("C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test)) + SuperTrip(dsp_test.c_str()); + +//.File::ReadFileToString("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. +*/ diff --git a/Source/UnitTests/Core/DSP/DSPTestBinary.cpp b/Source/UnitTests/Core/DSP/DSPTestBinary.cpp new file mode 100644 index 0000000000..5f64d4c113 --- /dev/null +++ b/Source/UnitTests/Core/DSP/DSPTestBinary.cpp @@ -0,0 +1,52 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DSPTestBinary.h" + +const std::vector s_dsp_test_bin = { + 0x029f, 0x015b, 0x029f, 0x015f, 0x029f, 0x0163, 0x029f, 0x0167, 0x029f, 0x016b, 0x029f, 0x016f, + 0x029f, 0x0180, 0x029f, 0x0184, 0x1302, 0x1303, 0x1204, 0x1305, 0x1306, 0x8e00, 0x0092, 0x00ff, + 0x8900, 0x8100, 0x02bf, 0x014f, 0x16fc, 0x8888, 0x16fd, 0xdead, 0x16fb, 0x0001, 0x02bf, 0x0155, + 0x26ff, 0x0340, 0x7fff, 0x00ff, 0x0f7e, 0x00fe, 0x0f7f, 0x0098, 0x0000, 0x0099, 0x0000, 0x009a, + 0x2000, 0x00dc, 0x0f7e, 0x00de, 0x0f7f, 0x02bf, 0x013f, 0x02bf, 0x014f, 0x16fc, 0x8888, 0x16fd, + 0xbeef, 0x16fb, 0x0001, 0x02bf, 0x0155, 0x26ff, 0x0340, 0x7fff, 0x00ff, 0x0f7e, 0x00fe, 0x0f7f, + 0x0098, 0x0f80, 0x0099, 0x0000, 0x009a, 0x0080, 0x00dc, 0x0f7e, 0x00de, 0x0f7f, 0x02bf, 0x013f, + 0x0080, 0x0f81, 0x1901, 0x1902, 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x1908, 0x1909, 0x190a, + 0x190b, 0x190c, 0x190d, 0x190e, 0x190f, 0x1910, 0x1911, 0x1912, 0x1913, 0x1914, 0x1915, 0x1916, + 0x1917, 0x1918, 0x1919, 0x191a, 0x191b, 0x191c, 0x191d, 0x191e, 0x191f, 0x00c0, 0x0f80, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8600, 0x02bf, 0x0194, 0x029f, 0x0136, 0x00de, 0x03f1, 0x02bf, 0x0194, + 0x0200, 0x0a60, 0x02bf, 0x0194, 0x1c7e, 0x02bf, 0x0194, 0x8100, 0x02bf, 0x0194, 0x8900, 0x02bf, + 0x0194, 0x009f, 0x00a0, 0x02bf, 0x0194, 0x00de, 0x03f1, 0x02bf, 0x0194, 0x5d00, 0x02bf, 0x0194, + 0x0e50, 0x02bf, 0x0194, 0x0750, 0x02bf, 0x0194, 0x0270, 0x02bf, 0x0194, 0x5d00, 0x02bf, 0x0194, + 0x00da, 0x03f2, 0x02bf, 0x0194, 0x8600, 0x02bf, 0x0194, 0x0290, 0x00e7, 0x00de, 0x03f3, 0x02bf, + 0x0194, 0x5c00, 0x02bf, 0x0194, 0x0293, 0x00bc, 0x029f, 0x00f0, 0x00db, 0x03f7, 0x02bf, 0x0194, + 0x009e, 0x8000, 0x02bf, 0x0194, 0x4600, 0x02bf, 0x0194, 0x029f, 0x00d4, 0x00db, 0x03f7, 0x02bf, + 0x0194, 0x009e, 0x8000, 0x02bf, 0x0194, 0x5600, 0x02bf, 0x0194, 0x00fe, 0x03f5, 0x02bf, 0x0194, + 0x1fda, 0x02bf, 0x0194, 0x7c00, 0x02bf, 0x0194, 0x1f5e, 0x02bf, 0x0194, 0x00fe, 0x03f2, 0x02bf, + 0x0194, 0x029f, 0x00f0, 0x00de, 0x03f4, 0x02bf, 0x0194, 0x5d00, 0x02bf, 0x0194, 0x0293, 0x00c9, + 0x8900, 0x02bf, 0x0194, 0x00dd, 0x03f5, 0x02bf, 0x0194, 0x1501, 0x02bf, 0x0194, 0x8100, 0x02bf, + 0x0194, 0x00dc, 0x03f6, 0x02bf, 0x0194, 0x008b, 0x009f, 0x02bf, 0x0194, 0x0080, 0x0a00, 0x02bf, + 0x0194, 0x0900, 0x02bf, 0x0194, 0x1150, 0x011d, 0x1878, 0x02bf, 0x0194, 0x4c00, 0x02bf, 0x0194, + 0x1cfe, 0x02bf, 0x0194, 0x001f, 0x02bf, 0x0194, 0x1fd9, 0x02bf, 0x0194, 0x1b18, 0x02bf, 0x0194, + 0x009f, 0x0a60, 0x02bf, 0x0194, 0x1fc3, 0x02bf, 0x0194, 0x5c00, 0x02bf, 0x0194, 0x00fe, 0x03f1, + 0x02bf, 0x0194, 0x00fc, 0x03f6, 0x02bf, 0x0194, 0x008b, 0xffff, 0x02bf, 0x0194, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x029f, 0x013d, 0x00fc, 0xffce, 0x00fe, 0xffcf, 0x00f8, + 0xffcd, 0x00f9, 0xffc9, 0x00fa, 0xffcb, 0x27c9, 0x03c0, 0x0004, 0x029d, 0x0149, 0x02df, 0x27fc, + 0x03c0, 0x8000, 0x029d, 0x014f, 0x02df, 0x27fe, 0x03c0, 0x8000, 0x029c, 0x0155, 0x02df, 0x009e, + 0x0000, 0x029f, 0x0188, 0x009e, 0x0001, 0x029f, 0x0188, 0x009e, 0x0002, 0x029f, 0x0188, 0x009e, + 0x0003, 0x029f, 0x0188, 0x009e, 0x0004, 0x029f, 0x0188, 0x8e00, 0x1dbc, 0x1dbe, 0x8100, 0x1fcd, + 0x1f8d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02ff, 0x009e, 0x0005, 0x029f, 0x0188, + 0x009e, 0x0006, 0x029f, 0x0188, 0x009e, 0x0007, 0x029f, 0x0188, 0x27fc, 0x03c0, 0x8000, 0x029d, + 0x0188, 0x16fc, 0x8bad, 0x00eb, 0xfffd, 0x16fb, 0x0001, 0x0021, 0x00e0, 0x0f80, 0x0080, 0x0f81, + 0x1b01, 0x1b02, 0x1b03, 0x1b04, 0x1b05, 0x1b06, 0x1b07, 0x1b08, 0x1b09, 0x1b0a, 0x1b0b, 0x1b0c, + 0x1b0d, 0x1b0e, 0x1b0f, 0x1b10, 0x1b11, 0x1b12, 0x1b13, 0x1b14, 0x1b15, 0x1b16, 0x1b17, 0x1b18, + 0x1b19, 0x1b1a, 0x1b1b, 0x1b1c, 0x1b1d, 0x1b1e, 0x1b1f, 0x0098, 0x0000, 0x0099, 0x0001, 0x009a, + 0x0200, 0x00dc, 0x0f7e, 0x00de, 0x0f7f, 0x0081, 0x0010, 0x0061, 0x01ce, 0x02bf, 0x013f, 0x0200, + 0x0200, 0x1ff8, 0x0300, 0x0100, 0x1f1f, 0x0000, 0x0000, 0x02bf, 0x014f, 0x16fc, 0x8888, 0x16fd, + 0xfeeb, 0x16fb, 0x0001, 0x02bf, 0x0155, 0x26ff, 0x0340, 0x7fff, 0x0080, 0x0f81, 0x1901, 0x1902, + 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x1908, 0x1909, 0x190a, 0x190b, 0x190c, 0x190d, 0x190e, + 0x190f, 0x1910, 0x1911, 0x1912, 0x1913, 0x1914, 0x1915, 0x1916, 0x1917, 0x1918, 0x1919, 0x191a, + 0x191b, 0x191c, 0x191d, 0x191e, 0x191f, 0x00c0, 0x0f80, 0x02df, 0x8e00, 0x02bf, 0x0194, 0x8f00, + 0x02df, 0x0082, 0x0000, 0x009e, 0x1000, 0x0081, 0x1000, 0x0061, 0x0215, 0x1c7e, 0x80f0, 0x1fe0, + 0x1c02, 0x1b1b, 0x1c40, 0x1c1f, 0x0401, 0x0000, 0x02df, 0x0000}; diff --git a/Source/UnitTests/Core/DSP/DSPTestBinary.h b/Source/UnitTests/Core/DSP/DSPTestBinary.h new file mode 100644 index 0000000000..ec1a1f6c0a --- /dev/null +++ b/Source/UnitTests/Core/DSP/DSPTestBinary.h @@ -0,0 +1,11 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "Common/CommonTypes.h" + +#include + +extern const std::vector s_dsp_test_bin; diff --git a/Source/DSPTool/Testdata/dsp_test.S b/Source/UnitTests/Core/DSP/DSPTestText.cpp similarity index 97% rename from Source/DSPTool/Testdata/dsp_test.S rename to Source/UnitTests/Core/DSP/DSPTestText.cpp index 2c4f4f4d56..6a6fdec382 100644 --- a/Source/DSPTool/Testdata/dsp_test.S +++ b/Source/UnitTests/Core/DSP/DSPTestText.cpp @@ -1,4 +1,10 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. +#include "DSPTestText.h" + +const char s_dsp_test_text[8434] = R"( DSCR: equ 0xffc9 ; DSP DMA Control Reg DSBL: equ 0xffcb ; DSP DMA Block Length DSPA: equ 0xffcd ; DSP DMA DMEM Address @@ -637,3 +643,4 @@ _fill_loop2: ret +)"; diff --git a/Source/UnitTests/Core/DSP/DSPTestText.h b/Source/UnitTests/Core/DSP/DSPTestText.h new file mode 100644 index 0000000000..c938b03c8a --- /dev/null +++ b/Source/UnitTests/Core/DSP/DSPTestText.h @@ -0,0 +1,9 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +extern const char s_dsp_test_text[8434]; diff --git a/Source/UnitTests/Core/DSP/HermesBinary.cpp b/Source/UnitTests/Core/DSP/HermesBinary.cpp new file mode 100644 index 0000000000..b6f7ae969c --- /dev/null +++ b/Source/UnitTests/Core/DSP/HermesBinary.cpp @@ -0,0 +1,69 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "HermesBinary.h" + +const std::vector s_hermes_bin = { + 0x029f, 0x02b3, 0x029f, 0x02b4, 0x029f, 0x02b5, 0x029f, 0x02b6, 0x029f, 0x02b7, 0x029f, 0x02b8, + 0x029f, 0x02b9, 0x029f, 0x02ba, 0x0092, 0x00ff, 0x0093, 0x0000, 0x8e00, 0x8c00, 0x8b00, 0x16fc, + 0xdcd1, 0x16fd, 0x0000, 0x16fb, 0x0001, 0x02bf, 0x027a, 0x02bf, 0x0280, 0x16fc, 0xdcd1, 0x8100, + 0x009e, 0xcdd1, 0x8200, 0x0295, 0x0057, 0x8900, 0x27ff, 0x0380, 0x0111, 0x0295, 0x00af, 0x0380, + 0x0112, 0x0295, 0x00d0, 0x0380, 0x0123, 0x0295, 0x00a2, 0x0380, 0x0222, 0x0295, 0x00ee, 0x0380, + 0x0666, 0x0295, 0x0091, 0x0380, 0x0777, 0x0295, 0x02bb, 0x0380, 0x0888, 0x0295, 0x02ca, 0x0380, + 0x0999, 0x0295, 0x0051, 0x16fd, 0x0004, 0x16fb, 0x0001, 0x029f, 0x001d, 0x16fd, 0x0003, 0x16fb, + 0x0001, 0x029f, 0x001d, 0x8900, 0x27ff, 0x0380, 0x0001, 0x0295, 0x0063, 0x0380, 0x0002, 0x0295, + 0x8000, 0x029f, 0x001d, 0x8e00, 0x02bf, 0x0280, 0x25ff, 0x02bf, 0x0280, 0x25ff, 0x02bf, 0x0280, + 0x25ff, 0x02bf, 0x0280, 0x00c5, 0xffff, 0x0340, 0x0fff, 0x1c9f, 0x02bf, 0x0280, 0x00c7, 0xffff, + 0x02bf, 0x0280, 0x00c6, 0xffff, 0x02bf, 0x0280, 0x00c0, 0xffff, 0x02bf, 0x0280, 0x20ff, 0x0340, + 0x0fff, 0x1f5f, 0x02bf, 0x0280, 0x21ff, 0x02bf, 0x0280, 0x23ff, 0x1205, 0x1206, 0x029f, 0x80b5, + 0x0021, 0x0080, 0x0054, 0x0901, 0x0098, 0x1000, 0x00de, 0x0010, 0x00dc, 0x0011, 0x02bf, 0x026a, + 0x16fd, 0x0004, 0x16fb, 0x0001, 0x029f, 0x001d, 0x02bf, 0x0280, 0x26fe, 0x00dc, 0xffff, 0x00fe, + 0x0000, 0x00fc, 0x0001, 0x16fb, 0x0000, 0x029f, 0x001d, 0x8100, 0x00de, 0x0000, 0x00dc, 0x0001, + 0x0804, 0x00f8, 0x0002, 0x16fb, 0x0000, 0x0080, 0x0010, 0x0900, 0x0840, 0x02bf, 0x026a, 0x0081, + 0x0054, 0x009d, 0x0000, 0x0098, 0x0400, 0x0078, 0x00c9, 0x1b3d, 0x1b3d, 0x0000, 0x00de, 0x0010, + 0x00dc, 0x0011, 0x029f, 0x00fe, 0x8100, 0x00de, 0x0000, 0x00dc, 0x0001, 0x0804, 0x00f8, 0x0002, + 0x16fb, 0x0000, 0x0080, 0x0010, 0x0099, 0x0000, 0x0840, 0x02bf, 0x026a, 0x00de, 0x0010, 0x00dc, + 0x0011, 0x0080, 0x0054, 0x0900, 0x0098, 0x1000, 0x02bf, 0x026a, 0x029f, 0x00fe, 0x8100, 0x00de, + 0x0000, 0x00dc, 0x0001, 0x0804, 0x00f8, 0x0002, 0x16fb, 0x0000, 0x0080, 0x0010, 0x0900, 0x0840, + 0x02bf, 0x026a, 0x0088, 0xbb80, 0x00da, 0x001d, 0x00db, 0x001c, 0x00df, 0x0015, 0x0340, 0x0003, + 0x0300, 0x01d8, 0x1c7f, 0x0313, 0x1c7f, 0x8100, 0x00de, 0x0015, 0x02c0, 0x0020, 0x029d, 0x0224, + 0x00de, 0x0016, 0x00dc, 0x0017, 0xb100, 0x0294, 0x0123, 0x0804, 0x00f8, 0x0002, 0x02bf, 0x0239, + 0xb100, 0x0295, 0x021c, 0x1cde, 0x1cfc, 0x00ca, 0x0018, 0x00cb, 0x0019, 0x0081, 0x0054, 0x0098, + 0x0400, 0x8100, 0x8900, 0x00d0, 0x0012, 0x00de, 0x0013, 0xb100, 0x0295, 0x0150, 0x0a00, 0x0b00, + 0x1ff8, 0x0009, 0x0009, 0x7900, 0x0295, 0x0143, 0x7800, 0x0295, 0x014b, 0x029f, 0x0139, 0x7800, + 0x00f0, 0x0012, 0x00fe, 0x0013, 0x0800, 0x029f, 0x0150, 0x00f0, 0x0012, 0x00fe, 0x0013, 0x1f1d, + 0x16c9, 0x0000, 0x02bf, 0x0286, 0x00c4, 0x0020, 0x00c5, 0x0021, 0x8100, 0x00d0, 0x001a, 0x00de, + 0x001b, 0x8900, 0x1fe8, 0x8200, 0x0080, 0x01c3, 0x0272, 0x0080, 0x01a2, 0x0078, 0x0210, 0x183c, + 0x6b00, 0x1498, 0x14f8, 0x4c00, 0x0280, 0x7fff, 0x0293, 0x0174, 0x009e, 0x7fff, 0x029f, 0x0179, + 0x0280, 0x8000, 0x0273, 0x009e, 0x8000, 0x1b3e, 0x183c, 0x6900, 0x1498, 0x14f8, 0x4c00, 0x0280, + 0x7fff, 0x0293, 0x0187, 0x009e, 0x7fff, 0x029f, 0x018c, 0x0280, 0x8000, 0x0273, 0x009e, 0x8000, + 0x1b3e, 0x8900, 0x00d1, 0x001e, 0x00df, 0x001f, 0x8100, 0x00d0, 0x001a, 0x00de, 0x001b, 0x4d00, + 0x8100, 0x1fc8, 0x8200, 0x1706, 0x00f1, 0x001e, 0x00ff, 0x001f, 0x029f, 0x0210, 0x5d00, 0x8100, + 0x1fc6, 0x1f87, 0x00d9, 0x0014, 0x7200, 0x1cde, 0x1cfc, 0x1fdc, 0x02a0, 0x001f, 0x02bd, 0x0286, + 0x8100, 0x1fc8, 0x8200, 0x0293, 0x01a2, 0x00f1, 0x001e, 0x00ff, 0x001f, 0x1fc6, 0x1f87, 0x8900, + 0x1fea, 0x1fab, 0x8200, 0x0297, 0x01dc, 0x029f, 0x0299, 0x5d00, 0x00f1, 0x001e, 0x00ff, 0x001f, + 0x8100, 0x1fc6, 0x1f87, 0x00d9, 0x0014, 0x7200, 0x8900, 0x1fea, 0x1fab, 0x8200, 0x0297, 0x01dc, + 0x1cde, 0x1cfc, 0x029f, 0x0299, 0x01ec, 0x0200, 0x01f7, 0x0204, 0x0804, 0x00f8, 0x0002, 0x02bf, + 0x0239, 0xb100, 0x0295, 0x01e8, 0x02bf, 0x0286, 0x029f, 0x0299, 0x0a00, 0x0b00, 0x029f, 0x0206, + 0x1fe7, 0x195c, 0x03a0, 0x0001, 0x027d, 0x14f8, 0x1488, 0x1f7c, 0x1f5c, 0x029f, 0x0206, 0x195c, + 0x1fdc, 0x0240, 0xff00, 0x1f7e, 0x1408, 0x1f5c, 0x029f, 0x0206, 0x195b, 0x1f5b, 0x029f, 0x0206, + 0x195b, 0x195a, 0x1f04, 0x9000, 0x6e00, 0x14f8, 0x1f5c, 0x1f25, 0x9800, 0x6e00, 0x14f8, 0x1f7c, + 0x0000, 0x8100, 0x1fc6, 0x1f87, 0xb100, 0x0294, 0x021c, 0x0804, 0x00f8, 0x0002, 0x02bf, 0x0239, + 0x00e6, 0x0016, 0x00e7, 0x0017, 0x00fa, 0x001d, 0x00fb, 0x001c, 0x8100, 0x00de, 0x0000, 0x00dc, + 0x0001, 0x0080, 0x0010, 0x0901, 0x0840, 0x02bf, 0x026a, 0x16fc, 0xdcd1, 0x00dc, 0x0002, 0x00fc, + 0xfffd, 0x16fb, 0x0001, 0x029f, 0x001d, 0x8100, 0x00de, 0x0026, 0x00dc, 0x0027, 0x00fe, 0x0020, + 0x00fc, 0x0021, 0x1c9e, 0x1cbc, 0x00de, 0x0024, 0x00dc, 0x0025, 0x00fe, 0x0018, 0x00fc, 0x0019, + 0x1d5e, 0x1d7c, 0x00de, 0x0022, 0x00dc, 0x0023, 0x00fe, 0x0016, 0x00fc, 0x0017, 0x00fe, 0x0028, + 0x00fc, 0x0029, 0x1cde, 0x1cfc, 0x00df, 0x0015, 0x03c0, 0x0004, 0x02dd, 0x00f0, 0x0022, 0x00f0, + 0x0023, 0x00f0, 0x0024, 0x00f0, 0x0025, 0x02df, 0x00fe, 0xffce, 0x00fc, 0xffcf, 0x00e0, 0xffcd, + 0x00f9, 0xffc9, 0x00f8, 0xffcb, 0x27c9, 0x03c0, 0x0004, 0x029d, 0x0274, 0x02df, 0x27fc, 0x03c0, + 0x8000, 0x029d, 0x027a, 0x02df, 0x27fe, 0x03c0, 0x8000, 0x029c, 0x0280, 0x02df, 0x1f87, 0x147b, + 0x1405, 0x00e6, 0xffce, 0x00fc, 0xffcf, 0x16cd, 0x0034, 0x16cb, 0x0020, 0x26c9, 0x02c0, 0x0004, + 0x029d, 0x0291, 0x0082, 0x0034, 0x02df, 0x1fc7, 0x14ff, 0x0240, 0x000f, 0x0295, 0x02a3, 0x0200, + 0x0034, 0x1c5e, 0x176f, 0x00e6, 0xffce, 0x00e7, 0xffcf, 0x16cd, 0x0034, 0x16cb, 0x0020, 0x26c9, + 0x02c0, 0x0004, 0x029d, 0x02ab, 0x0082, 0x0034, 0x176f, 0x02ff, 0x02ff, 0x02ff, 0x02ff, 0x02ff, + 0x02ff, 0x02ff, 0x02ff, 0x8100, 0x00de, 0xfffe, 0x0260, 0x8000, 0x1c1e, 0x8100, 0x0210, 0x00fc, + 0xfffc, 0x00fe, 0xfffd, 0x8100, 0x029f, 0x001d, 0x8100, 0x009e, 0x0000, 0x02a0, 0x0001, 0x00f3, + 0xfffc, 0x00fe, 0xfffd, 0x8100, 0x029f, 0x001d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000}; diff --git a/Source/UnitTests/Core/DSP/HermesBinary.h b/Source/UnitTests/Core/DSP/HermesBinary.h new file mode 100644 index 0000000000..227807c00d --- /dev/null +++ b/Source/UnitTests/Core/DSP/HermesBinary.h @@ -0,0 +1,11 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "Common/CommonTypes.h" + +#include + +extern const std::vector s_hermes_bin; diff --git a/Source/DSPTool/Testdata/hermes.s b/Source/UnitTests/Core/DSP/hermes.s similarity index 100% rename from Source/DSPTool/Testdata/hermes.s rename to Source/UnitTests/Core/DSP/hermes.s diff --git a/Source/UnitTests/UnitTests.vcxproj b/Source/UnitTests/UnitTests.vcxproj index dbab85e8fc..a0d9c67f24 100644 --- a/Source/UnitTests/UnitTests.vcxproj +++ b/Source/UnitTests/UnitTests.vcxproj @@ -59,6 +59,7 @@ + From 1765e54ab3e084334179e5540066cb5bbf62ee33 Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Fri, 19 May 2017 19:16:22 -0700 Subject: [PATCH 3/4] DSPCodeUtil: remove GenRandomCode It was only used in a specific DSPTool test, which was removed because non-deterministic tests aren't really useful. --- Source/Core/Core/DSP/DSPCodeUtil.cpp | 9 --------- Source/Core/Core/DSP/DSPCodeUtil.h | 1 - 2 files changed, 10 deletions(-) diff --git a/Source/Core/Core/DSP/DSPCodeUtil.cpp b/Source/Core/Core/DSP/DSPCodeUtil.cpp index 4db6f47c53..db8e6f6b24 100644 --- a/Source/Core/Core/DSP/DSPCodeUtil.cpp +++ b/Source/Core/Core/DSP/DSPCodeUtil.cpp @@ -100,15 +100,6 @@ bool Compare(const std::vector& code1, const std::vector& code2) return code1.size() == code2.size() && code1.size() == count_equal; } -void GenRandomCode(u32 size, std::vector& code) -{ - code.resize(size); - for (u32 i = 0; i < size; i++) - { - code[i] = rand() ^ (rand() << 8); - } -} - void CodeToHeader(const std::vector& code, std::string _filename, const char* name, std::string& header) { diff --git a/Source/Core/Core/DSP/DSPCodeUtil.h b/Source/Core/Core/DSP/DSPCodeUtil.h index 5fe8d64f30..a4906746ac 100644 --- a/Source/Core/Core/DSP/DSPCodeUtil.h +++ b/Source/Core/Core/DSP/DSPCodeUtil.h @@ -14,7 +14,6 @@ namespace DSP bool Assemble(const std::string& text, std::vector& code, bool force = false); bool Disassemble(const std::vector& code, bool line_numbers, std::string& text); bool Compare(const std::vector& code1, const std::vector& code2); -void GenRandomCode(u32 size, std::vector& code); void CodeToHeader(const std::vector& code, std::string _filename, const char* name, std::string& header); void CodesToHeader(const std::vector* codes, const std::vector* filenames, From 97e6ba773b3dae4167f8cf383df94d40eaaeac5b Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Fri, 19 May 2017 19:18:17 -0700 Subject: [PATCH 4/4] Move DSP::CodesToHeader to DSPTool It's the only place it's used, and highly-specific to DSPTool's needs. --- Source/Core/Core/DSP/DSPCodeUtil.cpp | 73 -------------------------- Source/Core/Core/DSP/DSPCodeUtil.h | 4 -- Source/DSPTool/DSPTool.cpp | 77 +++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 79 deletions(-) diff --git a/Source/Core/Core/DSP/DSPCodeUtil.cpp b/Source/Core/Core/DSP/DSPCodeUtil.cpp index db8e6f6b24..cef0e12f63 100644 --- a/Source/Core/Core/DSP/DSPCodeUtil.cpp +++ b/Source/Core/Core/DSP/DSPCodeUtil.cpp @@ -100,79 +100,6 @@ bool Compare(const std::vector& code1, const std::vector& code2) return code1.size() == code2.size() && code1.size() == count_equal; } -void CodeToHeader(const std::vector& code, std::string _filename, const char* name, - std::string& header) -{ - std::vector code_padded = code; - // Pad with nops to 32byte boundary - while (code_padded.size() & 0x7f) - code_padded.push_back(0); - header.clear(); - header.reserve(code_padded.size() * 4); - header.append("#define NUM_UCODES 1\n\n"); - std::string filename; - SplitPath(_filename, nullptr, &filename, nullptr); - header.append( - StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", filename.c_str())); - header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n"); - - header.append("\t{\n\t\t"); - for (u32 j = 0; j < code_padded.size(); j++) - { - if (j && ((j & 15) == 0)) - header.append("\n\t\t"); - header.append(StringFromFormat("0x%04x, ", code_padded[j])); - } - header.append("\n\t},\n"); - - header.append("};\n"); -} - -void CodesToHeader(const std::vector* codes, const std::vector* filenames, - u32 numCodes, const char* name, std::string& header) -{ - std::vector> codes_padded; - u32 reserveSize = 0; - for (u32 i = 0; i < numCodes; i++) - { - codes_padded.push_back(codes[i]); - // Pad with nops to 32byte boundary - while (codes_padded.at(i).size() & 0x7f) - codes_padded.at(i).push_back(0); - - reserveSize += (u32)codes_padded.at(i).size(); - } - header.clear(); - header.reserve(reserveSize * 4); - header.append(StringFromFormat("#define NUM_UCODES %u\n\n", numCodes)); - header.append("const char* UCODE_NAMES[NUM_UCODES] = {\n"); - for (u32 i = 0; i < numCodes; i++) - { - std::string filename; - if (!SplitPath(filenames->at(i), nullptr, &filename, nullptr)) - filename = filenames->at(i); - header.append(StringFromFormat("\t\"%s\",\n", filename.c_str())); - } - header.append("};\n\n"); - header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n"); - - for (u32 i = 0; i < numCodes; i++) - { - if (codes[i].size() == 0) - continue; - - header.append("\t{\n\t\t"); - for (u32 j = 0; j < codes_padded.at(i).size(); j++) - { - if (j && ((j & 15) == 0)) - header.append("\n\t\t"); - header.append(StringFromFormat("0x%04x, ", codes_padded.at(i).at(j))); - } - header.append("\n\t},\n"); - } - header.append("};\n"); -} - void CodeToBinaryStringBE(const std::vector& code, std::string& str) { str.resize(code.size() * 2); diff --git a/Source/Core/Core/DSP/DSPCodeUtil.h b/Source/Core/Core/DSP/DSPCodeUtil.h index a4906746ac..08dc8edd2d 100644 --- a/Source/Core/Core/DSP/DSPCodeUtil.h +++ b/Source/Core/Core/DSP/DSPCodeUtil.h @@ -14,10 +14,6 @@ namespace DSP bool Assemble(const std::string& text, std::vector& code, bool force = false); bool Disassemble(const std::vector& code, bool line_numbers, std::string& text); bool Compare(const std::vector& code1, const std::vector& code2); -void CodeToHeader(const std::vector& code, std::string _filename, const char* name, - std::string& header); -void CodesToHeader(const std::vector* codes, const std::vector* filenames, - u32 numCodes, const char* name, std::string& header); // Big-endian, for writing straight to file using File::WriteStringToFile. void CodeToBinaryStringBE(const std::vector& code, std::string& str); diff --git a/Source/DSPTool/DSPTool.cpp b/Source/DSPTool/DSPTool.cpp index de400f88dd..505750cd7a 100644 --- a/Source/DSPTool/DSPTool.cpp +++ b/Source/DSPTool/DSPTool.cpp @@ -39,6 +39,79 @@ void DSP::Host::UpdateDebugger() { } +static void CodeToHeader(const std::vector& code, std::string filename, const char* name, + std::string& header) +{ + std::vector code_padded = code; + // Pad with nops to 32byte boundary + while (code_padded.size() & 0x7f) + code_padded.push_back(0); + header.clear(); + header.reserve(code_padded.size() * 4); + header.append("#define NUM_UCODES 1\n\n"); + std::string filename_without_extension; + SplitPath(filename, nullptr, &filename_without_extension, nullptr); + header.append(StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", + filename_without_extension.c_str())); + header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n"); + + header.append("\t{\n\t\t"); + for (u32 j = 0; j < code_padded.size(); j++) + { + if (j && ((j & 15) == 0)) + header.append("\n\t\t"); + header.append(StringFromFormat("0x%04x, ", code_padded[j])); + } + header.append("\n\t},\n"); + + header.append("};\n"); +} + +static void CodesToHeader(const std::vector* codes, const std::vector* filenames, + u32 num_codes, const char* name, std::string& header) +{ + std::vector> codes_padded; + u32 reserveSize = 0; + for (u32 i = 0; i < num_codes; i++) + { + codes_padded.push_back(codes[i]); + // Pad with nops to 32byte boundary + while (codes_padded.at(i).size() & 0x7f) + codes_padded.at(i).push_back(0); + + reserveSize += (u32)codes_padded.at(i).size(); + } + header.clear(); + header.reserve(reserveSize * 4); + header.append(StringFromFormat("#define NUM_UCODES %u\n\n", num_codes)); + header.append("const char* UCODE_NAMES[NUM_UCODES] = {\n"); + for (u32 i = 0; i < num_codes; i++) + { + std::string filename; + if (!SplitPath(filenames->at(i), nullptr, &filename, nullptr)) + filename = filenames->at(i); + header.append(StringFromFormat("\t\"%s\",\n", filename.c_str())); + } + header.append("};\n\n"); + header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n"); + + for (u32 i = 0; i < num_codes; i++) + { + if (codes[i].size() == 0) + continue; + + header.append("\t{\n\t\t"); + for (u32 j = 0; j < codes_padded.at(i).size(); j++) + { + if (j && ((j & 15) == 0)) + header.append("\n\t\t"); + header.append(StringFromFormat("0x%04x, ", codes_padded.at(i).at(j))); + } + header.append("\n\t},\n"); + } + header.append("};\n"); +} + // Usage: // Disassemble a file: // dsptool -d -o asdf.txt asdf.bin @@ -313,7 +386,7 @@ int main(int argc, const char* argv[]) } } - DSP::CodesToHeader(codes, &files, lines, output_header_name.c_str(), header); + CodesToHeader(codes, &files, lines, output_header_name.c_str(), header); File::WriteStringToFile(header, output_header_name + ".h"); delete[] codes; @@ -342,7 +415,7 @@ int main(int argc, const char* argv[]) if (!output_header_name.empty()) { std::string header; - DSP::CodeToHeader(code, input_name, output_header_name.c_str(), header); + CodeToHeader(code, input_name, output_header_name.c_str(), header); File::WriteStringToFile(header, output_header_name + ".h"); } }