//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 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>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>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>8; bufferU[j++]=(addr+i)&0xFF; bufferU[j++]=RX16; bufferU[j++]=w; bufferU[j++]=FLUSH; for(;j>8)&0xFF; bufferU[j++]=addr&0xFF; bufferU[j++]=SET_CK_D; bufferU[j++]=0x2; //set D as input bufferU[j++]=FLUSH; for(;j>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>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>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>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>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>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>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(;j3) 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>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;i3) 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;i1)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;i1)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;itype==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;i0 && (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; }