CPU: Added support for PUSH and POP and fixed CALL and RET
This commit is contained in:
parent
4863db36ee
commit
966a0eee14
70
assembly.c
70
assembly.c
@ -73,6 +73,7 @@
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h15 | Call if carry flag is not set | NO |
|
||||
//
|
||||
//
|
||||
// | | | |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h0F | MOV immediate to SP | |
|
||||
@ -82,20 +83,24 @@
|
||||
//
|
||||
//
|
||||
// INSTRUCTION FORMAT 1 OPCODE NUM:
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | NUM | DESCRIPTION | AFFECT FLAGS |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 13'd0 | ADD | YES |
|
||||
// +-------+----------------------------------+--------------|
|
||||
// | 13'd1 | SUBTRACT | YES |
|
||||
// +-------+----------------------------------+--------------|
|
||||
// | 13'd2 | SHIFT LEFT | YES |
|
||||
// +-------+----------------------------------+--------------|
|
||||
// | 13'd3 | SHIFT RIGHT | YES |
|
||||
// +-------+----------------------------------+--------------|
|
||||
// | 13'd4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 13'd5 | HALT | NO |
|
||||
// +-------+----------------------------------+--------------+------------+------------+
|
||||
// | NUM | DESCRIPTION | AFFECT FLAGS | SOURCE REG | DEST REG |
|
||||
// +-------+----------------------------------+--------------+------------+------------+
|
||||
// | 13'd0 | ADD | YES | operand 1 | operand 1 |
|
||||
// +-------+----------------------------------+--------------|------------+------------+
|
||||
// | 13'd1 | SUBTRACT | YES | operand 1 | operand 1 |
|
||||
// +-------+----------------------------------+--------------|------------+------------+
|
||||
// | 13'd2 | SHIFT LEFT | YES | operand | |
|
||||
// +-------+----------------------------------+--------------|------------+------------+
|
||||
// | 13'd3 | SHIFT RIGHT | YES | operand | |
|
||||
// +-------+----------------------------------+--------------|------------+------------+
|
||||
// | 13'd4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES | operand 1 | operand 1 |
|
||||
// +-------+----------------------------------+--------------+------------+------------+
|
||||
// | 13'd5 | HALT | NO | | |
|
||||
// +-------+----------------------------------+--------------+------------+------------+
|
||||
// | 13'd6 | PUSH | NO | operand | |
|
||||
// +-------+----------------------------------+--------------+------------+------------+
|
||||
// | 13'd7 | POP | NO | operand | |
|
||||
//
|
||||
//
|
||||
// INSTRUCTION FORMAT 2 OPCODE NUM:
|
||||
@ -183,6 +188,12 @@ char *disassemble(uint32_t opcode_be){
|
||||
case 0x05:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"HALT");
|
||||
break;
|
||||
case 0x06:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"PUSH %%R%0d",val1);
|
||||
break;
|
||||
case 0x07:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"POP %%R%0d",val1);
|
||||
break;
|
||||
default:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION");
|
||||
break;
|
||||
@ -407,8 +418,37 @@ uint32_t assemble_line(char *line, struct assembler_context_t *assembler_context
|
||||
return 0xFFFFFFFF;
|
||||
}else if(strncmp(line,"RET",3)==0){
|
||||
return 0x10000000;
|
||||
}else if(*line==':')
|
||||
}else if(*line==':'){
|
||||
return 0xFFFFFFF0;
|
||||
}else if(strncmp(line,"PUSH",4)==0){
|
||||
x=4;
|
||||
while(line[x]==' ')x++;
|
||||
if(line[x]=='%'){
|
||||
x++;
|
||||
if(line[x]=='R'){
|
||||
x++;
|
||||
if(line[x]>='0'&&line[x]<='7')
|
||||
return 0x20060000|(line[x]-'0')<<8;
|
||||
else
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
}else
|
||||
return 0xFFFFFFFF;
|
||||
}else if(strncmp(line,"POP",3)==0){
|
||||
x=3;
|
||||
while(line[x]==' ')x++;
|
||||
if(line[x]=='%'){
|
||||
x++;
|
||||
if(line[x]=='R'){
|
||||
x++;
|
||||
if(line[x]>='0'&&line[x]<='7')
|
||||
return 0x20070000|(line[x]-'0')<<8;
|
||||
else
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
}else
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
31
cpu.c
31
cpu.c
@ -86,9 +86,15 @@ int decode(struct simdata_t *simdata){
|
||||
simdata->exec_data->in_op2->data=op2;
|
||||
|
||||
switch(opcode){
|
||||
case 5:
|
||||
case 0x05:
|
||||
simdata->exec_data->EXEC_ACTION=HALT;
|
||||
break;
|
||||
case 0x06:
|
||||
simdata->exec_data->EXEC_ACTION=PUSH;
|
||||
break;
|
||||
case 0x07:
|
||||
simdata->exec_data->EXEC_ACTION=POP;
|
||||
break;
|
||||
default:
|
||||
simdata->exec_data->EXEC_ACTION=EXEC_ALU;
|
||||
break;
|
||||
@ -116,6 +122,8 @@ int decode(struct simdata_t *simdata){
|
||||
case 3: simdata->exec_data->ALU_OP=ALU_SR; break;
|
||||
case 4: simdata->exec_data->ALU_OP=ALU_CMP; break;
|
||||
case 5: break;
|
||||
case 6: break;
|
||||
case 7: break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
@ -200,17 +208,17 @@ int exec(struct simdata_t *simdata){
|
||||
}
|
||||
if(condition){
|
||||
if(simdata->exec_data->EXEC_ACTION==CALL){
|
||||
simdata->RAM[simdata->registers->SP]=simdata->registers->PC;
|
||||
simdata->registers->SP+=6;
|
||||
*(uint32_t*)(simdata->RAM+simdata->registers->SP)=simdata->registers->PC;
|
||||
simdata->registers->SP+=4;
|
||||
}
|
||||
if(simdata->exec_data->out_op->OP_ADDR==IMMEDIATE)
|
||||
simdata->registers->PC=simdata->exec_data->out_op->data;
|
||||
simdata->registers->PC=(uint32_t)(simdata->exec_data->out_op->data);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case RET:
|
||||
simdata->registers->SP-=6;
|
||||
simdata->registers->SP-=4;
|
||||
simdata->registers->PC=simdata->RAM[simdata->registers->SP];
|
||||
break;
|
||||
case EXEC_ALU:
|
||||
@ -290,7 +298,18 @@ int exec(struct simdata_t *simdata){
|
||||
case HALT:
|
||||
simdata->cpu_state=CPU_HALTED;
|
||||
break;
|
||||
|
||||
case PUSH:
|
||||
simdata->RAM[simdata->registers->SP ]=simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x000000FF;
|
||||
simdata->RAM[simdata->registers->SP+1]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x0000FF00)>>8;
|
||||
simdata->RAM[simdata->registers->SP+2]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00FF0000)>>16;
|
||||
simdata->registers->SP+=4;
|
||||
break;
|
||||
case POP:
|
||||
simdata->registers->SP-=4;
|
||||
simdata->registers->GPR[simdata->exec_data->in_op1->data]=simdata->RAM[simdata->registers->SP];
|
||||
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+1]<<8;
|
||||
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+2]<<16;
|
||||
break;
|
||||
}
|
||||
add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address);
|
||||
return 0;
|
||||
|
4
cpu.h
4
cpu.h
@ -20,7 +20,9 @@ enum EXEC_ACTION_t {
|
||||
CALL,
|
||||
NOP,
|
||||
HALT,
|
||||
RET
|
||||
RET,
|
||||
PUSH,
|
||||
POP
|
||||
};
|
||||
|
||||
enum ALU_OP_t {
|
||||
|
10
test.asm
10
test.asm
@ -1,13 +1,19 @@
|
||||
MOV $123456,%SP
|
||||
MOV $FF0000,%SP
|
||||
MOV $0x0001,%R0l
|
||||
MOV $0x0000,%R0h
|
||||
MOV $0x0000,%R1l
|
||||
MOV $0xBEEF,%R1l
|
||||
MOV $0x0000,%R1h
|
||||
CALL $SUBROUTINE
|
||||
CALL $SUBROUTINE
|
||||
CALL $SUBROUTINE
|
||||
CALL $SUBROUTINE2
|
||||
JMP $END
|
||||
:SUBROUTINE
|
||||
PUSH %R1
|
||||
ADD %R0,%R1
|
||||
POP %R1
|
||||
RET
|
||||
:SUBROUTINE2
|
||||
ADD %R0,%R1
|
||||
RET
|
||||
:END
|
||||
|
Loading…
Reference in New Issue
Block a user