The In-Circuit Debugger Survial Guide

1F00  1170          bcf    0x70,0x2                      
1F01  1903          btfsc  STATUS,ZERO                      
1F02  1570          bsf    0x70,0x2    ; Copy Zero Bit                  
1F03  1370          bcf    0x70,0x6                      
1F04  1B03          btfsc  STATUS,RP1                     
1F05  1770          bsf    0x70,0x6    ; Copy RP1 Bit                  
1F06  12F0          bcf    0x70,0x5                      
1F07  1A83          btfsc  STATUS,RP0	                       
1F08  16F0          bsf    0x70,0x5    ; Copy RP0 Bit  
                
1F09  1703          bsf    STATUS,RP1                       
1F0A  1683          bsf    STATUS,RP0  ; Select Bank 3                       

1F0B  00ED          movwf  0x6D        ; Copy Working Register to 0x6D                  

1F0C  3064          movlw  0x64                          
1F0D  05F0          andwf  0x70   	; Clear Bits we have not worried about yet
					; !(RP1, RP2 & Zero)
                       
1F0E  0803          movf   STATUS,W                         
1F0F  399B          andlw  0x9B    	; Exclude Bits we have already read (RP1, RP2 & Zero)                      

1F10  04F0          iorwf  0x70         ; Or Result together (XOR?)              

1F11  0804          movf   FSR,W 	; Indirect Data Memory Address Pointer
1F12  00EE          movwf  0x6E         ; Store Temporarly at 0x6E                 

1F13  080A          movf   PCLATH,W     ; Store Temporarly at 0x6F                    
1F14  00EF          movwf  0x6F                          

1F15  301F          movlw  0x1F                          
1F16  008A          movwf  PCLATH       ; Set Upper Location                    

1F17  080E          movf   0xE,W	; Reserved                         
1F18  00EB          movwf  0x6B         ; Store Temporarly a 0x6B                 

1F19  1703          bsf    STATUS,RP1                       
1F1A  1683          bsf    STATUS,RP0	; Select Bank 3                       

1F1B  30E0          movlw  0xE0         ; 0x60                 
1F1C  05EC          andwf  0x6C                          

1F1D  1706          bsf    TRISB,0x6	; Set Clock Input                     
1F1E  1386          bcf    TRISB,0x7    ; Set Data  Output                
1F1F  1283          bcf    STATUS,RP0   ; Select Bank 2                    
1F20  1386          bcf    PORTB,0x7	; Clear Data                       
1F21  1683          bsf    STATUS,RP0	; Select Bank 3                       

1F22  0AEC  Loop    incf   0x6C         ;                  
1F23  1D6C          btfss  0x6C,0x2     ; Skip if Set                 
1F24  2F22          goto   0x1F22 (Loop); loop until bit 2 is set
1F25  116C          bcf    0x6C,0x2     ; Clear Bit 2                 

1F26  1283          bcf    STATUS,RP0   ; Select Bank 2 -> Access to Ports                      

1F27  0064  HitoLo  clrwdt                               
1F28  1B06          btfsc  PORTB,0x6(CLOCK) ; Loop until High to Low Transition                      
1F29  2F27          goto   0x1F27 (HitoLo)
                         
1F2A  0064  LotoHi  clrwdt
1F2B  1F06          btfss  PORTB,0x6(CLOCK) ; Loop until low to high Transition                       
1F2C  2F2A          goto   0x1F2A (LotoHi)
                         
1F2D  1786          bsf    PORTB,0x7 (DATA) ; Set Data Bit High
                   
1F2E  1683          bsf    STATUS,RP0 	; Select BANK 3 -> Access to Debug Registers                     

1F2F  0AEC          incf   0x6C                          
1F30  1DEC          btfss  0x6C,0x3                      
1F31  2F2F          goto   0x1F2F                         
1F32  11EC          bcf    0x6C,0x3 	; Clear Bit 3                     

1F33  1283          bcf    STATUS,RP0   ; Select BANK 2 -> Access to Ports                   
1F34  1386          bcf    PORTB,0x7 (DATA) ; Clear Data                   

1F35  0064          clrwdt                              
1F36  1B06          btfsc  PORTB,0x6 (CLOCK) ; Loop until High to Low Transition                     
1F37  2F35          goto   0x1F35                         

1F38  0064          clrwdt                               
1F39  1F06          btfss  PORTB,0x6 (CLOCK) ; Loop until low to high Transition                        
1F3A  2F38          goto   0x1F38    


                     
1F3B  1003          bcf    STATUS,CARRY      ; Clear Carry               
1F3C  1683          bsf    STATUS,RP0        ; Select BANK 3 -> Access to Debug Registers               
1F3D  1BEC          btfsc  0x6C,0x7          ; Copy Bit 7 of 6C            
1F3E  1403          bsf    STATUS,CARRY                     
1F3F  1283          bcf    STATUS,RP0        ; Select BANK 2 -> Access to Ports   
                   
1F40  1386          bcf    PORTB,0x7 (DATA)  ; Clear Data                      
1F41  1C03          btfss  STATUS,CARRY      ; Copy Bit 7 to Data               
1F42  1786          bsf    PORTB,0x7 (DATA)
                      
1F43  1B06          btfsc  PORTB,0x6 (CLOCK) ; Loop until High to Low Transition                      
1F44  2F43          goto   0x1F43                         



1F45  1683          bsf    STATUS,RP0        ; Select BANK 3 -> Access to Debug Registers                 
1F46  1786          bsf    TRISB,0x7 (DATA)  ; Make DATA Input                     
1F47  0064          clrwdt      
                         
1F48  0AEC          incf   0x6C                          

1F49  1283          bcf    STATUS,RP0        ; Select BANK 2 -> Access to Ports 		                     
1F4A  1003          bcf    STATUS,CARRY                     
1F4B  1B86          btfsc  PORTB,0x7 (DATA)  ; Read Data                     
1F4C  1403          bsf    STATUS,CARRY                     
1F4D  1683          bsf    STATUS,RP0        ; Select BANK 3 -> Access to Debug Registers                   
1F4E  13EC          bcf    0x6C,0x7          ; Store 6C            
1F4F  1803          btfsc  STATUS,CARRY                     
1F50  17EC          bsf    0x6C,0x7                      


1F51  1283  loop    bcf    STATUS,RP0        ; Select BANK 2 -> Access to Ports                     

1F52  0064          clrwdt                               
1F53  1F06          btfss  PORTB,0x6 (CLOCK) ; Loop until low to high Transition                        
1F54  2F52          goto   0x1F52           
              
1F55  1386          bcf    PORTB,0x7 (DATA)                      
1F56  1683          bsf    STATUS,RP0        ; Select BANK 3 -> Access to Debug Registers               
1F57  1386          bcf    PORTB,0x7 (DATA)                       
1F58  1003          bcf    STATUS,CARRY                     
1F59  1B6B          btfsc  0x6B,0x6                      
1F5A  1403          bsf    STATUS,CARRY                     
1F5B  1283          bcf    STATUS,RP0        ; Select BANK 2 -> Access to Ports                  
1F5C  1386          bcf    PORTB,0x7 (DATA)                       
1F5D  1803          btfsc  STATUS,CARRY                     
1F5E  1786          bsf    PORTB,0x7 (DATA)                      

1F5F  0064          clrwdt                               
1F60  1B06          btfsc  PORTB,0x6 (CLOCK) ; Loop until High to Low Transition                       
1F61  2F5F          goto   0x1F5F            
             
1F62  1683          bsf    STATUS,RP0        ; Select BANK 3 -> Access to Debug Registers               
1F63  1786          bsf    TRISB,0x7 (DATA)  ; Make Data an Input!                       
1F64  1003          bcf    STATUS,CARRY                     
1F65  0D8F          rlf    0x0F                           
1F66  0DEB          rlf    0x6B                          
1F67  0AEC          incf   0x6C                          
1F68  1283          bcf    STATUS,RP0        ; Select BANK 2 -> Access to Ports                
1F69  1003          bcf    STATUS,CARRY                     
1F6A  1B86          btfsc  PORTB,0x7 (DATA)  ; read data                       
1F6B  1403          bsf    STATUS,CARRY                     
1F6C  1683          bsf    STATUS,RP0        ; Select BANK 3 -> Access to Debug Registers                      
1F6D  1803          btfsc  STATUS,CARRY 
                      
1F6E  140F          bsf    0xF,0x0            (Reserved)                       

1F6F  1E6C          btfss  0x6C,0x4 
1F70  2F51          goto   0x1F51    
                     
1F71  1FEC          btfss  0x6C,0x7                      
1F72  2F84          goto   0x1F84    

	
1F73  086B          movf   0x6B,W	     ; Restore Registers                        
1F74  008E          movwf  0xE (Reserved)                           
1F75  086F          movf   0x6F,W                        
1F76  008A          movwf  PCLATH                           
1F77  086E          movf   0x6E,W                        
1F78  0084          movwf  FSR                           
1F79  0870          movf   0x70,W                        
1F7A  0083          movwf  STATUS

                           
1F7B  1683          bsf    STATUS,RP0                           
1F7C  1703          bsf    STATUS,RP1	     ; BANK SELECT 3                       

1F7D  0EED          swapf  0x6D                          
1F7E  0E6D          swapf  0x6D,W                        
1F7F  1F70          btfss  0x70,0x6                      
1F80  1303          bcf    STATUS,RP1                       
1F81  1EF0          btfss  0x70,0x5                      
1F82  1283          bcf    STATUS,RP0                       

1F83  0008          return  		      ; Pop of stack?                             


1F84  0E6B          swapf  0x6B,W                        
1F85  3907          andlw  0x7 		      ; 8 Possible Combinations of High Nibble                         
1F86  0782          addwf  PCL                           
1F87  2FAE          goto   0x1FAE                         
1F88  2FB2          goto   0x1FB2                         
1F89  2FB0          goto   0x1FB0                         
1F8A  2FB4          goto   0x1FB4                         
1F8B  2F9A          goto   0x1F9A                         
1F8C  2FA6          goto   0x1FA6                         
1F8D  2F8F          goto   0x1F8F                         
1F8E  2FA1          goto   0x1FA1
                         
1F8F  086B          movf   0x6B,W                          
1F90  3907          andlw  0x7                ; 8 Possible Combinations of Low Nibble                           
1F91  0782          addwf  PCL                           
1F92  2FB6          goto   0x1FB6                         
1F93  2FBC          goto   0x1FBC                         
1F94  2FB9          goto   0x1FB9                         
1F95  2FBF          goto   0x1FBF                         
1F96  2FC2          goto   0x1FC2                         
1F97  2FCE          goto   0x1FCE                         
1F98  2FA1          goto   0x1FA1                         
1F99  2FA1          goto   0x1FA1                         


1F9A  1383          bcf    STATUS,IRP ; (Bank 0,1 00h ffh) Used for Indirect Addressing                     
1F9B  186B          btfsc  0x6B,0x0                      
1F9C  1783          bsf    STATUS,IRP ; (Bank 2,3 100 1ffh)

1F9D  080F          movf   0xF,W                         
1F9E  0084          movwf  0x4 
                          
1F9F  0800          movf   0x0,W                         




1FA0  008F          movwf  0xF          ; High Byte                  

** WAIT FOR HIGH TO LOW TRANSITION ON DATA

1FA1  1283          bcf    STATUS,RP0	; Bank 2
1FA2  0064          clrwdt                               
1FA3  1F06          btfss  PORTB,DATA	; Read Data Line                       
1FA4  2FA2          goto   0x1FA2       ; Wait for low to High Transition                  

1FA5  2F19          goto   0x1F19                         


** SAVE VALUE of 0x6D to FILE REGISTERS (0x0F) 

1FA6  1383          bcf    STATUS,IRP   ; Indirect Addressing Register Bank                    
1FA7  186B          btfsc  0x6B,0x0     ; If 6B Bit 0 = 0 Bank 0,1 (00h  -> FFh)                  
1FA8  1783          bsf    STATUS,IRP   ;             = 1 Bank 2,3 (100h -> 1FFh)
                       
1FA9  080F          movf   0xF,W        ;                  
1FAA  0084          movwf  FSR		; Move Address of Data Memory from W to FSR                          
1FAB  086D          movf   0x6D,W       ;                 
1FAC  0080          movwf  0x0          ; Save Contents of REG6D to Addr 0xF                  
1FAD  2FA1          goto   0x1FA1                         

** SEND VALUE IN 6D

1FAE  086D          movf   0x6D,W                        
1FAF  2FA0          goto   0x1FA0                         

** SEND VALUE IN 6E

1FB0  086E          movf   0x6E,W                        
1FB1  2FA0          goto   0x1FA0                         

** SEND VALUE IN 70

1FB2  0870          movf   0x70,W                        
1FB3  2FA0          goto   0x1FA0                         

** SEND VALUE IN 6F

1FB4  086F          movf   0x6F,W                        
1FB5  2FA0          goto   0x1FA0                         



1FB6  080F          movf   0xF,W                         
1FB7  00ED          movwf  0x6D                          
1FB8  2FA1          goto   0x1FA1                         

1FB9  080F          movf   0xF,W                         
1FBA  00EE          movwf  0x6E                          
1FBB  2FA1          goto   0x1FA1                         

1FBC  080F          movf   0xF,W                         
1FBD  00F0          movwf  0x70                          
1FBE  2FA1          goto   0x1FA1                         





