getting floating point stuff now
This commit is contained in:
+15
-12
@@ -31,7 +31,7 @@ ircolib::u32 broadway::fetch(mem &mem) {
|
||||
void broadway::decode_special2(ircolib::u32 instr, mem &mem) {
|
||||
auto secondary = utils::secondary(instr);
|
||||
switch (secondary) {
|
||||
case 0x0D2: // mtsr
|
||||
case 0x0D2:
|
||||
ircolib::warn("broadway TODO mtsr (pc 0x{:08X})", pc - 4);
|
||||
break;
|
||||
case 0x153:
|
||||
@@ -66,19 +66,19 @@ void broadway::decode_special1(ircolib::u32 instr, mem &mem) {
|
||||
|
||||
void broadway::execute(ircolib::u32 instr, mem &mem) {
|
||||
switch (utils::primary(instr)) {
|
||||
case 11: // cmpi crfD, L, rA, simm
|
||||
case 11:
|
||||
cmpi(instr);
|
||||
break;
|
||||
case 14: // addi rd, ra, simm
|
||||
case 14:
|
||||
addi(instr);
|
||||
break;
|
||||
case 15: // addis rd, ra, simm
|
||||
case 15:
|
||||
addis(instr);
|
||||
break;
|
||||
case 16: // bcx BO, BI, target
|
||||
case 16:
|
||||
bcx(instr);
|
||||
break;
|
||||
case 18: // bx target
|
||||
case 18:
|
||||
bx(instr);
|
||||
break;
|
||||
case 19:
|
||||
@@ -87,7 +87,7 @@ void broadway::execute(ircolib::u32 instr, mem &mem) {
|
||||
case 21:
|
||||
rlwinm(instr);
|
||||
break;
|
||||
case 24: // ori ra, rs, uimm
|
||||
case 24:
|
||||
ori(instr);
|
||||
break;
|
||||
case 25:
|
||||
@@ -99,21 +99,24 @@ void broadway::execute(ircolib::u32 instr, mem &mem) {
|
||||
case 31:
|
||||
decode_special2(instr, mem);
|
||||
break;
|
||||
case 32: // lwz rd, d(ra)
|
||||
case 32:
|
||||
lwz(instr, mem);
|
||||
break;
|
||||
case 33: // lwz rd, d(ra)
|
||||
case 33:
|
||||
lwzu(instr, mem);
|
||||
break;
|
||||
case 36: // stw rs, d(ra)
|
||||
case 36:
|
||||
stw(instr, mem);
|
||||
break;
|
||||
case 37: // stwu rs, d(ra)
|
||||
case 37:
|
||||
stwu(instr, mem);
|
||||
break;
|
||||
case 44: // stwu rs, d(ra)
|
||||
case 44:
|
||||
sth(instr, mem);
|
||||
break;
|
||||
case 50:
|
||||
lfd(instr, mem);
|
||||
break;
|
||||
default:
|
||||
std::println("broadway::execute unimplemented instruction 0x{:08X} / 0b{:032b}", instr, instr);
|
||||
std::println("disassembly:");
|
||||
|
||||
@@ -30,12 +30,20 @@ struct broadway {
|
||||
ircolib::u32 raw;
|
||||
} xer;
|
||||
|
||||
void set_cr(ircolib::u8 value, ircolib::u8 index) {
|
||||
cr &= ~(0xffff << index * 4);
|
||||
cr |= (value << index * 4);
|
||||
}
|
||||
|
||||
bool get_cr_bit(ircolib::u8 index, ircolib::u8 bit) { return (cr >> index * 4) & (1 << (4 - bit)); }
|
||||
|
||||
// bat registers indexes
|
||||
static constexpr std::size_t BAT_LOWER_OFFSET = 0;
|
||||
static constexpr std::size_t BAT_UPPER_OFFSET = 8;
|
||||
|
||||
std::array<ircolib::u32, 16> ibat, dbat;
|
||||
std::array<ircolib::u32, 32> gpr{};
|
||||
std::array<double, 32> fpr{};
|
||||
// ircolib::u32 const_gpr_lookup{};
|
||||
csh capstone;
|
||||
// Xbyak::CodeGenerator code;
|
||||
@@ -60,10 +68,21 @@ struct broadway {
|
||||
void stwu(ircolib::u32, mem &);
|
||||
void sth(ircolib::u32, mem &);
|
||||
void lwz(ircolib::u32, mem &);
|
||||
void lfd(ircolib::u32, mem &);
|
||||
void bclrx(ircolib::u32);
|
||||
void cmpi(ircolib::u32);
|
||||
void rlwinm(ircolib::u32);
|
||||
void lwzu(ircolib::u32, mem &);
|
||||
void rfi(ircolib::u32);
|
||||
|
||||
inline void cr0_update(bool condition, ircolib::s32 result) {
|
||||
if (condition) {
|
||||
const bool b0 = result < 0;
|
||||
const bool b1 = result >= 0;
|
||||
const bool b2 = result == 0;
|
||||
const bool b3 = xer.so;
|
||||
set_cr((b0 << 3) | (b1 << 2) | (b2 << 1) | (b3 << 0), 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace weee::core
|
||||
|
||||
@@ -50,7 +50,7 @@ bool broadway::test_cond_and_ctr(ircolib::u32 instr) {
|
||||
const ircolib::u8 bo = (instr >> 21) & 0x1f;
|
||||
const ircolib::u8 bi = (instr >> 16) & 0x1f;
|
||||
const bool ctr_ok = ircolib::is_bit_set(bo, 2) || ((--ctr == 0) == (ircolib::is_bit_set(bo, 1)));
|
||||
const bool cond_ok = ircolib::is_bit_set(bo, 4) || (ircolib::is_bit_set(cr, 32 - bi) == ircolib::is_bit_set(bo, 3));
|
||||
const bool cond_ok = ircolib::is_bit_set(bo, 4) || (get_cr_bit(0, bi) == ircolib::is_bit_set(bo, 3));
|
||||
|
||||
return cond_ok && ctr_ok;
|
||||
}
|
||||
@@ -175,6 +175,18 @@ void broadway::lwz(ircolib::u32 instr, mem &mem) {
|
||||
gpr[utils::RD(instr)] = mem.read32(ea);
|
||||
}
|
||||
|
||||
void broadway::lfd(ircolib::u32 instr, mem &mem) {
|
||||
ircolib::u32 b = gpr[utils::RA(instr)];
|
||||
if (utils::RA(instr) == 0)
|
||||
b = 0;
|
||||
|
||||
ircolib::u32 ea = ircolib::s32(b) + utils::SIMM(instr);
|
||||
double val;
|
||||
ircolib::u64 read = mem.read64(ea);
|
||||
memcpy(&val, &read, 8);
|
||||
fpr[utils::RD(instr)] = val;
|
||||
}
|
||||
|
||||
void broadway::bclrx(ircolib::u32 instr) {
|
||||
const bool link = instr & 1;
|
||||
|
||||
@@ -195,9 +207,8 @@ void broadway::cmpi(ircolib::u32 instr) {
|
||||
else
|
||||
c = 0b100;
|
||||
|
||||
const ircolib::u32 result = ((xer.so << 3) | c) << (28 - 4 * utils::crfD(instr));
|
||||
cr &= ~(0xffff << (28 - 4 * utils::crfD(instr)));
|
||||
cr |= result;
|
||||
const ircolib::u8 result = (xer.so << 3) | c;
|
||||
set_cr(result, utils::crfD(instr));
|
||||
}
|
||||
|
||||
void broadway::rlwinm(ircolib::u32 instr) {
|
||||
@@ -222,6 +233,8 @@ void broadway::lwzu(ircolib::u32 instr, mem &mem) {
|
||||
void broadway::rfi(ircolib::u32 instr) { pc = srr0; }
|
||||
|
||||
void broadway::andi(ircolib::u32 instr) {
|
||||
gpr[utils::RA(instr)] = gpr[utils::RS(instr)] & (ircolib::u32(utils::UIMM(instr)) << 16);
|
||||
const ircolib::s32 result = gpr[utils::RS(instr)] & utils::UIMM(instr);
|
||||
gpr[utils::RA(instr)] = result;
|
||||
cr0_update(true, result);
|
||||
}
|
||||
} // namespace weee::core
|
||||
|
||||
@@ -55,10 +55,10 @@ void video_interface::write32(ircolib::u32 addr, ircolib::u32 value) {
|
||||
bboi.raw = value;
|
||||
break;
|
||||
case 0x1c:
|
||||
tfbl.raw = value;
|
||||
tfbl.raw = value & 0x1ffffe00;
|
||||
break;
|
||||
case 0x24:
|
||||
bfbl.raw = value;
|
||||
bfbl.raw = value & 0x10fffe00;
|
||||
break;
|
||||
case 0x4c:
|
||||
case 0x50:
|
||||
|
||||
+13
-16
@@ -8,6 +8,14 @@ struct video_interface {
|
||||
video_interface(mem &);
|
||||
void write16(ircolib::u32, ircolib::u16);
|
||||
void write32(ircolib::u32, ircolib::u32);
|
||||
ircolib::u32 xfb_top_addr() {
|
||||
auto addr = tfbl.fbb;
|
||||
if (tfbl.page) {
|
||||
addr <<= 5;
|
||||
}
|
||||
|
||||
return addr + tfbl.xof;
|
||||
}
|
||||
|
||||
union DCR {
|
||||
struct {
|
||||
@@ -80,26 +88,15 @@ struct video_interface {
|
||||
ircolib::u32 raw;
|
||||
} bbei, bboi;
|
||||
|
||||
union TFBL {
|
||||
union FBR {
|
||||
struct {
|
||||
unsigned : 9;
|
||||
unsigned fbb : 15;
|
||||
unsigned : 3;
|
||||
unsigned page : 1;
|
||||
unsigned xof : 4;
|
||||
unsigned : 4;
|
||||
unsigned fbb : 24;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} tfbl;
|
||||
|
||||
union BFBL {
|
||||
struct {
|
||||
unsigned : 9;
|
||||
unsigned fbb : 15;
|
||||
unsigned y : 8;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} bfbl;
|
||||
} tfbl, bfbl;
|
||||
|
||||
union FCT012 {
|
||||
struct {
|
||||
|
||||
@@ -13,6 +13,9 @@ mem::mem() : vi(*this) {
|
||||
register_read32_handler(0x00000000, 0x017fffff,
|
||||
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u32>(mem1, addr); });
|
||||
|
||||
register_read64_handler(0x00000000, 0x017fffff,
|
||||
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u64>(mem1, addr); });
|
||||
|
||||
register_write16_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u16 value) {
|
||||
ircolib::write_access<ircolib::u16>(mem1, addr, value);
|
||||
});
|
||||
@@ -20,6 +23,10 @@ mem::mem() : vi(*this) {
|
||||
register_write32_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) {
|
||||
ircolib::write_access<ircolib::u32>(mem1, addr, value);
|
||||
});
|
||||
|
||||
register_write64_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) {
|
||||
ircolib::write_access<ircolib::u64>(mem1, addr, value);
|
||||
});
|
||||
}
|
||||
|
||||
void mem::copy(std::vector<ircolib::u8> &src, const ircolib::u32 offset) {
|
||||
|
||||
@@ -78,6 +78,7 @@ struct mem {
|
||||
std::vector<write_handler<ircolib::u32>> write32_handlers{};
|
||||
std::vector<write_handler<ircolib::u64>> write64_handlers{};
|
||||
|
||||
public:
|
||||
video_interface vi;
|
||||
};
|
||||
} // namespace weee::core
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace fs = std::filesystem;
|
||||
int main(int argc, char **argv) {
|
||||
weee::core::mem mem;
|
||||
weee::core::broadway broadway;
|
||||
weee::core::video_interface &vi = mem.vi;
|
||||
std::string binName;
|
||||
|
||||
cflags::cflags flags;
|
||||
@@ -68,7 +69,7 @@ int main(int argc, char **argv) {
|
||||
open = false;
|
||||
}
|
||||
|
||||
SDL_ConvertPixels(640, 240, SDL_PIXELFORMAT_UYVY, &mem.mem1[0x104000], 640 * 4, SDL_PIXELFORMAT_BGR24,
|
||||
SDL_ConvertPixels(640, 240, SDL_PIXELFORMAT_UYVY, &mem.mem1[vi.xfb_top_addr()], 640 * 4, SDL_PIXELFORMAT_BGR24,
|
||||
rgbTexture.data(), 640 * 3);
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
Reference in New Issue
Block a user