PicShell - The DevZone

Basics :

Picshell is composed of two main parts : This page try to explain some concept of the engine part, so that you can use it to do your own program, or help me build a better PicShell (feel free to contact me if you are interested jumping into PicShell developement)...

More details about PicShell's Engine :



This diagram really looks more complex than it is... Most of the complexity (all that Inst, InstModel, Mnemonic ...) are used to gain some performance.

Here are the major actors behind the scene : There is also some utility class like Format which can be useful to display things.

Using the Pic Engine without UI :

Let's first start by writting a little program with JALv2 :
include pjal_877
include pic_general
pragma target clock 4_000_000
pragma target fuses 0x3F32

port_B_direction = all_output
forever loop

	PORTB = 1
	PORTB = 3
	PORTB = 5
	PORTB = 7

end loop
		
Compiling this code with JalV2 will produce an hex file... that looks like that :
:020000040000FA
:1000000007282108860008008312A1000128A0010A
:1000100083168601013004200330042005300420BB
:06002000073004200A284D
:02400E00323F3F
:00000001FF
		
We can now use the engine to dissamble that hex file, to view the asm instructions.
Here is a small python program that take the hex file, and displays its asm instructions.
Note that the hex may have been produced by another tool than JAL (even if it's still my favorite one !!!).
from picshell.engine.core.PicEngine import PicEngine
from picshell.engine.util.Format import Format
from picshell.engine.core.State import State

print "Start"

engine = PicEngine.newInstance(State(),"D:\\picshell\\examples\\test.hex")
for inst in engine.instructionList[:engine.lastAddress+1]:
    Format.dumpInstruction(inst)

print "End"

		
Which produce the following result :
Start
     0 GOTO      7
     1 MOVF(w)   33
     2 MOVWF(f)  6
     3 RETURN
     4 BCF       3, 5
     5 MOVWF(f)  33
     6 GOTO      1
     7 CLRF(f)   32
     8 BSF       3, 5
     9 CLRF(f)   6
    10 MOVLW     1
    11 CALL      4
    12 MOVLW     3
    13 CALL      4
    14 MOVLW     5
    15 CALL      4
    16 MOVLW     7
    17 CALL      4
    18 GOTO      10
End
		
Let's now execute this code once (the following program will execute the code till it reaches the last address and then the program will break. To dispay the result, we use an "Engine Monitor" which is called by the engine before and after each instruction's execution. Format.formatInstruction(inst, self.level, False) do some black magic for now to display the result.
from picshell.engine.core.PicEngine import PicEngine
from picshell.engine.util.Format import Format
from picshell.engine.core.State import State

class EngineMonitor :
    def __init__(self):
        self.level = 0

    def executeBefore (self,engine,inst):
        print Format.formatInstruction(inst, self.level, False)
    def executeAfter (self,engine,inst):
        if inst.model.mnemonic == "CALL"  :
            self.level += 1
        if inst.model.mnemonic == "RETURN" :
            self.level -= 1


# Code execution start here
print "Start"
engine = PicEngine.newInstance(State(),"D:\\picshell\\examples\\test.hex")
engine.monitors = [EngineMonitor()]
engine.runTillAddress(engine.lastAddress)
print "End"
		
Which produce the following result :
Start
     0 GOTO      7
     7 CLRF(f)   32
     8 BSF       3, 5
     9 CLRF(f)   6
    10 MOVLW     1
    11 CALL      4
     4 |  BCF    3, 5
     5 |  MOVWF(f) 33
     6 |  GOTO   1
     1 |  MOVF(w) 33
     2 |  MOVWF(f) 6
     3 |  RETURN
    12 MOVLW     3
    13 CALL      4
     4 |  BCF    3, 5
     5 |  MOVWF(f) 33
     6 |  GOTO   1
     1 |  MOVF(w) 33
     2 |  MOVWF(f) 6
     3 |  RETURN
    14 MOVLW     5
    15 CALL      4
     4 |  BCF    3, 5
     5 |  MOVWF(f) 33
     6 |  GOTO   1
     1 |  MOVF(w) 33
     2 |  MOVWF(f) 6
     3 |  RETURN
    16 MOVLW     7
    17 CALL      4
     4 |  BCF    3, 5
     5 |  MOVWF(f) 33
     6 |  GOTO   1
     1 |  MOVF(w) 33
     2 |  MOVWF(f) 6
     3 |  RETURN
    18 GOTO      10
End

		
Let's now say that we are not intersted in all this details, and that we just want to see what happend on PORTB. That's pretty easy to do using a "State monitor", like in this example :
from picshell.engine.core.PicEngine import PicEngine
from picshell.engine.core.State import State

class StateMonitor :
    def __init__(self):
        self.address = 6 # PORTB
    def execute(self,value):
        print value

# Code execution start here
#
print "Start"
engine = PicEngine.newInstance(State(),"D:\\picshell\\examples\\test.hex")
engine.state.setMonitors([StateMonitor()])
engine.runTillAddress(engine.lastAddress)
print "End"
		
Which produce the following result :
Start
1
3
5
7
End
		
Ok that's all for now, just send me an email if you are interested or need some more informations.