Merge pull request #1688 from shygoo/debug-mmu

[Debugger] Misc cleanup and fixes
This commit is contained in:
zilmar 2019-12-25 17:06:58 +10:30 committed by GitHub
commit 37beacbe09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 2315 additions and 2089 deletions

View File

@ -1,4 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>

View File

@ -8,7 +8,6 @@
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* * * *
****************************************************************************/ ****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
#include "Breakpoints.h" #include "Breakpoints.h"

View File

@ -1,7 +1,15 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
#include "CPULog.h" #include "CPULog.h"
#include <Project64-core/N64System/Mips/OpCodeName.h> #include <Project64-core/N64System/Mips/OpCodeName.h>
CCPULog::CCPULog(size_t size) : CCPULog::CCPULog(size_t size) :

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <stdafx.h> #include <stdafx.h>

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <Project64-core/Settings/SettingType/SettingsType-Application.h> #include <Project64-core/Settings/SettingType/SettingsType-Application.h>

View File

@ -1,304 +1,339 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdafx.h> #include <stdafx.h>
#include "DebugMMU.h" #include "DebugMMU.h"
#include <Common/MemoryManagement.h> #include <Common/MemoryManagement.h>
#include <Project64-core/N64System/N64DiskClass.h>
uint32_t* CDebugMMU::PAddrWordPtr(uint32_t paddr) #define PJMEM_CARTROM 1
uint8_t* CDebugMMU::GetPhysicalPtr(uint32_t paddr, WORD* flags)
{ {
if (g_MMU == NULL) if (g_MMU == NULL)
{ {
return NULL; return NULL;
} }
uint8_t* ptr = NULL;
int nbyte = paddr & 3;
paddr = paddr & ~3; paddr = paddr & ~3;
// RDRAM & DMEM/IMEM bool bBigEndian = false;
if ((paddr < g_MMU->RdramSize()) || bool bCartRom = false;
(paddr >= 0x04000000 && paddr <= 0x04001FFF))
{
return (uint32_t*)(g_MMU->Rdram() + paddr);
}
// 64DD buffer if ((paddr < g_MMU->RdramSize()) ||
if (paddr >= 0x05000000 && paddr <= 0x050004FF) (paddr >= 0x04000000 && paddr <= 0x04001FFF)) // RDRAM & DMEM/IMEM
{
ptr = (uint8_t*)(g_MMU->Rdram() + paddr);
}
else if (paddr >= 0x05000000 && paddr <= 0x050004FF) // 64DD buffer
{ {
// todo // todo
return NULL;
} }
else if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF) // Cartridge Domain 1 (Address 1) (64DD IPL ROM)
// Cartridge Domain 1 (Address 1) (64DD IPL ROM)
if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF)
{ {
uint32_t iplRomOffset = paddr - 0x06000000; uint32_t iplRomOffset = paddr - 0x06000000;
if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize()) if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize())
{ {
return (uint32_t*)(g_MMU->Rdram() + paddr); ptr = (uint8_t*)(g_MMU->Rdram() + paddr);
} }
return NULL;
} }
else if (paddr >= 0x10000000 && paddr <= 0x1FBFFFFF) // Cartridge ROM
// Cartridge Domain 2 (Address 2) (SRAM/FlashRAM)
if (paddr >= 0x08000000 && paddr < 0x08FFFFFF)
{
// stored in a file
return NULL;
}
// Cartridge ROM
if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF)
{ {
uint32_t cartRomOffset = paddr - 0x10000000; uint32_t cartRomOffset = paddr - 0x10000000;
if (g_Rom != NULL && cartRomOffset < g_Rom->GetRomSize()) if (g_Rom != NULL && cartRomOffset < g_Rom->GetRomSize())
{ {
return (uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset); ptr = (uint8_t*)(g_Rom->GetRomAddress() + cartRomOffset);
bCartRom = true;
} }
return false;
} }
else if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF) // PIF RAM
// PIF ROM
if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF)
{
return NULL;
}
// PIF RAM
if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF)
{ {
uint32_t pifRamOffset = paddr - 0x1FC007C0; uint32_t pifRamOffset = paddr - 0x1FC007C0;
return (uint32_t*)(g_MMU->PifRam() + pifRamOffset); ptr = (uint8_t*)(g_MMU->PifRam() + pifRamOffset);
bBigEndian = true;
} }
else
{
// note: write-only registers are excluded
switch (paddr) switch (paddr)
{ {
case 0x03F00000: return &g_Reg->RDRAM_CONFIG_REG; case 0x03F00000: ptr = (uint8_t*)&g_Reg->RDRAM_CONFIG_REG; break;
case 0x03F00004: return &g_Reg->RDRAM_DEVICE_ID_REG; case 0x03F00004: ptr = (uint8_t*)&g_Reg->RDRAM_DEVICE_ID_REG; break;
case 0x03F00008: return &g_Reg->RDRAM_DELAY_REG; case 0x03F00008: ptr = (uint8_t*)&g_Reg->RDRAM_DELAY_REG; break;
case 0x03F0000C: return &g_Reg->RDRAM_MODE_REG; case 0x03F0000C: ptr = (uint8_t*)&g_Reg->RDRAM_MODE_REG; break;
case 0x03F00010: return &g_Reg->RDRAM_REF_INTERVAL_REG; case 0x03F00010: ptr = (uint8_t*)&g_Reg->RDRAM_REF_INTERVAL_REG; break;
case 0x03F00014: return &g_Reg->RDRAM_REF_ROW_REG; case 0x03F00014: ptr = (uint8_t*)&g_Reg->RDRAM_REF_ROW_REG; break;
case 0x03F00018: return &g_Reg->RDRAM_RAS_INTERVAL_REG; case 0x03F00018: ptr = (uint8_t*)&g_Reg->RDRAM_RAS_INTERVAL_REG; break;
case 0x03F0001C: return &g_Reg->RDRAM_MIN_INTERVAL_REG; case 0x03F0001C: ptr = (uint8_t*)&g_Reg->RDRAM_MIN_INTERVAL_REG; break;
case 0x03F00020: return &g_Reg->RDRAM_ADDR_SELECT_REG; case 0x03F00020: ptr = (uint8_t*)&g_Reg->RDRAM_ADDR_SELECT_REG; break;
case 0x03F00024: return &g_Reg->RDRAM_DEVICE_MANUF_REG; case 0x03F00024: ptr = (uint8_t*)&g_Reg->RDRAM_DEVICE_MANUF_REG; break;
case 0x04040010: return &g_Reg->SP_STATUS_REG; case 0x04040010: ptr = (uint8_t*)&g_Reg->SP_STATUS_REG; break;
case 0x04040014: return &g_Reg->SP_DMA_FULL_REG; case 0x04040014: ptr = (uint8_t*)&g_Reg->SP_DMA_FULL_REG; break;
case 0x04040018: return &g_Reg->SP_DMA_BUSY_REG; case 0x04040018: ptr = (uint8_t*)&g_Reg->SP_DMA_BUSY_REG; break;
case 0x0404001C: return &g_Reg->SP_SEMAPHORE_REG; case 0x0404001C: ptr = (uint8_t*)&g_Reg->SP_SEMAPHORE_REG; break;
case 0x04080000: return &g_Reg->SP_PC_REG; case 0x04080000: ptr = (uint8_t*)&g_Reg->SP_PC_REG; break;
case 0x0410000C: return &g_Reg->DPC_STATUS_REG; case 0x0410000C: ptr = (uint8_t*)&g_Reg->DPC_STATUS_REG; break;
case 0x04100010: return &g_Reg->DPC_CLOCK_REG; case 0x04100010: ptr = (uint8_t*)&g_Reg->DPC_CLOCK_REG; break;
case 0x04100014: return &g_Reg->DPC_BUFBUSY_REG; case 0x04100014: ptr = (uint8_t*)&g_Reg->DPC_BUFBUSY_REG; break;
case 0x04100018: return &g_Reg->DPC_PIPEBUSY_REG; case 0x04100018: ptr = (uint8_t*)&g_Reg->DPC_PIPEBUSY_REG; break;
case 0x0410001C: return &g_Reg->DPC_TMEM_REG; case 0x0410001C: ptr = (uint8_t*)&g_Reg->DPC_TMEM_REG; break;
case 0x04300000: return &g_Reg->MI_MODE_REG; case 0x04300000: ptr = (uint8_t*)&g_Reg->MI_MODE_REG; break;
case 0x04300004: return &g_Reg->MI_VERSION_REG; case 0x04300004: ptr = (uint8_t*)&g_Reg->MI_VERSION_REG; break;
case 0x04300008: return &g_Reg->MI_INTR_REG; case 0x04300008: ptr = (uint8_t*)&g_Reg->MI_INTR_REG; break;
case 0x0430000C: return &g_Reg->MI_INTR_MASK_REG; case 0x0430000C: ptr = (uint8_t*)&g_Reg->MI_INTR_MASK_REG; break;
case 0x04400000: return &g_Reg->VI_STATUS_REG; case 0x04400000: ptr = (uint8_t*)&g_Reg->VI_STATUS_REG; break;
case 0x04400004: return &g_Reg->VI_ORIGIN_REG; case 0x04400004: ptr = (uint8_t*)&g_Reg->VI_ORIGIN_REG; break;
case 0x04400008: return &g_Reg->VI_WIDTH_REG; case 0x04400008: ptr = (uint8_t*)&g_Reg->VI_WIDTH_REG; break;
case 0x0440000C: return &g_Reg->VI_INTR_REG; case 0x0440000C: ptr = (uint8_t*)&g_Reg->VI_INTR_REG; break;
case 0x04400010: return &g_Reg->VI_V_CURRENT_LINE_REG; case 0x04400010: ptr = (uint8_t*)&g_Reg->VI_V_CURRENT_LINE_REG; break;
case 0x04400014: return &g_Reg->VI_BURST_REG; case 0x04400014: ptr = (uint8_t*)&g_Reg->VI_BURST_REG; break;
case 0x04400018: return &g_Reg->VI_V_SYNC_REG; case 0x04400018: ptr = (uint8_t*)&g_Reg->VI_V_SYNC_REG; break;
case 0x0440001C: return &g_Reg->VI_H_SYNC_REG; case 0x0440001C: ptr = (uint8_t*)&g_Reg->VI_H_SYNC_REG; break;
case 0x04400020: return &g_Reg->VI_LEAP_REG; case 0x04400020: ptr = (uint8_t*)&g_Reg->VI_LEAP_REG; break;
case 0x04400024: return &g_Reg->VI_H_START_REG; case 0x04400024: ptr = (uint8_t*)&g_Reg->VI_H_START_REG; break;
case 0x04400028: return &g_Reg->VI_V_START_REG; case 0x04400028: ptr = (uint8_t*)&g_Reg->VI_V_START_REG; break;
case 0x0440002C: return &g_Reg->VI_V_BURST_REG; case 0x0440002C: ptr = (uint8_t*)&g_Reg->VI_V_BURST_REG; break;
case 0x04400030: return &g_Reg->VI_X_SCALE_REG; case 0x04400030: ptr = (uint8_t*)&g_Reg->VI_X_SCALE_REG; break;
case 0x04400034: return &g_Reg->VI_Y_SCALE_REG; case 0x04400034: ptr = (uint8_t*)&g_Reg->VI_Y_SCALE_REG; break;
case 0x04600000: return &g_Reg->PI_DRAM_ADDR_REG; case 0x04600000: ptr = (uint8_t*)&g_Reg->PI_DRAM_ADDR_REG; break;
case 0x04600004: return &g_Reg->PI_CART_ADDR_REG; case 0x04600004: ptr = (uint8_t*)&g_Reg->PI_CART_ADDR_REG; break;
case 0x04600008: return &g_Reg->PI_RD_LEN_REG; case 0x04600008: ptr = (uint8_t*)&g_Reg->PI_RD_LEN_REG; break;
case 0x0460000C: return &g_Reg->PI_WR_LEN_REG; case 0x0460000C: ptr = (uint8_t*)&g_Reg->PI_WR_LEN_REG; break;
case 0x04600010: return &g_Reg->PI_STATUS_REG; case 0x04600010: ptr = (uint8_t*)&g_Reg->PI_STATUS_REG; break;
case 0x04600014: return &g_Reg->PI_DOMAIN1_REG; case 0x04600014: ptr = (uint8_t*)&g_Reg->PI_DOMAIN1_REG; break;
case 0x04600018: return &g_Reg->PI_BSD_DOM1_PWD_REG; case 0x04600018: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM1_PWD_REG; break;
case 0x0460001C: return &g_Reg->PI_BSD_DOM1_PGS_REG; case 0x0460001C: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM1_PGS_REG; break;
case 0x04600020: return &g_Reg->PI_BSD_DOM1_RLS_REG; case 0x04600020: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM1_RLS_REG; break;
case 0x04600024: return &g_Reg->PI_DOMAIN2_REG; case 0x04600024: ptr = (uint8_t*)&g_Reg->PI_DOMAIN2_REG; break;
case 0x04600028: return &g_Reg->PI_BSD_DOM2_PWD_REG; case 0x04600028: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM2_PWD_REG; break;
case 0x0460002C: return &g_Reg->PI_BSD_DOM2_PGS_REG; case 0x0460002C: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM2_PGS_REG; break;
case 0x04600030: return &g_Reg->PI_BSD_DOM2_RLS_REG; case 0x04600030: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM2_RLS_REG; break;
case 0x04700000: return &g_Reg->RI_MODE_REG; case 0x04700000: ptr = (uint8_t*)&g_Reg->RI_MODE_REG; break;
case 0x04700004: return &g_Reg->RI_CONFIG_REG; case 0x04700004: ptr = (uint8_t*)&g_Reg->RI_CONFIG_REG; break;
case 0x04700008: return &g_Reg->RI_CURRENT_LOAD_REG; case 0x04700008: ptr = (uint8_t*)&g_Reg->RI_CURRENT_LOAD_REG; break;
case 0x0470000C: return &g_Reg->RI_SELECT_REG; case 0x0470000C: ptr = (uint8_t*)&g_Reg->RI_SELECT_REG; break;
case 0x04700010: return &g_Reg->RI_REFRESH_REG; case 0x04700010: ptr = (uint8_t*)&g_Reg->RI_REFRESH_REG; break;
case 0x04700014: return &g_Reg->RI_LATENCY_REG; case 0x04700014: ptr = (uint8_t*)&g_Reg->RI_LATENCY_REG; break;
case 0x04700018: return &g_Reg->RI_RERROR_REG; case 0x04700018: ptr = (uint8_t*)&g_Reg->RI_RERROR_REG; break;
case 0x0470001C: return &g_Reg->RI_WERROR_REG; case 0x0470001C: ptr = (uint8_t*)&g_Reg->RI_WERROR_REG; break;
case 0x04800018: return &g_Reg->SI_STATUS_REG; case 0x04800018: ptr = (uint8_t*)&g_Reg->SI_STATUS_REG; break;
case 0x05000500: return &g_Reg->ASIC_DATA; case 0x05000500: ptr = (uint8_t*)&g_Reg->ASIC_DATA; break;
case 0x05000504: return &g_Reg->ASIC_MISC_REG; case 0x05000504: ptr = (uint8_t*)&g_Reg->ASIC_MISC_REG; break;
case 0x05000508: return &g_Reg->ASIC_STATUS; case 0x05000508: ptr = (uint8_t*)&g_Reg->ASIC_STATUS; break;
case 0x0500050C: return &g_Reg->ASIC_CUR_TK; case 0x0500050C: ptr = (uint8_t*)&g_Reg->ASIC_CUR_TK; break;
case 0x05000510: return &g_Reg->ASIC_BM_STATUS; case 0x05000510: ptr = (uint8_t*)&g_Reg->ASIC_BM_STATUS; break;
case 0x05000514: return &g_Reg->ASIC_ERR_SECTOR; case 0x05000514: ptr = (uint8_t*)&g_Reg->ASIC_ERR_SECTOR; break;
case 0x05000518: return &g_Reg->ASIC_SEQ_STATUS; case 0x05000518: ptr = (uint8_t*)&g_Reg->ASIC_SEQ_STATUS; break;
case 0x0500051C: return &g_Reg->ASIC_CUR_SECTOR; case 0x0500051C: ptr = (uint8_t*)&g_Reg->ASIC_CUR_SECTOR; break;
case 0x05000520: return &g_Reg->ASIC_HARD_RESET; case 0x05000520: ptr = (uint8_t*)&g_Reg->ASIC_HARD_RESET; break;
case 0x05000524: return &g_Reg->ASIC_C1_S0; case 0x05000524: ptr = (uint8_t*)&g_Reg->ASIC_C1_S0; break;
case 0x05000528: return &g_Reg->ASIC_HOST_SECBYTE; case 0x05000528: ptr = (uint8_t*)&g_Reg->ASIC_HOST_SECBYTE; break;
case 0x0500052C: return &g_Reg->ASIC_C1_S2; case 0x0500052C: ptr = (uint8_t*)&g_Reg->ASIC_C1_S2; break;
case 0x05000530: return &g_Reg->ASIC_SEC_BYTE; case 0x05000530: ptr = (uint8_t*)&g_Reg->ASIC_SEC_BYTE; break;
case 0x05000534: return &g_Reg->ASIC_C1_S4; case 0x05000534: ptr = (uint8_t*)&g_Reg->ASIC_C1_S4; break;
case 0x05000538: return &g_Reg->ASIC_C1_S6; case 0x05000538: ptr = (uint8_t*)&g_Reg->ASIC_C1_S6; break;
case 0x0500053C: return &g_Reg->ASIC_CUR_ADDR; case 0x0500053C: ptr = (uint8_t*)&g_Reg->ASIC_CUR_ADDR; break;
case 0x05000540: return &g_Reg->ASIC_ID_REG; case 0x05000540: ptr = (uint8_t*)&g_Reg->ASIC_ID_REG; break;
case 0x05000544: return &g_Reg->ASIC_TEST_REG; case 0x05000544: ptr = (uint8_t*)&g_Reg->ASIC_TEST_REG; break;
case 0x05000548: return &g_Reg->ASIC_TEST_PIN_SEL; case 0x05000548: ptr = (uint8_t*)&g_Reg->ASIC_TEST_PIN_SEL; break;
}
} }
if (ptr == NULL)
{
return NULL; return NULL;
}
if (flags != NULL)
{
*flags = (bCartRom ? PJMEM_CARTROM : 0);
}
if (bBigEndian)
{
return &ptr[nbyte];
}
else
{
return &ptr[nbyte ^ 3];
}
} }
bool CDebugMMU::DebugLW_PAddr(uint32_t paddr, uint32_t& value) bool CDebugMMU::GetPhysicalByte(uint32_t paddr, uint8_t* value)
{ {
if (g_MMU == NULL) uint8_t* ptr = GetPhysicalPtr(paddr, NULL);
{
return false;
}
uint32_t* ptr = PAddrWordPtr(paddr);
if (ptr != NULL) if (ptr != NULL)
{ {
value = *ptr; *value = *ptr;
return true; return true;
} }
if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2) int nByte = paddr & 3;
if (paddr >= 0x08000000 && paddr <= 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{ {
uint32_t saveOffset = paddr & 0x000FFFFF; uint32_t saveOffset = paddr & 0x000FFFFF;
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram
{ {
uint8_t tmp[4] = ""; uint32_t wordpaddr = paddr & ~3;
uint8_t data[4];
CSram *sram = g_MMU->GetSram(); CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(tmp, paddr - 0x08000000, 4); sram->DmaFromSram(data, wordpaddr - 0x08000000, 4);
value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0]; *value = data[nByte ^ 3];
return true; return true;
} }
else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset <= 3) // flash ram status
{ {
CFlashram* flashRam = g_MMU->GetFlashram(); CFlashram* flashRam = g_MMU->GetFlashram();
value = flashRam->ReadFromFlashStatus(0x08000000); uint32_t flashStatus = flashRam->ReadFromFlashStatus(0x08000000);
*value = (flashStatus >> (24 - nByte * 8)) & 0xFF;
return true; return true;
} }
} }
if (paddr == 0x04500004) if (paddr >= 0x04500004 && paddr <= 0x04500007)
{ {
uint32_t audioLength;
if (g_System->bFixedAudio()) if (g_System->bFixedAudio())
{ {
value = g_Audio->GetLength(); audioLength = g_Audio->GetLength();
} }
else else
{ {
CAudioPlugin* audioPlg = g_Plugins->Audio(); CAudioPlugin* audioPlg = g_Plugins->Audio();
value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0; audioLength = audioPlg->AiReadLength != NULL ? audioPlg->AiReadLength() : 0;
} }
*value = (audioLength >> (24 - nByte * 8)) & 0xFF;
return true; return true;
} }
if (paddr == 0x0450000C) if (paddr >= 0x0450000C && paddr <= 0x0450000F)
{ {
value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG; uint32_t audioStatus = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG;
*value = (audioStatus >> (24 - nByte * 8)) & 0xFF;
return true; return true;
} }
return false; return false;
} }
bool CDebugMMU::DebugLW_VAddr(uint32_t vaddr, uint32_t& value) bool CDebugMMU::SetPhysicalByte(uint32_t paddr, uint8_t value)
{ {
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB) WORD flags;
uint8_t* ptr = GetPhysicalPtr(paddr, &flags);
bool bCartRom = flags & PJMEM_CARTROM;
if (ptr != NULL)
{ {
if (g_MMU == NULL) if (!bCartRom)
{ {
return false; *ptr = value;
} }
else
return g_MMU->LW_VAddr(vaddr, value);
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugLW_PAddr(paddr, value);
}
bool CDebugMMU::DebugLB_PAddr(uint32_t vaddr, uint8_t& value)
{
uint32_t word;
if (!DebugLW_PAddr(vaddr & ~3, word))
{
return false;
}
value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF;
return true;
}
bool CDebugMMU::DebugLB_VAddr(uint32_t vaddr, uint8_t& value)
{
uint32_t word;
if (!DebugLW_VAddr(vaddr & ~3, word))
{
return false;
}
value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF;
return true;
}
bool CDebugMMU::DebugSB_PAddr(uint32_t paddr, uint8_t value)
{
bool bWriteToRom = false;
if (paddr >= 0x10000000 && paddr <= 0x1FBFFFFF)
{
uint32_t romOffset = paddr - 0x10000000;
if (romOffset > g_Rom->GetRomSize())
{
return false;
}
bWriteToRom = true;
}
int nbyte = 3 - (paddr & 3);
uint8_t* ptr = (uint8_t*)PAddrWordPtr(paddr & ~3);
if (ptr == NULL)
{
return false;
}
if (bWriteToRom)
{ {
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READWRITE); ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READWRITE);
} *ptr = value;
ptr[nbyte] = value;
if (bWriteToRom)
{
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READONLY); ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READONLY);
} }
return true; return true;
} }
bool CDebugMMU::DebugSB_VAddr(uint32_t vaddr, uint8_t value) int nByte = paddr & 3;
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB) if (paddr >= 0x08000000 && paddr <= 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{ {
if (g_MMU == NULL) uint32_t saveOffset = paddr & 0x000FFFFF;
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF)
{ {
uint32_t wordpaddr = paddr & ~3;
uint8_t data[4];
CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(data, wordpaddr - 0x08000000, sizeof(data));
data[nByte ^ 3] = value;
sram->DmaToSram(data, wordpaddr - 0x08000000, sizeof(data));
return true;
}
}
return false; return false;
} }
return g_MMU->SB_VAddr(vaddr, value); size_t CDebugMMU::ReadPhysical(uint32_t paddr, size_t length, uint8_t* buffer)
} {
size_t nByte;
uint32_t paddr = vaddr & 0x1FFFFFFF; for (nByte = 0; nByte < length; nByte++)
return DebugSB_PAddr(paddr, value); {
if (!GetPhysicalByte(paddr + nByte, &buffer[nByte]))
{
return nByte;
}
}
return nByte;
}
size_t CDebugMMU::ReadVirtual(uint32_t vaddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
uint32_t paddr;
if (!g_MMU || !g_MMU->TranslateVaddr(vaddr + nByte, paddr))
{
return nByte;
}
if (!GetPhysicalByte(paddr, &buffer[nByte]))
{
return nByte;
}
}
return nByte;
}
size_t CDebugMMU::WritePhysical(uint32_t paddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
if (!SetPhysicalByte(paddr + nByte, buffer[nByte]))
{
return nByte;
}
}
return nByte;
}
size_t CDebugMMU::WriteVirtual(uint32_t vaddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
uint32_t paddr;
if (!g_MMU || !g_MMU->TranslateVaddr(vaddr + nByte, paddr))
{
return nByte;
}
if (!SetPhysicalByte(paddr, buffer[nByte]))
{
return nByte;
}
}
return nByte;
} }

