From f7951a692e8f19fcf75d0b8cf76293efa5ae59e7 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 25 Apr 2012 10:40:41 -0700 Subject: [PATCH] Reorganized opcode types to be easier to change --- lib/assembler.js | 21 +++++++----- lib/cpu.js | 89 +++++++++++++++++++----------------------------- 2 files changed, 48 insertions(+), 62 deletions(-) diff --git a/lib/assembler.js b/lib/assembler.js index 707c44c..4fccf4e 100644 --- a/lib/assembler.js +++ b/lib/assembler.js @@ -80,9 +80,14 @@ Assembler.prototype = { } i += arg.length ; - if(OPCODES[op] !== null - && ((OPCODES[op] > 0xff && args.length > 1) || (OPCODES[op] < 0xff && args.length > 2))) { - throw new Error('Invalid amount of arguments for op ' + op); + if(OPCODES[op].id !== null) { + var error = new Error('Invalid amount of arguments for op ' + op); + + if(OPCODES[op].args === Infinity) { + if(args.length < 1) throw error; + } else if(args.length !== OPCODES[op].args) { + throw error; + } } if(arg.length > 0) @@ -115,7 +120,7 @@ Assembler.prototype = { var cpu = this.cpu, value, words, operand, line, op, args, sr, c; function pack(value) { - if(OPCODES[op] !== null) + if(OPCODES[op] !== undefined) words[0] |= value << (5 + operand * 5); } @@ -161,7 +166,7 @@ Assembler.prototype = { character = arg.charCodeAt(j); } - if(OPCODES[op] !== null) + if(OPCODES[op] !== undefined) pack(0x1f); words.push(character); } @@ -246,8 +251,8 @@ Assembler.prototype = { throw new Error('Invalid value 0x' + value.toString(16) + ', must be between 0 and 0xffff'); } - //0x20-0x3f: literal value 0x00-0x1f (literal) - if(!pointer && value <= 0x1e && OPCODES[op] !== null) { + //0x20-0x3f: literal value 0xffff-0x1e (literal) + if(!pointer && (value <= 0x1e || value === 0xffff) && OPCODES[op] !== undefined) { pack((value + 0x21) & 0xffff); } else { //0x1e: [next word] @@ -376,7 +381,7 @@ Assembler.prototype = { var op = serialized.instructions[this.instruction][0].toUpperCase(), args = serialized.instructions[this.instruction].slice(1); if( typeof op !== 'undefined') { if( typeof OPCODES[op] !== 'undefined') { - if(OPCODES[op] !== null) + if(OPCODES[op].id !== null) words = [OPCODES[op]]; else words = []; diff --git a/lib/cpu.js b/lib/cpu.js index 603d688..fe53b9e 100644 --- a/lib/cpu.js +++ b/lib/cpu.js @@ -25,63 +25,45 @@ function getSigned(word) { var OPCODES = { //assembler directives - 'DAT': null, + 'DAT': {id: null, cost: 0, args: Infinity}, //basic ops - 'SET': 0x01, - 'ADD': 0x02, - 'SUB': 0x03, - 'MUL': 0x04, - 'MLI': 0x05, - 'DIV': 0x06, - 'DVI': 0x07, - 'MOD': 0x08, - 'AND': 0x09, - 'BOR': 0x0a, - 'XOR': 0x0b, - 'SHR': 0x0c, - 'ASR': 0x0d, - 'SHL': 0x0e, - 'IFB': 0x10, - 'IFC': 0x11, - 'IFE': 0x12, - 'IFN': 0x13, - 'IFG': 0x14, - 'IFA': 0x15, - 'IFL': 0x16, - 'IFU': 0x17, + 'SET': {id: 0x01, cost: 1, args: 2}, + 'ADD': {id: 0x02, cost: 2, args: 2}, + 'SUB': {id: 0x03, cost: 2, args: 2}, + 'MUL': {id: 0x04, cost: 2, args: 2}, + 'MLI': {id: 0x05, cost: 2, args: 2}, + 'DIV': {id: 0x06, cost: 3, args: 2}, + 'DVI': {id: 0x07, cost: 3, args: 2}, + 'MOD': {id: 0x08, cost: 3, args: 2}, + 'AND': {id: 0x09, cost: 1, args: 2}, + 'BOR': {id: 0x0a, cost: 1, args: 2}, + 'XOR': {id: 0x0b, cost: 1, args: 2}, + 'SHR': {id: 0x0c, cost: 2, args: 2}, + 'ASR': {id: 0x0d, cost: 2, args: 2}, + 'SHL': {id: 0x0e, cost: 2, args: 2}, + 'IFB': {id: 0x10, cost: 2, args: 2}, + 'IFC': {id: 0x11, cost: 2, args: 2}, + 'IFE': {id: 0x12, cost: 2, args: 2}, + 'IFN': {id: 0x13, cost: 2, args: 2}, + 'IFG': {id: 0x14, cost: 2, args: 2}, + 'IFA': {id: 0x15, cost: 2, args: 2}, + 'IFL': {id: 0x16, cost: 2, args: 2}, + 'IFU': {id: 0x17, cost: 2, args: 2}, + 'ADX': {id: 0x1a, cost: 3, args: 2}, + 'SUX': {id: 0x1b, cost: 3, args: 2}, //non-basic ops - 'JSR': 0x20, - 'BRK': 0x40, - 'INT': 0x100, - 'ING': 0x120, - 'INS': 0x140, - 'HWN': 0x200, - 'HWQ': 0x220, - 'HWI': 0x240 + 'JSR': {id: 0x20, cost: 3, args: 1}, + 'BRK': {id: 0x40, cost: 0, args: 0}, + 'INT': {id: 0x100, cost: 4, args: 1}, + 'ING': {id: 0x120, cost: 1, args: 1}, + 'INS': {id: 0x140, cost: 1, args: 1}, + 'HWN': {id: 0x200, cost: 2, args: 1}, + 'HWQ': {id: 0x220, cost: 4, args: 1}, + 'HWI': {id: 0x240, cost: 4, args: 1} }; -var OPCODE_COST = [ - // Basic opcodes - 1, - 2, 2, 2, 2, - 3, 3, 3, - 1, 1, 1, - 2, 2, 2, - null, - 2, 2, 2, 2, 2, 2, 2, 2, - - // Non-basic opcodes - null, - 3, - null, null, null, null, null, null, - 4, 1, 1, - null, null, null, null, null, - 2, 4, 4, - null, null, null, null, null, null, null, null, null, null, null, null, null -]; - var REGISTER_NAMES = ['a', 'b', 'c', 'x', 'y', 'z', 'i', 'j']; var FLAG_LITERAL = 0x10000; @@ -222,7 +204,7 @@ CPU.prototype = { // Fetch the instruction insn = this.nextInstruction(); - this.cycle += OPCODE_COST[insn.opcode] || 0; + this.cycle += OPCODE[insn.opcode].cost || 0; // Read the arguments if(insn.opcode !== 0) { @@ -557,7 +539,7 @@ CPU.prototype = { output += 'J: ' + formatWord(this.mem.j) + '\n\n'; output += 'PC: ' + formatWord(this.mem.pc) + '\n'; output += 'SP: ' + formatWord(this.mem.stack) + '\n'; - output += 'O: ' + formatWord(this.mem.o) + '\n\n'; + output += 'EX: ' + formatWord(this.mem.ex) + '\n\n'; output += 'CPU CYCLES: ' + this.cycle + '\n\n'; output += '======= RAM: ======='; for( i = 0; i < this.ramSize; i += 8) { @@ -596,7 +578,6 @@ CPU.prototype = { CPU.FLAG_LITERAL = FLAG_LITERAL; CPU.REGISTER_NAMES = REGISTER_NAMES; CPU.OPCODES = OPCODES; -CPU.OPCODE_COST = OPCODE_COST; if (typeof module === 'undefined') { (root.DCPU16 = (root.DCPU16 || {})).CPU = CPU;