2016-07-23 02:32:35 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2016-07-23 02:32:35 +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>());
|
2016-07-22 12:03:25 +00:00
|
|
|
}
|
|
|
|
|
2016-07-23 02:32:35 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2016-07-22 12:03:25 +00:00
|
|
|
//when entering or exiting supervisor mode; swap SSP and USP into A7
|
2016-07-23 02:32:35 +00:00
|
|
|
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
|
|
|
}
|