+def dump_pm( start_addr, stop_addr, pretty=False ):
+ """Dump routine, now encapsulated in a function.
+Returns an instance of IntelHex corresponding to result.
+
+Note that we start and stop an ICSP session here! This means an
+existing session will be broken."""
+ readpm_cmd_li = [0x200000, # MOV #addr<23:16>, W0
+ 0x880000 | tblpag << 3, # MOV W0, TBLPAG
+ 0x200006, # MOV #addr<15:0>, W6
+ 0xEB0380, # CLR W7
+ 0x000000, # NOP
+ 0xBA1B96, # TBLRDL [W6], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBADBB6, # TBLRDH.B [W6++], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBADBD6, # TBLRDH.B [++W6], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBA1BB6, # TBLRDL [W6++], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBA1B96, # TBLRDL [W6], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBADBB6, # TBLRDH.B [W6++], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBADBD6, # TBLRDH.B [++W6], [W7++]
+ 0x000000, # NOP
+ 0x000000, # NOP
+ 0xBA0BB6, # TBLRDL [W6++], [W7]
+ 0x000000, # NOP
+ 0x000000] # NOP
+
+ dumphex = IntelHex()
+
+ startICSP()
+
+ print "Reading program memory 0x%06X:0x%06X ..." % ( start_addr, stop_addr )
+ # Prep device
+ client.writecmd( PICAPP, 0x82, 3, [0x00,0x02,0x04] ) #GOTO 0x200 (reset)
+ client.writecmd( PICAPP, 0x82, 3, [0x00,0x02,0x04] ) #GOTO 0x200 (reset)
+ client.writecmd( PICAPP, 0x82, 3, [0x00,0x00,0x00] ) #NOP (pump clock)
+
+ last_highb = -1 # Only set TBLPAG when needed.
+ packed_instr_list = [0,0,0,0,0,0] # For packing 4 (24-bit) instructions in 6 (16-bit) words
+ for addr in range( start_addr&0xfffff8, stop_addr+8, 8 ):
+ if (addr>>16)&0xff != last_highb:
+ last_highb = (addr>>16)&0xff;
+ specify_addr_cmd = [readpm_cmd_li[0] + ((addr & 0xff0000)>>12),
+ readpm_cmd_li[1],
+ readpm_cmd_li[2] + ((addr & 0xffff)<<4)]
+ else:
+ specify_addr_cmd = [readpm_cmd_li[2] + ((addr & 0xffff)<<4)]
+ runlist( specify_addr_cmd + readpm_cmd_li[3:] )
+
+ for reg_num in range(6): # Read W0:5, to get packed instructions
+ packed_instr_list[reg_num] = readreg( reg_num )
+ instr_list = words2instr( packed_instr_list )
+
+ for offset in range(4): # Print result
+ if addr+offset*2 < start_addr:
+ continue
+ if addr+offset*2 > stop_addr:
+ break
+ dumphex.puts( ((addr+offset*2)&0xffffff)*2,
+ chr(instr_list[offset]&0xff)
+ +chr((instr_list[offset]>>8)&0xff)
+ +chr((instr_list[offset]>>16)&0xff)
+ +chr(0) )
+ if pretty:
+ print "0x%06X 0x%06X" % (addr+offset*2,instr_list[offset])
+
+ stopICSP()
+
+ return dumphex
+
+