View File

@ -1,15 +1,115 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <stdafx.h> #include <stdafx.h>
class CDebugMMU class CDebugMMU
{ {
private:
uint32_t* PAddrWordPtr(uint32_t paddr);
public: public:
bool DebugLW_PAddr(uint32_t paddr, uint32_t& value); size_t ReadPhysical(uint32_t paddr, size_t length, uint8_t* buffer);
bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value); size_t ReadVirtual(uint32_t vaddr, size_t length, uint8_t* buffer);
bool DebugLB_PAddr(uint32_t paddr, uint8_t& value); size_t WritePhysical(uint32_t paddr, size_t length, uint8_t* buffer);
bool DebugLB_VAddr(uint32_t vaddr, uint8_t& value); size_t WriteVirtual(uint32_t vaddr, size_t length, uint8_t* buffer);
bool DebugSB_PAddr(uint32_t paddr, uint8_t value);
bool DebugSB_VAddr(uint32_t vaddr, uint8_t value); template<typename T>
bool DebugLoad_PAddr(uint32_t paddr, T& value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer;
if (ReadPhysical(paddr, sizeof(buffer), buffer.bytes) == sizeof(buffer))
{
value = ByteSwap<T>(buffer.word);
return true;
}
return false;
}
template<typename T>
bool DebugLoad_VAddr(uint32_t vaddr, T& value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer;
if (ReadVirtual(vaddr, sizeof(buffer), buffer.bytes) == sizeof(buffer))
{
value = ByteSwap<T>(buffer.word);
return true;
}
return false;
}
template<typename T>
bool DebugStore_PAddr(uint32_t paddr, T value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer = { ByteSwap<T>(value) };
return (WritePhysical(paddr, sizeof(buffer), buffer.bytes) == sizeof(buffer));
}
template<typename T>
bool DebugStore_VAddr(uint32_t vaddr, T value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer = { ByteSwap<T>(value) };
return (WriteVirtual(vaddr, sizeof(buffer), buffer.bytes) == sizeof(buffer));
}
private:
uint8_t* GetPhysicalPtr(uint32_t paddr, WORD* flags = NULL);
bool GetPhysicalByte(uint32_t paddr, uint8_t* value);
bool SetPhysicalByte(uint32_t paddr, uint8_t value);
template<typename T>
T ByteSwap(T value)
{
union
{
T value;
uint16_t u16;
uint32_t u32;
uint64_t u64;
} bytes;
bytes.value = value;
switch (sizeof(T))
{
case sizeof(uint8_t) :
break;
case sizeof(uint16_t) :
bytes.u16 = _byteswap_ushort(bytes.u16);
break;
case sizeof(uint32_t) :
bytes.u32 = _byteswap_ulong(bytes.u32);
break;
case sizeof(uint64_t) :
bytes.u64 = _byteswap_uint64(bytes.u64);
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
return bytes.value;
}
}; };

View File

