diff --git a/cpu.js b/cpu.js index d117a6a..9923010 100644 --- a/cpu.js +++ b/cpu.js @@ -79,7 +79,8 @@ function CPU_65816() { 0x98 : TYA, 0x4c : JMP_absolute, 0x6c : JMP_absolute_indirect, 0x80 : BRA, 0xf0 : BEQ, 0xd0 : BNE, 0x90 : BCC, 0xb0 : BCS, - 0x50 : BVC, 0x70 : BVS, 0x10 : BPL, 0x30 : BMI }; + 0x50 : BVC, 0x70 : BVS, 0x10 : BPL, 0x30 : BMI, + 0x69 : ADC_const }; } var MMU = { @@ -119,6 +120,44 @@ var MMU = { } }; +var ADC_const = { + bytes_required:function(cpu) { + if(cpu.p.m) { + return 2; + } else { + return 3; + } + }, + execute:function(cpu, bytes) { + // TODO: Signed overflow checking. + if(cpu.p.m) { + cpu.r.a += bytes[0] + cpu.p.c; + if(cpu.r.a & 0x100) { + cpu.p.c = 1; + } else { + cpu.p.c = 0; + } + cpu.r.a &= 0xff; + cpu.p.n = cpu.r.a >> 7; + } else { + cpu.r.a += (bytes[1]<<8)|bytes[0] + cpu.p.c; + if(cpu.r.a & 0x10000) { + cpu.p.c = 1; + } else { + cpu.p.c = 0; + } + cpu.r.a &= 0xffff; + cpu.p.n = cpu.r.a >> 15; + } + + if(cpu.r.a===0) { + cpu.p.z = 1; + } else { + cpu.p.z = 0; + } + } +}; + var BMI = { bytes_required:function() { return 2; diff --git a/test/tests.js b/test/tests.js index f76a7a0..d85b42f 100644 --- a/test/tests.js +++ b/test/tests.js @@ -18,6 +18,66 @@ function run_tests() { test_rep(); test_sep(); test_branching(); + test_adc(); +} + +function test_adc() { + module("ADC"); + // TODO: signed overflow testing. + test("Test normal addition of two 16-bit numbers that don't cause an "+ + "overflow (m bit is 0)", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18c230a90100690100"); + equals(cpu.r.a, 2, "0x0001 + 0x0001 should result in 0x0002 when using "+ + "ADC"); + equals(cpu.p.n, 0, "0x0001 + 0x0001 does not result in a negative "+ + "two's complement number when adding with ADC."); + equals(cpu.p.c, 0, "0x0001 + 0x0001 should not set the carry(c) bit when "+ + "adding with ADC"); + equals(cpu.p.z, 0, "0x0001 + 0x0001 should not set the zero(z) bit when "+ + "adding with ADC"); + }); + test("Test normal addition of two 8-bit numbers that don't cause an "+ + "overflow (m bit is 1)", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18e230a9016901"); + equals(cpu.r.a, 2, "0x01 + 0x01 should result in 0x02 when using "+ + "ADC"); + equals(cpu.p.n, 0, "0x01 + 0x01 does not result in a negative "+ + "two's complement number when adding with ADC."); + equals(cpu.p.c, 0, "0x01 + 0x01 should not set the carry(c) bit when "+ + "adding with ADC"); + equals(cpu.p.z, 0, "0x01 + 0x01 should not set the zero(z) bit when "+ + "adding with ADC"); + }); + + test("Test that overflow sets the carry flag and works in general with two"+ + "16-bit numbers (m bit is 0)", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18c230a9ffff690100"); + equals(cpu.p.c, 1, "0xffff + 0x0001 should set the carry bit when using "+ + "ADC"); + equals(cpu.r.a, 0, "0xffff + 0x0001 should result in the accumulator "+ + "being 0 when using ADC"); + equals(cpu.p.n, 0, "0xffff + 0x0001 should not set the negative(n) bit "+ + "when using ADC"); + equals(cpu.p.z, 1, "0xffff + 0x0001 should set the zero(z) bit when using "+ + "ADC"); + }); + + test("Test that overflow sets the carry flag and works in general with two"+ + "8-bit numbers (m bit is 1)", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18e230a9ff6901"); + equals(cpu.p.c, 1, "0xff + 0x01 should set the carry bit when using "+ + "ADC"); + equals(cpu.r.a, 0, "0xff + 0x01 should result in the accumulator "+ + "being 0 when using ADC"); + equals(cpu.p.n, 0, "0xff + 0x01 should not set the negative(n) bit when "+ + "using ADC"); + equals(cpu.p.z, 1, "0xff + 0x01 should set the zero(z) bit when using "+ + "ADC"); + }); } function test_branching() {