diff --git a/core/broadway.cpp b/core/broadway.cpp index f786754..572b6aa 100644 --- a/core/broadway.cpp +++ b/core/broadway.cpp @@ -40,7 +40,20 @@ void broadway::decode_special(ircolib::u32 instr, mem &mem) { add(instr); break; default: - ircolib::panic("broadway unknown special 0x{:04X}", utils::secondary(instr)); + ircolib::panic("broadway unknown special 0x{:04X} (pc 0x{:08X})", utils::secondary(instr), pc - 4); + } +} + +void broadway::decode_branch(ircolib::u32 instr, mem &mem) { + switch (utils::secondary(instr)) { + case 0x10: + bclrx(instr); + break; + case 0x32: + rfi(instr); + break; + default: + ircolib::panic("broadway unknown branch 0x{:04X} (pc 0x{:08X})", utils::secondary(instr), pc - 4); } } @@ -62,7 +75,7 @@ void broadway::execute(ircolib::u32 instr, mem &mem) { bx(instr); break; case 19: - bclrx(instr); + decode_branch(instr, mem); break; case 21: rlwinm(instr); diff --git a/core/broadway.hpp b/core/broadway.hpp index 0bd9cc2..65a6c38 100644 --- a/core/broadway.hpp +++ b/core/broadway.hpp @@ -17,7 +17,7 @@ struct broadway { void execute(ircolib::u32, mem &); bool disasm_available = true; - ircolib::u32 pc = 0, lr = 0, ctr = 0, cr = 0; + ircolib::u32 pc = 0, lr = 0, ctr = 0, cr = 0, srr0; union { struct { unsigned bytecount : 7; @@ -37,6 +37,7 @@ struct broadway { // instructions void decode_special(ircolib::u32, mem &); + void decode_branch(ircolib::u32, mem &); void add(ircolib::u32); void addis(ircolib::u32); @@ -55,5 +56,6 @@ struct broadway { void cmpi(ircolib::u32); void rlwinm(ircolib::u32); void lwzu(ircolib::u32, mem &); + void rfi(ircolib::u32); }; } // namespace weee::core diff --git a/core/broadway/instructions.cpp b/core/broadway/instructions.cpp index b372bd6..eb74710 100644 --- a/core/broadway/instructions.cpp +++ b/core/broadway/instructions.cpp @@ -94,8 +94,15 @@ void broadway::mfspr(ircolib::u32 instr) { case 0b0100100000: gpr[utils::RD(instr)] = ctr; break; + case 0b1101000000: + gpr[utils::RD(instr)] = srr0; + break; + case 0b1101100000: + // srr1 + break; default: - ircolib::panic("broadway::mfspr with unimplemented spr field of value 0x{:04X}", spr_field); + ircolib::panic("broadway::mfspr with unimplemented spr field of value 0x{:04X} (pc 0x{:08X})", spr_field, + pc - 4); } } @@ -111,8 +118,15 @@ void broadway::mtspr(ircolib::u32 instr) { case 0b0100100000: ctr = gpr[utils::RS(instr)]; break; + case 0b1101000000: + srr0 = gpr[utils::RS(instr)]; + break; + case 0b1101100000: + // srr1 + break; default: - ircolib::panic("broadway::mtspr with unimplemented spr field of value 0x{:04X}", spr_field); + ircolib::panic("broadway::mtspr with unimplemented spr field of value 0x{:04X} (pc 0x{:08X})", spr_field, + pc - 4); } } @@ -161,10 +175,10 @@ void broadway::bclrx(ircolib::u32 instr) { if (!ircolib::is_bit_set(instr)) { if (!ircolib::is_bit_set(instr)) - ircolib::panic("broadway::bclrx unimplemented variants with bit 24 == 0"); + ircolib::panic("broadway::bclrx unimplemented variants with bit 24 == 0 (pc 0x{:08X})", pc - 4); if (!ircolib::is_bit_set(instr)) - ircolib::panic("broadway::bclrx unimplemented variants with bit 23 == 0"); + ircolib::panic("broadway::bclrx unimplemented variants with bit 23 == 0 (pc 0x{:08X})", pc - 4); const ircolib::u8 bi = (instr >> 16) & 0x1f; @@ -241,4 +255,6 @@ void broadway::lwzu(ircolib::u32 instr, mem &mem) { gpr[utils::RD(instr)] = mem.read32(EA); gpr[utils::RA(instr)] = EA; } + +void broadway::rfi(ircolib::u32 instr) { pc = srr0; } } // namespace weee::core diff --git a/core/broadway/utils.hpp b/core/broadway/utils.hpp index 017785f..038f32f 100644 --- a/core/broadway/utils.hpp +++ b/core/broadway/utils.hpp @@ -3,7 +3,7 @@ namespace weee::core::utils { static inline ircolib::u8 primary(ircolib::u32 instr) { return (instr >> 26) & 0x3f; } -static inline ircolib::u16 secondary(ircolib::u32 instr) { return (instr >> 1) & 0x1ff; } +static inline ircolib::u16 secondary(ircolib::u32 instr) { return (instr >> 1) & 0x3ff; } static inline ircolib::u8 RD(ircolib::u32 instr) { return (instr >> 21) & 0x1f; } static inline ircolib::u8 RB(ircolib::u32 instr) { return (instr >> 11) & 0x1f; } static inline ircolib::u8 RS(ircolib::u32 instr) { return RD(instr); } diff --git a/main.cpp b/main.cpp index 1e7f13f..7382867 100644 --- a/main.cpp +++ b/main.cpp @@ -34,8 +34,14 @@ int main(int argc, char **argv) { }, "DOL binary to load"); - if (!flags.parse(argc, argv)) + if (argc < 3) { + flags.print_usage("./weee ", + "Available options:", "https://git.irco.sh/weeemu/weee"); return -1; + } + + if (!flags.parse(argc, argv)) + return -2; SDL_Init(SDL_INIT_VIDEO); SDL_Window *window = SDL_CreateWindow("weee", 800, 600, SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE); @@ -44,7 +50,8 @@ int main(int argc, char **argv) { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX); - ircolib::u8 *rgbTexture = (ircolib::u8 *)calloc(640 * 240, 3); + std::vector rgbTexture; + rgbTexture.resize(640 * 240 * 3); bool open = true; while (open) { @@ -62,14 +69,16 @@ int main(int argc, char **argv) { } SDL_ConvertPixels(640, 240, SDL_PIXELFORMAT_UYVY, &mem.mem1[0x104000], 640 * 4, SDL_PIXELFORMAT_BGR24, - rgbTexture, 640 * 3); + rgbTexture.data(), 640 * 3); SDL_RenderClear(renderer); - SDL_UpdateTexture(texture, nullptr, rgbTexture, 640 * 3); + SDL_UpdateTexture(texture, nullptr, rgbTexture.data(), 640 * 3); SDL_RenderTexture(renderer, texture, nullptr, nullptr); SDL_RenderPresent(renderer); } + SDL_DestroyTexture(texture); + SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit();