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