added decimal mode support for adc with 16-bit memory/accumulator mode and wrote unit tests to verify it

This commit is contained in:
Preston Skupinski 2011-09-03 21:56:39 -04:00
parent 8a1f3364ff
commit 7cee0a3cd1
2 changed files with 93 additions and 14 deletions

56
cpu.js
View File

@ -3653,22 +3653,50 @@ var ADC_const = {
}
} else {
var argument = (bytes[1]<<8)|bytes[0];
cpu.r.a += argument + cpu.p.c;
if(cpu.r.a & 0x10000) {
cpu.p.c = 1;
if(cpu.p.d) {
// Form a decimal number out of a.
var ones = cpu.r.a & 0xf;
var tens = (cpu.r.a >>4) & 0xf;
var hundreds = (cpu.r.a >> 8) & 0xf;
var thousands = (cpu.r.a >> 12) & 0xf;
var dec_a = (thousands*1000)+(hundreds*100)+(tens*10)+ones;
// Form a decimal number out of the argument.
ones = argument & 0xf;
tens = (argument >> 4) & 0xf;
hundreds = (argument >> 8) & 0xf;
thousands = (argument >> 12) & 0xf;
var dec_arg = (thousands*1000)+(hundreds*100)+(tens*10)+ones;
var result = dec_a + dec_arg;
// Check for decimal overflow.
if(result>9999) {
result -= 9999;
cpu.p.c = 1;
}
var digits = result.toString(10).split("");
var i = 0;
cpu.r.a = 0;
for(i=0;i<digits.length;i++) {
cpu.r.a += (digits[i]-0)*Math.pow(16,digits.length-i-1);
}
} else {
cpu.p.c = 0;
}
cpu.r.a &= 0xffff;
cpu.p.n = cpu.r.a >> 15;
cpu.r.a += argument + 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;
// 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 ^ argument) & 0x8000)) && ((cpu.r.a ^ old_a) & 0x8000)) {
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 ^ argument) & 0x8000)) && ((cpu.r.a ^ old_a) & 0x8000)) {
cpu.p.v = 1;
} else {
cpu.p.v = 0;
}
}
}

View File

@ -664,6 +664,57 @@ function test_adc() {
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 16-bit "+
"memory/accumulator mode when adding two single digit numbers.",
function() {
var cpu = new CPU_65816();
cpu.execute("18fb18f8c220a90100690900");
equals(cpu.r.a, 0x10, "0x0001 + 0x0009 should result in 0x0010 with "+
"decimal mode on and with 16-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, 0, "The m flag of the p status register should be 0 for "+
"16-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 16-bit "+
"memory/accumulator mode when adding two four digit numbers.",
function() {
var cpu = new CPU_65816();
cpu.execute("18fb18f8c220a90110699939");
equals(cpu.r.a, 0x5000, "0x1001 + 0x3999 should result in 0x5000 with "+
"decimal mode on and with 16-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, 0, "The m flag of the p status register should be 0 for "+
"16-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 16-bit "+
"memory/accumulator mode when adding two numbers that cause an "+
"overflow.", function() {
var cpu = new CPU_65816();
cpu.execute("18fb18f8c220a99756699999");
equals(cpu.r.a, 0x5697, "0x5697 + 0x9999 should result in 0x5697 with "+
"decimal mode on and with 16-bit "+
"memory/accumulator mode.");
equals(cpu.p.c, 1, "The carry flag of the p status register should be "+
"set after decimal overflow.");
equals(cpu.p.d, 1, "Decimal mode should be set to 1 in the p status "+
"register.");
equals(cpu.p.m, 0, "The m flag of the p status register should be 0 for "+
"16-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() {