Update to v100r13 release.

byuu says:

Changelog: M68K improvements, new instructions added.
This commit is contained in:
Tim Allen 2016-07-26 20:46:43 +10:00
parent f230d144b5
commit 306cac2b54
5 changed files with 211 additions and 26 deletions

View File

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

View File

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

View File

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

View File

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

View File

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