Follow us on Facebook
Follow us on Twitter
Signalogic on LinkedIn

C/C++ Technical Support

Case Incidents:

Web Site Link:

FTP Site Links:


Data Manipulation on the Userproc.c

From: Jeff 
Subject: Re: Need Help
To: Honshing 
Date: 04/25/99


>I need some help on the UserProc again. When I use the CONVERSIONINFO to do 
>real time data manipulation on the userproc.c with the szStimName="rt" or 
>"rtd" and the StimMode='R' there is output wave form something.adc and 
>something.tim come out but the userprco (which I have been tested with RT code 
>with digital I/O) output does not output the digit I/O signal at all. Here is the 
>code, please hint me, Thank you!!

Are you saying that you have a userproc.c program which works with digital I/O, 
and you can run from Hypersignal successfully?  If not, then I suggest to get it 
working using Hypersignal in "user mode" first.

If you can get it to work from Hypersignal, then you should be able to get it to 
work from a Windows C/C++ program.  The C code below will cause Hypersignal to 
run with the second line in the Analog Conversion menu set to:


which should be correct.  What is the value of m_CSFilename?

Jeff Brower

A/D and D/A Looping in Real Time

From: Yolanda 
Subject: Re: AD and DA Looping on M44
To: carsten 
Date: 07/07/99

Hi Carsten,

>I was wondering if you had any examples on demo C programs that do AD and DA 
looping in real time.

Yes, it will be rtcode.cpp which is located at \dspower\hwlib. 
I am also attaching a copy of rtcode.cpp just in case.

>Also is it possible to download a program, like one that does continuous AD 
>to DA looping on all 8 channels in real time with some signal modification, 
>to the M44 board so that it would run through program either as soon as it 
>was powered up or when the user initialized it.

Yes, you can use the HWLIB call DSLoadProcessorFile() to download any COFF file 
to the DSP.  Then use the DSRunProcessor() to initiate the DSP to run.  For 
proper sequence of initialization, please refer to rtcode.cpp for additional information.

Attached is an excerpt from ISR6.ASM which shows you how the DSP code can be 
modified so that it will A/D and D/A more than 2 channels of data.  Please 
search for the keyword "OUTLOOP".  Please note that we have not compiled or 
tested the code so you might encounter some syntax error.  Otherwise, the 
excerpt shows you the steps needed to set up 8 channels input and output.

With regards,

Casting Return Address Into a Short Int Pointer

From: Jeff 
Subject: Re: a few things tried...
To: Scott 
Date: 07/31/99


>The return from DSGetSymbolAddress is DWORD which is a 32 bit unsigned int right.
>Say my symbol is a short int.  I have been unsuccessful in casting the returned 
>address into a short int pointer.  These statements are performed after I have
>downloaded the code to the DSP board with the init routines.  Is there something 
I am missing?

Yes!  There is something...

Let's say your variable in the DSP32C C (or .asm) code is a short int, called 
"Scott".  In the host code (C/C++ or MATLAB or VB), you would do this (using 
C/C++ as example):

  dwScottAddr = DSGetSymbolAddress(hBoard, NULL, "_Scott");

Then, to write a value of 0x1234 to Scott, you would do:

  short int val = 0x1234;
  DSPutMem(hBoard, DS_GM_LINEAR_DATA, dwScottAddr / 2, DS_GM_SIZE_16, &val, 1);

For a 32-bit variable in the DSP32C C code (i.e. a long int), you would do:

  long int val = 0x12345678;
  DSPutMem(hBoard, DS_GM_LINEAR_DATA, dwScottAddr / 4, DS_GM_SIZE32, &val, 1);

The last value in the call is the count.  To write an array, the count should 
reflect the length of the array.  A memory type of DS_GM_LINEAR_PROGRAM could 
also be used, but for the DSP32C, data and program memory are the same (not true 
for some other DSP types). Note that the host data in the call must be a 
pointer, you cannot use a constant value in the DSPutMem (or DSGetMem) call.

The divide-by-2 and divide-by-4 account for the unusual capability of the DSP32C 
(relative to other DSP devices) to perform mixed byte/short/long memory 
addressing.  For byte accesses, you would not divide.

Jeff Brower

Setting Parameters Through Userproc.c File

From: Yolanda 
Subject: Re: AD and DA Looping on M44
To: carsten 
Date: 07/14/99

