diff --git a/BizHawk.Emulation/CPUs/68000/Diassembler.cs b/BizHawk.Emulation/CPUs/68000/Diassembler.cs index 0db77367f1..b2b4a0f99c 100644 --- a/BizHawk.Emulation/CPUs/68000/Diassembler.cs +++ b/BizHawk.Emulation/CPUs/68000/Diassembler.cs @@ -47,6 +47,7 @@ namespace BizHawk.Emulation.CPUs.M68000 else if (Opcodes[op] == EOR) EOR_Disasm(info); else if (Opcodes[op] == OR0) OR0_Disasm(info); else if (Opcodes[op] == OR1) OR1_Disasm(info); + else if (Opcodes[op] == NOT) NOT_Disasm(info); else if (Opcodes[op] == JMP) JMP_Disasm(info); else if (Opcodes[op] == JSR) JSR_Disasm(info); @@ -59,6 +60,12 @@ namespace BizHawk.Emulation.CPUs.M68000 else if (Opcodes[op] == TST) TST_Disasm(info); else if (Opcodes[op] == BTSTi) BTSTi_Disasm(info); else if (Opcodes[op] == BTSTr) BTSTr_Disasm(info); + else if (Opcodes[op] == BCHGi) BCHGi_Disasm(info); + else if (Opcodes[op] == BCHGr) BCHGr_Disasm(info); + else if (Opcodes[op] == BCLRi) BCLRi_Disasm(info); + else if (Opcodes[op] == BCLRr) BCLRr_Disasm(info); + 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] == NOP) NOP_Disasm(info); diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs b/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs index 9cd22f57a5..a654b01dfc 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs @@ -512,6 +512,77 @@ namespace BizHawk.Emulation.CPUs.M68000 info.Length = pc - info.PC; } + void NOT() + { + int size = (op >> 6) & 0x03; + int mode = (op >> 3) & 0x07; + int reg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + { + sbyte value = PeekValueB(mode, reg); + value = (sbyte) ~value; + WriteValueB(mode, reg, value); + PendingCycles -= (mode == 0) ? 4 : 8 + EACyclesBW[mode, reg]; + N = (value & 0x80) != 0; + Z = (value == 0); + return; + } + case 1: // Word + { + short value = PeekValueW(mode, reg); + value = (short) ~value; + WriteValueW(mode, reg, value); + PendingCycles -= (mode == 0) ? 4 : 8 + EACyclesBW[mode, reg]; + N = (value & 0x8000) != 0; + Z = (value == 0); + return; + } + case 2: // Long + { + int value = PeekValueL(mode, reg); + value = ~value; + WriteValueL(mode, reg, value); + PendingCycles -= (mode == 0) ? 8 : 12 + EACyclesL[mode, reg]; + N = (value & 0x80000000) != 0; + Z = (value == 0); + return; + } + } + } + + void NOT_Disasm(DisassemblyInfo info) + { + int size = (op >> 6) & 0x03; + int mode = (op >> 3) & 0x07; + int reg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "not.b"; + info.Args = DisassembleValue(mode, reg, 1, ref pc); + break; + case 1: // Word + info.Mnemonic = "not.w"; + info.Args = DisassembleValue(mode, reg, 2, ref pc); + break; + case 2: // Long + info.Mnemonic = "not.l"; + info.Args = DisassembleValue(mode, reg, 4, ref pc); + break; + } + + info.Length = pc - info.PC; + } + void LSLd() { int rot = (op >> 9) & 7; diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs b/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs index 92e5f318df..9f5cc16f1b 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs @@ -1,5 +1,4 @@ - -using System; +using System; namespace BizHawk.Emulation.CPUs.M68000 { @@ -241,10 +240,9 @@ namespace BizHawk.Emulation.CPUs.M68000 void BTSTi() { - int bit = ReadWord(PC); - PC += 2; + int bit = ReadWord(PC); PC += 2; int mode = (op >> 3) & 7; - int reg = op & 7; + int reg = op & 7; if (mode == 0) { @@ -262,10 +260,10 @@ namespace BizHawk.Emulation.CPUs.M68000 void BTSTi_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; - int bit = ReadWord(pc); pc += 2; + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; int mode = (op >> 3) & 7; - int reg = op & 7; + int reg = op & 7; info.Mnemonic = "btst"; info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); @@ -276,8 +274,8 @@ namespace BizHawk.Emulation.CPUs.M68000 { int dReg = (op >> 9) & 7; int mode = (op >> 3) & 7; - int reg = op & 7; - int bit = D[dReg].s32; + int reg = op & 7; + int bit = D[dReg].s32; if (mode == 0) { @@ -297,16 +295,247 @@ namespace BizHawk.Emulation.CPUs.M68000 void BTSTr_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int dReg = (op >> 9) & 7; int mode = (op >> 3) & 7; - int reg = op & 7; + int reg = op & 7; info.Mnemonic = "btst"; info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); info.Length = pc - info.PC; } + void BCHGi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 ^= mask; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value ^= (sbyte) mask; + WriteValueB(mode, reg, value); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BCHGi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bchg"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BCHGr() + { + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + int bit = D[dReg].s32; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 ^= mask; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value ^= (sbyte) mask; + WriteValueB(mode, reg, value); + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } + } + + void BCHGr_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bchg"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BCLRi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 &= ~mask; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value &= (sbyte) ~mask; + WriteValueB(mode, reg, value); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BCLRi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bclr"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BCLRr() + { + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + int bit = D[dReg].s32; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 &= ~mask; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value &= (sbyte) ~mask; + WriteValueB(mode, reg, value); + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } + } + + void BCLRr_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bclr"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BSETi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 |= mask; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value |= (sbyte) mask; + WriteValueB(mode, reg, value); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BSETi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bset"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BSETr() + { + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + int bit = D[dReg].s32; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 |= mask; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value |= (sbyte) mask; + WriteValueB(mode, reg, value); + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } + } + + void BSETr_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bset"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + void JMP() { int mode = (op >> 3) & 7; @@ -332,7 +561,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void JMP_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; info.Mnemonic = "jmp"; @@ -369,7 +598,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void JSR_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; info.Mnemonic = "jsr"; @@ -389,7 +618,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void LINK_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int reg = op & 7; info.Mnemonic = "link"; info.Args = "A"+reg+", "+DisassembleImmediate(2, ref pc); // TODO need a DisassembleSigned or something @@ -410,7 +639,7 @@ namespace BizHawk.Emulation.CPUs.M68000 { int cond = (op >> 8) & 0x0F; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; if (TestCondition(cond) == true) { @@ -426,10 +655,10 @@ namespace BizHawk.Emulation.CPUs.M68000 void Scc_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int cond = (op >> 8) & 0x0F; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; info.Mnemonic = "s" + DisassembleCondition(cond); info.Args = DisassembleValue(mode, reg, 1, ref pc); diff --git a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs index 557d5beb40..10f7c71ba3 100644 --- a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs +++ b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs @@ -9,10 +9,6 @@ namespace BizHawk.Emulation.CPUs.M68000 { // NOTE: Do not change the order of these assigns without testing. There is // some overwriting of less-specific opcodes with more-specific opcodes. - // * MOVEA overwrites MOVE. - // * EXT overwrites MOVEM0 - // * DBcc overwrites Scc - // * ORI to SR overwrites ORI Assign("move", MOVE, "00", "Size2_0", "XnAm", "AmXn"); Assign("movea", MOVEA, "00", "Size2_0", "Xn", "001", "AmXn"); @@ -38,6 +34,7 @@ namespace BizHawk.Emulation.CPUs.M68000 Assign("eor", EOR, "1011", "Xn", "1", "Size2_1", "AmXn"); Assign("or", OR0, "1000", "Xn", "0", "Size2_1", "AmXn"); Assign("or", OR1, "1000", "Xn", "1", "Size2_1", "AmXn"); + Assign("not", NOT, "01000110", "Size2_1", "AmXn"); Assign("jmp", JMP, "0100111011", "AmXn"); Assign("jsr", JSR, "0100111010", "AmXn"); @@ -50,6 +47,12 @@ namespace BizHawk.Emulation.CPUs.M68000 Assign("tst", TST, "01001010", "Size2_1", "AmXn"); Assign("btst", BTSTi, "0000100000", "AmXn"); Assign("btst", BTSTr, "0000", "Xn", "100", "AmXn"); + Assign("bchg", BCHGi, "0000100001", "AmXn"); + Assign("bchg", BCHGr, "0000", "Xn", "101", "AmXn"); + Assign("bclr", BCLRi, "0000100010", "AmXn"); + Assign("bclr", BCLRr, "0000", "Xn", "110", "AmXn"); + Assign("bset", BSETi, "0000100011", "AmXn"); + Assign("bset", BSETr, "0000", "Xn", "111", "AmXn"); Assign("link", LINK, "0100111001010", "Xn"); Assign("nop", NOP, "0100111001110001"); @@ -326,4 +329,4 @@ namespace BizHawk.Emulation.CPUs.M68000 #endregion } -} +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs index 9d12a6f426..d94802aad8 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.IO; -using BizHawk.Emulation.CPUs.M68K; +using BizHawk.Emulation.CPUs.M68000; using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Sound; diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs index 399ccaa892..7c3c067820 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs @@ -64,6 +64,8 @@ namespace BizHawk.Emulation.Consoles.Sega if (address >= 0xC00004 && address < 0xC00008) return (short) VDP.ReadVdpControl(); + if (address == 0xA1000C) return 0; // FIXME HACK for tg-sync. + Console.WriteLine("UNHANDLED READW {0:X6}", address); return 0x7DCD; } @@ -75,12 +77,15 @@ namespace BizHawk.Emulation.Consoles.Sega int maskedAddr; if (address < 0x400000) // Cartridge ROM return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3]; - + if (address >= 0xE00000) // Work RAM { maskedAddr = address & 0xFFFF; return (Ram[maskedAddr] << 24) | (Ram[maskedAddr + 1] << 16) | (Ram[maskedAddr + 2] << 8) | Ram[maskedAddr + 3]; } + + if (address == 0xA10008) return 0; // FIXME HACK for tg-sync. + Console.WriteLine("UNHANDLED READL {0:X6}", address); return 0x7DCDCDCD; }