Переглянути джерело

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

Завантаження…
Відмінити
Зберегти