Hi Carsten,

>Thanks for all the info, The experimental code works.  All 8 channels are 
>looping now.  I have a question about the delay between the input and output 
>signals when using the a,rt,r command.  It seems to vary depending on how 
>many channels are being used.  I wondering if adding too much code to 
>userproc would cause this or something in isr6.

Please check 

The 'a' entry causes an aquisition operation.

The 'rt' entry causes real-time simultaneous input/output operation (mode 6). 

The 'rtd' entry works the same way, except recording to waveform file is enabled. 

# of Channels vs delay time.

1) Using Hypersignal Macro

In Hypersiganl Macro, the default buffer size is 12288.

So if you have 2 channels, each channel will have 6144 samples.
   if you have 8 channels, each channel will have 1536 samples.

Therefore, if you have more channels, you will have less delay time
due to the fact that less samples will be collected for each channel.

2) Using HWLIB

Usually, we will define bufSize which is the required number
of samples for each channel.  Then we will defined DSP_BUFLEN to be:

(in MATLAB syntax)
PutVarMem(hBoard, DSP_BUFLEN, bufSize * numChan); 

In this way, the delay time will be independent of number of channles.

Hope this helps.

Changes to rtcode.cpp to Result in Correct Data

From: Jeff 
Subject: Re: tried suggestions...
To: Scott 
Date: 08/09/99


