272 lines
5.0 KiB
C#
272 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace MC68000
|
|
{
|
|
public partial class MC68K
|
|
{
|
|
private void ANDI_to_CCR()
|
|
{
|
|
Helpers.Inject(ref this.m_SR, (byte)(this.m_SR & FetchW()));
|
|
this.m_Cycles += 20;
|
|
}
|
|
|
|
private void ANDI_to_SR()
|
|
{
|
|
if (this.S)
|
|
{
|
|
this.m_SR &= FetchW();
|
|
|
|
// Might not be in supervisor mode any more...
|
|
if (!this.S)
|
|
{
|
|
this.m_Ssp = this.SP;
|
|
this.SP = this.m_Usp;
|
|
}
|
|
|
|
this.m_Cycles += 20;
|
|
}
|
|
else
|
|
{
|
|
// TODO - cycle counter
|
|
Trap(8);
|
|
}
|
|
}
|
|
|
|
private void CHK()
|
|
{
|
|
int registerToCheck = (this.m_IR >> 9) & 0x7;
|
|
int size = (this.m_IR >> 7) & 0x3;
|
|
int mode = (this.m_IR >> 3) & 0x7;
|
|
int register = this.m_IR & 0x7;
|
|
|
|
// Only word size is legal on the 68000
|
|
|
|
if ((short)this.m_D[registerToCheck] < 0)
|
|
{
|
|
this.N = true;
|
|
Trap(6);
|
|
}
|
|
else if ((short)this.m_D[registerToCheck] > FetchOperandW(mode, size))
|
|
{
|
|
this.N = false;
|
|
Trap(6);
|
|
}
|
|
else
|
|
{
|
|
this.m_Cycles += 10 + Helpers.EACalcTimeBW(mode, register);
|
|
}
|
|
}
|
|
|
|
private void EORI_to_CCR()
|
|
{
|
|
Helpers.Inject(ref this.m_SR, (byte)(this.m_SR ^ FetchW()));
|
|
this.m_Cycles += 20;
|
|
}
|
|
|
|
private void EORI_to_SR()
|
|
{
|
|
if (this.S)
|
|
{
|
|
this.m_SR ^= FetchW();
|
|
|
|
// Might not be in supervisor mode any more...
|
|
if (!this.S)
|
|
{
|
|
this.m_Ssp = this.SP;
|
|
this.SP = this.m_Usp;
|
|
}
|
|
|
|
this.m_Cycles += 20;
|
|
}
|
|
else
|
|
{
|
|
// TODO - cycle counter
|
|
Trap(8);
|
|
}
|
|
}
|
|
|
|
private void ILLEGAL()
|
|
{
|
|
Trap(4);
|
|
}
|
|
|
|
private void MOVE_from_SR()
|
|
{
|
|
int mode = (this.m_IR >> 3) & 0x7;
|
|
int register = this.m_IR & 0x7;
|
|
|
|
SetOperandW(mode, register, (short)this.m_SR);
|
|
this.m_Cycles += (mode == 0) ? 6 : 8 + Helpers.EACalcTimeBW(mode, register);
|
|
}
|
|
|
|
private void MOVE_to_CCR()
|
|
{
|
|
int mode = (this.m_IR >> 3) & 0x7;
|
|
int register = this.m_IR & 0x7;
|
|
|
|
this.m_SR &= 0xFF00;
|
|
this.m_SR |= (ushort)(FetchOperandW(mode, register) & 0x00FF);
|
|
this.m_Cycles += (mode == 0) ? 12 : 12 + Helpers.EACalcTimeBW(mode, register);
|
|
}
|
|
|
|
private void MOVE_to_SR() // Move to the Status Register
|
|
{
|
|
int mode = (this.m_IR >> 3) & 0x7;
|
|
int register = this.m_IR & 0x7;
|
|
|
|
if (this.S)
|
|
{
|
|
this.m_SR = (ushort)FetchOperandW(mode, register);
|
|
this.m_Cycles += (mode == 0) ? 12 : 12 + Helpers.EACalcTimeBW(mode, register);
|
|
|
|
// Might not be in supervisor mode now...
|
|
if (!this.S)
|
|
{
|
|
this.m_Ssp = this.SP;
|
|
this.SP = this.m_Usp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Trap(8);
|
|
}
|
|
}
|
|
|
|
private void MOVE_USP() // Move User Stack Pointer
|
|
{
|
|
if (this.S)
|
|
{
|
|
if (((this.m_IR >> 3) & 0x1) == 0)
|
|
{
|
|
this.m_Usp = this.m_A[this.m_IR & 0x7];
|
|
}
|
|
else
|
|
{
|
|
this.m_A[this.m_IR & 0x7] = this.m_Usp;
|
|
}
|
|
|
|
this.m_Cycles += 4;
|
|
}
|
|
else
|
|
{
|
|
// TODO Cycles
|
|
Trap(8);
|
|
}
|
|
}
|
|
|
|
private void ORI_to_CCR()
|
|
{
|
|
Helpers.Inject(ref this.m_SR, (byte)(this.m_SR | (ushort)FetchW()));
|
|
this.m_Cycles += 20;
|
|
}
|
|
|
|
private void ORI_to_SR()
|
|
{
|
|
if (this.S)
|
|
{
|
|
this.m_SR |= (ushort)FetchW();
|
|
|
|
// Might not be in supervisor mode any more...
|
|
if (!this.S)
|
|
{
|
|
this.m_Ssp = this.SP;
|
|
this.SP = this.m_Usp;
|
|
}
|
|
|
|
this.m_Cycles += 20;
|
|
}
|
|
else
|
|
{
|
|
// TODO - TRAP, cycle counter
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
private void RESET()
|
|
{
|
|
this.m_Cycles += 132;
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private void RTE()
|
|
{
|
|
if (this.S)
|
|
{
|
|
this.m_SR = (ushort)ReadW(this.SP);
|
|
this.SP += 2;
|
|
this.m_PC = ReadL(this.SP);
|
|
this.SP += 4;
|
|
|
|
// Might not be in supervisor mode any more...
|
|
if (!this.S)
|
|
{
|
|
this.m_Ssp = this.SP;
|
|
this.SP = this.m_Usp;
|
|
}
|
|
|
|
this.m_Cycles += 20;
|
|
}
|
|
else
|
|
{
|
|
// Privilege exception
|
|
Trap(8);
|
|
}
|
|
}
|
|
|
|
private void RTR()
|
|
{
|
|
// Seems a bit like RTE, but only affects condition codes
|
|
this.m_SR = (ushort)((0x00FF & ReadW(this.m_Ssp)) | (0xFF00 & this.m_SR));
|
|
this.SP += 2;
|
|
this.m_PC = ReadL(this.SP);
|
|
this.SP += 4;
|
|
this.m_Cycles += 20;
|
|
}
|
|
|
|
private void STOP()
|
|
{
|
|
this.m_Cycles += 4;
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private void Trap(int trapVector)
|
|
{
|
|
// Make sure we're in supervisor mode
|
|
if (!this.S)
|
|
{
|
|
this.m_Usp = this.SP;
|
|
this.SP = this.m_Ssp;
|
|
}
|
|
|
|
// Add stack frame
|
|
this.SP -= 4;
|
|
WriteL(this.SP, this.m_PC);
|
|
this.SP -= 2;
|
|
WriteW(this.SP, (short)this.m_SR);
|
|
|
|
// Enter supervisor mode
|
|
this.S = true;
|
|
|
|
// Get vector address from ROM header
|
|
this.m_PC = ReadL(trapVector * 4);
|
|
}
|
|
|
|
private void TRAP()
|
|
{
|
|
int trapVector = (this.m_IR & 0x000F);
|
|
Trap(trapVector + 32);
|
|
}
|
|
|
|
private void TRAPV()
|
|
{
|
|
this.m_Cycles += 4;
|
|
if (this.V)
|
|
{
|
|
Trap(7);
|
|
}
|
|
}
|
|
}
|
|
}
|