aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2016-03-14 16:24:48 +0000
committerIan C <ianc@noddybox.co.uk>2016-03-14 16:24:48 +0000
commite23a3e98bf4afc6bc900a427c20c01feac476d1a (patch)
tree57957cf943e267445724b9339160b9d1890549a4
parent9edfd06f3a609ff6a6c87e3d7bea4e1728eea474 (diff)
Initial code for handling of memory banks.
-rw-r--r--src/output.c15
-rw-r--r--src/state.c138
-rw-r--r--src/state.h41
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);