mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-01-18 05:08:55 +01:00
Update to v100r12 release.
byuu says: All of the above fixes, plus I added all 24 variations on the shift opcodes, plus SUBQ, plus fixes to the BCC instruction. I can now run 851,767 instructions into Sonic the Hedgehog before hitting an unimplemented instruction (SUB). The 68K core is probably only ~35% complete, and yet it's already within 4KiB of being the largest CPU core, code size wise, in all of higan. Fuck this chip.
This commit is contained in:
parent
7ccfbe0206
commit
f230d144b5
@ -11,7 +11,7 @@ using namespace nall;
|
||||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "100.11";
|
||||
static const string Version = "100.12";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
@ -28,6 +28,8 @@ auto CPU::step(uint clocks) -> void {
|
||||
|
||||
auto CPU::power() -> void {
|
||||
M68K::power();
|
||||
|
||||
for(auto& byte : ram) byte = 0x00;
|
||||
}
|
||||
|
||||
auto CPU::reset() -> void {
|
||||
@ -37,11 +39,23 @@ auto CPU::reset() -> void {
|
||||
|
||||
auto CPU::read(bool word, uint24 addr) -> uint16 {
|
||||
if(addr < 0x400000) return cartridge.read(word, addr);
|
||||
return 0x0000;
|
||||
if(addr < 0xe00000) return 0x0000;
|
||||
|
||||
uint16 data = ram[addr & 65535];
|
||||
if(word) data = data << 8 | ram[addr + 1 & 65535];
|
||||
return data;
|
||||
}
|
||||
|
||||
auto CPU::write(bool word, uint24 addr, uint16 data) -> void {
|
||||
if(addr < 0x400000) return cartridge.write(word, addr, data);
|
||||
if(addr < 0xe00000) return;
|
||||
|
||||
if(!word) {
|
||||
ram[addr & 65535] = data;
|
||||
} else {
|
||||
ram[addr + 0 & 65535] = data >> 8;
|
||||
ram[addr + 1 & 65535] = data >> 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ struct CPU : Processor::M68K, Thread {
|
||||
|
||||
auto read(bool word, uint24 addr) -> uint16 override;
|
||||
auto write(bool word, uint24 addr, uint16 data) -> void override;
|
||||
|
||||
private:
|
||||
uint8 ram[64 * 1024];
|
||||
};
|
||||
|
||||
extern CPU cpu;
|
||||
|
@ -17,11 +17,11 @@ template<uint Size> auto M68K::_readPC() -> uint32 {
|
||||
return clip<Size>(data);
|
||||
}
|
||||
|
||||
auto M68K::_register(DataRegister dr) -> string {
|
||||
auto M68K::_dataRegister(DataRegister dr) -> string {
|
||||
return {"d", dr.number};
|
||||
}
|
||||
|
||||
auto M68K::_register(AddressRegister ar) -> string {
|
||||
auto M68K::_addressRegister(AddressRegister ar) -> string {
|
||||
return {"a", ar.number};
|
||||
}
|
||||
|
||||
@ -34,27 +34,23 @@ template<uint Size> auto M68K::_address(EffectiveAddress& ea) -> string {
|
||||
return "???";
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::_read(EffectiveAddress& ea) -> string {
|
||||
if(ea.mode == 0) return {_register(DataRegister{ea.reg})};
|
||||
if(ea.mode == 1) return {_register(AddressRegister{ea.reg})};
|
||||
if(ea.mode == 2) return {"(", _register(AddressRegister{ea.reg}), ")"};
|
||||
if(ea.mode == 3) return {"(", _register(AddressRegister{ea.reg}), ")+"};
|
||||
if(ea.mode == 4) return {"-(", _register(AddressRegister{ea.reg}), ")"};
|
||||
template<uint Size> auto M68K::_effectiveAddress(EffectiveAddress& ea) -> string {
|
||||
if(ea.mode == 0) return {_dataRegister(DataRegister{ea.reg})};
|
||||
if(ea.mode == 1) return {_addressRegister(AddressRegister{ea.reg})};
|
||||
if(ea.mode == 2) return {"(", _addressRegister(AddressRegister{ea.reg}), ")"};
|
||||
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 == 8) return {"($", hex(_readPC<Long>(), 6L), ")"};
|
||||
if(ea.mode == 11) return {"#$", hex(_readPC<Size>(), 2 << Size)};
|
||||
return "???";
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::_write(EffectiveAddress& ea) -> string {
|
||||
return _read<Size>(ea);
|
||||
}
|
||||
|
||||
auto M68K::_branch(uint8 displacement) -> string {
|
||||
uint16 word = _readPC();
|
||||
if(displacement) displacement = (int8)displacement, _pc -= 2;
|
||||
else displacement = (int16)displacement;
|
||||
return {"$", hex(_pc + displacement, 6L)};
|
||||
uint16 extension = _readPC();
|
||||
_pc -= 2;
|
||||
int32 offset = displacement ? sign<Byte>(displacement) : sign<Word>(extension);
|
||||
return {"$", hex(_pc + offset, 6L)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::_suffix() -> string {
|
||||
@ -97,14 +93,14 @@ template<uint Size> auto M68K::disassembleADD(DataRegister dr, uint1 direction,
|
||||
string op{"add", _suffix<Size>(), " "};
|
||||
|
||||
if(direction == 0) {
|
||||
return {op, _read<Size>(ea), ",", _register(dr)};
|
||||
return {op, _effectiveAddress<Size>(ea), ",", _dataRegister(dr)};
|
||||
} else {
|
||||
return {op, "", _register(dr), ",", _read<Size>(ea)};
|
||||
return {op, "", _dataRegister(dr), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleANDI(EffectiveAddress ea) -> string {
|
||||
return {"andi", _suffix<Size>(), " ", _immediate<Size>(), ",", _read<Size>(ea)};
|
||||
return {"andi", _suffix<Size>(), " ", _immediate<Size>(), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleANDI_TO_CCR() -> string {
|
||||
@ -115,6 +111,30 @@ auto M68K::disassembleANDI_TO_SR() -> string {
|
||||
return {"andi ", _immediate<Word>(), ",sr"};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleASL(uint4 shift, DataRegister modify) -> string {
|
||||
return {"asl", _suffix<Size>(), " #", shift, ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleASL(DataRegister shift, DataRegister modify) -> string {
|
||||
return {"asl", _suffix<Size>(), " ", _dataRegister(shift), ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleASL(EffectiveAddress modify) -> string {
|
||||
return {"asl", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleASR(uint4 shift, DataRegister modify) -> string {
|
||||
return {"asr", _suffix<Size>(), " #", shift, ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleASR(DataRegister shift, DataRegister modify) -> string {
|
||||
return {"asr", _suffix<Size>(), " ", _dataRegister(shift), ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleASR(EffectiveAddress modify) -> string {
|
||||
return {"asr", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleBCC(uint4 condition, uint8 displacement) -> string {
|
||||
auto cc = _condition(condition);
|
||||
if(condition == 0) cc = "ra";
|
||||
@ -123,25 +143,25 @@ auto M68K::disassembleBCC(uint4 condition, uint8 displacement) -> string {
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleBTST(DataRegister dr, EffectiveAddress ea) -> string {
|
||||
return {"btst ", _register(dr), ",", _read<Size>(ea)};
|
||||
return {"btst ", _dataRegister(dr), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleBTST(EffectiveAddress ea) -> string {
|
||||
return {"btst ", _immediate<Byte>(), ",", _read<Size>(ea)};
|
||||
return {"btst ", _immediate<Byte>(), ",", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleCLR(EffectiveAddress ea) -> string {
|
||||
return {"clr", _suffix<Size>(), " ", _read<Size>(ea)};
|
||||
return {"clr", _suffix<Size>(), " ", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleCMP(DataRegister dr, EffectiveAddress ea) -> string {
|
||||
return {"cmp", _suffix<Size>(), " ", _read<Word>(ea), ",", _register(dr)};
|
||||
return {"cmp", _suffix<Size>(), " ", _effectiveAddress<Word>(ea), ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleDBCC(uint4 condition, DataRegister dr) -> string {
|
||||
auto base = _pc;
|
||||
auto displacement = (int16)_readPC();
|
||||
return {"db", _condition(condition), " ", _register(dr), ",$", hex(base + displacement, 6L)};
|
||||
return {"db", _condition(condition), " ", _dataRegister(dr), ",$", hex(base + displacement, 6L)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleEORI_TO_CCR() -> string {
|
||||
@ -153,15 +173,39 @@ auto M68K::disassembleEORI_TO_SR() -> string {
|
||||
}
|
||||
|
||||
auto M68K::disassembleLEA(AddressRegister ar, EffectiveAddress ea) -> string {
|
||||
return {"lea ", _address<Long>(ea), ",", _register(ar)};
|
||||
return {"lea ", _address<Long>(ea), ",", _addressRegister(ar)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleLSL(uint4 immediate, DataRegister dr) -> string {
|
||||
return {"lsl", _suffix<Size>(), " #", immediate, ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleLSL(DataRegister sr, DataRegister dr) -> string {
|
||||
return {"lsl", _suffix<Size>(), " ", _dataRegister(sr), ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleLSL(EffectiveAddress ea) -> string {
|
||||
return {"lsl", _suffix<Word>(), " ", _effectiveAddress<Word>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleLSR(uint4 immediate, DataRegister dr) -> string {
|
||||
return {"lsr", _suffix<Size>(), " #", immediate, ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleLSR(DataRegister shift, DataRegister dr) -> string {
|
||||
return {"lsr", _suffix<Size>(), " ", _dataRegister(shift), ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleLSR(EffectiveAddress ea) -> string {
|
||||
return {"lsr", _suffix<Word>(), " ", _effectiveAddress<Word>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleMOVE(EffectiveAddress to, EffectiveAddress from) -> string {
|
||||
return {"move", _suffix<Size>(), " ", _read<Size>(from), ",", _write<Size>(to)};
|
||||
return {"move", _suffix<Size>(), " ", _effectiveAddress<Size>(from), ",", _effectiveAddress<Size>(to)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleMOVEA(AddressRegister ar, EffectiveAddress ea) -> string {
|
||||
return {"movea ", _read<Size>(ea), ",", _register(ar)};
|
||||
return {"movea ", _effectiveAddress<Size>(ea), ",", _addressRegister(ar)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleMOVEM(uint1 direction, EffectiveAddress ea) -> string {
|
||||
@ -169,40 +213,40 @@ template<uint Size> auto M68K::disassembleMOVEM(uint1 direction, EffectiveAddres
|
||||
|
||||
uint16 list = _readPC();
|
||||
string regs;
|
||||
for(uint n : range(8)) if(list.bit(0 + n)) regs.append(_register(DataRegister{n}), ",");
|
||||
for(uint n : range(8)) if(list.bit(0 + n)) regs.append(_dataRegister(DataRegister{n}), ",");
|
||||
regs.trimRight(",");
|
||||
if(regs && list >> 8) regs.append("/");
|
||||
for(uint n : range(8)) if(list.bit(8 + n)) regs.append(_register(AddressRegister{n}), ",");
|
||||
for(uint n : range(8)) if(list.bit(8 + n)) regs.append(_addressRegister(AddressRegister{n}), ",");
|
||||
regs.trimRight(",");
|
||||
|
||||
if(direction == 0) {
|
||||
return {op, regs, ",", _read<Size>(ea)};
|
||||
return {op, regs, ",", _effectiveAddress<Size>(ea)};
|
||||
} else {
|
||||
return {op, _read<Size>(ea), ",", regs};
|
||||
return {op, _effectiveAddress<Size>(ea), ",", regs};
|
||||
}
|
||||
}
|
||||
|
||||
auto M68K::disassembleMOVEQ(DataRegister dr, uint8 immediate) -> string {
|
||||
return {"moveq #$", hex(immediate, 2L), ",", _register(dr)};
|
||||
return {"moveq #$", hex(immediate, 2L), ",", _dataRegister(dr)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleMOVE_FROM_SR(EffectiveAddress ea) -> string {
|
||||
return {"move sr,", _read<Word>(ea)};
|
||||
return {"move sr,", _effectiveAddress<Word>(ea)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleMOVE_TO_CCR(EffectiveAddress ea) -> string {
|
||||
return {"move ", _read<Byte>(ea), ",ccr"};
|
||||
return {"move ", _effectiveAddress<Byte>(ea), ",ccr"};
|
||||
}
|
||||
|
||||
auto M68K::disassembleMOVE_TO_SR(EffectiveAddress ea) -> string {
|
||||
return {"move ", _read<Word>(ea), ",sr"};
|
||||
return {"move ", _effectiveAddress<Word>(ea), ",sr"};
|
||||
}
|
||||
|
||||
auto M68K::disassembleMOVE_USP(uint1 direction, AddressRegister ar) -> string {
|
||||
if(direction == 0) {
|
||||
return {"move ", _register(ar), ",usp"};
|
||||
return {"move ", _addressRegister(ar), ",usp"};
|
||||
} else {
|
||||
return {"move usp,", _register(ar)};
|
||||
return {"move usp,", _addressRegister(ar)};
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,10 +262,62 @@ auto M68K::disassembleORI_TO_SR() -> string {
|
||||
return {"ori ", _immediate<Word>(), ",sr"};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROL(uint4 shift, DataRegister modify) -> string {
|
||||
return {"rol", _suffix<Size>(), " #", shift, ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROL(DataRegister shift, DataRegister modify) -> string {
|
||||
return {"rol", _suffix<Size>(), " ", _dataRegister(shift), ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleROL(EffectiveAddress modify) -> string {
|
||||
return {"rol", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROR(uint4 shift, DataRegister modify) -> string {
|
||||
return {"ror", _suffix<Size>(), " #", shift, ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROR(DataRegister shift, DataRegister modify) -> string {
|
||||
return {"ror", _suffix<Size>(), " ", _dataRegister(shift) ,",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleROR(EffectiveAddress modify) -> string {
|
||||
return {"ror", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROXL(uint4 shift, DataRegister modify) -> string {
|
||||
return {"roxl", _suffix<Size>(), " #", shift, ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROXL(DataRegister shift, DataRegister modify) -> string {
|
||||
return {"roxl", _suffix<Size>(), " ", _dataRegister(shift), ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleROXL(EffectiveAddress modify) -> string {
|
||||
return {"roxl", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROXR(uint4 shift, DataRegister modify) -> string {
|
||||
return {"roxr", _suffix<Size>(), " #", shift, ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleROXR(DataRegister shift, DataRegister modify) -> string {
|
||||
return {"roxr", _suffix<Size>(), " ", _dataRegister(shift), ",", _dataRegister(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleROXR(EffectiveAddress modify) -> string {
|
||||
return {"roxr", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
|
||||
}
|
||||
|
||||
auto M68K::disassembleRTS() -> string {
|
||||
return {"rts "};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleTST(EffectiveAddress ea) -> string {
|
||||
return {"tst", _suffix<Size>(), " ", _read<Size>(ea)};
|
||||
template<uint Size> auto M68K::disassembleSUBQ(uint4 immediate, EffectiveAddress ea) -> string {
|
||||
return {"subq", _suffix<Size>(), " #", immediate, _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::disassembleTST(EffectiveAddress ea) -> string {
|
||||
return {"tst", _suffix<Size>(), " ", _effectiveAddress<Size>(ea)};
|
||||
}
|
||||
|
@ -87,13 +87,13 @@ template<uint Size, bool Update> auto M68K::read(EffectiveAddress& ea) -> uint32
|
||||
|
||||
case AddressRegisterIndirectWithPostIncrement: {
|
||||
auto data = read<Size>(ea.address);
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address += (Size == Long ? 4 : 2));
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address += bytes<Size>());
|
||||
return data;
|
||||
}
|
||||
|
||||
case AddressRegisterIndirectWithPreDecrement: {
|
||||
auto data = read<Size>(ea.address - (Size == Long ? 4 : 2));
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address -= (Size == Long ? 4 : 2));
|
||||
auto data = read<Size>(ea.address - bytes<Size>());
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address -= bytes<Size>());
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -149,13 +149,13 @@ template<uint Size, bool Update> auto M68K::write(EffectiveAddress& ea, uint32 d
|
||||
|
||||
case AddressRegisterIndirectWithPostIncrement: {
|
||||
write<Size>(ea.address, data);
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address += (Size == Long ? 4 : 2));
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address += bytes<Size>());
|
||||
return;
|
||||
}
|
||||
|
||||
case AddressRegisterIndirectWithPreDecrement: {
|
||||
write<Size, Reverse>(ea.address - (Size == Long ? 4 : 2), data);
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address -= (Size == Long ? 4 : 2));
|
||||
write<Size, Reverse>(ea.address - bytes<Size>(), data);
|
||||
if(Update) write(AddressRegister{ea.reg}, ea.address -= bytes<Size>());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,13 @@ auto M68K::trap() -> void {
|
||||
auto M68K::instruction() -> void {
|
||||
instructionsExecuted++;
|
||||
|
||||
if(instructionsExecuted >= 20) trap();
|
||||
// if(instructionsExecuted >= 851570) trap();
|
||||
|
||||
print(disassembleRegisters(), "\n");
|
||||
print(disassemble(r.pc), "\n");
|
||||
print("\n");
|
||||
// if(instructionsExecuted >= 851530) {
|
||||
// print(disassembleRegisters(), "\n");
|
||||
// print(disassemble(r.pc), "\n");
|
||||
// print("\n");
|
||||
// }
|
||||
|
||||
opcode = readPC();
|
||||
return instructionTable[opcode]();
|
||||
@ -75,6 +77,74 @@ M68K::M68K() {
|
||||
bind(opcode, ANDI_TO_SR);
|
||||
}
|
||||
|
||||
//ASL (immediate)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++00 0---") | count << 9 | dreg << 0;
|
||||
|
||||
auto shift = count ? (uint4)count : (uint4)8;
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ASL<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ASL<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ASL<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ASL (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++10 0---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{sreg};
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ASL<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ASL<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ASL<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ASL (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0001 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode, ASL, modify);
|
||||
}
|
||||
|
||||
//ASR (immediate)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++00 0---") | count << 9 | dreg << 0;
|
||||
|
||||
auto shift = count ? (uint4)count : (uint4)8;
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ASR<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ASR<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ASR<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ASR (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++10 0---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{sreg};
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ASR<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ASR<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ASR<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ASR (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0000 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode, ASR, modify);
|
||||
}
|
||||
|
||||
//BCC
|
||||
for(uint4 condition : range( 16))
|
||||
for(uint8 displacement : range(256)) {
|
||||
@ -88,7 +158,7 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0000 ---1 00-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||
if(mode == 1) continue;
|
||||
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
||||
|
||||
DataRegister dr{dreg};
|
||||
EffectiveAddress ea{mode, reg};
|
||||
@ -100,7 +170,7 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0000 1000 00-- ----") | mode << 3 | reg << 0;
|
||||
if(mode == 1 || (mode == 7 && reg == 2)) continue;
|
||||
if(mode == 1 || (mode == 7 && (reg == 2 || reg >= 5))) continue;
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
if(mode == 0) bind(opcode, BTST<Long>, ea);
|
||||
@ -124,6 +194,7 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1011 ---0 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
||||
if(mode == 7 && reg >= 5) continue;
|
||||
|
||||
DataRegister dr{dreg};
|
||||
EffectiveAddress ea{mode, reg};
|
||||
@ -160,13 +231,81 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0100 ---1 11-- ----") | areg << 9 | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || mode == 3 || mode == 4 || (mode == 7 && reg == 4)) continue;
|
||||
if(mode <= 1 || mode == 3 || mode == 4 || (mode == 7 && reg >= 4)) continue;
|
||||
|
||||
AddressRegister ar{areg};
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode, LEA, ar, ea);
|
||||
}
|
||||
|
||||
//LSL (immediate)
|
||||
for(uint3 data : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++00 1---") | data << 9 | dreg << 0;
|
||||
|
||||
auto immediate = data ? (uint4)data : (uint4)8;
|
||||
DataRegister dr{dreg};
|
||||
bind(opcode | 0 << 6, LSL<Byte>, immediate, dr);
|
||||
bind(opcode | 1 << 6, LSL<Word>, immediate, dr);
|
||||
bind(opcode | 2 << 6, LSL<Long>, immediate, dr);
|
||||
}
|
||||
|
||||
//LSL (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++10 1---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister sr{sreg};
|
||||
DataRegister dr{dreg};
|
||||
bind(opcode | 0 << 6, LSL<Byte>, sr, dr);
|
||||
bind(opcode | 1 << 6, LSL<Word>, sr, dr);
|
||||
bind(opcode | 2 << 6, LSL<Long>, sr, dr);
|
||||
}
|
||||
|
||||
//LSL (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0011 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode, LSL, ea);
|
||||
}
|
||||
|
||||
//LSR (immediate)
|
||||
for(uint3 data : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++00 1---") | data << 9 | dreg << 0;
|
||||
|
||||
auto immediate = data ? (uint4)data : (uint4)8;
|
||||
DataRegister dr{dreg};
|
||||
bind(opcode | 0 << 6, LSR<Byte>, immediate, dr);
|
||||
bind(opcode | 1 << 6, LSR<Word>, immediate, dr);
|
||||
bind(opcode | 2 << 6, LSR<Long>, immediate, dr);
|
||||
}
|
||||
|
||||
//LSR (register)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++10 1---") | count << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{count};
|
||||
DataRegister dr{dreg};
|
||||
bind(opcode | 0 << 6, LSR<Byte>, shift, dr);
|
||||
bind(opcode | 1 << 6, LSR<Word>, shift, dr);
|
||||
bind(opcode | 2 << 6, LSR<Long>, shift, dr);
|
||||
}
|
||||
|
||||
//LSR (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0010 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode, LSR, ea);
|
||||
}
|
||||
|
||||
//MOVE
|
||||
for(uint3 toReg : range(8))
|
||||
for(uint3 toMode : range(8))
|
||||
@ -174,6 +313,7 @@ M68K::M68K() {
|
||||
for(uint3 fromReg : range(8)) {
|
||||
auto opcode = pattern("00++ ---- ---- ----") | toReg << 9 | toMode << 6 | fromMode << 3 | fromReg << 0;
|
||||
if(toMode == 1 || (toMode == 7 && toReg >= 2)) continue;
|
||||
if(fromMode == 7 && fromReg >= 5) continue;
|
||||
|
||||
EffectiveAddress to{toMode, toReg};
|
||||
EffectiveAddress from{fromMode, fromReg};
|
||||
@ -189,6 +329,7 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("00++ ---0 01-- ----") | areg << 9 | mode << 3 | reg << 0;
|
||||
if(mode == 7 && reg >= 5) continue;
|
||||
|
||||
AddressRegister ar{areg};
|
||||
EffectiveAddress ea{mode, reg};
|
||||
@ -202,7 +343,7 @@ M68K::M68K() {
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0100 1-00 1+-- ----") | direction << 10 | mode << 3 | reg << 0;
|
||||
if(direction == 0 && (mode <= 1 || mode == 3 || (mode == 7 && reg >= 2)));
|
||||
if(direction == 1 && (mode <= 1 || mode == 4 || (mode == 7 && reg == 4)));
|
||||
if(direction == 1 && (mode <= 1 || mode == 4 || (mode == 7 && reg >= 4)));
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode | 0 << 6, MOVEM<Word>, direction, ea);
|
||||
@ -232,7 +373,7 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0100 0100 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode == 1) continue;
|
||||
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode, MOVE_TO_CCR, ea);
|
||||
@ -242,7 +383,7 @@ M68K::M68K() {
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0100 0110 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode == 1) continue;
|
||||
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
||||
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode, MOVE_TO_SR, ea);
|
||||
@ -275,12 +416,164 @@ M68K::M68K() {
|
||||
bind(opcode, ORI_TO_SR);
|
||||
}
|
||||
|
||||
//ROL (immediate)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++01 1---") | count << 9 | dreg << 0;
|
||||
|
||||
auto shift = count ? (uint4)count : (uint4)8;
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROL<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROL<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROL<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROL (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++11 1---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{sreg};
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROL<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROL<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROL<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROL (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0111 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode, ROL, modify);
|
||||
}
|
||||
|
||||
//ROR (immediate)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++01 1---") | count << 9 | dreg << 0;
|
||||
|
||||
auto shift = count ? (uint4)count : (uint4)8;
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROR<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROR<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROR<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROR (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++11 1---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{sreg};
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROR<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROR<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROR<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROR (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0110 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode, ROR, modify);
|
||||
}
|
||||
|
||||
//ROXL (immediate)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++01 0---") | count << 9 | dreg << 0;
|
||||
|
||||
auto shift = count ? (uint4)count : (uint4)8;
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROXL<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROXL<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROXL<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROXL (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---1 ++11 0---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{sreg};
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROXL<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROXL<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROXL<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROXL (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0101 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode, ROXL, modify);
|
||||
}
|
||||
|
||||
//ROXR (immediate)
|
||||
for(uint3 count : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++01 0---") | count << 9 | dreg << 0;
|
||||
|
||||
auto shift = count ? (uint4)count : (uint4)8;
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROXR<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROXR<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROXR<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROXR (register)
|
||||
for(uint3 sreg : range(8))
|
||||
for(uint3 dreg : range(8)) {
|
||||
auto opcode = pattern("1110 ---0 ++11 0---") | sreg << 9 | dreg << 0;
|
||||
|
||||
DataRegister shift{sreg};
|
||||
DataRegister modify{dreg};
|
||||
bind(opcode | 0 << 6, ROXR<Byte>, shift, modify);
|
||||
bind(opcode | 1 << 6, ROXR<Word>, shift, modify);
|
||||
bind(opcode | 2 << 6, ROXR<Long>, shift, modify);
|
||||
}
|
||||
|
||||
//ROXR (effective address)
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("1110 0100 11-- ----") | mode << 3 | reg << 0;
|
||||
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
||||
|
||||
EffectiveAddress modify{mode, reg};
|
||||
bind(opcode, ROXR, modify);
|
||||
}
|
||||
|
||||
//RTS
|
||||
{ auto opcode = pattern("0100 1110 0111 0101");
|
||||
|
||||
bind(opcode, RTS);
|
||||
}
|
||||
|
||||
//SUBQ
|
||||
for(uint3 data : range(8))
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
auto opcode = pattern("0101 ---1 ++-- ----") | data << 9 | mode << 3 | reg << 0;
|
||||
if(mode == 7 && reg >= 2) continue;
|
||||
|
||||
auto immediate = data ? (uint4)data : (uint4)8;
|
||||
EffectiveAddress ea{mode, reg};
|
||||
bind(opcode | 0 << 6, SUBQ<Byte>, immediate, ea);
|
||||
bind(opcode | 1 << 6, SUBQ<Word>, immediate, ea);
|
||||
bind(opcode | 2 << 6, SUBQ<Long>, immediate, ea);
|
||||
|
||||
if(mode == 1) unbind(opcode | 0 << 6);
|
||||
}
|
||||
|
||||
//TST
|
||||
for(uint3 mode : range(8))
|
||||
for(uint3 reg : range(8)) {
|
||||
|
@ -22,10 +22,20 @@ auto M68K::testCondition(uint4 condition) -> bool {
|
||||
|
||||
//
|
||||
|
||||
template<> auto M68K::bytes<Byte>() -> uint { return 1; }
|
||||
template<> auto M68K::bytes<Word>() -> uint { return 2; }
|
||||
template<> auto M68K::bytes<Long>() -> uint { return 4; }
|
||||
|
||||
template<> auto M68K::bits<Byte>() -> uint { return 8; }
|
||||
template<> auto M68K::bits<Word>() -> uint { return 16; }
|
||||
template<> auto M68K::bits<Long>() -> uint { return 32; }
|
||||
|
||||
template<uint Size> auto M68K::lsb() -> uint32 { return 1; }
|
||||
|
||||
template<> auto M68K::msb<Byte>() -> uint32 { return 0x80; }
|
||||
template<> auto M68K::msb<Word>() -> uint32 { return 0x8000; }
|
||||
template<> auto M68K::msb<Long>() -> uint32 { return 0x80000000; }
|
||||
|
||||
template<> auto M68K::mask<Byte>() -> uint32 { return 0xff; }
|
||||
template<> auto M68K::mask<Word>() -> uint32 { return 0xffff; }
|
||||
template<> auto M68K::mask<Long>() -> uint32 { return 0xffffffff; }
|
||||
@ -38,14 +48,6 @@ template<> auto M68K::sign<Byte>(uint32 data) -> int32 { return (int8)data; }
|
||||
template<> auto M68K::sign<Word>(uint32 data) -> int32 { return (int16)data; }
|
||||
template<> auto M68K::sign<Long>(uint32 data) -> int32 { return (int32)data; }
|
||||
|
||||
template<uint Size> auto M68K::carry(uint32 result, uint32 source) -> bool {
|
||||
return clip<Size>(result) < clip<Size>(source);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::overflow(uint32 result, uint32 source, uint32 target) -> bool {
|
||||
return sign<Size>((target ^ source) & (target ^ result)) < 0;
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::zero(uint32 result) -> bool {
|
||||
return clip<Size>(result) == 0;
|
||||
}
|
||||
@ -57,9 +59,7 @@ template<uint Size> auto M68K::negative(uint32 result) -> bool {
|
||||
//
|
||||
|
||||
template<uint Size> auto M68K::instructionADD(DataRegister dr, uint1 direction, EffectiveAddress ea) -> void {
|
||||
uint32 source;
|
||||
uint32 target;
|
||||
uint32 result;
|
||||
uint64 source, target, result;
|
||||
|
||||
if(direction == 0) {
|
||||
source = read<Size>(ea);
|
||||
@ -73,10 +73,10 @@ template<uint Size> auto M68K::instructionADD(DataRegister dr, uint1 direction,
|
||||
write<Size>(ea, result);
|
||||
}
|
||||
|
||||
r.c = carry<Size>(result, source);
|
||||
r.v = overflow<Size>(result, source, target);
|
||||
r.z = zero<Size>(result);
|
||||
r.n = negative<Size>(result);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -104,12 +104,85 @@ auto M68K::instructionANDI_TO_SR() -> void {
|
||||
writeSR(readSR() & data);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::ASL(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = false;
|
||||
uint32 overflow = 0;
|
||||
for(auto _ : range(shift)) {
|
||||
carry = result & msb<Size>();
|
||||
uint32 before = result;
|
||||
result <<= 1;
|
||||
overflow |= before ^ result;
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = sign<Size>(overflow) < 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
if(shift) r.x = r.c;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionASL(uint4 shift, DataRegister modify) -> void {
|
||||
auto result = ASL<Size>(read<Size>(modify), shift);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionASL(DataRegister shift, DataRegister modify) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = ASL<Size>(read<Size>(modify), count);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionASL(EffectiveAddress modify) -> void {
|
||||
auto result = ASL<Word>(read<Word, NoUpdate>(modify), 1);
|
||||
write<Word>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::ASR(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = false;
|
||||
uint32 overflow = 0;
|
||||
for(auto _ : range(shift)) {
|
||||
carry = result & lsb<Size>();
|
||||
uint32 before = result;
|
||||
result = sign<Size>(result) >> 1;
|
||||
overflow |= before ^ result;
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = sign<Size>(overflow) < 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
if(shift) r.x = r.c;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionASR(uint4 shift, DataRegister modify) -> void {
|
||||
auto result = ASR<Size>(read<Size>(modify), shift);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionASR(DataRegister shift, DataRegister modify) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = ASR<Size>(read<Size>(modify), count);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionASR(EffectiveAddress modify) -> void {
|
||||
auto result = ASR<Word>(read<Word, NoUpdate>(modify), 1);
|
||||
write<Word>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionBCC(uint4 condition, uint8 displacement) -> void {
|
||||
auto extension = readPC();
|
||||
auto extension = readPC<Word>();
|
||||
if(condition == 1) push<Long>(r.pc);
|
||||
r.pc -= 2;
|
||||
if(condition >= 2 && !testCondition(condition)) return; //0 = BRA; 1 = BSR
|
||||
r.pc += displacement ? sign<Byte>(displacement) : sign<Word>(extension);
|
||||
if(condition >= 2 && !testCondition(condition)) { //0 = BRA; 1 = BSR
|
||||
if(displacement) r.pc -= 2;
|
||||
} else {
|
||||
r.pc -= 2;
|
||||
r.pc += displacement ? sign<Byte>(displacement) : sign<Word>(extension);
|
||||
}
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionBTST(DataRegister dr, EffectiveAddress ea) -> void {
|
||||
@ -139,22 +212,22 @@ template<uint Size> auto M68K::instructionCLR(EffectiveAddress ea) -> void {
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionCMP(DataRegister dr, EffectiveAddress ea) -> void {
|
||||
auto source = read<Size>(ea);
|
||||
auto target = read<Size>(dr);
|
||||
auto result = target - source;
|
||||
uint64 source = read<Size>(ea);
|
||||
uint64 target = read<Size>(dr);
|
||||
uint64 result = target - source;
|
||||
|
||||
r.c = carry<Size>(result, source);
|
||||
r.v = overflow<Size>(result, source, target);
|
||||
r.z = zero<Size>(result);
|
||||
r.n = negative<Size>(result);
|
||||
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;
|
||||
}
|
||||
|
||||
auto M68K::instructionDBCC(uint4 condition, DataRegister dr) -> void {
|
||||
auto displacement = (int16)readPC();
|
||||
auto displacement = readPC<Word>();
|
||||
if(!testCondition(condition)) {
|
||||
uint16 result = read<Word>(dr);
|
||||
write<Word>(dr, result - 1);
|
||||
if(result) r.pc -= 2, r.pc += displacement;
|
||||
if(result) r.pc -= 2, r.pc += sign<Word>(displacement);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,6 +247,70 @@ auto M68K::instructionLEA(AddressRegister ar, EffectiveAddress ea) -> void {
|
||||
write<Long>(ar, fetch<Long>(ea));
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::LSL(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = false;
|
||||
for(auto _ : range(shift)) {
|
||||
carry = result & msb<Size>();
|
||||
result <<= 1;
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
if(shift) r.x = r.c;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionLSL(uint4 immediate, DataRegister dr) -> void {
|
||||
auto result = LSL<Size>(read<Size>(dr), immediate);
|
||||
write<Size>(dr, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionLSL(DataRegister sr, DataRegister dr) -> void {
|
||||
auto shift = read<Long>(sr) & 63;
|
||||
auto result = LSL<Size>(read<Size>(dr), shift);
|
||||
write<Size>(dr, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionLSL(EffectiveAddress ea) -> void {
|
||||
auto result = LSL<Word>(read<Word, NoUpdate>(ea), 1);
|
||||
write<Word>(ea, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::LSR(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = false;
|
||||
for(auto _ : range(shift)) {
|
||||
carry = result & lsb<Size>();
|
||||
result >>= 1;
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
if(shift) r.x = r.c;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionLSR(uint4 immediate, DataRegister dr) -> void {
|
||||
auto result = LSR<Size>(read<Size>(dr), immediate);
|
||||
write<Size>(dr, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionLSR(DataRegister shift, DataRegister dr) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = LSR<Size>(read<Size>(dr), count);
|
||||
write<Size>(dr, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionLSR(EffectiveAddress ea) -> void {
|
||||
auto result = LSR<Word>(read<Word, NoUpdate>(ea), 1);
|
||||
write<Word>(ea, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionMOVE(EffectiveAddress to, EffectiveAddress from) -> void {
|
||||
auto data = read<Size>(from);
|
||||
write<Size>(to, data);
|
||||
@ -191,25 +328,33 @@ template<uint Size> auto M68K::instructionMOVEA(AddressRegister ar, EffectiveAdd
|
||||
|
||||
template<uint Size> auto M68K::instructionMOVEM(uint1 direction, EffectiveAddress ea) -> void {
|
||||
auto list = readPC();
|
||||
auto addr = fetch<Size>(ea);
|
||||
auto addr = fetch<Long>(ea);
|
||||
|
||||
for(uint n : range(8)) {
|
||||
if(!list.bit(0 + n)) continue;
|
||||
write<Size>(DataRegister{n}, read<Size>(addr));
|
||||
addr += Size == Long ? 4 : 2;
|
||||
for(uint n : range(16)) {
|
||||
if(!list.bit(n)) continue;
|
||||
|
||||
//pre-decrement mode traverses registers in reverse order {A7-A0, D7-D0}
|
||||
uint index = ea.mode == AddressRegisterIndirectWithPreDecrement ? 15 - n : n;
|
||||
|
||||
if(ea.mode == AddressRegisterIndirectWithPreDecrement) addr -= bytes<Size>();
|
||||
|
||||
if(direction == 0) {
|
||||
auto data = index < 8 ? read<Size>(DataRegister{index}) : read<Size>(AddressRegister{index});
|
||||
write<Size>(addr, data);
|
||||
} else {
|
||||
auto data = read<Size>(addr);
|
||||
data = sign<Size>(data);
|
||||
index < 8 ? write<Long>(DataRegister{index}, data) : write<Long>(AddressRegister{index}, data);
|
||||
}
|
||||
|
||||
if(ea.mode == AddressRegisterIndirectWithPostIncrement) addr += bytes<Size>();
|
||||
}
|
||||
|
||||
for(uint n : range(8)) {
|
||||
if(!list.bit(8 + n)) continue;
|
||||
write<Size>(AddressRegister{n}, read<Size>(addr));
|
||||
addr += Size == Long ? 4 : 2;
|
||||
}
|
||||
|
||||
flush<Size>(ea, addr);
|
||||
flush<Long>(ea, addr);
|
||||
}
|
||||
|
||||
auto M68K::instructionMOVEQ(DataRegister dr, uint8 immediate) -> void {
|
||||
write<Byte>(dr, immediate);
|
||||
write<Long>(dr, immediate);
|
||||
|
||||
r.c = 0;
|
||||
r.v = 0;
|
||||
@ -259,10 +404,153 @@ auto M68K::instructionORI_TO_SR() -> void {
|
||||
writeSR(readSR() | data);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::ROL(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = false;
|
||||
for(auto _ : range(shift)) {
|
||||
carry = result & msb<Size>();
|
||||
result = result << 1 | carry;
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionROL(uint4 shift, DataRegister modify) -> void {
|
||||
auto result = ROL<Size>(read<Size>(modify), shift);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionROL(DataRegister shift, DataRegister modify) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = ROL<Size>(read<Size>(modify), count);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionROL(EffectiveAddress modify) -> void {
|
||||
auto result = ROL<Word>(read<Word, NoUpdate>(modify), 1);
|
||||
write<Word>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::ROR(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = false;
|
||||
for(auto _ : range(shift)) {
|
||||
carry = result & lsb<Size>();
|
||||
result >>= 1;
|
||||
if(carry) result |= msb<Size>();
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = 0;
|
||||
r.z = clip<Size>(result) == 0;
|
||||
r.n = sign<Size>(result) < 0;
|
||||
|
||||
return clip<Size>(result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionROR(uint4 shift, DataRegister modify) -> void {
|
||||
auto result = ROR<Size>(read<Size>(modify), shift);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionROR(DataRegister shift, DataRegister modify) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = ROR<Size>(read<Size>(modify), count);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionROR(EffectiveAddress modify) -> void {
|
||||
auto result = ROR<Word>(read<Word, NoUpdate>(modify), 1);
|
||||
write<Word>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::ROXL(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = r.x;
|
||||
for(auto _ : range(shift)) {
|
||||
bool extend = carry;
|
||||
carry = result & msb<Size>();
|
||||
result = result << 1 | extend;
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = 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::instructionROXL(uint4 shift, DataRegister modify) -> void {
|
||||
auto result = ROXL<Size>(read<Size>(modify), shift);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionROXL(DataRegister shift, DataRegister modify) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = ROXL<Size>(read<Size>(modify), count);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionROXL(EffectiveAddress modify) -> void {
|
||||
auto result = ROXL<Word>(read<Word, NoUpdate>(modify), 1);
|
||||
write<Word>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::ROXR(uint32 result, uint shift) -> uint32 {
|
||||
bool carry = r.x;
|
||||
for(auto _ : range(shift)) {
|
||||
bool extend = carry;
|
||||
carry = result & lsb<Size>();
|
||||
result >>= 1;
|
||||
if(extend) result |= msb<Size>();
|
||||
}
|
||||
|
||||
r.c = carry;
|
||||
r.v = 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::instructionROXR(uint4 shift, DataRegister modify) -> void {
|
||||
auto result = ROXR<Size>(read<Size>(modify), shift);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionROXR(DataRegister shift, DataRegister modify) -> void {
|
||||
auto count = read<Long>(shift) & 63;
|
||||
auto result = ROXR<Size>(read<Size>(modify), count);
|
||||
write<Size>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionROXR(EffectiveAddress modify) -> void {
|
||||
auto result = ROXR<Word>(read<Word, NoUpdate>(modify), 1);
|
||||
write<Word>(modify, result);
|
||||
}
|
||||
|
||||
auto M68K::instructionRTS() -> void {
|
||||
r.pc = pop<Long>();
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionSUBQ(uint4 immediate, EffectiveAddress ea) -> void {
|
||||
uint64 target = read<Size, NoUpdate>(ea);
|
||||
uint64 source = immediate;
|
||||
uint64 result = target - source;
|
||||
write<Size>(ea, result);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::instructionTST(EffectiveAddress ea) -> void {
|
||||
auto data = read<Size>(ea);
|
||||
|
||||
|
@ -29,7 +29,7 @@ auto M68K::reset() -> void {
|
||||
r.z = 0;
|
||||
r.n = 0;
|
||||
r.x = 0;
|
||||
r.i = 0;
|
||||
r.i = 7;
|
||||
r.s = 1;
|
||||
r.t = 0;
|
||||
}
|
||||
|
@ -86,13 +86,14 @@ struct M68K {
|
||||
//instructions.cpp
|
||||
auto testCondition(uint4 condition) -> bool;
|
||||
|
||||
template<uint Size> auto bytes() -> uint;
|
||||
template<uint Size> auto bits() -> uint;
|
||||
template<uint Size> auto lsb() -> uint32;
|
||||
template<uint Size> auto msb() -> uint32;
|
||||
template<uint Size> auto mask() -> uint32;
|
||||
template<uint Size> auto clip(uint32 data) -> uint32;
|
||||
template<uint Size> auto sign(uint32 data) -> int32;
|
||||
|
||||
template<uint Size> auto carry(uint32 result, uint32 source) -> bool;
|
||||
template<uint Size> auto overflow(uint32 result, uint32 source, uint32 target) -> bool;
|
||||
template<uint Size> auto zero(uint32 result) -> bool;
|
||||
template<uint Size> auto negative(uint32 result) -> bool;
|
||||
|
||||
@ -100,6 +101,14 @@ struct M68K {
|
||||
template<uint Size> auto instructionANDI(EffectiveAddress ea) -> void;
|
||||
auto instructionANDI_TO_CCR() -> void;
|
||||
auto instructionANDI_TO_SR() -> void;
|
||||
template<uint Size> auto ASL(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionASL(uint4 shift, DataRegister modify) -> void;
|
||||
template<uint Size> auto instructionASL(DataRegister shift, DataRegister modify) -> void;
|
||||
auto instructionASL(EffectiveAddress modify) -> void;
|
||||
template<uint Size> auto ASR(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionASR(uint4 shift, DataRegister modify) -> void;
|
||||
template<uint Size> auto instructionASR(DataRegister shift, DataRegister modify) -> void;
|
||||
auto instructionASR(EffectiveAddress modify) -> void;
|
||||
auto instructionBCC(uint4 condition, uint8 displacement) -> void;
|
||||
template<uint Size> auto instructionBTST(DataRegister dr, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionBTST(EffectiveAddress ea) -> void;
|
||||
@ -109,6 +118,14 @@ struct M68K {
|
||||
auto instructionEORI_TO_CCR() -> void;
|
||||
auto instructionEORI_TO_SR() -> 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;
|
||||
template<uint Size> auto instructionLSL(DataRegister sr, DataRegister dr) -> void;
|
||||
auto instructionLSL(EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto LSR(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionLSR(uint4 immediate, DataRegister dr) -> void;
|
||||
template<uint Size> auto instructionLSR(DataRegister shift, DataRegister dr) -> void;
|
||||
auto instructionLSR(EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionMOVE(EffectiveAddress to, EffectiveAddress from) -> void;
|
||||
template<uint Size> auto instructionMOVEA(AddressRegister ar, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionMOVEM(uint1 direction, EffectiveAddress ea) -> void;
|
||||
@ -120,7 +137,24 @@ struct M68K {
|
||||
auto instructionNOP() -> void;
|
||||
auto instructionORI_TO_CCR() -> void;
|
||||
auto instructionORI_TO_SR() -> void;
|
||||
template<uint Size> auto ROL(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionROL(uint4 shift, DataRegister modify) -> void;
|
||||
template<uint Size> auto instructionROL(DataRegister shift, DataRegister modify) -> void;
|
||||
auto instructionROL(EffectiveAddress modify) -> void;
|
||||
template<uint Size> auto ROR(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionROR(uint4 shift, DataRegister modify) -> void;
|
||||
template<uint Size> auto instructionROR(DataRegister shift, DataRegister modify) -> void;
|
||||
auto instructionROR(EffectiveAddress modify) -> void;
|
||||
template<uint Size> auto ROXL(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionROXL(uint4 shift, DataRegister modify) -> void;
|
||||
template<uint Size> auto instructionROXL(DataRegister shift, DataRegister modify) -> void;
|
||||
auto instructionROXL(EffectiveAddress modify) -> void;
|
||||
template<uint Size> auto ROXR(uint32 result, uint shift) -> uint32;
|
||||
template<uint Size> auto instructionROXR(uint4 shift, DataRegister modify) -> void;
|
||||
template<uint Size> auto instructionROXR(DataRegister shift, DataRegister modify) -> void;
|
||||
auto instructionROXR(EffectiveAddress modify) -> void;
|
||||
auto instructionRTS() -> void;
|
||||
template<uint Size> auto instructionSUBQ(uint4 immediate, EffectiveAddress ea) -> void;
|
||||
template<uint Size> auto instructionTST(EffectiveAddress ea) -> void;
|
||||
|
||||
//disassembler.cpp
|
||||
@ -154,6 +188,12 @@ private:
|
||||
template<uint Size> auto disassembleANDI(EffectiveAddress ea) -> string;
|
||||
auto disassembleANDI_TO_CCR() -> string;
|
||||
auto disassembleANDI_TO_SR() -> string;
|
||||
template<uint Size> auto disassembleASL(uint4 shift, DataRegister modify) -> string;
|
||||
template<uint Size> auto disassembleASL(DataRegister shift, DataRegister modify) -> string;
|
||||
auto disassembleASL(EffectiveAddress modify) -> string;
|
||||
template<uint Size> auto disassembleASR(uint4 shift, DataRegister modify) -> string;
|
||||
template<uint Size> auto disassembleASR(DataRegister shift, DataRegister modify) -> string;
|
||||
auto disassembleASR(EffectiveAddress modify) -> string;
|
||||
auto disassembleBCC(uint4 condition, uint8 displacement) -> string;
|
||||
template<uint Size> auto disassembleBTST(DataRegister dr, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleBTST(EffectiveAddress ea) -> string;
|
||||
@ -163,6 +203,12 @@ private:
|
||||
auto disassembleEORI_TO_CCR() -> string;
|
||||
auto disassembleEORI_TO_SR() -> 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;
|
||||
auto disassembleLSL(EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleLSR(uint4 immediate, DataRegister dr) -> string;
|
||||
template<uint Size> auto disassembleLSR(DataRegister shift, DataRegister dr) -> string;
|
||||
auto disassembleLSR(EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleMOVE(EffectiveAddress to, EffectiveAddress from) -> string;
|
||||
template<uint Size> auto disassembleMOVEA(AddressRegister ar, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleMOVEM(uint1 direction, EffectiveAddress ea) -> string;
|
||||
@ -174,17 +220,29 @@ private:
|
||||
auto disassembleNOP() -> string;
|
||||
auto disassembleORI_TO_CCR() -> string;
|
||||
auto disassembleORI_TO_SR() -> string;
|
||||
template<uint Size> auto disassembleROL(uint4 shift, DataRegister modify) -> string;
|
||||
template<uint Size> auto disassembleROL(DataRegister shift, DataRegister modify) -> string;
|
||||
auto disassembleROL(EffectiveAddress modify) -> string;
|
||||
template<uint Size> auto disassembleROR(uint4 shift, DataRegister modify) -> string;
|
||||
template<uint Size> auto disassembleROR(DataRegister shift, DataRegister modify) -> string;
|
||||
auto disassembleROR(EffectiveAddress modify) -> string;
|
||||
template<uint Size> auto disassembleROXL(uint4 shift, DataRegister modify) -> string;
|
||||
template<uint Size> auto disassembleROXL(DataRegister shift, DataRegister modify) -> string;
|
||||
auto disassembleROXL(EffectiveAddress modify) -> string;
|
||||
template<uint Size> auto disassembleROXR(uint4 shift, DataRegister modify) -> string;
|
||||
template<uint Size> auto disassembleROXR(DataRegister shift, DataRegister modify) -> string;
|
||||
auto disassembleROXR(EffectiveAddress modify) -> string;
|
||||
auto disassembleRTS() -> string;
|
||||
template<uint Size> auto disassembleSUBQ(uint4 immediate, EffectiveAddress ea) -> string;
|
||||
template<uint Size> auto disassembleTST(EffectiveAddress ea) -> string;
|
||||
|
||||
template<uint Size> auto _read(uint32 addr) -> uint32;
|
||||
template<uint Size = Word> auto _readPC() -> uint32;
|
||||
auto _register(DataRegister dr) -> string;
|
||||
auto _register(AddressRegister ar) -> string;
|
||||
auto _dataRegister(DataRegister dr) -> string;
|
||||
auto _addressRegister(AddressRegister ar) -> string;
|
||||
template<uint Size> auto _immediate() -> string;
|
||||
template<uint Size> auto _address(EffectiveAddress& ea) -> string;
|
||||
template<uint Size> auto _read(EffectiveAddress& ea) -> string;
|
||||
template<uint Size> auto _write(EffectiveAddress& ea) -> string;
|
||||
template<uint Size> auto _effectiveAddress(EffectiveAddress& ea) -> string;
|
||||
auto _branch(uint8 displacement) -> string;
|
||||
template<uint Size> auto _suffix() -> string;
|
||||
auto _condition(uint4 condition) -> string;
|
||||
|
@ -81,11 +81,11 @@ template<> auto M68K::readPC<Long>() -> uint32 {
|
||||
|
||||
template<uint Size> auto M68K::pop() -> uint32 {
|
||||
auto data = read<Size>((uint32)r.a[7]);
|
||||
r.a[7] += Size == Long ? 4 : 2;
|
||||
r.a[7] += bytes<Size>();
|
||||
return data;
|
||||
}
|
||||
|
||||
template<uint Size> auto M68K::push(uint32 data) -> void {
|
||||
r.a[7] -= Size == Long ? 4 : 2;
|
||||
r.a[7] -= bytes<Size>();
|
||||
return write<Size, Reverse>((uint32)r.a[7], data);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user