>I made the following changes to rtcode.cpp and did not see the correct
>data displayed to the screen:
>     BOOL InitHardware(LPCSTR szBoard) {
>        .
>        .
>      // get address of input time domain data
>         dwBufferBaseAddr = DSGetHVarMem(hBoard, DSP_TIMDATAADDR);
>         DSPutHVarMem(hBoard, DSP_TIMDATAADDR, dwBufferBaseAddr +
>      // put output time domain data buffer after input buffer
>         DSPutHVarMem(hBoard, DSP_STMDATAADDR, dwBufferBaseAddr +
>2*wBuflen*NumChan + 32768);
>         return TRUE;
>     }
>Is there anything else I need to do?

Yes.  You need to change the actual values used later in your program.  The code 
above should be:

      // get address of input time domain data
         dwBufferBaseAddr = DSGetHVarMem(hBoard, DSP_TIMDATAADDR);
         dwBufferBaseAddr += 32768;
         DSPutHVarMem(hBoard, DSP_TIMDATAADDR, dwBufferBaseAddr);

      // put output time domain data buffer after input buffer
         dwOutBufferBaseAddr = dwBufferBaseAddr + 2*wBuflen*NumChan;
         DSPutHVarMem(hBoard, DSP_STMDATAADDR, dwOutBufferBaseAddr);

This way, the correct values for dw...BaseAddr will be used subsequently in your 
program anywhere they are referenced, and "consistency shall be maintained" !!  
For example, in subsequent DSGetMem calls, you would use dwBufferBaseAddr, and 
in DSPutMem calls, you would use dwOutBufferBaseAddr.

Jeff Brower

Calling Hamm0 Function From Userproc.c

From: Jeff 
Subject: Re: strange...
To: Scott 
Date: 08/13/99


>I have not gotten [hamm0] function to work being called from userproc.c

Please let me see the current userproc.c source.  One thought is that hamm0() is 
going to expect data in floating-point format, and data coming into userproc.c 
is 16-bit integer (A/D converter data).

>It compiles fine and I can see the symbols for hamm0 show up in the W32LINK.MAP file.  
>When I run it, the green pen draws the inital data and it does not seem to be getting 
>the buffer ready message to update the screen.  If I hit the hardware config button and 
>then hit the ok button, it looks like the output changes for one frame and then it 
freezes again.

Don't do that; this is basically a reset, causing real-time acquisition to restart.  
If you can't see data on the rtcode trace, then processing is not correct on the 
DSP side (userproc.c) and this is where to focus.

>Any ideas on this problem? I may start rolling my own programs for windowing
>and FFT/IFFT if I can not figure out what's going on.

There are window.s and fft.s asm. files included in the DSP32C source code 
interface. You can call these functions relatively easily from C programs.  The 
best way would be to call a .asm "stub" which then calls the asm. functions; to 
get the code for the stub, look at modul3.s, where Window() and fft() functions are called.

>Have you guys used any of these functions in libap32c.a ??

No, we have not.  But if they are Lucent C compiler compatible, and use r14 as a 
stack pointer, they should work.  

Jeff Brower

Calling Libap32c Functions

From: Jeff 
Subject: Re: calling libap32c functions
To: Scott 
Date: 08/19/99


>float A[2][2] = {
>      1.0, 2.0,
>      5.0, 6.0
>float B[2][2] = {
>      1.0, 2.0,
>      2.0, 3.0
>float C[2][2];
>UserProc(ptrIn, ptrOut, nLen, nNumTrace)
>short int* ptrIn;
>short int* ptrOut;
>short int nLen;
>short int nNumTrace;
>#define x ((short*)ptrIn)
>#define y ((short*)ptrOut)
>register float *a = A[0];
>register float *b = B[0];
>register float *c = C[0];
>  mat2x2((float *)a, (float *)b, (float *)c); 

It looks like there is a good reason to use registers to hold the pointers when 
calling libapi functions.  If so, try:

register float *a = &A[0];
register float *b = &B[0];
register float *c = &C[0];

  mat2x2(a, b, c);

If register pointers do not need to be used, try:

  mat2x2(A, B, C);

Or alternatively:

  mat2x2(&A[0], &B[0], &C[0]);

Jeff Brower

Calling Libap32c Functions in Regards to r19

From: Jeff 
Subject: Re: calling libap32c functions
To: Robert 
Cc: Scott 
Date: 08/19/99


a-ha! r19, yes that could be a problem.  I think you can also use this:

  call UserProc(r18)
  r19e = 4             /* set r19 before entering call */

  r14e = r24 - N       /* realign stack */
  r19e = *page         /* restore r19 to Sig. "page" value */

Signalogic code uses r19 as a "page pointer" which is used by some routines and 
code sections to maintain board independence for different memory modes and 
different starting memory banks.  I think we had to do this at one point because 
of the large number and variety of DSP32C boards that were being supported.  
Note that r19 usage is documented in the Signalogic DSP Software Users Guide 
.hlp file, under "DSP32C Source Code Interface Modification Notes" section.  
Note also that the above method could still be a problem if a Signalogic routine 
is called in turn from UserProc or libap32c functions.

Jeff Brower

>Ack I remember numerous occasions where not only calling ap32c functions  
>would fail, but c runtime functions as well. I dont remember exactly how i 
>corrected it, but here is one solution:
>Make the correction in the modul6.s file
>/* REI */
>			r19e= 4			/* C code expects this */
>			nop
>            call UserProc(r18)
>            nop
>            r14e = r14 - 16  /* re-align stack pointer */
>            nop
>			r19e=0		/* Signalogic code expects this */
>			nop
>by the time i figured out how to get userproc.c working, i basically was living and 
>breathing dsp32c assembly. I've finally gotten to the point where i dont need to 
>hack directly, so I have promptly forgotten most of it. 
>On Wed, 18 Aug 1999, Scott wrote:
>> Hi,
>> Jeff tells me that you have been successful at programming the DSP32C board 
>> in C.  Have you been able to use the AT&T C application library libap32c.a?
>> I have been able to access functions in this library using test code and d3bug.  But have had 
>> problems calling some functions from the userproc.c  code used with the signalogic software.
>> It seems the functions that give me problems are the ones that get passed array pointers.
>> The code I have tried is simple. I have attached a sample userproc.c that has caused 
>> the system to hang. Can you execute something like this?
>> Thanks,

Modification of rtcode Causing Flatline Flashes

From: Jeff 
Subject: Re: Some Success ???
To: Glenn 
Date: 08/31/99


>1) Userproc builds OK with lnk.bat. I ran the 0.75*x[n] + 1000 example 
>and even though I had no input data I received noise through (with the 
expand punched up).
>2) I modified rtcode.c to download my b.out file (under Visual C 1.52c) 
>and got the noise pass thru, however, there were flashes of flatlines in 
>the display.

Keep in mind that rtcode is not "synchronized" to what the DSP is doing in mode 
6; that is, the DSP doesn't wait for the host if the host gets behind.  This 
means that when the host gets done displaying data (or whatever processing), if 
it takes a long time, then the host doesn't know if the next buffer ready 
message is "old" or not.  If it's old, the host could read from the same buffer 
the DSP is working in, causing inconsistent results; i.e. showing data not 
processed yet by the .75*x + 1000 on time, then showing processed data the next.

Under Windows, things like displaying a buffer of data using Win GDI calls do 
tend to take a bit of time.  At sampling rates of 120 kHz, with a typical buffer 
size of 1000 to 10000 points (10 msec to 100 msec), the host certainly is going 
to have a hard time staying in real-time; with buffer sizes less than 1000 
there's no way.

>This occurred at 20k, and 40k sampling rates. 110K sampling was even 
>odder, still with Flatline flashes.
>Question : Can we do a 120K sample and do a clean bit of real time 
>processing on the data, without baseline bounce ?

There is also a mode 2 (digital scope), which allows the DSP and host to 
synchronize.  In this case, the host can go off and do any type of display or 
processing, for any amount of time, and the host and DSP will always stay 
synchronized, one buffer apart, and never "partake of each other's buffer".  But 
mode 2 is not continuous from the DSP's point of view; analog input data can be 
missed if the host cannot stay in real-time.  We call this "frame based 
operation", rather than continuous operation.  It is typically used in 
instrumentation applications, where the operator is not concerned as much with 
processing all points as with seeing an accurate snap-shot of what is happening, 
with no artifacts.

It depends on what you need your DSP code to do.  If you want continuous analog 
I/O operation on the DSP side, then you should use mode 6.  If you cannot 
guarantee fast host operation in mode 6, then what you might do is create an 
isolated, "processed" data buffer in the DSP code, where you put results when 
they are finished, independently of what the DSP is doing in handling the 
double-buffered continuous input/output data.  The host can then read from the 
isolated buffer as needed, on its own time schedule.  Even if the DSP is putting 
new data there at the same time the host is reading, there (likely) won't be a 
dramatic change in what the user / operator sees.

>3) I modified the dscope.c and built the dscope32 project under Visual C 
>5 (after finding out it would not build under 6.0). It also had the baseline 
>flashes, but the data itself (again noise) was much flatter.

