cleanup of DEC instructions and started writing tests for them

This commit is contained in:
Preston Skupinski 2012-01-03 10:15:43 -05:00
parent 55f059b09c
commit 577b47a497
2 changed files with 81 additions and 253 deletions

279
cpu.js
View File

@ -29,7 +29,10 @@ var cpu_lib = {
} }
}, },
inc: { inc: {
Inc_register: function(register, flag) { INC_register: function(register, flag, value) {
if(typeof value === 'undefined')
value = 1;
this.bytes_required = function() { this.bytes_required = function() {
return 1; return 1;
}; };
@ -37,7 +40,7 @@ var cpu_lib = {
this.execute = function(cpu) { this.execute = function(cpu) {
cpu.cycle_count+=2; cpu.cycle_count+=2;
cpu.r[register]++; cpu.r[register]+=value;
if(cpu.p.e||cpu.p[flag]) { if(cpu.p.e||cpu.p[flag]) {
cpu.r[register] &= 0xff; cpu.r[register] &= 0xff;
@ -50,17 +53,20 @@ var cpu_lib = {
cpu_lib.r.p.check_z(cpu, cpu.r[register]); cpu_lib.r.p.check_z(cpu, cpu.r[register]);
}; };
}, },
INC_memory: function() { INC_memory: function(value) {
if(typeof value === 'undefined')
value = 1;
this.execute = function(cpu, bytes, extra) { this.execute = function(cpu, bytes, extra) {
cpu.cycle_count+=4; cpu.cycle_count+=4;
if(cpu.p.e||cpu.p.m) { if(cpu.p.e||cpu.p.m) {
temp = (bytes[0] + 1) & 0xff; temp = (bytes[0] + value) & 0xff;
cpu.p.n = temp >> 7; cpu.p.n = temp >> 7;
cpu.mmu.store_byte(extra.memory_location, temp); cpu.mmu.store_byte(extra.memory_location, temp);
} else { } else {
cpu.cycle_count+=2; cpu.cycle_count+=2;
temp = ((bytes[1]<<8)|bytes[0]) + 1; temp = (((bytes[1]<<8)|bytes[0]) + value) & 0xffff;
cpu.p.n = temp >> 15; cpu.p.n = temp >> 15;
cpu.mmu.store_word(extra.memory_location, temp); cpu.mmu.store_word(extra.memory_location, temp);
} }
@ -3038,264 +3044,31 @@ var LDY_direct_page = new cpu_lib.addressing.Direct_page(LDY_const);
var LDY_direct_page_indexed_x = var LDY_direct_page_indexed_x =
new cpu_lib.addressing.Direct_page_indexed_x(LDY_direct_page); new cpu_lib.addressing.Direct_page_indexed_x(LDY_direct_page);
var DEX = { // Implement the decrement instructions as increment instructions that
bytes_required:function() { // increment by negative one.
return 1; var DEX = new cpu_lib.inc.INC_register('x', 'x', -1);
},
execute:function(cpu) {
cpu.cycle_count+=2;
if(cpu.r.x===0) { var DEY = new cpu_lib.inc.INC_register('y', 'x', -1);
if(cpu.p.e||cpu.p.x) {
cpu.r.x = 0xff;
} else {
cpu.r.x = 0xffff;
}
cpu.p.n = 1;
cpu.p.z = 0;
} else {
cpu.r.x--;
if(cpu.p.e||cpu.p.x) {
cpu.p.n = cpu.r.x >> 7;
} else {
cpu.p.n = cpu.r.x >> 15;
}
cpu_lib.r.p.check_z(cpu, cpu.r.x); var DEC_accumulator = new cpu_lib.inc.INC_register('a', 'm', -1);
}
}
};
var DEY = { var DEC_memory = new cpu_lib.inc.INC_memory(-1);
bytes_required:function() {
return 1;
},
execute:function(cpu) {
cpu.cycle_count+=2;
if(cpu.r.y===0) { var DEC_absolute = new cpu_lib.addressing.Absolute(DEC_memory);
if(cpu.p.e||cpu.p.x) {
cpu.r.y = 0xff;
} else {
cpu.r.y = 0xffff;
}
cpu.p.n = 1;
cpu.p.z = 0;
} else {
cpu.r.y--;
if(cpu.p.e||cpu.p.x) { var DEC_absolute_indexed_x =
cpu.p.n = cpu.r.y >> 7; new cpu_lib.addressing.Absolute_indexed_x(DEC_absolute, true);
} else {
cpu.p.n = cpu.r.y >> 15;
}
cpu_lib.r.p.check_z(cpu, cpu.r.y); var DEC_direct_page = new cpu_lib.addressing.Direct_page(DEC_memory);
}
}
};
var DEC_accumulator = { var DEC_direct_page_indexed_x =
bytes_required: function() { new cpu_lib.addressing.Direct_page_indexed_x(DEC_direct_page);
return 1;
},
execute: function(cpu) {
cpu.cycle_count+=2;
if(cpu.r.a===0) { var INX = new cpu_lib.inc.INC_register('x', 'x');
if(cpu.p.e||cpu.p.m) {
cpu.r.a = 0xff;
} else {
cpu.r.a = 0xffff;
}
cpu.p.n = 1;
cpu.p.z = 0;
} else {
cpu.r.a--;
if(cpu.p.e||cpu.p.m) {
cpu.r.a &= 0xff;
cpu.p.n = cpu.r.a >> 7;
} else {
cpu.r.a &= 0xffff;
cpu.p.n = cpu.r.a >> 15;
}
cpu_lib.r.p.check_z(cpu, cpu.r.a); var INY = new cpu_lib.inc.INC_register('y', 'x');
}
}
};
var DEC_absolute = { var INC_accumulator = new cpu_lib.inc.INC_register('a', 'm');
bytes_required: function() {
return 3;
},
execute: function(cpu, bytes) {
cpu.cycle_count+=6;
var memory_location = (bytes[1]<<8)|bytes[0],
temp;
if(cpu.p.e||cpu.p.m) {
temp = cpu.mmu.read_byte(memory_location);
if(temp===0) {
cpu.mmu.store_byte(memory_location, 0xff);
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.mmu.store_byte(memory_location, temp);
cpu.p.n = temp >> 7;
cpu_lib.r.p.check_z(cpu, temp);
}
} else {
cpu.cycle_count+=2;
temp = cpu.mmu.read_word(memory_location);
if(temp===0) {
temp = 0xffff;
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.p.n = temp >> 15;
cpu_lib.r.p.check_z(cpu, temp);
}
cpu.mmu.store_word(memory_location, temp);
}
}
};
var DEC_absolute_indexed_x = {
bytes_required: function() {
return 3;
},
execute: function(cpu, bytes) {
cpu.cycle_count+=7;
var memory_location = ((bytes[1]<<8)|bytes[0]) + cpu.r.x,
temp;
if(cpu.p.e||cpu.p.m) {
temp = cpu.mmu.read_byte(memory_location);
if(temp===0) {
cpu.mmu.store_byte(memory_location, 0xff);
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.mmu.store_byte(memory_location, temp);
cpu.p.n = temp >> 7;
cpu_lib.r.p.check_z(cpu, temp);
}
} else {
cpu.cycle_count+=2;
temp = cpu.mmu.read_word(memory_location);
if(temp===0) {
temp = 0xffff;
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.p.n = temp >> 15;
cpu_lib.r.p.check_z(cpu, temp);
}
cpu.mmu.store_word(memory_location, temp);
}
}
};
var DEC_direct_page = {
bytes_required: function() {
return 2;
},
execute: function(cpu, bytes) {
cpu.cycle_count+=5;
if((cpu.r.d&0xff)!==0)
cpu.cycle_count++;
var memory_location = bytes[0] + cpu.r.d,
temp;
if(cpu.p.e||cpu.p.m) {
temp = cpu.mmu.read_byte(memory_location);
if(temp===0) {
cpu.mmu.store_byte(memory_location, 0xff);
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.mmu.store_byte(memory_location, temp);
cpu.p.n = temp >> 7;
cpu_lib.r.p.check_z(cpu, temp);
}
} else {
cpu.cycle_count+=2;
temp = cpu.mmu.read_word(memory_location);
if(temp===0) {
temp = 0xffff;
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.p.n = temp >> 15;
cpu_lib.r.p.check_z(cpu, temp);
}
cpu.mmu.store_word(memory_location, temp);
}
}
};
var DEC_direct_page_indexed_x = {
bytes_required: function() {
return 2;
},
execute: function(cpu, bytes) {
cpu.cycle_count+=6;
if((cpu.r.d&0xff)!==0)
cpu.cycle_count++;
var memory_location = bytes[0] + cpu.r.d + cpu.r.x,
temp;
if(cpu.p.e||cpu.p.m) {
temp = cpu.mmu.read_byte(memory_location);
if(temp===0) {
cpu.mmu.store_byte(memory_location, 0xff);
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.mmu.store_byte(memory_location, temp);
cpu.p.n = temp >> 7;
cpu_lib.r.p.check_z(cpu, temp);
}
} else {
cpu.cycle_count+=2;
temp = cpu.mmu.read_word(memory_location);
if(temp===0) {
temp = 0xffff;
cpu.p.n = 1;
cpu.p.z = 0;
} else {
temp--;
cpu.p.n = temp >> 15;
cpu_lib.r.p.check_z(cpu, temp);
}
cpu.mmu.store_word(memory_location, temp);
}
}
};
var INX = new cpu_lib.inc.Inc_register('x', 'x');
var INY = new cpu_lib.inc.Inc_register('y', 'x');
var INC_accumulator = new cpu_lib.inc.Inc_register('a', 'm');
var INC_memory = new cpu_lib.inc.INC_memory(); var INC_memory = new cpu_lib.inc.INC_memory();

View File

@ -19,6 +19,7 @@ function run_tests() {
test_inc(); test_inc();
test_inx(); test_inx();
test_iny(); test_iny();
test_dec();
test_stz(); test_stz();
test_rep(); test_rep();
test_sep(); test_sep();
@ -492,6 +493,60 @@ function test_iny() {
}); });
} }
function test_dec() {
module("DEC");
test("Test DEC accumulator for 8-bit memory/accumulator mode.", function() {
var cpu = new CPU_65816();
cpu.load_binary("18fba9013a", 0x8000);
cpu.execute(0x8000);
equal(cpu.r.a, 0, "The accumulator should be zero after decrementing "+
"one by one.");
equal(cpu.p.e, 0, "The hidden e flag should be zero for native mode.");
equal(cpu.p.m, 1, "The m flag should be one for 8-bit "+
"memory/accumulator mode.");
equal(cpu.p.z, 1, "The z flag should be one for zero.");
equal(cpu.p.n, 0, "The n flag should be zero for a non-negative number.");
});
test("Test DEC accumulator decrementing zero by one behavior for 8-bit "+
"memory/accumulator mode.", function() {
var cpu = new CPU_65816();
cpu.load_binary("18fba9003a", 0x8000);
cpu.execute(0x8000);
equal(cpu.r.a, 0xff, "The accumulator should be 0xff after decrementing "+
"zero by one.");
equal(cpu.p.e, 0, "The hidden e flag should be zero for native mode.");
equal(cpu.p.m, 1, "The m flag should be one for 8-bit "+
"memory/accumulator mode.");
equal(cpu.p.z, 0, "The z flag should be zero for a non-zero number.");
equal(cpu.p.n, 1, "The n flag should be one for a negative number.");
});
test("Test DEC accumulator for 16-bit memory/accumulator mode.", function() {
var cpu = new CPU_65816();
cpu.load_binary("18fbc220a901003a", 0x8000);
cpu.execute(0x8000);
equal(cpu.r.a, 0, "The accumulator should be zero after decrementing "+
"one by one.");
equal(cpu.p.e, 0, "The hidden e flag should be zero for native mode.");
equal(cpu.p.m, 0, "The m flag should be zero for 16-bit "+
"memory/accumulator mode.");
equal(cpu.p.z, 1, "The z flag should be one for zero.");
equal(cpu.p.n, 0, "The n flag should be zero for a non-negative number.");
});
test("Test DEC accumulator decrementing zero by one behavior for 16-bit "+
"memory/accumulator mode.", function() {
var cpu = new CPU_65816();
cpu.load_binary("18fbc220a900003a", 0x8000);
cpu.execute(0x8000);
equal(cpu.r.a, 0xffff, "The accumulator should be 0xffff after "+
"decrementing zero by one.");
equal(cpu.p.e, 0, "The hidden e flag should be zero for native mode.");
equal(cpu.p.m, 0, "The m flag sholud be zero for 16-bit "+
"memory/accumulator mode.");
equal(cpu.p.z, 0, "The z flag should be zero for a non-zero number.");
equal(cpu.p.n, 1, "The n flag should be one for a negative number.");
});
}
function test_stz() { function test_stz() {
module("STZ"); module("STZ");
test("Test STZ direct page for 8-bit memory/accumulator mode.", function() { test("Test STZ direct page for 8-bit memory/accumulator mode.", function() {