Browse Source

Jump and Var labels complete.

master
Bryan Miller 5 years ago
parent
commit
1100b23ea5
1 changed files with 85 additions and 47 deletions
  1. +85
    -47
      src/MOS6502.js

+ 85
- 47
src/MOS6502.js View File

@@ -105,7 +105,40 @@ class Assembler{
this.__PC = (initpc >= 0) ? initpc : 0;
}

function __AddrModeVal(tA, tB){
__StoreVarLabel(lbl, val){
if (lbl in this.__varlabels)
throw new Error("Variable label '" + lbl + "' defined more than once.");
if (lbl in this.__jmplabels)
throw new Error("Variable label '" + lbl + "' matches already existing jump label.");
let v = Number.NaN;
if (val[0] === "$"){
if (val.length >= 2 && val.length <= 5)
v = parseInt(val.substr(1), 16);
} else if (val[0] === "#"){
if (val.startsWith("#b")){
v = parseInt(val.substr(2), 2);
} else {
v = parseInt(val);
}
}
if (!isNaN(v)){
if (v < 0 || v > 65535)
throw new Error("Variable '" + lbl + "' value is out of bounds for this processor.");
this.__varlabels[lbl] = v;
} else {
throw new Error("Variable '" + lbl + "' value malformed.");
}
}

__StoreJmpLabel(lbl){
if (lbl in this.__jmplabels)
throw new Error("Jump label '" + lbl + "' defined more than once at program address " + toHexString(this.__PC));
if (lbl in this.__varlabels)
throw new Error("Jump label '" + lbl + "' matches already existing variable name at program address " + toHexString(this.__PC));
this.__jmplabels[lbl] = this.__PC;
}

__AddrModeVal(tA, tB){
var mode = "";
var v = Number.NaN;
if (tA[0] === '#'){
@@ -207,15 +240,10 @@ class Assembler{

if (tokens[0] === 'define'){
// Variable label!!
this.__StoreVarLabel(tokens[1], tokens[2]);
} else if (tokens[0][tokens[0].length - 1] === ':'){
// Jump labels!
// TODO: Finish me!!
let lbl = tokens[0].substr(0, tokens[0].length - 1);
if (lbl in this.__jmplabels)
throw new Error("Jump label '" + lbl + "' defined more than once at program address " + toHexString(this.__PC));
if (lbl in this.__varlabels)
throw new Error("Jump label '" + lbl + "' matches already existing variable name at program address " + toHexString(this.__PC));
this.__jmplabels[lbl] = this.__PC;
this.__StoreJmpLabel(tokens[0].substr(0, tokens[0].length - 1););
} else if (tokens[0].length === 3){

let StoreSingleOp = (code)=>{
@@ -228,12 +256,19 @@ class Assembler{
};

let StoreBranchOp = (code) => {
// TODO: If value is not valid, test to see if it's a jump or variable value.
if (tokens.length === 2){
if (token[1][0] === '$' && (tokens[1].length === 3 || tokens[1].length === 5)){
let v = parseInt(token[1].substr(1), 16);
if (isNaN(v))
return false;
let v = Number.NaN;
if (token[1][0] === '$'){
if (tokens[1].length === 3 || tokens[1].length === 5){
v = parseInt(token[1].substr(1), 16);
}
} else {
if (tokens[1] in this.__jmplabels){
v = this.__jmplabels[tokens[1]];
}
}

if (!isNaN(v)){
if (v < this.__PC - 127 || v > this.__PC + 128)
throw new Error("Branch exceeds maximum number of bytes on program address " + toHexString(this.__PC));
v = v - this.__PC;
@@ -444,46 +479,49 @@ class Assembler{
procFailed = StoreSingleOp(0xC8); break;
// --- JMP
case 'jmp':
// TODO: Update value results to test for jump names if value not a number.
if (tokens.length === 2){
if (tokens[1].startsWith("$") && tokens[1].length === 5){
let v = parseInt(tokens[1].substr(1), 16);
if (!isNaN(v)){
op.push(0x4C);
op.push(v & 0x000000FF);
op.push((v & 0x0000FF00) >> 8);
this.__PC += 3;
} else {
throw new Error("Malformed op-code or value on program address " + toHexString(this.__PC));
}
} else if (tokens[1].startsWith("+$") && tokens[1].length === 6){
let v = parseInt(tokens[1].substr(2), 16);
if (!isNaN(v)){
op.push(0x6C);
op.push(v & 0x000000FF);
op.push((v & 0x0000FF00) >> 8);
this.__PC += 3;
} else {
throw new Error("Malformed op-code or value on program address " + toHexString(this.__PC));
}
} else { procFailed = true; }
let v = Number.NaN;
let code = (tokens[1].startsWith("+")) ? 0x6C : 0x4C;
if (tokens[1].startsWith("$")){
if (tokens[1].length === 5)
v = parseInt(tokens[1].substr(1), 16);
} else if (tokens[1].startsWith("+$")){
if (tokens[1].length === 6)
v = parseInt(tokens[1].substr(2), 16);
} else {
let lbl = (tokens[1].startsWith("+")) ? tokens[1].substr(1) : tokens[1];
if (lbl in this.__jmplabels)
v = this.__jmplabels[lbl];
}
if (!isNaN(v)){
op.push(code);
op.push(v & 0x000000FF);
op.push((v & 0x0000FF00) >> 8);
this.__PC += 3;
} else {
throw new Error("Malformed op-code or value on program address " + toHexString(this.__PC));
}
} else { procFailed = true; }
break;
// --- JSR
case 'jsr':
// TODO: Update value results to test for jump names if value not a number.
if (tokens.length === 2){
if (tokens[1].startsWith("$") && tokens[1].length === 5){
let v = parseInt(tokens[1].substr(1), 16);
if (!isNaN(v)){
op.push(0x20);
op.push(v & 0x000000FF);
op.push((v & 0x0000FF00) >> 8);
this.__PC += 3;
} else {
throw new Error("Malformed op-code or value on program address " + toHexString(this.__PC));
}
} else { procFailed = true; }
let v = Number.NaN;
if (tokens[1].startsWith("$")){
if (tokens[1].length === 5)
v = parseInt(tokens[1].substr(1), 16);
} else {
if (tokens[1] in this.__jmplabels)
v = this.__jmplabels[tokens[1]];
}
if (!isNaN(v)){
op.push(0x20);
op.push(v & 0x000000FF);
op.push((v & 0x0000FF00) >> 8);
this.__PC += 3;
} else {
throw new Error("Malformed op-code or value on program address " + toHexString(this.__PC));
}
} else {
procFailed = true;
}

Loading…
Cancel
Save