Dscope32 should build fine under Visual C 6.0.  What error did you get?  Did you 
open the dscope32.mdp file as the project file?

If you are running the dscope dmeo, there should be no flashes whatsoever -- 
data display should be smooth, with no spikes or drop-out sections.  What is 
your driver selection in the DSP/Analog Hardware Selector dialog box?  Are you 
using "SigC32" or "SigC32 with no DMA"?  You might try the 
"no DMA" driver selection.

>Question : Shouldn't rtcode and dscope32 have worked the same ? Did 
>I miss something in the mod of dscope.cpp ?

See comments about mode 6 and mode 2 above.

>Attached are my files. Note that my first important bit of application to 
>demonstrate is a clean 49 KHz AM modulation of the input at an fs of 120 KHz.
>Should be simple.

Tell me what this means on the DSP side.  What processing must be applied?  Note 
that in mode 6, 120 kHz is pushing real-time limits.  If you want very fast DSP 
processing, for example, more than 120 kHz in mode 6, you have to mess with the 
mode 6 ISR (interrupt service routine).  Here are some general notes about this:

     -you can streamline the isr6.asm file, for mode 6
      ISR (interrupt service routine).  Features not
      required, such as triggering, recording maximum
      amplitude tracking, digital scale and offset,
      etc. should be removed.

     -you will need to use the Texas Inst. C3x assembler
      to assemble these changes, then re-link.  The new
      COFF file (i.e. executable C3x program file) can
      then be used with standard Hypersignal and DSPower
      functions.  See the section in Signalogic DSP Users
      Guide about modifying C3x Source Code for more

     -at some point, what you might want to do is add a
      user-defined property (variable in asm or C code
      on the DSP side) which you can set from the host,
      and instruct the DSP code whether to use the default
      ISR 6, or the "fast ISR 6".  This would allow you
      to use the built-in mode 6 functionality when needed,
      and avoid it when higher performance is needed.

Jeff Brower

W32DEF File and reset.s File

From: Jeff 
Subject: Re: wait states and other stuff
To: Scott 
Date: 08/31/99


>Do I need to explicitly set the external memory waits
>states to zero within area A?  I thought I read somewhere
>that this was done already so I did not have to worry about that in userproc.

Already done.  See reset.s file.

>In your last email you mentioned anabfk.  I noticed that it is defined 
>or set to zero in the W32DEF file. So it looks like this must define 
>an offset since the memory 0x0000 0x200 is reserved for signalogic stuff. Right?

