/*
* $Id: part.c,v 1.24 2003/08/19 08:42:20 telka Exp $
*
* Copyright (C) 2002 ETC s.r.o.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by Marcel Telka <marcel@telka.sk>, 2002.
*
*/
#include "sysdep.h"
#include <stdlib.h>
#include <string.h>
#include "part.h"
/* part */
part_t *
part_alloc( const tap_register *id )
{
part_t *p = malloc( sizeof *p );
if (!p)
return NULL;
p->id = register_duplicate( id );
p->manufacturer[0] = '\0';
p->part[0] = '\0';
p->stepping[0] = '\0';
p->signals = NULL;
p->instruction_length = 0;
p->instructions = NULL;
p->active_instruction = NULL;
p->data_registers = NULL;
p->boundary_length = 0;
p->bsbits = NULL;
return p;
}
void
part_free( part_t *p )
{
int i;
if (!p)
return;
/* id */
free( p->id );
/* signals */
while (p->signals) {
signal_t *s = p->signals;
p->signals = s->next;
signal_free( s );
}
/* instructions */
while (p->instructions) {
instruction *i = p->instructions;
p->instructions = i->next;
instruction_free( i );
}
/* data registers */
while (p->data_registers) {
data_register *dr = p->data_registers;
p->data_registers = dr->next;
data_register_free( dr );
}
/* bsbits */
for (i = 0; i < p->boundary_length; i++)
bsbit_free( p->bsbits[i] );
free( p->bsbits );
free( p );
}
instruction *
part_find_instruction( part_t *p, const char *iname )
{
instruction *i;
if (!p || !iname)
return NULL;
i = p->instructions;
while (i) {
if (strcmp( iname, i->name ) == 0)
break;
i = i->next;
}
return i;
}
data_register *
part_find_data_register( part_t *p, const char *drname )
{
data_register *dr;
if (!p || !drname)
return NULL;
dr = p->data_registers;
while (dr) {
if (strcmp( drname, dr->name ) == 0)
break;
dr = dr->next;
}
return dr;
}
signal_t *
part_find_signal( part_t *p, const char *signalname )
{
signal_t *s;
if (!p || !signalname)
return NULL;
s = p->signals;
while (s) {
if (strcmp( signalname, s->name ) == 0)
break;
s = s->next;
}
return s;
}
void
part_set_instruction( part_t *p, const char *iname )
{
if (p)
p->active_instruction = part_find_instruction( p, iname );
}
void
part_set_signal( part_t *p, signal_t *s, int out, int val )
{
data_register *bsr;
if (!p || !s)
return;
/* search for Boundary Scan Register */
bsr = part_find_data_register( p, "BSR" );
if (!bsr) {
printf( _("%s(%s:%d) Boundary Scan Register (BSR) not found\n"), __FUNCTION__, __FILE__, __LINE__ );
return;
}
/* setup signal */
if (out) {
int control;
if (!s->output) {
printf( _("signal '%s' cannot be set as output\n"), s->name );
return;
}
bsr->in->data[s->output->bit] = val & 1;
control = p->bsbits[s->output->bit]->control;
if (control >= 0)
bsr->in->data[control] = p->bsbits[s->output->bit]->control_value ^ 1;
} else {
if (!s->input) {
printf( _("signal '%s' cannot be set as input\n"), s->name );
return;
}
if (s->output)
bsr->in->data[s->output->control] = p->bsbits[s->output->bit]->control_value;
}
}
int
part_get_signal( part_t *p, signal_t *s )
{
data_register *bsr;
if (!p || !s)
return -1;
/* search for Boundary Scan Register */
bsr = part_find_data_register( p, "BSR" );
if (!bsr) {
printf( _("%s(%s:%d) Boundary Scan Register (BSR) not found\n"), __FUNCTION__, __FILE__, __LINE__ );
return -1;
}
if (!s->input) {
printf( _("signal '%s' is not input signal\n"), s->name );
return -1;
}
return bsr->out->data[s->input->bit];
}
void
part_print( part_t *p )
{
char *instruction = NULL;
char *dr = NULL;
char format[100];
if (!p)
return;
snprintf( format, 100, _("%%-%ds %%-%ds %%-%ds %%-%ds %%-%ds\n"), MAXLEN_MANUFACTURER, MAXLEN_PART, MAXLEN_STEPPING,
MAXLEN_INSTRUCTION, MAXLEN_DATA_REGISTER );
if (p->active_instruction) {
instruction = p->active_instruction->name;
if (p->active_instruction->data_register != NULL)
dr = p->active_instruction->data_register->name;
}
if (instruction == NULL)
instruction = _("(none)");
if (dr == NULL)
dr = _("(none)");
printf( format, p->manufacturer, p->part, p->stepping, instruction, dr );
}
/* parts */
parts_t *
parts_alloc( void )
{
parts_t *ps = malloc( sizeof *ps );
if (!ps)
return NULL;
ps->len = 0;
ps->parts = NULL;
return ps;
}
void
parts_free( parts_t *ps )
{
int i;
if (!ps)
return;
for (i = 0; i < ps->len; i++)
part_free(ps->parts[i]);
free( ps->parts );
free( ps );
}
int
parts_add_part( parts_t *ps, part_t *p )
{
part_t **np = realloc( ps->parts, (ps->len + 1) * sizeof *ps->parts );
if (!np)
return 0;
ps->parts = np;
ps->parts[ps->len++] = p;
return 1;
}
void
parts_set_instruction( parts_t *ps, const char *iname )
{
int i;
for (i = 0; i < ps->len; i++)
ps->parts[i]->active_instruction = part_find_instruction( ps->parts[i], iname );
}
void
parts_print( parts_t *ps )
{
int i;
if (!ps)
return;
for (i = 0; i < ps->len; i++) {
part_t *p = ps->parts[i];
if (!p)
continue;
printf( _(" %3d "), i );
part_print( p );
}
}
syntax highlighted by Code2HTML, v. 0.9.1