📄 agdi.cpp
字号:
#include "stdafx.h"
#include "SampTarg.h"
#define _IN_TARG_ // define if used within target
#include "Agdi.h"
#include "Bom.h"
#include "ComTyp.h"
#include "Collect.h"
#include <stdio.h>
#include "resource.h"
#include "math.h"
RgARM REGARM; // Register structure for ARM7
BYTE initflag;
BYTE bootflag;
BYTE PlayDead; // Disables the driver after comm breaks down.
BYTE RegUpToDate; // Flag: mark driver is 'dead' (disconnected)
static UC8 comm_buffer[0x1010]; // common buffer for data or opcode
UL32 CacheMode = READ_CACHE | READ_CODE_CACHE; // Initialize the Cache mode
#define DSWAP16(a) ((((a)>>8) &0xFF)|(((a)<<8)&0xFF00))
#define DSWAP32(a) ((((a)>>24)&0xFF)|(((a)>>8)&0xFF00) | (((a)<<8)&0xFF0000) | (((a)<<24)&0xFF000000))
/*
* AGDI-Data
*/
SUPP supp; // supported features
UC8 iRun; // target is currently executing
UC8 StopRun; // Flag: stop execution
UC8 GoMode;
AG_BP **pBhead;
UL32 *pCURPC;
UL32 curPC;
struct bom *pBom;
AG_BP *pBX; // used for temporary Breakpoint
UL32 abreaks; // number of code-address Bp's
UL32 cbreaks; // number of conditional Bp's
UL32 wbreaks; // number of access Bp's
UL32 SetBrkCount;
LOADPARMS lParms; // LOAD-Parameters
static const char szNBP[] = "*** AGDI-Error: can't setup break at 0x%08X\n";
UL32 Uv2Msg; // Uv2-registered Message token
pCBF pCbFunc; // call-back function of s166
extern DYMENU Menu[]; // forward
// if an extension modeless dialog is activated, then '*pHwnd' *MUST*
// receive the HWND (m_hWnd in MFC) of the dialog. If the dialog
// looses focus or is closed, then '*pHwnd' *MUST* be set to NULL.
// This is to ensure the proper message chain within Uv2.
HWND *pHwnd;
HWND hMfrm; // parent handle (CMainFrame)
HMODULE hInst; // this DLL's instance handle
extern void InitRegs (void); // forward
/*
* Memory-allocation and clustering Functions
*/
#define MCC 16
typedef struct mcu {
struct mcu *next; // Link to next Cluster
DWORD aval; // available bytes in Cluster
BYTE b[MCC]; // buffer
} MCU;
//struct menv {
// MCU *head;
// MCU *tail;
//};
static MCU *mHead;
static MCU *mTail;
/*
* Free all Memory-Clusters starting at mHead.
*/
static void FreeClusters (void) {
MCU *pMem, *pNext;
if (mHead == NULL) { // Clusters are already cleaned up.
return;
}
pMem = mHead;
for ( ; pMem ; ) {
pNext = pMem->next; // save Next
free (pMem); // free
pMem = pNext;
}
mHead = NULL;
mTail = NULL;
}
static void OutOfMem (void) {
//---TODO: out of memory occurred !
while (1);
}
/*
* Allocate memory for Segment/Attributes chunks
* Note: GetMem is intended for the big memory blocks which live
* until this DLL is shut down.
*/
static void *GetMem (DWORD many) {
MCU *tmp;
tmp = (MCU *) calloc (many + 16, sizeof (UC8));
if (tmp == NULL) { // out of memory !!!
OutOfMem(); //
}
if (!mHead) mHead = tmp;
else mTail->next = tmp;
mTail = tmp;
mTail->aval = many;
return ((void *) mTail->b); // ptr to free Memory
}
//--- Memory cache handling.
//--- Simulate the (non-existing) target memory
static struct EMM (*slots[256])[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 00 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 10 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 20 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 30 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 40 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 50 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 60 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 70 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 80 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* 90 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* A0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* B0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* C0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* D0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* E0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
/* F0 */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
/*
* Map Memory
*/
static void MapSeg (DWORD nSeg, DWORD nSof, DWORD nLen, DWORD nAtr) {
AMAP adr;
struct EMM (*s) [256];
struct EMM acc;
DWORD *pA;
DWORD n;
if (nLen == 0) return;
adr.a32 = (nSeg << 16) + nSof;
s = slots[adr.ub[3]];
if (s == NULL) { // if slot is not yet allocated
s = (struct EMM (*)[256]) GetMem (sizeof(struct EMM) * 256); // 256 ptr's EMM
slots[adr.ub[3]] = s;
}
acc = (*s)[adr.ub[2]]; // slot available?
if (acc.mem == NULL) {
acc.mem = (UC8 *) GetMem (_MSGM); // allocate memory block
acc.atr = (UL32 *) GetMem (_MSGM); // allocate corresponding attributes
// if (nAtr & ATRX_EXEC) { // profiling...
// acc.ep = ioc.GetMem (4*_MSGM); // map 256K + 16
// }
(*s)[adr.ub[2]] = acc;
}
nLen = (nLen + 3) >> 2;
pA = &acc.atr [adr.w16 >> 2];
for ( n = 0 ; n < nLen ; ++n, ++pA ) { // initialize attribs
if (nAtr == 0) { // this is 'map clear'
*pA &= ~(ATRX_READ | ATRX_WRITE | ATRX_EXEC | ATRX_NOINST | ATRX_THUMB | ATRX_ARM);
}
else {
*pA |= nAtr; // Note: can't use memset() here !
}
}
}
/*
* Invalidate memory
*/
void InvalidateMemory (void) { // clears the ATRX_UPTD attribute bit in all mapped memory areas
UL32 i, j, z;
struct EMM (*s)[256];
struct EMM acc;
RegUpToDate = 0; // invalidate Registers
for ( i = 0 ; i < 256 ; i++ ) {
s = slots[i];
if (!s) continue;
for ( j = 0 ; j < 256 ; ++j ) {
acc = (*s)[j];
if (!acc.atr) continue;
for ( z = 0 ; z < (_MSGM / sizeof (acc.atr[0])); ++z ) {
acc.atr[z] &= ~ATRX_UPTD; // clear 'valid' bit in Attributes.
}
}
}
}
/*
* Cache data or opcode
*/
void WriteToCache (UL32 Adr, UC8 *pB, UL32 nMany) { // writing opcodes and variables is idential
MAMAP x;
struct EMM (*s)[256];
struct EMM acc;
x.a32 = Adr; // requested address
for ( ; nMany != 0 ; --nMany, ++x.a32 ) {
s = slots [x.ub[3]]; // a24-a31
if (!s) {
s = (struct EMM (*)[256]) GetMem (sizeof(struct EMM) * 256); // 256 ptr's EMM
slots[x.ub[3]] = s;
}
acc = (*s)[x.ub[2]]; // slot available?
if (acc.mem == NULL) {
acc.mem = (UC8 *) GetMem (_MSGM); // allocate memory block
}
if (acc.atr == NULL) {
acc.atr = (UL32 *) GetMem (_MSGM); // allocate corresponding attributes
}
(*s)[x.ub[2]] = acc;
acc.mem[x.w16] = *pB++;
((BYTE *) acc.atr) [x.w16] |= ATRX_UPTD; // mark address content as 'valid'
}
}
/*
* Map a cache segment descriptor.
*/
UL32 MMapMem (UL32 nAtr, UL32 nAdr, UL32 nLen) {
DWORD nSof, nSeg;
nSeg = nAdr >> 16; // Start-Segment
nSof = nAdr & 0xFFFF;
while ((nSof + nLen) > 0x10000) {
MapSeg (nSeg, nSof, 0x10000 - nSof, nAtr);
++nSeg;
nLen -= (0x10000 - nSof);
nSof = 0;
}
if (nLen != 0) {
MapSeg (nSeg, nSof, nLen, nAtr); // Segments are never > than 64K !
}
return (0);
}
/*
* Get Pointer to Attributes for addresss 'nAdr'
*/
UL32 *MGetAttr (UL32 nAdr) {
MAMAP adr;
struct EMM (*s) [256];
struct EMM acc;
DWORD *pA;
pA = NULL;
adr.a32 = nAdr;
s = slots [adr.ub[3]]; // a24-a31
if (s) {
acc = (*s) [adr.ub[2]];
if (acc.atr) {
pA = &acc.atr [adr.w16 >> 2]; // attributes for 'nAdr'
}
}
return (pA);
}
/*
* free any allocated memory before driver shutdown.
*/
static void FreeCache (void) {
//---TODO: free memory resources, if any
FreeClusters(); // free our Memory-Cluster chain.
memset (slots, 0, sizeof (slots));
}
static void InitCache (void) {
mHead = NULL;
mTail = NULL;
memset (slots, 0, sizeof (slots));
}
//--- End of c/i-chache
/*
* Output a message line into uVision2's command window
*/
void txtout (char *fmt, ...) {
va_list marker;
char txtbuf [2048];
va_start (marker, fmt);
vsprintf (&txtbuf[0], fmt, marker);
SendMessage (hMfrm, Uv2Msg, MSG_UV2_CMDLINE, (LPARAM) &txtbuf[0]);
}
/*
* Show target setup dialog
*/
static void ConfDisp (DYMENU *pM) {
struct MonConf oCnf;
int i;
pM;
oCnf = MonConf; // save current setup
i = DoDlgSetup(); // start setup dialog
if (i == IDOK) {
if (memcmp (&MonConf, &oCnf, sizeof (oCnf)) != 0) { // configuration has changed
i = MessageBox (hMfrm,"Configuration has been changed, take new values ?",
"Target Monitor Notification",
MB_OKCANCEL | MB_ICONWARNING);
if (i == IDCANCEL) {
MonConf = oCnf; // restore previous configuration
}
if (i == IDOK) { // take new configuration
if (ReInitTarget()) { // failed...
StopTarget(); // final shutdown
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
}
}
}
else { // cancelled: restore previous config
MonConf = oCnf;
}
}
/*
* Extension Menues and Dialogs
*/
//--- this relates to TestDlg.cpp: ------------
extern void MdUpdate (void); // Dialog Update function
extern void MdKill (DIAD *pM); // Dialog Kill function
extern void MdShow (DYMENU *pM); // Show/Hide modeless Dialog
DIAD ModDlg = { 0, NULL, NULL, { -1,-1,-1,-1, }, MdUpdate, MdKill };
//---------------------------------------------
static DYMENU Menu[] = {
{ 1, "Target Settings", ConfDisp, 0, 0, }, // modal dialog
{ 1, "Modeless Dialog", MdShow, 0, 0, &ModDlg }, // modeless dialog
{ -1, /* End of menu list */ },
};
/*
* uVision2 want's to update all modeless dialogs.
*/
void DlgUpdate (void) { // Update all modeless extension dialogs
DYMENU *pM;
pM = &Menu[0];
while (pM->nDelim != -1) { // while not end of Menu-list
if (pM->pDlg && pM->pDlg->Update) { // if dialog has been created
pM->pDlg->Update(); // then call it's update function
}
++pM; // next menu entry.
}
}
/*
* Need to close all currently open modeless dialogs
*/
void CloseAllDlg (void) {
DYMENU *pM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -