Truncated match.
PICList
Thread
'Program over 1k with a 16F877'
2000\04\12@090705
by
David Thompson
Hi guys,
My program is rapidly approaching the 1k mark and there is still a lot of
code to write. The development system uses a 16F877, but the final design
will probably use a smaller PIC - maybe a 16C73.
The question is, are there any things to look out for when crossing page
boundaries (2k with these chips, I think), or more particularly, are there
any tricks to lessen the hassle of doing so?
I've seen macros to do "long calls" and that kind of thing, which is why I
am asking.
Thanks,
Dave.
2000\04\12@184830
by
Tony Nixon
|
David Thompson wrote:
>
> Hi guys,
>
> My program is rapidly approaching the 1k mark and there is still a lot of
> code to write. The development system uses a 16F877, but the final design
> will probably use a smaller PIC - maybe a 16C73.
>
> The question is, are there any things to look out for when crossing page
> boundaries (2k with these chips, I think), or more particularly, are there
> any tricks to lessen the hassle of doing so?
>
> I've seen macros to do "long calls" and that kind of thing, which is why I
> am asking.
>
> Thanks,
>
> Dave.
The GOTO and CALL instructions can be used in any 2K bank of ROM space.
PCLATH bits 4 and 3 are always concatenated onto these instructions.
That gives four 2K banks to select from.
PCLATH 4 3
0 0 0h - 7FFh 2K
0 1 800h - FFFh 4K
1 0 1000h - 17FFh 6K
1 1 1800h - 1FFFh 8K
Just check to resulting *.lst file if you suspect one of these
instructions jumped a page boundary.
--
Best regards
Tony
http://www.picnpoke.com
spam_OUTsalesTakeThisOuT
picnpoke.com
2000\04\12@210709
by
Jeffrey D Spears
|
Hi David;
I have seen two replies to your query. Both seem valid--but here is
another anyway:
When I first got my nice new big flash pics and began to play around, I
found myself asking the same question you are. Although my fooling around
hasn't approached the physical page boundary, its seems good practice to
begin writing code suitable for use with all this extra program store now.
So, I went ahead and figured out how to use the linker (MPLINK). At first
I got the linker going at the command line since it was easier than in
MPLAB. This went fairly straight forward and showed me what it all looks
like. Getting my first set of object files to link in MPLAB required a
fair amount of time. Setting up that project configuration node thing
is a bear the first time!
MPASM can produce object files. These object files have no idea where
the program and file registers will live. The object file has built in
little hooks for the linker to grab onto and assign various address
locations. If we are very careful about how we write the source files,
the object files can live anywhere and call functions (subroutines)
from other object files without prior knowledge of which page they live
in.
I recommend you figure out how to use the linker. Although you can surely
do all this by hand, the benefits of time spent learning the linker will
pay off with a new level of abstraction with sound supporting methods.
Once you get the thing going, you will realize how cool it is.
This term runs out next week. Once school is out, I will be writing some
pic code. Intend to test out the MPLIB library program for making libraries
of common routines. Apparently, libraries are nothing more than a collection
of object files jammed into one file. Once code is written, it can be added
to a library file and then called by the linker. Hope this keeps me from
rewriting code!
Have fun.
ok..jef
Jeffrey D. Spears
University of Michigan
College of Engineering
``Double-E, can't spell gEEk without it!''
-Captain Gerald M. Bloomfield II, USMC
(my brother)
2000\04\13@102813
by
M. Adam Davis
|
When you are about to cross page boundaries, usually you end up putting the
less-frequently used code modules in the second and later pages, and you try to
stay within a single page as much as possible. If you are building a network
node, for instance, you may want to put your serial input and packet handling
routines all in the second page. When a packet comes in, you'll spend the bulk
of your time there, instead of jumping to and from the first page or other
pages.
The only thing you need to do to jump into a different page is load PCLATH:3 & 4
with the two upper bits of the new page before executing the jump instruction.
You don't need to change the pclath for returns since the full address of the
location to return to is stored on the stack. PCLATH retains its last setting,
so if you set it for the second page, jump to it, and return from it, your next
call or goto will also go to the second page unless you reset the PCLATH. This
is useful for staying in the 'current' page if you are careful about not
changing the PCLATH during interrupts and in other functions.
On the part in question, the PCLATH bits you need to know about are bits 3 and
4. The lower bits (0-2) are not used in gotos and calls and are ignored (they
are used when you write to the PCL). PCLATH is just a holding register, and
will never be referenced until a CALL, GOTO, or writing to PCL.
ORG 0
Start 'This resides in the first page. Calls to
'functions past this page need PCLATH updated.
CALL FuncIn1stPage 'Jump to function that starts in this page
MOVLW B'00001000' 'Next call will go to the second page
MOVWF PCLATH
CALL FuncIn2ndPage
MOVLW B'00010000' 'Next call will go to the third page
MOVWF PCLATH
CALL FuncIn2ndPage
MOVLW B'00011000' 'Next call will go to the fourth page
MOVWF PCLATH
CALL FuncIn2ndPage
...
...
ORG 0x7FF 'This next function will cross page boundaries
'Which is fine, the program counter can handle
'that, and it won't mess the return up.
'Do not allow computed gotos to cross page
'boundaries, though, without thinking of PCLATH
FuncIn1stPage 'This function starts in the first page, but
'crosses into the second page.
MOVLW .42 'Don't Panic! This instruction is in the
'1st Page
...
MOVLW B'00001000' 'This instruction is in the second page.
MOVWF PCLATH 'Since we are in the second page now we don't
CALL FuncIn2ndPage 'need to set the PCLATH, right? Wrong. So why
'did we set it? The PCLATH hasn't changed.
'Whatever was in it before is still in it,
'and will affect our calls and gotos.
'In this case, the last thing that modified
'it before this function was the device reset,
'which always makes it b'---00000'
'If we use a jump or call before setting it,
'we'll end up somewhere in the first page.
RETURN 'This instruction is in the second page
FuncIn2ndPage 'Function starts in the second page
MOVLW B'00000000' 'Next call will go to the first page
MOVWF PCLATH
CALL FuncIn1stPage
RETURN
ORG 0x1000 'Function starts in the 3rd page
FuncIn3rdPage
... 'If you are in the third page, and you jump
MOVLW B'00010000' 'to another third page location, you can
MOVWF PCLATH 'probably assume that the PCLATH contains
CALL SubIn3rdPage ' B'00010000' because we had to do that to
'jump into the third page before. But I
'wouldn't assume that myself, unless I
'absolutely HAD to save those two extra cycles.
'If you execute a call or goto without knowing
'what's in PCLATH, you can end up in the
'weirdest places, and debugging is a living
'nightmare...
'Tis better to be safe than sorry.
RETURN
SubIn3rdPage
...
RETURN
ORG 0x1800 'Function starts in 4th page
FuncIn4thPage
...
RETURN
I think this covers about all the bases you need to know to cross page
boundaries. This information was taken from the 16c6x data sheet, section 4.3
p.48 on PCL and PCLATH. Before you start writing code based on what I've
written above, read that section (it's short) or the similar section in the
16f8xx sheet.
I hope this helps!
-Adam
David Thompson wrote:
{Quote hidden}>
> Hi guys,
>
> My program is rapidly approaching the 1k mark and there is still a lot of
> code to write. The development system uses a 16F877, but the final design
> will probably use a smaller PIC - maybe a 16C73.
>
> The question is, are there any things to look out for when crossing page
> boundaries (2k with these chips, I think), or more particularly, are there
> any tricks to lessen the hassle of doing so?
>
> I've seen macros to do "long calls" and that kind of thing, which is why I
> am asking.
>
> Thanks,
>
> Dave.
2000\04\13@115058
by
Quitt, Walter
|
Isn't that what the PAGESEL directive does??????
-----Original Message-----
From: M. Adam Davis [.....adavisKILLspam
@spam@UBASICS.COM]
Sent: Thursday, April 13, 2000 7:26 AM
To: PICLIST
KILLspamMITVMA.MIT.EDU
Subject: Re: Program over 1k with a 16F877
When you are about to cross page boundaries, usually you end up putting the
less-frequently used code modules in the second and later pages, and you try
to
stay within a single page as much as possible. If you are building a
network
node, for instance, you may want to put your serial input and packet
handling
routines all in the second page. When a packet comes in, you'll spend the
bulk
of your time there, instead of jumping to and from the first page or other
pages.
The only thing you need to do to jump into a different page is load PCLATH:3
& 4
with the two upper bits of the new page before executing the jump
instruction.
You don't need to change the pclath for returns since the full address of
the
location to return to is stored on the stack. PCLATH retains its last
setting,
so if you set it for the second page, jump to it, and return from it, your
next
call or goto will also go to the second page unless you reset the PCLATH.
This
is useful for staying in the 'current' page if you are careful about not
changing the PCLATH during interrupts and in other functions.
On the part in question, the PCLATH bits you need to know about are bits 3
and
4. The lower bits (0-2) are not used in gotos and calls and are ignored
(they
are used when you write to the PCL). PCLATH is just a holding register, and
will never be referenced until a CALL, GOTO, or writing to PCL.
ORG 0
Start 'This resides in the first page. Calls to
'functions past this page need PCLATH
updated.
CALL FuncIn1stPage 'Jump to function that starts in this page
MOVLW B'00001000' 'Next call will go to the second page
MOVWF PCLATH
CALL FuncIn2ndPage
MOVLW B'00010000' 'Next call will go to the third page
MOVWF PCLATH
CALL FuncIn2ndPage
MOVLW B'00011000' 'Next call will go to the fourth page
MOVWF PCLATH
CALL FuncIn2ndPage
...
...
ORG 0x7FF 'This next function will cross page
boundaries
'Which is fine, the program counter can
handle
'that, and it won't mess the return up.
'Do not allow computed gotos to cross page
'boundaries, though, without thinking of
PCLATH
FuncIn1stPage 'This function starts in the first page, but
'crosses into the second page.
MOVLW .42 'Don't Panic! This instruction is in the
'1st Page
...
MOVLW B'00001000' 'This instruction is in the second page.
MOVWF PCLATH 'Since we are in the second page now we
don't
CALL FuncIn2ndPage 'need to set the PCLATH, right? Wrong. So
why
'did we set it? The PCLATH hasn't changed.
'Whatever was in it before is still in it,
'and will affect our calls and gotos.
'In this case, the last thing that modified
'it before this function was the device
reset,
'which always makes it b'---00000'
'If we use a jump or call before setting it,
'we'll end up somewhere in the first page.
RETURN 'This instruction is in the second page
FuncIn2ndPage 'Function starts in the second page
MOVLW B'00000000' 'Next call will go to the first page
MOVWF PCLATH
CALL FuncIn1stPage
RETURN
ORG 0x1000 'Function starts in the 3rd page
FuncIn3rdPage
... 'If you are in the third page, and you jump
MOVLW B'00010000' 'to another third page location, you can
MOVWF PCLATH 'probably assume that the PCLATH contains
CALL SubIn3rdPage ' B'00010000' because we had to do that to
'jump into the third page before. But I
'wouldn't assume that myself, unless I
'absolutely HAD to save those two extra
cycles.
'If you execute a call or goto without
knowing
'what's in PCLATH, you can end up in the
'weirdest places, and debugging is a living
'nightmare...
'Tis better to be safe than sorry.
RETURN
SubIn3rdPage
...
RETURN
ORG 0x1800 'Function starts in 4th page
FuncIn4thPage
...
RETURN
I think this covers about all the bases you need to know to cross page
boundaries. This information was taken from the 16c6x data sheet, section
4.3
p.48 on PCL and PCLATH. Before you start writing code based on what I've
written above, read that section (it's short) or the similar section in the
16f8xx sheet.
I hope this helps!
-Adam
David Thompson wrote:
{Quote hidden}>
> Hi guys,
>
> My program is rapidly approaching the 1k mark and there is still a lot of
> code to write. The development system uses a 16F877, but the final design
> will probably use a smaller PIC - maybe a 16C73.
>
> The question is, are there any things to look out for when crossing page
> boundaries (2k with these chips, I think), or more particularly, are there
> any tricks to lessen the hassle of doing so?
>
> I've seen macros to do "long calls" and that kind of thing, which is why I
> am asking.
>
> Thanks,
>
> Dave.
2000\04\13@163605
by
M. Adam Davis
PAGESEL:
For use when generating an object file. An instruction to the linker to generate
page selecting code to set the page bits to the page containing the designated
<label>. Only one <label> should be specified. No operations can be performed on
<label>. <label> must have been previously defined.
So it is intended to work with the linker, I haven't tried it within regular
code.
-Adam
"Quitt, Walter" wrote:
>
> Isn't that what the PAGESEL directive does??????
>
> {Original Message removed}
2000\04\13@184031
by
Thorsten Klose
To wrap around the problem I wrote two macros which produce smaller
code than the "lgoto" and "lcall" macros from MPASM.
They are for 1k devices but can be easily extended for 2k PICs
(only 4 cases to check)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XGOTO MACRO label
if label & 0x800
bsf PCLATH, 3
else
bcf PCLATH, 3
endif
goto label
ENDM
XCALL MACRO label
LOCAL testlabel
testlabel:
if label & 0x800
bsf PCLATH, 3
else
bcf PCLATH, 3
endif
call label
if testlabel & 0x800
bsf PCLATH, 3
else
bcf PCLATH, 3
endif
ENDM
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does the linker produce the same efficient code?
Best Regards, Thorsten.
--
_____________________________________________
_/ uC-Stuff for MIDI at http://go.to/uCApps /_______
/ Music is aesthetisized frequency (Klaus Schulze) /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2000\04\14@090809
by
David Thompson
Hi there,
Fabulous answer, lots of detail and a million comments. Much appreciated!
Dave.
----- Original Message -----
From: M. Adam Davis <.....adavisKILLspam
.....UBASICS.COM>
To: <EraseMEPICLISTspam_OUT
TakeThisOuTMITVMA.MIT.EDU>
Sent: Friday, April 14, 2000 12:26 AM
Subject: Re: Program over 1k with a 16F877
> When you are about to cross page boundaries, usually you end up putting
the
> less-frequently used code modules in the second and later pages, and you
try to
> stay within a single page as much as possible. If you are building a
network...
2000\04\14@141900
by
Quitt, Walter
|
In response to the question at the end of this post:
"Does the linker produce the same efficient code?"
My latest MPLAB project produces the following
from the .lst file for a 16F877 using the XCALL macro:
Error[151] C:\WINDOWS\DESKTOP\WALT\KEYER\MAIN.ASM 44 : Operand contains
unresolvable labels or is too complex
Error[151] C:\WINDOWS\DESKTOP\WALT\KEYER\MAIN.ASM 50 : Operand contains
unresolvable labels or is too complex
But produces the following with PAGESEL directive:
001973 3019 MOVLW 0x19 PAGESEL IO
001974 008a MOVWF 0xa
001975 217e CALL 0x17e call IO
This is how I call routines because I write totally (almost)
relocatable code. Do you hear the drum beat of relocatable
code? A careful review of the 16f87x data sheet page 26 of
DS30292B should show that you can address any routine anywhere
with in the 8K data space this way.
The same can be accomplished with:
MOVLW HIGH (SUBROUTINE_NAME)
MOVWF PCLATH
CALL LOW (SUBROUTINE_NAME)
This produces EXACTLY the same in my project as
shown:
001976 3019 MOVLW 0x19 movlw HIGH IO
001977 008a MOVWF 0xa movwf PCLATH
001978 2181 CALL 0x181 call LOW IO
The above is something I saw long ago in some MChip literature.
You really don't need to worry where any routine is in the
16F87x if you call with one of the two above methods.
If you are always in the same page then just use a CALL instruction.
If you write big programs (me) then always calling in the above
manner saves a lot of grief. Using relocatable code structure
also keeps me from worrying about having to figure out where to
load stuff via the org statement (generally.)
So linker or not choose your method.
"That's all I have to say about that."
-Walt...
{Original Message removed}
2000\04\14@155805
by
jamesnewton
So... you don't ever pass a parm in W? Does the linker tell you that W is
getting trashed on every goto or call? I must be missing something...
And the linker uses W(!) and two instructions prior to the call to access 8k
of address space rather than leaving W alone and using one instruction to
address within 2k, two for 4k, or 3 for 8k?
PCL goto or call
--- -----------
xxx XX XXXXXXXX 8K
0xx XX XXXXXXXX 8K
00x XX XXXXXXXX 2K
Boy am I going to miss the PAGE and RETP instructions if I move from the
Scenix SX to the Microchip '877.
BTY, Did anyone else get signed up for the seminar in August at the Rancho
Bernardo Raddison? The
http://buy.microchip.com
website working for a while and did accept my registration. Its F'd up now
but phone registrations are accepted. Special offer of an ICD for $80 (I
think) with seminar registration. Kelly and I are trying to get a tailgate
party together before or after the seminar so if you are in the San Diego
area please let us know that you will come drink some microbrew (or soda)
and say hello!
---
James Newton jamesnewton
spam_OUTgeocities.com 1-619-652-0593
{Original Message removed}
2000\04\14@161048
by
Dan Michaels
Jim Newton wrote:
....
>
>Boy am I going to miss the PAGE and RETP instructions if I move from the
>Scenix SX to the Microchip '877.
>
This is clearly **the best thing** scenix did when they hyperextended
the PIC. Some other things they did, like no RTIF flag, and no ability
to use the RTCC pin for general I/O, I'm not so sure about.
2000\04\14@180704
by
Thorsten Klose
|
"Quitt, Walter" wrote:
[..]
> You really don't need to worry where any routine is in the
> 16F87x if you call with one of the two above methods.
>
> If you are always in the same page then just use a CALL instruction.
> If you write big programs (me) then always calling in the above
> manner saves a lot of grief. Using relocatable code structure
> also keeps me from worrying about having to figure out where to
> load stuff via the org statement (generally.)
>
> So linker or not choose your method.
Hey, i'm driving very good with my method and yes, I write also
programs which are bigger than 4k ;-) If you have to optimize
your code for program size and execution time, if your are using
nested subroutines and many condition tables, you will also
search for a better solution sooner or later...
Best Regards, Thorsten.
--
_____________________________________________
_/ uC-Stuff for MIDI at http://go.to/uCApps /_______
/ Music is aesthetisized frequency (Klaus Schulze) /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2000\04\14@184332
by
Quitt, Walter
I've spent some time testing and all I want to say is that
the XCALL macro method does not (as written) work with the
assemble and then link process in a MPLAB project environment.
The assembler just can't deal with it. Hence it can't be
linked. I think it is because it can't deal with that far
forward looking code generation. That's why it says:
Error[151] Operand contains unresolvable labels or is too complex
When I try to assemble
XCALL Subroutine_name
In the MPLAB USER'S GUIDE with MPLINK and MPLIB it says in regards
to Error[151]:
When generating an object file, operands must be of the form
[HIGH|LOW(<relcatabvle address label>]+[<offset>]
So I'll rewrite it and try to make it work in a project environment.
I like the idea and that's why I am pursuing it.
Walt...
{Original Message removed}
More... (looser matching)
- Last day of these posts
- In 2000
, 2001 only
- Today
- New search...