summaryrefslogtreecommitdiffstats
path: root/fpga/xilinx/programmer/bit2svf
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/xilinx/programmer/bit2svf')
-rw-r--r--fpga/xilinx/programmer/bit2svf/LEEME.txt65
-rw-r--r--fpga/xilinx/programmer/bit2svf/Makefile41
-rw-r--r--fpga/xilinx/programmer/bit2svf/README.en52
-rw-r--r--fpga/xilinx/programmer/bit2svf/README.es55
-rw-r--r--fpga/xilinx/programmer/bit2svf/TODO3
-rw-r--r--fpga/xilinx/programmer/bit2svf/bit2svf.c297
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Bitfileheader101
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/COPYING340
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Changelog6
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Makefile21
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/README45
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.c233
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.h99
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitinfo.c57
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitshandle.c144
-rw-r--r--fpga/xilinx/programmer/bit2svf/bitshandle.h5
-rw-r--r--fpga/xilinx/programmer/bit2svf/commands.c556
-rw-r--r--fpga/xilinx/programmer/bit2svf/commands.h5
-rw-r--r--fpga/xilinx/programmer/bit2svf/debian/changelog76
-rw-r--r--fpga/xilinx/programmer/bit2svf/debian/control12
-rw-r--r--fpga/xilinx/programmer/bit2svf/debian/packages40
-rwxr-xr-xfpga/xilinx/programmer/bit2svf/debian/rules128
-rwxr-xr-xfpga/xilinx/programmer/bit2svf/debian/yada1557
-rw-r--r--fpga/xilinx/programmer/bit2svf/dumpbit.c93
-rw-r--r--fpga/xilinx/programmer/bit2svf/global.h16
-rwxr-xr-xfpga/xilinx/programmer/bit2svf/jbit232
-rw-r--r--fpga/xilinx/programmer/bit2svf/jbitrc_sample.txt21
-rw-r--r--fpga/xilinx/programmer/bit2svf/parts.c119
-rw-r--r--fpga/xilinx/programmer/bit2svf/parts.h19
-rw-r--r--fpga/xilinx/programmer/bit2svf/tags103
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/.DEVICES~42
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/.README.en~112
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/.README.es~237
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/DEVICES42
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/README.en115
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/README.es241
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/alg_18V.svft192
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_3.svft83
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_II.svft95
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/alg_Virtex_4.svft111
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/alg_XCF.svft190
-rw-r--r--fpga/xilinx/programmer/bit2svf/templates/alg_XCFP.svft208
-rw-r--r--fpga/xilinx/programmer/bit2svf/usage.txt63
43 files changed, 6272 insertions, 0 deletions
diff --git a/fpga/xilinx/programmer/bit2svf/LEEME.txt b/fpga/xilinx/programmer/bit2svf/LEEME.txt
new file mode 100644
index 0000000..a06e676
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/LEEME.txt
@@ -0,0 +1,65 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
+Copyright (c) 2001, 2002 by David Sullins
+Licencia: GPL por bitfile.c
+
+
+jbit:
+-----
+ Esta script es un shortcut para programar un dispositivo usando el
+ programa GNU JTAG con un archivo .bit. Genera y borra el SVF intermedio.
+ Se puede usar una configuracion personalizada, leer jbitrc_sample.txt.
+
+Ejemplo:
+
+bit2svf$ ./jbit ejemplo_prom.bit XC18V01
+
+jbit - bit2svf/jtag short cut - v1.0
+Copyright (c) 2005 Juan Pablo D. Borgna/INTI
+
+Creando archivo temporario /tmp/bit2svf.tmp
+
+bit2svf - SVF file generator - v1.0
+Copyright (c) 2005 Juan Pablo D. Borgna/INTI
+
+
+Bit file created on 2004/08/25 at 13:43:18.
+Created from file ejemplo.ncd for Xilinx part 2s100pq208.
+Bitstream length is 97652 bytes.
+
+Process finsished sucefully.
+Creado ok
+Invocando /home/jpablo/usr/bin/jtag
+Initializing Xilinx DLC5 JTAG Parallel Cable III on ppdev port /dev/parport0
+IR length: 8
+Chain length: 1
+Device Id: 00000101000000100100000010010011
+ Manufacturer: Xilinx
+ Part: XC18V01-SO20
+ Stepping: 1
+ Filename: /home/jpablo/usr//share/jtag/xilinx/xc18v01-so20/xc18v01-so20
+Warning svf: checking of TDO not supported for SIR.
+ This message is only displayed once.
+Borrando temporarios..
+Que tenga un buen dia :-)
+
+
+
+bit2svf:
+--------
+ Este programa sirve para generar un archivo SVF con el cual
+ utilizando el programa JTAG para linux, se puede programar una FPGA o
+ una PROM.
+
+Ejemplo:
+
+bit2svf$ ./bit2svf ejemplo_prom.bit ejemplo_prom.svf XC18V01
+
+Bit file created on 2004/08/25 at 13:43:18.
+Created from file ejemplo.ncd for Xilinx part 2s100pq208.
+Bitstream length is 97652 bytes.
+
+Process finsished sucefully.
+
+
+
diff --git a/fpga/xilinx/programmer/bit2svf/Makefile b/fpga/xilinx/programmer/bit2svf/Makefile
new file mode 100644
index 0000000..b5df378
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/Makefile
@@ -0,0 +1,41 @@
+CC=gcc
+CFLAGS=-Wall -g3 -I$(BIDIR)
+BIDIR=bitinfo-0.3
+LDFLAGS=-I$(BIDIR)
+PROYECTO=dumpbit bit2svf
+VERSION=1.3.1
+PKG=bit2svf-$(VERSION)
+
+all: $(PROYECTO) $(BIDIR)/bitinfo
+
+$(BIDIR)/bitfile.o:
+ $(MAKE) -C $(BIDIR)
+
+bit2svf: bit2svf.o $(BIDIR)/bitfile.o parts.o commands.o bitshandle.o
+
+dumpbit: dumpbit.o $(BIDIR)/bitfile.o
+
+debian/control: debian/packages debian/yada
+ debian/yada rebuild control
+
+debian/rules: debian/packages debian/yada
+ debian/yada rebuild rules
+
+deb: $(PROYECTO) debian/control debian/rules
+ fakeroot dpkg-buildpackage -b -uc
+
+tarball: clean
+ cp -r ../bit2svf /tmp/$(PKG)
+ -rm -rf /tmp/$(PKG)/CVS /tmp/$(PKG)/*/CVS /tmp/$(PKG)/*/*/CVS /tmp/$(PKG)/*/*/*/CVS /tmp/$(PKG)/*/*/*/*/CVS /tmp/$(PKG)/*/*/*/*/*/*/CVS /tmp/$(PKG)/*/*/*/*/*/*/CVS 2> /dev/null
+ -rm -f /tmp/$(PKG)/.cvsignore /tmp/$(PKG)/*/.cvsignore /tmp/$(PKG)/*/*/.cvsignore /tmp/$(PKG)/*/*/*/.cvsignore /tmp/$(PKG)/*/*/*/*/.cvsignore /tmp/$(PKG)/*/*/*/*/*/*/.cvsignore /tmp/$(PKG)/*/*/*/*/*/*/.cvsignore 2> /dev/null
+ -rm -f /tmp/$(PKG)/*.epr /tmp/$(PKG)/.*.dst /tmp/$(PKG)/Changelog /tmp/$(PKG)/lista 2> /dev/null
+ cd /tmp ; tar zcvf $(PKG).tar.gz $(PKG)
+ rm -r /tmp/$(PKG)
+ mv /tmp/$(PKG).tar.gz .
+
+clean:
+ -rm -f *.o $(PROYECTO) .*~
+ $(MAKE) -C $(BIDIR) clean
+ debian/rules clean
+
+
diff --git a/fpga/xilinx/programmer/bit2svf/README.en b/fpga/xilinx/programmer/bit2svf/README.en
new file mode 100644
index 0000000..f578451
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/README.en
@@ -0,0 +1,52 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2001, 2002 by David Sullins [bitinfo code]
+Copyright (c) 2006 Salvador E. Tropea <salvador en inti gov ar>
+Copyright (c) 2005-2006 Instituto Nacional de Tecnología Industrial
+
+ 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; version 2.
+
+ 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
+
+dumpbit:
+-------
+ Dumpbit its a simple program wich takes a .bit file generated by
+ Xilinx tools and dumps the binary stream in a file.
+
+bit2svf:
+-------
+ This program is used for generate a SVF file with the needed
+ sequence for store the contents of a Xilinx .bit file inside some
+ PROM or FPGA.
+
+Working mode:
+ A template file with instructions for generate the svf file is
+ used. A different template is used for each different algorithm.
+ The format specification can be found in a README file inside
+ the "templates/" dir wich also has two samples.
+
+bitinfo:
+-------
+ This program was written by Sullins [davesullins@earthlink.net] and is
+ used for read the header of the Xilinx bit files.
+ Its internally used by bit2svf and dumpbit.
+ The full distribution with its documentation can be found inside the
+ bitinfo-3.0 directory.
+
+jbit:
+----
+ This script, using bit2svf, generates a temporal SVF file for the
+ specified device with the specified bit file and then uses the program
+ JTAG for transfering it this file. When finish it erases the temp file.
+ It was created for simplify the process of programming a Xilinx device
+ with GPL tools.
+
diff --git a/fpga/xilinx/programmer/bit2svf/README.es b/fpga/xilinx/programmer/bit2svf/README.es
new file mode 100644
index 0000000..ce6dcef
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/README.es
@@ -0,0 +1,55 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2001, 2002 by David Sullins [bitinfo code]
+Copyright (c) 2006 Salvador E. Tropea <salvador en inti gov ar>
+Copyright (c) 2005-2006 Instituto Nacional de Tecnología Industrial
+
+ 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; version 2.
+
+ 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
+
+dumpbit:
+-------
+ Dumpbit es un simple programa que toma un archivo .bit generado por
+ herramientas de Xilinx y vuelca el contenido del stream binario en
+ un archivo.
+
+bit2svf:
+-------
+
+ Este programa se usa para generar un archivo SVF con la secuencia
+ necesaria para grabar el contenido de un archivo .bit de xilinx en
+ algun dispositivo PROM o en la misma FPGA.
+
+Funcionamiento:
+ Lo que se hace es utilizar un template con instrucciones para
+ generar el archivo svf. Se necesita un template para cada algoritmo
+ diferente que se quiera generar.
+ La explicacion del formato de templates se encunetra en un
+ archivo README en el directorio "templates/" que trae dos ejemplos.
+
+bitinfo:
+-------
+ Este es programa escrito por Dave Sullins [davesullins@earthlink.net]
+ sirve para interpretar el header de los archivos bit de xilinx.
+ Es usado internamente por bit2svf y dumpbit.
+ La distribucion completa junto con su documentacion se encuentra en el
+ directorio bitinfo-3.0.
+
+jbit:
+----
+ Esta script, utilizando bit2svf, genera un SVF temporal para el
+ dispositivo especificado con el archivo bit y luego utiliza el programa
+ JTAG para transferirle ese archivo. Al terminar borra el temporario.
+ Fue creada para simplificar el proceso de programar un dispositivo Xilinx
+ con un archivo bit con herramientas GPL.
+
diff --git a/fpga/xilinx/programmer/bit2svf/TODO b/fpga/xilinx/programmer/bit2svf/TODO
new file mode 100644
index 0000000..4765920
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/TODO
@@ -0,0 +1,3 @@
+* Reemplazar la lectura de archivo de origen por un plugin para poder
+ leer un MCS en lugar de un .bit o cualquier otro tipo de archivo.
+
diff --git a/fpga/xilinx/programmer/bit2svf/bit2svf.c b/fpga/xilinx/programmer/bit2svf/bit2svf.c
new file mode 100644
index 0000000..1bd9ac3
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bit2svf.c
@@ -0,0 +1,297 @@
+ /**[txh]********************************************************************
+
+ Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+ Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+ Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+ 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; version 2.
+
+ 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
+
+ Description: Generates a SVF file from a xilinx .bit file.
+
+***************************************************************************/
+/*****************************************************************************
+
+ Target: Any
+ Language: C
+ Compiler: gcc 3.3.5 (Debian GNU/Linux)
+ Text editor: SETEdit 0.5.5
+
+*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include "bitfile.h"
+#include "parts.h"
+#include "commands.h"
+#include "global.h"
+#include "bitshandle.h"
+
+#define DEFAULT_RES "/usr/share/bit2svf/"
+
+static char *theBitFile;
+static char *theSVFFile;
+static char *thePath=NULL;
+static char *theDevice;
+static long skip=-1, limit=-1;
+
+static
+struct option longopts[] =
+{
+ { "help", 0, 0, 'h' },
+ { "length", 1, 0, 'l' },
+ { "path", 1, 0, 'p' },
+ { "skip", 1, 0, 's' },
+ { 0, 0, 0, 0 }
+};
+
+static
+void Usage()
+{
+ #define PrintHelp(a) printf(a)
+ #define FlushHelp() printf("\n"); fflush(stdout)
+ PrintHelp("bit2svf [options] infile.bit outfile.svf DEVICE_NAME\n\n");
+ PrintHelp("Valid options are:\n");
+ PrintHelp("-h, --help displays this text ;-).\n");
+ PrintHelp("-l, --length=LIMIT limit the number of bits.\n");
+ PrintHelp("-p, --path=PATH is the full path to the directory with DEVICES file\n");
+ PrintHelp(" and the templates files to be used.\n");
+ PrintHelp("-s, --skip=OFFSET skip OFFSET bits in the bitstream.\n");
+ FlushHelp();
+ exit(1);
+}
+
+static
+void ParseCommandLine(int argc, char *argv[])
+{
+ int optc;
+
+ while ((optc=getopt_long(argc,argv,"hl:p:s:",longopts,0))!=EOF)
+ {
+ switch (optc)
+ {
+ case 'l':
+ limit=strtol(optarg,NULL,0);
+ if (limit%8)
+ {
+ fprintf(stderr,"The length must be multiple of 8\n");
+ exit(2);
+ }
+ limit/=8;
+ break;
+
+ case 'p':
+ thePath=optarg;
+ break;
+
+ case 's':
+ skip=strtol(optarg,NULL,0);
+ if (skip%8)
+ {
+ fprintf(stderr,"The skip must be multiple of 8\n");
+ exit(2);
+ }
+ skip/=8;
+ break;
+
+ case 'h':
+ default:
+ Usage();
+ }
+ }
+ if (argc-optind<3)
+ {
+ fprintf(stderr,"Error: Missing arguments\n\n");
+ Usage();
+ }
+ theBitFile=argv[optind];
+ theSVFFile=argv[optind+1];
+ theDevice=argv[optind+2];
+}
+
+
+/* main function */
+
+int main(int argc, char *argv[])
+{
+ struct bithead bh;
+ FILE *bitfile;
+ FILE *cfile;
+ FILE *tplate;
+ char line[1001];
+ part *selected=NULL;
+ char *res_path=NULL;
+ char *devices=NULL;
+ int isBit;
+
+ address=0l;
+ step=0l;
+ s_bytes=0l;
+ s_bits=0l;
+ stream_s=0l;
+ cutlines=1;
+
+ id=NULL;
+ idmask=NULL;
+ bsize=NULL;
+ msize=0l;
+ templ=NULL;
+
+ fprintf(stderr,"\nbit2svf - SVF file generator - v1.3.1\n");
+ fprintf(stderr,"Copyright (c) 2005 Juan Pablo D. Borgna/INTI\n");
+ fprintf(stderr,"Copyright (c) 2006-2007 Salvador E. Tropea/INTI\n\n");
+
+ ParseCommandLine(argc,argv);
+
+ if ((bitfile=fopen(theBitFile,"rb"))==NULL)
+ {
+ perror("BITFILE");
+ return 2;
+ }
+
+ if (!strcmp(theSVFFile,"-"))
+ cfile=stdout;
+ else
+ {
+ if ((cfile=fopen(theSVFFile,"wt"))==NULL)
+ {
+ perror("SVFFILE");
+ return 3;
+ }
+ }
+
+
+ if (thePath)
+ res_path=thePath;
+ else /* If is not a command line parameter */
+ if (((res_path=getenv("BIT2SVF_RES"))==NULL) || (strlen(res_path)==0))
+ res_path=strdup(DEFAULT_RES); /* if couldnt get it from env, default*/
+
+ //asprintf(&devices,"%s/DEVICES",res_path);
+ devices=(char *)malloc(strlen(res_path)+9);
+ strcpy(devices,res_path);
+ strcat(devices,"/");
+ strcat(devices,"DEVICES");
+
+ if (select_part_from_file(theDevice,devices,&selected)) return 12;
+
+ fprintf(stderr,"Using DEVICES: %s\n",devices);
+
+ id=strdup(selected->id);
+ idmask=strdup(selected->idmask);
+ msize=selected->msize;
+ bsize=selected->bsize;
+
+ //asprintf(&templ,"%s/%s",res_path,selected->alg_tpl);
+ templ=(char *)malloc(strlen(res_path)+strlen(selected->alg_tpl)+6);
+ strcpy(templ,res_path);
+ strcat(templ,"/");
+ strcat(templ,selected->alg_tpl);
+ strcat(templ,".svft");
+
+ if ((tplate=fopen(templ,"rt"))==NULL)
+ {
+ perror("TEMPLATE");
+ return 4;
+ }
+ fprintf(stderr,"Using template: %s\n",templ);
+
+ isBit=1;
+ initbh(&bh);
+ if (readhead(&bh, bitfile))
+ {
+ fprintf(stderr,"\nInvalid .bit file assuming .bin.\n");
+ isBit=0;
+ fseek(bitfile,0,SEEK_END);
+ bh.length=ftell(bitfile);
+ fseek(bitfile,0,SEEK_SET);
+ }
+ else
+ {
+ fprintf(stderr,"\n");
+ fprintf(stderr,"Bit file created on %s at %s.\n", bh.date, bh.time);
+ fprintf(stderr,"Created from file %s for Xilinx part %s.\n", bh.filename, bh.part);
+ }
+ fprintf(stderr,"Bitstream length is %d bytes.\n", bh.length);
+ if (skip>=0)
+ {
+ if (bh.length<skip)
+ {
+ fprintf(stderr,"The number of bytes to skip is bigger than the current length.\n");
+ return 13;
+ }
+ fseek(bitfile,skip,SEEK_CUR);
+ bh.length-=skip;
+ fprintf(stderr,"Skipping %ld bytes, new length %d.\n",skip,bh.length);
+ }
+ if (limit>=0)
+ {
+ if (bh.length<limit)
+ {
+ fprintf(stderr,"The specified length is bigger than the current length.\n");
+ return 12;
+ }
+ bh.length=limit;
+ fprintf(stderr,"Limiting bitstream length to %d bytes.\n",bh.length);
+ }
+ fprintf(stderr,"\n");
+
+ stream_s=ftell(bitfile);
+ s_bytes=bh.length;
+ s_bits=8*s_bytes;
+
+ fgets(line,1001,tplate);
+
+ while(!feof(tplate))
+ {
+
+ if (!strncasecmp(line,"--",2))
+ { /* block found */
+ /* LITERAL */
+ if (!strncasecmp(line,"--LITERAL START",15))
+ if(repeat(tplate,cfile,bitfile,0)) return 6;
+ /* end LITERAL */
+ /* REPEAT */
+ if (!strncasecmp(line,"--REPEAT START",14))
+ if (repeat(tplate,cfile,bitfile,-1)) return 7;
+ /* end REPEAT */
+ /* REPEAT UNTIL */
+ if (!strncasecmp(line,"--REPEAT UNTIL",14))
+ if (repeat(tplate,cfile,bitfile,value_from(line+15))) return 8;
+ /* end REPEAT UNTIL */
+ }
+ else if (!strncasecmp(line,"$",1))
+ {
+ int col=0;
+ if(do_command(line,bitfile,cfile,&col)) return 9;
+ }
+ else if (strncasecmp(line,"//",2) && (line[0]!='\n')) /* And if its not a comment or a blank line */
+ { /* Its a template error */
+ fprintf(stderr,"Invalid line outside block in template: %s\n",line);
+ return 10;
+ }
+
+ fgets(line,1001,tplate);
+ }
+
+ fclose(tplate);
+ fclose(cfile);
+ fclose(bitfile);
+ freebh(&bh);
+
+ fprintf(stderr,"Process finsished sucefully.\n");
+ return 0;
+}
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Bitfileheader b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Bitfileheader
new file mode 100644
index 0000000..cf579cf
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Bitfileheader
@@ -0,0 +1,101 @@
+05/23/2001
+
+Bit file header specification
+
+
+A bit file has two sections. The first section is a variable length header.
+The second section is a fixed-length bitstream which is downloaded into the
+FPGA. The format of the bitstream can be found in the data book for the
+appropriate FPGA, but the format of the header is not anywhere that I have
+found in the Xilinx literature. This document describes the structure the
+bit file header for the XC4005XL and XC4005E FPGAs. This structure may or
+may not be appropriate for headers of bit files for other Xilinx FPGAs.
+
+Preamble: unknown values
+
+The bit files generated with xmake for the XC4005XL and XC4005E FPGAs all
+begin with the following sequence of 13 bytes (shown here in hexadecimal):
+00 09 0F F0 0F F0 0F F0 0F F0 00 00 01
+
+Part "a": source file
+
+Parts a through e follow the same general format. First the part begins
+with the ASCII letter of the section followed by a NULL (00h). For example,
+part c begins with hexadecimal 63 00, since 63 is ASCII for "c". The next
+byte is a length byte, giving the length of the string to follow plus 1.
+The length is followed by an ASCII string, and that string is followed by a
+NULL (00h). If there is no string at all in the section, then the length
+byte is 0 and there is no NULL termination.
+
+Part a of the header tells the filename used to generate the bit file. For
+example, if the file "xc4005.ncd" was used to generate the bit file then the
+header will be:
+"a" 00 0B "xc4005.ncd" 00
+
+Convert the quoted letters into their ASCII representation.
+
+Part "b": part name
+
+Part b follows the same format as part a. The string identifies the part
+and package of the target device. In my limited tests this string has
+always been "4005xlpc84" or "4005epc84".
+
+Part "c": date
+
+Part c follows the same format as part a. The string gives the date the bit
+file was generated, for example "2001/03/12".
+
+Part "d": time
+
+Part d follows the same format as part a. The string gives the time the bit
+file was generated, for example "20:43:04".
+
+Part "e": unknown
+
+Part e seems to follow the same format as part a. However, in my tests this
+part has always been empty. In other words, the entire part is hexadecimal
+65 00 00.
+
+Final part: bitstream length
+
+The final part of the header gives the length of the bitstream to follow, in
+binary. This is two bytes long for the XC4005XL and XC4005E parts, but it
+is probable that this length will be more than two bytes long for larger
+Xilinx parts.
+
+For example, the XC4005XL part has a 18995 byte long bitstream. The final
+two bytes of the header are hexadecimal 4A33, which is 18995 when converted
+to decimal.
+
+Immediately following the final part of the header, the bitstream begins.
+The file ends immediately after the bitstream.
+
+
+05/24/2001
+UPDATE:
+
+I examined the bit file headers for two more Xilinx parts, a Spartan part
+and 1000 gate Virtex part. From this I determined my understanding of the
+sections was a little off. The section letters FOLLOW the sections. So the
+unknown garbage at the beginning (which was the same for all parts) is
+section a, the part name was section b, and so on. The time was section e,
+and the 00 following the 65 00 was the beginning of the length. So the
+length is actually three bytes long. This gives a maximum bitstream length
+of FFFFFFh, or 16,777,215 bytes.
+
+09/10/2002
+UPDATE:
+
+I got an email message from "Stephen from Australia" who set me straight on
+the format of the bit file header. He pointed me to the online FPGA FAQ,
+which gives an alternative view of how the header is laid out. Each section
+letter is a single byte. The 00 which follows the section letter is
+actually the first byte of a two-byte size. The final four bytes of the
+header make up a four-byte size. After considering the difference between
+the two specifications, I realized that even if the FAQ is wrong it wouldn't
+hurt to parse it that way since the first byte of the length would always be
+00. And it seems more aesthetically pleasing to have a four-byte bitstream
+length than a three-byte bitstream length. I have altered bitfile.c to
+reflect the change in my understanding of the format.
+
+Thanks for setting me straight, Steve!
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/COPYING b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/COPYING
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Changelog b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Changelog
new file mode 100644
index 0000000..958d5d9
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Changelog
@@ -0,0 +1,6 @@
+2002-09-10, version 0.2
+
+Updated the way I parse the bitstream length according to information in the
+online FPGA FAQ. Special thanks to "Stephen from Australia" for setting me
+straight. Started using version numbers. If you have an unnumbered
+version of bitinfo, it is version 0.1 and out of date.
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Makefile b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Makefile
new file mode 100644
index 0000000..12685c9
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/Makefile
@@ -0,0 +1,21 @@
+# Makefile for bitfile routines
+
+CC = gcc
+CFLAGS = -c -g -Wall
+LDFLAGS =
+OBJECTS = bitinfo.o bitfile.o
+
+
+all: bitinfo
+
+bitinfo.o: bitinfo.c bitfile.h
+ ${CC} ${CFLAGS} bitinfo.c -o bitinfo.o
+
+bitfile.o: bitfile.c bitfile.h
+ ${CC} ${CFLAGS} bitfile.c -o bitfile.o
+
+bitinfo: bitinfo.o bitfile.o
+ ${CC} ${LDFLAGS} ${OBJECTS} -o bitinfo
+
+clean:
+ rm -f ${OBJECTS} bitinfo
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/README b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/README
new file mode 100644
index 0000000..c100126
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/README
@@ -0,0 +1,45 @@
+ Bitinfo - Parse a Xilinx bit-file header
+
+
+ Description
+
+ Bitinfo is a simple utility that parses the header of a Xilinx bit file
+ and outputs all the information that can be obtained from that header.
+ This information includes the Xilinx FPGA the bit file was created for,
+ the NCD file the bit file was created from, the creation date and time,
+ and the bitstream length.
+
+ I had to reverse-engineer the file format to figure out how to parse all
+ of this information. So that someone else doesn't have to repeat my work,
+ I have included my reverse-engineering notes with the source code.
+
+ You may find this program useful if, like me, you often end up with
+ several bit files lying around, all called "xc4005.bit," and you can't
+ remember which one is the one you need. The header should at least give
+ you some clues about the file's contents. Another use for this program is
+ to prove to a student that the bit file they have brought to lab with them
+ is not the one from this week's experiment, since the timestamp is from
+ three weeks ago.
+
+
+ Compiling and using bitinfo
+
+ You can download the bitinfo source for free from
+ http://members.naspa.net/djs/software/bitinfo.tar.gz. It is released under
+ the GNU Public License. See the COPYING file for more details.
+
+ To compile bitinfo, first edit the Makefile if necessary. If you don't
+ have gcc installed, you will need to change the first line from "CC=gcc"
+ to "CC=cc" or whatever your C compiler is called. After editing the
+ Makefile, type "make" and you're done. Although bitinfo was written for
+ Unix, it has also been successfully compiled for Windows NT 4.0 using MS
+ Visual C++.
+
+ To run bitinfo, just type "bitinfo < file.bit". You will probably want to
+ put bitinfo in some bin directory for convenience.
+
+
+ Bugs
+
+ Please report any bugs by emailing me at djs@naspa.net.
+
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.c b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.c
new file mode 100644
index 0000000..af4579d
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.c
@@ -0,0 +1,233 @@
+/* bitfile.c
+ *
+ * Library routines for dealing with bit files, version 0.2
+ *
+ * Copyright 2001, 2002 by David Sullins
+ *
+ * This file is part of Bitinfo.
+ *
+ * Bitinfo 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, version 2 of the License.
+ *
+ * Bitinfo 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
+ * Bitinfo; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You may contact the author at djs@naspa.net.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "bitfile.h"
+
+#ifndef uchar
+#define uchar unsigned char
+#endif
+
+/* first 13 bytes of a bit file */
+static uchar head13[] = {0, 9, 15, 240, 15, 240, 15, 240, 15, 240, 0, 0, 1};
+
+/* initbh
+ *
+ * Initialize the bithead struct
+ */
+void initbh(struct bithead *bh)
+{
+ bh->filename = NULL;
+ bh->part = NULL;
+ bh->date = NULL;
+ bh->time = NULL;
+ bh->length = 0;
+}
+
+/* freebh
+ *
+ * Free up memory allocated for a bithead struct.
+ */
+void freebh(struct bithead *bh)
+{
+ free(bh->filename);
+ free(bh->part);
+ free(bh->date);
+ free(bh->time);
+ initbh(bh);
+}
+
+/* readhead
+ *
+ * Read the entire bit file header. The file pointer will be advanced to
+ * point to the beginning of the bitstream, and the bitfile header struct
+ * will be filled with the appropriate data.
+ *
+ * Return -1 if an error occurs, 0 otherwise.
+ */
+int readhead(struct bithead *bh, FILE *f)
+{
+ int t;
+
+ /* get first 13 bytes */
+ t = readhead13(f);
+ if (t) return t;
+
+ /* get filename */
+ t = readsecthead(NULL, f);
+ if (-1 == t) return -1;
+ bh->filename = malloc(t);
+ t = readsection(bh->filename, t, f);
+
+ /* get part name */
+ t = readsecthead(NULL, f);
+ if (-1 == t) return -1;
+ bh->part = malloc(t);
+ t = readsection(bh->part, t, f);
+
+ /* get file creation date */
+ t = readsecthead(NULL, f);
+ if (-1 == t) return -1;
+ bh->date = malloc(t);
+ t = readsection(bh->date, t, f);
+
+ /* get file creation time */
+ t = readsecthead(NULL, f);
+ if (-1 == t) return -1;
+ bh->time = malloc(t);
+ t = readsection(bh->time, t, f);
+
+ /* get bitstream length */
+ t = readlength(f);
+ if (-1 == t) return -1;
+ bh->length = t;
+
+ return 0;
+}
+
+/* readhead13
+ *
+ * Read the first 13 bytes of the bit file. Discards the 13 bytes but
+ * verifies that they are correct.
+ *
+ * Return -1 if an error occurs, 0 otherwise.
+ */
+int readhead13 (FILE *f)
+{
+ int t;
+ uchar buf[13];
+
+ /* read header */
+ t = fread(buf, 1, 13, f);
+ if (t != 13)
+ {
+ return -1;
+ }
+
+ /* verify header is correct */
+ t = memcmp(buf, head13, 13);
+ if (t)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* readsecthead
+ *
+ * Read the header of a bit file section. The section letter is placed in
+ * section buffer "buf" and the length of the following section is
+ * returned. If buf is NULL, the section letter is discarded.
+ *
+ * Return -1 if an error occurs, length of section otherwise.
+ */
+int readsecthead(char *buf, FILE *f)
+{
+ int t;
+ char tbuf = 0;
+ char lenbuf[2];
+
+ /* if buf is NULL, use tbuf instead */
+ if (NULL == buf)
+ {
+ buf = &tbuf;
+ }
+
+ /* get section letter */
+ t = fread(buf, 1, 1, f);
+ if (t != 1)
+ {
+ return -1;
+ }
+
+ /* read length */
+ t = fread(lenbuf, 1, 2, f);
+ if (t != 2)
+ {
+ return -1;
+ }
+
+ /* convert 2-byte length to an int */
+ return (((int)lenbuf[0]) <<8) | lenbuf[1];
+}
+
+
+/* readsection
+ *
+ * Read a section of a bit file. The section contents are placed
+ * in the contents buffer "buf."
+ *
+ * Return -1 if an error occurs, 0 otherwise.
+ */
+int readsection(char *buf, int length, FILE *f)
+{
+ int t;
+
+ /* get section data */
+ t = fread(buf, 1, length, f);
+ if ((t != length) || (buf[length-1] != 0))
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* readlength
+ *
+ * Read in the bitstream length. The section letter "e" is discarded
+ * and the length is returned.
+ *
+ * Return -1 if an error occurs, length otherwise.
+ */
+int readlength(FILE *f)
+{
+ char s = 0;
+ uchar buf[4];
+ int length;
+ int t;
+
+ /* get section, make sure it's "e" */
+ t = fread(&s, 1, 1, f);
+ if ((t != 1) || (s != 'e'))
+ {
+ return -1;
+ }
+
+ /* get length */
+ t = fread(buf, 1, 4, f);
+ if (t != 4)
+ {
+ return -1;
+ }
+
+ /* convert 4-byte length to an int */
+ length = (((int)buf[0]) <<24) | (((int)buf[1]) <<16)
+ | (((int)buf[2]) <<8) | buf[3];
+
+ return length;
+}
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.h b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.h
new file mode 100644
index 0000000..cb531a8
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitfile.h
@@ -0,0 +1,99 @@
+/* bitfile.h
+ *
+ * Library routines for dealing with bit files, version 0.2
+ *
+ * Copyright 2001, 2002 by David Sullins
+ *
+ * This file is part of Bitinfo.
+ *
+ * Bitinfo 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, version 2 of the License.
+ *
+ * Bitinfo 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
+ * Bitinfo; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You may contact the author at djs@naspa.net.
+ */
+
+#include <stdio.h>
+
+/* struct bithead
+ *
+ * Stores the information obtained from the bitfile header. Use initbh to
+ * initialize the struct, and freebh to free memory allocated for the struct.
+ */
+struct bithead
+{
+ char* filename;
+ char* part;
+ char* date;
+ char* time;
+ int length;
+};
+
+/* initbh
+ *
+ * Initialize the bithead struct
+ */
+void initbh(struct bithead *bh);
+
+/* freebh
+ *
+ * Free up memory allocated for a bithead struct.
+ */
+void freebh(struct bithead *bh);
+
+/* readhead
+ *
+ * Read the entire bit file header. The file pointer will be advanced to
+ * point to the beginning of the bitstream, and the bitfile header struct
+ * will be filled with the appropriate data.
+ *
+ * Return -1 if an error occurs, 0 otherwise.
+ */
+int readhead(struct bithead *bh, FILE *f);
+
+/* readhead13
+ *
+ * Read the first 13 bytes of the bit file. Discards the 13 bytes but
+ * verifies that they are correct.
+ *
+ * Return -1 if an error occurs, 0 otherwise.
+ */
+int readhead13 (FILE *f);
+
+/* readsecthead
+ *
+ * Read the header of a bit file section. The section letter is placed in
+ * section buffer "buf" and the length of the following section is
+ * returned. If buf is NULL, the section letter is discarded.
+ *
+ * Return -1 if an error occurs, length of section otherwise.
+ */
+int readsecthead(char *buf, FILE *f);
+
+/* readsection
+ *
+ * Read a section of a bit file. The section contents are placed
+ * in the contents buffer "buf."
+ *
+ * Return -1 if an error occurs, 0 otherwise.
+ */
+int readsection(char *buf, int length, FILE *f);
+
+/* readlength
+ *
+ * Read in the bitstream length. The section letter "e" is discarded
+ * and the length is returned.
+ *
+ * Return -1 if an error occurs, length otherwise.
+ */
+int readlength(FILE *f);
+
diff --git a/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitinfo.c b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitinfo.c
new file mode 100644
index 0000000..1fc1c84
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitinfo-0.3/bitinfo.c
@@ -0,0 +1,57 @@
+/* bitinfo.c
+ *
+ * Main function to parse Xilinx bit file header, version 0.2.
+ *
+ * Copyright 2001, 2002 by David Sullins
+ *
+ * This file is part of Bitinfo.
+ *
+ * Bitinfo 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, version 2 of the License.
+ *
+ * Bitinfo 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
+ * Bitinfo; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * You may contact the author at djs@naspa.net.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bitfile.h"
+
+/* read a bit file from stdin */
+int main(void)
+{
+ int t;
+ struct bithead bh;
+
+ initbh(&bh);
+
+ /* read header */
+ t = readhead(&bh, stdin);
+ if (t)
+ {
+ printf("Invalid bit file header.\n");
+ exit(1);
+ }
+
+ /* output header info */
+ printf("\n");
+ printf("Bit file created on %s at %s.\n", bh.date, bh.time);
+ printf("Created from file %s for Xilinx part %s.\n", bh.filename,
+ bh.part);
+ printf("Bitstream length is %d bytes.\n", bh.length);
+ printf("\n");
+
+ freebh(&bh);
+
+ return 0;
+}
diff --git a/fpga/xilinx/programmer/bit2svf/bitshandle.c b/fpga/xilinx/programmer/bit2svf/bitshandle.c
new file mode 100644
index 0000000..7fb2f40
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitshandle.c
@@ -0,0 +1,144 @@
+ /**[txh]********************************************************************
+
+ Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+ Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+ Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+ 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; version 2.
+
+ 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
+
+ Description: Low level functions to output hexadecimal bitstreams.
+
+***************************************************************************/
+/*****************************************************************************
+
+ Target: Any
+ Language: C
+ Compiler: gcc 3.3.5 (Debian GNU/Linux)
+ Text editor: SETEdit 0.5.5
+
+*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "global.h"
+#include "bitshandle.h"
+
+/* This function returns the inverted bits of its argument */
+unsigned char
+inv_byte(unsigned char b)
+{
+ int i;
+ unsigned char t=0;
+
+ for (i=0;i<7;i++)
+ {
+ t|= (b & 0x01);
+ t = t << 1;
+ b = b >> 1;
+ }
+ t|=b & 0x01;
+ return t;
+}
+
+/* This function is used to generate a string with the hex value of the
+ inverted bits of from */
+void
+pbi(char *to, char *from,long nbytes)
+{
+ int i;
+ int j;
+ char t[]="ZZ";
+
+ if (to==NULL) return;
+
+ j=nbytes*2;
+
+ for (i=0;i<nbytes;i++)
+ {
+ sprintf(t,"%02x",inv_byte(from[i]));
+ j-=2;
+ to[j]=t[0];
+ to[j+1]=t[1];
+ }
+}
+
+/* This function is used to generate a string with the hex value of the
+ bits of from */
+void
+pb(char *to, char *from,long nbytes)
+{
+ int i;
+ int j;
+ char t[]="ZZ";
+
+ if (to==NULL) return;
+
+ j=0;
+
+ for (i=0;i<nbytes;i++)
+ {
+ sprintf(t,"%02x",from[i]);
+ j+=2;
+ to[j]=t[0];
+ to[j+1]=t[1];
+ }
+}
+
+/*this function writes bytes to a file with a max nuber of
+ chars per line */ /* it should not be here */
+int
+cutputs(char *string, FILE *fp, long block, int *col)
+{
+ long remaining;
+ long wrote=0l;
+ int c=*col;
+
+ remaining=strlen(string);
+ if (!cutlines)
+ {
+ fwrite(string,1,remaining,fp);
+ col+=remaining;
+ return 0;
+ }
+ if (remaining<block)
+ block=remaining;
+
+ while (remaining)
+ {
+ long to_write=block-c;
+ if (to_write<0) to_write=0;
+ if (to_write & 1) to_write++;
+ wrote=fwrite(string,1,to_write,fp);
+ if (wrote!=to_write)
+ {
+ perror("CUTPUTS");
+ return 1;
+ }
+ c+=wrote;
+ string+=wrote;
+ remaining-=wrote;
+ if (remaining)
+ {
+ fputs("\n",fp);
+ c=0;
+ if (remaining<block)
+ block=remaining;
+ }
+ }
+ *col=c;
+ return 0;
+}
+
diff --git a/fpga/xilinx/programmer/bit2svf/bitshandle.h b/fpga/xilinx/programmer/bit2svf/bitshandle.h
new file mode 100644
index 0000000..a3ea91d
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/bitshandle.h
@@ -0,0 +1,5 @@
+unsigned char inv_byte(unsigned char b);
+void pbi(char *to, char *from,long nbytes);
+void pb(char *to, char *from,long nbytes);
+int cutputs(char *string, FILE *fp, long block, int *col);
+
diff --git a/fpga/xilinx/programmer/bit2svf/commands.c b/fpga/xilinx/programmer/bit2svf/commands.c
new file mode 100644
index 0000000..c4a9493
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/commands.c
@@ -0,0 +1,556 @@
+ /**[txh]********************************************************************
+
+ Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+ Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+ Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+ 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; version 2.
+
+ 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
+
+ Description: Commands parser and executor.
+
+***************************************************************************/
+/*****************************************************************************
+
+ Target: Any
+ Language: C
+ Compiler: gcc 3.3.5 (Debian GNU/Linux)
+ Text editor: SETEdit 0.5.5
+
+*****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "global.h"
+#include "commands.h"
+#include "bitshandle.h"
+
+#define MAX_WIDTH 246
+
+long
+value_from(char *varname)
+{
+ if (!strncasecmp("BSIZEB2",varname,7))
+ return strtol(bsize,NULL,0)/4;
+ if (!strncasecmp("BSIZEB",varname,6))
+ return strtol(bsize,NULL,0)/8;
+ if (!strncasecmp("BSIZE",varname,5))
+ return strtol(bsize,NULL,0);
+ if (!strncasecmp("MSIZE",varname,5))
+ return msize;
+ return strtol(varname,NULL,0);
+}
+
+void
+fill(FILE *fp, long c, long t, int *col)
+{
+ char b[4]="ZZ";
+ sprintf(b,"%02x",(unsigned int)c);
+ int co=*col;
+
+ for (;t>0;t--)
+ {
+ co+=fprintf(fp,"%s",b);
+ if (co>=MAX_WIDTH)
+ {
+ co=0;
+ fprintf(fp,"\n");
+ }
+ }
+ *col=co;
+}
+
+/* This function executes a $COMMAND$ */
+int
+do_command(char *cmd, FILE *dfp, FILE *ofp, int *col)
+{
+ char *temp;
+ char *dbuffer;
+ long nbytes=0l;
+ long readed=0l;
+ long value=0l;
+ long times=0l;
+ int padded=0;
+ char *args_pos_s=NULL;
+ char *args_pos_e=NULL;
+ char *separator=NULL;
+ char args[100]; /* I dont think i need more than 100 bytes for
+ passing args... */
+
+ /* DATA and DATA_INV command */
+
+ if (strstr(cmd,"DATA"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if( !args_pos_s || !args_pos_e)
+ {
+ fprintf(stderr,"Bad argument specification in $DATA_INV(ndatabytes)$\n");
+ return 1;
+ }
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te command */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ if ((nbytes=value_from(args))==0) /* Bad specification of number of bytes */
+ {
+ fprintf(stderr,"Bad specification of ndatabytes in $DATA_INV(ndatabytes)$\n");
+ return 2;
+ }
+ if ((nbytes=value_from(args))==-1) /* Want to process the whole stream */
+ {
+ nbytes=s_bytes;
+ }
+ if ((temp=(char *)malloc(nbytes*2+1))==NULL)
+ {
+ fprintf(stderr,"Cannot asign %li bytes in memory needed for $DATA_INV(ndatabytes)$\n",nbytes*2+1);
+ return 3;
+ }
+ if ((dbuffer=(char *)malloc(nbytes))==NULL)
+ {
+ free(temp);
+ fprintf(stderr,"Cannot asign %li bytes in memory needed for $DATA_INV(ndatabytes)$\n",nbytes);
+ return 3;
+ }
+ if ((readed=fread(dbuffer,1,nbytes,dfp))!=nbytes)
+ {
+ if (padded)
+ {
+ free(dbuffer);
+ free(temp);
+ fprintf(stderr,"Cannot read %li databytes for $DATA_INV(ndatabytes)$ from bitfile\n",nbytes);
+ return 3;
+ }
+ padded=1;
+ memset(dbuffer+readed,0xff,nbytes-readed);
+ }
+
+ if (strstr(cmd,"DATA_INV"))
+ pbi(temp,dbuffer,nbytes); /* Want to inver the bits*/
+ else
+ pb(temp,dbuffer,nbytes); /* Want to use the bits*/
+
+
+ temp[nbytes*2]='\0';
+
+ if (cutputs(temp,ofp,MAX_WIDTH,col))
+ {
+ fprintf(stderr,"Could not write $DATA to file.\n");
+ return 4;
+ }
+
+
+ free(temp);
+ free(dbuffer);
+ return 0;
+ }
+ /* end DATA and DATA_INV command */
+
+ /* ADDRESS command */
+ if (strstr(cmd,"ADDRESS"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $ADDRESS(DIR)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ if (msize<=0x10000)
+ *col+=fprintf(ofp,"%04x",(unsigned int)address);
+ else
+ *col+=fprintf(ofp,"%06x",(unsigned int)address);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ value=value_from(args);
+ address=value;
+ return 0;
+ }
+ /* end ADDRESS command */
+
+ /* SET: CUTLINES command */
+ if (strstr(cmd,"CUTLINES"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $CUTLINES(ON)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%04x",(unsigned int)cutlines);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ value=value_from(args);
+ cutlines=value;
+ return 0;
+ }
+ /* end CUTLINES command */
+
+ /* STEP command */
+ if (strstr(cmd,"STEP"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $STEP(VAL)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%04x",(unsigned int)step);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ value=value_from(args);
+ step=value;
+ return 0;
+ }
+ /* end STEP command */
+
+ /* REWIND command */
+ if (strstr(cmd,"REWIND"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if(args_pos_s || args_pos_e )
+ {
+ fprintf(stderr,"No arguments needed by $REWIND$\n");
+ return 1;
+ }
+ fseek(dfp,stream_s,0);
+ return 0;
+ }
+ /* end REWIND command */
+
+ /* SBITS command */
+ if (strstr(cmd,"SBITS"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $SBITS(VAL)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%d",(unsigned int)s_bits);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ value=value_from(args);
+ s_bits=value;
+ return 0;
+ }
+ /* end SBITS command */
+
+ /* SBYTES command */
+ if (strstr(cmd,"SBYTES"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $SBYTES(VAL)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%d",(unsigned int)s_bytes);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy the argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ value=value_from(args);
+ s_bytes=value;
+ return 0;
+ }
+ /* end SBYTES command */
+
+ /* FILL command */
+ if (strstr(cmd,"FILL"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ separator=strchr(cmd,',');
+ if(!args_pos_s || !args_pos_e || !separator)
+ {
+ fprintf(stderr,"Bad argument specification in $FILL(VAL,TIMES)$\n");
+ return 1;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,4); /* Copy the character */
+ args[4]='\0'; /* Put the null terminator */
+ value=value_from(args);
+ memcpy(args,separator+1,(size_t)(args_pos_e-separator)); /* Copy the times */
+ times=value_from(args);
+ if(times==-1) times=s_bytes;
+ fill(ofp,value,times,col);
+ return 0;
+ }
+ /* end FILL command */
+
+ /* IDMASK command */
+ if (strstr(cmd,"IDMASK"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $IDMASK(VAL)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%s",idmask);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ if (id) free(id);
+ if((id=(char *)malloc(strlen(args)))==NULL)
+ {
+ fprintf(stderr,"Cannot asign memory needed for $IDMASK$\n");
+ return 3;
+ }
+ strcpy(id,args);
+ return 0;
+ }
+ /* end IDMASK command */
+
+
+ /* ID command */
+ if (strstr(cmd,"ID"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $ID(VAL)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%s",id);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ if (id) free(id);
+ if((id=(char *)malloc(strlen(args)))==NULL)
+ {
+ fprintf(stderr,"Cannot asign memory needed for $ID$\n");
+ return 3;
+ }
+ strcpy(id,args);
+ return 0;
+ }
+ /* end ID command */
+
+ /* BSIZE2 command */
+ if (strstr(cmd,"BSIZE2"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if (args_pos_s || args_pos_e)
+ {
+ fprintf(stderr,"$BSIZE2$ is read only\n");
+ return 1;
+ }
+ *col+=fprintf(ofp,"%ld",strtol(bsize,NULL,0)*2);
+ return 0;
+ }
+ /* end BSIZE2 command */
+
+ /* BSIZE command */
+ if (strstr(cmd,"BSIZE"))
+ {
+ /* get the args inside the () */
+ args_pos_s=strchr(cmd,'(');
+ args_pos_e=strchr(cmd,')');
+ if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
+ {
+ fprintf(stderr,"Bad argument specification in $BSIZE(VAL)$\n");
+ return 1;
+ }
+ if (!args_pos_s && !args_pos_e)
+ { /* Want to use the value */
+ *col+=fprintf(ofp,"%s",bsize);
+ return 0;
+ }
+ /* Want to SET the value */
+ memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
+ args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
+ if (id) free(id);
+ if((id=(char *)malloc(strlen(args)))==NULL)
+ {
+ fprintf(stderr,"Cannot asign memory needed for $BSIZE$\n");
+ return 3;
+ }
+ strcpy(bsize,args);
+ return 0;
+ }
+ /* end BSIZE command */
+
+ return 0;
+}
+
+
+int
+repeat (FILE *ifp, FILE *ofp, FILE *dfp,long limit)
+{
+ char line[2001];
+ char *cmd_pos_s=NULL;
+ char *cmd_pos_e=NULL;
+ char cmd[30];
+ long entry_point;
+ long end_address=limit; /*+step; SET: Why?*/
+
+ /* Sanity check */
+ if (limit>0 && address>=end_address)
+ {
+ /* SET: Not an error, the PROMs have some "fillers", when we use the full
+ memory the fillers must be skipped */
+ fprintf(stderr,"WARNING: REPEAT UNTIL 0x%lX but current address is 0x%lX\n",
+ limit,address);
+ if (fgets(line,2001,ifp)==NULL) return 1;
+ do
+ {
+ if (!strncasecmp(line,"--END",5))
+ break;
+ if (fgets(line,2001,ifp)==NULL) return 1; /* get a new line to parse */
+ }
+ while(1);
+ return 0;
+ }
+
+ entry_point=ftell(ifp);
+
+ if (fgets(line,2001,ifp)==NULL) return 1;
+
+ do
+ {
+ int col=0;
+ cmd_pos_e=NULL; /* Ending position of command, also used as flag for a command found or not */
+
+ if (!strncasecmp(line,"--END",5))
+ {
+ address+=step;
+ /* Repeat condition */
+ /* SET: XCF02S can produce address>end_address */
+ if ( (limit==0) || ((limit <0) && feof(dfp)) || ((limit >0) && (address>=end_address)))
+ break;
+ if (ftell(dfp)-stream_s>=s_bytes)
+ {
+ fprintf(stderr,"INFO: Bitstream limit reached\n");
+ //fprintf(stderr,"limit: %ld address %ld end_address %ld\n",limit,address,end_address);
+ break;
+ }
+ /*Sanity check*/
+ if ( (0 < limit) && (end_address < address))
+ {
+ fprintf(stderr,"ERROR: REPEAT UNTIL 0x%lX but current address is 0x%lX (2)\n",limit,address);
+ return 24;
+ }
+ fseek(ifp,entry_point,0);
+ if (fgets(line,2001,ifp)==NULL)
+ return 1; /* get a new line to parse */
+ continue;
+ }
+
+ while((cmd_pos_s=strchr(line,'$'))) /* $ character found in line */
+ {
+
+ if (cmd_pos_e)
+ { /* There was another command on this line before */
+ /* Write intermedia bytes */
+ int size=cmd_pos_s-cmd_pos_e-1;
+ if (fwrite(cmd_pos_e+1,1,size,ofp)!=cmd_pos_s-cmd_pos_e-1)
+ {
+ fprintf(stderr,"There was an error writing to svf file.\n");
+ return 2;
+ }
+ col+=size;
+ }
+ else
+ { /* write from begining of line to the starting $ char to output file */
+ size_t size=cmd_pos_s-line;
+ if (fwrite(line,1,size,ofp)!=(size_t)(cmd_pos_s-line))
+ {
+ fprintf(stderr,"There was an error writing to svf file.\n");
+ return 2;
+ }
+ col+=size;
+ }
+
+ /* clear the starting '$' simbol so i can search the next */
+ *cmd_pos_s='_';
+ if ((cmd_pos_e=strchr(line,'$'))==NULL)
+ {
+ fprintf(stderr,"Parse error: Cant find ending '$' while parsing command.\n");
+ return 3;
+ }
+ *cmd_pos_e='_'; /* clear the ending '$' simbol so i can search the next */
+ memcpy(cmd,cmd_pos_s+1,(size_t)(cmd_pos_e-cmd_pos_s-1)); /* Copy the command */
+ cmd[cmd_pos_e-cmd_pos_s-1]='\0'; /* Put the null terminator */
+ if (do_command(cmd,dfp,ofp,&col))
+ return 3;
+ }
+ /* No more commands */
+ if (cmd_pos_e)
+ {
+ if (fputs(cmd_pos_e+1,ofp)==EOF) return 2; /* Write remainig bytes */
+ }
+ else
+ {
+ /* There was no command */
+ if (fputs(line,ofp)==EOF) return 2; /* Write all the line */
+ }
+
+ if (fgets(line,2001,ifp)==NULL) return 1; /* get a new line to parse */
+ }
+ while (1);
+
+ return 0;
+}
+
diff --git a/fpga/xilinx/programmer/bit2svf/commands.h b/fpga/xilinx/programmer/bit2svf/commands.h
new file mode 100644
index 0000000..e2060f7
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/commands.h
@@ -0,0 +1,5 @@
+long value_from(char *varname);
+void fill(FILE *fp, long c, long t, int *col);
+int do_command(char *cmd, FILE *dfp, FILE *ofp, int *col);
+int repeat (FILE *ifp, FILE *ofp, FILE *dfp,long limit);
+
diff --git a/fpga/xilinx/programmer/bit2svf/debian/changelog b/fpga/xilinx/programmer/bit2svf/debian/changelog
new file mode 100644
index 0000000..37e8cc0
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/debian/changelog
@@ -0,0 +1,76 @@
+bit2svf (1.3.1-1) stable; urgency=low
+
+ * Agregado: XCF08P y XC4VLX25.
+
+ -- Salvador E. Tropea <set@ieee.org> Fri, 21 Dec 2007 12:10:31 -0300
+
+bit2svf (1.3.0-1) stable; urgency=low
+
+ * Agregado: Soporte para memorias en cascada.
+ * Agregado: XCF01S y XCF04S.
+ * Corregido: Temporal no borrado si se definía TEMP.
+
+ -- Salvador E. Tropea <set@ieee.org> Fri, 23 Mar 2007 15:35:29 -0300
+
+bit2svf (1.2.2-1) stable; urgency=low
+
+ * Corregido: mktemp incluye un retorno de carro y eso molesta a
+ algunos shells.
+
+ -- Salvador E. Tropea <set@ieee.org> Thu, 15 Feb 2007 16:28:13 -0300
+
+bit2svf (1.2.1-1) stable; urgency=low
+
+ * Corregido: creación de archivos temporarios.
+
+ -- Salvador E. Tropea <set@ieee.org> Tue, 13 Feb 2007 08:52:40 -0300
+
+bit2svf (1.2.0-2) stable; urgency=low
+
+ * Nuevo jbit.
+
+ -- Salvador E. Tropea <set@ieee.org> Mon, 18 Dec 2006 15:53:04 -0300
+
+bit2svf (1.2.0-1) stable; urgency=low
+
+ * Nueva versión de los templates que usan el algoritmo del Impact 8.2.x.
+ * Agregado soporte para PROMs XCF02S y Spartan 3.
+
+ -- Salvador E. Tropea <set@ieee.org> Thu, 2 Nov 2006 09:39:04 -0300
+
+bit2svf (1.1.0-1) stable; urgency=low
+
+ * Nueva versión que usa templates de algoritmos.
+
+ -- Salvador E. Tropea <set@ieee.org> Mon, 20 Mar 2006 14:46:08 -0300
+
+bit2svf (1.0.0-5) stable; urgency=low
+
+ * Agregado documentación inglés.
+
+ -- Salvador E. Tropea <set@ieee.org> Fri, 30 Sep 2005 11:23:08 -0300
+
+bit2svf (1.0.0-4) stable; urgency=low
+
+ * Agregado ~/.jbitrc
+
+ -- Salvador E. Tropea <set@ieee.org> Wed, 18 May 2005 13:31:18 -0300
+
+bit2svf (1.0.0-3) stable; urgency=low
+
+ * Agregados al jbit.
+
+ -- Salvador E. Tropea <set@ieee.org> Fri, 22 Apr 2005 16:51:06 -0300
+
+bit2svf (1.0.0-2) stable; urgency=low
+
+ * Agregado el script jbit.
+
+ -- Salvador E. Tropea <set@ieee.org> Mon, 18 Apr 2005 16:51:06 -0300
+
+bit2svf (1.0.0-1) stable; urgency=low
+
+ * Initial Debian version.
+
+ -- Salvador E. Tropea <set@ieee.org> Tue, 15 Apr 2005 16:32:37 -0300
+
diff --git a/fpga/xilinx/programmer/bit2svf/debian/control b/fpga/xilinx/programmer/bit2svf/debian/control
new file mode 100644
index 0000000..30d773d
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/debian/control
@@ -0,0 +1,12 @@
+Source: bit2svf
+Maintainer: SET <set@ieee.org>
+Section: contrib/electronics
+Priority: optional
+Standards-Version: 3.5
+
+Package: bit2svf
+Architecture: i386
+Depends: jtag
+Description: Conversor de .BIT a SVF
+ Este programa sirve para generar un archivo SVF con el cual utilizando
+ el programa JTAG para linux, se puede programar una FPGA o una PROM.
diff --git a/fpga/xilinx/programmer/bit2svf/debian/packages b/fpga/xilinx/programmer/bit2svf/debian/packages
new file mode 100644
index 0000000..8477d7b
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/debian/packages
@@ -0,0 +1,40 @@
+# debian/packages for bit2svf
+# Written by Charles Briscoe-Smith, May 1999. Public Domain.
+# Customised for bit2svf by Salvador E. Tropea
+
+Source: bit2svf
+Section: contrib/electronics
+Priority: optional
+Maintainer: SET <set@ieee.org>
+Packager: SET <set@ieee.org>
+Standards-Version: 3.5
+Description: Conversor de .BIT a SVF
+Packaged-For: INTI
+Copyright: GPL
+ Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+ Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
+ Copyright (c) 2001, 2002 by David Sullins
+Major-Changes:
+ Creado.
+Build: sh
+ echo "Hecho!"
+Clean: sh
+ echo "Nada para borrar!"
+
+Package: bit2svf
+Depends: jtag
+Architecture: i386
+Description: Conversor de .BIT a SVF
+ Este programa sirve para generar un archivo SVF con el cual utilizando
+ el programa JTAG para linux, se puede programar una FPGA o una PROM.
+Install: sh
+ yada install -bin bit2svf
+ yada install -bin dumpbit
+ yada install -bin -unstripped jbit
+ yada install -into /usr/share/bit2svf/ templates/*.svft
+ yada install -into /usr/share/bit2svf/ templates/DEVICES
+ yada install -doc README.es
+ yada install -doc README.en
+ yada install -doc -subdir templates templates/README.es
+ yada install -doc -subdir templates templates/README.en
+
diff --git a/fpga/xilinx/programmer/bit2svf/debian/rules b/fpga/xilinx/programmer/bit2svf/debian/rules
new file mode 100755
index 0000000..53d36e8
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/debian/rules
@@ -0,0 +1,128 @@
+#! /usr/bin/make -f
+# Generated automatically from debian/packages
+# by yada v0.9, of Tue, 07 Dec 1999
+
+buildarch := $(shell dpkg --print-architecture)
+
+ifneq "$(buildarch)" "i386"
+buildarch := any
+endif
+
+.PHONY: default
+default:
+ @echo "Specify a target:"; \
+ echo " build compile the package"; \
+ echo " binary make all binary packages"; \
+ echo " binary-arch make all architecture-dependent binary packages"; \
+ echo " binary-indep make all architecture-independent binary packages"; \
+ echo " clean clean up the source package"; \
+ echo; \
+ echo " install-tree compile the package and create the install trees"; \
+ echo " clean-install-tree clean up only under debian/"; \
+ echo
+
+# Build the package and prepare the install tree
+
+.PHONY: build-only build
+build-only: debian/build-stamp
+build: build-only
+
+# Make sure these rules and the control file are up-to-date
+
+.PHONY: rules control
+rules: debian/rules
+debian/rules: debian/yada debian/packages
+ chmod +x debian/yada
+ debian/yada rebuild rules
+
+control: debian/control
+debian/control: debian/yada debian/packages
+ chmod +x debian/yada
+ debian/yada rebuild control
+
+debian/build-stamp:
+ @[ -f debian/yada -a -f debian/rules ]
+ @umask 022 && (\
+ echo -E 'eval "yada () { perl $$(pwd)/debian/yada \"\$$@\"; }"; set -e; set -v';\
+ echo -E 'echo "Hecho!"') | /bin/sh
+ touch debian/build-stamp
+
+.PHONY: install-tree
+install-tree: install-tree-$(buildarch)
+install-tree-i386: \
+ debian/tmp-bit2svf/DEBIAN/control
+install-tree-any:
+
+debian/tmp-bit2svf/DEBIAN/control: debian/build-stamp debian/control
+ rm -rf debian/tmp-bit2svf
+ umask 022 && install -d debian/tmp-bit2svf/DEBIAN
+ chmod +x debian/yada
+ install -d debian/tmp-bit2svf/usr/share/doc/bit2svf
+ umask 022; debian/yada generate copyright \
+ >debian/tmp-bit2svf/usr/share/doc/bit2svf/copyright
+ install -m 644 -p debian/changelog \
+ debian/tmp-bit2svf/usr/share/doc/bit2svf/changelog
+ @umask 022 && export PACKAGE="bit2svf" \
+ && export ROOT="$$(pwd)/debian/tmp-bit2svf" \
+ && export CONTROL="$$(pwd)/debian/tmp-bit2svf/DEBIAN" && (\
+ echo -E 'eval "yada () { perl $$(pwd)/debian/yada \"\$$@\"; }"; set -e; set -v';\
+ echo -E 'yada install -bin bit2svf';\
+ echo -E 'yada install -bin dumpbit';\
+ echo -E 'yada install -bin -unstripped jbit';\
+ echo -E 'yada install -into /usr/share/bit2svf/ templates/*.svft';\
+ echo -E 'yada install -into /usr/share/bit2svf/ templates/DEVICES';\
+ echo -E 'yada install -doc README.es';\
+ echo -E 'yada install -doc README.en';\
+ echo -E 'yada install -doc -subdir templates templates/README.es';\
+ echo -E 'yada install -doc -subdir templates templates/README.en') | /bin/sh
+ debian/yada compress bit2svf
+ find debian/tmp-bit2svf -type f -print \
+ | sed -n 's/^debian\/tmp-bit2svf\(\/etc\/.*\)$$/\1/p' \
+ > debian/tmp-bit2svf/DEBIAN/conffiles
+ if test ! -s debian/tmp-bit2svf/DEBIAN/conffiles; then rm -f debian/tmp-bit2svf/DEBIAN/conffiles; fi
+ debian/yada generate maintscripts bit2svf
+ umask 022 && dpkg-gencontrol -isp -pbit2svf -Pdebian/tmp-bit2svf
+
+# Build package files
+
+.PHONY: binary binary-arch binary-indep
+binary: binary-arch binary-indep
+binary-arch: binary-arch-$(buildarch)
+
+.PHONY: binary-arch-i386
+binary-arch-i386: \
+ binary-package-bit2svf
+.PHONY: binary-arch-any
+binary-arch-any:
+binary-indep:
+
+.PHONY: binary-package-bit2svf
+binary-package-bit2svf: check-root debian/tmp-bit2svf/DEBIAN/control
+ @[ -f debian/yada -a -f debian/rules ]
+ chown -R 0.0 debian/tmp-bit2svf
+ chmod -R u=rwX,go=rX debian/tmp-bit2svf
+ @if [ -d debian/tmp-bit2svf/usr/doc/bit2svf ]; then \
+ echo "*** Yada warning: /usr/doc/bit2svf should be /usr/share/doc/bit2svf";\
+ fi
+ dpkg-deb --build debian/tmp-bit2svf ..
+
+.PHONY: check-root
+check-root:
+ @[ `id -u` = 0 ] || (echo "You must be root to do this!"; false)
+
+# Clean up afterwards
+
+.PHONY: clean clean-install-tree clean-build
+clean: clean-install-tree clean-build debian/control debian/rules
+
+clean-build:
+ @[ -f debian/yada -a -f debian/rules ]
+ rm -f debian/build-stamp debian/depends-stamp
+ @umask 022 && (\
+ echo -E 'eval "yada () { perl $$(pwd)/debian/yada \"\$$@\"; }"; set -e; set -v';\
+ echo -E 'echo "Nada para borrar!"') | /bin/sh
+
+clean-install-tree: debian/rules
+ @[ -f debian/yada -a -f debian/rules ]
+ rm -f debian/install-tree-stamp
+ rm -rf debian/tmp* debian/files* debian/substvars
diff --git a/fpga/xilinx/programmer/bit2svf/debian/yada b/fpga/xilinx/programmer/bit2svf/debian/yada
new file mode 100755
index 0000000..a6ee08a
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/debian/yada
@@ -0,0 +1,1557 @@
+#! /usr/bin/perl -w
+# yada -- Yet Another Debianisation Aid
+# Copyright 1999 Charles Briscoe-Smith
+#
+# 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
+#
+# You can contact me by email at <cpbs@debian.org>
+#
+# $Id: yada,v 1.1 2005/04/15 21:07:44 salvador Exp $
+
+# Bugs:
+#
+# - Build depends and build conflicts do not take virtual packages into
+# account. This is a hard one to fix while not breaking encapsulation
+# on dpkg's database. Here's one method of extracting a copy of the
+# status file using only dpkg's defined interface:
+# dpkg --get-selections '*' | sed 's/[^!-~].*//' | xargs dpkg -s > status
+
+$modified = "";
+
+# $Format: "$project = \"$Project$\";"$
+$project = "yada";
+# $Format: "$projectversion = \"$ProjectVersion$\";"$
+$projectversion = "0.9";
+# $Format: "$projectdate = \"$ProjectDate$\";"$
+$projectdate = "Tue, 07 Dec 1999 20:15:08 +0000";
+# If you modify this file (e.g. for an NMU) please add a version line:
+#$modified .= "Modified by XXX on yyyy/mm/dd\n";
+
+$projectdate =~ s/ ..\:.*//;
+$yadaversion = "Yet Another Debianization Aid ($project v$projectversion, of $projectdate)\n${modified}Copyright 1999 Charles Briscoe-Smith.\nReleased as free software under the terms of the GNU General Public License.";
+
+########################################################################
+# Standard ways of printing error messages
+########################################################################
+sub choke {
+ print STDERR "@_ (Say `$0 --help' for help)\n";
+ exit 1;
+}
+
+BEGIN {
+ my $errors=0;
+ sub gasp {
+ print STDERR "@_\n";
+ $errors++;
+ }
+
+ sub chokepoint {
+ choke "Stopping after $errors errors." if $errors;
+ }
+}
+
+########################################################################
+# Execute an external program, and bomb out if errors occur
+########################################################################
+sub run {
+ print " -> @_\n";
+ if (my $pid = fork) {
+ waitpid $pid, 0;
+ choke "*** YADA error: $_[0] exited with status $?\n" if $? != 0;
+ } elsif (defined $pid) {
+ exec @_ or exit 1;
+ } else {
+ die "Cannot fork a child process";
+ }
+}
+
+########################################################################
+# Pull selected values out of the environment
+########################################################################
+sub getvars {
+ $ROOT=$ENV{"ROOT"};
+ $CONTROL=$ENV{"CONTROL"};
+ $PACKAGE=$ENV{"PACKAGE"};
+ if (not defined $ROOT) {
+ die "I must be called from within a rules file. (ROOT is not defined)\n";
+ }
+ if (not defined $CONTROL) {
+ die "I must be called from within a rules file. (CONTROL is not defined)\n";
+ }
+ if (not defined $PACKAGE) {
+ die "I must be called from within a rules file. (PACKAGE is not defined)\n";
+ }
+}
+
+########################################################################
+# Read paragraphs from debian/packages
+########################################################################
+# Read a paragraph into %par
+sub getpara {
+ while (<PACKAGES>) {
+ next if m/^\s*\#/;
+ s/\s+$//;
+ last unless m/^$/;
+ }
+ %par=();
+ while (defined) {
+ m/^([-A-Za-z0-9]+)\s*\:\s*(.*)$/ or die "Invalid line found";
+ $keyword=$1;
+ $keyword=~tr/A-Z/a-z/;
+ $contents=$2;
+ while (<PACKAGES>) {
+ next if m/^\#/;
+ s/\s+$//s;
+ last unless s/^(\s)//;
+ $x=$1;
+ s/^/$x/ if $x ne " ";
+ s/^\.(\.*)$/$1/;
+ $contents.="\n".$_;
+ }
+ $contents=~s/^\n//s;
+ $par{$keyword}=$contents;
+ last if not defined or m/^$/;
+ }
+}
+
+########################################################################
+# Parse source package from debian/packages
+########################################################################
+%sourcefields=(
+ "source"=>1, "section"=>1, "priority"=>1, "maintainer"=>1,
+ "standards-version"=>1, "upstream-source"=>1, "copyright"=>1,
+ "major-changes"=>1, "packaged-for"=>1, "description"=>1, "build"=>1,
+ "clean"=>1, "home-page"=>1, "packager"=>1, "other-maintainers"=>1,
+ "build-conflicts"=>1, "build-depends"=>1, "build-sequence"=>1,
+ "patches"=>1,
+);
+
+sub parsesourcepara {
+ if ($sourceparanum) {
+ gasp "Paragraph $paragraphnum: duplicate source package.\n Previously got source package from paragraph $sourceparanum.";
+ }
+ $sourceparanum=$paragraphnum;
+ my %srcpar=();
+ for (keys %par) {
+ if (not defined $sourcefields{$_}) {
+ gasp "Paragraph $paragraphnum: field `$_' not recognised for source packages.";
+ }
+ $srcpar{$_}=$par{$_};
+ }
+ %source=%par;
+}
+
+########################################################################
+# Parse binary package from debian/packages
+########################################################################
+%binaryfields=(
+ "package"=>1, "architecture"=>1, "section"=>1, "priority"=>1,
+ "essential"=>1, "pre-depends"=>1, "depends"=>1, "recommends"=>1,
+ "suggests"=>1, "provides"=>1, "conflicts"=>1, "replaces"=>1,
+ "description"=>1, "install"=>1, "finalise"=>1, "finalize"=>1,
+ "preinst"=>1, "postinst"=>1, "prerm"=>1, "postrm"=>1, "changelog"=>1,
+ "doc-depends"=>1, "alternatives"=>1, "menu"=>1, "shlibs"=>1,
+ "contains-libs"=>1, "doc-base"=>1,
+);
+
+sub parsebinarypara {
+ my $pkg=$par{"package"};
+ if ($binaryparanum{$pkg}) {
+ gasp "Paragraph $paragraphnum: duplicate binary package.\n Previously got binary package `$pkg' from paragraph $binaryparanum{$pkg}.";
+ }
+ $binaryparanum{$pkg}=$paragraphnum;
+ my %binpar=();
+ foreach (keys %par) {
+ if (not defined $binaryfields{$_}) {
+ gasp "Paragraph $paragraphnum: field `$_' not recognised for binary packages."
+ }
+ $binpar{$_}=$par{$_};
+ }
+ $binary{$pkg}=\%binpar;
+}
+
+########################################################################
+# Open, read and parse the whole of debian/packages
+########################################################################
+sub readpackages {
+ open PACKAGES, "debian/packages"
+ or die "Can't open debian/packages for reading";
+ local $paragraphnum=0;
+ my @skipped=();
+ &getpara;
+ while (1) {
+ $paragraphnum++;
+ last if not %par;
+ if (exists $par{"ignore"}) {
+ push @skipped, $paragraphnum;
+ } else {
+ # What sort of paragraph is this?
+ if (defined $par{"source"}) {
+ &parsesourcepara;
+ } elsif (defined $par{"package"}) {
+ &parsebinarypara;
+ } else {
+ gasp "Paragraph $paragraphnum: contains neither `source' nor `package' field.";
+ }
+ }
+ &getpara;
+ }
+ print "Paragraphs skipped: @skipped\n" if @skipped;
+ &chokepoint;
+}
+
+########################################################################
+# Output control-file fields
+########################################################################
+# Print a key/value pair to the given filehandle.
+sub printkey {
+ my ($OUT, $k, $v)=@_;
+ if ($v=~m/^\./m) { die "Can't escape . at start of line"; }
+ $k=~s/(^|-)(.)/$1\u$2/g;
+ $v=~s/^$/./gm;
+ $v=~s/^/ /gm;
+ print $OUT "$k:$v\n" or die "Can't write to output file";
+}
+
+# Print, to the given filehandle, the named keys from the given paragraph
+sub printkeys {
+ my ($OUT, $par, @keys)=@_;
+ foreach (@keys) {
+ if (defined $$par{$_}) { printkey $OUT, $_, $$par{$_}; }
+ }
+}
+
+########################################################################
+# Output Makefile fragments
+########################################################################
+# Print, on the given handle, make rules to execute the given executable
+# field.
+sub makescript {
+ my ($OUT, $fieldname, $pre, $text) = @_;
+ $_ = $text;
+ if (defined) {
+ if (s/^sh\n//s) {
+ # shell script
+ chomp;
+ s=^=set -e; set -v\n=s;
+ s=^=eval "yada () { perl \$(pwd)/debian/yada \\\"\\\$\@\\\"; }"; =s;
+ s/'/'\\''/g;
+ s/\$/\$\$/g;
+ s/\n/';\\\n\techo -E '/gs;
+ print OUT "$pre && (\\\n\techo -E '" or die;
+ print OUT or die;
+ print OUT "') | /bin/sh\n" or die;
+ } else {
+ gasp "Unknown executable type for `$fieldname'\n";
+ }
+ }
+}
+
+########################################################################
+# Append a line to a file, discarding duplicates
+########################################################################
+sub append {
+ my ($file, $line, $upto) = @_;
+ my $sep = $line;
+ $sep =~ s/$upto.*//s if defined $upto;
+ open APPENDOUT, ">$file.new" or die "Cannot open `$file.new' for output";
+ if (-f $file) {
+ open APPENDIN, "<$file" or die "Cannot open `$file' for input";
+ while (<APPENDIN>) {
+ my $tmp = $_;
+ s/$upto.*//s if defined $upto;
+ print APPENDOUT $tmp unless $_ eq $sep;
+ }
+ close APPENDIN or die "Cannot close `$file'";
+ }
+ print APPENDOUT $line or die "Cannot write to `$file.new'";
+ close APPENDOUT or die "Cannot close `$file.new'";
+ rename "$file.new", "$file" or die "Cannot rename `$file.new' to `$file'";
+}
+
+########################################################################
+# Convert package name into something which can be used for a substvar
+# name -- no dots or pluses, but colons are okay
+########################################################################
+sub normalise {
+ my ($pkg) = @_;
+ $pkg =~ s/\./:d/g;
+ $pkg =~ s/\+/:p/g;
+ return $pkg;
+}
+
+########################################################################
+# Main program starts here
+########################################################################
+if (not defined($_=shift) or m/^(-h|--h(e(lp?)?)?)$/i) {
+ print "$0: $yadaversion
+Usage: yada action [args...]
+Notably:
+ yada rebuild control|rules
+ yada install [-dir|-data|-doc|-bin|-script|-game|-lib|-man|-conffile]
+ [-x|-non-x] [-stripped|-unstripped] [-exec|-no-exec]
+ [-into <dir>] [-as <name>] [-subdir <subdir>]
+ [-section <mansect>] <file>...
+ yada undocumented [-x|-non-x] [-section <mansect>] <name>...
+ yada fixup libtool [path/to/libtool]
+ yada yada
+";
+ #yada symlink [-doc|-bin|-game|-lib|-man] [-into <dir>] [-as <name>]
+ # <file>...
+ if (defined) { exit 0; } else { exit 1; }
+}
+
+if (m/^(-v|--v(e(r(s(i(on?)?)?)?)?)?)$/i) {
+ print "$0: $yadaversion\n";
+ exit 0;
+}
+
+if (m/^rebuild$/i) {
+ if (not defined($_=shift)) { choke "Rebuild what?"; }
+
+ ######################################################################
+ # Rebuild debian/control
+ ######################################################################
+ if (m/^control$/i) {
+ &readpackages;
+ open OUT, ">debian/control.new"
+ or die "Can't open debian/control.new for writing";
+ @skipped=();
+ foreach ("source", "maintainer", "section", "priority", "standards-version")
+ {
+ if (defined $source{$_}) { &printkey(*OUT{IO}, $_, $source{$_}); }
+ }
+ for (keys %binary) {
+ $par=$binary{$_};
+ if ($$par{"architecture"}=~m/none/i) {
+ push @skipped, $$par{"package"};
+ } else {
+ $npkg = normalise($$par{"package"});
+ if (defined $$par{"pre-depends"}) {
+ $$par{"pre-depends"} =~
+ s/(^|\, ?)\s*\[.*?\]\s*(\,|$)/$1\${$npkg:Pre-Depends}$2/;
+ $$par{"pre-depends"} =~ s/(\,\s*\[.*?\]\s*)+(\,|$)/$2/g;
+ }
+ if (defined $$par{"depends"}) {
+ $$par{"depends"} =~
+ s/(^|\, ?)\s*\[.*?\]\s*(\,|$)/$1\${$npkg:Depends}$2/;
+ $$par{"depends"} =~ s/(\,\s*\[.*?\]\s*)+(\,|$)/$2/g;
+ }
+ if (defined $$par{"recommends"}) {
+ $$par{"recommends"} =~
+ s/(^|\, ?)\s*\[.*?\]\s*(\,|$)/$1\${$npkg:Recommends}$2/;
+ $$par{"recommends"} =~ s/(\,\s*\[.*?\]\s*)+(\,|$)/$2/g;
+ }
+ if (defined $$par{"suggests"}) {
+ $$par{"suggests"} =~
+ s/(^|\, ?)\s*\[.*?\]\s*(\,|$)/$1\${$npkg:Suggests}$2/;
+ $$par{"suggests"} =~ s/(\,\s*\[.*?\]\s*)+(\,|$)/$2/g;
+ }
+ print OUT "\n" or die "Can't write to debian/control.new";
+ &printkeys(*OUT{IO}, $par, "package", "architecture", "section",
+ "priority", "essential", "pre-depends", "depends",
+ "recommends", "suggests", "provides", "conflicts",
+ "replaces");
+ if (defined $$par{"description"}) {
+ $_ = "$source{\"description\"}\n";
+ s/^.*\n//;
+ s/(.)$/$1\n/s;
+ $$par{"description"} =~ m/^([^\n]*)\n(.*)/s;
+ &printkey(*OUT{IO}, "description", "$1\n$_$2");
+ }
+ }
+ }
+ print "Skipped binary packages: @skipped\n" if @skipped;
+ close OUT or die "Can't close debian/control.new";
+ rename "debian/control.new", "debian/control"
+ or die "Can't rename debian/control.new to debian/control";
+ exit 0;
+ }
+
+ ######################################################################
+ # Rebuild debian/rules
+ ######################################################################
+ if (m/^rules$/i) {
+ open OUT, ">debian/rules.new"
+ or die "Cannot open debian/rules.new for writing";
+ &readpackages;
+
+ $avoidroot=0;
+ $buildseq=$source{"build-sequence"};
+ $buildconfls=$source{"build-conflicts"};
+ $builddeps=$source{"build-depends"};
+
+ %packages=();
+ %architectures=();
+
+ %install=();
+ %architecture=();
+ %finalise=();
+ %docdep=();
+ %preinst=();
+ %postinst=();
+ %prerm=();
+ %postrm=();
+ %predepends=();
+ %depends=();
+ %recommends=();
+ %suggests=();
+
+ for (keys %binary) {
+ $par=$binary{$_};
+ $pkg=$$par{"package"};
+ $packages{$pkg}++;
+ $architecture{$pkg}=$$par{"architecture"};
+ $finalise{$pkg}=$$par{"finalise"};
+ if (defined $$par{"finalize"}) {
+ if (defined $finalise{$pkg}) {
+ gasp "Package `$pkg' has both `Finalise' and `Finalize'.\n";
+ } else {
+ $finalise{$pkg}=$$par{"finalize"};
+ }
+ }
+ $architecture{$pkg}=$$par{"architecture"};
+ $install{$pkg}=$$par{"install"};
+ $docdep{$pkg}=$$par{"doc-depends"};
+ $preinst{$pkg}=$$par{"preinst"};
+ $postinst{$pkg}=$$par{"postinst"};
+ $prerm{$pkg}=$$par{"prerm"};
+ $postrm{$pkg}=$$par{"postrm"};
+ $_=$$par{"pre-depends"};
+ if (defined) {
+ $_=join " ", grep s/^\[\s*(.+?)\s*\]$/$1/, split /\s*,\s*/;
+ s=(^| )/?([^ ])=$1debian/tmp-$pkg/$2=g;
+ $predepends{$pkg}=$_ if $_ ne "";
+ }
+ $_=$$par{"depends"};
+ if (defined) {
+ $_=join " ", grep s/^\[\s*(.+?)\s*\]$/$1/, split /\s*,\s*/;
+ s=(^| )/?([^ ])=$1debian/tmp-$pkg/$2=g;
+ $depends{$pkg}=$_ if $_ ne "";
+ }
+ $_=$$par{"recommends"};
+ if (defined) {
+ $_=join " ", grep s/^\s*\[(.+?)\s*\]$/$1/, split /\s*,\s*/;
+ s=(^| )/?([^ ])=$1debian/tmp-$pkg/$2=g;
+ $recommends{$pkg}=$_ if $_ ne "";
+ }
+ $_=$$par{"suggests"};
+ if (defined) {
+ $_=join " ", grep s/^\s*\[(.+?)\s*\]$/$1/, split /\s*,\s*/;
+ s=(^| )/?([^ ])=$1debian/tmp-$pkg/$2=g;
+ $suggests{$pkg}=$_ if $_ ne "";
+ }
+ $_=$architecture{$pkg};
+ if (defined) {
+ foreach (split / +/) {
+ $architectures{$_}++;
+ }
+ }
+ }
+
+ delete $architectures{"all"};
+ delete $architectures{"any"};
+
+ if (defined $buildseq) {
+ if ($buildseq =~ m/^avoid-root$/i) {
+ $avoidroot=1;
+ } elsif (not $buildseq =~ m/^conserve-space$/i) {
+ gasp "Unrecognised `Build-Sequence'; assuming `conserve-space'.\n",
+ " Build-Sequence: avoid-root | conserve-space\n";
+ }
+ }
+
+ ############################################################################
+ print OUT "#! /usr/bin/make -f
+# Generated automatically from debian/packages
+# by $project v$projectversion, of $projectdate
+" or die;
+ $_ = $modified;
+ s/^(.)/# &/g;
+ print OUT or die;
+ $usearches=0;
+ if (%architectures) {
+ $usearches=1;
+ print OUT "\nbuildarch := \$(shell dpkg --print-architecture)\n\n" or die;
+ foreach (keys %architectures) {
+ print OUT "ifneq \"\$(buildarch)\" \"$_\"\n" or die;
+ }
+ print OUT "buildarch := any\n" or die;
+ foreach (keys %architectures) {
+ print OUT "endif\n" or die;
+ }
+ }
+
+ $patch=$source{"patches"};
+ if (defined $patch) {
+ $patch="debian/".$patch;
+ }
+
+ ############################################################################
+ print OUT <<END or die;
+
+.PHONY: default
+default:
+ \@echo \"Specify a target:\"; \\
+ echo \" build compile the package\"; \\
+ echo \" binary make all binary packages\"; \\
+ echo \" binary-arch make all architecture-dependent binary packages\"; \\
+ echo \" binary-indep make all architecture-independent binary packages\"; \\
+ echo \" clean clean up the source package\"; \\
+ echo; \\
+END
+ print OUT <<END or die if defined $buildconfls or defined $builddeps;
+ echo \" depends check build-time dependencies\"; \\
+END
+ print OUT <<END or die if defined $patch;
+ echo \" patch apply patches from $patch\"; \\
+ echo \" unpatch unapply patches from ${patch}{,disabled}\"; \\
+END
+ print OUT <<END or die if $avoidroot;
+ echo \" build-only compile the package but do not create any install trees\"; \\
+END
+ print OUT <<END or die unless $avoidroot;
+ echo \" install-tree compile the package and create the install trees\"; \\
+END
+ print OUT <<END or die;
+ echo \" clean-install-tree clean up only under debian/\"; \\
+ echo
+
+END
+################################################################################
+ if (defined $buildconfls or defined $builddeps) {
+ print OUT <<END or die;
+# Check build dependencies and conflicts
+
+.PHONY: depends
+depends: debian/depends-stamp
+debian/depends-stamp:
+ \@echo 'Checking build conflicts and dependencies; just a minute...'
+END
+
+ if (defined $buildconfls) {
+ $_=$buildconfls;
+ s/^\s*(.*?)\s*$/$1/;
+ foreach (split /\s*,\s*/) {
+ if (m/^([-+.a-zA-Z0-9]+)(?:\s*\(\s*(\<\<|\<\=|\=|\>\=|\>\>)\s*([-+.:a-zA-Z0-9]+)\s*\))?$/) {
+ $spec="$1";
+ if (defined $2) {
+ $spec.=" (version $2 $3)";
+ } else {
+ $spec.=" (any version)";
+ }
+ print OUT "\t\@echo -n '$1...'; v=\$\$(dpkg -s '$1' | sed -n '/^[sS][tT][aA][tT][uU][sS]:.* config-files\$\$/q;s/^[vV][eE][rR][sS][iI][oO][nN]: *//p'); \\
+\tif test \"\$\$v\"" or die;
+ if (defined $2) {
+ print OUT " && dpkg --compare-versions \"\$\$v\" '$2' '$3'" or die;
+ }
+ print OUT "; then \\
+\t echo '*** Build conflicts with package $spec, which is installed'; \\
+\t exit 1; \\
+\tfi\n" or die;
+ # if (defined $2) {
+ # print "Processing conflict with package `$1', versioning ($2 $3) not yet checked\n";
+ # }
+ } else {
+ gasp "Invalid `Build-Conflicts' syntax: `$_'\n";
+ }
+ }
+ }
+
+ if (defined $builddeps) {
+ $_=$builddeps;
+ s/^\s*(.*?)\s*$/$1/;
+ foreach (split /\s*,\s*/) {
+ $speclist="";
+ foreach (split /\s*\|\s*/) {
+ if (m/^([-+.a-zA-Z0-9]+)(?:\s*\(\s*(\<\<|\<\=|\=|\>\=|\>\>)\s*([-+.:a-zA-Z0-9]+)\s*\))?$/) {
+ $spec="`$1'";
+ if (defined $2) {
+ $spec.=" (version $2 $3)";
+ } else {
+ $spec.=" (any version)";
+ }
+ if ($speclist eq "") { $at="\@"; } else { $at=""; }
+ $speclist.=", or $spec";
+ print OUT "\t${at}echo -n '$1...'; v=\$\$(dpkg -s '$1' | sed -n '/^[sS][tT][aA][tT][uU][sS]:.* config-files\$\$/q;s/^[vV][eE][rR][sS][iI][oO][nN]: *//p'); \\
+\tif test \"\$\$v\"; then \\\n" or die;
+ if (defined $2) {
+ print OUT "\t if dpkg --compare-versions \"\$\$v\" '$2' '$3'; then \\\n" or die;
+ }
+ print OUT "\t exit 0; \\\n" or die;
+ if (defined $2) {
+ print OUT "\t fi; \\\n" or die;
+ }
+ print OUT "\tfi; \\\n" or die;
+ } else {
+ gasp "Invalid `Build-Depends' syntax: `$_'\n";
+ }
+ }
+ $speclist =~ s/^, or //;
+ $speclist =~ s/'/'\\''/g;
+ print OUT "\techo 'Build depends on $speclist, which is not satisfied' | fmt; exit 1\n" or die;
+ }
+ }
+ print OUT <<END or die;
+ \@echo
+ \@echo 'Conflicts and dependencies all satisfied!'
+ touch debian/depends-stamp
+
+END
+ }
+
+ ############################################################################
+
+ print OUT <<END or die if defined $patch;
+.PHONY: patch unpatch
+# Apply patches matching `$patch' to the source tree,
+# and unapply any applied patches `$patch.disabled'
+patch: debian/patch-stamp
+debian/patch-stamp:
+ \@set -e; backupdirs=\$\$(ls -d debian/backup-* 2>/dev/null | wc -l); \\
+ if test \$\$backupdirs -gt 1; then \\
+ echo \"*** Yada error: There are multiple debian/backup-* directories.\"; \\
+ echo \"*** I can't cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ if test \$\$backupdirs = 1; then \\
+ patchname=\"\$\$(echo debian/backup-* | sed 's=^debian/backup-==')\"; \\
+ echo \"*** Cleaning up after interrupted patching run for \$\$patchname\"; \\
+ if test -f \"debian/patch-\$\$patchname-applied\"; then \\
+ rm -rf \"debian/backup-\$\$patchname\"; \\
+ else \\
+ (cd \"debian/backup-\$\$patchname\"; find . -type f -print0) | xargs -0ri mv -f -- debian/backup-\$\$patchname/{} {}; \\
+ find \"debian/backup-\$\$patchname\" -depth -type d -exec rmdir '{}' \\;; \\
+ if test -e \"debian/backup-\$\$patchname\"; then \\
+ echo \"*** Yada error: I could not recover cleanly from an interrupted patch.\"; \\
+ echo \"*** I can't cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ fi; \\
+ fi
+
+ \@set -e; backdowndirs=\$\$(ls -d debian/backdown-* 2>/dev/null | wc -l); \\
+ if test \$\$backdowndirs -gt 1; then \\
+ echo \"*** Yada error: There are multiple debian/backdown-* directories.\"; \\
+ echo \"*** I can't cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ if test \$\$backdowndirs = 1; then \\
+ patchname=\"\$\$(echo debian/backdown-* | sed 's=^debian/backdown-==')\"; \\
+ echo \"*** Cleaning up after interrupted unpatching run for \$\$patchname\"; \\
+ if test ! -f \"debian/patch-\$\$patchname-applied\"; then \\
+ rm -rf \"debian/backdown-\$\$patchname\"; \\
+ else \\
+ (cd \"debian/backdown-\$\$patchname\"; find . -type f -print0) | xargs -0ri mv -f -- debian/backdown-\$\$patchname/{} {}; \\
+ find \"debian/backdown-\$\$patchname\" -depth -type d -exec rmdir '{}' \\;; \\
+ if test -e \"debian/backdown-\$\$patchname\"; then \\
+ echo \"*** Yada error: I could not recover cleanly from an interrupted patch.\"; \\
+ echo \"*** I can't cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ fi; \\
+ fi
+
+ \@set -e; for stampfile in debian/patch-*-applied; do \\
+ if test -f \"\$\$stampfile\"; then \\
+ patchname=\"\$\$(echo \"\$\$stampfile\" | sed 's=^debian/patch-\\(.*\\)-applied\$\$=\\1=')\"; \\
+ patchfile=\"debian/\$\$patchname.disabled\"; \\
+ if test -f \"\$\$patchfile\"; then \\
+ echo \"*** \$\$patchfile is now disabled; patching it out\"; \\
+ patchoptions=\"\$\$(sed -n '/^#PATCHOPTIONS:/{;s/^[^:]*://;p;q;}' <\"\$\$patchfile\")\"; \\
+ patch -R -f -i \"\$\$patchfile\" -b -V simple -B \"debian/backdown-\$\$patchname/\" \$\$patchoptions; \\
+ rm -f \"\$\$stampfile\"; \\
+ rm -rf \"debian/backdown-\$\$patchname\"; \\
+ fi; \\
+ fi; \\
+ done
+
+ \@set -e; for patchfile in $patch; do \\
+ if test -f \"\$\$patchfile\"; then \\
+ patchname=\"\$\$(echo \"\$\$patchfile\" | sed 's=^debian/==')\"; \\
+ stampfile=\"debian/patch-\$\$patchname-applied\"; \\
+ if test ! -f \"\$\$stampfile\"; then \\
+ echo \"*** Applying patch from \$\$patchname\"; \\
+ patchoptions=\"\$\$(sed -n '/^#PATCHOPTIONS:/{;s/^[^:]*://;p;q;}' <\"\$\$patchfile\")\"; \\
+ patch -N -f -i \"\$\$patchfile\" -b -V simple -B \"debian/backup-\$\$patchname/\" \$\$patchoptions; \\
+ touch \"\$\$stampfile\"; \\
+ rm -rf \"debian/backup-\$\$patchname\"; \\
+ fi; \\
+ fi; \\
+ done
+
+ touch debian/patch-stamp
+
+# Remove all managed patches from the source tree
+unpatch:
+ \@set -e; backupdirs=\$\$(ls -d debian/backup-* 2>/dev/null | wc -l); \\
+ if test \$\$backupdirs -gt 1; then \\
+ echo \"*** Yada error: There are multiple debian/backup-* directories.\"; \\
+ echo \"*** I can not cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ if test \$\$backupdirs = 1; then \\
+ patchname=\"\$\$(echo debian/backup-* | sed 's=^debian/backup-==')\"; \\
+ echo \"*** Cleaning up after interrupted patching run for \$\$patchname\"; \\
+ if test -f \"debian/patch-\$\$patchname-applied\"; then \\
+ rm -rf \"debian/backup-\$\$patchname\"; \\
+ else \\
+ (cd \"debian/backup-\$\$patchname\"; find . -type f -print0) | xargs -0ri mv -f -- debian/backup-\$\$patchname/{} {}; \\
+ find \"debian/backup-\$\$patchname\" -depth -type d -exec rmdir '{}' \\;; \\
+ if test -e \"debian/backup-\$\$patchname\"; then \\
+ echo \"*** Yada error: I could not recover cleanly from an interrupted patch.\"; \\
+ echo \"*** I can not cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ fi; \\
+ fi
+
+ \@set -e; backdowndirs=\$\$(ls -d debian/backdown-* 2>/dev/null | wc -l); \\
+ if test \$\$backdowndirs -gt 1; then \\
+ echo \"*** Yada error: There are multiple debian/backdown-* directories.\"; \\
+ echo \"*** I can not cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ if test \$\$backdowndirs = 1; then \\
+ patchname=\"\$\$(echo debian/backdown-* | sed 's=^debian/backdown-==')\"; \\
+ echo \"*** Cleaning up after interrupted unpatching run for \$\$patchname\"; \\
+ if test ! -f \"debian/patch-\$\$patchname-applied\"; then \\
+ rm -rf \"debian/backdown-\$\$patchname\"; \\
+ else \\
+ (cd \"debian/backdown-\$\$patchname\"; find . -type f -print0) | xargs -0ri mv -f -- debian/backdown-\$\$patchname/{} {}; \\
+ find \"debian/backdown-\$\$patchname\" -depth -type d -exec rmdir '{}' \\;; \\
+ if test -e \"debian/backdown-\$\$patchname\"; then \\
+ echo \"*** Yada error: I could not recover cleanly from an interrupted patch.\"; \\
+ echo \"*** I can not cope. Please clean up for me.\"; \\
+ exit 1; \\
+ fi; \\
+ fi; \\
+ fi
+
+ \@set -e; for stampfile in debian/patch-*-applied; do \\
+ if test -f \"\$\$stampfile\"; then \\
+ patchname=\"\$\$(echo \"\$\$stampfile\" | sed 's=^debian/patch-\\(.*\\)-applied\$\$=\\1=')\"; \\
+ patchfile=\"debian/\$\$patchname\"; \\
+ if test ! -f \"\$\$patchfile\"; then \\
+ patchfile=\"\$\$patchfile.disabled\"; \\
+ fi; \\
+ if test -f \"\$\$patchfile\"; then \\
+ echo \"*** Removing patch from \$\$patchname\"; \\
+ patchoptions=\"\$\$(sed -n '/^#PATCHOPTIONS:/{;s/^[^:]*://;p;q;}' <\"\$\$patchfile\")\"; \\
+ patch -R -f -i \"\$\$patchfile\" -b -V simple -B \"debian/backdown-\$\$patchname/\" \$\$patchoptions; \\
+ rm -f \"\$\$stampfile\"; \\
+ rm -rf \"debian/backdown-\$\$patchname\"; \\
+ else \\
+ echo \"*** Yada warning: Cannot find a patchfile named \\`\$\$patchname' to unapply\"; \\
+ fi; \\
+ fi; \\
+ done
+
+ rm -f debian/patch-stamp
+
+END
+
+ print OUT <<END or die;
+# Build the package and prepare the install tree
+
+.PHONY: build-only build
+build-only: debian/build-stamp
+END
+ ############################################################################
+
+ if ($avoidroot) {
+ print OUT "build: install-tree\n" or die;
+ } else {
+ print OUT "build: build-only\n" or die;
+ }
+
+ ############################################################################
+ print OUT <<END or die;
+
+# Make sure these rules and the control file are up-to-date
+
+.PHONY: rules control
+rules: debian/rules
+debian/rules: debian/yada debian/packages
+ chmod +x debian/yada
+ debian/yada rebuild rules
+
+control: debian/control
+debian/control: debian/yada debian/packages
+ chmod +x debian/yada
+ debian/yada rebuild control
+
+END
+ print OUT "debian/build-stamp:" or die;
+ if (defined $buildconfls or defined $builddeps) {
+ print OUT " debian/depends-stamp" or die;
+ }
+ if (defined $patch) {
+ print OUT " debian/patch-stamp" or die;
+ }
+ print OUT "\n\t\@[ -f debian/yada -a -f debian/rules ]\n" or die;
+
+ &makescript(*OUT{IO}, "Build", "\t\@umask 022", $source{"build"});
+
+ ############################################################################
+ print OUT <<END or die;
+ touch debian/build-stamp
+
+.PHONY: install-tree
+END
+ if ($usearches) {
+ print OUT "install-tree: install-tree-\$(buildarch)\n" or die;
+ } else {
+ print OUT "install-tree: install-tree-any\n" or die;
+ }
+
+ foreach $arch (keys %architectures) {
+ print OUT "install-tree-$arch:" or die;
+ foreach (keys %packages) {
+ if ($architecture{$_} eq "all" or $architecture{$_} eq "any"
+ or $architecture{$_} =~ m/(^| )$arch( |$)/) {
+ print OUT " \\\n\tdebian/tmp-$_/DEBIAN/control" or die;
+ }
+ }
+ print OUT "\n" or die;
+ }
+
+ print OUT "install-tree-any:" or die;
+ foreach (keys %packages) {
+ if ($architecture{$_} eq "all" or $architecture{$_} eq "any") {
+ print OUT " \\\n\tdebian/tmp-$_/DEBIAN/control" or die;
+ }
+ }
+
+ foreach $pkg (keys %packages) {
+ print OUT "\n\ndebian/tmp-$pkg/DEBIAN/control: debian/build-stamp debian/control
+ rm -rf debian/tmp-$pkg
+ umask 022 && install -d debian/tmp-$pkg/DEBIAN
+ chmod +x debian/yada
+" or die;
+ if (defined $docdep{$pkg}) {
+ print OUT
+" umask 022 && install -d debian/tmp-$pkg/usr/share/doc/$docdep{$pkg}
+ umask 022 && ln -s $docdep{$pkg} debian/tmp-$pkg/usr/share/doc/$pkg
+" or die;
+ } else {
+ if (defined $source{"upstream-source"}) {
+ $_=".Debian";
+ } else {
+ $_="";
+ }
+ print OUT <<EOM or die;
+ install -d debian/tmp-$pkg/usr/share/doc/$pkg
+ umask 022; debian/yada generate copyright \\
+ >debian/tmp-$pkg/usr/share/doc/$pkg/copyright
+ install -m 644 -p debian/changelog \\
+ debian/tmp-$pkg/usr/share/doc/$pkg/changelog$_
+EOM
+ }
+ &makescript(*OUT{IO}, "Install",
+" \@umask 022 && export PACKAGE=\"$pkg\" \\
+ && export ROOT=\"\$\$(pwd)/debian/tmp-$pkg\" \\
+ && export CONTROL=\"\$\$(pwd)/debian/tmp-$pkg/DEBIAN\"",
+ $install{$pkg});
+ if (defined $predepends{$pkg} or defined $depends{$pkg}
+ or defined $recommends{$pkg} or defined $suggests{$pkg})
+ {
+ # FIXME: provide a way to add more directories to LD_LIBRARY_PATH.
+ print OUT "\tLD_LIBRARY_PATH=\"debian/tmp-$pkg/lib:debian/tmp-$pkg/usr/lib:\$\$LD_LIBRARY_PATH\" dpkg-shlibdeps -p" . normalise($pkg) or die;
+ if (defined $predepends{$pkg}) {
+ print OUT " -dPre-Depends $predepends{$pkg}" or die;
+ }
+ if (defined $depends{$pkg}) {
+ print OUT " -dDepends $depends{$pkg}" or die;
+ }
+ if (defined $recommends{$pkg}) {
+ print OUT " -dRecommends $recommends{$pkg}" or die;
+ }
+ if (defined $suggests{$pkg}) {
+ print OUT " -dSuggests $suggests{$pkg}" or die;
+ }
+ print OUT "\n" or die;
+ }
+ print OUT
+" debian/yada compress $pkg
+ find debian/tmp-$pkg -type f -print \\
+ | sed -n 's/^debian\\/tmp-$pkg\\(\\/etc\\/.*\\)\$\$/\\1/p' \\
+ > debian/tmp-$pkg/DEBIAN/conffiles
+ if test ! -s debian/tmp-$pkg/DEBIAN/conffiles; then rm -f debian/tmp-$pkg/DEBIAN/conffiles; fi
+ debian/yada generate maintscripts $pkg
+" or die;
+ if (defined $docdep{$pkg}) {
+ print OUT "\t-rmdir debian/tmp-$pkg/usr/share/doc/$docdep{$pkg}\n"
+ or die;
+ }
+ print OUT "\tumask 022 && dpkg-gencontrol -isp -p$pkg -Pdebian/tmp-$pkg" or die;
+ }
+
+ ############################################################################
+ print OUT <<END or die;
+
+
+# Build package files
+
+.PHONY: binary binary-arch binary-indep
+binary: binary-arch binary-indep
+END
+ print OUT <<END or die if $usearches;
+binary-arch: binary-arch-\$(buildarch)
+
+END
+ print OUT <<END or die unless $usearches;
+binary-arch: binary-arch-any
+
+END
+ ############################################################################
+
+ foreach $arch (keys %architectures) {
+ print OUT ".PHONY: binary-arch-$arch\nbinary-arch-$arch:" or die;
+ foreach (keys %packages) {
+ if ($architecture{$_} eq "any" or $architecture{$_} =~ m/(^| )$arch( |$)/) {
+ print OUT " \\\n\tbinary-package-$_" or die;
+ }
+ }
+ print OUT "\n" or die;
+ }
+
+ print OUT ".PHONY: binary-arch-any\nbinary-arch-any:" or die;
+ foreach (keys %packages) {
+ if ($architecture{$_} eq "any") {
+ print OUT " \\\n\tbinary-package-$_" or die;
+ }
+ }
+ print OUT "\n" or die;
+
+ print OUT "binary-indep:" or die;
+ foreach (keys %packages) {
+ if ($architecture{$_} eq "all") {
+ print OUT " \\\n\tbinary-package-$_" or die;
+ }
+ }
+
+ foreach $pkg (keys %packages) {
+ print OUT "\n\n.PHONY: binary-package-$pkg
+binary-package-$pkg: check-root debian/tmp-$pkg/DEBIAN/control
+ \@[ -f debian/yada -a -f debian/rules ]
+ chown -R 0.0 debian/tmp-$pkg
+ chmod -R u=rwX,go=rX debian/tmp-$pkg\n" or die;
+ &makescript(*OUT{IO}, "Finalise",
+" \@umask 022 && export PACKAGE=\"$pkg\" \\
+ && export ROOT=\"\$\$(pwd)/debian/tmp-$pkg\" \\
+ && export CONTROL=\"\$\$(pwd)/debian/tmp-$pkg/DEBIAN\"",
+ $finalise{$pkg});
+ print OUT "\t\@if [ -d debian/tmp-$pkg/usr/doc/$pkg ]; then \\\n" .
+ "\t echo \"*** Yada warning: /usr/doc/$pkg should be " .
+ "/usr/share/doc/$pkg\";\\\n" .
+ "\tfi\n";
+ print OUT "\tdpkg-deb --build debian/tmp-$pkg .." or die;
+ }
+
+ print OUT <<EOM or die;
+
+
+.PHONY: check-root
+check-root:
+ \@[ `id -u` = 0 ] || (echo \"You must be root to do this!\"; false)
+
+# Clean up afterwards
+
+.PHONY: clean clean-install-tree clean-build
+EOM
+ print OUT "clean: clean-install-tree clean-build" or die;
+ if (defined $patch) { print OUT " unpatch" or die; }
+ print OUT <<EOM or die;
+ debian/control debian/rules
+
+clean-build:
+ \@[ -f debian/yada -a -f debian/rules ]
+ rm -f debian/build-stamp debian/depends-stamp
+EOM
+ ############################################################################
+
+ &makescript(*OUT{IO}, "Clean", "\t\@umask 022", $source{"clean"});
+
+ ############################################################################
+ print OUT "
+clean-install-tree: debian/rules
+ \@[ -f debian/yada -a -f debian/rules ]
+ rm -f debian/install-tree-stamp
+ rm -rf debian/tmp* debian/files* debian/substvars
+" or die "Cannot write header to debian/rules.new";
+ ############################################################################
+
+ close OUT or die "Cannot close debian/rules.new";
+ chmod 0755, "debian/rules.new" or die "Cannot make debian/rules.new executable";
+
+ &chokepoint; # "leaving output in debian/rules.new\n";
+ rename "debian/rules.new", "debian/rules"
+ or die "Cannot rename debian/rules.new to debian/rules";
+ exit 0;
+ }
+}
+
+if (m/^install$/i) {
+ &getvars;
+ @files=();
+ $type="data";
+ $tree="/usr";
+ $dest=undef;
+ $destadd=undef;
+ $as=undef;
+ $strip=undef;
+ $exec=undef;
+ $sect=undef;
+ while (defined ($_=shift)) {
+ if ($_ eq "-dir") { $type="dir"; next; }
+ if ($_ eq "-data") { $type="data"; next; }
+ if ($_ eq "-doc") { $type="doc"; next; }
+ if ($_ eq "-bin") { $type="bin"; next; }
+ if ($_ eq "-script") { $type="bin"; $strip=0; next; }
+ if ($_ eq "-game") { $type="games"; next; }
+ if ($_ eq "-lib") { $type="lib"; next; }
+ if ($_ eq "-man") { $type="man"; next; }
+ if ($_ eq "-conffile") { if ($type ne "data") { warn "`-conffile' has changed in meaning!"; } $type="etc"; next; }
+ if ($_ eq "-x") { $tree="/usr/X11R6"; next; }
+ if ($_ eq "-non-x") { $tree="/usr"; next; }
+ if ($_ eq "-stripped") { $strip=1; next; }
+ if ($_ eq "-unstripped") { $strip=0; next; }
+ if ($_ eq "-exec") { $exec=1; next; }
+ if ($_ eq "-no-exec") { $exec=0; next; }
+ if ($_ eq "-into") { $dest=shift; next; }
+ if ($_ eq "-as") { $as=shift; next; }
+ if ($_ eq "-subdir") { $destadd=shift; next; }
+ if ($_ eq "-section") { $sect=shift; next; }
+ if ($_ =~ m/^-/) { print "I don't understand this option: `$_'\n"; exit 1; }
+ push @files, $_;
+ }
+ if (scalar @files == 0) { choke "Install what?"; }
+ if (defined $as and scalar @files != 1) {
+ choke "You can only install one file `-as' something at a time.\n";
+ }
+ if ($type eq "dir") {
+ map s|^/?|$ROOT/|, @files;
+ &run('install', '-d', '-m', '755', @files);
+ exit 0;
+ }
+ if (not defined $dest) {
+ if ($type =~ /doc|man|info/ and $tree eq "/usr") { $tree .= "/share"; }
+ if ($type eq "etc") { $tree=""; }
+ if ($type =~ /etc|bin|lib|games|man/) { $dest="$tree/$type"; }
+ if ($type eq "doc") { $dest="$tree/$type/$PACKAGE"; }
+ }
+ if (not defined $dest) { choke "Where should I install to?"; }
+ if (defined $destadd) {
+ $dest.="/$destadd";
+ }
+ if (not defined $strip) {
+ if ($type =~ /bin|games|lib/) { $strip=1; } else { $strip=0; }
+ }
+ $dest =~ s|^/?|$ROOT/|;
+ stat $dest;
+ if (! -e _) { &run('install', '-d', '-m', '755', "$dest"); stat $dest; }
+ if (! -d _) { die "`$dest' is not a directory"; }
+ if (not defined $exec) {
+ if ($type =~ m/bin|games/) { $exec=1; } else { $exec=0; }
+ }
+ if ($exec) { $mode='755'; } else { $mode='644'; }
+ foreach (@files) {
+ $asname=$as;
+ if (not defined $asname) { $asname=$_; $asname =~ s|.*/||; }
+ if ($type eq "man") {
+ $assect=$sect;
+ if (not defined $assect) { $assect=$asname; $assect =~ s/.*\.//; }
+ $assect =~ s/^(.).*/$1/;
+ $asname =~ s|^|man$assect/|;
+ stat "$dest/man$assect";
+ if (! -e _) {
+ &run('install', '-d', '-m', '755', "$dest/man$assect");
+ stat "$dest/man$assect";
+ }
+ if (! -d _) {
+ die "`$dest/man$assect' is not a directory";
+ }
+ }
+ &run('install', '-p', '-m', $mode, $_, "$dest/$asname");
+ if ($strip) { &run('strip', '--remove-section=.comment',
+ '--remove-section=.note', "$dest/$asname"); }
+ }
+ exit 0;
+}
+
+if (m/^undocumented$/i) {
+ &getvars;
+ @files=();
+ $x11=0;
+ $sect=undef;
+ while (defined ($_=shift)) {
+ if ($_ eq "-x") { $x11=1; next; }
+ if ($_ eq "-non-x") { $x11=0; next; }
+ if ($_ eq "-section") { $sect=shift; next; }
+ if ($_ =~ m/^-/) { print "I don't understand this option: `$_'\n"; exit 1; }
+ push @files, $_;
+ }
+ if (scalar @files == 0) { choke "What is undocumented?"; }
+ foreach (@files) {
+ if (defined $sect) {
+ $secnum = $sect;
+ s/$/.$sect/;
+ } else {
+ $secnum = $_;
+ $secnum =~ s/.*\.//;
+ }
+ $secnum =~ s/^(.).*/$1/;
+ $pre = '';
+ if ($secnum ne '7') {
+ $pre='../man7/';
+ }
+ if ($x11) {
+ $pre = "../../../share/man/man7/";
+ $dest = "$ROOT/usr/X11R6/man/man$secnum";
+ } else {
+ $dest = "$ROOT/usr/share/man/man$secnum";
+ }
+ stat "$dest";
+ if (! -e _) {
+ &run('install', '-d', '-m', '755', "$dest");
+ stat "$dest";
+ }
+ if (! -d _) {
+ die "`$dest' is not a directory";
+ }
+ $target="${pre}undocumented.7.gz";
+ &run('ln', '-s', $target, "$dest/$_.gz");
+ }
+ exit 0;
+}
+
+if (m/^dpkg-shlibdeps$/i) {
+ &getvars;
+ $ldlp=$ENV{"LD_LIBRARY_PATH"};
+ if (defined $ldlp) {
+ $ldlp.=":$ROOT/lib:$ROOT/usr/lib";
+ } else {
+ $ldlp="$ROOT/lib:$ROOT/usr/lib";
+ }
+ $ENV{"LD_LIBRARY_PATH"}=$ldlp;
+ &run('dpkg-shlibdeps', "-p$PACKAGE", @ARGV);
+ exit 0;
+}
+
+if (m/^generate$/i) {
+ $_=shift;
+ choke "Generate what?" if not defined;
+ if (m/^copyright$/i) {
+ &readpackages;
+ $dist=$source{"packaged-for"};
+ if (defined $dist) {
+ $dist="This is the $dist prepackaged version of ";
+ } else {
+ $dist="This is a prepackaged version of ";
+ }
+ $title=$source{"description"};
+ if (defined $title) {
+ $title=~s/\n.*//s;
+ } else {
+ $title=$source{"source"};
+ gasp "No Source field!" unless defined $title;
+ }
+ $packager=$source{"packager"};
+ $othermaints=$source{"other-maintainers"};
+ $maintainer=$source{"maintainer"};
+ if (defined $othermaints and not defined $packager) {
+ gasp "Other-Maintainers but no Packager?";
+ } elsif (defined $othermaints) {
+ $packager="$packager, then was subsequently maintained by $othermaints";
+ }
+ if (defined $packager) {
+ $maintainer="It was originally Debianised by $packager, and is currently maintained by $maintainer";
+ } else {
+ $maintainer="It was Debianised by $maintainer";
+ }
+ $upstreamuri=$source{"upstream-source"};
+ if (defined $upstreamuri) {
+ $upstreamuri=", using files obtained from $upstreamuri";
+ $native=0;
+ } else {
+ $upstreamuri="";
+ $native=1;
+ }
+ $homeuri=$source{"home-page"};
+ if (defined $homeuri) {
+ $homeuri="\nMore information about $title is available from $homeuri.\n";
+ } else {
+ $homeuri="";
+ }
+ $changes=$source{"major-changes"};
+ gasp "No Major-Changes field in non-native package!"
+ unless $native or defined $changes;
+ if (defined $changes) {
+ if ($changes eq "") {
+ $changes="\nNo major changes were made.\n";
+ } else {
+ $changes =~ s/^/ /gm;
+ $changes = "\nChanges were made as follows:\n$changes\n";
+ }
+ } else {
+ $changes="";
+ }
+ $copyright=$source{"copyright"};
+ gasp "No Copyright field!" unless defined $copyright;
+ $licence = $copyright;
+ $copyright =~ s/^/ /gm;
+ $copyright =~ s/^[^\n]*\n//s;
+ $licence =~ s/\n.*//s;
+ if ($licence ne ".") {
+ for ($licence) {
+ m/^GPL$/
+ && do { $licname="GNU GPL (GNU General Public License)"; }
+ or m/^LGPL$/
+ && do { $licname="GNU LGPL (GNU Library (or Lesser) General"
+ ." Public License)"; }
+ or m/^Artistic$/
+ && do { $licname="Artistic license"; }
+ or m/^BSD$/
+ && do { $licname="the standard BSD license"; }
+ or gasp "Unknown licence `$_'";
+ }
+ $licence = "On any Debian system, you can find the complete text of the "
+ ."$licname in the file /usr/share/common-licenses/$licence\n";
+ }
+ $|=1; # Ensure the output from fmt comes out in the right place.
+ if (not $copyright =~ m/copyright|\(c\)/i) {
+ warn "***** Are you sure you've included a proper copyright notice?\n";
+ }
+ $copyright = "\nCopyright and licence notice:\n\n$copyright";
+ open FMT, "|fmt" or die "Cannot spawn fmt";
+ print FMT "$dist$title.\n$maintainer$upstreamuri.\n$homeuri"
+ or die "Cannot write data to fmt";
+ close FMT or die "Cannot close pipe to fmt or fmt returned error status";
+ print "$changes$copyright\n\n" or die "Cannot write output";
+ open FMT, "|fmt" or die "Cannot spawn fmt";
+ print FMT "$licence" or die "Cannot write data to fmt";
+ close FMT or die "Cannot close pipe to fmt or fmt returned error status";
+ &chokepoint;
+ exit 0;
+ } elsif (m/^maintscripts$/i) {
+ $pkg=shift;
+ choke "Which package's maintainer scripts to generate?" unless defined $pkg;
+ &readpackages;
+ $par=$binary{$pkg};
+ choke "Cannot find package `$pkg' in debian/packages" unless %$par;
+ if (defined $$par{'doc-base'}) {
+ foreach (split /\n\n+(?=(?:.*[^ \n].*\n)*document\:)/i, $$par{'doc-base'})
+ {
+ m/^document\s*\:\s*(.*?)\s*$/mi;
+ $docbase{$1}=$_;
+ }
+ }
+ for ('preinst', 'postinst', 'prerm', 'postrm') {
+ if (defined $$par{$_}
+ or ($_ eq 'postinst') # and (defined $$par{'menu'}
+ # or defined $$par{'doc-base'}
+ # or defined $$par{'contains-libs'}
+ # or defined $$par{'alternatives'}))
+ or ($_ eq 'prerm') # and (defined $$par{'alternatives'}
+ # or defined $$par{'doc-base'}))
+ or ($_ eq 'postrm' and defined $$par{'menu'}))
+ {
+ open MAINT, ">debian/tmp-$pkg/DEBIAN/$_"
+ or die "Cannot open $_ for output";
+ $script=$$par{$_};
+ if (not defined $script or $script =~ s/^sh\n//s) {
+ # shell script
+ #chomp;
+ print MAINT "#! /bin/sh\n# This maintainer script was generated by yada\n\nset -e\n" or die;
+ if ($_ eq 'postinst') {
+ print MAINT <<EOM or die;
+
+if test "\$1" = configure -a -d /usr/doc -a ! -e "/usr/doc/$pkg" -a -d "/usr/share/doc/$pkg"
+then
+ ln -sf "../share/doc/$pkg" "/usr/doc/$pkg"
+fi
+EOM
+ }
+ if ($_ eq 'prerm') {
+ print MAINT <<EOM or die;
+
+if test \\( "\$1" = upgrade -o "\$1" = remove \\) -a -L "/usr/doc/$pkg"; then
+ rm -f "/usr/doc/$pkg"
+fi
+EOM
+ }
+ if (($_ eq 'postinst' or $_ eq 'postrm') and defined $$par{'menu'}) {
+ print MAINT "\nif test -x /usr/bin/update-menus; then update-menus; fi\n"
+ or die;
+ }
+ if ($_ eq 'postinst' and defined $$par{'contains-libs'}) {
+ print MAINT "\nif test \"\$1\" = configure; then ldconfig; fi\n"
+ or die;
+ }
+ if ($_ eq 'postinst' and defined $$par{'doc-base'}) {
+ print MAINT "\nif command -v install-docs >/dev/null 2>&1; then\n";
+ foreach (keys %docbase) {
+ print MAINT " install-docs -i /usr/share/doc-base/$_;\n";
+ }
+ print MAINT "fi\n";
+ }
+ if ($_ eq 'prerm' and defined $$par{'doc-base'}) {
+ print MAINT "\nif command -v install-docs >/dev/null 2>&1; then\n";
+ foreach (keys %docbase) {
+ print MAINT " install-docs -r $_;\n"
+ }
+ print MAINT "fi\n";
+ }
+ if ($_ eq 'postinst' and defined $$par{'alternatives'}) {
+ $alt = $$par{'alternatives'};
+ $alt =~ s/^\n|\n$//sg;
+ $alt =~ s/\n\n+/\n/sg;
+ $alt =~ s/$/\n/s;
+ gasp "Malformed `Alternatives' field."
+ unless $alt =~ m/^((\S+\s*->\s*\S+\s*->\s*\S+\s*\(\d+\)|>>\s*\S+\s*->\s*\S+\s*->\s*\S+)\n)+$/s;
+ while ($alt ne "") {
+ if ($alt =~ s/^(\S+)\s*->\s*(\S+)\s*->\s*(\S+)\s*\((\d+)\)\n//s) {
+ print MAINT "\nupdate-alternatives --install $1 $2 $3 $4"
+ or die;
+ } elsif ($alt =~ s/^>>\s*(\S+)\s*->\s*(\S+)\s*->\s*(\S+)\n//s) {
+ print MAINT " \\\n --slave $1 $2 $3"
+ or die;
+ } else {
+ die "Internal error";
+ }
+ }
+ print MAINT "\n" or die;
+ }
+ if ($_ eq 'prerm' and defined $$par{'alternatives'}) {
+ $alt = $$par{'alternatives'};
+ $alt =~ s/^\n|\n$//sg;
+ $alt =~ s/\n\n+/\n/sg;
+ $alt =~ s/$/\n/s;
+ gasp "Malformed `Alternatives' field."
+ unless $alt =~ m/^((\S+\s*->\s*\S+\s*->\s*\S+\s*\(\d+\)|>>\s*\S+\s*->\s*\S+\s*->\s*\S+)\n)+$/s;
+ while ($alt ne "") {
+ if ($alt =~ s/^(\S+)\s*->\s*(\S+)\s*->\s*(\S+)\s*\((\d+)\)\n//s) {
+ print MAINT "update-alternatives --remove $2 $3\n"
+ or die;
+ } elsif ($alt =~ s/^>>\s*(\S+)\s*->\s*(\S+)\s*->\s*(\S+)\n//s) {
+ 1;
+ } else {
+ die "Internal error";
+ }
+ }
+ }
+ if (defined $script) {
+ print MAINT "\n# Package maintainer's commands follow:\n$script\n# End of package maintainer's commands\n\nexit 0\n" or die;
+ } else {
+ print MAINT "\nexit 0\n" or die;
+ }
+ } else {
+ gasp "Unknown executable type for `$_'\n";
+ }
+ close MAINT or die "Cannot close `$_'";
+ chmod 0755, "debian/tmp-$pkg/DEBIAN/$_"
+ or die "Cannot make `$_' executable";
+ }
+ }
+ if (defined $$par{'menu'}) {
+ $_=$$par{'menu'};
+ s/$/\n/s;
+ system("install -d debian/tmp-$pkg/usr/lib/menu") == 0
+ or die "Cannot create menu directory";
+ open MAINT, ">debian/tmp-$pkg/usr/lib/menu/$pkg"
+ or die "Cannot open menu file for writing";
+ print MAINT or die "Cannot write to menu file";
+ close MAINT or die "Cannot close menu file";
+ }
+ if (defined $$par{'shlibs'}) {
+ $_=$$par{'shlibs'};
+ s/$/\n/s;
+ open MAINT, ">debian/tmp-$pkg/DEBIAN/shlibs"
+ or die "Cannot open shlibs file for writing";
+ print MAINT or die "Cannot write to shlibs file";
+ close MAINT or die "Cannot close shlibs file";
+ }
+ if (defined $$par{'doc-base'}) {
+ system("install -d debian/tmp-$pkg/usr/share/doc-base") == 0
+ or die "Cannot create doc-base directory";
+ foreach (keys %docbase) {
+ $tmp=$docbase{$_};
+ $tmp=~s/$/\n/s;
+ open MAINT, ">debian/tmp-$pkg/usr/share/doc-base/$_"
+ or die "Cannot open doc-base file `$_' for writing";
+ print MAINT $tmp or die "Cannot write to doc-base file `$_'";
+ close MAINT or die "Cannot close doc-base file `$_'";
+ }
+ }
+ exit 0;
+ }
+
+ choke "Generate what? (`$_' not understood.)";
+}
+
+if (m/^compress$/i) {
+ $pkg = shift;
+ choke "What package should I compress?" unless defined $pkg;
+ system("set -e; set -v; find debian/tmp-$pkg/usr/info debian/tmp-$pkg/usr/share/info debian/tmp-$pkg/usr/man debian/tmp-$pkg/usr/share/man debian/tmp-$pkg/usr/X11*/man -type f ! -name \\*.gz -print0 2>/dev/null | xargs -0r gzip -9n") == 0
+ or die "Problem compressing files (stage 1)";
+ system("set -e; find debian/tmp-$pkg/usr/share/doc -type f \\( -size +2k -or -name changelog\\* \\) ! -name \\*.htm\\* ! -name \\*.gif ! -name copyright ! -name \\*.gz -print0 2>/dev/null | xargs -0r gzip -9n") == 0
+ or die "Problem compressing files (stage 2)";
+ open FILES, "find debian/tmp-$pkg -type l -print0 |"
+ or die "Cannot find symlinks";
+ $/="\0";
+ while (<FILES>) {
+ chomp;
+ m=(.*)/([^/]*)$=; $dir=$1; $name=$2;
+ $_ = readlink or die "Cannot read symlink `$_'";
+ $changes = s=//+=/=g;
+ $changes += s=(^|/)\./=$1=g;
+ do {
+ $matches = s=(^|/)(?!\.\./)[^/]+/\.\./=$1=g;
+ $changes += $matches;
+ } while ($matches);
+ if (m=^/=) {
+ $dest="debian/tmp-$pkg";
+ } else {
+ $dest=$dir;
+ }
+ if (! -e "$dest/$_" && -f "$dest/$_.gz" && ! -e "$dir/$name.gz") {
+ unlink "$dir/$name" or die "Cannot unlink `$dir/$name'";
+ symlink "$_.gz", "$dir/$name.gz"
+ or die "Cannot create symlink `$dir/$name.gz'";
+ } elsif ($changes) {
+ unlink "$dir/$name" or die "Cannot unlink `$dir/$name'";
+ symlink "$_", "$dir/$name" or die "Cannot create symlink `$dir/$name'";
+ }
+ }
+ close FILES or die "Problem closing pipe";
+ exit 0;
+}
+
+if (m/^fixup$/i) {
+ $_ = shift;
+ if (m/^libtool$/i) {
+ $script = shift;
+ $script = "libtool" if not defined $script;
+ # The following adapted from Lintian's libtool-workarounds.txt
+ # Patch the generated libtool to avoid passing -rpath when linking,
+ # and to explicitly link libraries against the libraries they
+ # depend on.
+ open APPENDIN, "<$script" or die "Cannot open `$script' for reading";
+ open APPENDOUT, ">$script.new"
+ or die "Cannot open `$script.new' for writing";
+ while (<APPENDIN>) {
+ s/^hardcode_libdir_flag_spec.*$/hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/;
+ s/"$/ \\\$deplibs"/ if /^archive_cmds="/;
+ print APPENDOUT or die;
+ }
+ close APPENDIN or die "Cannot close $script";
+ close APPENDOUT or die "Cannot close $script.new";
+ chmod 0755, "$script.new" or die "Cannot change mode of `$script.new'";
+ rename "$script.new", $script
+ or die "Cannot move `$script.new' to `$script'";
+ exit 0;
+ }
+
+ choke "Fixup what? (`$_' not understood.)";
+}
+
+if (m/^yada$/i) {
+ if (! -d "debian") {
+ mkdir "debian", 0775 or die "Cannot create directory `debian'";
+ print "Creating directory `debian'\n";
+ }
+ if ($0 ne "debian/yada" and $0 ne "./debian/yada") {
+ print "Copying updated `yada' script into debian directory\n";
+ if (-e "debian/yada") {
+ print "(Keeping old version as `yada.old')\n";
+ rename "debian/yada", "debian/yada.old";
+ }
+ &run('cp', '--', $0, 'debian/yada');
+ }
+ $pkg=`pwd`;
+ chomp $pkg;
+ $pkgver=$pkg;
+ $pkgver=~s|.*-||;
+ $pkg=~s|.*/||;
+ $pkg=~s|-[^-]*||;
+ $today=`date -R`;
+ if (-e "debian/changelog") {
+ print "You already have a `debian/changelog'; I won't overwrite it.\n";
+ } else {
+ open CHANGELOG, ">debian/changelog"
+ or die "Cannot open debian/changelog for writing";
+ print "Creating initial `debian/changelog'\n";
+ print CHANGELOG <<EOM or die "Cannot write to `debian/changelog'";
+$pkg ($pkgver-1) unstable; urgency=low
+
+ * Initial Debian version.
+
+ -- Wile E. Coyote <coyote\@acme.com> $today
+EOM
+ close CHANGELOG or die "Cannot close `debian/changelog' after writing";
+ }
+ if (-e "debian/packages") {
+ print "You already have a `debian/packages'; I won't overwrite it.\n";
+ exit 0;
+ }
+ open PACKAGES, ">debian/packages"
+ or die "Cannot open `debian/packages' for writing";
+ print "Creating example `debian/packages'\n";
+ print PACKAGES <<EOM or die "Cannot write to `debian/packages'";
+# debian/packages for $pkg
+# Written by Charles Briscoe-Smith, May 1999. Public Domain.
+# Customised for $pkg by
+
+# This is an -example- packages file; read /usr/share/doc/yada/yada.txt.gz to
+# find out how to customise it to your needs.
+
+Source: $pkg
+Section: unknown
+Priority: unknown
+Maintainer: Mr. Nobody <nobody\@root.org>
+Packager: T. Raven <nevermore\@poe.net>
+Standards-Version: 0.0
+Upstream-Source: <URL:ftp://some.where/over/the/rainbow.tar.gz>
+Home-Page: <URL:http://some.thing/nasty/in/the/woodshed.html>
+Description: Some package
+Packaged-For: Yoyodyne Inc.
+Copyright: GPL
+ Copyright 1999 A. Snide Badger
+Major-Changes:
+ Introduced many bugs by not editing debian/packages appropriately.
+Build: sh
+ ./configure --prefix=/usr
+ make
+Clean: sh
+ make distclean || true
+
+Package: $pkg
+Architecture: any
+Depends: [/usr/bin/*]
+Description: Some binary package
+ This is a generic binary package. If you see this text, it hasn't been
+ built properly; the packager should have replaced this with something
+ appropriate.
+Install: sh
+ make install DESTDIR=\$ROOT
+EOM
+ close PACKAGES or die "Cannot close `debian/packages' after writing";
+ exit 0;
+}
+
+choke "I don't understand you.";
+
+exit 1;
diff --git a/fpga/xilinx/programmer/bit2svf/dumpbit.c b/fpga/xilinx/programmer/bit2svf/dumpbit.c
new file mode 100644
index 0000000..5d7c634
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/dumpbit.c
@@ -0,0 +1,93 @@
+ /**[txh]********************************************************************
+
+ Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+ Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
+
+ 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; version 2.
+
+ 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
+
+ Description: Dumps the contents of a xilinx bit file in stdout.
+
+***************************************************************************/
+/*****************************************************************************
+
+ Target: Any
+ Language: C
+ Compiler: gcc 3.3.5 (Debian GNU/Linux)
+ Text editor: SETEdit 0.5.5
+
+*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bitfile.h"
+
+#define BSIZE 1048576 /* 1k */
+
+
+/* read a bit file from stdin */
+int main(int argc, char *argv[])
+{
+ struct bithead bh;
+ FILE *bitfile, *outfile;
+ int remaining,readed;
+ char buff[BSIZE];
+
+ fprintf(stderr,"\ndumpbit - bit file stream dumper - v1.0\n");
+ fprintf(stderr,"Copyright (c) 2005 Juan Pablo D. Borgna/INTI\n\n");
+
+ if (argc==1 || argc>3)
+ {
+ fprintf(stderr,"Insufficient args %s filename.bit filename\n",argv[0]);
+ return 1;
+ }
+
+ if ((bitfile=fopen(argv[1],"rb"))==NULL)
+ {
+ perror("BITFILE");
+ return 2;
+ }
+
+ if ((outfile=fopen(argv[2],"wb"))==NULL)
+ {
+ perror("OUTFILE");
+ return 3;
+ }
+
+ initbh(&bh);
+ if (readhead(&bh, bitfile))
+ {
+ fprintf(stderr,"Invalid bit file header.\n");
+ return 3;
+ }
+
+ fprintf(stderr,"\n");
+ fprintf(stderr,"Bit file created on %s at %s.\n", bh.date, bh.time);
+ fprintf(stderr,"Created from file %s for Xilinx part %s.\n", bh.filename, bh.part);
+ fprintf(stderr,"Bitstream length is %d bytes.\n", bh.length);
+ fprintf(stderr,"\n");
+
+ remaining=bh.length;
+
+ while(remaining)
+ {
+ readed=fread(buff,1,BSIZE,bitfile);
+ fwrite(buff,readed,1,outfile);
+ remaining-=readed;
+ }
+
+ fclose(bitfile);
+ freebh(&bh);
+ return 0;
+}
diff --git a/fpga/xilinx/programmer/bit2svf/global.h b/fpga/xilinx/programmer/bit2svf/global.h
new file mode 100644
index 0000000..2d5e9bf
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/global.h
@@ -0,0 +1,16 @@
+/* Globaly used variables */
+
+long address;
+long step;
+long s_bytes;
+long s_bits;
+long stream_s;
+unsigned cutlines;
+
+char *id;
+char *idmask;
+char *bsize;
+long msize;
+
+
+char *templ;
diff --git a/fpga/xilinx/programmer/bit2svf/jbit b/fpga/xilinx/programmer/bit2svf/jbit
new file mode 100755
index 0000000..d7f6e5d
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/jbit
@@ -0,0 +1,232 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti.gov.ar>
+# Copyright (c) 2006-2007 Instituto Nacional de Tecnología Industrial
+#
+# Based on code:
+# Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+#
+# 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; version 2.
+#
+# 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
+#
+# Este script invoca a bit2svf y jtag para programar el contenido de
+# un archivo bit en un dispositivo Xilinx.
+#
+# Basado en el script original de Juan Pablo D. Borgna
+#
+#
+
+use Getopt::Long;
+use File::Basename;
+
+print "jbit - bit2svf/jtag short cut - v2.1\n";
+print "Copyright (c) 2006-2007 Salvador E. Tropea/INTI\n\n";
+
+GetOptions(
+ 'skip=s' => \$skip,
+ 'length=s' => \$len,
+ 'help' => \&help);
+
+if (scalar(@ARGV)!=2)
+ {
+ print "You must specify two arguments\n\n";
+ help();
+ }
+
+$bitfile=@ARGV[0];
+
+# Seteos por defecto
+$jtag="/usr/bin/jtag";
+$bit2svf="/usr/bin/bit2svf";
+$svft=@ARGV[1];
+$temp=`mktemp -t bit2svf.XXXXXX`;
+chomp($temp);
+$temp_r=`mktemp -t jbit.XXXXXX`;
+chomp($temp_r);
+
+$device="ppdev";
+$location="/dev/parport0";
+$cable_type="DLC5";
+
+if ($skip)
+ {
+ $skip=$1*(1<<20) if ($skip=~/(\d+)M/i);
+ $skip=$1*(1<<10) if ($skip=~/(\d+)k/i);
+ $skip="--skip=$skip";
+ }
+if ($len)
+ {
+ $len=$1*(1<<20) if ($len=~/(\d+)M/i);
+ $len=$1*(1<<10) if ($len=~/(\d+)k/i);
+ $len="--length=$len";
+ }
+
+# Leer seteos de ~/.jbitrc
+$jbitrc=$ENV{'HOME'}.'/.jbitrc';
+if (-e $jbitrc)
+ {
+ print "Configuration from $jbitrc:\n";
+ open(FIL,"<$jbitrc") or die "Error opening $jbitrc";
+ while ($a=<FIL>)
+ {
+ unless ($a=~/^\#/ or $a=~/^\s*$/)
+ {
+ if ($a=~/^(\S+)\s*=\s*\"?([^\"\n]*)\"?$/)
+ {
+ $var=uc($1);
+ $val=$2;
+ if ($val=~/^\$(\d)$/)
+ {
+ $val=$ARGV[$1-1];
+ }
+ print "$var -> \"$val\"\n";
+ if ($var eq 'JTAG')
+ {
+ $jtag=$val;
+ }
+ elsif ($var eq 'BIT2SVF')
+ {
+ $bit2svf=$val;
+ }
+ elsif ($var eq 'SVFT')
+ {
+ $svft=$val;
+ }
+ elsif ($var eq 'TEMP')
+ {
+ #$temp=$val;
+ print "TEMP is obsolete!!!\n";
+ }
+ elsif ($var eq 'DEVICE')
+ {
+ $device=$val;
+ }
+ elsif ($var eq 'LOCATION')
+ {
+ $location=$val;
+ }
+ elsif ($var eq 'CABLE_TYPE')
+ {
+ $cable_type=$val;
+ }
+ elsif ($var eq 'PARTNUM')
+ {
+ $partnum=$val;
+ print "PARTNUM is obsolete!!!\n";
+ }
+ else
+ {
+ die "Unknown variable $var";
+ }
+ }
+ else
+ {
+ die "Error parsing $jbitrc:\n$a";
+ }
+ }
+ }
+ close(FIL);
+ print "\n";
+ }
+else
+ {
+ print "No personal configuration '$jbitrc'\n";
+ }
+
+# Compuebo la existencia de todo lo necesario
+die "Can't find JTAG in $jtag" unless -e $jtag;
+die "Can't find bit2svf in $bit2svf" unless -e $bit2svf;
+die "Missing file: $bitfile" unless -e $bitfile;
+
+# Creo el .svf
+print "Creating temporary file $temp ...\n<--------- $bit2svf $skip $len $bitfile $temp $svft\n";
+die "Error creating temporary file $temp"
+ if system("$bit2svf $skip $len $bitfile $temp $svft");
+print "<--------- end of bit2svf\n\n";
+
+# Buscar que posición tiene en la cadena
+print "Analyzing JTAG chain using $jtag ...\n";
+open(FIL,"|$jtag > $temp_r") or die;
+print FIL "cable $device $location $cable_type\n";
+print FIL "detect\n";
+print FIL "quit\n";
+close FIL;
+$ndev=0;
+$devs=0;
+$partnum=-1;
+open(FIL,"<$temp_r") or die;
+while ($a=<FIL>)
+ {
+ if ($a=~/Chain length: (\d+)/)
+ {
+ $devs=$1;
+ print "Devices in the chain: $devs\n";
+ }
+ elsif ($a=~/Part:\s+(\S+)$/)
+ {
+ $dev=uc($1);
+ print "$ndev: $dev ";
+ if ($svft eq $dev)
+ {
+ print "<--";
+ $partnum=$ndev;
+ }
+ print "\n";
+ $ndev++;
+ }
+ }
+close(FIL);
+die "Can't find any device in the chain, consult $temp_r"
+ unless $devs;
+die "Can't find $svft in the chain" unless $partnum!=-1;
+print "Device number in the chain: $partnum\n\n";
+
+# Ejecutarlo
+print "Transferring $temp using $jtag ...\n<--------- jtag\n";
+open(FIL,"|$jtag") or die;
+print FIL "cable $device $location $cable_type\n";
+print FIL "detect\n";
+print FIL "part $partnum\n";
+print FIL "svf $temp\n";
+print FIL "quit\n";
+close FIL;
+print "<--------- fin de jtag\n\n";
+
+# Clean-up
+print "Cleaning temporary files ... ($temp $temp_r)\n";
+`rm -f $temp $temp_r`;
+print "Have a nice day :-)\n";
+
+
+sub help
+{
+ my $me=basename($0);
+
+ print <<END;
+$me is a program to configure Xilinx devices using JTAG.
+
+Usage:
+ jbit [OPTIONS] file.bit DEVICE
+
+Options:
+ --skip=value Skip bits the bitstream
+ --length=value Limit the bitstream length
+ --help This text
+
+file.bit is the file containing the bitstream.
+DEVICE is the name of the device to configure.
+
+END
+ exit 1;
+}
diff --git a/fpga/xilinx/programmer/bit2svf/jbitrc_sample.txt b/fpga/xilinx/programmer/bit2svf/jbitrc_sample.txt
new file mode 100644
index 0000000..d926fa1
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/jbitrc_sample.txt
@@ -0,0 +1,21 @@
+#
+# Ejemplo de configuracion personalizada
+# Custom config sample
+# ~/.jbitrc
+#
+
+#Paths de archivos necesarios
+#Needed files path
+
+JTAG=/usr/bin/jtag
+BIT2SVF=/usr/bin/bit2svf
+SVFT="$2"
+TEMP=/tmp/bit2svf.tmp
+
+
+#Conexion y configuracion de la cadena
+#Chain conection and configuration
+
+DEVICE="ppdev"
+LOCATION="/dev/parport0"
+CABLE_TYPE="DLC5"
diff --git a/fpga/xilinx/programmer/bit2svf/parts.c b/fpga/xilinx/programmer/bit2svf/parts.c
new file mode 100644
index 0000000..3b80240
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/parts.c
@@ -0,0 +1,119 @@
+#include <stdlib.h>
+#include <string.h>
+#include "parts.h"
+
+/*
+part known[] = {
+ {"XC18V01","f5034093","0ffeffff","alg_18V",0x3FC0},
+ {"XC2S100","f0614093","0fffffff","alg_VIRTEX",0l},
+ {NULL,NULL,NULL,NULL,0l}
+ };
+*/
+#define TOKDELIM " \t/,;.\n"
+
+part *
+text_to_part(char *text)
+{
+ part temp, *ret;
+ char *token;
+
+ token=strtok(text,TOKDELIM);
+ if (token==NULL) return NULL;
+ temp.name=strdup(token);
+
+ token=strtok(NULL,TOKDELIM);
+ if (token==NULL) return NULL;
+ temp.id=strdup(token);
+
+ token=strtok(NULL,TOKDELIM);
+ if (token==NULL) return NULL;
+ temp.idmask=strdup(token);
+
+ token=strtok(NULL, TOKDELIM);
+ if (token==NULL) return NULL;
+ temp.alg_tpl=strdup(token);
+
+ token=strtok(NULL, TOKDELIM);
+ if (token==NULL) return NULL;
+ temp.bsize=strdup(token);
+
+ token=strtok(NULL,TOKDELIM);
+ if (token==NULL) return NULL;
+ temp.msize=strtol(token,NULL,0);
+
+
+ if((ret=(part *)malloc(sizeof(part)))==NULL)
+ {
+ fprintf(stderr,"Cannot asign memory needed for a part\n");
+ return NULL;
+ }
+ *ret=temp;
+ return ret;
+}
+
+
+int
+select_part_from_file(char *name, char *file, part **ret)
+{
+ char buff[1000];
+ FILE *fp;
+
+ if((fp=fopen(file,"rt"))==NULL)
+ {
+ fprintf(stderr,"Unable to open devices file %s.\n",file);
+ return 1;
+ }
+
+ fgets(buff,1000,fp);
+
+ while(!feof(fp))
+ {
+ if (strncasecmp(buff,"//",2) && (buff[0]!='\n')) /*If its not a comment*/
+ { /* or a blank line ...*/
+ *ret=text_to_part(buff);
+ if (*ret==NULL)
+ fprintf(stderr,"Invalid line inside device file: %s\n",buff);
+ else if (!strcasecmp(name,(*ret)->name))
+ { /* FOUND! */
+ fclose(fp);
+ return 0;
+ }
+ }
+ fgets(buff,1000,fp);
+ }
+
+ *ret=NULL;
+ fprintf(stderr,"Device not found inside device file: %s\n",name);
+ fclose(fp);
+ return 1;
+}
+
+/*
+int
+select_part_by_name(char *name, part **ret)
+{
+ int found=0;
+ part *r;
+
+ r=known;
+
+ while (r->name && !found)
+ {
+ if (!strcasecmp(r->name,name))
+ found=1;
+ else
+ r++;
+ }
+
+ if (!found)
+ {
+ fprintf(stderr,"Device not found %s\n",name);
+ return 1;
+ }
+
+ *ret=r;
+
+ return 0;
+}
+
+*/
diff --git a/fpga/xilinx/programmer/bit2svf/parts.h b/fpga/xilinx/programmer/bit2svf/parts.h
new file mode 100644
index 0000000..48c5ae4
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/parts.h
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+typedef struct part_
+ {
+ char *name;
+ char *id;
+ char *idmask;
+ char *alg_tpl;
+ char *bsize;
+ long msize;
+ } part;
+
+
+
+/* Some headers */
+int select_part_by_name(char *name, part **ret);
+part *text_to_part(char *text);
+int select_part_from_file(char *name, char *file, part **ret);
+
diff --git a/fpga/xilinx/programmer/bit2svf/tags b/fpga/xilinx/programmer/bit2svf/tags
new file mode 100644
index 0000000..81203ae
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/tags
@@ -0,0 +1,103 @@
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME Exuberant Ctags //
+!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
+!_TAG_PROGRAM_VERSION 5.5.4 //
+Architecture debian/yada /^Architecture: any$/;" kind:l language:Perl
+BIDIR Makefile /^BIDIR=bitinfo-0.3$/;" kind:m language:Make
+BSIZE dumpbit.c 36;" kind:d language:C file:
+Build debian/yada /^Build: sh$/;" kind:l language:Perl
+CC Makefile /^CC=gcc$/;" kind:m language:Make
+CC bitinfo-0.3/Makefile /^CC = gcc$/;" kind:m language:Make
+CFLAGS Makefile /^CFLAGS=-Wall -g3 -I$(BIDIR)$/;" kind:m language:Make
+CFLAGS bitinfo-0.3/Makefile /^CFLAGS = -c -g -Wall$/;" kind:m language:Make
+Clean debian/yada /^Clean: sh$/;" kind:l language:Perl
+Copyright debian/yada /^Copyright: GPL$/;" kind:l language:Perl
+DEFAULT_RES bit2svf.c 41;" kind:d language:C file:
+Depends debian/yada /^Depends: [\/usr\/bin\/*]$/;" kind:l language:Perl
+Description debian/yada /^Description: Some binary package$/;" kind:l language:Perl
+Description debian/yada /^Description: Some package$/;" kind:l language:Perl
+Install debian/yada /^Install: sh$/;" kind:l language:Perl
+LDFLAGS Makefile /^LDFLAGS=-I$(BIDIR)$/;" kind:m language:Make
+LDFLAGS bitinfo-0.3/Makefile /^LDFLAGS = $/;" kind:m language:Make
+Maintainer debian/yada /^Maintainer: Mr. Nobody <nobody\\@root.org>$/;" kind:l language:Perl
+Notably debian/yada /^Notably:$/;" kind:l language:Perl
+OBJECTS bitinfo-0.3/Makefile /^OBJECTS = bitinfo.o bitfile.o$/;" kind:m language:Make
+PKG Makefile /^PKG=bit2svf-$(VERSION)$/;" kind:m language:Make
+PROYECTO Makefile /^PROYECTO=dumpbit bit2svf$/;" kind:m language:Make
+Package debian/yada /^Package: $pkg$/;" kind:l language:Perl
+Packager debian/yada /^Packager: T. Raven <nevermore\\@poe.net>$/;" kind:l language:Perl
+Priority debian/yada /^Priority: unknown$/;" kind:l language:Perl
+Section debian/yada /^Section: unknown$/;" kind:l language:Perl
+Source debian/yada /^Source: $pkg$/;" kind:l language:Perl
+TOKDELIM parts.c 12;" kind:d language:C file:
+Usage debian/yada /^Usage: yada action [args...]$/;" kind:l language:Perl
+VERSION Makefile /^VERSION=1.1.0$/;" kind:m language:Make
+address global.h /^long address;$/;" kind:v language:C++
+alg_tpl parts.h /^ char *alg_tpl;$/;" kind:m language:C++ struct:part_
+append debian/yada /^sub append {$/;" kind:s language:Perl
+binary debian/yada /^binary: binary-arch binary-indep$/;" kind:l language:Perl
+bithead bitinfo-0.3/bitfile.h /^struct bithead$/;" kind:s language:C++
+bsize global.h /^char *bsize;$/;" kind:v language:C++
+bsize parts.h /^ char *bsize;$/;" kind:m language:C++ struct:part_
+choke debian/yada /^sub choke {$/;" kind:s language:Perl
+chokepoint debian/yada /^ sub chokepoint {$/;" kind:s language:Perl
+control debian/yada /^control: debian\/control$/;" kind:l language:Perl
+cutputs bitshandle.c /^cutputs(char *string, FILE *fp, long block, int *col)$/;" kind:f language:C
+date bitinfo-0.3/bitfile.h /^ char* date;$/;" kind:m language:C++ struct:bithead
+default debian/yada /^default:$/;" kind:l language:Perl
+depends debian/yada /^depends: debian\/depends-stamp$/;" kind:l language:Perl
+do_command commands.c /^do_command(char *cmd, FILE *dfp, FILE *ofp, int *col)$/;" kind:f language:C
+filename bitinfo-0.3/bitfile.h /^ char* filename;$/;" kind:m language:C++ struct:bithead
+fill commands.c /^fill(FILE *fp, long c, long t)$/;" kind:f language:C
+freebh bitinfo-0.3/bitfile.c /^void freebh(struct bithead *bh)$/;" kind:f language:C
+gasp debian/yada /^ sub gasp {$/;" kind:s language:Perl
+getpara debian/yada /^sub getpara {$/;" kind:s language:Perl
+getvars debian/yada /^sub getvars {$/;" kind:s language:Perl
+head13 bitinfo-0.3/bitfile.c /^static uchar head13[] = {0, 9, 15, 240, 15, 240, 15, 240, 15, 240, 0, 0, 1};$/;" kind:v language:C file:
+id global.h /^char *id;$/;" kind:v language:C++
+id parts.h /^ char *id;$/;" kind:m language:C++ struct:part_
+idmask global.h /^char *idmask;$/;" kind:v language:C++
+idmask parts.h /^ char *idmask;$/;" kind:m language:C++ struct:part_
+initbh bitinfo-0.3/bitfile.c /^void initbh(struct bithead *bh)$/;" kind:f language:C
+inv_byte bitshandle.c /^inv_byte(unsigned char b)$/;" kind:f language:C
+length bitinfo-0.3/bitfile.h /^ int length;$/;" kind:m language:C++ struct:bithead
+main bit2svf.c /^int main(int argc, char *argv[])$/;" kind:f language:C
+main bitinfo-0.3/bitinfo.c /^int main(void)$/;" kind:f language:C
+main dumpbit.c /^int main(int argc, char *argv[])$/;" kind:f language:C
+makescript debian/yada /^sub makescript {$/;" kind:s language:Perl
+msize global.h /^long msize;$/;" kind:v language:C++
+msize parts.h /^ long msize;$/;" kind:m language:C++ struct:part_
+name parts.h /^ char *name;$/;" kind:m language:C++ struct:part_
+normalise debian/yada /^sub normalise {$/;" kind:s language:Perl
+parsebinarypara debian/yada /^sub parsebinarypara {$/;" kind:s language:Perl
+parsesourcepara debian/yada /^sub parsesourcepara {$/;" kind:s language:Perl
+part bitinfo-0.3/bitfile.h /^ char* part;$/;" kind:m language:C++ struct:bithead
+part parts.h /^ } part;$/;" kind:t language:C++
+part_ parts.h /^typedef struct part_$/;" kind:s language:C++
+patch debian/yada /^patch: debian\/patch-stamp$/;" kind:l language:Perl
+pb bitshandle.c /^pb(char *to, char *from,long nbytes)$/;" kind:f language:C
+pbi bitshandle.c /^pbi(char *to, char *from,long nbytes)$/;" kind:f language:C
+printkey debian/yada /^sub printkey {$/;" kind:s language:Perl
+printkeys debian/yada /^sub printkeys {$/;" kind:s language:Perl
+readhead bitinfo-0.3/bitfile.c /^int readhead(struct bithead *bh, FILE *f)$/;" kind:f language:C
+readhead13 bitinfo-0.3/bitfile.c /^int readhead13 (FILE *f)$/;" kind:f language:C
+readlength bitinfo-0.3/bitfile.c /^int readlength(FILE *f)$/;" kind:f language:C
+readpackages debian/yada /^sub readpackages {$/;" kind:s language:Perl
+readsecthead bitinfo-0.3/bitfile.c /^int readsecthead(char *buf, FILE *f)$/;" kind:f language:C
+readsection bitinfo-0.3/bitfile.c /^int readsection(char *buf, int length, FILE *f)$/;" kind:f language:C
+repeat commands.c /^repeat (FILE *ifp, FILE *ofp, FILE *dfp,long limit)$/;" kind:f language:C
+rules debian/yada /^rules: debian\/rules$/;" kind:l language:Perl
+run debian/yada /^sub run {$/;" kind:s language:Perl
+s_bits global.h /^long s_bits;$/;" kind:v language:C++
+s_bytes global.h /^long s_bytes;$/;" kind:v language:C++
+select_part_from_file parts.c /^select_part_from_file(char *name, char *file, part **ret)$/;" kind:f language:C
+step global.h /^long step;$/;" kind:v language:C++
+stream_s global.h /^long stream_s;$/;" kind:v language:C++
+templ global.h /^char *templ;$/;" kind:v language:C++
+text_to_part parts.c /^text_to_part(char *text)$/;" kind:f language:C
+time bitinfo-0.3/bitfile.h /^ char* time;$/;" kind:m language:C++ struct:bithead
+uchar bitinfo-0.3/bitfile.c 31;" kind:d language:C file:
+unpatch debian/yada /^unpatch:$/;" kind:l language:Perl
+value_from commands.c /^value_from(char *varname)$/;" kind:f language:C
diff --git a/fpga/xilinx/programmer/bit2svf/templates/.DEVICES~ b/fpga/xilinx/programmer/bit2svf/templates/.DEVICES~
new file mode 100644
index 0000000..9219f41
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/.DEVICES~
@@ -0,0 +1,42 @@
+//One device per line
+//NAME | ID | IDMASK | ALG_TPL | BSIZE | MSIZE (last mem pos)
+// XC18V memories
+XC18V256 , f5022093, 0ffeffff, alg_18V , 2048 , 0x1000
+XC18V512 , f5023093, 0ffeffff, alg_18V , 2048 , 0x2000
+XC18V01 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
+XC18V01-SO20 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
+XC18V02 , f5025093, 0ffeffff, alg_18V , 4096 , 0x4000
+XC18V04 , f5026093, 0ffeffff, alg_18V , 4096 , 0x8000
+
+// XCF memories
+XCF01S , f5044093, 0ffeffff, alg_XCF , 2048 , 0x4000
+XCF02S , f5045093, 0ffeffff, alg_XCF , 4096 , 0x4000
+XCF04S , f5046093, 0ffeffff, alg_XCF , 4096 , 0x8000
+
+// XCFxxP memories
+XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
+
+// Spartan II family (5 bits IR)
+XC2S15 , f0608093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S30 , f060c093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S50 , f0610093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S100 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S100-PQ208 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S150 , f0618093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S200 , f061c093, 0fffffff, alg_Spartan_II, VOID , 0l
+
+// Spartan 3 family (6 bits IR)
+XC3S50 , f140D093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S200 , f1414093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S400 , f141C093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S1000, f1428093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S1500, f1434093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S2000, f1440093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S4000, f1448093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S5000, f1450093, 0fffffff, alg_Spartan_3, VOID , 0l
+
+// Virtex 4 family (10 bits IR)
+XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
+
+//EOF
+
diff --git a/fpga/xilinx/programmer/bit2svf/templates/.README.en~ b/fpga/xilinx/programmer/bit2svf/templates/.README.en~
new file mode 100644
index 0000000..9201290
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/.README.en~
@@ -0,0 +1,112 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+Commands and blocks:
+ The template files have block commands and operation
+ commands. The block commands start with two substract
+ signs "--" and the operation are betwin dollar signs "$".
+ The block commands mark the excecution of a block and the
+ end of the block must be identifyed with the instruction
+ "--END".
+
+Internal variables:
+ The next internal variables are provided wich can be used
+ indicating their name betwin dollars signs "$" or modified
+ if a value is assigned using parentesis signs.
+ Ex.: $ADDRESS(0x00)$ asigns this variable the value 0x0000.
+
+$ADDRESS$ :
+ Accumulator useful at the time of incrementing a memory address.
+
+$STEP$ :
+ Value on wich $ADDRESS$ variable will be incremented.
+
+$BSIZEB$ :
+ Amount of bytes of the bitstream file.
+
+$BSIZEB2$ :
+ 2 * amount of bytes of the bitstream file.
+
+$BSIZE$ :
+ Amount of bits of the bitstream file.
+ Note: BSIZE an STEP are related. BSIZE is the size of the cache
+ used to store the data before flashing the device. Each memory
+ address contains some bits that's a word, the STEP is the size of
+ the cache in words. So BSIZE=STEP*word_size.
+ For the XC18V: 32*64=2048 o 32*128=4096.
+
+$MSIZE$ :
+ Taken from the msize field from the device definition in the
+ DEVICES file.
+ It contains the last memory position of a device with memory.
+
+$ID$ :
+ Taken from the id field from the device definition in the DEVICES
+ file.
+ It contains the IDCODE of the selected device.
+
+$IDMASK$ :
+ Taken from the idmask field from the device definition in the
+ DEVICE file.
+ It contains the mask wich be used in the comprobation of the IDCODE
+
+
+Block commands:
+
+--LITERAL START :
+ It indicate that in the output file must be copied the content
+ of this block until the end is found "as is".
+ If an operational command is found inside it is excecuted.
+
+--REPEAT START :
+
+ It indicate that this block will be repeated until the end of
+ the bitfile is reached.
+ This block must have inside some operational command wich
+ reads information from the input bitfile, if not, the end of
+ this will never be reached and the progran will keep
+ repeating this block until there is no more disk space.
+ With each block iteration the variable $ADDRESS$ is
+ incremented by $STEP$.
+
+--REPEAT UNTIL value :
+ It indicates that this block will be repeated until the
+ variable $ADDRESS$ reach the value passed as parameter.
+ With each block iteration the variable $ADDRESS$ is
+ incremented by $STEP$.
+ The value passwd as parameter must be $STEP$ multiplo,
+ or the exit condition will never be reached and the
+ program will keep repeating this block until there is
+ no more disk space.
+ Instead of value you can use a variable:
+ Ej.: --REPEAT UNTIL MSIZE
+
+
+--END :
+ It indicates the end of a LITERAL, REPEAT or REPEAT UNTIL block.
+
+
+Opeation commands:
+ The operation commands may recive as an argment the name of
+ a variable instead of a constant:
+ Ej.: $FILL(0xFF,BSIZE)$
+
+$DATA(ndatabytes)$ :
+ Writes in the output file a ndatabytes amount of bytes
+ from the input bitfile expressed in hex.
+
+$DATA_INV(ndatabytes)$ :
+ Writes in the output fila a ndatabytes amount of bytes
+ from the input bitfile inverting the order, expressed
+ in hex.
+
+$FILL(VAL,TIMES)$ :
+ Writes TIMES times the value VAL expressed in hex in the
+ output file.
+
+$REWIND$ :
+ Rewinds the bitfile to the first stream byte so it can be used in a
+ new block.
+
+
diff --git a/fpga/xilinx/programmer/bit2svf/templates/.README.es~ b/fpga/xilinx/programmer/bit2svf/templates/.README.es~
new file mode 100644
index 0000000..af3560b
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/.README.es~
@@ -0,0 +1,237 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+Comandos y bloques:
+ Los archivos de template tienen comandos de bloque y
+ comandos de operacion. Los comandos de bloque comienzan con
+ dos signos menos "--" y los de operacion van encerrados entre
+ signos pesos "$". Los comandos de bloque indican la ejecucion
+ de un bloque y el fin de bloque debe ser indicado con la
+ instruccion "--END".
+
+
+Variables internas:
+ Se proporcionan las siguientes variables internas que pueden
+ ser utilizadas invocando su nombre entre signos pesos "$" o
+ modificados si ademas se les asigna un valor entre
+ parentesis. Ej. $ADDRESS(0x0000)$ le asignara a esta variable
+ el valor 0x0000.
+
+$ADDRESS$ :
+ Acumulador que es util al momento de incrementar la direccion de una
+ memoria, por ejemplo.
+
+$STEP$ :
+ Valor con el cual se incrementara la variable $ADDRESS$.
+
+$SBYTES$ :
+ Cantidad de bytes que posee el bitstream del bitfile.
+
+$SBITES$ :
+ Cantidad de bits que posee el bitstream del bitfile.
+
+$MSIZE$ :
+ Obtenido del campo msize de la definicion del dispositivo en el
+ archivo DEVICES.
+ Expresa la ultima posicion de memoria de un dispositivo con memoria.
+
+$ID$ :
+ Obtenido del campo id de la definicion del dispositivo en el archivo
+ DEVICES.
+ Expresa el IDCODE del dispositivo actual.
+
+$IDMASK$ :
+ Obtenido del campo idmask de la definicion del dispositivo en el
+ archivo DEVICES.
+ Expresa la mascara que se usara en la comprobacion del IDCODE.
+
+$BSIZE$ :
+ Obtenido del campo BSIZE de la definicion del dispositivo en el
+ archivo DEVICES.
+ Es el "block size" (cantidad de bits) a transferir expresando
+ en bits.
+ Nota: El valor BSIZE y el valor STEP no son cosas separadas.
+ BSIZE es el tamaño en bits de la cache que tiene el dispositivo
+ para almacenar los datos antes de transferirlos a la flash.
+ Cada dirección de memoria direcciona una cantidad de bits (64
+ o 128 es lo común), el STEP es el número de posiciones de memoria
+ que entran en la cache, luego BSIZE=STEP*bits_por_dirección.
+ Esto es en las XC18V: 32*64=2048 o 32*128=4096.
+
+$BSIZEB$ :
+ Obtenido del campo BSIZE de la definicion del dispositivo en el
+ archivo DEVICES.
+ Es el "block size" (cantidad de bits) a transferir expresando
+ en bytes.
+
+$BSIZEB2$ :
+ $BSIZEB$ multiplicado por 2.
+
+Comandos de bloque:
+
+
+--LITERAL START :
+ Indica que se debe copiar en el archivo de salida el contenido
+ de este bloque y hasta el final del mismo tal y como esta.
+ Si se encuentra un comando de operacion entre medio este es
+ ejecutado.
+
+--REPEAT START :
+ Indica que se repetira de principio a fin el contenido de este
+ bloque mientras que haya informacion que leer en el bitfile
+ de entrada.
+ Este comando de bloque debe tener en su interior algun comando
+ de operacion que lea informacion del bitfile de entrada, si no
+ este nunca llegara a su fin y el programa se quedara
+ repitiendo el bloque hasta agotar el espacio en disco.
+ Con cada iteracion del bloque se incrementa la variable
+ $ADDRESS$ en $STEP$.
+
+--REPEAT UNTIL valor :
+ Indica que se repetira de principio a fin el contenido de
+ este bloque hasta que la variable $ADDRESS$ tome el valor
+ pasado como parametro. Con cada iteracion del bloque se
+ incrementara la variable $ADDRESS$ en $STEP$.
+ El valor pasado como parametro debe ser multiplo de
+ $STEP$, si no la condicion de salida del bloque nunca se
+ conseguira y el programa se quedara repitiendo el bloque
+ hasta agotar el espacio en disco.
+ En lugar de valor se puede utilizar una variable:
+ Ej.: --REPEAT UNTIL MSIZE
+
+
+--END :
+ Indica el final de un bloque LITERAL, REPEAT o REPEAT UNTIL.
+
+
+Comandos de operacion:
+ Los comandos de operacion pueden recibir como argumento
+ el nombre de una variable en lugar de una constante:
+ Ej.: $FILL(0xFF,BSIZE)$
+
+$DATA(ndatabytes)$ :
+ Escribe en el archivo de salida una cantidad ndatabytes de
+ bytes del bitfile de entrada expresados en hexadecimal.
+
+$DATA_INV(ndatabytes)$ :
+ Escribe en el archivo de salida una cantidad ndatabytes
+ de bytes del bitfile de entrada, invirtiendo el orden
+ de los bits del bloque, expresados en hexadecimal.
+
+$FILL(VAL,TIMES)$ :
+ Escribe TIMES veces el valor VAL expresado en hexadecimal en
+ el archivo de salida.
+
+$REWIND$ :
+ Vuelve a poner el archivo de bits en la posicion del primer byte del
+ stream para poder realizar otra pasada completa con un comando de
+ bloque.
+
+-------------------------------------------------------------------------------
+
+Como crear un template para una FPGA:
+-------------------------------------
+
+Autor: Salvador E. Tropea
+
+A) Crear un .SVF válido para esa FPGA:
+
+1) Obtener un .bit para la FPGA en cuestión.
+2) Abrir el impact:
+$ . /usr/local/ISEWb/settings.sh
+$ impact
+3) Elegir "I want to (*) Create a new project", Ok. (Darle un nombre si se
+quiere).
+4) Elegir "(*) Prepare a boundary-scan file [SVF]", Finish.
+5) Elegir un nombre para el SVF.
+6) Elegir el .bit.
+7) Presionar el botón derecho sobre la FPGA y elegir "Program", Ok.
+8) Salir del impact
+
+Automáticamente es:
+
+setPreference -pref AutoSignature:FALSE
+setPreference -pref KeepSVF:FALSE
+setPreference -pref ConcurrentMode:FALSE
+setPreference -pref UseHighz:FALSE
+setPreference -pref UserLevel:NOVICE
+setPreference -pref svfUseTime:FALSE
+setMode -bs
+setMode -bs
+setCable -port svf -file "salida.svf"
+addDevice -p 1 -file "archivo.bit"
+Program -p 1 -s -defaultVersion 0
+
+B) Crear un nuevo template (ej: alg_Virtex_4.svft)
+
+1) Abrir un template que ya exista para usarlo de guía.
+2) Borrar "FREQUENCY 1E6 HZ;"
+3) Reemplazar: $ID$ y $IDMASK$ en la parte que dice "Loading device with
+'idcode' instruction.". (f167c093)
+4) Reemplazar la megalínea del bitstream por:
+SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
+
+C) Probar su funcionamiento
+
+1) Colocar el nuevo template en /usr/share/bit2svf/
+2) Editar /usr/share/bit2svf/DEVICES agregando el ID de la FPGA y el algoritmo
+a usar:
+
+// Virtex 4 family (10 bits IR)
+XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
+
+3) Probar el template:
+
+$ bit2svf display_test_lx25.bit v4-b2s.svf XC4VLX25
+
+Esto genera v4-b2s.svf que debería ser practicamente idéntico al generado por
+impact.
+Nota: En este caso observé que el impact agrega 32 bits en 0 extra al
+bitstream. Esto no parece ser indispensable y sospecho que sirve para
+"limpiar/vaciar" la cadena.
+4) Si todo fue OK se puede probar con el dispositivo:
+
+$ jbit display_test_lx25.bit XC4VLX25
+
+
+-------------------------------------------------------------------------------
+
+Como crear un template para una PROM:
+-------------------------------------
+
+Autor: Salvador E. Tropea
+
+A) Crear un archivo de PROM válido.
+
+1) Obtener un .bit para la FPGA en cuestión.
+2) Abrir el impact:
+$ . /usr/local/ISEWb/settings.sh
+$ impact
+3) Elegir "I want to (*) Prepare a ROM file", Ok. (Darle un nombre si se
+quiere).
+4) Elegir "I want to target a (*) Xilinx PROM", "PROM File name" darle un
+nombre. Next. (Ojo con el path).
+5) Elegir la PROM y Add, luego Next.
+6) Agregar el .bit
+7) Elegir "Generate File ..." dentro de las acciones disponibles (la única).
+8) Esto genera un .MCS con el contenido para la PROM.
+
+B) Crear un .SVF válido para esa PROM. Esto es similar a la FPGA, la única
+diferencia es que le especificamos el .MCS en lugar de un .bit. En este caso
+nos preguntará cual es el dispositivo haciendo un guess de cual se trata. Esto
+es porque el .mcs es un bitstream crudo y no dice para que dispositivo se
+hizo.
+Durante este proceso se pueden elegir opciones como si la PROM se conecta en
+paralelo y si se incluye verificación. Además hay que elegir que primero la
+borre.
+
+B) Crear un nuevo template o usar uno ya hecho. Esto es como con la FPGA.
+
+C) Probar su funcionamiento. Esto es más o menos lo mismo que con la FPGA. La
+principal diferencia con las PROMs es que acá es necesario configurar su tamaño
+y el tamaño de la caché o página donde se guardarán temporalmente los datos:
+
+// XCFxxP memories
+XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
+
diff --git a/fpga/xilinx/programmer/bit2svf/templates/DEVICES b/fpga/xilinx/programmer/bit2svf/templates/DEVICES
new file mode 100644
index 0000000..86f53a9
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/DEVICES
@@ -0,0 +1,42 @@
+//One device per line
+//NAME | ID | IDMASK | ALG_TPL | BSIZE | MSIZE
+// XC18V memories
+XC18V256 , f5022093, 0ffeffff, alg_18V , 2048 , 0x1000
+XC18V512 , f5023093, 0ffeffff, alg_18V , 2048 , 0x2000
+XC18V01 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
+XC18V01-SO20 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
+XC18V02 , f5025093, 0ffeffff, alg_18V , 4096 , 0x4000
+XC18V04 , f5026093, 0ffeffff, alg_18V , 4096 , 0x8000
+
+// XCF memories
+XCF01S , f5044093, 0ffeffff, alg_XCF , 2048 , 0x4000
+XCF02S , f5045093, 0ffeffff, alg_XCF , 4096 , 0x4000
+XCF04S , f5046093, 0ffeffff, alg_XCF , 4096 , 0x8000
+
+// XCFxxP memories
+XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
+
+// Spartan II family (5 bits IR)
+XC2S15 , f0608093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S30 , f060c093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S50 , f0610093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S100 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S100-PQ208 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S150 , f0618093, 0fffffff, alg_Spartan_II, VOID , 0l
+XC2S200 , f061c093, 0fffffff, alg_Spartan_II, VOID , 0l
+
+// Spartan 3 family (6 bits IR)
+XC3S50 , f140D093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S200 , f1414093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S400 , f141C093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S1000, f1428093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S1500, f1434093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S2000, f1440093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S4000, f1448093, 0fffffff, alg_Spartan_3, VOID , 0l
+XC3S5000, f1450093, 0fffffff, alg_Spartan_3, VOID , 0l
+
+// Virtex 4 family (10 bits IR)
+XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
+
+//EOF
+
diff --git a/fpga/xilinx/programmer/bit2svf/templates/README.en b/fpga/xilinx/programmer/bit2svf/templates/README.en
new file mode 100644
index 0000000..f517b01
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/README.en
@@ -0,0 +1,115 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+Commands and blocks:
+ The template files have block commands and operation
+ commands. The block commands start with two substract
+ signs "--" and the operation are betwin dollar signs "$".
+ The block commands mark the excecution of a block and the
+ end of the block must be identifyed with the instruction
+ "--END".
+
+Internal variables:
+ The next internal variables are provided wich can be used
+ indicating their name betwin dollars signs "$" or modified
+ if a value is assigned using parentesis signs.
+ Ex.: $ADDRESS(0x00)$ asigns this variable the value 0x0000.
+
+$ADDRESS$ :
+ Accumulator useful at the time of incrementing a memory address.
+
+$STEP$ :
+ Value on wich $ADDRESS$ variable will be incremented.
+
+$BSIZEB$ :
+ Amount of bytes of the bitstream file.
+
+$BSIZEB2$ :
+ 2 * amount of bytes of the bitstream file.
+
+$BSIZE$ :
+ Amount of bits of the bitstream file.
+ Note: BSIZE an STEP are related. BSIZE is the size of the cache
+ used to store the data before flashing the device. Each memory
+ address contains some bits that's a word, the STEP is the size of
+ the cache in words. So BSIZE=STEP*word_size.
+ For the XC18V: 32*64=2048 o 32*128=4096.
+
+$MSIZE$ :
+ Taken from the msize field from the device definition in the
+ DEVICES file.
+ It contains the last memory position of a device with memory.
+
+$ID$ :
+ Taken from the id field from the device definition in the DEVICES
+ file.
+ It contains the IDCODE of the selected device.
+
+$IDMASK$ :
+ Taken from the idmask field from the device definition in the
+ DEVICE file.
+ It contains the mask wich be used in the comprobation of the IDCODE
+
+
+Block commands:
+
+--LITERAL START :
+ It indicate that in the output file must be copied the content
+ of this block until the end is found "as is".
+ If an operational command is found inside it is excecuted.
+
+--REPEAT START :
+
+ It indicate that this block will be repeated until the end of
+ the bitfile is reached.
+ This block must have inside some operational command wich
+ reads information from the input bitfile, if not, the end of
+ this will never be reached and the progran will keep
+ repeating this block until there is no more disk space.
+ With each block iteration the variable $ADDRESS$ is
+ incremented by $STEP$.
+
+--REPEAT UNTIL value :
+ It indicates that this block will be repeated until the
+ variable $ADDRESS$ reach the value passed as parameter.
+ With each block iteration the variable $ADDRESS$ is
+ incremented by $STEP$.
+ The value passwd as parameter must be $STEP$ multiplo,
+ or the exit condition will never be reached and the
+ program will keep repeating this block until there is
+ no more disk space.
+ Instead of value you can use a variable:
+ Ej.: --REPEAT UNTIL MSIZE
+
+
+--END :
+ It indicates the end of a LITERAL, REPEAT or REPEAT UNTIL block.
+
+
+Opeation commands:
+ The operation commands may recive as an argment the name of
+ a variable instead of a constant:
+ Ej.: $FILL(0xFF,BSIZE)$
+
+$DATA(ndatabytes)$ :
+ Writes in the output file a ndatabytes amount of bytes
+ from the input bitfile expressed in hex.
+
+$DATA_INV(ndatabytes)$ :
+ Writes in the output fila a ndatabytes amount of bytes
+ from the input bitfile inverting the order, expressed
+ in hex.
+
+$FILL(VAL,TIMES)$ :
+ Writes TIMES times the value VAL expressed in hex in the
+ output file.
+
+$REWIND$ :
+ Rewinds the bitfile to the first stream byte so it can be used in a
+ new block.
+
+$CUTLINES(n):
+ Using 0 stops cutting long lines, 1 starts cutting again.
+ Other values: reserved.
+
diff --git a/fpga/xilinx/programmer/bit2svf/templates/README.es b/fpga/xilinx/programmer/bit2svf/templates/README.es
new file mode 100644
index 0000000..58f47b5
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/README.es
@@ -0,0 +1,241 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
+Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
+
+Comandos y bloques:
+ Los archivos de template tienen comandos de bloque y
+ comandos de operacion. Los comandos de bloque comienzan con
+ dos signos menos "--" y los de operacion van encerrados entre
+ signos pesos "$". Los comandos de bloque indican la ejecucion
+ de un bloque y el fin de bloque debe ser indicado con la
+ instruccion "--END".
+
+
+Variables internas:
+ Se proporcionan las siguientes variables internas que pueden
+ ser utilizadas invocando su nombre entre signos pesos "$" o
+ modificados si ademas se les asigna un valor entre
+ parentesis. Ej. $ADDRESS(0x0000)$ le asignara a esta variable
+ el valor 0x0000.
+
+$ADDRESS$ :
+ Acumulador que es util al momento de incrementar la direccion de una
+ memoria, por ejemplo.
+
+$STEP$ :
+ Valor con el cual se incrementara la variable $ADDRESS$.
+
+$SBYTES$ :
+ Cantidad de bytes que posee el bitstream del bitfile.
+
+$SBITES$ :
+ Cantidad de bits que posee el bitstream del bitfile.
+
+$MSIZE$ :
+ Obtenido del campo msize de la definicion del dispositivo en el
+ archivo DEVICES.
+ Expresa la ultima posicion de memoria de un dispositivo con memoria.
+
+$ID$ :
+ Obtenido del campo id de la definicion del dispositivo en el archivo
+ DEVICES.
+ Expresa el IDCODE del dispositivo actual.
+
+$IDMASK$ :
+ Obtenido del campo idmask de la definicion del dispositivo en el
+ archivo DEVICES.
+ Expresa la mascara que se usara en la comprobacion del IDCODE.
+
+$BSIZE$ :
+ Obtenido del campo BSIZE de la definicion del dispositivo en el
+ archivo DEVICES.
+ Es el "block size" (cantidad de bits) a transferir expresando
+ en bits.
+ Nota: El valor BSIZE y el valor STEP no son cosas separadas.
+ BSIZE es el tamaño en bits de la cache que tiene el dispositivo
+ para almacenar los datos antes de transferirlos a la flash.
+ Cada dirección de memoria direcciona una cantidad de bits (64
+ o 128 es lo común), el STEP es el número de posiciones de memoria
+ que entran en la cache, luego BSIZE=STEP*bits_por_dirección.
+ Esto es en las XC18V: 32*64=2048 o 32*128=4096.
+
+$BSIZEB$ :
+ Obtenido del campo BSIZE de la definicion del dispositivo en el
+ archivo DEVICES.
+ Es el "block size" (cantidad de bits) a transferir expresando
+ en bytes.
+
+$BSIZEB2$ :
+ $BSIZEB$ multiplicado por 2.
+
+Comandos de bloque:
+
+
+--LITERAL START :
+ Indica que se debe copiar en el archivo de salida el contenido
+ de este bloque y hasta el final del mismo tal y como esta.
+ Si se encuentra un comando de operacion entre medio este es
+ ejecutado.
+
+--REPEAT START :
+ Indica que se repetira de principio a fin el contenido de este
+ bloque mientras que haya informacion que leer en el bitfile
+ de entrada.
+ Este comando de bloque debe tener en su interior algun comando
+ de operacion que lea informacion del bitfile de entrada, si no
+ este nunca llegara a su fin y el programa se quedara
+ repitiendo el bloque hasta agotar el espacio en disco.
+ Con cada iteracion del bloque se incrementa la variable
+ $ADDRESS$ en $STEP$.
+
+--REPEAT UNTIL valor :
+ Indica que se repetira de principio a fin el contenido de
+ este bloque hasta que la variable $ADDRESS$ tome el valor
+ pasado como parametro. Con cada iteracion del bloque se
+ incrementara la variable $ADDRESS$ en $STEP$.
+ El valor pasado como parametro debe ser multiplo de
+ $STEP$, si no la condicion de salida del bloque nunca se
+ conseguira y el programa se quedara repitiendo el bloque
+ hasta agotar el espacio en disco.
+ En lugar de valor se puede utilizar una variable:
+ Ej.: --REPEAT UNTIL MSIZE
+
+
+--END :
+ Indica el final de un bloque LITERAL, REPEAT o REPEAT UNTIL.
+
+
+Comandos de operacion:
+ Los comandos de operacion pueden recibir como argumento
+ el nombre de una variable en lugar de una constante:
+ Ej.: $FILL(0xFF,BSIZE)$
+
+$DATA(ndatabytes)$ :
+ Escribe en el archivo de salida una cantidad ndatabytes de
+ bytes del bitfile de entrada expresados en hexadecimal.
+
+$DATA_INV(ndatabytes)$ :
+ Escribe en el archivo de salida una cantidad ndatabytes
+ de bytes del bitfile de entrada, invirtiendo el orden
+ de los bits del bloque, expresados en hexadecimal.
+
+$FILL(VAL,TIMES)$ :
+ Escribe TIMES veces el valor VAL expresado en hexadecimal en
+ el archivo de salida.
+
+$REWIND$ :
+ Vuelve a poner el archivo de bits en la posicion del primer byte del
+ stream para poder realizar otra pasada completa con un comando de
+ bloque.
+
+$CUTLINES(n):
+ Con 0 deja de cortar las líneas largas, con 1 vuelve a cortarlas.
+ Otros valores: reservados.
+
+-------------------------------------------------------------------------------
+
+Como crear un template para una FPGA:
+-------------------------------------
+
+Autor: Salvador E. Tropea
+
+A) Crear un .SVF válido para esa FPGA:
+
+1) Obtener un .bit para la FPGA en cuestión.
+2) Abrir el impact:
+$ . /usr/local/ISEWb/settings.sh
+$ impact
+3) Elegir "I want to (*) Create a new project", Ok. (Darle un nombre si se
+quiere).
+4) Elegir "(*) Prepare a boundary-scan file [SVF]", Finish.
+5) Elegir un nombre para el SVF.
+6) Elegir el .bit.
+7) Presionar el botón derecho sobre la FPGA y elegir "Program", Ok.
+8) Salir del impact
+
+Automáticamente es:
+
+setPreference -pref AutoSignature:FALSE
+setPreference -pref KeepSVF:FALSE
+setPreference -pref ConcurrentMode:FALSE
+setPreference -pref UseHighz:FALSE
+setPreference -pref UserLevel:NOVICE
+setPreference -pref svfUseTime:FALSE
+setMode -bs
+setMode -bs
+setCable -port svf -file "salida.svf"
+addDevice -p 1 -file "archivo.bit"
+Program -p 1 -s -defaultVersion 0
+
+B) Crear un nuevo template (ej: alg_Virtex_4.svft)
+
+1) Abrir un template que ya exista para usarlo de guía.
+2) Borrar "FREQUENCY 1E6 HZ;"
+3) Reemplazar: $ID$ y $IDMASK$ en la parte que dice "Loading device with
+'idcode' instruction.". (f167c093)
+4) Reemplazar la megalínea del bitstream por:
+SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
+
+C) Probar su funcionamiento
+
+1) Colocar el nuevo template en /usr/share/bit2svf/
+2) Editar /usr/share/bit2svf/DEVICES agregando el ID de la FPGA y el algoritmo
+a usar:
+
+// Virtex 4 family (10 bits IR)
+XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
+
+3) Probar el template:
+
+$ bit2svf display_test_lx25.bit v4-b2s.svf XC4VLX25
+
+Esto genera v4-b2s.svf que debería ser practicamente idéntico al generado por
+impact.
+Nota: En este caso observé que el impact agrega 32 bits en 0 extra al
+bitstream. Esto no parece ser indispensable y sospecho que sirve para
+"limpiar/vaciar" la cadena.
+4) Si todo fue OK se puede probar con el dispositivo:
+
+$ jbit display_test_lx25.bit XC4VLX25
+
+
+-------------------------------------------------------------------------------
+
+Como crear un template para una PROM:
+-------------------------------------
+
+Autor: Salvador E. Tropea
+
+A) Crear un archivo de PROM válido.
+
+1) Obtener un .bit para la FPGA en cuestión.
+2) Abrir el impact:
+$ . /usr/local/ISEWb/settings.sh
+$ impact
+3) Elegir "I want to (*) Prepare a ROM file", Ok. (Darle un nombre si se
+quiere).
+4) Elegir "I want to target a (*) Xilinx PROM", "PROM File name" darle un
+nombre. Next. (Ojo con el path).
+5) Elegir la PROM y Add, luego Next.
+6) Agregar el .bit
+7) Elegir "Generate File ..." dentro de las acciones disponibles (la única).
+8) Esto genera un .MCS con el contenido para la PROM.
+
+B) Crear un .SVF válido para esa PROM. Esto es similar a la FPGA, la única
+diferencia es que le especificamos el .MCS en lugar de un .bit. En este caso
+nos preguntará cual es el dispositivo haciendo un guess de cual se trata. Esto
+es porque el .mcs es un bitstream crudo y no dice para que dispositivo se
+hizo.
+Durante este proceso se pueden elegir opciones como si la PROM se conecta en
+paralelo y si se incluye verificación. Además hay que elegir que primero la
+borre.
+
+B) Crear un nuevo template o usar uno ya hecho. Esto es como con la FPGA.
+
+C) Probar su funcionamiento. Esto es más o menos lo mismo que con la FPGA. La
+principal diferencia con las PROMs es que acá es necesario configurar su tamaño
+y el tamaño de la caché o página donde se guardarán temporalmente los datos:
+
+// XCFxxP memories
+XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
+
diff --git a/fpga/xilinx/programmer/bit2svf/templates/alg_18V.svft b/fpga/xilinx/programmer/bit2svf/templates/alg_18V.svft
new file mode 100644
index 0000000..e754da1
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/alg_18V.svft
@@ -0,0 +1,192 @@
+//Info: Sample template for programming XILINX XC18V01 PROMS
+//Info: Created with output from Impact
+
+--LITERAL START
+TRST OFF;
+ENDIR IDLE;
+ENDDR IDLE;
+STATE RESET;
+STATE IDLE;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 8 TDI (fe) SMASK (ff) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Check for Read/Write Protect.
+SIR 8 TDI (ff) TDO (01) MASK (03) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+// Loading device with 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI (0001) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with 'ferase' instruction.
+SIR 8 TDI (ec) ;
+RUNTEST 1 TCK;
+RUNTEST 15000000 TCK;
+// Loading devices with 'conld' or 'bypass' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+--END
+
+$ADDRESS(0x0000)$
+$STEP(0x0020)$
+
+
+--REPEAT START
+// Loading device with a 'fdata0' instruction.
+SIR 8 TDI (ed) ;
+SDR $BSIZE$ TDI ($DATA_INV(BSIZEB)$) SMASK ($FILL(0xFF,BSIZEB)$) ;
+ENDIR IDLE;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fpgm' instruction.
+ENDIR IRPAUSE;
+SIR 8 TDI (ea) ;
+RUNTEST 1 TCK;
+RUNTEST 14000 TCK;
+--END
+
+--LITERAL START
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI (0001) ;
+ENDIR IDLE;
+RUNTEST 1 TCK;
+// Loading device with 'serase' instruction.
+SIR 8 TDI (0a) ;
+RUNTEST 37000 TCK;
+// Loading devices with 'conld' or 'bypass' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) ;
+--END
+
+$REWIND$
+$ADDRESS(0x0000)$
+$STEP(0x0040)$
+
+--REPEAT START
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fvfy0' instruction.
+SIR 8 TDI (ef) ;
+RUNTEST 1 TCK;
+RUNTEST 50 TCK;
+SDR $BSIZE2$ TDI ($FILL(0x00,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($DATA_INV(BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
+--END
+
+
+--REPEAT UNTIL MSIZE
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fvfy0' instruction.
+SIR 8 TDI (ef) ;
+RUNTEST 1 TCK;
+RUNTEST 50 TCK;
+SDR $BSIZE2$ TDI ($FILL(0xFF,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($FILL(0xFF,BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
+--END
+
+--LITERAL START
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) ;
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) TDO (00) MASK (00) ;
+SDR 16 TDI (4000) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fdata3' instruction.
+SIR 8 TDI (f3) TDO (00) ;
+SDR 6 TDI (1f) SMASK (3f) TDO (00) MASK (00) ;
+// Loading device with a 'fpgm' instruction.
+SIR 8 TDI (ea) TDO (00) ;
+RUNTEST 1 TCK;
+RUNTEST 14000 TCK;
+// Loading device with a 'fvfy3' instruction.
+SIR 8 TDI (e2) TDO (00) ;
+RUNTEST 1 TCK;
+RUNTEST 50 TCK;
+SDR 6 TDI (1f) TDO (1f) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+// Loading device with a 'config' instruction.
+SIR 8 TDI (ee) TDO (00) ;
+RUNTEST 50 TCK;
+//Loading device with 'bypass' instruction.
+SIR 8 TDI (ff) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+SIR 8 TDI (ff) ;
+SDR 1 TDI (00) SMASK (01) ;
+--END
diff --git a/fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_3.svft b/fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_3.svft
new file mode 100644
index 0000000..d2dc978
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_3.svft
@@ -0,0 +1,83 @@
+//Info: Sample template for programming XILINX Spartan 3 FPGA
+//Info: Created with output from Impact
+
+--LITERAL START
+TRST OFF;
+ENDIR IDLE;
+ENDDR IDLE;
+STATE RESET;
+STATE IDLE;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 6 TDI (09) SMASK (3f) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 6 TDI (09) ;
+SDR 32 TDI (00000000) TDO ($ID$) ;
+//Loading device with 'bypass' instruction.
+SIR 6 TDI (3f) ;
+// Loading device with a `jprogram` instruction.
+SIR 6 TDI (0b) ;
+RUNTEST 1 TCK;
+// Loading device with a `bypass` instruction.
+SIR 6 TDI (3f) ;
+RUNTEST 14000 TCK;
+// Loading device with a `cfg_in` instruction.
+SIR 6 TDI (05) ;
+SDR 192 TDI (0000000000000000e00000008001000c66aa9955ffffffff) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffff) ;
+// Loading device with a `jshutdown` instruction.
+SIR 6 TDI (0d) ;
+RUNTEST 12 TCK;
+STATE RESET;
+// Loading device with a `cfg_in` instruction.
+SIR 6 TDI (05) ;
+SDR 64 TDI (0000000000000000) SMASK (ffffffffffffffff) ;
+SIR 6 TDI (05) TDO (00) MASK (00) ;
+SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
+// Loading device with a `jstart` instruction.
+SIR 6 TDI (0c) ;
+RUNTEST 12 TCK;
+//Loading device with 'bypass' instruction.
+SIR 6 TDI (3f) ;
+//Loading device with 'bypass' instruction.
+SIR 6 TDI (3f) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+// Loading device with a `jstart` instruction.
+SIR 6 TDI (0c) ;
+RUNTEST 12 TCK;
+//Checking done pin status.
+//Loading device with 'Bypass' instruction.
+SIR 6 TDI (3f) TDO (21) MASK (20) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+SIR 6 TDI (3f) ;
+SDR 1 TDI (00) SMASK (01) ;
+--END
diff --git a/fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_II.svft b/fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_II.svft
new file mode 100644
index 0000000..8ef16a4
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/alg_Spartan_II.svft
@@ -0,0 +1,95 @@
+//Info: Sample template for programming XILINX SpartanII FPGA
+//Info: Created with output from Impact
+
+--LITERAL START
+TRST OFF;
+ENDIR IDLE;
+ENDDR IDLE;
+STATE RESET;
+STATE IDLE;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 5 TDI (09) SMASK (1f) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 5 TDI (09) ;
+SDR 32 TDI (00000000) TDO ($ID$) ;
+//Loading device with 'bypass' instruction.
+SIR 5 TDI (1f) ;
+STATE RESET;
+// Loading device with a `cfg_in` instruction.
+SIR 5 TDI (05) ;
+SDR 288 TDI (00000000e00000008001000ca00000008001000cbcfd05008004800c66aa995500000000) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
+STATE RESET;
+// Loading device with a `jstart` instruction.
+SIR 5 TDI (0c) ;
+SDR 13 TDI (0000) SMASK (1fff) ;
+STATE RESET;
+// Loading device with a `cfg_in` instruction.
+SIR 5 TDI (05) ;
+SDR 352 TDI (00000000e00000008001000ca00000008001000cfffc05008004800c100000008001000c66aa995500000000) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
+STATE RESET;
+// Loading device with a `jstart` instruction.
+SIR 5 TDI (0c) ;
+SDR 13 TDI (0000) SMASK (1fff) ;
+STATE RESET;
+// Loading device with a `cfg_in` instruction.
+SIR 5 TDI (05) ;
+SDR 288 TDI (00000000e00000008001000ca00000008001000cb4fd05008004800c66aa995500000000) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
+STATE RESET;
+// Loading device with a `jstart` instruction.
+SIR 5 TDI (0c) ;
+SDR 13 TDI (0000) SMASK (1fff) ;
+STATE RESET;
+// Loading device with a `cfg_in` instruction.
+SIR 5 TDI (05) ;
+
+SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
+
+STATE RESET;
+// Loading device with a `jstart` instruction.
+SIR 5 TDI (0c) ;
+SDR 13 TDI (0000) SMASK (1fff) ;
+STATE RESET;
+//Loading device with 'bypass' instruction.
+SIR 5 TDI (1f) ;
+//Loading device with 'bypass' instruction.
+SIR 5 TDI (1f) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+STATE RESET;
+//Checking done pin status.
+//Loading device with 'Bypass' instruction.
+SIR 5 TDI (1f) TDO (05) MASK (04) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+SIR 5 TDI (1f) ;
+SDR 1 TDI (00) SMASK (01) ;
+--END
diff --git a/fpga/xilinx/programmer/bit2svf/templates/alg_Virtex_4.svft b/fpga/xilinx/programmer/bit2svf/templates/alg_Virtex_4.svft
new file mode 100644
index 0000000..1bd73f4
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/alg_Virtex_4.svft
@@ -0,0 +1,111 @@
+//Info: Sample template for programming XILINX Virtex 4 FPGA
+//Info: Created with output from Impact
+
+--LITERAL START
+TRST OFF;
+ENDIR IDLE;
+ENDDR IDLE;
+STATE RESET;
+STATE IDLE;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 10 TDI (03c9) SMASK (03ff) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 10 TDI (03c9) ;
+SDR 32 TDI (00000000) TDO ($ID$) ;
+//Loading device with 'bypass' instruction.
+SIR 10 TDI (03ff) ;
+// Loading device with a `ISC_ENABLE` instruction.
+ENDIR IRPAUSE;
+SIR 10 TDI (03d0) ;
+SDR 5 TDI (15) SMASK (1f) ;
+ENDIR IDLE;
+RUNTEST 12 TCK;
+// Loading device with a `ISC_PROGRAM_SECURITY` instruction.
+ENDIR IRPAUSE;
+SIR 10 TDI (03d2) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) ;
+ENDIR IDLE;
+RUNTEST 9 TCK;
+// Loading device with a `ISC_DISABLE` instruction.
+SIR 10 TDI (03d7) ;
+RUNTEST 12 TCK;
+// Loading device with a `jprogram` instruction.
+SIR 10 TDI (03cb) ;
+RUNTEST 1 TCK;
+// Loading device with a `bypass` instruction.
+SIR 10 TDI (03ff) ;
+RUNTEST 21000 TCK;
+// Loading device with a `cfg_in` instruction.
+SIR 10 TDI (03c5) ;
+RUNTEST 100000 TCK;
+// Check init_complete in ircapture.
+//Loading device with 'Bypass' instruction.
+SIR 10 TDI (03ff) TDO (0010) MASK (0010) ;
+// Loading device with a `jprogram` instruction.
+SIR 10 TDI (03cb) ;
+RUNTEST 1 TCK;
+// Loading device with a `bypass` instruction.
+SIR 10 TDI (03ff) ;
+RUNTEST 21000 TCK;
+// Loading device with a `cfg_in` instruction.
+SIR 10 TDI (03c5) ;
+RUNTEST 100000 TCK;
+// Check init_complete in ircapture.
+//Loading device with 'Bypass' instruction.
+SIR 10 TDI (03ff) TDO (0010) ;
+STATE RESET;
+// Loading device with a `cfg_in` instruction.
+SIR 10 TDI (03c5) TDO (0000) MASK (0000) ;
+SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
+// Loading device with a `jstart` instruction.
+SIR 10 TDI (03cc) ;
+RUNTEST 12 TCK;
+//Loading device with 'bypass' instruction.
+SIR 10 TDI (03ff) ;
+//Loading device with 'bypass' instruction.
+SIR 10 TDI (03ff) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+// Loading device with a `jstart` instruction.
+SIR 10 TDI (03cc) ;
+RUNTEST 12 TCK;
+// Loading device with a `cfg_in` instruction.
+SIR 10 TDI (03c5) ;
+SDR 224 TDI (0000000000000000200000008001000c0000000466aa9955ffffffff) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
+//Checking done pin status.
+//Loading device with 'Bypass' instruction.
+SIR 10 TDI (03ff) TDO (0021) MASK (0020) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+SIR 10 TDI (03ff) ;
+SDR 1 TDI (00) SMASK (01) ;
+--END
diff --git a/fpga/xilinx/programmer/bit2svf/templates/alg_XCF.svft b/fpga/xilinx/programmer/bit2svf/templates/alg_XCF.svft
new file mode 100644
index 0000000..73138c3
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/alg_XCF.svft
@@ -0,0 +1,190 @@
+//Info: Sample template for programming XILINX XCFxx PROMS
+//Info: Created with output from Impact
+
+--LITERAL START
+TRST OFF;
+ENDIR IDLE;
+ENDDR IDLE;
+STATE RESET;
+STATE IDLE;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'idcode' instruction.
+SIR 8 TDI (fe) SMASK (ff) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Check for Read/Write Protect.
+SIR 8 TDI (ff) TDO (01) MASK (07) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+// Loading device with 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI (0001) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with 'ferase' instruction.
+SIR 8 TDI (ec) ;
+RUNTEST 1 TCK;
+RUNTEST 15000000 TCK;
+// Loading devices with 'conld' or 'bypass' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+--END
+
+$ADDRESS(0x0000)$
+$STEP(0x0020)$
+
+--REPEAT START
+// Loading device with a 'fdata0' instruction.
+SIR 8 TDI (ed) ;
+SDR $BSIZE$ TDI ($DATA_INV(BSIZEB)$) SMASK ($FILL(0xFF,BSIZEB)$) ;
+ENDIR IDLE;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fpgm' instruction.
+ENDIR IRPAUSE;
+SIR 8 TDI (ea) ;
+RUNTEST 1 TCK;
+RUNTEST 14000 TCK;
+--END
+
+--LITERAL START
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI (0001) ;
+ENDIR IDLE;
+RUNTEST 1 TCK;
+// Loading device with 'serase' instruction.
+SIR 8 TDI (0a) ;
+RUNTEST 37000 TCK;
+// Loading devices with 'conld' or 'bypass' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) ;
+--END
+
+$REWIND$
+$ADDRESS(0x0000)$
+$STEP(0x0040)$
+
+--REPEAT START
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fvfy0' instruction.
+SIR 8 TDI (ef) ;
+RUNTEST 1 TCK;
+RUNTEST 50 TCK;
+SDR $BSIZE2$ TDI ($FILL(0x00,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($DATA_INV(BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
+--END
+
+--REPEAT UNTIL MSIZE
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) ;
+SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fvfy0' instruction.
+SIR 8 TDI (ef) ;
+RUNTEST 1 TCK;
+RUNTEST 50 TCK;
+SDR $BSIZE2$ TDI ($FILL(0xFF,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($FILL(0xFF,BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
+--END
+
+--LITERAL START
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) ;
+// Loading device with a 'faddr' instruction.
+SIR 8 TDI (eb) TDO (00) MASK (00) ;
+SDR 16 TDI (8000) SMASK (ffff) ;
+RUNTEST 1 TCK;
+RUNTEST 1 TCK;
+// Loading device with a 'fdata3' instruction.
+SIR 8 TDI (f3) TDO (00) ;
+SDR 3 TDI (07) SMASK (07) TDO (00) MASK (00) ;
+// Loading device with a 'fpgm' instruction.
+SIR 8 TDI (ea) TDO (00) ;
+RUNTEST 1 TCK;
+RUNTEST 14000 TCK;
+// Loading device with a 'fvfy3' instruction.
+SIR 8 TDI (e2) TDO (00) ;
+RUNTEST 1 TCK;
+RUNTEST 50 TCK;
+SDR 3 TDI (07) TDO (07) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+//Loading device with 'ispen' instruction.
+SIR 8 TDI (e8) ;
+SDR 6 TDI (34) SMASK (3f) ;
+//Loading device with 'conld' instruction.
+SIR 8 TDI (f0) ;
+RUNTEST 110000 TCK;
+// Loading device with a 'config' instruction.
+SIR 8 TDI (ee) TDO (00) ;
+RUNTEST 50 TCK;
+//Loading device with 'bypass' instruction.
+SIR 8 TDI (ff) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+SIR 8 TDI (ff) ;
+SDR 1 TDI (00) SMASK (01) ;
+--END
diff --git a/fpga/xilinx/programmer/bit2svf/templates/alg_XCFP.svft b/fpga/xilinx/programmer/bit2svf/templates/alg_XCFP.svft
new file mode 100644
index 0000000..214fa4a
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/templates/alg_XCFP.svft
@@ -0,0 +1,208 @@
+//Info: Sample template for programming XILINX XCFxxP PROMS
+//Info: Created with output from Impact
+
+--LITERAL START
+TRST OFF;
+ENDIR IDLE;
+ENDDR IDLE;
+STATE RESET;
+STATE IDLE;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) SMASK (ffff) ;
+SDR 8 TDI (03) SMASK (ff) ;
+//Loading device with 'idcode' instruction.
+SIR 16 TDI (00fe) ;
+SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (d0) SMASK (ff) ;
+// Loading device with a 'XSC_UNLOCK' instruction.
+SIR 16 TDI (aa55) ;
+SDR 24 TDI (00003f) SMASK (ffffff) ;
+// Loading device witha 'ISC_ERASE' instruction.
+ENDIR IRPAUSE;
+SIR 16 TDI (00ec) ;
+SDR 24 TDI (00003f) ;
+ENDIR IDLE;
+RUNTEST 140000000 TCK;
+// Loading devices with 'conld' or 'bypass' instruction.
+SIR 16 TDI (00f0) ;
+RUNTEST 50 TCK;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (d0) SMASK (ff) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) ;
+// Loading device with 'XSC_DATA_BTC' instruction.
+SIR 16 TDI (00f2) ;
+SDR 32 TDI (ffffffe0) SMASK (ffffffff) TDO (00000000) MASK (00000000) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 120 TCK;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+STATE RESET;
+// Loading devices with 'ispen' or 'bypass' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (d0) SMASK (ff) ;
+--END
+
+$CUTLINES(0)$
+
+--LITERAL START
+// Loading device with a 'ISC_DATA_SHIFT' instruction.
+SIR 16 TDI (00ed) ;
+SDR 256 TDI ($DATA_INV(32)$) SMASK ($FILL(0xFF,32)$) ;
+// Loading device with a 'ISC_ADDRESS_SHIFT' instruction.
+SIR 16 TDI (00eb) ;
+SDR 24 TDI (000000) SMASK (ffffff) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 1000 TCK;
+// Loading device with a 'ISC_DATA_SHIFT' instruction.
+SIR 16 TDI (00ed) ;
+SDR 256 TDI ($DATA_INV(32)$) SMASK ($FILL(0xFF,32)$) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 1000 TCK;
+--END
+
+--REPEAT START
+// Loading device with a 'ISC_DATA_SHIFT' instruction.
+SIR 16 TDI (00ed) ;
+SDR 256 TDI ($DATA_INV(32)$) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 1000 TCK;
+--END
+
+$CUTLINES(1)$
+
+--LITERAL START
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) SMASK (ff) ;
+// Loading device with a 'XSC_DATA_SUCR' instruction.
+SIR 16 TDI (000e) ;
+SDR 16 TDI (fffc) SMASK (ffff) TDO (0000) MASK (0000) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 60 TCK;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) SMASK (ff) ;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) ;
+// Loading device witha 'XSC_DATA_CCB' instruction.
+SIR 16 TDI (000c) ;
+SDR 16 TDI (fff9) SMASK (ffff) TDO (0000) MASK (0000) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 60 TCK;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+// Loading devices with 'conld' or 'bypass' instruction.
+SIR 16 TDI (00f0) ;
+RUNTEST 50 TCK;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) SMASK (ff) ;
+// Loading device with 'XSC_DATA_DONE' instruction.
+SIR 16 TDI (0009) ;
+SDR 8 TDI (ce) TDO (00) MASK (00) ;
+// Loading device with a 'ISC_PROGRAM' instruction.
+SIR 16 TDI (00ea) ;
+RUNTEST 60 TCK;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) ;
+--END
+
+$REWIND$
+$ADDRESS(0x0000)$
+$STEP(0x0400)$
+
+--REPEAT START
+// Loading device with a 'ISC_ADDRESS_SHIFT' instruction.
+SIR 16 TDI (00eb) ;
+SDR 24 TDI ($ADDRESS$) SMASK (ffffff) ;
+// Loading device with a 'XSC_READ' instruction.
+SIR 16 TDI (00ef) ;
+RUNTEST 15 TCK;
+SDR $BSIZE$ TDI ($FILL(0x00,BSIZEB)$) SMASK ($FILL(0xFF,BSIZEB)$) TDO ($DATA_INV(BSIZEB)$) MASK ($FILL(0xFF,BSIZEB)$) ;
+--END
+
+--LITERAL START
+// Check Device status.
+SIR 16 TDI (00e3) ;
+SDR 8 TDI (00) SMASK (ff) TDO (36) MASK (7f) ;
+//Loading device with 'conld' instruction.
+SIR 16 TDI (00f0) ;
+RUNTEST 50 TCK;
+//Loading device with 'ispen' instruction.
+SIR 16 TDI (00e8) ;
+SDR 8 TDI (03) ;
+//Loading device with 'conld' instruction.
+SIR 16 TDI (00f0) ;
+RUNTEST 50 TCK;
+// Loading device with a 'config' instruction.
+SIR 16 TDI (00ee) TDO (0000) MASK (0000) ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+HDR 0 ;
+TDR 0 ;
+TIR 0 ;
+HIR 0 ;
+TDR 0 ;
+HDR 0 ;
+SIR 16 TDI (ffff) ;
+SDR 1 TDI (00) SMASK (01) ;
+--END
diff --git a/fpga/xilinx/programmer/bit2svf/usage.txt b/fpga/xilinx/programmer/bit2svf/usage.txt
new file mode 100644
index 0000000..f04266d
--- /dev/null
+++ b/fpga/xilinx/programmer/bit2svf/usage.txt
@@ -0,0 +1,63 @@
+Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
+Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
+Copyright (c) 2001, 2002 by David Sullins
+Licese: GPL por bitfile.c
+
+
+jbit:
+-----
+ This script is a shortcut for programming a device using the GNU JTAG
+ program with a .bit file. It generates and deletes the intermediate SVF
+ file. It can read a personal config, refer to jbitrc_sample.txt.
+
+Sample:
+
+bit2svf$ ./jbit ejemplo_prom.bit XC18V01
+
+jbit - bit2svf/jtag short cut - v1.0
+Copyright (c) 2005 Juan Pablo D. Borgna/INTI
+
+Creando archivo temporario /tmp/bit2svf.tmp
+
+bit2svf - SVF file generator - v1.0
+Copyright (c) 2005 Juan Pablo D. Borgna/INTI
+
+
+Bit file created on 2004/08/25 at 13:43:18.
+Created from file ejemplo.ncd for Xilinx part 2s100pq208.
+Bitstream length is 97652 bytes.
+
+Process finsished sucefully.
+Creado ok
+Invocando /home/jpablo/usr/bin/jtag
+Initializing Xilinx DLC5 JTAG Parallel Cable III on ppdev port /dev/parport0
+IR length: 8
+Chain length: 1
+Device Id: 00000101000000100100000010010011
+ Manufacturer: Xilinx
+ Part: XC18V01-SO20
+ Stepping: 1
+ Filename: /home/jpablo/usr//share/jtag/xilinx/xc18v01-so20/xc18v01-so20
+Warning svf: checking of TDO not supported for SIR.
+ This message is only displayed once.
+Borrando temporarios..
+Que tenga un buen dia :-)
+
+
+
+bit2svf:
+--------
+ This program generates a SVF file wich using the program JTAG it is
+ possible to program a FPGA or PROM.
+
+Sample:
+
+bit2svf$ ./bit2svf ejemplo_prom.bit ejemplo_prom.svf XC18V01
+
+Bit file created on 2004/08/25 at 13:43:18.
+Created from file ejemplo.ncd for Xilinx part 2s100pq208.
+Bitstream length is 97652 bytes.
+
+Process finsished sucefully.
+
+