Be careful, the value in w32def.s is the *default* value.  The DSInitBoard and 
DSInitProcessor calls see the default value, and change the value depending on 
the board type and amount of memory.  There are 2 important notes about this:

  -if you change the default value in w32def.s, re-assemble and re-link, then 
   the host will not touch the value

  -to get the actual value being used, you must do a DSGetHVarMem(hBoard, 
   DSP_TIMDATAADDR) call and read the value after downloading your program 
   (i.e. calling DSLoadProcessor)

>What is the purpose of the stimulas buffer stmbfk?  It is set to 0x10000.

Output buffer (actually 2 buffers, each of size determined by DSP_STMBUFLEN 
property).  Anabfk is input, Stmbfk is output.  Of course, anabfk is also 2 
buffers, size determined by DSP_BUFLEN property.  Note that in most 
applications, DSP_BUFLEN and DSP_STMBUFLEN should be set the same.

>So the actual address of the input data found below is 0x43008 for the input data right?

Sounds reasonable.

>My C buffer starts at 0x41f4 according to the MAP file and is 0x1000 long.
>So it looks like there should not be a problem of overlap there.

Not with anabfk, but what about with code?  Where is your last executable code? 
What is the last address it consumes?  You have to study the map file to see 
what code section (including .text, .data, and .bss) is highest.

>Looking at what comes back when I do:
>// get address of input time domain data
>   dwBufferBaseAddr = DSGetHVarMem(hBoard, DSP_TIMDATAADDR);
>// dwBufferBaseAddr gets set to 10240
>   dwBufferBaseAddr += 32768;
>// dwBufferBaseAddr now set to 43008
>   DSPutHVarMem(hBoard, DSP_TIMDATAADDR, dwBufferBaseAddr);
>// put output time domain data buffer after input buffer
>// dwOutBufferBaseAddr is set to 45056
>   dwOutBufferBaseAddr = dwBufferBaseAddr + 2 * wBuflen*NumChan;
>   DSPutHVarMem(hBoard, DSP_STMDATAADDR, dwOutBufferBaseAddr);

One possible problem here:  the output buffer is only 2048 bytes higher than the 
input buffer.  This means the input buffer size can be 512 samples max before 
bumping into output (i.e. 512 x 2 buffers x 2 bytes per sample).  What is your buffer size?

>One last question, if it is taking you too long to do the processing
>to keep up with real time acquisition,  do you need to do nothing for
>the next couple of frame cycles to catch up and then do your
>processing again?  Like in the CAIP work they calculate sets of data at most 
>twice a second.  So do they take a snapshot of data, process it, skip a few 
>frames to catch back up, take snapshot, etc.?

That is one way to handle it.  Keep in mind that in a system using a reasonably 
fast sampling rate, say anything 8 kHz or more, the user can't possibly make 
sense of a display showing every frame--even if the host code was very, very 
fast and the system can do it.  And Windows C/C++ or Visual Basic or other code 
isn't going to be this fast, anyway.  Most user-interface displays are concerned 
with giving the operator an accurate snap-shot, which updates a most a few times per sec.

Jeff Brower

Analog Device C Runtime Procedure

From: Yolanda 
Subject: Re: Question
To: Lionel 
Date: 09/07/99

Hi Lionel,

>I would like to know how can I use a Analog Device C runtime procedure in your 
>UserProc.c.  For example, I have a procedure Foo in a Foo.h header file.
>How can I can Foo in the Userproc

Since Userproc.c is a C procedure, you can call Foo from Userproc as you will in 
any C program:


void Userproc(void){

  foo(100)  /* call foo and pass 100 as parameters */


If you want to call C routine from ASM or vice versa, then you will have to 
Consult the ADSP-21000 Family C Tools Manual Chapter 4 "Assembly Language 
Interface" for detail information.

We call userproc() in our ASM file too.  UserProc() is called from MODUL6.ASM.  
You can use that as a reference.

Almost forget, you need to compile your foo.c and link it with the other files. 
To link it, edit A60link.cmd such that it include the object file of foo.c.  
Also, you might need to modify the archetecture file, A60link.ach.

With regards

Corrected UserProc Files

From: Jeff
Subject: Re: Corrected UserProc files 
To: Lionel 
Cc: Jean
Date: 09/21/99


Yolanda has put together some new files and information which I have summarized 

1) As shown in the error message in your compile.jpg screen print, "the memory 
size for section seg_pmco in the architecture file is insufficient", it was 
necessary to modify the seg_pmco segment in the a60link.ach architecture file to 
increase code space.  We made this change for you, and the modified a60link.ach 
is attached below.

