UNPKG

@asm80/core

Version:

Core ASM80 compiler / assembler

249 lines (208 loc) 7.78 kB
import {CDP1802} from "../cpu/cdp1802.js"; import { Parser } from "../expression-parser.js"; QUnit.config.hidepassed = true; QUnit.module("ASM CDP1802"); QUnit.test( "Namespace", function() { QUnit.assert.notEqual( CDP1802, null, "CDP1802 is defined" ); QUnit.assert.equal( typeof(CDP1802), "object", "CDP1802 is an object" ); QUnit.assert.equal( typeof(CDP1802.parseOpcode), "function", "CDP1802.parseOpcode defined" ); }); //QUnit.module("Simple OP tests"); var vars = {"LOOP":0x1234,"SHORT":0x21,"_PC":0x0100}; var s = [], p; QUnit.test( "NOP test", function() { s = {"opcode":"NOP","addr":0x100,"lens":[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0xC4,"Opcode OK"); QUnit.assert.equal(p.bytes,1,"Length OK"); }); //QUnit.module("Single param tests"); //// QUnit.test( "ADCI", function() { s = {"opcode":"ADCI","params":["$23"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0x7c,"Opcode"); QUnit.assert.equal(typeof(p.lens[1]),"function","Opcode"); QUnit.assert.equal(p.bytes,2,"Length"); var par = p.lens[1]({}); QUnit.assert.equal(par,0x23,"Param"); }); QUnit.test( "ADCI #23", function() { s = {"opcode":"ADCI","params":["#23"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0x7c,"Opcode"); QUnit.assert.equal(typeof(p.lens[1]),"function","Opcode"); QUnit.assert.equal(p.bytes,2,"Length"); var par = p.lens[1]({}); QUnit.assert.equal(par,0x23,"Param"); }); //QUnit.module("Register tests"); QUnit.test( "SEX 1", function() { s = {"opcode":"SEX","params":["1"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0xe1,"Opcode"); QUnit.assert.equal(p.bytes,1,"Length"); }); QUnit.test( "SEX E", function() { s = {"opcode":"SEX","params":["e"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0xee,"Opcode"); QUnit.assert.equal(p.bytes,1,"Length"); }); QUnit.test( "SEX R15", function() { s = {"opcode":"SEX","params":["R15"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0xef,"Opcode"); QUnit.assert.equal(p.bytes,1,"Length"); }); QUnit.test( "SEX name", function() { s = {"opcode":"SEX","params":["VAR"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, {'VAR':13}, Parser); QUnit.assert.equal(p.lens[0],0xed,"Opcode"); QUnit.assert.equal(p.bytes,1,"Length"); }); //QUnit.module("Port tests"); QUnit.test( "INP 1", function() { s = {"opcode":"INP","params":["1"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0x69,"Opcode"); QUnit.assert.equal(p.bytes,1,"Length"); }); QUnit.test( "OUT 1", function() { s = {"opcode":"OUT","params":["1"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0x61,"Opcode"); QUnit.assert.equal(p.bytes,1,"Length"); }); //QUnit.module("Jump tests"); QUnit.test( "LBR 1234", function() { s = {"opcode":"LBR","params":["$1234"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0xc0,"Opcode"); QUnit.assert.equal(typeof(p.lens[1]),"function","Opcode"); QUnit.assert.equal(p.bytes,3,"Length"); }); QUnit.test( "LBR loop", function() { s = {"opcode":"LBR","params":["LOOP"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0xc0,"Opcode"); //check callback let ad1 = p.lens[1](vars); let ad2 = p.lens[2](vars); QUnit.assert.equal(ad2,0x12,"Param"); QUnit.assert.equal(ad1,0x34,"Param"); QUnit.assert.equal(p.bytes,3,"Length"); }); QUnit.test( "B1 $10", function() { s = {"opcode":"B1","params":["$10"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p.lens[0],0x34,"Opcode"); QUnit.assert.equal(typeof(p.lens[1]),"function","Opcode"); QUnit.assert.equal(p.bytes,2,"Length"); var par = p.lens[1]({}); QUnit.assert.equal(par,0x10,"Param"); }); QUnit.test( "B1 lbl", function() { s = {"opcode":"B1","params":["LBL"],addr:"0x100",lens:[],"bytes":0}; var varsLocal = {_PC:0x100,LBL:0x123}; p = CDP1802.parseOpcode(s,varsLocal, Parser); QUnit.assert.equal(p.lens[0],0x34,"Opcode"); QUnit.assert.equal(typeof(p.lens[1]),"function","Opcode"); QUnit.assert.equal(p.bytes,2,"Length"); var par = p.lens[1](varsLocal); QUnit.assert.equal(par,0x23,"Param"); }); //QUnit.module("Bad tests"); QUnit.test( "B1 over the boundary", function() { try { s = {"opcode":"B1","params":["LBL"],addr:"0x100",lens:[],"bytes":0}; var varsLocal = {_PC:0x100,LBL:0x223}; p = CDP1802.parseOpcode(s,varsLocal, Parser); var par = p.lens[1](varsLocal); } catch (e) { p = e; } QUnit.assert.equal(p,"Cross page jump","Cross page jump detected"); }); QUnit.test( "Bad port number", function() { try { s = {"opcode":"INP","params":["0"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); } catch (e) { p = e; } QUnit.assert.equal(p,"Unrecognized port: 0","Bad port number detected"); }); QUnit.test( "Register evaluation error handling", function() { try { s = {"opcode":"SEX","params":["UNDEFINED_VAR"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, {}, Parser); } catch (e) { p = e; } QUnit.assert.equal(p,"Unrecognized register: UNDEFINED_VAR","Register evaluation error detected"); }); QUnit.test( "Register out of range - too high", function() { try { s = {"opcode":"SEX","params":["16"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); } catch (e) { p = e; } QUnit.assert.equal(p,"Unrecognized register: 16","Register too high detected"); }); QUnit.test( "Register out of range - negative", function() { try { s = {"opcode":"SEX","params":["-1"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); } catch (e) { p = e; } QUnit.assert.equal(p,"Unrecognized register: -1","Negative register detected"); }); QUnit.test( "Port evaluation error handling", function() { try { s = {"opcode":"INP","params":["UNDEFINED_VAR"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, {}, Parser); } catch (e) { p = e; } QUnit.assert.equal(p,"Unrecognized port: UNDEFINED_VAR","Port evaluation error detected"); }); QUnit.test( "Port out of range - too high", function() { try { s = {"opcode":"INP","params":["8"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); } catch (e) { p = e; } QUnit.assert.equal(p,"Unrecognized port: 8","Port too high detected"); }); QUnit.test( "Unrecognized opcode returns null", function() { s = {"opcode":"INVALID","params":["1"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s, vars, Parser); QUnit.assert.equal(p, null, "Unrecognized opcode returns null"); }); QUnit.test( "Endian property", function() { QUnit.assert.equal(CDP1802.endian, true, "CDP1802 is big-endian"); }); /* test( "EXG A", function() { throws(function(){ s = {"opcode":"EXG","params":["A"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s); }); }); test( "EXG A,B,C", function() { throws(function(){ s = {"opcode":"EXG","params":["A","B","C"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s); }); }); test( "EXG A,C", function() { throws(function(){ s = {"opcode":"EXG","params":["A","C"],addr:"0x100",lens:[],"bytes":0}; p = CDP1802.parseOpcode(s); }); }); */