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] == BSR) BSR_Disasm(info);
|
||||||
else if (Opcodes[op] == DBcc) DBcc_Disasm(info);
|
else if (Opcodes[op] == DBcc) DBcc_Disasm(info);
|
||||||
else if (Opcodes[op] == Scc) Scc_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] == RTS) RTS_Disasm(info);
|
||||||
else if (Opcodes[op] == TST) TST_Disasm(info);
|
else if (Opcodes[op] == TST) TST_Disasm(info);
|
||||||
else if (Opcodes[op] == BTSTi) BTSTi_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] == BSETi) BSETi_Disasm(info);
|
||||||
else if (Opcodes[op] == BSETr) BSETr_Disasm(info);
|
else if (Opcodes[op] == BSETr) BSETr_Disasm(info);
|
||||||
else if (Opcodes[op] == LINK) LINK_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] == NOP) NOP_Disasm(info);
|
||||||
|
|
||||||
else if (Opcodes[op] == ADD0) ADD_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] == MOVEtSR) MOVEtSR_Disasm(info);
|
||||||
else if (Opcodes[op] == MOVEfSR) MOVEfSR_Disasm(info);
|
else if (Opcodes[op] == MOVEfSR) MOVEfSR_Disasm(info);
|
||||||
else if (Opcodes[op] == MOVEUSP) MOVEUSP_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] == ORI_SR) ORI_SR_Disasm(info);
|
||||||
|
else if (Opcodes[op] == TRAP) TRAP_Disasm(info);
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
for (int p = info.PC; p < info.PC + info.Length; p++)
|
for (int p = info.PC; p < info.PC + info.Length; p++)
|
||||||
|
|
|
@ -204,6 +204,22 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
info.Args = "";
|
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()
|
void TST()
|
||||||
{
|
{
|
||||||
int size = (op >> 6) & 3;
|
int size = (op >> 6) & 3;
|
||||||
|
@ -625,6 +641,23 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
info.Length = pc - info.PC;
|
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()
|
void NOP()
|
||||||
{
|
{
|
||||||
PendingCycles -= 4;
|
PendingCycles -= 4;
|
||||||
|
|
|
@ -67,6 +67,38 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
info.Length = pc - info.PC;
|
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()
|
void ORI_SR()
|
||||||
{
|
{
|
||||||
if (S == false)
|
if (S == false)
|
||||||
|
@ -82,5 +114,29 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
|
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
|
||||||
info.Length = pc - info.PC;
|
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;
|
public bool C;
|
||||||
|
|
||||||
/// <summary>Status Register</summary>
|
/// <summary>Status Register</summary>
|
||||||
public int SR
|
public short SR
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int value = 0;
|
short value = 0;
|
||||||
if (C) value |= 0x0001;
|
if (C) value |= 0x0001;
|
||||||
if (V) value |= 0x0002;
|
if (V) value |= 0x0002;
|
||||||
if (Z) value |= 0x0004;
|
if (Z) value |= 0x0004;
|
||||||
|
@ -67,7 +67,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
if (X) value |= 0x0010;
|
if (X) value |= 0x0010;
|
||||||
if (M) value |= 0x1000;
|
if (M) value |= 0x1000;
|
||||||
if (S) value |= 0x2000;
|
if (S) value |= 0x2000;
|
||||||
value |= (InterruptMaskLevel & 7) << 8;
|
value |= (short) ((InterruptMaskLevel & 7) << 8);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
|
@ -128,13 +128,14 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
{
|
{
|
||||||
if (Interrupt > 0 && (Interrupt > InterruptMaskLevel || Interrupt > 7))
|
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);
|
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.
|
S = true; // switch to supervisor mode, if not already in it.
|
||||||
A[7].s32 -= 4; // Push PC on stack
|
A[7].s32 -= 4; // Push PC on stack
|
||||||
WriteLong(A[7].s32, PC);
|
WriteLong(A[7].s32, PC);
|
||||||
A[7].s32 -= 2; // Push SR on stack
|
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
|
PC = ReadLong((24 + Interrupt) * 4); // Jump to interrupt vector
|
||||||
InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered
|
InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered
|
||||||
Interrupt = 0; // "ack" interrupt. Note: this is wrong.
|
Interrupt = 0; // "ack" interrupt. Note: this is wrong.
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
Assign("bsr", BSR, "01100001", "Data8");
|
Assign("bsr", BSR, "01100001", "Data8");
|
||||||
Assign("scc", Scc, "0101", "CondAll", "11","AmXn");
|
Assign("scc", Scc, "0101", "CondAll", "11","AmXn");
|
||||||
Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn");
|
Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn");
|
||||||
|
Assign("rte", RTE, "0100111001110011");
|
||||||
Assign("rts", RTS, "0100111001110101");
|
Assign("rts", RTS, "0100111001110101");
|
||||||
Assign("tst", TST, "01001010", "Size2_1", "AmXn");
|
Assign("tst", TST, "01001010", "Size2_1", "AmXn");
|
||||||
Assign("btst", BTSTi, "0000100000", "AmXn");
|
Assign("btst", BTSTi, "0000100000", "AmXn");
|
||||||
|
@ -54,6 +55,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
Assign("bset", BSETi, "0000100011", "AmXn");
|
Assign("bset", BSETi, "0000100011", "AmXn");
|
||||||
Assign("bset", BSETr, "0000", "Xn", "111", "AmXn");
|
Assign("bset", BSETr, "0000", "Xn", "111", "AmXn");
|
||||||
Assign("link", LINK, "0100111001010", "Xn");
|
Assign("link", LINK, "0100111001010", "Xn");
|
||||||
|
Assign("unlk", UNLK, "0100111001011", "Xn");
|
||||||
Assign("nop", NOP, "0100111001110001");
|
Assign("nop", NOP, "0100111001110001");
|
||||||
|
|
||||||
Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn");
|
Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn");
|
||||||
|
@ -73,7 +75,10 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
Assign("move2sr", MOVEtSR, "0100011011", "AmXn");
|
Assign("move2sr", MOVEtSR, "0100011011", "AmXn");
|
||||||
Assign("movefsr", MOVEfSR, "0100000011", "AmXn");
|
Assign("movefsr", MOVEfSR, "0100000011", "AmXn");
|
||||||
Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn");
|
Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn");
|
||||||
|
Assign("andi2sr", ANDI_SR, "0000001001111100");
|
||||||
|
Assign("eori2sr", EORI_SR, "0000101001111100");
|
||||||
Assign("ori2sr", ORI_SR, "0000000001111100");
|
Assign("ori2sr", ORI_SR, "0000000001111100");
|
||||||
|
Assign("trap", TRAP, "010011100100", "Data4");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assign(string instr, Action exec, string root, params string[] bitfield)
|
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 == "CondMain") opList = AppendPermutations(opList, ConditionMain);
|
||||||
else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll);
|
else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll);
|
||||||
else if (component == "Data1") opList = AppendData(opList, 1);
|
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 == "Data3") opList = AppendData(opList, 3);
|
||||||
else if (component == "Data8") opList = AppendData(opList, 8);
|
else if (component == "Data8") opList = AppendData(opList, 8);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +106,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
foreach (var opcode in opList)
|
foreach (var opcode in opList)
|
||||||
{
|
{
|
||||||
int opc = Convert.ToInt32(opcode, 2);
|
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);
|
Console.WriteLine("Setting opcode for {0}, a handler is already set. overwriting. {1:X4}", instr, opc);
|
||||||
Opcodes[opc] = exec;
|
Opcodes[opc] = exec;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue