示例#1
0
void Debugger::updateCallFrameAndPauseIfNeeded(CallFrame* callFrame)
{
    updateCallFrame(callFrame);
    pauseIfNeeded(callFrame);
    if (!isStepping())
        m_currentCallFrame = 0;
}
LRESULT CDebugCommandsView::OnViewPCButton(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hwnd*/, BOOL& /*bHandled*/)
{
    if (g_Reg != NULL && isStepping())
    {
        ShowAddress(g_Reg->m_PROGRAM_COUNTER, TRUE);
    }
    return FALSE;
}
示例#3
0
void Debugger::registerCodeBlock(CodeBlock* codeBlock)
{
    // FIXME: We should never have to jettison a code block (due to pending breakpoints
    // or stepping mode) that is being registered. operationOptimize() should have
    // prevented the optimizing of such code blocks in the first place. Find a way to
    // express this with greater clarity in the code. See <https://webkit.org/b131771>.
    applyBreakpoints(codeBlock);
    if (isStepping())
        codeBlock->setSteppingMode(CodeBlock::SteppingModeEnabled);
}
LRESULT CEditReg64::OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    if (!isStepping())
    {
        goto canceled;
    }

    char charCode = (char)wParam;

    if (!isxdigit(charCode) && charCode != ' ')
    {
        if (!isalnum(charCode))
        {
            goto unhandled;
        }
        goto canceled;
    }

    if (isalpha(charCode) && !isupper(charCode))
    {
        SendMessage(uMsg, toupper(wParam), lParam);
        goto canceled;
    }

    char text[20];
    GetWindowText(text, 20);
    int textLen = strlen(text);

    if (textLen >= 17)
    {
        int selStart, selEnd;
        GetSel(selStart, selEnd);
        if (selEnd - selStart == 0)
        {
            goto canceled;
        }
    }

    if (charCode == ' ' && strchr(text, ' ') != NULL)
    {
        goto canceled;
    }

unhandled:
    bHandled = FALSE;
    return 0;

