208 lines
4.5 KiB
C#
208 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace MC68000
|
|
{
|
|
public partial class MC68K
|
|
{
|
|
private void Bcc() // Branch conditionally
|
|
{
|
|
if ((sbyte)this.m_IR == 0)
|
|
{
|
|
if (TestCondition((this.m_IR >> 8) & 0xF))
|
|
{
|
|
this.m_PC += FetchW();
|
|
this.m_Cycles += 10;
|
|
}
|
|
else
|
|
{
|
|
this.m_PC += 2;
|
|
this.m_Cycles += 12;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (TestCondition((this.m_IR >> 8) & 0xF))
|
|
{
|
|
this.m_PC += (sbyte)this.m_IR;
|
|
this.m_Cycles += 10;
|
|
}
|
|
else
|
|
{
|
|
this.m_Cycles += 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DBcc() // Test condition, decrement, branch
|
|
{
|
|
if (TestCondition((this.m_IR >> 8) & 0xF))
|
|
{
|
|
// Need to move PC on...
|
|
this.m_PC += 2;
|
|
this.m_Cycles += 12;
|
|
}
|
|
else
|
|
{
|
|
short counter = (short)this.m_D[this.m_IR & 0x7];
|
|
Helpers.Inject(ref this.m_D[this.m_IR & 0x7], --counter);
|
|
|
|
if (counter == -1)
|
|
{
|
|
this.m_PC += 2;
|
|
this.m_Cycles += 14;
|
|
}
|
|
else
|
|
{
|
|
this.m_PC += FetchW();
|
|
this.m_Cycles += 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Scc() // Set according to condition
|
|
{
|
|
int cCode = (this.m_IR >> 8) & 0xF;
|
|
int mode = (this.m_IR >> 3) & 0x7;
|
|
int register = this.m_IR & 0x7;
|
|
|
|
if (TestCondition(cCode))
|
|
{
|
|
// Set all the bits
|
|
SetOperandB(mode, register, -1);
|
|
this.m_Cycles += (mode == 0) ? 6 : 8 + Helpers.EACalcTimeBW(mode, register);
|
|
}
|
|
else
|
|
{
|
|
// Clear all the bits
|
|
SetOperandB(mode, register, 0);
|
|
this.m_Cycles += (mode == 0) ? 4 : 8 + Helpers.EACalcTimeBW(mode, register);
|
|
}
|
|
}
|
|
|
|
private void BRA() // Branch Always
|
|
{
|
|
this.m_Cycles += 10;
|
|
|
|
if ((sbyte)this.m_IR == 0)
|
|
{
|
|
this.m_PC += PeekW();
|
|
}
|
|
else
|
|
{
|
|
this.m_PC += (sbyte)this.m_IR;
|
|
}
|
|
}
|
|
|
|
private void BSR() // Branch to subroutine
|
|
{
|
|
this.SP -= 4;
|
|
|
|
// 16-bit displacement
|
|
if ((sbyte)this.m_IR == 0)
|
|
{
|
|
WriteL(this.SP, this.m_PC + 2);
|
|
this.m_PC += PeekW();
|
|
}
|
|
|
|
// 8-bit displacement
|
|
else
|
|
{
|
|
WriteL(this.SP, this.m_PC);
|
|
this.m_PC += (sbyte)this.m_IR;
|
|
}
|
|
|
|
this.m_Cycles += 18;
|
|
}
|
|
|
|
private void JMP() // Jump
|
|
{
|
|
this.m_PC = FetchAddress((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
|
|
switch ((this.m_IR >> 3) & 0x7)
|
|
{
|
|
case 0x2: this.m_Cycles += 8; break;
|
|
case 0x5: this.m_Cycles += 10; break;
|
|
case 0x6: this.m_Cycles += 14; break;
|
|
case 0x7:
|
|
switch (this.m_IR & 0x7)
|
|
{
|
|
case 0x0: this.m_Cycles += 10; break;
|
|
case 0x1: this.m_Cycles += 12; break;
|
|
case 0x2: this.m_Cycles += 10; break;
|
|
case 0x3: this.m_Cycles += 14; break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void JSR() // Jump to subroutine
|
|
{
|
|
int address = FetchAddress((this.m_IR >> 3) & 0x7, this.m_IR & 0x7) & 0x00FFFFFF;
|
|
this.SP -= 4;
|
|
WriteL(this.SP, this.m_PC);
|
|
this.m_PC = address;
|
|
|
|
switch ((this.m_IR >> 3) & 0x7)
|
|
{
|
|
case 0x2: this.m_Cycles += 16; break;
|
|
case 0x5: this.m_Cycles += 18; break;
|
|
case 0x6: this.m_Cycles += 22; break;
|
|
case 0x7:
|
|
switch (this.m_IR & 0x7)
|
|
{
|
|
case 0x0: this.m_Cycles += 18; break;
|
|
case 0x1: this.m_Cycles += 20; break;
|
|
case 0x2: this.m_Cycles += 18; break;
|
|
case 0x3: this.m_Cycles += 22; break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void NOP() // No operation
|
|
{
|
|
// Doesn't do anything, it's there to help flush the integer pipeline
|
|
this.m_Cycles += 4;
|
|
}
|
|
|
|
private void RTS() // Return from Subroutine
|
|
{
|
|
this.m_PC = ReadL(this.SP);
|
|
this.SP += 4;
|
|
this.m_Cycles += 16;
|
|
}
|
|
|
|
private void TST() // Test an operand
|
|
{
|
|
// Use an integer operand, it gets sign-extended and we can check it afterwards
|
|
int operand = 0;
|
|
switch ((this.m_IR >> 6) & 0x3)
|
|
{
|
|
case 0: // B
|
|
{
|
|
operand = FetchOperandB((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
this.m_Cycles += 4 + Helpers.EACalcTimeBW((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
break;
|
|
}
|
|
case 1: // W
|
|
{
|
|
operand = FetchOperandW((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
this.m_Cycles += 4 + Helpers.EACalcTimeBW((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
break;
|
|
}
|
|
case 2: // L
|
|
{
|
|
operand = FetchOperandL((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
this.m_Cycles += 4 + Helpers.EACalcTimeL((this.m_IR >> 3) & 0x7, this.m_IR & 0x7);
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.V = this.C = false;
|
|
this.N = (operand < 0);
|
|
this.Z = (operand == 0);
|
|
}
|
|
}
|
|
} |