From 4564c7906be89463b8f9637685e1785dd900f4b3 Mon Sep 17 00:00:00 2001 From: Ian C Date: Wed, 16 Mar 2016 11:31:21 +0000 Subject: Updated banking to work with output. --- src/casm.c | 23 +++++++++++++ src/output.c | 111 ++++++++++++++++++++++++++++++++++++++--------------------- src/state.c | 68 ++++++++++++++++++++++-------------- src/state.h | 13 ++++--- 4 files changed, 144 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/casm.c b/src/casm.c index 9f685f8..1340eb7 100644 --- a/src/casm.c +++ b/src/casm.c @@ -139,6 +139,27 @@ static CommandStatus ORG(const char *label, int argc, char *argv[], LabelSet(label, result, ANY_LABEL); } + /* See if an optional bank was supplied + */ + if (argc > 2) + { + CMD_EXPR(argv[2], result); + SetAddressBank(result); + } + + return CMD_OK; +} + +static CommandStatus BANK(const char *label, int argc, char *argv[], + int quoted[], char *err, size_t errsize) +{ + int result; + + CMD_ARGC_CHECK(2); + CMD_EXPR(argv[1], result); + + SetAddressBank(result); + return CMD_OK; } @@ -410,6 +431,8 @@ static struct {".eq", EQU}, {"org", ORG}, {".org", ORG}, + {"bank", BANK}, + {".bank", BANK}, {"ds", DS}, {".ds", DS}, {"defs", DS}, diff --git a/src/output.c b/src/output.c index ccad6af..13a7809 100644 --- a/src/output.c +++ b/src/output.c @@ -65,20 +65,43 @@ static ValueTable format_table[] = /* ---------------------------------------- PRIVATE FUNCTIONS */ -static int OutputRawBinary(const Byte *mem, int min, int max) +static int OutputRawBinary(MemoryBank **bank, int count) { - FILE *fp = fopen(output, "wb"); + char buff[4096]; + int f; - if (!fp) + for(f = 0; f < count; f++) { - snprintf(error, sizeof error,"Failed to open %s\n", output); - return FALSE; + FILE *fp; + const char *name; + const Byte *mem; + int min, max; + + if (count == 1) + { + name = output; + } + else + { + snprintf(buff, sizeof buff, "%s.%u", output, bank[f]->number); + name = buff; + } + + if (!(fp = fopen(name, "wb"))) + { + snprintf(error, sizeof error,"Failed to open %s\n", name); + return FALSE; + } + + mem = bank[f]->memory; + min = bank[f]->min_address_used; + max = bank[f]->max_address_used; + + fwrite(mem + min, 1, max - min + 1, fp); + + fclose(fp); } - fwrite(mem + min, 1, max - min + 1, fp); - - fclose(fp); - return TRUE; } @@ -110,11 +133,10 @@ static Byte TapString(FILE *fp, const char *p, int len, Byte chk) } -static int OutputSpectrumTap(const Byte *mem, int min, int max) +static int OutputSpectrumTap(MemoryBank **bank, int count) { FILE *fp = fopen(output, "wb"); - Byte chk = 0; - int len = max - min + 1; + int f; if (!fp) { @@ -124,32 +146,44 @@ static int OutputSpectrumTap(const Byte *mem, int min, int max) /* Output header */ - TapWord(fp, 19, 0); + for(f = 0; f < count; f++) + { + Byte chk = 0; + const Byte *mem; + int min, max, len; - chk = TapByte(fp, 0, chk); - chk = TapByte(fp, 3, chk); - chk = TapString(fp, output, 10, chk); - chk = TapWord(fp, len, chk); - chk = TapWord(fp, min, chk); - chk = TapWord(fp, 32768, chk); + mem = bank[f]->memory; + min = bank[f]->min_address_used; + max = bank[f]->max_address_used; + len = max - min + 1; - TapByte(fp, chk, 0); + TapWord(fp, 19, 0); - /* Output file data - */ - TapWord(fp, len + 2, 0); + chk = TapByte(fp, 0, chk); + chk = TapByte(fp, 3, chk); + chk = TapString(fp, output, 10, chk); + chk = TapWord(fp, len, chk); + chk = TapWord(fp, min, chk); + chk = TapWord(fp, 32768, chk); - chk = 0; + TapByte(fp, chk, 0); - chk = TapByte(fp, 0xff, chk); + /* Output file data + */ + TapWord(fp, len + 2, 0); - while(min <= max) - { - chk = TapByte(fp, mem[min], chk); - min++; - } + chk = 0; + + chk = TapByte(fp, 0xff, chk); + + while(min <= max) + { + chk = TapByte(fp, mem[min], chk); + min++; + } - TapByte(fp, chk, 0); + TapByte(fp, chk, 0); + } fclose(fp); @@ -193,30 +227,27 @@ CommandStatus OutputSetOption(int opt, int argc, char *argv[], int OutputCode(void) { - const MemoryBank *bank = MemoryBanks(); + MemoryBank **bank; + int count; int min; int max; const Byte *mem; + bank = MemoryBanks(&count); + if (!bank) { fprintf(stderr, "Skipping output; no written memory to write\n"); return TRUE; } - /* TODO: Fix to pass banks proper - */ - min = bank[0].min_address_used; - max = bank[0].max_address_used; - mem = bank[0].memory; - switch(format) { case Raw: - return OutputRawBinary(mem, min, max); + return OutputRawBinary(bank, count); case SpectrumTap: - return OutputSpectrumTap(mem, min, max); + return OutputSpectrumTap(bank, count); default: break; diff --git a/src/state.c b/src/state.c index 32fa6b3..27225e5 100644 --- a/src/state.c +++ b/src/state.c @@ -38,40 +38,50 @@ static int pass = 1; static int maxpass = 2; static int pc = 0; +static int num_banks = 0; static unsigned currbank = 0; static WordMode wmode = LSB_Word; -static MemoryBank *bank; +static MemoryBank **bank; static MemoryBank *current; /* ---------------------------------------- PRIVATE */ +static int SortBank(const void *a, const void *b) +{ + const MemoryBank *ma = a; + const MemoryBank *mb = b; + + return (int)ma->number - (int)mb->number; +} + + static void RemoveBanks(void) { - while(bank) - { - MemoryBank *t = bank->next; + int f; - free(bank); - bank = t; + for(f = 0; f < num_banks; f++) + { + free(bank[f]); } - current = NULL; + free(bank); + currbank = 0; + bank = NULL; + current = NULL; } static MemoryBank *FindBank(unsigned n) { - MemoryBank *t = bank; + int f; - while(t) + for(f = 0; f < num_banks; f++) { - if (t->number == n) + if (bank[f]->number == n) { - return t; + return bank[f]; } - - t = t->next; } return NULL; @@ -79,28 +89,27 @@ static MemoryBank *FindBank(unsigned n) static void ClearBankWriteMarkers(void) { - MemoryBank *t = bank; + int f; - while(t) + for(f = 0; f < num_banks; f++) { - t->min_address_used = BANK_SIZE; - t->max_address_used = -1; - t = t->next; + bank[f]->min_address_used = BANK_SIZE; + bank[f]->max_address_used = -1; } } static MemoryBank *AddBank(unsigned n) { - MemoryBank *t = Malloc(sizeof *t); + current = NULL; + num_banks++; - t->min_address_used = BANK_SIZE; - t->max_address_used = -1; - t->number = n; + bank = Realloc(bank, (sizeof *bank) * num_banks); + bank[num_banks-1] = Malloc(sizeof **bank); + bank[num_banks-1]->number = n; - t->next = bank; - bank = t; + qsort(bank, num_banks, sizeof *bank, SortBank); - return t; + return FindBank(n); } static MemoryBank *GetOrAddBank(unsigned n) @@ -168,6 +177,7 @@ void SetNeededPasses(int n) void SetAddressBank(unsigned b) { currbank = b; + current = NULL; } @@ -257,8 +267,9 @@ void PCWriteWordMode(int i, WordMode mode) } -const MemoryBank *MemoryBanks(void) +MemoryBank **MemoryBanks(int *count) { + *count = num_banks; return bank; } @@ -267,6 +278,11 @@ Byte ReadByte(int addr) { Byte b = 0; + if (!current) + { + current = GetOrAddBank(currbank); + } + if (addr > -1 && addr < BANK_SIZE && current) { b = current->memory[addr]; diff --git a/src/state.h b/src/state.h index e10463c..247124f 100644 --- a/src/state.h +++ b/src/state.h @@ -39,13 +39,12 @@ typedef enum } WordMode; -typedef struct mbnk +typedef struct { unsigned number; /* The bank number, 0 .. n */ Byte memory[BANK_SIZE]; /* The memory in that bank */ int min_address_used; /* Will be BANK_SIZE if not used */ int max_address_used; /* Will be -1 if not used */ - struct mbnk *next; /* The next memory bank */ } MemoryBank; /* ---------------------------------------- INTERFACES @@ -119,10 +118,14 @@ void PCWriteWord(int i); void PCWriteWordMode(int i, WordMode mode); -/* Gets a list of the banks used. A NULL return means no memory was written - to at all. +/* Gets a list of the banks used as an array of pointers. A NULL return means + no memory was written to at all. + + *count will be updated with the number of banks used, or zero if no memory + was written to. Note that banks may not be contiguously numbered, but will + be in ascending order. */ -const MemoryBank *MemoryBanks(void); +MemoryBank **MemoryBanks(int *count); /* Read a byte from the current bank. -- cgit v1.2.3