From e23a3e98bf4afc6bc900a427c20c01feac476d1a Mon Sep 17 00:00:00 2001 From: Ian C Date: Mon, 14 Mar 2016 16:24:48 +0000 Subject: Initial code for handling of memory banks. --- src/output.c | 15 +++++-- src/state.c | 138 ++++++++++++++++++++++++++++++++++++++++++----------------- src/state.h | 41 ++++++++++-------- 3 files changed, 134 insertions(+), 60 deletions(-) diff --git a/src/output.c b/src/output.c index 3b1809f..ccad6af 100644 --- a/src/output.c +++ b/src/output.c @@ -193,16 +193,23 @@ CommandStatus OutputSetOption(int opt, int argc, char *argv[], int OutputCode(void) { - int min = GetMinAddressWritten(); - int max = GetMaxAddressWritten(); - const Byte *mem = AddressSpace(); + const MemoryBank *bank = MemoryBanks(); + int min; + int max; + const Byte *mem; - if (max == -1) + 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: diff --git a/src/state.c b/src/state.c index c92811d..32fa6b3 100644 --- a/src/state.c +++ b/src/state.c @@ -31,17 +31,89 @@ #include "expr.h" -/* ---------------------------------------- GLOBALS +/* ---------------------------------------- TYPES AND GLOBALS */ +#define BANK_SIZE 0x10000u + static int pass = 1; static int maxpass = 2; static int pc = 0; -static int size = 0x10000; -static Byte *mem = NULL; -static int minw = 0; -static int maxw = 0; +static unsigned currbank = 0; static WordMode wmode = LSB_Word; +static MemoryBank *bank; +static MemoryBank *current; + +/* ---------------------------------------- PRIVATE +*/ +static void RemoveBanks(void) +{ + while(bank) + { + MemoryBank *t = bank->next; + + free(bank); + bank = t; + } + + current = NULL; + currbank = 0; +} + +static MemoryBank *FindBank(unsigned n) +{ + MemoryBank *t = bank; + + while(t) + { + if (t->number == n) + { + return t; + } + + t = t->next; + } + + return NULL; +} + +static void ClearBankWriteMarkers(void) +{ + MemoryBank *t = bank; + + while(t) + { + t->min_address_used = BANK_SIZE; + t->max_address_used = -1; + t = t->next; + } +} + +static MemoryBank *AddBank(unsigned n) +{ + MemoryBank *t = Malloc(sizeof *t); + + t->min_address_used = BANK_SIZE; + t->max_address_used = -1; + t->number = n; + + t->next = bank; + bank = t; + + return t; +} + +static MemoryBank *GetOrAddBank(unsigned n) +{ + MemoryBank *b = FindBank(n); + + if (!b) + { + b = AddBank(n); + } + + return b; +} /* ---------------------------------------- INTERFACES */ @@ -50,10 +122,9 @@ void ClearState(void) { pass = 1; pc = 0; - minw = size; - maxw = -1; wmode = LSB_Word; - SetAddressSpace(0x10000); + RemoveBanks(); + SetAddressBank(0); } @@ -61,8 +132,7 @@ void NextPass(void) { if (pass < maxpass) { - minw = size; - maxw = -1; + ClearBankWriteMarkers(); pass++; } } @@ -95,12 +165,9 @@ void SetNeededPasses(int n) } -void SetAddressSpace(int s) +void SetAddressBank(unsigned b) { - size = s; - - mem = Malloc(s); - memset(mem, 0, size); + currbank = b; } @@ -128,28 +195,33 @@ void PCAdd(int i) while(pc < 0) { - pc += size; + pc += BANK_SIZE; } - pc %= size; + pc %= BANK_SIZE; } void PCWrite(int i) { - if (pc < minw) + if (!current) + { + current = GetOrAddBank(currbank); + } + + if (pc < current->min_address_used) { - minw = pc; + current->min_address_used = pc; } - if (pc > maxw) + if (pc > current->max_address_used) { - maxw = pc; + current->max_address_used = pc; } - mem[pc] = ExprConvert(8, i); + current->memory[pc] = ExprConvert(8, i); - pc = (pc + 1) % size; + pc = (pc + 1) % BANK_SIZE; } @@ -185,21 +257,9 @@ void PCWriteWordMode(int i, WordMode mode) } -int GetMinAddressWritten(void) -{ - return minw; -} - - -int GetMaxAddressWritten(void) -{ - return maxw; -} - - -const Byte *AddressSpace(void) +const MemoryBank *MemoryBanks(void) { - return mem; + return bank; } @@ -207,9 +267,9 @@ Byte ReadByte(int addr) { Byte b = 0; - if (addr > -1 && addr < size) + if (addr > -1 && addr < BANK_SIZE && current) { - b = mem[addr]; + b = current->memory[addr]; } return b; diff --git a/src/state.h b/src/state.h index 0ebdce5..e10463c 100644 --- a/src/state.h +++ b/src/state.h @@ -19,7 +19,9 @@ ------------------------------------------------------------------------- - Stores assembly state. + Stores assembly state (passes, memory, etc). + + Memory is arranged in banks of RAM of 64K each. */ @@ -28,23 +30,37 @@ /* ---------------------------------------- TYPES */ +#define BANK_SIZE 0x10000u + typedef enum { MSB_Word, LSB_Word } WordMode; + +typedef struct mbnk +{ + 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 */ -/* Clear state to default. This creates 64K of RAM to write into. +/* Clear state to default. This creates 64K of RAM to write into and sets + zero as the current bank. */ void ClearState(void); -/* Sets the number of bytes in RAM. Addressing always starts from zero. +/* Sets the current bank to use. If it's never been used before it will be + initialised as an empty 64K of RAM. */ -void SetAddressSpace(int size); +void SetAddressBank(unsigned bank); /* Move onto the next pass @@ -103,22 +119,13 @@ void PCWriteWord(int i); void PCWriteWordMode(int i, WordMode mode); -/* Get the minimum address written to -*/ -int GetMinAddressWritten(void); - - -/* Get the maximum address written to -*/ -int GetMaxAddressWritten(void); - - -/* Access the address space directly +/* Gets a list of the banks used. A NULL return means no memory was written + to at all. */ -const Byte *AddressSpace(void); +const MemoryBank *MemoryBanks(void); -/* Read a byte from the address space +/* Read a byte from the current bank. */ Byte ReadByte(int addr); -- cgit v1.2.3