@ -26,12 +26,12 @@ LRESULT CAddSymbolDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*l
for (int i = 0;; i++) for (int i = 0;; i++)
{ {
char* type = CSymbols::SymbolTypes[i]; const char* typeName = CSymbolTable::m_SymbolTypes[i].name;
if (type == NULL) if (typeName == NULL)
{ {
break; break;
} }
m_TypeComboBox.AddString(type); m_TypeComboBox.AddString(typeName);
} }
m_AddressEdit.SetWindowTextA(""); m_AddressEdit.SetWindowTextA("");
@ -50,7 +50,7 @@ LRESULT CAddSymbolDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*l
} }
else else
{ {
m_TypeComboBox.SetCurSel(CSymbols::TYPE_DATA); m_TypeComboBox.SetCurSel(SYM_DATA);
} }
return FALSE; return FALSE;
@ -90,10 +90,8 @@ LRESULT CAddSymbolDlg::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*
m_NameEdit.GetWindowTextA(name, nameLen + 1); m_NameEdit.GetWindowTextA(name, nameLen + 1);
m_DescriptionEdit.GetWindowTextA(description, descLen + 1); m_DescriptionEdit.GetWindowTextA(description, descLen + 1);
CSymbols::EnterCriticalSection(); m_Debugger->SymbolTable()->AddSymbol(type, address, name, description);
CSymbols::Add(type, address, name, description); m_Debugger->SymbolTable()->Save();
CSymbols::Save();
CSymbols::LeaveCriticalSection();
m_Debugger->Debug_RefreshSymbolsWindow(); m_Debugger->Debug_RefreshSymbolsWindow();

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
#include "DebuggerUI.h" #include "DebuggerUI.h"
#include "CPULog.h" #include "CPULog.h"
@ -75,6 +86,8 @@ LRESULT CDebugCPULogView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
LRESULT CDebugCPULogView::OnDestroy(void) LRESULT CDebugCPULogView::OnDestroy(void)
{ {
UnhookWindowsHookEx(hWinMessageHook);
m_CPUListView.Detach(); m_CPUListView.Detach();
m_StateInfoEdit.Detach(); m_StateInfoEdit.Detach();
m_EnabledChk.Detach(); m_EnabledChk.Detach();

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <stdafx.h> #include <stdafx.h>

View File

@ -530,8 +530,6 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
m_bvAnnotatedLines.clear(); m_bvAnnotatedLines.clear();
CSymbols::EnterCriticalSection();
for (int i = 0; i < m_CommandListRows; i++) for (int i = 0; i < m_CommandListRows; i++)
{ {
uint32_t opAddr = m_StartAddress + i * 4; uint32_t opAddr = m_StartAddress + i * 4;
@ -546,7 +544,7 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
COpInfo OpInfo; COpInfo OpInfo;
OPCODE& OpCode = OpInfo.m_OpCode; OPCODE& OpCode = OpInfo.m_OpCode;
if (!m_Debugger->DebugLW_VAddr(opAddr, OpCode.Hex)) if (!m_Debugger->DebugLoad_VAddr(opAddr, OpCode.Hex))
{ {
m_CommandList.AddItem(i, CCommandList::COL_COMMAND, "***"); m_CommandList.AddItem(i, CCommandList::COL_COMMAND, "***");
m_bvAnnotatedLines.push_back(false); m_bvAnnotatedLines.push_back(false);
@ -562,11 +560,10 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
{ {
uint32_t targetAddr = (0x80000000 | (OpCode.target << 2)); uint32_t targetAddr = (0x80000000 | (OpCode.target << 2));
// todo move symbols management to CDebuggerUI CSymbol symbol;
const char* targetSymbolName = CSymbols::GetNameByAddress(targetAddr); if (m_Debugger->SymbolTable()->GetSymbolByAddress(targetAddr, &symbol))
if (targetSymbolName != NULL)
{ {
cmdArgs = (char*)targetSymbolName; cmdArgs = (char*)symbol.m_Name;
} }
} }
@ -580,7 +577,7 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
{ {
OPCODE OpCodeTest; OPCODE OpCodeTest;
if (!m_Debugger->DebugLW_VAddr(opAddr + offset, OpCodeTest.Hex)) if (!m_Debugger->DebugLoad_VAddr(opAddr + offset, OpCodeTest.Hex))
{ {
break; break;
} }
@ -597,9 +594,12 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
uint32_t memAddr = (OpCodeTest.immediate << 16) + (short)OpCode.offset; uint32_t memAddr = (OpCodeTest.immediate << 16) + (short)OpCode.offset;
annotation = CSymbols::GetNameByAddress(memAddr); CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByAddress(memAddr, &symbol))
if (annotation == NULL) {
annotation = symbol.m_Name;
}
else
{ {
annotation = GetDataAddressNotes(memAddr); annotation = GetDataAddressNotes(memAddr);
} }
@ -620,10 +620,10 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
m_CommandList.AddItem(i, CCommandList::COL_PARAMETERS, cmdArgs); m_CommandList.AddItem(i, CCommandList::COL_PARAMETERS, cmdArgs);
// Show routine symbol name for this address // Show routine symbol name for this address
const char* routineSymbolName = CSymbols::GetNameByAddress(opAddr); CSymbol symbol;
if (routineSymbolName != NULL) if (m_Debugger->SymbolTable()->GetSymbolByAddress(opAddr, &symbol))
{ {
m_CommandList.AddItem(i, CCommandList::COL_SYMBOL, routineSymbolName); m_CommandList.AddItem(i, CCommandList::COL_SYMBOL, symbol.m_Name);
m_bvAnnotatedLines.push_back(false); m_bvAnnotatedLines.push_back(false);
} }
else if (annotation != NULL) else if (annotation != NULL)
@ -660,8 +660,6 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
} }
} }
CSymbols::LeaveCriticalSection();
if (!top) // update registers when called via breakpoint/stepping if (!top) // update registers when called via breakpoint/stepping
{ {
m_RegisterTabs.RefreshEdits(); m_RegisterTabs.RefreshEdits();
@ -697,7 +695,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
uint32_t pc = (g_Reg != NULL) ? g_Reg->m_PROGRAM_COUNTER : 0; uint32_t pc = (g_Reg != NULL) ? g_Reg->m_PROGRAM_COUNTER : 0;
OPCODE pcOpcode; OPCODE pcOpcode;
if (!m_Debugger->DebugLW_VAddr(pc, pcOpcode.Hex)) if (!m_Debugger->DebugLoad_VAddr(pc, pcOpcode.Hex))
{ {
pcOpcode.Hex = 0; pcOpcode.Hex = 0;
} }
@ -747,7 +745,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
// cmd & args // cmd & args
COpInfo OpInfo; COpInfo OpInfo;
OPCODE& OpCode = OpInfo.m_OpCode; OPCODE& OpCode = OpInfo.m_OpCode;
bool bAddrOkay = m_Debugger->DebugLW_VAddr(address, OpCode.Hex); bool bAddrOkay = m_Debugger->DebugLoad_VAddr(address, OpCode.Hex);
struct { struct {
COLORREF bg; COLORREF bg;
@ -1068,7 +1066,7 @@ void CDebugCommandsView::CPUResume()
void CDebugCommandsView::CPUStepOver() void CDebugCommandsView::CPUStepOver()
{ {
COpInfo opInfo; COpInfo opInfo;
if (!m_Debugger->DebugLW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex)) if (!m_Debugger->DebugLoad_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex))
{ {
return; return;
} }
@ -1220,7 +1218,7 @@ LRESULT CDebugCommandsView::OnPopupmenuRestoreAll(WORD /*wNotifyCode*/, WORD /*w
LRESULT CDebugCommandsView::OnPopupmenuAddSymbol(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hwnd*/, BOOL& /*bHandled*/) LRESULT CDebugCommandsView::OnPopupmenuAddSymbol(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hwnd*/, BOOL& /*bHandled*/)
{ {
m_AddSymbolDlg.DoModal(m_Debugger, m_SelectedAddress, CSymbols::TYPE_CODE); m_AddSymbolDlg.DoModal(m_Debugger, m_SelectedAddress, SYM_CODE);
return FALSE; return FALSE;
} }
@ -1255,7 +1253,7 @@ LRESULT CDebugCommandsView::OnPopupmenuClearBP(WORD /*wNotifyCode*/, WORD /*wID*
void CDebugCommandsView::BeginOpEdit(uint32_t address) void CDebugCommandsView::BeginOpEdit(uint32_t address)
{ {
uint32_t opcode; uint32_t opcode;
if (!m_Debugger->DebugLW_VAddr(address, opcode)) if (!m_Debugger->DebugLoad_VAddr(address, opcode))
{ {
return; return;
} }
@ -1368,7 +1366,7 @@ LRESULT CDebugCommandsView::OnCommandListRightClicked(NMHDR* pNMHDR)
uint32_t address = m_StartAddress + nItem * 4; uint32_t address = m_StartAddress + nItem * 4;
m_SelectedAddress = address; m_SelectedAddress = address;
if (!m_Debugger->DebugLW_VAddr(m_SelectedAddress, m_SelectedOpCode.Hex)) if (!m_Debugger->DebugLoad_VAddr(m_SelectedAddress, m_SelectedOpCode.Hex))
{ {
return 0; return 0;
} }
@ -1578,7 +1576,7 @@ BOOL CDebugCommandsView::IsOpEdited(uint32_t address)
void CDebugCommandsView::EditOp(uint32_t address, uint32_t op) void CDebugCommandsView::EditOp(uint32_t address, uint32_t op)
{ {
uint32_t currentOp; uint32_t currentOp;
if (!m_Debugger->DebugLW_VAddr(address, currentOp)) if (!m_Debugger->DebugLoad_VAddr(address, currentOp))
{ {
return; return;
} }
@ -1588,7 +1586,7 @@ void CDebugCommandsView::EditOp(uint32_t address, uint32_t op)
return; return;
} }
g_MMU->SW_VAddr(address, op); m_Debugger->DebugStore_VAddr(address, op);
if (!IsOpEdited(address)) if (!IsOpEdited(address))
{ {
@ -1604,7 +1602,7 @@ void CDebugCommandsView::RestoreOp(uint32_t address)
{ {
if (m_EditedOps[i].address == address) if (m_EditedOps[i].address == address)
{ {
g_MMU->SW_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp); m_Debugger->DebugStore_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp);
m_EditedOps.erase(m_EditedOps.begin() + i); m_EditedOps.erase(m_EditedOps.begin() + i);
break; break;
} }
@ -1616,7 +1614,7 @@ void CDebugCommandsView::RestoreAllOps()
int lastIndex = m_EditedOps.size() - 1; int lastIndex = m_EditedOps.size() - 1;
for (int i = lastIndex; i >= 0; i--) for (int i = lastIndex; i >= 0; i--)
{ {
g_MMU->SW_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp); m_Debugger->DebugStore_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp);
m_EditedOps.erase(m_EditedOps.begin() + i); m_EditedOps.erase(m_EditedOps.begin() + i);
} }
} }

View File

@ -100,21 +100,21 @@ void CDebugDMALogView::RefreshList()
m_DMAList.AddItem(itemIndex, 1, stdstr_f("%08X", lpEntry->ramAddr).c_str()); m_DMAList.AddItem(itemIndex, 1, stdstr_f("%08X", lpEntry->ramAddr).c_str());
m_DMAList.AddItem(itemIndex, 2, stdstr_f("%08X (%d)", lpEntry->length, lpEntry->length).c_str()); m_DMAList.AddItem(itemIndex, 2, stdstr_f("%08X (%d)", lpEntry->length, lpEntry->length).c_str());
char sigc[5]; union
memset(sigc, 0, sizeof(sigc)); {
uint32_t u32;
uint8_t sz[5];
} sig = { 0 };
if (lpEntry->romAddr < g_Rom->GetRomSize()) if (lpEntry->romAddr < g_Rom->GetRomSize())
{ {
uint32_t sig = *(uint32_t*)&rom[lpEntry->romAddr]; sig.u32 = *(uint32_t*)&rom[lpEntry->romAddr];
sig = _byteswap_ulong(sig);
memcpy(sigc, &sig, 4);
sigc[4] = '\0';
} }
// Todo checkbox to display all in hex // Todo checkbox to display all in hex
if (isalnum(sigc[0]) && isalnum(sigc[1]) && isalnum(sigc[2]) && isalnum(sigc[3])) if (isalnum(sig.sz[0]) && isalnum(sig.sz[1]) && isalnum(sig.sz[2]) && isalnum(sig.sz[3]))
{ {
m_DMAList.AddItem(itemIndex, 4, sigc); m_DMAList.AddItem(itemIndex, 4, (char*)sig.sz);
} }
itemIndex++; itemIndex++;

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
#include "DebuggerUI.h" #include "DebuggerUI.h"

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <stdafx.h> #include <stdafx.h>

View File

@ -161,7 +161,7 @@ bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC,
for (uint32_t pc = StartPC; pc < EndPC; pc += 4, DumpPC += 4) for (uint32_t pc = StartPC; pc < EndPC; pc += 4, DumpPC += 4)
{ {
OPCODE opcode; OPCODE opcode;
g_MMU->LW_VAddr(pc, opcode.Hex); m_Debugger->DebugLoad_VAddr(pc, opcode.Hex);
const char* command = R4300iOpcodeName(opcode.Hex, DumpPC); const char* command = R4300iOpcodeName(opcode.Hex, DumpPC);
@ -193,7 +193,7 @@ bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC,
for (uint32_t pc = StartPC; pc < EndPC; pc++, dumpIdx++) for (uint32_t pc = StartPC; pc < EndPC; pc++, dumpIdx++)
{ {
bool bReadable = g_MMU->LB_VAddr(pc, dumpBuf[dumpIdx]); bool bReadable = m_Debugger->DebugLoad_VAddr(pc, dumpBuf[dumpIdx]);
if (!bReadable) if (!bReadable)
{ {

View File

@ -107,8 +107,10 @@ LRESULT CDebugMemorySearch::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA
::GetWindowRect(GetDlgItem(IDC_SEPARATOR), &m_InitialSeparatorRect); ::GetWindowRect(GetDlgItem(IDC_SEPARATOR), &m_InitialSeparatorRect);
ScreenToClient(&m_InitialSeparatorRect); ScreenToClient(&m_InitialSeparatorRect);
uint32_t ramSize = (g_MMU != NULL) ? g_MMU->RdramSize() : 0x00400000;
m_AddrStart.SetValue(0x80000000, true, true); m_AddrStart.SetValue(0x80000000, true, true);
m_AddrEnd.SetValue(0x80000000 + g_MMU->RdramSize() - 1, true, true); m_AddrEnd.SetValue(0x80000000 + ramSize - 1, true, true);
FixListHeader(m_WatchListCtrl); FixListHeader(m_WatchListCtrl);
FixListHeader(m_ResultsListCtrl); FixListHeader(m_ResultsListCtrl);
@ -134,6 +136,7 @@ LRESULT CDebugMemorySearch::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA
LRESULT CDebugMemorySearch::OnDestroy(void) LRESULT CDebugMemorySearch::OnDestroy(void)
{ {
UnhookWindowsHookEx(hWinMessageHook);
KillTimer(TIMER_ID_AUTO_REFRESH); KillTimer(TIMER_ID_AUTO_REFRESH);
m_UnsignedCheckbox.Detach(); m_UnsignedCheckbox.Detach();
@ -343,8 +346,9 @@ LRESULT CDebugMemorySearch::OnRdramButton(WORD /*wNotifyCode*/, WORD /*wID*/, HW
{ {
bool bPhysicalChecked = (m_PhysicalCheckbox.GetCheck() == BST_CHECKED); bool bPhysicalChecked = (m_PhysicalCheckbox.GetCheck() == BST_CHECKED);
uint32_t addrStart = bPhysicalChecked ? 0 : 0x80000000; uint32_t addrStart = bPhysicalChecked ? 0 : 0x80000000;
uint32_t ramSize = (g_MMU != NULL) ? g_MMU->RdramSize() : 0x00400000;
m_AddrStart.SetValue(addrStart, true, true); m_AddrStart.SetValue(addrStart, true, true);
m_AddrEnd.SetValue(addrStart + g_MMU->RdramSize() - 1, true, true); m_AddrEnd.SetValue(addrStart + ramSize - 1, true, true);
return FALSE; return FALSE;
} }

View File

@ -498,7 +498,7 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID); WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);
COpInfo opInfo; COpInfo opInfo;
g_MMU->LW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex); m_Debugger->DebugLoad_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);
bool bOpReads = false; bool bOpReads = false;
bool bOpWrites = false; bool bOpWrites = false;

View File

@ -19,13 +19,11 @@ CDebugScripts::CDebugScripts(CDebuggerUI* debugger) :
CDebugDialog<CDebugScripts>(debugger) CDebugDialog<CDebugScripts>(debugger)
{ {
m_SelectedScriptName = (char*)malloc(MAX_PATH); m_SelectedScriptName = (char*)malloc(MAX_PATH);
InitializeCriticalSection(&m_CriticalSection);
//CScriptSystem::SetScriptsWindow(this); //CScriptSystem::SetScriptsWindow(this);
} }
CDebugScripts::~CDebugScripts(void) CDebugScripts::~CDebugScripts(void)
{ {
DeleteCriticalSection(&m_CriticalSection);
free(m_SelectedScriptName); free(m_SelectedScriptName);
} }
@ -93,7 +91,7 @@ void CDebugScripts::ConsolePrint(const char* text)
void CDebugScripts::RefreshConsole() void CDebugScripts::RefreshConsole()
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
m_Debugger->OpenScriptsWindow(); m_Debugger->OpenScriptsWindow();
CScriptSystem* scriptSystem = m_Debugger->ScriptSystem(); CScriptSystem* scriptSystem = m_Debugger->ScriptSystem();
@ -105,8 +103,6 @@ void CDebugScripts::RefreshConsole()
free((*logData)[0]); free((*logData)[0]);
logData->erase(logData->begin() + 0); logData->erase(logData->begin() + 0);
} }
LeaveCriticalSection(&m_CriticalSection);
} }
void CDebugScripts::ConsoleClear() void CDebugScripts::ConsoleClear()
@ -139,7 +135,7 @@ void CDebugScripts::ConsoleCopy()
void CDebugScripts::RefreshList() void CDebugScripts::RefreshList()
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
int nIndex = m_ScriptList.GetSelectedIndex(); int nIndex = m_ScriptList.GetSelectedIndex();
@ -147,7 +143,6 @@ void CDebugScripts::RefreshList()
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES)) if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
{ {
LeaveCriticalSection(&m_CriticalSection);
return; return;
} }
@ -168,8 +163,6 @@ void CDebugScripts::RefreshList()
m_ScriptList.SelectItem(nIndex); m_ScriptList.SelectItem(nIndex);
RefreshStatus(); RefreshStatus();
} }
LeaveCriticalSection(&m_CriticalSection);
} }
LRESULT CDebugScripts::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) LRESULT CDebugScripts::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
@ -210,7 +203,7 @@ LRESULT CDebugScripts::OnScriptListDblClicked(NMHDR* pNMHDR)
void CDebugScripts::RefreshStatus() void CDebugScripts::RefreshStatus()
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName); INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
char* szState = ""; char* szState = "";
@ -234,8 +227,6 @@ void CDebugScripts::RefreshStatus()
{ {
m_EvalEdit.EnableWindow(FALSE); m_EvalEdit.EnableWindow(FALSE);
} }
LeaveCriticalSection(&m_CriticalSection);
} }
LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR) LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR)