canceled:
    bHandled = TRUE;
    return 0;
}
示例#5
0
void Debugger::willExecuteProgram(CallFrame* callFrame)
{
    if (m_isPaused)
        return;

    PauseReasonDeclaration reason(*this, PausedAtStartOfProgram);
    // FIXME: This check for whether we're debugging a worker thread is a workaround
    // for https://bugs.webkit.org/show_bug.cgi?id=102637. Remove it when we rework
    // the debugger implementation to not require callbacks.
    if (!m_isInWorkerThread)
        updateCallFrameAndPauseIfNeeded(callFrame);
    else if (isStepping())
        updateCallFrame(callFrame);
}
示例#6
0
void Debugger::updateCallFrame(CallFrame* callFrame, CallFrameUpdateAction action)
{
    if (!callFrame) {
        m_currentCallFrame = nullptr;
        return;
    }

    updateCallFrameInternal(callFrame);

    if (action == AttemptPause)
        pauseIfNeeded(callFrame);

    if (!isStepping())
        m_currentCallFrame = nullptr;
}
LRESULT CDebugCommandsView::OnPCChanged(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    if (!m_Attached)
    {
        return 0;
    }
    if (m_bIgnorePCChange)
    {
        m_bIgnorePCChange = false;
        return 0;
    }
    if (g_Reg != NULL && isStepping())
    {
        g_Reg->m_PROGRAM_COUNTER = m_PCEdit.GetValue();
    }
    return 0;
}
// Highlight command list items & draw branch arrows
LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
{
    NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
    DWORD drawStage = pLVCD->nmcd.dwDrawStage;

    switch (drawStage)
    {
    case CDDS_PREPAINT: return (CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT);
    case CDDS_ITEMPREPAINT: return CDRF_NOTIFYSUBITEMDRAW;
    case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): break;
    case CDDS_POSTPAINT:
        DrawBranchArrows(pLVCD->nmcd.hdc);
        return CDRF_DODEFAULT;
    default:
        return CDRF_DODEFAULT;
    }

    uint32_t nItem = (uint32_t)pLVCD->nmcd.dwItemSpec;
    uint32_t nSubItem = pLVCD->iSubItem;

    uint32_t address = m_StartAddress + (nItem * 4);
    uint32_t pc = (g_Reg != NULL) ? g_Reg->m_PROGRAM_COUNTER : 0;

    OPCODE pcOpcode;
    if (g_MMU != NULL)
    {
        g_MMU->LW_VAddr(pc, pcOpcode.Hex);
    }
    else
    {
        pcOpcode.Hex = 0;
    }

    if (nSubItem == CCommandList::COL_ARROWS)
    {
        return CDRF_DODEFAULT;
    }

    if (nSubItem == CCommandList::COL_ADDRESS) // addr
    {
        CBreakpoints::BPSTATE bpState = m_Breakpoints->ExecutionBPExists(address);

        if (bpState == CBreakpoints::BP_SET)
        {
            // breakpoint
            pLVCD->clrTextBk = RGB(0x44, 0x00, 0x00);
            pLVCD->clrText = (address == pc && isDebugging()) ?
                RGB(0xFF, 0xFF, 0x00) : // breakpoint & current pc
                RGB(0xFF, 0xCC, 0xCC);
        }
        else if (bpState == CBreakpoints::BP_SET_TEMP)
        {
            // breakpoint
            pLVCD->clrTextBk = RGB(0x66, 0x44, 0x00);
            pLVCD->clrText = (address == pc && isDebugging()) ?
                RGB(0xFF, 0xFF, 0x00) : // breakpoint & current pc
                RGB(0xFF, 0xEE, 0xCC);
        }
        else if (address == pc && isStepping())
        {
            // pc
            pLVCD->clrTextBk = RGB(0x88, 0x88, 0x88);
            pLVCD->clrText = RGB(0xFF, 0xFF, 0);
        }
        else
        {
            //default
            pLVCD->clrTextBk = RGB(0xEE, 0xEE, 0xEE);
            pLVCD->clrText = RGB(0x44, 0x44, 0x44);
        }
        return CDRF_DODEFAULT;
    }

    // (nSubItem == 1 || nSubItem == 2)

    // cmd & args
    COpInfo OpInfo;
    OPCODE& OpCode = OpInfo.m_OpCode;
    bool bAddrOkay = false;

    if (AddressSafe(address))
    {
        bAddrOkay = g_MMU->LW_VAddr(address, OpCode.Hex);
    }

    struct {
        COLORREF bg;
        COLORREF fg;
    } colors;

    if (!bAddrOkay)
    {
        colors = { 0xFFFFFF, 0xFF0000 };
    }
    else if (address == pc && isStepping())
    {
        colors = { 0xFFFFAA, 0x222200 };
    }
    else if (IsOpEdited(address))
    {
        colors = { 0xFFEEFF, 0xFF00FF };
    }
    else if (OpInfo.IsStackAlloc())
    {
        colors = { 0xCCDDFF, 0x001144 };
    }
    else if (OpInfo.IsStackFree())
    {
        colors = { 0xFFDDDD, 0x440000 };
    }
    else if (OpInfo.IsNOP())
    {
        colors = { 0xFFFFFF, 0x888888 };
    }
    else if (OpInfo.IsJump())
    {
        colors = { 0xEEFFEE, 0x006600 };
    }
    else if (OpInfo.IsBranch())
    {
        colors = { 0xFFFFFF, 0x337700 };
    }
    else
    {
        colors = { 0xFFFFFF, 0x0000000 };
    }

    // Gray annotations
    if (nSubItem == CCommandList::COL_SYMBOL)
    {
        if (m_bvAnnotatedLines[nItem])
        {
            colors.fg = 0x666666;
        }
    }

    pLVCD->clrTextBk = _byteswap_ulong(colors.bg) >> 8;
    pLVCD->clrText = _byteswap_ulong(colors.fg) >> 8;

    if (!isStepping())
    {
        return CDRF_DODEFAULT;
    }

    // color register usage
    // todo localise to temp register context (dont look before/after jumps and frame shifts)
    COLORREF clrUsedRegister = RGB(0xF5, 0xF0, 0xFF); // light purple
    COLORREF clrAffectedRegister = RGB(0xFF, 0xF0, 0xFF); // light pink

    int pcUsedRegA = 0, pcUsedRegB = 0, pcChangedReg = 0;
    int curUsedRegA = 0, curUsedRegB = 0, curChangedReg = 0;

    if (pcOpcode.op == R4300i_SPECIAL)
    {
        pcUsedRegA = pcOpcode.rs;
        pcUsedRegB = pcOpcode.rt;
        pcChangedReg = pcOpcode.rd;
    }
    else
    {
        pcUsedRegA = pcOpcode.rs;
        pcChangedReg = pcOpcode.rt;
    }

    if (OpCode.op == R4300i_SPECIAL)
    {
        curUsedRegA = OpCode.rs;
        curUsedRegB = OpCode.rt;
        curChangedReg = OpCode.rd;
    }
    else
    {
        curUsedRegA = OpCode.rs;
        curChangedReg = OpCode.rt;
    }

    if (address < pc)
    {
        if (curChangedReg != 0 && (pcUsedRegA == curChangedReg || pcUsedRegB == curChangedReg))
        {
            pLVCD->clrTextBk = clrUsedRegister;
        }
    }
    else if (address > pc)
    {
        if (pcChangedReg != 0 && (curUsedRegA == pcChangedReg || curUsedRegB == pcChangedReg))
        {
            pLVCD->clrTextBk = clrAffectedRegister;
        }
    }
    return CDRF_DODEFAULT;
}
LRESULT	CDebugCommandsView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    g_Settings->RegisterChangeCB(Debugger_WaitingForStep, this, (CSettings::SettingChangedFunc)StaticWaitingForStepChanged);
    g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)StaticSteppingOpsChanged);

    m_CommandList.Attach(GetDlgItem(IDC_CMD_LIST));
    m_BreakpointList.Attach(GetDlgItem(IDC_BP_LIST));
    m_AddressEdit.Attach(GetDlgItem(IDC_ADDR_EDIT));
    m_PCEdit.Attach(GetDlgItem(IDC_PC_EDIT));
    m_ViewPCButton.Attach(GetDlgItem(IDC_VIEWPC_BTN));
    m_StepButton.Attach(GetDlgItem(IDC_STEP_BTN));
    m_StepOverButton.Attach(GetDlgItem(IDC_STEPOVER_BTN));
    m_SkipButton.Attach(GetDlgItem(IDC_SKIP_BTN));
    m_GoButton.Attach(GetDlgItem(IDC_GO_BTN));
    m_RegisterTabs.Attach(GetDlgItem(IDC_REG_TABS));
    m_Scrollbar.Attach(GetDlgItem(IDC_SCRL_BAR));
    m_BackButton.Attach(GetDlgItem(IDC_BACK_BTN));
    m_ForwardButton.Attach(GetDlgItem(IDC_FORWARD_BTN));
    m_OpEdit.Attach(GetDlgItem(IDC_OP_EDIT));

    DlgResize_Init(false, true);
    DlgToolTip_Init();

    GetWindowRect(&m_DefaultWindowRect);

    // Setup address input
    m_AddressEdit.SetDisplayType(CEditNumber32::DisplayHex);
    m_AddressEdit.SetLimitText(8);

    // Setup PC register input
    m_PCEdit.SetDisplayType(CEditNumber32::DisplayHex);
    m_PCEdit.SetLimitText(8);

    m_bIgnorePCChange = true;
    m_PCEdit.SetValue(0x80000180, false, true);

    // Setup View PC button
    m_ViewPCButton.EnableWindow(FALSE);
    m_StepButton.EnableWindow(FALSE);
    m_StepOverButton.EnableWindow(FALSE);
    m_SkipButton.EnableWindow(FALSE);
    m_GoButton.EnableWindow(FALSE);

    // Setup breakpoint list
    m_BreakpointList.ModifyStyle(NULL, LBS_NOTIFY);
    RefreshBreakpointList();

    // Setup list scrollbar
    m_Scrollbar.SetScrollRange(0, 100, FALSE);
    m_Scrollbar.SetScrollPos(50, TRUE);

    // Setup history buttons
    ToggleHistoryButtons();

    // Op editor
    m_OpEdit.SetCommandsWindow(this);

    m_bIgnoreAddrChange = true;
    m_AddressEdit.SetValue(0x80000000, false, true);
    ShowAddress(0x80000000, TRUE);

    if (isStepping())
    {
        m_ViewPCButton.EnableWindow(TRUE);
        m_StepButton.EnableWindow(TRUE);
        m_StepOverButton.EnableWindow(TRUE);
        m_SkipButton.EnableWindow(TRUE);
        m_GoButton.EnableWindow(TRUE);
    }

    _this = this;

    DWORD dwThreadID = ::GetCurrentThreadId();
    hWinMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookProc, NULL, dwThreadID);

    WindowCreated();
    m_Attached = true;
    return TRUE;
}
void CDebugCommandsView::ShowAddress(uint32_t address, bool top)
{
    if (top == TRUE)
    {
        m_StartAddress = address;

        if (!isStepping())
        {
            // Disable buttons
            m_ViewPCButton.EnableWindow(FALSE);
            m_StepButton.EnableWindow(FALSE);
            m_StepOverButton.EnableWindow(FALSE);
            m_SkipButton.EnableWindow(FALSE);
            m_GoButton.EnableWindow(FALSE);

            m_RegisterTabs.SetColorsEnabled(false);
        }
    }
    else
    {
        bool bOutOfView = address < m_StartAddress ||
            address > m_StartAddress + (m_CommandListRows - 1) * 4;

        if (bOutOfView)
        {
            m_StartAddress = address;
            m_bIgnoreAddrChange = true;
            m_AddressEdit.SetValue(address, false, true);
        }

        if (m_History.size() == 0 || m_History[m_HistoryIndex] != m_StartAddress)
        {
            HistoryPushState();
        }

        m_bIgnorePCChange = true;
        m_PCEdit.SetValue(g_Reg->m_PROGRAM_COUNTER, false, true);

        // Enable buttons
        m_ViewPCButton.EnableWindow(TRUE);
        m_StepButton.EnableWindow(TRUE);
        m_StepOverButton.EnableWindow(TRUE);
        m_SkipButton.EnableWindow(TRUE);
        m_GoButton.EnableWindow(TRUE);

        m_RegisterTabs.SetColorsEnabled(true);
    }

    m_CommandList.SetRedraw(FALSE);
    m_CommandList.DeleteAllItems();

    ClearBranchArrows();

    m_bvAnnotatedLines.clear();

    CSymbols::EnterCriticalSection();

    for (int i = 0; i < m_CommandListRows; i++)
    {
        uint32_t opAddr = m_StartAddress + i * 4;

        m_CommandList.AddItem(i, CCommandList::COL_ARROWS, " ");

        char addrStr[9];
        sprintf(addrStr, "%08X", opAddr);

        m_CommandList.AddItem(i, CCommandList::COL_ADDRESS, addrStr);

        COpInfo OpInfo;
        OPCODE& OpCode = OpInfo.m_OpCode;
        bool bAddrOkay = false;

        if (AddressSafe(opAddr))
        {
            bAddrOkay = g_MMU->LW_VAddr(opAddr, OpCode.Hex);
        }

        if (!bAddrOkay)
        {
            m_CommandList.AddItem(i, CCommandList::COL_COMMAND, "***");
            m_bvAnnotatedLines.push_back(false);
            continue;
        }

        char* command = (char*)R4300iOpcodeName(OpCode.Hex, opAddr);
        char* cmdName = strtok((char*)command, "\t");
        char* cmdArgs = strtok(NULL, "\t");

        // Show subroutine symbol name for JAL target
        if (OpCode.op == R4300i_JAL)
        {
            uint32_t targetAddr = (0x80000000 | (OpCode.target << 2));

            // todo move symbols management to CDebuggerUI
            const char* targetSymbolName = CSymbols::GetNameByAddress(targetAddr);
            if (targetSymbolName != NULL)
            {
                cmdArgs = (char*)targetSymbolName;
            }
        }

        // Detect reads and writes to mapped registers, cart header data, etc
        const char* annotation = NULL;
        bool bLoadStoreAnnotation = false;

        if (OpInfo.IsLoadStoreCommand())
        {
            for (int offset = -4; offset > -24; offset -= 4)
            {
                if (!AddressSafe(opAddr + offset))
                {
                    break;
                }

                OPCODE OpCodeTest;
                bAddrOkay = g_MMU->LW_VAddr(opAddr + offset, OpCodeTest.Hex);

                if (!bAddrOkay)
                {
                    break;
                }

                if (OpCodeTest.op != R4300i_LUI)
                {
                    continue;
                }

                if (OpCodeTest.rt != OpCode.rs)
                {
                    continue;
                }

                uint32_t memAddr = (OpCodeTest.immediate << 16) + (short)OpCode.offset;

                annotation = CSymbols::GetNameByAddress(memAddr);

                if (annotation == NULL)
                {
                    annotation = GetDataAddressNotes(memAddr);
                }
                break;
            }
        }

        if (annotation == NULL)
        {
            annotation = GetCodeAddressNotes(opAddr);
        }
        else
        {
            bLoadStoreAnnotation = true;
        }

        m_CommandList.AddItem(i, CCommandList::COL_COMMAND, cmdName);
        m_CommandList.AddItem(i, CCommandList::COL_PARAMETERS, cmdArgs);

        // Show routine symbol name for this address
        const char* routineSymbolName = CSymbols::GetNameByAddress(opAddr);
        if (routineSymbolName != NULL)
        {
            m_CommandList.AddItem(i, CCommandList::COL_SYMBOL, routineSymbolName);
            m_bvAnnotatedLines.push_back(false);
        }
        else if (annotation != NULL)
        {
            const char* annotationFormat = bLoadStoreAnnotation ? "// (%s)" : "// %s";
            m_CommandList.AddItem(i, CCommandList::COL_SYMBOL, stdstr_f(annotationFormat, annotation).c_str());
            m_bvAnnotatedLines.push_back(true);
        }
        else
        {
            m_bvAnnotatedLines.push_back(false);
        }

        // Add arrow for branch instruction
        if (OpInfo.IsBranch())
        {
            int startPos = i;
            int endPos = startPos + (int16_t)OpCode.offset + 1;

            AddBranchArrow(startPos, endPos);
        }

        // Branch arrow for close J
        if (OpCode.op == R4300i_J)
        {
            uint32_t target = (OpCode.target << 2);
            int dist = target - (opAddr & 0x3FFFFFF);
            if (abs(dist) < 0x10000)
            {
                int startPos = i;
                int endPos = startPos + (dist / 4);
                AddBranchArrow(startPos, endPos);
            }
        }
    }

    CSymbols::LeaveCriticalSection();

    if (!top) // update registers when called via breakpoint/stepping
    {
        m_RegisterTabs.RefreshEdits();
    }

    RefreshBreakpointList();

    m_CommandList.SetRedraw(TRUE);
}
示例#11
0
// Called from the interpreter core at the beginning of every CPU step
void CDebuggerUI::CPUStepStarted()
{
    if (isStepping() && bCPULoggingEnabled())
    {
        Debug_RefreshCPULogWindow();
    }

    uint32_t pc = g_Reg->m_PROGRAM_COUNTER;
    COpInfo opInfo(R4300iOp::m_Opcode);

    if (opInfo.IsStoreCommand())
    {
        uint32_t memoryAddress = opInfo.GetLoadStoreAddress();

        if (m_Breakpoints->MemLockExists(memoryAddress, opInfo.NumBytesToStore()))
        {
            // Memory is locked, skip op
            g_Settings->SaveBool(Debugger_SkipOp, true);
            return;
        }
    }

    m_ScriptSystem->HookCPUExec()->InvokeByAddressInRange(pc);
    if (SkipOp()) { return; }

    m_ScriptSystem->HookCPUExecOpcode()->InvokeByAddressInRange_MaskedOpcode(pc, R4300iOp::m_Opcode.Hex);
    if (SkipOp()) { return; }

    m_ScriptSystem->HookCPUGPRValue()->InvokeByAddressInRange_GPRValue(pc);
    if (SkipOp()) { return; }
    
    // Memory events, pi cart -> ram dma
    if (opInfo.IsLoadStoreCommand()) // Read and write instructions
    {
        uint32_t memoryAddress = opInfo.GetLoadStoreAddress();

        if (opInfo.IsLoadCommand()) // Read instructions
        {
            m_ScriptSystem->HookCPURead()->InvokeByAddressInRange(memoryAddress);
            if (SkipOp()) { return; }
        }
        else // Write instructions
        {
            m_ScriptSystem->HookCPUWrite()->InvokeByAddressInRange(memoryAddress);
            if (SkipOp()) { return; }

            if (memoryAddress == 0xA460000C) // PI_WR_LEN_REG
            {
                HandleCartToRamDMA();
            }
        }
    }

    if (CDebugSettings::ExceptionBreakpoints() != 0)
    {
        if (pc == 0x80000000 || pc == 0x80000080 ||
            pc == 0xA0000100 || pc == 0x80000180)
        {
            HandleCPUException();
        }
    }

    if (m_Breakpoints->HaveAnyGPRWriteBP())
    {
        int nReg = 0;
        opInfo.WritesGPR(&nReg);

        if (nReg != 0 && m_Breakpoints->HaveGPRWriteBP(nReg))
        {
            g_Settings->SaveBool(Debugger_SteppingOps, true);
        }
    }

    if (m_Breakpoints->HaveAnyGPRReadBP())
    {
        int nReg1 = 0, nReg2 = 0;
        opInfo.ReadsGPR(&nReg1, &nReg2);

        if ((nReg1 != 0 && m_Breakpoints->HaveGPRReadBP(nReg1)) ||
            (nReg2 != 0 && m_Breakpoints->HaveGPRReadBP(nReg2)))
        {
            g_Settings->SaveBool(Debugger_SteppingOps, true);
        }
    }

    if (m_Breakpoints->HaveHIWriteBP() && opInfo.WritesHI() ||
        m_Breakpoints->HaveLOWriteBP() && opInfo.WritesLO() ||
        m_Breakpoints->HaveHIReadBP()  && opInfo.ReadsHI()  ||
        m_Breakpoints->HaveLOReadBP()  && opInfo.ReadsLO())
    {
        g_Settings->SaveBool(Debugger_SteppingOps, true);
    }
}
示例#12
0
void Debugger::registerCodeBlock(CodeBlock* codeBlock)
{
    applyBreakpoints(codeBlock);
    if (isStepping())
        codeBlock->setSteppingMode(CodeBlock::SteppingModeEnabled);
}
示例#13
0
void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam)
{
    if (g_Reg == NULL || !isStepping())
    {
        return;
    }

    WORD ctrlId = LOWORD(wParam);

    CWindow editCtrl = ::GetDlgItem(hDlg, ctrlId);
    char text[20];
    editCtrl.GetWindowText(text, 20);

    if (srcTabId == TabGPR)
    {
        uint64_t value = CEditReg64::ParseValue(text);
        if (ctrlId == IDC_HI_EDIT)
        {
            g_Reg->m_HI.UDW = value;
        }
        else if (ctrlId == IDC_LO_EDIT)
        {
            g_Reg->m_LO.UDW = value;
        }
        else
        {
            int nReg = GetCtrlRegNum(ctrlId, GPREditIds);
            g_Reg->m_GPR[nReg].UDW = value;
        }
        return;
    }

    uint32_t value = strtoul(text, NULL, 16);
    sprintf(text, "%08X", value);
    editCtrl.SetWindowText(text); // reformat text

    if (srcTabId == TabFPR)
    {
        if (ctrlId == IDC_FCSR_EDIT)
        {
            g_Reg->m_FPCR[31] = value;
            return;
        }

        int nReg = GetCtrlRegNum(ctrlId, FPREditIds);
        *(uint32_t*)g_Reg->m_FPR_S[nReg] = value;
        return;
    }

    switch (ctrlId)
    {
    case IDC_COP0_0_EDIT:  g_Reg->INDEX_REGISTER = value; break;
    case IDC_COP0_1_EDIT:  g_Reg->RANDOM_REGISTER = value; break;
    case IDC_COP0_2_EDIT:  g_Reg->ENTRYLO0_REGISTER = value; break;
    case IDC_COP0_3_EDIT:  g_Reg->ENTRYLO1_REGISTER = value; break;
    case IDC_COP0_4_EDIT:  g_Reg->CONTEXT_REGISTER = value; break;
    case IDC_COP0_5_EDIT:  g_Reg->PAGE_MASK_REGISTER = value; break;
    case IDC_COP0_6_EDIT:  g_Reg->WIRED_REGISTER = value; break;
    case IDC_COP0_7_EDIT:  g_Reg->BAD_VADDR_REGISTER = value; break;
    case IDC_COP0_8_EDIT:  g_Reg->COUNT_REGISTER = value; break;
    case IDC_COP0_9_EDIT:  g_Reg->ENTRYHI_REGISTER = value; break;
    case IDC_COP0_10_EDIT: g_Reg->COMPARE_REGISTER = value; break;
    case IDC_COP0_11_EDIT: g_Reg->STATUS_REGISTER = value; break;
    case IDC_COP0_12_EDIT: g_Reg->CAUSE_REGISTER = value; break;
    case IDC_COP0_13_EDIT: g_Reg->EPC_REGISTER = value; break;
    case IDC_COP0_14_EDIT: g_Reg->CONFIG_REGISTER = value; break;
    case IDC_COP0_15_EDIT: g_Reg->TAGLO_REGISTER = value; break;
    case IDC_COP0_16_EDIT: g_Reg->TAGHI_REGISTER = value; break;
    case IDC_COP0_17_EDIT: g_Reg->ERROREPC_REGISTER = value; break;
    case IDC_COP0_18_EDIT: g_Reg->FAKE_CAUSE_REGISTER = value; break;

    case IDC_RDRAM00_EDIT: g_Reg->RDRAM_CONFIG_REG = value; break; // or device_type
    case IDC_RDRAM04_EDIT: g_Reg->RDRAM_DEVICE_ID_REG = value; break;
    case IDC_RDRAM08_EDIT: g_Reg->RDRAM_DELAY_REG = value; break;
    case IDC_RDRAM0C_EDIT: g_Reg->RDRAM_MODE_REG = value; break;
    case IDC_RDRAM10_EDIT: g_Reg->RDRAM_REF_INTERVAL_REG = value; break;
    case IDC_RDRAM14_EDIT: g_Reg->RDRAM_REF_ROW_REG = value; break;
    case IDC_RDRAM18_EDIT: g_Reg->RDRAM_RAS_INTERVAL_REG = value; break;
    case IDC_RDRAM1C_EDIT: g_Reg->RDRAM_MIN_INTERVAL_REG = value; break;
    case IDC_RDRAM20_EDIT: g_Reg->RDRAM_ADDR_SELECT_REG = value; break;
    case IDC_RDRAM24_EDIT: g_Reg->RDRAM_DEVICE_MANUF_REG = value; break;

    case IDC_SP00_EDIT:  g_Reg->SP_MEM_ADDR_REG = value; break;
    case IDC_SP04_EDIT:  g_Reg->SP_DRAM_ADDR_REG = value; break;
    case IDC_SP08_EDIT:  g_Reg->SP_RD_LEN_REG = value; break;
    case IDC_SP0C_EDIT:  g_Reg->SP_WR_LEN_REG = value; break;
    case IDC_SP10_EDIT:  g_Reg->SP_STATUS_REG = value; break;
    case IDC_SP14_EDIT:  g_Reg->SP_DMA_FULL_REG = value; break;
    case IDC_SP18_EDIT:  g_Reg->SP_DMA_BUSY_REG = value; break;
    case IDC_SP1C_EDIT:  g_Reg->SP_SEMAPHORE_REG = value; break;
    case IDC_SP_PC_EDIT: g_Reg->SP_PC_REG = value; break;

    case IDC_DPC00_EDIT: g_Reg->DPC_START_REG = value; break;
    case IDC_DPC04_EDIT: g_Reg->DPC_END_REG = value; break;
    case IDC_DPC08_EDIT: g_Reg->DPC_CURRENT_REG = value; break;
    case IDC_DPC0C_EDIT: g_Reg->DPC_STATUS_REG = value; break;
    case IDC_DPC10_EDIT: g_Reg->DPC_CLOCK_REG = value; break;
    case IDC_DPC14_EDIT: g_Reg->DPC_BUFBUSY_REG = value; break;
    case IDC_DPC18_EDIT: g_Reg->DPC_PIPEBUSY_REG = value; break;
    case IDC_DPC1C_EDIT: g_Reg->DPC_TMEM_REG = value; break;

    case IDC_MI00_EDIT: g_Reg->MI_INIT_MODE_REG = value; break; // or MI_MODE ?
    case IDC_MI04_EDIT: g_Reg->MI_VERSION_REG = value; break; // or MI_NOOP ?
    case IDC_MI08_EDIT: g_Reg->MI_INTR_REG = value; break; // or MI_INTR ?
    case IDC_MI0C_EDIT: g_Reg->MI_INTR_MASK_REG = value; break; // or MI_INTR_MASK ?

    case IDC_VI00_EDIT: g_Reg->VI_STATUS_REG = value; break;
    case IDC_VI04_EDIT: g_Reg->VI_ORIGIN_REG = value; break;
    case IDC_VI08_EDIT: g_Reg->VI_WIDTH_REG = value; break;
    case IDC_VI0C_EDIT: g_Reg->VI_INTR_REG = value; break;
    case IDC_VI10_EDIT: g_Reg->VI_CURRENT_REG = value; break;
    case IDC_VI14_EDIT: g_Reg->VI_BURST_REG = value; break;
    case IDC_VI18_EDIT: g_Reg->VI_V_SYNC_REG = value; break;
    case IDC_VI1C_EDIT: g_Reg->VI_H_SYNC_REG = value; break;
    case IDC_VI20_EDIT: g_Reg->VI_LEAP_REG = value; break;
    case IDC_VI24_EDIT: g_Reg->VI_H_START_REG = value; break;
    case IDC_VI28_EDIT: g_Reg->VI_V_START_REG = value; break;
    case IDC_VI2C_EDIT: g_Reg->VI_V_BURST_REG = value; break;
    case IDC_VI30_EDIT: g_Reg->VI_X_SCALE_REG = value; break;
    case IDC_VI34_EDIT: g_Reg->VI_Y_SCALE_REG = value; break;

    case IDC_AI00_EDIT: g_Reg->AI_DRAM_ADDR_REG = value; break;
    case IDC_AI04_EDIT: g_Reg->AI_LEN_REG = value; break;
    case IDC_AI08_EDIT: g_Reg->AI_CONTROL_REG = value; break;
    case IDC_AI0C_EDIT: g_Reg->AI_STATUS_REG = value; break;
    case IDC_AI10_EDIT: g_Reg->AI_DACRATE_REG = value; break;
    case IDC_AI14_EDIT: g_Reg->AI_BITRATE_REG = value; break;

    case IDC_PI00_EDIT: g_Reg->PI_DRAM_ADDR_REG = value; break;
    case IDC_PI04_EDIT: g_Reg->PI_CART_ADDR_REG = value; break;
    case IDC_PI08_EDIT: g_Reg->PI_RD_LEN_REG = value; break;
    case IDC_PI0C_EDIT: g_Reg->PI_WR_LEN_REG = value; break;
    case IDC_PI10_EDIT: g_Reg->PI_STATUS_REG = value; break;
    case IDC_PI14_EDIT: g_Reg->PI_BSD_DOM1_LAT_REG = value; break;
    case IDC_PI18_EDIT: g_Reg->PI_BSD_DOM1_PWD_REG = value; break;
    case IDC_PI1C_EDIT: g_Reg->PI_BSD_DOM1_PGS_REG = value; break;
    case IDC_PI20_EDIT: g_Reg->PI_BSD_DOM1_RLS_REG = value; break;
    case IDC_PI24_EDIT: g_Reg->PI_BSD_DOM2_LAT_REG = value; break;
    case IDC_PI28_EDIT: g_Reg->PI_BSD_DOM2_PWD_REG = value; break;
    case IDC_PI2C_EDIT: g_Reg->PI_BSD_DOM2_PGS_REG = value; break;
    case IDC_PI30_EDIT: g_Reg->PI_BSD_DOM2_RLS_REG = value; break;

    case IDC_RI00_EDIT: g_Reg->RI_MODE_REG = value; break;
    case IDC_RI04_EDIT: g_Reg->RI_CONFIG_REG = value; break;
    case IDC_RI08_EDIT: g_Reg->RI_CURRENT_LOAD_REG = value; break;
    case IDC_RI0C_EDIT: g_Reg->RI_SELECT_REG = value; break;
    case IDC_RI10_EDIT: g_Reg->RI_REFRESH_REG = value; break;
    case IDC_RI14_EDIT: g_Reg->RI_LATENCY_REG = value; break;
    case IDC_RI18_EDIT: g_Reg->RI_RERROR_REG = value; break;
    case IDC_RI1C_EDIT: g_Reg->RI_WERROR_REG = value; break;

    case IDC_SI00_EDIT: g_Reg->SI_DRAM_ADDR_REG = value; break;
    case IDC_SI04_EDIT: g_Reg->SI_PIF_ADDR_RD64B_REG = value; break;
    case IDC_SI08_EDIT: g_Reg->SI_PIF_ADDR_WR64B_REG = value; break;
    case IDC_SI0C_EDIT: g_Reg->SI_STATUS_REG = value; break;

    case IDC_DD00_EDIT: g_Reg->ASIC_DATA = value; break;
    case IDC_DD04_EDIT: g_Reg->ASIC_MISC_REG = value; break;
    case IDC_DD08_EDIT: g_Reg->ASIC_STATUS = value; break;
    case IDC_DD0C_EDIT: g_Reg->ASIC_CUR_TK = value; break;
    case IDC_DD10_EDIT: g_Reg->ASIC_BM_STATUS = value; break;
    case IDC_DD14_EDIT: g_Reg->ASIC_ERR_SECTOR = value; break;
    case IDC_DD18_EDIT: g_Reg->ASIC_SEQ_STATUS = value; break;
    case IDC_DD1C_EDIT: g_Reg->ASIC_CUR_SECTOR = value; break;
    case IDC_DD20_EDIT: g_Reg->ASIC_HARD_RESET = value; break;
    case IDC_DD24_EDIT: g_Reg->ASIC_C1_S0 = value; break;
    case IDC_DD28_EDIT: g_Reg->ASIC_HOST_SECBYTE = value; break;
    case IDC_DD2C_EDIT: g_Reg->ASIC_C1_S2 = value; break;
    case IDC_DD30_EDIT: g_Reg->ASIC_SEC_BYTE = value; break;
    case IDC_DD34_EDIT: g_Reg->ASIC_C1_S4 = value; break;
    case IDC_DD38_EDIT: g_Reg->ASIC_C1_S6 = value; break;
    case IDC_DD3C_EDIT: g_Reg->ASIC_CUR_ADDR = value; break;
    case IDC_DD40_EDIT: g_Reg->ASIC_ID_REG = value; break;
    case IDC_DD44_EDIT: g_Reg->ASIC_TEST_REG = value; break;
    case IDC_DD48_EDIT: g_Reg->ASIC_TEST_PIN_SEL = value; break;
    }
}