diff --git a/instruction-set.html b/instruction-set.html index fd2d8d5..af5d85e 100644 --- a/instruction-set.html +++ b/instruction-set.html @@ -81,6 +81,16 @@
Adds two numbers or subtracts one number from another. If the carry flag is set, this will add or subtract one more. This is useful for adding and subtracting numbers which are wider than 8 bits. These operations will modify the carry and zero flag. SP can be used as operand with ADDC and SUBC.
++ADDC reg, reg +ADDC reg, address +ADDC reg, constant +SUBC reg, reg +SUBC reg, address +SUBC reg, constantIncrement and Decrement
Increments or decrements a register by one. This operations will modify the carry and zero flag. SP can be used as operand with INC and DEC.
diff --git a/src/assembler/asm.js b/src/assembler/asm.js index c12ffd5..479ac6b 100644 --- a/src/assembler/asm.js +++ b/src/assembler/asm.js @@ -262,6 +262,23 @@ app.service('assembler', ['opcodes', function (opcodes) { else throw "ADD does not support this operands"; + code.push(opCode, p1.value, p2.value); + break; + case 'ADDC': + p1 = getValue(match[op1_group]); + p2 = getValue(match[op2_group]); + + if (p1.type === "register" && p2.type === "register") + opCode = opcodes.ADDC_REG_TO_REG; + else if (p1.type === "register" && p2.type === "regaddress") + opCode = opcodes.ADDC_REGADDRESS_TO_REG; + else if (p1.type === "register" && p2.type === "address") + opCode = opcodes.ADDC_ADDRESS_TO_REG; + else if (p1.type === "register" && p2.type === "number") + opCode = opcodes.ADDC_NUMBER_TO_REG; + else + throw "ADDC does not support this operands"; + code.push(opCode, p1.value, p2.value); break; case 'SUB': @@ -279,6 +296,23 @@ app.service('assembler', ['opcodes', function (opcodes) { else throw "SUB does not support this operands"; + code.push(opCode, p1.value, p2.value); + break; + case 'SUBC': + p1 = getValue(match[op1_group]); + p2 = getValue(match[op2_group]); + + if (p1.type === "register" && p2.type === "register") + opCode = opcodes.SUBC_REG_FROM_REG; + else if (p1.type === "register" && p2.type === "regaddress") + opCode = opcodes.SUBC_REGADDRESS_FROM_REG; + else if (p1.type === "register" && p2.type === "address") + opCode = opcodes.SUBC_ADDRESS_FROM_REG; + else if (p1.type === "register" && p2.type === "number") + opCode = opcodes.SUBC_NUMBER_FROM_REG; + else + throw "SUBC does not support this operands"; + code.push(opCode, p1.value, p2.value); break; case 'INC': diff --git a/src/emulator/cpu.js b/src/emulator/cpu.js index f4522eb..c572ed8 100644 --- a/src/emulator/cpu.js +++ b/src/emulator/cpu.js @@ -124,7 +124,7 @@ app.service('cpu', ['opcodes', 'memory', function(opcodes, memory) { throw "Instruction pointer is outside of memory"; } - var regTo, regFrom, memFrom, memTo, number; + var regTo, regFrom, memFrom, memTo, number, carryVal; var instr = memory.load(self.ip); switch(instr) { case opcodes.NONE: @@ -201,6 +201,34 @@ app.service('cpu', ['opcodes', 'memory', function(opcodes, memory) { setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) + number)); self.ip++; break; + case opcodes.ADDC_REG_TO_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + regFrom = checkGPR_SP(memory.load(++self.ip)); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) + getGPR_SP(regFrom) + carryVal )); + self.ip++; + break; + case opcodes.ADDC_REGADDRESS_TO_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + regFrom = memory.load(++self.ip); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) + memory.load(indirectRegisterAddress(regFrom)) + carryVal)); + self.ip++; + break; + case opcodes.ADDC_ADDRESS_TO_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + memFrom = memory.load(++self.ip); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) + memory.load(memFrom) + carryVal)); + self.ip++; + break; + case opcodes.ADDC_NUMBER_TO_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + number = memory.load(++self.ip); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) + number + carryVal)); + self.ip++; + break; case opcodes.SUB_REG_FROM_REG: regTo = checkGPR_SP(memory.load(++self.ip)); regFrom = checkGPR_SP(memory.load(++self.ip)); @@ -225,6 +253,34 @@ app.service('cpu', ['opcodes', 'memory', function(opcodes, memory) { setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) - number)); self.ip++; break; + case opcodes.SUBC_REG_FROM_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + regFrom = checkGPR_SP(memory.load(++self.ip)); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) - self.gpr[regFrom] - carryVal)); + self.ip++; + break; + case opcodes.SUBC_REGADDRESS_FROM_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + regFrom = memory.load(++self.ip); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) - memory.load(indirectRegisterAddress(regFrom)) - carryVal)); + self.ip++; + break; + case opcodes.SUBC_ADDRESS_FROM_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + memFrom = memory.load(++self.ip); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) - memory.load(memFrom) - carryVal)); + self.ip++; + break; + case opcodes.SUBC_NUMBER_FROM_REG: + regTo = checkGPR_SP(memory.load(++self.ip)); + number = memory.load(++self.ip); + carryVal = self.carry ? 1 : 0; + setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) - number - carryVal)); + self.ip++; + break; case opcodes.INC_REG: regTo = checkGPR_SP(memory.load(++self.ip)); setGPR_SP(regTo,checkOperation(getGPR_SP(regTo) + 1)); diff --git a/src/emulator/opcodes.js b/src/emulator/opcodes.js index 1a94a13..732f4f0 100644 --- a/src/emulator/opcodes.js +++ b/src/emulator/opcodes.js @@ -73,7 +73,15 @@ app.service('opcodes', [function() { SHR_REG_WITH_REG: 94, SHR_REGADDRESS_WITH_REG: 95, SHR_ADDRESS_WITH_REG: 96, - SHR_NUMBER_WITH_REG: 97 + SHR_NUMBER_WITH_REG: 97, + ADDC_REG_TO_REG: 98, + ADDC_REGADDRESS_TO_REG: 99, + ADDC_ADDRESS_TO_REG: 100, + ADDC_NUMBER_TO_REG: 101, + SUBC_REG_FROM_REG: 102, + SUBC_REGADDRESS_FROM_REG: 103, + SUBC_ADDRESS_FROM_REG: 104, + SUBC_NUMBER_FROM_REG: 105 }; return opcodes;