From 925d0670c45e1100e412070fa0ce2405604f219a Mon Sep 17 00:00:00 2001 From: Attila Veghelyi Date: Thu, 29 Jun 2023 16:24:54 +0200 Subject: Init repo --- icd.c | 1541 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1541 insertions(+) create mode 100644 icd.c (limited to 'icd.c') 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 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; +} + -- cgit v1.2.3-54-g00ecf