📄 agdi.cpp
字号:
case nR0: case nR1: case nR2: case nR3:
case nR4: case nR5: case nR6: case nR7:
REGARM.cur[nReg] = pV->u32;
val = DSWAP32(pV->u32);
// WriteRegister(DSWAP16(R0 + nReg), 4, &val);
break;
case nR8: case nR9: case nR10: case nR11:
case nR12:
REGARM.cur[nReg] = pV->u32;
val = DSWAP32(pV->u32);
switch (REGARM.cpsr & 0x1F) {
case 0x1F:
case 0x10:
case 0x12:
case 0x13:
case 0x17:
case 0x1B:
REGARM.usr[nReg - 0x08] = pV->u32;
// WriteRegister(DSWAP16(R0 + nReg), 4, &val);
break;
case 0x11:
REGARM.fiq[nReg - 0x08] = pV->u32;
// WriteRegister(DSWAP16(FIQ_R8 + (nReg - 0x08)), 4, &val);
break;
}
break;
case nR13: case nR14:
REGARM.cur[nReg] = pV->u32;
val = DSWAP32(pV->u32);
switch (REGARM.cpsr & 0x1F) {
case 0x1F:
case 0x10:
REGARM.usr [nReg - 0x08] = pV->u32;
// WriteRegister(DSWAP16(R0 + nReg), 4, &val);
break;
case 0x11:
REGARM.fiq [nReg - 0x08] = pV->u32;
// WriteRegister(DSWAP16(FIQ_R8 + (nReg - 0x08)), 4, &val);
break;
case 0x12:
REGARM.irq [nReg - 0x0D] = pV->u32;
// WriteRegister(DSWAP16(IRQ_R13 + (nReg - 0x0D)), 4, &val);
break;
case 0x13:
REGARM.svc [nReg - 0x0D] = pV->u32;
// WriteRegister(DSWAP16(SVC_R13 + (nReg - 0x0D)), 4, &val);
break;
case 0x17:
REGARM.abt [nReg - 0x0D] = pV->u32;
// WriteRegister(DSWAP16(ABT_R13 + (nReg - 0x0D)), 4, &val);
break;
case 0x1B:
REGARM.und [nReg - 0x0D] = pV->u32;
// WriteRegister(DSWAP16(UND_R13 + (nReg - 0x0D)), 4, &val);
break;
}
break;
case nR15:
case mPC: // current PC
REGARM.cur[15] = pV->u32;
WritePC(pV->u32);
break;
case nCPSR:
REGARM.cpsr = pV->u32;
pBom->Thumb = (REGARM.cpsr & 0x20) ? 1 : 0;
val = DSWAP32(pV->u32);
// WriteRegister(DSWAP16(CPSR),4, &val);
switch (REGARM.cpsr & 0x1F) {
case 0x1F:
case 0x10:
for (i=8;i<15;i++) REGARM.cur[i] = REGARM.usr[i-8];
break;
case 0x11:
for (i=8;i<15;i++) REGARM.cur[i] = REGARM.fiq[i-8];
REGARM.spsr = REGARM.fiq[7];
break;
case 0x12:
for (i=8;i<13;i++) REGARM.cur[i] = REGARM.usr[i-8];
REGARM.cur[13] = REGARM.irq[0];
REGARM.cur[14] = REGARM.irq[1];
REGARM.spsr = REGARM.irq[2];
break;
case 0x13:
for (i=8;i<13;i++) REGARM.cur[i] = REGARM.usr[i-8];
REGARM.cur[13] = REGARM.svc[0];
REGARM.cur[14] = REGARM.svc[1];
REGARM.spsr = REGARM.svc[2];
break;
case 0x17:
for (i=8;i<13;i++) REGARM.cur[i] = REGARM.usr[i-8];
REGARM.cur[13] = REGARM.abt[0];
REGARM.cur[14] = REGARM.abt[1];
REGARM.spsr = REGARM.abt[2];
break;
case 0x1B:
for (i=8;i<13;i++) REGARM.cur[i] = REGARM.usr[i-8];
REGARM.cur[13] = REGARM.und[0];
REGARM.cur[14] = REGARM.und[1];
REGARM.spsr = REGARM.und[2];
break;
}
break;
case nSPSR:
REGARM.spsr = pV->u32;
val = DSWAP32(pV->u32);
switch (REGARM.cpsr & 0x1F) {
case 0x1F:
case 0x10:
break;
case 0x11:
REGARM.fiq [7] = pV->u32;
// WriteRegister(DSWAP16(FIQ_SPSR), 4, &val);
break;
case 0x12:
REGARM.irq [2] = pV->u32;
// WriteRegister(DSWAP16(IRQ_SPSR), 4, &val);
break;
case 0x13:
REGARM.svc [2] = pV->u32;
// WriteRegister(DSWAP16(SVC_SPSR), 4, &val);
break;
case 0x17:
REGARM.abt [2] = pV->u32;
// WriteRegister(DSWAP16(ABT_SPSR), 4, &val);
break;
case 0x1B:
REGARM.und [2] = pV->u32;
// WriteRegister(DSWAP16(UND_SPSR), 4, &val);
break;
}
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) { // Disables the driver after the communication breaks down.
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Set Memory-Attribute for address 'nAdr'
* After the File has been loaded by SARM.DLL, it 'colors' in
* the memory attributes such as ATRX_THUMB, ATRX_ARM or ATRX_NOINST.
* This allows for correct interpretation of the memory content
* (ARM vs. THUMB vs. Not an Instruction).
*
* The typical attributes used here (also in combination) are:
* ATRX_EXEC 0x00000001 // 'executable' Attribute
* ATRX_READ 0x00000002 // 'readable' Attribute
* ATRX_WRITE 0x00000004 // 'writable' Attribute
* ATRX_THUMB 0x00000080 // Location contains 'Thumb' code
* ATRX_ARM 0x00008000 // Location contains 'ARM' code
* ATRX_NOINST 0x00080000 // not an instructuction, some constant or data location
*/
static void SetMemAttribute (UL32 nAdr, DWORD nAttr) {
UL32 *pAtr;
pAtr = MGetAttr (nAdr); // get pointer to Attributes for 'nAdr'
if (pAtr != NULL) { // pointer is valid
if (nAttr & (AG_ATR_THUMB | AG_ATR_ARM)) {
*pAtr &= ~AG_ATR_NOINST; // clear 'not an instruction' attribute
}
*pAtr |= nAttr; // or in new attribute
}
}
#if 1 // an Example to find out the type of content of the memory
#define NO_INST 0 // not an instruction
#define THUMB_INST 1 // a thumb instruction
#define ARM_INST 2 // an arm instruction
int GetInstMode (UL32 nAdr) {
UL32 *pAtr;
pAtr = MGetAttr (nAdr); // get pointer to Attributes for 'nAdr'
if (pAtr != NULL) { // pointer is valid
if (*pAtr & AG_ATR_NOINST) { // not an instruction
return (NO_INST);
}
if (*pAtr & AG_ATR_THUMB) { // a thumb instruction
return (THUMB_INST);
}
if (*pAtr & AG_ATR_ARM) { // an arm instruction
return (THUMB_INST);
}
}
return (NO_INST); // unmapped address, treat as NO_INST
}
#endif
U32 _EXPO_ AG_MemAtt (U16 nCode, UL32 nAttr, GADR *pA) {
U16 nErr;
if (iRun && !supp.MemAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return(AG_NOACCESS);
nErr = 0;
switch (nCode) {
case AG_MEMMAP: // map memory address range
pA->ErrAdr = MMapMem (nAttr, pA->Adr, pA->nLen);
break;
case AG_GETMEMATT: // Attribute descriptor is requested
pA->Adr = (UL32) MGetAttr (pA->Adr);
break;
case AG_SETMEMATT: // Set Memory Attribute
SetMemAttribute (pA->Adr, nAttr);
break;
}
if (PlayDead == 1) { // Disables the driver after the communication breaks down.
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0); // terminate driver
}
return (nErr);
}
/*
* Analyze the type of breakpoint and if it is enabled or disabled
*/
UL32 MBpInfo (UL32 nAdr, U16 nCode) {
MAMAP x;
struct EMM (*s)[256];
struct EMM acc;
U16 *pB;
UL32 nA;
AG_BP *pK, *pN;
switch (nCode) {
case AG_BPDISALL: // disable all Exec-Bp's
case AG_BPKILLALL: // kill all Exec-Bp's
break;
default:
x.a32 = nAdr; // requested code address
s = slots [x.ub[3]]; // a24-a31
if (s == NULL) {
MapSeg (x.a32 >> 16, x.a32 & 0xFFFF, 0x10000 - (x.a32 & 0xFFFF), 0); // map a segment
s = slots [x.ub[3]];
}
acc = (*s)[x.ub[2]]; // slot available?
if (acc.mem == NULL || acc.atr == NULL) {
return (0x80000000); // failed: unmapped address
}
pB = &((U16 *) acc.atr) [x.w16 >> 1]; // attributes
#if 0
acc = (*s)[x.ub[2]]; // slot available?
if (acc.mem == NULL) {
acc.mem = (BYTE *) calloc(_MSGM, 1); // map 64K + 4
acc.atr = (DWORD *) calloc(_MSGM, 1); // map 64K + 4
(*s)[x.ub[2]] = acc;
s = slots [x.ub[3]]; // slot available?
if (s == NULL) {
return (0x80000000); // failed: unmapped address
}
acc = (*s)[x.ub[2]]; // slot available?
if (acc.mem == NULL || acc.atr == NULL) { // exit if automap failed
return (0x80000000); // failed: unmapped address
}
}
pB = &((U16 *) acc.atr) [x.w16 >> 1];
#endif
break;
}
nA = 0;
switch (nCode) { // Function code
case AG_BPQUERY: // Query Break
case AG_BPEXQUERY: // Query for 'executed' attribute
nA = (UL32)*pB & (ATRX_BREAK | ATRX_BPDIS); // Attributes are similar to uVision
break;
case AG_BPENABLE: // enable breakpoint
if (*pB & ATRX_BPDIS) { // is Bp disabled ?
*pB = (*pB & ~ATRX_BPDIS) | ATRX_BREAK; // enable it
break;
}
case AG_BPDISABLE: // disable breakpoint
if (*pB & ATRX_BREAK) { // is Bp enabled ?
*pB = (*pB & ~ATRX_BREAK) | ATRX_BPDIS; // disable it
break;
}
break;
case AG_BPKILL: // kill breakpoint
*pB = *pB & ~(ATRX_BREAK | ATRX_BPDIS); // kill it
break;
case AG_BPSET: // Set breakpoint
*pB = (*pB & ~ATRX_BPDIS) | ATRX_BREAK; // set breakpoint
break;
case AG_BPDISALL: // disable all Bp's
pK = *pBhead;
for ( ; pK ; pK = pK->next ) {
if (pK->type == AG_ABREAK && pK->enabled) {
++nA;
MBpInfo (pK->Adr, AG_BPDISABLE);
}
}
break;
case AG_BPKILLALL: // kill all Bp's
pK = *pBhead;
while (pK) {
pN = pK->next;
if (pK->type == AG_ABREAK) {
++nA;
MBpInfo (pK->Adr, AG_BPKILL);
}
pK = pN;
}
break;
}
return (nA);
}
/*
* Get BreakPoints Infos
*/
U32 _EXPO_ AG_BpInfo (U16 nCode, void *vp) {
U32 n;
n = 0;
if (PlayDead) return(0);
n = MBpInfo (((GADR *) vp)->Adr, nCode);
if (PlayDead == 1) { // Disables the driver after the communication breaks down.
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (n);
}
int SaCBreaks (DWORD set, DWORD nA) { // 1:=set, 0:=clear
AG_BP *pB;
int nR;
abreaks = 0; // clear number of address Bp's
cbreaks = 0; // clear number of conditional Bp's
wbreaks = 0; // clear number of access Bp's
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (!pB->enabled) continue;
switch (pB->type) {
case AG_ABREAK: ++abreaks; break; // increase Nr. of AddressBreaks
case AG_CBREAK: ++cbreaks; break; // increase Nr. of CondBreaks
case AG_WBREAK: ++wbreaks; break; // increase Nr. of WatchBreaks
}
}
if (set == 0) { // Reset Breaks
if (SetBrkCount == 0) return (1);
--SetBrkCount;
}
else { // Set Breaks
if (SetBrkCount != 0) return (1);
++SetBrkCount;
}
//--- when CondBreaks or WatchBreaks are active, skip ExecBreaks
if (cbreaks || wbreaks) return (1);
nR = 1;
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (!pB->enabled) continue; // Break is disabled
switch (pB->type) {
case AG_ABREAK: // Addess-Break
if (pB->Adr == nA) { // g,main address
pBX = pB;
}
if (!SetClrBp (set, pB)) {
return (0);
}
break;
case AG_CBREAK: // Conditional-Break
break;
case AG_WBREAK: // Access-Break
break;
}
}
return (nR);
}
/*
* Is there a Breakpoint at address 'nAdr'
*/
DWORD IsBreak (DWORD nAdr) {
AG_BP *pB;
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (pB->enabled) {
if (pB->type == AG_ABREAK) {
if (pB->Adr == nAdr) {
return (1); // yes, 'nAdr' has a Bp on it
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -