main_spy.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. // Copyright 2009 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. // This is a test program for running code on the Wii DSP, with full control over input
  4. // and automatic compare with output. VERY useful for figuring out what those little
  5. // ops actually do.
  6. // It's very unpolished though
  7. // Use Dolphin's dsptool to generate a new dsp_code.h.
  8. // Originally written by duddie and modified by FIRES. Then further modified by ector.
  9. #include <array>
  10. #include <debug.h>
  11. #include <fat.h>
  12. #include <fcntl.h>
  13. #include <gccore.h>
  14. #include <malloc.h>
  15. #include <network.h>
  16. #include <ogcsys.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <time.h>
  21. #include <ogc/color.h>
  22. #include <ogc/consol.h>
  23. #include <unistd.h>
  24. #ifdef _MSC_VER
  25. // Just for easy looking :)
  26. #define HW_RVL // HW_DOL
  27. #endif
  28. #ifdef HW_RVL
  29. #include <sdcard/wiisd_io.h>
  30. #include <wiiuse/wpad.h>
  31. #else
  32. #include <sdcard/gcsd.h>
  33. #endif
  34. #include "ConsoleHelper.h"
  35. #include "dspregs.h"
  36. // This is where the DSP binary is.
  37. #include "dsp_code.h"
  38. #include "mem_dump.h"
  39. // Communication with the real DSP and with the DSP emulator.
  40. #include "dsp_interface.h"
  41. #include "real_dsp.h"
  42. // #include "virtual_dsp.h"
  43. // Used for communications with the DSP, such as dumping registers etc.
  44. u16 dspbuffer[16 * 1024] __attribute__((aligned(0x4000)));
  45. static void* xfb = nullptr;
  46. void (*reboot)() = (void (*)())0x80001800;
  47. GXRModeObj* rmode;
  48. static vu16* const _dspReg = (u16*)0xCC005000;
  49. u16* dspbufP;
  50. u16* dspbufC;
  51. u32* dspbufU;
  52. u16 dspreg_in[32] = {
  53. 0x0410, 0x0510, 0x0610, 0x0710, 0x0810, 0x0910, 0x0a10, 0x0b10, 0xFFFF, 0xFFFF, 0xFFFF,
  54. 0xFFFF, 0x0855, 0x0966, 0x0a77, 0x0b88, 0x0014, 0xfff5, 0x00ff, 0x2200, 0x0000, 0x0000,
  55. 0x0000, 0x0000, 0x0003, 0x0004, 0x8000, 0x000C, 0x0007, 0x0008, 0x0009, 0x000a,
  56. }; /// ax_h_1 ax_h_1
  57. /* ttt ?
  58. u16 dspreg_in[32] = {
  59. 0x0e4c, 0x03c0, 0x0bd9, 0x06a3, 0x0c06, 0x0240, 0x0010, 0x0ecc,
  60. 0x0000, 0x0000, 0x0000, 0x0000, 0x0322, 0x0000, 0x0000, 0x0000,
  61. 0x0000, 0x0000, 0x00ff, 0x1b41, 0x0000, 0x0040, 0x00ff, 0x0000,
  62. 0x1000, 0x96cc, 0x0000, 0x0000, 0x3fc0, 0x96cc, 0x0000, 0x0000,
  63. }; */
  64. // if i set bit 0x4000 of SR my tests crashes :(
  65. /*
  66. // zelda 0x00da
  67. u16 dspreg_in[32] = {
  68. 0x0a50, 0x0ca2, 0x04f8, 0x0ab0, 0x8039, 0x0000, 0x0000, 0x0000,
  69. 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x03d1, 0x0000, 0x0418, 0x0002, // r08 must have a value ... no
  70. idea why (ector: it's the looped addressing regs)
  71. 0x0000, 0x0000, 0x00ff, 0x1804, 0xdb70, 0x4ddb, 0x0000, 0x0000,
  72. 0x0000, 0x0000, 0x0000, 0xde6d, 0x0000, 0x0000, 0x0000, 0x004e,
  73. };*/
  74. u16 dspreg_out[1000][32];
  75. /*
  76. // gba ucode dmas result here
  77. u32 SecParams_out[2] __attribute__ ((aligned (0x20))) = {
  78. 0x11223344, // key
  79. 0x55667788 // bootinfo
  80. };
  81. // ripped from demo
  82. u32 SecParams_in[8] __attribute__ ((aligned (0x20))) = {
  83. 0xDB967E0F, // key from gba
  84. 0x00000002,
  85. 0x00000002,
  86. 0x00001078,
  87. (u32)SecParams_out, //0x80075060, // ptr to receiving buffer
  88. // padding?
  89. 0x00000000,
  90. 0x00000000,
  91. 0x00000000
  92. };
  93. */
  94. // UI (interactive register editing)
  95. u32 ui_mode;
  96. enum
  97. {
  98. UIM_SEL = 1,
  99. UIM_EDIT_REG = 2,
  100. UIM_EDIT_BIN = 4,
  101. };
  102. // Currently selected register.
  103. s32 cursor_reg = 0;
  104. // Currently selected digit.
  105. s32 small_cursor_x;
  106. // Value currently being edited.
  107. u16* reg_value;
  108. RealDSP real_dsp;
  109. // Currently running microcode
  110. int curUcode = 0, runningUcode = 1;
  111. int dsp_steps = 0;
  112. constexpr std::array reg_names = {
  113. "ar0", "ar1", "ar2", "ar3", "ix0", "ix1", "ix2", "ix3", "wr0", "wr1", "wr2",
  114. "wr3", "st0", "st1", "st2", "st3", "c0h", "c1h", "cr ", "sr ", "pl ", "pm1",
  115. "ph ", "pm2", "x0l", "x1l", "x0h", "x1h", "c0l", "c1l", "c0m", "c1m",
  116. };
  117. void print_reg_block(int x, int y, int sel, const u16* regs, const u16* compare_regs)
  118. {
  119. for (int j = 0; j < 4; j++)
  120. {
  121. for (int i = 0; i < 8; i++)
  122. {
  123. const int reg = j * 8 + i;
  124. u8 color1 = regs[reg] == compare_regs[reg] ? CON_BRIGHT_WHITE : CON_BRIGHT_RED;
  125. CON_SetColor(sel == reg ? CON_BRIGHT_YELLOW : CON_GREEN);
  126. CON_Printf(x + j * 9, i + y, "%s ", reg_names[reg]);
  127. for (int k = 0; k < 4; k++)
  128. {
  129. if (sel == reg && k == small_cursor_x && ui_mode == UIM_EDIT_REG)
  130. CON_SetColor(CON_BRIGHT_CYAN);
  131. else
  132. CON_SetColor(color1);
  133. CON_Printf(x + 4 + j * 9 + k, i + y, "%01x", (regs[reg] >> ((3 - k) * 4)) & 0xf);
  134. }
  135. }
  136. }
  137. CON_SetColor(CON_WHITE);
  138. CON_Printf(x + 2, y + 9, "ACC0: %02x %04x %04x", regs[DSP_REG_ACH0] & 0xff, regs[DSP_REG_ACM0],
  139. regs[DSP_REG_ACL0]);
  140. CON_Printf(x + 2, y + 10, "ACC1: %02x %04x %04x", regs[DSP_REG_ACH1] & 0xff, regs[DSP_REG_ACM1],
  141. regs[DSP_REG_ACL1]);
  142. CON_Printf(x + 2, y + 11, "AX0: %04x %04x", regs[DSP_REG_AXH0], regs[DSP_REG_AXL0]);
  143. CON_Printf(x + 2, y + 12, "AX1: %04x %04x", regs[DSP_REG_AXH1], regs[DSP_REG_AXL1]);
  144. u64 prod = (u64(regs[DSP_REG_PRODH]) << 32) + (u64(regs[DSP_REG_PRODM]) << 16) +
  145. (u64(regs[DSP_REG_PRODM2]) << 16) + u64(regs[DSP_REG_PRODL]);
  146. u8 prod_h = (prod >> 32) & 0xff;
  147. u16 prod_m = (prod >> 16) & 0xffff;
  148. u16 prod_l = prod & 0xffff;
  149. CON_Printf(x + 2, y + 13, "PROD: %02x %04x %04x", prod_h, prod_m, prod_l);
  150. CON_Printf(x + 2, y + 14, "SR:");
  151. for (int i = 0; i < 16; ++i)
  152. CON_Printf(x + 6 + i + i / 4, y + 14, "%c", regs[DSP_REG_SR] & (1 << (15 - i)) ? '1' : '0');
  153. CON_Printf(x + 21, y + 15, "SZOC");
  154. }
  155. void print_regs(int _step, int _dsp_steps)
  156. {
  157. const u16* regs = _step == 0 ? dspreg_in : dspreg_out[_step - 1];
  158. const u16* regs2 = dspreg_out[_step];
  159. print_reg_block(0, 2, _step == 0 ? cursor_reg : -1, regs, regs2);
  160. print_reg_block(38, 2, -1, regs2, regs);
  161. CON_SetColor(CON_WHITE);
  162. CON_Printf(33, 17, "%i / %i ", _step + 1, _dsp_steps);
  163. return;
  164. static int count = 0;
  165. int x = 0, y = 16;
  166. if (count > 2)
  167. CON_Clear();
  168. count = 0;
  169. CON_SetColor(CON_WHITE);
  170. for (int i = 0x0; i < 0xf70; i++)
  171. {
  172. if (dspbufC[i] != mem_dump[i])
  173. {
  174. CON_Printf(x, y, "%04x=%04x", i, dspbufC[i]);
  175. count++;
  176. x += 10;
  177. if (x >= 60)
  178. {
  179. x = 0;
  180. y++;
  181. }
  182. }
  183. }
  184. CON_Printf(4, 25, "%08x", count);
  185. }
  186. void UpdateLastMessage(const char* msg)
  187. {
  188. CON_PrintRow(4, 24, msg);
  189. }
  190. void DumpDSP_ROMs(const u16* rom, const u16* coef)
  191. {
  192. char filename[260] = {0};
  193. sprintf(filename, "sd:/dsp_rom.bin");
  194. FILE* fROM = fopen(filename, "wb");
  195. sprintf(filename, "sd:/dsp_coef.bin");
  196. FILE* fCOEF = fopen(filename, "wb");
  197. if (fROM && fCOEF)
  198. {
  199. fwrite(MEM_PHYSICAL_TO_K0(rom), 0x2000, 1, fROM);
  200. fwrite(MEM_PHYSICAL_TO_K0(coef), 0x1000, 1, fCOEF);
  201. UpdateLastMessage("DSP ROMs dumped to SD");
  202. }
  203. else
  204. {
  205. UpdateLastMessage("SD Write Error");
  206. }
  207. if (fROM)
  208. fclose(fROM);
  209. if (fCOEF)
  210. fclose(fCOEF);
  211. }
  212. void ui_pad_sel(void)
  213. {
  214. #ifdef HW_RVL
  215. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
  216. cursor_reg += 8;
  217. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
  218. cursor_reg -= 8;
  219. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
  220. cursor_reg--;
  221. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
  222. cursor_reg++;
  223. cursor_reg &= 0x1f;
  224. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
  225. {
  226. ui_mode = UIM_EDIT_REG;
  227. reg_value = &dspreg_in[cursor_reg];
  228. }
  229. #endif
  230. if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
  231. cursor_reg += 8;
  232. if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
  233. cursor_reg -= 8;
  234. if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
  235. cursor_reg--;
  236. if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
  237. cursor_reg++;
  238. cursor_reg &= 0x1f;
  239. if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
  240. {
  241. ui_mode = UIM_EDIT_REG;
  242. reg_value = &dspreg_in[cursor_reg];
  243. }
  244. }
  245. void ui_pad_edit_reg(void)
  246. {
  247. #ifdef HW_RVL
  248. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
  249. small_cursor_x++;
  250. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
  251. small_cursor_x--;
  252. small_cursor_x &= 0x3;
  253. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
  254. *reg_value += 0x1 << (4 * (3 - small_cursor_x));
  255. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
  256. *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
  257. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
  258. ui_mode = UIM_SEL;
  259. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_1)
  260. *reg_value = 0;
  261. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_2)
  262. *reg_value = 0xffff;
  263. #endif
  264. if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
  265. small_cursor_x++;
  266. if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
  267. small_cursor_x--;
  268. small_cursor_x &= 0x3;
  269. if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
  270. *reg_value += 0x1 << (4 * (3 - small_cursor_x));
  271. if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
  272. *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
  273. if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
  274. ui_mode = UIM_SEL;
  275. if (PAD_ButtonsDown(0) & PAD_BUTTON_X)
  276. *reg_value = 0;
  277. if (PAD_ButtonsDown(0) & PAD_BUTTON_Y)
  278. *reg_value = 0xffff;
  279. }
  280. void handle_dsp_mail(void)
  281. {
  282. // Should put a loop around this too.
  283. if (DSP_CheckMailFrom())
  284. {
  285. u32 mail = DSP_ReadMailFrom();
  286. if (mail == 0x8071feed)
  287. {
  288. // DSP ready for task. Let's send one.
  289. // First, prepare data.
  290. for (int n = 0; n < 32; n++)
  291. dspbufC[0x00 + n] = dspreg_in[n];
  292. DCFlushRange(dspbufC, 0x2000);
  293. // Then send the code.
  294. DCFlushRange((void*)dsp_code[curUcode], 0x2000);
  295. // DMA ucode to iram base, entry point is just after exception vectors...0x10
  296. // NOTE: for any ucode made by dsptool, the block length will be 8191
  297. real_dsp.SendTask((void*)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]), 0,
  298. sizeof(dsp_code[curUcode]) - 1, 0x10);
  299. runningUcode = curUcode + 1;
  300. // Clear exception status since we've loaded a new ucode
  301. CON_BlankRow(25);
  302. }
  303. else if ((mail & 0xffff0000) == 0x8bad0000)
  304. {
  305. // dsp_base.inc is reporting an exception happened
  306. CON_PrintRow(4, 25, "%s caused exception %x at step %i", UCODE_NAMES[curUcode], mail & 0xff,
  307. dsp_steps);
  308. }
  309. else if (mail == 0x8888dead)
  310. {
  311. // Send memory dump (DSP DRAM from someone's GameCube?)
  312. // not really sure why this is important - I guess just to try to keep tests predictable
  313. u16* tmpBuf = (u16*)MEM_VIRTUAL_TO_PHYSICAL(mem_dump);
  314. while (real_dsp.CheckMailTo())
  315. ;
  316. real_dsp.SendMailTo((u32)tmpBuf);
  317. while (real_dsp.CheckMailTo())
  318. ;
  319. }
  320. else if (mail == 0x8888beef)
  321. {
  322. // Provide register base to DSP (if using dsp_base.inc, it will DMA them to the correct place)
  323. while (real_dsp.CheckMailTo())
  324. ;
  325. real_dsp.SendMailTo((u32)dspbufP);
  326. while (real_dsp.CheckMailTo())
  327. ;
  328. }
  329. else if (mail == 0x8888feeb)
  330. {
  331. // We got a stepful of registers.
  332. DCInvalidateRange(dspbufC, 0x2000);
  333. for (int i = 0; i < 32; i++)
  334. dspreg_out[dsp_steps][i] = dspbufC[0xf80 + i];
  335. dsp_steps++;
  336. while (real_dsp.CheckMailTo())
  337. ;
  338. real_dsp.SendMailTo(0x8000dead);
  339. while (real_dsp.CheckMailTo())
  340. ;
  341. }
  342. else if (mail == 0x80050000)
  343. {
  344. CON_PrintRow(4, 25, "ACCOV at step %i", dsp_steps);
  345. }
  346. // ROM dumping mails
  347. else if (mail == 0x8888c0de)
  348. {
  349. // DSP has copied irom to its DRAM...send address so it can dma it back
  350. while (real_dsp.CheckMailTo())
  351. ;
  352. real_dsp.SendMailTo((u32)dspbufP);
  353. while (real_dsp.CheckMailTo())
  354. ;
  355. }
  356. else if (mail == 0x8888da7a)
  357. {
  358. // DSP has copied coef to its DRAM...send address so it can DMA it back
  359. while (real_dsp.CheckMailTo())
  360. ;
  361. real_dsp.SendMailTo((u32)&dspbufP[0x1000]);
  362. while (real_dsp.CheckMailTo())
  363. ;
  364. // Now we can do something useful with the buffer :)
  365. DumpDSP_ROMs(dspbufP, &dspbufP[0x1000]);
  366. }
  367. // SDK status mails
  368. /*
  369. // GBA ucode
  370. else if (mail == 0xdcd10000) // DSP_INIT
  371. {
  372. real_dsp.SendMailTo(0xabba0000);
  373. while (real_dsp.CheckMailTo());
  374. DCFlushRange(SecParams_in, sizeof(SecParams_in));
  375. CON_PrintRow(4, 25, "SecParams_out = %x", SecParams_in[4]);
  376. real_dsp.SendMailTo((u32)SecParams_in);
  377. while (real_dsp.CheckMailTo());
  378. }
  379. else if (mail == 0xdcd10003) // DSP_DONE
  380. {
  381. real_dsp.SendMailTo(0xcdd1babe); // custom mail to tell DSP to halt (calls end_of_test)
  382. while (real_dsp.CheckMailTo());
  383. DCInvalidateRange(SecParams_out, sizeof(SecParams_out));
  384. CON_PrintRow(4, 26, "SecParams_out: %08x %08x",
  385. SecParams_out[0], SecParams_out[1]);
  386. }
  387. */
  388. CON_PrintRow(2, 1, "UCode: %d/%d %s, Last mail: %08x", curUcode + 1, NUM_UCODES,
  389. UCODE_NAMES[curUcode], mail);
  390. }
  391. }
  392. void dump_all_ucodes(bool fastmode)
  393. {
  394. char filename[260] = {0};
  395. char temp[100];
  396. u32 written;
  397. sprintf(filename, "sd:/dsp_dump_all.bin");
  398. FILE* f2 = fopen(filename, "wb");
  399. fclose(f2);
  400. for (int UCodeToDump = 0; UCodeToDump < NUM_UCODES; UCodeToDump++)
  401. {
  402. // First, change the microcode
  403. dsp_steps = 0;
  404. curUcode = UCodeToDump;
  405. runningUcode = 0;
  406. DCInvalidateRange(dspbufC, 0x2000);
  407. DCFlushRange(dspbufC, 0x2000);
  408. real_dsp.Reset();
  409. // Loop over handling mail until we've stopped stepping
  410. // dsp_steps-3 compensates for mails to setup the ucode
  411. for (int steps_cache = dsp_steps - 3; steps_cache <= dsp_steps; steps_cache++)
  412. {
  413. VIDEO_WaitVSync();
  414. handle_dsp_mail();
  415. }
  416. VIDEO_WaitVSync();
  417. sprintf(filename, "sd:/dsp_dump_all.bin");
  418. FILE* f2 = fopen(filename, "ab");
  419. if (fastmode == false)
  420. {
  421. // Then write microcode dump to file
  422. sprintf(filename, "sd:/dsp_dump%d.bin", UCodeToDump);
  423. FILE* f = fopen(filename, "wb");
  424. if (f)
  425. {
  426. // First write initial regs
  427. written = fwrite(dspreg_in, 1, 32 * 2, f);
  428. // Then write all the dumps.
  429. written += fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
  430. fclose(f);
  431. }
  432. else
  433. {
  434. UpdateLastMessage("SD Write Error");
  435. break;
  436. }
  437. }
  438. if (f2) // all in 1 dump file (extra)
  439. {
  440. if (UCodeToDump == 0)
  441. {
  442. // First write initial regs
  443. written = fwrite(dspreg_in, 1, 32 * 2, f2);
  444. written += fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f2);
  445. }
  446. else
  447. {
  448. written = fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f2);
  449. }
  450. fclose(f2);
  451. if (UCodeToDump < NUM_UCODES - 1)
  452. {
  453. sprintf(temp, "Dump %d Successful. Wrote %d bytes, steps: %d", UCodeToDump + 1, written,
  454. dsp_steps);
  455. UpdateLastMessage(temp);
  456. }
  457. else
  458. {
  459. UpdateLastMessage("DUMPING DONE!");
  460. }
  461. }
  462. else
  463. {
  464. UpdateLastMessage("SD Write Error");
  465. break;
  466. }
  467. }
  468. }
  469. // Shove common, un-dsp-ish init things here
  470. void InitGeneral()
  471. {
  472. // Initialize the video system
  473. VIDEO_Init();
  474. // This function initializes the attached controllers
  475. PAD_Init();
  476. #ifdef HW_RVL
  477. WPAD_Init();
  478. #endif
  479. // Obtain the preferred video mode from the system
  480. // This will correspond to the settings in the Wii Menu
  481. rmode = VIDEO_GetPreferredMode(nullptr);
  482. // Allocate memory for the display in the uncached region
  483. xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
  484. // Set up the video registers with the chosen mode
  485. VIDEO_Configure(rmode);
  486. // Tell the video hardware where our display memory is
  487. VIDEO_SetNextFramebuffer(xfb);
  488. // Make the display visible
  489. VIDEO_SetBlack(FALSE);
  490. // Flush the video register changes to the hardware
  491. VIDEO_Flush();
  492. // Wait for Video setup to complete
  493. VIDEO_WaitVSync();
  494. if (rmode->viTVMode & VI_NON_INTERLACE)
  495. VIDEO_WaitVSync();
  496. // Initialize the console, required for printf
  497. CON_Init(xfb, 20, 64, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
  498. #ifdef HW_RVL
  499. // Initialize FAT so we can write to SD.
  500. __io_wiisd.startup();
  501. fatMountSimple("sd", &__io_wiisd);
  502. #else
  503. // Initialize FAT so we can write to SD Gecko in slot B.
  504. fatMountSimple("sd", &__io_gcsdb);
  505. // Init debug over BBA...change IPs to suite your needs
  506. tcp_localip = "192.168.1.103";
  507. tcp_netmask = "255.255.255.0";
  508. tcp_gateway = "192.168.1.2";
  509. DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT);
  510. #endif
  511. }
  512. void ExitToLoader()
  513. {
  514. fatUnmount("sd");
  515. #ifdef HW_RVL
  516. __io_wiisd.shutdown();
  517. #endif
  518. UpdateLastMessage("Exiting...");
  519. real_dsp.Reset();
  520. reboot();
  521. }
  522. int main()
  523. {
  524. InitGeneral();
  525. ui_mode = UIM_SEL;
  526. dspbufP = (u16*)MEM_VIRTUAL_TO_PHYSICAL(dspbuffer); // physical
  527. dspbufC = dspbuffer; // cached
  528. dspbufU = (u32*)(MEM_K0_TO_K1(dspbuffer)); // uncached
  529. DCInvalidateRange(dspbuffer, 0x2000);
  530. for (int j = 0; j < 0x800; j++)
  531. dspbufU[j] = 0xffffffff;
  532. // Initialize DSP.
  533. real_dsp.Init();
  534. int show_step = 0;
  535. while (true)
  536. {
  537. handle_dsp_mail();
  538. VIDEO_WaitVSync();
  539. PAD_ScanPads();
  540. if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
  541. ExitToLoader();
  542. #ifdef HW_RVL
  543. WPAD_ScanPads();
  544. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
  545. ExitToLoader();
  546. CON_Printf(2, 18, "Controls:");
  547. CON_Printf(4, 19, "+/- (GC:'L'/'R') to move");
  548. CON_Printf(4, 20, "A (GC:'A') to edit register; B (GC:'B') to start over");
  549. CON_Printf(4, 21, "1 (GC:'Z') to move next microcode");
  550. CON_Printf(4, 22,
  551. "2 (GC:'X') dump results to SD; UP (GC:'Y') dump results to SD (SINGLE FILE)");
  552. CON_Printf(4, 23, "Home (GC:'START') to exit");
  553. #else
  554. CON_Printf(2, 18, "Controls:");
  555. CON_Printf(4, 19, "L/R to move");
  556. CON_Printf(4, 20, "A to edit register, B to start over");
  557. CON_Printf(4, 21, "Z to move to next microcode");
  558. CON_Printf(4, 22, "Start to exit");
  559. #endif
  560. print_regs(show_step, dsp_steps);
  561. switch (ui_mode)
  562. {
  563. case UIM_SEL:
  564. ui_pad_sel();
  565. break;
  566. case UIM_EDIT_REG:
  567. ui_pad_edit_reg();
  568. break;
  569. case UIM_EDIT_BIN:
  570. // ui_pad_edit_bin();
  571. break;
  572. default:
  573. break;
  574. }
  575. DCFlushRange(xfb, 0x200000);
  576. // Use B to start over.
  577. #ifdef HW_RVL
  578. if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_B) || (PAD_ButtonsDown(0) & PAD_BUTTON_B))
  579. #else
  580. if (PAD_ButtonsDown(0) & PAD_BUTTON_B)
  581. #endif
  582. {
  583. dsp_steps =
  584. 0; // Let's not add the new steps after the original ones. That was just annoying.
  585. DCInvalidateRange(dspbufC, 0x2000);
  586. DCFlushRange(dspbufC, 0x2000);
  587. // Reset the DSP.
  588. real_dsp.Reset();
  589. UpdateLastMessage("OK");
  590. }
  591. // Navigate between results using + and - buttons.
  592. #ifdef HW_RVL
  593. if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_R))
  594. #else
  595. if (PAD_ButtonsDown(0) & PAD_TRIGGER_R)
  596. #endif
  597. {
  598. show_step++;
  599. if (show_step >= dsp_steps)
  600. show_step = 0;
  601. UpdateLastMessage("OK");
  602. }
  603. #ifdef HW_RVL
  604. if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
  605. #else
  606. if (PAD_ButtonsDown(0) & PAD_TRIGGER_L)
  607. #endif
  608. {
  609. show_step--;
  610. if (show_step < 0)
  611. show_step = dsp_steps - 1;
  612. UpdateLastMessage("OK");
  613. }
  614. #ifdef HW_RVL
  615. if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
  616. #else
  617. if (PAD_ButtonsDown(0) & PAD_TRIGGER_Z)
  618. #endif
  619. {
  620. curUcode++;
  621. if (curUcode == NUM_UCODES)
  622. curUcode = 0;
  623. // Reset step counters since we're in a new ucode.
  624. show_step = 0;
  625. dsp_steps = 0;
  626. DCInvalidateRange(dspbufC, 0x2000);
  627. for (int n = 0; n < 0x2000; n++)
  628. {
  629. // dspbufU[n/2] = 0; dspbufC[n] = 0;
  630. }
  631. DCFlushRange(dspbufC, 0x2000);
  632. // Reset the DSP.
  633. real_dsp.Reset();
  634. UpdateLastMessage("OK");
  635. // Waiting for video to synchronize (enough time to set our new microcode)
  636. VIDEO_WaitVSync();
  637. }
  638. #ifdef HW_RVL
  639. // Probably could offer to save to sd gecko or something on gc...
  640. // The future is web-based reporting ;)
  641. if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_2) || (PAD_ButtonsDown(0) & PAD_BUTTON_X))
  642. {
  643. dump_all_ucodes(false);
  644. }
  645. // Dump all results into 1 file (skip file per ucode part) = FAST because of LIBFAT filecreate
  646. // bug
  647. if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_UP) || (PAD_ButtonsDown(0) & PAD_BUTTON_Y))
  648. {
  649. dump_all_ucodes(true);
  650. }
  651. #endif
  652. } // end main loop
  653. ExitToLoader();
  654. // Will never reach here, but just to be sure..
  655. exit(0);
  656. return 0;
  657. }