137 lines
2.8 KiB
C
137 lines
2.8 KiB
C
|
#include "simdata.h"
|
||
|
#include "cpu.h"
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
|
||
|
|
||
|
struct fetch_data_t *malloc_fetch_data(){
|
||
|
return NULL;
|
||
|
}
|
||
|
void free_fetch_data(__attribute__((unused)) struct fetch_data_t *tofree){
|
||
|
}
|
||
|
int fetch(struct simdata_t *simdata){
|
||
|
simdata->decode_data->in_bytecode=(uint32_t)(simdata->RAM[simdata->PC])<<24|(uint32_t)(simdata->RAM[simdata->PC+1])<<16|(uint32_t)(simdata->RAM[simdata->PC+2])<<8|(uint32_t)(simdata->RAM[simdata->PC+3]);
|
||
|
simdata->PC+=4;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
struct decode_data_t *malloc_decode_data(){
|
||
|
return malloc(sizeof(struct decode_data_t));
|
||
|
}
|
||
|
void free_decode_data(struct decode_data_t *tofree){
|
||
|
free(tofree);
|
||
|
}
|
||
|
int decode(struct simdata_t *simdata){
|
||
|
uint16_t opcode;
|
||
|
switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){
|
||
|
case 0:
|
||
|
opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24;
|
||
|
switch(opcode){
|
||
|
case 1:
|
||
|
simdata->exec_data->out_op->OP_ADDR=IMMEDIATE;
|
||
|
simdata->exec_data->out_op->data=simdata->decode_data->in_bytecode&0x00FFFFFF;
|
||
|
simdata->exec_data->EXEC_ACTION=JUMP;
|
||
|
break;
|
||
|
default:
|
||
|
return 1;
|
||
|
}
|
||
|
break;
|
||
|
case 1:
|
||
|
return 1;
|
||
|
break;
|
||
|
case 2:
|
||
|
return 1;
|
||
|
break;
|
||
|
default:
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
struct exec_data_t *malloc_exec_data(){
|
||
|
struct exec_data_t *ret;
|
||
|
ret=malloc(sizeof(struct exec_data_t));
|
||
|
if(!ret)
|
||
|
return 0;
|
||
|
ret->in_op1=malloc(sizeof(struct exec_op_t));
|
||
|
if(!ret->in_op1){
|
||
|
free(ret);
|
||
|
return 0;
|
||
|
}
|
||
|
ret->in_op2=malloc(sizeof(struct exec_op_t));
|
||
|
if(!ret->in_op2){
|
||
|
free(ret->in_op1);
|
||
|
free(ret);
|
||
|
return 0;
|
||
|
}
|
||
|
ret->out_op=malloc(sizeof(struct exec_op_t));
|
||
|
if(!ret->out_op){
|
||
|
free(ret->in_op1);
|
||
|
free(ret->in_op2);
|
||
|
free(ret);
|
||
|
return 0;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
void free_exec_data(struct exec_data_t *tofree){
|
||
|
free(tofree->in_op1);
|
||
|
free(tofree->in_op2);
|
||
|
free(tofree->out_op);
|
||
|
free(tofree);
|
||
|
}
|
||
|
int exec(struct simdata_t *simdata){
|
||
|
switch(simdata->exec_data->EXEC_ACTION){
|
||
|
case JUMP:
|
||
|
if(simdata->exec_data->out_op->OP_ADDR==IMMEDIATE)
|
||
|
simdata->PC=simdata->exec_data->out_op->data;
|
||
|
else
|
||
|
return 1;
|
||
|
break;
|
||
|
case EXEC_ALU:
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int state=0;
|
||
|
|
||
|
int cpu_cycle_clock(struct simdata_t *simdata){
|
||
|
switch(state){
|
||
|
case 0: if( fetch(simdata) ) return 1; break;
|
||
|
case 1: if( decode(simdata) ) return 1; break;
|
||
|
case 2: if( exec(simdata) ) return 1; break;
|
||
|
}
|
||
|
if(state==2)
|
||
|
state=0;
|
||
|
else
|
||
|
state++;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int cpu_simdata_malloc(struct simdata_t *simdata){
|
||
|
simdata->fetch_data=malloc_fetch_data();
|
||
|
simdata->decode_data=malloc_decode_data();
|
||
|
simdata->exec_data=malloc_exec_data();
|
||
|
if((simdata->fetch_data!=NULL)&&(simdata->decode_data!=NULL)&&(simdata->exec_data!=NULL))
|
||
|
return 1;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void cpu_simdata_free(struct simdata_t *simdata){
|
||
|
free_fetch_data(simdata->fetch_data);
|
||
|
free_decode_data(simdata->decode_data);
|
||
|
free_exec_data(simdata->exec_data);
|
||
|
}
|