68000: implement UNLK, RTE, TRAP, ANDI to SR, and EORI to SR
This commit is contained in:
parent
1c38de023e
commit
a1d8e9a209
|
@ -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++)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue