/* ** This file is part of fsusb_picdem ** ** fsusb_picdem 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. ** ** fsusb_picdem 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 fsusb_picdem; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ** 02110-1301, USA */ #include "memimg.h" #include #include #include /* mi_make_patch: Allocate and initialize a mi_patch */ mi_patch *mi_make_patch(unsigned long base, unsigned long top) { mi_patch *pat; pat=malloc(sizeof(mi_patch)); if(pat == NULL) { return NULL; } pat->base=base; pat->top=top; pat->contents=malloc(sizeof(mi_byte_t)*(top-base)); if(pat->contents == NULL) { free(pat); return NULL; } memset(pat->contents, 0xff, sizeof(mi_byte_t)*(top-base)); pat->mask=malloc(sizeof(char)*(top-base)); if(pat->mask == NULL) { free(pat->contents); free(pat); return NULL; } memset(pat->mask, 0, sizeof(char)*(top-base)); return pat; } /* mi_free_patch: Free a mi_patch and its buffers */ void mi_free_patch(mi_patch *p) { if(p == NULL) { return; } free(p->contents); free(p->mask); free(p); } /* mi_free_image: Free a mi_patch and its contents */ void mi_free_image(mi_image *i) { if(i == NULL) { return; } mi_free_patch(i->program); mi_free_patch(i->id); mi_free_patch(i->config); mi_free_patch(i->devid); mi_free_patch(i->eeprom); free(i); } /* mi_modify_patch: Modify patch contents, tagging it as changed */ void mi_modify_patch(mi_patch *p, int base, int len, mi_byte_t *data) { int i; if(p == NULL) { return; } if(basebase || base+len-1 > p->top) { printf("*** mi_modify_patch(): patch out of range\n"); return; } for(i=0;icontents[base - p->base + i]=data[i]; p->mask[base - p->base + i]=0xff; } } /* mi_image: Create a mi_image from the contents of filename */ mi_image *mi_load_hexfile(char *filename) { mi_image *img; hex_record *r; FILE *f; hex_file *hf; if(filename == NULL) { return NULL; } f=fopen(filename, "r"); if(f == NULL) { return NULL; } hf=hex_open(f); if(hf == NULL) { fclose(f); return NULL; } img=malloc(sizeof(mi_image)); if(img == NULL) { fclose(f); free(hf); return NULL; } /* These nulls may not be required, but make me feel safer when * using free_image() on an error */ img->program = NULL; img->id = NULL; img->config = NULL; img->devid = NULL; img->eeprom = NULL; img->program=mi_make_patch(MI_PROGRAM_BASE, MI_PROGRAM_TOP); img->id=mi_make_patch(MI_ID_BASE, MI_ID_TOP); img->config=mi_make_patch(MI_CONFIG_BASE, MI_CONFIG_TOP); img->devid=mi_make_patch(MI_DEVID_BASE, MI_DEVID_TOP); img->eeprom=mi_make_patch(MI_EEPROM_BASE, MI_EEPROM_TOP); if(img->program == NULL || img->id == NULL || img->config == NULL || img->devid == NULL || img->eeprom == NULL) { fclose(f); free(hf); mi_free_image(img); return NULL; } while((r=hex_read(hf))) { if(r->type == 0) { /* printf("file: %.2i@0x%.8X:\t", r->datlen, r->addr); for(i=0;idatlen;i++) { printf("%.2x", r->data[i]); } printf("\n"); */ if(r->addr >= MI_PROGRAM_BASE && r->addr <= MI_PROGRAM_TOP) { // printf("Program memory\n"); mi_modify_patch(img->program, r->addr, r->datlen, r->data); } if(r->addr >= MI_ID_BASE && r->addr <= MI_ID_TOP) { // printf("ID memory\n"); mi_modify_patch(img->id, r->addr, r->datlen, r->data); } if(r->addr >= MI_CONFIG_BASE && r->addr <= MI_CONFIG_TOP) { // printf("Config memory\n"); mi_modify_patch(img->config, r->addr, r->datlen, r->data); } if(r->addr >= MI_DEVID_BASE && r->addr <= MI_DEVID_TOP) { // printf("Devid memory\n"); mi_modify_patch(img->devid, r->addr, r->datlen, r->data); } } free(r); // printf("\n"); } free(hf); fclose(f); return img; }