68000: implement BSET, BCLR, BCHG, and NOT

This commit is contained in:
beirich 2011-10-08 23:26:29 +00:00
parent 18de3c9efc
commit 1c38de023e
6 changed files with 340 additions and 25 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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
}
}
}

View File

@ -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;

View File

@ -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;
}