| @@ -4,7 +4,7 @@ | |||
| var Memory = require('src/memory'); | |||
| class MOS6502{ | |||
| class CPU{ | |||
| constructor(){ | |||
| // Registers | |||
| this.__PC = 0; // Program Counter (16 bit) | |||
| @@ -35,7 +35,12 @@ class MOS6502{ | |||
| this.__irq = (q === true); | |||
| } | |||
| CLK(){ | |||
| reset(){ | |||
| // TODO: Read memory address $FFFC - FFFD to find PC start location. | |||
| // TODO: Reset status registers that get changed on a reset. | |||
| } | |||
| clk(){ | |||
| if (this.__clkfn === null){ | |||
| this.__clkfn = (function(){ | |||
| // TODO: All the work!! | |||
| @@ -44,7 +49,7 @@ class MOS6502{ | |||
| return this.__clkfn; | |||
| } | |||
| Memory(mem){ | |||
| memory(mem){ | |||
| if (!(mem instanceof Memory)) | |||
| throw new ValueError("Expected Memory instance object."); | |||
| this.__mem = mem; | |||
| @@ -52,4 +57,180 @@ class MOS6502{ | |||
| } | |||
| module.exports = MOS6502; | |||
| // --------------------------------------------------------------------- | |||
| // --------------------------------------------------------------------- | |||
| function toHexString(v, l){ | |||
| l = (typeof(l) === 'number' && (l === 8 || l === 16)) ? l : 8; | |||
| var r = v.toString(16); | |||
| if (r.length < 2) | |||
| r = "0" + r; | |||
| if (l === 16 && r.length < 4) | |||
| r = ((r.length === 2) ? "00" : "0") + r; | |||
| return r; | |||
| } | |||
| class Assembler{ | |||
| constructor(initpc){ | |||
| // Labels that hold variable values. | |||
| this.__varlabels = {}; | |||
| // Labels that hold jump/branch locations. | |||
| this.__jmplabels = {}; | |||
| // Program counter to track where in the code/memory a | |||
| // operation is located. | |||
| this.__PC = (initpc >= 0) ? initpc : 0; | |||
| } | |||
| compile(src){ | |||
| var op = []; | |||
| src.split("\n").forEach((line)=>{ | |||
| line = line.trim(); | |||
| if (line[0] !== ";"){ // Skip comment lines. | |||
| line = line.split(";")[0].trim(); // Take out any trailing comments. | |||
| var tokens = line.split(/\s+/); | |||
| if (tokens[0] === 'define'){ | |||
| // Variable label!! | |||
| } else if (tokens[0][tokens[0].length - 1] === ':'){ | |||
| // Jump label!! | |||
| } else if (tokens[0].length === 3){ | |||
| // Possible op code. | |||
| switch(tokens[0].toLowerCase()){ | |||
| case 'adc': | |||
| break; | |||
| case 'and': | |||
| break; | |||
| case 'asl': | |||
| break; | |||
| case 'bcc': | |||
| break; | |||
| case 'bcs': | |||
| break; | |||
| case 'beq': | |||
| break; | |||
| case 'bit': | |||
| break; | |||
| case 'bmi': | |||
| break; | |||
| case 'bne': | |||
| break; | |||
| case 'bpl': | |||
| break; | |||
| case 'brk': | |||
| break; | |||
| case 'bvc': | |||
| break; | |||
| case 'bvs': | |||
| break; | |||
| case 'clc': | |||
| break; | |||
| case 'cld': | |||
| break; | |||
| case 'cli': | |||
| break; | |||
| case 'clv': | |||
| break; | |||
| case 'cmp': | |||
| break; | |||
| case 'cpx': | |||
| break; | |||
| case 'cpy': | |||
| break; | |||
| case 'dec': | |||
| break; | |||
| case 'dex': | |||
| break; | |||
| case 'dey': | |||
| break; | |||
| case 'eor': | |||
| break; | |||
| case 'inc': | |||
| break; | |||
| case 'inx': | |||
| break; | |||
| case 'iny': | |||
| break; | |||
| case 'jmp': | |||
| break; | |||
| case 'jsr': | |||
| break; | |||
| case 'lda': | |||
| break; | |||
| case 'ldx': | |||
| break; | |||
| case 'ldy': | |||
| break; | |||
| case 'lsr': | |||
| break; | |||
| case 'nop': | |||
| break; | |||
| case 'ora': | |||
| break; | |||
| case 'pha': | |||
| break; | |||
| case 'php': | |||
| break; | |||
| case 'pla': | |||
| break; | |||
| case 'plp': | |||
| break; | |||
| case 'rol': | |||
| break; | |||
| case 'ror': | |||
| break; | |||
| case 'rti': | |||
| break; | |||
| case 'rts': | |||
| break; | |||
| case 'sbc': | |||
| break; | |||
| case 'sec': | |||
| break; | |||
| case 'sed': | |||
| break; | |||
| case 'sei': | |||
| break; | |||
| case 'sta': | |||
| break; | |||
| case 'stx': | |||
| break; | |||
| case 'sty': | |||
| break; | |||
| case 'tax': | |||
| break; | |||
| case 'tay': | |||
| break; | |||
| case 'tsx': | |||
| break; | |||
| case 'txa': | |||
| break; | |||
| case 'txs': | |||
| break; | |||
| case 'tya': | |||
| break; | |||
| default: | |||
| throw new Error("Unknown op-code '" + tokens[0].toUpperCase() + "' at program address " + toHexString(this.__PC)); | |||
| } | |||
| } else { | |||
| throw new Error("Failed to compile line '" + line + "' at program address " + toHexString(this.__PC)); | |||
| } | |||
| } | |||
| }); | |||
| return new Uint8Array(op); | |||
| } | |||
| } | |||
| // --------------------------------------------------------------------- | |||
| // --------------------------------------------------------------------- | |||
| module.exports = { | |||
| CPU: CPU, | |||
| Assembler: Assembler | |||
| }; | |||