diff options
author | Attila Veghelyi <aveghelyi@dension.com> | 2023-06-29 16:24:54 +0200 |
---|---|---|
committer | Attila Veghelyi <aveghelyi@dension.com> | 2023-06-29 16:24:54 +0200 |
commit | 925d0670c45e1100e412070fa0ce2405604f219a (patch) | |
tree | 9bb4412d148bc80751b7a02023cd3e0167f588e7 /icd.c | |
download | OpenProgrammer-925d0670c45e1100e412070fa0ce2405604f219a.tar.gz OpenProgrammer-925d0670c45e1100e412070fa0ce2405604f219a.zip |
Init repo
Diffstat (limited to 'icd.c')
-rw-r--r-- | icd.c | 1541 |
1 files changed, 1541 insertions, 0 deletions
@@ -0,0 +1,1541 @@ +//General routines to communicate via ICD with a target +#include "common.h" +#include "coff.h" + +extern int saveLog; +extern double Tcom; +extern int running; +extern int DeviceDetected; +extern GtkWidget * b_log; +extern char* cur_path; + +GtkWidget * statusTxt; +GtkWidget * sourceTxt; +GtkTextBuffer * sourceBuf; +GtkWidget * icdVbox1; +GtkWidget * icdMenuPC; +GtkWidget * icdMenuSTAT; +GtkWidget * icdMenuBank0; +GtkWidget * icdMenuBank1; +GtkWidget * icdMenuBank2; +GtkWidget * icdMenuBank3; +GtkWidget * icdMenuEE; +GtkWidget * icdCommand; +GtkTextBuffer * statusBuf; +int icdTimer=0; +int break_addr,print_addr; +int currentSource=-1; +int sourceHilight=0; +char lastCmd[64]=""; +int UseCoff=0; +struct src_i source_info[LMAX]; +struct srcfile *s_files; +struct symbol *sym; +int nsym=0; +char* Slabel[LMAX],*Sulabel[ULMAX]; +struct symbol *watch; +int nwatch=0; +unsigned short coff_data[DATA_MAX]; +int ver=0,reset=1,freeze=0,icdConnected=0,running=0; +#define Tck 30 +double Tcom=0.001*Tck*18+0.03; //communication time for a 16 bit tranfer (ms) + +void ShowContext(); + +//The following commands are implemented in the debugger monitor +//routine which is written in the last memory page on the target chip. +#define VER 1 //;version +#define STEP 2 //;step +#define GO 3 //;go +#define RREG 4 //;read register +#define WREG 5 //;write register +#define EEADR 0x10D +#define EEADRH 0x10F +#define EEDATA 0x10C +#define EEDATH 0x10E +#define EECON1 0x18C +#define EECON2 0x18D +#define w_temp 0x6B +#define status_temp 0x6C +#define pclath_temp 0x6D +#define fsr_temp 0x6E + +struct var{ char* name; int display;} variables[0x200]; + +//Prepare ICD interface by resetting the target with a power-up sequence. +//MCLR is low so the target is reset even if power is not supplied by the programmer. +//Set communication speed at 1/(2*Tck us) +void startICD(int tck){ + int j=0; + bufferU[j++]=PROG_RST; + bufferU[j++]=SET_PARAMETER; + bufferU[j++]=SET_T1T2; + bufferU[j++]=tck; //T1=XXu + bufferU[j++]=100; //T2=100u + bufferU[j++]=SET_PARAMETER; + bufferU[j++]=SET_T3; //2ms + bufferU[j++]=2000>>8; + bufferU[j++]=2000&0xff; + bufferU[j++]=VREG_DIS; //disable HV regulator + bufferU[j++]=EN_VPP_VCC; // reset target + bufferU[j++]=0x0; + bufferU[j++]=WAIT_T3; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=EN_VPP_VCC; // power-up + bufferU[j++]=0x1; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(3); + if(saveLog){ + fprintf(logfile,"startICD()\n"); + } +} + +//Check whether the target is running or is executing the debug routine. +//This is signaled by RB7 (Data): D=1 -> debugger monitor running +int isRunning(){ + int z,j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x0; //D=0 + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=READ_PINS; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + if(saveLog){ + fprintf(logfile,"isRunning()\n"); + } + for(z=0;z<DIMBUF-1&&bufferI[z]!=READ_PINS;z++); + if(bufferI[z+1]&1) running=0; + else running=1; + return running; +} + +//Set the next breakpoint address, the freeze bit, +//and continue execution. +//This is necessary because at every break +//the ICD register is loaded with the last address. +void cont(int break_addr, int freeze){ + int j=0; + //set breakpoint and freeze + break_addr&=0x1FFF; + bufferU[j++]=TX16; + bufferU[j++]=0x2; + bufferU[j++]=WREG; //write register + bufferU[j++]=(break_addr>>8)+(freeze?0x40:0); + bufferU[j++]=0x1; + bufferU[j++]=0x8E; + bufferU[j++]=TX16; + bufferU[j++]=0x2; + bufferU[j++]=WREG; //write register + bufferU[j++]=break_addr&0xFF; + bufferU[j++]=0x1; + bufferU[j++]=0x8F; + bufferU[j++]=TX16; + bufferU[j++]=0x1; + bufferU[j++]=GO; //GO + bufferU[j++]=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+5*Tcom); + if(saveLog){ + fprintf(logfile,"continue()\n"); + } + running=1; +} + +//Execute a single step +void step(){ + int j=0; + bufferU[j++]=TX16; + bufferU[j++]=0x1; + bufferU[j++]=STEP; //single step + bufferU[j++]=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+Tcom); + if(saveLog){ + fprintf(logfile,"step()\n"); + } +} + +//Remove reset so that the target can start executing its code. +void run(){ + int j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; + bufferU[j++]=EN_VPP_VCC; //MCLR=H + bufferU[j++]=0x5; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + if(saveLog){ + fprintf(logfile,"run()\n"); + } + running=1; +} + +//Get the debugger monitor version +int version(){ + int j=0,z; + bufferU[j++]=TX16; + bufferU[j++]=0x1; + bufferU[j++]=VER; //version + bufferU[j++]=0; + bufferU[j++]=RX16; + bufferU[j++]=0x1; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+2*Tcom); + if(saveLog){ + fprintf(logfile,"version()\n"); + } + for(z=0;z<DIMBUF-2&&bufferI[z]!=RX16;z++); + return bufferI[z+3]; +} + +//Halt execution by setting RB6 (Clock) low +void Halt(){ + int j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x6; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + if(saveLog){ + fprintf(logfile,"halt()\n"); + } + running=0; + //printf("halted\n"); +} + +//Read register at address addr +int ReadRegister(int addr){ + int j=0,z; + bufferU[j++]=TX16; + bufferU[j++]=0x2; + bufferU[j++]=RREG; //Read register + bufferU[j++]=0x1; //1 byte + bufferU[j++]=(addr>>8)&0xFF; + bufferU[j++]=addr&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=0x1; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+3*Tcom); + if(saveLog){ + fprintf(logfile,"ReadRegister(0x%X)\n",addr); + } + for(z=0;z<DIMBUF-2&&bufferI[z]!=RX16;z++); + return bufferI[z+3]; +} + +//Read n registers starting at address addr +int ReadRegisterN(int addr,int n,int* buf){ + int i,j=0,z,w; + for(i=0;i<n;i+=w){ + w=i+(DIMBUF-9)/2<n?(DIMBUF-9)/2:n-i; + bufferU[j++]=TX16; + bufferU[j++]=0x2; + bufferU[j++]=RREG; //Read register + bufferU[j++]=w; + bufferU[j++]=(addr+i)>>8; + bufferU[j++]=(addr+i)&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=w; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+(w+2)*Tcom); + if(saveLog){ + fprintf(logfile,"ReadRegisterN(0x%X,%d)\n",addr,n); + } + for(z=0;z<DIMBUF-2&&bufferI[z]!=RX16;z++); + for(j=0;j<w;j++) buf[i+j]=bufferI[z+3+j*2]; + j=0; + } + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + return i==n?0:-1; +} + +//Write data at address addr +void WriteRegister(int addr,int data){ + int j=0; + bufferU[j++]=TX16; + bufferU[j++]=0x2; + bufferU[j++]=WREG; //write register + bufferU[j++]=data&0xFF; + bufferU[j++]=(addr>>8)&0xFF; + bufferU[j++]=addr&0xFF; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+2*Tcom); + if(saveLog){ + fprintf(logfile,"WriteRegister(0x%X,0x%X)\n",addr,data); + } +} + +//Read program memory at address addr +int ReadProgMem(int addr){ + int addr_temp, data_temp, eecon_temp,data; + addr_temp=(ReadRegister(EEADRH)<<8)+ReadRegister(EEADR); + data_temp=(ReadRegister(EEDATH)<<8)+ReadRegister(EEDATA); + eecon_temp=ReadRegister(EECON1); + WriteRegister(EEADRH,addr>>8); + WriteRegister(EEADR,addr&0xFF); + WriteRegister(EECON1,eecon_temp|0x80); //EEPGD=1 + WriteRegister(EECON1,eecon_temp|0x81); //EEPGD=1 + RD=1 + data=(ReadRegister(EEDATH)<<8)+ReadRegister(EEDATA); + WriteRegister(EEADRH,addr_temp<<8); + WriteRegister(EEADR,addr_temp&0xFF); + WriteRegister(EEDATH,data_temp<<8); + WriteRegister(EEDATA,data_temp&0xFF); + WriteRegister(EECON1,eecon_temp); + return data; +} + +//Read program memory (n locations) starting at address addr +int ReadProgMemN(int addr,int n,int* buf){ + int addr_temp, data_temp, eecon_temp; + if(saveLog) fprintf(logfile,"ReadProgMemN(0x%X,%d)\n",addr,n); + int i,j=0,z,w,k; + bufferU[j++]=TX16; + bufferU[j++]=2; + bufferU[j++]=RREG; //Read register + bufferU[j++]=4; //4 bytes: EEDATA,EEADR,EEDATH,EEADRH + bufferU[j++]=(EEDATA>>8)&0xFF; + bufferU[j++]=EEDATA&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=4; + bufferU[j++]=TX16; + bufferU[j++]=2; + bufferU[j++]=RREG; //Read register + bufferU[j++]=1; //1 byte + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=1; + bufferU[j++]=TX16; + bufferU[j++]=2; + bufferU[j++]=WREG; //write register + bufferU[j++]=0x80; //EEPGD=1 + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+13*Tcom); + j=0; + for(z=0;z<DIMBUF-5&&bufferI[z]!=RX16;z++); + data_temp=bufferI[z+3]+(bufferI[z+7]<<8); + addr_temp=bufferI[z+5]+(bufferI[z+9]<<8); + for(z+=10;z<DIMBUF-3&&bufferI[z]!=RX16;z++); + eecon_temp=bufferI[z+3]; + w=k=0; + for(i=0;i<n;i++){ + bufferU[j++]=TX16; + bufferU[j++]=8; + bufferU[j++]=WREG; //write register + bufferU[j++]=(addr+i)&0xFF; + bufferU[j++]=(EEADR>>8)&0xFF; + bufferU[j++]=EEADR&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=((addr+i)>>8)&0xFF; + bufferU[j++]=(EEADRH>>8)&0xFF; + bufferU[j++]=EEADRH&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=0x81; //RD=1 + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=RREG; //Read register + bufferU[j++]=3; //3 bytes: EEDATA,EEADR,EEDATH + bufferU[j++]=(EEDATA>>8)&0xFF; + bufferU[j++]=EEDATA&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=3; + w++; + if(j>DIMBUF-21||i==n-1){ + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2+13*Tcom*w); + j=0; + w=0; + for(z=0;z<DIMBUF-5;z++){ + if(bufferI[z]==RX16){ + buf[k++]=bufferI[z+3]+(bufferI[z+7]<<8); + z+=8; //******controllare!!********** + } + } + } + } + bufferU[j++]=TX16; + bufferU[j++]=10; + bufferU[j++]=WREG; //write register + bufferU[j++]=eecon_temp; //EEPGD=1 + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=data_temp&0xFF; + bufferU[j++]=(EEDATA>>8)&0xFF; + bufferU[j++]=EEDATA&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=data_temp>>8; + bufferU[j++]=(EEDATH>>8)&0xFF; + bufferU[j++]=EEDATH&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=addr_temp&0xFF; + bufferU[j++]=(EEADR>>8)&0xFF; + bufferU[j++]=EEADR&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=addr_temp>>8; + bufferU[j++]=(EEADRH>>8)&0xFF; + bufferU[j++]=EEADRH&0xFF; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+10*Tcom); + return i; +} + +//Read data memory at address addr +int ReadDataMem(int addr){ + int addr_temp, data_temp, eecon_temp,data; + addr_temp=ReadRegister(EEADR); + data_temp=ReadRegister(EEDATA); + eecon_temp=ReadRegister(EECON1); + WriteRegister(EEADR,addr); + WriteRegister(EECON1,eecon_temp&0x7F); //EEPGD=0 + WriteRegister(EECON1,(eecon_temp&0x7F)|0x1); //EEPGD=0 + RD=1 + data=ReadRegister(EEDATA); + WriteRegister(EEADR,addr_temp); + WriteRegister(EEDATA,data_temp); + WriteRegister(EECON1,eecon_temp); + return data; +} + +//Read n bytes from data memory starting at address addr +int ReadDataMemN(int addr,int n,unsigned char* buf){ + int addr_temp, data_temp, eecon_temp; + if(saveLog) fprintf(logfile,"ReadDataMemN(0x%X,%d)\n",addr,n); + int i,j=0,z,w,k; + bufferU[j++]=TX16; + bufferU[j++]=2; + bufferU[j++]=RREG; //Read register + bufferU[j++]=2; //2 bytes: EEDATA,EEADR + bufferU[j++]=(EEDATA>>8)&0xFF; + bufferU[j++]=EEDATA&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=2; + bufferU[j++]=TX16; + bufferU[j++]=2; + bufferU[j++]=RREG; //Read register + bufferU[j++]=1; //1 byte + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=1; + bufferU[j++]=TX16; + bufferU[j++]=2; + bufferU[j++]=WREG; //write register + bufferU[j++]=0; //EEPGD=0 + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+13*Tcom); + j=0; + for(z=0;z<DIMBUF-5&&bufferI[z]!=RX16;z++); + data_temp=bufferI[z+3]; + addr_temp=bufferI[z+5]; + for(z+=6;z<DIMBUF-3&&bufferI[z]!=RX16;z++); + eecon_temp=bufferI[z+3]; + w=k=0; + for(i=0;i<n;i++){ + bufferU[j++]=TX16; + bufferU[j++]=6; + bufferU[j++]=WREG; //write register + bufferU[j++]=(addr+i)&0xFF; + bufferU[j++]=(EEADR>>8)&0xFF; + bufferU[j++]=EEADR&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=0x1; //RD=1 + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=RREG; //Read register + bufferU[j++]=1; // EEDATA + bufferU[j++]=(EEDATA>>8)&0xFF; + bufferU[j++]=EEDATA&0xFF; + bufferU[j++]=RX16; + bufferU[j++]=1; + w++; + if(j>DIMBUF-17||i==n-1){ + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2+10*Tcom*w); + j=0; + w=0; + for(z=0;z<DIMBUF-5;z++){ + if(bufferI[z]==RX16){ + buf[k++]=bufferI[z+3]; + z+=4; + } + } + } + } + bufferU[j++]=TX16; + bufferU[j++]=6; + bufferU[j++]=WREG; //write register + bufferU[j++]=eecon_temp; //EEPGD=1 + bufferU[j++]=(EECON1>>8)&0xFF; + bufferU[j++]=EECON1&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=data_temp&0xFF; + bufferU[j++]=(EEDATA>>8)&0xFF; + bufferU[j++]=EEDATA&0xFF; + bufferU[j++]=WREG; //write register + bufferU[j++]=addr_temp&0xFF; + bufferU[j++]=(EEADR>>8)&0xFF; + bufferU[j++]=EEADR&0xFF; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(1+10*Tcom); + return i; +} + +// get register name from list +char* getVar(int addr,char *var){ + addr&=0x1FF; + if(variables[addr].name) strcpy(var,variables[addr].name); + else sprintf(var,"0x%03X",addr); + return var; +} + +//Disassemble a command and return string +//addrH is the higher (bank) address for memory (RP1-RP0) +char* decodeCmd(int cmd,char *str, int addrH){ + char ins[32],reg[32]; + if((cmd&0x3F9F)==0) sprintf(str,"nop"); + else if(cmd==0x0001) sprintf(str,"reset"); + else if(cmd==0x0008) sprintf(str,"return"); + else if(cmd==0x0009) sprintf(str,"retfie"); + else if(cmd==0x000A) sprintf(str,"callw"); + else if(cmd==0x000B) sprintf(str,"brw"); + else if(cmd==0x0062) sprintf(str,"option"); + else if(cmd==0x0063) sprintf(str,"sleep"); + else if(cmd==0x0064) sprintf(str,"clrwdt"); + else if(cmd==0x0065) sprintf(str,"trisa"); + else if(cmd==0x0066) sprintf(str,"trisb"); + else if(cmd==0x0067) sprintf(str,"trisc"); + else if((cmd>>12)==0){ //byte oriented instructions + if((cmd>>8)==0&&cmd&0x80) sprintf(str,"movwf %s",getVar(addrH+(cmd&0x7F),reg)); + else if((cmd>>8)==1){ + if(cmd&0x80) sprintf(str,"clrf %s",getVar(addrH+(cmd&0x7F),reg)); + else sprintf(str,"clrf w"); + } + else{ + switch(cmd>>8){ + case 2: + sprintf(ins,"subwf"); + break; + case 3: + sprintf(ins,"decf"); + break; + case 4: + sprintf(ins,"iorwf"); + break; + case 5: + sprintf(ins,"andwf"); + break; + case 6: + sprintf(ins,"xorwf"); + break; + case 7: + sprintf(ins,"addwf"); + break; + case 8: + sprintf(ins,"movf"); + break; + case 9: + sprintf(ins,"comf"); + break; + case 10: + sprintf(ins,"incf"); + break; + case 11: + sprintf(ins,"decfsz"); + break; + case 12: + sprintf(ins,"rrf"); + break; + case 13: + sprintf(ins,"rlf"); + break; + case 14: + sprintf(ins,"swapf"); + break; + case 15: + sprintf(ins,"incfsz"); + break; + default: + sprintf(ins,"???"); + break; + } + sprintf(str,"%s %s,%c",ins,getVar(addrH+(cmd&0x7F),reg),cmd&0x80?'f':'w'); + } + } + else if((cmd>>12)==1){ //bit oriented instructions + switch(cmd>>10){ + case 4: + sprintf(ins,"bcf"); + break; + case 5: + sprintf(ins,"bsf"); + break; + case 6: + sprintf(ins,"btfsc"); + break; + case 7: + sprintf(ins,"btfss"); + break; + default: + sprintf(ins,"??"); //(not possible) + } + sprintf(str,"%s %s,%d",ins,getVar(addrH+(cmd&0x7F),reg),(cmd&0x380)>>7); + } + else if((cmd>>12)==2) sprintf(str,"%s 0x%X",cmd&0x800?"goto":"call",cmd&0x7FF); + else if((cmd>>10)==0xC) sprintf(str,"movlw 0x%X",cmd&0xFF); + else if((cmd>>10)==0xD) sprintf(str,"retlw 0x%X",cmd&0xFF); + else if((cmd>>9)==0x1E) sprintf(str,"sublw 0x%X",cmd&0xFF); + else if((cmd>>9)==0x1F) sprintf(str,"addlw 0x%X",cmd&0xFF); + else if((cmd>>8)==0x38) sprintf(str,"iorlw 0x%X",cmd&0xFF); + else if((cmd>>8)==0x39) sprintf(str,"andlw 0x%X",cmd&0xFF); + else if((cmd>>8)==0x3A) sprintf(str,"xorlw 0x%X",cmd&0xFF); + else sprintf(str,"unknown command"); + return str; +} + +//Functions tied to GUI: +/// +///Print a message on the ICD data field +void PrintMessageICD(const char *msg){ + GtkTextIter iter; + gtk_text_buffer_set_text(statusBuf,msg,-1); + gtk_text_buffer_get_start_iter(statusBuf,&iter); + gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(statusTxt),&iter,0.0,FALSE,0,0); + while (gtk_events_pending ()) gtk_main_iteration(); +} +/// +///Append a message on the ICD data field +void AppendMessageICD(const char *msg){ + GtkTextIter iter; + gtk_text_buffer_get_end_iter(statusBuf,&iter); + gtk_text_buffer_insert(statusBuf,&iter,msg,-1); + gtk_text_buffer_get_start_iter(statusBuf,&iter); + gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(statusTxt),&iter,0.0,FALSE,0,0); + while (gtk_events_pending ()) gtk_main_iteration(); +} +/// +///Scroll source file +void scrollToLine(int line) +{ + GtkTextIter iter,iter2; + gtk_text_buffer_get_end_iter(sourceBuf,&iter); + if(line>0){ + gtk_text_iter_set_line(&iter,line-1); + iter2=iter; + gtk_text_iter_forward_char(&iter2); + gtk_text_iter_forward_to_line_end(&iter2); + } + else{ + gtk_text_buffer_get_selection_bounds(sourceBuf,&iter,&iter2); + iter2=iter; + } + gtk_text_buffer_select_range(sourceBuf,&iter,&iter2); + while (gtk_events_pending ()) gtk_main_iteration(); + gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(sourceTxt),&iter,0.0,TRUE,0,0.5); +} +/// +///Hilight line in source code +void SourceHilightLine(int line) +{ + GtkTextIter iter,iter2; + GtkTextTag* tag; + if(line>0){ + tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(sourceBuf),"break_text"); + if(!tag) tag=gtk_text_buffer_create_tag(sourceBuf,"break_text","background","red", NULL); + gtk_text_buffer_get_end_iter(sourceBuf,&iter); + gtk_text_iter_set_line(&iter,line-1); + iter2=iter; + gtk_text_iter_forward_char(&iter2); + gtk_text_iter_forward_to_line_end(&iter2); + gtk_text_buffer_apply_tag (sourceBuf,tag,&iter,&iter2); + } + while (gtk_events_pending ()) gtk_main_iteration(); +} +/// +///Remove hilight line in source code +void SourceRemoveHilightLine(int line) +{ + GtkTextIter iter,iter2; + if(line>0){ + gtk_text_buffer_get_end_iter(sourceBuf,&iter); + gtk_text_iter_set_line(&iter,line-1); + iter2=iter; + gtk_text_iter_forward_char(&iter2); + gtk_text_iter_forward_to_line_end(&iter2); + gtk_text_buffer_remove_tag_by_name(sourceBuf,"break_text",&iter,&iter2); + } + while (gtk_events_pending ()) gtk_main_iteration(); +} +/// +///load source file into source pane +int loadSource(FILE *f){ + if(!f) return 0; + fseek(f,0,SEEK_END); + int size=ftell(f); + fseek(f,0,SEEK_SET); + char* tmp=(char*)malloc(size+1); + size=fread(tmp,1,size,f); + tmp[size]=0; + char* g=g_locale_to_utf8(tmp,-1,NULL,NULL,NULL); + gtk_text_buffer_set_text(sourceBuf,g,-1); + free(tmp); + g_free(g); + return 1; +} +/// +///load and analyze coff file +void loadCoff(GtkWidget *widget,GtkWidget *window) +{ + GtkFileChooser *dialog; + dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_LOAD_COFF], //"Open Coff File", + GTK_WINDOW(window), + GTK_FILE_CHOOSER_ACTION_OPEN, + strings[I_CANCEL], GTK_RESPONSE_CANCEL, + strings[I_OPEN], GTK_RESPONSE_ACCEPT, + NULL); + if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT){ + char *filename; + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if(cur_path) free(cur_path); + cur_path = gtk_file_chooser_get_current_folder(dialog); + UseCoff=analyzeCOFF(filename,Slabel,Sulabel,source_info,&s_files,coff_data,&sym,&nsym); + g_free (filename); + //load source for address 0 + if(source_info[0].src_file!=-1){ + if(currentSource==source_info[0].src_file){ + scrollToLine(source_info[0].src_line); + } + else if(loadSource(s_files[source_info[0].src_file].ptr)){ + scrollToLine(source_info[0].src_line); + currentSource=source_info[0].src_file; + } + } + } + gtk_widget_destroy (GTK_WIDGET(dialog)); +} +/// +/// List of variables used when decoding an assembly word +void initVar(){ + int i; + for(i=0;i<0x200;i++){//clear variable list + variables[i].name=0; + variables[i].display=0; + } + variables[0].name="INDF"; + variables[1].name="TMR0"; + variables[2].name="PCL"; + variables[3].name="STATUS"; + variables[4].name="FSR"; + variables[5].name="PORTA"; + variables[6].name="PORTB"; + variables[7].name="PORTC"; + variables[8].name="PORTD"; + variables[9].name="PORTE"; + variables[10].name="PCLATH"; + variables[11].name="INTCON"; + variables[12].name="PIR1"; + variables[13].name="PIR2"; + variables[14].name="TMR1L"; + variables[15].name="TMR1H"; + variables[16].name="T1CON"; + variables[17].name="TMR2"; + variables[18].name="T2CON"; + variables[19].name="SSPBUF"; + variables[20].name="SSPCON"; + variables[21].name="CCPR1L"; + variables[22].name="CCPR1H"; + variables[23].name="CCP1CON"; + variables[24].name="RCSTA"; + variables[25].name="TXREG"; + variables[26].name="RCREG"; + variables[27].name="CCPR2L"; + variables[28].name="CCPR2H"; + variables[29].name="CCP2CON"; + variables[30].name="ADRESH"; + variables[31].name="ADCON0"; + variables[0x6B].name="DEBUG_VAR1"; + variables[0x6C].name="DEBUG_VAR2"; + variables[0x6D].name="DEBUG_VAR3"; + variables[0x6E].name="DEBUG_VAR4"; + variables[0x6F].name="DEBUG_VAR5"; + variables[0x70].name="DEBUG_VAR6"; + variables[0x71].name="DEBUG_VAR7"; + variables[0x72].name="DEBUG_VAR8"; + variables[0x80].name="INDF"; + variables[0x81].name="OPTION_REG"; + variables[0x82].name="PCL"; + variables[0x83].name="STATUS"; + variables[0x84].name="FSR"; + variables[0x85].name="TRISA"; + variables[0x86].name="TRISB"; + variables[0x87].name="TRISC"; + variables[0x88].name="TRISD"; + variables[0x89].name="TRISE"; + variables[0x8A].name="PCLATH"; + variables[0x8B].name="INTCON"; + variables[0x8C].name="PIE1"; + variables[0x8D].name="PIE2"; + variables[0x8E].name="PCON"; + variables[0x91].name="SSPCON2"; + variables[0x92].name="PR2"; + variables[0x93].name="SSPADD"; + variables[0x94].name="SSPSTAT"; + variables[0x98].name="TXSTA"; + variables[0x99].name="SPBRG"; + variables[0x9E].name="ADRESL"; + variables[0x9F].name="ADCON1"; + variables[0x100].name="INDF"; + variables[0x101].name="TMR0"; + variables[0x102].name="PCL"; + variables[0x103].name="STATUS"; + variables[0x104].name="FSR"; + variables[0x106].name="PORTB"; + variables[0x10A].name="PCLATH"; + variables[0x10B].name="INTCON"; + variables[0x10C].name="EEDATA"; + variables[0x10D].name="EEADR"; + variables[0x10E].name="EEDATH"; + variables[0x10F].name="EEADRH"; + variables[0x180].name="INDF"; + variables[0x181].name="OPTION_REG"; + variables[0x182].name="PCL"; + variables[0x183].name="STATUS"; + variables[0x184].name="FSR"; + variables[0x186].name="TRISB"; + variables[0x18A].name="PCLATH"; + variables[0x18B].name="INTCON"; + variables[0x18C].name="EECON1"; + variables[0x18D].name="EECON2"; +} +/// +///Show ICD help window +void ICDHelp(GtkWidget *widget,GtkWidget *window) +{ + GtkWidget* dialog = gtk_message_dialog_new (GTK_WINDOW(window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, + strings[I_ICD_HELP_TXT]); + + g_signal_connect_swapped (GTK_WINDOW(dialog), "response",G_CALLBACK (gtk_widget_destroy),dialog); + gtk_window_set_title(GTK_WINDOW(dialog),strings[I_ICD_HELP]); + gtk_widget_show_all (dialog); +} +/// +///ICD: check if program is running +void icdCheck(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(!isRunning()){ + g_source_remove(icdTimer); + ShowContext(); + } +} +/// +///ICD: run program +void icdRun(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(!icdConnected){ + saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log)); + if(saveLog){ + OpenLogFile(); //"Log.txt" + fprintf(logfile,"ICD start\n"); + } + startICD(Tck); //start ICD mode by supplying the target and forcing a reset + run(); //remove reset + icdConnected=1; + icdTimer=g_timeout_add(20,(GSourceFunc)icdCheck,NULL); + PrintMessageICD("running"); + } + else if(!running){ + cont(break_addr,freeze); //continue execution + icdTimer=g_timeout_add(20,(GSourceFunc)icdCheck,NULL); + PrintMessageICD("running"); + } +} +/// +///ICD: halt program +void icdHalt(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(running){ + g_source_remove(icdTimer); + Halt(); + ShowContext(); + } +} +/// +///ICD: step program +void icdStep(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(running){ + g_source_remove(icdTimer); + Halt(); + } + step(); +#ifdef DEBUG + addrDebug++; +#endif + ShowContext(); +} +/// +///ICD: step program jumping over calls +void icdStepOver(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + int addr,data; + if(running){ + g_source_remove(icdTimer); + Halt(); + } + addr=((ReadRegister(0x18E)&0x1F)<<8)+ReadRegister(0x18F); + data=ReadProgMem(addr); + if((data>>11)==4){ //if call break at return address + cont(addr+1,freeze); + icdTimer=g_timeout_add(20,(GSourceFunc)icdCheck,NULL); + } + else{ //normal step + step(); + #ifdef DEBUG + addrDebug++; + #endif + ShowContext(); + } +} +/// +///ICD: stop program +void icdStop(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(running){ + g_source_remove(icdTimer); + Halt(); + } +// bufferU[0]=0; + int j=0; + bufferU[j++]=EN_VPP_VCC; // reset target + bufferU[j++]=0x0; + bufferU[j++]=WAIT_T3; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x2; //set D as input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(3); + if(saveLog)WriteLogIO(); + icdConnected=0; + PrintMessageICD("stopped"); + scrollToLine(source_info[0].src_line); +} +/// +///ICD: refresh status +void icdRefresh(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(!running){ + ShowContext(); + } +} +/// +/// Read and display an entire bank of memory +void ShowBank(int bank,char* status){ + if(bank>3) bank=3; + if(bank<0) bank=0; + int b[128]; + char temp[128]; + int i; + sprintf(temp,"bank %d:",bank); + strcat(status,temp); + ReadRegisterN(bank*0x80,128,b); + for(i=0;i<128;i++){ + if(i%16==0){ + sprintf(temp,"\n0x%03X:",i+bank*0x80); + strcat(status,temp); + } + sprintf(temp,"%02X",b[i]); + strcat(status,temp); + } + strcat(status,"\n"); +} +/// +/// Main ICD show function: +/// prints status info according to selected options +/// and the value of variables in the watch list +void ShowContext(){ + int i,addr,data,s; + char cmd[32]=""; + char status[4096]="",temp[128]; + addr=((ReadRegister(0x18E)&0x1F)<<8)+ReadRegister(0x18F); + data=ReadProgMem(addr); + s=ReadRegister(status_temp); + s=(s>>4)+((s<<4)&0xF0); //STATUS is swapped +// printf("addr %X, status %X, data %X\n",addr,s,data); +#ifdef DEBUG + addr=addrDebug; + s=statusDebug; + if(UseCoff) data=coff_data[addr]; +#endif + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuPC))){ + sprintf(temp,"%s: %s (0x%04X) \nPC=0x%04X\n",strings[S_NextIns],decodeCmd(data,cmd,(s&0x60)<<2),data,addr); //"Next instruction" + strcat(status,temp); + } + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuSTAT))){ + sprintf(temp,"STATUS=0x%02X (",s); + strcat(status,temp); + sprintf(temp,"%s ",s&0x80?"IRP":" "); + strcat(status,temp); + sprintf(temp,"%s ",s&0x40?"RP1":" "); + strcat(status,temp); + sprintf(temp,"%s ",s&0x20?"RP0":" "); + strcat(status,temp); + sprintf(temp,"%s ",s&0x10?"TO":" "); + strcat(status,temp); + sprintf(temp,"%s ",s&0x8?"PD":" "); + strcat(status,temp); + sprintf(temp,"%s ",s&0x4?"Z":" "); + strcat(status,temp); + sprintf(temp,"%s ",s&0x2?"DC":" "); + strcat(status,temp); + sprintf(temp,"%s)\n",s&0x1?"C":" "); + strcat(status,temp); + sprintf(temp,"W=0x%02X PCLATH=0x%02X FSR=0x%02X\n",ReadRegister(w_temp),ReadRegister(pclath_temp),ReadRegister(fsr_temp)); + strcat(status,temp); + } + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank0))) ShowBank(0,status); + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank1))) ShowBank(1,status); + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank2))) ShowBank(2,status); + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuBank3))) ShowBank(3,status); + int rawsource=0; + if(UseCoff){ //hilight corresponding source line + if(data!=coff_data[addr]){ + sprintf(temp,"code at address 0x%04X (0x%04X) is different than what specified in coff file (0x%04X)\n",addr,data,coff_data[addr]); + strcat(status,temp); + rawsource=1; + } +#ifndef DEBUG + else{ +#endif +// printf("addr %d, file %d, line %d, current %d, ptr %X\n",addr,source_info[addr].src_file,source_info[addr].src_line,currentSource,s_files[source_info[addr].src_file].ptr); + if(source_info[addr].src_file!=-1){ + if(currentSource==source_info[addr].src_file) scrollToLine(source_info[addr].src_line); + else if(loadSource(s_files[source_info[addr].src_file].ptr)){ + scrollToLine(source_info[addr].src_line); + currentSource=source_info[addr].src_file; + } + else rawsource=1; + } + else rawsource=1; +#ifndef DEBUG + } +#endif + } + if(!UseCoff || rawsource==1){ //show raw source if no source file is available + #define LINES_BEFORE 5 + #define LINES_AFTER 7 + #define NLINES LINES_BEFORE + LINES_AFTER + int addr0,addr1,line_pc=0; + char tmp[64*NLINES],t2[64]; + tmp[0]=0; + int progmem[NLINES]; + addr0=addr-LINES_BEFORE<0?0:addr-LINES_BEFORE; + addr1=addr+LINES_AFTER>0x1FFF?0x1FFF:addr+LINES_AFTER; + ReadProgMemN(addr0,addr1-addr0,progmem); + for(i=addr0;i<addr1;i++){ + sprintf(t2,"0x%04X: %s (0x%04X)\n",i,decodeCmd(progmem[i-addr0],cmd,(s&0x60)<<2),progmem[i-addr0]); + strcat(tmp,t2); + if(i==addr) line_pc=i; + } + gtk_text_buffer_set_text(sourceBuf,tmp,-1); + currentSource=-1; + scrollToLine(line_pc-addr0+1); + } + for(i=0;i<nwatch;i++){ + sprintf(temp,"%s=0x%02X\n",watch[i].name,ReadRegister(watch[i].value)); + strcat(status,temp); + } + PrintMessageICD(status); + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(icdMenuEE))){ + unsigned char data[256]; + str[0]=0; + char s[64],t[9],*g; + t[8]=0; + ReadDataMemN(0,256,data); + strcat(str,"EEPROM:\n"); + for(i=0;i<0x100;i++){ + if(i%8==0){ + sprintf(s,"\n0x%02X: ",i); + strcat(str,s); + } + sprintf(s,"%02X ",data[i]); + strcat(str,s); + t[i&0x7]=isprint(data[i])?data[i]:'.'; + if(i%8==7){ + g=g_locale_to_utf8(t,-1,NULL,NULL,NULL); + if(g) strcat(str,g); + g_free(g); + } + } + AppendMessageICD(str); + } +} +/// +///Add symbol to the list of watched variables +int addWatch(struct symbol s){ + int i; + for(i=0;i<nwatch&&strcmp(watch[i].name,s.name);i++); + if(i<nwatch){ //remove watch + for(;i<nwatch-1;i++){ + watch[i].name=watch[i+1].name; + watch[i].value=watch[i+1].value; + } + nwatch--; + watch=realloc(watch,nwatch*sizeof(struct symbol)); + } + else{ //add watch + nwatch++; + watch=realloc(watch,nwatch*sizeof(struct symbol)); + watch[nwatch-1].name=s.name; + watch[nwatch-1].value=s.value; + return 1; + } + return 0; +} +/// +/// ICD Command parser +int executeCommand(char *command){ +//******************* break ******************************** + if(strstr(command,"break")){ + if(sscanf(command,"break %x",&break_addr)==1){ + if(running) Halt(); + break_addr&=0x1FFF; + sprintf(str,"break at address 0x%04X\n",break_addr); + AppendMessageICD(str); + SourceRemoveHilightLine(sourceHilight); + SourceHilightLine(source_info[break_addr].src_line); + sourceHilight=source_info[break_addr].src_line; + } + } +//******************* clear ******************************** + if(strstr(command,"clear")){ + PrintMessageICD(""); + } +//******************* freeze ******************************** + else if(strstr(command,"freeze")){ + char option[32]; + if(sscanf(command,"freeze %s",option)==1){ + if(running) Halt(); + if(!strcmp(option,"on")) freeze=1; + if(!strcmp(option,"off")) freeze=0; + WriteRegister(0x18E,(break_addr>>8)+(freeze?0x40:0)); + } + sprintf(str,"peripheral freeze is %s\n",freeze?"on":"off"); + AppendMessageICD(str); + } +//******************* halt ******************************** + else if(!strcmp(command,"h")||!strcmp(command,"halt")){ + icdHalt(NULL,NULL); + } +//******************* help ******************************** + else if(!strcmp(command,"help")){ + ICDHelp(NULL,NULL); + } +//******************* list ******************************** + else if(strstr(command,"list ")){ + #define LISTLINES 10 + int addr,i; + char tmp[32*LISTLINES],t2[32],cmd[32]=""; + tmp[0]=0; + int progmem[LISTLINES]; + if(sscanf(command,"list %x",&addr)==1){ + addr&=0x1FFF; + ReadProgMemN(addr,LISTLINES,progmem); + for(i=0;i<LISTLINES;i++){ + sprintf(t2,"0x%04X: %s (0x%04X)\n",i+addr,decodeCmd(progmem[i],cmd,0),progmem[i]); + strcat(tmp,t2); + } + //printf(tmp); + AppendMessageICD(tmp); + } + } +//******************* print ******************************** + else if(strstr(command,"print ")||strstr(command,"p ")){ + int bank,i,addr,data; + char var[128]; + if(strstr(command,"print p")||strstr(command,"p p")){ //program memory + int addr; + if(sscanf(command,"print p %x",&addr)==1||sscanf(command,"p p %x",&addr)==1){ + addr&=0x1FFF; + if(running) Halt(); + data=ReadProgMem(addr); + sprintf(str,"0x%04X: %s (0x%04X)\n",addr,decodeCmd(data,var,0x1000),data); + AppendMessageICD(str); + } + } + else if(!strcmp(command,"print ee")||!strcmp(command,"p ee")){ //eeprom + unsigned char data[256]; + str[0]=0; + char s[64],t[9],*g; + t[8]=0; + if(running) Halt(); + ReadDataMemN(0,256,data); + sprintf(str,"EEPROM:\n"); + for(i=0;i<0x100;i++){ + if(i%8==0){ + sprintf(s,"\n0x%02X: ",i); + strcat(str,s); + } + sprintf(s,"%02X ",data[i]); + strcat(str,s); + t[i&0x7]=isprint(data[i])?data[i]:'.'; + if(i%8==7){ + g=g_locale_to_utf8(t,-1,NULL,NULL,NULL); + if(g) strcat(str,g); + g_free(g); + } + } + strcat(str,"\n"); + //printf("EEPROM:\n");fflush(stdout); + AppendMessageICD(str); + } + else if(sscanf(command,"print ee %x",&addr)==1||sscanf(command,"p ee %x",&addr)==1){ //single EE address + addr&=0xFF; + if(running) Halt(); + data=ReadDataMem(addr); + sprintf(str,"eeprom memory at 0x%02X=0x%02X (%c)\n",addr,data,isprint(data)?data:'.'); + AppendMessageICD(str); + } + else if(sscanf(command,"print bank %x",&bank)==1||sscanf(command,"p bank %x",&bank)==1){ //memory bank + str[0]=0; + bank&=0x1FF; + if(bank>3) bank/=0x80; + if(running) Halt(); + ShowBank(bank,str); + AppendMessageICD(str); + } + else if(sscanf(command,"print 0x%x",&print_addr)==1||sscanf(command,"p 0x%x",&print_addr)==1){ //mem address + print_addr&=0x1FF; + if(running) Halt(); + sprintf(str,"[0x%03X]=0x%02X\n",print_addr,ReadRegister(print_addr)); + AppendMessageICD(str); + } + else if(sscanf(command,"print %s",var)==1||sscanf(command,"p %s",var)==1){ //var name + str[0]=0; + if(running) Halt(); + if(!strcmp("W",var)||!strcmp("w",var)) sprintf(str,"W = 0x%02X\n",ReadRegister(w_temp)); + else if(!strcmp("STATUS",var)) sprintf(str,"0x003: STATUS = 0x%02X\n",ReadRegister(status_temp)); + else if(!strcmp("FSR",var)) sprintf(str,"0x004: FSR = 0x%02X\n",ReadRegister(fsr_temp)); + else if(!strcmp("PCLATH",var)) sprintf(str,"0x00A: PCLATH = 0x%02X\n",ReadRegister(pclath_temp)); + else{ + for(i=0;i<nsym&&strcmp(var,sym[i].name);i++); + if(i<nsym){ + sprintf(str,"0x%03X: %s = 0x%02X\n",sym[i].value,sym[i].name,ReadRegister(sym[i].value)); + } + else{ //look in standard variables + for(i=0;i<0x200;i++){ + if(variables[i].name&&!strcmp(var,variables[i].name)){ + sprintf(str,"0x%03X: %s = 0x%02X\n",i,variables[i].name,ReadRegister(i)); + i=0x200; + } + } + } + } + AppendMessageICD(str); + } + } +//******************* run ******************************** + else if(!strcmp(command,"r")||!strcmp(command,"run")){ + icdRun(NULL,NULL); + } +//******************* step ******************************** + else if(!strcmp(command,"s")||!strcmp(command,"step")||strstr(command,"step")||strstr(command,"s ")){ + int i,n=1; + sscanf(command,"step %d",&n); + sscanf(command,"s %d",&n); +#ifdef DEBUG + addrDebug+=n; +#endif + if(running) Halt(); + for(i=0;i<n;i++) step(); + if(n>1)sprintf(str,"step %d\n",n); + else str[0]=0; + ShowContext(); + AppendMessageICD(str); + } +//******************* step over ******************************** + else if(!strcmp(command,"ss")||!strcmp(command,"step over")||strstr(command,"step over ")||strstr(command,"ss ")){ + int i,n=1; + sscanf(command,"step over %d",&n); + sscanf(command,"ss %d",&n); +#ifdef DEBUG + addrDebug+=n; +#endif + for(i=0;i<n;i++) icdStepOver(NULL,NULL); + if(n>1)sprintf(str,"step over %d\n",n); + AppendMessageICD(str); + } +//******************* version ******************************** + else if(!strcmp(command,"ver")||!strcmp(command,"version")){ + if(running) Halt(); + sprintf(str,"debugger version: %.1f\n",version()/10.0); + AppendMessageICD(str); + } +//******************* watch ******************************** + else if(strstr(command,"watch ")||strstr(command,"w ")){ + int i,var_addr; + char var[64]; + if(sscanf(command,"watch 0x%x",&var_addr)||sscanf(command,"w 0x%x",&var_addr)){ + struct symbol s; + sprintf(var,"[0x%X]",var_addr); + s.name=strdup(var); + s.value=var_addr; + addWatch(s); + if(!running) ShowContext(); + } + else if(sscanf(command,"watch %s",var)||sscanf(command,"w %s",var)){ + for(i=0;i<nsym&&strcmp(var,sym[i].name);i++); + if(i<nsym){ + addWatch(sym[i]); + if(!running) ShowContext(); + } + else{ //look in standard variables + for(i=0;i<0x200;i++){ + if(variables[i].name&&!strcmp(var,variables[i].name)){ + struct symbol s; + s.name=variables[i].name; + s.value=i; + addWatch(s); + if(!running) ShowContext(); + i=0x200; + } + } + } + } + } +//******************* set variable ******************************** +//to do: special addresses (PC, status ecc) + else{ + char var[64],*p; + int data,i,addr=-1; + if((p=strchr(command,'='))){ + *p=0; + if(sscanf(command,"[%x]",&addr)&&sscanf(p+1,"%x",&data)){ + if(running) Halt(); + WriteRegister(addr,data); + ShowContext(); + sprintf(str,"[0x%x]=0x%02X\n",addr,data); + AppendMessageICD(str); + } + else if(sscanf(command,"%s",var)&&sscanf(p+1,"%x",&data)){ + for(i=0;i<nsym&&strcmp(var,sym[i].name);i++); + if(i<nsym&&sym[i].value<0x400){ + addr=sym[i].value; + } + else{ //look in standard variables + for(i=0;i<0x200;i++){ + if(variables[i].name&&!strcmp(var,variables[i].name)){ + addr=i; + i=0x200; + } + } + } + if(addr!=-1){ + if(running) Halt(); + WriteRegister(addr,data); + ShowContext(); + sprintf(str,"%s=0x%02X\n",var,data); + AppendMessageICD(str); + } + } + } + else return 0; + } + return 1; +} +/// +///Remove variable from watch list +int removeWatch(char* name){ + int i; + for(i=0;i<nwatch&&strcmp(watch[i].name,name);i++); + if(i<nwatch){ //remove watch + for(;i<nwatch-1;i++){ + watch[i].name=watch[i+1].name; + watch[i].value=watch[i+1].value; + } + nwatch--; + watch=realloc(watch,nwatch*sizeof(struct symbol)); + return 1; + } + return 0; +} +/// +///Handle mouse events in source code window +gint source_mouse_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data) +{ + if(GTK_IS_TEXT_VIEW(widget)&&event->type==GDK_2BUTTON_PRESS){ + gint x,y,i; + GtkTextIter iter,iter2,itx; + gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),GTK_TEXT_WINDOW_WIDGET,event->x,event->y,&x,&y); + gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget),&iter,x,y); +// printf("x %d y %d\n",x,y); + iter2=iter; + char c; + for(itx=iter2,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter2=itx){ + gtk_text_iter_forward_char(&itx); + c=gtk_text_iter_get_char(&itx); + } + for(itx=iter,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter=itx){ + gtk_text_iter_backward_char(&itx); + c=gtk_text_iter_get_char(&itx); + } + gtk_text_iter_forward_char(&iter); + char* selection=gtk_text_buffer_get_text(sourceBuf,&iter,&iter2,FALSE); + for(i=0;i<nsym&&strcmp(selection,sym[i].name);i++); + if(i<nsym){ + addWatch(sym[i]); + ShowContext(); + } + else{ //set breakpoint + int line=gtk_text_iter_get_line(&iter)+1; + for(i=0;i<LMAX;i++) if(source_info[i].src_line==line){ + //if(UseCoff && i>0 && (coff_data[i-1]>>11)!=4) i--; //if not a call break at previous address; + break_addr=i; + sprintf(str,"break at address 0x%x\n",i); + AppendMessageICD(str); + SourceRemoveHilightLine(sourceHilight); + SourceHilightLine(line); + sourceHilight=line; + break; + } + } + } + return FALSE; +} +/// +///Handle mouse events in ICD status window +gint icdStatus_mouse_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data) +{ + if(GTK_IS_TEXT_VIEW(widget)&&event->type==GDK_2BUTTON_PRESS){ + gint x,y; + GtkTextIter iter,iter2,itx; + gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),GTK_TEXT_WINDOW_WIDGET,event->x,event->y,&x,&y); + gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW(widget),&iter,x,y); + iter2=iter; + char c; + for(itx=iter2,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter2=itx){ + gtk_text_iter_forward_char(&itx); + c=gtk_text_iter_get_char(&itx); + } + for(itx=iter,c=gtk_text_iter_get_char(&itx);isalnum(c)||c=='_';iter=itx){ + gtk_text_iter_backward_char(&itx); + c=gtk_text_iter_get_char(&itx); + } + gtk_text_iter_forward_char(&iter); + char* selection=gtk_text_buffer_get_text(statusBuf,&iter,&iter2,FALSE); + if(removeWatch(selection)) ShowContext(); + } + return FALSE; +} +/// +///Handle keyboard events in ICD command edit box +gint icdCommand_key_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data) +{ + if(event->type==GDK_KEY_PRESS&&((GdkEventKey*)event)->keyval==0xFF0D){ //enter + char s[64]; + strncpy(s,gtk_entry_get_text(GTK_ENTRY(icdCommand)),63); + if(!strlen(s)){ + strcpy(s,lastCmd); + gtk_entry_set_text(GTK_ENTRY(icdCommand),s); //briefly flash last command + while (gtk_events_pending ()) gtk_main_iteration(); + msDelay(60); + } + else strcpy(lastCmd,s); + if(executeCommand(s)) gtk_entry_set_text(GTK_ENTRY(icdCommand),""); +// sprintf(s,"k=%X\n",((GdkEventKey*)event)->keyval); +// AppendMessageICD(gtk_entry_get_text(icdCommand)); + } + return FALSE; +} +/// +///Handle keyboard events in ICD tab +gint icd_key_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data) +{ + while (gtk_events_pending ()) gtk_main_iteration(); //wait completion of other tasks + if(event->type==GDK_KEY_PRESS){ + switch(((GdkEventKey*)event)->keyval){ + case 0xFFBE: + ICDHelp(NULL,NULL); //F1 = help + break; + case 0xFFC2: + icdHalt(NULL,NULL); //F5 = halt + break; + case 0xFFC4: + icdStep(NULL,NULL); //F7 = step + break; + case 0xFFC5: + icdStepOver(NULL,NULL); //F8 = step over + break; + case 0xFFC6: + icdRun(NULL,NULL); //F9 = run + break; + } +// char s[64]; +// sprintf(s,"k=%X\n",((GdkEventKey*)event)->keyval); +// AppendMessageICD(s); + } + return FALSE; +} + |