summaryrefslogtreecommitdiffstats
path: root/icd.c
diff options
context:
space:
mode:
Diffstat (limited to 'icd.c')
-rw-r--r--icd.c1541
1 files changed, 1541 insertions, 0 deletions
diff --git a/icd.c b/icd.c
new file mode 100644
index 0000000..3cf8e39
--- /dev/null
+++ b/icd.c
@@ -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;
+}
+