68000: implement UNLK, RTE, TRAP, ANDI to SR, and EORI to SR

This commit is contained in:
beirich 2011-10-09 03:51:57 +00:00
parent 1c38de023e
commit a1d8e9a209
5 changed files with 108 additions and 7 deletions

View File

@ -56,6 +56,7 @@ namespace BizHawk.Emulation.CPUs.M68000
else if (Opcodes[op] == BSR) BSR_Disasm(info);
else if (Opcodes[op] == DBcc) DBcc_Disasm(info);
else if (Opcodes[op] == Scc) Scc_Disasm(info);
else if (Opcodes[op] == RTE) RTE_Disasm(info);
else if (Opcodes[op] == RTS) RTS_Disasm(info);
else if (Opcodes[op] == TST) TST_Disasm(info);
else if (Opcodes[op] == BTSTi) BTSTi_Disasm(info);
@ -67,6 +68,7 @@ namespace BizHawk.Emulation.CPUs.M68000
else if (Opcodes[op] == BSETi) BSETi_Disasm(info);
else if (Opcodes[op] == BSETr) BSETr_Disasm(info);
else if (Opcodes[op] == LINK) LINK_Disasm(info);
else if (Opcodes[op] == UNLK) UNLK_Disasm(info);
else if (Opcodes[op] == NOP) NOP_Disasm(info);
else if (Opcodes[op] == ADD0) ADD_Disasm(info);
@ -86,7 +88,10 @@ namespace BizHawk.Emulation.CPUs.M68000
else if (Opcodes[op] == MOVEtSR) MOVEtSR_Disasm(info);
else if (Opcodes[op] == MOVEfSR) MOVEfSR_Disasm(info);
else if (Opcodes[op] == MOVEUSP) MOVEUSP_Disasm(info);
else if (Opcodes[op] == ANDI_SR) ANDI_SR_Disasm(info);
else if (Opcodes[op] == EORI_SR) EORI_SR_Disasm(info);
else if (Opcodes[op] == ORI_SR) ORI_SR_Disasm(info);
else if (Opcodes[op] == TRAP) TRAP_Disasm(info);
var sb = new StringBuilder();
for (int p = info.PC; p < info.PC + info.Length; p++)

View File

@ -204,6 +204,22 @@ namespace BizHawk.Emulation.CPUs.M68000
info.Args = "";
}
void RTE()
{
short newSR = ReadWord(A[7].s32);
A[7].s32 += 2;
PC = ReadLong(A[7].s32);
A[7].s32 += 4;
SR = newSR;
PendingCycles -= 20;
}
void RTE_Disasm(DisassemblyInfo info)
{
info.Mnemonic = "rte";
info.Args = "";
}
void TST()
{
int size = (op >> 6) & 3;
@ -625,6 +641,23 @@ namespace BizHawk.Emulation.CPUs.M68000
info.Length = pc - info.PC;
}
void UNLK()
{
int reg = op & 7;
A[7].s32 = A[reg].s32;
A[reg].s32 = ReadLong(A[7].s32);
A[7].s32 += 4;
PendingCycles -= 12;
}
void UNLK_Disasm(DisassemblyInfo info)
{
int reg = op & 7;
info.Mnemonic = "unlk";
info.Args = "A" + reg;
info.Length = 2;
}
void NOP()
{
PendingCycles -= 4;

View File

@ -67,6 +67,38 @@ namespace BizHawk.Emulation.CPUs.M68000
info.Length = pc - info.PC;
}
void ANDI_SR()
{
if (S == false)
throw new Exception("trap!");
SR &= ReadWord(PC); PC += 2;
PendingCycles -= 20;
}
void ANDI_SR_Disasm(DisassemblyInfo info)
{
int pc = info.PC + 2;
info.Mnemonic = "andi";
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
info.Length = pc - info.PC;
}
void EORI_SR()
{
if (S == false)
throw new Exception("trap!");
SR ^= ReadWord(PC); PC += 2;
PendingCycles -= 20;
}
void EORI_SR_Disasm(DisassemblyInfo info)
{
int pc = info.PC + 2;
info.Mnemonic = "eori";
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
info.Length = pc - info.PC;
}
void ORI_SR()
{
if (S == false)
@ -82,5 +114,29 @@ namespace BizHawk.Emulation.CPUs.M68000
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
info.Length = pc - info.PC;
}
void TRAP()
{
int vector = 32 + (op & 0x0F);
TrapVector(vector);
PendingCycles -= 26;
}
void TRAP_Disasm(DisassemblyInfo info)
{
info.Mnemonic = "trap";
info.Args = string.Format("${0:X}", op & 0xF);
}
void TrapVector(int vector)
{
short sr = (short)SR; // capture current SR.
S = true; // switch to supervisor mode, if not already in it.
A[7].s32 -= 4; // Push PC on stack
WriteLong(A[7].s32, PC);
A[7].s32 -= 2; // Push SR on stack
WriteWord(A[7].s32, sr);
PC = ReadLong(vector * 4); // Jump to vector
}
}
}
}

