booogs
This commit is contained in:
@@ -3,10 +3,13 @@
|
|||||||
#include <mem.hpp>
|
#include <mem.hpp>
|
||||||
|
|
||||||
namespace weee::core {
|
namespace weee::core {
|
||||||
void broadway::add(ircolib::u32 instr) { gpr[utils::RD(instr)] = gpr[utils::RA(instr)] + gpr[utils::RB(instr)]; }
|
void broadway::add(ircolib::u32 instr) {
|
||||||
|
gpr[utils::RD(instr)] = gpr[utils::RA(instr)] + gpr[utils::RB(instr)];
|
||||||
|
cr0_update(instr & 1, gpr[utils::RD(instr)]);
|
||||||
|
}
|
||||||
|
|
||||||
void broadway::addi(ircolib::u32 instr) {
|
void broadway::addi(ircolib::u32 instr) {
|
||||||
if (utils::RA(instr) == 0) { // lis
|
if (utils::RA(instr) == 0) { // li
|
||||||
gpr[utils::RD(instr)] = ircolib::s32(utils::SIMM(instr));
|
gpr[utils::RD(instr)] = ircolib::s32(utils::SIMM(instr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -145,12 +148,14 @@ void broadway::stwu(ircolib::u32 instr, mem &mem) {
|
|||||||
|
|
||||||
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
||||||
auto _ = mem.write32(EA, gpr[utils::RS(instr)])
|
auto _ = mem.write32(EA, gpr[utils::RS(instr)])
|
||||||
.and_then([&] { return std::expected<void, std::string>(); })
|
.and_then([&] {
|
||||||
|
gpr[utils::RA(instr)] = EA;
|
||||||
|
return std::expected<void, std::string>();
|
||||||
|
})
|
||||||
.or_else([&](std::string e) {
|
.or_else([&](std::string e) {
|
||||||
ircolib::panic("stwu broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
ircolib::panic("stwu broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
||||||
return std::expected<void, std::string>();
|
return std::expected<void, std::string>();
|
||||||
});
|
});
|
||||||
gpr[utils::RA(instr)] = EA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway::stbu(ircolib::u32 instr, mem &mem) {
|
void broadway::stbu(ircolib::u32 instr, mem &mem) {
|
||||||
@@ -159,12 +164,14 @@ void broadway::stbu(ircolib::u32 instr, mem &mem) {
|
|||||||
|
|
||||||
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
||||||
auto _ = mem.write8(EA, gpr[utils::RS(instr)])
|
auto _ = mem.write8(EA, gpr[utils::RS(instr)])
|
||||||
.and_then([&] { return std::expected<void, std::string>(); })
|
.and_then([&] {
|
||||||
|
gpr[utils::RA(instr)] = EA;
|
||||||
|
return std::expected<void, std::string>();
|
||||||
|
})
|
||||||
.or_else([&](std::string e) {
|
.or_else([&](std::string e) {
|
||||||
ircolib::panic("stbu broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
ircolib::panic("stbu broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
||||||
return std::expected<void, std::string>();
|
return std::expected<void, std::string>();
|
||||||
});
|
});
|
||||||
gpr[utils::RA(instr)] = EA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway::stw(ircolib::u32 instr, mem &mem) {
|
void broadway::stw(ircolib::u32 instr, mem &mem) {
|
||||||
@@ -186,8 +193,7 @@ void broadway::sth(ircolib::u32 instr, mem &mem) {
|
|||||||
if (utils::RA(instr) == 0)
|
if (utils::RA(instr) == 0)
|
||||||
b = 0;
|
b = 0;
|
||||||
|
|
||||||
const ircolib::s32 d = utils::SIMM(instr);
|
const ircolib::u32 EA = b + utils::SIMM(instr);
|
||||||
const ircolib::u32 EA = b + d;
|
|
||||||
|
|
||||||
auto _ = mem.write16(EA, ircolib::u16(gpr[utils::RS(instr)]))
|
auto _ = mem.write16(EA, ircolib::u16(gpr[utils::RS(instr)]))
|
||||||
.and_then([&] { return std::expected<void, std::string>(); })
|
.and_then([&] { return std::expected<void, std::string>(); })
|
||||||
@@ -219,16 +225,15 @@ void broadway::lfd(ircolib::u32 instr, mem &mem) {
|
|||||||
b = 0;
|
b = 0;
|
||||||
|
|
||||||
ircolib::u32 ea = ircolib::s32(b) + utils::SIMM(instr);
|
ircolib::u32 ea = ircolib::s32(b) + utils::SIMM(instr);
|
||||||
double val;
|
|
||||||
ircolib::u64 read = mem.read64(ea)
|
fgrs[utils::RD(instr)].ps0 =
|
||||||
|
mem.read64(ea)
|
||||||
.and_then([&](ircolib::u64 val) { return std::expected<ircolib::u64, std::string>(val); })
|
.and_then([&](ircolib::u64 val) { return std::expected<ircolib::u64, std::string>(val); })
|
||||||
.or_else([&](std::string e) {
|
.or_else([&](std::string e) {
|
||||||
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
||||||
return std::expected<ircolib::u64, std::string>();
|
return std::expected<ircolib::u64, std::string>();
|
||||||
})
|
})
|
||||||
.value();
|
.value();
|
||||||
memcpy(&val, &read, 8);
|
|
||||||
fgrs[utils::RD(instr)].ps0 = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway::bclrx(ircolib::u32 instr) {
|
void broadway::bclrx(ircolib::u32 instr) {
|
||||||
@@ -305,9 +310,15 @@ void broadway::rlwinm(ircolib::u32 instr) {
|
|||||||
ircolib::u32 r = std::rotl(gpr[utils::RS(instr)], sh);
|
ircolib::u32 r = std::rotl(gpr[utils::RS(instr)], sh);
|
||||||
const ircolib::u8 mb = (instr >> 6) & 0x1f;
|
const ircolib::u8 mb = (instr >> 6) & 0x1f;
|
||||||
const ircolib::u8 me = (instr >> 1) & 0x1f;
|
const ircolib::u8 me = (instr >> 1) & 0x1f;
|
||||||
|
const ircolib::u32 start = 0xffffffff >> mb;
|
||||||
|
const ircolib::u32 end = 0x7fffffff >> me;
|
||||||
|
ircolib::u32 mask = start ^ end;
|
||||||
|
if (mb > me)
|
||||||
|
mask = ~mask;
|
||||||
|
|
||||||
r &= ~((0xFFFF'FFFF >> mb) << me);
|
r &= mask;
|
||||||
gpr[utils::RA(instr)] = r;
|
gpr[utils::RA(instr)] = r;
|
||||||
|
cr0_update(instr & 1, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway::lwzu(ircolib::u32 instr, mem &mem) {
|
void broadway::lwzu(ircolib::u32 instr, mem &mem) {
|
||||||
@@ -316,16 +327,21 @@ void broadway::lwzu(ircolib::u32 instr, mem &mem) {
|
|||||||
|
|
||||||
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
||||||
gpr[utils::RD(instr)] = mem.read32(EA)
|
gpr[utils::RD(instr)] = mem.read32(EA)
|
||||||
.and_then([&](ircolib::u32 val) { return std::expected<ircolib::u32, std::string>(val); })
|
.and_then([&](ircolib::u32 val) {
|
||||||
|
gpr[utils::RA(instr)] = EA;
|
||||||
|
return std::expected<ircolib::u32, std::string>(val);
|
||||||
|
})
|
||||||
.or_else([&](std::string e) {
|
.or_else([&](std::string e) {
|
||||||
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
||||||
return std::expected<ircolib::u32, std::string>();
|
return std::expected<ircolib::u32, std::string>();
|
||||||
})
|
})
|
||||||
.value();
|
.value();
|
||||||
gpr[utils::RA(instr)] = EA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway::rfi(ircolib::u32 instr) { pc = srr0; }
|
void broadway::rfi(ircolib::u32 instr) {
|
||||||
|
pc = srr0;
|
||||||
|
ircolib::clear_bit(msr, 13);
|
||||||
|
}
|
||||||
|
|
||||||
void broadway::andi(ircolib::u32 instr) {
|
void broadway::andi(ircolib::u32 instr) {
|
||||||
const ircolib::s32 result = gpr[utils::RS(instr)] & utils::UIMM(instr);
|
const ircolib::s32 result = gpr[utils::RS(instr)] & utils::UIMM(instr);
|
||||||
@@ -370,12 +386,12 @@ void broadway::nand(ircolib::u32 instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void broadway::subf(ircolib::u32 instr) {
|
void broadway::subf(ircolib::u32 instr) {
|
||||||
gpr[utils::RD(instr)] = ~(gpr[utils::RA(instr)] + gpr[utils::RB(instr)] + 1);
|
gpr[utils::RD(instr)] = ~gpr[utils::RA(instr)] + gpr[utils::RB(instr)];
|
||||||
cr0_update(instr & 1, gpr[utils::RD(instr)]);
|
cr0_update(instr & 1, gpr[utils::RD(instr)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway:: or (ircolib::u32 instr) {
|
void broadway:: or (ircolib::u32 instr) {
|
||||||
gpr[utils::RA(instr)] = gpr[utils::RS(instr)] & gpr[utils::RB(instr)];
|
gpr[utils::RA(instr)] = gpr[utils::RS(instr)] | gpr[utils::RB(instr)];
|
||||||
cr0_update(instr & 1, gpr[utils::RA(instr)]);
|
cr0_update(instr & 1, gpr[utils::RA(instr)]);
|
||||||
}
|
}
|
||||||
} // namespace weee::core
|
} // namespace weee::core
|
||||||
|
|||||||
Reference in New Issue
Block a user