goodfet.cc commands for dumping flash and data
[goodfet] / firmware / apps / chipcon / chipcon.c
index 2748a58..45a27e7 100644 (file)
@@ -50,7 +50,7 @@
 #define CCREAD P5DIR&=~MISO
 
 //! Set up the pins for CC mode.  Does not init debugger.
-unsigned char ccsetup(){
+void ccsetup(){
   P5OUT|=MOSI+SCK+RST;
   P5DIR|=MOSI+SCK+RST;
   //P5DIR&=~MISO;  //MOSI is MISO
@@ -126,7 +126,6 @@ void ccread(unsigned char len){
 void cchandle(unsigned char app,
               unsigned char verb,
               unsigned char len){
-  unsigned char i;
   switch(verb){
     //PEEK and POKE will come later.
   case READ:  //Write a command and return 1-byte reply.
@@ -140,12 +139,14 @@ void cchandle(unsigned char app,
     break;
   case START://enter debugger
     ccdebuginit();
+    txdata(app,verb,0);
     break;
   case STOP://exit debugger
     //Take RST low, then high.
     P5OUT&=~RST;
     CCDELAY(CCSPEED);
     P5OUT|=RST;
+    txdata(app,verb,0);
     break;
   case SETUP:
     ccsetup();
@@ -167,7 +168,7 @@ void cchandle(unsigned char app,
     break;
   case CC_GET_PC:
     cc_get_pc();
-    txdata(app,verb,1);
+    txdata(app,verb,2);
     break;
   case CC_READ_STATUS:
     cc_read_status();
@@ -186,7 +187,8 @@ void cchandle(unsigned char app,
     txdata(app,verb,1);
     break;
   case CC_DEBUG_INSTR:
-    txdata(app,NOK,0);//TODO add me
+    cc_debug_instr(len);
+    txdata(app,verb,1);
     break;
   case CC_STEP_INSTR:
     cc_step_instr();
@@ -203,8 +205,17 @@ void cchandle(unsigned char app,
 
   //Macro commands
   case CC_READ_CODE_MEMORY:
+    cmddata[0]=peekcodebyte(cmddataword[0]);
+    txdata(app,verb,1);
+    break;
   case CC_READ_XDATA_MEMORY:
+    cmddata[0]=peekdatabyte(cmddataword[0]);
+    txdata(app,verb,1);
+    break;
   case CC_WRITE_XDATA_MEMORY:
+    cmddata[0]=pokedatabyte(cmddataword[0], cmddata[2]);
+    txdata(app,verb,1);
+    break;
   case CC_SET_PC:
   case CC_CLOCK_INIT:
   case CC_WRITE_FLASH_PAGE:
@@ -255,7 +266,7 @@ unsigned short cc_get_chip_id(){
   
   //Return the word.
   toret=cmddata[1];
-  toret=toret<<8+cmddata[1];
+  toret=(toret<<8)+cmddata[1];
   return toret;
 }
 
@@ -303,3 +314,106 @@ void cc_step_instr(){
   ccread(1);
   return;
 }
+
+//! Debug an instruction.
+void cc_debug_instr(unsigned char len){
+  //Bottom two bits of command indicate length.
+  unsigned char cmd=0x54+(len&0x3);
+  CCWRITE;
+  cctrans8(cmd);  //Second command code
+  cccmd(len&0x3); //Command itself.
+  ccread(1);
+  return;
+}
+
+//! Debug an instruction, for local use.
+unsigned char cc_debug(unsigned char len,
+             unsigned char a,
+             unsigned char b,
+             unsigned char c){
+  unsigned char cmd=0x54+(len&0x3);//(len&0x3);
+  CCWRITE;
+  cctrans8(cmd);
+  if(len--)
+    cctrans8(a);
+  if(len--)
+    cctrans8(b);
+  if(len--)
+    cctrans8(c);
+  CCREAD;
+  return cctrans8(0x00);
+}
+
+//! Fetch a byte of code memory.
+unsigned char peekcodebyte(unsigned long adr){
+  /** See page 9 of SWRA124 */
+  unsigned char bank=adr>>15,
+    lb=adr&0xFF,
+    hb=(adr>>8)&0x7F,
+    toret=0;
+  adr&=0x7FFF;
+  
+  //MOV MEMCTR, (bank*16)+1
+  cc_debug(3, 0x75, 0xC7, (bank<<4) + 1);
+  //MOV DPTR, address
+  cc_debug(3, 0x90, hb, lb);
+  
+  //for each byte
+  //CLR A
+  cc_debug(2, 0xE4, 0, 0);
+  //MOVC A, @A+DPTR;
+  toret=cc_debug(1, 0x93, 0, 0);
+  //INC DPTR
+  //cc_debug(1, 0xA3, 0, 0);
+  
+  return toret;
+}
+
+
+//! Set a byte of data memory.
+unsigned char pokedatabyte(unsigned int adr,
+                          unsigned char val){
+  unsigned char
+    hb=(adr&0xFF00)>>8,
+    lb=adr&0xFF;
+  
+  //MOV DPTR, adr
+  cc_debug(3, 0x90, hb, lb);
+  //MOV A, val
+  cc_debug(2, 0x74, val, 0);
+  //MOVX @DPTR, A
+  cc_debug(1, 0xF0, 0, 0);
+  
+  return 0;
+  /*
+DEBUG_INSTR(IN: 0x90, HIBYTE(address), LOBYTE(address), OUT: Discard);
+for (n = 0; n < count; n++) {
+    DEBUG_INSTR(IN: 0x74, inputArray[n], OUT: Discard);
+    DEBUG_INSTR(IN: 0xF0, OUT: Discard);
+    DEBUG_INSTR(IN: 0xA3, OUT: Discard);
+}
+   */
+}
+
+//! Fetch a byte of data memory.
+unsigned char peekdatabyte(unsigned int adr){
+  unsigned char
+    hb=(adr&0xFF00)>>8,
+    lb=adr&0xFF,
+    toret;
+
+  //MOV DPTR, adr
+  cc_debug(3, 0x90, hb, lb);
+  //MOVX A, @DPTR
+  //Must be 2, perhaps for clocking?
+  toret=cc_debug(3, 0xE0, 0, 0);
+  return toret;
+  
+    /*
+DEBUG_INSTR(IN: 0x90, HIBYTE(address), LOBYTE(address), OUT: Discard);
+for (n = 0; n < count; n++) {
+    DEBUG_INSTR(IN: 0xE0, OUT: outputArray[n]);
+    DEBUG_INSTR(IN: 0xA3, OUT: Discard);
+}
+  */
+}