/* * $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 , 2002. * */ #include "sysdep.h" #include #include #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 ); } }