Skip to content

Commit

Permalink
Reorganized opcode types to be easier to change
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Bell committed Apr 25, 2012
1 parent df808db commit f7951a6
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 62 deletions.
21 changes: 13 additions & 8 deletions lib/assembler.js
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -161,7 +166,7 @@ Assembler.prototype = {
character = arg.charCodeAt(j);
}

if(OPCODES[op] !== null)
if(OPCODES[op] !== undefined)
pack(0x1f);
words.push(character);
}
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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 = [];
Expand Down
89 changes: 35 additions & 54 deletions lib/cpu.js
Expand Up @@ -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;

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f7951a6

Please sign in to comment.