1FBF  090F          comf   0xF,W                         
1FC0  00EF          movwf  0x6F                          
1FC1  2FA1          goto   0x1FA1             
            
1FC2  080F          movf   0xF,W                         
1FC3  1283          bcf    STATUS,RP0   ; Bank 0?                    
1FC4  008C          movwf  0xC          ; PIR1                 
1FC5  1683          bsf    STATUS,RP0	; Bank 1                       
1FC6  138C          bcf    0xC,0x7 	; PIE1                      
1FC7  150C          bsf    0xC,0x2      ; PIE1                 

1FC8  3055          movlw  0x55                          
1FC9  008D          movwf  0xD		; PIE2                           

1FCA  30AA          movlw  0xAA                          
1FCB  008D          movwf  0xD		; PIE2                           

1FCC  148C          bsf    0xC,0x1                       
1FCD  2FA1          goto   0x1FA1                         


1FCE  080F          movf   0xF,W	; TMR1H                         
1FCF  1283          bcf    STATUS,RP0	; BANK0                       
1FD0  008D          movwf  0xD          ; PIR2                 
1FD1  1683          bsf    STATUS,RP0   ; BANK1                    
1FD2  138C          bcf    0xC,0x7        (PIE1)               
1FD3  140C          bsf    0xC,0x0        (               
1FD4  1283          bcf    STATUS,RP0                       
1FD5  080C          movf   0xC,W                         
1FD6  1683          bsf    STATUS,RP0                       
1FD7  2FA0          goto   0x1FA0   	

                                                    

The ICD module itself has a 3,6864 Mhz Xtal.

The demo board has an empty socket and link for (optional) osc module, but normally runs as an RC osc...

Let me direct you to an article which John Day, A Principal Field Application Engineer for Microchip wrote in Circuit Cellar, Issue 109, August 1999.

John writes, "The debug kernel is downloaded along with the target firmware via the ICSP interface. A non-maskable interrupt vectors execution to the kernel when the program counter equals a preselected hardware breakpoint address, after a single step, or when a halt command is received from the host."

"As with all interrupts, this interrupt pushes the return address onto the stack. On reset, the breakpoint register is set equal to the reset vector, so the kernel is entered immediately when the device comes out of reset. The ICD module issues a reset to the target '16F877 immediately after a download, the kernel is entered and control is passed to MPLAB running on the host."

"You can then command the target processor as you choose. All RAM registers including the PC and other special function registers can be modified or interrogated. You can single step, set a breakpoint, animate and start or stop full speed execution."

Now it doesn't take too much effort to work out that we need two bytes for the Breakpoint Register. An considering the 16F87x documentation shows only to registers which are reserved, life couldn't be easier. Locations 0x18E and 0x18F are the breakpoint register. I've written a little program which allows me to access internal registers via the serial port. This is great for debugging/learning the operation of peripherals. What this has also told me, that in normal operation these two registers can't be written too.

So when a breakpoint occurs where does the program vector too? Maybe 0x1F00, the start of that all secret debug target code?

Tonight's Homework: Write a program at 0x1F00 to flash a LED or something similar. Then write a loop at 0x0000 so in normal operation, the code at 0x1F00 never gets executed. Then run the program both with the Debug Bit Clear and Set. Then summarize your observations to the PIC List . . . . (No I won't be marking it)

I have done this a couple of months back, but where getting mixed results. This was at the time my programmer was also given mixed results!, thus I could never verify exactly what was happening. However I suspect there is more to this. I also observed that is I placed about 10 NOP's at 0000 it would work. We do know for sure, reading from the ICD manual that you need to program the first location with a NOP. This is due to the fact that the breakpoint register is compared to the PC address after execution of the instruction.

John continues to write under the heading Silicon Requirements, "The breakpoint address register and compactor, along with some logic to single step and recognize asynchronous commands from the host, make up most of what is needed in the silicon. The ICSP interface is in place to support programming and doesn't constitute and additional silicon requirement."

"recognize asynchronous commands" This has stumped me. What I believe is that there is some other ICSP command which enables and disables operation? I'm open to any suggestions . . . .

Also check my reply to Robin Abbott dated Mon, 24 Jan 2000 if you are desperately scratching for more information. . . http://www.infosite.com/%7Ejkeyzer/piclist/2000/Jan/1552.html

From MChip App Note TB033:

Certain resources are consumed when the MPLAB™-ICD In-Circuit Debugger is used to develop code. These resources are released when the debugger is not used. The resources include: