mirror of https://github.com/bsnes-emu/bsnes.git
Update to v100r13 release.
byuu says: Changelog: M68K improvements, new instructions added.
This commit is contained in:
parent
f230d144b5
commit
306cac2b54
|
@ -11,7 +11,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "100.12";
|
||||
static const string Version = "100.13";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -41,6 +41,7 @@ template<uint Size> auto M68K::_effectiveAddress(EffectiveAddress& ea) -> string
|
|||
if(ea.mode == 3) return {"(", _addressRegister(AddressRegister{ea.reg}), ")+"};
|
||||
if(ea.mode == 4) return {"-(", _addressRegister(AddressRegister{ea.reg}), ")"};
|
||||
if(ea.mode == 5) return {"($", hex(read(AddressRegister{ea.reg}) + (int16)_readPC(), 6L), ")"};
|
||||
if(ea.mode == 7) return {"($", hex((int16)_readPC<Word>(), 6L), ")"};
|
||||
if(ea.mode == 8) return {"($", hex(_readPC<Long>(), 6L), ")"};
|
||||
if(ea.mode == 11) return {"#$", hex(_readPC<Size>(), 2 << Size)};
|
||||
return "???";
|
||||
|
@ -99,6 +100,18 @@ template<uint Size> auto M68K::disassembleADD(DataRegister dr, uint1 direction,
|
|||
}
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleADDA(AddressRegister ar, EffectiveAddress ea) -> string {
|
||||
return {"adda", _suffix<Size>(), " ", _effectiveAddress<Size>(ea), ",", _addressRegister(ar)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleADDI(EffectiveAddress ea) -> string {
|
||||
return {"addi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleADDQ(uint4 immediate, EffectiveAddress modify) -> string {
|
||||
return {"addq", _suffix<Size>(), " #", immediate, ",", _effectiveAddress<Size>(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleANDI(EffectiveAddress ea) -> string {
|
||||
return {"andi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
@ -155,7 +168,19 @@ template<uint Size> auto M68K::disassembleCLR(EffectiveAddress ea) -> string {
|
|||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleCMP(DataRegister dr, EffectiveAddress ea) -> string {
|
||||
return {"cmp", _suffix<Size>(), " ", _effectiveAddress<Word>(ea), ",", _dataRegister(dr)};
|
||||
return {"cmp", _suffix<Size>(), " ", _effectiveAddress<Size>(ea), ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleCMPA(AddressRegister ar, EffectiveAddress ea) -> string {
|
||||
return {"cmpa", _suffix<Size>(), " ", _effectiveAddress<Size>(ea), ",", _addressRegister(ar)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleCMPI(EffectiveAddress ea) -> string {
|
||||
return {"cmpi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleCMPM(EffectiveAddress ax, EffectiveAddress ay) -> string {
|
||||
return {"cmpm", _suffix<Size>(), " ", _effectiveAddress<Size>(ay), ",", _effectiveAddress<Size>(ax)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleDBCC(uint4 condition, DataRegister dr) -> string {
|
||||
|
@ -172,6 +197,10 @@ auto M68K::disassembleEORI_TO_SR() -> string {
|
|||
return {"eori ", _immediate<Word>(), ",sr"};
|
||||
}
|
||||
|
||||
auto M68K::disassembleJSR(EffectiveAddress target) -> string {
|
||||
return {"jsr ", _effectiveAddress<Long>(target)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleLEA(AddressRegister ar, EffectiveAddress ea) -> string {
|
||||
return {"lea ", _address<Long>(ea), ",", _addressRegister(ar)};
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ auto M68K::trap() -> void {
|
|||
auto M68K::instruction() -> void {
|
||||
instructionsExecuted++;
|
||||
|
||||
// if(instructionsExecuted >= 851570) trap();
|
||||
//if(instructionsExecuted >= 2000010) trap();
|
||||
|
||||
// if(instructionsExecuted >= 851530) {
|
||||
// print(disassembleRegisters(), "\n");
|
||||
// print(disassemble(r.pc), "\n");
|
||||
// print("\n");
|
||||
// }
|
||||
//if(instructionsExecuted >= 2000000) {
|
||||
// print(disassembleRegisters(), "\n");
|
||||
// print(disassemble(r.pc), "\n");
|
||||
// print("\n");
|
||||
//}
|
||||
|
||||
opcode = readPC();
|
||||
return instructionTable[opcode]();
|
||||
|
@ -53,6 +53,47 @@ M68K::M68K() {
|
|||
if(direction == 0 && mode == 1) unbind(opcode | 0 << 6);
|
||||
}
|
||||
|
||||
//ADDA
|
||||
for(uint3 areg : range(8))
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1101 ---+ 11-- ----") | areg << 9 | mode << 3 | reg << 0;
|
||||
if(mode == 7 && reg >= 5) continue;
|
||||
|
||||
AddressRegister ar{areg};
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode | 0 << 8, ADDA<Word>, ar, ea);
|
||||
bind(opcode | 1 << 8, ADDA<Long>, ar, ea);
|
||||
}
|
||||
|
||||
//ADDI
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0000 0110 ++-- ----") | mode << 3 | reg << 0;
|
||||
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode | 0 << 6, ADDI<Byte>, modify);
|
||||
bind(opcode | 1 << 6, ADDI<Word>, modify);
|
||||
bind(opcode | 2 << 6, ADDI<Long>, modify);
|
||||
}
|
||||
|
||||
//ADDQ
|
||||
for(uint3 data : range(8))
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0101 ---0 ++-- ----") | data << 9 | mode << 3 | reg << 0;
|
||||
if(mode == 7 && reg >= 2) continue;
|
||||
|
||||
uint4 immediate = data ? (uint4)data : (uint4)8;
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode | 0 << 6, ADDQ<Byte>, immediate, modify);
|
||||
bind(opcode | 1 << 6, ADDQ<Word>, immediate, modify);
|
||||
bind(opcode | 2 << 6, ADDQ<Long>, immediate, modify);
|
||||
|
||||
if(mode == 1) unbind(opcode | 0 << 6);
|
||||
}
|
||||
|
||||
//ANDI
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
|
@ -205,6 +246,42 @@ M68K::M68K() {
|
|||
if(mode == 1) unbind(opcode | 0 << 6);
|
||||
}
|
||||
|
||||
//CMPA
|
||||
for(uint3 areg : range(8))
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1011 ---+ 11-- ----") | areg << 9 | mode << 3 | reg << 0;
|
||||
|
||||
AddressRegister ar{areg};
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode | 0 << 8, CMPA<Word>, ar, ea);
|
||||
bind(opcode | 1 << 8, CMPA<Long>, ar, ea);
|
||||
}
|
||||
|
||||
//CMPI
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0000 1100 ++-- ----") | mode << 3 | reg << 0;
|
||||
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode | 0 << 6, CMPI<Byte>, ea);
|
||||
bind(opcode | 1 << 6, CMPI<Word>, ea);
|
||||
bind(opcode | 2 << 6, CMPI<Long>, ea);
|
||||
}
|
||||
|
||||
//CMPM
|
||||
for(uint3 xreg : range(8))
|
||||
for(uint3 yreg : range(8)) {
|
||||
auto opcode = pattern("1011 ---1 ++00 1---") | xreg << 9 | yreg << 0;
|
||||
|
||||
EffectiveAddress ax{AddressRegisterIndirectWithPostIncrement, xreg};
|
||||
EffectiveAddress ay{AddressRegisterIndirectWithPostIncrement, yreg};
|
||||
bind(opcode | 0 << 6, CMPM<Byte>, ax, ay);
|
||||
bind(opcode | 1 << 6, CMPM<Word>, ax, ay);
|
||||
bind(opcode | 2 << 6, CMPM<Long>, ax, ay);
|
||||
}
|
||||
|
||||
//DBCC
|
||||
for(uint4 condition : range(16))
|
||||
for(uint3 dreg : range( 8)) {
|
||||
|
@ -226,6 +303,16 @@ M68K::M68K() {
|
|||
bind(opcode, EORI_TO_SR);
|
||||
}
|
||||
|
||||
//JSR
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0100 1110 10-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || mode == 3 || mode == 4 || (mode == 7 && reg >= 4)) continue;
|
||||
|
||||
EffectiveAddress target{mode, reg};
|
||||
bind(opcode, JSR, target);
|
||||
}
|
||||
|
||||
//LEA
|
||||
for(uint3 areg : range(8))
|
||||
for(uint3 mode : range(8))
|
||||
|
|
|
@ -58,26 +58,50 @@ template<uint Size> auto M68K::negative(uint32 result) -> bool {
|
|||
|
||||
//
|
||||
|
||||
template<uint Size> auto M68K::instructionADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> void {
|
||||
uint64 source, target, result;
|
||||
|
||||
if(direction == 0) {
|
||||
source = read<Size>(ea);
|
||||
target = read<Size>(dr);
|
||||
result = source + target;
|
||||
write<Size>(dr, result);
|
||||
} else {
|
||||
source = read<Size>(dr);
|
||||
target = read<Size>(ea);
|
||||
result = source + target;
|
||||
write<Size>(ea, result);
|
||||
}
|
||||
template<uint Size> auto M68K::ADD(uint32 source, uint32 target) -> uint32 {
|
||||
uint64 result = (uint64)source + (uint64)target;
|
||||
|
||||
r.c = sign<Size>(result >> 1) < 0;
|
||||
r.v = sign<Size>(~(target ^ source) & (target ^ result)) < 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
r.x = r.c;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> void {
|
||||
if(direction == 0) {
|
||||
auto source = read<Size>(ea);
|
||||
auto target = read<Size>(dr);
|
||||
auto result = ADD<Size>(source, target);
|
||||
write<Size>(dr, result);
|
||||
} else {
|
||||
auto source = read<Size>(dr);
|
||||
auto target = read<Size>(ea);
|
||||
auto result = ADD<Size>(source, target);
|
||||
write<Size>(ea, result);
|
||||
}
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionADDI(EffectiveAddress modify) -> void {
|
||||
auto source = readPC<Size>();
|
||||
auto target = read<Size>(modify);
|
||||
auto result = ADD<Size>(source, target);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionADDA(AddressRegister ar, EffectiveAddress ea) -> void {
|
||||
auto source = read<Size>(ea);
|
||||
auto target = read<Size>(ar);
|
||||
write<Long>(ar, source + target);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionADDQ(uint4 immediate, EffectiveAddress modify) -> void {
|
||||
auto source = read<Size>(modify);
|
||||
auto target = immediate;
|
||||
auto result = ADD<Size>(source, target);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionANDI(EffectiveAddress ea) -> void {
|
||||
|
@ -211,15 +235,39 @@ template<uint Size> auto M68K::instructionCLR(EffectiveAddress ea) -> void {
|
|||
r.n = 0;
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionCMP(DataRegister dr, EffectiveAddress ea) -> void {
|
||||
uint64 source = read<Size>(ea);
|
||||
uint64 target = read<Size>(dr);
|
||||
uint64 result = target - source;
|
||||
template<uint Size> auto M68K::CMP(uint32 source, uint32 target) -> uint32 {
|
||||
uint64 result = (uint64)target - (uint64)source;
|
||||
|
||||
r.c = sign<Size>(result >> 1) < 0;
|
||||
r.v = sign<Size>((target ^ source) & (target ^ result)) < 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionCMP(DataRegister dr, EffectiveAddress ea) -> void {
|
||||
auto source = read<Size>(ea);
|
||||
auto target = read<Size>(dr);
|
||||
CMP<Size>(source, target);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionCMPA(AddressRegister ar, EffectiveAddress ea) -> void {
|
||||
auto source = read<Size>(ea);
|
||||
auto target = read<Size>(ar);
|
||||
CMP<Size>(source, target);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionCMPI(EffectiveAddress ea) -> void {
|
||||
auto source = readPC<Size>();
|
||||
auto target = read<Size>(ea);
|
||||
CMP<Size>(source, target);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionCMPM(EffectiveAddress ax, EffectiveAddress ay) -> void {
|
||||
auto source = read<Size>(ay);
|
||||
auto target = read<Size>(ax);
|
||||
CMP<Size>(source, target);
|
||||
}
|
||||
|
||||
auto M68K::instructionDBCC(uint4 condition, DataRegister dr) -> void {
|
||||
|
@ -243,6 +291,11 @@ auto M68K::instructionEORI_TO_SR() -> void {
|
|||
writeSR(readSR() ^ data);
|
||||
}
|
||||
|
||||
auto M68K::instructionJSR(EffectiveAddress target) -> void {
|
||||
push<Long>(r.pc);
|
||||
r.pc = fetch<Long>(target);
|
||||
}
|
||||
|
||||
auto M68K::instructionLEA(AddressRegister ar, EffectiveAddress ea) -> void {
|
||||
write<Long>(ar, fetch<Long>(ea));
|
||||
}
|
||||
|
|
|
@ -97,7 +97,11 @@ struct M68K {
|
|||
template<uint Size> auto zero(uint32 result) -> bool;
|
||||
template<uint Size> auto negative(uint32 result) -> bool;
|
||||
|
||||
template<uint Size> auto ADD(uint32 source, uint32 target) -> uint32;
|
||||
template<uint Size> auto instructionADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionADDA(AddressRegister ar, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionADDI(EffectiveAddress modify) -> void;
|
||||
template<uint Size> auto instructionADDQ(uint4 immediate, EffectiveAddress modify) -> void;
|
||||
template<uint Size> auto instructionANDI(EffectiveAddress ea) -> void;
|
||||
auto instructionANDI_TO_CCR() -> void;
|
||||
auto instructionANDI_TO_SR() -> void;
|
||||
|
@ -113,10 +117,15 @@ struct M68K {
|
|||
template<uint Size> auto instructionBTST(DataRegister dr, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionBTST(EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionCLR(EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto CMP(uint32 source, uint32 target) -> uint32;
|
||||
template<uint Size> auto instructionCMP(DataRegister dr, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionCMPA(AddressRegister ar, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionCMPI(EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionCMPM(EffectiveAddress ax, EffectiveAddress ay) -> void;
|
||||
auto instructionDBCC(uint4 condition, DataRegister dr) -> void;
|
||||
auto instructionEORI_TO_CCR() -> void;
|
||||
auto instructionEORI_TO_SR() -> void;
|
||||
auto instructionJSR(EffectiveAddress target) -> void;
|
||||
auto instructionLEA(AddressRegister ar, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto LSL(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionLSL(uint4 immediate, DataRegister dr) -> void;
|
||||
|
@ -185,6 +194,9 @@ struct M68K {
|
|||
private:
|
||||
//disassembler.cpp
|
||||
template<uint Size> auto disassembleADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleADDA(AddressRegister ar, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleADDI(EffectiveAddress modify) -> string;
|
||||
template<uint Size> auto disassembleADDQ(uint4 immediate, EffectiveAddress modify) -> string;
|
||||
template<uint Size> auto disassembleANDI(EffectiveAddress ea) -> string;
|
||||
auto disassembleANDI_TO_CCR() -> string;
|
||||
auto disassembleANDI_TO_SR() -> string;
|
||||
|
@ -199,9 +211,13 @@ private:
|
|||
template<uint Size> auto disassembleBTST(EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleCLR(EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleCMP(DataRegister dr, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleCMPA(AddressRegister ar, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleCMPI(EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleCMPM(EffectiveAddress ax, EffectiveAddress ay) -> string;
|
||||
auto disassembleDBCC(uint4 condition, DataRegister dr) -> string;
|
||||
auto disassembleEORI_TO_CCR() -> string;
|
||||
auto disassembleEORI_TO_SR() -> string;
|
||||
auto disassembleJSR(EffectiveAddress target) -> string;
|
||||
auto disassembleLEA(AddressRegister ar, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleLSL(uint4 immediate, DataRegister dr) -> string;
|
||||
template<uint Size> auto disassembleLSL(DataRegister sr, DataRegister dr) -> string;
|
||||
|
|
Loading…
Reference in New Issue