View File

@ -89,7 +89,7 @@ private:
char* m_SelectedScriptName; char* m_SelectedScriptName;
void RefreshStatus(); void RefreshStatus();
CRITICAL_SECTION m_CriticalSection; CriticalSection m_CS;
public: public:
enum { IDD = IDD_Debugger_Scripts }; enum { IDD = IDD_Debugger_Scripts };

View File

@ -98,8 +98,6 @@ void CDebugStackTrace::Refresh()
m_List.SetRedraw(FALSE); m_List.SetRedraw(FALSE);
m_List.DeleteAllItems(); m_List.DeleteAllItems();
CSymbols::EnterCriticalSection();
for (int i = 0; i < m_EntriesIndex; i++) for (int i = 0; i < m_EntriesIndex; i++)
{ {
uint32_t routineAddress = m_Entries[i].routineAddress; uint32_t routineAddress = m_Entries[i].routineAddress;
@ -112,10 +110,11 @@ void CDebugStackTrace::Refresh()
sprintf(szAddress, "%08X", routineAddress); sprintf(szAddress, "%08X", routineAddress);
m_List.AddItem(i, 1, szAddress); m_List.AddItem(i, 1, szAddress);
CSymbolEntry* symbol = CSymbols::GetEntryByAddress(routineAddress); CSymbol symbol;
if(symbol != NULL)
if (m_Debugger->SymbolTable()->GetSymbolByAddress(routineAddress, &symbol))
{ {
m_List.AddItem(i, 2, symbol->m_Name); m_List.AddItem(i, 2, symbol.m_Name);
} }
else else
{ {
@ -125,7 +124,5 @@ void CDebugStackTrace::Refresh()
m_List.SetItemData(i, routineAddress); m_List.SetItemData(i, routineAddress);
} }
CSymbols::LeaveCriticalSection();
m_List.SetRedraw(TRUE); m_List.SetRedraw(TRUE);
} }

View File

@ -59,9 +59,6 @@ private:
STACKTRACE_ENTRY m_Entries[STACKTRACE_MAX_ENTRIES]; STACKTRACE_ENTRY m_Entries[STACKTRACE_MAX_ENTRIES];
int m_EntriesIndex; int m_EntriesIndex;
HANDLE m_AutoRefreshThread;
static DWORD WINAPI AutoRefreshProc(void* _this);
CListViewCtrl m_List; CListViewCtrl m_List;
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);

View File

@ -91,8 +91,6 @@ void CDebugStackView::Refresh()
uint32_t spBase = g_Reg->m_GPR[29].UW[0]; uint32_t spBase = g_Reg->m_GPR[29].UW[0];
m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str()); m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str());
CSymbols::EnterCriticalSection();
for (int i = 0; i < 0x10; i++) for (int i = 0; i < 0x10; i++)
{ {
char t[4]; char t[4];
@ -104,7 +102,7 @@ void CDebugStackView::Refresh()
uint32_t vaddr = spBase + (i * 0x10) + (j * 4); uint32_t vaddr = spBase + (i * 0x10) + (j * 4);
uint32_t val; uint32_t val;
if (!m_Debugger->DebugLW_VAddr(vaddr, val)) if (!m_Debugger->DebugLoad_VAddr(vaddr, val))
{ {
m_StackList.AddItem(i, j + 1, "????????"); m_StackList.AddItem(i, j + 1, "????????");
continue; continue;
@ -116,7 +114,5 @@ void CDebugStackView::Refresh()
} }
} }
CSymbols::LeaveCriticalSection();
m_StackList.SetRedraw(TRUE); m_StackList.SetRedraw(TRUE);
} }

View File

@ -44,7 +44,7 @@ LRESULT CDebugSymbols::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*l
Refresh(); Refresh();
m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL); SetTimer(TIMER_ID_AUTO_REFRESH, 100, NULL);
LoadWindowPos(); LoadWindowPos();
WindowCreated(); WindowCreated();
@ -58,22 +58,16 @@ void CDebugSymbols::OnExitSizeMove(void)
LRESULT CDebugSymbols::OnDestroy(void) LRESULT CDebugSymbols::OnDestroy(void)
{ {
KillTimer(TIMER_ID_AUTO_REFRESH);
m_SymbolsListView.Detach(); m_SymbolsListView.Detach();
if (m_AutoRefreshThread != NULL)
{
TerminateThread(m_AutoRefreshThread, 0);
CloseHandle(m_AutoRefreshThread);
}
return 0; return 0;
} }
DWORD WINAPI CDebugSymbols::AutoRefreshProc(void* _this) void CDebugSymbols::OnTimer(UINT_PTR nIDEvent)
{ {
CDebugSymbols* self = (CDebugSymbols*)_this; if (nIDEvent == TIMER_ID_AUTO_REFRESH)
while (true)
{ {
self->RefreshValues(); RefreshValues();
Sleep(100);
} }
} }
@ -89,12 +83,14 @@ LRESULT CDebugSymbols::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*
break; break;
case IDC_REMOVESYMBOL_BTN: case IDC_REMOVESYMBOL_BTN:
{ {
int id = m_SymbolsListView.GetItemData(m_SymbolsListView.GetSelectedIndex()); int nItem = m_SymbolsListView.GetSelectedIndex();
CSymbols::EnterCriticalSection(); if (nItem != -1)
CSymbols::RemoveEntryById(id); {
CSymbols::Save(); int id = m_SymbolsListView.GetItemData(nItem);
CSymbols::LeaveCriticalSection(); m_Debugger->SymbolTable()->RemoveSymbolById(id);
m_Debugger->SymbolTable()->Save();
Refresh(); Refresh();
}
break; break;
} }
} }
@ -108,15 +104,20 @@ LRESULT CDebugSymbols::OnListDblClicked(NMHDR* pNMHDR)
int nItem = pIA->iItem; int nItem = pIA->iItem;
int id = m_SymbolsListView.GetItemData(nItem); int id = m_SymbolsListView.GetItemData(nItem);
CSymbolEntry* symbol = CSymbols::GetEntryById(id);
if (symbol->m_Type == 0) // code CSymbol symbol;
if (!m_Debugger->SymbolTable()->GetSymbolById(id, &symbol))
{ {
m_Debugger->Debug_ShowCommandsLocation(symbol->m_Address, true); return 0;
}
if (symbol.m_Type == SYM_CODE) // code
{
m_Debugger->Debug_ShowCommandsLocation(symbol.m_Address, true);
} }
else // data/number else // data/number
{ {
m_Debugger->Debug_ShowMemoryLocation(symbol->m_Address, true); m_Debugger->Debug_ShowMemoryLocation(symbol.m_Address, true);
} }
return 0; return 0;
@ -131,32 +132,25 @@ void CDebugSymbols::Refresh()
m_SymbolsListView.SetRedraw(FALSE); m_SymbolsListView.SetRedraw(FALSE);
m_SymbolsListView.DeleteAllItems(); m_SymbolsListView.DeleteAllItems();
CSymbols::EnterCriticalSection(); CSymbol symbol;
int nItem = 0;
int count = CSymbols::GetCount(); while (m_Debugger->SymbolTable()->GetSymbolByIndex(nItem, &symbol))
for (int i = 0; i < count; i++)
{
CSymbolEntry* lpSymbol = CSymbols::GetEntryByIndex(i);
stdstr addrStr = stdstr_f("%08X", lpSymbol->m_Address);
m_SymbolsListView.AddItem(i, 0, addrStr.c_str());
m_SymbolsListView.AddItem(i, 1, lpSymbol->TypeName());
m_SymbolsListView.AddItem(i, 2, lpSymbol->m_Name);
m_SymbolsListView.AddItem(i, 4, lpSymbol->m_Description);
m_SymbolsListView.SetItemData(i, lpSymbol->m_Id);
if (g_MMU)
{ {
char szValue[64]; char szValue[64];
CSymbols::GetValueString(szValue, lpSymbol); m_Debugger->SymbolTable()->GetValueString(szValue, &symbol);
m_SymbolsListView.AddItem(i, 3, szValue);
}
}
CSymbols::LeaveCriticalSection(); stdstr strAddr = stdstr_f("%08X", symbol.m_Address);
m_SymbolsListView.AddItem(nItem, 0, strAddr.c_str());
m_SymbolsListView.AddItem(nItem, 1, symbol.TypeName());
m_SymbolsListView.AddItem(nItem, 2, symbol.m_Name);
m_SymbolsListView.AddItem(nItem, 4, symbol.m_Description);
m_SymbolsListView.AddItem(nItem, 5, szValue);
m_SymbolsListView.SetItemData(nItem, symbol.m_Id);
nItem++;
}
m_SymbolsListView.SetRedraw(TRUE); m_SymbolsListView.SetRedraw(TRUE);
} }
@ -170,19 +164,20 @@ void CDebugSymbols::RefreshValues()
int count = m_SymbolsListView.GetItemCount(); int count = m_SymbolsListView.GetItemCount();
CSymbols::EnterCriticalSection(); CSymbol symbol;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
int symbolId = m_SymbolsListView.GetItemData(i); int symbolId = m_SymbolsListView.GetItemData(i);
CSymbolEntry* lpSymbol = CSymbols::GetEntryById(symbolId); if (!m_Debugger->SymbolTable()->GetSymbolById(symbolId, &symbol))
{
break;
}
char szValue[64]; char szValue[64];
CSymbols::GetValueString(szValue, lpSymbol); m_Debugger->SymbolTable()->GetValueString(szValue, &symbol);
m_SymbolsListView.SetItemText(i, 3, szValue); m_SymbolsListView.SetItemText(i, 3, szValue);
} }
CSymbols::LeaveCriticalSection();
} }

View File

@ -23,11 +23,9 @@ private:
CListViewCtrl m_SymbolsListView; CListViewCtrl m_SymbolsListView;
CAddSymbolDlg m_AddSymbolDlg; CAddSymbolDlg m_AddSymbolDlg;
HANDLE m_AutoRefreshThread;
static DWORD WINAPI CDebugSymbols::AutoRefreshProc(void* _this);
public: public:
enum { IDD = IDD_Debugger_Symbols }; enum { IDD = IDD_Debugger_Symbols };
enum { TIMER_ID_AUTO_REFRESH };
CDebugSymbols(CDebuggerUI * debugger); CDebugSymbols(CDebuggerUI * debugger);
//virtual ~CDebugScripts(void); //virtual ~CDebugScripts(void);
@ -40,13 +38,14 @@ public:
LRESULT OnListDblClicked(NMHDR* pNMHDR); LRESULT OnListDblClicked(NMHDR* pNMHDR);
LRESULT OnDestroy(void); LRESULT OnDestroy(void);
void OnExitSizeMove(void); void OnExitSizeMove(void);
void OnTimer(UINT_PTR nIDEvent);
BEGIN_MSG_MAP_EX(CDebugSymbols) BEGIN_MSG_MAP_EX(CDebugSymbols)
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MSG_WM_DESTROY(OnDestroy) MSG_WM_DESTROY(OnDestroy)
NOTIFY_HANDLER_EX(IDC_SYMBOLS_LIST, NM_DBLCLK, OnListDblClicked) NOTIFY_HANDLER_EX(IDC_SYMBOLS_LIST, NM_DBLCLK, OnListDblClicked)
//NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_RCLICK, OnListClicked) MSG_WM_TIMER(OnTimer)
CHAIN_MSG_MAP(CDialogResize<CDebugSymbols>) CHAIN_MSG_MAP(CDialogResize<CDebugSymbols>)
MSG_WM_EXITSIZEMOVE(OnExitSizeMove); MSG_WM_EXITSIZEMOVE(OnExitSizeMove);
END_MSG_MAP() END_MSG_MAP()

View File

