ISA completo
This commit is contained in:
parent
020a5062a2
commit
1490a6e6fc
@ -258,6 +258,8 @@ class VMInstruction:
|
|||||||
def __init__(self, opcode, instr_list):
|
def __init__(self, opcode, instr_list):
|
||||||
immediate_regexp = re.compile("^(0x*|[0-9]*$)")
|
immediate_regexp = re.compile("^(0x*|[0-9]*$)")
|
||||||
self.opcode = next((x for x in ops if x.name == opcode), None)
|
self.opcode = next((x for x in ops if x.name == opcode), None)
|
||||||
|
if self.opcode == None:
|
||||||
|
raise InvalidOperation(opcode)
|
||||||
self.args = []
|
self.args = []
|
||||||
for el in instr_list:
|
for el in instr_list:
|
||||||
if not immediate_regexp.match(el):
|
if not immediate_regexp.match(el):
|
||||||
@ -279,6 +281,12 @@ op_names = [["MOVI", "imm2reg"],
|
|||||||
["ADDR", "reg2reg"],
|
["ADDR", "reg2reg"],
|
||||||
["SUBI", "imm2reg"],
|
["SUBI", "imm2reg"],
|
||||||
["SUBR", "reg2reg"],
|
["SUBR", "reg2reg"],
|
||||||
|
["ANDB", "byt2reg"],
|
||||||
|
["ANDW", "imm2reg"],
|
||||||
|
["ANDR", "reg2reg"],
|
||||||
|
["YORB", "byt2reg"],
|
||||||
|
["YORW", "imm2reg"],
|
||||||
|
["YORR", "reg2reg"],
|
||||||
["XORB", "byt2reg"],
|
["XORB", "byt2reg"],
|
||||||
["XORW", "imm2reg"],
|
["XORW", "imm2reg"],
|
||||||
["XORR", "reg2reg"],
|
["XORR", "reg2reg"],
|
||||||
@ -299,6 +307,8 @@ op_names = [["MOVI", "imm2reg"],
|
|||||||
["JPBR", "regonly"],
|
["JPBR", "regonly"],
|
||||||
["JPEI", "immonly"],
|
["JPEI", "immonly"],
|
||||||
["JPER", "regonly"],
|
["JPER", "regonly"],
|
||||||
|
["JPNI", "immonly"],
|
||||||
|
["JPNR", "regonly"],
|
||||||
["SHIT", "single"],
|
["SHIT", "single"],
|
||||||
["NOPE", "single"],
|
["NOPE", "single"],
|
||||||
["GRMN", "single"]]
|
["GRMN", "single"]]
|
||||||
|
16
vm/opcodes.h
16
vm/opcodes.h
@ -10,6 +10,12 @@ enum OPS_STARTING_VALUES {
|
|||||||
ADDR,
|
ADDR,
|
||||||
SUBI,
|
SUBI,
|
||||||
SUBR,
|
SUBR,
|
||||||
|
ANDB,
|
||||||
|
ANDW,
|
||||||
|
ANDR,
|
||||||
|
YORB,
|
||||||
|
YORW,
|
||||||
|
YORR,
|
||||||
XORB,
|
XORB,
|
||||||
XORW,
|
XORW,
|
||||||
XORR,
|
XORR,
|
||||||
@ -30,6 +36,8 @@ enum OPS_STARTING_VALUES {
|
|||||||
JPBR,
|
JPBR,
|
||||||
JPEI,
|
JPEI,
|
||||||
JPER,
|
JPER,
|
||||||
|
JPNI,
|
||||||
|
JPNR,
|
||||||
SHIT,
|
SHIT,
|
||||||
NOPE,
|
NOPE,
|
||||||
GRMN,
|
GRMN,
|
||||||
@ -60,6 +68,12 @@ INSTRUCTION SIZES
|
|||||||
#define ADDR_SIZE REG2REG
|
#define ADDR_SIZE REG2REG
|
||||||
#define SUBI_SIZE IMM2REG
|
#define SUBI_SIZE IMM2REG
|
||||||
#define SUBR_SIZE REG2REG
|
#define SUBR_SIZE REG2REG
|
||||||
|
#define ANDB_SIZE BYT2REG
|
||||||
|
#define ANDW_SIZE IMM2REG
|
||||||
|
#define ANDR_SIZE REG2REG
|
||||||
|
#define YORB_SIZE BYT2REG
|
||||||
|
#define YORW_SIZE IMM2REG
|
||||||
|
#define YORR_SIZE REG2REG
|
||||||
#define XORB_SIZE BYT2REG
|
#define XORB_SIZE BYT2REG
|
||||||
#define XORW_SIZE IMM2REG
|
#define XORW_SIZE IMM2REG
|
||||||
#define XORR_SIZE REG2REG
|
#define XORR_SIZE REG2REG
|
||||||
@ -80,6 +94,8 @@ INSTRUCTION SIZES
|
|||||||
#define JPBR_SIZE REGONLY
|
#define JPBR_SIZE REGONLY
|
||||||
#define JPEI_SIZE IMMONLY
|
#define JPEI_SIZE IMMONLY
|
||||||
#define JPER_SIZE REGONLY
|
#define JPER_SIZE REGONLY
|
||||||
|
#define JPNI_SIZE IMMONLY
|
||||||
|
#define JPNR_SIZE REGONLY
|
||||||
#define SHIT_SIZE SINGLE
|
#define SHIT_SIZE SINGLE
|
||||||
#define NOPE_SIZE SINGLE
|
#define NOPE_SIZE SINGLE
|
||||||
#define GRMN_SIZE SINGLE
|
#define GRMN_SIZE SINGLE
|
397
vm/vm.cpp
397
vm/vm.cpp
@ -14,7 +14,7 @@ void VM::defineOpcodes(uint8_t *key) {
|
|||||||
keysize = strlen((char *)key);
|
keysize = strlen((char *)key);
|
||||||
for (i = 0; i < keysize; i++) {
|
for (i = 0; i < keysize; i++) {
|
||||||
for (j = 0; j < NUM_OPS; j++) {
|
for (j = 0; j < NUM_OPS; j++) {
|
||||||
OPS[j] = rol(key[i] ^ OPS[j], key[i] % 8, 8);
|
OPS[j] = rol(key[i] ^ OPS[j], key[i] % 8, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < NUM_OPS; i++) {
|
for (i = 0; i < NUM_OPS; i++) {
|
||||||
@ -123,6 +123,7 @@ void VM::status(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DBG_INFO(("Flags: ZF = %d, CF = %d\n", flags.ZF, flags.CF));
|
||||||
DBG_SUCC(("~~~~~~~~~~\n"));
|
DBG_SUCC(("~~~~~~~~~~\n"));
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
@ -277,6 +278,84 @@ bool VM::execSUBR(void) {
|
|||||||
regs[dst] -= regs[src];
|
regs[dst] -= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool VM::execANDB(void) {
|
||||||
|
/*
|
||||||
|
ANDB R0, 0x2 -> R0 &= 0x02 or R0 &= [BYTE] 0x02 (low byte)
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint8_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1];
|
||||||
|
src = as.code[regs[IP] + 2];
|
||||||
|
DBG_INFO(("ANDB %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] &= src;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execANDW(void) {
|
||||||
|
/*
|
||||||
|
ANDW R0, 0x2 -> R0 &= 0x0002 or R0, ^= [WORD] 0x2
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint16_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1];
|
||||||
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
|
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] &= src;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execANDR(void) {
|
||||||
|
/*
|
||||||
|
ANDR R0, R1 -> R0 ^= R1
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint8_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
|
DBG_INFO(("ANDR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] &= regs[src];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execYORB(void) {
|
||||||
|
/*
|
||||||
|
YORB R0, 0x2 -> R0 |= 0x02 or R0 |= [BYTE] 0x02 (low byte)
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint8_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1];
|
||||||
|
src = as.code[regs[IP] + 2];
|
||||||
|
DBG_INFO(("YORB %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] |= src;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execYORW(void) {
|
||||||
|
/*
|
||||||
|
YORW R0, 0x2 -> R0 |= 0x0002 or R0, |= [WORD] 0x2
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint16_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1];
|
||||||
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
|
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] |= src;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execYORR(void) {
|
||||||
|
/*
|
||||||
|
YORR R0, R1 -> R0 |= R1
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint8_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
|
DBG_INFO(("XORR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] |= regs[src];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
bool VM::execXORB(void) {
|
bool VM::execXORB(void) {
|
||||||
/*
|
/*
|
||||||
XORB R0, 0x2 -> R0 ^= 0x02 or R0 ^= [BYTE] 0x02 (low byte)
|
XORB R0, 0x2 -> R0 ^= 0x02 or R0 ^= [BYTE] 0x02 (low byte)
|
||||||
@ -342,7 +421,19 @@ bool VM::execMULI(void) {
|
|||||||
regs[dst] *= src;
|
regs[dst] *= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool VM::execMULR(void) { return true; }
|
bool VM::execMULR(void) {
|
||||||
|
/*
|
||||||
|
MULR R0, R1 -> R0 *= R1
|
||||||
|
*/
|
||||||
|
uint8_t dst;
|
||||||
|
uint8_t src;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
|
DBG_INFO(("MULR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
regs[dst] *= regs[src];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
bool VM::execDIVI(void) {
|
bool VM::execDIVI(void) {
|
||||||
/*
|
/*
|
||||||
DIVI R0, 0x2 | R0 /= 2
|
DIVI R0, 0x2 | R0 /= 2
|
||||||
@ -356,20 +447,224 @@ bool VM::execDIVI(void) {
|
|||||||
regs[dst] /= src;
|
regs[dst] /= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool VM::execDIVR(void) { return true; }
|
bool VM::execDIVR(void) {
|
||||||
bool VM::execPUSH(void) { return true; }
|
/*
|
||||||
bool VM::execPOOP(void) { return true; }
|
DIVR R0, R1 -> R0 /= R1
|
||||||
bool VM::execCMPI(void) { return true; }
|
*/
|
||||||
bool VM::execCMPR(void) { return true; }
|
uint8_t dst;
|
||||||
bool VM::execJMPI(void) { return true; }
|
uint8_t src;
|
||||||
bool VM::execJMPR(void) { return true; }
|
|
||||||
bool VM::execJPAI(void) { return true; }
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
bool VM::execJPAR(void) { return true; }
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
bool VM::execJPBI(void) { return true; }
|
DBG_INFO(("ADDR %s, 0x%x\n", getRegName(dst), src));
|
||||||
bool VM::execJPBR(void) { return true; }
|
regs[dst] /= regs[src];
|
||||||
bool VM::execJPEI(void) { return true; }
|
return true;
|
||||||
bool VM::execJPER(void) { return true; }
|
}
|
||||||
bool VM::execGRMN(void) { return true; }
|
bool VM::execPUSH(void) {
|
||||||
|
// TODO: STACK < 0
|
||||||
|
uint8_t src;
|
||||||
|
|
||||||
|
src = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("PUSH %s\n", getRegName(src)));
|
||||||
|
memcpy(&as.stack[regs[SP]], ®s[src], sizeof(uint16_t));
|
||||||
|
regs[SP] += sizeof(uint16_t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execPOOP(void) {
|
||||||
|
// TODO: STACK < 0
|
||||||
|
uint8_t dst;
|
||||||
|
|
||||||
|
dst = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("POOP %s\n", getRegName(dst)));
|
||||||
|
regs[SP] -= sizeof(uint16_t);
|
||||||
|
memcpy(®s[dst], &as.stack[regs[SP]], sizeof(uint16_t));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execCMPI(void) {
|
||||||
|
/*
|
||||||
|
CMPI R0, 0x2 -> Compare immediate with register
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
uint16_t imm;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
imm = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
|
DBG_INFO(("CMPI %s, 0x%x\n", getRegName(reg), imm));
|
||||||
|
if (regs[reg] == imm) {
|
||||||
|
flags.ZF = 1;
|
||||||
|
} else {
|
||||||
|
flags.ZF = 0;
|
||||||
|
}
|
||||||
|
if (regs[reg] > imm) {
|
||||||
|
flags.CF = 1;
|
||||||
|
} else {
|
||||||
|
flags.CF = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execCMPR(void) {
|
||||||
|
/*
|
||||||
|
CMPR R0, R1 -> Compares 2 registers
|
||||||
|
*/
|
||||||
|
uint8_t r1;
|
||||||
|
uint8_t r2;
|
||||||
|
|
||||||
|
r1 = as.code[regs[IP] + 1] >> 4;
|
||||||
|
r2 = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
|
DBG_INFO(("CMPR %s, %s\n", getRegName(r1), getRegName(r2)));
|
||||||
|
if (regs[r1] == regs[r2]) {
|
||||||
|
flags.ZF = 1;
|
||||||
|
} else {
|
||||||
|
flags.ZF = 0;
|
||||||
|
}
|
||||||
|
if (regs[r1] > regs[r2]) {
|
||||||
|
flags.CF = 1;
|
||||||
|
} else {
|
||||||
|
flags.CF = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execJMPI(void) {
|
||||||
|
/*
|
||||||
|
JMPI 0x2000 -> IP = 0x2000
|
||||||
|
*/
|
||||||
|
uint16_t imm;
|
||||||
|
|
||||||
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JMPI 0x%x\n", imm));
|
||||||
|
regs[IP] = imm;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execJMPR(void) {
|
||||||
|
/*
|
||||||
|
JMPR R0 -> IP = R0
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JMPR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
|
regs[IP] = regs[reg];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execJPAI(void) {
|
||||||
|
/*
|
||||||
|
JPAI 0x2000 -> Jump to 0x2000 if above
|
||||||
|
*/
|
||||||
|
uint16_t imm;
|
||||||
|
|
||||||
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPAI 0x%x\n", imm));
|
||||||
|
if (flags.CF == 1) {
|
||||||
|
regs[IP] = imm;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPAR(void) {
|
||||||
|
/*
|
||||||
|
JPAR R0 -> Jump to [R0] if above
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPAR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
|
if (flags.CF == 1) {
|
||||||
|
regs[IP] = reg;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPBI(void) {
|
||||||
|
/*
|
||||||
|
JPBI 0x2000 -> Jump to 0x2000 if below
|
||||||
|
*/
|
||||||
|
uint16_t imm;
|
||||||
|
|
||||||
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPBI 0x%x\n", imm));
|
||||||
|
if (flags.CF == 0) {
|
||||||
|
regs[IP] = imm;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPBR(void) {
|
||||||
|
/*
|
||||||
|
JPBR R0 -> Jump to [R0] if below
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPBR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
|
if (flags.CF == 0) {
|
||||||
|
regs[IP] = reg;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPEI(void) {
|
||||||
|
/*
|
||||||
|
JPEI 0x2000 -> Jump to 0x2000 if equal
|
||||||
|
*/
|
||||||
|
uint16_t imm;
|
||||||
|
|
||||||
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPEI 0x%x\n", imm));
|
||||||
|
if (flags.ZF == 1) {
|
||||||
|
regs[IP] = imm;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPER(void) {
|
||||||
|
/*
|
||||||
|
JPNR R0 -> Jump to [R0] if equal
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPER %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
|
if (flags.ZF == 1) {
|
||||||
|
regs[IP] = reg;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPNI(void) {
|
||||||
|
/*
|
||||||
|
JPEI 0x2000 -> Jump to 0x2000 if not equal
|
||||||
|
*/
|
||||||
|
uint16_t imm;
|
||||||
|
|
||||||
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPNI 0x%x\n", imm));
|
||||||
|
if (flags.ZF == 0) {
|
||||||
|
regs[IP] = imm;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execJPNR(void) {
|
||||||
|
/*
|
||||||
|
JPER R0 -> Jump to [R0] if not equal
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
DBG_INFO(("JPNR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
|
if (flags.ZF == 0) {
|
||||||
|
regs[IP] = reg;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool VM::execGRMN(void) {
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < NUM_REGS; i++) {
|
||||||
|
regs[i] = 0x4747;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
void VM::run(void) {
|
void VM::run(void) {
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
@ -399,6 +694,24 @@ void VM::run(void) {
|
|||||||
} else if (opcode == OPS[SUBR]) {
|
} else if (opcode == OPS[SUBR]) {
|
||||||
execSUBR();
|
execSUBR();
|
||||||
regs[IP] += SUBR_SIZE;
|
regs[IP] += SUBR_SIZE;
|
||||||
|
} else if (opcode == OPS[ANDB]) {
|
||||||
|
execANDB();
|
||||||
|
regs[IP] += ANDB_SIZE;
|
||||||
|
} else if (opcode == OPS[ANDW]) {
|
||||||
|
execANDW();
|
||||||
|
regs[IP] += ANDW_SIZE;
|
||||||
|
} else if (opcode == OPS[ANDR]) {
|
||||||
|
execANDR();
|
||||||
|
regs[IP] += ANDR_SIZE;
|
||||||
|
} else if (opcode == OPS[YORB]) {
|
||||||
|
execYORB();
|
||||||
|
regs[IP] += YORB_SIZE;
|
||||||
|
} else if (opcode == OPS[YORW]) {
|
||||||
|
execYORW();
|
||||||
|
regs[IP] += YORW_SIZE;
|
||||||
|
} else if (opcode == OPS[YORR]) {
|
||||||
|
execYORR();
|
||||||
|
regs[IP] += YORR_SIZE;
|
||||||
} else if (opcode == OPS[XORB]) {
|
} else if (opcode == OPS[XORB]) {
|
||||||
execXORB();
|
execXORB();
|
||||||
regs[IP] += XORB_SIZE;
|
regs[IP] += XORB_SIZE;
|
||||||
@ -434,28 +747,40 @@ void VM::run(void) {
|
|||||||
regs[IP] += CMPR_SIZE;
|
regs[IP] += CMPR_SIZE;
|
||||||
} else if (opcode == OPS[JMPI]) {
|
} else if (opcode == OPS[JMPI]) {
|
||||||
execJMPI();
|
execJMPI();
|
||||||
regs[IP] += JMPI_SIZE;
|
|
||||||
} else if (opcode == OPS[JMPR]) {
|
} else if (opcode == OPS[JMPR]) {
|
||||||
execJMPR();
|
execJMPR();
|
||||||
regs[IP] += JMPR_SIZE;
|
} else if (opcode == OPS[JPAI]) {
|
||||||
}else if (opcode == OPS[JPAI]) {
|
if (!execJPAI()) {
|
||||||
execJPAI();
|
regs[IP] += JPAI_SIZE;
|
||||||
regs[IP] += JPAI_SIZE;
|
}
|
||||||
}else if (opcode == OPS[JPAR]) {
|
} else if (opcode == OPS[JPAR]) {
|
||||||
execJPAR();
|
if (!execJPAR()) {
|
||||||
regs[IP] += JPAR_SIZE;
|
regs[IP] += JPAR_SIZE;
|
||||||
}else if (opcode == OPS[JPBI]) {
|
}
|
||||||
execJPBI();
|
} else if (opcode == OPS[JPBI]) {
|
||||||
regs[IP] += JPBI_SIZE;
|
if (!execJPBI()) {
|
||||||
}else if (opcode == OPS[JPBR]) {
|
regs[IP] += JPBI_SIZE;
|
||||||
execJPBR();
|
}
|
||||||
regs[IP] += JPBR_SIZE;
|
} else if (opcode == OPS[JPBR]) {
|
||||||
}else if (opcode == OPS[JPEI]) {
|
if (!execJPBR()) {
|
||||||
execJPEI();
|
regs[IP] += JPBR_SIZE;
|
||||||
regs[IP] += JPEI_SIZE;
|
}
|
||||||
}else if (opcode == OPS[JPER]) {
|
} else if (opcode == OPS[JPEI]) {
|
||||||
execJPER();
|
if (!execJPEI()) {
|
||||||
regs[IP] += JPER_SIZE;
|
regs[IP] += JPEI_SIZE;
|
||||||
|
}
|
||||||
|
} else if (opcode == OPS[JPER]) {
|
||||||
|
if (!execJPER()) {
|
||||||
|
regs[IP] += JPER_SIZE;
|
||||||
|
}
|
||||||
|
} else if (opcode == OPS[JPNI]) {
|
||||||
|
if (!execJPNI()) {
|
||||||
|
regs[IP] += JPNI_SIZE;
|
||||||
|
}
|
||||||
|
} else if (opcode == OPS[JPNR]) {
|
||||||
|
if (!execJPNR()) {
|
||||||
|
regs[IP] += JPNR_SIZE;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[GRMN]) {
|
} else if (opcode == OPS[GRMN]) {
|
||||||
execGRMN();
|
execGRMN();
|
||||||
regs[IP] += GRMN_SIZE;
|
regs[IP] += GRMN_SIZE;
|
||||||
|
19
vm/vm.h
19
vm/vm.h
@ -4,6 +4,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS };
|
enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS };
|
||||||
|
typedef struct flags {
|
||||||
|
uint8_t ZF : 1;
|
||||||
|
uint8_t CF : 1;
|
||||||
|
} flags_t;
|
||||||
|
|
||||||
class VM {
|
class VM {
|
||||||
private:
|
private:
|
||||||
@ -12,12 +16,9 @@ private:
|
|||||||
////////////////////////
|
////////////////////////
|
||||||
|
|
||||||
uint16_t regs[0xb];
|
uint16_t regs[0xb];
|
||||||
struct flags {
|
flags_t flags;
|
||||||
uint8_t zf : 1;
|
|
||||||
uint8_t cf : 1;
|
|
||||||
};
|
|
||||||
VMAddrSpace as;
|
|
||||||
|
|
||||||
|
VMAddrSpace as;
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// FUNCTIONS
|
// FUNCTIONS
|
||||||
///////////////////////
|
///////////////////////
|
||||||
@ -39,6 +40,12 @@ private:
|
|||||||
bool execADDR(void);
|
bool execADDR(void);
|
||||||
bool execSUBI(void);
|
bool execSUBI(void);
|
||||||
bool execSUBR(void);
|
bool execSUBR(void);
|
||||||
|
bool execANDB(void);
|
||||||
|
bool execANDW(void);
|
||||||
|
bool execANDR(void);
|
||||||
|
bool execYORB(void);
|
||||||
|
bool execYORW(void);
|
||||||
|
bool execYORR(void);
|
||||||
bool execXORB(void);
|
bool execXORB(void);
|
||||||
bool execXORW(void);
|
bool execXORW(void);
|
||||||
bool execXORR(void);
|
bool execXORR(void);
|
||||||
@ -59,6 +66,8 @@ private:
|
|||||||
bool execJPBR(void);
|
bool execJPBR(void);
|
||||||
bool execJPEI(void);
|
bool execJPEI(void);
|
||||||
bool execJPER(void);
|
bool execJPER(void);
|
||||||
|
bool execJPNI(void);
|
||||||
|
bool execJPNR(void);
|
||||||
bool execGRMN(void);
|
bool execGRMN(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -46,11 +46,10 @@ bool VMAddrSpace::allocate(void) {
|
|||||||
DBG_ERROR(("Couldn't allocate stack section.\n"));
|
DBG_ERROR(("Couldn't allocate stack section.\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(code, 0xff,
|
memset(code, 0xff, codesize); // auto halt in case the assembly is not correct
|
||||||
stacksize); // auto halt in case the assembly is not correct
|
|
||||||
memset(stack, 0x0, stacksize);
|
memset(stack, 0x0, stacksize);
|
||||||
memset(data, 0x0, stacksize);
|
memset(data, 0x0, datasize);
|
||||||
DBG_SUCC(("Done!\n"));
|
DBG_SUCC(("Done!\n"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user