aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Thomas <m8pple@github.com>2016-10-10 06:27:37 +0100
committerDavid Thomas <m8pple@github.com>2016-10-10 06:27:37 +0100
commit0673cc3651b60203b90eccdc1c5af5e455f4b6fb (patch)
tree6c50f8b4387ebda2c647b8e7bd66d60884d1e557 /src
parent969874832d55c00c1c5874ef5ae1fdb82b3ded83 (diff)
downloadMipsCPU-0673cc3651b60203b90eccdc1c5af5e455f4b6fb.tar.gz
MipsCPU-0673cc3651b60203b90eccdc1c5af5e455f4b6fb.zip
Updated for 2016.
Diffstat (limited to 'src')
-rw-r--r--src/eie2ugs/mips_cpu.cpp128
-rw-r--r--src/eie2ugs/test_mips.cpp131
-rw-r--r--src/shared/mips_mem_ram.cpp19
3 files changed, 11 insertions, 267 deletions
diff --git a/src/eie2ugs/mips_cpu.cpp b/src/eie2ugs/mips_cpu.cpp
deleted file mode 100644
index 475977e..0000000
--- a/src/eie2ugs/mips_cpu.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "mips.h"
-
-struct mips_cpu_impl
-{
- uint32_t pc;
- uint32_t pcNext;
-
- uint32_t regs[32];
-
- mips_mem_h mem;
-
- unsigned logLevel;
- FILE *logDst;
-};
-
-
-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
-)
-{
- // TODO : error handling
- *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
-)
-{
- // TODO : error handling
- state->regs[index] = value;
- return mips_Success;
-}
-
-mips_error mips_cpu_set_debug_level(mips_cpu_h state, unsigned level, FILE *dest)
-{
- state->logLevel = level;
- state->logDst = dest;
- return mips_Success;
-}
-
-mips_cpu_h mips_cpu_create(mips_mem_h mem)
-{
- mips_cpu_impl *cpu=new mips_cpu_impl;
-
- cpu->pc=0;
- for(int i=0;i<32;i++){
- cpu->regs[i]=0;
- }
- cpu->mem=mem;
-
- return cpu;
-}
-
-/*! \param pData Array of 4 bytes
- \retval The big-endian equivlent
-*/
-uint32_t to_big(const uint8_t *pData)
-{
- return
- (((uint32_t)pData[0])<<24)
- |
- (((uint32_t)pData[1])<<16)
- |
- (((uint32_t)pData[2])<<8)
- |
- (((uint32_t)pData[3])<<0);
-}
-
-mips_error mips_cpu_step(
- mips_cpu_h state //! Valid (non-empty) handle to a CPU
-)
-{
- uint8_t buffer[4];
-
- mips_error err=mips_mem_read(
- state->mem, //!< Handle to target memory
- state->pc, //!< Byte address to start transaction at
- 4, //!< Number of bytes to transfer
- buffer //!< Receives the target bytes
- );
-
- if(err!=0){
- return err;
- }
-
- uint32_t instruction= to_big(buffer);
-
- uint32_t opcode = (instruction>>26) & 0x3F;
- uint32_t src1 = (instruction>> 21 ) & 0x1F;
- uint32_t src2 = (instruction>> 16 ) & 0x1F;
- uint32_t dst = (instruction>> 11 ) & 0x1F;
- uint32_t shift = (instruction>> 6 ) & 0x1F ;
- uint32_t function = (instruction>> 0 ) & 0x3F ;
-
- if(opcode == 0){
- // This is R-type
- if(state->logLevel >= 2){
- fprintf(state->logDst, "R-Type : dst=%u, src1=%u, src2=%u, shift=%u, function=%u.\n instr=%08x\n",
- dst, src1, src2, shift, function, instruction
- );
- }
-
- if(function == 0x21){
- if(state->logLevel >= 1){
- fprintf(state->logDst, "addu %u, %u, %u.\n", dst, src1, src2);
- }
- uint32_t va=state->regs[src1];
- uint32_t vb=state->regs[src2];
-
- uint32_t res=va+vb;
-
- state->regs[dst] = res; // NOTE: what about zero reg?
-
- // NOTE : What about updating the program counter
- return mips_Success;
- }else{
- return mips_ErrorNotImplemented;
- }
- }else{
- return mips_ErrorNotImplemented;
- }
-}
diff --git a/src/eie2ugs/test_mips.cpp b/src/eie2ugs/test_mips.cpp
deleted file mode 100644
index 26db856..0000000
--- a/src/eie2ugs/test_mips.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#include "mips.h"
-
-int main()
-{
- mips_mem_h mem=mips_mem_create_ram(4096, 4);
-
- mips_cpu_h cpu=mips_cpu_create(mem);
-
- mips_error e=mips_cpu_set_debug_level(cpu, 4, stderr);
- if(e!=mips_Success){
- fprintf(stderr, "mips_cpu_set_debug_level : failed.\n");
- exit(1);
- }
-
-
- mips_test_begin_suite();
-
-
- int testId = mips_test_begin_test("addu");
-
- // 1 - Setup an instruction in ram
- // addu r3, r4, r5
- uint32_t instr =
- (0ul << 26) // opcode = 0
- |
- (4ul << 21) // srca = r4
- |
- (5ul << 16) // srcb = r5
- |
- (3ul << 11) // dst = r3
- |
- (0ul << 6) // shift = 0
- |
- (0x21 << 0);
-
- uint8_t buffer[4];
- buffer[0]=(instr>>24)&0xFF;
- buffer[1]=(instr>>16)&0xFF;
- buffer[2]=(instr>>8)&0xFF;
- buffer[3]=(instr>>0)&0xFF;
-
- e=mips_mem_write(
- mem, //!< Handle to target memory
- 0, //!< Byte address to start transaction at
- 4, //!< Number of bytes to transfer
- buffer //!< Receives the target bytes
- );
- if(e!=mips_Success){
- fprintf(stderr, "mips_mem_write : failed.\n");
- exit(1);
- }
-
- // 2 - put register values in cpu
- e=mips_cpu_set_register(cpu, 4, 40);
- e=mips_cpu_set_register(cpu, 5, 50);
-
- // 3 - step CPU
- e=mips_cpu_step(cpu);
- if(e!=mips_Success){
- fprintf(stderr, "mips_cpu_step : failed.\n");
- exit(1);
- }
-
- // 4 -Check the result
- uint32_t got;
- e=mips_cpu_get_register(cpu, 3, &got);
-
-
- int passed = got == 40+50;
-
- mips_test_end_test(testId, passed, "50 + 50 != 90");
-
-
- testId = mips_test_begin_test("addu");
-
- // 1 - Setup an instruction in ram
- // addu r3, r4, r5
- instr =
- (0ul << 26) // opcode = 0
- |
- (4ul << 21) // srca = r4
- |
- (5ul << 16) // srcb = r5
- |
- (0ul << 11) // dst = r0
- |
- (0ul << 6) // shift = 0
- |
- (0x21 << 0);
-
- buffer[0]=(instr>>24)&0xFF;
- buffer[1]=(instr>>16)&0xFF;
- buffer[2]=(instr>>8)&0xFF;
- buffer[3]=(instr>>0)&0xFF;
-
- e=mips_mem_write(
- mem, //!< Handle to target memory
- 0, //!< Byte address to start transaction at
- 4, //!< Number of bytes to transfer
- buffer //!< Receives the target bytes
- );
- if(e!=mips_Success){
- fprintf(stderr, "mips_mem_write : failed.\n");
- exit(1);
- }
-
- // 2 - put register values in cpu
- e=mips_cpu_set_register(cpu, 4, 40);
- e=mips_cpu_set_register(cpu, 5, 50);
-
- // 3 - step CPU
- e=mips_cpu_step(cpu);
- if(e!=mips_Success){
- fprintf(stderr, "mips_cpu_step : failed.\n");
- exit(1);
- }
-
- // 4 -Check the result
- e=mips_cpu_get_register(cpu, 0, &got);
-
-
- passed = got == 0;
-
- mips_test_end_test(testId, passed, "r0 <> 0");
-
-
-
- mips_test_end_suite();
-
- return 0;
-}
diff --git a/src/shared/mips_mem_ram.cpp b/src/shared/mips_mem_ram.cpp
index 276388b..0a01b5b 100644
--- a/src/shared/mips_mem_ram.cpp
+++ b/src/shared/mips_mem_ram.cpp
@@ -12,14 +12,16 @@
struct mips_mem_provider
{
uint32_t length;
- uint32_t blockSize;
uint8_t *data;
};
extern "C" mips_mem_h mips_mem_create_ram(
- uint32_t cbMem, //!< Total number of bytes of ram
- uint32_t blockSize //!< Granularity in bytes
+ uint32_t cbMem //!< Total number of bytes of ram
){
+ if(cbMem>0x10000000){
+ return 0; // No more than 256MB of RAM
+ }
+
uint8_t *data=(uint8_t*)malloc(cbMem);
if(data==0)
return 0;
@@ -31,7 +33,6 @@ extern "C" mips_mem_h mips_mem_create_ram(
}
mem->length=cbMem;
- mem->blockSize=blockSize;
mem->data=data;
return mem;
@@ -45,13 +46,15 @@ static mips_error mips_mem_read_write(
uint8_t *dataOut
)
{
- if(mem==0)
+ if(mem==0){
return mips_ErrorInvalidHandle;
+ }
- if(0 != (address%mem->blockSize) ){
- return mips_ExceptionInvalidAlignment;
+ if( (length!=1) && (length!=2) && (length!=4) ){
+ return mips_ExceptionInvalidLength;
}
- if(0 != ((address+length)%mem->blockSize)){
+
+ if(0 != (address % length) ){
return mips_ExceptionInvalidAlignment;
}
if((address+length) > mem->length){ // A subtle bug here, maybe?