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
|
||||
|
||||
*** Conditional Integer Jumps
|
||||
2C 0a ii ii # JUMP.C a i 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 2a ii ii # JUMP.O a i 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 4a ii ii # JUMP.GE a i 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 6a ii ii # JUMP.NE a i 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 8a ii ii # JUMP.L a i 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 Aa ii ii # JUMP.NZ a i ii ii :: NZERO? 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 ii ii :: Borrow? 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 ii ii :: GT? 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 ii ii :: EQ? 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 ii ii :: LT? a | EQ? 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 ii ii :: ZERO? 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 Cx xx xx # Reserved
|
||||
2C Dx xx xx # Reserved
|
||||
2C Ex 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 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.Z", "2C9", 4);
|
||||
setExpression(p, "JUMP.NZ", "2CA", 4);
|
||||
setExpression(p, "CALLI", "2D0", 4);
|
||||
setExpression(p, "LOADI", "2D1", 4);
|
||||
setExpression(p, "LOADUI", "2D2", 4);
|
||||
|
||||
/* 0OPI Group */
|
||||
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 */
|
||||
{
|
||||
strncpy(Name, "", 19);
|
||||
strncpy(Name, "CMPI", 19);
|
||||
break;
|
||||
}
|
||||
case 0x13: /* LOAD */
|
||||
|
@ -824,6 +824,49 @@ void decode_1OPI(struct Instruction* c)
|
|||
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)
|
||||
{
|
||||
/* Parse Raw Data */
|
||||
|
@ -941,6 +984,11 @@ void eval_instruction(struct Instruction* c)
|
|||
decode_1OPI(c);
|
||||
break;
|
||||
}
|
||||
case 0x2D: /* Branch 1OPI*/
|
||||
{
|
||||
decode_Branch_1OPI(c);
|
||||
break;
|
||||
}
|
||||
case 0x3C: /* Core 0OPI */
|
||||
{
|
||||
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 */
|
||||
{
|
||||
/* 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 */
|
||||
writeout_Reg(vm, utmp1, c->reg1);
|
||||
|
||||
/* Restore our index */
|
||||
vm->reg[c->reg1] = utmp1;
|
||||
writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
|
||||
|
||||
/* Update PC */
|
||||
vm->ip = vm->reg[c->reg0];
|
||||
|
@ -856,17 +847,11 @@ bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
|
|||
}
|
||||
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 */
|
||||
writeout_Reg(vm, utmp1, c->reg1);
|
||||
writeout_Reg(vm, vm->reg[c->reg1], vm->ip);
|
||||
|
||||
/* Update our index */
|
||||
vm->reg[c->reg1] = utmp1 + 4;
|
||||
vm->reg[c->reg1] = vm->reg[c->reg1] + 4;
|
||||
|
||||
/* Update PC */
|
||||
vm->ip = vm->reg[c->reg0];
|
||||
|
@ -910,43 +895,29 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
|
|||
}
|
||||
case 0x01001: /* RET */
|
||||
{
|
||||
/* Preserve index */
|
||||
uint32_t utmp1 = vm->reg[c->reg0];
|
||||
|
||||
/* Read in the new PC */
|
||||
readin_Reg(vm, utmp1, c->reg0);
|
||||
vm->ip = vm->reg[c->reg0];
|
||||
vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
|
||||
|
||||
/* Update our index */
|
||||
vm->reg[c->reg0] = utmp1 - 4;
|
||||
vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
|
||||
break;
|
||||
}
|
||||
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 */
|
||||
writeout_Reg(vm, utmp1, c->reg0);
|
||||
writeout_Reg(vm, vm->reg[c->reg0], vm->ip);
|
||||
|
||||
/* Update our index */
|
||||
vm->reg[c->reg0] = utmp1 + 4;
|
||||
vm->reg[c->reg0] = vm->reg[c->reg0] + 4;
|
||||
break;
|
||||
}
|
||||
case 0x02001: /* POPPC */
|
||||
{
|
||||
/* Preserve index */
|
||||
uint32_t utmp1 = vm->reg[c->reg0];
|
||||
|
||||
/* Read in the new PC */
|
||||
readin_Reg(vm, utmp1, c->reg0);
|
||||
vm->ip = vm->reg[c->reg0];
|
||||
vm->ip = readin_Reg(vm, vm->reg[c->reg0]);
|
||||
|
||||
/* Update our index */
|
||||
vm->reg[c->reg0] = utmp1 - 4;
|
||||
vm->reg[c->reg0] = vm->reg[c->reg0] - 4;
|
||||
break;
|
||||
}
|
||||
default: return true;
|
||||
|
@ -1007,7 +978,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
|||
}
|
||||
case 0x13: /* LOAD */
|
||||
{
|
||||
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
|
||||
vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
|
||||
break;
|
||||
}
|
||||
case 0x14: /* LOAD8 */
|
||||
|
@ -1051,7 +1022,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
|||
case 0x18: /* LOAD32 */
|
||||
case 0x19: /* LOADU32 */
|
||||
{
|
||||
readin_Reg(vm, (utmp1 + c->raw_Immediate) , c->reg0);
|
||||
vm->reg[c->reg0] = readin_Reg(vm, (utmp1 + c->raw_Immediate));
|
||||
break;
|
||||
}
|
||||
case 0x1F: /* CMPUI */
|
||||
|
@ -1074,7 +1045,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
|||
}
|
||||
case 0x20: /* STORE */
|
||||
{
|
||||
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
|
||||
writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
|
||||
break;
|
||||
}
|
||||
case 0x21: /* STORE8 */
|
||||
|
@ -1118,7 +1089,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
|||
case 0x25: /* STORE32 */
|
||||
case 0x26: /* STOREU32 */
|
||||
{
|
||||
writeout_Reg(vm, (utmp1 + c->raw_Immediate), c->reg0);
|
||||
writeout_Reg(vm, (utmp1 + c->raw_Immediate), vm->reg[c->reg0]);
|
||||
break;
|
||||
}
|
||||
default: return true;
|
||||
|
@ -1248,6 +1219,38 @@ bool eval_Integer_1OPI(struct lilith* vm, struct Instruction* c)
|
|||
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 */
|
||||
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;
|
||||
break;
|
||||
}
|
||||
case 0x2D:
|
||||
{
|
||||
decode_1OPI(current);
|
||||
invalid = eval_branch_1OPI(vm, current);
|
||||
if ( invalid) goto fail;
|
||||
break;
|
||||
}
|
||||
case 0x3C: /* JUMP */
|
||||
{
|
||||
decode_0OPI(current);
|
||||
|
|
18
vm.h
18
vm.h
|
@ -177,10 +177,10 @@ void unpack_instruction(struct Instruction* c)
|
|||
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;
|
||||
uint32_t tmp = vm->reg[r];
|
||||
uint32_t tmp = value;
|
||||
raw3 = tmp%0x100;
|
||||
tmp = 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;
|
||||
}
|
||||
|
||||
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];
|
||||
raw1 = vm->memory[p + 1];
|
||||
raw2 = vm->memory[p + 2];
|
||||
raw3 = vm->memory[p + 3];
|
||||
|
||||
vm->reg[r] = raw0*0x1000000 +
|
||||
raw1*0x10000 +
|
||||
raw2*0x100 +
|
||||
raw3;
|
||||
sum = raw0*0x1000000 +
|
||||
raw1*0x10000 +
|
||||
raw2*0x100 +
|
||||
raw3;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue