/* casm - Simple, portable assembler Copyright (C) 2003-2015 Ian Cowburn (ianc@noddybox.co.uk) 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 3 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, see . ------------------------------------------------------------------------- LIB binary file output */ #include #include #include #include "global.h" #include "libout.h" #include "label.h" /* Magic value for library file */ #define CASM_LIBRARY_MAGIC "CASMLIBv1%" #define CASM_LIBRARY_MAGIC_LEN 10 /* ---------------------------------------- PRIVATE INTERFACES */ static void WriteNumber(FILE *fp, int num) { fprintf(fp, "%.11d", num); } static int ReadNumber(FILE *fp) { char buff[12]; int f; for(f= 0 ;f < 11; f++) { buff[f] = getc(fp); } buff[f] = 0; return atoi(buff); } /* ---------------------------------------- INTERFACES */ const ValueTable *LibOutputOptions(void) { return NULL; } CommandStatus LibOutputSetOption(int opt, int argc, char *argv[], int quoted[], char *error, size_t error_size) { return CMD_NOT_KNOWN; } int LibOutput(const char *filename, const char *filename_bank, MemoryBank **bank, int count, char *error, size_t error_size) { FILE *fp; char buff[4096]; int f; if (!(fp = fopen(filename, "wb"))) { snprintf(error, error_size, "Failed to open %s", filename); return FALSE; } fwrite(CASM_LIBRARY_MAGIC, 1, CASM_LIBRARY_MAGIC_LEN, fp); WriteNumber(fp, count); for(f = 0; f < count; f++) { const Byte *mem; int min, max, len; mem = bank[f]->memory; min = bank[f]->min_address_used; max = bank[f]->max_address_used; len = max - min + 1; WriteNumber(fp, (int)bank[f]->number); WriteNumber(fp, min); WriteNumber(fp, len); fwrite(mem + min, 1, len, fp); } LabelWriteBlob(fp); fclose(fp); return TRUE; } int LibLoad(const char *filename, LibLoadOption opt, int offset, char *error, size_t error_size) { char magic[CASM_LIBRARY_MAGIC_LEN + 1] = {0}; FILE *fp; Byte buff[0x10000]; int count; int f; if (!(fp = fopen(filename, "rb"))) { snprintf(error, error_size, "Failed to open %s", filename); return FALSE; } fread(magic, 1, CASM_LIBRARY_MAGIC_LEN, fp); if (strcmp(magic, CASM_LIBRARY_MAGIC) != 0) { snprintf(error, error_size, "%s not a recognised library", filename); fclose(fp); return FALSE; } count = ReadNumber(fp); for(f = 0; f < count; f++) { int bank; int min; int len; int old_pc; unsigned old_bank; Byte *p; old_bank = Bank(); old_pc = PC(); bank = ReadNumber(fp); min = ReadNumber(fp); len = ReadNumber(fp); SetAddressBank(bank); fread(buff, 1, len, fp); SetPC((min + offset)); p = buff; if (opt != LibLoadLabels) { while(len-- > 0) { PCWrite(*p++); } } SetPC(old_pc); SetAddressBank(old_bank); } if (opt != LibLoadMemory) { LabelReadBlob(fp, offset); } fclose(fp); return TRUE; } /* vim: ai sw=4 ts=8 expandtab */