1 /******************************************************************************/
2 /* Mednafen Virtual Boy Emulation Module                                      */
3 /******************************************************************************/
4 /* debug.cpp:
5 **  Copyright (C) 2010-2016 Mednafen Team
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU General Public License
9 ** as published by the Free Software Foundation; either version 2
10 ** of the License, or (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software Foundation, Inc.,
19 ** 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 
22 #include "vb.h"
23 #include <mednafen/hw_cpu/v810/v810_cpuD.h>
24 #include <trio/trio.h>
25 #include <iconv.h>
26 
27 #include "debug.h"
28 #include "timer.h"
29 //#include "input.h"
30 #include "vip.h"
31 #include "vsu.h"
32 #include "timer.h"
33 
34 namespace MDFN_IEN_VB
35 {
36 
37 extern V810 *VB_V810;
38 extern VSU *VB_VSU;
39 
40 static void RedoCPUHook(void);
41 static void (*CPUHook)(uint32, bool bpoint) = NULL;
42 static bool CPUHookContinuous = false;
43 static void (*LogFunc)(const char *, const char *);
44 bool VB_LoggingOn = false;
45 
46 typedef struct __VB_BPOINT {
47         uint32 A[2];
48         int type;
49         bool logical;
50 } VB_BPOINT;
51 
52 static std::vector<VB_BPOINT> BreakPointsPC, BreakPointsRead, BreakPointsWrite;
53 static bool FoundBPoint = 0;
54 
55 struct BTEntry
56 {
57  uint32 from;
58  uint32 to;
59  uint32 branch_count;
60  uint32 ecode;
61  bool valid;
62 };
63 
64 #define NUMBT 24
65 static BTEntry BTEntries[NUMBT];
66 static int BTIndex;
67 static bool BTEnabled;
68 
AddBranchTrace(uint32 from,uint32 to,uint32 ecode)69 static void AddBranchTrace(uint32 from, uint32 to, uint32 ecode)
70 {
71  BTEntry *prevbt = &BTEntries[(BTIndex + NUMBT - 1) % NUMBT];
72 
73  //if(BTEntries[(BTIndex - 1) & 0xF] == PC) return;
74 
75  if(prevbt->from == from && prevbt->to == to && prevbt->ecode == ecode && prevbt->branch_count < 0xFFFFFFFF && prevbt->valid)
76   prevbt->branch_count++;
77  else
78  {
79   BTEntries[BTIndex].from = from;
80   BTEntries[BTIndex].to = to;
81   BTEntries[BTIndex].ecode = ecode;
82   BTEntries[BTIndex].branch_count = 1;
83   BTEntries[BTIndex].valid = true;
84 
85   BTIndex = (BTIndex + 1) % NUMBT;
86  }
87 }
88 
VBDBG_EnableBranchTrace(bool enable)89 void VBDBG_EnableBranchTrace(bool enable)
90 {
91  BTEnabled = enable;
92  if(!enable)
93  {
94   BTIndex = 0;
95   memset(BTEntries, 0, sizeof(BTEntries));
96  }
97 
98  RedoCPUHook();
99 }
100 
VBDBG_GetBranchTrace(void)101 std::vector<BranchTraceResult> VBDBG_GetBranchTrace(void)
102 {
103  BranchTraceResult tmp;
104  std::vector<BranchTraceResult> ret;
105 
106  for(int x = 0; x < NUMBT; x++)
107  {
108   const BTEntry *bt = &BTEntries[(x + BTIndex) % NUMBT];
109 
110   if(!bt->valid)
111    continue;
112 
113   tmp.count = bt->branch_count;
114   trio_snprintf(tmp.from, sizeof(tmp.from), "%08x", bt->from);
115   trio_snprintf(tmp.to, sizeof(tmp.to), "%08x", bt->to);
116 
117   tmp.code[0] = 0;
118 
119 
120   if(bt->ecode >= 0xFFA0 && bt->ecode <= 0xFFBF)      // TRAP
121   {
122 	trio_snprintf(tmp.code, sizeof(tmp.code), "TRAP");
123   }
124   else if(bt->ecode >= 0xFE00 && bt->ecode <= 0xFEFF)
125   {
126 	trio_snprintf(tmp.code, sizeof(tmp.code), "INT%d", (bt->ecode >> 4) & 0xF);
127   }
128   else switch(bt->ecode)
129   {
130    case 0: break;
131    default: trio_snprintf(tmp.code, sizeof(tmp.code), "e");
132             break;
133 
134    case 0xFFF0: // Reset
135         trio_snprintf(tmp.code, sizeof(tmp.code), "R");
136         break;
137 
138    case 0xFFD0: // NMI
139         trio_snprintf(tmp.code, sizeof(tmp.code), "NMI");
140         break;
141 
142    case 0xFFC0: // Address trap
143         trio_snprintf(tmp.code, sizeof(tmp.code), "ADTR");
144         break;
145 
146    case 0xFF90: // Illegal/invalid instruction code
147         trio_snprintf(tmp.code, sizeof(tmp.code), "ILL");
148         break;
149 
150    case 0xFF80: // Zero division
151         trio_snprintf(tmp.code, sizeof(tmp.code), "ZD");
152         break;
153 
154    case 0xFF70:
155         trio_snprintf(tmp.code, sizeof(tmp.code), "FIV");       // FIV
156         break;
157 
158    case 0xFF68:
159         trio_snprintf(tmp.code, sizeof(tmp.code), "FZD");       // FZD
160         break;
161 
162    case 0xFF64:
163         trio_snprintf(tmp.code, sizeof(tmp.code), "FOV");       // FOV
164         break;
165 
166    case 0xFF62:
167         trio_snprintf(tmp.code, sizeof(tmp.code), "FUD");       // FUD
168         break;
169 
170    case 0xFF61:
171         trio_snprintf(tmp.code, sizeof(tmp.code), "FPR");       // FPR
172         break;
173 
174    case 0xFF60:
175         trio_snprintf(tmp.code, sizeof(tmp.code), "FRO");       // FRO
176         break;
177   }
178 
179   ret.push_back(tmp);
180  }
181  return(ret);
182 }
183 
184 
VBDBG_CheckBP(int type,uint32 address,uint32 value,unsigned int len)185 void VBDBG_CheckBP(int type, uint32 address, uint32 value, unsigned int len)
186 {
187  std::vector<VB_BPOINT>::iterator bpit, bpit_end;
188 
189  if(type == BPOINT_READ || type == BPOINT_IO_READ)
190  {
191   bpit = BreakPointsRead.begin();
192   bpit_end = BreakPointsRead.end();
193  }
194  else if(type == BPOINT_WRITE || type == BPOINT_IO_WRITE)
195  {
196   bpit = BreakPointsWrite.begin();
197   bpit_end = BreakPointsWrite.end();
198  }
199  else
200   return;
201 
202  for(; bpit != bpit_end; bpit++)
203  {
204   uint32 tmp_address = address;
205   uint32 tmp_len = len;
206 
207   while(tmp_len--)
208   {
209    if(tmp_address >= bpit->A[0] && tmp_address <= bpit->A[1])
210    {
211     FoundBPoint = true;
212     break;
213    }
214    tmp_address++;
215   }
216  }
217 }
218 
MemPeek8(v810_timestamp_t timestamp,uint32 A)219 static uint16 MDFN_FASTCALL MemPeek8(v810_timestamp_t timestamp, uint32 A)
220 {
221  uint8 ret;
222 
223  // TODO: VB_InDebugPeek(implement elsewhere)
224  VB_InDebugPeek++;
225  ret = MemRead8(timestamp, A);
226  VB_InDebugPeek--;
227 
228  return(ret);
229 }
230 
MemPeek16(v810_timestamp_t timestamp,uint32 A)231 static uint16 MDFN_FASTCALL MemPeek16(v810_timestamp_t timestamp, uint32 A)
232 {
233  uint16 ret;
234 
235  // TODO: VB_InDebugPeek(implement elsewhere)
236  VB_InDebugPeek++;
237  ret = MemRead16(timestamp, A);
238  VB_InDebugPeek--;
239 
240  return(ret);
241 }
242 
CPUHandler(const v810_timestamp_t timestamp,uint32 PC)243 static void CPUHandler(const v810_timestamp_t timestamp, uint32 PC)
244 {
245  std::vector<VB_BPOINT>::iterator bpit;
246 
247  for(bpit = BreakPointsPC.begin(); bpit != BreakPointsPC.end(); bpit++)
248  {
249   if(PC >= bpit->A[0] && PC <= bpit->A[1])
250   {
251    FoundBPoint = true;
252    break;
253   }
254  }
255  VB_V810->CheckBreakpoints(VBDBG_CheckBP, MemPeek16, NULL);
256 
257  CPUHookContinuous |= FoundBPoint;
258 
259  if(CPUHook && CPUHookContinuous)
260  {
261   ForceEventUpdates(timestamp);
262   CPUHook(PC, FoundBPoint);
263  }
264 
265  FoundBPoint = false;
266 }
267 
RedoCPUHook(void)268 static void RedoCPUHook(void)
269 {
270  VB_V810->SetCPUHook((CPUHook || VB_LoggingOn || BreakPointsPC.size() || BreakPointsRead.size() || BreakPointsWrite.size()) ? CPUHandler : NULL,
271 	BTEnabled ? AddBranchTrace : NULL);
272 }
273 
VBDBG_FlushBreakPoints(int type)274 void VBDBG_FlushBreakPoints(int type)
275 {
276  std::vector<VB_BPOINT>::iterator bpit;
277 
278  if(type == BPOINT_READ)
279   BreakPointsRead.clear();
280  else if(type == BPOINT_WRITE)
281   BreakPointsWrite.clear();
282  else if(type == BPOINT_PC)
283   BreakPointsPC.clear();
284 
285  RedoCPUHook();
286 }
287 
VBDBG_AddBreakPoint(int type,unsigned int A1,unsigned int A2,bool logical)288 void VBDBG_AddBreakPoint(int type, unsigned int A1, unsigned int A2, bool logical)
289 {
290  VB_BPOINT tmp;
291 
292  tmp.A[0] = A1;
293  tmp.A[1] = A2;
294  tmp.type = type;
295 
296  if(type == BPOINT_READ)
297   BreakPointsRead.push_back(tmp);
298  else if(type == BPOINT_WRITE)
299   BreakPointsWrite.push_back(tmp);
300  else if(type == BPOINT_PC)
301   BreakPointsPC.push_back(tmp);
302 
303  RedoCPUHook();
304 }
305 
dis_readhw(uint32 A)306 static uint16 dis_readhw(uint32 A)
307 {
308  int32 timestamp = 0;
309  return(MemPeek16(timestamp, A));
310 }
311 
VBDBG_Disassemble(uint32 & a,uint32 SpecialA,char * TextBuf)312 void VBDBG_Disassemble(uint32 &a, uint32 SpecialA, char *TextBuf)
313 {
314  return(v810_dis(a, 1, TextBuf, dis_readhw, true));
315 }
316 
VBDBG_MemPeek(uint32 A,unsigned int bsize,bool hl,bool logical)317 uint32 VBDBG_MemPeek(uint32 A, unsigned int bsize, bool hl, bool logical)
318 {
319  uint32 ret = 0;
320  int32 ws = 0;
321 
322  for(unsigned int i = 0; i < bsize; i++)
323  {
324   A &= 0xFFFFFFFF;
325   //ret |= mem_peekbyte(A, ws) << (i * 8);
326   ret |= MemRead8(ws, A) << (i * 8);
327   A++;
328  }
329 
330  return(ret);
331 }
332 
GetAddressSpaceBytes_CPU(const char * name,uint32 Address,uint32 Length,uint8 * Buffer)333 static void GetAddressSpaceBytes_CPU(const char *name, uint32 Address, uint32 Length, uint8 *Buffer)
334 {
335  while(Length--)
336  {
337   *Buffer = MemPeek8(0, Address);
338 
339   Address++;
340   Buffer++;
341  }
342 }
343 
GetAddressSpaceBytes_RAM(const char * name,uint32 Address,uint32 Length,uint8 * Buffer)344 static void GetAddressSpaceBytes_RAM(const char *name, uint32 Address, uint32 Length, uint8 *Buffer)
345 {
346  while(Length--)
347  {
348   *Buffer = MemPeek8(0, (0x5 << 24) | (uint16)Address);
349 
350   Address++;
351   Buffer++;
352  }
353 }
354 
GetAddressSpaceBytes_VSUWD(const char * name,uint32 Address,uint32 Length,uint8 * Buffer)355 static void GetAddressSpaceBytes_VSUWD(const char *name, uint32 Address, uint32 Length, uint8 *Buffer)
356 {
357  const unsigned int which = name[5] - '0';
358 
359  while(Length--)
360  {
361   *Buffer = VB_VSU->PeekWave(which, Address);
362 
363   Address++;
364   Buffer++;
365  }
366 }
367 
PutAddressSpaceBytes_CPU(const char * name,uint32 Address,uint32 Length,uint32 Granularity,bool hl,const uint8 * Buffer)368 static void PutAddressSpaceBytes_CPU(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer)
369 {
370  while(Length--)
371  {
372   int32 dummy_ts = 0;
373 
374   MemWrite8(dummy_ts, Address, *Buffer);
375 
376   Address++;
377   Buffer++;
378  }
379 }
380 
PutAddressSpaceBytes_RAM(const char * name,uint32 Address,uint32 Length,uint32 Granularity,bool hl,const uint8 * Buffer)381 static void PutAddressSpaceBytes_RAM(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer)
382 {
383  while(Length--)
384  {
385   int32 dummy_ts = 0;
386 
387   MemWrite8(dummy_ts, (0x5 << 24) | (uint16)Address, *Buffer);
388 
389   Address++;
390   Buffer++;
391  }
392 }
393 
PutAddressSpaceBytes_VSUWD(const char * name,uint32 Address,uint32 Length,uint32 Granularity,bool hl,const uint8 * Buffer)394 static void PutAddressSpaceBytes_VSUWD(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer)
395 {
396  const unsigned int which = name[5] - '0';
397 
398  while(Length--)
399  {
400   VB_VSU->PokeWave(which, Address, *Buffer);
401 
402   Address++;
403   Buffer++;
404  }
405 }
406 
VBDBG_GetRegister(const unsigned int id,char * special,const uint32 special_len)407 static uint32 VBDBG_GetRegister(const unsigned int id, char* special, const uint32 special_len)
408 {
409  return VB_V810->GetRegister(id, special, special_len);
410 }
411 
VBDBG_SetRegister(const unsigned int id,uint32 value)412 static void VBDBG_SetRegister(const unsigned int id, uint32 value)
413 {
414  VB_V810->SetRegister(id, value);
415 }
416 
VBDBG_SetCPUCallback(void (* callb)(uint32 PC,bool bpoint),bool continuous)417 void VBDBG_SetCPUCallback(void (*callb)(uint32 PC, bool bpoint), bool continuous)
418 {
419  CPUHook = callb;
420  CPUHookContinuous = continuous;
421  RedoCPUHook();
422 }
423 
VBDBG_DoLog(const char * type,const char * format,...)424 void VBDBG_DoLog(const char *type, const char *format, ...)
425 {
426  if(LogFunc)
427  {
428   char *temp;
429 
430   va_list ap;
431   va_start(ap, format);
432 
433   temp = trio_vaprintf(format, ap);
434   LogFunc(type, temp);
435   free(temp);
436 
437   va_end(ap);
438  }
439 }
440 
VBDBG_SetLogFunc(void (* func)(const char *,const char *))441 void VBDBG_SetLogFunc(void (*func)(const char *, const char *))
442 {
443  LogFunc = func;
444 
445  VB_LoggingOn = func ? true : false;
446 
447  if(VB_LoggingOn)
448  {
449 
450  }
451  else
452  {
453 
454  }
455  RedoCPUHook();
456 }
457 
458 static RegType V810Regs[] =
459 {
460         { V810::GSREG_PC, "PC", "Program Counter", 4 },
461 	{ V810::GSREG_PR + 1, "PR1", "Program Register 1", 4 },
462 	{ V810::GSREG_PR + 2, "HSP", "Program Register 2(Handler Stack Pointer)", 4 },
463 	{ V810::GSREG_PR + 3, "SP", "Program Register 3(Stack Pointer)", 4 },
464 	{ V810::GSREG_PR + 4, "GP", "Program Register 4(Global Pointer)", 4 },
465 	{ V810::GSREG_PR + 5, "TP", "Program Register 5(Text Pointer)", 4 },
466 	{ V810::GSREG_PR + 6, "PR6", "Program Register 6", 4 },
467 	{ V810::GSREG_PR + 7, "PR7", "Program Register 7", 4 },
468 	{ V810::GSREG_PR + 8, "PR8", "Program Register 8", 4 },
469 	{ V810::GSREG_PR + 9, "PR9", "Program Register 9", 4 },
470 	{ V810::GSREG_PR + 10, "PR10", "Program Register 10", 4 },
471 	{ V810::GSREG_PR + 11, "PR11", "Program Register 11", 4 },
472 	{ V810::GSREG_PR + 12, "PR12", "Program Register 12", 4 },
473 	{ V810::GSREG_PR + 13, "PR13", "Program Register 13", 4 },
474 	{ V810::GSREG_PR + 14, "PR14", "Program Register 14", 4 },
475 	{ V810::GSREG_PR + 15, "PR15", "Program Register 15", 4 },
476         { V810::GSREG_PR + 16, "PR16", "Program Register 16", 4 },
477         { V810::GSREG_PR + 17, "PR17", "Program Register 17", 4 },
478         { V810::GSREG_PR + 18, "PR18", "Program Register 18", 4 },
479         { V810::GSREG_PR + 19, "PR19", "Program Register 19", 4 },
480         { V810::GSREG_PR + 20, "PR20", "Program Register 20", 4 },
481         { V810::GSREG_PR + 21, "PR21", "Program Register 21", 4 },
482         { V810::GSREG_PR + 22, "PR22", "Program Register 22", 4 },
483         { V810::GSREG_PR + 23, "PR23", "Program Register 23", 4 },
484         { V810::GSREG_PR + 24, "PR24", "Program Register 24", 4 },
485         { V810::GSREG_PR + 25, "PR25", "Program Register 25", 4 },
486         { V810::GSREG_PR + 26, "PR26", "Program Register 26(String Dest Bit Offset)", 4 },
487         { V810::GSREG_PR + 27, "PR27", "Program Register 27(String Source Bit Offset)", 4 },
488         { V810::GSREG_PR + 28, "PR28", "Program Register 28(String Length)", 4 },
489         { V810::GSREG_PR + 29, "PR29", "Program Register 29(String Dest)", 4 },
490         { V810::GSREG_PR + 30, "PR30", "Program Register 30(String Source)", 4 },
491         { V810::GSREG_PR + 31, "LP", "Program Register 31(Link Pointer)", 4 },
492 
493         { V810::GSREG_SR + 0, "SR0", "Exception/Interrupt PC", 4 },
494         { V810::GSREG_SR + 1, "SR1", "Exception/Interrupt PSW", 4 },
495         { V810::GSREG_SR + 2, "SR2", "Fatal Error PC", 4 },
496         { V810::GSREG_SR + 3, "SR3", "Fatal Error PSW", 4 },
497         { V810::GSREG_SR + 4, "SR4", "Exception Cause Register", 4 },
498         { V810::GSREG_SR + 5, "SR5", "Program Status Word", 4 },
499         { V810::GSREG_SR + 6, "SR6", "Processor ID Register", 4 },
500         { V810::GSREG_SR + 7, "SR7", "Task Control Word", 4 },
501         { V810::GSREG_SR + 24, "SR24", "Cache Control Word", 4 },
502         { V810::GSREG_SR + 25, "SR25", "Address Trap Register", 4 },
503 
504 	{ V810::GSREG_TIMESTAMP, "TStamp", "Timestamp", 3 },
505 
506         { 0, "", "", 0 },
507 };
508 
509 
510 static RegGroupType V810RegsGroup =
511 {
512  NULL,
513  V810Regs,
514  VBDBG_GetRegister,
515  VBDBG_SetRegister,
516 };
517 
MISC_GetRegister(const unsigned int id,char * special,const uint32 special_len)518 static uint32 MISC_GetRegister(const unsigned int id, char *special, const uint32 special_len)
519 {
520  return(TIMER_GetRegister(id, special, special_len));
521 }
522 
MISC_SetRegister(const unsigned int id,const uint32 value)523 static void MISC_SetRegister(const unsigned int id, const uint32 value)
524 {
525  TIMER_SetRegister(id, value);
526 }
527 
528 
529 static RegType Regs_Misc[] =
530 {
531 	{ TIMER_GSREG_TCR,	"TCR", "Timer Control Register", 1 },
532 	{ TIMER_GSREG_DIVCOUNTER, "DivCounter", "Timer Clock Divider Counter", 2 },
533 	{ TIMER_GSREG_RELOAD_VALUE, "ReloadValue", "Timer Reload Value", 2 },
534 	{ TIMER_GSREG_COUNTER, "Counter", "Timer Counter Value", 2 },
535         { 0, "", "", 0 },
536 };
537 
538 static RegGroupType RegsGroup_Misc =
539 {
540         "Misc",
541         Regs_Misc,
542         MISC_GetRegister,
543         MISC_SetRegister
544 };
545 
546 
547 static RegType Regs_VIP[] =
548 {
549 	{ VIP_GSREG_IPENDING,	"IPending", "Interrupts Pending", 2 },
550 	{ VIP_GSREG_IENABLE,	"IEnable", "Interrupts Enabled", 2 },
551 
552 	{ VIP_GSREG_DPCTRL,	"DPCTRL", "DPCTRL", 2 },
553 
554 	{ VIP_GSREG_BRTA,	"BRTA", "BRTA", 1 },
555 	{ VIP_GSREG_BRTB,	"BRTB", "BRTB", 1 },
556 	{ VIP_GSREG_BRTC,	"BRTC", "BRTC", 1 },
557 	{ VIP_GSREG_REST,	"REST", "REST", 1 },
558 	{ VIP_GSREG_FRMCYC,	"FRMCYC", "FRMCYC", 1 },
559 	{ VIP_GSREG_XPCTRL,	"XPCTRL", "XPCTRL", 2 },
560 
561 	{ VIP_GSREG_SPT0,	"SPT0", "SPT0", 2 },
562 	{ VIP_GSREG_SPT1,	"SPT1", "SPT1", 2 },
563 	{ VIP_GSREG_SPT2,	"SPT2", "SPT2", 2 },
564 	{ VIP_GSREG_SPT3,	"SPT3", "SPT3", 2 },
565 
566 	{ VIP_GSREG_GPLT0,	"GPLT0", "GPLT0", 1 },
567 	{ VIP_GSREG_GPLT1,	"GPLT1", "GPLT1", 1 },
568 	{ VIP_GSREG_GPLT2,	"GPLT2", "GPLT2", 1 },
569 	{ VIP_GSREG_GPLT3,	"GPLT3", "GPLT3", 1 },
570 
571 	{ VIP_GSREG_JPLT0,	"JPLT0", "JPLT0", 1 },
572 	{ VIP_GSREG_JPLT1,	"JPLT1", "JPLT1", 1 },
573 	{ VIP_GSREG_JPLT2,	"JPLT2", "JPLT2", 1 },
574 	{ VIP_GSREG_JPLT3,	"JPLT3", "JPLT3", 1 },
575 
576 	{ VIP_GSREG_BKCOL,	"BKCOL", "BKCOL", 1 },
577 
578         { 0, "", "", 0 },
579 };
580 
581 static RegGroupType RegsGroup_VIP =
582 {
583         "VIP",
584         Regs_VIP,
585         VIP_GetRegister,
586         VIP_SetRegister
587 };
588 
589 
VBDBG_Init(void)590 bool VBDBG_Init(void)
591 {
592  BTEnabled = false;
593  BTIndex = 0;
594  memset(BTEntries, 0, sizeof(BTEntries));
595 
596  MDFNDBG_AddRegGroup(&V810RegsGroup);
597  MDFNDBG_AddRegGroup(&RegsGroup_Misc);
598  MDFNDBG_AddRegGroup(&RegsGroup_VIP);
599 
600  ASpace_Add(GetAddressSpaceBytes_CPU, PutAddressSpaceBytes_CPU, "cpu", "CPU Physical", 27);
601  ASpace_Add(GetAddressSpaceBytes_RAM, PutAddressSpaceBytes_RAM, "ram", "RAM", 16);
602 
603  for(int x = 0; x < 5; x++)
604  {
605      AddressSpaceType newt;
606      char tmpname[128], tmpinfo[128];
607 
608      trio_snprintf(tmpname, 128, "vsuwd%d", x);
609      trio_snprintf(tmpinfo, 128, "VSU Wave Data %d", x);
610 
611      newt.GetAddressSpaceBytes = GetAddressSpaceBytes_VSUWD;
612      newt.PutAddressSpaceBytes = PutAddressSpaceBytes_VSUWD;
613 
614      newt.name = std::string(tmpname);
615      newt.long_name = std::string(tmpinfo);
616      newt.TotalBits = 5;
617      newt.NP2Size = 0;
618 
619      newt.IsWave = true;
620      newt.WaveFormat = ASPACE_WFMT_UNSIGNED;
621      newt.WaveBits = 6;
622      ASpace_Add(newt); //PSG_GetAddressSpaceBytes, PSG_PutAddressSpaceBytes, tmpname, tmpinfo, 5);
623  }
624 
625 
626 
627  return(true);
628 }
629 
630 }
631