eep24c-0.1.2/0000755000175000017500000000000010265023564012237 5ustar pznpzn00000000000000eep24c-0.1.2/help_en/0000755000175000017500000000000010265023137013645 5ustar pznpzn00000000000000eep24c-0.1.2/help_en/eep24c.txt0000644000175000017500000000500107701614032015465 0ustar pznpzn00000000000000EEP24C(1) EEP24C(1) NAME eep24c - read and write 24Cxxx eeprom devices SYNOPSIS eep24c -d device [ -r filename | -w filename | -k filename | -f xx ] DESCRIPTION The command eep24c can be used to read and write 24Cxxx eeprom devices. OPTIONS The following options are available: -d device Specify the device type. To see a list of the sup ported devices, try -d help -r filename Read from eeprom and save to a file. -w filename Read from a file and write to eeprom. The addresses not specified in the input file will be filled with 00. -k filename Read from a file and write to eeprom. The addresses not specified in the input file will be kept with its previous values. (this mode is twice slower. It reads whole memory to know previous val ues, then write whole memory) -f XX Fills the whole eeprom with XX (xx is an hexadeci mal value) USAGE EXAMPLES eep24c -d 24c04 -r file.hex read eeprom, write to file.hex eep24c -d 24c04 -w file.hex read file.hex and write to eeprom. All the bytes not found in file.hex will be written as 00. eep24c -d 24c04 -k file.hex read file.hex and write to eeprom. All the bytes not found in file.hex will remain unchanged. eep24c -d 24c04 -f 7A fill eeprom with 7A (hexadecimal). INPUT AND OUTPUT FORMAT Input and output file format is Intel Hexadecimal Object File Format You can find this specification at ftp://download.intel.com/support/processors/ i960/devtools/INTELHEX.PDF Record types 00 and 01 are implemented in this version. In input lines, LF and CR+LF are accepted as newline mark ers. Output files are generated with LF as a newline marker. DEVICE SPECIFIC If you are using Microchip 24*515, you must tie its pin A2 to VCC (needs a hardware modification, see device datasheet). SEE ALSO ihex2txt(1), txt2ihex(1). AUTHOR This manual page was written by Pedro Zorzenon Neto . 2002-11-14 EEP24C(1) eep24c-0.1.2/help_en/ihex2txt.txt0000644000175000017500000000311007700067350016165 0ustar pznpzn00000000000000EEP24C(1) EEP24C(1) NAME ihex2txt - converts Intelhex format to a simple text format txt2ihex - converts simple text format to Intelhex SYNOPSIS ihex2txt inputfile outputfile txt2ihex inputfile outputfile DESCRIPTION The commands ihex2txt and txt2ihex can be used to edit data in Intelhex format. First you get the original Intelhex file and use ihex2txt to convert it. Then you edit the text file and convert back to Intelhex using txt2ihex INTELHEX FORMAT Intel Hexadecimal Object File Format or simply Intelhex specification can be found at ftp://download.intel.com/support/processors/ i960/devtools/INTELHEX.PDF Record types 00 and 01 are implemented in this version. In input lines, LF and CR+LF are accepted as newline mark ers. Output files are generated with LF as a newline marker. TEXT FORMAT The text format is composed by a line with values sepa rated with spaces. The first value is the initial address, the following values are the values. Example: 02B7 07 B9 70 7A 6E means that the content of address 02B7 is 07, the content of address 02B8 is B9, the content of address 02B9 is 70, ... SEE ALSO eep24c(1). AUTHOR This manual page was written by Pedro Zorzenon Neto . 2002-11-14 EEP24C(1) eep24c-0.1.2/Makefile0000644000175000017500000000362410265023474013704 0ustar pznpzn00000000000000# $Id: Makefile,v 1.2 2003/06/30 17:20:24 pzn Exp $ CFLAGS=-O2 -Wall all: ihex2txt txt2ihex eep24c install: all # Create destination directories mkdir -p $(DESTDIR)/etc/eep24c mkdir -p $(DESTDIR)/usr/bin mkdir -p $(DESTDIR)/usr/share/man/man1 mkdir -p $(DESTDIR)/usr/share/doc/eep24c # install binary files install -m 755 eep24c $(DESTDIR)/usr/bin/ install -m 755 ihex2txt $(DESTDIR)/usr/bin/ install -m 755 txt2ihex $(DESTDIR)/usr/bin/ # install man pages cat eep24c.1 | gzip -9 > $(DESTDIR)/usr/share/man/man1/eep24c.1.gz cat ihex2txt.1 | gzip -9 > $(DESTDIR)/usr/share/man/man1/ihex2txt.1.gz cd $(DESTDIR)/usr/share/man/man1/; ln -sf ihex2txt.1.gz txt2ihex.1.gz # install documentation install -m 644 copyright $(DESTDIR)/usr/share/doc/eep24c/ install -m 644 eep.ps.gz $(DESTDIR)/usr/share/doc/eep24c/ install -m 644 eep.gschem.sch $(DESTDIR)/usr/share/doc/eep24c/ install -m 644 eep.jpg $(DESTDIR)/usr/share/doc/eep24c/ install -m 644 README.txt $(DESTDIR)/usr/share/doc/eep24c/ # install configuration file install -m 644 eep24c.cfg $(DESTDIR)/etc/eep24c/ uninstall: rm -fv $(DESTDIR)/etc/eep24c/eep24c.cfg rm -fv $(DESTDIR)/usr/bin/eep24c rm -fv $(DESTDIR)/usr/bin/ihex2txt rm -fv $(DESTDIR)/usr/bin/txt2ihex rm -fv $(DESTDIR)/usr/share/man/man1/eep24c.1.gz rm -fv $(DESTDIR)/usr/share/man/man1/ihex2txt.1.gz rm -fv $(DESTDIR)/usr/share/man/man1/txt2ihex.1.gz rm -fv $(DESTDIR)/usr/share/doc/eep24c/copyright rm -fv $(DESTDIR)/usr/share/doc/eep24c/eep.ps.gz rm -fv $(DESTDIR)/usr/share/doc/eep24c/eep.gschem.sch rm -fv $(DESTDIR)/usr/share/doc/eep24c/eep.tif rm -fv $(DESTDIR)/usr/share/doc/eep24c/README.txt rmdir $(DESTDIR)/etc/eep24c || true rmdir $(DESTDIR)/usr/share/doc/eep24c || true ihex2txt: ihex2txt.o intelhex.o txt2ihex: txt2ihex.o intelhex.o eep24c: eep24c.o eeprom.o intelhex.o memory.o parport.o mcdelay.o conf.o clean: rm -f ihex2txt txt2ihex eep24c *.o *~ distclean: clean eep24c-0.1.2/README.txt0000644000175000017500000000225110265023477013740 0ustar pznpzn00000000000000$Id: README.txt,v 1.2 2003/06/30 17:20:24 pzn Exp $ EEP24C is a program to read from and write to 24Cxxx eeprom devices. You can find the hardware schematics at the files: "eep.ps.gz" or if you prefer in "eep.jpg" Hardware connections: Build the hardware using the schematics and connect it to the parallel port of the computer. Common options: It uses by default LPT1 = 0x378. If you want to change it, edit the configuration file. Compiling/installing in GNU/Linux systems: make make install DESTDIR=/ edit the configuration file /etc/eep24c/eep24c.cfg Note: this program will access the parallel port hardware, it needs to be run by root or need to be root setuid. If you want only root to use it, than it is ready for use. If you want you can use the command: "chmod +s /usr/bin/eep24c" to enable all users. To uninstall try: make uninstall DESTDIR=/ Compiling/installing in DOS systems: edit common.h and read the instructions Compile with your prefered compiler. Choose "compact" memory model. Put the .exe files and also eep24c.cfg in C:\eep24c\ Modify eep24.cfg if needed. eep24c-0.1.2/common.h0000644000175000017500000000225110265023462013675 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: common.h,v 1.2 2003/06/30 17:20:24 pzn Exp $ */ #ifndef _EEPCOMMON_H #define _EEPCOMMON_H /* to compile in DOS systems, define __dos__ * if your compiler does not define it, use the line below */ /* #define __dos__ */ /* The DOS executable was compiled with Borland TurboC * version 2.01, option: compact memory model * and was tested on Win98 MS-DOS prompt. */ #endif eep24c-0.1.2/conf.c0000644000175000017500000000365110265023463013333 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: conf.c,v 1.2 2003/06/30 17:20:24 pzn Exp $ */ #include #include #include #include "common.h" #define LINESIZE 1024 unsigned long int parport_baseaddress(void) { FILE *f; char l[LINESIZE]; unsigned long int pp=0; #ifdef __dos__ f=fopen("/eep24c/eep24c.cfg","r"); if (f==NULL) { f=fopen("eep24c.cfg","r"); if (f==NULL) { fprintf(stderr,"could not open configuration file. tryed to open " "file eep24c.cfg in directory \\eep24c\\ and also in the " "current directory "); perror(""); abort(); } } #else f=fopen("/etc/eep24c/eep24c.cfg","r"); if (f==NULL) { perror("could not open configuration file /etc/eep24c/eep24c.cfg"); abort(); } #endif /* parse config file */ fgets(l, LINESIZE-1, f); while ( feof(f)==0 ) { if (strncmp(l,"parport_address",15)==0) { pp=strtoul(l+15,NULL,16); } fgets(l, LINESIZE-1, f); } if (pp==0) { fprintf(stderr,"did not understand config file.\n" "configuration must have a line similar with the line below:\n" "parport_address 378\n"); abort(); } return pp; } eep24c-0.1.2/conf.h0000644000175000017500000000167310265023463013342 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: conf.h,v 1.2 2003/06/30 17:20:24 pzn Exp $ */ #ifndef _EEPCONF_H #define _EEPCONF_H unsigned long int parport_baseaddress(void); #endif eep24c-0.1.2/copyright0000644000175000017500000000153310265023464014173 0ustar pznpzn00000000000000Copyright notes for eep24c, ihex2txt, txt2ihex and its source files Copyright (C) 2002 Pedro Zorzenon Neto 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. $Id: copyright,v 1.2 2003/06/30 17:20:24 pzn Exp $ eep24c-0.1.2/eep.gschem.sch0000644000175000017500000001141710265023466014761 0ustar pznpzn00000000000000v 20010722 C 16400 66400 1 0 0 DB25-2.sym { T 16700 71900 5 10 1 1 0 0 uref=CN1 } C 18500 70200 1 0 0 diode-1.sym { T 19200 70500 5 10 1 1 0 0 uref=D1 T 19900 70800 5 10 1 1 0 0 value=6x 1N4148 } C 19300 69800 1 0 0 diode-1.sym { T 20000 70100 5 10 1 1 0 0 uref=D2 } C 20100 69400 1 0 0 diode-1.sym { T 20800 69700 5 10 1 1 0 0 uref=D3 } C 18500 69000 1 0 0 diode-1.sym { T 19200 69300 5 10 1 1 0 0 uref=D4 } C 19300 68600 1 0 0 diode-1.sym { T 20000 68900 5 10 1 1 0 0 uref=D5 } C 20100 68200 1 0 0 diode-1.sym { T 20800 68500 5 10 1 1 0 0 uref=D6 } N 21000 68400 21500 68400 4 N 21500 70400 19400 70400 4 N 20200 70000 21500 70000 4 N 19400 69200 21500 69200 4 N 20200 68800 21500 68800 4 N 21000 69600 21500 69600 4 N 18500 70400 17900 70400 4 N 17900 70000 19300 70000 4 N 17900 69600 20100 69600 4 N 18500 69200 17900 69200 4 N 17900 68800 19300 68800 4 N 20100 68400 17900 68400 4 N 16400 69800 16000 69800 4 N 16000 67000 16400 67000 4 N 16400 67400 16000 67400 4 N 16400 67800 16000 67800 4 N 16400 68200 16000 68200 4 N 16400 68600 16000 68600 4 N 16400 69000 16000 69000 4 N 16400 69400 16000 69400 4 C 21300 67600 1 270 0 capacitor-2.sym { T 21000 66600 5 10 1 1 0 0 uref=C2 T 21000 66300 5 10 1 1 0 0 name=10uF } C 20800 66700 1 90 0 capacitor-1.sym { T 20100 66700 5 10 1 1 180 0 uref=C1 T 19900 66300 5 10 1 1 0 0 value=100nF } N 16000 65800 16000 69800 4 N 21500 65800 21500 66700 4 N 20600 66700 20600 65800 4 N 20600 67600 20600 67800 4 N 20600 67800 21500 67800 4 N 21500 67600 21500 70400 4 C 18400 73000 1 0 0 resistor-1.sym { T 18500 72800 5 10 1 1 0 0 uref=R1 T 18500 72500 5 10 1 1 0 0 value=10K } C 19800 72000 1 90 0 resistor-1.sym { T 19400 72700 5 10 1 1 180 0 uref=R2 T 19500 72400 5 10 1 1 180 0 value=10K } C 23300 72700 1 180 0 resistor-1.sym { T 22500 73200 5 10 1 1 0 0 uref=R3 T 22500 72900 5 10 1 1 0 0 value=47K } C 20200 72600 1 0 0 npn-1.sym { T 20900 73100 5 10 1 1 0 0 uref=Q1 T 20900 72800 5 10 1 1 0 0 value=BC547 } N 19300 73100 20200 73100 4 N 19700 72900 19700 73100 4 N 19700 72000 20700 72000 4 N 20700 72000 20700 72600 4 C 21400 65500 1 0 0 gnd-1.sym C 20600 71700 1 0 0 gnd-1.sym C 21300 70400 1 0 0 vcc-1.sym N 17900 70800 18200 70800 4 N 18200 70800 18200 73100 4 N 18200 73100 18400 73100 4 N 16400 71000 16000 71000 4 N 16000 71000 16000 73700 4 N 16000 73700 21800 73700 4 C 24500 72800 1 0 0 vcc-1.sym P 23900 69700 24200 69700 1 { T 23950 69750 5 8 1 1 0 0 pin5=5 } P 22700 70300 23000 70300 1 { T 22900 70350 5 8 1 1 0 0 pin1=1 } T 23100 70300 9 8 1 0 0 0 A0 T 23100 70100 9 8 1 0 0 0 A1 T 23100 69900 9 8 1 0 0 0 A2 T 23500 69700 9 8 1 0 0 0 SDA P 22700 69900 23000 69900 1 { T 22850 69950 5 8 1 1 0 0 pin3=3 } P 23900 69900 24200 69900 1 { T 23950 69950 5 8 1 1 0 0 pin6=6 } T 23550 70100 9 8 1 0 0 0 n/c T 23700 73050 5 8 0 0 0 0 device=24Cxx P 22700 70100 23000 70100 1 { T 22850 70150 5 8 1 1 0 0 pin2=2 } P 23900 70100 24200 70100 1 { T 23950 70150 5 8 1 1 0 0 pin7=7 } T 23000 70550 9 8 1 0 0 0 24Cxxx T 23500 69900 9 8 1 0 0 0 SCL T 23700 70600 8 10 1 1 0 0 uref=U1 P 22700 69700 23000 69700 1 { T 22850 69750 5 8 1 1 0 0 pin4=4 } P 23900 70300 24200 70300 1 { T 23950 70350 5 8 1 1 0 0 pin8=8 } T 23500 70300 9 8 1 0 0 0 VCC T 23100 69700 9 8 1 0 0 0 GND B 23000 69600 900 900 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1 N 22700 70300 22500 70300 4 N 22500 69700 22700 69700 4 N 22700 69900 22500 69900 4 N 22700 70100 22500 70100 4 N 22500 69500 22500 70300 4 N 24200 70100 24400 70100 4 N 24400 70100 24400 69500 4 P 24400 69300 24400 69500 1 { T 24458 69361 5 4 0 1 0 0 pin1=1 } L 24300 69300 24500 69300 3 0 0 0 -1 -1 L 24355 69250 24445 69250 3 0 0 0 -1 -1 L 24380 69210 24420 69210 3 0 0 0 -1 -1 T 24700 71650 5 10 0 0 0 0 net=GND:1 P 22500 69300 22500 69500 1 { T 22558 69361 5 4 0 1 0 0 pin1=1 } L 22400 69300 22600 69300 3 0 0 0 -1 -1 L 22455 69250 22545 69250 3 0 0 0 -1 -1 L 22480 69210 22520 69210 3 0 0 0 -1 -1 T 22800 71650 5 10 0 0 0 0 net=GND:1 P 24400 70500 24400 70700 1 { T 24450 70550 5 6 0 1 0 0 pin1=1 } L 24250 70700 24550 70700 3 0 0 0 -1 -1 T 24275 70750 9 8 1 0 0 0 Vcc T 24350 72900 8 10 0 0 0 0 net=Vcc:1 N 24200 70300 24400 70300 4 N 24400 70300 24400 70500 4 N 17900 71200 22000 71200 4 N 22000 71200 22000 68600 4 N 22000 68600 24800 68600 4 N 24800 68600 24800 69900 4 N 24800 69900 24200 69900 4 N 24200 69700 25000 69700 4 N 25000 69700 25000 71800 4 N 25000 71800 21800 71800 4 N 21800 71800 21800 73700 4 C 22500 66700 1 90 0 resistor-1.sym { T 22100 66700 5 10 1 1 180 0 uref=R4 T 22200 66400 5 10 1 1 180 0 value=100K } N 22400 67600 22400 67800 4 N 22400 67800 21500 67800 4 N 22400 66700 22400 65800 4 N 16000 65800 22400 65800 4 N 20700 73600 20700 73700 4 N 22400 72600 21800 72600 4 C 24400 72800 1 180 0 diode-1.sym { T 23800 73300 5 10 1 1 180 0 uref=D7 T 23600 72900 5 10 1 1 0 0 value=1N4148 } N 23500 72600 23300 72600 4 N 24400 72600 24700 72600 4 N 24700 72600 24700 72800 4 eep24c-0.1.2/eep.jpg0000644000175000017500000026270010265023467013523 0ustar pznpzn00000000000000JFIFHHCreated with The GIMPC    $.' ",#(7),01444'9=82<.342 <"a  !1V"72AQUfu#FHTa(38B$R45Wq%Sbr'DEv&d?n:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2jMGj$>@xH.8HIx?۽Ak+saӆ3.8i| `i۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=iSf+uK?|xxz?0l/Dc3{4r9oOĭdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j='bZvIUt=E%L|HkwӼ\Z ؆[n1T/孴򺙔l{dt8`Iu̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyG\}Y lѷ;'UKo\uŧ8 t?Y>%p"""""""""""""""""""""""""""",eiO-*sˇҲ}JDDDDDDDQwRUNUY>%p"""""""""""""""""""""""""""",eiO-ӖsWvMTMGH%lnG0\p2NIㆇ(uo;zlRr윲3G27s8}+'DDDDDDDE~/5/U_t_|^\>W""""""""""""""""""""""""""""_֟$rzCkPIp6ʚbY"01.nFzwi6EdWq4-- .?Y>%p"""""""(y~*u2'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDP;VWm傐[(QcR!8q?H:kקt j.TRR/an@u@<=ZnVm ]Ot뜏luP'Q 2*DDDDDDDQwRUNUY>%p"""""""""""""""""""""""""""",eiO-=(ugQJQ}uzk+Q&[KHa22? ~зKkz9[Ęu(X8 7v^|a]ԿEU}ӕqypVO\], ~rཿÁ=W]ݬwC](#d n s&FW=]k( 2P8 mHslPOa4+U&;$;x ðppr2"h?"""""""""""""""""""""""""""""""""՟EG-*_]k^I1}C>&Ht-|^V&Ao{p-%9 .wDDDDDDDDQwRUNUY>%p"""""+^׵h4o9Nr8};˺:7mIyQig;]E200򁀰9xH.J.Y 㑭i Nc"o5>,|rI<Zfak$0 ]n\}PN>RR37c#'+!_G'j)'ܛWU3O 98 |G m (W+jIG_5vӽD#y`o ?4}e bkeS{s$TH#ހ\H!\n9-P$o= 2OW2'DDDDDDDDDDDDDDDDDDDUj^([鷹~N9k9GFi,spg1A}V*Wmjۥ5M:9ReK( !qwt h{QOQI%lޒ8ek] $haN x)h%`|rF潤dGDDDDDDDDDT↋IȺz{}Օu$Ѳ~QakGџ:Suzk+Q&[KHa22? ~зKkz9[Ęu(X8 7v^|aWz]w6mk[VϯptTť`GZNm= mʂ{kk's:NZp쵣 `p_MuMi'j?/%+XenbsK[Gxu6uԷia԰v}m앲2 Iw B""""誯r>/.JQ+?N.4;G֗j}`$<' kq -y6GuQ3ʲ<0G '/ t{5}>;!uvy M|\GA#q硵OziYYPبPwƳÖp"DDDDDE_O+t?54hlvΦ:j:vo+?$H$^aKoU݋E %!hh$ZZ~/*fWMEvM kuǃ7cVb"""""""""""""_֟$rPM/qU7~:H2G(pdrx*߲MkƨdKAӎO{KCDy̛85e\{1hj+ޮ?L2z _07)GuzRD_v:ܐ ˥Q3Yʾ<<=?Q61jf7IS3H9<ASmM<<# cpcAi >Y-rO0orqo.<\I%,xj⨧9A#W2'DDDDDDDDDDDDDDDDYBBM[i`r5u_ލeN_ލeN_ލeN_ލeN_ލmg[T4ww. phqj=1z ?+O'5K> DDE箠G_I],߆xČv#-<-u{j=iM#G(mPI)JD$3sz3\OBn\n.Kq968º?^j_ʿ8}+'DDDDDDDDDDDDDDDDDDDDDUcum0ֺ &JikZF %9d{uttQJ[,s;$' EYeR]jQLbm[[;c-' :WUSK qG8[){\ւ`ۖ)ym=lݭߤ݃`01qA2'DDDDDDDDDDDDDDDDYeZwش""*l:7 Q;~j7[Ìay ˚(Tܮt0xg !\#ݦh x@'{?)Cr:}q}IͶ;u#awIÝ30BUi}W6:nGW`~ X3ӌBlz:ꆗPCIXa1~Wmܷv4ai4DDDYjEy޴""""*OYTү>M&ֺ*V'8~$X\hiOk8nZy89:X8dH """"""""(y~*uEάZd[KlpoHxQG_UrܻP[0oH?pӻqqouznRD_ 0.C[\NH SWh4sZ#;bpH hnF\$q6+;2HMZe'At?tm!M}D>;ɷϨڧ|v6U$[Yֻ]%uCUu9"""",eiO-?.űhDP{h횎cNj;U'ЉQ~:ľt[WMyܬ=st[MB1.9 38xii娨8`I#ZƁI<W΂nB7 NGJ"""""""S+S{PϢ\ bEAw7ђx - 1z ?+O'5K> DE՚H[(n5W.WӉy0gz õwz;ղ'" &p-qI8h$pRik[W)7 zZKI' flQKUrj;U¶DK5.?FJ_5NYKq[^CQ+d.isqAkIB6u Mrqv,iq8x0\:-a`YW+ukeUDlqkLm~8x`4*7n:UJ4ީjt:˥S ><<H=]E~/5/U_t_|^\>W""""*NӫO7 EVt6ha;v.r8'vM_#Dl}O/gMI.gw3;]/e򽺫lm-vs\4p7 Xdc;tx(j*-N:ĪRѲLI<_x; UlwTALwaK;{"Hf{{]`4[O U9#ps^2#q"""""(y~&yMi=6qFdT*Xwdf=ۭvwwCrNúZ߯]uN7;.hƚ%e+I-` !sG3R\uU~Z]Eu՝s)dMsӗNNe6Gڋ`[bi8G]9ןծܪ-Mj cf_Q53-8.ii#ǣ\6[|[èf@NwWߦ&u.uƮVvs EK Id#wwse}gԺ>Uwc}odH.x;6B""誯r>/.JQ+2'DDDDDDDDDDDDDDDDYeZwش"*~ U׵]{#U/nw|x?mUG4\VO[}2üGK#aw<7x6WJڋh-L*i&{dF-oI$ О/4Tt DDDDDDE!tW-@"""""՟EG-*PޗQMDU'?u`F>skGf;_]vOYHKhmPnrヲoEW"M`WW=f[g'{B:O"1vr0Rwrrֹx#q.( {nZ'>m\4yp 2c ||'kl75u6 y)td3U;Qh7L,]I9j%crSIƞT4dnx-HTPWU\xPk#RKvC@h$FZQkl".L:"0Fv@od9y;COlj 8:Z]KY ,'u'ח"C; ;pF\Ɛ@0d;5Z(KIbf@s.'$q$DQwRUNUY>%p""""".>tzGNRX$JZ]^w眐qѥze]]E]:~Xu0Zư55p2s~7GWْN"Cȸ #vAxWjZ-:hh,OppAAzcOKCp.{^03tgDDDDD^;͚Pm<:2^FAZm٬6wH(㧍\ZƆpKi=#),tO%-.p/;sHt ݚd& !k繻!pFH$% ]ktJyii# E-6lj];tT.-cCA8g v]rwk_O9LÜc]Ƿi;f_!wU]c 0 $ݶWb%Plw*ɞV`3n0GKrqISGZ}DTRjOPI߁dOI$]ԿEU}ӕqypVO\?"""""""""""""""",˿ŠAe>ԵdԓKUǙw`pv`8\=nW COkNۜottWRN2@ q Bzxym,8\$h&кz)!+e3$F4A<0.ŽhDDDDT:W(}qިS@wC_2܃KZ]ί5 |w*ѱxs#zV޵^iXHg➩`kLs<'̿N~5,E[jfWl[-gvC-wod.>ַMS7\qOup}r@p8 NOi+ږ u?lCgZ4 kZ~L䦴=WM}E dw ֓qVlg ;M E*.PSbdqsL8-kA;k.IYw[%p5eE>=C\woxW""""",eiO-?.űhDDDDDDDDDDYl[6Dȩ%7v-#ƭ)4泧\cp)$'s$7[$DDDD^86n]"237%l-89 x{xWkmK% xcd43N?Q}Sl7 wmtս2WN!dOu]ԿEU}ӕqypVO\sˇҲ}J_9熖Zc_$85h$8TzkWM3Z kacC}d4?f͟D7{CR=1\I ր:}]ԿEU}ӕqypVO\?"""""""""""""""",˿ŠWRkp^;.ٿ2s:jNѧ.|mO5>_ <3 w5ѨmԲ^ז2[urn' .fN\>|z{iU=E'ݤa `h8##p$`""W(䬯#-wᒭPߥ$$FxB"""""*ukiGݪc #x0wH1 .1<{IH(.axox֌=a%\ 9hֶl1R489ėO@ Gx+JDDDQwRUNUY>%p""""""_֟$r?B_.[DE]k6OQEN5cy:0 l{84^h^ZH+@.C[q8g *AV?I[7rIMK+l4F\w|&'xd3lXj{vntP<4Čր IJKWEkIpc1-SdfW|'u rOO;>U ''8gwc+Ǯ[Fi:5thf{)RY:y1w\ dJ*ǭtQQCKlt scr-.Ibz^Z5=%eeHU[2\ kN.l_9熖Zc_$85h$8Tw]q}'W%ͅ KXprB۶A}u]FӼĜ@ nwK\#8?*سXzz ET܅ ` q+v^:/- ੒fCs]^ީQڴ.k=[TT7xt=?Q?sˇҲ}JDDDDDDDU~rKQRWk| ǎKOF I=7DeQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣٮ>۞K_w1Rf=;=;WMl6-=]+L5Laa%  xĵ<ם-EtQ-pdG 5<4ZJi{D^9G3 o8g3U,,SjPĐ2"ֲؕ-g_fS]npxs\% о^h^ZH+@.C[q8g *d:qP=H^mGҵG)či$4M\j4Q%$Q@-1d$\uM}d-,OgƂ\p8zݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGT3i=iU\O@":_ч`[z/d4jߵ5lE[SP繰9$tn+1?yoV?H9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:Uqf%F((EUUYؓ7`dҼd?Z|@"""""""""""""""", |lZ7'Di7'DkݳAX*4Z 7!;9Uk6]Cai~'r8m"+ʃRASzJJ;'a,DDQ~9{IOx/g>?mMj rIuU\q $z~XvGm69CJ)/CZZַp9c~ Nqqogvdr>w92s U<G4Hhs^0Ap¨}/=cnc+ ,;]<8`m~+ m.=r`,$Zo8N2fUfZ +i] HuåiAGߋKUW9WdtmbjMR 9F@$o42څƚКvz'[W;8befG*蠡[(ibd0x4ѓҪ}ګ-Rg;iYF\@|%<eSS̽-LKjL1rPO fSCYh캨c&^~ s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q l)٧c/Tx!AWsMKwy{u31 kh>Kg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W)Fm#nGؔJfs9Wɗ9y' ?Z|@"""""""""""""""", |lZ[itu;?\wq} =SAY)KUᙛo1 # [dlw=i]]imcI,hFn[,ZF=h 룎8k D 4`%p"""""")gf,o3w\:T?b9v4q^+ 0o4p.vIAV,z[hf-\N 8qUghmHIOɿyC{x9s![_COsTVGRDffp!#'S{-MNkZ%=$kֵpn DDDDEO|^\>Sc?(+.CwDux$r.H#qYz1Q_P60Ge0!ԌnG<޵+ە:Bp@A!V~cU?Z|@"""""""""""""""", |lZVl+}`iy5ۗs;\ګc@;1&Ndi+bҔfl7{K$o/.JQ+GߋKUW9Wd8}+'Dj姨9G#C<#GKq^$5eܡŢF KF\=AfP m%DCdZ'j+2K#ȿ/qp]iqgs/O9hDDDDDDDDDDDDDDDEY!u~-@"""""""'PM5cNIIQYHđ =sUtEDM%p"""""""(y~*uqޖit:>ĥS3ʾL = ]EԚMjL-Ufˣ7};w'w82?"""""""""""""""",˿ŠGߋKUW94'5U/5D5sz#M+C#xe5:y᥹Sr.A#-#<Th~lh̗C-Vs||1 N_uN[]!as9F48#GE:VŪ-lmǒ xÛќ`YPs;|hmٱlTFFG'Le4nIWކ^bX^YW"""""""誯r>/.JQ+gs/O9hDDDDDDDDDDDDDDDEY!u~-@"""""""""""S+GߋKUW9Wd*sˇҲ}JDDDDDDDDDDDDDDDDDDDDDDDDDDDDYZVkK6WrX&sFHkG 42FBõwz;ղ'" &p-qI8h$p]Wl6f Y]s40G tsF9 .>ԔzNR_(#:ZN7^HiW UҲLrVQ27&!& '8#>DDDDDDDEY!u~-@"""""""""""S+Azw@!vI5%, [ ?d_=+Mn~J%[c c`!p$g*sˇҲ}JDDDDDDDDDDDDDDDDDDDDDDDDDDDDYZwj^**i()h,'u :PI_HftzNU:Z7^׌hw+Cz<7)O_\v_y#8.ԯ،-% `c@szCN܂6O@mt,3HVȓ;q8FUWTB=\$.p'yǎ?.űhDDDDDDDDDDU~?v9Fr]{| ѿ;ѿ;ѿ;ѿ;ѿ;ѿ;ѿ;mh;]5 .nyeL9ṽđK>qm2[HKoߖ0F44<2wp<,dktDDDDDDE~/5/U_t_|^\>W""""""""""""""""""""""""""""_֟$r=[A~]q]୧m5$xkNp2q9}]}V9֞˭!wsKr` = ;Yl;0)mtl7c\d3x|Ui!MEf{O$N Y8ǀ xwBlٲ5}$Q# (+)k&:Z<όK\x;B"*SGi(&[ nܷMkU=#m |y%y-h#y/Z1qĀV[.@uˑ?qq.isN:W>6-T5TJfk9i #uHli"pdB7fp`o7G8DDDDYeZwش""""""""""""""""""誯r>/.JQ+GߋKUW9Wd?""""""".>V-)F*8(w$L\o g'6rVod};"cs4rϞ-Mj&&1sh(KAwDm{KM1-bvT\ElN\[x#9 x(DTlzrC&˅슲7#vXO#8Û̫rnB7 NGJ"""",˿Š]ԿEU}ӕqypVO\?^j_ʿ8}+'DDDDDDDDDDDDDDDDDDDDDDDDDDDDE̿>IWl+Nrmm&~'lݟu`qnn;#R9omUW%uQ݊I 899xY4v8) ;$ᣀ$""(ӭvetc(P z!ʴq?=+ϲ[]^sNv'&$`'磡Mg]kߋbzմ2Am;[$UQ8˼f'-?ڮv ]c'3907CE>FA= k#nǩtJfs0dz?खatՖi쨍QGCph[? DDDDDDEԶٯ:Vktmjx!!ah'dEQ݋m6N{^/tt]2CXp f銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LU!NO.sµz""",eiO-wIeӔIBǽiC] h˷284|jMeY(v}+MD"shK%{C@w8x&DDEY!u~-@""""""""""""""""""*Ok+DK5:s8EpnljZ+fZ5>xPU>-kp7Z㜼|h?U+@""""_֟$r;D3z9vwi"Fn Yb%ρJMnܗ5s3à "G$r#$4p$^DE˿;Fz<3}Ǡ5xzU6nݭӗ+*Kc-wx0 {NR&M Hc-8IVWT[4mNNQ4/uŧCCOIlG%\9'}GF>/*DDDTۻ-vǐ?;#'So3´5WhKv=ww<1;q'^({?I?㷿Oק^}I{3GsOӯŧSmOVM#?#c38q${70Zr =f6kyjyq$ܒx8I'IQA}_*@FK !Shy# t]ԿEU}Ӕb^(l^QLZukEVN-sx>'? EUڎ[bVKIk}Fqp;NUACOlSPQaf;h'zGߋKUW9G%X?.űhDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY5Z2'DDE֐MUu =MREVY;-΂yk"iya$txViP} ۄV+A9aldxi$ഷ vzYnѧ'ݰsO5;MQD7_ӳ{u$.6LZkmqO=Y`ab <:Xs&rA*aXGwch?ؗ~"E`"""",˿Šgt귕%hDDDYZS_ɫ %y>F6pQt/CΞz]9PWi;S:;z%nU3!.$ uB`]lj{[Q.ds1.>%OkB=_^ג feFS$Un?2Pl‚8+R^AOI$ >DzI]ԿEU}Ӕb^(l^QWPns[[!8rp4:WG#߇uzUTuٶOO]DE{r}]<:x)"誯rK ?"m x?K=MRWnax96gGkY7׻KCр79[?.űhDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY5Z2'DDDDQwRUNQxyG$V"""&^tf%ZV9]E2㜼Z]ё$G]4pXhlEPÉ#xak^&3G/N>/N>/N>/P +v{}콓rOst <k揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hKk揤);hK򕁳-O+csgt귕%hDDDYZ/h,̨2W:F1 Vߔq ;\A4mZA5ޮK&Ff1h]+Z*o|pr;`s]ԿEU}Ӕb^(l^QDlqPQuTi"Bρ ZUV6yAgjx1a뷈'-s~niv[kd-g(8\x`qຈ*CbHDDDYeZwش"""""""""""""""""""""""""""",eiO-k[""",eiO-?^j_W>v뭐oq1ND+Advw9\{ Nr[N^j(KcD,sHn}#]ԿEU}Ӕb^(l^Qw-KaT6{:DܑAAt x)h%`|rF潤dGEOMM -u]zi7*9+Rbݽ#3968o3zNP56Yn|S/O r ˚t5me~}ln\&&owdc>x7-G ܪg,*H+9vH&0x&7*CbHDDDYeZwش"""""""""""""""""""""""""""",eiO-k[""",-sO%t)|I~Rw|'|I~Rw|'|I~Rw|'|I~Rw|'|I~R_};Or܏gRKM{s}q!sN;6;3yOw'#y3oc]>/_ tEE=7ؕRDCQNI.YNԚ _+x seK ..ю+.5iccdH״n/DDE~/5/U_tؗ~"E`"""",˿Šgs/O9hDDDDDDDDDDDDDDDDDDDDDE_WGߋKUW9G%Xwkl75u6 y)td3M9Jl66Zi%ކBL 'w}nF| 9%ٔlg׍;|jMSr}b14.y wHhChn88B"""誯rK ?"jIGt]9䥥d y`$Fzueè|g1CC~vs mrzH[r#j;EOr 5 K! $dd^;]ֆ@mLuT{ɣrokiw`r[U*VMt{w\pEV4&uS5>|RIq$2J+7-n6Zi:zG kN>2ZsViFjsh*/Z _J|͋y-$<p1ؗ~"EsA{m%i*d/hYplp9iIx9l‚MGSir܎=`79' [=kӵ:Jz~^&ne:oFj9b88ewz\{zin`n2qg+?""""""""""""""""/=U}!ٕpSyi9IX%+rVWIK7Aˏ@UDDDDY5Z]ԿEU}Ӕb^(l^QH!X{~NsA,vn[8d|rΓnQG&!NsNNzWBZ 9tA$'q|y?.%'#X8CW t7=8_JkMI/(Z ` $=C4,(a{ZƆ8LJ\I'$U^Ti3*dHdha -`.q8oŐ|u[AW=6ݖ+%iCѼ4;ܽ9CT)amDA8p̃n sS;G|}whoQ\K+yҷ{]=hChsZ Ą'+#-:+T2ý+0L8| G?DSOQh,9)s^0ALG .}m;2T:פgs %-'׃qwhoQNm!M}D>;ɷϨڧ|v6T&>jCyfSF[OUQd851Fp~2Z""""""""""""m;O-u$ܮ wg8UZOi=7v7n12DRJ#/xq`Z>flO *Jݘ+k߿>i!97KH8-&mMT16]7Mֆhx X+*6!JZ^vĎECw87'Jm&äԴs_ '_=h~#9KHh Ú eDVG٤j nC M9y8ݑ1@9!5̫!{o7-\gX<7x lY-]nG{nVg3?ej9oWTb~xwnFZAWm*OgԺ솊s+\w96o8ӓ77I%Sk\6'+OLdtQ4- _5]tٕ uT╮c6wYZ0@𕙦YP=4:2KKF@8"""""""",eiO-;:MLJً,W0|"s|GGH:͡rb OPʚȄx%#| ֍ZA-]I>76V).yyZ^1A'!|ci;m>}eluu.4q@!Fr*A*|S}jt1T5{KH'&H?U+@"""""""(֖-nmeꯒwL挐֏8h$dV^՗sؔ4N08D΍q?A'<{hֻ%f.Z[7crc9#8v:*CbHDDE_KD\uMboIMM+n챤ȍj}j\+v^z;`9t;d!$Yv_^nU;"zHs'yq`%;.p??SMK4^кMY+eK:8D!9\=i=7smOڪ枊9O q8S4U,gCp??SMK&ꥏ}TGRt>w c:U;ThX·^n٪Qk[hgs %-+"qnA- z6u-\FƼ1ť!kIq8iK認QF.̃}Fܸd23ɮ6jڊI(稧Y).sA,9gs/O9hDDDDDDDDDDDE篮[k$ib|?t4Д;u5}-TLZpx:Wn\m4KpF39< ½O /3"k{Kߌ 興[8Қrв'Yyw!J1lt$Aƚ^e59ZWewybZpd\FەPY%PCO-kT_(f\8nZFjzۆTTU2&2760;./$k["""""""mh[EmzKeS餚л',$e-#{ݑ̯[k-si 7+Gvڥ^(T[GdKNbc;8ݚk誯rK ?"ì.oȚ#u8Fec\3p .Bv~:N:z?JZ -t"7%is\ӽDCRk'Vz45(27O[K,Wj%@9a'*H8wx9]~/5/U_tؗ~"E`""""""""""""""""""""""""""""/=} =SAY)KUᙛo1 # C۪k.6;.o[%= ?H12ȏ4pRK./PjS\'%Y,, k^Zd-%ǠpsQaНZ{<9+j\M廢FF"q`h %ytҷݯOU mΨt5xnN\Nz"",eiO-**KQ5߶Yz}BAO+[ $5wђp1p""*-N;ԷD;8UC?cEs;=>cӫM~y_VDDDDDDEKF"YŬ +_4R'3;o1 ddмsm+d:hiqiϣpђ`a _M!Q=E:Y`dzp H c8 ٫6.z6AG}*Ĝo=Ѹ4d$nԴnŦv=t)bŬ *an:U9X|ʣٯ=~%=j;eG ?cO* k7xnNOFTOJ >\t[2h6}|sp탢[5p7\ݶFdG )5DE㣻[nTW JS35#-#?*5ޮIjh/uT -C㞎+k:IkJM3.0])ovlqӞQoC$`dFI.6mjt`!8p;9o@;DDDDDDDDDDDDDDEG>ܶmI*,.qghtt{5j e{KOҰ go]%Il}F Y)iqx`6i]f5V喷\MC*}ld"vnCxL6k[ti"RKYr==nݖG5n2`˼ݮi ,ݏrEnUnrX] inGbn/sߢ-fH%s8oC8bAwmҷJJmEth! qt"0ZKAsrN7F Qy;t>;"pIἡ8>27m'tv-=%ƎnTK^;vGnvN\z@>&4cPNk]d6xx!; "[lם+wӺ6[E5X c't;sePϩ?oBwC>X c't;sePϩ?oBwC>X c't;sePn6ګN>Pw/qn7fp*DDDYpZM~y_VDDDDDDDDE~/5/U_tؗ~"E`"(>RӲz)%mXzKtUK]doy!t/!v3LJ lj}<}DwҸp=+ثk{ڬT){w"vZp]|1ڦv^lcUi4؁6g x-c7C JCMqZ+vE4qHCIM<ʖGu9qI<0{ ՚nٲ5~RUG=lqB2r2?ч\~>컨ݯ'(9>O3{?qv;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>}nhk;fX1q_XO>JKPl0 ;gVp^LTW$:MYLu#xa8ki MW+T4J*$ <呕lwwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kч^zuMgtvB'B$\q>G9/w{ڏ!{Vh @Z+2A-K]@p9g."",eiO-NjuN>SKYY4dX7điʮ<[4I#WI;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_]Kn ;\ N;ezSC/)$9k8t4aܶ = ]ZZ`'㞌zsq)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+s~u)!'2HikJA ¿?j:]룗.Ʀ-)'ӼK8Be%Jʽ'gR\+VE$AmLcn{N 0@p-6R~_UջVE?z'A!X֖v,w{uEF$*L7\p8 zakvwvupu*YĮaE-6ĎuC٠5 44K<&FAۭZ=_y r J)/vr't`$.e4[)-:Z'țYDowNpb{.VS*5P.wʹgyD kbg(]ӌct)V/_zTF+*Z- $}7Fk0cu$ݖ{2G%:Zتm[N̗D xNO oN[m eO-l; 7 Dۮ÷7YghDDDY5ZArV}To^Is7= <^i~Ǥ$Q] טQp4Bk誯rK ?">j.%jz c PH\9HAi\>ݴ+K)H)g&1̉-!F ] ^\ɬuNc5shðWBݟArGD*;qhݍhkAáGߋKUW9G%X=*~\ hO m@ :9PV͵iҫ$e8fF c!o9W% :: H))c0F#crI8h2I?}xwңj?ן @""",eiO-/MIYt%AUR[JAqUAC-㬠ѰUɝɠUH`pG/:{_tOkB=_^ӝ= ~szNt/C!}i5gt,l'z@ǀA\q-^zGY$e$vggRGwHiw c;=KsYbies;i`wŧ ٶ4jҵn|o0gta{$bnwXFOJ"*AlJjʪBȟEg܅+|Ųo4Kpwz5AѵT0]狱 vZ ;gTQj-cYj}E)E 7H){qhswH-qF\1}4aksptΔi 1YevVAY{rc68;{*FG"au4f8 1җ aOMuQ,Lsc Ii!{ 4i6K-W|GWȸWJ68\Ç1$QwRUNQxyG$V""""""""]Ol[:>iN%9qp_;Kϳi->FM}cdat.2qk 9M4.4KOf X#N]N 8"AiJW""""""-eqӗ%`uۗMk4Ď+UEa+5Vftzn1>1p <2HY]7B\j ZÈd$G[X5-=yW3zzQA F""""""""",^_-?""*m(oOb^(l^Q7.Midu ةAtTvs,;'7ݿTf,wUPKvsMҍc߂ yoV?\=*~YNGܿj;9>O8gwc*/:ZERjZH[kLX7o8qzDDDDDDE_WSa}t}\;ݍܠws{/Fjwo{/Fj_};u<`KSvwq۹3gsN7Ov)#A]_ލe_ s]E=j=IuQO">Uopܜ +Wjeqleٝ9nr@Yvmz[M F*Y7X7a<79R'37cFA= zb۩kuW稊C;ZNH54p#EuM$^UU}{kb/)0Kˉoo-DDDDDDDDEk2'DDE_ lK ?"AtsRέlcY8X h;㧀<=-.5E]T\XXyZփ#CqGx+Ji}yD<=k%y ws= MFUS˶{|xy<9~UvO89θjv[|RIg}wd/p`[^\m=1i+U-͕ibGSfC״rqi'{;-Lli)yIq kZ܌ 9E{H{.52Ln iNRի[%:9W]=%+`ےFy79 ;oH8iCyP)#`6pk#8?^DDQwRUNQxyG$]n{?PX#.UQX 9 pU@46zFt]/TU<9)$tZI-' ]?^j_?/6/(D?65]vK3)pN#.n pђZOlqv?j/4.bIgtI|nEsL 7[CFtxaqծYb펈:2'oow d?/N>/N>/N>>9v#VڞW\n7sj_-[5Q&Y*R2X"ht :r2=ez^;+ b)\ ~7j+%ƻh.MOCm˗}! grrF8LCIq瓷;._}vFwE:&v7[}pvDL,M}`xCp/ cC|Ze,BO$99K4rTjX OKLK c1H$8GMC.܏-5sT[ۻ۹q|I~Rw|'|I~Rw|'|I~Rw|'|I~RhwclverSwv7?c9O®DDDY5Z]ԿEU}Ӕb^(l^Ql:mi*L6|1<2@xѴVjٷI'[$n k f]g׉n"MGDTl<7|Fb]ƻx=ŶKJ;CI0o7sσwhxfHYqF: {I|n`81ܱ[;I[H]c'q ' yCtl*E\ 2:s`5$WmjZ(o7 HNlnv]2K8%[rCt %S 7u |a88(y~(ļPؼ)f}{]yu-' 20FFA##9Q:mkoWgSeZFQ2q|-8pu*CbH՚.ŭmͣRrf8H\Z-$ vF('t^a g,ZYlβWWP',:JrdepVDDDDDDDDDDD_9熖Zc_$85h$8e]^Hn?#ӻ ߃<xj⨧9A#W2'DDEOGZNepXF:f9tֺ +Ms$2 hq=1WjiKu$݃=uUu[(hs[N8֒qz msLd6WD[KdpZᘟ;XUp""""""*k0cu`kWO}-4Jj:HK'vw#8p?OjuuX*(9kcwcw OKw?ן @""""o+JpO U9#ps^2#q(y~(ļPؼ+Sl-CjZ.ɶnrnni.op㻖Iv)tm2zw {.a"7{^ JT: -c)o.-n 927!çv~wz7Sw5x/iۺ[i%_3'a} t}\;ݑܠws{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/Fjwo{/FjwoEҲYe m!p^Z>ҡ{.PYo%ךH.ϩXL H@p<9wfJݢ+=XZjd s`<ٲnIkIjX+OE-D;`.n0Ii Rt tn7\F7`.vKG9Z*CbHDDE_Z2K[y:IOQ{Зx25oxbtuidFV0HHf䑐 sM_cOUW%$gQsӒF3}Sf한k';q.apnO誯rK ?"]ԿEU}Ӕb^(l^QyᥧX&$ kI$9UxLփw6ZX. 8qru4^i,jj/}s`sXIynH\ُҧi?ן @""",eiO-:m]} Tbx_tFà4Fỏ|A'p[)tlVHwbM H_xܴyG%}WK&7ធ FZd6㳋'+ڝ1]AcJ xgvAdeE6Ҵ]%eCUǷu96}uOht6_Qt'~stq.Dj?7mG{CpZH~n!x=YWq4n^s袆[I@ܒlwυu5gcOynIu3>oR\,tصlz\8H؇ 2ёq4TzG`ͨ竎SkM@$v? .vC2)׫(⪦$hnڲWbLbl/1{/F1{;GB[luYIUK I,;ҽ[nֺzSU Ue?zA ܡj*#Fqk g ?DSOQh,9)s^0ALG /n;8r9NĠwdOOWC;G|}whoQNm!M}D>;ɷϨڪÜ{?>v5wk?[ܗF?m!M}D>;ɷϨڧ|v6T&>j[Oozڈtq!8gt귕%hDDDDDDEԶٯ:Vktmjx!!ah'dEE峛 t)ghߋ`toܖ=iڲ-XWZjbpP[#2 {~x`H5ߋKUW9G%Xs -< 0I$pkX2I'qʬ:;E_-9lm>N#ak4x^#=.bJ[ ks8ѐ234E]mDRGQ+߽'$* ZZ' P=-E%MafM+9AF!ks$7CvAy FCl7򌑳%̬ѝ؆IoaU:z<ԭ49Z ZI3,QwRUNQxyG$V""""""""""""""誯r4ح[VCc@j%7"@}oɧ$7'h1\U`Ӗ-kmC% y~IqsIsIq$t=*~\_]OlTI~;h%AX|ʣ٩C|13~)Y x8!yZfm=mluULŹ# 83 A<5TTSJ{H +興?ן @""",eiO-i$\--'HFx x%=M-Uvl.ϊHcvR ;;\8煱&ꥏ}TGRt>w c:U;ThX·PD٠ۙLi$-40c$tՆ͡hj-vKm IKJȜ[JpK@8+S{fujz nnd潦ZpApk-4M]ȩK Fg9ap v<^{ i[Zi{) pkZ8጑,GRt>w c:U;ThX·N4U,gCCV~^vv;9]hX·N4U,gCp??SMK&ꥏ}UJm mmFS09/tt&vSHh8ggt귕%hDDDYCBhڝi]`|e*cw{ӏK_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W/fS:ˎ)%?%-`+tzB`սlieQ$s]౥.<>5k}_mf}FdU+n 0p‚9*+*"^|EGH GL:|*u!eC%`c]7.\A-w GߋKUW9G%Xm^tN=mBCCN8oKvw.aq  F]論Z:E=$pYkMEKf{aI!O4/v#YtTOD PBd{^;Ėp4v4m5[ 2QNZX x8rVWT[4mNNQ4/uŧq[{=ZnjȮ%k7f{G**zbOlw;mg[we+ZiD' $<:m+t-i۽W?cC$[ޒ/hTcTSKWIkQiq.ۦ0$%wlDDDYpZgs/O9hDDU|P|ļPؼ+iPj*u eC<78GH!%|";-ὑ}Vi(J&UlNmӸDhāw_OtwұԪP{gQfF9́~bH!i UA=9nJ}+,ͷ*xb)78'#:8Pj];4~w8=+`cI'x<7IIx(k)* 枎P18n|pF޺?DDYjEy޴,V?Z|@""""(y~(ļPؼ+Uwl!2Q]m5ZCѺL,!mmIW,ZLз2:G^$: m[o4)+k%,͕qB"""誯rK ?"m.]yw[k dmna|f: Čd 8*HݛGlW沱cdtuxbvwNOsވ=(ugQJd4_l E]SN絳# ;!Į^xL*7rb*憈^!-prH![O U9#ps^2#q誯rK ?"k誯r=KfV_y:[}<33';lm t47On[A6ziC;|tt}l6f6j0C[J7_n{+ueKc]nQ-"H)InK\Iox&DDEk2'DDEz)[(,Q\DG1ן;͍rNPI%DpZc=ccI 9n:U9X|ʣ٧=<T{4ga*f>eQמlžUnD̷L.w#˰8 (uv{.;&s;Xthu%uKu]Yj&eE #7tSpќ-]ea]uF̅  k 4a 9OsE VG4G#CZ Q ~ZoE[ږjzO0Z ;Nj&7cA|%Tf,%tI6cuֿRkZy)"Dhqݍ bG#!w5kpOSgh)D4Kpc<¤T)]U]>* s9!y <W5MH:gbRɦ-$2RH`' E~כLVw4M +0eafN Ӟi\=/FTz;E>|FTNX<7-#Mݪ*tE4\[ry1۸78d}WS5Ϋ$ingN\p8zk0G_vLo=iFZc6K'+ښ[bZwbOOWCݞu̪=s۳ΰGN{vy2in:U9X|ʣ٪m;_l?'\r~w{= ga*f>eQӞݞu̪=s۳ΰGN{vy2jNɥ-lNȟ{㆐x{vy2in:UTtwX^C${ܞhw]->?Z|@""""(y~(ļPؼ+Ujlֹ4pյFZ) r@ə<\I$qhKMEk3L4]#`34*FH9.'nM=I[&ꬽ*XF1 NLưxD>8 PwGhַ\URo8O@*ͺiåj:[eL&\&o!| n!> p {NR&M Hc-8F%8p2 Rdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=;ӽvb~I)Эdy=̖:9W'2[<{DKg^ڏh tl^n69iP;..h Kg^ڏhl{Q-u{j=gs/O9hDDDE~/5/U_tؗ~"E`"""*_m݇ݖλcvlO)wxaZ]{;M󻻞ww8g/r=ܟox^{EkC]^ >\ovv$ap 磏Ĺ'^({?I?㷿Oק^zhק^zhק^zhק^zhק^zhק^zhק^zhק^zhק^zhק^zh׮ݺOOviY%9|wg'rkQ}RAEwuvDXpttW"̛nE^~H17Q͈xsә;VЖ4֙V˪ɜU99y+c't;sePϩ?oBwC>X c't;sePϩ?oBwC>X c't;sePϩ?oBwC>X c.=ujzYiJChi)mL_IQ '?ghDE!tW-@""""",eiO-殱iT[lE4HH5#yI ]T^{(/I(mUռE,gw\rNxn3VMAWLi\3  %f-I0),1ɝFp2C[2CbHDDDDE;EgGj{Yco{n= C 8]nagt  PW:{_tOkB=_^ӝ= ~szNt/CΞz]9PWi;S:;z%nU3!.$ uB`]lj{[Q.ds1.>%OkB=_^ג feFS$Un?2Pl‚8+R^AOI$ >Dzl9MOrܤ[~pAATghDDE̿>IWmC}FCbHDDDDDDDDDDDDDYpZg]?zw9h6[oT18tGGA*6ZjۜYDM+ =8':-GߋKUW9G%Xs U<G4Hhs^0Ap¬-;ZWXtnmFFcys\dx^% ^욨wWq;HN uv2I8v&?^j_?/6/(Da{Y禴;W\N?'|p9=t:ZZW663c& }PgÑp`׻>?{1T:jAZE,h:Q8`80ђWlPtNh7WcwIiZV*d0څp*gftKݶwj:DܰdqFK=bYoVv h(LQ8.Ax{ڍy6P'Zw#o@ h$Ӄ> odJ~N9wg>w8⭄DDDDDDDDDDDDDDEk2'DDE_ lK ?"ghDE!tW-@""""",eiO-*CbHEO9j#B˭LW|2Y{.7o)Fk[禱 ]%Olh,sl6i\ޝ斝с 4e$=WkaR>9*ʾ8]Ѻai;,=8%MyᥧX&$ kI$9Q>u47n;W5dy{9>.<GߋKUW9G%X **,zozzjb &18b%G;`ُҧiEصwNW0LI 0K\?夁pVʭoWɨc_]UǕin^K!,>[_WYuzt,n-w8$qUI*zGQ_(+nUR2yc,;s@Ytӕv:'s}8׵:Z>OMlHۣ_J!k&^A a{as}KԟMkfں%}|S #Ki=#),tO%-.p/;sHt .ŽhDDDDE̿>I]ԿEU}Ӕb^(l^Q= IGkVWun/8ntdH/!4M-+=e4 t>0ǧ  {Ki: $).c*_p-.n-1!gvhKk揤)x/~띧nG%{arc8q'ni sؼ;ޑ7.|I~Rw|'|I~Rw|'|I~Rw|'|I~Rw|'|I~Rw|'|I~Rw|'|I~Rw|'|I~Rw|.n;-{6W@ז:JZ[ (W=m%]`k9>/>ѳдz"- u3WS0yxx4d5C6kZB=ڡ- qt/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/N>/_ tEE=7ؕRDCQNI*Nkʦ.*9҇7|``]tsHk*)|`A-1x8c#"""_֟$r=˄UO@iWü$x| gr-E]Fb=;}pe-s-!?f"""""""""""""/mӶoluPV`FpH*.C?WmSo/tt&` p ؈?OB![րDDDDDYZ/RݵuPY Fkѓ DMtcxX$bcjZwP˩inQDIP׺2d7 .A;3W~m/ӺZKe082trD]ԿEU}Ӕb^(l^Q{FtOU%e#˩Zo4| dVKn:nU] u\\K@wޗcwfӖ -))XZQq$'.$uGߋKUW9G%X=*~\=iK5{:fK|Nkn^Akz7]/N{G_;y3 KL,ho8x9{]uzxmdqֱZp¹x!(VIkF Ys |7ryNK;۽not{wZx"`dqֱ`DDE̿>Ig]?z?Z|@"""X-&j ) M|1;QZ3p0@.:nAhi1x܄zG˞9Z K趇=U_6%LU9 o&"wock誯rK ?".l6j/vUTȜ[28#?UOE<H״Ar)R7M6G%sYٌC{9sg& 2~voQA҆-еxIQ!sZ[>ٯԏ2-MӚM"N8 ,x'١ju_ò"q3S5sCG%#Kx~/5/U_tؗ~"E`""""""""*k0cuf_KZrWGIH\\ւ\zN<=~{ַ1{I9*A.at8֜yY;gCV]o +g tA/a 9&Pxwңj?ן @""",eiO-?OB![րDDDDEU\i-5ICjJzP(Z^ 4.h;௠</N>/N>/N>/N>wvΤ wɌ9B蝺w(lvgbO{zG?gO_4}%I5G_JuL4zo*솣!1a88=8]=KO5w;WOT#I`\]ǣSg:@Je#Da,iAvg+GߋKUW9G%XƦUhymT\)j$#_F1K֜=M;[UlmT--0@pYK Zx"`dqֱ`EOӾ{PDD^;5P<60 XHiqGjjdxo q B"Mkm 'Tv=3cKX7/ˁ2z *hp\ފzk;m0=ܜL{x| y:PiszgXj:g7ZUCTƃZ qC)<6cSDDDDDDDDEk2'DDDDDDDDDDDDDDDDDDDDE!tW-@"""""CԖz$g  Pє:R+䐋+>W9LyH 4DDDE~/5/U_tؗ~"E`"ݭlֺH+i䧑ѐ2U7jmg~GJK#{/crA/ Ҥ1W5e\uZƴÇ9# CFhn+1GߋKUW9G%J5N:r_Ro`K¢l5yQjWiPJjko,45h'9ςp,DDDDDDDDDDDDDE~/5/U_tLh͔Egd6 ]J;$~&cZps~'ӻZ/靥PvLE\ [!ţ.I3tr ᪧXV$nkFAp 9_EO~?{N_:?õL/==c׿r'J \NH ҺϨvg:zi/YMns̀.n!wJ^tuFI']`W[>āHr4` ghDDE̿>Ig]?z?Z|@""""(y~(ļPؼ+VmHz7,r0ALd\?7r5j&GJ#Dig@wLOUǪ/JmcvI$qhL@b i8F """誯rK ?"miG@`2,i/ Gk=.Szem#OdzgY#`wZ=9wZt"""""""""""""誯rK ?"_TmPWH^ZZZZzFA ~{.ɖr#8vf?ן @""",eiO-?OB![րDDDDDYZGߋKUW9G%Xܞl{vw+OaGrw=9^iNVFanapсւރ>$mjwS09{W;kL銙)j/u1üc#nKX7@dVix"UMiwee{yIZsŠ破o7 9v/N{P8%{[Q-%j?CW/RJtOoz)tq!8lmzoHKm%U/+"J =hoQ\nvefuEIU:J[u4N-8%&>j?CS;G|}whoQNm!M}D>;ɷϨڧ|v6T&>j?CS;G|}whoQNm!M}D>;ɷϨڧ|v6T&>j?CS;G|}whoQNm!M}D>;ɷϨڧ|v6T&>j?CW #hQ9zv3!sp⚳kowRQ ,IFK02H]xyG$V*Zl^+iw9x[z\ޝd8Tj}_[D,nDй3x9'Y$ZBX|ʣ٨|v6T&>j?CS;G|}whoQNm!M}D>;ɷϨڧ|v6T&>j?CS;G|}whoQNm!M}D>;ɷϨڧ|v6T&>j?CS;G|}whoQNm!?CJWSگ2NLl8;py gU9H;m'ӽ9z^|nuqdM;dp]DDYZڟ^C?""(:nZ7[9gG{3/V|0o9'$hh1#= u¾ԑJ`1A/8'}5ߋKUW9G%Xږ;mUl&<7rWe;cH'jjK]ע'ܣ݆60zCk)fuǤ-׋=p3>/s] zCG;hX·N4U,gCzVB}5fx/H"k xpAej?jߚz({w c:U;ThX·N4U,gCp??SMK&ꥏ}TGRt>w c:U;ThX·N4U,gCp??SMK&ꥏ}TGRt>w c:U;ThX·N4U,gCp??SMK4^кMY+eK:8D!9_=xyG$V<4TK0D$c@$*Jnٕɢ"(9kن78pkI*ٴ:GWrp\$R;  Qg{8Wp??SMK&ꥏ}TGRt>w c:U;ThX·N4U,gCp??SMK&ꥏ}TGRt>w c:U;ThX·N4U,gCp??SMK&ꥏ}TGRt>w c:U;ThX·^zhuMs~^'S#o1ۼ3~$3[ o~A|%w8x$#<5GtVnRDؙv:\ 'I%tgs/O9hDDDDDDDDDDDDDDDDDDDDYjEy޴"""""_֟$rzPoPZXeg|!zy};x$sIX\1Su).K46FwH=qI4ž(-QZ㍡c@`8aI5ߋKUW9G%XaVj7{_[buMI F#2.~ݙ8| !q;Aj'}=^ m%-TqDԺ[ʹiˢp`㡩5Nv+=}uWZ\Dnys'-SVK*؎*J~ɦh'k2<ks pz(y~(ļPؼ+GߋKUW9G%t5,ZtܵH~^88!qUZCXnYqkDcrvZHsZּpYv=ne *VBoqs\rN8W~?{NDDDDDDDDDDDYpZgs/O9hDDDDDDDDDDDDDDDDDDDDYjEy޴""""*kD~tQC:K pwZ1=xDl{hSe˓eD׀=|3#u׿=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2j'{7G\UUՖoW4554t8zI^15+[5onwߴBյ-;7מG䭨ev8^}Y sѷ ;)UUov$y%$t>vt-6HgL-aS{vy2in:Uy)3Q.8ixWKYcrp2z2JǪv$}kuY6Mi kэ <3ї|zѯ+Ӊ&h ܒrH,%ȵFdG )eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٧=<T{4ga*f>eQӞݞu̪=s۳ΰGN{vy2in:U9X|ʣ٪Xj6ۮv],rBO.$a.ߴ ,tSAΊR$0a3y%P)K4 [~V;x7w;1 Kg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhd٣ov.NQ4/N p@\}F=Znk7dWOrTݙl{Q-u{j=3BT[av%T=vLrO tɇ`E􎯺l'tVUz e?+Qxh.-q$$ӞϬznBt[u2S7dyA"""誯rK ?"O<4TK0D$c@$*/`^F,s ":ww8T|yi"h%ad潤`mjwS09{mTRV*g~4B׺d|K؈k=j:; J(k(fc)wx nʹAn,ӛHGinֆ|ciq8(ktqPUWK&w&A#AÇEQwRUNQxyG$R wRUNM M}KMQz~nChvW%Sn7mΞ;/e}ypټ/^- F>gRвi+\AtvwsC  76foLX륒Op hcۻ<$e3DDYpZWl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyGNdy=̖:9W'2[<{DKg^ڏhl{Q-u{j=s%ίyG^ hKeƚRɡew^ N p@SDDDDE̿>I]ԿEU}Ӕb^(l^Q[J+,v^%k(Ȫdc(hsI,Z=nXgSNȃbu$Φ `$AᎥOY][%º][ɉj+Cc5kAsWaWR-GmXykSMDD쵻x/h? 0bgkV 95<:f` tD2#o\C[1.'L44Kۮ7媂hdSOWNd /$4KstG>wwcFYpҵZP[4ldq_;$ Y-Q U%T|3ۙ#-'# Yuk\f>?G@#(ݒgj溗{%m斿pA˜wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?aֻ0ޏ]}dG>}+k(*૥ɠH`SE[뭐4gi YoѲYwä|6C9;@.{A:OO^tn;GAtC C$n̸xC.'j7lmPZ*ា8!i9SZh'wz?v?aֻ0ޏ]}dG>wwcFY;kчNZh'wz?v?ah>SY4оI7A;n`oK{'7?^w=Cc?~&̐Ks`AA ?"".}gr]r.oGG=Ka5+ݵ_-[jbcps|&'[u-P{]];X^j+rHi' g~/5/U_tؗ~"E`"""*k@.:[TX(uOKJ cy 5tx[|K&TCMmy$4!àĜ$}vz/n]is%$cZZKCvWcG|}w_\K-+fҷ{=訦Mis\`# i]-۬uU\ 0+0 d4|*OR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}w_NIR}|>w vϡ'd`k`=x=< '9ԶM?cjo'<\IN.VjCNOyF:qpϏG|}w_NIR}|>;tWϯ'{J$q)_>d:?+쓽G|}oҮ[s'Z 23DO/yt{)cǖ8hkg) <.8?ZCt]d$28tx;v23g"""""""""""""""""""""""""""""",eiO-6M#]Il(5'Kw.rw {-]ΖcalAh|Heq1{٧4P٫tfdikC5ܡx78~/5/U_tؗ~"E`"""(ޞTڂ@&ҚٻQ 5ѽ#ykpo+I+/3-C)'rC$1pF&sKBVk*kmmmROv{ƺ6H)^T:X$e8^n\K5 Rngt誯rK ?"S{PϢ\ [b;ZwCG~N67ҷ9.CGւIwB}_ZEJ/wi6g)/88x\0Ⴇ*CbHDDDDEko\: WG$ļCO8 i$8e˶k̴Ho1r2^0O+O""&7sjx-uPR HjPْI{K2N><{3Z][5qeE=ip> AdӺʆM]҅ܥj!HNF N1𮆻y~(ļPؼ+nLwXKB캟jGp2`|5p:gCj;MKTvAnf]+wH!GyKնqQ6~(y &y]+9 ivH>mQ[[Qzje)IK(~A{7ȣzq;>wMTܤe-EMgwSj5^YM0|.8?$#oɧ4c+[UǕhn % %ZOEشUvZNK330 a2TGߋKUW9G%X?ן @""""""""""""""""""""""""""""""*o&窱5 سj]+[먹3-=c c,{\9i-x"""誯rK ?"Wu'|\;$x|?U~tzA$Rq.?w^h==et>#(H h馋~:G+KwF Ê6=-5tA*#Xo0 ~FIpsxXuϱ FVǺrn9``c?^j_?/6/(DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDYpZxZsI'Ē*6]hind1YZMD|H8-g~QZ٧槷S;It64.= n*m;MSW5O](j#Ozp:7 H smYr֖G+C1H KK__(-?<0w*CbH_9熖Zc_$85h$8Vqmj|믖ZT}'pXI]i2RGsӷt偅qpᏇ8S]hkvaAAOStP}|{r>"p#"NHoJO;qC .t\A½]ԿEU}Ӕb^(l^QZnU:RŨqcj&N%v'ĒwO:ǯͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Qy./vjk +m az_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mD &ݨtRW<-gM,/3o8zGHZ=|yi"h%ad潤`AZ|@""""(y~(ļPؼ+Tw-[%b9{Aiah SHi+[[eejsU6V4-ė B[n;-w JIK3ehv-$g*CbHr?#<);q hqk}kKnQ.c4W0nq'r|W÷-2ʒK=MEstFS -~ DDDDDDDDDDDDDDDDDDDDEk|j}!k^ ?pVDDDDDDYpZ2'DDDDQwRUNQxyG$V"n٥riE jSSL *37 x2HЗ~,fi*Ffi|U󈌑8,s\N &zMQ}Y{UdT29$Lb,sG`|p0rѥn^ p..q kA.='T tK_QdtʙDLMBC9 A8vCr|YO U9#ps^2#q"誯rK ?"?N.4;G֗j}`$<' kq 軵5> .]O5 >0DDDDDDDDDDDDDDDDDDDDEk?DDDDDDYpZ2'DDDDQwRUNQxyG$V"""-ֻ;#ef3X3wz n 885WhKv=ww<1;q'^({?I?㷿Oק^}I{3GsOștw\83$8SwRUNQxyG$V"6Ǣ,U>k{C'lL$9K4J,ѪmmYk/,h--pk-=Q'XLZzkOgTHUɫ69t}x2)Ѧ:\Ar ]-JKYGXf,/c|7ʝ3Zk l8YesHCPֹnn((ij 8:ZX ,'u4d8tB誯rK ?"?DDDDDDYpZgKֆu}ʦ:ZF=|pkK '8Vxj⨧9A#W'\բ6WPU#C.`68=&0G*w+Rkj`s ;;HUΞz]9PW:{_tOkB=_^ӝ= ~szNt/CΞz]x/IڝvtWcI,Uvnavv''\d6d<#Sډw# 8qp.:{_tOkB=_mmfK5s*4|0:A%\vʨwN^_91;؅͔R:K,+ٽH]nq<2NxfM{n=mVZ'wO 8wrHWB"""誯rK ?"$C#37s@{{-\2>GDDDDDEAa|HL-~1 +GzKj>]k Dd?JCJn<ż3|J̲mKF;M+Yp*`}C[[4<yMmp9K vM{{Uj gs}'I4iJ3KcAE`%`7rcx$8ags/O9hDDDE~/5/U_tؗ~"E`"*}Yt÷e.6u+#|&{l%;m!s"TVIP[qex{&.l1h&̄ P_*XLcZGCVG3\7D.#y$)<4TK0D$c@$*/ӴDI/N>б{wmΫwɌ9BVhè<ݩaܭɹ.Xb'zaaBu~-:ӛ{}u7aSS"Qpt_kf kf iڞhh6cy8˻ \ a􎎐DDDE[ꝣKPlvsr&c\q8GI\~w_?7Nw_?7Q PNm݇LyLF%ލ ; '; .Ɩ>j:Ke~.Yg2nE99td"""""mi-ʇ8n"9pC470g6=|O(uE?ԏ./ iaA2 NGb7Ece b:XsŮ%;K;fiv[kd-g(8\x`qຈ*CbHDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDU7d̷1#0.t|ͨK|\KOI pFQsr5ō `im-n"Ip88 r?Z|@"""X-&j ) M|1;QZ3p0@eNFتv} jO3ډw. 2C8/M_vc'CGIP/5tΥ"97y>rw푮^j_?/6/(DD\٪OthgsUS"qnH O U9#ps^2#q"efWTیϖRPd2>WiF8G763i** orxdtI]ԿEU}Ӕb^(l^Q;8ԗGWsK6MȰƴq ҸkYonkYon5(6i|_$#{3rxW];2h5,?7Nh5,?7^N5UC[Qd%4]ٚXs1 cj"""(ju :~ TOR q4xt8c9P~۝lz{w}w/NqO}k*g~/!<8cA'<ـh> aA N"'l)SٜÓrqmeMQ7Ii ]1¾};Of fxv.c}Ƌj~ UT[AR>K8t9RDDD\}UaKl=fDc>xZq7ZHU)e׭&ViZMCk.Ig vw</oMy58}oII'<| 2""""""""""""""""""""""""kK%=}``Lt-y/`x 6}k. d4xMxyhoQNm!M}D>;ɷϨڧ|v6T&>j?CS;G|}whoQ\K+yҷ{]=hChsZ Ą'+#-:+T2ý+0L8| OM}D>;ɷϨگWEkp}w c:U;ThX·N4U,gCp??SMK&ꥏ}U֚/J]CQOMs"q܂4Y_UuRrOEv' )p??SMK_]nrOjzY${;wrUojmg~GJK#{/crA/ Ҥ1W5e\uZƴÇ9# CFhn+1GߋKUW9G%N+9:ZX4'uq8(^϶ЮCG%=>9YS|@ O<_65<.O}__ e'!oq9SP?\?I'JDDDDDEzNhr8,ގ?y8;`-#xHUhN߃F[;Ed~{iV7!8acRM1-9f}5 GO^\Ky2H$q/.20DDDDDDDDDDDDDDDDDDDDDDE̿>I]ԿEU}Ӕb^(l^Qvjzhe~ýU⊖JhR s&2.k`o9t5j꣎%WwB"4 3 sx &ic%U붱K;$84&Q 1IɆv׏I#JGߋKUW9G%X 2:m*VC$c-lQO¯DDDDDEA<{adBȚ.~!qUu-ǵ)-܌xqnr8]QQY#=Ir&NH84 eh{&ڏmCQ4ܝ?*3s;I]ԿEU}Ӕb^(l^QǹWgrd|)g{CZ6 i)h]%Tp_T5~7n<)%}}ʦ%-%4OQWn쎑cXװK0orW ij.~X#t2gJ cy\s (y~(ļPؼ+Sju Z>QWWS0m5 ^$;ta;Jkek#eP2Go𑲜]4dǂj]eַ+c9@ 3g${,W>eۑ{:*K{{s}۹3."""}O\܏-4[ۻ.3gDWtwjI/׆>[Ku Hz(h;,y{.,$'sQ(mki\nܪ$ckZGx c-z6a8&Kmԇ a1ghDE[jMyszǦӍv6_rlbaҼ-c4\ںcK+aphH -w8 @u_]OlTI~;h%F!j˥= AZX${Zָ V˧)tk]+U7.8Ɛ \ج6qPWAjjfcv7##1WCBx_ERTghDE[a٫uVO# 85-$dLmAQãu螂m DXX{S[t#gAWPyHYW< 04ܰnGIG%}$tc~1 8 U6r=ܣA+ 8>,sO-Zn:*a<Z3+E-Ցj?uuRetk9GXMIetI\=Cpwpx8K*CbHDDDDDDDDDDDDDDDDUz=PuFACrR:t\ {p\VPR몫,T2ΐevKNxӇ6ym^tN=mBCCN8ilm+h:7OEE <042> ?ן @"""""",^_-=7Ylz4:}8 gE\敥礆xYPU=ihcہԂ}j%ViI%NsNI$$+6}G+.QQUA4 zwqh,",^_-?Z|@"""""""PQ䣯LoZ?^ F} H\yZi*&t4NF03phmԴ[dӕuͽeDU. 7k08#}/zOi1=&^{%XqtghgCo䥯#_oAAHCԗ9n:\y~ q<?vn3;<);3 гy~""(Fl'GOYQ4wgr1q?À'[Dn;&fm}[*"vpY_с9:xړjzNR_(#ѱo2v׹ :Z~8wW?v7jo㽿qhDDDDDEkgs/O9hDDDDDDDDD^;ym=I]^lT/-u{j=Y46Ӝ6y9 yHz8t)""""""""""""""""""V+=k?M)ؔ8k8!Yz׺: j̖vG#nOIx*yo;V,^_-XMl6[O8g{c ?D\}kt{,68>988c$DMy-7Fjy!inGق@h9'9#ps^2#q""""""X{8;S=v/#wo{q8.y~""""""""""""""""""""""",lv윯ju= -S+"qqk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LU_In]cٱ'Rڤa 9x*]og[Vmuzv>ZEh k}_mͯ~sYbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~]_ϨW@y t9`af\8cKN%JOKTN , KG |YbNk6LUf銿Q9_}1W'5_*Dk}_mͯ~sYbNk6LUf銿Q9_}1W.mT_5)I3K3 ogoI DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\Ն.-VV:Pt ]DDDDDDE;ېH9W1v),qZghDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE5M9W>ǂr;$ =#oc(s;[h{g옹y.[{?Rv7YZW)'ԴPQ]ݿ@Ac0;""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""]7rhhz;*+iC úz8*|]_z+Mܴj+Jښ4po= H?&ꥏ}U DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD_eep24c-0.1.2/eep.ps.gz0000644000175000017500000000716710265023467014010 0ustar pznpzn00000000000000"5=eep.ps]o}~C1mC:}t퍳k؛@pwRL IIQ˟KoYvuuTQ{fsQtQWq7l8vjnUO^ހWKgsW{.33LF_]e/voW7u/|/jyrrRu]|'U{yUCԖ/_M~ƂfDpREcuF;持/z0|buu^?oL]{§ >;j*?|@' CF2͔̇>Z #G 9Mf" 0"[(-dDU56pjlFPJjJͧ(R$K#FJ\Z(HHO_]NEJ"+NJ@r?n%DFSKu:Z*] E"Sd#Pd'飧:=KuzVld"{w%ѓKv%;=Z+u2KȁYI%iɎH(S+ra*b:HwmW EEd-b';#ȣ%;md"5PmWIEFIv"vc0^.U}RJieaMCIG+Mom(si(iT.`w爎PKaДtMP%8ɂCkTG˲tQ\!\8* tS>PrZF:ZE,"h|(x\EP酇CESN_/ͱ؛C[0iM u勨T8ӹ n,MzX AfZZ b/PI`08{gˍ'S:KhWΣ(C1XYk} S,SŐ+T夦Pi1E]fpŹ*3'Din,bI*ʨ{쁘1}Шb_evRƟԡhAfL'DF1W,ՄŹB6U. D@ A8 ˭'NČ+y'|]EBatBdwYf綳kt&t(uH,ؚ3'vD!be'bbu%(c$Hf~ Q1yȸlEkt&v)fhrɲOH1_;1bR 'eH4l7 %?muK{tFǜ@Cr W3fd~<[Oë0c$'D R=c$K4̘NRe~8ȴ`BY Vd#gPzI ,oYѬO0UO^R E4'"͠`+g‘]M9MQA)dAAs" '=[h%c 1(Ăư=lAi5݃`D`kE`Ij)O5iJ"scQz`=ZXZ`]#Jt =E=O,R7gօ}O_^R^eyq;cq#X$dm%f \Kg9]h4gfNZKIM5܌L өrZzD e9Ҹò#H1->{ltI~Kq\x=QvD`@x fi!vذ@wn%*1<8@[\T"bB8uNZL}vDT}S`.vD˄2e3N~|By A͢,R:))ᾷ+>ŅUo:(,S dz0@F&1Ke\i,{4N*7`[`:bl%ópu]ht[ʏcq\ 15kM|qho_F/B:x_欮 ܄ĥz \m4*̝jӊ@߳l+ F܍L !hQ(Ȭo=U sRl,LwWi7n+ F܍LS%@o7pO0pZ#O,   #}z褬0ϓJ# l}L LBFP*3F{Qn<ǵr+p}+Ǖ[e+)VSJM ?hS 욝- 1JmBeLH򠟃 PtϺc\݇ߢJ`~d0Cg([8[捲K&Gd w0+(y0- ڹBш~Mukŋ:t-BԧԲs{?Ŧњ2Нf21S5My 7jp6n'2؏8'&,?\hwp JM=U9V;z#꽞\JcΛ+VŮ9uň]b#v];\QK@gކlGv:M]etuLóR(J6^B6gK?g%K2Li}\FD"#(Hd LHT'ڽD"ÔG%Sv+sR|vD Jo)X7!C,}yvD _{?@[h4-3]PDpZE/#n浻o`].hJ5ٗd+Q)/p 46Mwr(mhbQ81fS'*ŸQ3YF] E Qd0p.3vaM?fO.乔 zWJtj[4ܸ.(zkeMϦ"pr_ IIц69݂1s25 25I$AZ5vp9xéc$|IcS_䥲pNQ`Si NՋ#..lYfwsheep24c-0.1.2/eep24c.10000644000175000017500000000474310265023464013412 0ustar pznpzn00000000000000.\" Hey, EMACS: -*- nroff -*- .\" $Id: eep24c.1,v 1.3 2003/07/05 18:23:22 pzn Exp $ .TH EEP24C 1 "2002-11-14" .\" Please adjust this date whenever revising the manpage. .SH NAME eep24c \- read and write 24Cxxx eeprom devices .SH SYNOPSIS .B eep24c .RI "-d device [ -r[n] filename | -w[n] filename | -k[n] filename | -f[n] xx ]" .SH DESCRIPTION The command .B eep24c can be used to read and write 24Cxxx eeprom devices. .br .PP .SH OPTIONS The following options are available: .TP .B \-d device Specify the device type. To see a list of the supported devices, try .B \-d help .TP .B \-r filename Read from eeprom and save to a file. .TP .B \-w filename Read from a file and write to eeprom. The addresses not specified in the input file will be filled with 00. .TP .B \-k filename Read from a file and write to eeprom. The addresses not specified in the input file will be kept with its previous values. (this mode is twice slower. It reads whole memory to know previous values, then write whole memory) .TP .B \-f XX Fills the whole eeprom with XX (XX is an hexadecimal value) .TP .B n Can be used to multiply clock time. If you have a long cable, you may use this option. Example: \-r5 will read eeprom 5 times slower (pulse width will be standard value multiplied by 5). Valid range for n is from 1 to 50. Default value is 1. .SH USAGE EXAMPLES .TP .B eep24c -d 24c04 -r file.hex read eeprom, write to file.hex .TP .B eep24c -d 24c04 -r3 file.hex read eeprom, write to file.hex, 3 times slower. .TP .B eep24c -d 24c04 -w file.hex read file.hex and write to eeprom. All the bytes not found in file.hex will be written as 00. .TP .B eep24c -d 24c04 -k file.hex read file.hex and write to eeprom. All the bytes not found in file.hex will remain unchanged. .TP .B eep24c -d 24c04 -f 7A fill eeprom with 7A (hexadecimal). .SH INPUT AND OUTPUT FORMAT Input and output file format is .B Intel Hexadecimal Object File Format .br You can find this specification at .br ftp://download.intel.com/support/processors/ .br i960/devtools/INTELHEX.PDF .br Record types 00 and 01 are implemented in this version. In input lines, LF and CR+LF are accepted as newline markers. Output files are generated with LF as a newline marker. .SH DEVICE SPECIFIC If you are using Microchip 24*515, you must tie its pin A2 to VCC (needs a hardware modification, see device datasheet). .SH SEE ALSO .BR ihex2txt (1), .BR txt2ihex (1). .br .SH AUTHOR This manual page was written by Pedro Zorzenon Neto . eep24c-0.1.2/eep24c.c0000644000175000017500000001510610265023516013465 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: eep24c.c,v 1.3 2003/07/05 18:23:22 pzn Exp $ */ #include #include #include #include #include "common.h" #include "intelhex.h" #include "eeprom.h" #include "conf.h" #define EEP_VERSION "0.1.2" #define EEP_READ 1 #define EEP_WRITE 2 #define EEP_READWRITE 3 #define EEP_FILL 4 int mem_to_ihex (char * filename, memory_t * mem); int ihex_to_mem (char * filename, memory_t * mem); int mem_to_ihex (char * filename, memory_t * mem) { inteldata ihex; int reclen=0x10; unsigned int size, i, j; size=mem->size; assert( (size%reclen) == 0 ); intelhex_fileopen ( &ihex, filename, 0); ihex.reclen=reclen; for (i=0; i 2 ) { microdelay_factor = atoi(argv[3]+2); if (microdelay_factor < 1) { microdelay_factor = 1; } if (microdelay_factor > 50) { microdelay_factor = 50; } fprintf(stderr,"Timing Info: multiply times by %d.\n", microdelay_factor); } eep=eeprom_init(parport_baseaddress(), par[0], par[1], par[2], par[3],par[4],microdelay_factor); mem=memory_init(par[3]); /* initialize buffer */ switch (mode) { case EEP_READ: eeprom_fullread (eep, mem); mem_to_ihex(argv[4], mem); break; case EEP_WRITE: memory_fill (mem, 0x00); ihex_to_mem(argv[4], mem); eeprom_fullwrite (eep, mem); break; case EEP_READWRITE: eeprom_fullread (eep, mem); ihex_to_mem(argv[4], mem); eeprom_fullwrite (eep, mem); break; case EEP_FILL: memory_fill (mem, 0xFF & strtol(argv[4],NULL,16)); eeprom_fullwrite (eep, mem); break; } memory_destroy(mem); eeprom_destroy(eep); return 0; } eep24c-0.1.2/eep24c.cfg0000644000175000017500000000042610265023465014004 0ustar pznpzn00000000000000# Configuration file for eep24c # $Id: eep24c.cfg,v 1.2 2003/06/30 17:20:24 pzn Exp $ # parport_address is the base address of the parallel port # most common values are: 378 (LPT1) # 278 (LPT2) # 3bc (LPT3) parport_address 378 eep24c-0.1.2/eep24c.prj0000644000175000017500000000011010265023466014027 0ustar pznpzn00000000000000eep24c.c eeprom.c intelhex.c memory.c parport.c mcdelay.c conf.c eep24c-0.1.2/eeprom.c0000644000175000017500000002220210265023470013664 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: eeprom.c,v 1.3 2003/07/05 18:23:22 pzn Exp $ */ #include "common.h" #include "memory.h" #include "eeprom.h" #include "mcdelay.h" #include #include #include #ifndef __dos__ # include #endif #define EEPROM_DELAY 25 #define EEPROM_POWERDELAY 250000 void exit_error (eeprom_t * eep, int status, char * s); void eeprom_startbit (eeprom_t * self); void eeprom_stopbit (eeprom_t * self); void eeprom_writebit (eeprom_t * self, int value); int eeprom_readbit (eeprom_t * self); int eeprom_controlbyte (eeprom_t * self, int page, int readmode); int eeprom_getbyte (eeprom_t * self); void eeprom_sendbyte (eeprom_t * self, int value); void exit_error (eeprom_t * eep, int status, char * s) { eeprom_destroy(eep); fprintf(stderr,"%s\n",s); exit(status); } eeprom_t * eeprom_init (unsigned long int parallel_port_address, unsigned long int write_size, unsigned int addr_size, unsigned long int read_size, unsigned long int total_size, unsigned char inv_page, unsigned int microdelay_factor) { eeprom_t * self; microdelay_init(microdelay_factor); self=malloc(sizeof(eeprom_t)); assert(self!=NULL); self->pp=parport_init(parallel_port_address); self->write_size=write_size; self->addr_size=addr_size; self->read_size=read_size; self->total_size=total_size; self->inv_page=inv_page; /* hardware initialize */ eeprom_power(self,0); return self; } void eeprom_destroy (eeprom_t * self) { if (self!=NULL) { eeprom_power(self,0); /* power off */ parport_destroy(self->pp); free(self); } } /* TODO: implement the code */ /* int eeprom_readbyte (eeprom_t * self, int addr) { assert(0); } int eeprom_writebyte (eeprom_t * self, int addr, int value) { assert(0); } */ int eeprom_fullread (eeprom_t * self, memory_t * mem) { int i, addr=0; int total_pages=0; int current_page=0; eeprom_power(self,1); total_pages=self->total_size / self->read_size; for (current_page=0; current_pageaddr_size; i++) { eeprom_sendbyte(self, 0); if (eeprom_readbit(self)!=0) /* check ACK */ exit_error(self, 0x21,"read error - ACK not received"); } /* Sequencial Read */ eeprom_controlbyte(self, current_page, 1); for (addr=0; addrread_size; addr++) { if (addr!=0) { eeprom_writebit(self, 0); /* send ACK */ } memory_write (mem, addr+(self->read_size*current_page), eeprom_getbyte (self)); /* send byte to memory */ } if (eeprom_readbit(self)==0) /* check NOACK */ exit_error(self, 0x22,"read error - NOACK not received"); eeprom_stopbit(self); for (i=0; i<16; i++) { /* some dummy clock cycles */ parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); } } eeprom_power(self,0); return 1; } int eeprom_fullwrite (eeprom_t *self, memory_t * mem) { int i; int addr; int total_pages=0; int current_page=0; eeprom_power(self,1); total_pages=self->total_size / self->read_size; for (current_page=0; current_pageread_size); addr+=self->write_size) { if (eeprom_controlbyte(self, current_page, 0)==0) exit_error(self, 0x30,"write error - control byte failed"); /* send address bytes */ for (i=(self->addr_size-1); i>=0; i--) { eeprom_sendbyte (self, 0xFF & (addr>>(i*8))); if (eeprom_readbit(self)!=0) /* check ACK */ exit_error(self, 0x31,"write error - ACK not received"); } for (i=addr; i<(addr+self->write_size); i++) { eeprom_sendbyte (self, memory_read(mem, i+ (self->read_size*current_page))); eeprom_writebit(self, 0); /* send ACK */ } eeprom_stopbit(self); /* Acknoledge pooling */ { int timeout=10000, ack=0, i; while ((timeout>0) && (ack==0)) { timeout--; if (eeprom_controlbyte(self, 0, 1)) { ack=1; } eeprom_stopbit(self); for (i=0; i<80; i++) { /* some dummy clock cycles */ parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); if (i==40) eeprom_stopbit(self); } } if (ack==0) exit_error(self, 0x32,"write error - ACK pooling not received"); } } } eeprom_power(self,0); return 1; } void eeprom_power (eeprom_t * self, int poweron) { if (poweron) { /* power on */ int i; parport_writebyte(self->pp, 0xFF); parport_writebit (self->pp, EEPROM_NDATAIN, 0); microdelay(EEPROM_POWERDELAY); /* power up delay */ for (i=0; i<256; i++) { /* some dummy clock cycles */ parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); } } else { /* power off */ parport_writebyte(self->pp, 0x00); parport_writebit (self->pp, EEPROM_NDATAIN, 1); } } void eeprom_startbit (eeprom_t * self) { /* send start condition */ parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_NDATAIN, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_NDATAIN, 0); microdelay(EEPROM_DELAY); } void eeprom_stopbit (eeprom_t * self) { /* send stop condition */ parport_writebit (self->pp, EEPROM_NDATAIN, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_NDATAIN, 0); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); } void eeprom_writebit (eeprom_t * self, int value) { if (value) { parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); } else { parport_writebit (self->pp, EEPROM_NDATAIN, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_NDATAIN, 0); microdelay(EEPROM_DELAY); } } int eeprom_readbit (eeprom_t * self) { int i; parport_writebit (self->pp, EEPROM_CLOCK, 1); microdelay(EEPROM_DELAY); i=parport_readbit(self->pp, EEPROM_DATAOUT); microdelay(EEPROM_DELAY); parport_writebit (self->pp, EEPROM_CLOCK, 0); microdelay(EEPROM_DELAY); return i; } int eeprom_controlbyte (eeprom_t * self, int page, int readmode) { eeprom_startbit(self); /* device address */ eeprom_writebit(self, 1); eeprom_writebit(self, 0); eeprom_writebit(self, 1); eeprom_writebit(self, 0); /* page number */ if ((self->inv_page) != 0) { eeprom_writebit(self, page & 0x01); /* page P0 */ eeprom_writebit(self, page & 0x02); /* page P1 */ eeprom_writebit(self, page & 0x04); /* page P2 */ } else { eeprom_writebit(self, page & 0x04); /* page P2 */ eeprom_writebit(self, page & 0x02); /* page P1 */ eeprom_writebit(self, page & 0x01); /* page P0 */ } eeprom_writebit(self, readmode); /* 0 = write, 1 = read */ /* check ACK */ if (eeprom_readbit(self)!=0) return 0; /* Failed */ return 1; /* Success */ } int eeprom_getbyte (eeprom_t * self) { int i=0; i|=eeprom_readbit(self)<<7; /* D7 - MSB */ i|=eeprom_readbit(self)<<6; /* D6 */ i|=eeprom_readbit(self)<<5; /* D5 */ i|=eeprom_readbit(self)<<4; /* D4 */ i|=eeprom_readbit(self)<<3; /* D3 */ i|=eeprom_readbit(self)<<2; /* D2 */ i|=eeprom_readbit(self)<<1; /* D1 */ i|=eeprom_readbit(self)<<0; /* D0 - LSB */ return i; } void eeprom_sendbyte (eeprom_t * self, int value) { eeprom_writebit(self, value & 0x80); /* D7 - MSB */ eeprom_writebit(self, value & 0x40); /* D6 */ eeprom_writebit(self, value & 0x20); /* D5 */ eeprom_writebit(self, value & 0x10); /* D4 */ eeprom_writebit(self, value & 0x08); /* D3 */ eeprom_writebit(self, value & 0x04); /* D2 */ eeprom_writebit(self, value & 0x02); /* D1 */ eeprom_writebit(self, value & 0x01); /* D0 - LSB */ } eep24c-0.1.2/eeprom.h0000644000175000017500000000633310265023470013700 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: eeprom.h,v 1.3 2003/07/05 18:23:22 pzn Exp $ */ #ifndef _EEPROM_H #define _EEPROM_H #include "memory.h" #include "parport.h" #include "eeprpins.h" /* NOTE: will use unsigned long int because if compiled * in old DOS compilers, unsigned int will have 16bit * and will not support values greater than 65535 */ typedef struct { parport_t * pp; int access_mode; unsigned long int write_size; unsigned int addr_size; unsigned long int read_size; unsigned long int total_size; unsigned char inv_page; } eeprom_t; eeprom_t * eeprom_init (unsigned long int parallel_port_address, unsigned long int write_size, /* how many bytes can be written sequencially */ unsigned int addr_size, /* how many words the address command has */ unsigned long int read_size, /* how many bytes can be read sequencially */ unsigned long int total_size, /* how many bytes the memory has */ unsigned char inv_page, /* invert page specification bits in control word (lsb will go first) I only know Microchip 24xx515 which uses this */ unsigned int microdelay_factor /* multiply the standard timing (microseconds) by this factor. 1 will use standard values */ ); void eeprom_destroy (eeprom_t * self); /* int eeprom_readbyte (eeprom_t * self, int addr); int eeprom_writebyte (eeprom_t * self, int addr, int value); */ int eeprom_fullread (eeprom_t * self, memory_t * mem); int eeprom_fullwrite (eeprom_t *self, memory_t * mem); void eeprom_power (eeprom_t * self, int poweron); /* AT24Cxxx values: * * I found some chips (from other manufacturers) that have * write_size smaller than the values found in Atmel datasheet. * I recommend using write_size smaller than the values below. * * model write_size addr_size read_size total_size inv_page * 24c01 8 1 128 128 0 * 24c02 8 1 256 256 0 * 24c04 16 1 256 512 0 * 24c08 16 1 256 1024 0 * 24c16 16 1 256 2048 0 * 24c32 32 2 4096 4096 0 * 24c64 32 2 8192 8192 0 * 24c128 64 2 16384 16384 0 * 24c256 64 2 32768 32768 0 * 24c512 128 2 65536 65536 0 * 24c515 64 2 32768 65536 1 * */ #endif eep24c-0.1.2/eeprpins.h0000644000175000017500000000202410265023471014230 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: eeprpins.h,v 1.2 2003/06/30 17:20:24 pzn Exp $ */ #ifndef _EEPRPINS_H #define _EEPRPINS_H #include "parport.h" #define EEPROM_CLOCK PARPORT_D0 #define EEPROM_NDATAIN PARPORT_D1 #define EEPROM_DATAOUT PARPORT_ERROR #endif eep24c-0.1.2/ihex2txt.10000644000175000017500000000271010265023471014075 0ustar pznpzn00000000000000.\" Hey, EMACS: -*- nroff -*- .\" $Id: ihex2txt.1,v 1.2 2003/06/30 17:20:24 pzn Exp $ .TH EEP24C 1 "2002-11-14" .\" Please adjust this date whenever revising the manpage. .SH NAME ihex2txt \- converts Intelhex format to a simple text format .br txt2ihex \- converts simple text format to Intelhex .SH SYNOPSIS .B ihex2txt inputfile outputfile .br .B txt2ihex inputfile outputfile .SH DESCRIPTION The commands .B ihex2txt and .B txt2ihex can be used to edit data in Intelhex format. First you get the original Intelhex file and use .B ihex2txt to convert it. Then you edit the text file and convert back to Intelhex using .B txt2ihex .SH INTELHEX FORMAT .B Intel Hexadecimal Object File Format or simply Intelhex specification can be found at .br ftp://download.intel.com/support/processors/ .br i960/devtools/INTELHEX.PDF .br Record types 00 and 01 are implemented in this version. In input lines, LF and CR+LF are accepted as newline markers. Output files are generated with LF as a newline marker. .SH TEXT FORMAT The text format is composed by a line with values separated with spaces. The first value is the initial address, the following values are the values. .br Example: .B 02B7 07 B9 70 7A 6E .br means that the content of address 02B7 is 07, the content of address 02B8 is B9, the content of address 02B9 is 70, ... .SH SEE ALSO .BR eep24c (1). .br .SH AUTHOR This manual page was written by Pedro Zorzenon Neto . eep24c-0.1.2/ihex2txt.c0000644000175000017500000000424210265023472014162 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: ihex2txt.c,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #include "common.h" #include #include #include #include "intelhex.h" int main (int argc, char *argv[]) { inteldata ihex; int i; FILE *f; char l[780]; /* > (256*3)+5 */ char ll[4]; /* space + 2 chars + 0x00 */ if ( argc == 2 ) { if ( (strcmp(argv[1],"--help")) || (strcmp(argv[1],"-h")) || (strcmp(argv[1],"-?")) || (strcmp(argv[1],"--usage")) || (strcmp(argv[1],"/?")) ) { fprintf(stderr,"ihex2txt is free software with ABSOLUTELY " "NO WARRANTY. \nCopyright (c) 2002 - Pedro Zorzenon " "Neto.\nihex2txt: converts Intelhex file to simple " "text format\nUsage: ihex2txt inputfilename.hex " "outputfilename.txt\nWarning: outputfilename.txt will " "be overwritten.\n"); return 1; } } if ( argc != 3 ) { fprintf(stderr,"Try: ihex2txt --help\n"); return 1; } intelhex_fileopen ( &ihex, argv[1], 1); f=fopen(argv[2],"w"); if (f==NULL) { perror("Error opening output file"); intelhex_fileclose (&ihex); abort(); } while ( intelhex_readline (&ihex)==1 ) { sprintf(l,"%04X",ihex.offset); for (i=0; i and Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: intelhex.c,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #include "common.h" #include "intelhex.h" #include #include #ifdef __linux__ # include #endif int intelhex_fileopen (inteldata *id, char *filename, int mode) { /*mode = 1 -> open file for reading 0 -> creates a new file for writing */ /* TODO: please, check if the file already exists before overwriting */ if (mode==0) { id->file=fopen(filename,"w"); if (id->file==NULL) { fprintf(stderr,"File create error\n"); abort(); } id->eof_found=0; return 1; } id->file=fopen(filename,"r"); if (id->file==NULL) { fprintf(stderr,"Error when opening the file '%s' for reading.\n",filename); abort(); } id->eof_found=0; return 1; } int intelhex_fileclose (inteldata * id) { return fclose(id->file); } int intelhex_readline (inteldata * id) { /* returns: 0 EOF found 1 line read ok >1 some error occoured */ char line[526], conv[5]; int rectype, chksum, linelen, reccount, i; /* verifies eof and eof_record */ if (id->eof_found==1) return 0; /* eof_record found */ if (feof(id->file)) { fprintf(stderr,"error in intelhex file - eof_record not found\n"); return 2; } /* reads a line from stdin (hex file format) */ fgets(line, 525, id->file); /* changes CR+LF to FL if needed and checks if LF is present */ linelen=strlen(line); if (line[linelen-2] == 13) { line[linelen-2]=line[linelen-1]; line[linelen-1]=0; linelen=strlen(line); } if (line[linelen-1] != 10) { fprintf(stderr,"error in intelhex file - linefeed not found at end of line\n"); return 3; } /* checks for record mark */ if (line[0] != 0x3a) { fprintf(stderr,"error in intelhex file - ':' missing\n"); return 4; } /* verifies the minimum linelength */ if (linelen < 12) { fprintf(stderr,"error in intelhex file - less than 11 characters in a line\n"); return 5; } /* verifies the checksum */ conv[2]=0; chksum=0; for(i=1; i<(linelen-1); i+=2) { conv[0]=line[i]; conv[1]=line[i+1]; chksum+=(int)strtoul(conv,(char **)NULL,16); } if (chksum % 256) { fprintf(stderr,"error in intelhex file - bad chksum\n"); return 6; } /* reads record length */ conv[2]=0; i=1; conv[0]=line[i]; conv[1]=line[i+1]; i+=2; id->reclen=(int)strtoul(conv,(char **)NULL,16); /* checks if linelength is (reclength*2 + 12) */ if (((id->reclen*2)+12) != linelen) { fprintf(stderr,"error in intelhex file - number of characters doesn't match reclength\n"); return 7; } /* reads load offset */ conv[4]=0; conv[0]=line[i]; conv[1]=line[i+1]; conv[2]=line[i+2]; conv[3]=line[i+3]; i+=4; id->offset=(int)strtoul(conv,(char **)NULL,16); /* reads record type */ conv[2]=0; conv[0]=line[i]; conv[1]=line[i+1]; i+=2; rectype=(int)strtoul(conv,(char **)NULL,16); /* returns if rectype is 01 (eof_record) */ if(rectype==1) { id->eof_found=1; return 0; /* eof_record found */ } /* checks if rectype is 00 */ if(rectype!=0) { fprintf(stderr,"error in intelhex file - this program only accepts rectype 00(data) or 01(eof)\n"); return 8; } /* reads record data */ for(reccount=0; reccountreclen; reccount++) { conv[0]=line[i]; conv[1]=line[i+1]; i+=2; id->recdata[reccount]=(int)strtoul(conv,(char **)NULL,16); } return 1; /* successfull read - data available */ } int intelhex_writeline (inteldata * id) { unsigned int chksum; int reccount; if (id->reclen==0 || id->reclen>255 || id->offset<0 || id->offset>0xffff) { fprintf(stderr,"error in intelhex file - offset/reclen invalid when writing file\n"); return 0; } fprintf(id->file, ":%02X%04X00", id->reclen, id->offset); chksum = id->reclen; /* reclength */ chksum += id->offset % 256; /* low 8 bits of load offset */ chksum += id->offset / 256; /* high 8 bits of load offset */ /* chksum += 0x00;*/ /* rectype */ for (reccount=0; reccountreclen; reccount++) { fprintf(id->file, "%02X", id->recdata[reccount]); chksum += id->recdata[reccount]; } chksum = 256 - (chksum % 256); if (chksum==256) chksum=0; fprintf(id->file, "%02X", chksum); fprintf(id->file, "\n"); return 1; } void intelhex_writeeof (inteldata * id) { fprintf(id->file, ":00000001FF\n"); } eep24c-0.1.2/intelhex.h0000644000175000017500000000607410265023473014236 0ustar pznpzn00000000000000/* Copyright (C) 2000-2002 Jos Roberto B. de A. Monteiro and Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: intelhex.h,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #ifndef _INTELHEX_H #define _INTELHEX_H #include /* defining type 'inteldata': offset is the address offset datalen is the actual number of elements in data file is a pointer to the file/stream eof_found is set to 1 when :00000001FF if found (endoffile) */ typedef struct { unsigned char recdata[256]; unsigned int offset; unsigned int reclen; FILE * file; int eof_found; } inteldata; /* mode = 1 -> open file for reading * 0 -> creates a new file for writing * * returns always 1. aborts the program if could not open file */ int intelhex_fileopen (inteldata *id, char *filename, int mode); int intelhex_fileclose (inteldata *id); /* intelhex_readline returns: 1 = successfull read - data available 0 = successfull read - eof_record found or did't read because eof_record had already been found >1 = unsuccessfull read, error sent to stdout */ int intelhex_readline (inteldata *id); /* put data in inteldata->recdata put datalength in inteldata->reclen put load offset in inteldata->offset then execute intelhex_writeline instruction */ int intelhex_writeline (inteldata *id); /* writes an eof record in the file */ void intelhex_writeeof (inteldata *id); /* Usage example: * READING AN INTELHEX FILE: inteldata ihex; int i; intelhex_fileopen ( &ihex, "filename.hex", 1); while ( intelhex_readline (&ihex)==1 ) { for (i=0; i and Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: mcdelay.c,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ /* From http://www.linuxdoc.org/HOWTO/mini/IO-Port-Programming.html an outb to port 0x80 gives a delay of aprox 1microsec independent of your machine type/clock. See also documentation in asm/io.h */ #include "common.h" #include "mcdelay.h" #include #include #ifdef __dos__ # include #else # include # include # include #endif int old_port_value; unsigned int m_f; void microdelay_init(int multiply_factor) { /* permition to write in port 0x80 nothing is suposed to use this port however, we will write the same value we read... */ #ifdef __dos__ old_port_value=inportb(0x80); #else if (geteuid()!=0) { fprintf(stderr,"ERROR: this programs needs root permisions to access parallel port. Please use root user to run or setuid bit.\n"); abort(); } ioperm(0x80,1,1); old_port_value=inb(0x80); #endif m_f = multiply_factor; } void microdelay(unsigned int microsec) { unsigned int i; i = m_f; while (i) { while (microsec) { #ifdef __dos__ outportb(0x80, old_port_value); #else outb(old_port_value,0x80); #endif microsec--; } i--; } } eep24c-0.1.2/mcdelay.h0000644000175000017500000000210110265023475014021 0ustar pznpzn00000000000000/* Copyright (C) 2000-2002 Jos Roberto B. de A. Monteiro and Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: mcdelay.h,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #ifndef _MICRODELAY_H #define _MICRODELAY_H void microdelay_init(int multiply_factor); void microdelay(unsigned int microsec); #endif eep24c-0.1.2/memory.c0000644000175000017500000000442510265023475013721 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: memory.c,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #include "common.h" #include "memory.h" #include #include #include memory_t * memory_init(unsigned long int size) { memory_t * self; int * data; self=malloc(sizeof(memory_t*)); assert(self!=NULL); assert(size>0); data=malloc((sizeof(int))*size); assert(data!=NULL); self->size=size; self->data=data; return self; } void memory_destroy(memory_t* self) { if (self!=NULL) { if (self->data!=NULL) { free(self->data); } free(self); } } void memory_fill (memory_t* self, int value) { int i; for (i=0; isize; i++) { self->data[i]=value; } } int memory_read(memory_t* self, unsigned int addr) { assert( self->size > addr ); return self->data[addr]; } void memory_write (memory_t* self, unsigned int addr, int value) { assert( self->size > addr ); self->data[addr]=value; } int memory_compare (memory_t* mem1, memory_t* mem2) { unsigned int i; if (mem1->size != mem2->size) return 0; for (i=0; i<(mem1->size); i++) { if ( (mem1->data[i]) != (mem2->data[i]) ) { return 0; } } return 1; } #ifdef TEST int main() { memory_t* mt; int i; mt=memory_init(16); memory_fill(mt, -34); memory_write (mt, 13, 1132); memory_write (mt, 12, 1122); memory_write (mt, 14, 1142); memory_write (mt, 11, 1112); for (i=0; i<16; i++) { printf("addr=%d value=%d\n",i,memory_read(mt, i)); } memory_destroy(mt); return 0; } #endif eep24c-0.1.2/memory.h0000644000175000017500000000241110265023476013720 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: memory.h,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #ifndef _MEMORY_H #define _MEMORY_H typedef struct memory { unsigned long int size; int * data; } memory_t; memory_t * memory_init(unsigned long int size); void memory_destroy(memory_t* self); void memory_fill (memory_t* self, int value); int memory_read(memory_t* self, unsigned int addr); void memory_write (memory_t* self, unsigned int addr, int value); int memory_compare (memory_t* mem1, memory_t* mem2); #endif eep24c-0.1.2/parport.c0000644000175000017500000000637710265023476014111 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: parport.c,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #include "common.h" #include "parport.h" #include #include #include #ifdef __linux__ # include # include # include #endif #ifdef __dos__ # include #endif #include "mcdelay.h" parport_t * parport_init (long int base_address) { parport_t * self; self=malloc(sizeof(parport_t)); assert(self!=NULL); self->base_address=base_address; self->last_write=~0; #ifdef __linux__ if (geteuid()!=0) { fprintf(stderr,"ERROR: this programs needs root permisions to access parallel port. Please use root user to run or setuid bit.\n"); abort(); } ioperm(self->base_address,3,1); #endif return self; } void parport_destroy (parport_t * self) { if (self!=NULL) { #ifdef __linux__ ioperm(self->base_address,3,0); #endif free(self); } } int parport_readbit (parport_t * self, int bit) { int i; i=parport_readbyte (self); if (i & (0x01<base_address+1); #endif #ifdef __dos__ return (unsigned int) inportb (self->base_address+1); #endif } void parport_writebit (parport_t * self, int bit, unsigned value) { int i; i=self->last_write; if (value) { i|=(0x01<last_write&0xFF)) outb(value&0xFF,self->base_address); if ((value&0xF00) != (self->last_write&0xF00)) outb((value>>8)&0x0F,self->base_address+2); #endif #ifdef __dos__ if ((value&0xFF) != (self->last_write&0xFF)) outportb(self->base_address,value&0xFF); if ((value&0xF00) != (self->last_write&0xF00)) outportb(self->base_address+2,(value>>8)&0x0F); #endif self->last_write=value; } #ifdef TEST int main() { parport_t * pp; unsigned int i, j; pp=parport_init(0x378); i=parport_readbyte(pp); j=0; if (i & PARPORT_ERROR) j=1; printf("status ERROR %d\n",j); j=0; if (i & PARPORT_SELECTIN) j=1; printf("status SELECTIN %d\n",j); j=0; if (i & PARPORT_PAPEROUT) j=1; printf("status PAPEROUT %d\n",j); j=0; if (i & PARPORT_ACK) j=1; printf("status ACK %d\n",j); j=0; if (i & PARPORT_BUSY) j=1; printf("status BUSY %d\n",j); parport_destroy(pp); return 0; } #endif eep24c-0.1.2/parport.h0000644000175000017500000000370310265023477014105 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: parport.h,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #ifndef _PARPORT_H #define _PARPORT_H /* SPP standard parallel port * http://www.beyondlogic.org/spp/parallel.htm */ /* parallel port output bits */ #define PARPORT_D0 0 #define PARPORT_D1 1 #define PARPORT_D2 2 #define PARPORT_D3 3 #define PARPORT_D4 4 #define PARPORT_D5 5 #define PARPORT_D6 6 #define PARPORT_D7 7 #define PARPORT_STROBE 0 /* hardware inverted */ #define PARPORT_LINEFEED 1 /* hardware inverted */ #define PARPORT_RESET 2 #define PARPORT_SELECT 3 /* parallel port input bits */ #define PARPORT_ERROR 3 #define PARPORT_SELECTIN 4 /* hardware inverted */ #define PARPORT_PAPEROUT 5 #define PARPORT_ACK 6 #define PARPORT_BUSY 7 /* hardware inverted */ typedef struct parport { long int base_address; unsigned int last_write; } parport_t; parport_t * parport_init (long int base_address); void parport_destroy (parport_t * self); int parport_readbit (parport_t * self, int bit); unsigned int parport_readbyte (parport_t * self); void parport_writebit (parport_t * self, int bit, unsigned int value); void parport_writebyte (parport_t * self, unsigned int value); #endif eep24c-0.1.2/txt2ihex.c0000644000175000017500000000443510265023500014156 0ustar pznpzn00000000000000/* Copyright (C) 2002 Pedro Zorzenon Neto 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. Do not forget to visit Free Software Foundation site: http://fsf.org $Id: txt2ihex.c,v 1.2 2003/06/30 17:20:25 pzn Exp $ */ #include "common.h" #include #include #include #include "intelhex.h" int main (int argc, char *argv[]) { inteldata ihex; FILE *f; char l[780]; /* > (256*3)+5 */ if ( argc == 2 ) { if ( (strcmp(argv[1],"--help")) || (strcmp(argv[1],"-h")) || (strcmp(argv[1],"-?")) || (strcmp(argv[1],"--usage")) || (strcmp(argv[1],"/?")) ) { fprintf(stderr,"txt2ihex is free software with ABSOLUTELY " "NO WARRANTY. \nCopyright (c) 2002 - Pedro Zorzenon " "Neto.\ntxt2ihex: converts simple text format to " "Intelhex format\nUsage: txt2ihex inputfilename.txt " "outputfilename.hex\nWarning: outputfilename.hex will " "be overwritten.\n"); return 1; } } if ( argc != 3 ) { fprintf(stderr,"Try: txt2ihex --help\n"); return 1; } f=fopen(argv[1],"r"); if (f==NULL) { perror("Error opening input file"); abort(); } intelhex_fileopen ( &ihex, argv[2], 0); fgets(l, 779, f); while ( feof(f)==0 ) { unsigned int offset; int i=0; char *s; s=strtok(l," "); offset=(unsigned int)strtol(s,NULL,16); ihex.offset=offset; s=strtok(NULL," "); while (s != NULL) { ihex.recdata[i]= 0xFF & strtol(s,NULL,16); i++; ihex.reclen=i; s=strtok(NULL," "); } intelhex_writeline (&ihex); fgets(l, 779, f); } fclose(f); intelhex_writeeof (&ihex); intelhex_fileclose (&ihex); return 0; } eep24c-0.1.2/txt2ihex.prj0000644000175000017500000000003010265023501014513 0ustar pznpzn00000000000000intelhex.c txt2ihex.c eep24c-0.1.2/help_pt/0000755000175000017500000000000010265023156013667 5ustar pznpzn00000000000000eep24c-0.1.2/help_pt/eep24c.txt0000644000175000017500000000506307701614212015516 0ustar pznpzn00000000000000EEP24C(1) EEP24C(1) NOME eep24c - le e grava eeproms da srie 24Cxxx SINOPSE eep24c -d device [ -r filename | -w filename | -k filename | -f xx ] DESCRIO O comando eep24c pode ser utilizado para ler e gravar memrias do tipo 24Cxxx. OPES As seguintes opes esto disponveis: -d device Espeficica o tipo da eeprom. Para ver uma lisat dos tipos suportados, tente: eep24c -d help -r filename Le da eeprom e grava em um arquivo. -w filename Le de um arquivo e grava na eeprom. Os endereos no especificados no arquivo sero escritos com 00. -k filename Le de um arquivo e grava na eeprom. Os endereos no especificados no arquivo sero mantidos como estavam. -f XX Enche a memria com XX (XX um valor hexadecimal) EXEMPLOS DE USO eep24c -d 24c04 -r file.hex le a eeprom, grava no arquivo file.hex eep24c -d 24c04 -w file.hex le o arquivo file.hex e grava na eeprom. Todos os endereos no encontrados neste arquivo sero escritos como 00. eep24c -d 24c04 -k file.hex le o arquivo file.hex e grava na eeprom. Todos os endereos no encontrados neste arquivo no sero alterados. eep24c -d 24c04 -f 7A grava 7A (hexadecimal) em todas as posies da eeprom. FORMATOS DE ENTRADA E SADA O formato dos arquivo de entrada e sada o: Intel Hexadecimal Object File Format Voc pode encontrar a especificao deste formato em: ftp://download.intel.com/support/processors/ i960/devtools/INTELHEX.PDF Os Record-types 00 e 01 esto implementados nesta verso. Tanto o terminador CR+LF quanto o terminador LF so aceitos nos arquivos de entrada. Os arquivos de sada so gerados com LF se o programa estiver sendo executado em um sistema Unix ou gerados como CR+LF se o sistema for Dos. INFORMACAO ESPECIFICA Se voc est usando a eeprom da Microchip 24*515, ento voc deve conectar o pino A2 ao VCC. ( preciso modificar o circuito, veja o manual deste CI). VEJA TAMBM ihex2txt(1), txt2ihex(1). AUTOR Este manual foi escrito por Pedro Zorzenon Neto . 2002-11-14 EEP24C(1) eep24c-0.1.2/help_pt/ihex2txt.txt0000644000175000017500000000350307700067350016214 0ustar pznpzn00000000000000EEP24C(1) EEP24C(1) NOME ihex2txt - converte do formato Intelhex para um formato texto simplificado. txt2ihex - converts do formato de texto simplificado para o formato Intelhex. SINOPSE ihex2txt arquivoentrada arquivosaida txt2ihex arquivoentrada arquivosaida DESCRIO Os comandos ihex2txt e txt2ihex podem ser utilizados para editar dados no formato Intelhex. Voc pode converver o arquivo originalmente no formato Intelhex usando o ihex2txt, editar o arquivo no formato texto e reconverter para Intelhex usando o txt2ihex. FORMATO INTELHEX As especificaes do formato Intelhex, ou ento Intel Hexadecimal Object File Format podem ser encontradas no endereo: ftp://download.intel.com/support/processors/ i960/devtools/INTELHEX.PDF Os Record-types 00 e 01 esto implementados nesta verso. Tanto o terminador CR+LF quanto o terminador LF so aceitos nos arquivos de entrada. Os arquivos de sada so gerados com LF se o programa estiver sendo executado em um sistema Unix ou gerados como CR+LF se o sistema for Dos. FORMATO TEXTO SIMPLIFICADO Este formato composto por linhas com campos separados por espaos. O primeiro valor o endereo inicial. Os valores consecutivos so os dados. Exemplo: 02B7 07 B9 70 7A 6E significa que o contedo do endereo 02B7 07, o contedo do endereo 02B8 B9, o contedo do endereo 02B9 70, e assim por diante. VEJA TAMBM eep24c(1). AUTOR Este manual foi escrito por Pedro Zorzenon Neto . 2002-11-14 EEP24C(1) eep24c-0.1.2/Changelog0000644000175000017500000000040310265023461014042 0ustar pznpzn00000000000000$Id: Changelog,v 1.2 2003/07/05 18:23:22 pzn Exp $ Version 0.1.1 - Sat, 5 Jul 2003 15:11:02 -0300 Bug fix, wrong bit mask in eeprom.c. Thanks to Dan Williams. Added 24xx515 eeprom and modified eeprom.c eeprom.h to support its diferent control byte.