mirror of
https://github.com/pskupinski/65816.js.git
synced 2024-11-16 13:06:52 +00:00
added decimal mode support for SBC, wrote unit tests to verify that support and updated the TODO
This commit is contained in:
parent
b505f7a50d
commit
d902611e9c
8
TODO
8
TODO
@ -3,14 +3,14 @@ Testing:
|
||||
- More tests for CMP/CPY/CPX operations
|
||||
- Tests needed for JMP operations
|
||||
- Tests needed for LD* and ST* operations
|
||||
- Tests needed for bank/page wrapping
|
||||
- Tests needed for IN* and DE* operations
|
||||
- Tests needed for T** transfer operations
|
||||
- Tests needed for interrupt support
|
||||
- Tests needed for the numerous other operations added
|
||||
CPU:
|
||||
- More work on interrupts
|
||||
- Decimal mode support(figure out details as to how it handles illegal BCD
|
||||
numbers)
|
||||
- Figure out the exact details of how the 65816 handles illegal BCD numbers
|
||||
when decimal mode is set
|
||||
- Have each operation return the number of cycles used by the execute function.
|
||||
- Optimization
|
||||
Memory:
|
||||
@ -18,8 +18,6 @@ Memory:
|
||||
settings
|
||||
- Page wrapping or not wrapping for certain addressing modes and with certain
|
||||
settings
|
||||
- ROM protection
|
||||
- Improve the memory mapped I/O interface and handling
|
||||
Display:
|
||||
- Add the ability to step, pause and stop execution
|
||||
- Ability to view the path of operation execution as it executes, like have
|
||||
|
127
cpu.js
127
cpu.js
@ -3227,44 +3227,109 @@ var SBC_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 < 0) {
|
||||
cpu.p.c = 0;
|
||||
cpu.r.a = 0x100 + cpu.r.a;
|
||||
} else {
|
||||
cpu.p.c = 1;
|
||||
}
|
||||
cpu.p.n = cpu.r.a >> 7;
|
||||
var temp = 0;
|
||||
if(cpu.p.c===0)
|
||||
temp = 1;
|
||||
|
||||
// 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;
|
||||
if(cpu.p.e|cpu.p.m) {
|
||||
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 - temp;
|
||||
// Check for decimal overflow.
|
||||
if(result<0) {
|
||||
result += 100;
|
||||
cpu.p.c = 0;
|
||||
} else {
|
||||
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.v = 0;
|
||||
cpu.r.a -= bytes[0] - temp;
|
||||
if(cpu.r.a < 0) {
|
||||
cpu.p.c = 0;
|
||||
cpu.r.a = 0x100 + cpu.r.a;
|
||||
} else {
|
||||
cpu.p.c = 1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var argument = (bytes[1]<<8)|bytes[0];
|
||||
cpu.r.a -= argument - cpu.p.c;
|
||||
if(cpu.r.a < 0) {
|
||||
cpu.p.c = 0;
|
||||
cpu.r.a = 0x10000 + cpu.r.a;
|
||||
} else {
|
||||
cpu.p.c = 1;
|
||||
}
|
||||
cpu.p.n = cpu.r.a >> 15;
|
||||
var temp = 0;
|
||||
if(cpu.p.c===0)
|
||||
temp = 1;
|
||||
|
||||
// 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;
|
||||
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 - temp;
|
||||
// Check for decimal overflow.
|
||||
if(result<0) {
|
||||
result += 10000;
|
||||
cpu.p.c = 0;
|
||||
} else {
|
||||
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.v = 0;
|
||||
}
|
||||
}
|
||||
cpu.r.a -= argument - temp;
|
||||
if(cpu.r.a < 0) {
|
||||
cpu.p.c = 0;
|
||||
cpu.r.a = 0x10000 + cpu.r.a;
|
||||
} else {
|
||||
cpu.p.c = 1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cpu.r.a===0) {
|
||||
cpu.p.z = 1;
|
||||
|
@ -373,7 +373,7 @@ function test_sbc() {
|
||||
test("Test normal subtraction of two 8-bit numbers that don't cause a "+
|
||||
"borrow.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbe23018a901e901");
|
||||
cpu.execute("18fbe230a90138e901");
|
||||
equals(cpu.r.a, 0, "0x01 - 0x01 should result in zero when using "+
|
||||
"SBC");
|
||||
equals(cpu.p.z, 1, "0x01 - 0x01 should set the zero(z) bit when "+
|
||||
@ -389,7 +389,7 @@ function test_sbc() {
|
||||
test("Test normal subtraction of two 16-bit numbers that don't cause a "+
|
||||
"borrow.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbc23018a90100e90100");
|
||||
cpu.execute("18fbc230a9010038e90100");
|
||||
equals(cpu.r.a, 0, "0x0001 - 0x0001 should result in zero when using "+
|
||||
"SBC");
|
||||
equals(cpu.p.z, 1, "0x0001 - 0x0001 should set the zero(z) bit when "+
|
||||
@ -404,7 +404,7 @@ function test_sbc() {
|
||||
test("Test subtraction that triggers a borrow with 8-bit numbers",
|
||||
function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbe23018a9d0e9ef");
|
||||
cpu.execute("18fbe230a9d038e9ef");
|
||||
equals(cpu.r.a, 0xe1, "0xd0 - 0xef should set the accumulator to 0xe1 "+
|
||||
"when using SBC");
|
||||
equals(cpu.p.n, 1, "0xd0 - 0xef should set the negative(n) bit when "+
|
||||
@ -419,7 +419,7 @@ function test_sbc() {
|
||||
test("Test subtraction that triggers a borrow with 16-bit numbers",
|
||||
function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbc23018a900d0e900ef");
|
||||
cpu.execute("18fbc230a900d038e900ef");
|
||||
equals(cpu.r.a, 0xe100, "0xd000 - 0xef00 should set the accumulator to "+
|
||||
"0xe0ff when using SBC");
|
||||
equals(cpu.p.n, 1, "0xd000 - 0xef00 should set the negative(n) bit when "+
|
||||
@ -431,6 +431,90 @@ function test_sbc() {
|
||||
equals(cpu.p.c, 0, "0xd000 - 0xef00 should not set the carry(c) bit when "+
|
||||
"using SBC");
|
||||
});
|
||||
test("Test subtraction with decimal mode on with two single digit 8-bit "+
|
||||
"numbers.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbf8a90938e905");
|
||||
equals(cpu.r.a, 4, "The accumulator should be 4 after subtracting 0x5 "+
|
||||
"0x9 with decimal mode on with 8-bit "+
|
||||
"memory/accumulator mode.");
|
||||
equals(cpu.p.c, 1, "The carry bit should be set after no borrow is "+
|
||||
"triggered.");
|
||||
equals(cpu.p.m, 1, "The m flag of the p status register should be one "+
|
||||
"for 8-bit memory/accumulator mode.");
|
||||
equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+
|
||||
"be zero for native mode.");
|
||||
});
|
||||
test("Test subtraction with decimal mode on with two double digit 8-bit "+
|
||||
"numbers.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbf8a99038e949");
|
||||
equals(cpu.r.a, 0x41, "The accumulator should be 41 after subtracting 0x49 "+
|
||||
"from 0x90 with decimal mode on with 8-bit "+
|
||||
"memory/accumulator mode.");
|
||||
equals(cpu.p.c, 1, "The carry bit should be set after no borrow is "+
|
||||
"triggered.");
|
||||
equals(cpu.p.m, 1, "The m flag of the p status register should be one "+
|
||||
"for 8-bit memory/accumulator mode.");
|
||||
equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+
|
||||
"be zero for native mode.");
|
||||
});
|
||||
test("Test subtraction with decimal mode on with 8-bit numbers that causes "+
|
||||
"a borrow.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbf8a91038e920");
|
||||
equals(cpu.r.a, 0x90, "The accumulator should be 0x90 after subtracting "+
|
||||
"0x20 from 0x10 with decimal and 8-bit "+
|
||||
"memory/accumulator modes.");
|
||||
equals(cpu.p.c, 0, "The carry bit should be clear after a borrow is "+
|
||||
"triggered.");
|
||||
equals(cpu.p.m, 1, "The m flag of the p status register should be one "+
|
||||
"for 8-bit memory/accumulator mode.");
|
||||
equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+
|
||||
"be zero for native mode.");
|
||||
});
|
||||
test("Test subtraction of two single digit 16-bit numbers with decimal "+
|
||||
"mode set.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbc220f8a9050038e90200");
|
||||
equals(cpu.r.a, 0x03, "The accumulator should be 0x03 after subtracting "+
|
||||
"0x02 from 0x05 with decimal and 16-bit "+
|
||||
"memory/accumulator modes.");
|
||||
equals(cpu.p.c, 1, "The carry bit should be set after no borrow is "+
|
||||
"triggered.");
|
||||
equals(cpu.p.m, 0, "The m flag of the p status register should be zero "+
|
||||
"for 16-bit memory/accumulator mode.");
|
||||
equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+
|
||||
"be zero for native mode.");
|
||||
});
|
||||
test("Test subtraction of two four digit 16-bit numbers with decimal "+
|
||||
"mode set.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbc220f8a9999938e91111");
|
||||
equals(cpu.r.a, 0x8888, "The accumulator should be 0x8888 after "+
|
||||
"subtracting 0x1111 from 0x9999 with decimal "+
|
||||
"and 16-bit memory/accumulator modes.");
|
||||
equals(cpu.p.c, 1, "The carry bit should be set after no borrow is "+
|
||||
"triggered.");
|
||||
equals(cpu.p.m, 0, "The m flag of the p status register should be zero "+
|
||||
"for 16-bit memory/accumulator mode.");
|
||||
equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+
|
||||
"be zero for native mode.");
|
||||
});
|
||||
test("Test subtraction of two four digit 16-bit numbers with decimal "+
|
||||
"mode set that causes a borrow.", function() {
|
||||
var cpu = new CPU_65816();
|
||||
cpu.execute("18fbc220f8a9111138e99999");
|
||||
equals(cpu.r.a, 0x1112, "The accumulator should be 0x1112 after "+
|
||||
"subtracting 0x9999 from 0x1111 with decimal "+
|
||||
"and 16-bit memory/accumulator modes.");
|
||||
equals(cpu.p.c, 0, "The carry bit should be clear after a borrow is "+
|
||||
"triggered.");
|
||||
equals(cpu.p.m, 0, "The m flag of the p status register should be zero "+
|
||||
"for 16-bit memory/accumulator mode.");
|
||||
equals(cpu.p.e, 0, "The hidden e flag of the p status register should "+
|
||||
"be zero for native mode.");
|
||||
});
|
||||
}
|
||||
|
||||
function test_adc() {
|
||||
|
Loading…
Reference in New Issue
Block a user