CPU: Fixed numeric comparisons
This commit is contained in:
parent
222acaccb3
commit
d048b080b8
22
assembly.c
22
assembly.c
@ -61,6 +61,10 @@
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h5 | Jump if carry flag is not set | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h6 | Jump if sign flag is set | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h7 | Jump if sign flag is not set | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h10 | Unconditional ret | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h11 | Unconditional call | NO |
|
||||
@ -72,6 +76,10 @@
|
||||
// | 5'h14 | Call if carry flag is set | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h15 | Call if carry flag is not set | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h16 | Call if sign flag is set | NO |
|
||||
// +-------+----------------------------------+--------------+
|
||||
// | 5'h17 | Call if sign flag is not set | NO |
|
||||
//
|
||||
//
|
||||
// | | | |
|
||||
@ -180,6 +188,12 @@ char *disassemble(uint32_t opcode_be){
|
||||
case 0x0F:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV $%06X,%%SP",val);
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"%s,%s $%06X",(opcode_num&0x10)?"CALL":"JMP",opcode_num&1?"NS":"S",val);
|
||||
break;
|
||||
default:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTR");
|
||||
break;
|
||||
@ -369,9 +383,11 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context)
|
||||
return -1;//empty line or comment
|
||||
if( (strncmp(line,"JMP,",4)==0) || (strncmp(line,"JMP ",4)==0) || ((call=strncmp(line,"CALL ",5))==0) ){
|
||||
if(!call){
|
||||
/*if it was a call*/
|
||||
x=4;
|
||||
opcode=0x10;
|
||||
}else{
|
||||
/*if it wasn't*/
|
||||
x=3;
|
||||
opcode=0x00;
|
||||
}
|
||||
@ -385,6 +401,9 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context)
|
||||
}else if(line[x]=='C'){
|
||||
opcode|=0x04;
|
||||
x++;
|
||||
}else if(line[x]=='S'){
|
||||
opcode|=0x06;
|
||||
x++;
|
||||
}else if(line[x]=='N'){
|
||||
x++;
|
||||
if(line[x]=='Z'){
|
||||
@ -393,6 +412,9 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context)
|
||||
}else if(line[x]=='C'){
|
||||
opcode|=0x09;
|
||||
x++;
|
||||
}else if(line[x]=='S'){
|
||||
opcode|=0x07;
|
||||
x++;
|
||||
}else
|
||||
return -2;
|
||||
}else
|
||||
|
10
cpu.c
10
cpu.c
@ -84,17 +84,23 @@ int decode(struct simdata_t *simdata){
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
switch(opcode){
|
||||
case 0x01: case 0x11: simdata->exec_data->COND=COND_NONE; break;
|
||||
case 0x02: case 0x12: simdata->exec_data->COND=COND_ZERO; break;
|
||||
case 0x03: case 0x13: simdata->exec_data->COND=COND_NZERO; break;
|
||||
case 0x04: case 0x14: simdata->exec_data->COND=COND_CARRY; break;
|
||||
case 0x05: case 0x15: simdata->exec_data->COND=COND_NCARRY; break;
|
||||
case 0x06: case 0x16: simdata->exec_data->COND=COND_SIGN; break;
|
||||
case 0x07: case 0x17: simdata->exec_data->COND=COND_NSIGN; break;
|
||||
default: return 1;
|
||||
}
|
||||
simdata->exec_data->out_op->OP_ADDR=IMMEDIATE;
|
||||
@ -350,6 +356,8 @@ int exec(struct simdata_t *simdata){
|
||||
case COND_NZERO: condition=!(simdata->registers->FLAGS&1); break;
|
||||
case COND_CARRY: condition=simdata->registers->FLAGS&2; break;
|
||||
case COND_NCARRY: condition=!(simdata->registers->FLAGS&2); break;
|
||||
case COND_SIGN: condition=simdata->registers->FLAGS&4; break;
|
||||
case COND_NSIGN: condition=!(simdata->registers->FLAGS&4); break;
|
||||
}
|
||||
switch(simdata->exec_data->COND){
|
||||
case COND_NONE:
|
||||
@ -404,6 +412,8 @@ int exec(struct simdata_t *simdata){
|
||||
simdata->registers->GPR[simdata->exec_data->in_op1->data];
|
||||
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
|
||||
(simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
|
||||
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFB)|
|
||||
(simdata->registers->GPR[simdata->exec_data->in_op2->data]<simdata->registers->GPR[simdata->exec_data->in_op1->data])<<2;
|
||||
|
||||
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
|
||||
|
||||
|
4
cpu.h
4
cpu.h
@ -65,7 +65,9 @@ enum COND_t{
|
||||
COND_ZERO,
|
||||
COND_NZERO,
|
||||
COND_CARRY,
|
||||
COND_NCARRY
|
||||
COND_NCARRY,
|
||||
COND_SIGN,
|
||||
COND_NSIGN
|
||||
};
|
||||
|
||||
struct exec_data_t {
|
||||
|
@ -1,5 +1,42 @@
|
||||
MOV $0xFF0000,%SP
|
||||
MOV %SP,%R2
|
||||
MOV $0x0000,%R0h
|
||||
MOV $DATA,%R0l
|
||||
PUSH %R0
|
||||
MOV %SP,%R2
|
||||
MOV $DATA_END,%R0l
|
||||
PUSH %R0
|
||||
CALL $QUICKSORT
|
||||
HALT
|
||||
|
||||
:QUICKSORT
|
||||
#Get parameters from stack
|
||||
MOV %SP,%R0
|
||||
MOV $0x0000,%R1h
|
||||
MOV $0x0004,%R1l
|
||||
SUB %R1,%R0
|
||||
SUB %R1,%R0
|
||||
MOV (%R0),%R2
|
||||
SUB %R1,%R0
|
||||
MOV (%R0),%R3
|
||||
|
||||
#Compare input and quit if start >= end
|
||||
CMP %R2,%R3
|
||||
JMP,NS $BAIL
|
||||
|
||||
ADD %R2,%R3
|
||||
|
||||
:BAIL
|
||||
RET
|
||||
|
||||
|
||||
:DATA
|
||||
DDW $0x00000000
|
||||
DDW $0x00000004
|
||||
DDW $0x00000009
|
||||
DDW $0x00000031
|
||||
DDW $0x000000BB
|
||||
DDW $0x0000000e
|
||||
DDW $0x00000002
|
||||
DDW $0x000000BB
|
||||
DDW $0x01000000
|
||||
:DATA_END
|
||||
DDW $0xFFFFFFFF
|
||||
|
Loading…
Reference in New Issue
Block a user