Update to v101r02 release.

byuu says:

Changelog:

  - Emulator: use `(uintmax)-1 >> 1` for the units of time
  - MD: implemented 13 new 68K instructions (basically all of the
    remaining easy ones); 21 remain
  - nall: replaced `(u)intmax_t` (64-bit) with *actual* `(u)intmax` type
    (128-bit where available)
      - this extends to everything: atoi, string, etc. You can even
        print 128-bit variables if you like

22,552 opcodes still don't exist in the 68K map. Looking like quite a
few entries will be blank once I finish.
This commit is contained in:
Tim Allen 2016-08-09 21:07:18 +10:00
parent 8bdf8f2a55
commit 0a57cac70c
27 changed files with 703 additions and 202 deletions

View File

@ -11,7 +11,7 @@ using namespace nall;
namespace Emulator { namespace Emulator {
static const string Name = "higan"; static const string Name = "higan";
static const string Version = "101.01"; static const string Version = "101.02";
static const string Author = "byuu"; static const string Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "http://byuu.org/"; static const string Website = "http://byuu.org/";

View File

@ -3,7 +3,7 @@
namespace Emulator { namespace Emulator {
struct Thread { struct Thread {
enum : uintmax { Second = (uintmax)1 << (8 * sizeof(uintmax) - 1) }; enum : uintmax { Second = (uintmax)-1 >> 1 };
virtual ~Thread() { virtual ~Thread() {
if(_handle) co_delete(_handle); if(_handle) co_delete(_handle);

View File

@ -165,12 +165,36 @@ auto M68K::disassembleBCC(uint4 condition, uint8 displacement) -> string {
return {"b", cc, " ", _branch(displacement)}; return {"b", cc, " ", _branch(displacement)};
} }
template<uint Size> auto M68K::disassembleBTST(DataRegister dr, EffectiveAddress ea) -> string { template<uint Size> auto M68K::disassembleBCHG(DataRegister bit, EffectiveAddress with) -> string {
return {"btst ", _dataRegister(dr), ",", _effectiveAddress<Size>(ea)}; return {"bchg", _suffix<Size>(), " ", _dataRegister(bit), ",", _effectiveAddress<Size>(with)};
} }
template<uint Size> auto M68K::disassembleBTST(EffectiveAddress ea) -> string { template<uint Size> auto M68K::disassembleBCHG(EffectiveAddress with) -> string {
return {"btst ", _immediate<Byte>(), ",", _effectiveAddress<Size>(ea)}; return {"bchg", _suffix<Size>(), " ", _immediate<Byte>(), ",", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleBCLR(DataRegister bit, EffectiveAddress with) -> string {
return {"bclr", _suffix<Size>(), " ", _dataRegister(bit), ",", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleBCLR(EffectiveAddress with) -> string {
return {"bclr", _suffix<Size>(), " ", _immediate<Byte>(), ",", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleBSET(DataRegister bit, EffectiveAddress with) -> string {
return {"bset", _suffix<Size>(), " ", _dataRegister(bit), ",", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleBSET(EffectiveAddress with) -> string {
return {"bset", _suffix<Size>(), " ", _immediate<Byte>(), ",", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleBTST(DataRegister bit, EffectiveAddress with) -> string {
return {"btst", _suffix<Size>(), " ", _dataRegister(bit), ",", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleBTST(EffectiveAddress with) -> string {
return {"btst", _suffix<Size>(), " ", _immediate<Byte>(), ",", _effectiveAddress<Size>(with)};
} }
template<uint Size> auto M68K::disassembleCLR(EffectiveAddress ea) -> string { template<uint Size> auto M68K::disassembleCLR(EffectiveAddress ea) -> string {
@ -215,6 +239,10 @@ auto M68K::disassembleEORI_TO_SR() -> string {
return {"eori ", _immediate<Word>(), ",sr"}; return {"eori ", _immediate<Word>(), ",sr"};
} }
auto M68K::disassembleJMP(EffectiveAddress target) -> string {
return {"jmp ", _effectiveAddress<Long>(target)};
}
auto M68K::disassembleJSR(EffectiveAddress target) -> string { auto M68K::disassembleJSR(EffectiveAddress target) -> string {
return {"jsr ", _effectiveAddress<Long>(target)}; return {"jsr ", _effectiveAddress<Long>(target)};
} }
@ -289,18 +317,30 @@ auto M68K::disassembleMOVE_TO_SR(EffectiveAddress ea) -> string {
return {"move ", _effectiveAddress<Word>(ea), ",sr"}; return {"move ", _effectiveAddress<Word>(ea), ",sr"};
} }
auto M68K::disassembleMOVE_USP(uint1 direction, AddressRegister ar) -> string { auto M68K::disassembleMOVE_FROM_USP(AddressRegister to) -> string {
if(direction == 0) { return {"move usp,", _addressRegister(to)};
return {"move ", _addressRegister(ar), ",usp"}; }
} else {
return {"move usp,", _addressRegister(ar)}; auto M68K::disassembleMOVE_TO_USP(AddressRegister from) -> string {
} return {"move ", _addressRegister(from), ",usp"};
}
template<uint Size> auto M68K::disassembleNEG(EffectiveAddress with) -> string {
return {"neg", _suffix<Size>(), " ", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleNEGX(EffectiveAddress with) -> string {
return {"negx", _suffix<Size>(), " ", _effectiveAddress<Size>(with)};
} }
auto M68K::disassembleNOP() -> string { auto M68K::disassembleNOP() -> string {
return {"nop "}; return {"nop "};
} }
template<uint Size> auto M68K::disassembleNOT(EffectiveAddress with) -> string {
return {"not", _suffix<Size>(), " ", _effectiveAddress<Size>(with)};
}
template<uint Size> auto M68K::disassembleOR(EffectiveAddress from, DataRegister with) -> string { template<uint Size> auto M68K::disassembleOR(EffectiveAddress from, DataRegister with) -> string {
return {"eor", _suffix<Size>(), " ", _effectiveAddress<Size>(from), ",", _dataRegister(with)}; return {"eor", _suffix<Size>(), " ", _effectiveAddress<Size>(from), ",", _dataRegister(with)};
} }
@ -369,10 +409,22 @@ auto M68K::disassembleROXR(EffectiveAddress modify) -> string {
return {"roxr", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)}; return {"roxr", _suffix<Word>(), " ", _effectiveAddress<Word>(modify)};
} }
auto M68K::disassembleRTE() -> string {
return {"rte "};
}
auto M68K::disassembleRTR() -> string {
return {"rtr "};
}
auto M68K::disassembleRTS() -> string { auto M68K::disassembleRTS() -> string {
return {"rts "}; return {"rts "};
} }
auto M68K::disassembleSCC(uint4 condition, EffectiveAddress to) -> string {
return {"s", _condition(condition), " ", _effectiveAddress<Byte>(to)};
}
template<uint Size> auto M68K::disassembleSUB(EffectiveAddress source, DataRegister target) -> string { template<uint Size> auto M68K::disassembleSUB(EffectiveAddress source, DataRegister target) -> string {
return {"sub", _suffix<Size>(), " ", _effectiveAddress<Size>(source), ",", _dataRegister(target)}; return {"sub", _suffix<Size>(), " ", _effectiveAddress<Size>(source), ",", _dataRegister(target)};
} }

View File

@ -253,6 +253,78 @@ M68K::M68K() {
bind(opcode, BCC, condition, displacement); 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) //BTST (register)
for(uint3 dreg : range(8)) for(uint3 dreg : range(8))
for(uint3 mode : range(8)) for(uint3 mode : range(8))
@ -270,7 +342,7 @@ M68K::M68K() {
for(uint3 mode : range(8)) for(uint3 mode : range(8))
for(uint3 reg : range(8)) { for(uint3 reg : range(8)) {
auto opcode = pattern("0000 1000 00-- ----") | mode << 3 | reg << 0; auto opcode = pattern("0000 1000 00-- ----") | mode << 3 | reg << 0;
if(mode == 1 || (mode == 7 && (reg == 2 || reg >= 5))) continue; if(mode == 1 || (mode == 7 && reg >= 4)) continue;
EffectiveAddress ea{mode, reg}; EffectiveAddress ea{mode, reg};
if(mode == 0) bind(opcode, BTST<Long>, ea); if(mode == 0) bind(opcode, BTST<Long>, ea);
@ -388,6 +460,16 @@ M68K::M68K() {
bind(opcode, EORI_TO_SR); bind(opcode, EORI_TO_SR);
} }
//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 //JSR
for(uint3 mode : range(8)) for(uint3 mode : range(8))
for(uint3 reg : range(8)) { for(uint3 reg : range(8)) {
@ -561,13 +643,44 @@ M68K::M68K() {
bind(opcode, MOVE_TO_SR, ea); bind(opcode, MOVE_TO_SR, ea);
} }
//MOVE_USP //MOVE_FROM_USP
for(uint1 direction : range(2)) for(uint3 areg : range(8)) {
for(uint3 areg : range(8)) { auto opcode = pattern("0100 1110 0110 1---") | areg << 0;
auto opcode = pattern("0100 1110 0110 ----") | direction << 3 | areg << 0;
AddressRegister ar{areg}; AddressRegister to{areg};
bind(opcode, MOVE_USP, direction, ar); 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);
}
//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 //NOP
@ -576,6 +689,18 @@ M68K::M68K() {
bind(opcode, NOP); 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 //OR
for(uint3 dreg : range(8)) for(uint3 dreg : range(8))
for(uint3 mode : range(8)) for(uint3 mode : range(8))
@ -764,12 +889,35 @@ M68K::M68K() {
bind(opcode, ROXR, modify); 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 //RTS
{ auto opcode = pattern("0100 1110 0111 0101"); { auto opcode = pattern("0100 1110 0111 0101");
bind(opcode, RTS); bind(opcode, RTS);
} }
//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);
}
//SUB //SUB
for(uint3 dreg : range(8)) for(uint3 dreg : range(8))
for(uint3 mode : range(8)) for(uint3 mode : range(8))

View File

@ -243,20 +243,64 @@ auto M68K::instructionBCC(uint4 condition, uint8 displacement) -> void {
} }
} }
template<uint Size> auto M68K::instructionBTST(DataRegister dr, EffectiveAddress ea) -> void { template<uint Size> auto M68K::instructionBCHG(DataRegister bit, EffectiveAddress with) -> void {
auto bit = read<Size>(dr); auto index = read<Size>(bit) & bits<Size>() - 1;
auto test = read<Size>(ea); auto test = read<Size>(with);
bit &= bits<Size>() - 1; r.z = test.bit(index) == 0;
test.bit(index) ^= 1;
r.z = test.bit(bit) == 0; write<Size>(with, test);
} }
template<uint Size> auto M68K::instructionBTST(EffectiveAddress ea) -> void { template<uint Size> auto M68K::instructionBCHG(EffectiveAddress with) -> void {
auto bit = (uint8)readPC<Word>(); auto index = readPC<Word>() & bits<Size>() - 1;
auto test = read<Size>(ea); auto test = read<Size>(with);
bit &= bits<Size>() - 1; r.z = test.bit(index) == 0;
test.bit(index) ^= 1;
write<Size>(with, test);
}
r.z = test.bit(bit) == 0; template<uint Size> auto M68K::instructionBCLR(DataRegister bit, EffectiveAddress with) -> void {
auto index = read<Size>(bit) & bits<Size>() - 1;
auto test = read<Size>(with);
r.z = test.bit(index) == 0;
test.bit(index) = 0;
write<Size>(with, test);
}
template<uint Size> auto M68K::instructionBCLR(EffectiveAddress with) -> void {
auto index = readPC<Word>() & bits<Size>() - 1;
auto test = read<Size>(with);
r.z = test.bit(index) == 0;
test.bit(index) = 0;
write<Size>(with, test);
}
template<uint Size> auto M68K::instructionBSET(DataRegister bit, EffectiveAddress with) -> void {
auto index = read<Size>(bit) & bits<Size>() - 1;
auto test = read<Size>(with);
r.z = test.bit(index) == 0;
test.bit(index) = 1;
write<Size>(with, test);
}
template<uint Size> auto M68K::instructionBSET(EffectiveAddress with) -> void {
auto index = readPC<Word>() & bits<Size>() - 1;
auto test = read<Size>(with);
r.z = test.bit(index) == 0;
test.bit(index) = 1;
write<Size>(with, test);
}
template<uint Size> auto M68K::instructionBTST(DataRegister bit, EffectiveAddress with) -> void {
auto index = read<Size>(bit) & bits<Size>() - 1;
auto test = read<Size>(with);
r.z = test.bit(index) == 0;
}
template<uint Size> auto M68K::instructionBTST(EffectiveAddress with) -> void {
auto index = readPC<Word>() & bits<Size>() - 1;
auto test = read<Size>(with);
r.z = test.bit(index) == 0;
} }
template<uint Size> auto M68K::instructionCLR(EffectiveAddress ea) -> void { template<uint Size> auto M68K::instructionCLR(EffectiveAddress ea) -> void {
@ -350,6 +394,10 @@ auto M68K::instructionEORI_TO_SR() -> void {
writeSR(readSR() ^ data); writeSR(readSR() ^ data);
} }
auto M68K::instructionJMP(EffectiveAddress target) -> void {
r.pc = fetch<Long>(target);
}
auto M68K::instructionJSR(EffectiveAddress target) -> void { auto M68K::instructionJSR(EffectiveAddress target) -> void {
push<Long>(r.pc); push<Long>(r.pc);
r.pc = fetch<Long>(target); r.pc = fetch<Long>(target);
@ -491,19 +539,43 @@ auto M68K::instructionMOVE_TO_SR(EffectiveAddress ea) -> void {
writeSR(data); writeSR(data);
} }
auto M68K::instructionMOVE_USP(uint1 direction, AddressRegister ar) -> void { auto M68K::instructionMOVE_FROM_USP(AddressRegister to) -> void {
if(!supervisor()) return; if(!supervisor()) return;
if(direction == 0) { write<Long>(to, r.sp);
r.sp = read<Long>(ar); }
} else {
write<Long>(ar, r.sp); auto M68K::instructionMOVE_TO_USP(AddressRegister from) -> void {
} if(!supervisor()) return;
r.sp = read<Long>(from);
}
template<uint Size> auto M68K::instructionNEG(EffectiveAddress with) -> void {
auto source = read<Size>(with);
auto result = SUB<Size>(0, source);
write<Size>(with, result);
}
template<uint Size> auto M68K::instructionNEGX(EffectiveAddress with) -> void {
auto source = read<Size>(with);
auto result = SUB<Size, Extend>(0, source);
write<Size>(with, result);
} }
auto M68K::instructionNOP() -> void { auto M68K::instructionNOP() -> void {
} }
template<uint Size> auto M68K::instructionNOT(EffectiveAddress with) -> void {
auto result = ~read<Size>(with);
write<Size>(with, result);
r.c = 0;
r.v = 0;
r.z = clip<Size>(result) == 0;
r.n = sign<Size>(result) < 0;
}
template<uint Size> auto M68K::OR(uint32 source, uint32 target) -> uint32 { template<uint Size> auto M68K::OR(uint32 source, uint32 target) -> uint32 {
auto result = target | source; auto result = target | source;
@ -678,10 +750,28 @@ auto M68K::instructionROXR(EffectiveAddress modify) -> void {
write<Word>(modify, result); write<Word>(modify, result);
} }
auto M68K::instructionRTE() -> void {
if(!supervisor()) return;
auto sr = pop<Word>();
r.pc = pop<Long>();
writeSR(sr);
}
auto M68K::instructionRTR() -> void {
writeCCR(pop<Word>());
r.pc = pop<Long>();
}
auto M68K::instructionRTS() -> void { auto M68K::instructionRTS() -> void {
r.pc = pop<Long>(); r.pc = pop<Long>();
} }
auto M68K::instructionSCC(uint4 condition, EffectiveAddress to) -> void {
uint8 result = testCondition(condition) ? ~0 : 0;
write<Byte>(to, result);
}
template<uint Size, bool Extend> auto M68K::SUB(uint32 source, uint32 target) -> uint32 { template<uint Size, bool Extend> auto M68K::SUB(uint32 source, uint32 target) -> uint32 {
uint64 result = source - target; uint64 result = source - target;
if(Extend) result -= r.x; if(Extend) result -= r.x;

View File

@ -119,8 +119,14 @@ struct M68K {
template<uint Size> auto instructionASR(DataRegister shift, DataRegister modify) -> void; template<uint Size> auto instructionASR(DataRegister shift, DataRegister modify) -> void;
auto instructionASR(EffectiveAddress modify) -> void; auto instructionASR(EffectiveAddress modify) -> void;
auto instructionBCC(uint4 condition, uint8 displacement) -> void; auto instructionBCC(uint4 condition, uint8 displacement) -> void;
template<uint Size> auto instructionBTST(DataRegister dr, EffectiveAddress ea) -> void; template<uint Size> auto instructionBCHG(DataRegister bit, EffectiveAddress with) -> void;
template<uint Size> auto instructionBTST(EffectiveAddress ea) -> void; template<uint Size> auto instructionBCHG(EffectiveAddress with) -> void;
template<uint Size> auto instructionBCLR(DataRegister bit, EffectiveAddress with) -> void;
template<uint Size> auto instructionBCLR(EffectiveAddress with) -> void;
template<uint Size> auto instructionBSET(DataRegister bit, EffectiveAddress with) -> void;
template<uint Size> auto instructionBSET(EffectiveAddress with) -> void;
template<uint Size> auto instructionBTST(DataRegister bit, EffectiveAddress with) -> void;
template<uint Size> auto instructionBTST(EffectiveAddress with) -> void;
template<uint Size> auto instructionCLR(EffectiveAddress ea) -> void; template<uint Size> auto instructionCLR(EffectiveAddress ea) -> void;
template<uint Size> auto CMP(uint32 source, uint32 target) -> uint32; template<uint Size> auto CMP(uint32 source, uint32 target) -> uint32;
template<uint Size> auto instructionCMP(DataRegister dr, EffectiveAddress ea) -> void; template<uint Size> auto instructionCMP(DataRegister dr, EffectiveAddress ea) -> void;
@ -133,6 +139,7 @@ struct M68K {
template<uint Size> auto instructionEORI(EffectiveAddress with) -> void; template<uint Size> auto instructionEORI(EffectiveAddress with) -> void;
auto instructionEORI_TO_CCR() -> void; auto instructionEORI_TO_CCR() -> void;
auto instructionEORI_TO_SR() -> void; auto instructionEORI_TO_SR() -> void;
auto instructionJMP(EffectiveAddress target) -> void;
auto instructionJSR(EffectiveAddress target) -> void; auto instructionJSR(EffectiveAddress target) -> void;
auto instructionLEA(AddressRegister ar, EffectiveAddress ea) -> void; auto instructionLEA(AddressRegister ar, EffectiveAddress ea) -> void;
template<uint Size> auto LSL(uint32 result, uint shift) -> uint32; template<uint Size> auto LSL(uint32 result, uint shift) -> uint32;
@ -150,8 +157,12 @@ struct M68K {
auto instructionMOVE_FROM_SR(EffectiveAddress ea) -> void; auto instructionMOVE_FROM_SR(EffectiveAddress ea) -> void;
auto instructionMOVE_TO_CCR(EffectiveAddress ea) -> void; auto instructionMOVE_TO_CCR(EffectiveAddress ea) -> void;
auto instructionMOVE_TO_SR(EffectiveAddress ea) -> void; auto instructionMOVE_TO_SR(EffectiveAddress ea) -> void;
auto instructionMOVE_USP(uint1 direction, AddressRegister ar) -> void; auto instructionMOVE_FROM_USP(AddressRegister to) -> void;
auto instructionMOVE_TO_USP(AddressRegister from) -> void;
template<uint Size> auto instructionNEG(EffectiveAddress with) -> void;
template<uint Size> auto instructionNEGX(EffectiveAddress with) -> void;
auto instructionNOP() -> void; auto instructionNOP() -> void;
template<uint Size> auto instructionNOT(EffectiveAddress with) -> void;
template<uint Size> auto OR(uint32 source, uint32 target) -> uint32; template<uint Size> auto OR(uint32 source, uint32 target) -> uint32;
template<uint Size> auto instructionOR(EffectiveAddress from, DataRegister with) -> void; template<uint Size> auto instructionOR(EffectiveAddress from, DataRegister with) -> void;
template<uint Size> auto instructionOR(DataRegister from, EffectiveAddress with) -> void; template<uint Size> auto instructionOR(DataRegister from, EffectiveAddress with) -> void;
@ -174,7 +185,10 @@ struct M68K {
template<uint Size> auto instructionROXR(uint4 shift, DataRegister modify) -> void; template<uint Size> auto instructionROXR(uint4 shift, DataRegister modify) -> void;
template<uint Size> auto instructionROXR(DataRegister shift, DataRegister modify) -> void; template<uint Size> auto instructionROXR(DataRegister shift, DataRegister modify) -> void;
auto instructionROXR(EffectiveAddress modify) -> void; auto instructionROXR(EffectiveAddress modify) -> void;
auto instructionRTE() -> void;
auto instructionRTR() -> void;
auto instructionRTS() -> void; auto instructionRTS() -> void;
auto instructionSCC(uint4 condition, EffectiveAddress to) -> void;
template<uint Size, bool Extend = false> auto SUB(uint32 source, uint32 target) -> uint32; template<uint Size, bool Extend = false> auto SUB(uint32 source, uint32 target) -> uint32;
template<uint Size> auto instructionSUB(EffectiveAddress source, DataRegister target) -> void; template<uint Size> auto instructionSUB(EffectiveAddress source, DataRegister target) -> void;
template<uint Size> auto instructionSUB(DataRegister source, EffectiveAddress target) -> void; template<uint Size> auto instructionSUB(DataRegister source, EffectiveAddress target) -> void;
@ -229,8 +243,14 @@ private:
template<uint Size> auto disassembleASR(DataRegister shift, DataRegister modify) -> string; template<uint Size> auto disassembleASR(DataRegister shift, DataRegister modify) -> string;
auto disassembleASR(EffectiveAddress modify) -> string; auto disassembleASR(EffectiveAddress modify) -> string;
auto disassembleBCC(uint4 condition, uint8 displacement) -> string; auto disassembleBCC(uint4 condition, uint8 displacement) -> string;
template<uint Size> auto disassembleBTST(DataRegister dr, EffectiveAddress ea) -> string; template<uint Size> auto disassembleBCHG(DataRegister bit, EffectiveAddress with) -> string;
template<uint Size> auto disassembleBTST(EffectiveAddress ea) -> string; template<uint Size> auto disassembleBCHG(EffectiveAddress with) -> string;
template<uint Size> auto disassembleBCLR(DataRegister bit, EffectiveAddress with) -> string;
template<uint Size> auto disassembleBCLR(EffectiveAddress with) -> string;
template<uint Size> auto disassembleBSET(DataRegister bit, EffectiveAddress with) -> string;
template<uint Size> auto disassembleBSET(EffectiveAddress with) -> string;
template<uint Size> auto disassembleBTST(DataRegister bit, EffectiveAddress with) -> string;
template<uint Size> auto disassembleBTST(EffectiveAddress with) -> string;
template<uint Size> auto disassembleCLR(EffectiveAddress ea) -> string; template<uint Size> auto disassembleCLR(EffectiveAddress ea) -> string;
template<uint Size> auto disassembleCMP(DataRegister dr, EffectiveAddress ea) -> string; template<uint Size> auto disassembleCMP(DataRegister dr, EffectiveAddress ea) -> string;
template<uint Size> auto disassembleCMPA(AddressRegister ar, EffectiveAddress ea) -> string; template<uint Size> auto disassembleCMPA(AddressRegister ar, EffectiveAddress ea) -> string;
@ -241,6 +261,7 @@ private:
template<uint Size> auto disassembleEORI(EffectiveAddress with) -> string; template<uint Size> auto disassembleEORI(EffectiveAddress with) -> string;
auto disassembleEORI_TO_CCR() -> string; auto disassembleEORI_TO_CCR() -> string;
auto disassembleEORI_TO_SR() -> string; auto disassembleEORI_TO_SR() -> string;
auto disassembleJMP(EffectiveAddress target) -> string;
auto disassembleJSR(EffectiveAddress target) -> string; auto disassembleJSR(EffectiveAddress target) -> string;
auto disassembleLEA(AddressRegister ar, EffectiveAddress ea) -> string; auto disassembleLEA(AddressRegister ar, EffectiveAddress ea) -> string;
template<uint Size> auto disassembleLSL(uint4 immediate, DataRegister dr) -> string; template<uint Size> auto disassembleLSL(uint4 immediate, DataRegister dr) -> string;
@ -256,8 +277,12 @@ private:
auto disassembleMOVE_FROM_SR(EffectiveAddress ea) -> string; auto disassembleMOVE_FROM_SR(EffectiveAddress ea) -> string;
auto disassembleMOVE_TO_CCR(EffectiveAddress ea) -> string; auto disassembleMOVE_TO_CCR(EffectiveAddress ea) -> string;
auto disassembleMOVE_TO_SR(EffectiveAddress ea) -> string; auto disassembleMOVE_TO_SR(EffectiveAddress ea) -> string;
auto disassembleMOVE_USP(uint1 direction, AddressRegister ar) -> string; auto disassembleMOVE_FROM_USP(AddressRegister to) -> string;
auto disassembleMOVE_TO_USP(AddressRegister from) -> string;
template<uint Size> auto disassembleNEG(EffectiveAddress with) -> string;
template<uint Size> auto disassembleNEGX(EffectiveAddress with) -> string;
auto disassembleNOP() -> string; auto disassembleNOP() -> string;
template<uint Size> auto disassembleNOT(EffectiveAddress with) -> string;
template<uint Size> auto disassembleOR(EffectiveAddress from, DataRegister with) -> string; template<uint Size> auto disassembleOR(EffectiveAddress from, DataRegister with) -> string;
template<uint Size> auto disassembleOR(DataRegister from, EffectiveAddress with) -> string; template<uint Size> auto disassembleOR(DataRegister from, EffectiveAddress with) -> string;
template<uint Size> auto disassembleORI(EffectiveAddress with) -> string; template<uint Size> auto disassembleORI(EffectiveAddress with) -> string;
@ -275,7 +300,10 @@ private:
template<uint Size> auto disassembleROXR(uint4 shift, DataRegister modify) -> string; template<uint Size> auto disassembleROXR(uint4 shift, DataRegister modify) -> string;
template<uint Size> auto disassembleROXR(DataRegister shift, DataRegister modify) -> string; template<uint Size> auto disassembleROXR(DataRegister shift, DataRegister modify) -> string;
auto disassembleROXR(EffectiveAddress modify) -> string; auto disassembleROXR(EffectiveAddress modify) -> string;
auto disassembleRTE() -> string;
auto disassembleRTR() -> string;
auto disassembleRTS() -> string; auto disassembleRTS() -> string;
auto disassembleSCC(uint4 condition, EffectiveAddress to) -> string;
template<uint Size> auto disassembleSUB(EffectiveAddress source, DataRegister target) -> string; template<uint Size> auto disassembleSUB(EffectiveAddress source, DataRegister target) -> string;
template<uint Size> auto disassembleSUB(DataRegister source, EffectiveAddress target) -> string; template<uint Size> auto disassembleSUB(DataRegister source, EffectiveAddress target) -> string;
template<uint Size> auto disassembleSUBA(AddressRegister to, EffectiveAddress from) -> string; template<uint Size> auto disassembleSUBA(AddressRegister to, EffectiveAddress from) -> string;

View File

@ -4,7 +4,7 @@
namespace nall { namespace nall {
constexpr inline auto toBinary_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto toBinary_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s == '0' || *s == '1' ? toBinary_(s + 1, (sum << 1) | *s - '0') : *s == '0' || *s == '1' ? toBinary_(s + 1, (sum << 1) | *s - '0') :
*s == '\'' ? toBinary_(s + 1, sum) : *s == '\'' ? toBinary_(s + 1, sum) :
@ -12,7 +12,7 @@ constexpr inline auto toBinary_(const char* s, uintmax_t sum = 0) -> uintmax_t {
); );
} }
constexpr inline auto toOctal_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto toOctal_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s >= '0' && *s <= '7' ? toOctal_(s + 1, (sum << 3) | *s - '0') : *s >= '0' && *s <= '7' ? toOctal_(s + 1, (sum << 3) | *s - '0') :
*s == '\'' ? toOctal_(s + 1, sum) : *s == '\'' ? toOctal_(s + 1, sum) :
@ -20,7 +20,7 @@ constexpr inline auto toOctal_(const char* s, uintmax_t sum = 0) -> uintmax_t {
); );
} }
constexpr inline auto toDecimal_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto toDecimal_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s >= '0' && *s <= '9' ? toDecimal_(s + 1, (sum * 10) + *s - '0') : *s >= '0' && *s <= '9' ? toDecimal_(s + 1, (sum * 10) + *s - '0') :
*s == '\'' ? toDecimal_(s + 1, sum) : *s == '\'' ? toDecimal_(s + 1, sum) :
@ -28,7 +28,7 @@ constexpr inline auto toDecimal_(const char* s, uintmax_t sum = 0) -> uintmax_t
); );
} }
constexpr inline auto toHex_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto toHex_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s >= 'A' && *s <= 'F' ? toHex_(s + 1, (sum << 4) | *s - 'A' + 10) : *s >= 'A' && *s <= 'F' ? toHex_(s + 1, (sum << 4) | *s - 'A' + 10) :
*s >= 'a' && *s <= 'f' ? toHex_(s + 1, (sum << 4) | *s - 'a' + 10) : *s >= 'a' && *s <= 'f' ? toHex_(s + 1, (sum << 4) | *s - 'a' + 10) :
@ -40,21 +40,21 @@ constexpr inline auto toHex_(const char* s, uintmax_t sum = 0) -> uintmax_t {
// //
constexpr inline auto toBinary(const char* s) -> uintmax_t { constexpr inline auto toBinary(const char* s) -> uintmax {
return ( return (
*s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) : *s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) :
*s == '%' ? toBinary_(s + 1) : toBinary_(s) *s == '%' ? toBinary_(s + 1) : toBinary_(s)
); );
} }
constexpr inline auto toOctal(const char* s) -> uintmax_t { constexpr inline auto toOctal(const char* s) -> uintmax {
return ( return (
*s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) : *s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) :
toOctal_(s) toOctal_(s)
); );
} }
constexpr inline auto toHex(const char* s) -> uintmax_t { constexpr inline auto toHex(const char* s) -> uintmax {
return ( return (
*s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? toHex_(s + 2) : *s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? toHex_(s + 2) :
*s == '$' ? toHex_(s + 1) : toHex_(s) *s == '$' ? toHex_(s + 1) : toHex_(s)
@ -63,7 +63,7 @@ constexpr inline auto toHex(const char* s) -> uintmax_t {
// //
constexpr inline auto toNatural(const char* s) -> uintmax_t { constexpr inline auto toNatural(const char* s) -> uintmax {
return ( return (
*s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) : *s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) :
*s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) : *s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) :
@ -72,7 +72,7 @@ constexpr inline auto toNatural(const char* s) -> uintmax_t {
); );
} }
constexpr inline auto toInteger(const char* s) -> intmax_t { constexpr inline auto toInteger(const char* s) -> intmax {
return ( return (
*s == '+' ? +toNatural(s + 1) : *s == '-' ? -toNatural(s + 1) : toNatural(s) *s == '+' ? +toNatural(s + 1) : *s == '-' ? -toNatural(s + 1) : toNatural(s)
); );

View File

@ -4,28 +4,28 @@
namespace nall { namespace nall {
template<uint bits> inline auto uclamp(const uintmax_t x) -> uintmax_t { template<uint bits> inline auto uclamp(const uintmax x) -> uintmax {
enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 }; enum : uintmax { b = 1ull << (bits - 1), y = b * 2 - 1 };
return y + ((x - y) & -(x < y)); //min(x, y); return y + ((x - y) & -(x < y)); //min(x, y);
} }
template<uint bits> inline auto uclip(const uintmax_t x) -> uintmax_t { template<uint bits> inline auto uclip(const uintmax x) -> uintmax {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 }; enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 };
return (x & m); return (x & m);
} }
template<uint bits> inline auto sclamp(const intmax_t x) -> intmax_t { template<uint bits> inline auto sclamp(const intmax x) -> intmax {
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 }; enum : intmax { b = 1ull << (bits - 1), m = b - 1 };
return (x > m) ? m : (x < -b) ? -b : x; return (x > m) ? m : (x < -b) ? -b : x;
} }
template<uint bits> inline auto sclip(const intmax_t x) -> intmax_t { template<uint bits> inline auto sclip(const intmax x) -> intmax {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 }; enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 };
return ((x & m) ^ b) - b; return ((x & m) ^ b) - b;
} }
namespace bit { namespace bit {
constexpr inline auto mask(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto mask(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) : *s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) :
*s == ' ' || *s == '_' ? mask(s + 1, sum) : *s == ' ' || *s == '_' ? mask(s + 1, sum) :
@ -34,7 +34,7 @@ namespace bit {
); );
} }
constexpr inline auto test(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto test(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) : *s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) :
*s == ' ' || *s == '_' ? test(s + 1, sum) : *s == ' ' || *s == '_' ? test(s + 1, sum) :
@ -44,22 +44,22 @@ namespace bit {
} }
//lowest(0b1110) == 0b0010 //lowest(0b1110) == 0b0010
constexpr inline auto lowest(const uintmax_t x) -> uintmax_t { constexpr inline auto lowest(const uintmax x) -> uintmax {
return x & -x; return x & -x;
} }
//clear_lowest(0b1110) == 0b1100 //clear_lowest(0b1110) == 0b1100
constexpr inline auto clearLowest(const uintmax_t x) -> uintmax_t { constexpr inline auto clearLowest(const uintmax x) -> uintmax {
return x & (x - 1); return x & (x - 1);
} }
//set_lowest(0b0101) == 0b0111 //set_lowest(0b0101) == 0b0111
constexpr inline auto setLowest(const uintmax_t x) -> uintmax_t { constexpr inline auto setLowest(const uintmax x) -> uintmax {
return x | (x + 1); return x | (x + 1);
} }
//count number of bits set in a byte //count number of bits set in a byte
inline auto count(uintmax_t x) -> uint { inline auto count(uintmax x) -> uint {
uint count = 0; uint count = 0;
do count += x & 1; while(x >>= 1); do count += x & 1; while(x >>= 1);
return count; return count;
@ -67,7 +67,7 @@ namespace bit {
//return index of the first bit set (or zero of no bits are set) //return index of the first bit set (or zero of no bits are set)
//first(0b1000) == 3 //first(0b1000) == 3
inline auto first(uintmax_t x) -> uint { inline auto first(uintmax x) -> uint {
uint first = 0; uint first = 0;
while(x) { if(x & 1) break; x >>= 1; first++; } while(x) { if(x & 1) break; x >>= 1; first++; }
return first; return first;
@ -75,7 +75,7 @@ namespace bit {
//round up to next highest single bit: //round up to next highest single bit:
//round(15) == 16, round(16) == 16, round(17) == 32 //round(15) == 16, round(16) == 16, round(17) == 32
inline auto round(uintmax_t x) -> uintmax_t { inline auto round(uintmax x) -> uintmax {
if((x & (x - 1)) == 0) return x; if((x & (x - 1)) == 0) return x;
while(x & (x - 1)) x &= x - 1; while(x & (x - 1)) x &= x - 1;
return x << 1; return x << 1;

View File

@ -5,7 +5,7 @@ namespace nall { namespace Decode {
struct BMP { struct BMP {
BMP() = default; BMP() = default;
BMP(const string& filename) { load(filename); } BMP(const string& filename) { load(filename); }
BMP(const uint8_t* data, unsigned size) { load(data, size); } BMP(const uint8_t* data, uint size) { load(data, size); }
explicit operator bool() const { return _data; } explicit operator bool() const { return _data; }
@ -15,28 +15,28 @@ struct BMP {
auto data() -> uint32_t* { return _data; } auto data() -> uint32_t* { return _data; }
auto data() const -> const uint32_t* { return _data; } auto data() const -> const uint32_t* { return _data; }
auto width() const -> unsigned { return _width; } auto width() const -> uint { return _width; }
auto height() const -> unsigned { return _height; } auto height() const -> uint { return _height; }
auto load(const string& filename) -> bool { auto load(const string& filename) -> bool {
auto buffer = file::read(filename); auto buffer = file::read(filename);
return load(buffer.data(), buffer.size()); return load(buffer.data(), buffer.size());
} }
auto load(const uint8_t* data, unsigned size) -> bool { auto load(const uint8_t* data, uint size) -> bool {
if(size < 0x36) return false; if(size < 0x36) return false;
const uint8_t* p = data; const uint8_t* p = data;
if(read(p, 2) != 0x4d42) return false; //signature if(read(p, 2) != 0x4d42) return false; //signature
read(p, 8); read(p, 8);
unsigned offset = read(p, 4); uint offset = read(p, 4);
if(read(p, 4) != 40) return false; //DIB size if(read(p, 4) != 40) return false; //DIB size
signed width = read(p, 4); int width = read(p, 4);
if(width < 0) return false; if(width < 0) return false;
signed height = read(p, 4); int height = read(p, 4);
bool flip = height < 0; bool flip = height < 0;
if(flip) height = -height; if(flip) height = -height;
read(p, 2); read(p, 2);
unsigned bitsPerPixel = read(p, 2); uint bitsPerPixel = read(p, 2);
if(bitsPerPixel != 24 && bitsPerPixel != 32) return false; if(bitsPerPixel != 24 && bitsPerPixel != 32) return false;
if(read(p, 4) != 0) return false; //compression type if(read(p, 4) != 0) return false; //compression type
@ -44,9 +44,9 @@ struct BMP {
_height = height; _height = height;
_data = new uint32_t[width * height]; _data = new uint32_t[width * height];
unsigned bytesPerPixel = bitsPerPixel / 8; uint bytesPerPixel = bitsPerPixel / 8;
unsigned alignedWidth = width * bytesPerPixel; uint alignedWidth = width * bytesPerPixel;
unsigned paddingLength = 0; uint paddingLength = 0;
while(alignedWidth % 4) alignedWidth++, paddingLength++; while(alignedWidth % 4) alignedWidth++, paddingLength++;
p = data + offset; p = data + offset;
@ -63,12 +63,12 @@ struct BMP {
private: private:
uint32_t* _data = nullptr; uint32_t* _data = nullptr;
unsigned _width = 0; uint _width = 0;
unsigned _height = 0; uint _height = 0;
auto read(const uint8_t*& buffer, unsigned length) -> uintmax_t { auto read(const uint8_t*& buffer, uint length) -> uintmax {
uintmax_t result = 0; uintmax result = 0;
for(auto n : range(length)) result |= (uintmax_t)*buffer++ << (n << 3); for(auto n : range(length)) result |= (uintmax)*buffer++ << (n << 3);
return result; return result;
} }
}; };

View File

@ -32,22 +32,22 @@ struct library {
auto close() -> void; auto close() -> void;
private: private:
uintptr_t handle = 0; uintptr handle = 0;
}; };
#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
inline auto library::open(const string& name, const string& path) -> bool { inline auto library::open(const string& name, const string& path) -> bool {
if(handle) close(); if(handle) close();
if(path) handle = (uintptr_t)dlopen(string(path, "lib", name, ".so"), RTLD_LAZY); if(path) handle = (uintptr)dlopen(string(path, "lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string(Path::user(), ".local/lib/lib", name, ".so"), RTLD_LAZY); if(!handle) handle = (uintptr)dlopen(string(Path::user(), ".local/lib/lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY); if(!handle) handle = (uintptr)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("lib", name, ".so"), RTLD_LAZY); if(!handle) handle = (uintptr)dlopen(string("lib", name, ".so"), RTLD_LAZY);
return handle; return handle;
} }
inline auto library::openAbsolute(const string& name) -> bool { inline auto library::openAbsolute(const string& name) -> bool {
if(handle) close(); if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY); handle = (uintptr)dlopen(name, RTLD_LAZY);
return handle; return handle;
} }
@ -64,16 +64,16 @@ inline auto library::close() -> void {
#elif defined(PLATFORM_MACOSX) #elif defined(PLATFORM_MACOSX)
inline auto library::open(const string& name, const string& path) -> bool { inline auto library::open(const string& name, const string& path) -> bool {
if(handle) close(); if(handle) close();
if(path) handle = (uintptr_t)dlopen(string(path, "lib", name, ".dylib"), RTLD_LAZY); if(path) handle = (uintptr)dlopen(string(path, "lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string(Path::user(), ".local/lib/lib", name, ".dylib"), RTLD_LAZY); if(!handle) handle = (uintptr)dlopen(string(Path::user(), ".local/lib/lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY); if(!handle) handle = (uintptr)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("lib", name, ".dylib"), RTLD_LAZY); if(!handle) handle = (uintptr)dlopen(string("lib", name, ".dylib"), RTLD_LAZY);
return handle; return handle;
} }
inline auto library::openAbsolute(const string& name) -> bool { inline auto library::openAbsolute(const string& name) -> bool {
if(handle) close(); if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY); handle = (uintptr)dlopen(name, RTLD_LAZY);
return handle; return handle;
} }
@ -92,18 +92,18 @@ inline auto library::open(const string& name, const string& path) -> bool {
if(handle) close(); if(handle) close();
if(path) { if(path) {
string filepath = {path, name, ".dll"}; string filepath = {path, name, ".dll"};
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath)); handle = (uintptr)LoadLibraryW(utf16_t(filepath));
} }
if(!handle) { if(!handle) {
string filepath = {name, ".dll"}; string filepath = {name, ".dll"};
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath)); handle = (uintptr)LoadLibraryW(utf16_t(filepath));
} }
return handle; return handle;
} }
inline auto library::openAbsolute(const string& name) -> bool { inline auto library::openAbsolute(const string& name) -> bool {
if(handle) close(); if(handle) close();
handle = (uintptr_t)LoadLibraryW(utf16_t(name)); handle = (uintptr)LoadLibraryW(utf16_t(name));
return handle; return handle;
} }

View File

@ -61,7 +61,7 @@ struct file : inode, varint {
return !(data.st_mode & S_IFDIR); return !(data.st_mode & S_IFDIR);
} }
static auto size(const string& filename) -> uintmax_t { static auto size(const string& filename) -> uintmax {
#if defined(API_POSIX) #if defined(API_POSIX)
struct stat data; struct stat data;
stat(filename, &data); stat(filename, &data);
@ -127,16 +127,16 @@ struct file : inode, varint {
return buffer[(file_offset++) & buffer_mask]; return buffer[(file_offset++) & buffer_mask];
} }
auto readl(uint length = 1) -> uintmax_t { auto readl(uint length = 1) -> uintmax {
uintmax_t data = 0; uintmax data = 0;
for(int i = 0; i < length; i++) { for(int i = 0; i < length; i++) {
data |= (uintmax_t)read() << (i << 3); data |= (uintmax)read() << (i << 3);
} }
return data; return data;
} }
auto readm(uint length = 1) -> uintmax_t { auto readm(uint length = 1) -> uintmax {
uintmax_t data = 0; uintmax data = 0;
while(length--) { while(length--) {
data <<= 8; data <<= 8;
data |= read(); data |= read();
@ -164,14 +164,14 @@ struct file : inode, varint {
if(file_offset > file_size) file_size = file_offset; if(file_offset > file_size) file_size = file_offset;
} }
auto writel(uintmax_t data, uint length = 1) -> void { auto writel(uintmax data, uint length = 1) -> void {
while(length--) { while(length--) {
write(data); write(data);
data >>= 8; data >>= 8;
} }
} }
auto writem(uintmax_t data, uint length = 1) -> void { auto writem(uintmax data, uint length = 1) -> void {
for(int i = length - 1; i >= 0; i--) { for(int i = length - 1; i >= 0; i--) {
write(data >> (i << 3)); write(data >> (i << 3));
} }
@ -200,7 +200,7 @@ struct file : inode, varint {
if(!fp) return; //file not open if(!fp) return; //file not open
buffer_flush(); buffer_flush();
intmax_t req_offset = file_offset; intmax req_offset = file_offset;
switch(index_) { switch(index_) {
case index::absolute: req_offset = offset; break; case index::absolute: req_offset = offset; break;
case index::relative: req_offset += offset; break; case index::relative: req_offset += offset; break;

View File

@ -114,7 +114,7 @@ auto Server::ipv4_scan() -> bool {
if(query.fd == fd4 && query.revents & POLLIN) { if(query.fd == fd4 && query.revents & POLLIN) {
++connections; ++connections;
thread::create([&](uintptr_t) { thread::create([&](uintptr) {
thread::detach(); thread::detach();
signed clientfd = -1; signed clientfd = -1;
@ -161,7 +161,7 @@ auto Server::ipv6_scan() -> bool {
if(query.fd == fd6 && query.revents & POLLIN) { if(query.fd == fd6 && query.revents & POLLIN) {
++connections; ++connections;
thread::create([&](uintptr_t) { thread::create([&](uintptr) {
thread::detach(); thread::detach();
signed clientfd = -1; signed clientfd = -1;

View File

@ -60,19 +60,36 @@ template<uint Bits> struct Natural {
struct Reference { struct Reference {
inline Reference(Natural& source, uint lo, uint hi) : source(source), Lo(lo), Hi(hi) {} inline Reference(Natural& source, uint lo, uint hi) : source(source), Lo(lo), Hi(hi) {}
inline operator type() const { inline auto get() const -> type {
const type RangeBits = Hi - Lo + 1; const type RangeBits = Hi - Lo + 1;
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask; const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
return (source & RangeMask) >> Lo; return (source & RangeMask) >> Lo;
} }
inline auto& operator=(const type value) { inline auto& set(const type value) {
const type RangeBits = Hi - Lo + 1; const type RangeBits = Hi - Lo + 1;
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask; const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
source = (source & ~RangeMask) | ((value << Lo) & RangeMask); source = (source & ~RangeMask) | ((value << Lo) & RangeMask);
return *this; return *this;
} }
inline operator type() const { return get(); }
inline auto& operator =(const type value) { return set( value); }
inline auto& operator &=(const type value) { return set(get() & value); }
inline auto& operator |=(const type value) { return set(get() | value); }
inline auto& operator ^=(const type value) { return set(get() ^ value); }
inline auto& operator<<=(const type value) { return set(get() << value); }
inline auto& operator>>=(const type value) { return set(get() >> value); }
inline auto& operator +=(const type value) { return set(get() + value); }
inline auto& operator -=(const type value) { return set(get() - value); }
inline auto& operator *=(const type value) { return set(get() * value); }
inline auto& operator /=(const type value) { return set(get() / value); }
inline auto& operator %=(const type value) { return set(get() % value); }
inline auto& operator++(int) { auto value = get(); set(value + 1); return value; }
inline auto& operator--(int) { auto value = get(); set(value - 1); return value; }
inline auto& operator++() { return set(get() + 1); }
inline auto& operator--() { return set(get() - 1); }
private: private:
Natural& source; Natural& source;
const type Lo; const type Lo;
@ -87,15 +104,15 @@ template<uint Bits> struct Natural {
inline auto bit(uint index) const -> const Reference { return {(Natural&)*this, index, index}; } inline auto bit(uint index) const -> const Reference { return {(Natural&)*this, index, index}; }
inline auto byte(uint index) const -> const Reference { return {(Natural&)*this, index * 8 + 0, index * 8 + 7}; } inline auto byte(uint index) const -> const Reference { return {(Natural&)*this, index * 8 + 0, index * 8 + 7}; }
inline auto clamp(uint bits) -> uintmax_t { inline auto clamp(uint bits) -> uintmax {
const uintmax_t b = 1ull << (bits - 1); const uintmax b = 1ull << (bits - 1);
const uintmax_t m = b * 2 - 1; const uintmax m = b * 2 - 1;
return data < m ? data : m; return data < m ? data : m;
} }
inline auto clip(uint bits) -> uintmax_t { inline auto clip(uint bits) -> uintmax {
const uintmax_t b = 1ull << (bits - 1); const uintmax b = 1ull << (bits - 1);
const uintmax_t m = b * 2 - 1; const uintmax m = b * 2 - 1;
return data & m; return data & m;
} }
@ -146,19 +163,36 @@ template<uint Bits> struct Integer {
struct Reference { struct Reference {
inline Reference(Integer& source, uint lo, uint hi) : source(source), Lo(lo), Hi(hi) {} inline Reference(Integer& source, uint lo, uint hi) : source(source), Lo(lo), Hi(hi) {}
inline operator utype() const { inline auto get() const -> utype {
const type RangeBits = Hi - Lo + 1; const type RangeBits = Hi - Lo + 1;
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask; const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
return ((utype)source & RangeMask) >> Lo; return ((utype)source & RangeMask) >> Lo;
} }
inline auto& operator=(const utype value) { inline auto& set(const utype value) {
const type RangeBits = Hi - Lo + 1; const type RangeBits = Hi - Lo + 1;
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask; const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
source = ((utype)source & ~RangeMask) | ((value << Lo) & RangeMask); source = ((utype)source & ~RangeMask) | ((value << Lo) & RangeMask);
return *this; return *this;
} }
inline operator utype() const { return get(); }
inline auto& operator =(const utype value) { return set( value); }
inline auto& operator &=(const utype value) { return set(get() & value); }
inline auto& operator |=(const utype value) { return set(get() | value); }
inline auto& operator ^=(const utype value) { return set(get() ^ value); }
inline auto& operator<<=(const utype value) { return set(get() << value); }
inline auto& operator>>=(const utype value) { return set(get() >> value); }
inline auto& operator +=(const utype value) { return set(get() + value); }
inline auto& operator -=(const utype value) { return set(get() - value); }
inline auto& operator *=(const utype value) { return set(get() * value); }
inline auto& operator /=(const utype value) { return set(get() / value); }
inline auto& operator %=(const utype value) { return set(get() % value); }
inline auto& operator++(int) { auto value = get(); set(value + 1); return value; }
inline auto& operator--(int) { auto value = get(); set(value - 1); return value; }
inline auto& operator++() { return set(get() + 1); }
inline auto& operator--() { return set(get() - 1); }
private: private:
Integer& source; Integer& source;
const uint Lo; const uint Lo;
@ -173,15 +207,15 @@ template<uint Bits> struct Integer {
inline auto bit(uint index) const -> const Reference { return {(Integer&)*this, index, index}; } inline auto bit(uint index) const -> const Reference { return {(Integer&)*this, index, index}; }
inline auto byte(uint index) const -> const Reference { return {(Integer&)*this, index * 8 + 0, index * 8 + 7}; } inline auto byte(uint index) const -> const Reference { return {(Integer&)*this, index * 8 + 0, index * 8 + 7}; }
inline auto clamp(uint bits) -> intmax_t { inline auto clamp(uint bits) -> intmax {
const intmax_t b = 1ull << (bits - 1); const intmax b = 1ull << (bits - 1);
const intmax_t m = b - 1; const intmax m = b - 1;
return data > m ? m : data < -b ? -b : data; return data > m ? m : data < -b ? -b : data;
} }
inline auto clip(uint bits) -> intmax_t { inline auto clip(uint bits) -> intmax {
const uintmax_t b = 1ull << (bits - 1); const uintmax b = 1ull << (bits - 1);
const uintmax_t m = b * 2 - 1; const uintmax m = b * 2 - 1;
return ((data & m) ^ b) - b; return ((data & m) ^ b) - b;
} }
@ -224,13 +258,147 @@ private:
type data; type data;
}; };
}
using boolean = nall::Boolean; using boolean = nall::Boolean;
using integer = nall::Integer<sizeof( int) * 8>;
using natural = nall::Natural<sizeof(uint) * 8>; using natural = nall::Natural<sizeof(uint) * 8>;
using integer = nall::Integer<sizeof( int) * 8>;
using real = nall::Real<sizeof(double) * 8>; using real = nall::Real<sizeof(double) * 8>;
using natural1 = nall::Natural< 1>;
using natural2 = nall::Natural< 2>;
using natural3 = nall::Natural< 3>;
using natural4 = nall::Natural< 4>;
using natural5 = nall::Natural< 5>;
using natural6 = nall::Natural< 6>;
using natural7 = nall::Natural< 7>;
using natural8 = nall::Natural< 8>;
using natural9 = nall::Natural< 9>;
using natural10 = nall::Natural<10>;
using natural11 = nall::Natural<11>;
using natural12 = nall::Natural<12>;
using natural13 = nall::Natural<13>;
using natural14 = nall::Natural<14>;
using natural15 = nall::Natural<15>;
using natural16 = nall::Natural<16>;
using natural17 = nall::Natural<17>;
using natural18 = nall::Natural<18>;
using natural19 = nall::Natural<19>;
using natural20 = nall::Natural<20>;
using natural21 = nall::Natural<21>;
using natural22 = nall::Natural<22>;
using natural23 = nall::Natural<23>;
using natural24 = nall::Natural<24>;
using natural25 = nall::Natural<25>;
using natural26 = nall::Natural<26>;
using natural27 = nall::Natural<27>;
using natural28 = nall::Natural<28>;
using natural29 = nall::Natural<29>;
using natural30 = nall::Natural<30>;
using natural31 = nall::Natural<31>;
using natural32 = nall::Natural<32>;
using natural33 = nall::Natural<33>;
using natural34 = nall::Natural<34>;
using natural35 = nall::Natural<35>;
using natural36 = nall::Natural<36>;
using natural37 = nall::Natural<37>;
using natural38 = nall::Natural<38>;
using natural39 = nall::Natural<39>;
using natural40 = nall::Natural<40>;
using natural41 = nall::Natural<41>;
using natural42 = nall::Natural<42>;
using natural43 = nall::Natural<43>;
using natural44 = nall::Natural<44>;
using natural45 = nall::Natural<45>;
using natural46 = nall::Natural<46>;
using natural47 = nall::Natural<47>;
using natural48 = nall::Natural<48>;
using natural49 = nall::Natural<49>;
using natural50 = nall::Natural<50>;
using natural51 = nall::Natural<51>;
using natural52 = nall::Natural<52>;
using natural53 = nall::Natural<53>;
using natural54 = nall::Natural<54>;
using natural55 = nall::Natural<55>;
using natural56 = nall::Natural<56>;
using natural57 = nall::Natural<57>;
using natural58 = nall::Natural<58>;
using natural59 = nall::Natural<59>;
using natural60 = nall::Natural<60>;
using natural61 = nall::Natural<61>;
using natural62 = nall::Natural<62>;
using natural63 = nall::Natural<63>;
using natural64 = nall::Natural<64>;
using integer1 = nall::Integer< 1>;
using integer2 = nall::Integer< 2>;
using integer3 = nall::Integer< 3>;
using integer4 = nall::Integer< 4>;
using integer5 = nall::Integer< 5>;
using integer6 = nall::Integer< 6>;
using integer7 = nall::Integer< 7>;
using integer8 = nall::Integer< 8>;
using integer9 = nall::Integer< 9>;
using integer10 = nall::Integer<10>;
using integer11 = nall::Integer<11>;
using integer12 = nall::Integer<12>;
using integer13 = nall::Integer<13>;
using integer14 = nall::Integer<14>;
using integer15 = nall::Integer<15>;
using integer16 = nall::Integer<16>;
using integer17 = nall::Integer<17>;
using integer18 = nall::Integer<18>;
using integer19 = nall::Integer<19>;
using integer20 = nall::Integer<20>;
using integer21 = nall::Integer<21>;
using integer22 = nall::Integer<22>;
using integer23 = nall::Integer<23>;
using integer24 = nall::Integer<24>;
using integer25 = nall::Integer<25>;
using integer26 = nall::Integer<26>;
using integer27 = nall::Integer<27>;
using integer28 = nall::Integer<28>;
using integer29 = nall::Integer<29>;
using integer30 = nall::Integer<30>;
using integer31 = nall::Integer<31>;
using integer32 = nall::Integer<32>;
using integer33 = nall::Integer<33>;
using integer34 = nall::Integer<34>;
using integer35 = nall::Integer<35>;
using integer36 = nall::Integer<36>;
using integer37 = nall::Integer<37>;
using integer38 = nall::Integer<38>;
using integer39 = nall::Integer<39>;
using integer40 = nall::Integer<40>;
using integer41 = nall::Integer<41>;
using integer42 = nall::Integer<42>;
using integer43 = nall::Integer<43>;
using integer44 = nall::Integer<44>;
using integer45 = nall::Integer<45>;
using integer46 = nall::Integer<46>;
using integer47 = nall::Integer<47>;
using integer48 = nall::Integer<48>;
using integer49 = nall::Integer<49>;
using integer50 = nall::Integer<50>;
using integer51 = nall::Integer<51>;
using integer52 = nall::Integer<52>;
using integer53 = nall::Integer<53>;
using integer54 = nall::Integer<54>;
using integer55 = nall::Integer<55>;
using integer56 = nall::Integer<56>;
using integer57 = nall::Integer<57>;
using integer58 = nall::Integer<58>;
using integer59 = nall::Integer<59>;
using integer60 = nall::Integer<60>;
using integer61 = nall::Integer<61>;
using integer62 = nall::Integer<62>;
using integer63 = nall::Integer<63>;
using integer64 = nall::Integer<64>;
using real32 = nall::Real<32>;
using real64 = nall::Real<64>;
//using real80 = nall::Real<80>;
}
using int1 = nall::Integer< 1>; using int1 = nall::Integer< 1>;
using int2 = nall::Integer< 2>; using int2 = nall::Integer< 2>;
using int3 = nall::Integer< 3>; using int3 = nall::Integer< 3>;
@ -360,7 +528,3 @@ using uint61 = nall::Natural<61>;
using uint62 = nall::Natural<62>; using uint62 = nall::Natural<62>;
using uint63 = nall::Natural<63>; using uint63 = nall::Natural<63>;
using uint64 = nall::Natural<64>; using uint64 = nall::Natural<64>;
using real32 = nall::Real<32>;
using real64 = nall::Real<64>;
//using real80 = nall::Real<80>;

View File

@ -110,7 +110,7 @@ struct shared_pointer {
template<typename U, typename = enable_if<is_compatible<U>>> template<typename U, typename = enable_if<is_compatible<U>>>
auto operator=(const shared_pointer<U>& source) -> shared_pointer& { auto operator=(const shared_pointer<U>& source) -> shared_pointer& {
if((uintptr_t)this != (uintptr_t)&source) { if((uintptr)this != (uintptr)&source) {
reset(); reset();
if((bool)source) { if((bool)source) {
manager = source.manager; manager = source.manager;
@ -122,7 +122,7 @@ struct shared_pointer {
template<typename U, typename = enable_if<is_compatible<U>>> template<typename U, typename = enable_if<is_compatible<U>>>
auto operator=(shared_pointer&& source) -> shared_pointer& { auto operator=(shared_pointer&& source) -> shared_pointer& {
if((uintptr_t)this != (uintptr_t)&source) { if((uintptr)this != (uintptr)&source) {
reset(); reset();
manager = source.manager; manager = source.manager;
source.manager = nullptr; source.manager = nullptr;

View File

@ -28,13 +28,14 @@
//note: (u)intmax actually mean it: use as many bits as is possible //note: (u)intmax actually mean it: use as many bits as is possible
#if defined(__SIZEOF_INT128__) #if defined(__SIZEOF_INT128__)
#define HAS_INT128
using int128_t = signed __int128; using int128_t = signed __int128;
using uint128_t = unsigned __int128; using uint128_t = unsigned __int128;
#define INTMAX_BITS 128
using intmax = int128_t; using intmax = int128_t;
using uintmax = uint128_t; using uintmax = uint128_t;
#else #else
#define INTMAX_BITS 64
using intmax = intmax_t; using intmax = intmax_t;
using uintmax = uintmax_t; using uintmax = uintmax_t;
#endif #endif

View File

@ -63,11 +63,11 @@ template<typename T> struct stringify;
template<typename... P> inline auto print(P&&...) -> void; template<typename... P> inline auto print(P&&...) -> void;
template<typename... P> inline auto print(FILE*, P&&...) -> void; template<typename... P> inline auto print(FILE*, P&&...) -> void;
template<typename T> inline auto pad(const T& value, long precision = 0, char padchar = ' ') -> string; template<typename T> inline auto pad(const T& value, long precision = 0, char padchar = ' ') -> string;
inline auto hex(uintmax_t value, long precision = 0, char padchar = '0') -> string; inline auto hex(uintmax value, long precision = 0, char padchar = '0') -> string;
inline auto octal(uintmax_t value, long precision = 0, char padchar = '0') -> string; inline auto octal(uintmax value, long precision = 0, char padchar = '0') -> string;
inline auto binary(uintmax_t value, long precision = 0, char padchar = '0') -> string; inline auto binary(uintmax value, long precision = 0, char padchar = '0') -> string;
template<typename T> inline auto pointer(const T* value, long precision = 0) -> string; template<typename T> inline auto pointer(const T* value, long precision = 0) -> string;
inline auto pointer(uintptr_t value, long precision = 0) -> string; inline auto pointer(uintptr value, long precision = 0) -> string;
//match.hpp //match.hpp
inline auto tokenize(const char* s, const char* p) -> bool; inline auto tokenize(const char* s, const char* p) -> bool;
@ -75,8 +75,8 @@ inline auto tokenize(string_vector& list, const char* s, const char* p) -> bool;
//utility.hpp //utility.hpp
inline auto slice(string_view self, int offset = 0, int length = -1) -> string; inline auto slice(string_view self, int offset = 0, int length = -1) -> string;
inline auto fromInteger(char* result, intmax_t value) -> char*; inline auto fromInteger(char* result, intmax value) -> char*;
inline auto fromNatural(char* result, uintmax_t value) -> char*; inline auto fromNatural(char* result, uintmax value) -> char*;
inline auto fromReal(char* str, long double value) -> uint; inline auto fromReal(char* str, long double value) -> uint;
struct string { struct string {
@ -168,9 +168,9 @@ public:
auto end() const -> const char* { return &data()[size()]; } auto end() const -> const char* { return &data()[size()]; }
//atoi.hpp //atoi.hpp
inline auto integer() const -> intmax_t; inline auto integer() const -> intmax;
inline auto natural() const -> uintmax_t; inline auto natural() const -> uintmax;
inline auto hex() const -> uintmax_t; inline auto hex() const -> uintmax;
inline auto real() const -> double; inline auto real() const -> double;
//core.hpp //core.hpp

View File

@ -2,15 +2,15 @@
namespace nall { namespace nall {
auto string::integer() const -> intmax_t { auto string::integer() const -> intmax {
return toInteger(data()); return toInteger(data());
} }
auto string::natural() const -> uintmax_t { auto string::natural() const -> uintmax {
return toNatural(data()); return toNatural(data());
} }
auto string::hex() const -> uintmax_t { auto string::hex() const -> uintmax {
return toHex(data()); return toHex(data());
} }

View File

@ -67,6 +67,15 @@ template<> struct stringify<signed long long> {
char _data[2 + sizeof(signed long long) * 3]; char _data[2 + sizeof(signed long long) * 3];
}; };
#if INTMAX_BITS >= 128
template<> struct stringify<int128_t> {
stringify(int128_t source) { fromInteger(_data, source); }
auto data() const -> const char* { return _data; }
auto size() const -> uint { return strlen(_data); }
char _data[2 + sizeof(int128_t) * 3];
};
#endif
template<uint Bits> struct stringify<Integer<Bits>> { template<uint Bits> struct stringify<Integer<Bits>> {
stringify(Integer<Bits> source) { fromInteger(_data, source); } stringify(Integer<Bits> source) { fromInteger(_data, source); }
auto data() const -> const char* { return _data; } auto data() const -> const char* { return _data; }
@ -111,6 +120,15 @@ template<> struct stringify<unsigned long long> {
char _data[1 + sizeof(unsigned long long) * 3]; char _data[1 + sizeof(unsigned long long) * 3];
}; };
#if INTMAX_BITS >= 128
template<> struct stringify<uint128_t> {
stringify(uint128_t source) { fromNatural(_data, source); }
auto data() const -> const char* { return _data; }
auto size() const -> uint { return strlen(_data); }
char _data[1 + sizeof(uint128_t) * 3];
};
#endif
template<uint Bits> struct stringify<Natural<Bits>> { template<uint Bits> struct stringify<Natural<Bits>> {
stringify(Natural<Bits> source) { fromNatural(_data, source); } stringify(Natural<Bits> source) { fromNatural(_data, source); }
auto data() const -> const char* { return _data; } auto data() const -> const char* { return _data; }

View File

@ -84,9 +84,9 @@ template<typename T> auto pad(const T& value, long precision, char padchar) -> s
return buffer; return buffer;
} }
auto hex(uintmax_t value, long precision, char padchar) -> string { auto hex(uintmax value, long precision, char padchar) -> string {
string buffer; string buffer;
buffer.resize(sizeof(uintmax_t) * 2); buffer.resize(sizeof(uintmax) * 2);
char* p = buffer.get(); char* p = buffer.get();
uint size = 0; uint size = 0;
@ -101,9 +101,9 @@ auto hex(uintmax_t value, long precision, char padchar) -> string {
return buffer; return buffer;
} }
auto octal(uintmax_t value, long precision, char padchar) -> string { auto octal(uintmax value, long precision, char padchar) -> string {
string buffer; string buffer;
buffer.resize(sizeof(uintmax_t) * 3); buffer.resize(sizeof(uintmax) * 3);
char* p = buffer.get(); char* p = buffer.get();
uint size = 0; uint size = 0;
@ -117,9 +117,9 @@ auto octal(uintmax_t value, long precision, char padchar) -> string {
return buffer; return buffer;
} }
auto binary(uintmax_t value, long precision, char padchar) -> string { auto binary(uintmax value, long precision, char padchar) -> string {
string buffer; string buffer;
buffer.resize(sizeof(uintmax_t) * 8); buffer.resize(sizeof(uintmax) * 8);
char* p = buffer.get(); char* p = buffer.get();
uint size = 0; uint size = 0;
@ -135,10 +135,10 @@ auto binary(uintmax_t value, long precision, char padchar) -> string {
template<typename T> auto pointer(const T* value, long precision) -> string { template<typename T> auto pointer(const T* value, long precision) -> string {
if(value == nullptr) return "(nullptr)"; if(value == nullptr) return "(nullptr)";
return {"0x", hex((uintptr_t)value, precision)}; return {"0x", hex((uintptr)value, precision)};
} }
auto pointer(uintptr_t value, long precision) -> string { auto pointer(uintptr value, long precision) -> string {
if(value == 0) return "(nullptr)"; if(value == 0) return "(nullptr)";
return {"0x", hex(value, precision)}; return {"0x", hex(value, precision)};
} }

View File

@ -32,7 +32,7 @@ struct ManagedNode {
protected: protected:
string _name; string _name;
string _value; string _value;
uintptr_t _metadata = 0; uintptr _metadata = 0;
vector<SharedNode> _children; vector<SharedNode> _children;
inline auto _evaluate(string query) const -> bool; inline auto _evaluate(string query) const -> bool;
@ -59,8 +59,8 @@ struct Node {
auto text() const -> string { return value().strip(); } auto text() const -> string { return value().strip(); }
auto boolean() const -> bool { return text() == "true"; } auto boolean() const -> bool { return text() == "true"; }
auto integer() const -> intmax_t { return text().integer(); } auto integer() const -> intmax { return text().integer(); }
auto natural() const -> uintmax_t { return text().natural(); } auto natural() const -> uintmax { return text().natural(); }
auto real() const -> double { return text().real(); } auto real() const -> double { return text().real(); }
auto setName(const string& name = "") -> Node& { shared->_name = name; return *this; } auto setName(const string& name = "") -> Node& { shared->_name = name; return *this; }

View File

@ -92,7 +92,7 @@ auto slice(string_view self, int offset, int length) -> string {
return result; return result;
} }
auto fromInteger(char* result, intmax_t value) -> char* { auto fromInteger(char* result, intmax value) -> char* {
bool negative = value < 0; bool negative = value < 0;
if(negative) value = -value; if(negative) value = -value;
@ -111,7 +111,7 @@ auto fromInteger(char* result, intmax_t value) -> char* {
return result; return result;
} }
auto fromNatural(char* result, uintmax_t value) -> char* { auto fromNatural(char* result, uintmax value) -> char* {
char buffer[64]; char buffer[64];
uint size = 0; uint size = 0;

View File

@ -19,13 +19,13 @@ namespace nall {
struct thread { struct thread {
inline auto join() -> void; inline auto join() -> void;
static inline auto create(const function<void (uintptr_t)>& callback, uintptr_t parameter = 0, uint stacksize = 0) -> thread; static inline auto create(const function<void (uintptr)>& callback, uintptr parameter = 0, uint stacksize = 0) -> thread;
static inline auto detach() -> void; static inline auto detach() -> void;
static inline auto exit() -> void; static inline auto exit() -> void;
struct context { struct context {
function<auto (uintptr_t) -> void> callback; function<auto (uintptr) -> void> callback;
uintptr_t parameter = 0; uintptr parameter = 0;
}; };
private: private:
@ -43,7 +43,7 @@ auto thread::join() -> void {
pthread_join(handle, nullptr); pthread_join(handle, nullptr);
} }
auto thread::create(const function<void (uintptr_t)>& callback, uintptr_t parameter, uint stacksize) -> thread { auto thread::create(const function<void (uintptr)>& callback, uintptr parameter, uint stacksize) -> thread {
thread instance; thread instance;
auto context = new thread::context; auto context = new thread::context;
@ -76,13 +76,13 @@ struct thread {
inline ~thread(); inline ~thread();
inline auto join() -> void; inline auto join() -> void;
static inline auto create(const function<void (uintptr_t)>& callback, uintptr_t parameter = 0, uint stacksize = 0) -> thread; static inline auto create(const function<void (uintptr)>& callback, uintptr parameter = 0, uint stacksize = 0) -> thread;
static inline auto detach() -> void; static inline auto detach() -> void;
static inline auto exit() -> void; static inline auto exit() -> void;
struct context { struct context {
function<auto (uintptr_t) -> void> callback; function<auto (uintptr) -> void> callback;
uintptr_t parameter = 0; uintptr parameter = 0;
}; };
private: private:
@ -111,7 +111,7 @@ auto thread::join() -> void {
} }
} }
auto thread::create(const function<void (uintptr_t)>& callback, uintptr_t parameter, uint stacksize) -> thread { auto thread::create(const function<void (uintptr)>& callback, uintptr parameter, uint stacksize) -> thread {
thread instance; thread instance;
auto context = new thread::context; auto context = new thread::context;

View File

@ -10,8 +10,8 @@ struct varint {
virtual auto read() -> uint8_t = 0; virtual auto read() -> uint8_t = 0;
virtual auto write(uint8_t) -> void = 0; virtual auto write(uint8_t) -> void = 0;
auto readvu() -> uintmax_t { auto readvu() -> uintmax {
uintmax_t data = 0, shift = 1; uintmax data = 0, shift = 1;
while(true) { while(true) {
uint8_t x = read(); uint8_t x = read();
data += (x & 0x7f) * shift; data += (x & 0x7f) * shift;
@ -22,15 +22,15 @@ struct varint {
return data; return data;
} }
auto readvs() -> intmax_t { auto readvs() -> intmax {
uintmax_t data = readvu(); uintmax data = readvu();
bool negate = data & 1; bool negate = data & 1;
data >>= 1; data >>= 1;
if(negate) data = ~data; if(negate) data = ~data;
return data; return data;
} }
auto writevu(uintmax_t data) -> void { auto writevu(uintmax data) -> void {
while(true) { while(true) {
uint8_t x = data & 0x7f; uint8_t x = data & 0x7f;
data >>= 7; data >>= 7;
@ -40,7 +40,7 @@ struct varint {
} }
} }
auto writevs(intmax_t data) -> void { auto writevs(intmax data) -> void {
bool negate = data < 0; bool negate = data < 0;
if(negate) data = ~data; if(negate) data = ~data;
data = (data << 1) | negate; data = (data << 1) | negate;

View File

@ -11,15 +11,15 @@ struct file : vfs::file {
return instance; return instance;
} }
auto size() const -> uintmax_t override { auto size() const -> uintmax override {
return _fp.size(); return _fp.size();
} }
auto offset() const -> uintmax_t override { auto offset() const -> uintmax override {
return _fp.offset(); return _fp.offset();
} }
auto seek(intmax_t offset_, index index_) -> void override { auto seek(intmax offset_, index index_) -> void override {
_fp.seek(offset_, (nall::file::index)index_); _fp.seek(offset_, (nall::file::index)index_);
} }

View File

@ -5,18 +5,18 @@ namespace nall { namespace vfs { namespace memory {
struct file : vfs::file { struct file : vfs::file {
~file() { delete[] _data; } ~file() { delete[] _data; }
static auto open(const uint8_t* data, uintmax_t size) -> vfs::shared::file { static auto open(const uint8_t* data, uintmax size) -> vfs::shared::file {
auto instance = shared_pointer<file>{new file}; auto instance = shared_pointer<file>{new file};
instance->_open(data, size); instance->_open(data, size);
return instance; return instance;
} }
auto size() const -> uintmax_t override { return _size; } auto size() const -> uintmax override { return _size; }
auto offset() const -> uintmax_t override { return _offset; } auto offset() const -> uintmax override { return _offset; }
auto seek(intmax_t offset, index mode) -> void override { auto seek(intmax offset, index mode) -> void override {
if(mode == index::absolute) _offset = (uintmax_t)offset; if(mode == index::absolute) _offset = (uintmax)offset;
if(mode == index::relative) _offset += (intmax_t)offset; if(mode == index::relative) _offset += (intmax)offset;
} }
auto read() -> uint8_t override { auto read() -> uint8_t override {
@ -34,15 +34,15 @@ private:
file(const file&) = delete; file(const file&) = delete;
auto operator=(const file&) -> file& = delete; auto operator=(const file&) -> file& = delete;
auto _open(const uint8_t* data, uintmax_t size) -> void { auto _open(const uint8_t* data, uintmax size) -> void {
_size = size; _size = size;
_data = new uint8_t[size]; _data = new uint8_t[size];
nall::memory::copy(_data, data, size); nall::memory::copy(_data, data, size);
} }
uint8_t* _data = nullptr; uint8_t* _data = nullptr;
uintmax_t _size = 0; uintmax _size = 0;
uintmax_t _offset = 0; uintmax _offset = 0;
}; };
}}} }}}

View File

@ -11,10 +11,10 @@ struct file {
virtual ~file() = default; virtual ~file() = default;
virtual auto size() const -> uintmax_t = 0; virtual auto size() const -> uintmax = 0;
virtual auto offset() const -> uintmax_t = 0; virtual auto offset() const -> uintmax = 0;
virtual auto seek(intmax_t offset, index = index::absolute) -> void = 0; virtual auto seek(intmax offset, index = index::absolute) -> void = 0;
virtual auto read() -> uint8_t = 0; virtual auto read() -> uint8_t = 0;
virtual auto write(uint8_t data) -> void = 0; virtual auto write(uint8_t data) -> void = 0;
virtual auto flush() -> void {} virtual auto flush() -> void {}
@ -23,19 +23,19 @@ struct file {
return offset() >= size(); return offset() >= size();
} }
auto read(void* vdata, uintmax_t bytes) -> void { auto read(void* vdata, uintmax bytes) -> void {
auto data = (uint8_t*)vdata; auto data = (uint8_t*)vdata;
while(bytes--) *data++ = read(); while(bytes--) *data++ = read();
} }
auto readl(uint bytes) -> uintmax_t { auto readl(uint bytes) -> uintmax {
uintmax_t data = 0; uintmax data = 0;
for(auto n : range(bytes)) data |= (uintmax_t)read() << n * 8; for(auto n : range(bytes)) data |= (uintmax)read() << n * 8;
return data; return data;
} }
auto readm(uint bytes) -> uintmax_t { auto readm(uint bytes) -> uintmax {
uintmax_t data = 0; uintmax data = 0;
for(auto n : range(bytes)) data = data << 8 | read(); for(auto n : range(bytes)) data = data << 8 | read();
return data; return data;
} }
@ -47,16 +47,16 @@ struct file {
return s; return s;
} }
auto write(const void* vdata, uintmax_t bytes) -> void { auto write(const void* vdata, uintmax bytes) -> void {
auto data = (const uint8_t*)vdata; auto data = (const uint8_t*)vdata;
while(bytes--) write(*data++); while(bytes--) write(*data++);
} }
auto writel(uintmax_t data, uint bytes) -> void { auto writel(uintmax data, uint bytes) -> void {
for(auto n : range(bytes)) write(data), data >>= 8; for(auto n : range(bytes)) write(data), data >>= 8;
} }
auto writem(uintmax_t data, uint bytes) -> void { auto writem(uintmax data, uint bytes) -> void {
for(auto n : rrange(bytes)) write(data >> n * 8); for(auto n : rrange(bytes)) write(data >> n * 8);
} }

View File

@ -86,7 +86,7 @@ auto detour::insert(const string& moduleName, const string& functionName, void*&
DWORD privileges; DWORD privileges;
VirtualProtect((void*)mirrorData, 512, PAGE_EXECUTE_READWRITE, &privileges); VirtualProtect((void*)mirrorData, 512, PAGE_EXECUTE_READWRITE, &privileges);
VirtualProtect((void*)sourceData, 256, PAGE_EXECUTE_READWRITE, &privileges); VirtualProtect((void*)sourceData, 256, PAGE_EXECUTE_READWRITE, &privileges);
uintmax address = (uintmax)target - ((uintmax)sourceData + 5); uint64_t address = (uint64_t)target - ((uint64_t)sourceData + 5);
sourceData[0] = 0xe9; //jmp target sourceData[0] = 0xe9; //jmp target
sourceData[1] = address >> 0; sourceData[1] = address >> 0;
sourceData[2] = address >> 8; sourceData[2] = address >> 8;
@ -157,11 +157,11 @@ auto detour::mirror(uint8* target, const uint8* source) -> uint {
break; break;
case RelNear: { case RelNear: {
source++; source++;
uintmax sourceAddress = (uintmax)source + 1 + (int8)*source; uint64_t sourceAddress = (uint64_t)source + 1 + (int8)*source;
*target++ = opcode->modify; *target++ = opcode->modify;
if(opcode->modify >> 8) *target++ = opcode->modify >> 8; if(opcode->modify >> 8) *target++ = opcode->modify >> 8;
uintmax targetAddress = (uintmax)target + 4; uint64_t targetAddress = (uint64_t)target + 4;
uintmax address = sourceAddress - targetAddress; uint64_t address = sourceAddress - targetAddress;
*target++ = address >> 0; *target++ = address >> 0;
*target++ = address >> 8; *target++ = address >> 8;
*target++ = address >> 16; *target++ = address >> 16;
@ -173,7 +173,7 @@ auto detour::mirror(uint8* target, const uint8* source) -> uint {
size -= opcode->length; size -= opcode->length;
} }
uintmax address = (entryPoint + detour::length(entryPoint)) - (target + 5); uint64_t address = (entryPoint + detour::length(entryPoint)) - (target + 5);
*target++ = 0xe9; //jmp entryPoint *target++ = 0xe9; //jmp entryPoint
*target++ = address >> 0; *target++ = address >> 0;
*target++ = address >> 8; *target++ = address >> 8;