Electronics > Beginners
Assembly code Help! PIC16F57
<< < (8/32) > >>
Ian.M:
The PIC baseline program memory limitations are due to the short instruction word of the 12 bit core.  It takes 11 address bits for the full address range (2K words) possible for the baseline architecture.  The top two bits come from STATUS<6:5>, and the remaining 9 bits must be provided by the instruction.    GOTO is special - it has a three bit opcode, so has 9 address bits and can jump to any address, but CALL has a 4 bit opcode so only has an 8 bit address.  This maxes the upper 256 words of every 512 word page inaccessible to CALL. 

The easy fix is to put a jump table for subroutines in the bottom half of the page so their entry point is always at a callable address.

However IMHO the pain of wrestling with the baseline architecture just isn't worth it.  See my comments earlier about replacing it with a modern PIC.
KL27x:
^So the part that doesn't make sense to me is that the code assembles and apparently works just fine the way that the op posted it.
There are many subroutines between 0x400 and 0x600. But after adding the seven lines of code in this patch, I get error on the "call dummy" saying it has to be in the lower half of the page.

Now after moving this "dummy" subroutine to 0x600, it assembles without error. Meanwhile there are other subroutines left between 400f and 600f which (are still being called but) are still not causing that error. "slow" is located at 0x4EC, and it is called from code. And it does cause this error.

Also, what is half a page? In the midrange pics, a page is every 800f. So a half page would be 400f. What does the 600f line have to do with anything, then? 

There was no overwriting of code. I did not run out of space between any org instruction.

 :-// :-// :-//

Hang on, I'll change the org 600 instruction and see exactly where "dummy" was when it caused error.
* Ok. with the error, dummy is located at 0x503. So subroutines at 0x4EC work. At 0x600 works. At 0x503 it doesn't work. What the heck is half page in this context? Is it every 0x200 = a page? (With midrange, you have to long call/goto when passing a (0x800)"page" boundary, and this doesn't appear to be needed in this context)

That must be it, then. Pages are every 0x200, so half page is 0x100. When I added that code, I pushed dummy from 0x4ff to 0x500+? And the first part of the code 0x000 to 0x100 is the bottom half of the page, not the top half, like what you might expect looking at the "page on your screen" lol. If that isn't right, then I'll never figure it out. "Pages" are a totally different can of worms with the midrange. Actually (if this is right), the baseline is easier... once you finally get over the dyslexia. If there is no pagesel and longcalls, then as long as it assembles without error, it will worky?

Error[120]   Z:\EMBEDDED DESIGN\FIRMWARE\CLIP\FRUIT CLIP.ASM 181 : Call or jump not allowed at this address (must be in low half of page)
Electrofinn:
Wow OK I have a lot to go through here, it's was late over here in UK when I posted my last post so had to go to bed. Will report back when gone through it all.

When they said 3 bytes to spare I assumed they meant what was already there but I can not confirm nor deny this.
KL27x:
Yeah, I'm learning a lot, too.

In fact, after chewing on what Ian said, I'm pretty sure I borked the code.

I pushed dummy subroutine to another page, and now I'm pretty sure it is not going to work. I think on these baseline, there is no way to cross page boundary with long calls and pagesel.... hmm...

sorry, been a long time.

Now that I see what I did wrong, I think "the 3 lines left of program memory" that you were told was because of this, exactly! So hmm.. I have to take another look here. What I posted up there is not going to work!
KL27x:
Code addendum:

So, here it is... don't do step 5 from my previous code post

Do step 1 through 4. And do step 6 :) .

And you will get a error because I added a few lines of code to page 400f-600f. And this pushed "dummy" across a half page boundary. So to fix it, I have reclaimed 4 lines of code with these changes.

1.
timeout1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;    incf   counter_lo,f
;   btfss   status,zer
   incfsz   counter_lo,f            ;saves one line
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   goto   timend
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   decf   counter_hi,f
;   btfss   status,zer
   decfsz    counter_hi,f             ;saves one line
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   goto   timend
   bcf   mode_byte,7
   bcf   mode_byte,0
   bsf   mode_byte,5         ; incf/decf affect status Z. But...
timend   retlw   00                ; incfsz doesn't affect status,Z. But timeout1 is called from extimeout, and I see no checks of Z after the return. So I think it's ok.

2.
sequence1   
      bsf      counter_lo,7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;      incf   counter_lo,f
;      btfss   status,zer           
      incfsz counter_lo,f          ;save one line of code. against have to figure out is status,Z is importance after the return. So maybe ok.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      goto   sequend
      incf   counter_hi,f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;insert this code
      movlw   .1                     ;this is the 3 lines I added in the previous post
      btfsc   counter_hi,4
      xorwf   new_byte,f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   bcf      counter_hi,4   ;this must go back to the original bcf counter_hi,4
   movf   credit_count,f
   btfsc   status,zer
   goto   sequend
   bcf   mode_byte,7
   bcf   mode_byte,5
   bsf   mode_byte,0
sequend   retlw   00                 ;sequence1 is a branch from sequence, and this is called from exsequence,
                                           ; and I see no checks of Z after this return. So I think it's fine that incfsz doesn't affect Z like incf does.

3.
start3
   clrf   fsr
   bcf   mode_byte,0      
   bsf   mode_byte,1
   bcf   portC,2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   clrw
;   movwf   counter_hi
;   movwf   counter_lo
   clrf counter_hi                  ;save 1 line
   clrf counter_lo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   bcf   function_byte,7   
starend   retlw   00                  ;and retlw 00 loads 0 in W register. So clrw should not be missed for this reason. RETLW doesn't affect status Z;
                                              ;the clrw instruction sets Z bit. But... clrf also sets Z. So absolutely no worries on this one.
                                               


These changes bring "dummy" subroutine back to 0x4FE in program memory to stay on the same page as it is supposed to be, which I believe is page 2 (starting from 0). So now we have room for one more line of additional code in the future!!! :phew:

Also, I chanced upon STATUS, <6,5> are how pages are selected, and pages are 512 "words" which is simply more confusing to me. So yes, pages have to be selected, and it will be nice to keep everything on the page it started with, esp if you are a hack like me that can't figure out this nonsense. (Took me long enough to figure out the midrange). 
Navigation
Message Index
Next page
Previous page
There was an error while thanking
Thanking...

Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod