/* Application headers */
#include "simcom.h"
#include "simdev.h"
#include "simusr.h"
#include "driver.h"
#include "cc.h"
#include "adsreg58.h"
#include "protocom.h"

/* Local defines */
#define SR_LF 0x8000l /* Loop flag bit in SR */

#define P_FLASH_CLOCK 4000
#define X_FLASH_CLOCK 4000

/* Structure definitions */
/* This is for the unix device driver */
#if UNIX

struct fakeit
{
#if SUN4
    char fake[_IOCPARM_MASK];
#else
    char fake[IOCPARM_MASK];
#endif /* SUN4 */
};

#endif

#if ADSx && WIN_NT
#undef n_name
#undef N_BTMASK
#undef N_TMASK
#undef N_BTSHFT
#undef N_TSHIFT
#undef REG_NONE

#include <windows.h>
#include <winioctl.h>

extern HANDLE hndDevice;

#include "..\\drivers\\WinNT\\mdspioctl.h"
/*
// intercept from device driver for NT. filename=mdspioctl.h


#define MDSP_TYPE 40000
#define IOCTL_MDSP_READ_PORT_UCHAR  CTL_CODE( MDSP_TYPE, 0x900, METHOD_BUFFERED, FILE_READ_ACCESS )

#define IOCTL_MDSP_WRITE_PORT_UCHAR  CTL_CODE(MDSP_TYPE,  0x910, METHOD_BUFFERED, FILE_WRITE_ACCESS)
*/
#endif


/* Static function declarations */
static int adm_read (int, int , unsigned long, unsigned long, unsigned long *);
static int adm_write (int, int, unsigned long, unsigned long, unsigned long *);
static int adm_write_flash (int, int, unsigned long, unsigned long, unsigned long *);
static int adm_erase_flash (int, int, unsigned long, unsigned long);
static int send_byte (int, unsigned);
static int send_words (int, unsigned long, unsigned long *);
static int send_cc_words (int, unsigned long, unsigned long *);
static int get_words (int, unsigned long, unsigned long *);
static int get_cc_words (int, unsigned long, unsigned long *);
static int flag_test (int, int);
static int select_device (int);
static void deselect_device (void);
static void select_cc (int);
static int input (int);
static void output (int, int);
static int handshake (int, int);
static void reverse_array (unsigned long *, int);

static int load_cc_monitor (int, char *);
static int match_idx (char *, char **, int);
static void serial_cc_load (int, unsigned long, unsigned long,
                            unsigned long *);
static int parallel_cc_load (int, unsigned long, unsigned long, unsigned long,
                             unsigned long *);
static void serial_output (int);
static void sclock_out (int);
static int strcmp_i (char *, char *);

static int set_active_device (int);
static int get_jtag_count (int, int);
static int configure_cc (int);


/* Extern function declarations */
#if macintosh
extern pascal int peekb (char *);
extern pascal void pokeb (int *, int);

#endif

extern struct dev_var *dv_var;
extern struct dt_var *dx_var; /* Only needed to detect the actual device
                                 type for the 56811 interrupt bug workaround */
extern struct dev_const dv_const;

static int TIMEOUT = 1;
static int HOST_ADDRESS = 0;
static int table_offset_multiplier = BYTES_PER_MOVEP_OPCODE;
static int once_table_offset_multiplier = 3;

static struct cc_config cc_info[] =
{
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE},
    {DSP_OLD_CC, 1, 1, FALSE, FALSE}
};

static struct dev_config dev_info[] =
{
    {0, 0, 0},
    {1, 0, 0},
    {2, 0, 0},
    {3, 0, 0},
    {4, 0, 0},
    {5, 0, 0},
    {6, 0, 0},
    {7, 0, 0},
    {8, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0},
    {0, 0, 0}
};


/* Public functions */
int
dspd_read_core_registers (int device_index,
			  int reg_num,
			  unsigned long count,
			  unsigned long *value)
{
    int error;
    unsigned long sr;
    
    select_device (device_index);

    /* If range includes the top of the stack */
    if (((reg_num + count) > ADS_HWS) && (reg_num <= ADS_HWS))
    {
        /* Read Loop Flag */
        error = adm_read (device_index, RREAD, (unsigned long) ADS_SR, 1l,
                          &sr);

        if (error != DSP_ERROR)
        {
            error = adm_read (device_index, RREAD, (unsigned long) reg_num,
                              count, value);

            if ((sr & SR_LF) && error != DSP_ERROR)
            {
                /* You popped the hardware stack, so push back the top value */
                error = adm_write (device_index, RWRITE,
                                   (unsigned long) ADS_HWS, 1l,
                                   &value[ADS_HWS - reg_num]);
            }
        }
    }

    else
    {
        error = adm_read (device_index, RREAD, (unsigned long) reg_num,
                          count, value);
    }

    deselect_device ();

    return (error);
}


int
dspd_write_core_registers (int device_index,
			   int reg_num,
			   unsigned long count,
			   unsigned long *value)
{
    int error;
    
    select_device (device_index);
    
    error = adm_write (device_index, RWRITE, (unsigned long) reg_num, count,
                       value);

    deselect_device ();
    
    return (error);
}

int
dspd_read_once_registers (int device_index,
			  int reg_num,
			  unsigned long count,
			  unsigned long *value)
{
    int error;

    select_device (device_index);

    /* send command */
    if (send_byte (device_index, OREG_RD) ||
	send_byte (device_index, reg_num) ||
	send_byte (device_index, (int) count))
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    /* get data */
    else if (get_words (device_index, count, value))
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    deselect_device ();

    /* The command converter returns the values in the opposite order */
    reverse_array (value, count);

    return (error);
}

