diff --git a/TODO b/TODO index bdd8fc8..0aab6b3 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,8 @@ Testing: - Tests needed for the numerous other operations added CPU: - More work on interrupts -- Decimal mode support +- Decimal mode support(figure out details as to how it handles illegal BCD + numbers) - Have each operation return the number of cycles used by the execute function. - Optimization Memory: diff --git a/cpu.js b/cpu.js index 322c45e..2983425 100644 --- a/cpu.js +++ b/cpu.js @@ -3610,22 +3610,46 @@ var ADC_const = { execute:function(cpu, bytes) { var old_a = cpu.r.a; if(cpu.p.e|cpu.p.m) { - cpu.r.a += bytes[0] + cpu.p.c; - if(cpu.r.a & 0x100) { - cpu.p.c = 1; + if(cpu.p.d) { + // Form a decimal number out of a. + var ones = cpu.r.a & 0x0f; + var tens = cpu.r.a >>4; + var dec_a = (tens*10)+ones; + + // Form a decimal number out of the argument. + ones = bytes[0] & 0x0f; + tens = bytes[0] >>4; + var dec_arg = (tens*10)+ones; + var result = dec_a + dec_arg; + // Check for decimal overflow. + if(result>99) { + result -= 99; + cpu.p.c = 1; + } + var digits = result.toString(10).split(""); + var i = 0; + cpu.r.a = 0; + for(i=0;i> 7; + 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; - // Check for signed overflow. - // If they started with the same sign and then the resulting sign is - // different then we have a signed overflow. - if((!((old_a ^ bytes[0]) & 0x80)) && ((cpu.r.a ^ old_a) & 0x80)) { - cpu.p.v = 1; - } else { - cpu.p.v = 0; + // Check for signed overflow. + // If they started with the same sign and then the resulting sign is + // different then we have a signed overflow. + if((!((old_a ^ bytes[0]) & 0x80)) && ((cpu.r.a ^ old_a) & 0x80)) { + cpu.p.v = 1; + } else { + cpu.p.v = 0; + } } } else { var argument = (bytes[1]<<8)|bytes[0]; diff --git a/test/tests.js b/test/tests.js index 13601ff..e451c9e 100644 --- a/test/tests.js +++ b/test/tests.js @@ -15,7 +15,7 @@ */ function run_tests() { - test_lda(); + test_lda(); test_rep(); test_sep(); test_branching(); @@ -566,6 +566,52 @@ function test_adc() { "using ADC"); }); + test("Test that ADC handles decimal mode with legal BCD numbers in 8-bit "+ + "memory/accumulator mode with single digit numbers.", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18f8a9056905"); + equals(cpu.r.a, 0x10, "0x05 + 0x05 should result in 0x10 with decimal "+ + "mode on and with 8-bit memory/accumulator mode."); + equals(cpu.p.c, 0, "The carry flag of the p status register should be "+ + "clear after no decimal overflow."); + equals(cpu.p.d, 1, "Decimal mode should be set to 1 in the p status "+ + "register."); + equals(cpu.p.m, 1, "The m flag of the p status register should be 1 for "+ + "8-bit memory/accumulator mode."); + equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+ + "be 0 for native mode."); + }); + test("Test that ADC handles decimal mode with legal BCD numbers in 8-bit "+ + "memory/accumulator mode with double digit numbers.", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18f8a9156926"); + equals(cpu.r.a, 0x41, "0x15 + 0x26 should result in 0x41 with decimal "+ + "mode on and with 8-bit memory/accumulator mode."); + equals(cpu.p.c, 0, "The carry flag of the p status register should be "+ + "clear after no decimal overflow."); + equals(cpu.p.d, 1, "Decimal mode should be set to 1 in the p status "+ + "register."); + equals(cpu.p.m, 1, "The m flag of the p status register should be 1 for "+ + "8-bit memory/accumulator mode."); + equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+ + "be 0 for native mode."); + }); + test("Test that ADC handles decimal mode with legal BCD numbers in 8-bit "+ + "memory/accumulator mode when adding two numbers that cause an "+ + "overflow.", function() { + var cpu = new CPU_65816(); + cpu.execute("18fb18f8a9556960"); + equals(cpu.r.a, 0x16, "0x55 + 0x60 should result in 0x16 with decimal "+ + "mode on and with 8-bit memory/accumulator mode."); + equals(cpu.p.c, 1, "The carry flag of the p status register should be "+ + "set after the decimal overflow."); + equals(cpu.p.d, 1, "Decimal mode should be set to 1 in the p status "+ + "register."); + equals(cpu.p.m, 1, "The m flag of the p status register should be 1 for "+ + "8-bit memory/accumulator mode."); + equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+ + "be 0 for native mode."); + }); } function test_branching() {