Jump to content

Computed Goto And Auto Bank Selection


Recommended Posts

Hi,

 

Not sure if this is a bug, or if it has been seen before. I'm using SourceBoost V6 upgraded from the previous v5 version.

 

The problem is the automatic bank select code is not working. More to the point, it is working up to a point, then doesn't. I can't figure out why.

 

I've got code in an asm segment, which is referring to some variables I've let the compiler allocate. When I look at the assembly, it's put them into bank1. I'm also using bank0 registers like checking port inputs.

 

The compiler correctly inserts proper RP0,RP1 statements up to the last bit of the code below when I look at the code view....however for some reason it then stops putting bank select statements in....(my comments in <<<<<>>>>)

 

In my INP_MEASURE computed goto below, the increment of the sw_measure variable has no bank select statements, while the previous section in INP_CONFZERO has them correctly set up when the same variable was clrf'd.

 

I can only think that somehow the compiler has got it into it's head that the bank select statements set up in INP_CONFZERO carry through to INP_MEASURE and there is no need to add them....but why did it sort things out OK in INP_CONFZERO?

 

What's going on? For now I've moved my variables explicitly into bank0.....but I'd rather let the compiler do the allocation.

 

The bank <variable> directive in c2c doesn't seem to work in boostc...is there an alternative?

 

Phil

 

 

note variables sw_state and sw_measure are defined as:

unsigned char sw_state;

unsigned char sw_measure;

INP_PORT is #define INP_PORT _porta

 

 

The asm file created shows them as allocated to bank1....located 0xec, 0xed

 

void inp_scan(void)

{

asm

{

<<<<compiler correctly switches to bank 1>>>

movf _sw_state,W ;just to current state

<<<<<then switches to bank 0 to calculate pcl change>>>>>>

addwf _pcl,F

goto INP_IDLE

goto INP_CONFZERO

goto INP_MEASURE

goto INP_CONFMEASURE

<code snipped>

goto INP_EXIT

INP_IDLE:

btfsc INP_PORT,INP_PIN

goto INP_EXIT

INP_CONFZERO:

movlw IN_IDLE

<<<<compiler correctly switches to bank1>>>>

movwf _sw_state

<<<<compilr correctly switches to bank 0>>>>>

btfsc INP_PORT,INP_PIN

goto INP_EXIT

movlw IN_MEASURE

<<<compiler still gets it right, and correctly switches to bank 1>>>>>

movwf _sw_state

clrf _sw_measure

goto INP_EXIT

INP_MEASURE:

<<<<doh....after getting it right all this time, now it 'forgets' to switch to bank 1

incf _sw_measure,F

movlw MEASURE_MAX

<<<<remaining cod has no bank select instructions inserted by compiler>>>>>

Link to post
Share on other sites

ppulle,

 

The memory allocation and bank switching is performed by the Linker (boostlink.pic.exe).

 

The linker is quite clever in that it runs through the code and all execution paths, keeps track of which bank is required and adds in the appropriate bank switching.

 

Linker has a problem with inline assembler that modifies PCL. Linker does not know the range of values that PCL may be loaded with, so it can't follow the possible valid branches. Sadly linker does not have your brain :(

 

Also another problem here is that the code may staddle a code page boundary, in which case some of the gotos may need PCLATH setting, this then totally messes up the the jump table.

 

My recommendation is do not use code that modifies PCL to change the code flow of control.

 

Use switch case instead.

 

Regards

Dave

Regards

Dave

Link to post
Share on other sites

Thanks for the confirmation Dave, I thought it might be something like that. Looking at the most assembly the linker is indeed very clever, though I didn't expect that you guys had figured out a way of making it read my mind!! Fair enough.

Do have a suggestion though, how about getting the linker to put up a warning when it sees a 'addwf pcl' line.....to remind the user to check out the source..it's pretty much second nature now having used PIC assembly for a while, but new wonder what's happening.

 

Incidentally, I was considering changing the state machine code to something like

movf _sw_state,W

xorlw STATE1

btfsc _status,Z

goto DO_STATE1

movf _sw_state,W

xorlw STATE2

btfsc _status,Z

goto DO_STATE2......and so on....have to keep it in assembly as it's an interrupt routine.

 

Is this a reasonable alternative.....or have you guys (or forum members) figured out a more efficient state/jump method?

 

phil

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...