We will deal with tests later as idea needs to be explored before integration
This commit is contained in:
parent
373e00ca47
commit
cc5219c8fa
290
vm.c
290
vm.c
|
@ -1,8 +1,278 @@
|
|||
#include "vm_instructions.c"
|
||||
#include "vm.h"
|
||||
#define DEBUG true
|
||||
|
||||
uint32_t performance_counter;
|
||||
|
||||
/* Prototypes for functions in vm_instructions.c*/
|
||||
void vm_FOPEN(struct lilith* vm);
|
||||
void vm_FCLOSE(struct lilith* vm);
|
||||
void vm_FSEEK(struct lilith* vm);
|
||||
void vm_REWIND(struct lilith* vm);
|
||||
void vm_FGETC(struct lilith* vm);
|
||||
void vm_FPUTC(struct lilith* vm);
|
||||
void ADD_CI(struct lilith* vm, struct Instruction* c);
|
||||
void ADD_CO(struct lilith* vm, struct Instruction* c);
|
||||
void ADD_CIO(struct lilith* vm, struct Instruction* c);
|
||||
void ADDU_CI(struct lilith* vm, struct Instruction* c);
|
||||
void ADDU_CO(struct lilith* vm, struct Instruction* c);
|
||||
void ADDU_CIO(struct lilith* vm, struct Instruction* c);
|
||||
void SUB_BI(struct lilith* vm, struct Instruction* c);
|
||||
void SUB_BO(struct lilith* vm, struct Instruction* c);
|
||||
void SUB_BIO(struct lilith* vm, struct Instruction* c);
|
||||
void SUBU_BI(struct lilith* vm, struct Instruction* c);
|
||||
void SUBU_BO(struct lilith* vm, struct Instruction* c);
|
||||
void SUBU_BIO(struct lilith* vm, struct Instruction* c);
|
||||
void MULTIPLY(struct lilith* vm, struct Instruction* c);
|
||||
void MULTIPLYU(struct lilith* vm, struct Instruction* c);
|
||||
void DIVIDE(struct lilith* vm, struct Instruction* c);
|
||||
void DIVIDEU(struct lilith* vm, struct Instruction* c);
|
||||
void MUX(struct lilith* vm, struct Instruction* c);
|
||||
void NMUX(struct lilith* vm, struct Instruction* c);
|
||||
void SORT(struct lilith* vm, struct Instruction* c);
|
||||
void SORTU(struct lilith* vm, struct Instruction* c);
|
||||
void ADD(struct lilith* vm, struct Instruction* c);
|
||||
void ADDU(struct lilith* vm, struct Instruction* c);
|
||||
void SUB(struct lilith* vm, struct Instruction* c);
|
||||
void SUBU(struct lilith* vm, struct Instruction* c);
|
||||
void CMP(struct lilith* vm, struct Instruction* c);
|
||||
void CMPU(struct lilith* vm, struct Instruction* c);
|
||||
void MUL(struct lilith* vm, struct Instruction* c);
|
||||
void MULH(struct lilith* vm, struct Instruction* c);
|
||||
void MULU(struct lilith* vm, struct Instruction* c);
|
||||
void MULUH(struct lilith* vm, struct Instruction* c);
|
||||
void DIV(struct lilith* vm, struct Instruction* c);
|
||||
void MOD(struct lilith* vm, struct Instruction* c);
|
||||
void DIVU(struct lilith* vm, struct Instruction* c);
|
||||
void MODU(struct lilith* vm, struct Instruction* c);
|
||||
void MAX(struct lilith* vm, struct Instruction* c);
|
||||
void MAXU(struct lilith* vm, struct Instruction* c);
|
||||
void MIN(struct lilith* vm, struct Instruction* c);
|
||||
void MINU(struct lilith* vm, struct Instruction* c);
|
||||
void PACK(struct lilith* vm, struct Instruction* c);
|
||||
void UNPACK(struct lilith* vm, struct Instruction* c);
|
||||
void PACK8_CO(struct lilith* vm, struct Instruction* c);
|
||||
void PACK8U_CO(struct lilith* vm, struct Instruction* c);
|
||||
void PACK16_CO(struct lilith* vm, struct Instruction* c);
|
||||
void PACK16U_CO(struct lilith* vm, struct Instruction* c);
|
||||
void PACK32_CO(struct lilith* vm, struct Instruction* c);
|
||||
void PACK32U_CO(struct lilith* vm, struct Instruction* c);
|
||||
void AND(struct lilith* vm, struct Instruction* c);
|
||||
void OR(struct lilith* vm, struct Instruction* c);
|
||||
void XOR(struct lilith* vm, struct Instruction* c);
|
||||
void NAND(struct lilith* vm, struct Instruction* c);
|
||||
void NOR(struct lilith* vm, struct Instruction* c);
|
||||
void XNOR(struct lilith* vm, struct Instruction* c);
|
||||
void MPQ(struct lilith* vm, struct Instruction* c);
|
||||
void LPQ(struct lilith* vm, struct Instruction* c);
|
||||
void CPQ(struct lilith* vm, struct Instruction* c);
|
||||
void BPQ(struct lilith* vm, struct Instruction* c);
|
||||
void SAL(struct lilith* vm, struct Instruction* c);
|
||||
void SAR(struct lilith* vm, struct Instruction* c);
|
||||
void SL0(struct lilith* vm, struct Instruction* c);
|
||||
void SR0(struct lilith* vm, struct Instruction* c);
|
||||
void SL1(struct lilith* vm, struct Instruction* c);
|
||||
void SR1(struct lilith* vm, struct Instruction* c);
|
||||
void ROL(struct lilith* vm, struct Instruction* c);
|
||||
void ROR(struct lilith* vm, struct Instruction* c);
|
||||
void LOADX(struct lilith* vm, struct Instruction* c);
|
||||
void LOADX8(struct lilith* vm, struct Instruction* c);
|
||||
void LOADXU8(struct lilith* vm, struct Instruction* c);
|
||||
void LOADX16(struct lilith* vm, struct Instruction* c);
|
||||
void LOADXU16(struct lilith* vm, struct Instruction* c);
|
||||
void LOADX32(struct lilith* vm, struct Instruction* c);
|
||||
void LOADXU32(struct lilith* vm, struct Instruction* c);
|
||||
void STOREX(struct lilith* vm, struct Instruction* c);
|
||||
void STOREX8(struct lilith* vm, struct Instruction* c);
|
||||
void STOREX16(struct lilith* vm, struct Instruction* c);
|
||||
void STOREX32(struct lilith* vm, struct Instruction* c);
|
||||
void NEG(struct lilith* vm, struct Instruction* c);
|
||||
void ABS(struct lilith* vm, struct Instruction* c);
|
||||
void NABS(struct lilith* vm, struct Instruction* c);
|
||||
void SWAP(struct lilith* vm, struct Instruction* c);
|
||||
void COPY(struct lilith* vm, struct Instruction* c);
|
||||
void MOVE(struct lilith* vm, struct Instruction* c);
|
||||
void BRANCH(struct lilith* vm, struct Instruction* c);
|
||||
void CALL(struct lilith* vm, struct Instruction* c);
|
||||
void READPC(struct lilith* vm, struct Instruction* c);
|
||||
void READSCID(struct lilith* vm, struct Instruction* c);
|
||||
void FALSE(struct lilith* vm, struct Instruction* c);
|
||||
void TRUE(struct lilith* vm, struct Instruction* c);
|
||||
void JSR_COROUTINE(struct lilith* vm, struct Instruction* c);
|
||||
void RET(struct lilith* vm, struct Instruction* c);
|
||||
void PUSHPC(struct lilith* vm, struct Instruction* c);
|
||||
void POPPC(struct lilith* vm, struct Instruction* c);
|
||||
void ADDI(struct lilith* vm, struct Instruction* c);
|
||||
void ADDUI(struct lilith* vm, struct Instruction* c);
|
||||
void SUBI(struct lilith* vm, struct Instruction* c);
|
||||
void SUBUI(struct lilith* vm, struct Instruction* c);
|
||||
void CMPI(struct lilith* vm, struct Instruction* c);
|
||||
void LOAD(struct lilith* vm, struct Instruction* c);
|
||||
void LOAD8(struct lilith* vm, struct Instruction* c);
|
||||
void LOADU8(struct lilith* vm, struct Instruction* c);
|
||||
void LOAD16(struct lilith* vm, struct Instruction* c);
|
||||
void LOADU16(struct lilith* vm, struct Instruction* c);
|
||||
void LOAD32(struct lilith* vm, struct Instruction* c);
|
||||
void LOADU32(struct lilith* vm, struct Instruction* c);
|
||||
void CMPUI(struct lilith* vm, struct Instruction* c);
|
||||
void STORE(struct lilith* vm, struct Instruction* c);
|
||||
void STORE8(struct lilith* vm, struct Instruction* c);
|
||||
void STORE16(struct lilith* vm, struct Instruction* c);
|
||||
void STORE32(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_C(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_B(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_O(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_G(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_GE(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_E(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_NE(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_LE(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_L(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_Z(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP_NZ(struct lilith* vm, struct Instruction* c);
|
||||
void CALLI(struct lilith* vm, struct Instruction* c);
|
||||
void LOADI(struct lilith* vm, struct Instruction* c);
|
||||
void LOADUI(struct lilith* vm, struct Instruction* c);
|
||||
void SALI(struct lilith* vm, struct Instruction* c);
|
||||
void SARI(struct lilith* vm, struct Instruction* c);
|
||||
void SL0I(struct lilith* vm, struct Instruction* c);
|
||||
void SR0I(struct lilith* vm, struct Instruction* c);
|
||||
void SL1I(struct lilith* vm, struct Instruction* c);
|
||||
void SR1I(struct lilith* vm, struct Instruction* c);
|
||||
void JUMP(struct lilith* vm, struct Instruction* c);
|
||||
|
||||
/* Allocate and intialize memory/state */
|
||||
struct lilith* create_vm(size_t size)
|
||||
{
|
||||
struct lilith* vm;
|
||||
vm = calloc(1, sizeof(struct lilith));
|
||||
vm->memory = calloc(size, sizeof(uint8_t));
|
||||
vm->halted = false;
|
||||
vm->exception = false;
|
||||
return vm;
|
||||
}
|
||||
|
||||
/* Free up the memory we previously allocated */
|
||||
void destroy_vm(struct lilith* vm)
|
||||
{
|
||||
free(vm->memory);
|
||||
free(vm);
|
||||
}
|
||||
|
||||
/* Deal with 4OP */
|
||||
void decode_4OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw2/16;
|
||||
c->reg1 = c->raw2%16;
|
||||
c->reg2 = c->raw3/16;
|
||||
c->reg3 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 3OP */
|
||||
void decode_3OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1*0x10 + c->raw2/16;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->XOP[2] = c->operation[4];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw2%16;
|
||||
c->reg1 = c->raw3/16;
|
||||
c->reg2 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 2OP */
|
||||
void decode_2OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1*0x100 + c->raw2;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->XOP[2] = c->operation[4];
|
||||
c->XOP[3] = c->operation[5];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw3/16;
|
||||
c->reg1 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 1OP */
|
||||
void decode_1OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1*0x1000 + c->raw2*0x10 + c->raw3/16;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->XOP[2] = c->operation[4];
|
||||
c->XOP[3] = c->operation[5];
|
||||
c->XOP[4] = c->operation[6];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 2OPI */
|
||||
void decode_2OPI(struct Instruction* c)
|
||||
{
|
||||
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||
c->Immediate[0] = c->operation[4];
|
||||
c->Immediate[1] = c->operation[5];
|
||||
c->Immediate[2] = c->operation[6];
|
||||
c->Immediate[3] = c->operation[7];
|
||||
c->reg0 = c->raw1/16;
|
||||
c->reg1 = c->raw1%16;
|
||||
}
|
||||
|
||||
/* Deal with 1OPI */
|
||||
void decode_1OPI(struct Instruction* c)
|
||||
{
|
||||
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||
c->Immediate[0] = c->operation[4];
|
||||
c->Immediate[1] = c->operation[5];
|
||||
c->Immediate[2] = c->operation[6];
|
||||
c->Immediate[3] = c->operation[7];
|
||||
c->HAL_CODE = 0;
|
||||
c->raw_XOP = c->raw1/16;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->reg0 = c->raw1%16;
|
||||
}
|
||||
/* Deal with 0OPI */
|
||||
void decode_0OPI(struct Instruction* c)
|
||||
{
|
||||
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||
c->Immediate[0] = c->operation[4];
|
||||
c->Immediate[1] = c->operation[5];
|
||||
c->Immediate[2] = c->operation[6];
|
||||
c->Immediate[3] = c->operation[7];
|
||||
c->HAL_CODE = 0;
|
||||
c->raw_XOP = c->raw1;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
}
|
||||
|
||||
/* Deal with Halcode */
|
||||
void decode_HALCODE(struct Instruction* c)
|
||||
{
|
||||
c->HAL_CODE = c->raw1*0x10000 + c->raw2*0x100 + c->raw3;
|
||||
}
|
||||
|
||||
/* Useful unpacking functions */
|
||||
void unpack_byte(uint8_t a, char* c)
|
||||
{
|
||||
char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
|
||||
c[0] = table[a / 16];
|
||||
c[1] = table[a % 16];
|
||||
}
|
||||
|
||||
/* Unpack the full instruction */
|
||||
void unpack_instruction(struct Instruction* c)
|
||||
{
|
||||
unpack_byte(c->raw0, &(c->operation[0]));
|
||||
unpack_byte(c->raw1, &(c->operation[2]));
|
||||
unpack_byte(c->raw2, &(c->operation[4]));
|
||||
unpack_byte(c->raw3, &(c->operation[6]));
|
||||
c->opcode[0] = c->operation[0];
|
||||
c->opcode[1] = c->operation[1];
|
||||
}
|
||||
|
||||
/* Load program tape into Memory */
|
||||
void load_program(struct lilith* vm, char **argv)
|
||||
{
|
||||
|
@ -823,8 +1093,6 @@ bool eval_3OP_Int(struct lilith* vm, struct Instruction* c)
|
|||
/* Process 2OP Integer instructions */
|
||||
bool eval_2OP_Int(struct lilith* vm, struct Instruction* c)
|
||||
{
|
||||
int32_t tmp1 = (int32_t)(vm->reg[c->reg1]);
|
||||
uint32_t utmp1 = vm->reg[c->reg1];
|
||||
#ifdef DEBUG
|
||||
char Name[20] = "ILLEGAL_2OP";
|
||||
#endif
|
||||
|
@ -917,6 +1185,7 @@ bool eval_1OP_Int(struct lilith* vm, struct Instruction* c)
|
|||
#ifdef DEBUG
|
||||
char Name[20] = "ILLEGAL_1OP";
|
||||
#endif
|
||||
|
||||
switch(c->raw_XOP)
|
||||
{
|
||||
case 0x00000: /* READPC */
|
||||
|
@ -1173,21 +1442,10 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
|
|||
/* Process 1OPI Integer instructions */
|
||||
bool eval_Integer_1OPI(struct lilith* vm, struct Instruction* c)
|
||||
{
|
||||
bool C, B, O, GT, EQ, LT;
|
||||
uint32_t tmp;
|
||||
#ifdef DEBUG
|
||||
char Name[20] = "ILLEGAL_1OPI";
|
||||
#endif
|
||||
|
||||
tmp = vm->reg[c->reg0];
|
||||
|
||||
C = tmp & Carry;
|
||||
B = tmp & Borrow;
|
||||
O = tmp & Overflow;
|
||||
GT = tmp & GreaterThan;
|
||||
EQ = tmp & EQual;
|
||||
LT = tmp & LessThan;
|
||||
|
||||
/* 0x2C */
|
||||
switch(c->raw_XOP)
|
||||
{
|
||||
|
@ -1303,6 +1561,7 @@ bool eval_branch_1OPI(struct lilith* vm, struct Instruction* c)
|
|||
#ifdef DEBUG
|
||||
char Name[20] = "ILLEGAL_1OPI";
|
||||
#endif
|
||||
|
||||
switch(c->raw_XOP)
|
||||
{
|
||||
case 0x0: /* CALLI */
|
||||
|
@ -1400,6 +1659,7 @@ bool eval_Integer_0OPI(struct lilith* vm, struct Instruction* c)
|
|||
#ifdef DEBUG
|
||||
char Name[20] = "ILLEGAL_0OPI";
|
||||
#endif
|
||||
|
||||
switch(c->raw_XOP)
|
||||
{
|
||||
case 0x00: /* JUMP */
|
||||
|
|
271
vm.h
271
vm.h
|
@ -32,274 +32,3 @@ struct Instruction
|
|||
uint8_t reg3;
|
||||
bool invalid;
|
||||
};
|
||||
|
||||
/* Condition Codes */
|
||||
enum condition
|
||||
{
|
||||
Carry = (1 << 5),
|
||||
Borrow = (1 << 4),
|
||||
Overflow = (1 << 3),
|
||||
GreaterThan = (1 << 2),
|
||||
EQual = (1 << 1),
|
||||
LessThan = 1
|
||||
};
|
||||
|
||||
/* Allocate and intialize memory/state */
|
||||
struct lilith* create_vm(size_t size)
|
||||
{
|
||||
struct lilith* vm;
|
||||
vm = calloc(1, sizeof(struct lilith));
|
||||
vm->memory = calloc(size, sizeof(uint8_t));
|
||||
vm->halted = false;
|
||||
vm->exception = false;
|
||||
return vm;
|
||||
}
|
||||
|
||||
/* Free up the memory we previously allocated */
|
||||
void destroy_vm(struct lilith* vm)
|
||||
{
|
||||
free(vm->memory);
|
||||
free(vm);
|
||||
}
|
||||
|
||||
/* Deal with 4OP */
|
||||
void decode_4OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw2/16;
|
||||
c->reg1 = c->raw2%16;
|
||||
c->reg2 = c->raw3/16;
|
||||
c->reg3 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 3OP */
|
||||
void decode_3OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1*0x10 + c->raw2/16;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->XOP[2] = c->operation[4];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw2%16;
|
||||
c->reg1 = c->raw3/16;
|
||||
c->reg2 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 2OP */
|
||||
void decode_2OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1*0x100 + c->raw2;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->XOP[2] = c->operation[4];
|
||||
c->XOP[3] = c->operation[5];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw3/16;
|
||||
c->reg1 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 1OP */
|
||||
void decode_1OP(struct Instruction* c)
|
||||
{
|
||||
c->raw_XOP = c->raw1*0x1000 + c->raw2*0x10 + c->raw3/16;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
c->XOP[2] = c->operation[4];
|
||||
c->XOP[3] = c->operation[5];
|
||||
c->XOP[4] = c->operation[6];
|
||||
c->raw_Immediate = 0;
|
||||
c->reg0 = c->raw3%16;
|
||||
}
|
||||
|
||||
/* Deal with 2OPI */
|
||||
void decode_2OPI(struct Instruction* c)
|
||||
{
|
||||
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||
c->Immediate[0] = c->operation[4];
|
||||
c->Immediate[1] = c->operation[5];
|
||||
c->Immediate[2] = c->operation[6];
|
||||
c->Immediate[3] = c->operation[7];
|
||||
c->reg0 = c->raw1/16;
|
||||
c->reg1 = c->raw1%16;
|
||||
}
|
||||
|
||||
/* Deal with 1OPI */
|
||||
void decode_1OPI(struct Instruction* c)
|
||||
{
|
||||
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||
c->Immediate[0] = c->operation[4];
|
||||
c->Immediate[1] = c->operation[5];
|
||||
c->Immediate[2] = c->operation[6];
|
||||
c->Immediate[3] = c->operation[7];
|
||||
c->HAL_CODE = 0;
|
||||
c->raw_XOP = c->raw1/16;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->reg0 = c->raw1%16;
|
||||
}
|
||||
/* Deal with 0OPI */
|
||||
void decode_0OPI(struct Instruction* c)
|
||||
{
|
||||
c->raw_Immediate = c->raw2*0x100 + c->raw3;
|
||||
c->Immediate[0] = c->operation[4];
|
||||
c->Immediate[1] = c->operation[5];
|
||||
c->Immediate[2] = c->operation[6];
|
||||
c->Immediate[3] = c->operation[7];
|
||||
c->HAL_CODE = 0;
|
||||
c->raw_XOP = c->raw1;
|
||||
c->XOP[0] = c->operation[2];
|
||||
c->XOP[1] = c->operation[3];
|
||||
}
|
||||
|
||||
/* Deal with Halcode */
|
||||
void decode_HALCODE(struct Instruction* c)
|
||||
{
|
||||
c->HAL_CODE = c->raw1*0x10000 + c->raw2*0x100 + c->raw3;
|
||||
}
|
||||
|
||||
/* Useful unpacking functions */
|
||||
void unpack_byte(uint8_t a, char* c)
|
||||
{
|
||||
char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
|
||||
c[0] = table[a / 16];
|
||||
c[1] = table[a % 16];
|
||||
}
|
||||
|
||||
/* Unpack the full instruction */
|
||||
void unpack_instruction(struct Instruction* c)
|
||||
{
|
||||
unpack_byte(c->raw0, &(c->operation[0]));
|
||||
unpack_byte(c->raw1, &(c->operation[2]));
|
||||
unpack_byte(c->raw2, &(c->operation[4]));
|
||||
unpack_byte(c->raw3, &(c->operation[6]));
|
||||
c->opcode[0] = c->operation[0];
|
||||
c->opcode[1] = c->operation[1];
|
||||
}
|
||||
|
||||
/* Correctly write out bytes on little endian hardware */
|
||||
void writeout_Reg(struct lilith* vm, uint32_t p, uint32_t value)
|
||||
{
|
||||
uint8_t raw0, raw1, raw2, raw3;
|
||||
uint32_t tmp = value;
|
||||
raw3 = tmp%0x100;
|
||||
tmp = tmp/0x100;
|
||||
raw2 = tmp%0x100;
|
||||
tmp = tmp/0x100;
|
||||
raw1 = tmp%0x100;
|
||||
tmp = tmp/0x100;
|
||||
raw0 = tmp%0x100;
|
||||
|
||||
vm->memory[p] = raw0;
|
||||
vm->memory[p + 1] = raw1;
|
||||
vm->memory[p + 2] = raw2;
|
||||
vm->memory[p + 3] = raw3;
|
||||
}
|
||||
|
||||
/* Allow the use of native data format for Register operations */
|
||||
uint32_t readin_Reg(struct lilith* vm, uint32_t p)
|
||||
{
|
||||
uint8_t raw0, raw1, raw2, raw3;
|
||||
uint32_t sum;
|
||||
raw0 = vm->memory[p];
|
||||
raw1 = vm->memory[p + 1];
|
||||
raw2 = vm->memory[p + 2];
|
||||
raw3 = vm->memory[p + 3];
|
||||
|
||||
sum = raw0*0x1000000 +
|
||||
raw1*0x10000 +
|
||||
raw2*0x100 +
|
||||
raw3;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Unify byte write functionality */
|
||||
void writeout_byte(struct lilith* vm, uint32_t p, uint32_t value)
|
||||
{
|
||||
vm->memory[p] = (uint8_t)(value%0x100);
|
||||
}
|
||||
|
||||
/* Unify byte read functionality*/
|
||||
uint32_t readin_byte(struct lilith* vm, uint32_t p, bool Signed)
|
||||
{
|
||||
if(Signed)
|
||||
{
|
||||
int32_t raw0;
|
||||
raw0 = (int8_t)(vm->memory[p]);
|
||||
return (uint32_t)(raw0);
|
||||
}
|
||||
|
||||
return (uint32_t)(vm->memory[p]);
|
||||
}
|
||||
|
||||
/* Unify doublebyte write functionality */
|
||||
void writeout_doublebyte(struct lilith* vm, uint32_t p, uint32_t value)
|
||||
{
|
||||
uint8_t uraw0, uraw1;
|
||||
uint32_t utmp = value;
|
||||
utmp = utmp%0x10000;
|
||||
uraw1 = utmp%0x100;
|
||||
utmp = utmp/0x100;
|
||||
uraw0 = utmp%0x100;
|
||||
|
||||
vm->memory[p] = uraw0;
|
||||
vm->memory[p + 1] = uraw1;
|
||||
}
|
||||
|
||||
/* Unify doublebyte read functionality*/
|
||||
uint32_t readin_doublebyte(struct lilith* vm, uint32_t p, bool Signed)
|
||||
{
|
||||
if(Signed)
|
||||
{
|
||||
int8_t raw0, raw1;
|
||||
int32_t sum;
|
||||
raw0 = vm->memory[p];
|
||||
raw1 = vm->memory[p + 1];
|
||||
|
||||
sum = raw0*0x100 + raw1;
|
||||
return (uint32_t)(sum);
|
||||
}
|
||||
|
||||
uint8_t uraw0, uraw1;
|
||||
uint32_t usum;
|
||||
uraw0 = vm->memory[p];
|
||||
uraw1 = vm->memory[p + 1];
|
||||
|
||||
usum = uraw0*0x100 + uraw1;
|
||||
return usum;
|
||||
}
|
||||
|
||||
/* Determine the result of bit shifting */
|
||||
uint32_t shift_register(uint32_t source, uint32_t amount, bool left, bool zero)
|
||||
{
|
||||
uint32_t tmp = source;
|
||||
|
||||
if(left)
|
||||
{
|
||||
while( amount > 0 )
|
||||
{
|
||||
tmp = tmp * 2;
|
||||
amount = amount - 1;
|
||||
if(!zero)
|
||||
{
|
||||
tmp = tmp + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( amount > 0 )
|
||||
{
|
||||
tmp = tmp / 2;
|
||||
amount = amount - 1;
|
||||
if(!zero)
|
||||
{
|
||||
tmp = tmp | (1 << 31);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,132 @@
|
|||
FILE* tape_01;
|
||||
FILE* tape_02;
|
||||
|
||||
/* Correctly write out bytes on little endian hardware */
|
||||
void writeout_Reg(struct lilith* vm, uint32_t p, uint32_t value)
|
||||
{
|
||||
uint8_t raw0, raw1, raw2, raw3;
|
||||
uint32_t tmp = value;
|
||||
raw3 = tmp%0x100;
|
||||
tmp = tmp/0x100;
|
||||
raw2 = tmp%0x100;
|
||||
tmp = tmp/0x100;
|
||||
raw1 = tmp%0x100;
|
||||
tmp = tmp/0x100;
|
||||
raw0 = tmp%0x100;
|
||||
|
||||
vm->memory[p] = raw0;
|
||||
vm->memory[p + 1] = raw1;
|
||||
vm->memory[p + 2] = raw2;
|
||||
vm->memory[p + 3] = raw3;
|
||||
}
|
||||
|
||||
/* Allow the use of native data format for Register operations */
|
||||
uint32_t readin_Reg(struct lilith* vm, uint32_t p)
|
||||
{
|
||||
uint8_t raw0, raw1, raw2, raw3;
|
||||
uint32_t sum;
|
||||
raw0 = vm->memory[p];
|
||||
raw1 = vm->memory[p + 1];
|
||||
raw2 = vm->memory[p + 2];
|
||||
raw3 = vm->memory[p + 3];
|
||||
|
||||
sum = raw0*0x1000000 +
|
||||
raw1*0x10000 +
|
||||
raw2*0x100 +
|
||||
raw3;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Unify byte write functionality */
|
||||
void writeout_byte(struct lilith* vm, uint32_t p, uint32_t value)
|
||||
{
|
||||
vm->memory[p] = (uint8_t)(value%0x100);
|
||||
}
|
||||
|
||||
/* Unify byte read functionality*/
|
||||
uint32_t readin_byte(struct lilith* vm, uint32_t p, bool Signed)
|
||||
{
|
||||
if(Signed)
|
||||
{
|
||||
int32_t raw0;
|
||||
raw0 = (int8_t)(vm->memory[p]);
|
||||
return (uint32_t)(raw0);
|
||||
}
|
||||
|
||||
return (uint32_t)(vm->memory[p]);
|
||||
}
|
||||
|
||||
/* Unify doublebyte write functionality */
|
||||
void writeout_doublebyte(struct lilith* vm, uint32_t p, uint32_t value)
|
||||
{
|
||||
uint8_t uraw0, uraw1;
|
||||
uint32_t utmp = value;
|
||||
utmp = utmp%0x10000;
|
||||
uraw1 = utmp%0x100;
|
||||
utmp = utmp/0x100;
|
||||
uraw0 = utmp%0x100;
|
||||
|
||||
vm->memory[p] = uraw0;
|
||||
vm->memory[p + 1] = uraw1;
|
||||
}
|
||||
|
||||
/* Unify doublebyte read functionality*/
|
||||
uint32_t readin_doublebyte(struct lilith* vm, uint32_t p, bool Signed)
|
||||
{
|
||||
if(Signed)
|
||||
{
|
||||
int8_t raw0, raw1;
|
||||
int32_t sum;
|
||||
raw0 = vm->memory[p];
|
||||
raw1 = vm->memory[p + 1];
|
||||
|
||||
sum = raw0*0x100 + raw1;
|
||||
return (uint32_t)(sum);
|
||||
}
|
||||
|
||||
uint8_t uraw0, uraw1;
|
||||
uint32_t usum;
|
||||
uraw0 = vm->memory[p];
|
||||
uraw1 = vm->memory[p + 1];
|
||||
|
||||
usum = uraw0*0x100 + uraw1;
|
||||
return usum;
|
||||
}
|
||||
|
||||
/* Determine the result of bit shifting */
|
||||
uint32_t shift_register(uint32_t source, uint32_t amount, bool left, bool zero)
|
||||
{
|
||||
uint32_t tmp = source;
|
||||
|
||||
if(left)
|
||||
{
|
||||
while( amount > 0 )
|
||||
{
|
||||
tmp = tmp * 2;
|
||||
amount = amount - 1;
|
||||
if(!zero)
|
||||
{
|
||||
tmp = tmp + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( amount > 0 )
|
||||
{
|
||||
tmp = tmp / 2;
|
||||
amount = amount - 1;
|
||||
if(!zero)
|
||||
{
|
||||
tmp = tmp | (1 << 31);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void vm_FOPEN(struct lilith* vm)
|
||||
{
|
||||
if(0x00001100 == vm->reg[0])
|
||||
|
@ -96,6 +222,17 @@ void vm_FPUTC(struct lilith* vm)
|
|||
}
|
||||
}
|
||||
|
||||
/* Condition Codes */
|
||||
enum condition
|
||||
{
|
||||
Carry = (1 << 5),
|
||||
Borrow = (1 << 4),
|
||||
Overflow = (1 << 3),
|
||||
GreaterThan = (1 << 2),
|
||||
EQual = (1 << 1),
|
||||
LessThan = 1
|
||||
};
|
||||
|
||||
bool Carry_bit_set(uint32_t a)
|
||||
{
|
||||
return a & Carry;
|
||||
|
@ -1379,7 +1516,6 @@ void LOADUI(struct lilith* vm, struct Instruction* c)
|
|||
vm->reg[c->reg0] = c->raw_Immediate;
|
||||
}
|
||||
|
||||
|
||||
void SALI(struct lilith* vm, struct Instruction* c)
|
||||
{
|
||||
vm->reg[c->reg0] = vm->reg[c->reg0] << c->raw_Immediate;
|
||||
|
|
20
vm_tests.c
20
vm_tests.c
|
@ -1,20 +0,0 @@
|
|||
#include "vm_instructions.c"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Make sure we have a program tape to run */
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s $FileName\nWhere $FileName is the name of the paper tape of the program being run\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Perform all the essential stages in order */
|
||||
struct lilith* vm;
|
||||
vm = create_vm(1 << 20);
|
||||
struct Instruction* c = calloc(1, sizeof(struct Instruction));
|
||||
|
||||
destroy_vm(vm);
|
||||
free(c);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue