From b2f03937a31ae9158841fdfbd61971e13c6b988f Mon Sep 17 00:00:00 2001 From: bee8bit Date: Mon, 15 Feb 2016 10:54:09 +0100 Subject: [PATCH] extended instruction set: ADDC - Add with carry, SUBC - Subtract with carry --- instruction-set.html | 10 +++++++ src/assembler/asm.js | 34 ++++++++++++++++++++++++ src/emulator/cpu.js | 58 ++++++++++++++++++++++++++++++++++++++++- src/emulator/opcodes.js | 10 ++++++- 4 files changed, 110 insertions(+), 2 deletions(-) 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 @@

Math operations

SUB reg, reg SUB reg, address SUB reg, constant + + Addition with carry and Subtraction with borrowb> +

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, constant
 
Increment 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;