The 8080 CPU now passes all the 8080 Exerciser tests

This commit is contained in:
Jeff Parsons 2016-04-29 17:57:28 -07:00
commit 41f58a0035
7 changed files with 1231 additions and 1231 deletions

View file

@ -441,24 +441,18 @@ CPUDef.opMVIH = function()
*/
CPUDef.opDAA = function()
{
var acc = this.regA;
var fCarry = !!this.getCF();
var fAuxCarry = !!this.getAF();
if ((acc & 0xf) > 9 || fAuxCarry) {
acc += 0x6;
fAuxCarry = true;
} else {
fAuxCarry = false;
var src = 0;
var CF = this.getCF();
var AF = this.getAF();
if (AF || (this.regA & 0x0F) > 9) {
src |= 0x06;
}
if (acc >= 0xa0 || fCarry) {
acc += 0x60;
fCarry = true;
} else {
fCarry = false;
if (CF || this.regA >= 0x9A) {
src |= 0x60;
CF = CPUDef.PS.CF;
}
this.resultZeroCarry = this.resultParitySign = this.regA = (acc & 0xff);
this.updateCF(fCarry);
this.updateAF(fAuxCarry);
this.regA = this.addByte(src);
this.updateCF(!!CF);
this.nStepCycles -= 4;
};
@ -2055,7 +2049,7 @@ CPUDef.opORAA = function()
*/
CPUDef.opCMPB = function()
{
this.cmpByte(this.regB);
this.subByte(this.regB);
this.nStepCycles -= 4;
};
@ -2066,7 +2060,7 @@ CPUDef.opCMPB = function()
*/
CPUDef.opCMPC = function()
{
this.cmpByte(this.regC);
this.subByte(this.regC);
this.nStepCycles -= 4;
};
@ -2077,7 +2071,7 @@ CPUDef.opCMPC = function()
*/
CPUDef.opCMPD = function()
{
this.cmpByte(this.regD);
this.subByte(this.regD);
this.nStepCycles -= 4;
};
@ -2088,7 +2082,7 @@ CPUDef.opCMPD = function()
*/
CPUDef.opCMPE = function()
{
this.cmpByte(this.regE);
this.subByte(this.regE);
this.nStepCycles -= 4;
};
@ -2099,7 +2093,7 @@ CPUDef.opCMPE = function()
*/
CPUDef.opCMPH = function()
{
this.cmpByte(this.regH);
this.subByte(this.regH);
this.nStepCycles -= 4;
};
@ -2110,7 +2104,7 @@ CPUDef.opCMPH = function()
*/
CPUDef.opCMPL = function()
{
this.cmpByte(this.regL);
this.subByte(this.regL);
this.nStepCycles -= 4;
};
@ -2121,7 +2115,7 @@ CPUDef.opCMPL = function()
*/
CPUDef.opCMPM = function()
{
this.cmpByte(this.getByte(this.getHL()));
this.subByte(this.getByte(this.getHL()));
this.nStepCycles -= 7;
};
@ -2132,7 +2126,7 @@ CPUDef.opCMPM = function()
*/
CPUDef.opCMPA = function()
{
this.cmpByte(this.regA);
this.subByte(this.regA);
this.nStepCycles -= 4;
};
@ -2859,7 +2853,7 @@ CPUDef.opCM = function()
*/
CPUDef.opCPI = function()
{
this.cmpByte(this.getPCByte());
this.subByte(this.getPCByte());
this.nStepCycles -= 7;
};

View file

@ -749,34 +749,11 @@ CPUSim.prototype.andByte = function(src)
return this.resultZeroCarry;
};
/**
* cmpByte(src)
*
* We perform this operation using 8-bit two's complement arithmetic, by negating src, adding,
* and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic how
* the 8080 manages the Auxiliary Carry flag (AF).
*
* @this {CPUSim}
* @param {number} src
*/
CPUSim.prototype.cmpByte = function(src)
{
src = -src & 0xff;
this.resultAuxOverflow = this.regA ^ src;
/*
* The final AND with 0xff isn't strictly necessary, since the result of the comparison is
* not returned, but I like limiting the result variables to tidy 8-bit values (resultZeroCarry
* being the 9-bit exception).
*/
this.resultParitySign = (this.resultZeroCarry = (this.regA + src) ^ 0x100) & 0xff;
};
/**
* decByte(b)
*
* We perform this operation using 8-bit two's complement arithmetic, by negating src, adding,
* and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic how
* the 8080 manages the Auxiliary Carry flag (AF).
* We perform this operation using 8-bit two's complement arithmetic, by negating and then adding
* the implied src of 1. This appears to mimic how the 8080 manages the Auxiliary Carry flag (AF).
*
* @this {CPUSim}
* @param {number} b
@ -820,9 +797,32 @@ CPUSim.prototype.orByte = function(src)
/**
* subByte(src)
*
* We perform this operation using 8-bit two's complement arithmetic, by negating src, adding,
* and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic how
* the 8080 manages the Auxiliary Carry flag (AF).
* We perform this operation using 8-bit two's complement arithmetic, by inverting src, adding
* src + 1, and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic
* how the 8080 manages the Auxiliary Carry flag (AF).
*
* This function is also used as a cmpByte() function; compare instructions simply ignore the
* return value.
*
* Example: A=66, SUI $10
*
* If we created the two's complement of 0x10 by negating it, there would just be one addition:
*
* 0110 0110 (0x66)
* + 1111 0000 (0xF0) (ie, -0x10)
* ---------
* 1 0101 0110 (0x56)
*
* But in order to mimic the 8080's AF flag, we must perform the two's complement of src in two steps,
* inverting it before the add, and then incrementing after the add; eg:
*
* 0110 0110 (0x66)
* + 1110 1111 (0xEF) (ie, ~0x10)
* ---------
* 1 0101 0101 (0x55)
* + 0000 0001 (0x01)
* ---------
* 1 0101 0110 (0x56)
*
* @this {CPUSim}
* @param {number} src
@ -830,17 +830,20 @@ CPUSim.prototype.orByte = function(src)
*/
CPUSim.prototype.subByte = function(src)
{
src = -src & 0xff;
src ^= 0xff;
this.resultAuxOverflow = this.regA ^ src;
return this.resultParitySign = (this.resultZeroCarry = (this.regA + src) ^ 0x100) & 0xff;
return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + 1) ^ 0x100) & 0xff;
};
/**
* subByteBorrow(src)
*
* We perform this operation using 8-bit two's complement arithmetic, by negating (src + carry),
* adding, and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic
* how the 8080 manages the Auxiliary Carry flag (AF).
* We perform this operation using 8-bit two's complement arithmetic, using logic similar to subByte(),
* but changing the final increment to a conditional increment, because if the Carry flag (CF) is set, then
* we don't need to perform the increment at all.
*
* This mimics the behavior of subByte() when the Carry flag (CF) is clear, and hopefully also mimics how the
* 8080 manages the Auxiliary Carry flag (AF) when the Carry flag (CF) is set.
*
* @this {CPUSim}
* @param {number} src
@ -848,9 +851,9 @@ CPUSim.prototype.subByte = function(src)
*/
CPUSim.prototype.subByteBorrow = function(src)
{
src = -(src + ((this.resultZeroCarry & 0x100)? 1 : 0)) & 0xff;
src ^= 0xff
this.resultAuxOverflow = this.regA ^ src;
return this.resultParitySign = (this.resultZeroCarry = (this.regA + src) ^ 0x100) & 0xff;
return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + ((this.resultZeroCarry & 0x100)? 0 : 1)) ^ 0x100) & 0xff;
};
/**

View file

@ -2544,7 +2544,7 @@ X86CPU.prototype.getPF = function()
* getAF()
*
* To determine if there's been a carry out of the low 4 bits of an arithmetic operation,
* we look at all the possible inputs for bit 4, and calculate AF = PS^(D^S):
* we look at all the possible inputs for bit 4, and calculate AF = A^(D^S).
*
* D S A D^S AF
* - - - --- --