/* 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 . ------------------------------------------------------------------------- Spectrum TAP file output handler. */ #include #include #include "global.h" #include "specout.h" /* ---------------------------------------- PRIVATE FUNCTIONS */ static Byte TapByte(FILE *fp, Byte b, Byte chk) { chk ^= b; putc(b, fp); return chk; } static Byte TapWord(FILE *fp, int w, Byte chk) { chk = TapByte(fp, w & 0xff, chk); chk = TapByte(fp, (w & 0xff00) >> 8, chk); return chk; } static Byte TapString(FILE *fp, const char *p, int len, Byte chk) { while(len--) { chk = TapByte(fp, *p ? *p++ : ' ', chk); } return chk; } /* ---------------------------------------- INTERFACES */ const ValueTable *SpecTAPOutputOptions(void) { return NULL; } CommandStatus SpecTAPOutputSetOption(int opt, int argc, char *argv[], int quoted[], char *error, size_t error_size) { return CMD_NOT_KNOWN; } int SpecTAPOutput(const char *filename, const char *filename_bank, MemoryBank **bank, int count, char *error, size_t error_size) { FILE *fp = fopen(filename, "wb"); int f; if (!fp) { snprintf(error, error_size, "Failed to create %s", filename); return FALSE; } for(f = 0; f < count; f++) { Byte chk = 0; 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; TapWord(fp, 19, 0); chk = TapByte(fp, 0, chk); chk = TapByte(fp, 3, chk); if (count == 1) { chk = TapString(fp, filename, 10, chk); } else { char fn[16]; snprintf(fn, sizeof fn, filename_bank, bank[f]->number); chk = TapString(fp, fn, 10, chk); } chk = TapWord(fp, len, chk); chk = TapWord(fp, min, chk); chk = TapWord(fp, 32768, chk); TapByte(fp, chk, 0); /* Output file data */ TapWord(fp, len + 2, 0); chk = 0; chk = TapByte(fp, 0xff, chk); while(min <= max) { chk = TapByte(fp, mem[min], chk); min++; } TapByte(fp, chk, 0); } fclose(fp); return TRUE; } /* vim: ai sw=4 ts=8 expandtab */