add decimal mode support for adc in emulation or 8-bit memory/accumulator mode and wrote up unit tests to verify it

This commit is contained in:
Preston Skupinski 2011-09-03 21:20:52 -04:00
parent 3f23b8f7f7
commit 990bbdc06c
3 changed files with 87 additions and 16 deletions

3
TODO
View File

@ -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:

52
cpu.js
View File

@ -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<digits.length;i++) {
cpu.r.a += (digits[i]-0)*Math.pow(16,digits.length-i-1);
}
} else {
cpu.p.c = 0;
}
cpu.r.a &= 0xff;
cpu.p.n = cpu.r.a >> 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];

View File

@ -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() {