BizHawk/mednafen/src/debug.h

222 lines
7.5 KiB
C++

#ifndef __MDFN_DEBUG_H
#define __MDFN_DEBUG_H
#ifdef WANT_DEBUGGER
enum
{
BPOINT_READ = 1,
BPOINT_WRITE,
BPOINT_PC,
BPOINT_IO_READ,
BPOINT_IO_WRITE,
BPOINT_AUX_READ,
BPOINT_AUX_WRITE,
BPOINT_OP // Opcode
};
struct RegType
{
~RegType();
const unsigned int id;
std::string name;
std::string long_name;
unsigned int bsize; // Byte size, 1, 2, 4
};
typedef struct
{
const char *name;
RegType *Regs;
// GetRegister() should modify the string at special if special is non-NULL to provide
// more details about the register.
uint32 (*GetRegister)(const unsigned int id, char *special, const uint32 special_len);
void (*SetRegister)(const unsigned int id, uint32 value);
// Used if SetRegister and GetRegister are both NULL. Deprecated.
uint32 (*OLDGetRegister)(const std::string &name, std::string *special);
void (*OLDSetRegister)(const std::string &name, uint32 value);
} RegGroupType;
typedef enum
{
ASPACE_WFMT_UNSIGNED = 0, // Unsigned, wooo.
ASPACE_WFMT_SIGNED, // Signed two's complement
ASPACE_WMFT_SIGNED_MAG_0NEG, // Signed/magnitude. 0 in the sign bit means negative.
ASPACE_WFMT_SIGNED_MAG_1NEG, // Sign/magnitude style. 1 in the sign bit means negative.
ASPACE_WFMT_SIGNED_ONES, // Signed one's complement
} ASpace_WFMT;
// Visible to CPU, physical, RAM, ROM, ADPCM RAM, etc etc.
typedef struct
{
// The short name, all lowercase, 0-9 a-z _
char *name;
// The longer, descriptive name for this address space.
char *long_name;
// The number of address bits for this address space.
uint32 TotalBits;
// (Segmentation bits TODO)
bool IsSegmented;
uint32 SegmentBits;
uint32 OffsetBits;
uint32 BitsOverlapped; // For future use, maybe.
// Non-power-of-2 size. Normally 0, unless the size of the address space isn't a power of 2!
uint32 NP2Size;
bool IsWave;
ASpace_WFMT WaveFormat; // TODO
uint32 WaveBits; // Total number of bits(including sign) per waveform sample. Only <= 8 for now...
void (*GetAddressSpaceBytes)(const char *name, uint32 Address, uint32 Length, uint8 *Buffer);
void (*PutAddressSpaceBytes)(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer);
void *private_data;
// Internal use...
void (*EnableUsageMap)(bool);
uint64 ****UsageMapRead; // [a.24:31][a.16:23][a.8:15][a.0:7], pointer tables allocated as needed.
uint64 ****UsageMapWrite; // (same)
uint64 UsageReadMemUsed; // Keep track of how much memory we've allocated for UsageMap, so we don't go kaka-kookoo and use up an // excessive amount of RAM.
uint64 UsageWriteMemUsed;
} AddressSpaceType;
// TODO: newer branch trace interface not implemented yet.
struct BranchTraceResult
{
#if 0
// Segment stuff is only to be hackishly implemented, for WonderSwan debugger support.
uint32 from;
uint32 to;
uint16 from_segment;
uint16 to_segment;
bool from_valid;
bool segment_valid;
#endif
char from[32];
char to[32];
char code[16];
uint32 count;
};
#if 0
struct DGD_Source
{
int id;
const char *name;
unsigned width;
unsigned height;
unsigned pb_bpp; // Palette bank bits-per-pixel
};
#endif
typedef struct
{
const char *DefaultCharEnc; // Default(or most common) internal character encoding for text for the system.
uint32 MaxInstructionSize; // Maximum instruction size in bytes
uint32 InstructionAlignment; // Required instruction alignment, in bytes(frequently 1 on CISC, and other powers of 2 on RISC, but not always ;)).
uint32 LogAddrBits; // Logical address bits
uint32 PhysAddrBits; // Physical address bits
uint32 DefaultWatchAddr;
uint32 ZPAddr; // Set to ~0U to disable
// If logical is true, then do the peek/poke on logical address A, else do the
// peek/poke on physical address A. For now, this distinction only exists
// on CPUs with built-in bank-switching, like the HuC6280.
// If hl is true, do not cause any change in the underlying hardware state.
uint32 (*MemPeek)(uint32 A, unsigned int bsize, bool hl, bool logical);
// Disassemble one instruction at logical address A, and increment A to point to the next instruction.
// TextBuf should point to at least 256 bytes of space!
void (*Disassemble)(uint32 &A, uint32 SpecialA, char *TextBuf);
// Toggle syntax mode(example: for WonderSwan x86 decoding, Intel or AT&T)
void (*ToggleSyntax)(void);
// Force an IRQ at the desired level(IRQ0, IRQ1, or whatever). Pass -1 to cause an NMI, if available.
// Note that this should cause an interrupt regardless of any flag settings or interrupt status.
void (*IRQ)(int level);
// Get the vector for the specified IRQ level. -1 is NMI(if available), and -2 is RESET.
uint32 (*GetVector)(int level);
void (*FlushBreakPoints)(int type);
void (*AddBreakPoint)(int type, unsigned int A1, unsigned int A2, bool logical);
void (*SetCPUCallback)(void (*callb)(uint32 PC));
void (*SetBPCallback)(void (*callb)(uint32 PC));
std::vector<BranchTraceResult> (*GetBranchTrace)(void);
// If surface is NULL, disable decoding.
// If line is -1, do decoding instantaneously, before this function returns.
// "which" is the same index as passed to MDFNI_ToggleLayer()
void (*SetGraphicsDecode)(MDFN_Surface *surface, int line, int which, int xscroll, int yscroll, int pbn);
void (*SetLogFunc)(void (*logfunc)(const char *type, const char *text));
// Game emulation code shouldn't touch these directly.
std::vector<AddressSpaceType> *AddressSpaces;
std::vector<RegGroupType*> *RegGroups;
} DebuggerInfoStruct;
// ASpace_Add() functions return an ID that should be used with with MDFNDBG_ASpace_Read()
// and ASpace_Write() functions. The ID is guaranteed to be 0 for the first address space,
// and increment by 1 for each address space added thereafter.
// An address space should only be added during Load() or LoadCD().
int ASpace_Add(void (*gasb)(const char *name, uint32 Address, uint32 Length, uint8 *Buffer),
void (*pasb)(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer), const char *name, const char *long_name,
uint32 TotalBits, uint32 NP2Size = 0, bool IsSegmented = 0, uint32 SegmentBits = 0, uint32 OffsetBits = 0, uint32 BitsOverlapped = 0);
int ASpace_Add(const AddressSpaceType &);
// Removes all registered address spaces.
void ASpace_Reset(void);
// pre_bpoint should be TRUE if these are "estimated" read/writes that will occur when the current instruction
// is actually executed/committed.
// size is the size of the read/write(ex: 1 byte, 2 bytes, 4 bytes), defaulting to 1 byte.
//
// The return value is always FALSE if pre_bpoint is FALSE. If pre_bpoint is TRUE, the return value will be
// TRUE if the "estimated" read/write matches a registered breakpoint.
bool ASpace_Read(const int id, const uint32 address, const unsigned int size = 1, const bool pre_bpoint = FALSE);
bool ASpace_Write(const int id, const uint32 address, const uint32 value, const unsigned int size = 1, const bool pre_bpoint = FALSE);
// Clears read/write usage maps.
void ASpace_ClearReadMap(const int id);
void ASpace_ClearWriteMap(const int id);
void ASpace_AddBreakPoint(const int id, const int type, const uint32 A1, const uint32 A2, const bool logical);
void ASpace_FlushBreakPoints(const int id);
void MDFNDBG_ResetRegGroupsInfo(void);
void MDFNDBG_AddRegGroup(RegGroupType *groupie);
void MDFNDBG_Init(void);
void MDFNDBG_PostGameLoad(void);
void MDFNDBG_Kill(void);
#endif
#endif