|
|
|
|
|
|
|
|
|
|
|
// Each array orders op codes as... |
|
|
|
|
|
// [<immediate>, <zero page>, <zero page X/Y>, <absolute>, <absolute X>, <absolute Y>, <Indirect X>, <Indirect Y>, <Indirect>, <accumulator>] |
|
|
|
|
|
// If an opcode does not support a particular format, null will be in that space. |
|
|
|
|
|
// NOTE: Opcode that do not have arguments will store their opcode value directly (no array). |
|
|
|
|
|
const CODES = { |
|
|
|
|
|
"ADC":[0x69, 0x65, 0x75, 0x6D, 0x7D, 0x79, 0x61, 0x71, null, null], |
|
|
|
|
|
"AND":[0x29, 0x25, 0x35, 0x2D, 0x3D, 0x39, 0x21, 0x31, null, null], |
|
|
|
|
|
"ASL":[null, 0x06, 0x16, 0x0E, 0x1E, null, null, null, null, 0x0A], |
|
|
|
|
|
"BCC":0x90, |
|
|
|
|
|
"BCS":0xB0, |
|
|
|
|
|
"BEQ":0xF0, |
|
|
|
|
|
"BIT":[null, 0x24, null, 0x2C, null, null, null, null, null, null], |
|
|
|
|
|
"BMI":0x30, |
|
|
|
|
|
"BNE":0xD0, |
|
|
|
|
|
"BPL":0x10, |
|
|
|
|
|
"BRK":0x00, |
|
|
|
|
|
"BVC":0x50, |
|
|
|
|
|
"BVS":0x70, |
|
|
|
|
|
"CLC":0x18, |
|
|
|
|
|
"CLD":0xD8, |
|
|
|
|
|
"CLI":0x58, |
|
|
|
|
|
"CLV":0xB8, |
|
|
|
|
|
"CMP":[0xC9, 0xC5, 0xD5, 0xCD, 0xDD, 0xD9, 0xC1, 0xD1, null, null], |
|
|
|
|
|
"CPX":[0xE0, 0xE4, null, 0xEC, null, null, null, null, null, null], |
|
|
|
|
|
"CPY":[0xC0, 0xC4, null, 0xCC, null, null, null, null, null, null], |
|
|
|
|
|
"DEC":[null, 0xC6, 0xD6, 0xCE, 0xDE, null, null, null, null, null], |
|
|
|
|
|
"DEX":0xCA, |
|
|
|
|
|
"DEY":0x88, |
|
|
|
|
|
"EOR":[0x49, 0x45, 0x55, 0x4D, 0x5D, 0x59, 0x41, 0x51, null, null], |
|
|
|
|
|
"INC":[null, 0xE6, 0xF6, 0xEE, 0xFE, null, null, null, null, null], |
|
|
|
|
|
"INX":0xE8, |
|
|
|
|
|
"INY":0xC8, |
|
|
|
|
|
"JMP":[null, null, null, 0x4C, null, null, null, null, 0x6C, null], |
|
|
|
|
|
"JSR":[null, null, null, 0x20, null, null, null, null, null, null], |
|
|
|
|
|
"LDA":[0xA9, 0xA5, 0xB5, 0xAD, 0xBD, 0xB9, 0xA1, 0xB1, null, null], |
|
|
|
|
|
"LDX":[0xA2, 0xA6, 0xB6, 0xAE, 0xBE, null, null, null, null, null], |
|
|
|
|
|
"LDY":[0xA0, 0xA4, 0xB4, 0xAC, 0xBC, null, null, null, null, null], |
|
|
|
|
|
"LSR":[null, 0x46, 0x56, 0x4E, 0x5E, null, null, null, null, 0x4A], |
|
|
|
|
|
"NOP":0xEA, |
|
|
|
|
|
"ORA":[0x09, 0x05, 0x15, 0x0D, 0x1D, 0x19, 0x01, 0x11, null, null], |
|
|
|
|
|
"PHA":0x48, |
|
|
|
|
|
"PHP":0x08, |
|
|
|
|
|
"PLA":0x68, |
|
|
|
|
|
"PLP":0x28, |
|
|
|
|
|
"ROL":[null, 0x26, 0x36, 0x2E, 0x3E, null, null, null, null, 0x2A], |
|
|
|
|
|
"ROR":[null, 0x66, 0x76, 0x6E, 0x7E, null, null, null, null, 0x6A], |
|
|
|
|
|
"RTI":0x40, |
|
|
|
|
|
"RTS":0x60, |
|
|
|
|
|
"SBC":[0xE9, 0xE5, 0xF5, 0xED, 0xFD, 0xF9, 0xE1, 0xF1, null, null], |
|
|
|
|
|
"SEC":0x38, |
|
|
|
|
|
"SED":0xF8, |
|
|
|
|
|
"SEI":0x78, |
|
|
|
|
|
"STA":[null, 0x85, 0x95, 0x8D, 0x9D, 0x99, 0x81, 0x91, null, null], |
|
|
|
|
|
"STX":[null, 0x86, 0x96, 0x8E, null, null, null, null, null, null], |
|
|
|
|
|
"STY":[null, 0x84, 0x94, 0x8C, null, null, null, null, null, null], |
|
|
|
|
|
"TAX":0xAA, |
|
|
|
|
|
"TAY":0xA8, |
|
|
|
|
|
"TSX":0xBA, |
|
|
|
|
|
"TXA":0x8A, |
|
|
|
|
|
"TXS":0x9A, |
|
|
|
|
|
"TYA":0x98 |
|
|
|
|
|
}; |
|
|
|
|
|
var NAMES = Object.keys(CODES); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = Object.freeze({ |
|
|
|
|
|
OPInfo:{ |
|
|
|
|
|
MODES:{ |
|
|
|
|
|
IMMEDIATE: 0, |
|
|
|
|
|
ZEROPAGE: 1, |
|
|
|
|
|
ZEROPAGEXY: 2, |
|
|
|
|
|
ABSOLUTE: 3, |
|
|
|
|
|
ABSOLUTEX: 4, |
|
|
|
|
|
ABSOLUTEY: 5, |
|
|
|
|
|
INDIRECTX: 6, |
|
|
|
|
|
INDIRECTY: 7, |
|
|
|
|
|
INDIRECT: 8, |
|
|
|
|
|
ACCUMULATOR: 9 |
|
|
|
|
|
}, |
|
|
|
|
|
CODES: CODES, |
|
|
|
|
|
NAMES: NAMES, |
|
|
|
|
|
isCode:function(op){return (NAMES.indexOf(op) >= 0);}, |
|
|
|
|
|
getCode:function(op, mode){ |
|
|
|
|
|
if (NAMES.indexOf(op) >= 0){ |
|
|
|
|
|
if (typeof(CODES[op]) === 'number') |
|
|
|
|
|
return CODES[op]; |
|
|
|
|
|
return (!(mode >= 0 && mode <= 9)) ? CODES[op][mode] : null; |
|
|
|
|
|
} |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
parseOpCodes: function(parser){ |
|
|
|
|
|
return (function(){ |
|
|
|
|
|
let line = this.stream.line(); |
|
|
|
|
|
let col = this.stream.col(); |
|
|
|
|
|
let val = this.stream.next(); |
|
|
|
|
|
let mode = 0; // Guess between absolute and zero page. |
|
|
|
|
|
if (this.isOp("#")){ |
|
|
|
|
|
this.stream.next(); |
|
|
|
|
|
mode = 1; // Immediate |
|
|
|
|
|
} else if (this.isPunc("(")){ |
|
|
|
|
|
mode = 2; // Indirect |
|
|
|
|
|
} |
|
|
|
|
|
return { |
|
|
|
|
|
type: "opcode", |
|
|
|
|
|
op: val, |
|
|
|
|
|
args: this.parseDelimited(null, null, ",", this.parseExpression.bind(this)), |
|
|
|
|
|
mode: mode, |
|
|
|
|
|
line: line, |
|
|
|
|
|
col: col |
|
|
|
|
|
}; |
|
|
|
|
|
}).bind(parser); |
|
|
|
|
|
} |
|
|
|
|
|
}); |