View File

@ -55,11 +55,11 @@ namespace BizHawk.Emulation.CPUs.M68000
public bool C;
/// <summary>Status Register</summary>
public int SR
public short SR
{
get
{
int value = 0;
short value = 0;
if (C) value |= 0x0001;
if (V) value |= 0x0002;
if (Z) value |= 0x0004;
@ -67,7 +67,7 @@ namespace BizHawk.Emulation.CPUs.M68000
if (X) value |= 0x0010;
if (M) value |= 0x1000;
if (S) value |= 0x2000;
value |= (InterruptMaskLevel & 7) << 8;
value |= (short) ((InterruptMaskLevel & 7) << 8);
return value;
}
set
@ -128,13 +128,14 @@ namespace BizHawk.Emulation.CPUs.M68000
{
if (Interrupt > 0 && (Interrupt > InterruptMaskLevel || Interrupt > 7))
{
// TODO: Entering interrupt is not free. how many cycles does it take?
Log.Error("CPU","****** ENTER INTERRUPT {0} *******", Interrupt);
int sr = SR; // capture current SR.
short sr = (short) SR; // capture current SR.
S = true; // switch to supervisor mode, if not already in it.
A[7].s32 -= 4; // Push PC on stack
WriteLong(A[7].s32, PC);
A[7].s32 -= 2; // Push SR on stack
WriteLong(A[7].s32, sr);
WriteWord(A[7].s32, sr);
PC = ReadLong((24 + Interrupt) * 4); // Jump to interrupt vector
InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered
Interrupt = 0; // "ack" interrupt. Note: this is wrong.

View File

@ -43,6 +43,7 @@ namespace BizHawk.Emulation.CPUs.M68000
Assign("bsr", BSR, "01100001", "Data8");
Assign("scc", Scc, "0101", "CondAll", "11","AmXn");
Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn");
Assign("rte", RTE, "0100111001110011");
Assign("rts", RTS, "0100111001110101");
Assign("tst", TST, "01001010", "Size2_1", "AmXn");
Assign("btst", BTSTi, "0000100000", "AmXn");
@ -54,6 +55,7 @@ namespace BizHawk.Emulation.CPUs.M68000
Assign("bset", BSETi, "0000100011", "AmXn");
Assign("bset", BSETr, "0000", "Xn", "111", "AmXn");
Assign("link", LINK, "0100111001010", "Xn");
Assign("unlk", UNLK, "0100111001011", "Xn");
Assign("nop", NOP, "0100111001110001");
Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn");
@ -73,7 +75,10 @@ namespace BizHawk.Emulation.CPUs.M68000
Assign("move2sr", MOVEtSR, "0100011011", "AmXn");
Assign("movefsr", MOVEfSR, "0100000011", "AmXn");
Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn");
Assign("andi2sr", ANDI_SR, "0000001001111100");
Assign("eori2sr", EORI_SR, "0000101001111100");
Assign("ori2sr", ORI_SR, "0000000001111100");
Assign("trap", TRAP, "010011100100", "Data4");
}
void Assign(string instr, Action exec, string root, params string[] bitfield)
@ -93,6 +98,7 @@ namespace BizHawk.Emulation.CPUs.M68000
else if (component == "CondMain") opList = AppendPermutations(opList, ConditionMain);
else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll);
else if (component == "Data1") opList = AppendData(opList, 1);
else if (component == "Data4") opList = AppendData(opList, 4);
else if (component == "Data3") opList = AppendData(opList, 3);
else if (component == "Data8") opList = AppendData(opList, 8);
}
@ -100,7 +106,7 @@ namespace BizHawk.Emulation.CPUs.M68000
foreach (var opcode in opList)
{
int opc = Convert.ToInt32(opcode, 2);
if (Opcodes[opc] != null && instr.NotIn("movea","ori2sr","ext","dbcc","swap"))
if (Opcodes[opc] != null && instr.NotIn("movea","andi2sr","ori2sr","ext","dbcc","swap"))
Console.WriteLine("Setting opcode for {0}, a handler is already set. overwriting. {1:X4}", instr, opc);
Opcodes[opc] = exec;
}