aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorm8pple <dt10@imperial.ac.uk>2014-10-20 13:30:29 +0100
committerm8pple <dt10@imperial.ac.uk>2014-10-20 13:30:29 +0100
commit3e6cbdeda83c2955b9f40c6995c76cce49cb33d7 (patch)
treed6afa0e2dbe0ce9ef2672c302f8ba168ae2ad4d1 /src
parentfcf1520d54bf62fd419ace371f11e86815503428 (diff)
downloadMipsCPU-3e6cbdeda83c2955b9f40c6995c76cce49cb33d7.tar.gz
MipsCPU-3e6cbdeda83c2955b9f40c6995c76cce49cb33d7.zip
Very basic skeleton from the classes.
Diffstat (limited to 'src')
-rw-r--r--src/eie2ugs/mips_cpu.c85
-rw-r--r--src/eie2ugs/test_mips.cpp47
2 files changed, 132 insertions, 0 deletions
diff --git a/src/eie2ugs/mips_cpu.c b/src/eie2ugs/mips_cpu.c
new file mode 100644
index 0000000..7138bcd
--- /dev/null
+++ b/src/eie2ugs/mips_cpu.c
@@ -0,0 +1,85 @@
+#include "mips.h"
+
+#include <stdlib.h>
+
+struct mips_cpu_impl{
+
+ uint32_t pc;
+ uint32_t pcN;
+ uint32_t regs[32];
+
+ mips_mem_h mem;
+};
+
+mips_cpu_h mips_cpu_create(mips_mem_h mem)
+{
+ unsigned i;
+ mips_cpu_h res=(mips_cpu_h)malloc(sizeof(struct mips_cpu_impl));
+
+ res->mem=mem;
+
+ res->pc=0;
+ res->pcN=4; // NOTE: why does this make sense?
+
+ for( i=0;i<32;i++){
+ res->regs[i]=0;
+ }
+
+ return res;
+}
+
+void mips_cpu_free(mips_cpu_h state)
+{
+ free(state);
+}
+
+mips_error mips_cpu_get_register(
+ mips_cpu_h state, //!< Valid (non-empty) handle to a CPU
+ unsigned index, //!< Index from 0 to 31
+ uint32_t *value //!< Where to write the value to
+)
+{
+ if(state==0)
+ return mips_ErrorInvalidHandle;
+ if(index>=32)
+ return mips_ErrorInvalidArgument;
+ if(value==0)
+ return mips_ErrorInvalidArgument;
+
+ *value = state->regs[index];
+ return mips_Success;
+}
+
+/*! Modifies one of the 32 general purpose MIPS registers. */
+mips_error mips_cpu_set_register(
+ mips_cpu_h state, //!< Valid (non-empty) handle to a CPU
+ unsigned index, //!< Index from 0 to 31
+ uint32_t value //!< New value to write into register file
+)
+{
+ if(state==0)
+ return mips_ErrorInvalidHandle;
+ if(index>=32)
+ return mips_ErrorInvalidArgument;
+
+ // TODO : What about register zero?
+ state->regs[index]=value;
+
+ return mips_Success;
+}
+
+mips_error mips_cpu_step(mips_cpu_h state)
+{
+ uint32_t pc=state->pc;
+
+ if(state==0)
+ return mips_ErrorInvalidHandle;
+
+ //TODO: Here is where the magic happens
+ // - Fetch the instruction from memory (mips_mem_read)
+ // - Decode the instruction (is it R, I, J)?
+ // - Execute the instruction (do maths, access memory, ...)
+ // - Writeback the results (update registers, advance pc)
+
+ return mips_ErrorNotImplemented;
+}
diff --git a/src/eie2ugs/test_mips.cpp b/src/eie2ugs/test_mips.cpp
new file mode 100644
index 0000000..e9a6955
--- /dev/null
+++ b/src/eie2ugs/test_mips.cpp
@@ -0,0 +1,47 @@
+#include "mips_test.h"
+
+int main()
+{
+ mips_mem_h mem=mips_mem_create_ram(
+ 1<<20,
+ 4
+ );
+
+ mips_cpu_h cpu=mips_cpu_create(mem);
+
+ mips_test_begin_suite();
+
+ int testId=mips_test_begin_test("and");
+ int passed=0;
+
+
+ mips_error err = mips_cpu_set_register(cpu, 8, 0x0000FFFFul);
+ if(err==0)
+ err = mips_cpu_set_register(cpu, 9, 0x00FFFF00ul);
+
+ // and $10, $8, $9
+
+ // TODO : work out the bit-wise encoding for the instruction.
+
+ // TODO : Write it into mempory at a known address
+
+ // TODO : Make sure the program-counter is at that address
+
+ if(err==0)
+ err=mips_cpu_step(cpu);
+
+ uint32_t got;
+ if(err==0)
+ err = (mips_error)(err | mips_cpu_get_register(cpu, 10, &got));
+
+ passed = (err == mips_Success) && (got==0x0000FF00);
+
+ mips_test_end_test(testId, passed, NULL);
+
+ mips_test_end_suite();
+
+ mips_cpu_free(cpu);
+ mips_mem_free(mem);
+
+ return 0;
+} \ No newline at end of file