From 3e6cbdeda83c2955b9f40c6995c76cce49cb33d7 Mon Sep 17 00:00:00 2001 From: m8pple Date: Mon, 20 Oct 2014 13:30:29 +0100 Subject: Very basic skeleton from the classes. --- src/eie2ugs/mips_cpu.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++ src/eie2ugs/test_mips.cpp | 47 ++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/eie2ugs/mips_cpu.c create mode 100644 src/eie2ugs/test_mips.cpp 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 + +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 -- cgit