Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace nall {
|
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
template<int...> struct BitRange;
|
Update to v106r85 release.
byuu says:
The bad instruction was due to the instruction before it fetching one
too many bytes. Didn't notice right away as the disassembler got it
right.
The register map was incorrect on the active 16-bit flags.
I fixed and improved some other things along those lines. Hooked up some
basic KnGE (VPU) timings, made it print out VRAM and some of the WRAM
onto the screen each frame, tried to drive Vblank and Hblank IRQs, but
... I don't know for sure what vector addresses they belong to.
MAME says "INT4" for Vblank, and says nothing for Hblank. I am wildly
guessing INT4==SWI 4==0xffff10, but ... I have no idea. I'm also not
emulating the interrupts properly based on line levels, I'm just firing
on the 0→1 transitions. Sounds like Vblank is more nuanced too, but I
guess we'll see.
Emulation is running further along now, even to the point of it
successfully enabling the KnGE IRQs, but VRAM doesn't appear to get much
useful stuff written into it yet.
I reverted the nall/primitive changes, so request for testing is I guess
rescinded, for whatever it was worth.
2019-01-22 00:26:20 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
/* static BitRange */
|
|
|
|
|
|
|
|
template<int Precision, int Lo, int Hi> struct BitRange<Precision, Lo, Hi> {
|
Update to v106r83 release.
byuu says:
Changelog:
- reverted nall/inline-if.hpp usage for now, since the
nall/primitives.hpp math operators still cast to (u)int64_t
- improved nall/primitives.hpp more; integer8 x = -128; print(-x) will
now print 128 (unary operator+ and - cast to (u)int64_t)
- renamed processor/lr35902 to processor/sm83; after the Sharp SM83
CPU core [gekkio discovered the name]
- a few bugfixes to the TLCS900H CPU core
- completed the disassembler for the TLCS900H core
As a result of reverting most of the inline if stuff, I guess the
testing priority has been reduced. Which is probably a good thing,
considering I seem to have a smaller pool of testers these days.
Indeed, the TLCS900H core has ended up at 131KiB compared to the M68000
core at 128KiB. So it's now the largest CPU core in all of higan. It's
even more ridiculous because the M68000 core would ordinarily be quite a
bit smaller, had I not gone overboard with the extreme templating to
reduce instruction decoding overhead (you kind of have to do this for
RISC CPUs, and the inverted design of the TLCS900H kind of makes it
infeasible to do the same there.)
This CPU core is bound to have dozens of extremely difficult CPU bugs,
and there's no easy way for me to test them. I would greatly appreciate
any help in looking over the core for bugs. A fresh pair of eyes to spot
a mistake could save me up to several days of tedious debugging work.
The core still isn't ready to actually be tested: I have to hook up
cartridge loading, a memory bus, interrupts, timers, and the micro DMA
controller before it's likely that anything happens at all.
2019-01-19 01:34:17 +00:00
|
|
|
static_assert(Precision >= 1 && Precision <= 64);
|
2019-08-16 10:44:16 +00:00
|
|
|
enum : uint { bits = Precision };
|
|
|
|
using type =
|
|
|
|
conditional_t<bits <= 8, uint8_t,
|
|
|
|
conditional_t<bits <= 16, uint16_t,
|
|
|
|
conditional_t<bits <= 32, uint32_t,
|
|
|
|
conditional_t<bits <= 64, uint64_t,
|
Update to v106r85 release.
byuu says:
The bad instruction was due to the instruction before it fetching one
too many bytes. Didn't notice right away as the disassembler got it
right.
The register map was incorrect on the active 16-bit flags.
I fixed and improved some other things along those lines. Hooked up some
basic KnGE (VPU) timings, made it print out VRAM and some of the WRAM
onto the screen each frame, tried to drive Vblank and Hblank IRQs, but
... I don't know for sure what vector addresses they belong to.
MAME says "INT4" for Vblank, and says nothing for Hblank. I am wildly
guessing INT4==SWI 4==0xffff10, but ... I have no idea. I'm also not
emulating the interrupts properly based on line levels, I'm just firing
on the 0→1 transitions. Sounds like Vblank is more nuanced too, but I
guess we'll see.
Emulation is running further along now, even to the point of it
successfully enabling the KnGE IRQs, but VRAM doesn't appear to get much
useful stuff written into it yet.
I reverted the nall/primitive changes, so request for testing is I guess
rescinded, for whatever it was worth.
2019-01-22 00:26:20 +00:00
|
|
|
void>>>>;
|
2019-08-16 10:44:16 +00:00
|
|
|
enum : uint { lo = Lo < 0 ? Precision + Lo : Lo };
|
|
|
|
enum : uint { hi = Hi < 0 ? Precision + Hi : Hi };
|
|
|
|
enum : type { mask = ~0ull >> 64 - (hi - lo + 1) << lo };
|
|
|
|
enum : uint { shift = lo };
|
|
|
|
|
|
|
|
BitRange(const BitRange& source) = delete;
|
|
|
|
|
|
|
|
inline auto& operator=(const BitRange& source) {
|
|
|
|
target = target & ~mask | ((source.target & source.mask) >> source.shift) << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline BitRange(T* source) : target((type&)*source) {
|
|
|
|
static_assert(sizeof(T) == sizeof(type));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline operator type() const {
|
|
|
|
return (target & mask) >> shift;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline auto operator++(int) {
|
|
|
|
auto value = (target & mask) >> shift;
|
|
|
|
target = target & ~mask | target + (1 << shift) & mask;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline auto operator--(int) {
|
|
|
|
auto value = (target & mask) >> shift;
|
|
|
|
target = target & ~mask | target - (1 << shift) & mask;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline auto& operator++() {
|
|
|
|
target = target & ~mask | target + (1 << shift) & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline auto& operator--() {
|
|
|
|
target = target & ~mask | target - (1 << shift) & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator*=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) * source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator/=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) / source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator%=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) % source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator+=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) + source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator-=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) - source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator<<=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) << source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator>>=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) >> source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator&=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target & (~mask | value << shift & mask);
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator^=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target ^ value << shift & mask;
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator|=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target | value << shift & mask;
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
private:
|
|
|
|
type& target;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* dynamic BitRange */
|
|
|
|
|
|
|
|
template<int Precision> struct BitRange<Precision> {
|
|
|
|
static_assert(Precision >= 1 && Precision <= 64);
|
|
|
|
enum : uint { bits = Precision };
|
|
|
|
using type =
|
|
|
|
conditional_t<bits <= 8, uint8_t,
|
|
|
|
conditional_t<bits <= 16, uint16_t,
|
|
|
|
conditional_t<bits <= 32, uint32_t,
|
|
|
|
conditional_t<bits <= 64, uint64_t,
|
|
|
|
void>>>>;
|
|
|
|
|
|
|
|
BitRange(const BitRange& source) = delete;
|
|
|
|
|
|
|
|
inline auto& operator=(const BitRange& source) {
|
|
|
|
target = target & ~mask | ((source.target & source.mask) >> source.shift) << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline BitRange(T* source, int index) : target((type&)*source) {
|
|
|
|
static_assert(sizeof(T) == sizeof(type));
|
|
|
|
if(index < 0) index = Precision + index;
|
|
|
|
mask = 1ull << index;
|
|
|
|
shift = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline BitRange(T* source, int lo, int hi) : target((type&)*source) {
|
|
|
|
static_assert(sizeof(T) == sizeof(type));
|
2019-01-14 06:16:28 +00:00
|
|
|
if(lo < 0) lo = Precision + lo;
|
|
|
|
if(hi < 0) hi = Precision + hi;
|
|
|
|
if(lo > hi) swap(lo, hi);
|
2019-08-16 10:44:16 +00:00
|
|
|
mask = ~0ull >> 64 - (hi - lo + 1) << lo;
|
|
|
|
shift = lo;
|
2019-01-14 06:16:28 +00:00
|
|
|
}
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
inline operator type() const {
|
|
|
|
return (target & mask) >> shift;
|
|
|
|
}
|
Update to v106r85 release.
byuu says:
The bad instruction was due to the instruction before it fetching one
too many bytes. Didn't notice right away as the disassembler got it
right.
The register map was incorrect on the active 16-bit flags.
I fixed and improved some other things along those lines. Hooked up some
basic KnGE (VPU) timings, made it print out VRAM and some of the WRAM
onto the screen each frame, tried to drive Vblank and Hblank IRQs, but
... I don't know for sure what vector addresses they belong to.
MAME says "INT4" for Vblank, and says nothing for Hblank. I am wildly
guessing INT4==SWI 4==0xffff10, but ... I have no idea. I'm also not
emulating the interrupts properly based on line levels, I'm just firing
on the 0→1 transitions. Sounds like Vblank is more nuanced too, but I
guess we'll see.
Emulation is running further along now, even to the point of it
successfully enabling the KnGE IRQs, but VRAM doesn't appear to get much
useful stuff written into it yet.
I reverted the nall/primitive changes, so request for testing is I guess
rescinded, for whatever it was worth.
2019-01-22 00:26:20 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
inline auto operator++(int) {
|
|
|
|
auto value = (target & mask) >> shift;
|
|
|
|
target = target & ~mask | target + (1 << shift) & mask;
|
|
|
|
return value;
|
|
|
|
}
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
inline auto operator--(int) {
|
|
|
|
auto value = (target & mask) >> shift;
|
|
|
|
target = target & ~mask | target - (1 << shift) & mask;
|
|
|
|
return value;
|
|
|
|
}
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
inline auto& operator++() {
|
|
|
|
target = target & ~mask | target + (1 << shift) & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
inline auto& operator--() {
|
|
|
|
target = target & ~mask | target - (1 << shift) & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator*=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) * source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
}
|
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
template<typename T> inline auto& operator/=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) / source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-08-16 10:44:16 +00:00
|
|
|
template<typename T> inline auto& operator%=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) % source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator+=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) + source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator-=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) - source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator<<=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) << source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator>>=(const T& source) {
|
|
|
|
auto value = ((target & mask) >> shift) >> source;
|
|
|
|
target = target & ~mask | value << shift & mask;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator&=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target & (~mask | value << shift & mask);
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator^=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target ^ value << shift & mask;
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline auto& operator|=(const T& source) {
|
2021-04-14 12:18:25 +00:00
|
|
|
type value = source;
|
|
|
|
target = target | value << shift & mask;
|
2019-08-16 10:44:16 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
type& target;
|
|
|
|
type mask;
|
|
|
|
uint shift;
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|