Expanded Instruction set
This commit is contained in:
parent
14e4c6746a
commit
7ce6a98931
|
@ -236,23 +236,28 @@
|
||||||
1OPI i ii ii is the Immediate, a = a OP i ii ii
|
1OPI i ii ii is the Immediate, a = a OP i ii ii
|
||||||
|
|
||||||
*** Conditional Integer Jumps
|
*** Conditional Integer Jumps
|
||||||
2C 0a ii ii # JUMP.C a i ii ii :: Carry? a; PC = PC + i ii ii
|
2C 0a ii ii # JUMP.C a ii ii :: Carry? a; PC = PC + i ii ii
|
||||||
2C 1a ii ii # JUMP.B a i ii ii :: Borrow? a; PC = PC + i ii ii
|
2C 1a ii ii # JUMP.B a ii ii :: Borrow? a; PC = PC + i ii ii
|
||||||
2C 2a ii ii # JUMP.O a i ii ii :: Overflow? a; PC = PC + i ii ii
|
2C 2a ii ii # JUMP.O a ii ii :: Overflow? a; PC = PC + i ii ii
|
||||||
2C 3a ii ii # JUMP.G a i ii ii :: GT? a; PC = PC + i ii ii
|
2C 3a ii ii # JUMP.G a ii ii :: GT? a; PC = PC + i ii ii
|
||||||
2C 4a ii ii # JUMP.GE a i ii ii :: GT? a | EQ? a; PC = PC + i ii ii
|
2C 4a ii ii # JUMP.GE a ii ii :: GT? a | EQ? a; PC = PC + i ii ii
|
||||||
2C 5a ii ii # JUMP.E a i ii ii :: EQ? a; PC = PC + i ii ii
|
2C 5a ii ii # JUMP.E a ii ii :: EQ? a; PC = PC + i ii ii
|
||||||
2C 6a ii ii # JUMP.NE a i ii ii :: NEQ? a; PC = PC + i ii ii
|
2C 6a ii ii # JUMP.NE a ii ii :: NEQ? a; PC = PC + i ii ii
|
||||||
2C 7a ii ii # JUMP.LE a i ii ii :: LT? a | EQ? a; PC = PC + i ii ii
|
2C 7a ii ii # JUMP.LE a ii ii :: LT? a | EQ? a; PC = PC + i ii ii
|
||||||
2C 8a ii ii # JUMP.L a i ii ii :: LT? a; PC = PC + i ii ii
|
2C 8a ii ii # JUMP.L a ii ii :: LT? a; PC = PC + i ii ii
|
||||||
2C 9a ii ii # JUMP.Z a i ii ii :: ZERO? a; PC = PC + i ii ii
|
2C 9a ii ii # JUMP.Z a ii ii :: ZERO? a; PC = PC + i ii ii
|
||||||
2C Aa ii ii # JUMP.NZ a i ii ii :: NZERO? a; PC = PC + i ii ii
|
2C Aa ii ii # JUMP.NZ a ii ii :: NZERO? a; PC = PC + i ii ii
|
||||||
2C Bx xx xx # Reserved
|
2C Bx xx xx # Reserved
|
||||||
2C Cx xx xx # Reserved
|
2C Cx xx xx # Reserved
|
||||||
2C Dx xx xx # Reserved
|
2C Dx xx xx # Reserved
|
||||||
2C Ex xx xx # Reserved
|
2C Ex xx xx # Reserved
|
||||||
2C Fx xx xx # Reserved
|
2C Fx xx xx # Reserved
|
||||||
|
|
||||||
|
*** Branch Immediates
|
||||||
|
2D 0a ii ii # CALLI a ii ii :: MEM[a] = PC; a = a + (register size in bytes); PC = PC + ii ii
|
||||||
|
2D 1a ii ii # LOADI a ii ii :: a = ii ii (signed)
|
||||||
|
2D 2a ii ii # LOADUI a ii ii :: a = ii ii (unsigned)
|
||||||
|
|
||||||
** 0OPI group
|
** 0OPI group
|
||||||
0OPI ii ii is the Immediate, OP ii ii
|
0OPI ii ii is the Immediate, OP ii ii
|
||||||
|
|
||||||
|
|
3
asm.c
3
asm.c
|
@ -287,6 +287,9 @@ void assemble(struct Token* p)
|
||||||
setExpression(p, "JUMP.L", "2C8", 4);
|
setExpression(p, "JUMP.L", "2C8", 4);
|
||||||
setExpression(p, "JUMP.Z", "2C9", 4);
|
setExpression(p, "JUMP.Z", "2C9", 4);
|
||||||
setExpression(p, "JUMP.NZ", "2CA", 4);
|
setExpression(p, "JUMP.NZ", "2CA", 4);
|
||||||
|
setExpression(p, "CALLI", "2D0", 4);
|
||||||
|
setExpression(p, "LOADI", "2D1", 4);
|
||||||
|
setExpression(p, "LOADUI", "2D2", 4);
|
||||||
|
|
||||||
/* 0OPI Group */
|
/* 0OPI Group */
|
||||||
setExpression(p, "JUMP", "3C00", 4);
|
setExpression(p, "JUMP", "3C00", 4);
|
||||||
|
|
50
disasm.c
50
disasm.c
|
@ -653,7 +653,7 @@ void decode_Integer_2OPI(struct Instruction* c)
|
||||||
}
|
}
|
||||||
case 0x12: /* CMPI */
|
case 0x12: /* CMPI */
|
||||||
{
|
{
|
||||||
strncpy(Name, "", 19);
|
strncpy(Name, "CMPI", 19);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x13: /* LOAD */
|
case 0x13: /* LOAD */
|
||||||
|
@ -824,6 +824,49 @@ void decode_1OPI(struct Instruction* c)
|
||||||
fprintf(stdout, "# %s\n", c->operation);
|
fprintf(stdout, "# %s\n", c->operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void decode_Branch_1OPI(struct Instruction* c)
|
||||||
|
{
|
||||||
|
/* Parse Raw Data */
|
||||||
|
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||||
|
c->Immediate[0] = c->operation[3];
|
||||||
|
c->Immediate[1] = c->operation[4];
|
||||||
|
c->Immediate[2] = c->operation[5];
|
||||||
|
c->Immediate[3] = c->operation[6];
|
||||||
|
c->Immediate[4] = c->operation[7];
|
||||||
|
c->HAL_CODE = 0;
|
||||||
|
c->raw_XOP = c->raw1/16;
|
||||||
|
c->reg0 = c->raw1%16;
|
||||||
|
|
||||||
|
char Name[20] = "ILLEGAL_1OPI";
|
||||||
|
|
||||||
|
/* Convert to Human readable form */
|
||||||
|
switch(c->raw_XOP)
|
||||||
|
{
|
||||||
|
case 0x0: /* CALLI */
|
||||||
|
{
|
||||||
|
strncpy(Name, "CALLI", 19);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x1: /* LOADI */
|
||||||
|
{
|
||||||
|
strncpy(Name, "LOADI", 19);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x2: /* LOADUI */
|
||||||
|
{
|
||||||
|
strncpy(Name, "LOADUI", 19);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: /* Unknown 1OPI*/
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "%s reg%o %d\t", Name, c->reg0, c->raw_Immediate);
|
||||||
|
fprintf(stdout, "# %s\n", c->operation);
|
||||||
|
}
|
||||||
|
|
||||||
void decode_0OPI(struct Instruction* c)
|
void decode_0OPI(struct Instruction* c)
|
||||||
{
|
{
|
||||||
/* Parse Raw Data */
|
/* Parse Raw Data */
|
||||||
|
@ -941,6 +984,11 @@ void eval_instruction(struct Instruction* c)
|
||||||
decode_1OPI(c);
|
decode_1OPI(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x2D: /* Branch 1OPI*/
|
||||||
|
{
|
||||||
|
decode_Branch_1OPI(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x3C: /* Core 0OPI */
|
case 0x3C: /* Core 0OPI */
|
||||||
{
|
{
|
||||||
decode_0OPI(c);
|
decode_0OPI(c);
|
||||||
|
|
94
vm.c
94
vm.c
|
@ -838,17 +838,8 @@ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
|
||||||
}
|
}
|
||||||
case 0x0100: /* BRANCH */
|
case 0x0100: /* BRANCH */
|
||||||
{
|
{
|
||||||
/* Preserve index */
|
|
||||||
uint32_t utmp1 = vm->reg[c->reg1];
|
|
||||||
|
|
||||||
/* Use the index register to store the PC for upload to MEM */
|
|
||||||
vm->reg[c->reg1] = vm->ip;
|
|
||||||
|
|
||||||
/* Write out the PC */
|
/* Write out the PC */
|
||||||
writeout_Reg(vm, utmp1, c->reg1);
|
writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
|
||||||
|
|
||||||
/* Restore our index */
|
|
||||||
vm->reg[c->reg1] = utmp1;
|
|
||||||
|
|
||||||
/* Update PC */
|
/* Update PC */
|
||||||
vm->ip = vm->reg[c->reg0];
|
vm->ip = vm->reg[c->reg0];
|
||||||
|
@ -856,17 +847,11 @@ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
|
||||||
}
|
}
|
||||||
case 0x0101: /* CALL */
|
case 0x0101: /* CALL */
|
||||||
{
|
{
|
||||||
/* Preserve index */
|
|
||||||
uint32_t utmp1 = vm->reg[c->reg1];
|
|
||||||
|
|
||||||
/* Use the index register to store the PC for upload to MEM */
|
|
||||||
vm->reg[c->reg1] = vm->ip;
|
|
||||||
|
|
||||||
/* Write out the PC */
|
/* Write out the PC */
|
||||||
writeout_Reg(vm, utmp1, c->reg1);
|
writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
|
||||||
|
|
||||||
/* Update our index */
|
/* Update our index */
|
||||||
vm->reg[c->reg1] = utmp1 + 4;
|
vm->reg[c->reg1] = vm->reg[c->reg1] + 4;
|
||||||
|
|
||||||
/* Update PC */
|
/* Update PC */
|
||||||
vm->ip = vm->reg[c->reg0];
|
vm->ip = vm->reg[c->reg0];
|
||||||
|
@ -910,43 +895,29 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
|
||||||
}
|
}
|
||||||
case 0x01001: /* RET */
|
case 0x01001: /* RET */
|
||||||
{
|
{
|
||||||
/* Preserve index */
|
|
||||||
uint32_t utmp1 = vm->reg[c->reg0];
|
|
||||||
|
|
||||||
/* Read in the new PC */
|
/* Read in the new PC */
|
||||||
readin_Reg(vm, utmp1, c->reg0);
|
vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
|
||||||
vm->ip = vm->reg[c->reg0];
|
|
||||||
|
|
||||||
/* Update our index */
|
/* Update our index */
|
||||||
vm->reg[c->reg0] = utmp1 - 4;
|
vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x02000: /* PUSHPC */
|
case 0x02000: /* PUSHPC */
|
||||||
{
|
{
|
||||||
/* Preserve index */
|
|
||||||
uint32_t utmp1 = vm->reg[c->reg0];
|
|
||||||
|
|
||||||
/* Use the index register to store the PC for upload to MEM */
|
|
||||||
vm->reg[c->reg0] = vm->ip;
|
|
||||||
|
|
||||||
/* Write out the PC */
|
/* Write out the PC */
|
||||||
writeout_Reg(vm, utmp1, c->reg0);
|
writeout_Reg(vm, vm->reg[c->reg0], vm->ip);
|
||||||
|
|
||||||
/* Update our index */
|
/* Update our index */
|
||||||
vm->reg[c->reg0] = utmp1 + 4;
|
vm->reg[c->reg0] = vm->reg[c->reg0] + 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x02001: /* POPPC */
|
case 0x02001: /* POPPC */
|
||||||
{
|
{
|
||||||
/* Preserve index */
|
|
||||||
uint32_t utmp1 = vm->reg[c->reg0];
|
|
||||||
|
|
||||||
/* Read in the new PC */
|
/* Read in the new PC */
|
||||||
readin_Reg(vm, utmp1, c->reg0);
|
vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
|
||||||
vm->ip = vm->reg[c->reg0];
|
|
||||||
|
|
||||||
/* Update our index */
|
/* Update our index */
|
||||||
vm->reg[c->reg0] = utmp1 - 4;
|
vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: return true;
|
default: return true;
|
||||||
|
@ -1007,7 +978,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
||||||
}
|
}
|
||||||
case 0x13: /* LOAD */
|
case 0x13: /* LOAD */
|
||||||
{
|
{
|
||||||
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
|
vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x14: /* LOAD8 */
|
case 0x14: /* LOAD8 */
|
||||||
|
@ -1051,7 +1022,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
||||||
case 0x18: /* LOAD32 */
|
case 0x18: /* LOAD32 */
|
||||||
case 0x19: /* LOADU32 */
|
case 0x19: /* LOADU32 */
|
||||||
{
|
{
|
||||||
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
|
vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x1F: /* CMPUI */
|
case 0x1F: /* CMPUI */
|
||||||
|
@ -1074,7 +1045,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
||||||
}
|
}
|
||||||
case 0x20: /* STORE */
|
case 0x20: /* STORE */
|
||||||
{
|
{
|
||||||
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
|
writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x21: /* STORE8 */
|
case 0x21: /* STORE8 */
|
||||||
|
@ -1118,7 +1089,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
||||||
case 0x25: /* STORE32 */
|
case 0x25: /* STORE32 */
|
||||||
case 0x26: /* STOREU32 */
|
case 0x26: /* STOREU32 */
|
||||||
{
|
{
|
||||||
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
|
writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: return true;
|
default: return true;
|
||||||
|
@ -1248,6 +1219,38 @@ bool eval_Integer_1OPI(struct lilith* vm, struct Instruction* c)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool eval_branch_1OPI(struct lilith* vm, struct Instruction* c)
|
||||||
|
{
|
||||||
|
switch(c->raw_XOP)
|
||||||
|
{
|
||||||
|
case 0x0: /* CALLI */
|
||||||
|
{
|
||||||
|
/* Write out the PC */
|
||||||
|
writeout_Reg(vm, vm->reg[c->reg0], vm->ip);
|
||||||
|
|
||||||
|
/* Update our index */
|
||||||
|
vm->reg[c->reg0] = vm->reg[c->reg0] + 4;
|
||||||
|
|
||||||
|
/* Update PC */
|
||||||
|
vm->ip = vm->ip + c->raw_Immediate - 4;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x1: /* LOADI */
|
||||||
|
{
|
||||||
|
vm->reg[c->reg0] = (int16_t)c->raw_Immediate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x2: /* LOADUI*/
|
||||||
|
{
|
||||||
|
vm->reg[c->reg0] = c->raw_Immediate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process 0OPI Integer instructions */
|
/* Process 0OPI Integer instructions */
|
||||||
bool eval_Integer_0OPI(struct lilith* vm, struct Instruction* c)
|
bool eval_Integer_0OPI(struct lilith* vm, struct Instruction* c)
|
||||||
{
|
{
|
||||||
|
@ -1316,6 +1319,13 @@ void eval_instruction(struct lilith* vm, struct Instruction* current)
|
||||||
if ( invalid) goto fail;
|
if ( invalid) goto fail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x2D:
|
||||||
|
{
|
||||||
|
decode_1OPI(current);
|
||||||
|
invalid = eval_branch_1OPI(vm, current);
|
||||||
|
if ( invalid) goto fail;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x3C: /* JUMP */
|
case 0x3C: /* JUMP */
|
||||||
{
|
{
|
||||||
decode_0OPI(current);
|
decode_0OPI(current);
|
||||||
|
|
12
vm.h
12
vm.h
|
@ -177,10 +177,10 @@ void unpack_instruction(struct Instruction* c)
|
||||||
c->opcode[1] = c->operation[1];
|
c->opcode[1] = c->operation[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeout_Reg(struct lilith* vm, uint32_t p, uint8_t r)
|
void writeout_Reg(struct lilith* vm, uint32_t p, uint32_t value)
|
||||||
{
|
{
|
||||||
uint8_t raw0, raw1, raw2, raw3;
|
uint8_t raw0, raw1, raw2, raw3;
|
||||||
uint32_t tmp = vm->reg[r];
|
uint32_t tmp = value;
|
||||||
raw3 = tmp%0x100;
|
raw3 = tmp%0x100;
|
||||||
tmp = tmp/0x100;
|
tmp = tmp/0x100;
|
||||||
raw2 = tmp%0x100;
|
raw2 = tmp%0x100;
|
||||||
|
@ -195,16 +195,18 @@ void writeout_Reg(struct lilith* vm, uint32_t p, uint8_t r)
|
||||||
vm->memory[p + 3] = raw3;
|
vm->memory[p + 3] = raw3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void readin_Reg(struct lilith* vm, uint32_t p, uint8_t r)
|
uint32_t readin_Reg(struct lilith* vm, uint32_t p)
|
||||||
{
|
{
|
||||||
uint8_t raw0, raw1, raw2, raw3;
|
uint8_t raw0, raw1, raw2, raw3, sum;
|
||||||
raw0 = vm->memory[p];
|
raw0 = vm->memory[p];
|
||||||
raw1 = vm->memory[p + 1];
|
raw1 = vm->memory[p + 1];
|
||||||
raw2 = vm->memory[p + 2];
|
raw2 = vm->memory[p + 2];
|
||||||
raw3 = vm->memory[p + 3];
|
raw3 = vm->memory[p + 3];
|
||||||
|
|
||||||
vm->reg[r] = raw0*0x1000000 +
|
sum = raw0*0x1000000 +
|
||||||
raw1*0x10000 +
|
raw1*0x10000 +
|
||||||
raw2*0x100 +
|
raw2*0x100 +
|
||||||
raw3;
|
raw3;
|
||||||
|
|
||||||
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue