/* fixed-length 48-byte records */                                            
#define PWSA_RECSIZE 48                                                       
                                                                              
/* utility macros (use these to generate access macros, not directly in code) 
 * p is a buffer pointer of any type (pointing to the beginning of the record)
 * i and j are high-order and low-order (respectively) byte offsets           
 */                                                                            
#define xINT1(p,i)      ( (int)((unsigned char *)(p))[i] )                    
#define xINT2(p,i,j)    ( xINT1(p,i) << 8 | xINT1(p,j) )                      
                                                                              
/* extract fields given a pointer to a record (assumes ints >= 32-bits)       
 * y1900 - years past 1900 (2001 = 101)                                       
 * hoy   - hour of year beginning with 24 (so hoy / 24 = day of year)         
 * soh   - second of hour                                                     
 * msec  - millisecond of second                                              
 * mod16 - FDS SCLK modulo 65536 (2**16) counter                              
 * mod60 - FDS SCLK modulo 60 counter (increments every 48 seconds)           
 * line  - FDS SCLK line counter (1-800)                                      
 * mode  - telemetry mode                                                     
 * sc    - 1 for VG1 and 2 for VG2 (note arrays indexed with sc-1 )           
 */                                                                            
#define PWSA_y1900(p)   xINT2(p,1,0)                                          
#define PWSA_hoy(p)     xINT2(p,3,2)                                          
#define PWSA_soh(p)     xINT2(p,5,4)                                          
#define PWSA_msec(p)    xINT2(p,7,6)                                          
#define PWSA_mod16(p)   xINT2(p,9,8)                                          
#define PWSA_mod60(p)   xINT2(p,11,10)                                        
#define PWSA_line(p)    xINT2(p,13,12)                                        
#define PWSA_mode(p)    xINT1(p,14)                                           
#define PWSA_sc(p)      xINT1(p,15)                                           
                                                                              
/* PWSA_dn(p,c) returns data number bits as stored in the cd format given a   
 * pointer to a record "p" and a channel number "c" (0-15).  Note that        
 * corrections must still be made for CR5A/UV5A 10-bit sums and for negative  
 * values.  For 10-bit sums, simply divide the data number by 4.0.            
 * Some GS3 are tagged negative (for interference), but PWSA_dn will only     
 * return the least significant 16-bits of this.  After "idn = PWSA_dn(p,c);" 
 * one might use "if (idn & 0x8000) idn = 0;" to ignore these or else         
 * "if (idn & 0x8000) idn |= 0xFFFF0000;" to sign extend for a 32-bit         
 * negative value.                                                            
 */                                                                            
#define PWSA_dn(p,c)    xINT2(p,((c)<<1)+17,((c)<<1)+16)                      
                                                                              
/* more convenient derived time components */                                 
#define PWSA_year(p)    ( PWSA_y1900(p) + 1900 )                              
#define PWSA_day(p)     ( PWSA_hoy(p) / 24 )                                  
#define PWSA_hour(p)    ( PWSA_hoy(p) % 24 )                                  
#define PWSA_minute(p)  ( PWSA_soh(p) / 60 )                                  
#define PWSA_sec(p)     ( PWSA_soh(p) % 60 )                                  
#define PWSA_msod(p)    ( PWSA_msec(p)+PWSA_soh(p)*1000+PWSA_hour(p)*3600000 )
                                                                              
/* valid telemetry modes */                                                   
#define CR2   0x01                                                            
#define CR3   0x02                                                            
#define CR4   0x03                                                            
#define CR5   0x04                                                            
#define CR6   0x05                                                            
#define CR1   0x07                                                            
#define GS10A 0x08                                                            
#define GS3   0x0A                                                            
#define GS7   0x0C                                                            
#define GS6   0x0E                                                            
#define OC2   0x16                                                            
#define OC1   0x17                                                            
#define CR5A  0x18                                                            
#define GS10  0x19                                                            
#define GS8   0x1A                                                            
#define UV5A  0x1D                                                            
                                                                              
static const char *TLM_mode_name[32] = {                                      
"ENG0","CR2","CR3","CR4","CR5","CR6","CR7","CR1",                             
"GS10A","0x09","GS3","0x0B","GS7","0x0D","GS6","GS4",                         
"0x10","GS2","0x12","0x13","0x14","0x15","OC2","OC1",                         
"CR5A","GS10","GS8","0x1B","0x1C","UV5A","0x1E","0x1F" };                     
                                                                              
/* channel frequencies in Hz (indexed 0 - 15) */                              
static const double PWSA_freq[16] = {                                         
     10.0,    17.8,    31.1,    56.2,                                         
    100.0,   178.0,   311.0,   562.0,                                         
   1000.0,  1780.0,  3110.0,  5620.0,                                         
  10000.0, 17800.0, 31100.0, 56200.0 };                                       
                                                                              
/* channel bandwidths in Hz, indexed by sc (0 - 1) and channel (0 - 15) */    
static const double PWSA_bw[2][16] = { {                                      
    2.99, 3.77, 7.50,10.06, 13.3,  29.8,  59.5,  106.,                        
    133., 211., 298., 421., 943., 2110., 4210., 5950. }, {                    
    2.16, 3.58, 4.50, 10.7, 13.8,  28.8,  39.8,  75.9,                        
    75.9, 151., 324., 513., 832., 1260., 2400., 3800. } };                    
                                                                              
/* effective electrical length of antenna in meters */                        
#define PWS_elength 7.07                                                      
