mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-23 06:32:32 +01:00
byuu says: Changelog: - I caved on the `samples[] = {0.0}` thing, but I'm very unhappy about it - if it's really invalid C++, then GCC needs to stop accepting it in strict `-std=c++14` mode - Emulator::Interface::Information::resettable is gone - Emulator::Interface::reset() is gone - FC, SFC, MD cores updated to remove soft reset behavior - split GameBoy::Interface into GameBoyInterface, GameBoyColorInterface - split WonderSwan::Interface into WonderSwanInterface, WonderSwanColorInterface - PCE: fixed off-by-one scanline error [hex_usr] - PCE: temporary hack to prevent crashing when VDS is set to < 2 - hiro: Cocoa: removed (u)int(#) constants; converted (u)int(#) types to (u)int_(#)t types - icarus: replaced usage of unique with strip instead (so we don't mess up frameworks on macOS) - libco: added macOS-specific section marker [Ryphecha] So ... the major news this time is the removal of the soft reset behavior. This is a major!! change that results in a 100KiB diff file, and it's very prone to accidental mistakes!! If anyone is up for testing, or even better -- looking over the code changes between v102r01 and v102r02 and looking for any issues, please do so. Ideally we'll want to test every NES mapper type and every SNES coprocessor type by loading said games and power cycling to make sure the games are all cleanly resetting. It's too big of a change for me to cover there not being any issues on my own, but this is truly critical code, so yeah ... please help if you can. We technically lose a bit of hardware documentation here. The soft reset events do all kinds of interesting things in all kinds of different chips -- or at least they do on the SNES. This is obviously not ideal. But in the process of removing these portions of code, I found a few mistakes I had made previously. It simplifies resetting the system state a lot when not trying to have all the power() functions call the reset() functions to share partial functionality. In the future, the goal will be to come up with a way to add back in the soft reset behavior via keyboard binding as with the Master System core. What's going to have to happen is that the key binding will have to send a "reset pulse" to every emulated chip, and those chips are going to have to act independently to power() instead of reusing functionality. We'll get there eventually, but there's many things of vastly greater importance to work on right now, so it'll be a while. The information isn't lost ... we'll just have to pull it out of v102 when we are ready. Note that I left the SNES reset vector simulation code in, even though it's not possible to trigger, for the time being. Also ... the Super Game Boy core is still disconnected. To be honest, it totally slipped my mind when I released v102 that it wasn't connected again yet. This one's going to be pretty tricky to be honest. I'm thinking about making a third GameBoy::Interface class just for SGB, and coming up with some way of bypassing platform-> calls when in this mode.
1267 lines
37 KiB
C++
1267 lines
37 KiB
C++
auto M68K::instruction() -> void {
|
|
opcode = readPC();
|
|
return instructionTable[opcode]();
|
|
}
|
|
|
|
M68K::M68K() {
|
|
#define bind(id, name, ...) { \
|
|
assert(!instructionTable[id]); \
|
|
instructionTable[id] = [=] { return instruction##name(__VA_ARGS__); }; \
|
|
disassembleTable[id] = [=] { return disassemble##name(__VA_ARGS__); }; \
|
|
}
|
|
|
|
#define unbind(id) { \
|
|
instructionTable[id].reset(); \
|
|
disassembleTable[id].reset(); \
|
|
}
|
|
|
|
#define pattern(s) \
|
|
std::integral_constant<uint16_t, bit::test(s)>::value
|
|
|
|
//ABCD
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1100 ---1 0000 ----") | xreg << 9 | yreg << 0;
|
|
|
|
EffectiveAddress dataWith{DataRegisterDirect, xreg};
|
|
EffectiveAddress dataFrom{DataRegisterDirect, yreg};
|
|
bind(opcode | 0 << 3, ABCD, dataWith, dataFrom);
|
|
|
|
EffectiveAddress addressWith{AddressRegisterIndirectWithPreDecrement, xreg};
|
|
EffectiveAddress addressFrom{AddressRegisterIndirectWithPreDecrement, yreg};
|
|
bind(opcode | 1 << 3, ABCD, addressWith, addressFrom);
|
|
}
|
|
|
|
//ADD
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1101 ---0 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 7 && reg >= 5) continue;
|
|
|
|
EffectiveAddress from{mode, reg};
|
|
DataRegister with{dreg};
|
|
bind(opcode | 0 << 6, ADD<Byte>, from, with);
|
|
bind(opcode | 1 << 6, ADD<Word>, from, with);
|
|
bind(opcode | 2 << 6, ADD<Long>, from, with);
|
|
|
|
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
|
|
for(uint3 areg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1101 ---+ 11-- ----") | areg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 7 && reg >= 5) continue;
|
|
|
|
AddressRegister ar{areg};
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode | 0 << 8, ADDA<Word>, ar, ea);
|
|
bind(opcode | 1 << 8, ADDA<Long>, ar, ea);
|
|
}
|
|
|
|
//ADDI
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 0110 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress modify{mode, reg};
|
|
bind(opcode | 0 << 6, ADDI<Byte>, modify);
|
|
bind(opcode | 1 << 6, ADDI<Word>, modify);
|
|
bind(opcode | 2 << 6, ADDI<Long>, modify);
|
|
}
|
|
|
|
//ADDQ
|
|
for(uint3 data : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0101 ---0 ++-- ----") | data << 9 | mode << 3 | reg << 0;
|
|
if(mode == 7 && reg >= 2) continue;
|
|
|
|
uint4 immediate = data ? (uint4)data : (uint4)8;
|
|
if(mode != 1) {
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode | 0 << 6, ADDQ<Byte>, immediate, with);
|
|
bind(opcode | 1 << 6, ADDQ<Word>, immediate, with);
|
|
bind(opcode | 2 << 6, ADDQ<Long>, immediate, with);
|
|
} else {
|
|
AddressRegister with{reg};
|
|
bind(opcode | 1 << 6, ADDQ<Word>, immediate, with);
|
|
bind(opcode | 2 << 6, ADDQ<Long>, immediate, with);
|
|
}
|
|
}
|
|
|
|
//ADDX
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1101 ---1 ++00 ----") | xreg << 9 | yreg << 0;
|
|
|
|
EffectiveAddress dataWith{DataRegisterDirect, xreg};
|
|
EffectiveAddress dataFrom{DataRegisterDirect, yreg};
|
|
bind(opcode | 0 << 6 | 0 << 3, ADDX<Byte>, dataWith, dataFrom);
|
|
bind(opcode | 1 << 6 | 0 << 3, ADDX<Word>, dataWith, dataFrom);
|
|
bind(opcode | 2 << 6 | 0 << 3, ADDX<Long>, dataWith, dataFrom);
|
|
|
|
EffectiveAddress addressWith{AddressRegisterIndirectWithPreDecrement, xreg};
|
|
EffectiveAddress addressFrom{AddressRegisterIndirectWithPreDecrement, yreg};
|
|
bind(opcode | 0 << 6 | 1 << 3, ADDX<Byte>, addressWith, addressFrom);
|
|
bind(opcode | 1 << 6 | 1 << 3, ADDX<Word>, addressWith, addressFrom);
|
|
bind(opcode | 2 << 6 | 1 << 3, ADDX<Long>, addressWith, addressFrom);
|
|
}
|
|
|
|
//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
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 0010 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode | 0 << 6, ANDI<Byte>, with);
|
|
bind(opcode | 1 << 6, ANDI<Word>, with);
|
|
bind(opcode | 2 << 6, ANDI<Long>, with);
|
|
}
|
|
|
|
//ANDI_TO_CCR
|
|
{ auto opcode = pattern("0000 0010 0011 1100");
|
|
|
|
bind(opcode, ANDI_TO_CCR);
|
|
}
|
|
|
|
//ANDI_TO_SR
|
|
{ auto opcode = pattern("0000 0010 0111 1100");
|
|
|
|
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)) {
|
|
auto opcode = pattern("0110 ---- ---- ----") | condition << 8 | displacement << 0;
|
|
|
|
bind(opcode, BCC, condition, displacement);
|
|
}
|
|
|
|
//BCHG (register)
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 ---1 01-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
DataRegister bit{dreg};
|
|
EffectiveAddress with{mode, reg};
|
|
if(mode == 0) bind(opcode, BCHG<Long>, bit, with);
|
|
if(mode != 0) bind(opcode, BCHG<Byte>, bit, with);
|
|
}
|
|
|
|
//BCHG (immediate)
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 1000 01-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
if(mode == 0) bind(opcode, BCHG<Long>, with);
|
|
if(mode != 0) bind(opcode, BCHG<Byte>, with);
|
|
}
|
|
|
|
//BCLR (register)
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 ---1 10-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
DataRegister bit{dreg};
|
|
EffectiveAddress with{mode, reg};
|
|
if(mode == 0) bind(opcode, BCLR<Long>, bit, with);
|
|
if(mode != 0) bind(opcode, BCLR<Byte>, bit, with);
|
|
}
|
|
|
|
//BCLR (immediate)
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 1000 10-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
if(mode == 0) bind(opcode, BCLR<Long>, with);
|
|
if(mode != 0) bind(opcode, BCLR<Byte>, with);
|
|
}
|
|
|
|
//BSET (register)
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 ---1 11-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
DataRegister bit{dreg};
|
|
EffectiveAddress with{mode, reg};
|
|
if(mode == 0) bind(opcode, BSET<Long>, bit, with);
|
|
if(mode != 0) bind(opcode, BSET<Byte>, bit, with);
|
|
}
|
|
|
|
//BSET (immediate)
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 1000 11-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
if(mode == 0) bind(opcode, BSET<Long>, with);
|
|
if(mode != 0) bind(opcode, BSET<Byte>, with);
|
|
}
|
|
|
|
//BTST (register)
|
|
for(uint3 dreg : range(8))
|
|
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 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
DataRegister dr{dreg};
|
|
EffectiveAddress ea{mode, reg};
|
|
if(mode == 0) bind(opcode, BTST<Long>, dr, ea);
|
|
if(mode != 0) bind(opcode, BTST<Byte>, dr, ea);
|
|
}
|
|
|
|
//BTST (immediate)
|
|
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 >= 4)) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
if(mode == 0) bind(opcode, BTST<Long>, ea);
|
|
if(mode != 0) bind(opcode, BTST<Byte>, ea);
|
|
}
|
|
|
|
//CHK
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 ---1 10-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
DataRegister compare{dreg};
|
|
EffectiveAddress maximum{mode, reg};
|
|
bind(opcode, CHK, compare, maximum);
|
|
}
|
|
|
|
//CLR
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0010 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode | 0 << 6, CLR<Byte>, ea);
|
|
bind(opcode | 1 << 6, CLR<Word>, ea);
|
|
bind(opcode | 2 << 6, CLR<Long>, ea);
|
|
}
|
|
|
|
//CMP
|
|
for(uint3 dreg : range(8))
|
|
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};
|
|
bind(opcode | 0 << 6, CMP<Byte>, dr, ea);
|
|
bind(opcode | 1 << 6, CMP<Word>, dr, ea);
|
|
bind(opcode | 2 << 6, CMP<Long>, dr, ea);
|
|
|
|
if(mode == 1) unbind(opcode | 0 << 6);
|
|
}
|
|
|
|
//CMPA
|
|
for(uint3 areg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1011 ---+ 11-- ----") | areg << 9 | mode << 3 | reg << 0;
|
|
|
|
AddressRegister ar{areg};
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode | 0 << 8, CMPA<Word>, ar, ea);
|
|
bind(opcode | 1 << 8, CMPA<Long>, ar, ea);
|
|
}
|
|
|
|
//CMPI
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0000 1100 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode | 0 << 6, CMPI<Byte>, ea);
|
|
bind(opcode | 1 << 6, CMPI<Word>, ea);
|
|
bind(opcode | 2 << 6, CMPI<Long>, ea);
|
|
}
|
|
|
|
//CMPM
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1011 ---1 ++00 1---") | xreg << 9 | yreg << 0;
|
|
|
|
EffectiveAddress ax{AddressRegisterIndirectWithPostIncrement, xreg};
|
|
EffectiveAddress ay{AddressRegisterIndirectWithPostIncrement, yreg};
|
|
bind(opcode | 0 << 6, CMPM<Byte>, ax, ay);
|
|
bind(opcode | 1 << 6, CMPM<Word>, ax, ay);
|
|
bind(opcode | 2 << 6, CMPM<Long>, ax, ay);
|
|
}
|
|
|
|
//DBCC
|
|
for(uint4 condition : range(16))
|
|
for(uint3 dreg : range( 8)) {
|
|
auto opcode = pattern("0101 ---- 1100 1---") | condition << 8 | dreg << 0;
|
|
|
|
DataRegister dr{dreg};
|
|
bind(opcode, DBCC, condition, dr);
|
|
}
|
|
|
|
//DIVS
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1000 ---1 11-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
DataRegister with{dreg};
|
|
EffectiveAddress from{mode, reg};
|
|
bind(opcode, DIVS, with, from);
|
|
}
|
|
|
|
//DIVU
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1000 ---0 11-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
DataRegister with{dreg};
|
|
EffectiveAddress from{mode, reg};
|
|
bind(opcode, DIVU, with, from);
|
|
}
|
|
|
|
//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
|
|
{ auto opcode = pattern("0000 1010 0011 1100");
|
|
|
|
bind(opcode, EORI_TO_CCR);
|
|
}
|
|
|
|
//EORI_TO_SR
|
|
{ auto opcode = pattern("0000 1010 0111 1100");
|
|
|
|
bind(opcode, EORI_TO_SR);
|
|
}
|
|
|
|
//EXG
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1100 ---1 0100 0---") | xreg << 9 | yreg << 0;
|
|
|
|
DataRegister x{xreg};
|
|
DataRegister y{yreg};
|
|
bind(opcode, EXG, x, y);
|
|
}
|
|
|
|
//EXG
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1100 ---1 0100 1---") | xreg << 9 | yreg << 0;
|
|
|
|
AddressRegister x{xreg};
|
|
AddressRegister y{yreg};
|
|
bind(opcode, EXG, x, y);
|
|
}
|
|
|
|
//EXG
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1100 ---1 1000 1---") | xreg << 9 | yreg << 0;
|
|
|
|
DataRegister x{xreg};
|
|
AddressRegister y{yreg};
|
|
bind(opcode, EXG, x, y);
|
|
}
|
|
|
|
//EXT
|
|
for(uint3 dreg : range(8)) {
|
|
auto opcode = pattern("0100 1000 1+00 0---") | dreg << 0;
|
|
|
|
DataRegister with{dreg};
|
|
bind(opcode | 0 << 6, EXT<Word>, with);
|
|
bind(opcode | 1 << 6, EXT<Long>, with);
|
|
}
|
|
|
|
//ILLEGAL
|
|
{ auto opcode = pattern("0100 1010 1111 1100");
|
|
|
|
bind(opcode, ILLEGAL);
|
|
}
|
|
|
|
//JMP
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1110 11-- ----") | mode << 3 | reg << 0;
|
|
if(mode <= 1 || mode == 3 || mode == 4 || (mode == 7 && reg >= 4)) continue;
|
|
|
|
EffectiveAddress target{mode, reg};
|
|
bind(opcode, JMP, target);
|
|
}
|
|
|
|
//JSR
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1110 10-- ----") | mode << 3 | reg << 0;
|
|
if(mode <= 1 || mode == 3 || mode == 4 || (mode == 7 && reg >= 4)) continue;
|
|
|
|
EffectiveAddress target{mode, reg};
|
|
bind(opcode, JSR, target);
|
|
}
|
|
|
|
//LEA
|
|
for(uint3 areg : range(8))
|
|
for(uint3 mode : range(8))
|
|
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;
|
|
|
|
AddressRegister ar{areg};
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode, LEA, ar, ea);
|
|
}
|
|
|
|
//LINK
|
|
for(uint3 areg : range(8)) {
|
|
auto opcode = pattern("0100 1110 0101 0---") | areg << 0;
|
|
|
|
AddressRegister with{areg};
|
|
bind(opcode, LINK, with);
|
|
}
|
|
|
|
//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))
|
|
for(uint3 fromMode : range(8))
|
|
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};
|
|
bind(opcode | 1 << 12, MOVE<Byte>, to, from);
|
|
bind(opcode | 3 << 12, MOVE<Word>, to, from);
|
|
bind(opcode | 2 << 12, MOVE<Long>, to, from);
|
|
|
|
if(fromMode == 1) unbind(opcode | 1 << 12);
|
|
}
|
|
|
|
//MOVEA
|
|
for(uint3 areg : range(8))
|
|
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};
|
|
bind(opcode | 3 << 12, MOVEA<Word>, ar, ea);
|
|
bind(opcode | 2 << 12, MOVEA<Long>, ar, ea);
|
|
}
|
|
|
|
//MOVEM
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1000 1+-- ----") | mode << 3 | reg << 0;
|
|
if(mode <= 1 || mode == 3 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress to{mode, reg};
|
|
bind(opcode | 0 << 6, MOVEM_TO_MEM<Word>, to);
|
|
bind(opcode | 1 << 6, MOVEM_TO_MEM<Long>, to);
|
|
}
|
|
|
|
//MOVEM
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1100 1+-- ----") | mode << 3 | reg << 0;
|
|
if(mode <= 1 || mode == 4 || (mode == 7 && reg >= 4)) continue;
|
|
|
|
EffectiveAddress from{mode, reg};
|
|
bind(opcode | 0 << 6, MOVEM_TO_REG<Word>, from);
|
|
bind(opcode | 1 << 6, MOVEM_TO_REG<Long>, from);
|
|
}
|
|
|
|
//MOVEP
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 areg : range(8)) {
|
|
auto opcode = pattern("0000 ---1 1+00 1---") | dreg << 9 | areg << 0;
|
|
|
|
DataRegister from{dreg};
|
|
EffectiveAddress to{AddressRegisterIndirectWithDisplacement, areg};
|
|
bind(opcode | 0 << 6, MOVEP<Word>, from, to);
|
|
bind(opcode | 1 << 6, MOVEP<Long>, from, to);
|
|
}
|
|
|
|
//MOVEP
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 areg : range(8)) {
|
|
auto opcode = pattern("0000 ---1 0+00 1---") | dreg << 9 | areg << 0;
|
|
|
|
DataRegister to{dreg};
|
|
EffectiveAddress from{AddressRegisterIndirectWithDisplacement, areg};
|
|
bind(opcode | 0 << 6, MOVEP<Word>, from, to);
|
|
bind(opcode | 1 << 6, MOVEP<Long>, from, to);
|
|
}
|
|
|
|
//MOVEQ
|
|
for(uint3 dreg : range( 8))
|
|
for(uint8 immediate : range(256)) {
|
|
auto opcode = pattern("0111 ---0 ---- ----") | dreg << 9 | immediate << 0;
|
|
|
|
DataRegister dr{dreg};
|
|
bind(opcode, MOVEQ, dr, immediate);
|
|
}
|
|
|
|
//MOVE_FROM_SR
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0000 11-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode, MOVE_FROM_SR, ea);
|
|
}
|
|
|
|
//MOVE_TO_CCR
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0100 11-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode, MOVE_TO_CCR, ea);
|
|
}
|
|
|
|
//MOVE_TO_SR
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0110 11-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode, MOVE_TO_SR, ea);
|
|
}
|
|
|
|
//MOVE_FROM_USP
|
|
for(uint3 areg : range(8)) {
|
|
auto opcode = pattern("0100 1110 0110 1---") | areg << 0;
|
|
|
|
AddressRegister to{areg};
|
|
bind(opcode, MOVE_FROM_USP, to);
|
|
}
|
|
|
|
//MOVE_TO_USP
|
|
for(uint3 areg : range(8)) {
|
|
auto opcode = pattern("0100 1110 0110 0---") | areg << 0;
|
|
|
|
AddressRegister from{areg};
|
|
bind(opcode, MOVE_TO_USP, from);
|
|
}
|
|
|
|
//MULS
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1100 ---1 11-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
DataRegister with{dreg};
|
|
EffectiveAddress from{mode, reg};
|
|
bind(opcode, MULS, with, from);
|
|
}
|
|
|
|
//MULU
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1100 ---0 11-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 5)) continue;
|
|
|
|
DataRegister with{dreg};
|
|
EffectiveAddress from{mode, reg};
|
|
bind(opcode, MULU, with, from);
|
|
}
|
|
|
|
//NBCD
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1000 00-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode, NBCD, with);
|
|
}
|
|
|
|
//NEG
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0100 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode | 0 << 6, NEG<Byte>, with);
|
|
bind(opcode | 1 << 6, NEG<Word>, with);
|
|
bind(opcode | 2 << 6, NEG<Long>, with);
|
|
}
|
|
|
|
//NEGX
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0000 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode | 0 << 6, NEGX<Byte>, with);
|
|
bind(opcode | 1 << 6, NEGX<Word>, with);
|
|
bind(opcode | 2 << 6, NEGX<Long>, with);
|
|
}
|
|
|
|
//NOP
|
|
{ auto opcode = pattern("0100 1110 0111 0001");
|
|
|
|
bind(opcode, NOP);
|
|
}
|
|
|
|
//NOT
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 0110 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode | 0 << 6, NOT<Byte>, with);
|
|
bind(opcode | 1 << 6, NOT<Word>, with);
|
|
bind(opcode | 2 << 6, NOT<Long>, with);
|
|
}
|
|
|
|
//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
|
|
{ auto opcode = pattern("0000 0000 0011 1100");
|
|
|
|
bind(opcode, ORI_TO_CCR);
|
|
}
|
|
|
|
//ORI_TO_SR
|
|
{ auto opcode = pattern("0000 0000 0111 1100");
|
|
|
|
bind(opcode, ORI_TO_SR);
|
|
}
|
|
|
|
//PEA
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1000 01-- ----") | mode << 3 | reg << 0;
|
|
if(mode <= 1 || mode == 3 || mode == 4 || (mode == 7 && reg >= 4)) continue;
|
|
|
|
EffectiveAddress from{mode, reg};
|
|
bind(opcode, PEA, from);
|
|
}
|
|
|
|
//RESET
|
|
{ auto opcode = pattern("0100 1110 0111 0000");
|
|
|
|
bind(opcode, RESET);
|
|
}
|
|
|
|
//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);
|
|
}
|
|
|
|
//RTE
|
|
{ auto opcode = pattern("0100 1110 0111 0011");
|
|
|
|
bind(opcode, RTE);
|
|
}
|
|
|
|
//RTR
|
|
{ auto opcode = pattern("0100 1110 0111 0111");
|
|
|
|
bind(opcode, RTR);
|
|
}
|
|
|
|
//RTS
|
|
{ auto opcode = pattern("0100 1110 0111 0101");
|
|
|
|
bind(opcode, RTS);
|
|
}
|
|
|
|
//SBCD
|
|
for(uint3 xreg : range(8))
|
|
for(uint3 yreg : range(8)) {
|
|
auto opcode = pattern("1000 ---1 0000 ----") | xreg << 9 | yreg << 0;
|
|
|
|
EffectiveAddress dataWith{DataRegisterDirect, xreg};
|
|
EffectiveAddress dataFrom{DataRegisterDirect, yreg};
|
|
bind(opcode | 0 << 3, SBCD, dataWith, dataFrom);
|
|
|
|
EffectiveAddress addressWith{AddressRegisterIndirectWithPreDecrement, xreg};
|
|
EffectiveAddress addressFrom{AddressRegisterIndirectWithPreDecrement, yreg};
|
|
bind(opcode | 1 << 3, SBCD, addressWith, addressFrom);
|
|
}
|
|
|
|
//SCC
|
|
for(uint4 condition : range(16))
|
|
for(uint3 mode : range( 8))
|
|
for(uint3 reg : range( 8)) {
|
|
auto opcode = pattern("0101 ---- 11-- ----") | condition << 8 | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress to{mode, reg};
|
|
bind(opcode, SCC, condition, to);
|
|
}
|
|
|
|
//STOP
|
|
{ auto opcode = pattern("0100 1110 0111 0010");
|
|
|
|
bind(opcode, STOP);
|
|
}
|
|
|
|
//SUB
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1001 ---0 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode == 7 && reg >= 5) continue;
|
|
|
|
EffectiveAddress source{mode, reg};
|
|
DataRegister target{dreg};
|
|
bind(opcode | 0 << 6, SUB<Byte>, source, target);
|
|
bind(opcode | 1 << 6, SUB<Word>, source, target);
|
|
bind(opcode | 2 << 6, SUB<Long>, source, target);
|
|
|
|
if(mode == 1) unbind(opcode | 0 << 6);
|
|
}
|
|
|
|
//SUB
|
|
for(uint3 dreg : range(8))
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("1001 ---1 ++-- ----") | dreg << 9 | mode << 3 | reg << 0;
|
|
if(mode <= 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
DataRegister source{dreg};
|
|
EffectiveAddress target{mode, reg};
|
|
bind(opcode | 0 << 6, SUB<Byte>, source, target);
|
|
bind(opcode | 1 << 6, SUB<Word>, 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
|
|
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;
|
|
if(mode != 1) {
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode | 0 << 6, SUBQ<Byte>, immediate, with);
|
|
bind(opcode | 1 << 6, SUBQ<Word>, immediate, with);
|
|
bind(opcode | 2 << 6, SUBQ<Long>, immediate, with);
|
|
} else {
|
|
AddressRegister with{reg};
|
|
bind(opcode | 1 << 6, SUBQ<Word>, immediate, with);
|
|
bind(opcode | 2 << 6, SUBQ<Long>, immediate, with);
|
|
}
|
|
}
|
|
|
|
//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);
|
|
}
|
|
|
|
//SWAP
|
|
for(uint3 dreg : range(8)) {
|
|
auto opcode = pattern("0100 1000 0100 0---") | dreg << 0;
|
|
|
|
DataRegister with{dreg};
|
|
bind(opcode, SWAP, with);
|
|
}
|
|
|
|
//TAS
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1010 11-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 1 || (mode == 7 && reg >= 2)) continue;
|
|
|
|
EffectiveAddress with{mode, reg};
|
|
bind(opcode, TAS, with);
|
|
}
|
|
|
|
//TRAP
|
|
for(uint4 vector : range(16)) {
|
|
auto opcode = pattern("0100 1110 0100 ----") | vector << 0;
|
|
|
|
bind(opcode, TRAP, vector);
|
|
}
|
|
|
|
//TRAPV
|
|
{ auto opcode = pattern("0100 1110 0111 0110");
|
|
|
|
bind(opcode, TRAPV);
|
|
}
|
|
|
|
//TST
|
|
for(uint3 mode : range(8))
|
|
for(uint3 reg : range(8)) {
|
|
auto opcode = pattern("0100 1010 ++-- ----") | mode << 3 | reg << 0;
|
|
if(mode == 7 && reg >= 2) continue;
|
|
|
|
EffectiveAddress ea{mode, reg};
|
|
bind(opcode | 0 << 6, TST<Byte>, ea);
|
|
bind(opcode | 1 << 6, TST<Word>, ea);
|
|
bind(opcode | 2 << 6, TST<Long>, ea);
|
|
|
|
if(mode == 1) unbind(opcode | 0 << 6);
|
|
}
|
|
|
|
//UNLK
|
|
for(uint3 areg : range(8)) {
|
|
auto opcode = pattern("0100 1110 0101 1---") | areg << 0;
|
|
|
|
AddressRegister with{areg};
|
|
bind(opcode, UNLK, with);
|
|
}
|
|
|
|
//ILLEGAL
|
|
for(uint16 opcode : range(65536)) {
|
|
if(instructionTable[opcode]) continue;
|
|
bind(opcode, ILLEGAL);
|
|
}
|
|
|
|
#undef bind
|
|
#undef unbind
|
|
#undef pattern
|
|
}
|