From 35588a07c841d7492349c92a24d5747388073f0a Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Wed, 14 Feb 2024 14:03:03 +0000 Subject: [PATCH] CPU: Added support for reading into registers from indirect memory access with register --- assembly.c | 40 ++++++++++++++++++++++++++++++++++++++++ cpu.c | 28 ++++++++++++++++++---------- test.asm | 4 ++++ 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/assembly.c b/assembly.c index 30cfc50..f6aead6 100644 --- a/assembly.c +++ b/assembly.c @@ -456,6 +456,46 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context) return -2; }else return -2; + }else if(line[x]=='('){ + while(line[x]==' ')x++; + x++; + if(line[x]=='%'){ + x++; + if(line[x]=='R'){ + x++; + if(line[x]>='0'&&line[x]<='7'){ + r0=line[x]-'0'; + x++; + while(line[x]==' ')x++; + if(line[x]==')'){ + x++; + while(line[x]==' ')x++; + if(line[x]==','){ + x++; + while(line[x]==' ')x++; + if(line[x]=='%'){ + x++; + if(line[x]=='R'){ + x++; + if(line[x]>='0'&&line[x]<='7'){ + r1=line[x]-'0'; + return 0x20090000|(r0&0xFF)<<8|(r1&0xFF); + }else + return -2; + }else + return -2; + }else + return -2; + }else + return -2; + }else + return -2; + }else + return -2; + }else + return -2; + }else + return -2; }else return -2; }else if(strncmp(line,"HALT ",5)==0||strncmp(line,"HALT\0",5)==0){ diff --git a/cpu.c b/cpu.c index f64494a..2213520 100644 --- a/cpu.c +++ b/cpu.c @@ -59,12 +59,12 @@ int decode(struct simdata_t *simdata){ simdata->exec_data->out_op->data=simdata->decode_data->in_bytecode&0x00FFFFFF; simdata->exec_data->EXEC_ACTION=(opcode&0x10)?CALL:JUMP; break; - case 0x0F: + case 0x0F:/* load SP */ simdata->exec_data->EXEC_ACTION=MOVE; simdata->exec_data->in_op1->OP_ADDR=IMMEDIATE; simdata->exec_data->in_op1->data=simdata->decode_data->in_bytecode&0x00FFFFFF; simdata->exec_data->out_op->OP_ADDR=REGISTER; - simdata->exec_data->out_op->data=0; + simdata->exec_data->out_op->data=0xFF; break; case 0x10: simdata->exec_data->EXEC_ACTION=RET; @@ -311,17 +311,25 @@ int exec(struct simdata_t *simdata){ simdata->registers->GPR[simdata->exec_data->in_op1->data])<<16); break; case REGISTER: /* This is for special registers like the SP which is 24bits long */ - if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){ - if( (simdata->exec_data->in_op1->data&0xFF000000) == 0 ) - simdata->registers->SP=simdata->exec_data->in_op1->data; - else - return 2; - }else{ + if(simdata->exec_data->out_op->data==0xFF){ + if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){ + if( (simdata->exec_data->in_op1->data&0xFF000000) == 0 ) + simdata->registers->SP=simdata->exec_data->in_op1->data; + else + return 2; + }else if( simdata->exec_data->in_op1->OP_ADDR==REGISTER ){ /*for completeion, not valid ( yet )*/ + if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ) + simdata->registers->SP=simdata->registers->GPR[simdata->exec_data->in_op1->data]; + else + return 2; + } + }else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER_IND){ if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ) - simdata->registers->SP=simdata->registers->GPR[simdata->exec_data->in_op1->data]; + simdata->registers->GPR[simdata->exec_data->out_op->data]=*(uint32_t*)(simdata->RAM+simdata->registers->GPR[simdata->exec_data->in_op1->data]); else return 2; - } + }else + return 1; break; case REGISTER_IND: if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){ diff --git a/test.asm b/test.asm index ce71671..9ecbe6c 100644 --- a/test.asm +++ b/test.asm @@ -48,6 +48,10 @@ MOV %R1,(%R0) MOV $0xcccd,%R1l MOV $0x3f4c,%R1h MOV %R1,(%R0) +MOV $0x00D0,%R0l +MOV $0x0000,%R0h +MOV %R1,(%R0) +MOV (%R0),%R5 HALT :TR_LOW DDW $0xDEADBEEF