From 925d0670c45e1100e412070fa0ce2405604f219a Mon Sep 17 00:00:00 2001 From: Attila Veghelyi Date: Thu, 29 Jun 2023 16:24:54 +0200 Subject: Init repo --- fileIO.c | 835 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 835 insertions(+) create mode 100644 fileIO.c (limited to 'fileIO.c') diff --git a/fileIO.c b/fileIO.c new file mode 100644 index 0000000..30da4b0 --- /dev/null +++ b/fileIO.c @@ -0,0 +1,835 @@ +/* + * fileIO.c - file read and write + * Copyright (C) 2010-2021 Alberto Maccioni + * + * 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 USA + * or see + */ + +//configure for GUI or command-line +#include "common.h" +#include "progP12.h" +#include "progP16.h" +#include "progP18.h" +#include "progP24.h" +#include "progAVR.h" + +unsigned int htoi(const char *hex, int length) +{ + int i; + unsigned int v = 0; + for (i = 0; i < length; i++) { + v <<= 4; + if (hex[i] >= '0' && hex[i] <= '9') v += hex[i] - '0'; + else if (hex[i] >= 'a' && hex[i] <= 'f') v += hex[i] - 'a' + 10; + else if (hex[i] >= 'A' && hex[i] <= 'F') v += hex[i] - 'A' + 10; + else PrintMessage1(strings[S_Inohex],hex); //"Error: '%.4s' doesn't look very hexadecimal, right?\n" + } + return v; +} + +void Save(char* dev,char* savefile) +{ + FILE* f=fopen(savefile,"w"); + if(!f) return; + char str[512],str1[512]=""; + int i,sum=0,count=0,ext=0,s,base; +//**************** 10-16F ******************************************* + if(!strncmp(dev,"10",2)||!strncmp(dev,"12",2)||!strncmp(dev,"16",2)){ + int x=0x3fff,addr; + //if(!strncmp(dev,"16",2)||!strncmp(dev,"12F6",4)) x=0x3fff; + fprintf(f,":020000040000FA\n"); //extended address=0 + for(i=0;i=x;i++); //remove leading 0xFFF + for(;i>8)+(memCODE_W[i]&0xff); + sprintf(str,"%02X%02X",memCODE_W[i]&0xff,memCODE_W[i]>>8); + strcat(str1,str); + count++; + if(count==8||i==sizeW-1){ + base=i-count+1; + for(s=i;s>=base&&memCODE_W[s]>=x;s--){ //remove trailing 0xFFF + sum-=(memCODE_W[s]>>8)+(memCODE_W[s]&0xff); + str1[strlen(str1)-4]=0; + } + count-=i-s; + addr=(s-count+1)*2; + sum+=count*2+(addr&0xff)+(addr>>8); + if(base>>15>ext){ + ext=base>>15; + fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff); + } + if(count) fprintf(f,":%02X%04X00%s%02X\n",count*2,addr&0xFFFF,str1,(-sum)&0xff); + str1[0]=0; + count=sum=0; + } + } + if(sizeEE){ //this is only for 16F1xxx + if(ext!=0x01) fprintf(f,":020000040001F9\n"); + for(i=0,count=sum=0;ii-count&&memEE[s]>=0xff;s--){ //remove trailing 0xFF + sum-=memEE[s]&0xff; + str1[strlen(str1)-4]=0; + } + count-=i-s; + addr=(s-count+1)*2+0xE000; + sum+=count*2+(addr&0xff)+(addr>>8); + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count*2,addr,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + } + fprintf(f,":00000001FF\n"); + } +//**************** 18F ******************************************* + else if(!strncmp(dev,"18F",3)){ + fprintf(f,":020000040000FA\n"); //extended address=0 + for(i=0;i=base&&memCODE[s]==0xff;s--){ //remove trailing 0xFF + sum-=memCODE[s]; + str1[strlen(str1)-2]=0; + } + count-=i-s; + sum+=count+(base&0xff)+((base>>8)&0xff); + if(base>>16>ext){ + ext=base>>16; + fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff); + } + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + for(i=0,count=sum=0;i<8;i++){ + sum+=memID[i]; + sprintf(str,"%02X",memID[i]&0xff); + strcat(str1,str); + count++; + if(count==8){ + fprintf(f,":020000040020DA\n"); + base=i-count+1; + for(s=i;s>i-count&&memID[s]>=0xff;s--){ //remove trailing 0xFF + sum-=memID[s]&0xff; + str1[strlen(str1)-2]=0; + } + count-=i-s; + sum+=count+(base&0xff)+((base>>8)&0xff); + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + for(i=0,count=sum=0;i<14;i++){ + sum+=memCONFIG[i]; + sprintf(str,"%02X",memCONFIG[i]&0xff); + strcat(str1,str); + count++; + if(count==14){ + fprintf(f,":020000040030CA\n"); + base=i-count+1; + for(s=i;s>i-count&&memCONFIG[s]>=0xff;s--){ //remove trailing 0xFF + sum-=memCONFIG[s]&0xff; + str1[strlen(str1)-2]=0; + } + count-=i-s; + sum+=count+(base&0xff)+((base>>8)&0xff); + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + if(sizeEE){ + fprintf(f,":0200000400F00A\n"); + for(i=0,count=sum=0;ii-count&&memEE[s]>=0xff;s--){ //remove trailing 0xFF + sum-=memEE[s]&0xff; + str1[strlen(str1)-2]=0; + } + count-=i-s; + sum+=count+(base&0xff)+((base>>8)&0xff); + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + } + fprintf(f,":00000001FF\n"); + } +//**************** 24F ******************************************* + else if((!strncmp(dev,"24F",3)||!strncmp(dev,"24H",3)||!strncmp(dev,"24E",3)||!strncmp(dev,"30F",3)||!strncmp(dev,"33F",3)||!strncmp(dev,"33E",3))){ + int valid; + fprintf(f,":020000040000FA\n"); //extended address=0 + int sum=0,count=0,s,word; + word=memCODE[0]+(memCODE[1]<<8)+(memCODE[2]<<16)+(memCODE[3]<<24); + for(i=0;i>8)&0xff); + if(base>>16>ext){ + ext=base>>16; + fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff); + } + if(count&&valid){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + if(sizeCONFIG){ + fprintf(f,":0200000401F009\n"); + for(i=0,count=sum=0;i>8)&0xff); + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + } + if(sizeEE){ + fprintf(f,":0200000400FFFB\n"); + str1[0]=0; + for(i=0,count=sum=0;i>8); + if(count&&valid){ + fprintf(f,":%02X%04X00%s%02X\n",count,base+0xE000,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + } + fprintf(f,":00000001FF\n"); + } +//**************** ATxxxx ******************************************* + else if(!strncmp(dev,"AT",2)){ + fprintf(f,":020000040000FA\n"); //extended address=0 + for(i=0;i=base&&memCODE[s]==0xff;s--){ //remove trailing 0xFF + sum-=memCODE[s]; + str1[strlen(str1)-2]=0; + } + count-=i-s; + sum+=count+(base&0xff)+((base>>8)&0xff); + if(base>>16>ext){ + ext=base>>16; + fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff); + } + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + fprintf(f,":00000001FF\n"); + } +//**************** 24xxx / 93xxx / 25xxx / 95xxx / DSxxxx ******************************************* + else if(!strncmp(dev,"24",2)||!strncmp(dev,"93",2)||!strncmp(dev,"25",2)||!strncmp(dev,"95",2)||\ + !strncmp(dev,"DS",2)||!strncmp(dev,"11",2)){ + if(strstr(savefile,".bin")||strstr(savefile,".BIN")){ + #ifdef _WIN32 + //brain-damaged op. systems need this to avoid messing with some bytes + f=freopen(savefile,"wb",f); + if(!f) return; + #endif + fwrite(memEE,1,sizeEE,f); + } + else{ //HEX + int valid; + fprintf(f,":020000040000FA\n"); //extended address=0 + for(i=0;i>8)&0xff); + if(base>>16>ext){ + ext=base>>16; + fprintf(f,":02000004%04X%02X\n",ext,(-6-ext)&0xff); + } + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + } + str1[0]=0; + count=sum=0; + } + } + fprintf(f,":00000001FF\n"); + } + } + if(f) fclose(f); +} + +void SaveEE(char* dev,char* savefile){ + FILE* f=fopen(savefile,"w"); + if(!f) return; +//**************** ATMEL ******************************************* + if(!strncmp(dev,"AT",2)){ + char str[512],str1[512]=""; + int i,base; + fprintf(f,":020000040000FA\n"); //extended address=0 + int sum=0,count=0,s; + for(i=0,count=sum=0;ii-count&&memEE[s]>=0xff;s--){ //remove trailing 0xFF + sum-=memEE[s]&0xff; + str1[strlen(str1)-2]=0; + } + count-=i-s; + sum+=count+(base&0xff)+((base>>8)&0xff); + if(count){ + fprintf(f,":%02X%04X00%s%02X\n",count,base&0xFFFF,str1,(-sum)&0xff); + } + str1[0]=0; + count=sum=0; + } + } + fprintf(f,":00000001FF\n"); + } + if(f) fclose(f); +} + +int Load(char*dev,char*loadfile){ + int i,input_address=0,ext_addr=0,sum,valid; + char line[256]; + FILE* f=fopen(loadfile,"r"); + if(!f) return -1; + PrintMessage1("%s :\r\n",loadfile); +//**************** 10-16F ******************************************* + if(!strncmp(dev,"10",2)||!strncmp(dev,"12",2)||!strncmp(dev,"16",2)){ + unsigned char buffer[0x20000],bufferEE[0x1000]; + int sizeM=0; + memset(buffer,0xFF,sizeof(buffer)); + memset(bufferEE,0xFF,sizeof(bufferEE)); + sizeEE=0; + for(;fgets(line,256,f);){ + if(strlen(line)>9&&line[0]==':'){ + int hex_count = htoi(line+1, 2); + if((int)strlen(line)-11sizeW) sizeW=sizeM; + for (i=0;i=0x1E000&&input_address<0x1F000){ //EEPROM + sizeM=(input_address-0x1E000+hex_count)/2; + if(sizeM>sizeEE) sizeEE=sizeM; + for (i=0;i14) ext_addr=htoi(line+9,4); + break; + default: + break; + } + } + } + } + } + sizeW/=2; + if(memCODE_W) free(memCODE_W); + memCODE_W=(WORD*)malloc(sizeof(WORD)*sizeW); + for(i=0;i0x8000?0x8500:0x2100; + DisplayCODE16F(imax); + if(sizeW>=0x2100&&sizeW<0x3000){ //EEPROM@0x2100 + PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n" + DisplayEE16F(0x700); + } + else if(sizeEE) DisplayEE(); + PrintMessage("\r\n"); + } +//**************** 18F ******************************************* + else if(!strncmp(dev,"18F",3)){ + unsigned char buffer[0x30000],bufferEE[0x1000]; + int sizeM; + memset(buffer,0xFF,sizeof(buffer)); + memset(bufferEE,0xFF,sizeof(bufferEE)); + memset(memID,0xFF,sizeof(memID)); + memset(memCONFIG,0xFF,sizeof(memCONFIG)); + for(;fgets(line,256,f);){ + if(strlen(line)>9&&line[0]==':'){ + int hex_count = htoi(line+1, 2); + if((int)strlen(line) - 11 < hex_count * 2) { + PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n" + } + else{ + input_address=htoi(line+3,4); + sum=0; + for (i=1;i<=hex_count*2+9;i+=2) + sum += htoi(line+i,2); + if ((sum & 0xff)!=0) { + PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n" + } + else{ + switch(htoi(line+7,2)){ + case 0: //Data record + if(ext_addr<0x20){ //Code <0x200000 + sizeM=(ext_addr<<16)+input_address+hex_count; + if(sizeM>size) size=sizeM; + for (i=0;isizeEE) sizeEE=sizeM; + + } + break; + case 4: //extended linear address record + if(strlen(line)>14) ext_addr=htoi(line+9,4); + break; + default: + break; + } + } + } + } + } + if(memCODE) free(memCODE); + memCODE=(unsigned char*)malloc(size); + memcpy(memCODE,buffer,size); + if(memEE) free(memEE); + memEE=(unsigned char*)malloc(sizeEE); + memcpy(memEE,bufferEE,sizeEE); + PrintMessage(strings[S_IDMem]); //"ID memory:\r\n" + for(i=0;i<8;i+=2) PrintMessage4("ID%d: 0x%02X ID%d: 0x%02X\r\n",i,memID[i],i+1,memID[i+1]); + PrintMessage(strings[S_ConfigMem]); //"CONFIG memory:\r\n" + for(i=0;i<7;i++){ + PrintMessage2(strings[S_ConfigWordH],i+1,memCONFIG[i*2+1]); //"CONFIG%dH: 0x%02X\t" + PrintMessage2(strings[S_ConfigWordL],i+1,memCONFIG[i*2]); //"CONFIG%dL: 0x%02X\r\n" + } + PrintMessage(strings[S_CodeMem]); //"\r\nCODE memory:\r\n" + DisplayCODE18F(size); + if(sizeEE) DisplayEE(); + PrintMessage("\r\n"); + } +//**************** 24F ******************************************* + else if(!strncmp(dev,"24F",3)||!strncmp(dev,"24H",3)||!strncmp(dev,"24E",3)||!strncmp(dev,"30F",3)||!strncmp(dev,"33F",3)||!strncmp(dev,"33E",3)){ + unsigned char *buffer,bufferEE[0x2000]; + int d; + buffer=(unsigned char*)malloc(0x100000); + memset(buffer,0xFF,0x100000); + memset(bufferEE,0xFF,sizeof(bufferEE)); + memset(memCONFIG,0xFF,sizeof(memCONFIG)); + memset(memUSERID,0xFF,sizeof(memUSERID)); + sizeUSERID=0; + for(;fgets(line,256,f);){ + if(strlen(line)>9&&line[0]==':'){ + int hex_count = htoi(line+1, 2); + if((int)strlen(line) - 11 < hex_count * 2) { + PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n" + } + else{ + input_address=htoi(line+3,4); + sum=0; + for (i=1;i<=hex_count*2+9;i+=2) + sum += htoi(line+i,2); + if ((sum & 0xff)!=0) { + PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n" + } + else{ + switch(htoi(line+7,2)){ + case 0: //Data record + if(ext_addr<0x20){ //Code + int end1=(ext_addr<<16)+input_address+hex_count; + if(size=0xE000){ //EEPROM + for (i=0;i14) ext_addr=htoi(line+9,4); + break; + default: + break; + } + } + } + } + } + if(memCODE) free(memCODE); + memCODE=(unsigned char*)malloc(size); + memcpy(memCODE,buffer,size); + free(buffer); + sizeEE=sizeEE?0x1000:0; + if(memEE) free(memEE); + memEE=(unsigned char*)malloc(sizeEE); + for(i=0;i9&&line[0]==':'){ + int hex_count = htoi(line+1, 2); + if((int)strlen(line) - 11 < hex_count * 2) { + PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n" + } + else{ + input_address=htoi(line+3,4); + sum=0; + for (i=1;i<=hex_count*2+9;i+=2) + sum += htoi(line+i,2); + if ((sum & 0xff)!=0) { + PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n" + } + else{ + switch(htoi(line+7,2)){ + case 0: //Data record + if(ext_addr<0x20){ //Code + size=input_address+hex_count; + for (i=0;i14) ext_addr=htoi(line+9,4); + break; + default: + break; + } + } + } + } + } + if(memCODE) free(memCODE); + memCODE=(unsigned char*)malloc(size); + memcpy(memCODE,buffer,size); + if(size) PrintMessage(strings[S_CodeMem]); //"\r\nmemoria CODICE:\r\n" + DisplayCODEAVR(size); + PrintMessage("\r\n"); + } +//**************** 24xxx / 93xxx / 25xxx / 95xxx / DSxxxx /11xxx ******************************* + else if(!strncmp(dev,"24",2)||!strncmp(dev,"93",2)||!strncmp(dev,"25",2)||!strncmp(dev,"95",2)||\ + !strncmp(dev,"DS",2)||!strncmp(dev,"11",2)){ + if(strstr(loadfile,".bin")||strstr(loadfile,".BIN")){ + #ifdef _WIN32 + //brain-damaged op. systems need this to avoid messing with some bytes + f=freopen(loadfile,"rb",f); + if(!f) return -1; + #endif + fseek(f, 0L, SEEK_END); + sizeEE=ftell(f); + fseek(f, 0L, SEEK_SET); + if(sizeEE>0x1000000) sizeEE=0x1000000; //max 16MB + if(memEE) free(memEE); + memEE=(unsigned char*)malloc(sizeEE); + sizeEE=fread(memEE,1,sizeEE,f); + } + else{ //Hex file + int bufSize=0x40000; //256K + unsigned char *bufferEE=(unsigned char*)malloc(bufSize); + memset(bufferEE,0xFF,bufSize); + for(;fgets(line,256,f);){ + if(strlen(line)>9&&line[0]==':'){ + int hex_count = htoi(line+1, 2); + if((int)strlen(line) - 11 < hex_count * 2) { + PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n" + } + else{ + input_address=htoi(line+3,4); + sum=0; + int end1; + for (i=1;i<=hex_count*2+9;i+=2) sum+=htoi(line+i,2); + if ((sum & 0xff)!=0) { + PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n" + } + else{ + switch(htoi(line+7,2)){ + case 0: //Data record + end1=(ext_addr<<16)+input_address+hex_count; + if(end1>=0x1000000) break; //max 16MB + if(sizeEE14) ext_addr=htoi(line+9,4); + break; + default: + break; + } + } + } + } + } + if(memEE) free(memEE); + memEE=(unsigned char*)malloc(sizeEE); + memcpy(memEE,bufferEE,sizeEE); + free(bufferEE); + } + DisplayEE(); //visualize + int sum=0; + for(i=0;i9&&line[0]==':'){ + int hex_count = htoi(line+1, 2); + if((int)strlen(line) - 11 < hex_count * 2) { + PrintMessage1(strings[S_IhexShort],line); //"Intel hex8 line too short:\r\n%s\r\n" + } + else{ + input_address=htoi(line+3,4); + int sum = 0; + for (i=1;i<=hex_count*2+9;i+=2) sum+=htoi(line+i,2); + if ((sum & 0xff)!=0) { + PrintMessage1(strings[S_IhexChecksum],line); //"Intel hex8 checksum error in line:\r\n%s\r\n" + } + else{ + switch(htoi(line+7,2)){ + case 0: //Data record + if(ext_addr==0&&input_address<0x1000){ //EEPROM + for (i=0;i14) ext_addr=htoi(line+9,4); + break; + default: + break; + } + } + } + } + } + if(memEE) free(memEE); + memEE=(unsigned char*)malloc(sizeEE); + memcpy(memEE,bufferEE,sizeEE); + if(sizeEE) DisplayEE(); //visualize + PrintMessage("\r\n"); + fclose(f); + } +} + +void OpenLogFile() +{ + logfile=fopen(LogFileName,"w"); + if(!logfile) return; + fprintf(logfile,_APPNAME " version %s (%s)\n",VERSION,SYSNAME); + fprintf(logfile,"Firmware version %d.%d.%d\n",FWVersion>>16,(FWVersion>>8)&0xFF,FWVersion&0xFF); + struct tm * timeinfo; + time_t rawtime; + time( &rawtime ); /* Get time as long integer. */ + timeinfo = localtime( &rawtime ); /* Convert to local time. */ + fprintf(logfile,"%s\n", asctime (timeinfo) ); +} + +void CloseLogFile() +{ + if(logfile)fclose(logfile); + logfile=0; +} + +void WriteLogIO() +{ + int i; + //fprintf(logfile,"bufferU=[%02X\n",bufferU[0]); + fprintf(logfile,"bufferU=["); + for(i=0;i