@ -33,7 +33,7 @@ CDebugMemoryView::jump_item_t CDebugMemoryView::JumpItems[] = {
{ 0xA4700000, 0x04700000, 0x0000020, "RI Registers" }, { 0xA4700000, 0x04700000, 0x0000020, "RI Registers" },
{ 0xA4800000, 0x04800000, 0x0000010, "SI Registers" }, { 0xA4800000, 0x04800000, 0x0000010, "SI Registers" },
{ 0xA5000500, 0x05000500, 0x000004C, "DD Registers" }, { 0xA5000500, 0x05000500, 0x000004C, "DD Registers" },
{ 0xA8000000, 0xA8000000, 0x0000000, "Cartridge Save Data" }, { 0xA8000000, 0x08000000, 0x1000000, "Cartridge Save Data" },
{ 0xB0000000, 0x10000000, 0xFC00000, "Cartridge ROM" }, { 0xB0000000, 0x10000000, 0xFC00000, "Cartridge ROM" },
{ 0xBFC00000, 0x1FC00000, 0x00007C0, "PIF ROM" }, { 0xBFC00000, 0x1FC00000, 0x00007C0, "PIF ROM" },
{ 0xBFC007C0, 0x1FC007C0, 0x0000040, "PIF RAM" }, { 0xBFC007C0, 0x1FC007C0, 0x0000040, "PIF RAM" },
@ -76,11 +76,11 @@ bool CDebugMemoryView::GetByte(uint32_t address, uint8_t* value)
{ {
if (m_bVirtualMemory) if (m_bVirtualMemory)
{ {
return m_Debugger->DebugLB_VAddr(address, *value); return m_Debugger->DebugLoad_VAddr(address, *value);
} }
else else
{ {
return m_Debugger->DebugLB_PAddr(address, *value); return m_Debugger->DebugLoad_PAddr(address, *value);
} }
} }
@ -88,11 +88,11 @@ bool CDebugMemoryView::SetByte(uint32_t address, uint8_t value)
{ {
if (m_bVirtualMemory) if (m_bVirtualMemory)
{ {
return m_Debugger->DebugSB_VAddr(address, value); return m_Debugger->DebugStore_VAddr(address, value);
} }
else else
{ {
return m_Debugger->DebugSB_PAddr(address, value); return m_Debugger->DebugStore_PAddr(address, value);
} }
} }
@ -214,11 +214,11 @@ void CDebugMemoryView::FollowPointer(bool bContextMenuAddress)
if (m_bVirtualMemory) if (m_bVirtualMemory)
{ {
bValid = m_Debugger->DebugLW_VAddr(address, pointer); bValid = m_Debugger->DebugLoad_VAddr(address, pointer);
} }
else else
{ {
bValid = m_Debugger->DebugLW_PAddr(address, pointer); bValid = m_Debugger->DebugLoad_VAddr(address, pointer);
} }
if (bValid) if (bValid)
@ -359,6 +359,7 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
SetupJumpMenu(true); SetupJumpMenu(true);
m_CmbJump.SetCurSel(0); m_CmbJump.SetCurSel(0);
m_TabData.clear();
AddTab(0x80000000, true, 4); AddTab(0x80000000, true, 4);
m_HexEditCtrl.Draw(); m_HexEditCtrl.Draw();
@ -796,17 +797,13 @@ LRESULT CDebugMemoryView::OnHxGetByteInfo(LPNMHDR lpNMHDR)
// todo should be the other way around // todo should be the other way around
uint32_t vaddress = m_bVirtualMemory ? address : address + 0x80000000; uint32_t vaddress = m_bVirtualMemory ? address : address + 0x80000000;
CSymbols::EnterCriticalSection(); CSymbol symbol;
CSymbolEntry* symbol = CSymbols::GetEntryByAddress(vaddress); if (m_Debugger->SymbolTable()->GetSymbolByAddress(vaddress, &symbol))
if (symbol != NULL)
{ {
m_SymbolColorStride = symbol->TypeSize(); m_SymbolColorStride = symbol.TypeSize();
m_SymbolColorPhase = m_SymbolColorPhase ? 0 : 1; m_SymbolColorPhase = m_SymbolColorPhase ? 0 : 1;
} }
CSymbols::LeaveCriticalSection();
if (bHaveWriteTarget && address == cpuReadWriteAddress) if (bHaveWriteTarget && address == cpuReadWriteAddress)
{ {
m_WriteTargetColorStride = cpuReadWriteNumBytes; m_WriteTargetColorStride = cpuReadWriteNumBytes;
@ -932,24 +929,10 @@ LRESULT CDebugMemoryView::OnHxHotAddrChanged(LPNMHDR /*lpNMHDR*/)
m_HotAddress = m_HexEditCtrl.GetHotAddress(); m_HotAddress = m_HexEditCtrl.GetHotAddress();
stdstr strAddrInfo = ""; stdstr strAddrInfo = "";
CSymbols::EnterCriticalSection(); CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByOverlappedAddress(m_HotAddress, &symbol))
CSymbolEntry* foundSymbol = NULL;
int numSymbols = CSymbols::GetCount();
for (int i = 0; i < numSymbols; i++)
{ {
CSymbolEntry* symbol = CSymbols::GetEntryByIndex(i); strAddrInfo += stdstr_f("%08X %s %s", symbol.m_Address, symbol.TypeName(), symbol.m_Name);
if (m_HotAddress >= symbol->m_Address && m_HotAddress < symbol->m_Address + symbol->TypeSize())
{
foundSymbol = symbol;
break;
}
}
if (foundSymbol != NULL)
{
strAddrInfo += stdstr_f("%08X %s %s", foundSymbol->m_Address, foundSymbol->TypeName(), foundSymbol->m_Name);
} }
else else
{ {
@ -957,8 +940,6 @@ LRESULT CDebugMemoryView::OnHxHotAddrChanged(LPNMHDR /*lpNMHDR*/)
} }
m_StatusBar.SetText(MEMSB_HOTADDR, strAddrInfo.c_str()); m_StatusBar.SetText(MEMSB_HOTADDR, strAddrInfo.c_str());
CSymbols::LeaveCriticalSection();
return FALSE; return FALSE;
} }

View File

@ -36,6 +36,7 @@ CDebuggerUI::CDebuggerUI() :
m_ExcBreakpoints(NULL), m_ExcBreakpoints(NULL),
m_DMALog(NULL), m_DMALog(NULL),
m_CPULog(NULL), m_CPULog(NULL),
m_SymbolTable(NULL),
m_StepEvent(false) m_StepEvent(false)
{ {
g_Debugger = this; g_Debugger = this;
@ -45,10 +46,8 @@ CDebuggerUI::CDebuggerUI() :
m_DMALog = new CDMALog(); m_DMALog = new CDMALog();
m_CPULog = new CCPULog(); m_CPULog = new CCPULog();
m_SymbolTable = new CSymbolTable(this);
InitializeCriticalSection(&m_CriticalSection);
CSymbols::InitializeCriticalSection();
g_Settings->RegisterChangeCB(GameRunning_InReset, this, (CSettings::SettingChangedFunc)GameReset); g_Settings->RegisterChangeCB(GameRunning_InReset, this, (CSettings::SettingChangedFunc)GameReset);
g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)SteppingOpsChanged); g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)SteppingOpsChanged);
g_Settings->RegisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunningChanged); g_Settings->RegisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunningChanged);
@ -75,9 +74,7 @@ CDebuggerUI::~CDebuggerUI(void)
delete m_ExcBreakpoints; delete m_ExcBreakpoints;
delete m_DMALog; delete m_DMALog;
delete m_CPULog; delete m_CPULog;
delete m_SymbolTable;
CSymbols::DeleteCriticalSection();
DeleteCriticalSection(&m_CriticalSection);
} }
void CDebuggerUI::SteppingOpsChanged(CDebuggerUI * _this) void CDebuggerUI::SteppingOpsChanged(CDebuggerUI * _this)
@ -129,9 +126,10 @@ void CDebuggerUI::GameReset(CDebuggerUI * _this)
_this->m_StackTrace->ClearEntries(); _this->m_StackTrace->ClearEntries();
} }
CSymbols::EnterCriticalSection(); if (_this->m_SymbolTable)
CSymbols::Load(); {
CSymbols::LeaveCriticalSection(); _this->m_SymbolTable->Load();
}
if (_this->m_Symbols) if (_this->m_Symbols)
{ {
@ -458,6 +456,11 @@ CCPULog* CDebuggerUI::CPULog()
return m_CPULog; return m_CPULog;
} }
CSymbolTable* CDebuggerUI::SymbolTable()
{
return m_SymbolTable;
}
// CDebugger implementation // CDebugger implementation
void CDebuggerUI::TLBChanged() void CDebuggerUI::TLBChanged()

View File

