cleanup of DEC instructions and started writing tests for them
This commit is contained in:
parent
55f059b09c
commit
577b47a497
279
cpu.js
279
cpu.js
|
@ -29,7 +29,10 @@ var cpu_lib = {
|
|||
}
|
||||
},
|
||||
inc: {
|
||||
Inc_register: function(register, flag) {
|
||||
INC_register: function(register, flag, value) {
|
||||
if(typeof value === 'undefined')
|
||||
value = 1;
|
||||
|
||||
this.bytes_required = function() {
|
||||
return 1;
|
||||
};
|
||||
|
@ -37,7 +40,7 @@ var cpu_lib = {
|
|||
this.execute = function(cpu) {
|
||||
cpu.cycle_count+=2;
|
||||
|
||||
cpu.r[register]++;
|
||||
cpu.r[register]+=value;
|
||||
|
||||
if(cpu.p.e||cpu.p[flag]) {
|
||||
cpu.r[register] &= 0xff;
|
||||
|
@ -50,17 +53,20 @@ var cpu_lib = {
|
|||
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) {
|
||||
cpu.cycle_count+=4;
|
||||
|
||||
if(cpu.p.e||cpu.p.m) {
|
||||
temp = (bytes[0] + 1) & 0xff;
|
||||
temp = (bytes[0] + value) & 0xff;
|
||||
cpu.p.n = temp >> 7;
|
||||
cpu.mmu.store_byte(extra.memory_location, temp);
|
||||
} else {
|
||||
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.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 =
|
||||
new cpu_lib.addressing.Direct_page_indexed_x(LDY_direct_page);
|
||||
|
||||
var DEX = {
|
||||
bytes_required:function() {
|
||||
return 1;
|
||||
},
|
||||
execute:function(cpu) {
|
||||
cpu.cycle_count+=2;
|
||||
// Implement the decrement instructions as increment instructions that
|
||||
// increment by negative one.
|
||||
var DEX = new cpu_lib.inc.INC_register('x', 'x', -1);
|
||||
|
||||
if(cpu.r.x===0) {
|
||||
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;
|
||||
}
|
||||
var DEY = new cpu_lib.inc.INC_register('y', 'x', -1);
|
||||
|
||||
cpu_lib.r.p.check_z(cpu, cpu.r.x);
|
||||
}
|
||||
}
|
||||
};
|
||||
var DEC_accumulator = new cpu_lib.inc.INC_register('a', 'm', -1);
|
||||
|
||||
var DEY = {
|
||||
bytes_required:function() {
|
||||
return 1;
|
||||
},
|
||||
execute:function(cpu) {
|
||||
cpu.cycle_count+=2;
|
||||
var DEC_memory = new cpu_lib.inc.INC_memory(-1);
|
||||
|
||||
if(cpu.r.y===0) {
|
||||
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--;
|
||||
var DEC_absolute = new cpu_lib.addressing.Absolute(DEC_memory);
|
||||
|
||||
if(cpu.p.e||cpu.p.x) {
|
||||
cpu.p.n = cpu.r.y >> 7;
|
||||
} else {
|
||||
cpu.p.n = cpu.r.y >> 15;
|
||||
}
|
||||
var DEC_absolute_indexed_x =
|
||||
new cpu_lib.addressing.Absolute_indexed_x(DEC_absolute, true);
|
||||
|
||||
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 = {
|
||||
bytes_required: function() {
|
||||
return 1;
|
||||
},
|
||||
execute: function(cpu) {
|
||||
cpu.cycle_count+=2;
|
||||
var DEC_direct_page_indexed_x =
|
||||
new cpu_lib.addressing.Direct_page_indexed_x(DEC_direct_page);
|
||||
|
||||
if(cpu.r.a===0) {
|
||||
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;
|
||||
}
|
||||
var INX = new cpu_lib.inc.INC_register('x', 'x');
|
||||
|
||||
cpu_lib.r.p.check_z(cpu, cpu.r.a);
|
||||
}
|
||||
}
|
||||
};
|
||||
var INY = new cpu_lib.inc.INC_register('y', 'x');
|
||||
|
||||
var DEC_absolute = {
|
||||
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_accumulator = new cpu_lib.inc.INC_register('a', 'm');
|
||||
|
||||
var INC_memory = new cpu_lib.inc.INC_memory();
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ function run_tests() {
|
|||
test_inc();
|
||||
test_inx();
|
||||
test_iny();
|
||||
test_dec();
|
||||
test_stz();
|
||||
test_rep();
|
||||
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() {
|
||||
module("STZ");
|
||||
test("Test STZ direct page for 8-bit memory/accumulator mode.", function() {
|
||||
|
|
Loading…
Reference in New Issue