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

File diff suppressed because one or more lines are too long

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
* - - - --- --

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long