bsnes/higan/processor/m68k/registers.cpp

49 lines
1.1 KiB
C++
Raw Normal View History

template<uint Size> auto M68K::read(DataRegister reg) -> uint32 {
return clip<Size>(r.d[reg.number]);
Update to v100r06 release. byuu says: Up to ten 68K instructions out of somewhere between 61 and 88, depending upon which PDF you look at. Of course, some of them aren't 100% completed yet, either. Lots of craziness with MOVEM, and BCC has a BSR variant that needs stack push/pop functions. This WIP actually took over eight hours to make, going through every possible permutation on how to design the core itself. The updated design now builds both the instruction decoder+dispatcher and the disassembler decoder into the same main loop during M68K's constructor. The special cases are also really psychotic on this processor, and I'm afraid of missing something via the fallthrough cases. So instead, I'm ordering the instructions alphabetically, and including exclusion cases to ignore binding invalid cases. If I end up remapping an existing register, then it'll throw a run-time assertion at program startup. I wanted very much to get rid of struct EA (EffectiveAddress), but it's too difficult to keep track of the internal effective address without it. So I split out the size to a separate parameter, since every opcode only has one size parameter, and otherwise it was getting duplicated in opcodes that take two EAs, and was also awkward with the flag testing. It's a bit more typing, but I feel it's more clean this way. Overall, I'm really worried this is going to be too slow. I don't want to turn the EA stuff into templates, because that will massively bloat out compilation times and object sizes, and will also need a special DSL preprocessor since C++ doesn't have a static for loop. I can definitely optimize a lot of EA's address/read/write functions away once the core is completed, but it's never going to hold a candle to a templatized 68K core. ---- Forgot to include the SA-1 regression fix. I always remember immediately after I upload and archive the WIP. Will try to get that in next time, I guess.
2016-07-16 08:39:44 +00:00
}
template<uint Size> auto M68K::write(DataRegister reg, uint32 data) -> void {
r.d[reg.number] = (r.d[reg.number] & ~mask<Size>()) | (data & mask<Size>());
}
//
template<uint Size> auto M68K::read(AddressRegister reg) -> uint32 {
return sign<Size>(r.a[reg.number]);
}
template<uint Size> auto M68K::write(AddressRegister reg, uint32 data) -> void {
r.a[reg.number] = sign<Size>(data);
}
//
//CCR,SR unused bits cannot be set; always read out as 0
auto M68K::readCCR() -> uint8 {
return r.c << 0 | r.v << 1 | r.z << 2 | r.n << 3 | r.x << 4;
}
auto M68K::readSR() -> uint16 {
return readCCR() << 0 | r.i << 8 | r.s << 13 | r.t << 15;
}
auto M68K::writeCCR(uint8 ccr) -> void {
r.c = ccr.bit(0);
r.v = ccr.bit(1);
r.z = ccr.bit(2);
r.n = ccr.bit(3);
r.x = ccr.bit(4);
}
auto M68K::writeSR(uint16 sr) -> void {
writeCCR(sr);
//when entering or exiting supervisor mode; swap SSP and USP into A7
if(r.s != sr.bit(13)) swap(r.a[7], r.sp);
r.i = sr.bits(8,10);
r.s = sr.bit(13);
r.t = sr.bit(15);
Update to v100r06 release. byuu says: Up to ten 68K instructions out of somewhere between 61 and 88, depending upon which PDF you look at. Of course, some of them aren't 100% completed yet, either. Lots of craziness with MOVEM, and BCC has a BSR variant that needs stack push/pop functions. This WIP actually took over eight hours to make, going through every possible permutation on how to design the core itself. The updated design now builds both the instruction decoder+dispatcher and the disassembler decoder into the same main loop during M68K's constructor. The special cases are also really psychotic on this processor, and I'm afraid of missing something via the fallthrough cases. So instead, I'm ordering the instructions alphabetically, and including exclusion cases to ignore binding invalid cases. If I end up remapping an existing register, then it'll throw a run-time assertion at program startup. I wanted very much to get rid of struct EA (EffectiveAddress), but it's too difficult to keep track of the internal effective address without it. So I split out the size to a separate parameter, since every opcode only has one size parameter, and otherwise it was getting duplicated in opcodes that take two EAs, and was also awkward with the flag testing. It's a bit more typing, but I feel it's more clean this way. Overall, I'm really worried this is going to be too slow. I don't want to turn the EA stuff into templates, because that will massively bloat out compilation times and object sizes, and will also need a special DSL preprocessor since C++ doesn't have a static for loop. I can definitely optimize a lot of EA's address/read/write functions away once the core is completed, but it's never going to hold a candle to a templatized 68K core. ---- Forgot to include the SA-1 regression fix. I always remember immediately after I upload and archive the WIP. Will try to get that in next time, I guess.
2016-07-16 08:39:44 +00:00
}