From d048b080b8295fdce0a6b71b9c3e23a12dc0a96b Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Fri, 3 May 2024 07:09:57 +0100 Subject: [PATCH] CPU: Fixed numeric comparisons --- assembly.c | 22 ++++++++++++++++++++++ cpu.c | 10 ++++++++++ cpu.h | 4 +++- programs/quicksort.asm | 41 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/assembly.c b/assembly.c index 107ff8f..0f237eb 100644 --- a/assembly.c +++ b/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 diff --git a/cpu.c b/cpu.c index ace01f4..1a3140e 100644 --- a/cpu.c +++ b/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]registers->GPR[simdata->exec_data->in_op1->data])<<2; simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX]; diff --git a/cpu.h b/cpu.h index dee908d..f574b5f 100644 --- a/cpu.h +++ b/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 { diff --git a/programs/quicksort.asm b/programs/quicksort.asm index 0b3b919..fb4788c 100644 --- a/programs/quicksort.asm +++ b/programs/quicksort.asm @@ -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