Note that if in the future, as you add more code or data areas, you may have to 
edit the different segments in a60link.ach to accommodate these changes.

2) Since you would like to use Analog Devices library files, in the linker 
batch file (lnk.bat) you will need to add the C Runtime library linker 
option, -lc.  Note also that I think you can put the -lc option directly in the 
.cmd file.

3) In VibProc.c (formerly userproc.c), you have called a SWAP Macro which is 
defined in MACROS.H.  However, macros.h is not included as the header file, so 
we add that in for you, too.  Please remember in the future to add all .h files 
that will be needed for your application--standard C programming practice.

4) Note that our changes should enable to you successfully compile and link.  
This does not guarantee that your code will run!  There may be some debugging in 
your future.

Jeff Brower

Compile Error: LNK1136(Invalid or Corrupt File)

From: Jeff 
Subject: Re: NIST problem with HwLib + M44
To: Marc 
Date: 10/13/99


>I try to use your DSPower-HWLib Software. Compiling your dscope.cpp
>example program with Visual C++ 6.0 under Windows 98 produce the error
>LNK1136 ("invalid or corrupt file") for the hwlib.lib file. The
>explanation for this error is : "The input file either has a corrupt
>header or is zero size or abnormally small".

Please load the "dscope32" project (browse and click on 
\dspower\hwlib\dscope32.mdp filename).  I think what you are trying to do is 
load the "dscope" project, which is a Win16 project.

Dscope32.mdp is a Win32 project for Visual C++ 5.0 and higher.  It references 
hwlib32ms.lib, hwmgr32ms.lib, enmgr32ms.lib, and tlib32ms.lib, which are .lib 
files suitable for Microsoft Visual C++.

Try this and tell us what happens.

Also, when was the last software update you received from Signalogic?  We have 
made a lot of improvements for M44 and module support.  The current version of 
DSPower-HwLib software has more Visual C++ demos (including simultaneous analog 
I/O), more MATLAB demos, and more Visual Basic demos.  

Jeff Brower

DSP to Host Communication

From: Jeff 
Subject: Re: DSP to HOST Communication
To: Scott 
Cc: Hanh 
Date: 10/28/99


>My machine at home seems to be doing weird things but at least it was able to
>send data to the host program via the above function calls.  Since I have been
>having problems with the DSP board on my home machine, I have been using the 
>machine at school that I also installed a signalogic board on. It seems to run 
>my DSP code ok but I can not get anything across to the host code.
>The following is defined in userproc and host code:
>short int tdoa1;
>tdoa1 = 5;
>DWORD tdoa_ptr;
>short int T12;
>   tdoa_ptr = DSGetSymbolAddress(hBoard, NULL, "tdoa1");
>   case WM_BUF_READY (or something like that)
>      DSGetMem(hBoard, DS_GM_LINEAR_DATA, tdoa_ptr/2, DS_GM_SIZE16, &T12, 1);
>I am always getting the value zero for T12.

The declarations and divide-by-two in the above code look Ok.  What is the value 
of tdoa_ptr after DSGetSymbolAddress call?  Are you making DSGetSymbolAddress 
call after DSLoadFileBoard() or DSLoadFileProcessor() call?  What is the return 
value of the DSGetMem() call?  I don't think it makes any difference, but you 
might also try the DS_GM_LINEAR_DATA_RT parameter in the DSGetMem() call.

>With the different CDs that you sent with possible bugs, could it be that I 
>don't have the latest on this machine to support this?

There is always stuff we are adding and bugs we are fixing.  But the 
GetSymbolAddress call has not changed or been in for repair in a long time.  It 
should work fine in your software / CD version.

>Although I do see the prototype for DSGetSymbolAddress in the header file.
>Is there a new realease of the supporting code with patches and updates?

Yes, there is a new release.  I have asked Hanh to send to you an update CD so 
that you have the latest, although I don't think it will make a difference for 
GetSymbolAddress related functionality.

Jeff Brower

Setting DSP_Gainlist Variable in DScope.cpp