Quietly log writes to 0xc0003030. Written to only by bs1, and we don't seem to really...
[dolphin.git] / Source / DSPSpy / main_spy.cpp
blobaba2007852a932c310c53f755762f5a0f3f091d5
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 // This is a test program for running code on the Wii DSP, with full control over input
19 // and automatic compare with output. VERY useful for figuring out what those little
20 // ops actually do.
21 // It's very unpolished though
22 // Use Dolphin's dsptool to generate a new dsp_code.h.
23 // Originally written by duddie and modified by FIRES. Then further modified by ector.
25 #include <gccore.h>
26 #include <malloc.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <network.h>
31 #include <ogcsys.h>
32 #include <time.h>
33 #include <fat.h>
34 #include <fcntl.h>
35 #include <debug.h>
37 #include <unistd.h>
38 #include <ogc/color.h>
39 #include <ogc/consol.h>
41 #ifdef _MSC_VER
42 // Just for easy looking :)
43 #define HW_RVL //HW_DOL
44 #endif
46 #ifdef HW_RVL
47 #include <wiiuse/wpad.h>
48 #include <sdcard/wiisd_io.h>
49 #endif
51 #include "ConsoleHelper.h"
53 #include "dspregs.h"
55 // This is where the DSP binary is.
56 #include "dsp_code.h"
57 #include "mem_dump.h"
59 // Communication with the real DSP and with the DSP emulator.
60 #include "dsp_interface.h"
61 #include "real_dsp.h"
62 // #include "virtual_dsp.h"
64 // Used for communications with the DSP, such as dumping registers etc.
65 u16 dspbuffer[16 * 1024] __attribute__ ((aligned (0x4000)));
67 static void *xfb = NULL;
68 void (*reboot)() = (void(*)())0x80001800;
69 GXRModeObj *rmode;
71 static vu16* const _dspReg = (u16*)0xCC005000;
73 u16 *dspbufP;
74 u16 *dspbufC;
75 u32 *dspbufU;
77 u16 dspreg_in[32] = {
78 0x0410, 0x0510, 0x0610, 0x0710, 0x0810, 0x0910, 0x0a10, 0x0b10,
79 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0855, 0x0966, 0x0a77, 0x0b88,
80 0x0014, 0xfff5, 0x00ff, 0x2200, 0x0000, 0x0000, 0x0000, 0x0000,
81 0x0003, 0x0004, 0x8000, 0x000C, 0x0007, 0x0008, 0x0009, 0x000a,
82 }; /// ax_h_1 ax_h_1
84 /* ttt ?
86 u16 dspreg_in[32] = {
87 0x0e4c, 0x03c0, 0x0bd9, 0x06a3, 0x0c06, 0x0240, 0x0010, 0x0ecc,
88 0x0000, 0x0000, 0x0000, 0x0000, 0x0322, 0x0000, 0x0000, 0x0000,
89 0x0000, 0x0000, 0x00ff, 0x1b41, 0x0000, 0x0040, 0x00ff, 0x0000,
90 0x1000, 0x96cc, 0x0000, 0x0000, 0x3fc0, 0x96cc, 0x0000, 0x0000,
91 }; */
93 // if i set bit 0x4000 of SR my tests crashes :(
96 // zelda 0x00da
97 u16 dspreg_in[32] = {
98 0x0a50, 0x0ca2, 0x04f8, 0x0ab0, 0x8039, 0x0000, 0x0000, 0x0000,
99 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x03d1, 0x0000, 0x0418, 0x0002, // r08 must have a value ... no idea why (ector: it's the looped addressing regs)
100 0x0000, 0x0000, 0x00ff, 0x1804, 0xdb70, 0x4ddb, 0x0000, 0x0000,
101 0x0000, 0x0000, 0x0000, 0xde6d, 0x0000, 0x0000, 0x0000, 0x004e,
102 };*/
104 u16 dspreg_out[1000][32];
107 // gba ucode dmas result here
108 u32 SecParams_out[2] __attribute__ ((aligned (0x20))) = {
109 0x11223344, // key
110 0x55667788 // bootinfo
113 // ripped from demo
114 u32 SecParams_in[8] __attribute__ ((aligned (0x20))) = {
115 0xDB967E0F, // key from gba
116 0x00000002,
117 0x00000002,
118 0x00001078,
119 (u32)SecParams_out, //0x80075060, // ptr to receiving buffer
120 // padding?
121 0x00000000,
122 0x00000000,
123 0x00000000
127 // UI (interactive register editing)
128 u32 ui_mode;
130 enum {
131 UIM_SEL = 1,
132 UIM_EDIT_REG = 2,
133 UIM_EDIT_BIN = 4,
136 // Currently selected register.
137 s32 cursor_reg = 0;
138 // Currently selected digit.
139 s32 small_cursor_x;
140 // Value currently being edited.
141 u16 *reg_value;
143 RealDSP real_dsp;
145 // Currently running microcode
146 int curUcode = 0, runningUcode = 1;
148 int dsp_steps = 0;
151 // When comparing regs, ignore the loop stack registers.
152 bool regs_equal(int reg, u16 value1, u16 value2)
154 if (reg >= DSP_REG_ST0 && reg <= DSP_REG_ST3)
155 return true;
156 else
157 return value1 == value2;
160 void print_reg_block(int x, int y, int sel, const u16 *regs, const u16 *compare_regs)
162 for (int j = 0; j < 4 ; j++)
164 for (int i = 0; i < 8 ; i++)
166 // Do not even display the loop stack registers.
167 const int reg = j * 8 + i;
168 CON_SetColor(sel == reg ? CON_BRIGHT_YELLOW : CON_GREEN);
169 CON_Printf(x + j * 8, i + y, "%02x ", reg);
170 if (j != 1 || i < 4)
172 u8 color1 = regs_equal(reg, regs[reg], compare_regs[reg]) ? CON_BRIGHT_WHITE : CON_BRIGHT_RED;
173 for (int k = 0; k < 4; k++)
175 if (sel == reg && k == small_cursor_x && ui_mode == UIM_EDIT_REG)
176 CON_SetColor(CON_BRIGHT_CYAN);
177 else
178 CON_SetColor(color1);
179 CON_Printf(x + 3 + j * 8 + k, i + y, "%01x", (regs[reg] >> ((3 - k) * 4)) & 0xf);
184 CON_SetColor(CON_WHITE);
186 CON_Printf(x+2, y+9, "ACC0: %02x %04x %04x", regs[DSP_REG_ACH0]&0xff, regs[DSP_REG_ACM0], regs[DSP_REG_ACL0]);
187 CON_Printf(x+2, y+10, "ACC1: %02x %04x %04x", regs[DSP_REG_ACH1]&0xff, regs[DSP_REG_ACM1], regs[DSP_REG_ACL1]);
188 CON_Printf(x+2, y+11, "AX0: %04x %04x", regs[DSP_REG_AXH0], regs[DSP_REG_AXL0]);
189 CON_Printf(x+2, y+12, "AX1: %04x %04x", regs[DSP_REG_AXH1], regs[DSP_REG_AXL1]);
192 void print_regs(int _step, int _dsp_steps)
194 const u16 *regs = _step == 0 ? dspreg_in : dspreg_out[_step - 1];
195 const u16 *regs2 = dspreg_out[_step];
197 print_reg_block(0, 2, _step == 0 ? cursor_reg : -1, regs, regs2);
198 print_reg_block(33, 2, -1, regs2, regs);
200 CON_SetColor(CON_WHITE);
201 CON_Printf(33, 17, "%i / %i ", _step + 1, _dsp_steps);
203 return;
205 static int count = 0;
206 int x = 0, y = 16;
207 if (count > 2)
208 CON_Clear();
209 count = 0;
210 CON_SetColor(CON_WHITE);
211 for (int i = 0x0; i < 0xf70 ; i++)
213 if (dspbufC[i] != mem_dump[i])
215 CON_Printf(x, y, "%04x=%04x", i, dspbufC[i]);
216 count++;
217 x += 10;
218 if (x >= 60) {
219 x = 0;
220 y++;
224 CON_Printf(4, 25, "%08x", count);
227 void UpdateLastMessage(const char* msg)
229 CON_PrintRow(4, 24, msg);
232 void DumpDSP_ROMs(const u16* rom, const u16* coef)
234 #ifdef HW_RVL
235 char filename[260] = {0};
236 sprintf(filename, "sd:/dsp_rom.bin");
237 FILE *fROM = fopen(filename, "wb");
238 sprintf(filename, "sd:/dsp_coef.bin");
239 FILE *fCOEF = fopen(filename, "wb");
240 if (fROM && fCOEF)
242 fwrite(MEM_PHYSICAL_TO_K0(rom), 0x2000, 1, fROM);
243 fclose(fROM);
245 fwrite(MEM_PHYSICAL_TO_K0(coef), 0x1000, 1, fCOEF);
246 fclose(fCOEF);
247 UpdateLastMessage("DSP ROMs dumped to SD");
249 else
251 UpdateLastMessage("SD Write Error");
253 #else
254 // Allow to connect to gdb (dump ram... :s)
255 _break();
256 #endif
259 void ui_pad_sel(void)
261 #ifdef HW_RVL
262 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
263 cursor_reg += 8;
264 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
265 cursor_reg -= 8;
266 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
267 cursor_reg--;
268 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
269 cursor_reg++;
270 cursor_reg &= 0x1f;
271 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
273 ui_mode = UIM_EDIT_REG;
274 reg_value = &dspreg_in[cursor_reg];
276 #else
277 if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
278 cursor_reg += 8;
279 if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
280 cursor_reg -= 8;
281 if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
282 cursor_reg--;
283 if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
284 cursor_reg++;
285 cursor_reg &= 0x1f;
286 if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
288 ui_mode = UIM_EDIT_REG;
289 reg_value = &dspreg_in[cursor_reg];
291 #endif
294 void ui_pad_edit_reg(void)
296 #ifdef HW_RVL
297 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_RIGHT)
298 small_cursor_x++;
299 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_LEFT)
300 small_cursor_x--;
301 small_cursor_x &= 0x3;
303 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_UP)
304 *reg_value += 0x1 << (4 * (3 - small_cursor_x));
305 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN)
306 *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
307 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A)
308 ui_mode = UIM_SEL;
309 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_1)
310 *reg_value = 0;
311 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_2)
312 *reg_value = 0xffff;
313 #else
314 if (PAD_ButtonsDown(0) & PAD_BUTTON_RIGHT)
315 small_cursor_x++;
316 if (PAD_ButtonsDown(0) & PAD_BUTTON_LEFT)
317 small_cursor_x--;
318 small_cursor_x &= 0x3;
320 if (PAD_ButtonsDown(0) & PAD_BUTTON_UP)
321 *reg_value += 0x1 << (4 * (3 - small_cursor_x));
322 if (PAD_ButtonsDown(0) & PAD_BUTTON_DOWN)
323 *reg_value -= 0x1 << (4 * (3 - small_cursor_x));
324 if (PAD_ButtonsDown(0) & PAD_BUTTON_A)
325 ui_mode = UIM_SEL;
326 if (PAD_ButtonsDown(0) & PAD_BUTTON_X)
327 *reg_value = 0;
328 if (PAD_ButtonsDown(0) & PAD_BUTTON_Y)
329 *reg_value = 0xffff;
330 #endif
333 void handle_dsp_mail(void)
335 // Should put a loop around this too.
336 if (DSP_CheckMailFrom())
338 u32 mail = DSP_ReadMailFrom();
340 if (mail == 0x8071feed)
342 // DSP ready for task. Let's send one.
343 // First, prepare data.
344 for (int n = 0 ; n < 32 ; n++)
345 dspbufC[0x00 + n] = dspreg_in[n];
346 DCFlushRange(dspbufC, 0x2000);
347 // Then send the code.
348 DCFlushRange((void *)dsp_code[curUcode], 0x2000);
349 // DMA ucode to iram base, entry point is just after exception vectors...0x10
350 // NOTE: for any ucode made by dsptool, the block length will be 8191
351 real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]), 0, sizeof(dsp_code[curUcode])-1, 0x10);
353 runningUcode = curUcode + 1;
355 // Clear exception status since we've loaded a new ucode
356 CON_BlankRow(25);
358 else if ((mail & 0xffff0000) == 0x8bad0000)
360 // dsp_base.inc is reporting an exception happened
361 CON_PrintRow(4, 25, "%s caused exception %x at step %i", UCODE_NAMES[curUcode], mail & 0xff, dsp_steps);
363 else if (mail == 0x8888dead)
365 // Send memory dump (dsp dram from someone's cube?)
366 // not really sure why this is important - I guess just to try to keep tests predictable
367 u16* tmpBuf = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(mem_dump);
369 while (real_dsp.CheckMailTo());
370 real_dsp.SendMailTo((u32)tmpBuf);
371 while (real_dsp.CheckMailTo());
373 else if (mail == 0x8888beef)
375 // Provide register base to dsp (if using dsp_base.inc, it will dma them to the correct place)
376 while (real_dsp.CheckMailTo());
377 real_dsp.SendMailTo((u32)dspbufP);
378 while (real_dsp.CheckMailTo());
380 else if (mail == 0x8888feeb)
382 // We got a stepful of registers.
383 DCInvalidateRange(dspbufC, 0x2000);
384 for (int i = 0 ; i < 32 ; i++)
385 dspreg_out[dsp_steps][i] = dspbufC[0xf80 + i];
387 dsp_steps++;
389 while (real_dsp.CheckMailTo());
390 real_dsp.SendMailTo(0x8000dead);
391 while (real_dsp.CheckMailTo());
394 // ROM dumping mails
395 else if (mail == 0x8888c0de)
397 // DSP has copied irom to its dram...send address so it can dma it back
398 while (real_dsp.CheckMailTo());
399 real_dsp.SendMailTo((u32)dspbufP);
400 while (real_dsp.CheckMailTo());
402 else if (mail == 0x8888da7a)
404 // DSP has copied coef to its dram...send address so it can dma it back
405 while (real_dsp.CheckMailTo());
406 real_dsp.SendMailTo((u32)&dspbufP[0x1000]);
407 while (real_dsp.CheckMailTo());
409 // Now we can do something useful with the buffer :)
410 DumpDSP_ROMs(dspbufP, &dspbufP[0x1000]);
413 // SDK status mails
415 // GBA ucode
416 else if (mail == 0xdcd10000) // DSP_INIT
418 real_dsp.SendMailTo(0xabba0000);
419 while (real_dsp.CheckMailTo());
420 DCFlushRange(SecParams_in, sizeof(SecParams_in));
421 CON_PrintRow(4, 25, "SecParams_out = %x", SecParams_in[4]);
422 real_dsp.SendMailTo((u32)SecParams_in);
423 while (real_dsp.CheckMailTo());
425 else if (mail == 0xdcd10003) // DSP_DONE
427 real_dsp.SendMailTo(0xcdd1babe); // custom mail to tell dsp to halt (calls end_of_test)
428 while (real_dsp.CheckMailTo());
430 DCInvalidateRange(SecParams_out, sizeof(SecParams_out));
431 CON_PrintRow(4, 26, "SecParams_out: %08x %08x",
432 SecParams_out[0], SecParams_out[1]);
436 CON_PrintRow(2, 1, "UCode: %d/%d %s, Last mail: %08x",
437 curUcode + 1, NUM_UCODES, UCODE_NAMES[curUcode], mail);
441 void dump_all_ucodes(bool fastmode)
443 char filename[260] = {0};
444 char temp[100];
445 u32 written;
447 sprintf(filename, "sd:/dsp_dump_all.bin");
448 FILE *f2 = fopen(filename, "wb");
449 fclose(f2);
451 for (int UCodeToDump = 0; UCodeToDump < NUM_UCODES; UCodeToDump++)
453 // First, change the microcode
454 dsp_steps = 0;
455 curUcode = UCodeToDump;
456 runningUcode = 0;
458 DCInvalidateRange(dspbufC, 0x2000);
459 DCFlushRange(dspbufC, 0x2000);
461 real_dsp.Reset();
463 VIDEO_WaitVSync();
464 // Loop over handling mail until we've stopped stepping
465 // dsp_steps-3 compensates for mails to setup the ucode
466 for (int steps_cache = dsp_steps-3; steps_cache <= dsp_steps; steps_cache++)
467 handle_dsp_mail();
468 VIDEO_WaitVSync();
470 sprintf(filename, "sd:/dsp_dump_all.bin");
471 FILE *f2 = fopen(filename, "ab");
473 if (fastmode == false)
475 // Then write microcode dump to file
476 sprintf(filename, "sd:/dsp_dump%d.bin", UCodeToDump);
477 FILE *f = fopen(filename, "wb");
478 if (f)
480 // First write initial regs
481 written = fwrite(dspreg_in, 1, 32 * 2, f);
483 // Then write all the dumps.
484 written += fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
485 fclose(f);
487 else
489 UpdateLastMessage("SD Write Error");
490 break;
494 if (f2) //all in 1 dump file (extra)
496 if (UCodeToDump == 0) {
497 // First write initial regs
498 written = fwrite(dspreg_in, 1, 32 * 2, f2);
499 written += fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f2);
501 else {
502 written = fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f2);
505 fclose(f2);
507 if (UCodeToDump < NUM_UCODES-1)
509 sprintf(temp, "Dump %d Successful. Wrote %d bytes, steps: %d", UCodeToDump+1, written, dsp_steps);
510 UpdateLastMessage(temp);
512 else {
513 UpdateLastMessage("DUMPING DONE!");
516 else
518 UpdateLastMessage("SD Write Error");
519 break;
524 // Shove common, un-dsp-ish init things here
525 void InitGeneral()
527 // Initialize the video system
528 VIDEO_Init();
530 // This function initializes the attached controllers
531 PAD_Init();
532 #ifdef HW_RVL
533 WPAD_Init();
534 #endif
536 // Obtain the preferred video mode from the system
537 // This will correspond to the settings in the Wii menu
538 rmode = VIDEO_GetPreferredMode(NULL);
540 // Allocate memory for the display in the uncached region
541 xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
543 // Set up the video registers with the chosen mode
544 VIDEO_Configure(rmode);
545 // Tell the video hardware where our display memory is
546 VIDEO_SetNextFramebuffer(xfb);
547 // Make the display visible
548 VIDEO_SetBlack(FALSE);
549 // Flush the video register changes to the hardware
550 VIDEO_Flush();
551 // Wait for Video setup to complete
552 VIDEO_WaitVSync();
553 if (rmode->viTVMode & VI_NON_INTERLACE)
554 VIDEO_WaitVSync();
556 // Initialize the console, required for printf
557 CON_Init(xfb, 20, 64, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
559 #ifdef HW_RVL
560 // Initialize FAT so we can write to SD.
561 __io_wiisd.startup();
562 fatMountSimple("sd", &__io_wiisd);
563 #else
564 // Init debug over BBA...change IPs to suite your needs
565 tcp_localip="192.168.1.103";
566 tcp_netmask="255.255.255.0";
567 tcp_gateway="192.168.1.2";
568 DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT);
569 #endif
572 void ExitToLoader()
574 #ifdef HW_RVL
575 fatUnmount("sd");
576 __io_wiisd.shutdown();
577 #endif
579 UpdateLastMessage("Exiting...");
580 real_dsp.Reset();
581 reboot();
584 int main()
586 InitGeneral();
588 ui_mode = UIM_SEL;
590 dspbufP = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(dspbuffer); // physical
591 dspbufC = dspbuffer; // cached
592 dspbufU = (u32 *)(MEM_K0_TO_K1(dspbuffer)); // uncached
594 DCInvalidateRange(dspbuffer, 0x2000);
595 for (int j = 0; j < 0x800; j++)
596 dspbufU[j] = 0xffffffff;
598 // Initialize DSP.
599 real_dsp.Init();
602 int show_step = 0;
603 while (true)
605 handle_dsp_mail();
607 VIDEO_WaitVSync();
609 PAD_ScanPads();
610 if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
611 ExitToLoader();
612 #ifdef HW_RVL
613 WPAD_ScanPads();
614 if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
615 ExitToLoader();
617 CON_Printf(2, 18, "Controls:");
618 CON_Printf(4, 19, "+/- (GC:'L'/'R') to move");
619 CON_Printf(4, 20, "A (GC:'A') to edit register; B (GC:'B') to start over");
620 CON_Printf(4, 21, "1 (GC:'Z') to move next microcode");
621 CON_Printf(4, 22, "2 (GC:'X') dump results to SD; UP (GC:'Y') dump results to SD (SINGLE FILE)");
622 CON_Printf(4, 23, "Home (GC:'START') to exit");
623 #else
624 CON_Printf(2, 18, "Controls:");
625 CON_Printf(4, 19, "L/R to move");
626 CON_Printf(4, 20, "A to edit register, B to start over");
627 CON_Printf(4, 21, "Z to move to next microcode");
628 CON_Printf(4, 22, "Start to exit");
629 #endif
631 print_regs(show_step, dsp_steps);
633 switch (ui_mode)
635 case UIM_SEL:
636 ui_pad_sel();
637 break;
638 case UIM_EDIT_REG:
639 ui_pad_edit_reg();
640 break;
641 case UIM_EDIT_BIN:
642 // ui_pad_edit_bin();
643 break;
644 default:
645 break;
647 DCFlushRange(xfb, 0x200000);
650 // Use B to start over.
651 #ifdef HW_RVL
652 if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_B) || (PAD_ButtonsDown(0) & PAD_BUTTON_B))
653 #else
654 if (PAD_ButtonsDown(0) & PAD_BUTTON_B)
655 #endif
657 dsp_steps = 0; // Let's not add the new steps after the original ones. That was just annoying.
659 DCInvalidateRange(dspbufC, 0x2000);
660 DCFlushRange(dspbufC, 0x2000);
662 // Reset the DSP.
663 real_dsp.Reset();
664 UpdateLastMessage("OK");
667 // Navigate between results using + and - buttons.
668 #ifdef HW_RVL
669 if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_R))
670 #else
671 if (PAD_ButtonsDown(0) & PAD_TRIGGER_R)
672 #endif
674 show_step++;
675 if (show_step >= dsp_steps)
676 show_step = 0;
677 UpdateLastMessage("OK");
679 #ifdef HW_RVL
680 if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
681 #else
682 if (PAD_ButtonsDown(0) & PAD_TRIGGER_L)
683 #endif
685 show_step--;
686 if (show_step < 0)
687 show_step = dsp_steps - 1;
688 UpdateLastMessage("OK");
691 #ifdef HW_RVL
692 if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
693 #else
694 if (PAD_ButtonsDown(0) & PAD_TRIGGER_Z)
695 #endif
697 curUcode++;
698 if(curUcode == NUM_UCODES)
699 curUcode = 0;
701 // Reset step counters since we're in a new ucode.
702 show_step = 0;
703 dsp_steps = 0;
705 DCInvalidateRange(dspbufC, 0x2000);
706 for (int n = 0 ; n < 0x2000 ; n++)
708 // dspbufU[n/2] = 0; dspbufC[n] = 0;
710 DCFlushRange(dspbufC, 0x2000);
712 // Reset the DSP.
713 real_dsp.Reset();
714 UpdateLastMessage("OK");
716 // Waiting for video to synchronize (enough time to set our new microcode)
717 VIDEO_WaitVSync();
720 #ifdef HW_RVL
721 // Probably could offer to save to sd gecko or something on gc...
722 // The future is web-based reporting ;)
723 if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_2) || (PAD_ButtonsDown(0) & PAD_BUTTON_X))
725 dump_all_ucodes(false);
728 // Dump all results into 1 file (skip file per ucode part) = FAST because of LIBFAT filecreate bug
729 if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_UP) || (PAD_ButtonsDown(0) & PAD_BUTTON_Y))
731 dump_all_ucodes(true);
733 #endif
735 } // end main loop
737 ExitToLoader();
739 // Will never reach here, but just to be sure..
740 exit(0);
741 return 0;