@ -409,6 +409,11 @@ bool CScanResult::SetMemoryValueFromString(char* str)
bool CScanResult::SetAddressSafe(uint32_t address) bool CScanResult::SetAddressSafe(uint32_t address)
{ {
if (!g_MMU || !g_Rom)
{
return false;
}
uint32_t ramSize = g_MMU->RdramSize(); uint32_t ramSize = g_MMU->RdramSize();
uint32_t romSize = g_Rom->GetRomSize(); uint32_t romSize = g_Rom->GetRomSize();
@ -442,6 +447,11 @@ bool CScanResult::SetAddressSafe(uint32_t address)
bool CScanResult::SetStrLengthSafe(int length) bool CScanResult::SetStrLengthSafe(int length)
{ {
if (!g_MMU || !g_Rom)
{
return false;
}
uint32_t ramSize = g_MMU->RdramSize(); uint32_t ramSize = g_MMU->RdramSize();
uint32_t romSize = g_Rom->GetRomSize(); uint32_t romSize = g_Rom->GetRomSize();
@ -536,6 +546,11 @@ void CMemoryScanner::Reset(void)
bool CMemoryScanner::SetAddressRange(uint32_t startAddress, uint32_t endAddress) bool CMemoryScanner::SetAddressRange(uint32_t startAddress, uint32_t endAddress)
{ {
if (!g_MMU || !g_Rom)
{
return false;
}
if(m_DidFirstScan) if(m_DidFirstScan)
{ {
return false; return false;
@ -596,6 +611,11 @@ bool CMemoryScanner::SetAddressRange(uint32_t startAddress, uint32_t endAddress)
uint8_t* CMemoryScanner::GetMemoryPool(uint32_t physAddr) uint8_t* CMemoryScanner::GetMemoryPool(uint32_t physAddr)
{ {
if (!g_MMU || !g_Rom)
{
return NULL;
}
if ((physAddr >= 0x00000000 && physAddr < g_MMU->RdramSize()) || if ((physAddr >= 0x00000000 && physAddr < g_MMU->RdramSize()) ||
(physAddr >= 0x04000000 && physAddr <= 0x04001FFF)) (physAddr >= 0x04000000 && physAddr <= 0x04001FFF))
{ {

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdafx.h> #include <stdafx.h>
#include "ScriptHook.h" #include "ScriptHook.h"

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include <stdafx.h> #include <stdafx.h>

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdafx.h> #include <stdafx.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -47,7 +57,6 @@ CScriptInstance::CScriptInstance(CDebuggerUI* debugger)
m_ScriptSystem = m_Debugger->ScriptSystem(); m_ScriptSystem = m_Debugger->ScriptSystem();
m_NextListenerId = 0; m_NextListenerId = 0;
m_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); m_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
InitializeCriticalSection(&m_CriticalSection);
CacheInstance(this); CacheInstance(this);
m_hKernel = LoadLibrary("Kernel32.dll"); m_hKernel = LoadLibrary("Kernel32.dll");
m_CancelIoEx = NULL; m_CancelIoEx = NULL;
@ -60,7 +69,6 @@ CScriptInstance::CScriptInstance(CDebuggerUI* debugger)
CScriptInstance::~CScriptInstance() CScriptInstance::~CScriptInstance()
{ {
UncacheInstance(this); UncacheInstance(this);
DeleteCriticalSection(&m_CriticalSection);
duk_destroy_heap(m_Ctx); duk_destroy_heap(m_Ctx);
TerminateThread(m_hThread, 0); TerminateThread(m_hThread, 0);
@ -81,9 +89,8 @@ void CScriptInstance::Start(char* path)
void CScriptInstance::ForceStop() void CScriptInstance::ForceStop()
{ {
// Close all files and delete all hooked callbacks // Close all files and delete all hooked callbacks
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
CleanUp(); CleanUp();
LeaveCriticalSection(&m_CriticalSection);
SetState(STATE_STOPPED); SetState(STATE_STOPPED);
} }
@ -408,13 +415,13 @@ void CScriptInstance::RemoveListenersByFd(HANDLE fd)
void CScriptInstance::InvokeListenerCallback(IOLISTENER* lpListener) void CScriptInstance::InvokeListenerCallback(IOLISTENER* lpListener)
{ {
CGuard guard(m_CS);
if (lpListener->callback == NULL) if (lpListener->callback == NULL)
{ {
return; return;
} }
EnterCriticalSection(&m_CriticalSection);
duk_push_heapptr(m_Ctx, lpListener->callback); duk_push_heapptr(m_Ctx, lpListener->callback);
int nargs = 0; int nargs = 0;
@ -458,57 +465,27 @@ void CScriptInstance::InvokeListenerCallback(IOLISTENER* lpListener)
const char* msg = duk_safe_to_string(m_Ctx, -1); const char* msg = duk_safe_to_string(m_Ctx, -1);
MessageBox(NULL, msg, "Script error", MB_OK | MB_ICONWARNING); MessageBox(NULL, msg, "Script error", MB_OK | MB_ICONWARNING);
} }
LeaveCriticalSection(&m_CriticalSection);
} }
const char* CScriptInstance::Eval(const char* jsCode) const char* CScriptInstance::Eval(const char* jsCode)
{ {
CGuard guard(m_CS);
int result = duk_peval_string(m_Ctx, jsCode); int result = duk_peval_string(m_Ctx, jsCode);
const char* msg = duk_safe_to_string(m_Ctx, -1); const char* msg = NULL;
if (result != 0) if (result != 0)
{ {
MessageBox(NULL, msg, "Script error", MB_OK | MB_ICONWARNING); MessageBox(NULL, msg, "Script error", MB_OK | MB_ICONWARNING);
} }
else
{
msg = duk_safe_to_string(m_Ctx, -1);
}
duk_pop(m_Ctx); duk_pop(m_Ctx);
return msg; return msg;
} }
class PendingEval {
char* m_CodeCopy;
CScriptInstance* m_ScriptInstance;
public:
PendingEval(CScriptInstance* instance, const char* jsCode)
{
m_CodeCopy = (char*)malloc(strlen(jsCode));
m_ScriptInstance = instance;
MessageBox(NULL, "pending eval created", "", MB_OK);
}
~PendingEval()
{
MessageBox(NULL, "pending eval deleted", "", MB_OK);
free(m_CodeCopy);
}
void Run()
{
MessageBox(NULL, "pending eval invoked", "", MB_OK);
m_ScriptInstance->Eval(m_CodeCopy);
}
};
void CScriptInstance::EvalAsync(const char* jsCode)
{
PendingEval* pendingEval = new PendingEval(this, jsCode);
QueueAPC(EvalAsyncCallback, (ULONG_PTR)pendingEval);
}
void CALLBACK CScriptInstance::EvalAsyncCallback(ULONG_PTR _pendingEval)
{
PendingEval* evalWait = (PendingEval*)_pendingEval;
evalWait->Run();
delete evalWait;
}
bool CScriptInstance::AddFile(const char* path, const char* mode, int* fd) bool CScriptInstance::AddFile(const char* path, const char* mode, int* fd)
{ {
FILE* fp = fopen(path, mode); FILE* fp = fopen(path, mode);
@ -584,7 +561,7 @@ const char* CScriptInstance::EvalFile(const char* jsPath)
void CScriptInstance::Invoke(void* heapptr, uint32_t param) void CScriptInstance::Invoke(void* heapptr, uint32_t param)
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
duk_push_heapptr(m_Ctx, heapptr); duk_push_heapptr(m_Ctx, heapptr);
duk_push_uint(m_Ctx, param); duk_push_uint(m_Ctx, param);
@ -598,12 +575,11 @@ void CScriptInstance::Invoke(void* heapptr, uint32_t param)
} }
duk_pop(m_Ctx); duk_pop(m_Ctx);
LeaveCriticalSection(&m_CriticalSection);
} }
void CScriptInstance::Invoke2(void* heapptr, uint32_t param, uint32_t param2) void CScriptInstance::Invoke2(void* heapptr, uint32_t param, uint32_t param2)
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
duk_push_heapptr(m_Ctx, heapptr); duk_push_heapptr(m_Ctx, heapptr);
duk_push_uint(m_Ctx, param); duk_push_uint(m_Ctx, param);
duk_push_uint(m_Ctx, param2); duk_push_uint(m_Ctx, param2);
@ -618,7 +594,6 @@ void CScriptInstance::Invoke2(void* heapptr, uint32_t param, uint32_t param2)
} }
duk_pop(m_Ctx); duk_pop(m_Ctx);
LeaveCriticalSection(&m_CriticalSection);
} }
void CScriptInstance::QueueAPC(PAPCFUNC userProc, ULONG_PTR param) void CScriptInstance::QueueAPC(PAPCFUNC userProc, ULONG_PTR param)
@ -1138,6 +1113,7 @@ return_err:
duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx) duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
{ {
CScriptInstance* _this = FetchInstance(ctx);
uint32_t address = duk_to_uint32(ctx, 0); uint32_t address = duk_to_uint32(ctx, 0);
int bitwidth = duk_to_int(ctx, 1); int bitwidth = duk_to_int(ctx, 1);
duk_bool_t bSigned = duk_to_boolean(ctx, 2); duk_bool_t bSigned = duk_to_boolean(ctx, 2);
@ -1156,7 +1132,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
case 8: case 8:
{ {
uint8_t val; uint8_t val;
if (!g_MMU->LB_VAddr(address, val)) if (!_this->m_Debugger->DebugLoad_VAddr(address, val))
{ {
goto return_err; goto return_err;
} }
@ -1166,7 +1142,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
case 16: case 16:
{ {
uint16_t val; uint16_t val;
if (!g_MMU->LH_VAddr(address, val)) if (!_this->m_Debugger->DebugLoad_VAddr(address, val))
{ {
goto return_err; goto return_err;
} }
@ -1176,7 +1152,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
case 32: case 32:
{ {
uint32_t val; uint32_t val;
if (!g_MMU->LW_VAddr(address, val)) if (!_this->m_Debugger->DebugLoad_VAddr(address, val))
{ {
goto return_err; goto return_err;
} }
@ -1205,6 +1181,7 @@ return_err:
duk_ret_t CScriptInstance::js_SetRDRAMInt(duk_context* ctx) duk_ret_t CScriptInstance::js_SetRDRAMInt(duk_context* ctx)
{ {
CScriptInstance* _this = FetchInstance(ctx);
uint32_t address = duk_to_uint32(ctx, 0); uint32_t address = duk_to_uint32(ctx, 0);
int bitwidth = duk_to_int(ctx, 1); int bitwidth = duk_to_int(ctx, 1);
DWORD newValue = duk_to_uint32(ctx, 2); DWORD newValue = duk_to_uint32(ctx, 2);
@ -1219,19 +1196,19 @@ duk_ret_t CScriptInstance::js_SetRDRAMInt(duk_context* ctx)
switch (bitwidth) switch (bitwidth)
{ {
case 8: case 8:
if (!g_MMU->SB_VAddr(address, (uint8_t)newValue)) if (!_this->m_Debugger->DebugStore_VAddr(address, (uint8_t)newValue))
{ {
goto return_err; goto return_err;
} }
goto return_ok; goto return_ok;
case 16: case 16:
if (!g_MMU->SH_VAddr(address, (uint16_t)newValue)) if (!_this->m_Debugger->DebugStore_VAddr(address, (uint16_t)newValue))
{ {
goto return_err; goto return_err;
} }
goto return_ok; goto return_ok;
case 32: case 32:
if (!g_MMU->SW_VAddr(address, (uint32_t)newValue)) if (!_this->m_Debugger->DebugStore_VAddr(address, (uint32_t)newValue))
{ {
goto return_err; goto return_err;
} }
@ -1251,6 +1228,7 @@ return_err:
duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx) duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx)
{ {
CScriptInstance* _this = FetchInstance(ctx);
int argc = duk_get_top(ctx); int argc = duk_get_top(ctx);
uint32_t address = duk_to_uint32(ctx, 0); uint32_t address = duk_to_uint32(ctx, 0);
@ -1271,7 +1249,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx)
if (!bDouble) if (!bDouble)
{ {
uint32_t rawValue; uint32_t rawValue;
if (!g_MMU->LW_VAddr(address, rawValue)) if (!_this->m_Debugger->DebugLoad_VAddr(address, rawValue))
{ {
goto return_err; goto return_err;
} }
@ -1284,7 +1262,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx)
} }
uint64_t rawValue; uint64_t rawValue;
if (!g_MMU->LD_VAddr(address, rawValue)) if (!_this->m_Debugger->DebugLoad_VAddr(address, rawValue))
{ {
goto return_err; goto return_err;
} }
@ -1302,6 +1280,7 @@ return_err:
duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx) duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx)
{ {
CScriptInstance* _this = FetchInstance(ctx);
int argc = duk_get_top(ctx); int argc = duk_get_top(ctx);
uint32_t address = duk_to_uint32(ctx, 0); uint32_t address = duk_to_uint32(ctx, 0);
@ -1325,7 +1304,7 @@ duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx)
float floatValue = (float)value; float floatValue = (float)value;
uint32_t rawValue; uint32_t rawValue;
memcpy(&rawValue, &floatValue, sizeof(float)); memcpy(&rawValue, &floatValue, sizeof(float));
if (!g_MMU->SW_VAddr(address, rawValue)) if (!_this->m_Debugger->DebugStore_VAddr(address, rawValue))
{ {
goto return_err; goto return_err;
} }
@ -1335,7 +1314,7 @@ duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx)
double floatValue = (double)value; double floatValue = (double)value;
uint64_t rawValue; uint64_t rawValue;
memcpy(&rawValue, &floatValue, sizeof(double)); memcpy(&rawValue, &floatValue, sizeof(double));
if (!g_MMU->SD_VAddr(address, rawValue)) if (!_this->m_Debugger->DebugStore_VAddr(address, rawValue))
{ {
goto return_err; goto return_err;
} }
@ -1351,6 +1330,7 @@ return_err:
duk_ret_t CScriptInstance::js_GetRDRAMBlock(duk_context* ctx) duk_ret_t CScriptInstance::js_GetRDRAMBlock(duk_context* ctx)
{ {
CScriptInstance* _this = FetchInstance(ctx);
uint32_t address = duk_get_uint(ctx, 0); uint32_t address = duk_get_uint(ctx, 0);
uint32_t size = duk_get_uint(ctx, 1); uint32_t size = duk_get_uint(ctx, 1);
@ -1366,7 +1346,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMBlock(duk_context* ctx)
for (uint32_t i = 0; i < size; i++) for (uint32_t i = 0; i < size; i++)
{ {
g_MMU->LB_VAddr(address + i, block[i]); _this->m_Debugger->DebugLoad_VAddr(address + i, block[i]);
} }
return 1; return 1;
@ -1394,6 +1374,8 @@ duk_ret_t CScriptInstance::js_MsgBox(duk_context* ctx)
// Return zero-terminated string from ram // Return zero-terminated string from ram
duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx) duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx)
{ {
CScriptInstance* _this = FetchInstance(ctx);
// (address[, maxLen]) // (address[, maxLen])
int nargs = duk_get_top(ctx); int nargs = duk_get_top(ctx);
uint32_t address = duk_get_uint(ctx, 0); uint32_t address = duk_get_uint(ctx, 0);
@ -1412,7 +1394,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx)
int len = 0; int len = 0;
// determine length of string // determine length of string
while (len < maxLen && g_MMU->LB_VAddr(address + len, test) && test != 0) // todo protect from ram overrun while (len < maxLen && _this->m_Debugger->DebugLoad_VAddr(address + len, test) && test != 0) // todo protect from ram overrun
{ {
if ((address & 0xFFFFFF) + len >= g_MMU->RdramSize()) if ((address & 0xFFFFFF) + len >= g_MMU->RdramSize())
{ {
@ -1425,7 +1407,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx)
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
g_MMU->LB_VAddr(address + i, str[i]); _this->m_Debugger->DebugLoad_VAddr(address + i, str[i]);
} }
str[len] = '\0'; str[len] = '\0';

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
@ -73,7 +83,6 @@ public:
INSTANCE_STATE GetState(); INSTANCE_STATE GetState();
friend class PendingEval; friend class PendingEval;
void EvalAsync(const char* jsCode);
const char* Eval(const char* jsCode); const char* Eval(const char* jsCode);
private: private:
@ -83,7 +92,7 @@ private:
HANDLE m_hThread; HANDLE m_hThread;
HANDLE m_hIOCompletionPort; HANDLE m_hIOCompletionPort;
CRITICAL_SECTION m_CriticalSection; CriticalSection m_CS;
vector<IOFD> m_AsyncFiles; vector<IOFD> m_AsyncFiles;
vector<IOLISTENER*> m_Listeners; vector<IOLISTENER*> m_Listeners;
@ -121,7 +130,7 @@ private:
void RemoveListenersByFd(HANDLE fd); void RemoveListenersByFd(HANDLE fd);
void InvokeListenerCallback(IOLISTENER* lpListener); void InvokeListenerCallback(IOLISTENER* lpListener);
static void CALLBACK EvalAsyncCallback(ULONG_PTR evalWait); //static void CALLBACK EvalAsyncCallback(ULONG_PTR evalWait);
bool AddFile(const char* path, const char* mode, int* fd); // return fd bool AddFile(const char* path, const char* mode, int* fd); // return fd
void CloseFile(int fd); void CloseFile(int fd);

View File

@ -25,8 +25,6 @@ CScriptSystem::CScriptSystem(CDebuggerUI* debugger)
m_Debugger = debugger; m_Debugger = debugger;
InitializeCriticalSection(&m_CriticalSection);
m_HookCPUExec = new CScriptHook(this); m_HookCPUExec = new CScriptHook(this);
m_HookCPUExecOpcode = new CScriptHook(this); m_HookCPUExecOpcode = new CScriptHook(this);
m_HookCPURead = new CScriptHook(this); m_HookCPURead = new CScriptHook(this);
@ -63,8 +61,6 @@ CScriptSystem::~CScriptSystem()
UnregisterHooks(); UnregisterHooks();
free(m_APIScript); free(m_APIScript);
DeleteCriticalSection(&m_CriticalSection);
} }
const char* CScriptSystem::APIScript() const char* CScriptSystem::APIScript()
@ -74,13 +70,12 @@ const char* CScriptSystem::APIScript()
void CScriptSystem::RunScript(char* path) void CScriptSystem::RunScript(char* path)
{ {
CGuard guard(m_CS);
CScriptInstance* scriptInstance = new CScriptInstance(m_Debugger); CScriptInstance* scriptInstance = new CScriptInstance(m_Debugger);
char* pathSaved = (char*)malloc(strlen(path)+1); // freed via DeleteStoppedInstances char* pathSaved = (char*)malloc(strlen(path)+1); // freed via DeleteStoppedInstances
strcpy(pathSaved, path); strcpy(pathSaved, path);
EnterCriticalSection(&m_CriticalSection);
m_RunningInstances.push_back({ pathSaved, scriptInstance }); m_RunningInstances.push_back({ pathSaved, scriptInstance });
LeaveCriticalSection(&m_CriticalSection);
scriptInstance->Start(pathSaved); scriptInstance->Start(pathSaved);
} }
@ -99,7 +94,7 @@ void CScriptSystem::StopScript(char* path)
void CScriptSystem::DeleteStoppedInstances() void CScriptSystem::DeleteStoppedInstances()
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
int lastIndex = m_RunningInstances.size() - 1; int lastIndex = m_RunningInstances.size() - 1;
for (int i = lastIndex; i >= 0; i--) for (int i = lastIndex; i >= 0; i--)
@ -112,44 +107,37 @@ void CScriptSystem::DeleteStoppedInstances()
m_RunningInstances.erase(m_RunningInstances.begin() + i); m_RunningInstances.erase(m_RunningInstances.begin() + i);
} }
} }
LeaveCriticalSection(&m_CriticalSection);
} }
INSTANCE_STATE CScriptSystem::GetInstanceState(char* path) INSTANCE_STATE CScriptSystem::GetInstanceState(char* path)
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
for (size_t i = 0; i < m_RunningInstances.size(); i++) for (size_t i = 0; i < m_RunningInstances.size(); i++)
{ {
if (strcmp(m_RunningInstances[i].path, path) == 0) if (strcmp(m_RunningInstances[i].path, path) == 0)
{ {
INSTANCE_STATE ret = m_RunningInstances[i].scriptInstance->GetState(); INSTANCE_STATE ret = m_RunningInstances[i].scriptInstance->GetState();
LeaveCriticalSection(&m_CriticalSection);
return ret; return ret;
} }
} }
LeaveCriticalSection(&m_CriticalSection);
return STATE_INVALID; return STATE_INVALID;
} }
CScriptInstance* CScriptSystem::GetInstance(char* path) CScriptInstance* CScriptSystem::GetInstance(char* path)
{ {
EnterCriticalSection(&m_CriticalSection); CGuard guard(m_CS);
for (size_t i = 0; i < m_RunningInstances.size(); i++) for (size_t i = 0; i < m_RunningInstances.size(); i++)
{ {
if (strcmp(m_RunningInstances[i].path, path) == 0) if (strcmp(m_RunningInstances[i].path, path) == 0)
{ {
CScriptInstance *ret = m_RunningInstances[i].scriptInstance; CScriptInstance *ret = m_RunningInstances[i].scriptInstance;
LeaveCriticalSection(&m_CriticalSection);
return ret; return ret;
} }
} }
LeaveCriticalSection(&m_CriticalSection);
return NULL; return NULL;
} }

View File

@ -58,7 +58,7 @@ private:
CScriptHook* m_HookCPUGPRValue; CScriptHook* m_HookCPUGPRValue;
CScriptHook* m_HookFrameDrawn; CScriptHook* m_HookFrameDrawn;
CRITICAL_SECTION m_CriticalSection; CriticalSection m_CS;
void RegisterHook(const char* hookId, CScriptHook* cbList); // associate string id with callback list void RegisterHook(const char* hookId, CScriptHook* cbList); // associate string id with callback list
void UnregisterHooks(); void UnregisterHooks();

View File

@ -1,47 +1,92 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
#include "Symbols.h" #include "Symbols.h"
bool CSymbols::m_bInitialized = false; CSymbolTable::CSymbolTable(CDebuggerUI* debugger) :
vector<CSymbolEntry*> CSymbols::m_Symbols; m_Debugger(debugger),
int CSymbols::m_NextSymbolId; m_NextSymbolId(0),
m_SymFileBuffer(NULL),
m_SymFileSize(0),
m_ParserToken(NULL),
m_ParserTokenLength(0),
m_ParserDelimeter(0),
m_SymFileParseBuffer(NULL),
m_bHaveFirstToken(false),
m_TokPos(NULL)
{
}
CFile CSymbols::m_SymFileHandle; CSymbolTable::~CSymbolTable()
char* CSymbols::m_SymFileBuffer; {
size_t CSymbols::m_SymFileSize; if (m_SymFileBuffer != NULL)
{
free(m_SymFileBuffer);
}
char CSymbols::m_ParserDelimeter; if (m_SymFileParseBuffer != NULL)
char* CSymbols::m_ParserToken; {
size_t CSymbols::m_ParserTokenLength; free(m_SymFileParseBuffer);
bool CSymbols::m_bHaveFirstToken; }
char* CSymbols::m_SymFileParseBuffer; }
CRITICAL_SECTION CSymbols::m_CriticalSection = {0}; symbol_type_info_t CSymbolTable::m_SymbolTypes[] = {
{ SYM_CODE, "code", 1 },
{ SYM_DATA, "data", 1 },
{ SYM_U8, "u8", 1 },
{ SYM_U16, "u16", 2 },
{ SYM_U32, "u32", 4 },
{ SYM_U64, "u64", 8 },
{ SYM_S8, "s8", 1 },
{ SYM_S16, "s16", 2 },
{ SYM_S32, "s32", 4 },
{ SYM_S64, "s64", 8 },
{ SYM_FLOAT, "float", 4 },
{ SYM_DOUBLE, "double", 8 },
{ SYM_INVALID, NULL, 0 }
};
int CSymbols::GetTypeNumber(char* typeName) symbol_type_id_t CSymbolTable::GetTypeId(char* typeName)
{ {
const char* name; const char* name;
for (int i = 0; (name = SymbolTypes[i]) != NULL; i++) for (int i = 0; (name = m_SymbolTypes[i].name) != NULL; i++)
{ {
if (strcmp(typeName, name) == 0) if (strcmp(typeName, name) == 0)
{ {
return i; return (symbol_type_id_t)i;
} }
} }
return -1; return SYM_INVALID;
} }
const char* CSymbols::GetTypeName(int typeNumber) const char* CSymbolTable::GetTypeName(int typeId)
{ {
if (typeNumber > 11) if (typeId >= NUM_SYM_TYPES)
{ {
return NULL; return NULL;
} }
return SymbolTypes[typeNumber]; return m_SymbolTypes[typeId].name;
}
int CSymbolTable::GetTypeSize(int typeId)
{
if (typeId >= NUM_SYM_TYPES)
{
return NULL;
}
return m_SymbolTypes[typeId].size;
} }
// Open symbols file for game and parse into list // Open symbols file for game and parse into list
CPath CSymbolTable::GetSymFilePath()
CPath CSymbols::GetSymFilePath()
{ {
stdstr symFileName; stdstr symFileName;
symFileName.Format("%s.sym", g_Settings->LoadStringVal(Game_GameName).c_str()); symFileName.Format("%s.sym", g_Settings->LoadStringVal(Game_GameName).c_str());
@ -52,7 +97,9 @@ CPath CSymbols::GetSymFilePath()
{ {
symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
symFilePath.NormalizePath(CPath(CPath::MODULE_DIRECTORY)); symFilePath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!symFilePath.DirectoryExists()) if (!symFilePath.DirectoryExists())
{ {
symFilePath.DirectoryCreate(); symFilePath.DirectoryCreate();
@ -61,28 +108,34 @@ CPath CSymbols::GetSymFilePath()
return symFilePath; return symFilePath;
} }
void CSymbols::ParserInit() void CSymbolTable::ParserInit()
{ {
if (m_SymFileParseBuffer != NULL)
{
free(m_SymFileParseBuffer);
}
m_SymFileParseBuffer = (char*)malloc(m_SymFileSize + 1); m_SymFileParseBuffer = (char*)malloc(m_SymFileSize + 1);
strcpy(m_SymFileParseBuffer, m_SymFileBuffer); strcpy(m_SymFileParseBuffer, m_SymFileBuffer);
m_bHaveFirstToken = false; m_bHaveFirstToken = false;
} }
void CSymbols::ParserDone() void CSymbolTable::ParserDone()
{ {
free(m_SymFileParseBuffer); free(m_SymFileParseBuffer);
} }
void CSymbols::ParserFetchToken(const char* delim) void CSymbolTable::ParserFetchToken(const char* delim)
{ {
if (!m_bHaveFirstToken) if (!m_bHaveFirstToken)
{ {
m_ParserToken = strtok(m_SymFileParseBuffer, delim); m_TokPos = NULL;
m_ParserToken = strtok_s(m_SymFileParseBuffer, delim, &m_TokPos);
m_bHaveFirstToken = true; m_bHaveFirstToken = true;
} }
else else
{ {
m_ParserToken = strtok(NULL, delim); m_ParserToken = strtok_s(NULL, delim, &m_TokPos);
} }
if (m_ParserToken != NULL) if (m_ParserToken != NULL)
@ -97,10 +150,12 @@ void CSymbols::ParserFetchToken(const char* delim)
} }
} }
void CSymbols::Load() void CSymbolTable::Load()
{ {
CGuard guard(m_CS);
m_NextSymbolId = 0; m_NextSymbolId = 0;
Reset(); m_Symbols.clear();
if (g_Settings->LoadStringVal(Game_GameName).length() == 0) if (g_Settings->LoadStringVal(Game_GameName).length() == 0)
{ {
@ -123,7 +178,7 @@ void CSymbols::Load()
m_SymFileHandle.Close(); m_SymFileHandle.Close();
m_SymFileBuffer[m_SymFileSize] = '\0'; m_SymFileBuffer[m_SymFileSize] = '\0';
ParseError errorCode = ERR_SUCCESS; symbol_parse_error_t errorCode = ERR_SUCCESS;
int lineNumber = 1; int lineNumber = 1;
ParserInit(); ParserInit();
@ -162,7 +217,7 @@ void CSymbols::Load()
} }
ParserFetchToken(",\n\0"); ParserFetchToken(",\n\0");
type = GetTypeNumber(m_ParserToken); type = GetTypeId(m_ParserToken);
if (type == -1) if (type == -1)
{ {
@ -188,7 +243,7 @@ void CSymbols::Load()
} }
// Add symbol object to the vector // Add symbol object to the vector
Add(type, address, name, description); AddSymbol(type, address, name, description);
if (m_ParserDelimeter == '\0') if (m_ParserDelimeter == '\0')
{ {
@ -221,157 +276,122 @@ void CSymbols::Load()
} }
} }
void CSymbols::Save() void CSymbolTable::Save()
{ {
int nSymbols = m_Symbols.size(); CGuard guard(m_CS);
char* symfile;
int symfile_size = 0;
int symfile_idx = 0;
// Determine file size
for (int i = 0; i < nSymbols; i++)
{
CSymbolEntry* symbol = m_Symbols[i];
symfile_size += 11; // address 8, required commas 2, newline 1
symfile_size += strlen(symbol->m_Name);
symfile_size += strlen(symbol->TypeName());
if (symbol->m_Description != NULL && strlen(symbol->m_Description) != 0)
{
symfile_size += 1; // comma
symfile_size += strlen(symbol->m_Description);
}
}
if (symfile_size == 0)
{
return;
}
symfile = (char*) malloc(symfile_size + 1);
symfile[symfile_size] = '\0';
// Write out
for (int i = 0; i < nSymbols; i++)
{
CSymbolEntry* symbol = m_Symbols[i];
symfile_idx += sprintf(&symfile[symfile_idx], "%08X,%s,%s", symbol->m_Address, symbol->TypeName(), symbol->m_Name);
if (symbol->m_Description != NULL)
{
symfile_idx += sprintf(&symfile[symfile_idx], ",%s", symbol->m_Description);
}
symfile_idx += sprintf(&symfile[symfile_idx], "\n");
}
m_SymFileHandle.Open(GetSymFilePath(), CFileBase::modeCreate | CFileBase::modeReadWrite); m_SymFileHandle.Open(GetSymFilePath(), CFileBase::modeCreate | CFileBase::modeReadWrite);
m_SymFileHandle.SeekToBegin(); m_SymFileHandle.SeekToBegin();
m_SymFileHandle.Write(symfile, symfile_size);
for (size_t i = 0; i < m_Symbols.size(); i++)
{
CSymbol& symbol = m_Symbols[i];
stdstr strLine = stdstr_f("%08X,%s,%s", symbol.m_Address, symbol.TypeName(), symbol.m_Name);
if (symbol.m_Description != NULL)
{
strLine += stdstr_f(",%s", symbol.m_Description);
}
strLine += "\n";
m_SymFileHandle.Write(strLine.c_str(), strLine.length());
}
m_SymFileHandle.SetEndOfFile(); m_SymFileHandle.SetEndOfFile();
m_SymFileHandle.Close(); m_SymFileHandle.Close();
free(symfile);
} }
void CSymbols::GetValueString(char* dest, CSymbolEntry* lpSymbol) void CSymbolTable::GetValueString(char* dst, CSymbol* symbol)
{ {
uint8_t v8; union
uint16_t v16;
uint32_t v32;
uint64_t v64;
float vf;
double vd;
uint32_t address = lpSymbol->m_Address;
switch (lpSymbol->m_Type)
{ {
case TYPE_CODE: uint8_t u8;
case TYPE_DATA: int8_t s8;
sprintf(dest, ""); uint16_t u16;
int16_t s16;
uint32_t u32;
int32_t s32;
uint64_t u64;
int64_t s64;
float f32;
double f64;
} value;
uint32_t address = symbol->m_Address;
switch (symbol->m_Type)
{
case SYM_CODE:
case SYM_DATA:
sprintf(dst, "");
break; break;
case TYPE_U8: case SYM_U8:
g_MMU->LB_VAddr(address, v8); m_Debugger->DebugLoad_VAddr(address, value.u8);
sprintf(dest, "%u", v8); sprintf(dst, "%u", value.u8);
break; break;
case TYPE_U16: case SYM_U16:
g_MMU->LH_VAddr(address, v16); m_Debugger->DebugLoad_VAddr(address, value.u16);
sprintf(dest, "%u", v16); sprintf(dst, "%u", value.u16);
break; break;
case TYPE_U32: case SYM_U32:
g_MMU->LW_VAddr(address, v32); m_Debugger->DebugLoad_VAddr(address, value.u32);
sprintf(dest, "%u", v32); sprintf(dst, "%u", value.u32);
break; break;
case TYPE_U64: case SYM_U64:
g_MMU->LD_VAddr(address, v64); m_Debugger->DebugLoad_VAddr(address, value.u64);
sprintf(dest, "%I64u", v64); sprintf(dst, "%I64u", value.u64);
break; break;
case TYPE_S8: case SYM_S8:
g_MMU->LB_VAddr(address, v8); m_Debugger->DebugLoad_VAddr(address, value.s8);
sprintf(dest, "%ihh", v8); sprintf(dst, "%ihh", value.s8);
break; break;
case TYPE_S16: case SYM_S16:
g_MMU->LH_VAddr(address, v16); m_Debugger->DebugLoad_VAddr(address, value.s16);
sprintf(dest, "%i", v16); sprintf(dst, "%i", value.s16);
break; break;
case TYPE_S32: case SYM_S32:
g_MMU->LW_VAddr(address, v32); m_Debugger->DebugLoad_VAddr(address, value.s32);
sprintf(dest, "%i", v32); sprintf(dst, "%i", value.s32);
break; break;
case TYPE_S64: case SYM_S64:
g_MMU->LD_VAddr(address, v64); m_Debugger->DebugLoad_VAddr(address, value.s64);
sprintf(dest, "%I64i", v64); sprintf(dst, "%I64i", value.s64);
break; break;
case TYPE_FLOAT: case SYM_FLOAT:
g_MMU->LW_VAddr(address, *(uint32_t*)&vf); m_Debugger->DebugLoad_VAddr(address, value.f32);
sprintf(dest, "%f", vf); sprintf(dst, "%f", value.f32);
break; break;
case TYPE_DOUBLE: case SYM_DOUBLE:
g_MMU->LD_VAddr(address, *(uint64_t*)&vd); m_Debugger->DebugLoad_VAddr(address, value.f64);
sprintf(dest, "%f", vd); sprintf(dst, "%f", value.f64);
break; break;
default: default:
MessageBox(NULL, "unkown type", "", MB_OK); g_Notify->BreakPoint(__FILE__, __LINE__);
break; break;
} }
} }
void CSymbols::ParseErrorAlert(char* message, int lineNumber) void CSymbolTable::ParseErrorAlert(char* message, int lineNumber)
{ {
stdstr messageFormatted = stdstr_f("%s\nLine %d", message, lineNumber); stdstr messageFormatted = stdstr_f("%s\nLine %d", message, lineNumber);
MessageBox(NULL, messageFormatted.c_str(), "Parse error", MB_OK | MB_ICONWARNING); MessageBox(NULL, messageFormatted.c_str(), "Parse error", MB_OK | MB_ICONWARNING);
} }
void CSymbols::Reset() void CSymbolTable::Reset()
{ {
for (int i = 0; i < GetCount(); i++) CGuard guard(m_CS);
{
delete m_Symbols[i];
}
m_Symbols.clear(); m_Symbols.clear();
} }
const char* CSymbols::GetNameByAddress(uint32_t address) bool CSymbolTable::CmpSymbolAddresses(CSymbol& a, CSymbol& b)
{ {
uint32_t len = GetCount(); return (a.m_Address < b.m_Address);
for (uint32_t i = 0; i < len; i++)
{
if (m_Symbols[i]->m_Address == address)
{
return m_Symbols[i]->m_Name;
}
}
return NULL;
} }
bool CSymbols::SortFunction(CSymbolEntry* a, CSymbolEntry* b) void CSymbolTable::AddSymbol(int type, uint32_t address, char* name, char* description)
{ {
return (a->m_Address < b->m_Address); CGuard guard(m_CS);
}
void CSymbols::Add(int type, uint32_t address, char* name, char* description)
{
if (name == NULL || strlen(name) == 0) if (name == NULL || strlen(name) == 0)
{ {
return; return;
@ -384,87 +404,82 @@ void CSymbols::Add(int type, uint32_t address, char* name, char* description)
int id = m_NextSymbolId++; int id = m_NextSymbolId++;
CSymbolEntry* symbol = new CSymbolEntry(id, type, address, name, description); CSymbol symbol = CSymbol(id, type, address, name, description);
m_Symbols.push_back(symbol); m_Symbols.push_back(symbol);
sort(m_Symbols.begin(), m_Symbols.end(), SortFunction); sort(m_Symbols.begin(), m_Symbols.end(), CmpSymbolAddresses);
} }
int CSymbols::GetCount() int CSymbolTable::GetCount()
{ {
CGuard guard(m_CS);
return m_Symbols.size(); return m_Symbols.size();
} }
CSymbolEntry* CSymbols::GetEntryByIndex(int index) bool CSymbolTable::GetSymbolByIndex(size_t index, CSymbol* symbol)
{ {
if (index < 0 || index >= GetCount()) CGuard guard(m_CS);
if (index < 0 || index >= m_Symbols.size())
{ {
return NULL; return false;
} }
return m_Symbols[index]; *symbol = m_Symbols[index];
return true;
} }
CSymbolEntry* CSymbols::GetEntryByAddress(uint32_t address) bool CSymbolTable::GetSymbolByAddress(uint32_t address, CSymbol* symbol)
{ {
for (int i = 0; i < GetCount(); i++) CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{ {
if (m_Symbols[i]->m_Address == address) if (m_Symbols[i].m_Address == address)
{ {
return m_Symbols[i]; *symbol = m_Symbols[i];
return true;
} }
} }
return NULL; return false;
} }
CSymbolEntry* CSymbols::GetEntryById(int id) bool CSymbolTable::GetSymbolByOverlappedAddress(uint32_t address, CSymbol* symbol)
{ {
for (int i = 0; i < GetCount(); i++) CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{ {
if (m_Symbols[i]->m_Id == id) if (address >= m_Symbols[i].m_Address &&
address < m_Symbols[i].m_Address + m_Symbols[i].TypeSize())
{ {
return m_Symbols[i]; *symbol = m_Symbols[i];
return true;
} }
} }
return NULL; return false;
} }
void CSymbols::RemoveEntryById(int id) bool CSymbolTable::GetSymbolById(int id, CSymbol* symbol)
{ {
for (int i = 0; i < GetCount(); i++) CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{ {
if (m_Symbols[i]->m_Id == id) if (m_Symbols[i].m_Id == id)
{
*symbol = m_Symbols[i];
return true;
}
}
return false;
}
bool CSymbolTable::RemoveSymbolById(int id)
{
CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{
if (m_Symbols[i].m_Id == id)
{ {
delete m_Symbols[i];
m_Symbols.erase(m_Symbols.begin() + i); m_Symbols.erase(m_Symbols.begin() + i);
break; return true;
} }
} }
} return false;
void CSymbols::EnterCriticalSection()
{
::EnterCriticalSection(&m_CriticalSection);
}
void CSymbols::LeaveCriticalSection()
{
::LeaveCriticalSection(&m_CriticalSection);
}
void CSymbols::InitializeCriticalSection()
{
if (!m_bInitialized)
{
m_bInitialized = true;
::InitializeCriticalSection(&m_CriticalSection);
}
}
void CSymbols::DeleteCriticalSection()
{
if (m_bInitialized)
{
m_bInitialized = false;
::DeleteCriticalSection(&m_CriticalSection);
}
} }

View File

@ -1,110 +1,103 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
class CSymbolEntry; class CSymbol;
class CSymbols typedef enum {
SYM_INVALID = -1,
SYM_CODE,
SYM_DATA,
SYM_U8,
SYM_U16,
SYM_U32,
SYM_U64,
SYM_S8,
SYM_S16,
SYM_S32,
SYM_S64,
SYM_FLOAT,
SYM_DOUBLE,
NUM_SYM_TYPES
} symbol_type_id_t;
typedef struct
{ {
public: symbol_type_id_t id;
typedef enum { const char* name;
int size;
} symbol_type_info_t;
typedef enum {
ERR_SUCCESS, ERR_SUCCESS,
ERR_INVALID_TYPE, ERR_INVALID_TYPE,
ERR_INVALID_ADDR, ERR_INVALID_ADDR,
ERR_INVALID_NAME, ERR_INVALID_NAME,
ERR_MISSING_FIELDS, ERR_MISSING_FIELDS,
} ParseError; } symbol_parse_error_t;
typedef enum { class CSymbolTable
TYPE_CODE, {
TYPE_DATA, public:
TYPE_U8, CSymbolTable(CDebuggerUI* debugger);
TYPE_U16, ~CSymbolTable();
TYPE_U32,
TYPE_U64,
TYPE_S8,
TYPE_S16,
TYPE_S32,
TYPE_S64,
TYPE_FLOAT,
TYPE_DOUBLE
} DataType;
static constexpr char* SymbolTypes[] = {
"code", // 0
"data", // 1
"u8",
"u16",
"u32",
"u64",
"s8",
"s16",
"s32",
"s64",
"float",
"double",
NULL
};
static constexpr int TypeSizes[] = {
1, 1, // code data
1, 2, 4, 8, // u8 u16 u32 u64
1, 2, 4, 8, // s8 s16 s32 s64
4, 8 // float double
};
private: private:
static bool m_bInitialized; CSymbolTable();
static vector<CSymbolEntry*> m_Symbols; CDebuggerUI* m_Debugger;
static int m_NextSymbolId; CriticalSection m_CS;
std::vector<CSymbol> m_Symbols;
static CFile m_SymFileHandle; int m_NextSymbolId;
static char* m_SymFileBuffer;
static size_t m_SymFileSize;
static CRITICAL_SECTION m_CriticalSection; CFile m_SymFileHandle;
char* m_SymFileBuffer;
size_t m_SymFileSize;
char* m_ParserToken;
size_t m_ParserTokenLength;
char* m_TokPos;
char m_ParserDelimeter;
char* m_SymFileParseBuffer;
bool m_bHaveFirstToken;
static char* m_ParserToken; void ParserInit();
static size_t m_ParserTokenLength; void ParserDone();
static char m_ParserDelimeter; void ParserFetchToken(const char* delim);
static char* m_SymFileParseBuffer;
static bool m_bHaveFirstToken;
static void ParserInit();
static void ParserDone();
static void ParserFetchToken(const char* delim);
static bool SortFunction(CSymbolEntry* a, CSymbolEntry* b);
public: public:
static CPath GetSymFilePath(); static symbol_type_info_t m_SymbolTypes[];
static void Load(); static const char* GetTypeName(int typeId);
static void Save(); static int GetTypeSize(int typeId);
static void ParseErrorAlert(char* message, int lineNumber); static symbol_type_id_t GetTypeId(char* typeName);
static bool CmpSymbolAddresses(CSymbol& a, CSymbol& b);
static void Add(int type, uint32_t address, char* name, char* description = NULL); void GetValueString(char* dst, CSymbol* symbol);
static void RemoveEntryById(int id);
static void Reset(); CPath GetSymFilePath();
void Load();
void Save();
void ParseErrorAlert(char* message, int lineNumber);
static const char* GetTypeName(int typeNumber); void AddSymbol(int type, uint32_t address, char* name, char* description = NULL);
static int GetTypeNumber(char* typeName); void Reset();
static void GetValueString(char* str, CSymbolEntry* lpSymbol); int GetCount();
bool GetSymbolById(int id, CSymbol* symbol);
static int GetCount(); bool GetSymbolByIndex(size_t index, CSymbol* symbol);
bool GetSymbolByAddress(uint32_t address, CSymbol* symbol);
static CSymbolEntry* GetEntryById(int id); bool GetSymbolByOverlappedAddress(uint32_t address, CSymbol* symbol);
static CSymbolEntry* GetEntryByIndex(int id); bool RemoveSymbolById(int id);
static CSymbolEntry* GetEntryByAddress(uint32_t address);
static const char* GetNameByAddress(uint32_t address);
static void InitializeCriticalSection();
static void DeleteCriticalSection();
static void EnterCriticalSection();
static void LeaveCriticalSection();
}; };
class CSymbolEntry { class CSymbol {
public: public:
int m_Id; int m_Id;
int m_Type; int m_Type;
@ -112,34 +105,71 @@ public:
char* m_Name; char* m_Name;
char* m_Description; char* m_Description;
CSymbolEntry(int id, int type, uint32_t address, char* name, char* description) : CSymbol() :
m_Id(0),
m_Type(SYM_INVALID),
m_Address(0),
m_Name(NULL), m_Name(NULL),
m_Description(NULL), m_Description(NULL)
{
}
CSymbol(int id, int type, uint32_t address, char* name, char* description) :
m_Id(id), m_Id(id),
m_Type(type), m_Type(type),
m_Address(address) m_Address(address),
m_Name(NULL),
m_Description(NULL)
{ {
if (name != NULL) if (name != NULL)
{ {
size_t nameLen = strlen(name); m_Name = _strdup(name);
m_Name = (char*)malloc(nameLen + 1);
strcpy(m_Name, name);
} }
if (description != NULL) if (description != NULL)
{ {
size_t descLen = strlen(description); m_Description = _strdup(description);
m_Description = (char*)malloc(descLen + 1);
strcpy(m_Description, description);
} }
} }
~CSymbolEntry() CSymbol(const CSymbol& symbol):
m_Id(symbol.m_Id),
m_Type(symbol.m_Type),
m_Address(symbol.m_Address),
m_Name(NULL),
m_Description(NULL)
{
m_Name = symbol.m_Name ? _strdup(symbol.m_Name) : NULL;
m_Description = symbol.m_Description ? _strdup(symbol.m_Description) : NULL;
}
CSymbol& operator= (const CSymbol& symbol)
{ {
if (m_Name != NULL) if (m_Name != NULL)
{ {
free(m_Name); free(m_Name);
} }
if (m_Description != NULL)
{
free(m_Description);
}
m_Id = symbol.m_Id;
m_Type = symbol.m_Type;
m_Address = symbol.m_Address;
m_Name = symbol.m_Name ? _strdup(symbol.m_Name) : NULL;
m_Description = symbol.m_Description ? _strdup(symbol.m_Description) : NULL;
return *this;
}
~CSymbol()
{
if (m_Name != NULL)
{
free(m_Name);
}
if (m_Description != NULL) if (m_Description != NULL)
{ {
free(m_Description); free(m_Description);
@ -148,11 +178,11 @@ public:
const char* TypeName() const char* TypeName()
{ {
return CSymbols::SymbolTypes[m_Type]; return CSymbolTable::GetTypeName(m_Type);
} }
int TypeSize() int TypeSize()
{ {
return CSymbols::TypeSizes[m_Type]; return CSymbolTable::GetTypeSize(m_Type);
} }
}; };

View File

@ -29,6 +29,7 @@ class CDebugExcBreakpoints;
class CCPULog; class CCPULog;
class CDMALog; class CDMALog;
class CSymbolTable;
class CBreakpoints; class CBreakpoints;
class CScriptSystem; class CScriptSystem;
@ -84,15 +85,13 @@ public:
CDebugScripts* ScriptConsole(); CDebugScripts* ScriptConsole();
CDMALog* DMALog(); CDMALog* DMALog();
CCPULog* CPULog(); CCPULog* CPULog();
CSymbolTable* SymbolTable();
static void GameReset(CDebuggerUI * _this); static void GameReset(CDebuggerUI * _this);
static void GameCpuRunningChanged(CDebuggerUI * _this); static void GameCpuRunningChanged(CDebuggerUI * _this);
static void GameNameChanged(CDebuggerUI * _this); static void GameNameChanged(CDebuggerUI * _this);
static void SteppingOpsChanged(CDebuggerUI * _this); static void SteppingOpsChanged(CDebuggerUI * _this);
//bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value);
//bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
protected: protected:
void TLBChanged(void); void TLBChanged(void);
void CPUStepStarted(void); void CPUStepStarted(void);
@ -104,7 +103,6 @@ private:
CDebuggerUI(const CDebuggerUI&); // Disable copy constructor CDebuggerUI(const CDebuggerUI&); // Disable copy constructor
CDebuggerUI& operator=(const CDebuggerUI&); // Disable assignment CDebuggerUI& operator=(const CDebuggerUI&); // Disable assignment
CRITICAL_SECTION m_CriticalSection;
CDumpMemory * m_MemoryDump; CDumpMemory * m_MemoryDump;
CDebugMemoryView * m_MemoryView; CDebugMemoryView * m_MemoryView;
CDebugMemorySearch * m_MemorySearch; CDebugMemorySearch * m_MemorySearch;
@ -120,6 +118,7 @@ private:
CBreakpoints * m_Breakpoints; CBreakpoints * m_Breakpoints;
CScriptSystem * m_ScriptSystem; CScriptSystem * m_ScriptSystem;
CSymbolTable * m_SymbolTable;
CDMALog * m_DMALog; CDMALog * m_DMALog;
CCPULog * m_CPULog; CCPULog * m_CPULog;

View File

@ -1048,13 +1048,17 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
*******************/ *******************/
//ID_DEBUGGER_LOGOPTIONS //ID_DEBUGGER_LOGOPTIONS
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Commands..."); Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"&Commands...");
Item.SetItemEnabled(CPURunning);
DebugR4300Menu.push_back(Item); DebugR4300Menu.push_back(Item);
//Item.Reset(ID_DEBUGGER_R4300REGISTERS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Registers..."); Item.Reset(ID_DEBUGGER_CPULOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Command Log...");
//Item.SetItemEnabled(true); DebugR4300Menu.push_back(Item);
// DebugR4300Menu.push_back(Item); Item.Reset(ID_DEBUGGER_EXCBREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Exceptions...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUGGER_STACKVIEW, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUGGER_STACKTRACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack Trace...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUG_DISABLE_GAMEFIX, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Disable Game Fixes"); Item.Reset(ID_DEBUG_DISABLE_GAMEFIX, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Disable Game Fixes");
if (g_Settings->LoadBool(Debugger_DisableGameFixes)) if (g_Settings->LoadBool(Debugger_DisableGameFixes))
{ {
@ -1070,10 +1074,14 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
DebugMemoryMenu.push_back(Item); DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_SEARCHMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Search..."); Item.Reset(ID_DEBUGGER_SEARCHMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Search...");
DebugMemoryMenu.push_back(Item); DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_SYMBOLS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Symbols...");
DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_DUMPMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Dump..."); Item.Reset(ID_DEBUGGER_DUMPMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Dump...");
DebugMemoryMenu.push_back(Item); DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_TLBENTRIES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB Entries..."); Item.Reset(ID_DEBUGGER_TLBENTRIES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB Entries...");
DebugMemoryMenu.push_back(Item); DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_DMALOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DMA Log...");
DebugMemoryMenu.push_back(Item);
/* Debug - App logging /* Debug - App logging
*******************/ *******************/
@ -1166,52 +1174,25 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
/* Debugger Main Menu /* Debugger Main Menu
****************/ ****************/
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Breakpoint..."); Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Commands...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item); DebugMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_MEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"View Memory...");
/* Debug - Exception breakpoints
*******************/
Item.Reset(ID_DEBUGGER_EXCBREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"CPU Exception Breakpoints...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item); DebugMenu.push_back(Item);
/* Debugger - Symbols
****************/
Item.Reset(ID_DEBUGGER_SYMBOLS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Symbols...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - Scripts
*******************/
Item.Reset(ID_DEBUGGER_SCRIPTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Scripts..."); Item.Reset(ID_DEBUGGER_SCRIPTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Scripts...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - DMA Log
*******************/
Item.Reset(ID_DEBUGGER_DMALOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DMA Log...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - CPU Log
*******************/
Item.Reset(ID_DEBUGGER_CPULOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"CPU Log...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - Stack
*******************/
Item.Reset(ID_DEBUGGER_STACKVIEW, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack...");
DebugMenu.push_back(Item);
/* Debug - Stack Trace
*******************/
Item.Reset(ID_DEBUGGER_STACKTRACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack Trace...");
DebugMenu.push_back(Item); DebugMenu.push_back(Item);
DebugMenu.push_back(MENU_ITEM(SPLITER)); DebugMenu.push_back(MENU_ITEM(SPLITER));
/* Debug - Memory
*******************/
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory");
DebugMenu.push_back(Item);
/* Debug - R4300i
*******************/
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i");
DebugMenu.push_back(Item);
/* Debug - RSP /* Debug - RSP
*******************/ *******************/
if (g_Plugins && g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu())) if (g_Plugins && g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu()))
@ -1249,10 +1230,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
} }
DebugNotificationMenu.push_back(Item); DebugNotificationMenu.push_back(Item);
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i");
DebugMenu.push_back(Item);
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory");
DebugMenu.push_back(Item);
DebugMenu.push_back(MENU_ITEM(SPLITER)); DebugMenu.push_back(MENU_ITEM(SPLITER));
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile"); Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile");
DebugMenu.push_back(Item); DebugMenu.push_back(Item);

View File

@ -909,7 +909,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | W
CAPTION "Symbols" CAPTION "Symbols"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
CONTROL "",IDC_SYMBOLS_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_TABSTOP,0,0,313,123 CONTROL "",IDC_SYMBOLS_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_TABSTOP,0,0,313,123
PUSHBUTTON "+",IDC_ADDSYMBOL_BTN,284,125,24,12 PUSHBUTTON "+",IDC_ADDSYMBOL_BTN,284,125,24,12
PUSHBUTTON "-",IDC_REMOVESYMBOL_BTN,259,125,24,12 PUSHBUTTON "-",IDC_REMOVESYMBOL_BTN,259,125,24,12
EDITTEXT IDC_FILTER_EDIT,29,125,150,12,ES_AUTOHSCROLL | WS_DISABLED EDITTEXT IDC_FILTER_EDIT,29,125,150,12,ES_AUTOHSCROLL | WS_DISABLED
@ -1076,13 +1076,13 @@ BEGIN
END END
IDD_Debugger_RegSI DIALOGEX 0, 0, 190, 210 IDD_Debugger_RegSI DIALOGEX 0, 0, 190, 210
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU
FONT 9, "Lucida Console", 400, 0, 0x1 FONT 9, "Lucida Console", 400, 0, 0x1
BEGIN BEGIN
LTEXT "00 SI_DRAM_ADDR_REG",-1,3,29,94,8 LTEXT "00 SI_DRAM_ADDR_REG",-1,3,29,94,8
LTEXT "04 SI_PIF_ADDR_RD64B_REG",-1,3,39,98,8 LTEXT "04 SI_PIF_ADDR_RD64B_REG",-1,3,39,98,8
LTEXT "08 SI_PIF_ADDR_WR64B_REG",-1,3,50,100,8 LTEXT "10 SI_PIF_ADDR_WR64B_REG",-1,3,50,100,8
LTEXT "0C SI_STATUS_REG",-1,3,61,94,8 LTEXT "18 SI_STATUS_REG",-1,3,61,94,8
EDITTEXT IDC_SI00_EDIT,107,28,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT EDITTEXT IDC_SI00_EDIT,107,28,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_SI04_EDIT,107,39,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT EDITTEXT IDC_SI04_EDIT,107,39,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_SI08_EDIT,107,50,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT EDITTEXT IDC_SI08_EDIT,107,50,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT