- Updated debugger classes to get them to compile with latest changes

- Moved CPU debugger for Turbo68K into separate class CTurbo68KDebug and made C68KDebug base class for later addition of Musashi core
- Fixed typos in ConsoleDebugger
This commit is contained in:
Nik Henson 2011-07-20 21:39:11 +00:00
parent 03fa9532eb
commit 45dd662dee
7 changed files with 659 additions and 570 deletions

View file

@ -1,5 +1,4 @@
#ifdef SUPERMODEL_DEBUGGER
#ifdef SUPERMODEL_SOUND
#include "68KDebug.h"
@ -8,73 +7,8 @@
namespace Debugger
{
UINT32 GetSpecialReg(CCPUDebug *cpu, unsigned id)
C68KDebug::C68KDebug() : CCPUDebug("68K", 2, 10, true, 24, 7)
{
switch (id)
{
case M68KSPECIAL_SP: return (UINT32)turbo68kcontext_68000.a[7];
case M68KSPECIAL_SR: return (UINT32)turbo68kcontext_68000.sr;
default: return 0;
}
}
bool SetSpecialReg(CCPUDebug *cpu, unsigned id, UINT32 data)
{
switch (id)
{
case M68KSPECIAL_SP: turbo68kcontext_68000.a[7] = data; return true;
case M68KSPECIAL_SR: turbo68kcontext_68000.sr = data; return true;
default: return false;
}
}
UINT32 GetDataReg(CCPUDebug *cpu, unsigned id)
{
return (UINT32)turbo68kcontext_68000.d[id];
}
bool SetDataReg(CCPUDebug *cpu, unsigned id, UINT32 data)
{
turbo68kcontext_68000.d[id] = data;
return true;
}
UINT32 GetAddressReg(CCPUDebug *cpu, unsigned id)
{
return (UINT32)turbo68kcontext_68000.a[id];
}
bool SetAddressReg(CCPUDebug *cpu, unsigned id, UINT32 data)
{
turbo68kcontext_68000.a[id] = data;
return true;
}
static const char *srGroup = "Special Registers";
static const char *drGroup = "Data Registers";
static const char *arGroup = "Address Regsters";
C68KDebug::C68KDebug() : CCPUDebug("68K", 2, 10, true, 24, 7), m_resetAddr(0)
{
// Special registers
AddPCRegister ("PC", srGroup);
AddAddrRegister ("SP", srGroup, M68KSPECIAL_SP, GetSpecialReg, SetSpecialReg);
AddStatus32Register("SR", srGroup, M68KSPECIAL_SR, "TtSM.210...XNZVC", GetSpecialReg, SetSpecialReg);
// Data registers
for (unsigned id = 0; id < 8; id++)
{
sprintf(m_drNames[id], "D%u", id);
AddInt32Register(m_drNames[id], drGroup, id, GetDataReg, SetDataReg);
}
// Address registers
for (unsigned id = 0; id < 8; id++)
{
sprintf(m_arNames[id], "A%u", id);
AddInt32Register(m_arNames[id], arGroup, id, GetAddressReg, SetAddressReg);
}
// Exceptions
AddException("BUS", 2, "Bus Error");
AddException("ADDRESS", 3, "Address Error");
@ -148,180 +82,6 @@ namespace Debugger
}
}
C68KDebug::~C68KDebug()
{
DetachFromCPU();
}
BOOL __cdecl DebugHandler(TURBO68K_INT32 pc, TURBO68K_INT32 opcode)
{
// Return true to let Turbo68K know if PC was changed by user
return debug->CheckExecution((UINT32)pc, (UINT32)opcode);
}
void __cdecl InterruptHandler(TURBO68K_UINT32 intVec)
{
// TODO - is following correct handling of interrupts? - need to check readme file
if (intVec > 47)
return;
else if (intVec >= 25 || intVec < 32)
{
debug->CheckException(25);
debug->CheckInterrupt((UINT16)intVec - 25);
}
else
debug->CheckException((UINT16)intVec);
if (origIntAckPtr != NULL)
origIntAckPtr(intVec);
}
void C68KDebug::AttachToCPU()
{
if (debug != NULL)
DetachFromCPU();
debug = this;
origDebugPtr = (DebugPtr)turbo68kcontext_68000.Debug;
origIntAckPtr = (IntAckPtr)turbo68kcontext_68000.InterruptAcknowledge;
origRead8Regions = (TURBO68K_DATAREGION*)Turbo68KGetReadByte(TURBO68K_NULL);
origRead16Regions = (TURBO68K_DATAREGION*)Turbo68KGetReadWord(TURBO68K_NULL);
origRead32Regions = (TURBO68K_DATAREGION*)Turbo68KGetReadLong(TURBO68K_NULL);
origWrite8Regions = (TURBO68K_DATAREGION*)Turbo68KGetWriteByte(TURBO68K_NULL);
origWrite16Regions = (TURBO68K_DATAREGION*)Turbo68KGetWriteWord(TURBO68K_NULL);
origWrite32Regions = (TURBO68K_DATAREGION*)Turbo68KGetWriteLong(TURBO68K_NULL);
turbo68kcontext_68000.Debug = DebugHandler;
turbo68kcontext_68000.InterruptAcknowledge = InterruptHandler;
debugRead8Regions[0].handler = ReadByteDebug;
debugRead16Regions[0].handler = ReadWordDebug;
debugRead32Regions[0].handler = ReadLongDebug;
debugWrite8Regions[0].handler = WriteByteDebug;
debugWrite16Regions[0].handler = WriteWordDebug;
debugWrite32Regions[0].handler = WriteLongDebug;
Turbo68KSetReadByte(debugRead8Regions, TURBO68K_NULL);
Turbo68KSetReadWord(debugRead16Regions, TURBO68K_NULL);
Turbo68KSetReadLong(debugRead32Regions, TURBO68K_NULL);
Turbo68KSetWriteByte(debugWrite8Regions, TURBO68K_NULL);
Turbo68KSetWriteWord(debugWrite16Regions, TURBO68K_NULL);
Turbo68KSetWriteLong(debugWrite32Regions, TURBO68K_NULL);
// Reset address is held at 0x000004
m_resetAddr = ReadLongDirect(0x000004);
}
void C68KDebug::DetachFromCPU()
{
if (debug == NULL)
return;
turbo68kcontext_68000.Debug = origDebugPtr;
turbo68kcontext_68000.InterruptAcknowledge = origIntAckPtr;
Turbo68KSetReadByte(origRead8Regions, TURBO68K_NULL);
Turbo68KSetReadWord(origRead16Regions, TURBO68K_NULL);
Turbo68KSetReadLong(origRead32Regions, TURBO68K_NULL);
Turbo68KSetWriteByte(origWrite8Regions, TURBO68K_NULL);
Turbo68KSetWriteWord(origWrite16Regions, TURBO68K_NULL);
Turbo68KSetWriteLong(origWrite32Regions, TURBO68K_NULL);
debug = NULL;
}
UINT32 C68KDebug::GetResetAddr()
{
return m_resetAddr;
}
bool C68KDebug::UpdatePC(UINT32 newPC)
{
turbo68kcontext_68000.pc = newPC;
return true;
}
bool C68KDebug::ForceException(CException *ex)
{
//switch (ex->code)
//{
// TODO
//}
return false;
}
bool C68KDebug::ForceInterrupt(CInterrupt *in)
{
if (in->code > 6)
return false;
//Turbo68KInterrupt(in->code, TURBO64K_AUTOVECTOR);
//Turbo68KProcessInterrupts(); TODO - call this?
return false; // TODO
}
UINT64 C68KDebug::ReadMem(UINT32 addr, unsigned dataSize)
{
switch (dataSize)
{
case 1: return ReadByteDirect(addr);
case 2: return ReadWordDirect(addr);
case 4: return ReadLongDirect(addr);
default: return CCPUDebug::ReadMem(addr, dataSize);
}
}
bool C68KDebug::WriteMem(UINT32 addr, unsigned dataSize, UINT64 data)
{
switch (dataSize)
{
case 1: WriteByteDirect(addr, (TURBO68K_UINT8)data); return true;
case 2: WriteWordDirect(addr, (TURBO68K_UINT16)data); return true;
case 4: WriteLongDirect(addr, (TURBO68K_UINT32)data); return true;
default: return CCPUDebug::WriteMem(addr, dataSize, data);
}
}
TURBO68K_UINT8 __cdecl ReadByteDebug(TURBO68K_UINT32 addr)
{
TURBO68K_UINT8 data = ReadByteDirect(addr);
debug->CheckRead8((UINT32)addr, (UINT8)data);
return data;
}
TURBO68K_UINT16 __cdecl ReadWordDebug(TURBO68K_UINT32 addr)
{
TURBO68K_UINT16 data = ReadWordDirect(addr);
debug->CheckRead16((UINT32)addr, (UINT16)data);
return data;
}
TURBO68K_UINT32 __cdecl ReadLongDebug(TURBO68K_UINT32 addr)
{
TURBO68K_UINT32 data = ReadLongDirect(addr);
debug->CheckRead32((UINT32)addr, (UINT32)data);
return data;
}
void __cdecl WriteByteDebug(TURBO68K_UINT32 addr, TURBO68K_UINT8 data)
{
WriteByteDirect(addr, data);
debug->CheckWrite8((UINT32)addr, (UINT8)data);
}
void __cdecl WriteWordDebug(TURBO68K_UINT32 addr, TURBO68K_UINT16 data)
{
WriteWordDirect(addr, data);
debug->CheckWrite16((UINT32)addr, (UINT16)data);
}
void __cdecl WriteLongDebug(TURBO68K_UINT32 addr, TURBO68K_UINT32 data)
{
WriteLongDirect(addr, data);
debug->CheckWrite32((UINT32)addr, (UINT32)data);
}
static const char *opATable0004[] = { "movep.w [DW3](A0),D0","movep.w [DW3](A1),D0","movep.w [DW3](A2),D0",
"movep.w [DW3](A3),D0","movep.w [DW3](A4),D0","movep.w [DW3](A5),D0","movep.w [DW3](A6),D0",
"movep.w [DW3](A7),D0" };
@ -1485,7 +1245,7 @@ namespace Debugger
int C68KDebug::Disassemble(UINT32 addr, char *mnemonic, char *operands)
{
// Read opcode head word
UINT16 opcode = ReadWordDirect(addr);
UINT16 opcode = (UINT16)ReadMem(addr, 16);
int offset = 2;
const char *instr;
@ -1537,7 +1297,7 @@ namespace Debugger
if ((opcode&0x0B80) == 0x0880)
{
// movem.z reg-list,a or movem.z a,reg-list
u16 = ReadWordDirect(addr + offset);
u16 = (UINT16)ReadMem(addr + offset, 2);
offset += 2;
char sizeC = (opcode&0x40 ? 'l' : 'w');
char regList[50];
@ -1923,14 +1683,14 @@ namespace Debugger
if (p[2] == 'N')
{
// Check first byte is zero
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
if (u8 != 0)
{
offset++;
goto invalid;
}
// Get data byte
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
// Check top 3 bits are zero
if (u8&0xE0)
goto invalid;
@ -1940,16 +1700,16 @@ namespace Debugger
else if (p[2] == 'B')
{
// Check first byte is zero
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
if (u8 != 0)
{
offset++;
goto invalid;
}
// Get data byte
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
FormatData(r, 1, u8);
//i8 = (INT8)ReadByteDirect(addr + offset++);
//i8 = (INT8)ReadMem(addr + offset++, 1);
//if (i8 < 0)
//{
// *r++ = '-';
@ -1964,10 +1724,10 @@ namespace Debugger
}
else if (p[2] == 'W')
{
u16 = ReadWordDirect(addr + offset);
u16 = (UINT16)ReadMem(addr + offset, 2);
offset += 2;
FormatData(r, 2, u16);
//i16 = (INT16)ReadWordDirect(addr + offset);
//i16 = (INT16)ReadMem(addr + offset, 2);
//offset += 2;
//if (i16 < 0)
//{
@ -1983,10 +1743,10 @@ namespace Debugger
}
else
{
u32 = ReadLongDirect(addr + offset);
u32 = (UINT32)ReadMem(addr + offset, 4);
offset += 4;
FormatData(r, 4, u32);
//i32 = (INT32)ReadLongDirect(addr + offset);
//i32 = (INT32)ReadMem(addr + offset, 4);
//offset += 4;
//if (i32 < 0)
//{
@ -2006,7 +1766,7 @@ namespace Debugger
else if (sscanf(p, "[LL%d]", &part) == 1) // TODO - this should be LW
{
// Fixed width label offset
i16 = (INT16)ReadWordDirect(addr + offset);
i16 = (INT16)ReadMem(addr + offset, 2);
offset += 2;
// Offset is from PC + 2
opFlags = GetOpFlags(addr, opcode);
@ -2022,14 +1782,14 @@ namespace Debugger
INT32 labOffset;
if (i8 == 0x00)
{
i16 = (INT16)ReadWordDirect(addr + offset);
i16 = (INT16)ReadMem(addr + offset, 2);
offset += 2;
labOffset = i16;
}
// Following 68020+ only
//else if (i8 == 0xFF)
//{
// i32 = (INT32)ReadLongDirect(addr + offset);
// i32 = (INT32)ReadMem(addr + offset, 4);
// offset += 4;
// labOffset = i32;
//*/
@ -2138,7 +1898,7 @@ namespace Debugger
sprintf(dest, "-(A%u)", reg);
break;
case 0x05: // (d16,An)
i16 = (INT16)ReadWordDirect(addr + offset);
i16 = (INT16)ReadMem(addr + offset, 2);
offset += 2;
if (i16 < 0)
{
@ -2154,7 +1914,7 @@ namespace Debugger
}
break;
case 0x06: // (d8,An,Ri.z)
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
// Check first 3-bits of first byte are zero
if (u8&0x7)
{
@ -2171,7 +1931,7 @@ namespace Debugger
ofsReg -= 8;
}
ofsSizeC = (u8&0x8 ? 'l' : 'w');
i8 = (INT8)ReadByteDirect(addr + offset++);
i8 = (INT8)ReadMem(addr + offset++, 1);
if (i8 < 0)
{
FormatData(dataStr, 1, -i8);
@ -2189,21 +1949,21 @@ namespace Debugger
switch (reg)
{
case 0x00: // addr16
u16 = ReadWordDirect(addr + offset);
u16 = (UINT16)ReadMem(addr + offset, 2);
offset += 2;
opFlags = GetOpFlags(addr, opcode);
FormatJumpAddress(dest, u16, opFlags);
//sprintf(dest, "0x%06X", u16); // Format this way as memory bus width is 24-bits
break;
case 0x01: // addr32
u32 = ReadLongDirect(addr + offset);
u32 = (UINT32)ReadMem(addr + offset, 4);
offset += 4;
opFlags = GetOpFlags(addr, opcode);
FormatJumpAddress(dest, u32, opFlags);
//sprintf(dest, "0x%06X", u32); // Format this way as memory bus width is only 24-bits
break;
case 0x02: // d16(PC)
i16 = (INT16)ReadWordDirect(addr + offset);
i16 = (INT16)ReadMem(addr + offset, 2);
offset += 2;
if (i16 < 0)
{
@ -2219,7 +1979,7 @@ namespace Debugger
}
break;
case 0x03: // u8(PC,Ri.x)
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
// Check first 3-bits of first byte are zero
if (u8&0x7)
{
@ -2236,7 +1996,7 @@ namespace Debugger
ofsReg -= 8;
}
ofsSizeC = (u8&0x8 ? 'l' : 'w');
i8 = (INT8)ReadByteDirect(addr + offset++);
i8 = (INT8)ReadMem(addr + offset++, 1);
if (i8 < 0)
{
FormatData(dataStr, 1, -i8);
@ -2254,17 +2014,17 @@ namespace Debugger
if (sizeC == 'b')
{
// Check first byte is zero
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
if (u8 != 0)
{
offset++;
return false;
}
// Get data byte
u8 = ReadByteDirect(addr + offset++);
u8 = (UINT8)ReadMem(addr + offset++, 1);
FormatData(dataStr, 1, u8);
sprintf(dest, "#%s", dataStr);
//i8 = (INT8)ReadByteDirect(addr + offset++);
//i8 = (INT8)ReadMem(addr + offset++, 1);
//if (i8 < 0)
//{
// FormatData(dataStr, 1, -i8);
@ -2280,11 +2040,11 @@ namespace Debugger
}
else if (sizeC == 'w')
{
u16 = ReadWordDirect(addr + offset);
u16 = (UINT16)ReadMem(addr + offset, 2);
offset += 2;
FormatData(dataStr, 2, u16);
sprintf(dest, "#%s", dataStr);
//i16 = (INT16)ReadWordDirect(addr + offset);
//i16 = (INT16)ReadMem(addr + offset, 2);
//offset += 2;
//if (i16 < 0)
//{
@ -2301,11 +2061,11 @@ namespace Debugger
}
else if (sizeC == 'l')
{
u32 = ReadLongDirect(addr + offset);
u32 = (UINT32)ReadMem(addr + offset, 4);
offset += 4;
FormatData(dataStr, 4, u32);
sprintf(dest, "#%s", dataStr);
//i32 = (INT32)ReadLongDirect(addr + offset);
//i32 = (INT32)ReadMem(addr + offset, 4);
//offset += 4;
//if (i32 < 0)
//{
@ -2372,12 +2132,12 @@ namespace Debugger
{
if (reg == 0x00)
{
jumpAddr = ReadWordDirect(addr + 2);
jumpAddr = (UINT32)ReadMem(addr + 2, 4);
return true;
}
else if (reg == 0x01)
{
jumpAddr = ReadLongDirect(addr + 2);
jumpAddr = (UINT32)ReadMem(addr + 2, 4);
return true;
}
}
@ -2388,7 +2148,7 @@ namespace Debugger
// Instruction is bra, bsr or bCC
INT8 i8 = (INT8)(opcode&0xFF);
if (i8 == 0x00)
jumpAddr = addr + 2 + (INT16)ReadWordDirect(addr + 2);
jumpAddr = addr + 2 + (INT16)ReadMem(addr + 2, 2);
else
jumpAddr = addr + 2 + i8;
return true;
@ -2396,7 +2156,7 @@ namespace Debugger
else if ((opcode&0xF0F8) == 0x50C8)
{
// Instruction is dbCC
jumpAddr = addr + 2 + (INT16)ReadWordDirect(addr + 2);
jumpAddr = addr + 2 + (INT16)ReadMem(addr + 2, 2);
return true;
}
else
@ -2444,28 +2204,27 @@ namespace Debugger
if (opcode != 0x4E74 && opcode != 0x4E75 && opcode != 0x4E73)
return false;
// Return address will be at top of stack for rts and stack + 2 for rtr or rte
UINT32 sp = (UINT32)turbo68kcontext_68000.a[7];
UINT32 sp = 0; // TODO GetSP(); //(UINT32)turbo68kcontext_68000.a[7];
if (opcode == 0x4E75)
retAddr = ReadLongDirect(sp);
retAddr = (UINT32)ReadMem(sp, 4);
else
retAddr = ReadLongDirect(sp + 2);
retAddr = (UINT32)ReadMem(sp + 2, 4);
return true;
}
bool C68KDebug::GetHandlerAddr(CException *ex, UINT32 &handlerAddr)
{
UINT32 vecAddr = ex->code * 4;
handlerAddr = (UINT32)ReadLongDirect(vecAddr);
handlerAddr = (UINT32)ReadMem(vecAddr, 4);
return !!handlerAddr;
}
bool C68KDebug::GetHandlerAddr(CInterrupt *in, UINT32 &handlerAddr)
{
UINT32 vecAddr = (in->code + 25) * 4;
handlerAddr = (UINT32)ReadLongDirect(vecAddr);
handlerAddr = (UINT32)ReadMem(vecAddr, 4);
return !!handlerAddr;
}
}
#endif // SUPERMODEL_SOUND
#endif // SUPERMODEL_DEBUGGER

View file

@ -1,12 +1,11 @@
#ifdef SUPERMODEL_DEBUGGER
#ifdef SUPERMODEL_SOUND
#ifndef INCLUDED_68KDEBUG_H
#define INCLUDED_68KDEBUG_H
#include "Debugger/CPUDebug.h"
#include "Types.h"
#include "CPU/68K/Turbo68K.h"
#include "CPU/68K/Turbo68K/Turbo68K.h"
#define M68KSPECIAL_SP 0
#define M68KSPECIAL_SR 1
@ -16,77 +15,8 @@
namespace Debugger
{
class C68KDebug;
static C68KDebug *debug = NULL;
typedef bool (*DebugPtr)(TURBO68K_INT32 pc, TURBO68K_INT32 opcode);
typedef void (*IntAckPtr)(TURBO68K_UINT32 intVec);
static DebugPtr origDebugPtr = NULL;
static IntAckPtr origIntAckPtr = NULL;
static TURBO68K_DATAREGION *origRead8Regions;
static TURBO68K_DATAREGION *origRead16Regions;
static TURBO68K_DATAREGION *origRead32Regions;
static TURBO68K_DATAREGION *origWrite8Regions;
static TURBO68K_DATAREGION *origWrite16Regions;
static TURBO68K_DATAREGION *origWrite32Regions;
static TURBO68K_DATAREGION debugRead8Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugRead16Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugRead32Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugWrite8Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugWrite16Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugWrite32Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static UINT32 GetSpecialReg(CCPUDebug *cpu, unsigned id);
static bool SetSpecialReg(CCPUDebug *cpu, unsigned id, UINT32 data);
static UINT32 GetDataReg(CCPUDebug *cpu, unsigned id);
static bool SetDataReg(CCPUDebug *cpu, unsigned id, UINT32 data) ;
static UINT32 GetAddressReg(CCPUDebug *cpu, unsigned id);
static bool SetAddressReg(CCPUDebug *cpu, unsigned id, UINT32 data);
static TURBO68K_UINT8 ReadByteDebug(TURBO68K_UINT32 addr);
static TURBO68K_UINT16 ReadWordDebug(TURBO68K_UINT32 addr);
static TURBO68K_UINT32 ReadLongDebug(TURBO68K_UINT32 addr);
static void WriteByteDebug(TURBO68K_UINT32 addr, TURBO68K_UINT8 data);
static void WriteWordDebug(TURBO68K_UINT32 addr, TURBO68K_UINT16 data);
static void WriteLongDebug(TURBO68K_UINT32 addr, TURBO68K_UINT32 data);
static TURBO68K_UINT8 ReadByteDirect(TURBO68K_UINT32 addr);
static TURBO68K_UINT16 ReadWordDirect(TURBO68K_UINT32 addr);
static TURBO68K_UINT32 ReadLongDirect(TURBO68K_UINT32 addr);
static void WriteByteDirect(TURBO68K_UINT32 addr, TURBO68K_UINT8 data);
static void WriteWordDirect(TURBO68K_UINT32 addr, TURBO68K_UINT16 data);
static void WriteLongDirect(TURBO68K_UINT32 addr, TURBO68K_UINT32 data);
/*
* CCPUDebug implementation for the Turbo68K Motorola 68000 emulator.
* Base class CCPUDebug implementation for Motorola 68000 CPUs.
*/
class C68KDebug : public CCPUDebug
{
@ -98,33 +28,16 @@ namespace Debugger
char m_sSlotStr[32][20];
char m_regStr[16][12];
UINT32 m_resetAddr;
bool FormatAddrMode(UINT32 addr, UINT32 opcode, int &offset, UINT8 addrMode, char sizeC, char *dest);
protected:
virtual UINT32 GetSP() = 0;
public:
C68KDebug();
virtual ~C68KDebug();
// CCPUDebug methods
void AttachToCPU();
void DetachFromCPU();
UINT32 GetResetAddr();
bool UpdatePC(UINT32 pc);
bool ForceException(CException *ex);
bool ForceInterrupt(CInterrupt *in);
UINT64 ReadMem(UINT32 addr, unsigned dataSize);
bool WriteMem(UINT32 addr, unsigned dataSize, UINT64 data);
int Disassemble(UINT32 addr, char *mnemonic, char *operands);
EOpFlags GetOpFlags(UINT32 addr, UINT32 opcode);
@ -139,197 +52,7 @@ namespace Debugger
bool GetHandlerAddr(CInterrupt *in, UINT32 &handlerAddr);
};
//
// Inlined functions
//
typedef TURBO68K_UINT8 (*ReadByteFPtr)(TURBO68K_UINT32);
typedef TURBO68K_UINT16 (*ReadWordFPtr)(TURBO68K_UINT32);
typedef TURBO68K_UINT32 (*ReadLongFPtr)(TURBO68K_UINT32);
typedef void (*WriteByteFPtr)(TURBO68K_UINT32, TURBO68K_UINT8);
typedef void (*WriteWordFPtr)(TURBO68K_UINT32, TURBO68K_UINT16);
typedef void (*WriteLongFPtr)(TURBO68K_UINT32, TURBO68K_UINT32);
inline TURBO68K_UINT8 ReadByteDirect(TURBO68K_UINT32 addr)
{
#if USE_NATIVE_READ
Turbo68KSetReadByte(origRead8Regions, TURBO68K_NULL);
TURBO68K_UINT8 data = Turbo68KReadByte(addr);
Turbo68KSetReadByte(debugRead8Regions, TURBO68K_NULL);
return data;
#else
for (TURBO68K_DATAREGION *region = origRead8Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when reading bytes
TURBO68K_UINT8 *dataP = (TURBO68K_UINT8*)(region->ptr + (addr^1));
return *dataP;
}
else
{
ReadByteFPtr fPtr = (ReadByteFPtr)region->handler;
return fPtr(addr);
}
}
}
return 0;
#endif
}
inline TURBO68K_UINT16 ReadWordDirect(TURBO68K_UINT32 addr)
{
#if USE_NATIVE_READ
Turbo68KSetReadWord(origRead16Regions, TURBO68K_NULL);
TURBO68K_UINT16 data = Turbo68KReadWord(addr);
Turbo68KSetReadWord(debugRead16Regions, TURBO68K_NULL);
return data;
#else
for (TURBO68K_DATAREGION *region = origRead16Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when reading bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
return *dataP;
}
else
{
ReadWordFPtr fPtr = (ReadWordFPtr)region->handler;
return fPtr(addr);
}
}
}
return 0;
#endif
}
inline TURBO68K_UINT32 ReadLongDirect(TURBO68K_UINT32 addr)
{
#if USE_NATIVE_READ
Turbo68KSetReadLong(origRead32Regions, TURBO68K_NULL);
TURBO68K_UINT32 data = Turbo68KReadLong(addr);
Turbo68KSetReadLong(debugRead32Regions, TURBO68K_NULL);
return data;
#else
for (TURBO68K_DATAREGION *region = origRead32Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when reading bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
return (TURBO68K_UINT32)dataP[1] | ((TURBO68K_UINT32)dataP[0])<<16;
}
else
{
ReadLongFPtr fPtr = (ReadLongFPtr)region->handler;
return fPtr(addr);
}
}
}
return 0;
#endif
}
inline void WriteByteDirect(TURBO68K_UINT32 addr, TURBO68K_UINT8 data)
{
#if USE_NATIVE_WRITE
Turbo68KSetWriteByte(origWrite8Regions, TURBO68K_NULL);
Turbo68KWriteByte(addr, data);
Turbo68KSetWriteByte(debugWrite8Regions, TURBO68K_NULL);
#else
for (TURBO68K_DATAREGION *region = origWrite8Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when writing bytes
TURBO68K_UINT8 *dataP = (TURBO68K_UINT8*)(region->ptr + (addr^1));
*dataP = data;
return;
}
else
{
WriteByteFPtr fPtr = (WriteByteFPtr)region->handler;
fPtr(addr, data);
return;
}
}
}
return;
#endif
}
inline void WriteWordDirect(TURBO68K_UINT32 addr, TURBO68K_UINT16 data)
{
#if USE_NATIVE_WRITE
Turbo68KSetWriteWord(origWrite16Regions, TURBO68K_NULL);
Turbo68KWriteWord(addr, data);
Turbo68KSetWriteWord(debugWrite16Regions, TURBO68K_NULL);
#else
for (TURBO68K_DATAREGION *region = origWrite16Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when writing bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
*dataP = data;
return;
}
else
{
WriteWordFPtr fPtr = (WriteWordFPtr)region->handler;
fPtr(addr, data);
return;
}
}
}
return;
#endif
}
inline void WriteLongDirect(TURBO68K_UINT32 addr, TURBO68K_UINT32 data)
{
#if USE_NATIVE_WRITE
Turbo68KSetWriteLong(origWrite32Regions, TURBO68K_NULL);
Turbo68KWriteLong(addr, data);
Turbo68KSetWriteLong(debugWrite32Regions, TURBO68K_NULL);
#else
for (TURBO68K_DATAREGION *region = origWrite32Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when writing bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
dataP[0] = data>>16;
dataP[1] = data&0xFFFF;
return;
}
else
{
WriteLongFPtr fPtr = (WriteLongFPtr)region->handler;
fPtr(addr, data);
return;
}
}
}
return;
#endif
}
}
#endif // INCLUDED_68KDEBUG_H
#endif // SUPERMODEL_SOUND
#endif // SUPERMODEL_DEBUGGER

View file

@ -3,7 +3,7 @@
#define INCLUDED_PPCDEBUG_H
#include "Debugger/CPUDebug.h"
#include "Model3/Bus.h"
#include "CPU/Bus.h"
#include "Types.h"
#define PPCSPECIAL_LR 0

View file

@ -0,0 +1,291 @@
#ifdef SUPERMODEL_DEBUGGER
#include "Turbo68KDebug.h"
#include <string.h>
#include <ctype.h>
namespace Debugger
{
UINT32 GetSpecialReg(CCPUDebug *cpu, unsigned id)
{
switch (id)
{
case M68KSPECIAL_SP: return (UINT32)turbo68kcontext_68000.a[7];
case M68KSPECIAL_SR: return (UINT32)turbo68kcontext_68000.sr;
default: return 0;
}
}
bool SetSpecialReg(CCPUDebug *cpu, unsigned id, UINT32 data)
{
switch (id)
{
case M68KSPECIAL_SP: turbo68kcontext_68000.a[7] = data; return true;
case M68KSPECIAL_SR: turbo68kcontext_68000.sr = data; return true;
default: return false;
}
}
UINT32 GetDataReg(CCPUDebug *cpu, unsigned id)
{
return (UINT32)turbo68kcontext_68000.d[id];
}
bool SetDataReg(CCPUDebug *cpu, unsigned id, UINT32 data)
{
turbo68kcontext_68000.d[id] = data;
return true;
}
UINT32 GetAddressReg(CCPUDebug *cpu, unsigned id)
{
return (UINT32)turbo68kcontext_68000.a[id];
}
bool SetAddressReg(CCPUDebug *cpu, unsigned id, UINT32 data)
{
turbo68kcontext_68000.a[id] = data;
return true;
}
static const char *srGroup = "Special Registers";
static const char *drGroup = "Data Registers";
static const char *arGroup = "Address Regsters";
CTurbo68KDebug::CTurbo68KDebug() : C68KDebug(), m_resetAddr(0)
{
// Special registers
AddPCRegister ("PC", srGroup);
AddAddrRegister ("SP", srGroup, M68KSPECIAL_SP, GetSpecialReg, SetSpecialReg);
AddStatus32Register("SR", srGroup, M68KSPECIAL_SR, "TtSM.210...XNZVC", GetSpecialReg, SetSpecialReg);
// Data registers
for (unsigned id = 0; id < 8; id++)
{
sprintf(m_drNames[id], "D%u", id);
AddInt32Register(m_drNames[id], drGroup, id, GetDataReg, SetDataReg);
}
// Address registers
for (unsigned id = 0; id < 8; id++)
{
sprintf(m_arNames[id], "A%u", id);
AddInt32Register(m_arNames[id], arGroup, id, GetAddressReg, SetAddressReg);
}
// TODO - following Model3-specific stuff should be moved to SupermodelDebugger
// Regions
AddRegion(0x000000, 0x0FFFFF, true, false, "SCSP1 RAM");
AddRegion(0x200000, 0x2FFFFF, true, false, "SCSP2 RAM");
AddRegion(0x600000, 0x67FFFF, true, true, "Program ROM");
AddRegion(0x800000, 0x9FFFFF, false, true, "Sample ROM (low 2 MB)");
AddRegion(0xA00000, 0xDFFFFF, false, true, "Sample ROM (bank)");
AddRegion(0xE00000, 0xFFFFFF, false, true, "Sample ROM (bank)");
AddRegion(0x100000, 0x10FFFF, false, false, "SCSP Master");
AddRegion(0x300000, 0x30FFFF, false, false, "SCSP Slave");
// Mapped I/O
for (unsigned slot = 0; slot < 32; slot++)
{
sprintf(m_mSlotStr[slot], "SCSP Master Slot %02X", slot);
for (unsigned reg = 0; reg < 16; reg++)
{
UINT32 addr = 0x100000 + slot * 0x20 + reg * 0x02;
sprintf(m_regStr[reg], "Register %u", reg);
AddMappedIO(addr, 2, m_regStr[reg], m_mSlotStr[slot]);
}
}
for (unsigned slot = 0; slot < 32; slot++)
{
sprintf(m_sSlotStr[slot], "SCSP Slave Slot %02X", slot);
for (unsigned reg = 0; reg < 16; reg++)
{
UINT32 addr = 0x300000 + slot * 0x20 + reg * 0x02;
AddMappedIO(addr, 2, m_regStr[reg], m_sSlotStr[slot]);
}
}
}
CTurbo68KDebug::~CTurbo68KDebug()
{
DetachFromCPU();
}
BOOL __cdecl DebugHandler(TURBO68K_INT32 pc, TURBO68K_INT32 opcode)
{
// Return true to let Turbo68K know if PC was changed by user
return debug->CheckExecution((UINT32)pc, (UINT32)opcode);
}
void __cdecl InterruptHandler(TURBO68K_UINT32 intVec)
{
// TODO - is following correct handling of interrupts? - need to check readme file
if (intVec > 47)
return;
else if (intVec >= 25 || intVec < 32)
{
debug->CheckException(25);
debug->CheckInterrupt((UINT16)intVec - 25);
}
else
debug->CheckException((UINT16)intVec);
if (origIntAckPtr != NULL)
origIntAckPtr(intVec);
}
void CTurbo68KDebug::AttachToCPU()
{
if (debug != NULL)
DetachFromCPU();
debug = this;
origDebugPtr = (DebugPtr)turbo68kcontext_68000.Debug;
origIntAckPtr = (IntAckPtr)turbo68kcontext_68000.InterruptAcknowledge;
origRead8Regions = (TURBO68K_DATAREGION*)Turbo68KGetReadByte(TURBO68K_NULL);
origRead16Regions = (TURBO68K_DATAREGION*)Turbo68KGetReadWord(TURBO68K_NULL);
origRead32Regions = (TURBO68K_DATAREGION*)Turbo68KGetReadLong(TURBO68K_NULL);
origWrite8Regions = (TURBO68K_DATAREGION*)Turbo68KGetWriteByte(TURBO68K_NULL);
origWrite16Regions = (TURBO68K_DATAREGION*)Turbo68KGetWriteWord(TURBO68K_NULL);
origWrite32Regions = (TURBO68K_DATAREGION*)Turbo68KGetWriteLong(TURBO68K_NULL);
turbo68kcontext_68000.Debug = DebugHandler;
turbo68kcontext_68000.InterruptAcknowledge = InterruptHandler;
debugRead8Regions[0].handler = ReadByteDebug;
debugRead16Regions[0].handler = ReadWordDebug;
debugRead32Regions[0].handler = ReadLongDebug;
debugWrite8Regions[0].handler = WriteByteDebug;
debugWrite16Regions[0].handler = WriteWordDebug;
debugWrite32Regions[0].handler = WriteLongDebug;
Turbo68KSetReadByte(debugRead8Regions, TURBO68K_NULL);
Turbo68KSetReadWord(debugRead16Regions, TURBO68K_NULL);
Turbo68KSetReadLong(debugRead32Regions, TURBO68K_NULL);
Turbo68KSetWriteByte(debugWrite8Regions, TURBO68K_NULL);
Turbo68KSetWriteWord(debugWrite16Regions, TURBO68K_NULL);
Turbo68KSetWriteLong(debugWrite32Regions, TURBO68K_NULL);
// Reset address is held at 0x000004
m_resetAddr = ReadLongDirect(0x000004);
}
void CTurbo68KDebug::DetachFromCPU()
{
if (debug == NULL)
return;
turbo68kcontext_68000.Debug = origDebugPtr;
turbo68kcontext_68000.InterruptAcknowledge = origIntAckPtr;
Turbo68KSetReadByte(origRead8Regions, TURBO68K_NULL);
Turbo68KSetReadWord(origRead16Regions, TURBO68K_NULL);
Turbo68KSetReadLong(origRead32Regions, TURBO68K_NULL);
Turbo68KSetWriteByte(origWrite8Regions, TURBO68K_NULL);
Turbo68KSetWriteWord(origWrite16Regions, TURBO68K_NULL);
Turbo68KSetWriteLong(origWrite32Regions, TURBO68K_NULL);
debug = NULL;
}
UINT32 CTurbo68KDebug::GetResetAddr()
{
return m_resetAddr;
}
UINT32 CTurbo68KDebug::GetSP()
{
return (UINT32)turbo68kcontext_68000.a[7];
}
bool CTurbo68KDebug::UpdatePC(UINT32 newPC)
{
turbo68kcontext_68000.pc = newPC;
return true;
}
bool CTurbo68KDebug::ForceException(CException *ex)
{
//switch (ex->code)
//{
// TODO
//}
return false;
}
bool CTurbo68KDebug::ForceInterrupt(CInterrupt *in)
{
if (in->code > 6)
return false;
//Turbo68KInterrupt(in->code, TURBO64K_AUTOVECTOR);
//Turbo68KProcessInterrupts(); TODO - call this?
return false; // TODO
}
UINT64 CTurbo68KDebug::ReadMem(UINT32 addr, unsigned dataSize)
{
switch (dataSize)
{
case 1: return ReadByteDirect(addr);
case 2: return ReadWordDirect(addr);
case 4: return ReadLongDirect(addr);
default: return CCPUDebug::ReadMem(addr, dataSize);
}
}
bool CTurbo68KDebug::WriteMem(UINT32 addr, unsigned dataSize, UINT64 data)
{
switch (dataSize)
{
case 1: WriteByteDirect(addr, (TURBO68K_UINT8)data); return true;
case 2: WriteWordDirect(addr, (TURBO68K_UINT16)data); return true;
case 4: WriteLongDirect(addr, (TURBO68K_UINT32)data); return true;
default: return CCPUDebug::WriteMem(addr, dataSize, data);
}
}
TURBO68K_UINT8 __cdecl ReadByteDebug(TURBO68K_UINT32 addr)
{
TURBO68K_UINT8 data = ReadByteDirect(addr);
debug->CheckRead8((UINT32)addr, (UINT8)data);
return data;
}
TURBO68K_UINT16 __cdecl ReadWordDebug(TURBO68K_UINT32 addr)
{
TURBO68K_UINT16 data = ReadWordDirect(addr);
debug->CheckRead16((UINT32)addr, (UINT16)data);
return data;
}
TURBO68K_UINT32 __cdecl ReadLongDebug(TURBO68K_UINT32 addr)
{
TURBO68K_UINT32 data = ReadLongDirect(addr);
debug->CheckRead32((UINT32)addr, (UINT32)data);
return data;
}
void __cdecl WriteByteDebug(TURBO68K_UINT32 addr, TURBO68K_UINT8 data)
{
WriteByteDirect(addr, data);
debug->CheckWrite8((UINT32)addr, (UINT8)data);
}
void __cdecl WriteWordDebug(TURBO68K_UINT32 addr, TURBO68K_UINT16 data)
{
WriteWordDirect(addr, data);
debug->CheckWrite16((UINT32)addr, (UINT16)data);
}
void __cdecl WriteLongDebug(TURBO68K_UINT32 addr, TURBO68K_UINT32 data)
{
WriteLongDirect(addr, data);
debug->CheckWrite32((UINT32)addr, (UINT32)data);
}
}
#endif // SUPERMODEL_DEBUGGER

View file

@ -0,0 +1,319 @@
#ifdef SUPERMODEL_DEBUGGER
#ifndef INCLUDED_TURBO68KDEBUG_H
#define INCLUDED_TURBO68KDEBUG_H
#include "Debugger/CPU/68KDebug.h"
#include "Types.h"
#include "CPU/68K/Turbo68K/Turbo68K.h"
#define M68KSPECIAL_SP 0
#define M68KSPECIAL_SR 1
#define USE_NATIVE_READ 0
#define USE_NATIVE_WRITE 0
namespace Debugger
{
class CTurbo68KDebug;
static CTurbo68KDebug *debug = NULL;
typedef bool (*DebugPtr)(TURBO68K_INT32 pc, TURBO68K_INT32 opcode);
typedef void (*IntAckPtr)(TURBO68K_UINT32 intVec);
static DebugPtr origDebugPtr = NULL;
static IntAckPtr origIntAckPtr = NULL;
static TURBO68K_DATAREGION *origRead8Regions;
static TURBO68K_DATAREGION *origRead16Regions;
static TURBO68K_DATAREGION *origRead32Regions;
static TURBO68K_DATAREGION *origWrite8Regions;
static TURBO68K_DATAREGION *origWrite16Regions;
static TURBO68K_DATAREGION *origWrite32Regions;
static TURBO68K_DATAREGION debugRead8Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugRead16Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugRead32Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugWrite8Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugWrite16Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static TURBO68K_DATAREGION debugWrite32Regions[] =
{
{ 0x000000, 0xFFFFFF, TURBO68K_NULL, TURBO68K_NULL },
{ -1, -1, TURBO68K_NULL, TURBO68K_NULL }
};
static UINT32 GetSpecialReg(CCPUDebug *cpu, unsigned id);
static bool SetSpecialReg(CCPUDebug *cpu, unsigned id, UINT32 data);
static UINT32 GetDataReg(CCPUDebug *cpu, unsigned id);
static bool SetDataReg(CCPUDebug *cpu, unsigned id, UINT32 data) ;
static UINT32 GetAddressReg(CCPUDebug *cpu, unsigned id);
static bool SetAddressReg(CCPUDebug *cpu, unsigned id, UINT32 data);
static TURBO68K_UINT8 ReadByteDebug(TURBO68K_UINT32 addr);
static TURBO68K_UINT16 ReadWordDebug(TURBO68K_UINT32 addr);
static TURBO68K_UINT32 ReadLongDebug(TURBO68K_UINT32 addr);
static void WriteByteDebug(TURBO68K_UINT32 addr, TURBO68K_UINT8 data);
static void WriteWordDebug(TURBO68K_UINT32 addr, TURBO68K_UINT16 data);
static void WriteLongDebug(TURBO68K_UINT32 addr, TURBO68K_UINT32 data);
static TURBO68K_UINT8 ReadByteDirect(TURBO68K_UINT32 addr);
static TURBO68K_UINT16 ReadWordDirect(TURBO68K_UINT32 addr);
static TURBO68K_UINT32 ReadLongDirect(TURBO68K_UINT32 addr);
static void WriteByteDirect(TURBO68K_UINT32 addr, TURBO68K_UINT8 data);
static void WriteWordDirect(TURBO68K_UINT32 addr, TURBO68K_UINT16 data);
static void WriteLongDirect(TURBO68K_UINT32 addr, TURBO68K_UINT32 data);
/*
* CCPUDebug implementation for the Turbo68K Motorola 68000 emulator.
*/
class CTurbo68KDebug : public C68KDebug
{
private:
char m_drNames[8][3];
char m_arNames[8][3];
char m_mSlotStr[32][20];
char m_sSlotStr[32][20];
char m_regStr[16][12];
UINT32 m_resetAddr;
public:
CTurbo68KDebug();
virtual ~CTurbo68KDebug();
// CCPUDebug methods
void AttachToCPU();
void DetachFromCPU();
UINT32 GetResetAddr();
UINT32 GetSP();
bool UpdatePC(UINT32 pc);
bool ForceException(CException *ex);
bool ForceInterrupt(CInterrupt *in);
UINT64 ReadMem(UINT32 addr, unsigned dataSize);
bool WriteMem(UINT32 addr, unsigned dataSize, UINT64 data);
};
//
// Inlined functions
//
typedef TURBO68K_UINT8 (*ReadByteFPtr)(TURBO68K_UINT32);
typedef TURBO68K_UINT16 (*ReadWordFPtr)(TURBO68K_UINT32);
typedef TURBO68K_UINT32 (*ReadLongFPtr)(TURBO68K_UINT32);
typedef void (*WriteByteFPtr)(TURBO68K_UINT32, TURBO68K_UINT8);
typedef void (*WriteWordFPtr)(TURBO68K_UINT32, TURBO68K_UINT16);
typedef void (*WriteLongFPtr)(TURBO68K_UINT32, TURBO68K_UINT32);
inline TURBO68K_UINT8 ReadByteDirect(TURBO68K_UINT32 addr)
{
#if USE_NATIVE_READ
Turbo68KSetReadByte(origRead8Regions, TURBO68K_NULL);
TURBO68K_UINT8 data = Turbo68KReadByte(addr);
Turbo68KSetReadByte(debugRead8Regions, TURBO68K_NULL);
return data;
#else
for (TURBO68K_DATAREGION *region = origRead8Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when reading bytes
TURBO68K_UINT8 *dataP = (TURBO68K_UINT8*)(region->ptr + (addr^1));
return *dataP;
}
else
{
ReadByteFPtr fPtr = (ReadByteFPtr)region->handler;
return fPtr(addr);
}
}
}
return 0;
#endif
}
inline TURBO68K_UINT16 ReadWordDirect(TURBO68K_UINT32 addr)
{
#if USE_NATIVE_READ
Turbo68KSetReadWord(origRead16Regions, TURBO68K_NULL);
TURBO68K_UINT16 data = Turbo68KReadWord(addr);
Turbo68KSetReadWord(debugRead16Regions, TURBO68K_NULL);
return data;
#else
for (TURBO68K_DATAREGION *region = origRead16Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when reading bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
return *dataP;
}
else
{
ReadWordFPtr fPtr = (ReadWordFPtr)region->handler;
return fPtr(addr);
}
}
}
return 0;
#endif
}
inline TURBO68K_UINT32 ReadLongDirect(TURBO68K_UINT32 addr)
{
#if USE_NATIVE_READ
Turbo68KSetReadLong(origRead32Regions, TURBO68K_NULL);
TURBO68K_UINT32 data = Turbo68KReadLong(addr);
Turbo68KSetReadLong(debugRead32Regions, TURBO68K_NULL);
return data;
#else
for (TURBO68K_DATAREGION *region = origRead32Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when reading bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
return (TURBO68K_UINT32)dataP[1] | ((TURBO68K_UINT32)dataP[0])<<16;
}
else
{
ReadLongFPtr fPtr = (ReadLongFPtr)region->handler;
return fPtr(addr);
}
}
}
return 0;
#endif
}
inline void WriteByteDirect(TURBO68K_UINT32 addr, TURBO68K_UINT8 data)
{
#if USE_NATIVE_WRITE
Turbo68KSetWriteByte(origWrite8Regions, TURBO68K_NULL);
Turbo68KWriteByte(addr, data);
Turbo68KSetWriteByte(debugWrite8Regions, TURBO68K_NULL);
#else
for (TURBO68K_DATAREGION *region = origWrite8Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when writing bytes
TURBO68K_UINT8 *dataP = (TURBO68K_UINT8*)(region->ptr + (addr^1));
*dataP = data;
return;
}
else
{
WriteByteFPtr fPtr = (WriteByteFPtr)region->handler;
fPtr(addr, data);
return;
}
}
}
return;
#endif
}
inline void WriteWordDirect(TURBO68K_UINT32 addr, TURBO68K_UINT16 data)
{
#if USE_NATIVE_WRITE
Turbo68KSetWriteWord(origWrite16Regions, TURBO68K_NULL);
Turbo68KWriteWord(addr, data);
Turbo68KSetWriteWord(debugWrite16Regions, TURBO68K_NULL);
#else
for (TURBO68K_DATAREGION *region = origWrite16Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when writing bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
*dataP = data;
return;
}
else
{
WriteWordFPtr fPtr = (WriteWordFPtr)region->handler;
fPtr(addr, data);
return;
}
}
}
return;
#endif
}
inline void WriteLongDirect(TURBO68K_UINT32 addr, TURBO68K_UINT32 data)
{
#if USE_NATIVE_WRITE
Turbo68KSetWriteLong(origWrite32Regions, TURBO68K_NULL);
Turbo68KWriteLong(addr, data);
Turbo68KSetWriteLong(debugWrite32Regions, TURBO68K_NULL);
#else
for (TURBO68K_DATAREGION *region = origWrite32Regions; region->ptr != TURBO68K_NULL || region->handler != TURBO68K_NULL; region++)
{
if (region->base <= addr && addr <= region->limit)
{
if (region->ptr != TURBO68K_NULL)
{
// Turbo68K requires native memory to be byte swapped, so must reverse this when writing bytes
TURBO68K_UINT16 *dataP = (TURBO68K_UINT16*)(region->ptr + addr);
dataP[0] = data>>16;
dataP[1] = data&0xFFFF;
return;
}
else
{
WriteLongFPtr fPtr = (WriteLongFPtr)region->handler;
fPtr(addr, data);
return;
}
}
}
return;
#endif
}
}
#endif // INCLUDED_TURBO68KDEBUG_H
#endif // SUPERMODEL_DEBUGGER

View file

@ -18,7 +18,7 @@ namespace Debugger
//
}
// TODO - tidy upf this function, ie do some proper parsing of commands - it is a mess!
// TODO - tidy up this function, ie do some proper parsing of commands - it is a mess!
void CConsoleDebugger::WaitCommand(CCPUDebug *cpu)
{
m_cpu = cpu;
@ -485,7 +485,7 @@ namespace Debugger
}
ex->trap = false;
Print("Trap for exception %s removed.\n", ex->name);
Print("Trap for exceptions of type %s removed.\n", ex->id);
}
else if (CheckToken(token, "i", "interrupt"))
{
@ -503,7 +503,7 @@ namespace Debugger
}
in->trap = false;
Print("Trap for interrupt %s removed.\n", in->name);
Print("Trap for interrupts ot type %s removed.\n", in->id);
}
else
{
@ -725,7 +725,7 @@ namespace Debugger
else if (CheckToken(token, "ral", "removealllabels")) // removealllabels
{
m_cpu->RemoveAllLabels();
Print("All custom labels removed.\m");
Print("All custom labels removed.\n");
}
else if (CheckToken(token, "ac", "addcomment")) // addcomment <addr> <text...>
{

View file

@ -16,9 +16,6 @@ namespace Debugger
m_loadEmuState(false), m_saveEmuState(false), m_resetEmu(false)
{
AddCPU(new CPPCDebug());
#ifdef SUPERMODEL_SOUND
AddCPU(new C68KDebug());
#endif
}
void CSupermodelDebugger::WaitCommand(CCPUDebug *cpu)