From db01783eaf2e6ff7256ab667293bd347ab058870 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 13:30:25 +0200 Subject: [PATCH 1/7] ee: fix thread struct --- src/ee/ee_def.hpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/ee/ee_def.hpp b/src/ee/ee_def.hpp index 5f52fbd..068dd36 100644 --- a/src/ee/ee_def.hpp +++ b/src/ee/ee_def.hpp @@ -611,25 +611,36 @@ struct ee_state { #define THS_WAITSUSPEND 0x0C // THS_WAIT | THS_SUSPEND #define THS_DORMANT 0x10 +struct ee_thread_ctx { + uint32_t sa; + uint32_t fcsr; + uint32_t float_thing; + uint32_t unk; + // gpr excluding $zero + // k0/k1 contains hi, hi1, lo, lo1 + uint128_t gpr[31]; + float fpr[32]; +}; + struct ee_thread { uint32_t prev; // TCB* uint32_t next; // TCB* int status; - uint32_t func; // void* - uint32_t current_stack; // void* + uint32_t resume_addr; // void* + uint32_t register_storage; // ee_thread_ctx* uint32_t gp_reg; // void* - short current_priority; short init_priority; - int wait_type; //0=not waiting, 1=sleeping, 2=waiting on semaphore + short current_priority; + int wait_type; // 0=not waiting, 1=sleeping, 2=waiting on semaphore int sema_id; int wakeup_count; int attr; int option; - uint32_t func_; // void* ??? + uint32_t entry_point; // void* ??? int argc; uint32_t argv; // char** - uint32_t initial_stack; // void* + uint32_t stack_memory; // void* int stack_size; - uint32_t root; // int* function to return to when exiting thread? + uint32_t root; // int* function to return to when exiting thread? uint32_t heap_base; // void* -}; \ No newline at end of file +}; From 1fd52c5d306c850e707cdde5df23fff518d5c909 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 13:31:47 +0200 Subject: [PATCH 2/7] frontend: rename show_threads --- frontend/iris.cpp | 4 ++-- frontend/iris.hpp | 4 ++-- frontend/settings.cpp | 4 ++-- frontend/ui/menubar.cpp | 4 ++-- frontend/ui/threads.cpp | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/frontend/iris.cpp b/frontend/iris.cpp index 8211353..bd6154a 100644 --- a/frontend/iris.cpp +++ b/frontend/iris.cpp @@ -302,7 +302,7 @@ void update_window(iris::instance* iris) { if (iris->show_settings) show_settings(iris); if (iris->show_pad_debugger) show_pad_debugger(iris); if (iris->show_symbols) show_symbols(iris); - if (iris->show_threads) show_threads(iris); + if (iris->show_ee_threads) show_ee_threads(iris); if (iris->show_timers) show_timers(iris); if (iris->show_sysmem_logs) show_sysmem_logs(iris); if (iris->show_memory_card_tool) show_memory_card_tool(iris); @@ -780,7 +780,7 @@ void destroy(iris::instance* iris) { iris->show_memory_search = false; iris->show_vu_disassembler = false; iris->show_breakpoints = false; - iris->show_threads = false; + iris->show_ee_threads = false; iris->show_timers = false; iris->show_sysmem_logs = false; iris->show_imgui_demo = false; diff --git a/frontend/iris.hpp b/frontend/iris.hpp index dd21000..75f0a95 100644 --- a/frontend/iris.hpp +++ b/frontend/iris.hpp @@ -508,7 +508,7 @@ struct instance { bool show_settings = false; bool show_pad_debugger = false; bool show_symbols = false; - bool show_threads = false; + bool show_ee_threads = false; bool show_memory_card_tool = false; bool show_hdd_tool = false; bool show_imgui_demo = false; @@ -828,7 +828,7 @@ void show_about_window(iris::instance* iris); void show_settings(iris::instance* iris); void show_pad_debugger(iris::instance* iris); void show_symbols(iris::instance* iris); -void show_threads(iris::instance* iris); +void show_ee_threads(iris::instance* iris); void show_overlay(iris::instance* iris); void show_memory_card_tool(iris::instance* iris); void show_hdd_tool(iris::instance* iris); diff --git a/frontend/settings.cpp b/frontend/settings.cpp index 4f7e0db..1f26979 100644 --- a/frontend/settings.cpp +++ b/frontend/settings.cpp @@ -159,7 +159,7 @@ bool parse_toml_settings(iris::instance* iris) { iris->show_vu_disassembler = debugger["show_vu_disassembler"].value_or(false); iris->show_status_bar = debugger["show_status_bar"].value_or(true); iris->show_pad_debugger = debugger["show_pad_debugger"].value_or(false); - iris->show_threads = debugger["show_threads"].value_or(false); + iris->show_ee_threads = debugger["show_ee_threads"].value_or(false); iris->show_timers = debugger["show_timers"].value_or(false); iris->show_sysmem_logs = debugger["show_sysmem_logs"].value_or(false); iris->show_overlay = debugger["show_overlay"].value_or(false); @@ -543,7 +543,7 @@ void close(iris::instance* iris) { { "show_status_bar", iris->show_status_bar }, { "show_pad_debugger", iris->show_pad_debugger }, { "show_breakpoints", iris->show_breakpoints }, - { "show_threads", iris->show_threads }, + { "show_ee_threads", iris->show_ee_threads }, { "show_timers", iris->show_timers }, { "show_sysmem_logs", iris->show_sysmem_logs }, { "show_imgui_demo", iris->show_imgui_demo }, diff --git a/frontend/ui/menubar.cpp b/frontend/ui/menubar.cpp index c85fe98..ad5057c 100644 --- a/frontend/ui/menubar.cpp +++ b/frontend/ui/menubar.cpp @@ -507,7 +507,7 @@ void show_main_menubar(iris::instance* iris) { if (MenuItem(ICON_MS_CODE " Symbols##ee", NULL, &iris->show_symbols)); EndDisabled(); - if (MenuItem(ICON_MS_ACCOUNT_TREE " Threads##ee", NULL, &iris->show_threads)); + if (MenuItem(ICON_MS_ACCOUNT_TREE " Threads##ee", NULL, &iris->show_ee_threads)); // ImGui::EndMenu(); // } @@ -575,7 +575,7 @@ void show_main_menubar(iris::instance* iris) { iris->show_vu_disassembler = false; iris->show_status_bar = false; iris->show_breakpoints = false; - iris->show_threads = false; + iris->show_ee_threads = false; iris->show_sysmem_logs = false; iris->show_imgui_demo = false; iris->show_overlay = false; diff --git a/frontend/ui/threads.cpp b/frontend/ui/threads.cpp index 59b685f..deb4c37 100644 --- a/frontend/ui/threads.cpp +++ b/frontend/ui/threads.cpp @@ -37,7 +37,7 @@ static const char* get_entry_symbol(iris::instance* iris, uint32_t addr) { return nullptr; } -void show_thread_list(iris::instance* iris) { +void show_ee_thread_list(iris::instance* iris) { using namespace ImGui; struct ee_state* ee = iris->ps2->ee; @@ -93,10 +93,10 @@ void show_thread_list(iris::instance* iris) { } } -void show_threads(iris::instance* iris) { +void show_ee_threads(iris::instance* iris) { using namespace ImGui; - if (imgui::BeginEx("Threads", &iris->show_threads)) { + if (imgui::BeginEx("EE Threads", &iris->show_ee_threads)) { if (!iris->ps2->ee->thread_list_base) { ImVec2 size = CalcTextSize(ICON_MS_WARNING " Thread list hasn't been initialized yet"); ImVec2 pos = ImVec2(GetContentRegionAvail().x / 2 - size.x / 2, GetContentRegionAvail().y / 2 - size.y / 2); @@ -110,7 +110,7 @@ void show_threads(iris::instance* iris) { return; } - show_thread_list(iris); + show_ee_thread_list(iris); } End(); } From ad13b87f4f1dc240eac50cc6318ae5afb3ec0849 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 13:36:46 +0200 Subject: [PATCH 3/7] frontend: make ee thread display a bit nicer --- frontend/ui/threads.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/frontend/ui/threads.cpp b/frontend/ui/threads.cpp index deb4c37..b8c5463 100644 --- a/frontend/ui/threads.cpp +++ b/frontend/ui/threads.cpp @@ -42,14 +42,15 @@ void show_ee_thread_list(iris::instance* iris) { struct ee_state* ee = iris->ps2->ee; - ImGuiTableFlags table_flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_ScrollY; + ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_ScrollY; - if (BeginTable("##threadlist", 5, table_flags)) { + if (BeginTable("##threadlist_ee", 6, table_flags)) { TableSetupScrollFreeze(0, 1); TableSetupColumn("ID"); TableSetupColumn("Priority"); TableSetupColumn("Entry"); TableSetupColumn("PC"); + TableSetupColumn("Argv"); TableSetupColumn("Status"); PushFont(iris->font_small_code); TableHeadersRow(); @@ -67,23 +68,25 @@ void show_ee_thread_list(iris::instance* iris) { Text("%d", thr->current_priority); TableSetColumnIndex(2); - const char* symbol = get_entry_symbol(iris, thr->func); + const char* symbol = get_entry_symbol(iris, thr->entry_point); if (symbol) { - Text("%s", symbol); + Text("%s (0x%08x)", symbol, thr->entry_point); } else { - Text("0x%08X", thr->func); + Text("0x%08X", thr->entry_point); } - uint32_t argv = *(uint32_t*)&iris->ps2->ee_ram->buf[(thr->argv + 4) & 0x1fffffff]; - - // if (thr->argc) { - // printf("argv=%08x *argv=%08x\n", thr->argv, argv); - // } - TableSetColumnIndex(3); - Text("%s", thr->argc ? (char*)&iris->ps2->ee_ram->buf[argv & 0x1fffffff] : "NULL"); + if (thr->status == THS_RUN) { + Text("0x%08x", ee->pc); + } else { + Text("0x%08x", thr->resume_addr); + } + + uint32_t argv = *(uint32_t*)&iris->ps2->ee_ram->buf[(thr->argv + 4) & 0x1fffffff]; TableSetColumnIndex(4); + Text("%s", thr->argc ? (char*)&iris->ps2->ee_ram->buf[argv & 0x1fffffff] : "NULL"); + TableSetColumnIndex(5); Text("%s", get_status_string(thr->status)); thr++; From 9d9b23d9f93264c9a906845e4bf14f638e5c5f64 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 05:18:09 +0200 Subject: [PATCH 4/7] iop: find thread list --- src/iop/hle/loadcore.cpp | 32 +++++++++++++++++++++++++++++--- src/iop/iop_def.hpp | 1 + 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/iop/hle/loadcore.cpp b/src/iop/hle/loadcore.cpp index 7044759..e4fad52 100644 --- a/src/iop/hle/loadcore.cpp +++ b/src/iop/hle/loadcore.cpp @@ -34,6 +34,25 @@ static unsigned get_module_list(struct iop_state* iop) return lc_struct + 0x10; } +static unsigned get_thread_list(struct iop_state* iop) +{ + unsigned module_version = iop_read32(iop, iop->r[4] + 8); + + /* Read address of ordinal 3 */ + unsigned func = iop_read32(iop, iop->r[4] + 0x20); + + /* Read lui+ori of address to the thread manager global */ + unsigned th_struct = iop_read32(iop, func) << 16; + th_struct |= iop_read32(iop, func + 4) & 0xffff; + + unsigned th_list = th_struct + 0x42c; + if (module_version > 0x101) { + th_list = th_struct + 0x430; + } + + return th_list; +} + static void iop_strncpy(struct iop_state* iop, char* dest, unsigned src, int n) { char c; @@ -96,11 +115,18 @@ void refresh_module_list(struct iop_state* iop) int loadcore_reg_lib_ent(struct iop_state* iop) { - unsigned list = get_module_list(iop); + unsigned module_list = get_module_list(iop); + iop->module_list_addr = module_list; + refresh_module_list(iop); - iop->module_list_addr = list; + char name[8] = {}; - refresh_module_list(iop); + iop_strncpy(iop, name, iop->r[4] + 0xc, sizeof(name)); + if (strncmp(name, "thbase", 6) == 0) { + unsigned thread_list = get_thread_list(iop); + iop->thread_list_addr = thread_list; + printf("iop: found thread list at %x\n", thread_list); + } return 0; } diff --git a/src/iop/iop_def.hpp b/src/iop/iop_def.hpp index 15aa37c..7b38a97 100644 --- a/src/iop/iop_def.hpp +++ b/src/iop/iop_def.hpp @@ -137,6 +137,7 @@ struct iop_state { uint32_t cop0_r[16] = { 0 }; uint32_t module_list_addr = 0; + uint32_t thread_list_addr = 0; /* cache module list */ int module_count = 0; From 71a57a58eface3255363f4e47d8f82df81fc9e5c Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 13:30:04 +0200 Subject: [PATCH 5/7] iop: add thread struct definitions --- src/iop/iop_def.hpp | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/iop/iop_def.hpp b/src/iop/iop_def.hpp index 7b38a97..79ea4fe 100644 --- a/src/iop/iop_def.hpp +++ b/src/iop/iop_def.hpp @@ -143,3 +143,78 @@ struct iop_state { int module_count = 0; struct iop_module* module_list = nullptr; }; + +struct iop_thread_ctx { + uint32_t unk; + uint32_t at; + uint32_t v0; + uint32_t v1; + uint32_t a0; + uint32_t a1; + uint32_t a2; + uint32_t a3; + uint32_t t0; + uint32_t t1; + uint32_t t2; + uint32_t t3; + uint32_t t4; + uint32_t t5; + uint32_t t6; + uint32_t t7; + uint32_t s0; + uint32_t s1; + uint32_t s2; + uint32_t s3; + uint32_t s4; + uint32_t s5; + uint32_t s6; + uint32_t s7; + uint32_t t8; + uint32_t t9; + uint32_t unk68; + uint32_t unk6c; + uint32_t gp; + uint32_t sp; + uint32_t fp; + uint32_t ra; + uint32_t hi; + uint32_t lo; + uint32_t sr; + uint32_t pc; + uint32_t I_CTRL; + uint32_t unk2; +}; + +struct iop_thread { + /* Links for priority list */ + uint32_t next; + uint32_t prev; + + uint16_t tag; + uint16_t id; + uint8_t status; + uint16_t priority; + uint32_t reg_storage; // iop_thread_ctx* + int unk14; + int unk18; + uint16_t wait_type; + uint16_t wakeup_count; + uint32_t wait_id; // ptr to wait object + uint32_t next_thread; // iop_thread* + uint32_t event_bits; + uint16_t event_mode; + uint16_t init_prio; + uint32_t run_clocks_hi; + uint32_t run_clocks_lo; + uint32_t entry_point; + uint32_t stack_memory; + uint32_t stack_size; + uint32_t gp_reg; + uint32_t attr; + uint32_t option; + uint32_t wait_return; + uint32_t reason_counter; + uint32_t irq_preempt_count; + uint32_t thread_preempt_count; + uint32_t release_count; +}; From 83de91a41f28a82c093ec469dbdd9731a28df39a Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 13:37:42 +0200 Subject: [PATCH 6/7] frontend: add iop thread display --- frontend/iris.cpp | 2 ++ frontend/iris.hpp | 2 ++ frontend/settings.cpp | 2 ++ frontend/ui/menubar.cpp | 2 ++ frontend/ui/threads.cpp | 76 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/frontend/iris.cpp b/frontend/iris.cpp index bd6154a..a76c88d 100644 --- a/frontend/iris.cpp +++ b/frontend/iris.cpp @@ -303,6 +303,7 @@ void update_window(iris::instance* iris) { if (iris->show_pad_debugger) show_pad_debugger(iris); if (iris->show_symbols) show_symbols(iris); if (iris->show_ee_threads) show_ee_threads(iris); + if (iris->show_iop_threads) show_iop_threads(iris); if (iris->show_timers) show_timers(iris); if (iris->show_sysmem_logs) show_sysmem_logs(iris); if (iris->show_memory_card_tool) show_memory_card_tool(iris); @@ -781,6 +782,7 @@ void destroy(iris::instance* iris) { iris->show_vu_disassembler = false; iris->show_breakpoints = false; iris->show_ee_threads = false; + iris->show_iop_threads = false; iris->show_timers = false; iris->show_sysmem_logs = false; iris->show_imgui_demo = false; diff --git a/frontend/iris.hpp b/frontend/iris.hpp index 75f0a95..309545f 100644 --- a/frontend/iris.hpp +++ b/frontend/iris.hpp @@ -509,6 +509,7 @@ struct instance { bool show_pad_debugger = false; bool show_symbols = false; bool show_ee_threads = false; + bool show_iop_threads = false; bool show_memory_card_tool = false; bool show_hdd_tool = false; bool show_imgui_demo = false; @@ -829,6 +830,7 @@ void show_settings(iris::instance* iris); void show_pad_debugger(iris::instance* iris); void show_symbols(iris::instance* iris); void show_ee_threads(iris::instance* iris); +void show_iop_threads(iris::instance* iris); void show_overlay(iris::instance* iris); void show_memory_card_tool(iris::instance* iris); void show_hdd_tool(iris::instance* iris); diff --git a/frontend/settings.cpp b/frontend/settings.cpp index 1f26979..73c0d3c 100644 --- a/frontend/settings.cpp +++ b/frontend/settings.cpp @@ -160,6 +160,7 @@ bool parse_toml_settings(iris::instance* iris) { iris->show_status_bar = debugger["show_status_bar"].value_or(true); iris->show_pad_debugger = debugger["show_pad_debugger"].value_or(false); iris->show_ee_threads = debugger["show_ee_threads"].value_or(false); + iris->show_iop_threads = debugger["show_iop_threads"].value_or(false); iris->show_timers = debugger["show_timers"].value_or(false); iris->show_sysmem_logs = debugger["show_sysmem_logs"].value_or(false); iris->show_overlay = debugger["show_overlay"].value_or(false); @@ -544,6 +545,7 @@ void close(iris::instance* iris) { { "show_pad_debugger", iris->show_pad_debugger }, { "show_breakpoints", iris->show_breakpoints }, { "show_ee_threads", iris->show_ee_threads }, + { "show_iop_threads", iris->show_iop_threads }, { "show_timers", iris->show_timers }, { "show_sysmem_logs", iris->show_sysmem_logs }, { "show_imgui_demo", iris->show_imgui_demo }, diff --git a/frontend/ui/menubar.cpp b/frontend/ui/menubar.cpp index ad5057c..bb72944 100644 --- a/frontend/ui/menubar.cpp +++ b/frontend/ui/menubar.cpp @@ -519,6 +519,7 @@ void show_main_menubar(iris::instance* iris) { if (MenuItem(ICON_MS_TERMINAL " Logs##iop", NULL, &iris->show_iop_logs)); if (MenuItem(ICON_MS_BOLT " Interrupts##iop", NULL, &iris->show_iop_interrupts)); if (MenuItem(ICON_MS_EXTENSION " Modules##iop", NULL, &iris->show_iop_modules)); + if (MenuItem(ICON_MS_ACCOUNT_TREE " Threads##iop", NULL, &iris->show_iop_threads)); // ImGui::EndMenu(); // } @@ -576,6 +577,7 @@ void show_main_menubar(iris::instance* iris) { iris->show_status_bar = false; iris->show_breakpoints = false; iris->show_ee_threads = false; + iris->show_iop_threads = false; iris->show_sysmem_logs = false; iris->show_imgui_demo = false; iris->show_overlay = false; diff --git a/frontend/ui/threads.cpp b/frontend/ui/threads.cpp index b8c5463..3dcde85 100644 --- a/frontend/ui/threads.cpp +++ b/frontend/ui/threads.cpp @@ -6,6 +6,7 @@ #include "iris.hpp" #include "ee/ee_def.hpp" +#include "iop/iop_def.hpp" #include "res/IconsMaterialSymbols.h" @@ -117,4 +118,77 @@ void show_ee_threads(iris::instance* iris) { } End(); } -} \ No newline at end of file + +void show_iop_thread_list(iris::instance* iris) { + using namespace ImGui; + + struct iop_state* iop = iris->ps2->iop; + + ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_ScrollY; + + if (BeginTable("##threadlist_iop", 5, table_flags)) { + TableSetupScrollFreeze(0, 1); + TableSetupColumn("ID"); + TableSetupColumn("Priority"); + TableSetupColumn("Entry"); + TableSetupColumn("PC"); + TableSetupColumn("Status"); + PushFont(iris->font_small_code); + TableHeadersRow(); + PopFont(); + + uint32_t addr = iop_read32(iop, iop->thread_list_addr); + + while (addr) { + struct iop_thread* thr = (struct iop_thread*)&iris->ps2->iop_ram->buf[addr & 0x1fffffff]; + struct iop_thread_ctx* ctx = (struct iop_thread_ctx*)&iris->ps2->iop_ram->buf[thr->reg_storage & 0x1fffffff]; + + TableNextRow(); + TableSetColumnIndex(0); + Text("%d", thr->id); + + TableSetColumnIndex(1); + Text("%d", thr->priority); + + TableSetColumnIndex(2); + Text("0x%08X", thr->entry_point); + + TableSetColumnIndex(3); + if (thr->status == THS_RUN) { + Text("0x%08x", iop->pc); + } else { + Text("0x%08x", ctx->pc); + } + + TableSetColumnIndex(4); + Text("%s", get_status_string(thr->status)); + + addr = thr->next_thread; + } + + EndTable(); + } +} + +void show_iop_threads(iris::instance* iris) { + using namespace ImGui; + + if (imgui::BeginEx("IOP Threads", &iris->show_iop_threads)) { + if (!iris->ps2->iop->thread_list_addr) { + ImVec2 size = CalcTextSize(ICON_MS_WARNING " Thread list hasn't been initialized yet"); + ImVec2 pos = ImVec2(GetContentRegionAvail().x / 2 - size.x / 2, GetContentRegionAvail().y / 2 - size.y / 2); + ImVec4 col = GetStyle().Colors[ImGuiCol_Text]; + + SetCursorPos(pos); + TextDisabled(ICON_MS_WARNING " Thread list hasn't been initialized yet"); + + End(); + + return; + } + + show_iop_thread_list(iris); + } End(); +} + +} From 0e81476aab217af7f201beb7ca80b5b2b2641a12 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 May 2026 14:08:34 +0200 Subject: [PATCH 7/7] frontend: show thread wait type --- frontend/ui/threads.cpp | 39 +++++++++++++++++++++++++++++++++++++-- src/ee/ee_def.hpp | 4 ++++ src/iop/iop_def.hpp | 9 +++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/frontend/ui/threads.cpp b/frontend/ui/threads.cpp index 3dcde85..5505fdc 100644 --- a/frontend/ui/threads.cpp +++ b/frontend/ui/threads.cpp @@ -25,6 +25,16 @@ static inline const char* get_status_string(int status) { return ""; } +static inline const char* get_ee_wait_string(int wait) { + switch (wait) { + case TSW_EE_NONE: return "NONE"; + case TSW_EE_SLEEP: return "SLEEP"; + case TSW_EE_SEMA: return "SEMA"; + } + + return ""; +} + static const char* get_entry_symbol(iris::instance* iris, uint32_t addr) { // Look up the address in the symbol table if (addr == 0x81fc0) return "EE Idle Thread"; @@ -45,7 +55,7 @@ void show_ee_thread_list(iris::instance* iris) { ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_ScrollY; - if (BeginTable("##threadlist_ee", 6, table_flags)) { + if (BeginTable("##threadlist_ee", 7, table_flags)) { TableSetupScrollFreeze(0, 1); TableSetupColumn("ID"); TableSetupColumn("Priority"); @@ -53,6 +63,7 @@ void show_ee_thread_list(iris::instance* iris) { TableSetupColumn("PC"); TableSetupColumn("Argv"); TableSetupColumn("Status"); + TableSetupColumn("WaitType"); PushFont(iris->font_small_code); TableHeadersRow(); PopFont(); @@ -89,6 +100,8 @@ void show_ee_thread_list(iris::instance* iris) { Text("%s", thr->argc ? (char*)&iris->ps2->ee_ram->buf[argv & 0x1fffffff] : "NULL"); TableSetColumnIndex(5); Text("%s", get_status_string(thr->status)); + TableSetColumnIndex(6); + Text("%s", get_ee_wait_string(thr->wait_type)); thr++; } @@ -118,6 +131,20 @@ void show_ee_threads(iris::instance* iris) { } End(); } +static inline const char* get_iop_wait_string(int wait) { + switch (wait) { + case TSW_IOP_NONE: return "NONE"; + case TSW_IOP_SLEEP: return "SLEEP"; + case TSW_IOP_DELAY: return "DELAY"; + case TSW_IOP_SEMA: return "SEMA"; + case TSW_IOP_EVENTFLAG: return "EVENTFLAG"; + case TSW_IOP_MBX: return "MBX"; + case TSW_IOP_VPL: return "VPL"; + case TSW_IOP_FPL: return "FPL"; + } + + return ""; +} void show_iop_thread_list(iris::instance* iris) { using namespace ImGui; @@ -126,13 +153,14 @@ void show_iop_thread_list(iris::instance* iris) { ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_ScrollY; - if (BeginTable("##threadlist_iop", 5, table_flags)) { + if (BeginTable("##threadlist_iop", 6, table_flags)) { TableSetupScrollFreeze(0, 1); TableSetupColumn("ID"); TableSetupColumn("Priority"); TableSetupColumn("Entry"); TableSetupColumn("PC"); TableSetupColumn("Status"); + TableSetupColumn("WaitType"); PushFont(iris->font_small_code); TableHeadersRow(); PopFont(); @@ -143,6 +171,10 @@ void show_iop_thread_list(iris::instance* iris) { struct iop_thread* thr = (struct iop_thread*)&iris->ps2->iop_ram->buf[addr & 0x1fffffff]; struct iop_thread_ctx* ctx = (struct iop_thread_ctx*)&iris->ps2->iop_ram->buf[thr->reg_storage & 0x1fffffff]; + if (thr->tag != 0x7f01) { + break; + } + TableNextRow(); TableSetColumnIndex(0); Text("%d", thr->id); @@ -163,6 +195,9 @@ void show_iop_thread_list(iris::instance* iris) { TableSetColumnIndex(4); Text("%s", get_status_string(thr->status)); + TableSetColumnIndex(5); + Text("%s", get_iop_wait_string(thr->wait_type)); + addr = thr->next_thread; } diff --git a/src/ee/ee_def.hpp b/src/ee/ee_def.hpp index 068dd36..aa4d57f 100644 --- a/src/ee/ee_def.hpp +++ b/src/ee/ee_def.hpp @@ -611,6 +611,10 @@ struct ee_state { #define THS_WAITSUSPEND 0x0C // THS_WAIT | THS_SUSPEND #define THS_DORMANT 0x10 +#define TSW_EE_NONE 0x0 +#define TSW_EE_SLEEP 0x1 +#define TSW_EE_SEMA 0x2 + struct ee_thread_ctx { uint32_t sa; uint32_t fcsr; diff --git a/src/iop/iop_def.hpp b/src/iop/iop_def.hpp index 79ea4fe..3253c6d 100644 --- a/src/iop/iop_def.hpp +++ b/src/iop/iop_def.hpp @@ -144,6 +144,15 @@ struct iop_state { struct iop_module* module_list = nullptr; }; +#define TSW_IOP_NONE 0x0 +#define TSW_IOP_SLEEP 0x1 +#define TSW_IOP_DELAY 0x2 +#define TSW_IOP_SEMA 0x3 +#define TSW_IOP_EVENTFLAG 0x4 +#define TSW_IOP_MBX 0x5 +#define TSW_IOP_VPL 0x6 +#define TSW_IOP_FPL 0x7 + struct iop_thread_ctx { uint32_t unk; uint32_t at;