mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-12 01:04:09 +02:00
Update to v101r01 release.
byuu says: Changelog: - added eight more 68K instructions - split ADD(direction) into two separate ADD functions I now have 54 out of 88 instructions implemented (thus, 34 remaining.) The map is missing 25,182 entries out of 65,536. Down from 32,680 for v101.00 Aside: this version number feels really silly. r10 and r11 surely will as well ...
This commit is contained in:
@@ -11,7 +11,7 @@ using namespace nall;
|
|||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
static const string Name = "higan";
|
||||||
static const string Version = "101";
|
static const string Version = "101.01";
|
||||||
static const string Author = "byuu";
|
static const string Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
static const string Website = "http://byuu.org/";
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
|
|
||||||
struct Thread {
|
struct Thread {
|
||||||
|
enum : uintmax { Second = (uintmax)1 << (8 * sizeof(uintmax) - 1) };
|
||||||
|
|
||||||
virtual ~Thread() {
|
virtual ~Thread() {
|
||||||
if(_handle) co_delete(_handle);
|
if(_handle) co_delete(_handle);
|
||||||
}
|
}
|
||||||
@@ -15,7 +17,7 @@ struct Thread {
|
|||||||
|
|
||||||
auto setFrequency(double frequency) -> void {
|
auto setFrequency(double frequency) -> void {
|
||||||
_frequency = frequency + 0.5;
|
_frequency = frequency + 0.5;
|
||||||
_scalar = ((uintmax)1 << (8 * sizeof(uintmax) - 1)) / _frequency;
|
_scalar = Second / _frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setScalar(uintmax scalar) -> void {
|
auto setScalar(uintmax scalar) -> void {
|
||||||
@@ -30,6 +32,7 @@ struct Thread {
|
|||||||
if(_handle) co_delete(_handle);
|
if(_handle) co_delete(_handle);
|
||||||
_handle = co_create(64 * 1024 * sizeof(void*), entrypoint);
|
_handle = co_create(64 * 1024 * sizeof(void*), entrypoint);
|
||||||
setFrequency(frequency);
|
setFrequency(frequency);
|
||||||
|
setClock(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto step(uint clocks) -> void {
|
inline auto step(uint clocks) -> void {
|
||||||
|
@@ -90,14 +90,12 @@ auto M68K::disassembleRegisters() -> string {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
template<uint Size> auto M68K::disassembleADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> string {
|
template<uint Size> auto M68K::disassembleADD(EffectiveAddress from, DataRegister with) -> string {
|
||||||
string op{"add", _suffix<Size>(), " "};
|
return {"add", _suffix<Size>(), " ", _effectiveAddress<Size>(from), ",", _dataRegister(with)};
|
||||||
|
|
||||||
if(direction == 0) {
|
|
||||||
return {op, _effectiveAddress<Size>(ea), ",", _dataRegister(dr)};
|
|
||||||
} else {
|
|
||||||
return {op, "", _dataRegister(dr), ",", _effectiveAddress<Size>(ea)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleADD(DataRegister from, EffectiveAddress with) -> string {
|
||||||
|
return {"add", _suffix<Size>(), " ", _dataRegister(from), ",", _effectiveAddress<Size>(with)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::disassembleADDA(AddressRegister ar, EffectiveAddress ea) -> string {
|
template<uint Size> auto M68K::disassembleADDA(AddressRegister ar, EffectiveAddress ea) -> string {
|
||||||
@@ -116,6 +114,14 @@ template<uint Size> auto M68K::disassembleADDX(EffectiveAddress target, Effectiv
|
|||||||
return {"addx", _suffix<Size>(), " ", _effectiveAddress<Size>(target), ",", _effectiveAddress<Size>(source)};
|
return {"addx", _suffix<Size>(), " ", _effectiveAddress<Size>(target), ",", _effectiveAddress<Size>(source)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleAND(EffectiveAddress from, DataRegister with) -> string {
|
||||||
|
return {"and", _suffix<Size>(), " ", _effectiveAddress<Size>(from), ",", _dataRegister(with)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleAND(DataRegister from, EffectiveAddress with) -> string {
|
||||||
|
return {"and", _suffix<Size>(), " ", _dataRegister(from), ",", _effectiveAddress<Size>(with)};
|
||||||
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::disassembleANDI(EffectiveAddress ea) -> string {
|
template<uint Size> auto M68K::disassembleANDI(EffectiveAddress ea) -> string {
|
||||||
return {"andi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(ea)};
|
return {"andi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(ea)};
|
||||||
}
|
}
|
||||||
@@ -193,6 +199,14 @@ auto M68K::disassembleDBCC(uint4 condition, DataRegister dr) -> string {
|
|||||||
return {"db", _condition(condition), " ", _dataRegister(dr), ",$", hex(base + displacement, 6L)};
|
return {"db", _condition(condition), " ", _dataRegister(dr), ",$", hex(base + displacement, 6L)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleEOR(DataRegister from, EffectiveAddress with) -> string {
|
||||||
|
return {"eor", _suffix<Size>(), " ", _dataRegister(from), ",", _effectiveAddress<Size>(with)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleEORI(EffectiveAddress with) -> string {
|
||||||
|
return {"eori", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(with)};
|
||||||
|
}
|
||||||
|
|
||||||
auto M68K::disassembleEORI_TO_CCR() -> string {
|
auto M68K::disassembleEORI_TO_CCR() -> string {
|
||||||
return {"eori ", _immediate<Byte>(), ",ccr"};
|
return {"eori ", _immediate<Byte>(), ",ccr"};
|
||||||
}
|
}
|
||||||
@@ -287,6 +301,18 @@ auto M68K::disassembleNOP() -> string {
|
|||||||
return {"nop "};
|
return {"nop "};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleOR(EffectiveAddress from, DataRegister with) -> string {
|
||||||
|
return {"eor", _suffix<Size>(), " ", _effectiveAddress<Size>(from), ",", _dataRegister(with)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleOR(DataRegister from, EffectiveAddress with) -> string {
|
||||||
|
return {"eor", _suffix<Size>(), " ", _dataRegister(from), ",", _effectiveAddress<Size>(with)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleORI(EffectiveAddress with) -> string {
|
||||||
|
return {"ori", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(with)};
|
||||||
|
}
|
||||||
|
|
||||||
auto M68K::disassembleORI_TO_CCR() -> string {
|
auto M68K::disassembleORI_TO_CCR() -> string {
|
||||||
return {"ori ", _immediate<Byte>(), ",ccr"};
|
return {"ori ", _immediate<Byte>(), ",ccr"};
|
||||||
}
|
}
|
||||||
@@ -355,10 +381,22 @@ template<uint Size> auto M68K::disassembleSUB(DataRegister source, EffectiveAddr
|
|||||||
return {"sub", _suffix<Size>(), " ", _dataRegister(source), ",", _effectiveAddress<Size>(target)};
|
return {"sub", _suffix<Size>(), " ", _dataRegister(source), ",", _effectiveAddress<Size>(target)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleSUBA(AddressRegister to, EffectiveAddress from) -> string {
|
||||||
|
return {"suba", _suffix<Size>(), " ", _addressRegister(to), ",", _effectiveAddress<Size>(from)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleSUBI(EffectiveAddress with) -> string {
|
||||||
|
return {"subi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(with)};
|
||||||
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::disassembleSUBQ(uint4 immediate, EffectiveAddress ea) -> string {
|
template<uint Size> auto M68K::disassembleSUBQ(uint4 immediate, EffectiveAddress ea) -> string {
|
||||||
return {"subq", _suffix<Size>(), " #", immediate, _effectiveAddress<Size>(ea)};
|
return {"subq", _suffix<Size>(), " #", immediate, _effectiveAddress<Size>(ea)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::disassembleSUBX(EffectiveAddress with, EffectiveAddress from) -> string {
|
||||||
|
return {"subx", _suffix<Size>(), " ", _effectiveAddress<Size>(with), ",", _effectiveAddress<Size>(from)};
|
||||||
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::disassembleTST(EffectiveAddress ea) -> string {
|
template<uint Size> auto M68K::disassembleTST(EffectiveAddress ea) -> string {
|
||||||
return {"tst", _suffix<Size>(), " ", _effectiveAddress<Size>(ea)};
|
return {"tst", _suffix<Size>(), " ", _effectiveAddress<Size>(ea)};
|
||||||
}
|
}
|
||||||
|
@@ -38,19 +38,32 @@ M68K::M68K() {
|
|||||||
|
|
||||||
//ADD
|
//ADD
|
||||||
for(uint3 dreg : range(8))
|
for(uint3 dreg : range(8))
|
||||||
for(uint1 direction : range(2))
|
|
||||||
for(uint3 mode : range(8))
|
for(uint3 mode : range(8))
|
||||||
for(uint3 reg : range(8)) {
|
for(uint3 reg : range(8)) {
|
||||||
auto opcode = pattern("1101 ---- ++-- ----") | dreg << 9 | direction << 8 | mode << 3 | reg << 0;
|
auto opcode = pattern("1101 ---0 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
if(direction == 1 && (mode == 0 || mode == 1 || (mode == 7 && reg >= 2))) continue;
|
if(mode == 7 && reg >= 5) continue;
|
||||||
|
|
||||||
DataRegister dr{dreg};
|
EffectiveAddress from{mode, reg};
|
||||||
EffectiveAddress ea{mode, reg};
|
DataRegister with{dreg};
|
||||||
bind(opcode | 0 << 6, ADD<Byte>, dr, direction, ea);
|
bind(opcode | 0 << 6, ADD<Byte>, from, with);
|
||||||
bind(opcode | 1 << 6, ADD<Word>, dr, direction, ea);
|
bind(opcode | 1 << 6, ADD<Word>, from, with);
|
||||||
bind(opcode | 2 << 6, ADD<Long>, dr, direction, ea);
|
bind(opcode | 2 << 6, ADD<Long>, from, with);
|
||||||
|
|
||||||
if(direction == 0 && mode == 1) unbind(opcode | 0 << 6);
|
if(mode == 1) unbind(opcode | 0 << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ADD
|
||||||
|
for(uint3 dreg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1101 ---1 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
DataRegister from{dreg};
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, ADD<Byte>, from, with);
|
||||||
|
bind(opcode | 1 << 6, ADD<Word>, from, with);
|
||||||
|
bind(opcode | 2 << 6, ADD<Long>, from, with);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ADDA
|
//ADDA
|
||||||
@@ -112,6 +125,34 @@ M68K::M68K() {
|
|||||||
bind(opcode | 2 << 6 | 1 << 3, ADDX<Long>, addressTarget, addressSource);
|
bind(opcode | 2 << 6 | 1 << 3, ADDX<Long>, addressTarget, addressSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AND
|
||||||
|
for(uint3 dreg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1100 ---0 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
||||||
|
|
||||||
|
EffectiveAddress from{mode, reg};
|
||||||
|
DataRegister with{dreg};
|
||||||
|
bind(opcode | 0 << 6, AND<Byte>, from, with);
|
||||||
|
bind(opcode | 1 << 6, AND<Word>, from, with);
|
||||||
|
bind(opcode | 2 << 6, AND<Long>, from, with);
|
||||||
|
}
|
||||||
|
|
||||||
|
//AND
|
||||||
|
for(uint3 dreg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1100 ---1 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
DataRegister from{dreg};
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, AND<Byte>, from, with);
|
||||||
|
bind(opcode | 1 << 6, AND<Word>, from, with);
|
||||||
|
bind(opcode | 2 << 6, AND<Long>, from, with);
|
||||||
|
}
|
||||||
|
|
||||||
//ANDI
|
//ANDI
|
||||||
for(uint3 mode : range(8))
|
for(uint3 mode : range(8))
|
||||||
for(uint3 reg : range(8)) {
|
for(uint3 reg : range(8)) {
|
||||||
@@ -309,6 +350,32 @@ M68K::M68K() {
|
|||||||
bind(opcode, DBCC, condition, dr);
|
bind(opcode, DBCC, condition, dr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//EOR
|
||||||
|
for(uint3 dreg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1011 ---1 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
DataRegister from{dreg};
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, EOR<Byte>, from, with);
|
||||||
|
bind(opcode | 1 << 6, EOR<Word>, from, with);
|
||||||
|
bind(opcode | 2 << 6, EOR<Long>, from, with);
|
||||||
|
}
|
||||||
|
|
||||||
|
//EORI
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("0000 1010 ++-- ----") | mode << 3 | reg << 0;
|
||||||
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, EORI<Byte>, with);
|
||||||
|
bind(opcode | 1 << 6, EORI<Word>, with);
|
||||||
|
bind(opcode | 2 << 6, EORI<Long>, with);
|
||||||
|
}
|
||||||
|
|
||||||
//EORI_TO_CCR
|
//EORI_TO_CCR
|
||||||
{ auto opcode = pattern("0000 1010 0011 1100");
|
{ auto opcode = pattern("0000 1010 0011 1100");
|
||||||
|
|
||||||
@@ -509,6 +576,46 @@ M68K::M68K() {
|
|||||||
bind(opcode, NOP);
|
bind(opcode, NOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//OR
|
||||||
|
for(uint3 dreg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1000 ---0 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
||||||
|
|
||||||
|
EffectiveAddress from{mode, reg};
|
||||||
|
DataRegister with{dreg};
|
||||||
|
bind(opcode | 0 << 6, OR<Byte>, from, with);
|
||||||
|
bind(opcode | 1 << 6, OR<Word>, from, with);
|
||||||
|
bind(opcode | 2 << 6, OR<Long>, from, with);
|
||||||
|
}
|
||||||
|
|
||||||
|
//OR
|
||||||
|
for(uint3 dreg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1000 ---1 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
DataRegister from{dreg};
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, OR<Byte>, from, with);
|
||||||
|
bind(opcode | 1 << 6, OR<Word>, from, with);
|
||||||
|
bind(opcode | 2 << 6, OR<Long>, from, with);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ORI
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("0000 0000 ++-- ----") | mode << 3 | reg << 0;
|
||||||
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, ORI<Byte>, with);
|
||||||
|
bind(opcode | 1 << 6, ORI<Word>, with);
|
||||||
|
bind(opcode | 2 << 6, ORI<Long>, with);
|
||||||
|
}
|
||||||
|
|
||||||
//ORI_TO_CCR
|
//ORI_TO_CCR
|
||||||
{ auto opcode = pattern("0000 0000 0011 1100");
|
{ auto opcode = pattern("0000 0000 0011 1100");
|
||||||
|
|
||||||
@@ -693,6 +800,31 @@ M68K::M68K() {
|
|||||||
bind(opcode | 2 << 6, SUB<Long>, source, target);
|
bind(opcode | 2 << 6, SUB<Long>, source, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SUBA
|
||||||
|
for(uint3 areg : range(8))
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("1001 ---+ 11-- ----") | areg << 9 | mode << 3 | reg << 0;
|
||||||
|
if(mode == 7 && reg >= 5) continue;
|
||||||
|
|
||||||
|
AddressRegister to{areg};
|
||||||
|
EffectiveAddress from{mode, reg};
|
||||||
|
bind(opcode | 0 << 8, SUBA<Word>, to, from);
|
||||||
|
bind(opcode | 1 << 8, SUBA<Long>, to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
//SUBI
|
||||||
|
for(uint3 mode : range(8))
|
||||||
|
for(uint3 reg : range(8)) {
|
||||||
|
auto opcode = pattern("0000 0100 ++-- ----") | mode << 3 | reg << 0;
|
||||||
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
||||||
|
|
||||||
|
EffectiveAddress with{mode, reg};
|
||||||
|
bind(opcode | 0 << 6, SUBI<Byte>, with);
|
||||||
|
bind(opcode | 1 << 6, SUBI<Word>, with);
|
||||||
|
bind(opcode | 2 << 6, SUBI<Long>, with);
|
||||||
|
}
|
||||||
|
|
||||||
//SUBQ
|
//SUBQ
|
||||||
for(uint3 data : range(8))
|
for(uint3 data : range(8))
|
||||||
for(uint3 mode : range(8))
|
for(uint3 mode : range(8))
|
||||||
@@ -709,6 +841,24 @@ M68K::M68K() {
|
|||||||
if(mode == 1) unbind(opcode | 0 << 6);
|
if(mode == 1) unbind(opcode | 0 << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SUBX
|
||||||
|
for(uint3 treg : range(8))
|
||||||
|
for(uint3 sreg : range(8)) {
|
||||||
|
auto opcode = pattern("1001 ---1 ++00 ----") | treg << 9 | sreg << 0;
|
||||||
|
|
||||||
|
EffectiveAddress dataTarget{DataRegisterDirect, treg};
|
||||||
|
EffectiveAddress dataSource{DataRegisterDirect, sreg};
|
||||||
|
bind(opcode | 0 << 6 | 0 << 3, SUBX<Byte>, dataTarget, dataSource);
|
||||||
|
bind(opcode | 1 << 6 | 0 << 3, SUBX<Word>, dataTarget, dataSource);
|
||||||
|
bind(opcode | 2 << 6 | 0 << 3, SUBX<Long>, dataTarget, dataSource);
|
||||||
|
|
||||||
|
EffectiveAddress addressTarget{AddressRegisterIndirectWithPreDecrement, treg};
|
||||||
|
EffectiveAddress addressSource{AddressRegisterIndirectWithPreDecrement, sreg};
|
||||||
|
bind(opcode | 0 << 6 | 1 << 3, SUBX<Byte>, addressTarget, addressSource);
|
||||||
|
bind(opcode | 1 << 6 | 1 << 3, SUBX<Word>, addressTarget, addressSource);
|
||||||
|
bind(opcode | 2 << 6 | 1 << 3, SUBX<Long>, addressTarget, addressSource);
|
||||||
|
}
|
||||||
|
|
||||||
//TST
|
//TST
|
||||||
for(uint3 mode : range(8))
|
for(uint3 mode : range(8))
|
||||||
for(uint3 reg : range(8)) {
|
for(uint3 reg : range(8)) {
|
||||||
|
@@ -72,18 +72,24 @@ template<uint Size, bool Extend> auto M68K::ADD(uint32 source, uint32 target) ->
|
|||||||
return clip<Size>(result);
|
return clip<Size>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::instructionADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> void {
|
template<uint Size> auto M68K::instructionADD(EffectiveAddress from, DataRegister with) -> void {
|
||||||
if(direction == 0) {
|
auto source = read<Size>(from);
|
||||||
auto source = read<Size>(ea);
|
auto target = read<Size>(with);
|
||||||
auto target = read<Size>(dr);
|
|
||||||
auto result = ADD<Size>(source, target);
|
auto result = ADD<Size>(source, target);
|
||||||
write<Size>(dr, result);
|
write<Size>(with, 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::instructionADD(DataRegister from, EffectiveAddress with) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = ADD<Size>(source, target);
|
||||||
|
write<Size>(with, 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::instructionADDI(EffectiveAddress modify) -> void {
|
template<uint Size> auto M68K::instructionADDI(EffectiveAddress modify) -> void {
|
||||||
@@ -93,12 +99,6 @@ template<uint Size> auto M68K::instructionADDI(EffectiveAddress modify) -> void
|
|||||||
write<Size>(modify, result);
|
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 {
|
template<uint Size> auto M68K::instructionADDQ(uint4 immediate, EffectiveAddress modify) -> void {
|
||||||
auto source = read<Size>(modify);
|
auto source = read<Size>(modify);
|
||||||
auto target = immediate;
|
auto target = immediate;
|
||||||
@@ -113,10 +113,35 @@ template<uint Size> auto M68K::instructionADDX(EffectiveAddress target_, Effecti
|
|||||||
write<Size>(target, result);
|
write<Size>(target, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::AND(uint32 source, uint32 target) -> uint32 {
|
||||||
|
uint32 result = target & source;
|
||||||
|
|
||||||
|
r.c = 0;
|
||||||
|
r.v = 0;
|
||||||
|
r.z = clip<Size>(result) == 0;
|
||||||
|
r.n = sign<Size>(result) < 0;
|
||||||
|
|
||||||
|
return clip<Size>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionAND(EffectiveAddress from, DataRegister with) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = AND<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionAND(DataRegister from, EffectiveAddress with) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = AND<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::instructionANDI(EffectiveAddress ea) -> void {
|
template<uint Size> auto M68K::instructionANDI(EffectiveAddress ea) -> void {
|
||||||
auto source = readPC<Size>();
|
auto source = readPC<Size>();
|
||||||
auto target = read<Size, NoUpdate>(ea);
|
auto target = read<Size, NoUpdate>(ea);
|
||||||
auto result = target & source;
|
auto result = AND<Size>(source, target);
|
||||||
write<Size>(ea, result);
|
write<Size>(ea, result);
|
||||||
|
|
||||||
r.c = 0;
|
r.c = 0;
|
||||||
@@ -288,6 +313,31 @@ auto M68K::instructionDBCC(uint4 condition, DataRegister dr) -> void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::EOR(uint32 source, uint32 target) -> uint32 {
|
||||||
|
uint32 result = target ^ source;
|
||||||
|
|
||||||
|
r.c = 0;
|
||||||
|
r.v = 0;
|
||||||
|
r.z = clip<Size>(result) == 0;
|
||||||
|
r.n = sign<Size>(result) < 0;
|
||||||
|
|
||||||
|
return clip<Size>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionEOR(DataRegister from, EffectiveAddress with) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = EOR<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionEORI(EffectiveAddress with) -> void {
|
||||||
|
auto source = readPC<Size>();
|
||||||
|
auto target = read<Size, NoUpdate>(with);
|
||||||
|
auto result = EOR<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
auto M68K::instructionEORI_TO_CCR() -> void {
|
auto M68K::instructionEORI_TO_CCR() -> void {
|
||||||
auto data = readPC<Word>();
|
auto data = readPC<Word>();
|
||||||
writeCCR(readCCR() ^ data);
|
writeCCR(readCCR() ^ data);
|
||||||
@@ -454,6 +504,38 @@ auto M68K::instructionMOVE_USP(uint1 direction, AddressRegister ar) -> void {
|
|||||||
auto M68K::instructionNOP() -> void {
|
auto M68K::instructionNOP() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::OR(uint32 source, uint32 target) -> uint32 {
|
||||||
|
auto result = target | source;
|
||||||
|
|
||||||
|
r.c = 0;
|
||||||
|
r.v = 0;
|
||||||
|
r.z = clip<Size>(result) == 0;
|
||||||
|
r.n = sign<Size>(result) < 0;
|
||||||
|
|
||||||
|
return clip<Size>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionOR(EffectiveAddress from, DataRegister with) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = OR<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionOR(DataRegister from, EffectiveAddress with) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = OR<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionORI(EffectiveAddress with) -> void {
|
||||||
|
auto source = readPC<Size>();
|
||||||
|
auto target = read<Size, NoUpdate>(with);
|
||||||
|
auto result = OR<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
auto M68K::instructionORI_TO_CCR() -> void {
|
auto M68K::instructionORI_TO_CCR() -> void {
|
||||||
auto data = readPC<Word>();
|
auto data = readPC<Word>();
|
||||||
writeCCR(readCCR() | data);
|
writeCCR(readCCR() | data);
|
||||||
@@ -628,6 +710,19 @@ template<uint Size> auto M68K::instructionSUB(DataRegister source_, EffectiveAdd
|
|||||||
write<Size>(target_, result);
|
write<Size>(target_, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionSUBA(AddressRegister to, EffectiveAddress from) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(to);
|
||||||
|
write<Long>(to, target - source);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionSUBI(EffectiveAddress with) -> void {
|
||||||
|
auto source = readPC<Size>();
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = SUB<Size>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::instructionSUBQ(uint4 immediate, EffectiveAddress ea) -> void {
|
template<uint Size> auto M68K::instructionSUBQ(uint4 immediate, EffectiveAddress ea) -> void {
|
||||||
auto source = immediate;
|
auto source = immediate;
|
||||||
auto target = read<Size, NoUpdate>(ea);
|
auto target = read<Size, NoUpdate>(ea);
|
||||||
@@ -635,6 +730,13 @@ template<uint Size> auto M68K::instructionSUBQ(uint4 immediate, EffectiveAddress
|
|||||||
write<Size>(ea, result);
|
write<Size>(ea, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint Size> auto M68K::instructionSUBX(EffectiveAddress with, EffectiveAddress from) -> void {
|
||||||
|
auto source = read<Size>(from);
|
||||||
|
auto target = read<Size>(with);
|
||||||
|
auto result = SUB<Size, Extend>(source, target);
|
||||||
|
write<Size>(with, result);
|
||||||
|
}
|
||||||
|
|
||||||
template<uint Size> auto M68K::instructionTST(EffectiveAddress ea) -> void {
|
template<uint Size> auto M68K::instructionTST(EffectiveAddress ea) -> void {
|
||||||
auto data = read<Size>(ea);
|
auto data = read<Size>(ea);
|
||||||
|
|
||||||
|
@@ -98,11 +98,15 @@ struct M68K {
|
|||||||
template<uint Size> auto negative(uint32 result) -> bool;
|
template<uint Size> auto negative(uint32 result) -> bool;
|
||||||
|
|
||||||
template<uint Size, bool Extend = false> auto ADD(uint32 source, uint32 target) -> uint32;
|
template<uint Size, bool Extend = false> auto ADD(uint32 source, uint32 target) -> uint32;
|
||||||
template<uint Size> auto instructionADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> void;
|
template<uint Size> auto instructionADD(EffectiveAddress from, DataRegister with) -> void;
|
||||||
|
template<uint Size> auto instructionADD(DataRegister from, EffectiveAddress with) -> void;
|
||||||
template<uint Size> auto instructionADDA(AddressRegister ar, 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 instructionADDI(EffectiveAddress modify) -> void;
|
||||||
template<uint Size> auto instructionADDQ(uint4 immediate, EffectiveAddress modify) -> void;
|
template<uint Size> auto instructionADDQ(uint4 immediate, EffectiveAddress modify) -> void;
|
||||||
template<uint Size> auto instructionADDX(EffectiveAddress target, EffectiveAddress source) -> void;
|
template<uint Size> auto instructionADDX(EffectiveAddress target, EffectiveAddress source) -> void;
|
||||||
|
template<uint Size> auto AND(uint32 source, uint32 target) -> uint32;
|
||||||
|
template<uint Size> auto instructionAND(EffectiveAddress from, DataRegister with) -> void;
|
||||||
|
template<uint Size> auto instructionAND(DataRegister from, EffectiveAddress with) -> void;
|
||||||
template<uint Size> auto instructionANDI(EffectiveAddress ea) -> void;
|
template<uint Size> auto instructionANDI(EffectiveAddress ea) -> void;
|
||||||
auto instructionANDI_TO_CCR() -> void;
|
auto instructionANDI_TO_CCR() -> void;
|
||||||
auto instructionANDI_TO_SR() -> void;
|
auto instructionANDI_TO_SR() -> void;
|
||||||
@@ -124,6 +128,9 @@ struct M68K {
|
|||||||
template<uint Size> auto instructionCMPI(EffectiveAddress ea) -> void;
|
template<uint Size> auto instructionCMPI(EffectiveAddress ea) -> void;
|
||||||
template<uint Size> auto instructionCMPM(EffectiveAddress ax, EffectiveAddress ay) -> void;
|
template<uint Size> auto instructionCMPM(EffectiveAddress ax, EffectiveAddress ay) -> void;
|
||||||
auto instructionDBCC(uint4 condition, DataRegister dr) -> void;
|
auto instructionDBCC(uint4 condition, DataRegister dr) -> void;
|
||||||
|
template<uint Size> auto EOR(uint32 source, uint32 target) -> uint32;
|
||||||
|
template<uint Size> auto instructionEOR(DataRegister from, EffectiveAddress with) -> void;
|
||||||
|
template<uint Size> auto instructionEORI(EffectiveAddress with) -> void;
|
||||||
auto instructionEORI_TO_CCR() -> void;
|
auto instructionEORI_TO_CCR() -> void;
|
||||||
auto instructionEORI_TO_SR() -> void;
|
auto instructionEORI_TO_SR() -> void;
|
||||||
auto instructionJSR(EffectiveAddress target) -> void;
|
auto instructionJSR(EffectiveAddress target) -> void;
|
||||||
@@ -145,6 +152,10 @@ struct M68K {
|
|||||||
auto instructionMOVE_TO_SR(EffectiveAddress ea) -> void;
|
auto instructionMOVE_TO_SR(EffectiveAddress ea) -> void;
|
||||||
auto instructionMOVE_USP(uint1 direction, AddressRegister ar) -> void;
|
auto instructionMOVE_USP(uint1 direction, AddressRegister ar) -> void;
|
||||||
auto instructionNOP() -> void;
|
auto instructionNOP() -> void;
|
||||||
|
template<uint Size> auto OR(uint32 source, uint32 target) -> uint32;
|
||||||
|
template<uint Size> auto instructionOR(EffectiveAddress from, DataRegister with) -> void;
|
||||||
|
template<uint Size> auto instructionOR(DataRegister from, EffectiveAddress with) -> void;
|
||||||
|
template<uint Size> auto instructionORI(EffectiveAddress with) -> void;
|
||||||
auto instructionORI_TO_CCR() -> void;
|
auto instructionORI_TO_CCR() -> void;
|
||||||
auto instructionORI_TO_SR() -> void;
|
auto instructionORI_TO_SR() -> void;
|
||||||
template<uint Size> auto ROL(uint32 result, uint shift) -> uint32;
|
template<uint Size> auto ROL(uint32 result, uint shift) -> uint32;
|
||||||
@@ -167,7 +178,10 @@ struct M68K {
|
|||||||
template<uint Size, bool Extend = false> auto SUB(uint32 source, uint32 target) -> uint32;
|
template<uint Size, bool Extend = false> auto SUB(uint32 source, uint32 target) -> uint32;
|
||||||
template<uint Size> auto instructionSUB(EffectiveAddress source, DataRegister target) -> void;
|
template<uint Size> auto instructionSUB(EffectiveAddress source, DataRegister target) -> void;
|
||||||
template<uint Size> auto instructionSUB(DataRegister source, EffectiveAddress target) -> void;
|
template<uint Size> auto instructionSUB(DataRegister source, EffectiveAddress target) -> void;
|
||||||
|
template<uint Size> auto instructionSUBA(AddressRegister to, EffectiveAddress from) -> void;
|
||||||
|
template<uint Size> auto instructionSUBI(EffectiveAddress with) -> void;
|
||||||
template<uint Size> auto instructionSUBQ(uint4 immediate, EffectiveAddress ea) -> void;
|
template<uint Size> auto instructionSUBQ(uint4 immediate, EffectiveAddress ea) -> void;
|
||||||
|
template<uint Size> auto instructionSUBX(EffectiveAddress with, EffectiveAddress from) -> void;
|
||||||
template<uint Size> auto instructionTST(EffectiveAddress ea) -> void;
|
template<uint Size> auto instructionTST(EffectiveAddress ea) -> void;
|
||||||
|
|
||||||
//disassembler.cpp
|
//disassembler.cpp
|
||||||
@@ -197,11 +211,14 @@ struct M68K {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
//disassembler.cpp
|
//disassembler.cpp
|
||||||
template<uint Size> auto disassembleADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> string;
|
template<uint Size> auto disassembleADD(EffectiveAddress from, DataRegister with) -> string;
|
||||||
|
template<uint Size> auto disassembleADD(DataRegister from, EffectiveAddress with) -> string;
|
||||||
template<uint Size> auto disassembleADDA(AddressRegister ar, 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 disassembleADDI(EffectiveAddress modify) -> string;
|
||||||
template<uint Size> auto disassembleADDQ(uint4 immediate, EffectiveAddress modify) -> string;
|
template<uint Size> auto disassembleADDQ(uint4 immediate, EffectiveAddress modify) -> string;
|
||||||
template<uint Size> auto disassembleADDX(EffectiveAddress target, EffectiveAddress source) -> string;
|
template<uint Size> auto disassembleADDX(EffectiveAddress target, EffectiveAddress source) -> string;
|
||||||
|
template<uint Size> auto disassembleAND(EffectiveAddress from, DataRegister with) -> string;
|
||||||
|
template<uint Size> auto disassembleAND(DataRegister from, EffectiveAddress with) -> string;
|
||||||
template<uint Size> auto disassembleANDI(EffectiveAddress ea) -> string;
|
template<uint Size> auto disassembleANDI(EffectiveAddress ea) -> string;
|
||||||
auto disassembleANDI_TO_CCR() -> string;
|
auto disassembleANDI_TO_CCR() -> string;
|
||||||
auto disassembleANDI_TO_SR() -> string;
|
auto disassembleANDI_TO_SR() -> string;
|
||||||
@@ -220,6 +237,8 @@ private:
|
|||||||
template<uint Size> auto disassembleCMPI(EffectiveAddress ea) -> string;
|
template<uint Size> auto disassembleCMPI(EffectiveAddress ea) -> string;
|
||||||
template<uint Size> auto disassembleCMPM(EffectiveAddress ax, EffectiveAddress ay) -> string;
|
template<uint Size> auto disassembleCMPM(EffectiveAddress ax, EffectiveAddress ay) -> string;
|
||||||
auto disassembleDBCC(uint4 condition, DataRegister dr) -> string;
|
auto disassembleDBCC(uint4 condition, DataRegister dr) -> string;
|
||||||
|
template<uint Size> auto disassembleEOR(DataRegister from, EffectiveAddress with) -> string;
|
||||||
|
template<uint Size> auto disassembleEORI(EffectiveAddress with) -> string;
|
||||||
auto disassembleEORI_TO_CCR() -> string;
|
auto disassembleEORI_TO_CCR() -> string;
|
||||||
auto disassembleEORI_TO_SR() -> string;
|
auto disassembleEORI_TO_SR() -> string;
|
||||||
auto disassembleJSR(EffectiveAddress target) -> string;
|
auto disassembleJSR(EffectiveAddress target) -> string;
|
||||||
@@ -239,6 +258,9 @@ private:
|
|||||||
auto disassembleMOVE_TO_SR(EffectiveAddress ea) -> string;
|
auto disassembleMOVE_TO_SR(EffectiveAddress ea) -> string;
|
||||||
auto disassembleMOVE_USP(uint1 direction, AddressRegister ar) -> string;
|
auto disassembleMOVE_USP(uint1 direction, AddressRegister ar) -> string;
|
||||||
auto disassembleNOP() -> string;
|
auto disassembleNOP() -> string;
|
||||||
|
template<uint Size> auto disassembleOR(EffectiveAddress from, DataRegister with) -> string;
|
||||||
|
template<uint Size> auto disassembleOR(DataRegister from, EffectiveAddress with) -> string;
|
||||||
|
template<uint Size> auto disassembleORI(EffectiveAddress with) -> string;
|
||||||
auto disassembleORI_TO_CCR() -> string;
|
auto disassembleORI_TO_CCR() -> string;
|
||||||
auto disassembleORI_TO_SR() -> string;
|
auto disassembleORI_TO_SR() -> string;
|
||||||
template<uint Size> auto disassembleROL(uint4 shift, DataRegister modify) -> string;
|
template<uint Size> auto disassembleROL(uint4 shift, DataRegister modify) -> string;
|
||||||
@@ -256,7 +278,10 @@ private:
|
|||||||
auto disassembleRTS() -> string;
|
auto disassembleRTS() -> string;
|
||||||
template<uint Size> auto disassembleSUB(EffectiveAddress source, DataRegister target) -> string;
|
template<uint Size> auto disassembleSUB(EffectiveAddress source, DataRegister target) -> string;
|
||||||
template<uint Size> auto disassembleSUB(DataRegister source, EffectiveAddress target) -> string;
|
template<uint Size> auto disassembleSUB(DataRegister source, EffectiveAddress target) -> string;
|
||||||
|
template<uint Size> auto disassembleSUBA(AddressRegister to, EffectiveAddress from) -> string;
|
||||||
|
template<uint Size> auto disassembleSUBI(EffectiveAddress with) -> string;
|
||||||
template<uint Size> auto disassembleSUBQ(uint4 immediate, EffectiveAddress ea) -> string;
|
template<uint Size> auto disassembleSUBQ(uint4 immediate, EffectiveAddress ea) -> string;
|
||||||
|
template<uint Size> auto disassembleSUBX(EffectiveAddress with, EffectiveAddress from) -> string;
|
||||||
template<uint Size> auto disassembleTST(EffectiveAddress ea) -> string;
|
template<uint Size> auto disassembleTST(EffectiveAddress ea) -> string;
|
||||||
|
|
||||||
template<uint Size> auto _read(uint32 addr) -> uint32;
|
template<uint Size> auto _read(uint32 addr) -> uint32;
|
||||||
|
@@ -6,8 +6,8 @@ auto SMP::step(uint clocks) -> void {
|
|||||||
synchronize(cpu);
|
synchronize(cpu);
|
||||||
#else
|
#else
|
||||||
//forcefully sync S-SMP to S-CPU in case chips are not communicating
|
//forcefully sync S-SMP to S-CPU in case chips are not communicating
|
||||||
//sync if S-SMP is more than 24 samples ahead of S-CPU
|
//sync if S-SMP is more than 1ms ahead of S-CPU
|
||||||
if(clock() - cpu.clock() > frequency() * scalar() / (768 / 24)) synchronize(cpu);
|
if(clock() - cpu.clock() > Thread::Second / 1'000) synchronize(cpu);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user