From 4bf4be55566440d9c08a48a38759f302b2d4cb02 Mon Sep 17 00:00:00 2001 From: Ian C Date: Thu, 22 Dec 2016 13:47:51 +0000 Subject: First stab at CPC TAPE file. --- src/cpcout.c | 168 ++++++++++++++++++--------------------------------- src/example/Makefile | 4 +- src/example/cpc.asm | 4 +- src/example/cpc.cdt | Bin 34915 -> 0 bytes 4 files changed, 62 insertions(+), 114 deletions(-) delete mode 100644 src/example/cpc.cdt diff --git a/src/cpcout.c b/src/cpcout.c index 6dbafc1..659ba28 100644 --- a/src/cpcout.c +++ b/src/cpcout.c @@ -35,6 +35,8 @@ /* ---------------------------------------- MACROS & TYPES */ +#define BLOCK_SIZE 2048 + enum option_t { OPT_START_ADDR, @@ -55,32 +57,6 @@ static Options options = {-1}; /* ---------------------------------------- PRIVATE FUNCTIONS */ - -static int PokeB(Byte *mem, int addr, Byte b) -{ - mem[addr++] = b; - return (addr % 0x10000); -} - - -static int PokeW(Byte *mem, int addr, int w) -{ - addr = PokeB(mem, addr, w & 0xff); - return PokeB(mem, addr, (w & 0xff00) >> 8); -} - - -static int PokeS(Byte *mem, int addr, const char *str) -{ - while(*str) - { - addr = PokeB(mem, addr, CodeFromNative(CP_ASCII, *str++)); - } - - return addr; -} - - static void WriteByte(FILE *fp, Byte b) { putc(b, fp); @@ -148,7 +124,6 @@ int CPCOutput(const char *filename, const char *filename_bank, { FILE *fp = fopen(filename, "wb"); int f; - int offset; if (!fp) { @@ -156,111 +131,85 @@ int CPCOutput(const char *filename, const char *filename_bank, return FALSE; } - /* Write signature - */ - WriteString(fp, "C64 tape image file", 32, 0, CP_ASCII); - - /* Write directory header + /* First get the initial address is none defined */ - WriteWord(fp, 0x200); - WriteWord(fp, count); - WriteWord(fp, count); - WriteString(fp, filename, 24, ' ', CP_ASCII); - - /* Offset to tape data - */ - offset = 64 + 32 * count; + if (options.start_addr == -1) + { + options.start_addr = bank[0]->min_address_used; + } - /* Write directory entries + /* Output the binary files */ for(f = 0; f < count; f++) { - int min, max, len; + const Byte *mem; + int min, max, len, blocks, addr; + int block, blocklen; + mem = bank[f]->memory; min = bank[f]->min_address_used; + addr = min; max = bank[f]->max_address_used; - - /* If this is the first bank, we're going to prepend some BASIC - */ - if (f == 0) - { - if (min < 0x810) - { - snprintf(error, error_size, "First bank starts below a safe " - "area to add BASIC loader"); - - return FALSE; - } - - min = 0x801; /* Start of BASIC */ - } - len = max - min + 1; + blocks = len / BLOCK_SIZE; - WriteByte(fp, 1); - WriteByte(fp, 0x82); - WriteWord(fp, min); - WriteWord(fp, max + 1); - WriteLong(fp, offset); - - if (count == 1) - { - WriteString(fp, filename, 16, ' ', CP_CBM); - } - else + for(block = 0; block <= blocks; block++) { - char fn[16]; + int first, last; - snprintf(fn, sizeof fn, filename_bank, bank[f]->number); - WriteString(fp, fn, 16, ' ', CP_CBM); - } + first = 0; + last = 0; - /* +2 is to include the 2-byte PRG header - offset += len + 2; - */ - offset += len; - } + WriteWord(fp, 0x1d); + WriteByte(fp, 0x2c); - /* Write actual contents - */ - for(f = 0; f < count; f++) - { - Byte *mem; - int min, max, len; - - mem = bank[f]->memory; + if (f == 0) + { + WriteString(fp, filename, 16, 0, CP_ASCII); + } + else + { + char fn[16]; - min = bank[f]->min_address_used; - max = bank[f]->max_address_used; + snprintf(fn, sizeof fn, filename_bank, bank[f]->number); + WriteString(fp, fn, 16, 0, CP_ASCII); + } - /* If this is the first bank, we're going to prepend some BASIC. - Note that output drivers are allowed to manipulate memory directly. - */ - if (f == 0) - { - char sys[16]; - int a = 0x803; - int next; + WriteByte(fp, block+1); - snprintf(sys, sizeof sys, "%u", min); + if (block == 0) + { + first = 255; + blocklen = BLOCK_SIZE; + } - a = PokeW(mem, a, 10); - a = PokeB(mem, a, 0x9e); - a = PokeS(mem, a, sys); - a = PokeB(mem, a, 0x00); + if (block == blocks) + { + last = 255; + blocklen = len % BLOCK_SIZE; + } - next = a; + WriteByte(fp, last); + WriteByte(fp, 2); + WriteWord(fp, blocklen); + WriteWord(fp, addr); + WriteByte(fp, first); + WriteWord(fp, len); + WriteWord(fp, options.start_addr); - a = PokeW(mem, a, 0x00); + addr += blocklen; - PokeW(mem, 0x801, next); + /* Output file data + */ + WriteWord(fp, blocklen + 3); + WriteByte(fp, 0x16); - min = 0x801; + while(min < addr) + { + WriteByte(fp, mem[min]); + min++; + } } - - len = max - min + 1; - - fwrite(mem + min, len, 1, fp); } fclose(fp); @@ -268,7 +217,6 @@ int CPCOutput(const char *filename, const char *filename_bank, return TRUE; } - /* vim: ai sw=4 ts=8 expandtab */ diff --git a/src/example/Makefile b/src/example/Makefile index a1807a2..8bf1992 100644 --- a/src/example/Makefile +++ b/src/example/Makefile @@ -20,7 +20,7 @@ # Makefile for examples # -ALL = spectrum.tap c64.t64 zx81.p gb.gb vcs.bin snes.sfc nes.nes cpc.cdt +ALL = spectrum.tap c64.t64 zx81.p gb.gb vcs.bin snes.sfc nes.nes cpc.tap CASM = ../casm all: $(ALL) $(CASM) @@ -36,7 +36,7 @@ spectrum.tap: spectrum.asm $(CASM) c64.t64: c64.asm $(CASM) $(CASM) c64.asm -cpc.cdt: cpc.asm +cpc.tap: cpc.asm $(CASM) cpc.asm zx81.p: zx81.asm $(CASM) diff --git a/src/example/cpc.asm b/src/example/cpc.asm index 1490cf9..aa9fcb0 100644 --- a/src/example/cpc.asm +++ b/src/example/cpc.asm @@ -4,7 +4,7 @@ ; ; RUN "" - option output-file,cpc.cdt + option output-file,cpc.tap option output-format,cpc option cpc-start,start @@ -18,5 +18,5 @@ loop: inc hl jr loop -msg: org $9000 +msg: org $8800 defb "Hello World",0 diff --git a/src/example/cpc.cdt b/src/example/cpc.cdt deleted file mode 100644 index 06bbcc0..0000000 Binary files a/src/example/cpc.cdt and /dev/null differ -- cgit v1.2.3