int
dspd_write_once_registers (int device_index,
			   int reg_num,
			   unsigned long count,
			   unsigned long *value)
{
    int error;
    unsigned long word_count;

    select_device (device_index);

    /* send command */
    if (send_byte (device_index, OREG_WR) ||
	send_byte (device_index, (reg_num * once_table_offset_multiplier)) ||
	send_byte (device_index, (int) count))
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    /* send data */
    else
    {
	for (word_count = 0; word_count < count; word_count++)
	{
	    if (send_words (device_index, 1l, &value[word_count]))
	    {
		deselect_device ();
		return (DSP_ERROR);
	    }
	}
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    deselect_device ();

    return (error);
}


int
dspd_read_memory (int device_index,
		  int mem_space,
		  unsigned long address,
		  unsigned long count,
		  unsigned long *value)
{
    int command = PREAD;
    int error = DSP_OK;
    
    switch (mem_space)
    {
    case P_MEM:
	command = PREAD;
	break;
    case X_MEM:
	command = XREAD;
	break;
    case Y_MEM:
	command = YREAD;
	break;
    default:
	error = DSP_ERROR;
	break;
    }
    
    if (!error)
    {
	select_device (device_index);
	
	error = adm_read (device_index, command, address, count, value);
	
	deselect_device ();
    }
    
    return (error);
}

int
dspd_write_memory (int device_index,
		   int mem_space,
		   unsigned long address,
		   unsigned long count,
		   unsigned long *value)
{
    int command = PWRITES;
    int error = DSP_OK;
    
    switch (mem_space)
    {
    case P_MEM:
	command = PWRITES;
	break;
    case X_MEM:
	command = XWRITES;
	break;
    case Y_MEM:
	command = YWRITES;
	break;
    default:
	error = DSP_ERROR;
	break;
    }
    
    if (!error)
    {
	select_device (device_index);
	
	error = adm_write (device_index, command, address, count, value);
	
	deselect_device ();
    }
    
    return (error);
}

int
dspd_set_flash_clock (int device_index,
					  int mem_space,
                      int device_freq,
                      int reset_clock)
{
    long fcdr_reg;
    int  error = DSP_OK;
    
    /*
    long factor_table[31] = { 0x0400, 0x0800, 0x0c00, 0x1000,
                              0x1400, 0x1800, 0x1c00, 0x2000,
                              0x2400, 0x2800, 0x2c00, 0x3000,
                              0x3400, 0x3800, 0x3c00, 0x4000,
                              0x4400, 0x4800, 0x4c00, 0x5000,
                              0x5400, 0x5800, 0x5c00, 0x5000,
                              0x6400, 0x6800, 0x6c00, 0x6000,
                              0x7400, 0x7800, 0x7c00};
    */


    /* Find the proper division factor for theFlash Clock Divider,
       so that it is 1 MHz+/-10%.  This is an actual restriction,
       the core frequency cannot be less than 4MHz.
    */

    /*
    char div_factor = device_freq/1000/(mem_space==P_MEM ? 1 : 2);
    */
    
    
    /* our operating range is 4<=div_factor<=64 */
    /*
    if (div_factor < 4 || div_factor > 64)
    {
        return (DSP_ERROR);
    }
    
    fcdr_reg = factor_table[(div_factor-4)/2];

    */
    fcdr_reg = ((device_freq/4000) << 10) & 0x7FFF;

    if ( fcdr_reg < 1 )
    {
        return (DSP_ERROR);
    }
    
    /* set the core requency */
    error = dspd_write_memory (device_index, /* device index */
                               X_MEM,        /* FCDR is mapped to X-mem */
                               0xffc4,       /* address */
                               1l,           /* only one data to write */
                               &fcdr_reg);   /* new value */
    if ( error != DSP_OK )
    {
        return (error);
    }
    
    /* if we are trying to lower the clock rate */
    if ( ! reset_clock ) 
    {
        /*
        fcdr_reg = 0x8000 | factor_table[(div_factor-4)/2];
        */
        fcdr_reg = 0x8000 | ((device_freq/4000) << 10);
        
        /* enable the FCDR */
        error = dspd_write_memory (device_index, /* device index */
                                   X_MEM,        /* FCDR is mammped to X-mem */
                                   0xffc4,       /* address */
                                   1l,           /* only one data to write */
                                   &fcdr_reg);   /* new value */
        /* the above two operations, set the devide ratio and enable FCDR,
           must be caried out seperately according to the spec
        */
    }

    return error; 
}

int
dspd_set_commandconv_clock ( int device_index, unsigned long device_freq )
{
    int error = DSP_OK;
    
#if macintosh || MSDOS
    unsigned int protocol[3];

    int index;

    select_cc (get_cc_num(device_index));

    /* if the clock frequency is higher that 65MHz just make it maximum */
    if ( device_freq > 65000 )
    {
        device_freq = 65000;
    }

    /* if the clock frequency is less that 4MHz just make it minimum */
    if ( device_freq < 29 )
    {
        device_freq = 29;
    }

    protocol[0] = MODIFY_COM_SPEED;      /* command */

    /* the clock speed */
    protocol[1] = (unsigned) ((device_freq >> 8) & 0xffl);  /* high clock-speed byte */
    protocol[2] = (unsigned)  (device_freq & 0xffl);        /* low clock-speed byte */
                                                                
    /* send command */ 
    for (index = 0; index < sizeof (protocol) / sizeof (unsigned int); index++)
    {
        if (send_byte (device_index, protocol[index]))
        {
            return (DSP_ERROR);
        }
    }

    /* wait for CC to complete command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

#else
    char protocol[4];

    select_cc (get_cc_num(device_index));

    /* if the clock frequency is higher that 65MHz just make it maximum */
    if ( device_freq > 65000 )
    {
        device_freq = 65000;
    }

    /* if the clock frequency is less that 4MHz just make it minimum */
    if ( device_freq < 29 )
    {
        device_freq = 29;
    }


    protocol[0] = (char) 3;                    /* command count */
    protocol[1] = (char) MODIFY_COM_SPEED;     /* command */

    /* the clock speed */
    protocol[2] = (unsigned) ((device_freq >> 8) & 0xffl);  /* high address byte */
    protocol[3] = (unsigned)  (device_freq & 0xffl);        /*  low address byte */

    /* send command */
    if (ioctl (HOST_ADDRESS, MDSPCOMMAND, protocol))
    {
        return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);    

#endif /* machintosh || MSDOS */

    return (error); 
}


int
dspd_write_flash (int device_index,
                  int device_freq,
                  int mem_space,
                  unsigned long min_addr,
                  unsigned long max_addr,
                  unsigned long *value)
{
    int  command    = PROGRAM_PFLASH;
    int  error      = DSP_OK;
    long coreRegs[21];
	long xSave;

    
    switch (mem_space)
    {
    case P_MEM:
        command = PROGRAM_PFLASH;
        break;
    case X_MEM:
        command = PROGRAM_XFLASH ;
        break;
    default:
        error = DSP_ERROR;
        break;
    }


    /* if there was an error, just return */
    if (error != DSP_OK)
    {
        return (error);
    }

    /* before starting anything else, save the core registers */
    dspd_read_core_registers (device_index,  /* device index */
                              0,             /* register index */
                              21l,           /* count */
                              coreRegs);     /* value to be put into */

    /* if the command is PROGRAM_XFLASH we have to save the X:0x0001 */
    if ( command == PROGRAM_XFLASH )
    {
        dspd_read_memory( device_index, mem_space, 0x0001L, 1L, &xSave );
    }

    /* slow the command converter speed down
       if P_MEM => 4000 KHz
       if X_MEM => 4000 KHz
    */
    dspd_set_commandconv_clock ( device_index, mem_space==P_MEM ? P_FLASH_CLOCK : X_FLASH_CLOCK );

    /* slow the core speed down */
    dspd_set_flash_clock ( device_index, mem_space, device_freq, 0 );

    /* write the data out */
    if (!error)
    {
        select_device (device_index);
	
        error = adm_write_flash ( device_index, command, min_addr, max_addr, value );
	
        deselect_device ();
    }

    /* set the core speed back to what it was */
    dspd_set_flash_clock ( device_index, mem_space, device_freq, 1);

	/* increase the command converter speed back up again */
    dspd_set_commandconv_clock ( device_index, device_freq );

    /* if the command is PROGRAM_XFLASH we have to restore the X:0x0001 */
    if ( command == PROGRAM_XFLASH )
    {
        dspd_write_memory( device_index, mem_space, 0x0001L, 1L, &xSave );
    }

    /* when done, restore the core registers */
    dspd_write_core_registers (device_index,  /* device index */
                               0,             /* register index */
                               18l,           /* count */
                               coreRegs);     /* new value */
    /* we are just skipping the HWR register */
    dspd_write_core_registers (device_index,  /* device index */
                               19,            /* register index */
                               2l,            /* count */
                               &coreRegs[19]);/* new value */

    return (error);
}


int
dspd_erase_flash (int device_index,
                  int device_freq,
                  int mem_space,
                  unsigned long blocksize,
                  unsigned long address )
{
    int  command    = PROGRAM_PFLASH;
    int  error      = DSP_OK;
    long coreRegs[21];

    
    switch (mem_space)
    {
    case P_MEM:
        command = ERASE_PFLASH;
        break;
    case X_MEM:
        command = ERASE_XFLASH ;
        break;
    default:
        error = DSP_ERROR;
        break;
    }

	/*
	   ERASE THIS
	*/
    /* device_freq = 20000; */

    /* if there was an error, just resturn */
    if (error != DSP_OK)
    {
        return (error);
    }

    /* before starting anything else, save the core registers */
    dspd_read_core_registers (device_index,  /* device index */
                              0,             /* register index */
                              21l,           /* count */
                              coreRegs);     /* value to be put into */
     
    /* slow the command converter speed down
       if P_MEM => P_FLASH_CLOCK (4000) KHz
       if X_MEM => X_FLASH_CLOCK (4000) KHz
    */
    dspd_set_commandconv_clock ( device_index, mem_space==P_MEM ? P_FLASH_CLOCK : X_FLASH_CLOCK );

    /* slow the core clock speed down */
    dspd_set_flash_clock ( device_index, mem_space, device_freq, 0 );

    /* write the data out */
    if (!error)
    {
        select_device (device_index);
	
        error = adm_erase_flash ( device_index, command, blocksize, address );
	
        deselect_device ();
    }

    /* set the core speed back to what it was */
    dspd_set_flash_clock ( device_index, mem_space, device_freq, 1 );
 
    /* increase the command converter speed back up again */
    dspd_set_commandconv_clock ( device_index, device_freq );
    
    /* when done, restore the core registers */
    dspd_write_core_registers (device_index,  /* device index */
                               0,             /* register index */
                               18l,           /* count */
                               coreRegs);     /* new value */
    /* we are just skipping the HWR register */
    dspd_write_core_registers (device_index,  /* device index */
                               19,            /* register index */
                               2l,            /* count */
                               &coreRegs[19]);/* new value */
    
    return (error);
}

int
dspd_fill_memory (int device_index,
                  int mem_space,
                  unsigned long address,
                  unsigned long count,
                  unsigned long value)
{
    int command = PWRITE;
    int error = DSP_OK;
    
    switch (mem_space)
    {
    case P_MEM:
        command = PWRITE;
        break;
    case X_MEM:
        command = XWRITE;
        break;
    case Y_MEM:
        command = YWRITE;
        break;
    default:
        error = DSP_ERROR;
        break;
    }
    
    if (!error)
    {
        select_device (device_index);
	
        error = adm_write (device_index, command, address, count, &value);

        deselect_device ();
    }
    
    return (error);
}

int
dspd_go (int device_index,
         unsigned long opcode,
	 unsigned long address)
{
    int error;
    int command = EXECIMED;

    if (dx_var->devnum == 0x2L &&
        dv_var->exec_method == 1) /* DSP56811 */
    {
        command = EXEC_56811;
    }
    else if (dv_const.sv[device_index]->pc_modified)
    {
        command = EXEC_FROM_ADDR;
    }

    select_device (device_index);

    if (send_byte (device_index, command) ||
        send_words (device_index, 1l, &opcode) ||
        send_words (device_index, 1l, &address))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    error = handshake (get_cc_num (device_index), TIMEOUT);

    deselect_device ();

    return (error);
}


int
dspd_break (int device_index,
            int command)
{
    int error;
    int break_type;
    int cc_num;
    int i;

    
    /* service device if it is yanking on host_brk */
    if (dspd_check_service_request (device_index) == TRUE)
    {
        return (DSP_OK);
    }

    select_device (device_index);

    /* HACK - for some reason the monitor does not like getting */
    /* break immediately after checking status if the target is */
    /* in an external access, so wait - Chris */

    for (i=0;i<0xFFFF;i++);

    /* send command */
    if (send_byte (device_index, command))
    {
        return (DSP_ERROR);
    }

    /* There are bugs in the command converter monitor.  Using DE to break
       is the only reliable way to break for the old command converter, and
       using the jtag break command is the only reliable way to break for
       the new command converter. */

    cc_num = get_cc_num (device_index);
    
    if (get_cc_type (cc_num) == DSP_NEW_CC)
    {
        break_type = DSP_BREAK_JTAG;
    }
    else
    {
        break_type = DSP_BREAK_DE;
    }

    /* send break type */
    if (send_byte (device_index, break_type))
    {
        return (DSP_ERROR);
    }

    error = handshake (cc_num, TIMEOUT);

    deselect_device ();

    return (error);
}

int
dspd_reset (int device_index,
            int reset_mode)
{
    time_t curtm;
    time_t endtime;
    int command = JTAG_RESET;

    
    /* service device if it is yanking on host_brk */
    (void) dspd_check_service_request (device_index);

    select_device (device_index);

    /* send reset command and mode to command converter */
    if (send_byte (device_index, command) ||
        send_byte (device_index, reset_mode))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* clear int_ack and adm_group */
    output (CTRL2, 0);

    /* wait for TIMEOUT seconds */
    (void) time (&curtm);
    for (endtime = curtm + TIMEOUT; curtm <= endtime; (void) time (&curtm));

    /* send terminate reset byte */
    if (send_byte (device_index, 0))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* wait for CC to complete the command */
    if (handshake (get_cc_num (device_index), TIMEOUT) == DSP_ERROR)
    {
        deselect_device ();
        return (DSP_ERROR);
    }
    
    deselect_device ();

    return (DSP_OK);
}


/*  Reset Jtag port */
int
dspd_jtag_reset (int device_index,
                 int reset_type)
{
    select_device (device_index);

    /* send reset command and type to command converter */
    if (send_byte (device_index, JTAG_RESET_STATE_MACHINE) ||
	send_byte (device_index, reset_type))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* wait for CC to complete the command */
    if (handshake (get_cc_num (device_index), TIMEOUT) == DSP_ERROR)
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    deselect_device ();
    return (DSP_OK);
}


int
dspd_status (int device_index, int *mode)
{
    int ok = TRUE;
    unsigned long status;
    
    /* Set up device number, etc in command converter */
    select_device (device_index);

    /* Ask cc if the device is requesting service */
    if (send_byte (device_index, GET_STATUS))
    {
        ok = FALSE;
    }

    if (ok)
    {
        if (get_words (device_index, 1l, &status))
        { 
            ok = FALSE;
        }
    }

    if (ok)
    {
        /* wait for CC to finish command */
        if (handshake (get_cc_num (device_index), TIMEOUT) == DSP_ERROR)
        {
            ok = FALSE;
        }
    }
    
    deselect_device ();

    if (ok)
    {
        *mode = (status & 0xc0l) >> 6;
    }
    
    if (ok)
    {
        if ((status & 0x30l) != 0x10l)
        {
            ok = FALSE;
        }
    }
    
    return (ok);
}


int
dspd_cc_architecture (int device_index,
		      int device_type)
{
    unsigned long flag;
    int cc_num;
    
    /* preset device type in monitor */
    if (dspd_cc_write_flag (device_index, DEVICE_ADDRESS,
                            device_type) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    /* Set tms0flag, jtagflag */
    if (dspd_cc_read_flag (device_index, DEVICE_FLAGS, &flag) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    if (dspd_cc_write_flag (device_index, DEVICE_FLAGS,
                            (flag | 0x18l)) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    cc_num = get_cc_num (device_index);
    
    select_cc (cc_num);

    /* send reset command and type to command converter */
    if (send_byte (device_index, OFORCER) ||
        send_byte (device_index, 2) ||
        send_byte (device_index, device_type))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* wait for CC to complete the command */
    if (handshake (cc_num, TIMEOUT) == DSP_ERROR)
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    deselect_device ();
    return (DSP_OK);
}

int
dspd_check_service_request (int device_index)
{
    int cc_num;
    
    /* check to see if any device is requesting service */
    if (input (CTRL1) & HST_BRK)
    {
        return (FALSE);
    }

    cc_num = get_cc_num (device_index);
    
    if (get_cc_type (cc_num) == DSP_OLD_CC)
    {
        /* check if specific device is requesting service */
        select_device (device_index);

        if ((input (CTRL1) & 0xf) == ADM_INT)
        {
            /* acknowledge service request */
            if (handshake (cc_num, TIMEOUT) == DSP_ERROR)
            {
                deselect_device ();
                return (DSP_ERROR);
            }

            else
            {
                deselect_device ();
                return (TRUE);
            }
        }

        else
        {
            deselect_device ();
            return (FALSE);
        }
    }

    else
    {
        unsigned long current_chain_pos;
        unsigned long tms_chain;
        unsigned long  chain_pos;
        int service_requested = FALSE;

        current_chain_pos = get_chain_pos (device_index);

        /* Set up device number, etc in command converter */
        select_device (device_index);

        /* Ask cc if the device is requesting service */
        if (send_byte (device_index, GET_REQUESTING_DEVICE))
        {
            deselect_device ();
            return (DSP_ERROR);
        }

        if (get_words (device_index, 1l, &tms_chain))
        { 
            deselect_device ();
            return (DSP_ERROR);
        }

        if (get_words (device_index, 1l, &chain_pos))
        { 
            deselect_device ();
            return (DSP_ERROR);
        }

        /* The command converter goes from 1 to n for chain positions */
        --chain_pos;

        /* wait for CC to finish command */
        if (handshake (cc_num, TIMEOUT) == DSP_ERROR)
        {
            deselect_device ();
            return (DSP_ERROR);
        }

        /* Check to see if device_index is the requesting device */
        if (get_tms_num (device_index) == tms_chain &&
            current_chain_pos == chain_pos)
        {
            service_requested = TRUE;

            /* Send command to clear HST_BRK and resume cc polling */
            if (send_byte (device_index, RESUME_POLLING))
            {
                deselect_device ();
                return (DSP_ERROR);
            }

            /* wait for CC to finish command */
            if (handshake (cc_num, TIMEOUT) == DSP_ERROR)
            {
                deselect_device ();
                return (DSP_ERROR);
            }
        }

        if (!service_requested)
        {
            int mode;
            
            /* Check to see if the current device is in debug mode */
            if (!dspd_status (device_index, &mode))
            {
                deselect_device ();
                return (DSP_ERROR);
            }

            if (mode == 0x3) /* Debug mode */
            {
                unsigned long executing_list;
                
                /* Clear executing bit for this device */
                if (dspd_cc_read_memory (device_index, DSP_CC_XMEM,
                                         0x20l, 1l,
                                         &executing_list) == DSP_ERROR)
                {
                    deselect_device ();
                    return (DSP_ERROR);
                }

                executing_list &= ~(0x1 << current_chain_pos);
                
                if (dspd_cc_write_memory (device_index, DSP_CC_XMEM,
                                          0x20l, 1l,
                                          &executing_list) == DSP_ERROR)
                {
                    deselect_device ();
                    return (DSP_ERROR);
                }

                service_requested = TRUE;
            }
        }
        
        return (service_requested);
    }
}


int
dspd_cc_read_memory (int device_index,
                     int memory_space,
                     unsigned long address,
                     unsigned long count,
                     unsigned long *value)
{
    int error;
    int cc_num;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    if (get_cc_type (cc_num) == DSP_NEW_CC)
    {
        /* send command */
        if (send_byte (device_index, SEQREAD) ||
            send_byte (device_index, (int) ((address >> 8) & 0xffl)) ||
            send_byte (device_index, (int) (address & 0xffl)) ||
            send_byte (device_index, (int) ((count >> 8) & 0xffl)) ||
            send_byte (device_index, (int) (count & 0xffl)) ||
            send_byte (device_index, memory_space))
        {
            deselect_device ();
            return (DSP_ERROR);
        }
    }
    else
    {
        /* send command */
        if (send_byte (device_index, SEQREAD) ||
            send_byte (device_index, (int) address) ||
            send_byte (device_index, (int) count) ||
            send_byte (device_index, memory_space))
        {
            deselect_device ();
            return (DSP_ERROR);
        }
    }
    
    /* get data */
    if (get_cc_words (device_index, count, value))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (cc_num, TIMEOUT);

    deselect_device ();

    return (error);
}

int
dspd_cc_write_memory (int device_index,
                      int memory_space,
                      unsigned long address,
                      unsigned long count,
                      unsigned long *value)
{
    int error;
    int cc_num;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    if (get_cc_type (cc_num) == DSP_NEW_CC)
    {
        /* send command */
        if (send_byte (device_index, SEQWRITE) ||
            send_byte (device_index, (int) ((address >> 8) & 0xffl)) ||
            send_byte (device_index, (int) (address & 0xffl)) ||
            send_byte (device_index, (int) ((count >> 8) & 0xffl)) ||
            send_byte (device_index, (int) (count & 0xffl)) ||
            send_byte (device_index, memory_space))
        {
            deselect_device ();
            return (DSP_ERROR);
        }
    }
    
    else
    {
        /* send command */
        if (send_byte (device_index, SEQWRITE) ||
            send_byte (device_index, (int) address) ||
            send_byte (device_index, (int) count) ||
            send_byte (device_index, memory_space))
        {
            deselect_device ();
            return (DSP_ERROR);
        }
    }
    

    /* send data */
    if (send_cc_words (device_index, count, value))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (cc_num, TIMEOUT);

    deselect_device ();

    return (error);
}

/*
 *      Flags
 *
 *	0		OnCE status bits
 *	1		command converter flags
 *	2		command converter OnCE sequence pointer
 *	3		command converter revision number
 *
 */
int
dspd_cc_read_flag (int device_index,
                   int flag,
                   unsigned long *value)
{
    int error;
    int cc_num;
    
    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    /* send command */
    if (send_byte (device_index, MISC_RD) ||
	send_byte (device_index, flag))
    {	
        deselect_device ();
        return (DSP_ERROR);
    }

    /* get data */
    if (get_words (device_index, 1l, value))
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    *value = *value >> 8;

    /* wait for CC to finish command */
    error = handshake (cc_num, TIMEOUT);

    deselect_device ();

    return (error);
}

/*
 *
 *	flag
 *	0		write to command converter flag
 *	1		write to command converter pointer
 *
 */
int
dspd_cc_write_flag (int device_index,
		    int flag,
		    unsigned long value)
{
    int error;
    int cc_num;
    

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    /* send command */
    if (send_byte (device_index, MISC_WR) ||
        send_byte (device_index, flag))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* send data */
    if (send_byte (device_index, (int) value))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* wait for CC to finish command */
    error = handshake (cc_num, TIMEOUT);

    deselect_device ();

    return (error);
}

int
dspd_cc_break (int device_index)
{
    int cc_num;
    
#if UNIX
    char devices[2];
#endif /* UNIX */
    
    cc_num = get_cc_num (device_index);

    select_cc (cc_num);

#if UNIX
    if (ioctl (HOST_ADDRESS, MDSPBREAK, devices))
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    deselect_device ();

    return (DSP_OK);

#else
    output (CTRL1, (cc_num << 4));

    /* set ADM_BRK to 1  */
    output (CTRL1, (cc_num << 4) | ADM_BRK);

    /* set ADM_BRK to 0  */
    output (CTRL1, (cc_num << 4));

    /* wait for ADM_INT=1 */
    if (flag_test (DSP_HIGH, ADM_INT) == DSP_ERROR)
    {
        deselect_device ();
        return (DSP_ERROR);
    }

    /* acknowledge irq rec. */
    output (CTRL2, INT_ACK);

    /* wait for ADM_INT=0 	 */
    if (flag_test (DSP_LOW, ADM_INT) == DSP_ERROR)
    {
        /* deassert INT_ACK */
        output (CTRL2, 0);
        deselect_device ();
        return (DSP_ERROR);
    }

    /* deassert INT_ACK */
    output (CTRL2, 0);

    deselect_device ();

    return (DSP_OK);
#endif
}


static unsigned long serial_loader[] = 
{
    0x08f4bel, 0x000220l, 0x08f4a4l, 0x007000l, 0x08f4a2l, 0x007f00l,
    0x0ab0f2l, 0x007fc6l, 0x0ab0f4l, 0x007fdal, 0x0ab0d6l, 0x007fc6l,
    0x0bf080l, 0x007fedl, 0x219000l, 0x0bf080l, 0x007fedl, 0x219100l,
    0x06d100l, 0x007fd7l, 0x0bf080l, 0x007fdfl, 0x07588cl, 0x000000l,
    0x0af080l, 0x007fc6l, 0x0bf080l, 0x007fedl, 0x219200l, 0x000000l,
    0x0ae280l, 0x200013l, 0x0bf080l, 0x007ff3l, 0x0608a0l, 0x200022l,
    0x0bf080l, 0x007ff3l, 0x0608a0l, 0x200022l, 0x0bf080l, 0x007ff3l,
    0x0608a0l, 0x200022l, 0x00000cl, 0x200013l, 0x0bf080l, 0x007fe4l,
    0x0608a0l, 0x200022l, 0x00000cl, 0x0ab0d6l, 0x007ff3l, 0x084a24l,
    0x0aa428l, 0x0ab0f6l, 0x007ff7l, 0x0aa408l, 0x00000cl
};


static unsigned long monitor[] =
{
    0xaf080l, 0x29bl, 0xa0131l, 0xc029dl, 0x0l, 0x0l, 0x0l, 0x0l, 0xbf080l,
    0x36bl, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0xbf080l,
    0x36bl, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0xa0132l, 0x0l,
    0x200033l, 0xaf0a0l, 0x46l, 0xa2120l, 0xaf080l, 0x47l, 0xa2100l,
    0xaf0a0l, 0x4dl, 0xb2121l, 0xaf0a0l, 0x4dl, 0xace70l, 0xa2121l, 0xcl,
    0x8f4a1l, 0x0l, 0x60920l, 0x0l, 0xb2120l, 0xaf0a0l, 0x5al, 0x60920l,
    0xaa528l, 0xaf080l, 0x5cl, 0x60920l, 0xaa508l, 0xa2123l, 0x55f400l,
    0x800001l, 0xbf080l, 0x6cl, 0xa2103l, 0x8f4bfl, 0x3el, 0xa0101l,
    0x55f400l, 0x800002l, 0xbf080l, 0x6cl, 0xa0126l, 0xa2101l, 0xcl,
    0x21ab00l, 0xa0124l, 0x8f4a1l, 0x0l, 0x6cb00l, 0x8al, 0x20003bl,
    0xa0184l, 0x8cl, 0xe8078l, 0xaa40dl, 0xc007bl, 0xaa42dl, 0x60920l,
    0x0l, 0xd0091l, 0x60920l, 0x0l, 0xb2123l, 0xaf0a0l, 0x8al, 0xba527l,
    0xaf0a0l, 0x88l, 0x60920l, 0xa2122l, 0xaf080l, 0x8al, 0x60920l,
    0xa2102l, 0x0l, 0xcl, 0xe808fl, 0xaa40el, 0xc007bl, 0xaa42el, 0xc007bl,
    0x8f4a1l, 0x0l, 0xaa526l, 0x60920l, 0x0l, 0xba527l, 0xaf0a8l, 0x9cl,
    0xa010al, 0xaf080l, 0x9dl, 0xa012al, 0xaa526l, 0x60920l, 0x0l,
    0xaa506l, 0x60920l, 0x0l, 0xcl, 0x8f4a1l, 0x0l, 0xb2120l, 0xaf0a0l,
    0xacl, 0xaa528l, 0xaf080l, 0xadl, 0xaa508l, 0xaa526l, 0x60920l, 0x0l,
    0xba527l, 0xaf0a8l, 0xb6l, 0xa2102l, 0xaf080l, 0xb7l, 0xa2122l,
    0xaa506l, 0x60920l, 0x0l, 0xcl, 0xa062dl, 0xa062el, 0xaf080l, 0xc9l,
    0xa060dl, 0xa062el, 0xaf080l, 0xc9l, 0xa062dl, 0xa060el, 0xaf080l,
    0xc9l, 0xa060dl, 0xa060el, 0x3f8l, 0x8f4bfl, 0x0l, 0x8f4adl, 0x3e60l,
    0x8f4a1l, 0x0l, 0x8f0acl, 0x6l, 0x8f4a1l, 0x1c0l, 0xcl, 0x548c00l,
    0x200023l, 0xaf0a8l, 0xdbl, 0xd00a4l, 0xc00d6l, 0xcl, 0x200013l,
    0x548c00l, 0xaf940l, 0x60b20l, 0x200027l, 0xaf0a8l, 0xe6l, 0xd00a4l,
    0x200033l, 0xc00e1l, 0xcl, 0x55f400l, 0x800003l, 0xd006cl, 0xd00bbl,
    0xaf080l, 0xf7l, 0x55f400l, 0x800003l, 0xd006cl, 0xd00bfl, 0xaf080l,
    0xf7l, 0x55f400l, 0x800003l, 0xd006cl, 0xd00c7l, 0x54a200l, 0xd0040l,
    0x547000l, 0xffefl, 0xaae86l, 0xfbl, 0xaae87l, 0xfdl, 0x54f000l,
    0xffefl, 0xd00dcl, 0xd004fl, 0xcl, 0x55f400l, 0x800003l, 0xd006cl,
    0xd00d5l, 0xd00bbl, 0xaf080l, 0x117l, 0x55f400l, 0x800003l, 0xd006cl,
    0xd00d5l, 0xd00bfl, 0xaf080l, 0x117l, 0x55f400l, 0x800003l, 0xd006cl,
    0xd00d5l, 0xd00c7l, 0x200013l, 0x20001bl, 0x547000l, 0xffefl, 0xaae86l,
    0x11bl, 0xaae87l, 0x11dl, 0x54f000l, 0xffefl, 0xa07a2l, 0x12al,
    0xa18a5l, 0x12al, 0x218d00l, 0x608a0l, 0x200033l, 0x608a0l, 0x20002bl,
    0x545b00l, 0xa07a2l, 0x12el, 0x555b00l, 0x55f400l, 0xc00003l, 0xd006cl,
    0x8f4bfl, 0x3el, 0xa0101l, 0xcl, 0x56f400l, 0x603l, 0x562200l,
    0x56f400l, 0xf03l, 0x562300l, 0xa0108l, 0xa0120l, 0x55f400l, 0xc00004l,
    0xd006cl, 0x578c00l, 0x550d00l, 0x60b00l, 0x185l, 0x0l, 0x56f400l,
    0x1l, 0x44fbfl, 0x200005l, 0xaf0a2l, 0x14el, 0xa2124l, 0xaf080l,
    0x14fl, 0xa2104l, 0x578b00l, 0x446bfl, 0x20005cl, 0x46f400l, 0x1l,
    0x200058l, 0x572400l, 0xbf080l, 0x250l, 0xaf0a0l, 0x170l, 0x54a200l,
    0xbf080l, 0x209l, 0x559500l, 0x47f400l, 0xd00000l, 0x45f400l,
    0xf00000l, 0x20006el, 0x20007dl, 0xaf0a2l, 0x16al, 0xa0106l, 0xa0135l,
    0xaf080l, 0x16el, 0x571100l, 0xa0128l, 0xa0100l, 0xa0115l, 0xaf080l,
    0x184l, 0x7f096l, 0xdecl, 0x76a400l, 0x0l, 0x7ee8fl, 0xacd57l,
    0xaf0a0l, 0x180l, 0x45f400l, 0x1l, 0x20006cl, 0x21aa00l, 0x54f400l,
    0xffffffl, 0xaf080l, 0x182l, 0x54a300l, 0x2a0300l, 0xbf080l, 0x229l,
    0x0l, 0x0l, 0x0l, 0x55f400l, 0x800002l, 0xd006cl, 0xcl, 0x56f400l,
    0xf03l, 0x562300l, 0xa0108l, 0xa0120l, 0x55f400l, 0xc00004l, 0xd006cl,
    0x578c00l, 0x550d00l, 0x60b00l, 0x1d3l, 0x0l, 0x56f400l, 0x1l,
    0x44fbfl, 0x200005l, 0xa2104l, 0x578b00l, 0x446bfl, 0x20005cl,
    0x46f400l, 0x1l, 0x200058l, 0x572400l, 0xbf080l, 0x250l, 0xaf0a0l,
    0x1bel, 0x54a200l, 0xbf080l, 0x209l, 0x559500l, 0x47f400l, 0xd00000l,
    0x45f400l, 0xf00000l, 0x20006el, 0x20007dl, 0xaf0a2l, 0x1b8l, 0xa0106l,
    0xa0135l, 0xaf080l, 0x1bcl, 0x571100l, 0xa0128l, 0xa0100l, 0xa0115l,
    0xaf080l, 0x1d2l, 0x7f096l, 0xdecl, 0x76a400l, 0x0l, 0x7ee8fl,
    0xacd57l, 0xaf0a0l, 0x1cel, 0x45f400l, 0x1l, 0x20006cl, 0x21aa00l,
    0x54f400l, 0xffffffl, 0xaf080l, 0x1d0l, 0x54a300l, 0x2a0300l, 0xbf080l,
    0x229l, 0x0l, 0x0l, 0x0l, 0xd00bbl, 0x54f400l, 0xffffffl, 0x547000l,
    0xffefl, 0xaae86l, 0x1dal, 0xaae87l, 0x1dcl, 0x54f000l, 0xffefl,
    0x54f400l, 0xffffffl, 0x547000l, 0xffefl, 0xaae86l, 0x1e4l, 0xaae87l,
    0x1e6l, 0x54f000l, 0xffefl, 0x54f400l, 0xffffffl, 0x547000l, 0xffefl,
    0xaae86l, 0x1eel, 0xaae87l, 0x1f0l, 0x54f000l, 0xffefl, 0x54f400l,
    0xffffffl, 0x547000l, 0xffefl, 0xaae86l, 0x1f8l, 0xaae87l, 0x1fal,
    0x54f000l, 0xffefl, 0x52f400l, 0x1l, 0x54f400l, 0xffffffl, 0xa2124l,
    0xbf080l, 0x229l, 0x55f400l, 0x800002l, 0xd006cl, 0xcl, 0x218a00l,
    0x608a0l, 0x200023l, 0x6ca00l, 0x213l, 0xd024al, 0xd0091l, 0x579500l,
    0xb012al, 0x20002fl, 0x551500l, 0x0l, 0xd024al, 0xb2124l, 0xaf0a0l,
    0x222l, 0x55f400l, 0x800001l, 0xd006cl, 0x579500l, 0xb012al, 0x20002fl,
    0x551500l, 0xaf080l, 0x227l, 0xd0091l, 0x579500l, 0xb012al, 0x20002fl,
    0x551500l, 0xcl, 0x549500l, 0x608a0l, 0x200023l, 0x6ca00l, 0x237l,
    0xacc77l, 0x200023l, 0xaf0a0l, 0x234l, 0xaa528l, 0xaf080l, 0x235l,
    0xaa508l, 0xd0091l, 0x0l, 0x0l, 0xacc77l, 0x200023l, 0xaf0a0l, 0x23fl,
    0xaa528l, 0xaf080l, 0x240l, 0xaa508l, 0xb2124l, 0xaf0a0l, 0x248l,
    0x55f400l, 0x800001l, 0xd006cl, 0xaf080l, 0x249l, 0xd0091l, 0xcl,
    0x200023l, 0xe824el, 0xaa508l, 0xc024fl, 0xaa528l, 0xcl, 0x558d00l,
    0x20002bl, 0x550d00l, 0xcl, 0x578b00l, 0x56a00bl, 0xaf0a2l, 0x259l,
    0xcl, 0x578c03l, 0xaf0a2l, 0x25dl, 0xcl, 0x561f0bl, 0xaf0a2l, 0x261l,
    0xcl, 0x571900l, 0x57a500l, 0x572600l, 0x57f400l, 0x0l, 0x572500l,
    0x57f400l, 0x1l, 0x570c00l, 0x60b00l, 0x28al, 0x66a500l, 0x0l,
    0x205e00l, 0x662500l, 0x579f00l, 0x20002bl, 0xaf0a0l, 0x287l,
    0x571f00l, 0x54f400l, 0xf03l, 0x542200l, 0xd0138l, 0xb0120l, 0xaf0a0l,
    0x285l, 0xbf080l, 0x295l, 0xbf080l, 0xa6cl, 0x66a500l, 0x661d00l,
    0x8cl, 0xaf080l, 0x28bl, 0xaf080l, 0x288l, 0x571f00l, 0x568c00l,
    0x200033l, 0x560c00l, 0x579900l, 0x570c00l, 0x57a600l, 0x572500l, 0xcl,
    0x45a000l, 0x578c00l, 0x20006al, 0x572000l, 0xcl, 0x45a000l, 0x578c00l,
    0x20001fl, 0x20006el, 0x572000l, 0xcl, 0x45f400l, 0x7fff55l, 0x500bbl,
    0x54f400l, 0x2c1l, 0x540800l, 0x450700l, 0x54f400l, 0x110l, 0x541700l,
    0x2e0000l, 0x562000l, 0x561e00l, 0x56f400l, 0x1l, 0x560c00l, 0x560b00l,
    0x65f400l, 0x152al, 0x60f400l, 0xdecl, 0x77090l, 0xdecl, 0x7d88cl,
    0x2c0400l, 0x618a0l, 0x7588cl, 0x548100l, 0x44f400l, 0x1l, 0x440900l,
    0x200046l, 0x540100l, 0x502bal, 0x328000l, 0x620400l, 0x620200l,
    0x56f400l, 0x3e20l, 0x540500l, 0x56f400l, 0x8l, 0x540600l, 0x56f400l,
    0x40002l, 0x561600l, 0x8f4a5l, 0xa4l, 0x8f4a4l, 0x7000l, 0x8f4a2l,
    0x7f00l, 0x45f400l, 0x61a7l, 0x453000l, 0x45f400l, 0x3el, 0x453100l,
    0x45f400l, 0x1f4l, 0x453200l, 0x45f400l, 0xf90l, 0x453300l, 0x45f400l,
    0x3el, 0x453400l, 0x45f400l, 0x1f4l, 0x453500l, 0x45f400l, 0x1f4l,
    0x453600l, 0x45f400l, 0x5l, 0x453700l, 0x45f400l, 0x5l, 0x453800l,
    0x62f400l, 0xdbcl, 0x60f400l, 0x14efl, 0x7f091l, 0x151fl, 0x6d100l,
    0x2f3l, 0x7d88el, 0x75a8cl, 0x60f400l, 0xaal, 0x601100l, 0x549700l,
    0x547000l, 0xfffel, 0xd0304l, 0x380065l, 0x4d8bbl, 0x549600l, 0x8cc3dl,
    0x664a0l, 0x0l, 0xbe080l, 0xd032cl, 0xc02f4l, 0xb1ea0l, 0x254l,
    0x548500l, 0x547000l, 0xffedl, 0x2f0013l, 0x8ce21l, 0x8f4a4l, 0x7000l,
    0x8f4a2l, 0x7f00l, 0x8f4a3l, 0x17cl, 0xab0f2l, 0x304l, 0xab0d6l,
    0x304l, 0xd03cbl, 0x20ce00l, 0x200003l, 0x44f400l, 0x10l, 0x7f087l,
    0x151dl, 0x45f475l, 0x21l, 0xaf0afl, 0x321l, 0xc0304l, 0x200045l,
    0xaf0a1l, 0x325l, 0xc0304l, 0x61f444l, 0xdbcl, 0x219900l, 0x0l,
    0x7e990l, 0x20cc00l, 0xcl, 0x549100l, 0x54f400l, 0xaaaaaal, 0xd03f9l,
    0x200013l, 0xaa429l, 0xab0d4l, 0x332l, 0xaa5b2l, 0x332l, 0xaa409l,
    0xab0f4l, 0x337l, 0xd03f5l, 0xcl, 0x67f000l, 0x65l, 0xd0354l,
    0x67f000l, 0x66l, 0xd0348l, 0xd0404l, 0x578000l, 0x44f400l, 0x1l,
    0x20004cl, 0x21a400l, 0xcl, 0xd03acl, 0x5f427l, 0xffffl, 0xa07a2l,
    0x34fl, 0xa01a3l, 0x351l, 0x4c6700l, 0xcl, 0x4c5f00l, 0x4d6700l, 0xcl,
    0xd0364l, 0xd035al, 0xd0349l, 0xd035al, 0x540000l, 0xcl, 0xb0721l,
    0xe8361l, 0xa07a2l, 0x3bcl, 0xa07a0l, 0x3bcl, 0xc03acl, 0xa07a0l,
    0x3acl, 0xc03bcl, 0x320000l, 0x57f400l, 0x1l, 0x7d88el, 0x5c5a05l,
    0xe2367l, 0xcl, 0xa0194l, 0x36dl, 0xaa429l, 0xab0d4l, 0x36el, 0xaa5b2l,
    0x36el, 0xaa409l, 0xab0f4l, 0x373l, 0x500bbl, 0xa0182l, 0x379l,
    0xd0386l, 0xc02f4l, 0xa0120l, 0xaa523l, 0xd032cl, 0xaa503l, 0xa0101l,
    0xcl, 0x60f000l, 0x54l, 0x370500l, 0x337100l, 0xaf080l, 0x38dl,
    0x337100l, 0x370300l, 0xa0782l, 0x38bl, 0x370200l, 0x60f000l, 0x52l,
    0xd0364l, 0x340400l, 0x229c00l, 0xa0782l, 0x394l, 0x340300l, 0x229c00l,
    0x6d700l, 0x3a2l, 0x56db00l, 0x5c5c00l, 0xa07a2l, 0x3a1l, 0xa0781l,
    0x39fl, 0xa07a0l, 0x39fl, 0xc03a1l, 0x56db00l, 0x5c5c00l, 0x204c00l,
    0x0l, 0xd0404l, 0xa0102l, 0x337100l, 0xcl, 0x57f413l, 0x1l, 0x5ce200l,
    0x200005l, 0xcl, 0xa07a2l, 0x3bcl, 0xa07a0l, 0x3b3l, 0xa07a1l, 0x3bcl,
    0xc03b5l, 0xa0781l, 0x3b9l, 0xd03bcl, 0x208500l, 0xd03bcl, 0xcl,
    0x240000l, 0xd03c1l, 0xc03b6l, 0x47f400l, 0x8000l, 0xd03cbl, 0x2000b0l,
    0x210400l, 0xd03cbl, 0x47f400l, 0x80l, 0x2000b0l, 0x210c00l, 0x200042l,
    0x218400l, 0x608a0l, 0x200023l, 0xcl, 0xab0d6l, 0x3cbl, 0x84624l,
    0xaa428l, 0x2dff00l, 0x20005el, 0x21a600l, 0xab0f6l, 0x3d2l, 0xaa408l,
    0xcl, 0xa07a2l, 0x3del, 0x20ae00l, 0xd03e5l, 0xd03eel, 0x20ae00l,
    0xd03e8l, 0xd03eel, 0x208e00l, 0xd03e5l, 0xd03eel, 0x208e00l, 0xd03e8l,
    0xd03eel, 0xcl, 0x610a0l, 0x200022l, 0xc03eal, 0x608a0l, 0x200022l,
    0x46f400l, 0xffl, 0x200056l, 0xcl, 0xd03f9l, 0xaa42al, 0xab0d5l,
    0x3f0l, 0xaa40al, 0xab0f5l, 0x3f3l, 0x8f4a2l, 0x7f00l, 0xaa40bl, 0xcl,
    0x46f400l, 0xff00l, 0xaa42bl, 0x84f24l, 0x20005el, 0x21a600l,
    0x200052l, 0x8cc24l, 0x8f4a2l, 0x7fffl, 0xcl, 0x320000l, 0xa0127l,
    0x5eda00l, 0x561800l, 0xa1880l, 0x40dl, 0x2f8l, 0xf2b8l, 0xcl,
    0x200013l, 0x561500l, 0x558c00l, 0x550d00l, 0xbf080l, 0x41bl, 0x0l,
    0x0l, 0xa0186l, 0x41al, 0xd0135l, 0xa01a8l, 0x415l, 0xc0405l, 0xa0187l,
    0x41el, 0xd046el, 0x47f413l, 0xffl, 0x561500l, 0xa18a2l, 0x473l,
    0xa18a1l, 0x492l, 0xb18a4l, 0x474l, 0xa0106l, 0xcl, 0x218a00l,
    0x608a0l, 0x200023l, 0x758900l, 0x6ca00l, 0x434l, 0xd024al, 0xd0091l,
    0x579500l, 0xb012al, 0x20002fl, 0x551500l, 0x0l, 0xd024al, 0x55f400l,
    0x800001l, 0xd006cl, 0xd0469l, 0xcl, 0x608a0l, 0x200023l, 0x758900l,
    0x6ca00l, 0x446l, 0xd024al, 0xd0091l, 0x579500l, 0xb012al, 0x20002fl,
    0x551500l, 0x0l, 0xcl, 0xaa508l, 0xd0091l, 0xcl, 0x55f400l, 0x800003l,
    0xd006cl, 0xcl, 0x549500l, 0x758900l, 0x6ca00l, 0x46cl, 0x200023l,
    0xe8458l, 0xaa508l, 0xc0459l, 0xaa528l, 0x8f4a1l, 0x0l, 0xa010al,
    0xaa526l, 0x602a0l, 0x0l, 0xba527l, 0xaf0a0l, 0x463l, 0xa012al,
    0xaa526l, 0x60920l, 0x0l, 0xaa506l, 0x60920l, 0x0l, 0x579500l,
    0xb012al, 0x20002fl, 0x551500l, 0xcl, 0x549800l, 0x608a0l, 0x200033l,
    0x542200l, 0xc00f3l, 0x20001bl, 0x218700l, 0xa18a5l, 0x489l, 0x5dda00l,
    0xa0782l, 0x47dl, 0x21ac00l, 0xaf080l, 0x484l, 0x608a0l, 0x20002bl,
    0x21a700l, 0x5cda00l, 0x608a0l, 0x200033l, 0x200072l, 0x542200l,
    0xa07a2l, 0xedl, 0xa0782l, 0xe7l, 0x5cda00l, 0x205a00l, 0x542200l,
    0xc00edl, 0x55f400l, 0x800002l, 0xd006cl, 0xa0126l, 0xcl, 0x3f8l,
    0x8f4bfl, 0x0l, 0xa07a2l, 0x10bl, 0xa1885l, 0x104l, 0xc010bl,
    0x20001bl, 0x551500l, 0xd0429l, 0x549500l, 0xa07a2l, 0x4a1l, 0xd03c8l,
    0x545b00l, 0x8f4bfl, 0x3el, 0xcl, 0xd0135l, 0x60f000l, 0x50l,
    0x370100l, 0xd0364l, 0xd03acl, 0xa07a2l, 0x4b3l, 0xa0781l, 0x4b2l,
    0xa07a0l, 0x4c3l, 0xc04b3l, 0x4d5f00l, 0x4c5f00l, 0x205f00l, 0xd03acl,
    0xa07a2l, 0x4bel, 0xa0781l, 0x4bdl, 0xa07a0l, 0x4c6l, 0xc04bel,
    0x4d5f00l, 0x4c6700l, 0xd0404l, 0xa0100l, 0xd0290l, 0xcl, 0x4c5f00l,
    0x4d5f00l, 0xc04b4l, 0x4c5f00l, 0x4d6700l, 0xc04bfl, 0xd0135l,
    0x60f000l, 0x50l, 0x370100l, 0xd0364l, 0xd03acl, 0xa07a2l, 0x4d7l,
    0xa0781l, 0x4d6l, 0xa07a0l, 0x4f3l, 0xc04d7l, 0x4d5f00l, 0x4c5f00l,
    0x205f00l, 0xd03acl, 0xa07a2l, 0x4e2l, 0xa0781l, 0x4e1l, 0xa07a0l,
    0x4f6l, 0xc04e2l, 0x4d5f00l, 0x4c5f00l, 0x46f400l, 0x55l, 0x47f400l,
    0xaal, 0x44f400l, 0xffl, 0x84c24l, 0x200046l, 0x200055l, 0xea4f0l,
    0x200075l, 0xea4f2l, 0xc04e9l, 0xd0404l, 0xa0100l, 0xcl, 0x4c5f00l,
    0x4d5f00l, 0xc04d8l, 0x4c5f00l, 0x4d6700l, 0xc04e3l, 0xd0135l,
    0x60f000l, 0x53l, 0x337100l, 0xa0783l, 0x501l, 0x60f000l, 0x55l,
    0xd0364l, 0xd0404l, 0xa0122l, 0x60f000l, 0x4al, 0x61bc00l, 0xd050el,
    0xa0783l, 0x50cl, 0xd0380l, 0xcl, 0xd0386l, 0xcl, 0x67f000l, 0x65l,
    0xd0354l, 0xd0518l, 0xd0342l, 0xea525l, 0x223000l, 0xd0364l, 0x6c400l,
    0x524l, 0xd0404l, 0xa0781l, 0x51dl, 0xa07a0l, 0x526l, 0x44fb00l,
    0xa07a1l, 0x523l, 0xa07a2l, 0x523l, 0x45fb00l, 0xd03d6l, 0x0l, 0xcl,
    0x45fb00l, 0xa0783l, 0x52dl, 0x45fb00l, 0x44fb00l, 0x44fb00l, 0xc0523l,
    0x44fb00l, 0xc0523l, 0xd0135l, 0x60f000l, 0x53l, 0x337100l, 0xd0364l,
    0xd0404l, 0xa0122l, 0x60f000l, 0x4bl, 0x61bd00l, 0xd053cl, 0xd0386l,
    0xcl, 0x67f000l, 0x65l, 0xd0354l, 0xd0546l, 0xd0342l, 0xea553l,
    0x223000l, 0xd0364l, 0x6c400l, 0x552l, 0xd0404l, 0xa0781l, 0x54bl,
    0xa07a0l, 0x554l, 0x44fb00l, 0xa07a1l, 0x551l, 0xa07a2l, 0x551l,
    0x45fb00l, 0xd03d6l, 0x0l, 0xcl, 0x45fb00l, 0x44fb00l, 0xc0551l,
    0xd0135l, 0x60f000l, 0x53l, 0x337100l, 0xd0364l, 0xd0404l, 0xa0122l,
    0x60f000l, 0x4cl, 0x61be00l, 0xd0564l, 0xd0386l, 0xcl, 0x67f000l,
    0x65l, 0xd0354l, 0xd056el, 0xd0342l, 0xea57bl, 0x223000l, 0xd0364l,
    0x6c400l, 0x57al, 0xd0404l, 0xa0781l, 0x573l, 0xa07a0l, 0x57cl,
    0x44fb00l, 0xa07a1l, 0x579l, 0xa07a2l, 0x579l, 0x45fb00l, 0xd03d6l,
    0x0l, 0xcl, 0x45fb00l, 0x44fb00l, 0xc0579l, 0xd0135l, 0x60f000l, 0x53l,
    0x337100l, 0xa0783l, 0x587l, 0x60f000l, 0x55l, 0xd0364l, 0xd0404l,
    0xa0122l, 0x60f000l, 0x4dl, 0xb0783l, 0x33bl, 0xb07a3l, 0x59dl,
    0xea597l, 0x6c400l, 0x596l, 0x62f000l, 0x6dl, 0xd0405l, 0x0l, 0xa0783l,
    0x59bl, 0xd0380l, 0xcl, 0xd0386l, 0xcl, 0x67f000l, 0x65l, 0xd0354l,
    0xd03acl, 0x5f427l, 0xffffl, 0x4c0a00l, 0x4d1000l, 0xd0404l, 0x578000l,
    0x44f400l, 0x1l, 0x20004cl, 0x21a400l, 0xcl, 0xd0135l, 0x60f000l,
    0x53l, 0x337100l, 0xd0364l, 0xd0404l, 0xa0122l, 0x60f000l, 0x4el,
    0x61bf00l, 0xd033bl, 0xea5bel, 0x6c400l, 0x5bdl, 0x62f000l, 0x6el,
    0xd0405l, 0x0l, 0xd0386l, 0xcl, 0xd0135l, 0x60f000l, 0x53l, 0x337100l,
    0xd0364l, 0xd0404l, 0xa0122l, 0x60f000l, 0x4fl, 0x61bf00l, 0xd033bl,
    0xea5d2l, 0x6c400l, 0x5d1l, 0x62f000l, 0x6fl, 0xd0405l, 0x0l, 0xd0386l,
    0xcl, 0xd0135l, 0xa0782l, 0x5dcl, 0x60f000l, 0x53l, 0x337100l,
    0xd0364l, 0xd0404l, 0x60f000l, 0x48l, 0x66f000l, 0x43l, 0xd0607l,
    0x6cc00l, 0x5fel, 0x61f400l, 0x1l, 0xa07a0l, 0x5e9l, 0xa07a1l, 0x5eel,
    0xa07a2l, 0x5eel, 0x0l, 0x60280l, 0x5f0l, 0x7d88el, 0x5c5900l, 0x0l,
    0x0l, 0xd0404l, 0xa0781l, 0x5f7l, 0xa07a0l, 0x604l, 0x44fb00l,
    0xa07a1l, 0x5fdl, 0xa07a2l, 0x5fdl, 0x45fb00l, 0xd03d6l, 0x0l, 0x0l,
    0xa0782l, 0x603l, 0xd0386l, 0xcl, 0x45fb00l, 0x44fb00l, 0xc05fdl,
    0xd0364l, 0x200013l, 0xd035al, 0x22cf00l, 0x200010l, 0x219000l,
    0xd035al, 0xcl, 0xd0135l, 0x60f000l, 0x49l, 0x66f000l, 0x44l, 0xd062al,
    0x66f000l, 0x69l, 0x6cc00l, 0x628l, 0x61f400l, 0x1l, 0xa07a2l, 0x623l,
    0xa07a0l, 0x621l, 0xa07a1l, 0x623l, 0x60280l, 0x624l, 0x7d88el,
    0x5c5900l, 0x22d700l, 0xd0348l, 0xd0404l, 0x0l, 0xcl, 0xd0364l,
    0xd035al, 0x22cf00l, 0x200010l, 0x219000l, 0xd035al, 0xcl, 0xd0135l,
    0x60f000l, 0x53l, 0x337100l, 0xa0783l, 0x639l, 0x60f000l, 0x55l,
    0xd0364l, 0xd0404l, 0xa0122l, 0x60f000l, 0x4dl, 0x61f000l, 0x40l,
    0xb0783l, 0x33bl, 0xb07a3l, 0x59dl, 0xea652l, 0x223000l, 0xd0364l,
    0x66f000l, 0x68l, 0x6c400l, 0x651l, 0x22d700l, 0xb0783l, 0x348l,
    0xb07a3l, 0x658l, 0xd0404l, 0x0l, 0xa0783l, 0x656l, 0xd0380l, 0xcl,
    0xd0386l, 0xcl, 0xd03acl, 0x5f427l, 0xffffl, 0x4c0400l, 0x4d0a00l,
    0xcl, 0xd0135l, 0x60f000l, 0x53l, 0x337100l, 0xd0364l, 0xd0404l,
    0xa0122l, 0x60f000l, 0x4el, 0x61f000l, 0x41l, 0xd033bl, 0xea675l,
    0x223000l, 0xd0364l, 0x66f000l, 0x68l, 0x6c400l, 0x674l, 0x22d700l,
    0xd0348l, 0xd0404l, 0x0l, 0xd0386l, 0xcl, 0xd0135l, 0x60f000l, 0x53l,
    0x337100l, 0xd0364l, 0xd0404l, 0xa0122l, 0x60f000l, 0x4fl, 0x61f000l,
    0x42l, 0xd033bl, 0xea68el, 0x223000l, 0xd0364l, 0x66f000l, 0x68l,
    0x6c400l, 0x68dl, 0x22d700l, 0xd0348l, 0xd0404l, 0x0l, 0xd0386l, 0xcl,
    0xd0135l, 0x60f000l, 0x45l, 0xd0364l, 0xd03cbl, 0x20d200l, 0x20db00l,
    0xd03cbl, 0x20d300l, 0x340100l, 0x6c6b00l, 0x3b0000l, 0x337100l,
    0xd0405l, 0x46f400l, 0x71l, 0x226e00l, 0x200054l, 0xb07a2l, 0x6bdl,
    0xa07a0l, 0x6a8l, 0xa07a1l, 0x6abl, 0xa07a2l, 0x6abl, 0x200022l,
    0x6cc00l, 0x6b8l, 0xa0781l, 0x6b1l, 0xa07a0l, 0x6bal, 0x44fb00l,
    0xa07a1l, 0x6b7l, 0xa07a2l, 0x6b7l, 0x45fb00l, 0xd03d6l, 0x0l, 0xcl,
    0x45fb00l, 0x44fb00l, 0xc06b7l, 0x57f400l, 0x14l, 0x200005l, 0xaf0a2l,
    0x6d1l, 0x540d00l, 0xd044cl, 0x56f400l, 0x9e07l, 0xd049al, 0xd048dl,
    0x548d00l, 0x219700l, 0x55fb00l, 0x608a0l, 0x20002bl, 0x555b00l,
    0x205f00l, 0x0l, 0x22ec00l, 0xcl, 0xd0135l, 0xd03cbl, 0x57f000l, 0x47l,
    0x200058l, 0x21b000l, 0xd03cbl, 0x6c600l, 0x6eal, 0x7d88el, 0x5c0000l,
    0x360100l, 0xa07a2l, 0x6e4l, 0xa0781l, 0x6e6l, 0xa07a0l, 0x6e6l,
    0x6e0200l, 0xc06e7l, 0x6e0300l, 0x22d700l, 0xd0348l, 0xd0404l, 0x0l,
    0xcl, 0x5e8000l, 0x46f400l, 0x20l, 0x200056l, 0x200003l, 0xaf0aal,
    0x6fdl, 0x200053l, 0x5e0000l, 0x5e8100l, 0x21cf00l, 0x608a0l,
    0x200033l, 0x5e0100l, 0x608a0l, 0x20002bl, 0x5f0200l, 0xcl, 0xd0135l,
    0xd03cbl, 0x628200l, 0x638400l, 0x6c600l, 0x71fl, 0x3a0113l, 0x4ee200l,
    0x54f400l, 0x4l, 0x200056l, 0xe2713l, 0x3a0200l, 0xa07a2l, 0x713l,
    0xa07a0l, 0x711l, 0xa07a1l, 0x713l, 0x3a0300l, 0x0l, 0x4eea00l,
    0x56f400l, 0x1l, 0x5c6a00l, 0x460300l, 0xd0405l, 0x468300l, 0x648200l,
    0x235c00l, 0x0l, 0x4e6c00l, 0x3a0000l, 0x3c0000l, 0x620200l, 0xcl,
    0xd0135l, 0x628200l, 0x638400l, 0xd0405l, 0xcl, 0xd0135l, 0x60f000l,
    0x46l, 0xd0364l, 0x337100l, 0xd0404l, 0x340900l, 0xa0183l, 0x735l,
    0x341200l, 0xa07a0l, 0x740l, 0x340c00l, 0x0l, 0x6d400l, 0x73el,
    0x44fb00l, 0xa07a1l, 0x73dl, 0xa07a2l, 0x73dl, 0x45fb00l, 0xd03d6l,
    0x0l, 0xcl, 0x6d400l, 0x745l, 0x45fb00l, 0x44fb00l, 0xd03d6l, 0x0l,
    0xcl, 0xd0135l, 0xd03bcl, 0x209000l, 0x208e00l, 0x608a0l, 0x200023l,
    0x21d000l, 0xd03bcl, 0x209100l, 0x208e00l, 0x608a0l, 0x200023l,
    0x21d100l, 0xd03cbl, 0x57f400l, 0xffl, 0x20005el, 0x21f700l, 0x6d100l,
    0x770l, 0x45e000l, 0x22e600l, 0x57f400l, 0x1l, 0x20005dl, 0xea765l,
    0x4de000l, 0xaf0a7l, 0x765l, 0x7e085l, 0x20ac00l, 0x608a0l, 0x200032l,
    0x218400l, 0x608a0l, 0x200022l, 0x2a0000l, 0x608a0l, 0x200022l,
    0x218500l, 0xd03dbl, 0x205800l, 0xcl, 0xd0135l, 0xd03bcl, 0x209000l,
    0x208e00l, 0x608a0l, 0x200023l, 0x21d000l, 0xd03bcl, 0x209100l,
    0x208e00l, 0x608a0l, 0x200023l, 0x21d100l, 0xd03cbl, 0x57f400l, 0xffl,
    0x20005el, 0x21b700l, 0x6d100l, 0x79bl, 0xd03b9l, 0x208c00l, 0x608a0l,
    0x200023l, 0x20ad00l, 0x608a0l, 0x20003bl, 0x21a500l, 0x200062l,
    0x57f400l, 0x1l, 0x22e600l, 0x20005dl, 0xea799l, 0xe7797l, 0x7588cl,
    0xc079al, 0x5c5800l, 0xc079al, 0x545800l, 0x0l, 0x0l, 0xcl, 0xd03cbl,
    0x56f400l, 0x2l, 0x200055l, 0xe97a8l, 0xea7afl, 0x20ce00l, 0x200003l,
    0xea7abl, 0x548100l, 0xc07b0l, 0x54f400l, 0x2c1l, 0xc07b0l, 0x84c25l,
    0x606a0l, 0x200023l, 0xc07b0l, 0x548200l, 0x218500l, 0x608a0l,
    0x200033l, 0x218400l, 0xa07a3l, 0x3d8l, 0xd03del, 0xa07a2l, 0x7c1l,
    0xa07a0l, 0x7bdl, 0xa07a1l, 0x7c1l, 0xd03eel, 0xa0781l, 0x7c1l,
    0xd03eel, 0xcl, 0xd03cbl, 0x20d000l, 0xd03cbl, 0x466000l, 0xa0114l,
    0x568700l, 0x57f400l, 0x3l, 0x200005l, 0xaf0a9l, 0x7cel, 0xa0134l,
    0xcl, 0x8f4bfl, 0x0l, 0xa0101l, 0xd03cbl, 0x56f400l, 0x1l, 0x20c700l,
    0x200075l, 0xe97eal, 0xe27dal, 0xaa505l, 0xaa524l, 0xd03cbl, 0x8f4bfl,
    0x3el, 0xaa504l, 0x200075l, 0xea7e3l, 0xa0100l, 0xcl, 0xa0181l, 0x7e3l,
    0xaa525l, 0xa0101l, 0xa0120l, 0xd0295l, 0xcl, 0xd03cbl, 0x461800l,
    0x317000l, 0x60f400l, 0x1520l, 0x223300l, 0x20db00l, 0x62f400l, 0xal,
    0x56cb00l, 0xd0810l, 0x60e300l, 0xd080dl, 0x56f400l, 0x3l, 0x200055l,
    0xe7807l, 0xaa42cl, 0xa0134l, 0x56f400l, 0x8l, 0x200055l, 0xaf0a2l,
    0x806l, 0x56f400l, 0x3l, 0x200050l, 0x560700l, 0xcl, 0xaa40cl,
    0xa0114l, 0x54f400l, 0x40002l, 0x541600l, 0xcl, 0x7f092l, 0x151el,
    0x313c00l, 0x6d200l, 0x813l, 0x7d88el, 0x545900l, 0x460700l, 0xcl,
    0xd0135l, 0xaa505l, 0xa0181l, 0x818l, 0xaa525l, 0xa0101l, 0xa0120l,
    0xcl, 0xd0135l, 0xd03bcl, 0x209000l, 0x209100l, 0xd03bcl, 0x208e00l,
    0x608a0l, 0x200022l, 0x6ce00l, 0x832l, 0xd03b9l, 0x208c00l, 0x608a0l,
    0x200023l, 0x20ad00l, 0x608a0l, 0x20003bl, 0x21a500l, 0x200062l,
    0x7588el, 0x0l, 0xae180l, 0xd03cbl, 0x20cf00l, 0x20000bl, 0xe283cl,
    0x55f400l, 0xfc0008l, 0xd006cl, 0xcl, 0xaa505l, 0x6ffafl, 0x20000bl,
    0xaa525l, 0x2d0100l, 0xd006cl, 0xcl, 0xa0100l, 0xd03cbl, 0x57f400l,
    0xfc0008l, 0xd006cl, 0xd0135l, 0x54f400l, 0x703l, 0x542200l, 0xd0138l,
    0xa01a8l, 0x84cl, 0xd0135l, 0xa0120l, 0xa0101l, 0xd0295l, 0xcl,
    0xaa40cl, 0xaa505l, 0x6ffafl, 0x20000bl, 0xaa525l, 0xaa42cl, 0xa0181l,
    0x85al, 0xa0120l, 0xa0101l, 0xd0295l, 0xcl, 0xa0782l, 0xa0al, 0xd03cbl,
    0xaa42cl, 0x20cf00l, 0xaa524l, 0x20000bl, 0xea894l, 0xa07a2l, 0x8a1l,
    0x55f400l, 0xfc0008l, 0xd006cl, 0x56f400l, 0x703l, 0x562200l,
    0x56f400l, 0x703l, 0x562300l, 0xd0138l, 0xd03cbl, 0xaa504l, 0x56f400l,
    0x603l, 0x562200l, 0xd0138l, 0xd0135l, 0xa01a8l, 0x87al, 0xaf080l,
    0x883l, 0xa0181l, 0x87fl, 0xa07a2l, 0x887l, 0xa0120l, 0xa0101l,
    0xd0295l, 0xcl, 0x56f400l, 0x4l, 0x5e0000l, 0x200013l, 0x5e0100l,
    0x56f400l, 0x1l, 0x5e0200l, 0xd0404l, 0x614a0l, 0x20002bl, 0x571100l,
    0xc0883l, 0xa07a2l, 0x8c1l, 0xd0135l, 0xd03cbl, 0xaa504l, 0xa0100l,
    0x54f400l, 0xf03l, 0x542200l, 0xd0138l, 0xd0135l, 0xd0290l, 0xcl,
    0xaa505l, 0x600a1l, 0x0l, 0xaa525l, 0xd03cbl, 0x55f400l, 0xfb000al,
    0xd006cl, 0x56f400l, 0x703l, 0xd0429l, 0xd048dl, 0xaa504l, 0x55f400l,
    0xc00004l, 0xd006cl, 0x56f400l, 0x603l, 0xd0429l, 0xd048dl, 0x56f400l,
    0x204l, 0x5e0000l, 0x56f400l, 0x800000l, 0x5e0100l, 0x56f400l, 0x1l,
    0x5e0200l, 0xd0404l, 0xaa504l, 0xc0883l, 0xaa505l, 0x600a1l, 0x0l,
    0xaa525l, 0xd03cbl, 0x55f400l, 0xfb000al, 0xd006cl, 0x56f400l, 0x603l,
    0xd0429l, 0xd048dl, 0xaa504l, 0x55f400l, 0xc00004l, 0xd006cl,
    0x56f400l, 0x603l, 0xd0429l, 0xd048dl, 0x56f400l, 0x210l, 0x5e0000l,
    0x56f400l, 0x800000l, 0x5e0100l, 0x56f400l, 0x1l, 0x5e0200l, 0xd0404l,
    0xaa504l, 0xa0100l, 0xa0101l, 0xd0290l, 0xcl, 0xd0135l, 0x60f000l,
    0x56l, 0x370100l, 0xd0364l, 0xd03acl, 0xa07a2l, 0x8f1l, 0xa07a0l,
    0x900l, 0xa07a1l, 0x8f1l, 0x4d5f00l, 0x4c5f00l, 0x205f00l, 0xd03acl,
    0xa07a2l, 0x8fbl, 0xa07a0l, 0x907l, 0xa07a1l, 0x8fbl, 0x4d5f00l,
    0x4c6700l, 0xd0404l, 0xa0100l, 0xd0290l, 0xcl, 0xa07a2l, 0x8f1l,
    0xa0781l, 0x8f0l, 0x4c5f00l, 0x4d5f00l, 0xc08f2l, 0xa07a2l, 0x8fbl,
    0xa0781l, 0x8fal, 0x4c5f00l, 0x4d6700l, 0x44f400l, 0x6c10l, 0x4c0300l,
    0xc08fcl, 0xd0135l, 0xa07a3l, 0x944l, 0x337100l, 0x758900l, 0x300c00l,
    0x6d000l, 0x93bl, 0x54f400l, 0x920000l, 0x542200l, 0xd00f3l, 0xd044cl,
    0xd00d5l, 0x200013l, 0x561500l, 0x560d00l, 0xd0091l, 0xa018al, 0x927l,
    0x2a0100l, 0x520d00l, 0x2a1000l, 0xd0451l, 0x559500l, 0x555b00l,
    0x200013l, 0x561500l, 0x2a0700l, 0xd042al, 0x549500l, 0x608a0l,
    0x200023l, 0x578d00l, 0x20002bl, 0xaf0a0l, 0x939l, 0x46f400l, 0x10000l,
    0x200052l, 0x545b00l, 0xd048dl, 0x0l, 0x300c00l, 0x6d000l, 0x942l,
    0x45fb00l, 0x44fb00l, 0xd03d6l, 0x0l, 0xcl, 0x337100l, 0x758900l,
    0x300800l, 0x6d000l, 0x966l, 0x54f400l, 0x920000l, 0x542200l, 0xd00f3l,
    0xd044cl, 0xd00d5l, 0x200013l, 0x561500l, 0x560d00l, 0xd0091l,
    0xa018al, 0x957l, 0x2a0100l, 0x520d00l, 0x2a0f00l, 0xd042al, 0x559500l,
    0x555b00l, 0x200013l, 0x561500l, 0x578d00l, 0x20002bl, 0xaf0a0l,
    0x964l, 0x46f400l, 0x10000l, 0x200052l, 0x545b00l, 0xd048dl, 0x0l,
    0x300800l, 0x6d000l, 0x96dl, 0x45fb00l, 0x44fb00l, 0xd03d6l, 0x0l,
    0xcl, 0xa0100l, 0x337100l, 0x55f400l, 0xf03l, 0x552200l, 0xd0138l,
    0x20001bl, 0x559500l, 0x47f400l, 0xf000l, 0x46f400l, 0xd000l, 0x608a0l,
    0x20002bl, 0x20007el, 0x21a400l, 0x250000l, 0x20005dl, 0xaf0a2l,
    0x987l, 0xa0120l, 0xd03d6l, 0xaf080l, 0x989l, 0xa0100l, 0xd03d6l, 0xcl,
    0x448600l, 0x75d84l, 0x448900l, 0x75d84l, 0x44f400l, 0x80ffl,
    0x440600l, 0x44f400l, 0x500l, 0x440900l, 0xd03cbl, 0xa0124l, 0x55f400l,
    0xfb000al, 0xd006cl, 0xd00c7l, 0x54f400l, 0xffffffl, 0x60f80l, 0x9a2l,
    0xaae86l, 0x99el, 0x547000l, 0xffefl, 0x0l, 0xa2120l, 0xa2121l,
    0xd004fl, 0x55f400l, 0x800003l, 0xd006cl, 0xd00c7l, 0x200013l,
    0x61480l, 0x9b1l, 0xaae86l, 0x9adl, 0x547000l, 0xffefl, 0x0l, 0x8f4a1l,
    0x0l, 0x200013l, 0x560b00l, 0x44f400l, 0x1l, 0xa2120l, 0xd00a4l,
    0xb2122l, 0xaf0a8l, 0x9c1l, 0x568b00l, 0x200040l, 0x560b00l, 0xc09b8l,
    0xd004fl, 0x250000l, 0x568b00l, 0x200003l, 0xaf0a2l, 0x9cal, 0x56f400l,
    0x1l, 0x560b00l, 0x608a0l, 0x200033l, 0x21c400l, 0xd03d6l, 0x568c00l,
    0x561900l, 0x56f400l, 0x1l, 0x560c00l, 0x60b00l, 0x9dfl, 0xd0135l,
    0xb0120l, 0xaf0a8l, 0x9dcl, 0xd0290l, 0xaf080l, 0x9ddl, 0xd0295l,
    0x568c00l, 0x200033l, 0x560c00l, 0x569900l, 0x560c00l, 0xd0135l,
    0xa1e20l, 0x7fd84l, 0x440900l, 0x7fd84l, 0x440600l, 0xcl, 0xd03cbl,
    0x462500l, 0x54f400l, 0x1l, 0x200023l, 0x6c620l, 0x200037l, 0xd03cbl,
    0x540c00l, 0xa0100l, 0x55f400l, 0xf03l, 0x552200l, 0xd0138l, 0x20001bl,
    0x559500l, 0x47f400l, 0xf000l, 0x46f400l, 0xd000l, 0x608a0l, 0x20002bl,
    0x20007el, 0x21a400l, 0x250000l, 0x20005dl, 0xaf0a2l, 0xa08l, 0xa0120l,
    0xaf080l, 0xa09l, 0xa0100l, 0xcl, 0xd03cbl, 0xaa42cl, 0x20cf00l,
    0xaa524l, 0xaa505l, 0x6ffa0l, 0x20000bl, 0xaa525l, 0x20000bl, 0xaf0aal,
    0xa39l, 0xa07a2l, 0xa46l, 0x55f400l, 0xfc0008l, 0xd006cl, 0x56f400l,
    0x703l, 0x562200l, 0x562300l, 0xd013bl, 0xd03cbl, 0xaa504l, 0x56f400l,
    0x603l, 0x562200l, 0xd0138l, 0xd0135l, 0xa0120l, 0xa0101l, 0x2f0000l,
    0x572000l, 0xd0295l, 0xcl, 0x56f400l, 0x4l, 0x5e0000l, 0x200013l,
    0x5e0100l, 0x56f400l, 0x1l, 0x5e0200l, 0xd0404l, 0x614a0l, 0x20002bl,
    0x571100l, 0xc0a26l, 0xd03cbl, 0x55f400l, 0xfc0008l, 0xd006cl,
    0xaa504l, 0x54f400l, 0x603l, 0x542200l, 0xd0138l, 0xd0135l, 0xa0100l,
    0xd0290l, 0xcl, 0xaa505l, 0x600a1l, 0x0l, 0xaa525l, 0xd03cbl,
    0x54f400l, 0x603l, 0x542200l, 0xd0138l, 0x55f400l, 0xfb000al, 0xd006cl,
    0x56f400l, 0x703l, 0xd0429l, 0xd048dl, 0x55f400l, 0xc00004l, 0xd006cl,
    0x56f400l, 0x603l, 0xd0429l, 0xd048dl, 0x56f400l, 0x204l, 0x5e0000l,
    0x56f400l, 0xc00000l, 0x5e0100l, 0x56f400l, 0x1l, 0x5e0200l, 0xd0404l,
    0xc0a26l, 0xaa503l, 0xa0101l, 0xa1e20l, 0xcl, 0xaa523l, 0xa1e00l, 0xcl,
    0xd03cbl, 0xd03cbl, 0x20d900l, 0x7f091l, 0xdecl, 0xd03cbl, 0x20c400l,
    0xd03cbl, 0xbc660l, 0xaf0a0l, 0xa7bl, 0xac477l, 0x76984l, 0xcl,
    0x240000l, 0x250000l, 0xd03d6l, 0x569d00l, 0x608a0l, 0x200033l,
    0x21c400l, 0xd03d6l, 0xcl, 0x60f000l, 0x57l, 0x337100l, 0xd0364l,
    0xd0404l, 0x337100l, 0x0l, 0x56db00l, 0x205b00l, 0x44db00l, 0x200045l,
    0xaf0a2l, 0xa99l, 0x337100l, 0x0l, 0x205b00l, 0x44e300l, 0xaf080l,
    0xab0l, 0x205b00l, 0x44f400l, 0x300l, 0x56d300l, 0x200044l, 0x57e300l,
    0x44f400l, 0xfdff00l, 0x20004el, 0x21e400l, 0x21c600l, 0x60f000l,
    0x58l, 0x337100l, 0xd0364l, 0x337100l, 0x0l, 0x446300l, 0x4e0300l,
    0xd0404l, 0x337100l, 0x0l, 0x44e300l, 0x250000l, 0xd03d6l, 0xcl,
    0x60f000l, 0x53l, 0x337100l, 0xd0364l, 0xd0404l, 0x337100l, 0x60f000l,
    0x59l, 0xd0364l, 0xd03acl, 0x4c0500l, 0x44db00l, 0x4c0b00l, 0xd03acl,
    0x4c0f00l, 0xd0404l, 0xd0135l, 0xa0100l, 0xd0290l, 0xcl, 0x75d88l,
    0x75d8cl, 0x75d8al, 0x75d89l, 0x75d8dl, 0x75d8bl, 0x75d84l, 0x75d85l,
    0x75d86l, 0x75d87l, 0x75d90l, 0x75d91l, 0x75d92l, 0x75d93l, 0x75d94l,
    0x75d97l, 0x75d96l, 0x75d98l, 0x75d99l, 0x75d9al, 0x75d9bl, 0x75d9cl,
    0x75d9fl, 0x75d9el, 0x75da0l, 0x75da1l, 0x75da2l, 0x75da3l, 0x75da4l,
    0x75da7l, 0x75da6l, 0xd0135l, 0x60f000l, 0x5el, 0xd0364l, 0x54b100l,
    0x608a0l, 0x200033l, 0x5c0300l, 0x54b000l, 0x608a0l, 0x200033l,
    0x5c0900l, 0xd03acl, 0x4c0f00l, 0xd03acl, 0x5c9500l, 0x200042l,
    0x5c1500l, 0x5c9900l, 0x200042l, 0x5c1900l, 0xd0404l, 0x63200l, 0xb01l,
    0x61ea0l, 0x0l, 0x0l, 0x0l, 0x7fda6l, 0x7fda7l, 0x7fda4l, 0x7fda3l,
    0x7fda2l, 0x7fda1l, 0x7fda0l, 0x7fd9el, 0x7fd9fl, 0x7fd9cl, 0x7fd9bl,
    0x7fd9al, 0x7fd99l, 0x7fd98l, 0x7fd96l, 0x7fd97l, 0x7fd94l, 0x7fd93l,
    0x7fd92l, 0x7fd91l, 0x7fd90l, 0x7fd87l, 0x7fd86l, 0x7fd85l, 0x7fd84l,
    0x7fd8bl, 0x7fd8dl, 0x7fd89l, 0x7fd8al, 0x7fd8cl, 0x7fd88l, 0xcl,
    0x75d88l, 0x75d8cl, 0x75d8al, 0x75d89l, 0x75d8dl, 0x75d8bl, 0x75d84l,
    0x75d85l, 0x75d86l, 0x75d87l, 0x75d90l, 0x75d91l, 0x75d92l, 0x75d93l,
    0x75d94l, 0x75d97l, 0x75d96l, 0x75d98l, 0x75d99l, 0x75d9al, 0x75d9bl,
    0x75d9cl, 0x75d9fl, 0x75d9el, 0x75da0l, 0x75da1l, 0x75da2l, 0x75da3l,
    0x75da4l, 0x75da7l, 0x75da6l, 0xd0135l, 0x60f000l, 0x5al, 0xd0364l,
    0x54b100l, 0x608a0l, 0x200033l, 0x5c0300l, 0x54b000l, 0x608a0l,
    0x200033l, 0x5c0900l, 0xd03acl, 0x4c0f00l, 0xd03acl, 0x5c9500l,
    0x200042l, 0x5c1500l, 0x5c9900l, 0x200042l, 0x5c1900l, 0xd0404l,
    0x63200l, 0xb5cl, 0x61ea0l, 0x0l, 0x0l, 0x0l, 0x7fda6l, 0x7fda7l,
    0x7fda4l, 0x7fda3l, 0x7fda2l, 0x7fda1l, 0x7fda0l, 0x7fd9el, 0x7fd9fl,
    0x7fd9cl, 0x7fd9bl, 0x7fd9al, 0x7fd99l, 0x7fd98l, 0x7fd96l, 0x7fd97l,
    0x7fd94l, 0x7fd93l, 0x7fd92l, 0x7fd91l, 0x7fd90l, 0x7fd87l, 0x7fd86l,
    0x7fd85l, 0x7fd84l, 0x7fd8bl, 0x7fd8dl, 0x7fd89l, 0x7fd8al, 0x7fd8cl,
    0x7fd88l, 0xcl, 0x75d88l, 0x75d8cl, 0x75d8al, 0x75d89l, 0x75d8dl,
    0x75d8bl, 0x75d84l, 0x75d85l, 0x75d86l, 0x75d87l, 0x75d90l, 0x75d91l,
    0x75d92l, 0x75d93l, 0x75d94l, 0x75d97l, 0x75d96l, 0x75d98l, 0x75d99l,
    0x75d9al, 0x75d9bl, 0x75d9cl, 0x75d9fl, 0x75d9el, 0x75da0l, 0x75da1l,
    0x75da2l, 0x75da3l, 0x75da4l, 0x75da7l, 0x75da6l, 0xd0135l, 0xd03acl,
    0x443900l, 0xd03acl, 0x443a00l, 0x63800l, 0xbdcl, 0x337100l, 0x60f000l,
    0x5fl, 0xd0364l, 0x44b900l, 0x4c0300l, 0x44ba00l, 0x4c0700l, 0x54b400l,
    0x608a0l, 0x200033l, 0x5c0b00l, 0x54b300l, 0x608a0l, 0x200033l,
    0x5c1100l, 0xd0404l, 0x63500l, 0xbb9l, 0x61ea0l, 0x0l, 0x0l, 0x0l,
    0x60f000l, 0x60l, 0xd0364l, 0x44b900l, 0x4c0300l, 0x54b700l, 0x608a0l,
    0x200033l, 0x5c0700l, 0x5c1300l, 0xd0404l, 0x63600l, 0xbcal, 0x61ea0l,
    0x0l, 0x0l, 0x0l, 0x60f000l, 0x61l, 0xd0364l, 0xd0404l, 0x57f000l,
    0x71l, 0x56ba00l, 0x20000dl, 0xaf0a2l, 0xbdbl, 0x8cl, 0x44f400l,
    0x100l, 0x250000l, 0xaf080l, 0xbdfl, 0x0l, 0x0l, 0x240000l, 0x250000l,
    0xd03d6l, 0x7fda6l, 0x7fda7l, 0x7fda4l, 0x7fda3l, 0x7fda2l, 0x7fda1l,
    0x7fda0l, 0x7fd9el, 0x7fd9fl, 0x7fd9cl, 0x7fd9bl, 0x7fd9al, 0x7fd99l,
    0x7fd98l, 0x7fd96l, 0x7fd97l, 0x7fd94l, 0x7fd93l, 0x7fd92l, 0x7fd91l,
    0x7fd90l, 0x7fd87l, 0x7fd86l, 0x7fd85l, 0x7fd84l, 0x7fd8bl, 0x7fd8dl,
    0x7fd89l, 0x7fd8al, 0x7fd8cl, 0x7fd88l, 0xcl, 0x75d88l, 0x75d8cl,
    0x75d8al, 0x75d89l, 0x75d8dl, 0x75d8bl, 0x75d84l, 0x75d85l, 0x75d86l,
    0x75d87l, 0x75d90l, 0x75d91l, 0x75d92l, 0x75d93l, 0x75d94l, 0x75d97l,
    0x75d96l, 0x75d98l, 0x75d99l, 0x75d9al, 0x75d9bl, 0x75d9cl, 0x75d9fl,
    0x75d9el, 0x75da0l, 0x75da1l, 0x75da2l, 0x75da3l, 0x75da4l, 0x75da7l,
    0x75da6l, 0xd0135l, 0xd03acl, 0x443900l, 0xd03acl, 0x443a00l, 0xd03acl,
    0x443b00l, 0x63800l, 0xc69l, 0x337100l, 0x60f000l, 0x5bl, 0xd0364l,
    0x44b900l, 0x4c0300l, 0x44ba00l, 0x4c0700l, 0x44bb00l, 0x4c0b00l,
    0x54b400l, 0x608a0l, 0x200033l, 0x5c1300l, 0x54b300l, 0x608a0l,
    0x200033l, 0x5c1900l, 0xd0404l, 0x63500l, 0xc40l, 0x61ea0l, 0x0l, 0x0l,
    0x0l, 0x60f000l, 0x5cl, 0xd0364l, 0x44b900l, 0x4c0300l, 0x54b700l,
    0x608a0l, 0x200033l, 0x5c0700l, 0x5c1300l, 0xd0404l, 0x63600l, 0xc51l,
    0x61ea0l, 0x0l, 0x0l, 0x0l, 0x60f000l, 0x5dl, 0xd0364l, 0xd0404l,
    0x57f000l, 0x71l, 0x56ba00l, 0x20000dl, 0xaf0a2l, 0xc68l, 0x57f000l,
    0x72l, 0x56bb00l, 0x20000dl, 0xaf0a2l, 0xc68l, 0x8cl, 0x44f400l,
    0x100l, 0x250000l, 0xaf080l, 0xc6cl, 0x0l, 0x0l, 0x240000l, 0x250000l,
    0xd03d6l, 0x7fda6l, 0x7fda7l, 0x7fda4l, 0x7fda3l, 0x7fda2l, 0x7fda1l,
    0x7fda0l, 0x7fd9el, 0x7fd9fl, 0x7fd9cl, 0x7fd9bl, 0x7fd9al, 0x7fd99l,
    0x7fd98l, 0x7fd96l, 0x7fd97l, 0x7fd94l, 0x7fd93l, 0x7fd92l, 0x7fd91l,
    0x7fd90l, 0x7fd87l, 0x7fd86l, 0x7fd85l, 0x7fd84l, 0x7fd8bl, 0x7fd8dl,
    0x7fd89l, 0x7fd8al, 0x7fd8cl, 0x7fd88l, 0xcl, 0x75d88l, 0x75d8cl,
    0x75d8al, 0x75d89l, 0x75d8dl, 0x75d8bl, 0x75d84l, 0x75d85l, 0x75d86l,
    0x75d87l, 0x75d90l, 0x75d91l, 0x75d92l, 0x75d93l, 0x75d94l, 0x75d97l,
    0x75d96l, 0x75d98l, 0x75d99l, 0x75d9al, 0x75d9bl, 0x75d9cl, 0x75d9fl,
    0x75d9el, 0x75da0l, 0x75da1l, 0x75da2l, 0x75da3l, 0x75da4l, 0x75da7l,
    0x75da6l, 0x44f400l, 0x40002l, 0x441600l, 0xd03acl, 0x208c00l,
    0x608a0l, 0x200023l, 0x218400l, 0x56f400l, 0x1d5l, 0x200045l, 0xaf0a7l,
    0xcc9l, 0x45f400l, 0x1d4c0l, 0xbf080l, 0xd0bl, 0x20a400l, 0xbf080l,
    0xd21l, 0x440900l, 0x548600l, 0x44f400l, 0x7f00l, 0x200046l, 0x200062l,
    0x540600l, 0xaf080l, 0xcebl, 0x56f400l, 0x3bl, 0x200045l, 0xaf0a7l,
    0xce2l, 0x45f400l, 0x3a98l, 0xbf080l, 0xd0bl, 0x20a400l, 0xbf080l,
    0xd21l, 0x208d00l, 0x603a0l, 0x20003bl, 0x550900l, 0x548600l,
    0x44f400l, 0x7f00l, 0x200046l, 0xac56fl, 0x200062l, 0x540600l,
    0xaf080l, 0xcebl, 0x44f400l, 0x40000l, 0x441600l, 0x44f400l, 0x80ffl,
    0x440600l, 0x44f400l, 0x500l, 0x440900l, 0x7fda6l, 0x7fda7l, 0x7fda4l,
    0x7fda3l, 0x7fda2l, 0x7fda1l, 0x7fda0l, 0x7fd9el, 0x7fd9fl, 0x7fd9cl,
    0x7fd9bl, 0x7fd9al, 0x7fd99l, 0x7fd98l, 0x7fd96l, 0x7fd97l, 0x7fd94l,
    0x7fd93l, 0x7fd92l, 0x7fd91l, 0x7fd90l, 0x7fd87l, 0x7fd86l, 0x7fd85l,
    0x7fd84l, 0x7fd8bl, 0x7fd8dl, 0x7fd89l, 0x7fd8al, 0x7fd8cl, 0x7fd88l,
    0xcl, 0x75d88l, 0x75d8cl, 0x75d8al, 0x75d90l, 0x20ae00l, 0x300000l,
    0x200045l, 0xaf0afl, 0xd18l, 0x200044l, 0x205800l, 0x200045l, 0xc0d12l,
    0x205800l, 0x200044l, 0x218400l, 0x220500l, 0x7fd90l, 0x7fd8al,
    0x7fd8cl, 0x7fd88l, 0xcl, 0x75d88l, 0x75d8cl, 0x75d8al, 0x75d89l,
    0x75d8dl, 0x75d8bl, 0x75d85l, 0x45f400l, 0x526e98l, 0x2000a0l,
    0x2b0000l, 0x55f400l, 0x4l, 0x51f400l, 0x266666l, 0x200014l, 0x280000l,
    0x200003l, 0xaf0a7l, 0xd39l, 0x44f400l, 0x1l, 0xaf080l, 0xd3al,
    0x218400l, 0x7fd85l, 0x7fd8bl, 0x7fd8dl, 0x7fd89l, 0x7fd8al, 0x7fd8cl,
    0x7fd88l, 0xcl, 0x75d88l, 0x75d8cl, 0x75d8al, 0x75d89l, 0x75d8dl,
    0x75d8bl, 0x75d84l, 0x75d85l, 0x75d86l, 0x75d87l, 0x75d90l, 0x75d91l,
    0x75d92l, 0x75d93l, 0x75d94l, 0x75d97l, 0x75d96l, 0x75d98l, 0x75d99l,
    0x75d9al, 0x75d9bl, 0x75d9cl, 0x75d9fl, 0x75d9el, 0x75da0l, 0x75da1l,
    0x75da2l, 0x75da3l, 0x75da4l, 0x75da7l, 0x75da6l, 0xd0135l, 0x60f000l,
    0x63l, 0x337100l, 0xd0364l, 0xd03acl, 0x4c0f00l, 0xd0404l, 0xd03acl,
    0x200013l, 0x208c00l, 0x608a0l, 0x200023l, 0x6cc00l, 0xd78l, 0x60f000l,
    0x62l, 0xd0364l, 0xd0404l, 0x250000l, 0x44fb00l, 0xd03d6l, 0x0l, 0x0l,
    0x0l, 0x60f000l, 0x64l, 0xd0364l, 0x44f000l, 0x71l, 0x4c0300l,
    0x44f000l, 0x72l, 0x4c0700l, 0x44f000l, 0x73l, 0x4c0b00l, 0x44f000l,
    0x74l, 0x4c0f00l, 0xd0404l, 0x7fda6l, 0x7fda7l, 0x7fda4l, 0x7fda3l,
    0x7fda2l, 0x7fda1l, 0x7fda0l, 0x7fd9el, 0x7fd9fl, 0x7fd9cl, 0x7fd9bl,
    0x7fd9al, 0x7fd99l, 0x7fd98l, 0x7fd96l, 0x7fd97l, 0x7fd94l, 0x7fd93l,
    0x7fd92l, 0x7fd91l, 0x7fd90l, 0x7fd87l, 0x7fd86l, 0x7fd85l, 0x7fd84l,
    0x7fd8bl, 0x7fd8dl, 0x7fd89l, 0x7fd8al, 0x7fd8cl, 0x7fd88l, 0xcl,
    0x57f400l, 0xfc0008l, 0xd006cl, 0x56f400l, 0xf03l, 0x562200l, 0xd0138l,
    0xc0daal, 0xd083cl, 0x57f400l, 0xfc0008l, 0xd006cl, 0xd0135l,
    0x56f400l, 0x703l, 0x562200l, 0xd0138l, 0xc0daal, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0xdecl, 0x4l,
    0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l,
    0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x4l, 0x0l,
    0x0l, 0xc83c00l, 0x800l, 0xcc3c00l, 0x800l, 0xca3c00l, 0x800l, 0x0l,
    0x0l, 0xc93c00l, 0x800l, 0xcd3c00l, 0x800l, 0xcb3c00l, 0x800l, 0x0l,
    0x0l, 0x0l, 0x0l, 0xfe3c00l, 0x800l, 0xff3c00l, 0x800l, 0xe03c00l,
    0x800l, 0xe13c00l, 0x800l, 0xe23c00l, 0x800l, 0xe33c00l, 0x800l,
    0xe43c00l, 0x800l, 0xe53c00l, 0x800l, 0xe63c00l, 0x800l, 0xe73c00l,
    0x800l, 0xd83c00l, 0x800l, 0xd93c00l, 0x800l, 0xda3c00l, 0x800l,
    0xdb3c00l, 0x800l, 0xdc3c00l, 0x800l, 0xdd3c00l, 0x800l, 0xde3c00l,
    0x800l, 0xdf3c00l, 0x800l, 0xfa3c00l, 0x800l, 0x0l, 0x0l, 0xd03c00l,
    0x800l, 0xd13c00l, 0x800l, 0xd23c00l, 0x800l, 0xd33c00l, 0x800l,
    0xd43c00l, 0x800l, 0xd53c00l, 0x800l, 0xd63c00l, 0x800l, 0xd73c00l,
    0x800l, 0xfb3c00l, 0x800l, 0xf93c00l, 0x800l, 0xfc3c00l, 0x800l,
    0xfd3c00l, 0x800l, 0x0l, 0x0l, 0xc43c00l, 0x800l, 0xc53c00l, 0x800l,
    0x0l, 0x0l, 0xc63c00l, 0x800l, 0xc73c00l, 0x800l, 0xea3c00l, 0x800l,
    0xf83c00l, 0x800l, 0xf13c00l, 0x800l, 0xf03c00l, 0x800l, 0x0l, 0x0l,
    0xf40000l, 0x5000l, 0xf40000l, 0x5400l, 0xf40000l, 0x5200l, 0x0l, 0x0l,
    0xf40000l, 0x5100l, 0xf40000l, 0x5500l, 0xf40000l, 0x5300l, 0x0l, 0x0l,
    0x0l, 0x0l, 0xf43e00l, 0x500l, 0xf43f00l, 0x500l, 0xf42000l, 0x500l,
    0xf42100l, 0x500l, 0xf42200l, 0x500l, 0xf42300l, 0x500l, 0xf42400l,
    0x500l, 0xf42500l, 0x500l, 0xf42600l, 0x500l, 0xf42700l, 0x500l,
    0xf40000l, 0x7000l, 0xf40000l, 0x7100l, 0xf40000l, 0x7200l, 0xf40000l,
    0x7300l, 0xf40000l, 0x7400l, 0xf40000l, 0x7500l, 0xf40000l, 0x7600l,
    0xf40000l, 0x7700l, 0xf43a00l, 0x500l, 0x0l, 0x0l, 0xf40000l, 0x6000l,
    0xf40000l, 0x6100l, 0xf40000l, 0x6200l, 0xf40000l, 0x6300l, 0xf40000l,
    0x6400l, 0xf40000l, 0x6500l, 0xf40000l, 0x6600l, 0xf40000l, 0x6700l,
    0xf43b00l, 0x500l, 0xf43900l, 0x500l, 0xf43c00l, 0x500l, 0xf43d00l,
    0x500l, 0x0l, 0x0l, 0xf40000l, 0x4400l, 0xf40000l, 0x4500l, 0x0l, 0x0l,
    0xf40000l, 0x4600l, 0xf40000l, 0x4700l, 0xf42a00l, 0x500l, 0xf43800l,
    0x500l, 0xf43100l, 0x500l, 0xf43000l, 0x500l, 0x8002l, 0x8102l,
    0x8202l, 0x8502l, 0x8602l, 0x8902l, 0x8d02l, 0x8e02l, 0x8e02l, 0x8e02l,
    0x8e02l, 0x8e02l, 0x8e02l, 0x8e02l, 0x8e02l, 0x8e02l, 0x8a02l, 0x8b02l,
    0x8f02l, 0x9002l, 0x9102l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l,
    0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l,
    0x1l, 0x4l, 0x104l, 0x204l, 0x504l, 0x604l, 0x904l, 0xd04l, 0xe04l,
    0xe04l, 0xe04l, 0xe04l, 0xe04l, 0xe04l, 0xe04l, 0xe04l, 0xe04l, 0xa04l,
    0xb04l, 0xf04l, 0x1004l, 0x1104l, 0xf04l, 0xf04l, 0xf04l, 0xf04l,
    0xf04l, 0xf04l, 0xf04l, 0xf04l, 0xf04l, 0xf04l, 0xf04l, 0xf04l, 0xf04l,
    0x1l, 0x4a04l, 0x0l, 0x0l, 0x8902l, 0x1l, 0xa04l, 0x0l, 0x0l, 0x4a04l,
    0x0l, 0x0l, 0x1l, 0xa04l, 0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l,
    0x4a04l, 0xd87c00l, 0x800l, 0x8902l, 0x1l, 0xa04l, 0xf40000l, 0x6000l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0xd8bc00l, 0x800l, 0x8902l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0x4a04l, 0xd8fc00l, 0x800l,
    0x8902l, 0x1l, 0x5f08l, 0x8902l, 0x1l, 0x5f08l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf40000l, 0x4400l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0x588400l, 0x700l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf40000l, 0x4400l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0x580000l, 0x4400l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf40000l, 0x4400l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0x580000l, 0x4c00l, 0x1l, 0xa04l, 0x0l,
    0x0l, 0x6a10l, 0x0l, 0x0l, 0x1l, 0xa04l, 0xf40000l, 0x4400l, 0x4a04l,
    0x0l, 0x0l, 0xa04l, 0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l,
    0xf42000l, 0x500l, 0x4a04l, 0x0l, 0x0l, 0x1l, 0x4a04l, 0xc43c00l,
    0x800l, 0x8902l, 0x4a04l, 0xd03c00l, 0x800l, 0x8902l, 0x4a04l,
    0xe03c00l, 0x800l, 0x8902l, 0xa04l, 0xf42000l, 0x500l, 0x4a04l,
    0xffff00l, 0xff00l, 0x1l, 0xe04000l, 0x800800l, 0x800600l, 0x800a00l,
    0x800900l, 0x800700l, 0x800b00l, 0x801f00l, 0x801e00l, 0x800c00l,
    0x801500l, 0x801800l, 0x801000l, 0x801100l, 0x801200l, 0x801300l,
    0x800f00l, 0x801d00l, 0x801b00l, 0x800100l, 0x800300l, 0x87c000l,
    0x87c800l, 0x87c600l, 0x87ca00l, 0x87c900l, 0x87c700l, 0x87cb00l,
    0x87df00l, 0x87de00l, 0x87cc00l, 0x87d500l, 0x87d800l, 0x87d000l,
    0x87d100l, 0x87d200l, 0x87d300l, 0x87cf00l, 0x87dd00l, 0x87db00l,
    0x87c100l, 0x87c300l, 0x1l, 0x8902l, 0x8902l, 0x8102l, 0x8202l,
    0x8402l, 0x8802l, 0x8502l, 0x8602l, 0x8702l, 0x8a02l, 0x9002l, 0x9302l,
    0x9102l, 0x9102l, 0x9102l, 0x9102l, 0x9102l, 0x9102l, 0x9102l, 0x9102l,
    0x1l, 0x904l, 0x904l, 0x104l, 0x204l, 0x404l, 0x804l, 0x504l, 0x604l,
    0x704l, 0xa04l, 0x1004l, 0x1304l, 0x1104l, 0x1104l, 0x1104l, 0x1104l,
    0x1104l, 0x1104l, 0x1104l, 0x1104l, 0x1l, 0x4904l, 0x0l, 0x4904l,
    0x907f00l, 0x8802l, 0x1l, 0x904l, 0x0l, 0x4904l, 0x0l, 0x1l, 0x904l,
    0x87d200l, 0x4904l, 0x0l, 0x4904l, 0xe02200l, 0x4904l, 0x907f00l,
    0x8802l, 0x1l, 0x904l, 0x87d200l, 0x4904l, 0x0l, 0x4904l, 0xf00200l,
    0x4904l, 0x907f00l, 0x8802l, 0x1l, 0x904l, 0x87d200l, 0x4904l, 0x0l,
    0x904l, 0x87c000l, 0x4904l, 0x0l, 0x4904l, 0xe00200l, 0x4904l,
    0xde1200l, 0x4904l, 0xe02200l, 0x1l, 0x4008l, 0x1l, 0x904l, 0x87d200l,
    0x4904l, 0x0l, 0x904l, 0x87c000l, 0x4904l, 0x0l, 0x4904l, 0xd01600l,
    0x4904l, 0xf00200l, 0x1l, 0x904l, 0x0l, 0x6910l, 0x0l, 0x1l, 0x904l,
    0x0l, 0x4904l, 0x0l, 0x6910l, 0xe04000l, 0x1l, 0x904l, 0x87c000l,
    0x4904l, 0x0l, 0x904l, 0x87d200l, 0x4904l, 0x0l, 0x1l, 0x4904l,
    0x907f00l, 0x8802l, 0x4904l, 0x9a7f00l, 0x8802l, 0x1l, 0x904l,
    0xd7d400l, 0x4904l, 0xffff00l, 0x8802l, 0x904l, 0xddd400l, 0x4904l,
    0xffff00l, 0x8802l, 0x904l, 0xd7d400l, 0x4904l, 0xffff00l, 0x8802l,
    0x904l, 0xddd400l, 0x4904l, 0xffff00l, 0x8802l, 0x904l, 0xd7d400l,
    0x4904l, 0xffff00l, 0x8802l, 0x904l, 0x83dd00l, 0x4904l, 0x30000l,
    0x4904l, 0xe04000l, 0x4904l, 0xe04000l, 0x4904l, 0xe04000l, 0x1l,
    0x904l, 0x87cf00l, 0x4904l, 0x0l, 0x1l, 0x4904l, 0xde0b00l, 0x904l,
    0x87c000l, 0x4904l, 0x0l, 0x4904l, 0xd01f00l, 0x904l, 0x87c000l,
    0x4904l, 0x0l, 0x904l, 0xe98400l, 0x4904l, 0x0l, 0x6910l, 0xfd9b00l,
    0x1l, 0x904l, 0x87d100l, 0x4904l, 0x200l, 0x4904l, 0x994100l, 0x904l,
    0x87d100l, 0x4904l, 0x300l, 0x4904l, 0x994000l, 0x904l, 0x87d300l,
    0x4904l, 0x0l, 0x4904l, 0xc80000l, 0x904l, 0x87d100l, 0x4904l,
    0x950000l, 0x904l, 0x87d200l, 0x4904l, 0x950800l, 0x4904l, 0x994300l,
    0x4904l, 0x690000l, 0x4904l, 0x9a4300l, 0x1l, 0x904l, 0x87d100l,
    0x4904l, 0x200l, 0x4904l, 0x994100l, 0x904l, 0x87d100l, 0x4904l,
    0x300l, 0x4904l, 0x994000l, 0x904l, 0x87d300l, 0x4904l, 0x0l, 0x4904l,
    0xc80000l, 0x904l, 0x87d100l, 0x4904l, 0x931000l, 0x904l, 0x87d200l,
    0x4904l, 0x931800l, 0x4904l, 0x994300l, 0x4904l, 0xe02300l, 0x4904l,
    0x9a4300l, 0x1l, 0x904l, 0x87d300l, 0x4904l, 0x0l, 0x904l, 0x87c600l,
    0x4904l, 0x0l, 0x904l, 0x87d100l, 0x4904l, 0x200l, 0x4904l, 0x994100l,
    0x904l, 0x87d100l, 0x4904l, 0x200l, 0x4904l, 0x994000l, 0x4904l,
    0xc80000l, 0x904l, 0x87d100l, 0x4904l, 0x5f0000l, 0x904l, 0x87d200l,
    0x4904l, 0x5f0800l, 0x4904l, 0x994300l, 0x4904l, 0x690000l, 0x4904l,
    0xd60000l, 0x4904l, 0x9a4300l, 0x1l, 0x904l, 0x87d300l, 0x4904l, 0x0l,
    0x904l, 0x87d100l, 0x4904l, 0x200l, 0x4904l, 0x994100l, 0x904l,
    0x87d100l, 0x4904l, 0x7f0000l, 0x4904l, 0x994300l, 0x904l, 0x87d100l,
    0x4904l, 0x200l, 0x4904l, 0x994000l, 0x904l, 0x87d100l, 0x4904l,
    0x3f0000l, 0x904l, 0x87d200l, 0x4904l, 0x0l, 0x4904l, 0x994300l, 0x1l,
    0x4904l, 0x690000l, 0x4904l, 0x9a4300l, 0x4904l, 0x907f00l, 0x8802l,
    0x1l, 0x904l, 0x87d300l, 0x4904l, 0x0l, 0x904l, 0x87c000l, 0x4904l,
    0x0l, 0x904l, 0x87c100l, 0x4904l, 0x0l, 0x904l, 0x87d500l, 0x4904l,
    0x800l, 0x904l, 0xc90200l, 0x4904l, 0x200l, 0x4904l, 0x994100l, 0x904l,
    0x87d100l, 0x4904l, 0x200l, 0x4904l, 0x994000l, 0x904l, 0x87d100l,
    0x4904l, 0x551000l, 0x904l, 0x87d200l, 0x4904l, 0x551800l, 0x4904l,
    0x994300l, 0x4904l, 0xe00700l, 0x4904l, 0xe10300l, 0x4904l, 0x9a4300l,
    0x1l, 0x904l, 0x87d300l, 0x4904l, 0x0l, 0x904l, 0x87d100l, 0x4904l,
    0x200l, 0x4904l, 0x994100l, 0x904l, 0x87d100l, 0x4904l, 0x711000l,
    0x4904l, 0x994300l, 0x904l, 0x87d100l, 0x4904l, 0x200l, 0x4904l,
    0x994000l, 0x904l, 0x87d100l, 0x4904l, 0x311000l, 0x4904l, 0xca0000l,
    0x4904l, 0x994300l, 0x1l, 0x4904l, 0xe62700l, 0x4904l, 0xe72300l,
    0x4904l, 0x9a4300l, 0x4904l, 0x967f00l, 0x8802l, 0x4904l, 0x977f00l,
    0x8802l, 0x1l, 0x4904l, 0x690000l, 0x4904l, 0x907f00l, 0x8802l, 0x1l,
    0x4904l, 0x907f00l, 0x8802l, 0x4904l, 0x917f00l, 0x8802l, 0x4904l,
    0x987f00l, 0x8802l, 0x4904l, 0x9b7f00l, 0x8802l, 0x904l, 0x87d300l,
    0x4904l, 0x0l, 0x1l, 0x904l, 0x87c000l, 0x4904l, 0x0l, 0x904l,
    0x87c100l, 0x4904l, 0x0l, 0x904l, 0x87d000l, 0x4904l, 0x0l, 0x904l,
    0x87d300l, 0x4904l, 0x0l, 0x1l, 0x0l, 0x0l, 0xc83b00l, 0x800l,
    0xcc3b00l, 0x800l, 0xca3b00l, 0x800l, 0x0l, 0x0l, 0xc93b00l, 0x800l,
    0xcd3b00l, 0x800l, 0xcb3b00l, 0x800l, 0x0l, 0x0l, 0x0l, 0x0l,
    0xfe3b00l, 0x800l, 0xff3b00l, 0x800l, 0xe03b00l, 0x800l, 0xe13b00l,
    0x800l, 0xe23b00l, 0x800l, 0xe33b00l, 0x800l, 0xe43b00l, 0x800l,
    0xe53b00l, 0x800l, 0xe63b00l, 0x800l, 0xe73b00l, 0x800l, 0xd83b00l,
    0x800l, 0xd93b00l, 0x800l, 0xda3b00l, 0x800l, 0xdb3b00l, 0x800l,
    0xdc3b00l, 0x800l, 0xdd3b00l, 0x800l, 0xde3b00l, 0x800l, 0xdf3b00l,
    0x800l, 0xfa3b00l, 0x800l, 0x0l, 0x0l, 0xd03b00l, 0x800l, 0xd13b00l,
    0x800l, 0xd23b00l, 0x800l, 0xd33b00l, 0x800l, 0xd43b00l, 0x800l,
    0xd53b00l, 0x800l, 0xd63b00l, 0x800l, 0xd73b00l, 0x800l, 0xfb3b00l,
    0x800l, 0xf93b00l, 0x800l, 0xfc3b00l, 0x800l, 0xfd3b00l, 0x800l, 0x0l,
    0x0l, 0xc43b00l, 0x800l, 0xc53b00l, 0x800l, 0x0l, 0x0l, 0xc63b00l,
    0x800l, 0xc73b00l, 0x800l, 0xea3b00l, 0x800l, 0xf83b00l, 0x800l,
    0xf13b00l, 0x800l, 0xf03b00l, 0x800l, 0x0l, 0x0l, 0xf40000l, 0x5000l,
    0xf40000l, 0x5400l, 0xf40000l, 0x5200l, 0x0l, 0x0l, 0xf40000l, 0x5100l,
    0xf40000l, 0x5500l, 0xf40000l, 0x5300l, 0x0l, 0x0l, 0x0l, 0x0l,
    0xf43e00l, 0x500l, 0xf43f00l, 0x500l, 0xf42000l, 0x500l, 0xf42100l,
    0x500l, 0xf42200l, 0x500l, 0xf42300l, 0x500l, 0xf42400l, 0x500l,
    0xf42500l, 0x500l, 0xf42600l, 0x500l, 0xf42700l, 0x500l, 0xf40000l,
    0x7000l, 0xf40000l, 0x7100l, 0xf40000l, 0x7200l, 0xf40000l, 0x7300l,
    0xf40000l, 0x7400l, 0xf40000l, 0x7500l, 0xf40000l, 0x7600l, 0xf40000l,
    0x7700l, 0xf43a00l, 0x500l, 0x0l, 0x0l, 0xf40000l, 0x6000l, 0xf40000l,
    0x6100l, 0xf40000l, 0x6200l, 0xf40000l, 0x6300l, 0xf40000l, 0x6400l,
    0xf40000l, 0x6500l, 0xf40000l, 0x6600l, 0xf40000l, 0x6700l, 0xf43b00l,
    0x500l, 0xf43900l, 0x500l, 0xf43c00l, 0x500l, 0xf43d00l, 0x500l, 0x0l,
    0x0l, 0xf40000l, 0x4400l, 0xf40000l, 0x4500l, 0x0l, 0x0l, 0xf40000l,
    0x4600l, 0xf40000l, 0x4700l, 0xf42a00l, 0x500l, 0xf43800l, 0x500l,
    0xf43100l, 0x500l, 0xf43000l, 0x500l, 0x8002l, 0x8a02l, 0x8b02l,
    0x8122l, 0x8222l, 0x8522l, 0x8622l, 0x8922l, 0x8d22l, 0x8f22l, 0x9022l,
    0x9122l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l, 0x9202l,
    0x9202l, 0x1l, 0x4l, 0xa04l, 0xb04l, 0x124l, 0x224l, 0x524l, 0x624l,
    0x924l, 0xd24l, 0xf24l, 0x1024l, 0x1124l, 0xf24l, 0xf24l, 0xf24l,
    0xf24l, 0xf24l, 0xf24l, 0xf24l, 0xf24l, 0x1l, 0x4a04l, 0x0l, 0x0l,
    0x8922l, 0x1l, 0xa04l, 0x0l, 0x0l, 0x4a04l, 0x0l, 0x0l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0x4a04l, 0xd87400l, 0x800l,
    0xa04l, 0x70b300l, 0x800l, 0x4a04l, 0xfffb00l, 0x0l, 0x8922l, 0xa04l,
    0x70b200l, 0x800l, 0x4a04l, 0xfffb00l, 0x0l, 0x8922l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0x4a04l, 0xd8bb00l, 0x800l,
    0x8922l, 0x1l, 0xa04l, 0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l,
    0x4a04l, 0xd8fb00l, 0x800l, 0x8922l, 0x1l, 0x5f08l, 0x8922l, 0x1l,
    0x5f08l, 0x1l, 0xa04l, 0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l,
    0xf4b300l, 0x800l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf4b200l, 0x800l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0x587400l, 0x800l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf40000l, 0x4400l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0x580000l, 0x4400l, 0x1l, 0xa04l,
    0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf40000l, 0x4400l,
    0x4a04l, 0x0l, 0x0l, 0x4a04l, 0x580000l, 0x4c00l, 0x1l, 0xa04l, 0x0l,
    0x0l, 0x6a10l, 0x0l, 0x0l, 0x1l, 0xa04l, 0xf40000l, 0x4400l, 0x4a04l,
    0x0l, 0x0l, 0xa04l, 0xf40000l, 0x6000l, 0x4a04l, 0x0l, 0x0l, 0xa04l,
    0xf42000l, 0x500l, 0x4a04l, 0x0l, 0x0l, 0x1l, 0xa04l, 0xf40000l,
    0x4400l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf40000l, 0x6000l, 0x4a04l,
    0x0l, 0x0l, 0xa04l, 0xf42000l, 0x500l, 0x4a04l, 0x0l, 0x0l, 0xa04l,
    0xf4b200l, 0x800l, 0x4a04l, 0x0l, 0x0l, 0xa04l, 0xf4b300l, 0x800l,
    0x4a04l, 0x0l, 0x0l, 0x1l, 0x4a04l, 0xc43b00l, 0x800l, 0x8922l,
    0x4a04l, 0xd03b00l, 0x800l, 0x8922l, 0x4a04l, 0xe03b00l, 0x800l,
    0x8922l, 0xa04l, 0xf42000l, 0x500l, 0x4a04l, 0xffff00l, 0x0l, 0x1l,
    0x4a04l, 0xc43b00l, 0x800l, 0x8922l, 0x4a04l, 0xd03b00l, 0x800l,
    0x8922l, 0x4a04l, 0xe03b00l, 0x800l, 0x8922l, 0xa04l, 0xf42000l,
    0x500l, 0x4a04l, 0xffff00l, 0x0l, 0xa04l, 0x70b200l, 0x800l, 0x4a04l,
    0xfffb00l, 0x0l, 0x8922l, 0xa04l, 0x70b300l, 0x800l, 0x4a04l,
    0xfffb00l, 0x0l, 0x8922l, 0x1l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0xf2dl, 0xf38l, 0xf43l, 0xf4bl,
    0xf53l, 0xf63l, 0xf73l, 0xe05l, 0xe6dl, 0xed5l, 0xee5l, 0xef8l, 0xf1bl,
    0xf20l, 0xf27l, 0xf32l, 0xf3dl, 0xf4dl, 0xf5dl, 0xf6dl, 0xf7dl, 0xf4bl,
    0xf84l, 0xf97l, 0x0l, 0x0l, 0xf7dl, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x4l, 0xal, 0x6l, 0x4l,
    0x4l, 0x4l, 0xal, 0x10l, 0xcl, 0xcl, 0xcl, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x100el, 0x1018l, 0x0l, 0x0l, 0x1022l, 0x1033l, 0x0l, 0xfaal, 0xfbfl,
    0xfd5l, 0xfdel, 0xfeal, 0xfffl, 0x1005l, 0x100al, 0x1014l, 0x0l,
    0x101el, 0x102fl, 0x0l, 0x103cl, 0x102dl, 0x1048l, 0x1051l, 0x0l, 0x0l,
    0x1041l, 0x1058l, 0x107cl, 0x1081l, 0x10b5l, 0x1126l, 0x1153l, 0x1172l,
    0x1094l, 0x10d6l, 0x10fdl, 0x111el, 0x117fl, 0x1185l, 0x1196l, 0x3l,
    0x7l, 0x4l, 0x3l, 0x3l, 0x3l, 0x7l, 0x0l, 0x8l, 0x8l, 0x8l, 0x12b3l,
    0x12cbl, 0x12d6l, 0x12del, 0x12e6l, 0x12fcl, 0x130cl, 0x11a7l, 0x120fl,
    0x1277l, 0x1280l, 0x128cl, 0x12a1l, 0x12a6l, 0x12adl, 0x12c5l, 0x12d0l,
    0x12e0l, 0x12f6l, 0x1306l, 0x1316l, 0x12del, 0x131dl, 0x134fl, 0x1330l,
    0x1362l, 0x1316l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x4l, 0xal, 0x6l, 0x4l, 0x4l, 0x4l, 0xal,
    0x10l, 0x12l, 0xcl, 0xcl, 0x4a5l, 0x4c9l, 0x4f9l, 0x57fl, 0x52fl,
    0x5acl, 0x557l, 0x5c0l, 0x5d4l, 0x60fl, 0x631l, 0x65el, 0x677l, 0x690l,
    0x6d2l, 0x6fel, 0x722l, 0x727l, 0x747l, 0x772l, 0x79dl, 0x7c2l, 0x7cfl,
    0x816l, 0x81el, 0x834l, 0x843l, 0x860l, 0x8e4l, 0x911l, 0x96fl, 0x98al,
    0x9e9l, 0x860l, 0xa68l, 0xa6cl, 0xa6fl, 0xa7dl, 0xa86l, 0xab3l, 0xac7l,
    0xb22l, 0xb7dl, 0xc00l, 0xc8dl, 0xd42l, 0x3el, 0x34l, 0x2el, 0x1383l,
    0x13b7l, 0x13ebl, 0x141fl, 0x1453l, 0x1487l, 0x0l, 0x0l, 0x14bbl,
    0x14efl, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l,
    0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l, 0x0l
};







int
dspd_cc_reset (int device_index)
{
    int cc_num;
    time_t curtm;
    time_t endtime;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    /* clear int_ack, adm_group, set serial xmit bit */
    output (CTRL2, STX);

    /* assert ADM_RESET and HST_ACK */
    output (CTRL1, (cc_num << 4));
    output (CTRL1, (cc_num << 4) | ADM_RESET | HST_ACK);

    /* wait for TIMEOUT seconds */
    (void) time (&curtm);
    for (endtime = curtm + TIMEOUT; curtm <= endtime; (void) time (&curtm));

    /* release ADM_RESET line */
    output (CTRL1, (cc_num << 4) | HST_ACK);

    /* wait for TIMEOUT seconds */
    (void) time (&curtm);
    for (endtime = curtm + TIMEOUT; curtm <= endtime; (void) time (&curtm));

    /* if ADM_ACK is high it is a universal CC */
    if (input (CTRL1) & ADM_ACK)
    {
        char *monitor_file = NULL;


        set_cc_type (get_cc_num (device_index), DSP_NEW_CC);

        table_offset_multiplier = BYTES_PER_MOVEP_OPCODE / 3;
        once_table_offset_multiplier = 1;
        
        serial_cc_load (device_index, 0x7fc0l,
                        sizeof (serial_loader) / sizeof (unsigned long),
                        serial_loader);

        monitor_file = getenv ("CC56800");

        if (monitor_file)
        {
            if (!load_cc_monitor (device_index, monitor_file))
            {
                return (DSP_ERROR);
            }
        }
        else
        {
            parallel_cc_load (device_index, 0l,
                              sizeof (monitor) / sizeof (unsigned long),
                              0l, monitor);
        }
    }
    else
    {
        set_cc_type (get_cc_num (device_index), DSP_OLD_CC);

        table_offset_multiplier = BYTES_PER_MOVEP_OPCODE;
        once_table_offset_multiplier = 3;

        /* wait for ADM_INT */
        (void) time (&curtm);
        for (endtime = curtm + (TIMEOUT * 2); curtm <= endtime;
             (void) time (&curtm))
        {
            if (input (CTRL1) & ADM_INT)
            {
                break;
            }
        }
    
        /* if timeout */
        if (curtm > endtime)
        {
            return (DSP_ERROR);
        }

        /* wait for CC to complete command */
        if (handshake (cc_num, TIMEOUT) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }
    }

    if (dspd_cc_architecture (device_index, DSP_CC_56800) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    cc_num = get_cc_num (device_index);

    set_cc_has_been_configured (cc_num, FALSE);
    
    set_cc_has_been_reset (cc_num, TRUE);

    deselect_device ();
    
    return (DSP_OK);
}

int
dspd_cc_go (int device_index)
{
    int error = DSP_OK;
    
    select_cc (get_cc_num (device_index));

    if (send_byte (device_index, SEQEXEC))
    {
        error = DSP_ERROR;
    }

    deselect_device ();

    return (error);
}

int 
dspd_cc_service_bp (int device_index)
{
    int cc_num;

    
    cc_num = get_cc_num (device_index);
    select_cc (cc_num);
    
    /* Wait for ADM_INT=1 */
    if (flag_test (DSP_HIGH, ADM_INT) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    /* Clear HST_ACK line */
    output (CTRL1, cc_num << 4);

    /* Acknowledge irq received */
    output (CTRL2, INT_ACK);

    /* Wait for ADM_INT=0 */
    if (flag_test (DSP_LOW, ADM_INT) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    /* Deassert interrupt acknowledge */
    output (CTRL2, 0);

    deselect_device ();
    
    return (DSP_OK);
}

int
dspd_cc_revision (int device_index, char *revstring)
{
    float rev;
    unsigned long data;
    
    if (dspd_cc_read_memory (device_index, DSP_CC_XMEM, DSP_CC_REV, 1l,
                             &data) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    else
    {
        data &= 0xfffl;
        rev = (float)(data) / (float)100.0;
        sprintf (revstring, "Command Converter monitor revision {%4.2f}", rev);
    }

    return (DSP_OK);
}


void
dspd_set_host_timeout (int timeout)
{
#if WIN_NT

    PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  InputBuffer[sizeof(MDSP_TRANSFER_PARAMS)+sizeof(ULONG)];    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // NuMDSP_TRANSFER_PARAMSmber of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_SET_TIMEOUT;
    ULONG                 DataLength = sizeof(MDSP_TRANSFER_PARAMS)+sizeof(ULONG);

    pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

	pIOBuffer->Data.LongData[0] = (ULONG)timeout;

	DeviceIoControl( hndDevice,
                     IoctlCode,
                     InputBuffer,
                     DataLength,
                     NULL,
                     0,
                     &ReturnedLength,
                     NULL );
#endif

    TIMEOUT = timeout;

}

int
dspd_set_host_address (int hostaddr)
{
#if WIN_NT

    PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  InputBuffer[sizeof(MDSP_TRANSFER_PARAMS)+sizeof(ULONG)];    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_SET_IOPORTNO;
    ULONG                 DataLength = sizeof(MDSP_TRANSFER_PARAMS)+sizeof(ULONG);

    BOOL                  Status;

    pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

    pIOBuffer->Data.LongData[0] = (ULONG)hostaddr;

    Status = DeviceIoControl( hndDevice,
                              IoctlCode,
                              InputBuffer,
                              DataLength,
                              NULL,
                              0,
                              &ReturnedLength,
                              NULL );

    // if there was an error condition returned by the Device Driver
    // do not set the host address
    if ( !Status )
    {
        /* Cannot set the I/O Address under Windows NT */

        return (DSP_ERROR);
    }

#endif

    HOST_ADDRESS = hostaddr;

    return (DSP_OK);
}

void
dspd_configure_device (int devindex, int ccnum, int tmsnum, int chainpos)
{
    if (devindex < 31)
    {
        set_cc_num (devindex, ccnum);
        set_tms_num (devindex, tmsnum);
        set_chain_pos (devindex, chainpos);
    }
}

void
dspd_set_tms_chain_length (int ccindex, int tmsnum, int chainlen)
{
    if (ccindex < 8 && tmsnum < 2)
    {
        if (tmsnum)
        {
            set_tms1_count (ccindex, chainlen);
        }
        else
        {
            set_tms0_count (ccindex, chainlen);
        }
    }
}

int
dspd_get_host_timeout (void)
{
    return (TIMEOUT);
}

int
dspd_get_host_address (void)
{
    return (HOST_ADDRESS);
}

void
dspd_get_device_configuration (int devindex, int *ccnum, int *tmsnum,
                               int *chainpos)
{
    if (devindex < 31)
    {
        *ccnum = get_cc_num (devindex);
        *tmsnum = get_tms_num (devindex);
        *chainpos = get_chain_pos (devindex);
    }
    else
    {
        *ccnum = -1;
        *tmsnum = -1;
        *chainpos = -1;
    }
}

int
dspd_get_cc_num (int devindex)
{
    int cc_num;
    
    if (devindex < 31)
    {
        cc_num = get_cc_num (devindex);
    }
    else
    {
        cc_num = -1;
    }

    return (cc_num);
}

int
dspd_get_tms_chain_length (int ccindex, int tmsnum)
{
    int length;
    
    if (ccindex < 8 && tmsnum < 2)
    {
        if (tmsnum)
        {
            length = get_tms1_count (ccindex);
        }
        else
        {
            length = get_tms0_count (ccindex);
        }
    }
    else
    {
        length = 0;
    }
    
    return (length);
}


/* Private functions */
#if macintosh || MSDOS
static int
adm_read (int device_index,
	  int command,
	  unsigned long address,
	  unsigned long count,
	  unsigned long *value)
{
    int error;
    unsigned index = 0;
    unsigned protocol[5];

    /* if register read, compute offset into eprom table */
    if (command == RREAD)
    {
	address = address * table_offset_multiplier;
    }

    /* internal X-memory cannot be read with XREAD in 56812.
       check the command for XREAD, and replace it with XIREAD if
       necessary.
    */
    if ( command == XREAD && in_xi_space ( address) )
    {
	command = XIREAD;
    }

    protocol[0] = (unsigned) command;	                /* command */
    protocol[1] = (unsigned) ((address >> 8) & 0xffl);	/* high address byte */
    protocol[2] = (unsigned) (address & 0xffl);	        /* low address byte */
    protocol[3] = (unsigned) ((count >> 8) & 0xffl);	/* high count byte */
    protocol[4] = (unsigned) (count & 0xffl);	        /* low count byte */

    /* send command */
    for (index = 0; index < sizeof (protocol) / sizeof (unsigned int); index++)
    {
	if (send_byte (device_index, protocol[index]))
        {
	    return (DSP_ERROR);
        }
    }

    /* get data */
    if (get_words (device_index, count, value))
    {
	return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    return (error);
}

#endif

#if UNIX
static int
adm_read (int device_index,
	  int command,
	  unsigned long address,
	  unsigned long count,
	  unsigned long *value)
{
    int error;
    char protocol[10];

    /* if register read, compute offset into eprom table */
    if (command == RREAD)
    {
	address = address * table_offset_multiplier;
    }
    
    /* internal X-memory cannot be read with XREAD in 56812.
       check the command for XREAD, and replace it with XIREAD if
       necessary.
    */
    if ( command == XREAD && in_xi_space ( address) )
    {
	command = XIREAD;
    }
    
    protocol[0] = (char) 5;	                    /* command count */
    protocol[1] = (char) command;	            /* command */
    protocol[2] = (char) ((address >> 8) & 0xffl);  /* high address byte */
    protocol[3] = (char) (address & 0xffl);	    /* low address byte */
    protocol[4] = (char) ((count >> 8) & 0xffl);    /* high count byte */
    protocol[5] = (char) (count & 0xffl);	    /* low count byte */

    /* send command */
    if (ioctl (HOST_ADDRESS, MDSPCOMMAND, protocol))
    {
	return (DSP_ERROR);
    }

    /* get data */
    if (read (HOST_ADDRESS, (char *) value,
              (int) (count * sizeof (long))) == DSP_ERROR)
    {
    	return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    return (error);
}


#endif

#if macintosh || MSDOS
static int
adm_write (int device_index,
	   int command,
	   unsigned long address,
	   unsigned long count,
	   unsigned long *value)
{
    int error;
    unsigned index = 0;
    unsigned int protocol[5];

    /* if register write, compute offset into eprom table */
    if (command == RWRITE)
    {
        address = address * table_offset_multiplier;
    }

    protocol[0] = command;                              /* command */
    protocol[1] = (unsigned) ((address >> 8) & 0xffl);	/* high address byte */
    protocol[2] = (unsigned) (address & 0xffl);	        /* low address byte */
    protocol[3] = (unsigned) ((count >> 8) & 0xffl);	/* high count byte */
    protocol[4] = (unsigned) (count & 0xffl);	        /* low count byte */

    /* send command */
    for (index = 0; index < sizeof (protocol) / sizeof (unsigned int); index++)
    {
        if (send_byte (device_index, protocol[index]))
        {
            return (DSP_ERROR);
        }
    }

    /* send data */

    /* if memory fill command, send only one word of data */
    if (command == PWRITE || command == XWRITE || command == YWRITE)
    {
        if (send_words (device_index, 1l, value))
        {
            return (DSP_ERROR);
        }
    }

    else
    {
        if (send_words (device_index, count, value))
        {
            return (DSP_ERROR);
        }
    }

    /* wait for CC to complete command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    return (error);
}

#endif

#if UNIX
static int
adm_write (int device_index,
	   int command,
	   unsigned long address,
	   unsigned long count,
	   unsigned long *value)
{
    int error;
    char protocol[11];

    /* if register write, compute offset into eprom table */
    if (command == RWRITE)
    {
	address = address * table_offset_multiplier;
    }

    protocol[0] = (char) 5;                        /* command count */
    protocol[1] = (char) command;	           /* command */
    protocol[2] = (char) ((address >> 8) & 0xffl); /* high address byte */
    protocol[3] = (char) (address & 0xffl);	   /* low address byte */
    protocol[4] = (char) ((count >> 8) & 0xffl);   /* high count byte */
    protocol[5] = (char) (count & 0xffl);	   /* low count byte */

    /* send command */
    if (ioctl (HOST_ADDRESS, MDSPCOMMAND, protocol))
    {
	return (DSP_ERROR);
    }

    /* send data */

    /* if memory fill command, send only one word of data */
    if (command == PWRITE || command == XWRITE || command == YWRITE)
    {
	if (send_words (device_index, 1l, value))
        {
	    return (DSP_ERROR);
        }
    }

    else
    {
	if (write (HOST_ADDRESS, (char *) value,
                   (int) (count * sizeof (long))) == DSP_ERROR)
        {
	    return (DSP_ERROR);
        }
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    return (error);
}

#endif


#if macintosh || MSDOS
static int
adm_write_flash (int device_index,
                 int command,
                 unsigned long min_addr,
                 unsigned long max_addr,
                 unsigned long *value)
{
    unsigned int index = 0;
    unsigned int protocol[3];
    unsigned long address;
    unsigned long data[2];

    char buf[128];

    int error = DSP_OK;

    protocol[0] = command;                              /* command */

    /* for programming the x-memory */
    if ( command == PROGRAM_XFLASH )
    {
        address = min_addr;
        /* main data send loop for the X-memory */
        do {
            /* for each data word to be sent
               - check if the data @ address is non-zero
               - if zero go to the next data
               - if non-zero
                 - send the command
                 - send the address
                 - send the data
            */


            if ( value[address] != 0 )
            {
                /*set the address */
                protocol[1] = (unsigned) ((address >> 8) & 0xffl);  /* high address byte */
                protocol[2] = (unsigned) (address & 0xffl);	        /*  low address byte */

                /* send command */
                for ( index = 0; index < sizeof (protocol) / sizeof (unsigned int); index++ )
                {
                    if ( send_byte( device_index, protocol[index] ))
                    {
                        (void) sprintf( buf, "Unrecoverable communication error #1" );
                        simw_wscr_c( buf, 1 );
                        simw_refresh();
                        return (DSP_ERROR);
                    }
                }
                
                /* send data */
                if ( send_words( device_index, 1l, &value[address] ))
                {
                    (void) sprintf( buf, "Unrecoverable communication error #2" );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    return (DSP_ERROR);
                }
                
                /* get the result status back */
                if ( get_words ( device_index, 1l, data ))
                {
                    (void) sprintf( buf, "Unrecoverable communication error #3" );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    return (DSP_ERROR);
                }

                /* wait for CC to complete command. */
                if ( error != DSP_ERROR ) 
                {
                    error = handshake( get_cc_num (device_index), TIMEOUT );
                }
                else 
                {
                    handshake( get_cc_num (device_index), TIMEOUT );
                }

                /* if the sent was unsuccessfull, set the error */
                if ( *data == 0l )
                {
                    (void) sprintf( buf, "Error programming at x:$%x", address );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    error = DSP_ERROR;
                }
            }
            
            /* go to the next data */
            address++;

        } while (address<max_addr);  /* continue sending data for all valid addresses for
                                        min_addr < address < max_addr
        	                         */
	    return (error);
    }

    /* for programming the p-memory */

    /* we need to reset the address to the beginning of a block */
    address = (min_addr/16)*16;

    /* main P-data send loop */
    do 
    {
        /* for each data word to be sent
           - Check if the data @ address and data @ address+8 are non-zero
           - if zero, go to the next data
           - if non zero,
             - send the command
             - send the address
             - send the data pair
        */
        
        if ( value[address] != 0 || value[address+8] != 0 )   /* if at least one of the pair is non-zero */
        {
            data[0] = value[address];
            data[1] = value[address+8];
            
            /*set the address */
            protocol[1] = (unsigned) ((address >> 8) & 0xffl);  /* high address byte */
            protocol[2] = (unsigned) (address & 0xffl);	        /*  low address byte */
                                                                
            /* send command */ 
            for ( index = 0; index < sizeof (protocol) / sizeof (unsigned int); index++ )
            {
                if ( send_byte( device_index, protocol[index] ))
                {
                    (void) sprintf( buf, "Unrecoverable communication error #4" );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    return (DSP_ERROR);
                }
            }

            /* send data */
            if ( send_words( device_index, 2l, data ))
            {
                (void) sprintf( buf, "Unrecoverable communication error #5" );
                simw_wscr_c (buf, 1);
                simw_refresh ();
                return (DSP_ERROR);
            }

            /* get the result status back */
            if ( get_words ( device_index, 1l, data ))
            {
                (void) sprintf( buf, "Unrecoverable communication error #6" );
                simw_wscr_c (buf, 1);
                simw_refresh ();
                return (DSP_ERROR);
            }
            
            /* wait for CC to complete command. */
            if ( error != DSP_ERROR )
            {
                error = handshake( get_cc_num (device_index), TIMEOUT );
            }
            else
            {
                handshake(get_cc_num (device_index), TIMEOUT);
            }

            /* if the sent was unsuccessfull, set the error */
            if ( *data == 0l )
            {
                (void) sprintf (buf, "Error programming at p:$%x", address);
                simw_wscr_c (buf, 1);
                simw_refresh ();
                error = DSP_ERROR;
            }
        }
        
        /* go to the next data */
        address++;

        /* determine if we have already sent the data */

        /* if the address is the bottom half of a 16-word block,
           it is already sent. just go to the next block.
        */
        if (address % 16 > 7)
        {
            address = ((int)(address/16)+1)*16;
        }
    } while (address<=max_addr);  /* continue sending data for all valid addresses for
                                     min_addr < address < max_addr
                                  */
    return (error);
}

#endif


#if UNIX
static int
adm_write_flash (int device_index,
                 int command,
                 unsigned long min_addr,
                 unsigned long max_addr,
                 unsigned long *value)

{
    char protocol[4];
    unsigned long address;
    unsigned long data[2];

    char buf[128];
    
    int error = DSP_OK;
    

    protocol[0] = (char) 3;                    /* command count */
    protocol[1] = (char) command;	           /* command */

    /* for programming the x-memory */
    if ( command == PROGRAM_XFLASH )
    {
        address = min_addr;
        /* main data send loop for the X-memory */
        do {
            /* for each data word to be sent
               - check if the data @ address is non-zero
               - if zero go to the next data
               - if non-zero
                 - send the command
            	 - send the address
            	 - send the data
            */
            
            if ( value[address] != 0 )
            {
                /*set the address */
                protocol[2] = (unsigned) ((address >> 8) & 0xffl);  /* high address byte */
                protocol[3] = (unsigned) (address & 0xffl);         /*  low address byte */

                /* send command */ 
                if (ioctl (HOST_ADDRESS, MDSPCOMMAND, protocol))
                {
                    (void) sprintf( buf, "Unrecoverable communication error #1" );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    return (DSP_ERROR);
                }

                /* send data */
                if (write (HOST_ADDRESS, (char *) &value[address],
                           (int) (1l * sizeof (long))) == DSP_ERROR)
                {
                    (void) sprintf( buf, "Unrecoverable communication error #2" );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    return (DSP_ERROR);
                }

                /* sleep( 2 ); */

                do 
                {
                    /* this do loop was implemented as a workaround of a UNIX
                       driver bug, which immediatelly returns from the get_words
                       function calls if the command converter is still busy
                       waiting the end of send words command.
                    */
                    *data = 0xfefe;
                    
                    /* get the result status back */
                    if ( read ( HOST_ADDRESS, (char *) data,
                            (int) (1l * sizeof (long))) == DSP_ERROR)
                    {
                        (void) sprintf( buf, "Unrecoverable communication error #3" );
                        simw_wscr_c (buf, 1);
                        simw_refresh ();
                        return (DSP_ERROR);
                    }

                    /*
                    if ( *data!=0 && *data!=1 )
                    {
                        sleep( 1 );
                    }
                    */
                    
                } while (*data!=0 && *data!=1);

                /* wait for CC to complete command. */
                if ( error != DSP_ERROR ) 
                {
                    error = handshake (get_cc_num (device_index), TIMEOUT);
                }
                else 
                {
                    handshake(get_cc_num (device_index), TIMEOUT);
                }

                /* if the sent was unsuccessfull, set the error */
                if ( *data == 0l )
                {
                    (void) sprintf (buf, "Error programming at x:$%lx", address);
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    error = DSP_ERROR;
                }
            }

            /* go to the next data */
            address++;

            } while (address<max_addr);  /* continue sending data for all valid addresses for
                                            min_addr < address < max_addr
                                         */
        return ( error );
    }


    /* for programming the p-memory */

    /* we need to reset the address to the beginning a a block */
    address = (min_addr/16)*16;

    /* main data send loop */
    do 
    {
        /* for each data word to be sent
           - Check if the data @ address and data @ address+8 are non-zero
           - if zero, go to the next data
           - if non zero,
             - send the command
             - send the address
             - send the data pair
        */

        if (value[address] != 0 || value[address+8] != 0)   /* if at least one of the pair is non-zero */
        {
            data[0] = value[address];
            data[1] = value[address+8];
            
            /*set the address */
            protocol[2] = (unsigned) ((address >> 8) & 0xffl);  /* high address byte */
            protocol[3] = (unsigned) (address & 0xffl);	        /*  low address byte */
            
            /* send command */
            if (ioctl (HOST_ADDRESS, MDSPCOMMAND, protocol))
            {
                (void) sprintf( buf, "Unrecoverable communication error #4" );
                simw_wscr_c (buf, 1);
                simw_refresh ();
                return (DSP_ERROR);
            }

            /* send data */
            if (write (HOST_ADDRESS, (char *) data,
                       (int) (2l * sizeof (long))) == DSP_ERROR)
            {
                (void) sprintf( buf, "Unrecoverable communication error #5" );
                simw_wscr_c (buf, 1);
                simw_refresh ();
                return (DSP_ERROR);
            }

            /* sleep( 2 ); */
            

            do
            {
                /* this do loop was implemented as a workaround of a UNIX
                   driver bug, which immediatelly returns from the get_words
                   function calls if the command converter is still busy
                   waiting the end of send words command.
                */
                *data = 0xfefe;
                
                /* get the result status back */
                if ( read ( HOST_ADDRESS, (char *) data,
                            (int) (1l * sizeof (long))) == DSP_ERROR)
                {
                    (void) sprintf( buf, "Unrecoverable communication error #3" );
                    simw_wscr_c (buf, 1);
                    simw_refresh ();
                    return (DSP_ERROR);
                }

                /*
                if ( *data!=0 && *data!=1 )
                {
                    sleep( 1 );
                }
                */
                
            } while (*data!=0 && *data!=1);
            
            /* wait for CC to complete command. */
            if ( error != DSP_ERROR ) 
            {
                error = handshake (get_cc_num (device_index), TIMEOUT);
            }
            else
            {
                handshake (get_cc_num (device_index), TIMEOUT);
            }
            
            /* if the sent was unsuccessfull, set the error */
            if ( *data == 0l )
            {
                (void) sprintf (buf, "Error programming at p:$%lx", address);
                simw_wscr_c (buf, 1);
                simw_refresh ();
                error = DSP_ERROR;
            }
        }

        /* go to the next data */
        address++;

        /* determine if we have already sent the data */

        /* if the address is the bottom half of a 16-word block,
           it is already sent. just go to the next block.
        */
        if (address % 16 > 7)
        {
            address = ((int)(address/16)+1)*16;
        }
        
    } while (address<=max_addr);  /* continue sending data for all valid addresses for
                                     min_addr < address < max_addr
                                  */
    return (error);
}

#endif


#if macintosh || MSDOS
static int
adm_erase_flash (int device_index,
                 int command,
                 unsigned long blocksize,
                 unsigned long address)
{
    unsigned int index;
    unsigned int protocol[3];
    
    int error = DSP_OK;
    
    protocol[0] = command;                              /* command */
    protocol[1] = (unsigned) ((address >> 8) & 0xffl);	/* high address byte */
    protocol[2] = (unsigned) (address & 0xffl); 	/* low address byte */
    

    /* send the command */
    for (index = 0; index < sizeof (protocol) / sizeof (unsigned int); index++)
    {
        if (send_byte (device_index, protocol[index]))
        {
            return (DSP_ERROR);
        }
    }

    /* send the buffer size */
    if (send_words (device_index, 1l, &blocksize))
    {
        return (DSP_ERROR);
    }
    
    /* wait for CC to complete command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);
    
    /* if there is an error, return error */
    if (error != DSP_OK)
    {
        return (error);
    }
    
    return (DSP_OK);
}

#endif


#if UNIX
static int
adm_erase_flash (int device_index,
                 int command,
                 unsigned long blocksize,
                 unsigned long address)

{
    char protocol[10];
    unsigned long result;
    
    int  error = DSP_OK;    

                    
    protocol[0] = (char) 5;                              /* command count */
    protocol[1] = (char) command;	                 /* command */
    protocol[2] = (unsigned) ((address >> 8) & 0xffl);	 /* high address byte */
    protocol[3] = (unsigned) (address & 0xffl);	         /* low address byte */
    protocol[4] = (unsigned) ((blocksize >> 8) & 0xffl); /* high size byte */
    protocol[5] = (unsigned) (blocksize & 0xffl);        /* low size byte */

    /* send command */
    if (ioctl (HOST_ADDRESS, MDSPCOMMAND, protocol))
    {
        return (DSP_ERROR);
    }
    
    /* wait for CC to complete command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    /* if the sent was unsuccessfull, set the error */
    if ( result == 0L )
    {
        return (DSP_ERROR);
    }

    return (error);
}

#endif

#if macintosh || MSDOS
static int
send_byte (int device_index,
	       unsigned value)
{
#if WIN_NT

	BOOL			      IoctlResult;

	PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  InputBuffer[sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)];    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_SEND_PORT_DATA;
    ULONG				  DataLength = sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR);

    DWORD                 temp;

	pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

	pIOBuffer->Params.NoOfItems        = 1;			// number of items to write
 
	pIOBuffer->Params.CCNo             = (UCHAR)get_cc_num (device_index);

	pIOBuffer->Data.CharData[0] = (UCHAR)value;

    temp = GetTickCount();

	IoctlResult = DeviceIoControl( hndDevice,
                                   IoctlCode,
                                   InputBuffer,
                                   DataLength,
                                   NULL,
                                   0,
                                   &ReturnedLength,
                                   NULL );

    temp = GetTickCount()-temp;

    if ( !IoctlResult )
    {
        return (DSP_ERROR);
    }

#else

    int address;
    int cc_num;

    cc_num = get_cc_num (device_index);

    address = (cc_num << 4) & 0x70;

    /* set up data */
    output (DATA, value);

    /* select device address */
    output (CTRL1, address);

    /* set HST_REQ high */
    output (CTRL1, (address | HST_REQ));

    /* wait for ADM_ACK to go high */
    if (flag_test (DSP_HIGH, ADM_ACK) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    /* set HST_REQ low */
    output (CTRL1, address);

    /* wait for ADM_ACK to go low */
    if (flag_test (DSP_LOW, ADM_ACK) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    /* clear data byte to 0 */
    output (DATA, 0);
#endif

    return (DSP_OK);
}

#endif

#if UNIX
static int
send_byte (int device_index,
	   unsigned value)
{
    char data[3];

    data[0] = (char) value;

    if (ioctl (HOST_ADDRESS, MDSPWBYTE, data))
    {
	return (DSP_ERROR);
    }

    else
    {
	return (DSP_OK);
    }
}

#endif

#if macintosh || MSDOS
static int
send_words (int device_index,
            unsigned long count,
            unsigned long *value)
{
#if WIN_NT

	BOOL			      IoctlResult;

	PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  *InputBuffer;    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_SEND_PORT_DATA;
    ULONG				  DataLength = sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*count*DSP_NUMBYTES;
    LONG                  i, j;


    // allocate buffer for the send buffer
    InputBuffer = (UCHAR*)malloc( DataLength );

    if ( !InputBuffer )
    {
        return (DSP_ERROR);
    }

	pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

	pIOBuffer->Params.NoOfItems        = count*DSP_NUMBYTES;			// number of bytes to write
 
	pIOBuffer->Params.CCNo             = (UCHAR)get_cc_num (device_index);

    // pack the data into the send buffer
    for (i=0; i<count; i++)
    {
        for (j=DSP_NUMBYTES-1; j>=0; j--)
        {
	        pIOBuffer->Data.CharData[i*DSP_NUMBYTES+(DSP_NUMBYTES-1)-j] = (UCHAR)((value[i] >> (j * 8)) & 0xffl);
        }
    }

    // send the data
	IoctlResult = DeviceIoControl( hndDevice,
                                   IoctlCode,
                                   InputBuffer,
                                   DataLength,
                                   NULL,
                                   0,
                                   &ReturnedLength,
                                   NULL );

    // dealloc the memory
    free( InputBuffer );

    if ( !IoctlResult )
    {
        return (DSP_ERROR);
    }

#else

    unsigned long byte;
    unsigned long i;
    int j;

    for (i = 0; i < count; i++)
    {
        for (j = DSP_NUMBYTES - 1; j >= 0; j--)
        {
            byte = (value[i] >> (j * 8)) & 0xffl;

            if (send_byte (device_index, (int) byte))
            {
                return (DSP_ERROR);
            }
        }
    }
#endif

    return (DSP_OK);
}

#endif

#if UNIX
static int
send_words (int device_index,
	    unsigned long count,
	    unsigned long *value)
{
    if (write (HOST_ADDRESS, (char *) value,
               (int) (count * sizeof (long))) == DSP_ERROR)
    {
        return (DSP_ERROR);
    }

    else
    {
        return (DSP_OK);
    }
}

#endif

#if macintosh || MSDOS
static int
send_cc_words (int device_index,
               unsigned long count,
               unsigned long *value)
{
#if WIN_NT

	BOOL			      IoctlResult;

	PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  *InputBuffer;    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_SEND_PORT_DATA;
    ULONG				  DataLength = sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*count*3;
    LONG                  i;


    // allocate buffer for the send buffer
    InputBuffer = (UCHAR*)malloc( DataLength );

    if ( !InputBuffer )
    {
        return (DSP_ERROR);
    }

	pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

	pIOBuffer->Params.NoOfItems        = count*3;			// number of bytes to write
 
	pIOBuffer->Params.CCNo             = (UCHAR)get_cc_num (device_index);

    // pack the data into the send buffer
    for (i=0; i<count; i++)
    {
        pIOBuffer->Data.CharData[i*3]   = (UCHAR)((value[i] >> 16) & 0xff);
        pIOBuffer->Data.CharData[i*3+1] = (UCHAR)((value[i] >> 8) & 0xff);
        pIOBuffer->Data.CharData[i*3+2] = (UCHAR)(value[i] & 0xff);
    }

    // send the data
	IoctlResult = DeviceIoControl( hndDevice,
                                   IoctlCode,
                                   InputBuffer,
                                   DataLength,
                                   NULL,
                                   0,
                                   &ReturnedLength,
                                   NULL );

    // dealloc the memory
    free( InputBuffer );

    if ( !IoctlResult )
    {
        return (DSP_ERROR);
    }


#else

    unsigned long byte, i;

    for (i = 0; i < count; i++)
    {
        /* send high byte */
        byte = (value[i] >> 16) & 0xffl;

        if (send_byte (device_index, (int) byte))
        {
            return (DSP_ERROR);
        }

        /* send middle byte */
        byte = (value[i] >> 8) & 0xffl;

        if (send_byte (device_index, (int) byte))
        {
            return (DSP_ERROR);
        }

        /* send low byte */
        byte = (value[i] & 0xffl);

        if (send_byte (device_index, (int) byte))
        {
            return (DSP_ERROR);
        }
    }

#endif

    return (DSP_OK);
}

#endif

#if UNIX
static int
send_cc_words (int device_index,
	       unsigned long count,
	       unsigned long *value)
{
    unsigned long i;
    int byte_count;
    char word[4];

    for (i = 0; i < count; i++)
    {
        word[0] = (char) ((value[i] >> 16) & 0xffl); /* high byte */
        word[1] = (char) ((value[i] >> 8) & 0xffl);  /* middle byte */
        word[2] = (char) (value[i] & 0xffl);	     /* low byte */

        for (byte_count = 0; byte_count < 3; byte_count++)
        {
            if (ioctl (HOST_ADDRESS, MDSPWBYTE, &word[byte_count]))
            {
                return (DSP_ERROR);
            }
        }
    }

    return (DSP_OK);
}

#endif

#if macintosh || MSDOS
static int
get_words (int device_index,
           unsigned long count,
           unsigned long *value)
{
    int cc_num;

#if WIN_NT

	BOOL			      IoctlResult;

	PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  InputBuffer[sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*2];    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_GET_PORT_DATA;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

    pIOBuffer->Params.NoOfItems        = count;			// number of items to write
 
    pIOBuffer->Params.CCNo             = (UCHAR)cc_num;

    pIOBuffer->Params.BytesPerItem     = DSP_NUMBYTES;

    IoctlResult = DeviceIoControl( hndDevice,
                                   IoctlCode,
                                   InputBuffer,
                                   sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*2,
                                   value,
                                   sizeof(ULONG)*count,
                                   &ReturnedLength,
                                   NULL );
    if ( !IoctlResult )
    {
        return (DSP_ERROR);
    }

#else

    int flag;
    int byte_count;
    unsigned long word_count;
    unsigned long byte;
    unsigned long word;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    for (word_count = 0; word_count < count; word_count++)
    {
        word = 0l;

        for (byte_count = 0; byte_count < DSP_NUMBYTES; byte_count++)
        {
            /* wait for ADM_REQ to go high */
            if (flag_test (DSP_HIGH, ADM_REQ) == DSP_ERROR)
            {
                return (DSP_ERROR);
            }

            /* set HST_ACK high */
            flag = ((cc_num << 4) | HST_ACK);
            output (CTRL1, flag);

            /* get byte */
            byte = (unsigned long) input (DATA);

            word = word << 8;
            word |= (byte & 0xff);

            /* wait for ADM_REQ to go low */
            if (flag_test (DSP_LOW, ADM_REQ) == DSP_ERROR)
            {
                return (DSP_ERROR);
            }

            /* set HST_ACK low */
            output (CTRL1, (cc_num << 4) & 0x70);
        }

	    value[word_count] = word;
    }

#endif

    return (DSP_OK);
}

#endif

#if UNIX
static int
get_words (int device_index,
	   unsigned long count,
	   unsigned long *value)
{

    if (read (HOST_ADDRESS, (char *) value,
              (int) (count * sizeof (long))) == DSP_ERROR)
    {
	return (DSP_ERROR);
    }

    else
    {
	return (DSP_OK);
    }
}

#endif

#if macintosh || MSDOS
static int
get_cc_words (int device_index,
    	      unsigned long count,
	          unsigned long *value)
{
    int cc_num;
#if WIN_NT

	BOOL			      IoctlResult;

	PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  InputBuffer[sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*2];    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_GET_PORT_DATA;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);

    pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

    pIOBuffer->Params.NoOfItems        = count;			// number of items to write
 
    pIOBuffer->Params.CCNo             = (UCHAR)cc_num;

    pIOBuffer->Params.BytesPerItem     = 3;

    IoctlResult = DeviceIoControl( hndDevice,
                                   IoctlCode,
                                   InputBuffer,
                                   sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*2,
                                   value,
                                   sizeof(ULONG)*count,
                                   &ReturnedLength,
                                   NULL );
    if ( !IoctlResult )
    {
        return (DSP_ERROR);
    }

#else

    int flag;
    int byte_count;
    unsigned long word_count;
    unsigned long byte;
    unsigned long word;

    cc_num = get_cc_num (device_index);
    select_cc (cc_num);
    
    for (word_count = 0; word_count < count; word_count++)
    {
        word = 0l;

        for (byte_count = 0; byte_count < 3; byte_count++)
        {
            /* wait for ADM_REQ to go high */
            if (flag_test (DSP_HIGH, ADM_REQ) == DSP_ERROR)
            {
                return (DSP_ERROR);
            }

            /* set HST_ACK high */
            flag = ((cc_num << 4) | HST_ACK);
            output (CTRL1, flag);

            /* get byte */
            byte = (unsigned long) input (DATA);

            word = word << 8;
            word |= (byte & 0xff);

            /* wait for ADM_REQ to go low */
            if (flag_test (DSP_LOW, ADM_REQ) == DSP_ERROR)
            {
                return (DSP_ERROR);
            }

            /* set HST_ACK low */
            output (CTRL1, (cc_num << 4) & 0x70);
        }

        value[word_count] = word;
    }

#endif

    return (DSP_OK);
}

#endif

#if UNIX
static int
get_cc_words (int device_index,
	      unsigned long count,
	      unsigned long *value)
{
    char byte;
    int byte_count;
    unsigned long word;
    unsigned long word_count;

    for (word_count = 0; word_count < count; word_count++)
    {
	word = 0l;

	/* get 3 bytes from 24 bit CC */
	for (byte_count = 0; byte_count < 3; byte_count++)
	{
	    if (ioctl (HOST_ADDRESS, MDSPRBYTE, &byte))
            {
		return (DSP_ERROR);
            }

	    word = word << 8;
	    word |= (byte & 0xff);
	}

	value[word_count] = word;
    }

    return (DSP_OK);
}

#endif

static int
flag_test (int level,
	   int flag)
{
    int loop_count;
    time_t curtm;
    time_t endtime;

    /* Check for the desired level several times before we make an expensive
       call to time() */
    for (loop_count = 0; loop_count < DSP_MAX_ATTEMPTS; loop_count++)
    {
	/* check to see if we got desired signal */
	if (((level == 1) && (input (CTRL1) & flag)) ||
	    ((level == 0) && !(input (CTRL1) & flag)))
        {
	    return (DSP_OK);
        }
    }

    /* save the current time */
    (void) time (&curtm);
    for (endtime = curtm + TIMEOUT; curtm <= endtime; (void) time (&curtm))
    {
	/* check to see if we got desired signal */
	if (((level == 1) && (input (CTRL1) & flag)) ||
	    ((level == 0) && !(input (CTRL1) & flag)))
        {
	    return (DSP_OK);
        }
    }

    /* indicate that flag_test() timed out */
    return (DSP_ERROR);
}

static int
select_device (int device_index)
{
    static int old_cc_num = -1;
    static int old_tms_num = -1;
    static int old_chain_pos = -1;
    static int old_chain_length = 0;
    int tms_num;
    int chain_pos;
    int cc_num;
    int chain_length;


    cc_num = get_cc_num (device_index);
    tms_num = get_tms_num (device_index);
    chain_pos = get_chain_pos (device_index);

    if (get_cc_has_been_configured (cc_num) == FALSE)
    {
        if (configure_cc (cc_num) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }
        if (set_active_device (device_index) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }
    }

    chain_length = dspd_get_tms_chain_length (cc_num, tms_num);
    
    
    /* If device info has changed, or we are talking to a new device */
    if (tms_num != old_tms_num || chain_pos != old_chain_pos ||
        cc_num != old_cc_num || chain_length != old_chain_length)
    {
        /* Store for future reference */
        old_tms_num = tms_num;
        old_chain_pos = chain_pos;
        old_cc_num = cc_num;
        old_chain_length = chain_length;

        if (set_active_device (device_index) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }
    }
    
    /* Select the command converter */
    select_cc (cc_num);
    
    return (DSP_OK);
}


static void
deselect_device (void)
{
    output (CTRL1, 0);
}


static void
select_cc (int cc_num)
{
#if UNIX
    char cc[2];
    cc[0] = cc_num;

    /* select command converter */
    (void) ioctl (HOST_ADDRESS, MDSPDEVICE, cc);
#else
    /* select command converter */
    output (CTRL1, (cc_num << 4) & 0x70);
#endif

    return;
}

static int
input (int port)
{

#if MSDOS

#if WIN_NT
    ULONG   PortNumber;         // Buffer sent to the driver (Port #).
    UCHAR   DataBuffer;         // Buffer received from driver (Data).
    DWORD   ReturnedLength;     // Number of bytes returned

    LONG    IoctlCode  = IOCTL_MDSP_READ_PORT_UCHAR;
    ULONG   DataLength = sizeof(DataBuffer);

    PortNumber = port;         // Get the port number to be read

    DeviceIoControl(hndDevice, IoctlCode, &PortNumber, sizeof(PortNumber), &DataBuffer, DataLength, &ReturnedLength, NULL);

    /* Here I should have checked
       the return value from DeviceIoControl + ReturnedLength
       Unfortunatelly, the current software architecture does not let me to return any error codes.
       I have to retrn the contenets of the DataBuffer without any error checkes
    */
	return ((int)DataBuffer);
#else
    return (inp (HOST_ADDRESS + port));
#endif

#elif macintosh
    return (peekb ((char *) (HOST_ADDRESS + port)) & 0xff);

#elif UNIX
    char address[2];

    address[0] = (char) port;

    (void) ioctl (HOST_ADDRESS, MDSPIOR, address);

    return ((int) address[0]);
#endif
}


#if MSDOS
static void
output (int port, int value)
{
#if WIN_NT

    MDSPPORT_WRITE_INPUT InputBuffer;    // Input buffer for DeviceIoControl
    ULONG                ReturnedLength; // Number of bytes returned in output buffer
    LONG                 IoctlCode = IOCTL_MDSP_WRITE_PORT_UCHAR;
    ULONG				 DataLength = offsetof(MDSPPORT_WRITE_INPUT, CharData) + sizeof(InputBuffer.CharData);

	InputBuffer.PortNumber = port;
	InputBuffer.CharData   = (UCHAR)value;

	DeviceIoControl(hndDevice, IoctlCode, &InputBuffer, DataLength, NULL, 0, &ReturnedLength, NULL );

#else
    outp ((HOST_ADDRESS + port), value);
#endif

    return;
}

#endif

#if UNIX
static void
output (int port, int value)
{
    char data[2];

    data[0] = (char) port;
    data[1] = (char) value;

    (void) ioctl (HOST_ADDRESS, MDSPIOW, data);

    return;
}

#endif

static int
handshake (int cc_num, int timeout)
{
#if WIN_NT

    PMDSP_TRANSFER_BUFFER pIOBuffer;
    UCHAR				  InputBuffer[sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*2];    // Input buffer for DeviceIoControl
    ULONG                 ReturnedLength; // Number of bytes returned in output buffer
    LONG                  IoctlCode = IOCTL_MDSP_HAND_SHAKE;
    ULONG                 DataLength = sizeof(MDSP_TRANSFER_PARAMS)+sizeof(UCHAR)*2;
    BOOL                  Status;


    pIOBuffer = (PMDSP_TRANSFER_BUFFER)InputBuffer;

	pIOBuffer->Params.CCNo = cc_num;

	Status = DeviceIoControl( hndDevice,
                              IoctlCode,
                              InputBuffer,
                              DataLength,
                              NULL,
                              0,
                              &ReturnedLength,
                              NULL );

    if ( Status )
    {
        return (DSP_OK);
    }
    else
    {
        return (DSP_ERROR);
    }

#else

    int loop_count;
    int error;
    time_t curtm;
    time_t endtime;
    int device_address;


    device_address = (cc_num << 4) & 0x70;

    /* enable CC latch */
    output (CTRL1, device_address | HST_ACK);

    /* check for ADM_INT several times before we make an expensive call to
       time() */
    for (loop_count = 0; loop_count < DSP_MAX_ATTEMPTS; loop_count++)
    {
        if (input (CTRL1) & ADM_INT)
        {
            break;
        }
    }

    if (loop_count == DSP_MAX_ATTEMPTS)
    {
        /* get current time */
        (void) time (&curtm);
        for (endtime = curtm + timeout; curtm <= endtime; (void) time (&curtm))
        {
            if (input (CTRL1) & ADM_INT)
            {
                break;
            }
        }

        if (curtm > endtime)
        {
            return (DSP_ERROR);
        }
    }

    /* get result code from CC */
    error = input (DATA);

    /* return 0, not return value for now */
    error = DSP_OK;

    /* acknowledge interrupt received 	 */
    output (CTRL2, INT_ACK);

    if (flag_test (DSP_LOW, ADM_INT) == DSP_ERROR)
    {
        error = DSP_ERROR;
    }

    /* de-assert interrupt acknowledge */
    output (CTRL2, 0);

    return (error);

#endif
}

static void
reverse_array (unsigned long *array, int count)
{
    int i;
    int j;
    int k;
    unsigned long temp;

    k = count - 1;
    
    for (i = 0; i < (count / 2); i++)
    {

        j = k - i;

        temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    return;
}

static int
match_idx (char *str, char **array, int arrsize)
{
    int i;
    int result;

    /* Returns index of string match in array, or -1 if no match */
    for (i = 0, result = 1;
         i < arrsize && ((result = strcmp_i (str, array[i])) > 0); i++);

    return ((i == arrsize || result) ? -1 : i);
}

/* record headers for object files */
static
char *object[] =
{
    "blockdata",
    "comment",
    "data",
    "end",
    "start",
    "symbol"
};

static unsigned long membuf[CC_MEM_SIZE]; /* Too big to put on the stack */

static int
load_cc_monitor (int dev_index, char *loadfn)
{
    int var1;
    int i;
    int ok;
    static int obsiz = sizeof (object) / sizeof (char *);
    unsigned long hexdata[2];
    int addincr;
    unsigned long blksiz;
    unsigned long address;
    FILE *loadfile;
    char buf[92];

    int mi;
    int pmem;
    int lmem;
    unsigned long high_address = 0l;
    unsigned long low_address = 0xffffl;
    unsigned long xfer_address = 0l;

    /* Initialize memory buffer */
    for (mi = 0; mi < CC_MEM_SIZE; mi++)
    {
        membuf[mi] = 0l;
    }

    if (!(loadfile = fopen (loadfn, "r")))
    {
	return (0);
    }

    i = fscanf (loadfile, "%90s", buf);

    ok = (*buf == '_') ? 1 : 0;	/* check for start record */

    for (var1 = -1; ok && (i != EOF);)
    {
	if (*buf == '_')
	{			/* test for new record type */
	    var1 = match_idx (buf + 1, object, obsiz);
	}
	switch (var1)
	{
	case 3:		/* end */
	    i = fscanf (loadfile, "%90s", buf);
	    if (i != EOF)
	    {
		if (sscanf (buf, "%lx", hexdata))
		{
		    hexdata[1] = 0;

                    xfer_address = hexdata[0];

                    if (xfer_address > CC_MAX_ADDR)
                    {
                        ok = FALSE;
                    }
		}
	    }
	    break;
	case 2:		/* data */
	    if (fscanf (loadfile, "%90s", buf) == EOF)
	    {
		ok = FALSE;
		break;
	    }

            pmem = lmem = FALSE;
            addincr = 1;
            
            if (buf[0] == 'p' || buf[0] == 'P')
            {
                pmem = TRUE;
            }
            else if (buf[0] == 'l' || buf[0] == 'L')
            {
                lmem = TRUE;
                addincr = 2;
            }
            
	    if (fscanf (loadfile, "%90s", buf) == EOF)
	    {
		ok = FALSE;
		break;
	    }
	    if (!sscanf (buf, "%lx", &address))
	    {
		ok = FALSE;
		break;
	    }

            while ((i = fscanf (loadfile, "%90s", buf)) != EOF && *buf != '_')
            {
                if (lmem)
                {
                    if (!sscanf (buf, "%lx", &hexdata[1]))
                    {
                        ok = FALSE;
                        break;
                    }
                    if (fscanf (loadfile, "%90s", buf) == EOF)
                    {
                        ok = FALSE;
                        break;
                    }
                }

                if (!sscanf (buf, "%lx", hexdata))
                {
                    ok = FALSE;
                    break;
                }

                /* Only write out p memory */
                if (pmem)
                {
                    if (address > CC_MAX_ADDR)
                    {
                        ok = FALSE;
                        break;
                    }
                    
                    membuf[address] = hexdata[0];

                    if (address > high_address)
                    {
                        high_address = address;
                    }

                    if (address < low_address)
                    {
                        low_address = address;
                    }
                }

                address += addincr;
            }
	    break;
	case 0:		/* blockdata */
	    if (fscanf (loadfile, "%90s", buf) == EOF)
	    {
		ok = FALSE;
		break;
	    }

            pmem = lmem = FALSE;
            addincr = 1;
            
            if (buf[0] == 'p' || buf[0] == 'P')
            {
                pmem = TRUE;
            }
            else if (buf[0] == 'l' || buf[0] == 'L')
            {
                lmem = TRUE;
                addincr = 2;
            }
            
	    if (fscanf (loadfile, "%90s", buf) == EOF)
	    {
		ok = FALSE;
		break;
	    }

	    if (!sscanf (buf, "%lx", &address))
	    {
		ok = FALSE;
		break;
	    }

	    if (fscanf (loadfile, "%90s", buf) == EOF)
	    {
		ok = FALSE;
		break;
	    }
	    if (!sscanf (buf, "%lx", &blksiz))
	    {
		ok = FALSE;
		break;
	    }

	    if (lmem)
	    {
		if (!sscanf (buf, "%lx", &hexdata[1]))
		{
		    ok = FALSE;
		    break;
		}
		if (fscanf (loadfile, "%90s", buf) == EOF)
		{
		    ok = FALSE;
		    break;
		}
	    }
	    if (fscanf (loadfile, "%90s", buf) == EOF)
	    {
		ok = FALSE;
		break;
	    }
	    if (!sscanf (buf, "%lx", hexdata))
	    {
		ok = FALSE;
		break;
	    }

            if (pmem)
            {
                unsigned long last_block_address = address + blksiz;
                
                if (last_block_address > CC_MAX_ADDR)
                {
                    ok = FALSE;
                    break;
                }
                
                for (i = 0; i < blksiz; i++)
                {
                    membuf[address + i] = hexdata[0];
                }

                if (last_block_address > high_address)
                {
                    high_address = last_block_address;
                }

                if (address < low_address)
                {
                    low_address = address;
                }
                
                
            }
            
	default:/* start=4, comment=1, symbol=5  continue to next field */
	    while (((i = fscanf (loadfile, "%90s", buf)) != EOF) &&
                   (*buf != '_'));
	    break;
	case -1:
	    ok = FALSE;
	    break;
	}			/* end of switch */
    }				/* end of for */

    (void) fclose (loadfile);

    if (ok)
    {
        ok = parallel_cc_load (dev_index, low_address,
                               high_address - low_address + 1,
                               xfer_address, membuf);
    }

    return (ok);
}


static void
serial_cc_load (int device_index, unsigned long address,
                unsigned long word_count, unsigned long *data)
{
    int temp;
    int i;
    int j;


    select_cc (get_cc_num (device_index));
    
    temp = (int) word_count;	/* send word count */

    for (i = 0; i < 3; i++)
    {
        serial_output (temp & 0xff);
        temp >>= 8;
    }

    temp = (int) address;	/* send load address */

    for (i = 0; i < 3; i++)
    {
        serial_output (temp & 0xff);
        temp >>= 8;
    }

    for (j = 0; j < word_count; j++) /* for each memory location in turn */
    {
        temp = (int) data[j];	/* send next word... */

        for (i = 0; i < 3; i++)	/* a byte at a time  */
        {
            serial_output (temp & 0xff);
            temp >>= 8;
        }
    }

    return;
}

static int
parallel_cc_load (int dev_index, unsigned long address,
                  unsigned long word_count, unsigned long start_addr,
                  unsigned long *data)
{
    int cc_num;
    int error;
    
    cc_num = get_cc_num (dev_index);
    select_cc (cc_num);
    
    /* send load address */
    error = send_byte (dev_index, (unsigned) (address & 0xffl));

    if (!error)
    {
        error = send_byte (dev_index, (unsigned) ((address >> 8) & 0xffl));
    }

    if (!error)
    {
        /* send word count */
        error = send_byte (dev_index, (unsigned) (word_count & 0xffl));
    }

    if (!error)
    {
        error = send_byte (dev_index, (unsigned) ((word_count >> 8) & 0xffl));
    }

    if (!error)
    {
        int i;
        
        /* while working OK... */
        for (i = 0; i < word_count && !error; i++)
        {
            unsigned int temp;
            
            temp = (unsigned int) data[address + i];	/* get next word */

            /* send low byte */
            error = send_byte (dev_index, temp & 0xff);

            if (!error)	/* if that worked... */
            {
                temp >>= 8;	/*... send mid byte  */
                error = send_byte (dev_index, temp & 0xff);
            }
            if (!error)	/* if that worked... */
            {
                temp >>= 8;	/*... send high byte */
                error = send_byte (dev_index, temp & 0xff);
            }
        }

        output (CTRL2, INT_ACK);	/* load finished */
        output (CTRL1, (cc_num << 4) & 0x70);
    }

    if (!error)
    {
        /* send xfer address */
        error = send_byte (dev_index, (unsigned) (start_addr & 0xffl));
    }

    output (CTRL2, 0);	/* deassert INT_ACK */
        
    if (!error)
    {
        error = send_byte (dev_index, (unsigned) ((start_addr >> 8) & 0xffl));
    }

    return (!error);
}


static void
serial_output (int out_char)
{
    int out_frame;

    out_frame = (out_char + 0x100) << 1;

    while (out_frame)
    {
	sclock_out (out_frame & LSB);
	out_frame = out_frame >> 1;
    }

    return;
}

static void
sclock_out (int out_bit)
{
    int i;

    int bit = out_bit ? STX : 0;
    int bit_n_clock = bit | SCK;

    for (i = 0; i < 16; i++)
    {
	output (CTRL2, bit_n_clock);	/* present output bit */
	output (CTRL2, bit);	/* cycle clock */
    }

    return;
}

static int
strcmp_i (char *a, char *b)
{
    char c1;
    char c2;

    do
    {
	c1 = *a++;
	c2 = *b++;
	if (c1 != c2)
	{
	    if (isupper (c1))
            {
		c1 = tolower (c1);
            }
            
	    if (isupper (c2))
            {
		c2 = tolower (c2);
            }
	}
    }

    while (c1 && c2 && (c1 == c2));

    return ((int) (c1 - c2));
}

int
dspd_is_cc_already_reset (int device_index)
{
    return (get_cc_has_been_reset (get_cc_num (device_index)));
}

static int
get_jtag_count (int cc_num, int tms_chain)
{
    int i;
    int device_index = 0;
    unsigned long count;

    for (i = 0; i < (sizeof (dev_info) / sizeof (struct dev_config)); i++)
    {
        if (get_cc_num (i) == cc_num)
        {
            device_index = i;
        }
    }

    select_cc (cc_num);

    if (send_byte (device_index, JTAG_COUNT) ||
        send_byte (device_index, tms_chain))
    {
        deselect_device ();
        return (DSP_ERROR);
    }
        
    if (get_words (device_index, 1l, &count))
    {
        return (DSP_ERROR);
    }
    
    /* wait for CC to complete the command. */
    if (handshake (cc_num, TIMEOUT))
    {
        return (DSP_ERROR);
    }
    
    return ((int) count);
}


static int
configure_cc (int cc_num)
{
    if (get_cc_type (cc_num) == DSP_NEW_CC)
    {
        int count;

        count = get_jtag_count (cc_num, 0);

        if (count == DSP_ERROR)
        {
            return (DSP_ERROR);
        }

        set_tms0_count (cc_num, count);
        
        count = get_jtag_count (cc_num, 1);

        if (count == DSP_ERROR)
        {
            return (DSP_ERROR);
        }
            
        set_tms1_count (cc_num, count);
    }

    set_cc_has_been_configured (cc_num, TRUE);

    return (DSP_OK);
}

static int
set_active_device (int device_index)
{
    int cc_num;
    int tms_chain;
    int chain_pos;

    cc_num = get_cc_num (device_index);
    tms_chain = get_tms_num (device_index);
    chain_pos = get_chain_pos (device_index);
    
    if (get_cc_type (cc_num) == DSP_NEW_CC)
    {
        select_cc (cc_num);
    
        if (send_byte (device_index, SET_ACTIVE_DEVICE) ||
            send_byte (device_index, chain_pos + 1) ||
            send_byte (device_index, tms_chain))
        {
            deselect_device ();
            return (DSP_ERROR);
        }
        
        /* wait for CC to complete the command. */
        if (handshake (cc_num, TIMEOUT))
        {
            return (DSP_ERROR);
        }
    }
    else
    {
        unsigned long flags;
        
        
        /* Set tms chain number and jtag type bit */

        /* read current flag settings */
        if (dspd_cc_read_flag (device_index, DEVICE_FLAGS,
                               &flags) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }

        /* Clear the tms bits, set correct tms bit, set jtag type bit */
        flags = (flags & ~(0x30l)) | (tms_chain ? 0x20l : 0x10l) | 0x8l;
    
        if (dspd_cc_write_flag (device_index, DEVICE_FLAGS,
                                flags) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }

        /* set max chain position of current tms chain */
        if (dspd_cc_write_flag (device_index, DEVICE_COUNT, 0x1l) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }

        /* set chain position of active device */
        if (dspd_cc_write_flag (device_index, DEVICE_ACTIVE,
                                (0x1l << chain_pos)) == DSP_ERROR)
        {
            return (DSP_ERROR);
        }

    }
    
    return (DSP_OK);
}

int
dspd_set_ir_length (int cc_num, int tms_num, int chain_pos, int ir_length)
{
    int i;
    int device_index = 0;
    int error;

    /* Get dummy device_index for use with send_byte() */
    for (i = 0; i < (sizeof (dev_info) / sizeof (struct dev_config)); i++)
    {
        if (get_cc_num (i) == cc_num)
        {
            device_index = i;
        }
    }

    select_cc (cc_num);

    /* send command */
    if (send_byte (device_index, SET_JTAG_IR_LENGTH) ||
	send_byte (device_index, tms_num) ||
	send_byte (device_index, chain_pos + 1) ||
	send_byte (device_index, ir_length) ||
	send_byte (device_index, 1)) /* 1 = NOT_DSP */
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (cc_num, TIMEOUT);

    deselect_device ();

    return (error);
}

int
dspd_56811_interrupt_in_debug_mode_workaround (int device_index,
                                               unsigned long *sr)
{
    int error;

    select_device (device_index);

    /* send command */
    if (send_byte (device_index, INT_FIX_56811))
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    /* get data */
    else if (get_words (device_index, 1l, sr))
    {
	deselect_device ();
	return (DSP_ERROR);
    }

    /* wait for CC to complete the command. */
    error = handshake (get_cc_num (device_index), TIMEOUT);

    deselect_device ();

    return (error);
}




