68000: add MULU, MULS, DIVU, DIVS, MOVE to CCR
Some genesis source reorganization
This commit is contained in:
parent
c787b70613
commit
5b5c7c2890
|
@ -163,6 +163,7 @@
|
||||||
<Compile Include="Consoles\PC Engine\MemoryMap.Populous.cs" />
|
<Compile Include="Consoles\PC Engine\MemoryMap.Populous.cs" />
|
||||||
<Compile Include="Consoles\PC Engine\ScsiCDBus.cs" />
|
<Compile Include="Consoles\PC Engine\ScsiCDBus.cs" />
|
||||||
<Compile Include="Consoles\PC Engine\TurboCD.cs" />
|
<Compile Include="Consoles\PC Engine\TurboCD.cs" />
|
||||||
|
<Compile Include="Consoles\Sega\Genesis\Input.cs" />
|
||||||
<Compile Include="Consoles\Sega\SMS\MemoryMap.CodeMasters.cs" />
|
<Compile Include="Consoles\Sega\SMS\MemoryMap.CodeMasters.cs" />
|
||||||
<Compile Include="Consoles\Sega\SMS\MemoryMap.Sega.cs" />
|
<Compile Include="Consoles\Sega\SMS\MemoryMap.Sega.cs" />
|
||||||
<Compile Include="Consoles\Sega\SMS\VDP.ModeTMS.cs" />
|
<Compile Include="Consoles\Sega\SMS\VDP.ModeTMS.cs" />
|
||||||
|
@ -174,7 +175,7 @@
|
||||||
<Compile Include="CPUs\68000\Instructions\IntegerMath.cs" />
|
<Compile Include="CPUs\68000\Instructions\IntegerMath.cs" />
|
||||||
<Compile Include="CPUs\68000\Instructions\ProgramFlow.cs" />
|
<Compile Include="CPUs\68000\Instructions\ProgramFlow.cs" />
|
||||||
<Compile Include="CPUs\68000\Instructions\Supervisor.cs" />
|
<Compile Include="CPUs\68000\Instructions\Supervisor.cs" />
|
||||||
<Compile Include="CPUs\68000\M68000.cs" />
|
<Compile Include="CPUs\68000\MC68000.cs" />
|
||||||
<Compile Include="CPUs\68000\Memory.cs" />
|
<Compile Include="CPUs\68000\Memory.cs" />
|
||||||
<Compile Include="CPUs\68000\OpcodeTable.cs" />
|
<Compile Include="CPUs\68000\OpcodeTable.cs" />
|
||||||
<Compile Include="CPUs\68000\Tables.cs" />
|
<Compile Include="CPUs\68000\Tables.cs" />
|
||||||
|
@ -277,7 +278,6 @@
|
||||||
<Compile Include="Consoles\PC Engine\VPC.cs" />
|
<Compile Include="Consoles\PC Engine\VPC.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Consoles\Sega\Genesis\Genesis.cs" />
|
<Compile Include="Consoles\Sega\Genesis\Genesis.cs" />
|
||||||
<Compile Include="Consoles\Sega\Genesis\Genesis.Input.cs" />
|
|
||||||
<Compile Include="Consoles\Sega\Genesis\GenVDP.cs" />
|
<Compile Include="Consoles\Sega\Genesis\GenVDP.cs" />
|
||||||
<Compile Include="Consoles\Sega\Genesis\GenVDP.DMA.cs" />
|
<Compile Include="Consoles\Sega\Genesis\GenVDP.DMA.cs" />
|
||||||
<Compile Include="Consoles\Sega\Genesis\GenVDP.Render.cs" />
|
<Compile Include="Consoles\Sega\Genesis\GenVDP.Render.cs" />
|
||||||
|
@ -300,6 +300,7 @@
|
||||||
<Content Include="Consoles\Nintendo\Docs\notes_for_disch.txt" />
|
<Content Include="Consoles\Nintendo\Docs\notes_for_disch.txt" />
|
||||||
<Content Include="Consoles\Nintendo\Docs\test_status.txt" />
|
<Content Include="Consoles\Nintendo\Docs\test_status.txt" />
|
||||||
<Content Include="Consoles\PC Engine\Compat.txt" />
|
<Content Include="Consoles\PC Engine\Compat.txt" />
|
||||||
|
<Content Include="Consoles\Sega\Genesis\Compat.txt" />
|
||||||
<Content Include="Consoles\Sega\SMS\Compat.txt" />
|
<Content Include="Consoles\Sega\SMS\Compat.txt" />
|
||||||
<Content Include="ExternalCores\Snippets.txt" />
|
<Content Include="ExternalCores\Snippets.txt" />
|
||||||
<Content Include="Notes.txt" />
|
<Content Include="Notes.txt" />
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.CPUs.M68000
|
namespace BizHawk.Emulation.CPUs.M68000
|
||||||
{
|
{
|
||||||
public class DisassemblyInfo
|
public sealed class DisassemblyInfo
|
||||||
{
|
{
|
||||||
public int PC;
|
public int PC;
|
||||||
public string Mnemonic;
|
public string Mnemonic;
|
||||||
|
@ -88,6 +88,10 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
else if (Opcodes[op] == CMP) CMP_Disasm(info);
|
else if (Opcodes[op] == CMP) CMP_Disasm(info);
|
||||||
else if (Opcodes[op] == CMPA) CMPA_Disasm(info);
|
else if (Opcodes[op] == CMPA) CMPA_Disasm(info);
|
||||||
else if (Opcodes[op] == CMPI) CMPI_Disasm(info);
|
else if (Opcodes[op] == CMPI) CMPI_Disasm(info);
|
||||||
|
else if (Opcodes[op] == MULU) MULU_Disasm(info);
|
||||||
|
else if (Opcodes[op] == MULS) MULS_Disasm(info);
|
||||||
|
else if (Opcodes[op] == DIVU) DIVU_Disasm(info);
|
||||||
|
else if (Opcodes[op] == DIVS) DIVS_Disasm(info);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -95,6 +99,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
else if (Opcodes[op] == ANDI_SR) ANDI_SR_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] == 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] == MOVECCR) MOVECCR_Disasm(info);
|
||||||
else if (Opcodes[op] == TRAP) TRAP_Disasm(info);
|
else if (Opcodes[op] == TRAP) TRAP_Disasm(info);
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
{
|
{
|
||||||
partial class MC68000
|
partial class MC68000
|
||||||
{
|
{
|
||||||
|
// TODO, the timing on AND variants is wrong. IE, and.w w/ immediate should be 8 cycles, but I cant figure out how that should work.
|
||||||
void AND0() // AND <ea>, Dn
|
void AND0() // AND <ea>, Dn
|
||||||
{
|
{
|
||||||
int dstReg = (op >> 9) & 0x07;
|
int dstReg = (op >> 9) & 0x07;
|
||||||
|
|
|
@ -439,8 +439,8 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
int reg = (op >> 0) & 7;
|
int reg = (op >> 0) & 7;
|
||||||
int pc = info.PC + 2;
|
int pc = info.PC + 2;
|
||||||
|
|
||||||
|
ushort registers = (ushort)ReadWord(pc); pc += 2;
|
||||||
string address = DisassembleAddress(mode, reg, ref pc);
|
string address = DisassembleAddress(mode, reg, ref pc);
|
||||||
ushort registers = (ushort) ReadWord(pc); pc += 2;
|
|
||||||
|
|
||||||
info.Mnemonic = size == 0 ? "movem.w" : "movem.l";
|
info.Mnemonic = size == 0 ? "movem.w" : "movem.l";
|
||||||
info.Args = DisassembleRegisterList0(registers) + ", " + address;
|
info.Args = DisassembleRegisterList0(registers) + ", " + address;
|
||||||
|
@ -454,9 +454,9 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
int reg = (op >> 0) & 7;
|
int reg = (op >> 0) & 7;
|
||||||
int pc = info.PC + 2;
|
int pc = info.PC + 2;
|
||||||
|
|
||||||
string address = DisassembleAddress(mode, reg, ref pc);
|
|
||||||
ushort registers = (ushort)ReadWord(pc); pc += 2;
|
ushort registers = (ushort)ReadWord(pc); pc += 2;
|
||||||
|
string address = DisassembleAddress(mode, reg, ref pc);
|
||||||
|
|
||||||
info.Mnemonic = size == 0 ? "movem.w" : "movem.l";
|
info.Mnemonic = size == 0 ? "movem.w" : "movem.l";
|
||||||
info.Args = address + ", " + DisassembleRegisterList1(registers);
|
info.Args = address + ", " + DisassembleRegisterList1(registers);
|
||||||
info.Length = pc - info.PC;
|
info.Length = pc - info.PC;
|
||||||
|
|
|
@ -307,8 +307,11 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
PendingCycles -= 8 + EACyclesBW[mode, reg];
|
PendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||||
} else { // long
|
} else { // long
|
||||||
int value = ReadValueL(mode, reg);
|
int value = ReadValueL(mode, reg);
|
||||||
A[aReg].s32 -= value;
|
A[aReg].s32 += value;
|
||||||
PendingCycles += 6 + EACyclesL[mode, reg];
|
if (mode == 0 || mode == 1 || (mode == 7 && reg == 4))
|
||||||
|
PendingCycles -= 8 + EACyclesL[mode, reg];
|
||||||
|
else
|
||||||
|
PendingCycles -= 6 + EACyclesL[mode, reg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +634,10 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
} else { // long
|
} else { // long
|
||||||
int value = ReadValueL(mode, reg);
|
int value = ReadValueL(mode, reg);
|
||||||
A[aReg].s32 -= value;
|
A[aReg].s32 -= value;
|
||||||
PendingCycles -= 6 + EACyclesL[mode, reg];
|
if (mode == 0 || mode == 1 || (mode == 7 && reg == 4))
|
||||||
|
PendingCycles -= 8 + EACyclesL[mode, reg];
|
||||||
|
else
|
||||||
|
PendingCycles -= 6 + EACyclesL[mode, reg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,5 +957,135 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
}
|
}
|
||||||
info.Length = pc - info.PC;
|
info.Length = pc - info.PC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MULU()
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
uint result = (uint) (D[dreg].u16 * (ushort)ReadValueW(mode, reg));
|
||||||
|
D[dreg].u32 = result;
|
||||||
|
|
||||||
|
V = false;
|
||||||
|
C = false;
|
||||||
|
N = (result & 0x80000000) != 0;
|
||||||
|
Z = result == 0;
|
||||||
|
|
||||||
|
PendingCycles -= 70 + EACyclesBW[mode, reg];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MULU_Disasm(DisassemblyInfo info)
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
int pc = info.PC;
|
||||||
|
info.Mnemonic = "mulu";
|
||||||
|
info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg);
|
||||||
|
info.Length = pc - info.PC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MULS()
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
int result = D[dreg].s16 * ReadValueW(mode, reg);
|
||||||
|
D[dreg].s32 = result;
|
||||||
|
|
||||||
|
V = false;
|
||||||
|
C = false;
|
||||||
|
N = (result & 0x80000000) != 0;
|
||||||
|
Z = result == 0;
|
||||||
|
|
||||||
|
PendingCycles -= 70 + EACyclesBW[mode, reg];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MULS_Disasm(DisassemblyInfo info)
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
int pc = info.PC;
|
||||||
|
info.Mnemonic = "muls";
|
||||||
|
info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg);
|
||||||
|
info.Length = pc - info.PC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DIVU()
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
uint source = (ushort) ReadValueW(mode, reg);
|
||||||
|
uint dest = D[dreg].u32;
|
||||||
|
|
||||||
|
if (source == 0)
|
||||||
|
throw new Exception("divide by zero");
|
||||||
|
|
||||||
|
uint quotient = dest / source;
|
||||||
|
uint remainder = dest % source;
|
||||||
|
|
||||||
|
V = ((int) quotient < short.MinValue || (int) quotient > short.MaxValue);
|
||||||
|
N = (quotient & 0x8000) != 0;
|
||||||
|
Z = quotient == 0;
|
||||||
|
C = false;
|
||||||
|
|
||||||
|
D[dreg].u32 = (quotient & 0xFFFF) | (remainder << 16);
|
||||||
|
PendingCycles -= 140 + EACyclesBW[mode, reg]; // this is basically a rough approximation at best.
|
||||||
|
}
|
||||||
|
|
||||||
|
void DIVU_Disasm(DisassemblyInfo info)
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
int pc = info.PC;
|
||||||
|
info.Mnemonic = "divu";
|
||||||
|
info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg);
|
||||||
|
info.Length = pc - info.PC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DIVS()
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
int source = ReadValueW(mode, reg);
|
||||||
|
int dest = D[dreg].s32;
|
||||||
|
|
||||||
|
if (source == 0)
|
||||||
|
throw new Exception("divide by zero");
|
||||||
|
|
||||||
|
int quotient = dest / source;
|
||||||
|
int remainder = dest % source;
|
||||||
|
|
||||||
|
V = ((int)quotient < short.MinValue || (int)quotient > short.MaxValue);
|
||||||
|
N = (quotient & 0x8000) != 0;
|
||||||
|
Z = quotient == 0;
|
||||||
|
C = false;
|
||||||
|
|
||||||
|
D[dreg].s32 = (quotient & 0xFFFF) | (remainder << 16);
|
||||||
|
PendingCycles -= 140 + EACyclesBW[mode, reg];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DIVS_Disasm(DisassemblyInfo info)
|
||||||
|
{
|
||||||
|
int dreg = (op >> 9) & 3;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
int pc = info.PC;
|
||||||
|
info.Mnemonic = "divs";
|
||||||
|
info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg);
|
||||||
|
info.Length = pc - info.PC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -628,7 +628,8 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
A[7].s32 -= 4;
|
A[7].s32 -= 4;
|
||||||
short offset = ReadWord(PC); PC += 2;
|
short offset = ReadWord(PC); PC += 2;
|
||||||
WriteLong(A[7].s32, A[reg].s32);
|
WriteLong(A[7].s32, A[reg].s32);
|
||||||
A[reg].s32 = A[7].s32 + offset;
|
A[reg].s32 = A[7].s32;
|
||||||
|
A[7].s32 += offset;
|
||||||
PendingCycles -= 16;
|
PendingCycles -= 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
int mode = (op >> 3) & 7;
|
int mode = (op >> 3) & 7;
|
||||||
int reg = (op >> 0) & 7;
|
int reg = (op >> 0) & 7;
|
||||||
SR = ReadValueW(mode, reg);
|
SR = ReadValueW(mode, reg);
|
||||||
PendingCycles -= (mode == 0) ? 12 : 12 + EACyclesBW[mode, reg];
|
PendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MOVEtSR_Disasm(DisassemblyInfo info)
|
void MOVEtSR_Disasm(DisassemblyInfo info)
|
||||||
|
@ -115,6 +115,27 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
info.Length = pc - info.PC;
|
info.Length = pc - info.PC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MOVECCR()
|
||||||
|
{
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
|
||||||
|
ushort sr = (ushort) (SR & 0xFF00);
|
||||||
|
sr |= (byte)ReadValueB(mode, reg);
|
||||||
|
SR = (short)sr;
|
||||||
|
PendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOVECCR_Disasm(DisassemblyInfo info)
|
||||||
|
{
|
||||||
|
int pc = info.PC + 2;
|
||||||
|
int mode = (op >> 3) & 7;
|
||||||
|
int reg = (op >> 0) & 7;
|
||||||
|
info.Mnemonic = "move";
|
||||||
|
info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", CCR";
|
||||||
|
info.Length = pc - info.PC;
|
||||||
|
}
|
||||||
|
|
||||||
void TRAP()
|
void TRAP()
|
||||||
{
|
{
|
||||||
int vector = 32 + (op & 0x0F);
|
int vector = 32 + (op & 0x0F);
|
||||||
|
|
|
@ -144,6 +144,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
int prevCycles = PendingCycles;
|
int prevCycles = PendingCycles;
|
||||||
Log.Note("CPU", State());
|
Log.Note("CPU", State());
|
||||||
op = (ushort)ReadWord(PC);
|
op = (ushort)ReadWord(PC);
|
||||||
|
if (Opcodes[op] == null) throw new Exception(string.Format("unhandled opcode at pc={0:X6}",PC));
|
||||||
PC += 2;
|
PC += 2;
|
||||||
Opcodes[op]();
|
Opcodes[op]();
|
||||||
int delta = prevCycles - PendingCycles;
|
int delta = prevCycles - PendingCycles;
|
|
@ -173,7 +173,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
value = ReadByte((A[reg].s32 + ReadWord(PC)));
|
value = ReadByte((A[reg].s32 + ReadWord(PC)));
|
||||||
return value;
|
return value;
|
||||||
case 6: // (d8,An,Xn)
|
case 6: // (d8,An,Xn)
|
||||||
return ReadByte(A[reg].s32 + GetIndex());
|
return ReadByte(A[reg].s32 + PeekIndex());
|
||||||
case 7:
|
case 7:
|
||||||
switch (reg)
|
switch (reg)
|
||||||
{
|
{
|
||||||
|
@ -545,7 +545,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
|
|
||||||
int GetIndex()
|
int GetIndex()
|
||||||
{
|
{
|
||||||
Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!");
|
//Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!");
|
||||||
// TODO kid chameleon triggers this in startup sequence
|
// TODO kid chameleon triggers this in startup sequence
|
||||||
|
|
||||||
short extension = ReadWord(PC); PC += 2;
|
short extension = ReadWord(PC); PC += 2;
|
||||||
|
@ -574,7 +574,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
|
|
||||||
int PeekIndex()
|
int PeekIndex()
|
||||||
{
|
{
|
||||||
Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!");
|
//Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!");
|
||||||
|
|
||||||
short extension = ReadWord(PC);
|
short extension = ReadWord(PC);
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,10 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
Assign("cmp", CMP, "1011", "Xn", "0", "Size2_1", "AmXn");
|
Assign("cmp", CMP, "1011", "Xn", "0", "Size2_1", "AmXn");
|
||||||
Assign("cmpa", CMPA, "1011", "Xn", "Size1", "11", "AmXn");
|
Assign("cmpa", CMPA, "1011", "Xn", "Size1", "11", "AmXn");
|
||||||
Assign("cmpi", CMPI, "00001100", "Size2_1", "AmXn");
|
Assign("cmpi", CMPI, "00001100", "Size2_1", "AmXn");
|
||||||
|
Assign("mulu", MULU, "1100", "Xn", "011", "AmXn"); // TODO accurate timing
|
||||||
|
Assign("muls", MULS, "1100", "Xn", "111", "AmXn"); // TODO accurate timing
|
||||||
|
Assign("divu", DIVU, "1000", "Xn", "011", "AmXn"); // TODO accurate timing
|
||||||
|
Assign("divs", DIVS, "1000", "Xn", "111", "AmXn"); // TODO accurate timing
|
||||||
|
|
||||||
Assign("move2sr", MOVEtSR, "0100011011", "AmXn");
|
Assign("move2sr", MOVEtSR, "0100011011", "AmXn");
|
||||||
Assign("movefsr", MOVEfSR, "0100000011", "AmXn");
|
Assign("movefsr", MOVEfSR, "0100000011", "AmXn");
|
||||||
|
@ -82,6 +86,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
||||||
Assign("andi2sr", ANDI_SR, "0000001001111100");
|
Assign("andi2sr", ANDI_SR, "0000001001111100");
|
||||||
Assign("eori2sr", EORI_SR, "0000101001111100");
|
Assign("eori2sr", EORI_SR, "0000101001111100");
|
||||||
Assign("ori2sr", ORI_SR, "0000000001111100");
|
Assign("ori2sr", ORI_SR, "0000000001111100");
|
||||||
|
Assign("moveccr", MOVECCR, "0100010011", "AmXn");
|
||||||
Assign("trap", TRAP, "010011100100", "Data4");
|
Assign("trap", TRAP, "010011100100", "Data4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,28 +34,28 @@
|
||||||
{ 12, 12, 20, 20, 20, 24, 26, 24, 28 }
|
{ 12, 12, 20, 20, 20, 24, 26, 24, 28 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static readonly int[,] EACyclesBW = new int[8, 9]
|
static readonly int[,] EACyclesBW = new int[8, 8]
|
||||||
{
|
{
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 4 },
|
{ 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 4 },
|
{ 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||||
{ 6, 6, 6, 6, 6, 6, 6, 6, 6 },
|
{ 6, 6, 6, 6, 6, 6, 6, 6 },
|
||||||
{ 8, 8, 8, 8, 8, 8, 8, 8, 8 },
|
{ 8, 8, 8, 8, 8, 8, 8, 8 },
|
||||||
{ 10, 10, 10, 10, 10, 10, 10, 10, 10 },
|
{ 10, 10, 10, 10, 10, 10, 10, 10 },
|
||||||
{ 8, 12, 8, 10, 4, 99, 99, 99, 99 }
|
{ 8, 12, 8, 10, 4, 99, 99, 99 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static readonly int[,] EACyclesL = new int[8, 9]
|
static readonly int[,] EACyclesL = new int[8, 8]
|
||||||
{
|
{
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 8, 8, 8, 8, 8, 8, 8, 8, 8 },
|
{ 8, 8, 8, 8, 8, 8, 8, 8 },
|
||||||
{ 8, 8, 8, 8, 8, 8, 8, 8, 8 },
|
{ 8, 8, 8, 8, 8, 8, 8, 8 },
|
||||||
{ 10, 10, 10, 10, 10, 10, 10, 10, 10 },
|
{ 10, 10, 10, 10, 10, 10, 10, 10 },
|
||||||
{ 12, 12, 12, 12, 12, 12, 12, 12, 12 },
|
{ 12, 12, 12, 12, 12, 12, 12, 12 },
|
||||||
{ 14, 14, 14, 14, 14, 14, 14, 14, 14 },
|
{ 14, 14, 14, 14, 14, 14, 14, 14 },
|
||||||
{ 12, 16, 12, 14, 8, 99, 99, 99, 99 }
|
{ 12, 16, 12, 14, 8, 99, 99, 99 }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
68000:
|
||||||
|
|
||||||
|
Timings:
|
||||||
|
|
||||||
|
- MULU/MULS/DIVU/DIVS have funky timings.
|
||||||
|
- How many cycles does TRAP take to execute?
|
||||||
|
- How many cycles does it take to accept an interrupt?
|
||||||
|
- AND has some funky timings when it comes to immediates?
|
|
@ -7,7 +7,8 @@ using BizHawk.Emulation.Sound;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Consoles.Sega
|
namespace BizHawk.Emulation.Consoles.Sega
|
||||||
{
|
{
|
||||||
public sealed partial class Genesis : IEmulator
|
[CoreVersion("0.0.0.1", FriendlyName = "MegaHawk")]
|
||||||
|
public sealed partial class Genesis : IEmulator
|
||||||
{
|
{
|
||||||
// ROM
|
// ROM
|
||||||
public byte[] RomData;
|
public byte[] RomData;
|
||||||
|
@ -61,15 +62,15 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
YM2612 = new YM2612();
|
YM2612 = new YM2612();
|
||||||
PSG = new SN76489();
|
PSG = new SN76489();
|
||||||
VDP = new GenVDP();
|
VDP = new GenVDP();
|
||||||
VDP.DmaReadFrom68000 = ReadW;
|
VDP.DmaReadFrom68000 = ReadWord;
|
||||||
SoundMixer = new SoundMixer(YM2612, PSG);
|
SoundMixer = new SoundMixer(YM2612, PSG);
|
||||||
|
|
||||||
MainCPU.ReadByte = ReadB;
|
MainCPU.ReadByte = ReadByte;
|
||||||
MainCPU.ReadWord = ReadW;
|
MainCPU.ReadWord = ReadWord;
|
||||||
MainCPU.ReadLong = ReadL;
|
MainCPU.ReadLong = ReadLong;
|
||||||
MainCPU.WriteByte = WriteB;
|
MainCPU.WriteByte = WriteByte;
|
||||||
MainCPU.WriteWord = WriteW;
|
MainCPU.WriteWord = WriteWord;
|
||||||
MainCPU.WriteLong = WriteL;
|
MainCPU.WriteLong = WriteLong;
|
||||||
|
|
||||||
SoundCPU.ReadMemory = ReadMemoryZ80;
|
SoundCPU.ReadMemory = ReadMemoryZ80;
|
||||||
SoundCPU.WriteMemory = WriteMemoryZ80;
|
SoundCPU.WriteMemory = WriteMemoryZ80;
|
||||||
|
@ -94,7 +95,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
|
|
||||||
if (VDP.ScanLine < 224)
|
if (VDP.ScanLine < 224)
|
||||||
VDP.RenderLine();
|
VDP.RenderLine();
|
||||||
|
|
||||||
MainCPU.ExecuteCycles(487); // 488??
|
MainCPU.ExecuteCycles(487); // 488??
|
||||||
if (Z80Runnable)
|
if (Z80Runnable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
namespace BizHawk.Emulation.Consoles.Sega
|
namespace BizHawk.Emulation.Consoles.Sega
|
||||||
{
|
{
|
||||||
public partial class Genesis
|
partial class Genesis
|
||||||
{
|
{
|
||||||
// todo ???????
|
|
||||||
public bool SegaCD = false;
|
public bool SegaCD = false;
|
||||||
|
|
||||||
public int ReadIO(int offset)
|
public byte ReadIO(int offset)
|
||||||
{
|
{
|
||||||
int value;
|
offset &= 3;
|
||||||
|
byte value;
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0: // version
|
case 0: // version
|
||||||
value = SegaCD ? 0x00 : 0x20;
|
value = (byte) (SegaCD ? 0x00 : 0x20);
|
||||||
switch((char)RomData[0x01F0])
|
switch((char)RomData[0x01F0])
|
||||||
{
|
{
|
||||||
case 'J': value |= 0x00; break;
|
case 'J': value |= 0x00; break;
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
case '4': value |= 0x80; break;
|
case '4': value |= 0x80; break;
|
||||||
default: value |= 0x80; break;
|
default: value |= 0x80; break;
|
||||||
}
|
}
|
||||||
value |= 1; // US
|
//value |= 1; // US
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace BizHawk.Emulation.Consoles.Sega
|
namespace BizHawk.Emulation.Consoles.Sega
|
||||||
{
|
{
|
||||||
public partial class Genesis
|
partial class Genesis
|
||||||
{
|
{
|
||||||
public static readonly ControllerDefinition GenesisController = new ControllerDefinition
|
public static readonly ControllerDefinition GenesisController = new ControllerDefinition
|
||||||
{
|
{
|
|
@ -2,17 +2,9 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Consoles.Sega
|
namespace BizHawk.Emulation.Consoles.Sega
|
||||||
{
|
{
|
||||||
public partial class Genesis
|
partial class Genesis
|
||||||
{
|
{
|
||||||
private byte ReadByte(uint address) { return (byte) ReadB((int)address); }
|
public sbyte ReadByte(int address)
|
||||||
private ushort ReadWord(uint address) { return (ushort) ReadW((int)address); }
|
|
||||||
private uint ReadLong(uint address) { return (uint) ReadL((int)address); }
|
|
||||||
|
|
||||||
private void WriteByte(uint address, byte value) { WriteB((int)address, (sbyte)value); }
|
|
||||||
private void WriteWord(uint address, ushort value) { WriteW((int)address, (short)value); }
|
|
||||||
private void WriteLong(uint address, uint value) { WriteL((int)address, (int) value); }
|
|
||||||
|
|
||||||
public sbyte ReadB(int address)
|
|
||||||
{
|
{
|
||||||
address &= 0x00FFFFFF;
|
address &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
@ -47,7 +39,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
return 0x7D;
|
return 0x7D;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short ReadW(int address)
|
public short ReadWord(int address)
|
||||||
{
|
{
|
||||||
address &= 0x00FFFFFF;
|
address &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
@ -70,7 +62,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
return 0x7DCD;
|
return 0x7DCD;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReadL(int address)
|
public int ReadLong(int address)
|
||||||
{
|
{
|
||||||
address &= 0x00FFFFFF;
|
address &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
@ -90,13 +82,13 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
return 0x7DCDCDCD;
|
return 0x7DCDCDCD;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteB(int address, sbyte value)
|
public void WriteByte(int address, sbyte value)
|
||||||
{
|
{
|
||||||
address &= 0x00FFFFFF;
|
address &= 0x00FFFFFF;
|
||||||
|
|
||||||
if (address >= 0xE00000) // Work RAM
|
if (address >= 0xE00000) // Work RAM
|
||||||
{
|
{
|
||||||
Console.WriteLine("MEM[{0:X4}] change from {1:X2} to {2:X2}", address & 0xFFFF, Ram[address & 0xFFFF], value);
|
//Console.WriteLine("MEM[{0:X4}] change from {1:X2} to {2:X2}", address & 0xFFFF, Ram[address & 0xFFFF], value);
|
||||||
Ram[address & 0xFFFF] = (byte)value;
|
Ram[address & 0xFFFF] = (byte)value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +137,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value);
|
Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteW(int address, short value)
|
public void WriteWord(int address, short value)
|
||||||
{
|
{
|
||||||
address &= 0x00FFFFFF;
|
address &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
@ -187,7 +179,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);
|
Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteL(int address, int value)
|
public void WriteLong(int address, int value)
|
||||||
{
|
{
|
||||||
address &= 0x00FFFFFF;
|
address &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
@ -202,8 +194,8 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
}
|
}
|
||||||
if (address >= 0xC00000)
|
if (address >= 0xC00000)
|
||||||
{
|
{
|
||||||
WriteW(address, (short)(value >> 16));
|
WriteWord(address, (short)(value >> 16));
|
||||||
WriteW(address, (short)value);
|
WriteWord(address, (short)value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Consoles.Sega
|
namespace BizHawk.Emulation.Consoles.Sega
|
||||||
{
|
{
|
||||||
public partial class Genesis
|
partial class Genesis
|
||||||
{
|
{
|
||||||
private int BankRegion;
|
private int BankRegion;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
if (address >= 0x8000)
|
if (address >= 0x8000)
|
||||||
{
|
{
|
||||||
// 68000 Bank region
|
// 68000 Bank region
|
||||||
return (byte) ReadB(BankRegion | (address & 0x7FFF));
|
return (byte) ReadByte(BankRegion | (address & 0x7FFF));
|
||||||
}
|
}
|
||||||
Console.WriteLine("UNHANDLED Z80 READ {0:X4}",address);
|
Console.WriteLine("UNHANDLED Z80 READ {0:X4}",address);
|
||||||
return 0xCD;
|
return 0xCD;
|
||||||
|
@ -51,7 +51,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
||||||
}
|
}
|
||||||
if (address >= 0x8000)
|
if (address >= 0x8000)
|
||||||
{
|
{
|
||||||
WriteB(BankRegion | (address & 0x7FFF), (sbyte) value);
|
WriteByte(BankRegion | (address & 0x7FFF), (sbyte) value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Console.WriteLine("UNHANDLED Z80 WRITE {0:X4}:{1:X2}", address, value);
|
Console.WriteLine("UNHANDLED Z80 WRITE {0:X4}:{1:X2}", address, value);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
public void Write(int addr, byte value)
|
public void Write(int addr, byte value)
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("YM2612: {0:X2} -> {1:X2}", addr, value);
|
//System.Console.WriteLine("YM2612: {0:X2} -> {1:X2}", addr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
|
|
Loading…
Reference in New Issue