📄 agdi.cpp
字号:
*/
int InitDevFlash (void)
{
int nE;
//---We use 'EnterProgMode()' function to activate the programming mode of the device
//---when a special procedure to activate the programming mode is required.
//---If this is not required, we can skip this function.
nE = EnterProgMode ();
if (nE) {
PgmError ("Programming failed. Device in programming socket does not response.");
return (1); // failed
}
//---We use 'CheckDevID()' function to verify if right target device is attached.
//---If this is not required, we can skip this function.
nE = CheckDevID ();
if (nE) {
PgmError ("Programming failed. This device is not supported");
return (1); // failed
}
if (!(MonConf.Opt & FLASH_ERASE)) { // check if Download Function-Erase Flash enabled
return (0);
}
//---We erase the target flash here and prepare for flash writing.
nE = EraseFlash ();
if (nE) {
PgmError ("Flash Erase failed.");
return (1); // failed Flash not Erased
}
txtout ("Flash Erase Done.\n");
return (0); // Ok.
}
/*
* Write data for Flash Memory to Target
*
* If target hardware has installed SRAM that is big enough to hold the
* complete Flash image data, it is a good practice to use it as a buffer.
* This would speedup the flash verify process a lot if a big flash with
* big amount of data is programmed using 'slow RS232' interface.
*/
int FlashLoad (void) {
FLASHPARM *pF;
DWORD bCnt,errAdr;
char szMsg[80];
int nE = 0;
if (!(MonConf.Opt & FLASH_PROGRAM)) goto skipProg;
//---Write Flash memory if enabled
InitProgress("Loading...");
//---Get Flash Parameters from S8051.DLL
pF = (FLASHPARM *)pCbFunc (AG_CB_GETFLASHPARAM, NULL);
bCnt = 0;
while (pF->many != 0) { // while more chunks..
nE = WriteToFlash (pF->start, pF->image, pF->many, &errAdr);
if (nE) { // failed, send message
sprintf (szMsg,"Flash Write Failed at %04X", errAdr);
PgmError (szMsg);
goto x;
}
bCnt += pF->many;
SetProgress (bCnt*100/pF->ActSize);
pF = (FLASHPARM *)pCbFunc (AG_CB_GETFLASHPARAM, pF);// Get next parameters
}
SetProgress (100);
txtout ("Flash Write Done: %d bytes programmed.\n", bCnt);
StopProgress ();
skipProg:
if (!(MonConf.Opt & FLASH_VERIFY)) goto x;
//---Verify Flash memory if enabled
InitProgress("Verifying...");
//---Get Flash Parameters from S8051.DLL
pF = (FLASHPARM *)pCbFunc (AG_CB_GETFLASHPARAM, NULL);
bCnt = 0;
while (pF->many != 0) { // while more chunks..
nE = VerifyFlash (pF->start, pF->image, pF->many, &errAdr);
if (nE) { // failed, send message
sprintf (szMsg,"Flash Verify Failed at %04X", errAdr);
PgmError (szMsg);
goto x;
}
bCnt += pF->many;
SetProgress (bCnt*100/pF->ActSize);
pF = (FLASHPARM *)pCbFunc (AG_CB_GETFLASHPARAM, pF);// Get next parameters
}
SetProgress (100);
txtout ("Flash Verify Done: %d bytes verified.\n", bCnt);
x:StopProgress ();
ExitProgrammer ();
return (nE);
}
/*
*----------- AGDI Basic Functions -----------------
*/
/*
* AGDI-Init Function
*/
U32 _EXPO_ AG_Init (U16 nCode, void *vp) {
U32 nE;
nE = 0;
switch (nCode & 0xFF00) {
case AG_INITFEATURES: // Initialize & start the target
PlayDead = 0; // clear some variables...
//---We don't have special features here, so all variables are cleared.
//---uVision2 will query these features lateron.
//---Note: the 'supp' structure is defined in 'AGDI.H'
supp.MemAccR = 0; // memory-access while running
supp.RegAccR = 0; // register-access while running
supp.hTrace = 0; // trace support
supp.hCover = 0; // code coverage support
supp.hPaLyze = 0; // Performance-Analyzer support
supp.hMemMap = 0; // Memory-Map support
supp.ResetR = 0; // Reset while running support
//---Note: if InitTarget() fails, then set nE=1, else nE=0.
// if 1 is returned, then uVision will cancel using this driver
FlashProg = 0;
InitMem(); // init Cache memory
bootflag = 1;
nE = InitTarget(); // Initialize your target...
bootflag = 0;
if (nE == 0) { // initialization was Ok.
InitRegs(); // define register layout for RegWindow
}
if (nE == 0) { // everything is ok so far
pCbFunc (AG_CB_EXECCMD, "U $\n"); // force disassemble @curPC
}
NumRecs = 0; // clear 'number of trace records'
break;
case AG_INITITEM: // init item
switch (nCode & 0x00FF) {
case AG_INITMENU: // init extension menu
*((DYMENU **) vp) = (DYMENU *) Menu;
break;
case AG_INITEXTDLGUPD: // init modeless extesion dlg update function
*((UC8 **) vp) = (UC8 *) DlgUpdate;
break;
case AG_INITMHANDLEP: // setup ptr to HWND of active modeless dlg
pHwnd = (HWND *) vp;
break;
case AG_INITPHANDLEP: // pointer to parent handle (MainFrame)
hMfrm = (HWND) vp;
break;
case AG_INITINSTHANDLE: // pointer to Agdi-instance handle
hInst = (HMODULE) vp;
break;
case AG_INITBPHEAD: // pointer to head of Bp-List
pBhead = (AG_BP **) vp;
break;
case AG_INITCURPC: // pointer to program counter
pCURPC = (UL32 *) vp;
break;
case AG_INITDOEVENTS: // DoEvents function pointer
//--- this is no longer relevant due to uVision's threading.
break;
case AG_INITUSRMSG: // Registered Message for SendMessage
Uv2Msg = (DWORD) vp; // (Serial-Window, TextOut messages)
break;
case AG_INITCALLBACK: // pointer to callback function
pCbFunc = (pCBF) vp; // call-back function of s166
break;
case AG_INITFLASHLOAD: // Prepare for Flash Download
nE = InitProgrammer ();
if (nE) break;
nE = InitDevFlash (); // Initialize Flash, Erase
break;
case AG_STARTFLASHLOAD: // S8051 says 'Ready for Flash DownLoad'
nE = FlashLoad(); // Flash-Download, write, verify
break;
}
break;
case AG_GETFEATURE: // uVision2 want's details about features...
switch (nCode & 0x00FF) {
case AG_F_MEMACCR: nE = supp.MemAccR; break;
case AG_F_REGACCR: nE = supp.RegAccR; break;
case AG_F_TRACE: nE = supp.hTrace; break;
case AG_F_COVERAGE: nE = supp.hCover; break;
case AG_F_PALYZE: nE = supp.hPaLyze; break;
case AG_F_MEMMAP: nE = supp.hMemMap; break;
case AG_F_RESETR: nE = supp.ResetR; break;
}
break;
case AG_EXECITEM: // execute various commands
switch (nCode & 0x00FF) {
case AG_UNINIT: // Clean up target system settings
ExitProgrammer (); // Stop Programmer
PlayDead = 1; // mark target as disconnected.
CloseAllDlg(); // close all open dialogs
StopTarget(); // shutdown target & communication
WriteMonParms (pdbg->TargArgs); // update argument string
break;
case AG_RESET: // perform a reset on the target system
if (PlayDead || hMfrm == NULL) break; // target is disconnected
ResetTarget(); // reset the target
pCbFunc (AG_CB_EXECCMD, "U $\n"); // dasm $
NumRecs = 0; // clear 'number of trace records'
break;
}
break;
}
if (PlayDead) { // driver is disconnected
StopTarget(); // shut down driver
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0); // unload this driver
}
return (nE);
}
/*
* Memory Interface functions
*/
static DWORD ReadMem (DWORD nAdr, BYTE *pB, DWORD nMany) {
DWORD n1, n, ErrAdr;
DWORD nA, nM;
BYTE *p1;
nA = nAdr; // save values for caching...
p1 = pB;
nM = nMany;
while (nMany != 0) {
n = (nMany > 256) ? 256 : nMany;
nMany -= n;
switch (nAdr >> 24) { // extract mSpace from address.
case amDATA:
if ((nAdr & 0xFF) >= 0x80) { // Sfr-area: D:0x80...D:0xFF
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = ReadSFR (pB, nAdr & 0xFF0000FF, n1);
}
else { // Data-area: D:0x00...D:0x7F
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = ReadData (pB, nAdr & 0xFF0000FF, n1);
}
break;
case amIDATA: // Idata
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = ReadIdata (pB, nAdr & 0xFF0000FF, n1);
break;
case amXDATA: // Xdata
case amPDATA:
ErrAdr = ReadXdata (pB, nAdr, n);
break;
// case amCODE: // Code
default: // anything else assumed to be c-address
ErrAdr = ReadCode (pB, nAdr, n);
break;
}
pB += n;
nAdr += n;
}
return (ErrAdr);
}
static DWORD WriteMem (DWORD nAdr, BYTE *pB, DWORD nMany) {
DWORD n1, n, ErrAdr;
BYTE *p1;
DWORD nA, nM;
nA = nAdr; // save values for caching...
p1 = pB;
nM = nMany;
n = nAdr >> 24;
if (n == amDATA || n == amIDATA) { // write to data/idata
if ((nAdr & 0xFF) < 0x20) { // register bank area
RegUpToDate = 0; // regs might be written...
}
}
while (nMany != 0) {
n = (nMany > 256) ? 256 : nMany;
nMany -= n;
switch (nAdr >> 24) {
case amDATA:
if ((nAdr & 0xFF) >= 0x80) {
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = WriteSFR (pB, nAdr & 0xFF0000FF, n1);
}
else {
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = WriteData (pB, nAdr & 0xFF0000FF, n1);
}
break;
case amIDATA:
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = WriteIdata (pB, nAdr & 0xFF0000FF, n1);
break;
// case amCODE:
default:
ErrAdr = WriteCode (pB, nAdr, n);
break;
}
pB += n;
nAdr += n;
}
if (ErrAdr == 0) { // write was Ok.
CacheData (p1, nA, nM); // put write data into cache
}
else { // write failed...
ClearCaR (nA, nM); // invalidate cache range
}
return (ErrAdr);
}
/*
* Access target memory
*/
U32 _EXPO_ AG_MemAcc (U16 nCode, UC8 *pB, GADR *pA, UL32 nMany) {
U16 nErr;
UL32 nA;
if (iRun && !supp.MemAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) { // driver disconnected.
return (AG_NOACCESS);
}
nErr = 0;
if (hMfrm == NULL) return (nErr);
nA = pA->Adr;
switch (nCode) {
case AG_READ: // need 'read' permission
pA->ErrAdr = ReadMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_RDFAILED;
break;
case AG_WRITE: // need 'write' permission
pA->ErrAdr = WriteMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_WRFAILED;
break;
// used for Program download
case AG_WROPC: // need 'Read/Execute' permissions
nA |= (amCODE << 24);
pA->ErrAdr = WriteMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_WRFAILED;
break;
// used for disassembly etc.
case AG_RDOPC: // need 'Read/Execute' permissions
nA |= (amCODE << 24);
pA->ErrAdr = ReadMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_RDFAILED;
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) { // disconnected...
StopTarget(); // shut down driver
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Read/Write Registers
*/
U32 _EXPO_ AG_AllReg (U16 nCode, void *vp) {
U16 nErr;
if (iRun && !supp.RegAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return (AG_NOACCESS);
nErr = 0;
switch (nCode) { // which Opcode
case AG_READ: // read register
GetRegs();
break;
case AG_WRITE:
SetRegs (®51); // write Regs + PC
RegUpToDate = 1; // mark regs as 'up to date'
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) {
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Read/Write a single Register
*/
U32 _EXPO_ AG_RegAcc (U16 nCode, U32 nReg, GVAL *pV) {
U16 nErr;
if (iRun && !supp.RegAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return (AG_NOACCESS); // driver is disconnected.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -