ソースを参照

MOS6502/cpu has the method .hardReset(). Improvements to ALU function, especially in BCD math. Tests enhanced and added test for ADC Immediate BCD mode.

master
Bryan Miller 5年前
コミット
887c5adfd3
2個のファイルの変更106行の追加19行の削除
  1. +23
    -7
      src/MOS6502/cpu.js
  2. +83
    -12
      test/unit.src.MOS6502.cpu.spec.js

+ 23
- 7
src/MOS6502/cpu.js ファイルの表示

@@ -729,11 +729,9 @@ function ALU(cpu, m, b){
switch(m){
case 0: // Addition
A = (cpu.__AR + b) + ((cpu.C === 1) ? 1 : 0);
//cpu.C = (this.__AR >= 256);
break;
case 1: // Subtraction
A = (cpu.__AR - b) - ((cpu.C === 0) ? 1 : 0);
//cpu.C = (this.__AR >= 0);
A += (A < 0) ? 256 : 0;
break;
}
@@ -743,26 +741,25 @@ function ALU(cpu, m, b){
// Both inputs have the same sign, but the output doesn't match the sign of the input.
// (Twos Compliment)
cpu.V = ((IAR & 0x80) === (b & 0x80)) && ((IAR & 0x80) !== (cpu.__AR & 0x80));
//cpu.V = (BITM.isOn(cpu.__AR, 7) === BITM.isOn(b, 7)) && (BITM.val(cpu.__AR, 7) !== BITM.val(cpu.__AR, 7));
cpu.C = (m === 0) ? (A >= 256) : (cpu.V === 0);
cpu.N = BITM.isOn(cpu.__AR, 7);
//cpu.__AR &= 0xFF;
cpu.Z = (cpu.__AR === 0);
} else { // Decimal (BCD) Mode
// Borrowed from information located on...
// http://www.6502.org/tutorials/decimal_mode.html
let AL = 0;
switch(m){
switch(m){
case 0: // Addition
AL = (cpu.__AR & 0x0F) + (b & 0x0F) + ((cpu.C === 1) ? 1 : 0);
AL = (AL < 0x0A) ? AL : ((AL + 0x06) & 0x0F) + 0x10;
A = (cpu.__AR & 0xF0) + (b & 0xF0) + AL;
A += (A >= 0xA0) ? 0x60 : 0;
cpu.__AR = A & 0xFF;
cpu.Z = (IAR + b + ((cpu.C === 1) ? 1 : 0) === 256);
cpu.C = (A >= 0x100);
cpu.N = (BITM.isOn(A, 7)) ? 1 : 0;
cpu.V = (A >= -128 && A <= 127) ? 0 : 1;
cpu.V = (A >= -128 && A <= 127) ? 0 : 1;
break;
case 1: // Subtraction
AL = (cpu.__AR & 0x0F) - (b & 0x0F) + (cpu.C - 1);
@@ -772,9 +769,9 @@ function ALU(cpu, m, b){
cpu.__AR = A & 0xFF;

cpu.V = ((IAR & 0x80) === (b & 0x80)) && ((IAR & 0x80) !== (cpu.__AR & 0x80));
cpu.Z = ((cpu.__AR - b) - ((cpu.C === 0) ? 1 : 0) === 0);
cpu.C = (cpu.V === 0);
cpu.N = BITM.isOn(cpu.__AR, 7);
cpu.Z = (cpu.__AR === 0);
break;
}
}
@@ -877,6 +874,25 @@ class CPU{


// -----------------------------------------
hardReset(){
this.__pcc = 0;
this.__cycle = 0;
this.__op = -1;
this.__ophold = 0;
this.__opv = 0;
this.__iinit = false;
this.__irq = false;
this.__nmi = false;
this.__rst = false;
this.__SP = 255;
this.__PR = 32;

this.__mem.address = 0xFFFC;
this.__PC = this.__mem.byte;
this.__mem.address = 0xFFFD;
this.__PC |= this.__mem.byte << 8;
}

clk(){
if (this.__clkfn === null){

+ 83
- 12
test/unit.src.MOS6502.cpu.spec.js ファイルの表示

@@ -68,8 +68,9 @@ describe("Testing MOS6502 CPU...", function(){
asm.reset().compile(prg);
cpu.memory.clearPage(0);
cpu.memory.load(0, asm.result());
cpu.reset = true;
tick();
cpu.hardReset();
//cpu.reset = true;
//tick();
tick();
tick();
expect(cpu.A).to.equal(0x01);
@@ -97,20 +98,35 @@ describe("Testing MOS6502 CPU...", function(){
prg += "CLI\n";
prg += "LDA #$00\n";
prg += "ADC #$01\n";
prg += "ADC #$01\n";
prg += "ADC #$7F\n";
prg += "ADC #$80";
asm.reset().compile(prg);
cpu.memory.clearPage(0);
cpu.memory.load(0, asm.result());
cpu.reset = true;
tick(); // To reset;
while (cpu.PC !== 10){
cpu.hardReset();
//cpu.reset = true;
//tick(); // To reset;
while (cpu.PC !== 13){
switch(cpu.PC){
case 6:
expect(cpu.A).to.equal(0); break;
expect(cpu.A).to.equal(0x00); break;
case 8:
expect(cpu.A).to.equal(1); break;
expect(cpu.A).to.equal(0x01);
expect(cpu.Z).to.equal(0);
expect(cpu.C).to.equal(0);
expect(cpu.N).to.equal(0);
break;
case 10:
expect(cpu.A).to.equal(2); break;
expect(cpu.A).to.equal(0x80);
expect(cpu.Z).to.equal(0);
expect(cpu.C).to.equal(0);
expect(cpu.N).to.equal(1);
break;
case 12:
expect(cpu.A).to.equal(0x00);
expect(cpu.Z).to.equal(1);
expect(cpu.C).to.equal(1);
expect(cpu.N).to.equal(0);
}
tick();
}
@@ -126,7 +142,61 @@ describe("Testing MOS6502 CPU...", function(){
});

describe("ADC Decimal (BCD) Mode...", function(){
it("ADC Immediate");
it("ADC Immediate", function(){
let prg = "CLC\n";
prg += "CLV\n";
prg += "SED\n";
prg += "CLI\n";
prg += "LDA #$00\n";
prg += "ADC #$01\n";
prg += "ADC #$09\n";
prg += "ADC #$89\n";
prg += "ADC #$01\n";
prg += "LDA #$0A\n"; // 0A is an invalid BCD number
prg += "CLC\n"; // Need to reset the clear flag from previous add.
prg += "ADC #$01";
asm.reset().compile(prg);
cpu.memory.clearPage(0);
cpu.memory.load(0, asm.result());
cpu.hardReset();
//cpu.reset = true;
//tick(); // To reset;
while (cpu.PC !== 20){
switch(cpu.PC){
case 6:
expect(cpu.A).to.equal(0x00); break;
case 8:
expect(cpu.A).to.equal(0x01);
expect(cpu.Z).to.equal(0);
expect(cpu.C).to.equal(0);
expect(cpu.N).to.equal(0);
break;
case 10:
expect(cpu.A).to.equal(0x10);
expect(cpu.Z).to.equal(0);
expect(cpu.C).to.equal(0);
expect(cpu.N).to.equal(0);
break;
case 12:
expect(cpu.A).to.equal(0x99);
expect(cpu.Z).to.equal(0);
expect(cpu.C).to.equal(0);
expect(cpu.N).to.equal(1);
break;
case 14:
expect(cpu.A).to.equal(0x00);
expect(cpu.Z).to.equal(0);
expect(cpu.C).to.equal(1);
expect(cpu.N).to.equal(0);
break;
case 19:
//console.log(cpu.A);
expect(cpu.A).to.equal(0x11);
break;
}
tick();
}
});
it("ADC Zero Page");
it("ADC Zero Page, X");
it("ADC Absolute");
@@ -150,8 +220,9 @@ describe("Testing MOS6502 CPU...", function(){
asm.reset().compile(prg);
cpu.memory.clearPage(0);
cpu.memory.load(0, asm.result());
cpu.reset = true;
tick(); // To reset;
cpu.hardReset();
//cpu.reset = true;
//tick(); // To reset;
while(cpu.PC !== 11){
// NOTE TO SELF: Depending on the OP code, these tests could be
// checked multiple times, as the cpu may sit at a program cntr

読み込み中…
キャンセル
保存