Searching \ for '[PIC] Code packing' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Code packing'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Code packing'
2008\07\04@075016 by Jinx

face picon face
Have this EEPROM storage in an 18F MPLAB project

de  d25                          ;baud rate
de  d36,d38,d48,d47,d51,d49,d46  ;sensors 0 - 6
de  d42,d0,d63,d127,d0,d0        ;sensors 7 - 12

What happens is that the data is actually stored as 25,0,36,38, ....

The notes in Assembler Help say that odd numbers of de and db
will be packed with a 0, and that to not pack you must use the
code_pack directive when creating an object file. To me though,
the "oddness" is simply because d25 is on one line, and the next
address is on the following. The intention is for contiguous data.
As I'm not creating an object file, I can't use code_pack

I'm not short of EE space so it actually doesn't matter in this instance
if data is packed with zeroes. Although I'll have to make sure that EE
reads get the right data. It's just one of those "why do they do that ?"
questions. And "can I do it a different way ?"

TIA

2008\07\04@081808 by olin piclist

face picon face
Jinx wrote:
> Have this EEPROM storage in an 18F MPLAB project
>
> de  d25                          ;baud rate
> de  d36,d38,d48,d47,d51,d49,d46  ;sensors 0 - 6
> de  d42,d0,d63,d127,d0,d0        ;sensors 7 - 12
>
> What happens is that the data is actually stored as 25,0,36,38, ....

Right.  You need to use DB and make sure it is in a CODE_PACK section, not
CODE section.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\04@085414 by Jinx

face picon face
> > What happens is that the data is actually stored as 25,0,36,38, ....
>
> Right.  You need to use DB and make sure it is in a CODE_PACK section,
> not CODE section

Think you'll have to help me out a little with this

MPLAB says

[label] code_pack [ROM_address]

This directive declares the beginning of a section of program
code or ROM data where a padding byte of zero is not appended
to an odd number of bytes. If label is not specified, the section
is named .code. The starting address is initialized to ROM_address
or will be assigned at link time if no address is specified. If
ROM_address is specified, it must be word-aligned. If padded data
is desired, use db

So, I tried (using the 18F4550 EEPROM absolute address, although
any address I use generates the same errors)

309 ee_init code_pack 0xf00000
310
311 de  .25                             ;baud rate
312 de  .36,.38,.48,.47,.51,.49,.46     ;sensors 0 - 6
313 de  .42,.62,.63,.127,.43,.71,.83    ;sensors 7 - 12

and get

Error[149]   309 : Directive only allowed when generating an object file
Warning[220] 311 : Address exceeds maximum range for this processor.
Error[118]   311 : Overwriting previous address contents (0006)
......
Warning[220] 318 : Address exceeds maximum range for this processor.
Warning[220] 318 : Address exceeds maximum range for this processor.
Warning[220] 318 : Address exceeds maximum range for this processor.
Halting build on first failure as requested.
BUILD FAILED: Sat Jul 05 00:41:21 2008

Could the reason be that I'm using absolute rather than relocatable ?

2008\07\04@093719 by Jan-Erik Soderholm

face picon face
Jinx wrote:

> Error[149]   309 : Directive only allowed when generating an object file

> Could the reason be that I'm using absolute rather than relocatable ?

Yes, That's is what Error-149 was trying to tell you.

"generating an object file" = "using relocatable mode".


Jan-Erik.

2008\07\04@103556 by olin piclist

face picon face
Jinx wrote:
> 309 ee_init code_pack 0xf00000
> 310
> 311 de  .25                             ;baud rate
> 312 de  .36,.38,.48,.47,.51,.49,.46     ;sensors 0 - 6
> 313 de  .42,.62,.63,.127,.43,.71,.83    ;sensors 7 - 12

Again, I think you want DB not DE, but otherwise this looks fine.  Also,
while F00000h is correct for all 18F as far as I know, it is different for
other PICs.  I don't like hard coding the EEPROM start address into the
code, so I use the symbol EE_START which is defined seperately depending on
the processor being built for.  Of course CODE_PACK won't port to other than
a PIC 18, but I still think it's better to use a symbol.  A symbol like
EE_START is a better hint than F00000h unless the reader happened to
remember that EEPROM starts there on PIC 18.

> Error[149]   309 : Directive only allowed when generating an object
> file

Somehow you got into absolute mode.  CODE, CODE_PACK, UDATA, etc are not
supported in absolute mode.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\04@110603 by Jan-Erik Soderholm

face picon face
Olin Lathrop wrote:

>> Error[149]   309 : Directive only allowed when generating an object
>> file
>
> Somehow you got into absolute mode.  CODE, CODE_PACK, UDATA, etc are not
> supported in absolute mode.

AFAIK, relocatable/absolut mode is selected by either including
the Linker Script file to the project, or not including it.

Is there any other way to "get into" one mode or the other ?

Jan-Erik.

2008\07\04@114107 by olin piclist

face picon face
Jan-Erik Soderholm wrote:
> AFAIK, relocatable/absolut mode is selected by either including
> the Linker Script file to the project, or not including it.
>
> Is there any other way to "get into" one mode or the other ?

The /o command line switch to MPASMWIN.  Adding a linker file to the project
is only meaningful from within the IDE.  The IDE then passes the /o command
line option to the assembler, runs MPLINK, etc.  You can do all this
yourself with scripts or other programs, of course.

Building in the IDE might be a quick shortcut for doing a one-off hobby
project, but real projects always have other things that need to get built,
other tools that need to be run, the build needs to be automated, and you
usually want to use a common editor for everything.  The IDE is only useful
for debugging for serious projects.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\04@143815 by Jan-Erik Soderholm

face picon face
Olin Lathrop wrote:

> Jan-Erik Soderholm wrote:
>> AFAIK, relocatable/absolut mode is selected by either including
>> the Linker Script file to the project, or not including it.
>>
>> Is there any other way to "get into" one mode or the other ?
>

> The /o command line switch to MPASMWIN.  Adding a linker
> file to the project is only meaningful from within the IDE.

Right, and the IDE is where 99% of the piclist members
probably run their projects. :-) :-)

*I* ment within the IDE, of course.

> Building in the IDE might be a quick shortcut for doing a
> one-off hobby project, but real projects always have other
> things that need to get built,...

*Some* of these needs might be solved
by the new pre- and post-processing that was included
in the IDE just a few versions ago. I do not agree that
one can *not* build a "real project" using the MPLAB IDE.

> other tools that need to be run, the build needs to be
> automated, and you usually want to use a common
> editor for everything.

Yes, just as a proof of concept, I created an environment
built on UltraEdit where all builds and flashing was run
from within the UE-IDE. UltraEdit also has an extra
full-feature IDE where such tasks as "make" are built-in.

> The IDE is only useful
> for debugging for serious projects.

And again, for quite a lot of the piclist readers "serious
projects" can probably be edited and build just fine using
the MPLAB-IDE only...

Jan-Erik.

2008\07\04@184959 by Jinx

face picon face
> And again, for quite a lot of the piclist readers "serious
> projects" can probably be edited and build just fine using
> the MPLAB-IDE only...

I know Olin is an advocate for relocatable and its benefits but.....
every project/product I've ever done for the last dozen years has
been for a particular chip, and absolute code built with MPASM
has never been a problem. Code ends up where it's meant to
and runs fine

If I hadn't put a single "de" on a line I wouldn't have even been
confronted with code_pack. Still don't know why it's necessary
at all to pack 8-bit memory with 0

2008\07\04@195225 by Jinx

face picon face
> Again, I think you want DB not DE, but otherwise this looks fine

I'd generally use db for something like '0'-terminated strings in program
memory and de for EEPROM. Just my way of doing things, and de is
a reminder of which memory the data is going to

> Also, while F00000h is correct for all 18F as far as I know, it is
> different for other PICs

There's just 0x2100 and 0xF00000. Had a glance at the 30F3012
d/s (might be looking at a project that would suit a 3040) and
EEPROM handling appears quite different for that range

> I don't like hard coding the EEPROM start address into the code,
> so I use the symbol EE_START which is defined seperately
> depending on the processor being built for

That's a definition that you'd think *should* be in the .inc file. Now
that you mention it, I'll do that

> Of course CODE_PACK won't port to other than a PIC 18, but
> I still think it's better to use a symbol.  A symbol like EE_START
> is a better hint than F00000h unless the reader happened to
> remember that EEPROM starts there on PIC 18.

Symbols should be used and are obviously more meaningful than
bare numbers. This code uses so many 18F features it's not going
to work in another PIC without a lot of re-writing, but that's no
excuse for at least trying to make it look good


2008\07\04@211450 by Jinx

face picon face
> the symbol EE_START which is defined separately

I've added to the .inc file

EE_BASE          EQU  H'F00000'

which makes loading/editing EEPROM tidier, back-spaces the
de '0' terminator (so data is now contiguous) and provides labels
for FSRs. MPLAB complains about an odd address if ee_base2
= ee_base+.1, so it has to = ee_base+.2, meaning there's a '0'
after baud rate, but some re-arranging will fix that. Seems that
de is lumped in with other, 16-bit, data directives which have to
be even addresses, even though EE can be written to an odd
address, being 8-bit


num_sensors    = .14
num_parameters = .6
num_offsets    = num_sensors
num_patches    = .9

ee_base2       = ee_base+.2
sensors        = ee_base2
parameters     = ee_base2+num_sensors
offsets        = ee_base2+num_sensors+num_parameters
patches        = ee_base2+num_sensors+num_parameters+num_offsets

 org ee_base

de  .25  ;baud rate

 org sensors  ;sensor init values

de  .36,.38,.48,.47,.51,.49,.46,.42,.62,.63,.127,.43,.71,.83

 org parameters  ;sensor grouping

de  .1,.63,.63,.100,.4,.0

 org offsets

de  .0,.0,.0,.0,.0,.0,.0,.0,.0,.0,.0,.0,.0,.0

 org patches

de  .1,.9,.17,.25,.26,.33,.41,.49,.57,.1

2008\07\05@090114 by olin piclist

face picon face
Jinx wrote:
> every project/product I've ever done for the last dozen years has
> been for a particular chip,

Sure, but I bet there is a lot of common code between project.  How many
times have you written a interrupt driven UART routine, set up timer 2 for
periodic interrupts, or the same interrupt enter/exit code?  With
relocatable mode these all go into separate modules so the local symbol
names can't collide.

Doesn't it bother you that assumptions about pin usage are scattered around
the code?  Hasn't a project ever changed so that pin usage got reassigned.
Then you had to go thru the TRIS and PORT initialization and analog
peripheral disabling or setup, and all the rest of the code that touched a
pin.  Wouldn't it be nicer to symbolically define each pin once then have
the rest of the code use those symbols?

> and absolute code built with MPASM
> has never been a problem.

How would you know?  Problem as apposed to what?  You are not seeing the
problems because you're used to it and that's how it's always been.  You
won't realize how many problems you were having until you no longer have to
deal with them.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\05@090433 by olin piclist

face picon face
Jinx wrote:
> That's a definition that you'd think *should* be in the .inc file. Now
> that you mention it, I'll do that

That's one of the things my STD_DEF.INS.ASPIC file does.  It has separate
sections for each supported PIC and adds the little bits of information
Microchip should have put in their include files.  These are usually
constant definitions that allow for writing general code that configures
itself to a particular PIC at assembly time.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\05@091416 by olin piclist

face picon face
Jinx wrote:
> I've added to the .inc file
>
> EE_BASE          EQU  H'F00000'

If you get used to EE_START instead of EE_BASE, then your code will be just
a little more compatible with my PIC development environment should you ever
decide to use it, or possibly copy snippets of it.

> Seems that
> de is lumped in with other, 16-bit, data directives which have to
> be even addresses, even though EE can be written to an odd
> address, being 8-bit

That's why I keep saying to use DB in CODE_PACK sections.  One DB starts
where the previous left off regardless of whether it is at a odd address or
not.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\05@101103 by Jinx

face picon face
> Sure, but I bet there is a lot of common code between projects

Hmmm, no. Not really. I mean that, I thought long and hard. They're
all so very different, on everything from 10F to 18F, and they have
very little in common

Tell you what though. I've got the current project at a stage where
I'm happy to leave it for a short while and look into relocatable code.
Then I can assess it for myself and see whether I really would benefit
by switching

> How many times have you written a interrupt driven UART routine,
> set up timer 2 for periodic interrupts, or the same interrupt enter/exit
> code?

Hardly ever. I think we must work on quite different projects. It's most
uncommon for me to need modules that were used in other projects

> With relocatable mode these all go into separate modules so the local
> symbol names can't collide

Yes, I appreciate that, and I'm not defending absolute coding. Partly
because it works fine for me so from my POV there's nothing to be
defensive about

> Doesn't it bother you that assumptions about pin usage are scattered
> around the code?  Hasn't a project ever changed so that pin usage got
> reassigned. Then you had to go thru the TRIS and PORT initialization
> and analog peripheral disabling or setup, and all the rest of the code
> that touched a pin

Honestly truly - no. As I generally make and assemble the first prototype
PCB by hand, using even TQFP / TSOP / SMT, I think carefully about
pin usage beforehand. It seldom needs changing, and then only minorly

> Wouldn't it be nicer to symbolically define each pin once then have
> the rest of the code use those symbols?
>
> > and absolute code built with MPASM has never been a problem
>
> How would you know?  Problem as opposed to what?

Problem as opposed to the chip in situ doesn't work. And it always
does

2008\07\05@101558 by Jinx

face picon face
> > EE_BASE          EQU  H'F00000'
>
> If you get used to EE_START instead of EE_BASE, then your code
> will be just a little more compatible with my PIC development environ-
> ment should you ever decide to use it, or possibly copy snippets of it

Maybe I will (see other post)

> > Seems that
> > DE is lumped in with other, 16-bit, data directives which have to
> > be even addresses, even though EE can be written to an odd
> > address, being 8-bit
>
> That's why I keep saying to use DB in CODE_PACK sections.  One
> DB starts where the previous left off regardless of whether it is at a
> odd address or not

It wasn't that so much. Rather that Program Memory is 16-bit and
EEPROM is 8-bit. So why shouldn't the specific DE directive be able
to point to either odd and even addresses (in absolute mode at least) ?

2008\07\05@105908 by olin piclist

face picon face
Jinx wrote:
>> Sure, but I bet there is a lot of common code between projects
>
> Hmmm, no. Not really. I mean that, I thought long and hard. They're
> all so very different, on everything from 10F to 18F, and they have
> very little in common

While PIC projects really are very different from each other, I find some
things that I can reuse between projects.  These are the general structure
of projects, interrupt save/restore, UART I/O, input command stream
handling, multi-threading, timer 2 initialization for a periodic interrupt,
I/O pin initialization, and analog peripheral initial disabling.  Of course
not all projects have all these items, but there is a lot of commonality
when they do.

Other things don't seem to be all that common.  One of these is A/D
handling.  Every project is different enough that reasonably efficient
common A/D code doesn't seem possible.  I may look at what I did on a
previous project, but write new A/D code as needed.

> Tell you what though. I've got the current project at a stage where
> I'm happy to leave it for a short while and look into relocatable
> code. Then I can assess it for myself and see whether I really would
> benefit by switching

The RES directive and the private local namespaces per module make it worth
it by themselves, even if you don't really embrace the "relocatable" way of
thinking.

Do you have a project you'd be willing to share the code for that's not too
big but no so small as to be trivial?  I might be interested in converting
it to relocatable mode and my development environment as a demonstration.
I'm not making any promises, but if there's code you're willing to make
public you've got little to loose.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\05@120341 by Jan-Erik Soderholm

face picon face
Jinx wrote:

> Tell you what though. I've got the current project at a stage where
> I'm happy to leave it for a short while and look into relocatable code.
> Then I can assess it for myself and see whether I really would benefit
> by switching

I think I'd just like to add that switching to reloc mode code
and (eventualy) using Olin's development environment are two
rather different things.

Switching to reloce mode is a no-brainer. You can do everything
you did in your absolute code and you'll get a lot of
benefits on top of that. "Cleaner" code, easier integration
of multiple source files, a MAP file where size of code
segments are cleary pointed out and automatic (more or
less) variable allocation are just a few of them.

Using Olin's dev envir, OTOH, is a much larger switch
in your coding "style", IMHO. Yes, it's an impressive
environment, but I guess you'd better be a "believer"... :-)

Jan-Erik.

2008\07\05@124617 by olin piclist

face picon face
Jan-Erik Soderholm wrote:
> Using Olin's dev envir, OTOH, is a much larger switch
> in your coding "style", IMHO. Yes, it's an impressive
> environment, but I guess you'd better be a "believer"... :-)

I agree it's not easy to wrap your mind around, which is why I don't
recommend it to newbies.  A experienced person like Jinx should be able
figure it out.  I know that you and Alan and a few others that seem to
remain quiet have figured it out and use it.

By the way, I just refreshed the version available on the net at
http://www.embedinc.com/pic/dload.htm.  I don't remember all that has
changed since the last version, but a lot has been added in the last year or
so.  Some of the things I can remember are:

- Significant preprocessor enhancements.  It now handles time natively, can
test for existance of symbols and system environment variables, can get
system environment variables, and native support for sequence numbers stored
in external files.  Output bits can be declared positive or negative logic,
and can be set on and off according to that logic with the macros
SET_name_ON and SET_name_OFF.

- New QQQLIB.INS.ASPIC template and STD_DEF.INS.ASPIC so that the processor
choice is in only one line of source code.  The right Microchip include file
and the MPASM processor setting are automatically derived from this.  See
comments near the top of STD_DEF.INS.ASPIC.

- Automatic version and sequence number generation per build.  The assembly
and preprocessor constants FWVER and FWSEQ are set to the build version and
sequence number and can be used anywhere in the source code.  The new
SEQUENCE.INS.ASPIC library file is used to get the unique sequence number
for a build.

- More QQQ_XXXX.ASPIC template modules and XXX.INS.ASPIC standard "library"
routines.  This includes the 18F USB firmware.  Some enhancements to
MAKE_PIC_MODULE script to support library files associated with template
files.  All the 24 bit floating point and 32 bit fixed point math routines
are now included.

- Support for more PICs.  This includes a xxx.LINKPIC linker file and a
section in the STD_DEF.INS.ASPIC file.  It is easy to add your own for any
PIC I haven't gotten around to yet.

- Updated MAKE_PIC_PROJECT script, although I don't remember the details.

- Various little enhancements, like more features in STD.INS.ASPIC, etc.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\05@180400 by William \Chops\ Westfield

face picon face

On Jul 5, 2008, at 7:14 AM, Jinx wrote:

> It wasn't that so much. Rather that Program Memory is 16-bit and
> EEPROM is 8-bit. So why shouldn't the specific DE directive be able
> to point to either odd and even addresses (in absolute mode at  
> least) ?

Cause microchip programmers are as lazy as anyone else, and when  
someone told them that a new kind of memory had been added to the  
chips, they just copied the existing "db" code to a new name and  
internal accounting symbols?  EEPROM is the ONLY "byte wide" memory  
whose content can be filled in via ASM, right?  Having done that,  
back in the 16c84 days, they could never again fix it actually work  
sensibly, for fear of breaking the existing codebase...

BillW

2008\07\05@184945 by olin piclist

face picon face
William Chops" Westfield" wrote:
> EEPROM is the ONLY "byte wide" memory
> whose content can be filled in via ASM, right?

No.  The program memory on all PIC 18 and dsPICs is byte addressable.

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\05@192818 by Jinx

face picon face
> Do you have a project you'd be willing to share the code for that's
> not too big but no so small as to be trivial?  I might be interested in
> converting it to relocatable mode and my development environment
> as a demonstration. I'm not making any promises, but if there's code
> you're willing to make public you've got little to loose.

I have a few projects in abeyance. One I'm thinking of could quite
easily be a candidate. It's a 2-channel high-voltage PWM generator,
adjustable with 4 pots. Haven't touched that one since the beginning
of the year (potential product, no customer waiting), so I'll dig it out
and give it the once-over

2008\07\05@210441 by Jinx

face picon face
> > EE_BASE          EQU  H'F00000'
>
> If you get used to EE_START

BTW, I chose EE_BASE as I'd picked up

ConfigBase equ  0x300000

from someone somewhere. Although the .inc file does have

_CONFIG1L        EQU  H'300000'

so defining ConfigBase is tautological. Plus you get a [207] label
warning as a bonus

And 18F has deprecated to eg CONFIG  FOSC= XTPLL_XT
anyway

2008\07\05@211256 by Justin Richards

face picon face
>
> Do you have a project you'd be willing to share the code for that's not too
> big but no so small as to be trivial?  I might be interested in converting
> it to relocatable mode and my development environment as a demonstration.
> I'm not making any promises, but if there's code you're willing to make
> public you've got little to loose.
>

Hi Olin,

I would like to see this in action.  I find that your approach to
programming quickly distracts me from what I actually want the
processor to do.  When I am experimenting for some reason I often find
it easier if references and values are hard coded.  For example I I
tend to use the bit number to reference bits rather than by label then
try to tidy it up after.

However,I believe you approach is clearly superior and would like to
embrace it but at the moment it distracts me from the problem at hand.
Someone once commented that you use so many macros that you have
forgoten what it is like to do real programming.  This was unfair but
helps highlight the increased difficulty due to introduced obscurity.

I am very keen to follow anything you have to say about using your
development environment and relocatable mode.  I know you are not
promising anything but I am putting up my hand.

If Jinx is unable to offer a project I have one that may be suitable
at http://www.pickledeye.com/pic/index.htm  3tc.zip contains the files and
3tc.pic is the main module.  It is for a 16f84 which may make it
unsuitable.

Cheers Justin

2008\07\05@214750 by Jinx

face picon face
>highlight the increased difficulty due to introduced obscurity.

Kind of my feeling too. It's always been my way to write code
and get just a .hex file out of it. No .obj no .lkr. no libraries no
anything else but a .hex. Apart from the device .inc I never use
those either. I'm game for seeing an absolute project reproduced
as relocatable though, to be a little more educated if nothing else

2008\07\05@223656 by William \Chops\ Westfield

face picon face

On Jul 5, 2008, at 6:46 PM, Jinx wrote:

> Kind of my feeling too. It's always been my way to write code
> and get just a .hex file out of it. No .obj no .lkr. no libraries no
> anything else but a .hex.

But that can all be automated away, using an IDE, something like  
"make", or just .BAT files, leaving you with nothing but a .HEX, if  
that's what you want.  The added build time ought to be trivial on a  
modern OS.  For example, the Arduino environment for AVR ends up  
generating pre-processed source, .o (relocatable input for  
linker), .a (linkable/searchable libraries), .elf ("executable", but  
with symbols and such), .rom and .hex files (not sure what the  
difference is between those.)

But all that is kept invisible to the user...

BillW

2008\07\05@230007 by Jinx

face picon face
> no anything else but a .hex
>
> But that can all be automated away, using an IDE

You're right of course. MPLAB makes files other than .hex
when you build a project and I don't worry about those

2008\07\06@072815 by Jan-Erik Soderholm

face picon face
Jinx wrote:

> It's always been my way to write code
> and get just a .hex file out of it. No .obj no .lkr.
> no libraries no anything else but a .hex.

As someone else said, you do not need to "see" the obj file
and the other temorary files during the build process.
At least not as long as you're building using MPLAB.

> I'm game for seeing an absolute project reproduced
> as relocatable though, to be a little more educated
> if nothing else

For a quick port from abs to reloc, there isn't realy
that much to see, realy. This is a simple showcase
of a single file code example with the minumum changes:
http://www.jescab.se/abs_reloc.html

Yes, the page is in swedish, but the actual changes
in the code are marked in red and should be clear enough.

Generaly speaking, I think that many are making this
abs-to-reloc "thing" a much larger issue then it is.

Jan-Erik.


2008\07\06@075017 by Jinx

face picon face
> Yes, the page is in swedish, but the actual changes
> in the code are marked in red and should be clear enough.

Thanks, I'll have a look

> Generaly speaking, I think that many are making this
> abs-to-reloc "thing" a much larger issue then it is.

I'm pretty relaxed about it really. Certainly not going to bag
someone who prefers a different way (if they do it at least
reasonably tidily and 'standardly'). As long as I get code into
a PIC, I'm happy. Olin feels that coding would be simplified
and less prone to problems by using the relocatable style of
writing. Maybe that's right for me, maybe it isn't. I shall find
out ASAP

2008\07\06@083718 by olin piclist

face picon face
Jinx wrote:
> I have a few projects in abeyance. One I'm thinking of could quite
> easily be a candidate. It's a 2-channel high-voltage PWM generator,
> adjustable with 4 pots. Haven't touched that one since the beginning
> of the year (potential product, no customer waiting), so I'll dig it
> out and give it the once-over

OK, sounds like a reasonable candidate.

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\06@090820 by olin piclist

face picon face
Jan-Erik Soderholm wrote:
> This is a simple showcase
> of a single file code example with the minumum changes:
> http://www.jescab.se/abs_reloc.html

You forgot the absolute addresses for the CODE sections that need to be at
the reset and interrupt vectors.

> Generaly speaking, I think that many are making this
> abs-to-reloc "thing" a much larger issue then it is.

Absolutely!  I think it's due to once someone has a working system, they
don't want to spend the time learning a new one, no matter how easy it is.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\06@091642 by olin piclist

face picon face
Jinx wrote:
>> highlight the increased difficulty due to introduced obscurity.
>
> Kind of my feeling too.

It's only obscure until you learn it.  It's just like the MPASM mnemonics
and directives.  They looked obscure at some point too, then you sat down
and learned them and thereby gained a capability you didn't have before.

You also seem to be confusing relocatable mode and my PIC development
environment.  Using native MPASM relocatable mode as apposed to the archaic
absolute mode is trivial.  My development environment is layerd on MPASM
relocatable mode, and does take some learning but also gives you
considerable power and software cleanliness in return.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\06@092901 by olin piclist

face picon face
Justin Richards wrote:
> If Jinx is unable to offer a project I have one that may be suitable
> at http://www.pickledeye.com/pic/index.htm  3tc.zip contains the files and
> 3tc.pic is the main module.

I want to give Jinx first crack, but I did take a quick look at your code.
There must be some code missing since I can't find definitions for some of
your macros, like ORGDATA and ORGEEDATA.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\06@093337 by Jinx

face picon face
> You also seem to be confusing relocatable mode and my PIC
> development environment

Fair enough. I'll refrain from saying anything else that sounds
disparaging about things I don't really know much about

2008\07\06@094312 by Jan-Erik Soderholm

face picon face
Olin Lathrop wrote:

> Jan-Erik Soderholm wrote:
>> This is a simple showcase
>> of a single file code example with the minumum changes:
>> http://www.jescab.se/abs_reloc.html
>
> You forgot the absolute addresses for the CODE sections that need to be at
> the reset and interrupt vectors.
>

Hm, this is weird...

I was more or less sure that there was a named section
the LKR file named "STARTUP". Maybe it was in earlier
versions of MPLAB or maybe I had added that myself.

Well, changing the line into "STARTUP CODE  h'0000'
put it right.

Or (if one prefer a no-hardcoded-addreses-at-all
source code) one can add a named section to the LKR.

Jan-Erik.


2008\07\06@095637 by olin piclist

face picon face
Jan-Erik Soderholm wrote:
> Well, changing the line into "STARTUP CODE  h'0000'
> put it right.
>
> Or (if one prefer a no-hardcoded-addreses-at-all
> source code) one can add a named section to the LKR.

I think in this case the section addresses should be fixed int the source
code.  If you want you can define constants for the two absolute addresses
dictated by the hardware.

Using sections bound to specific memory regions in the linker file for this
purpose is bad for two reasons.  First, it requires that a separate memory
region is defined.  This breaks up the otherwise contiguous page 0
needlessly, and you have to guess how long you will need for the interrupt
routine.  Second, it only guarantees that the code will go somewhere in the
section, not specifically at its starting address.  If you only have one
code section, then it will be placed at the beginning.  But this won't catch
accidental collisions with if multiple pieces of source accidentally use the
same section or try to place code at colliding specific addresses.  If the
fixed address is specified in the source file, then that code will be placed
there or you will get a link error.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\07@011924 by Justin Richards

face picon face
> There must be some code missing since I can't find definitions for some of
> your macros, like ORGDATA and ORGEEDATA.
>
Olin,

you dont miss a trick.  Thanks for taking the time casting an eye over my code.

It turns out ORGDATA and ORGEEDATA are compiler directives for George
Mannings K81 compiler.  I have just spent some time working out what
was going on here.

It was the last project I did before switching the MPLAB which was
quite some time ago.

Jinx's project sounds like an interesting one.  With a bit of luck I
might get the opportunity to learn several things here.

Cheers Justin

2008\07\07@082656 by David Duffy

flavicon
face
I've been following the Code Packing thread with interest, as I know I
should change to better coding methods. I still use absolute mode and
never use the device include files. Why? It probably stems from the bad
programming habits learned long ago.

I have my own port definitions that I paste into the top of the asm
file. I also have a boat load of #defines like this:
#define carry   status,0
#define zero    status,2
#define rp0     status,5
#define rp1     status,6
#define irp     status,7

#define rd      eecon1,0        ;eeprom read bit
#define wr      eecon1,1        ;eeprom write bit
#define wren    eecon1,2        ;eeprom write enable
#define wrerr   eecon1,3        ;eeprom write error
#define eepgd   eecon1,7        ;eeprom data/program select

I started doing this long ago so that I didn't have to remember what
register the various bits belonged to. I had a go last night at using
the device inc files but of course then all the bit names clashed.

Does everyone else write "bsf  eecon1,rd" where I'd write "bsf  rd"?
After programming (the wrong way?) for so many years it does get very
ingrained.

David...

2008\07\07@091923 by Jan-Erik Soderholm

face picon face
David Duffy wrote:

> I've been following the Code Packing thread with interest, as I know I
> should change to better coding methods. I still use absolute mode and
> never use the device include files. Why?

Good questions. Why ? :-)

> #define carry   status,0
> #define rd      eecon1,0        ;eeprom read bit

That isn't *that* bad realy. But why not use the
definitions for "status" and "eecon1" that Microchip
already supplies ?

> Does everyone else write "bsf  eecon1,rd" where I'd write "bsf  rd"?

If I'd do *anything* about that, I'd probably do :

macro   enable_ee_read
        bsf   eecon1, rd
endm

and then :

  enable_ee_read

in the actual code.

But I'd probably just use the "bsf eecon1,rd" format.

And of course, this has nothing to do with abs vs. reloc mode... :-)

Jan-Erik.

2008\07\07@092206 by Jinx

face picon face
> I want to give Jinx first crack

OK. I've dug the project out of the back of the cupboard and am
going over it now. Will have it available in the next day or two. I
just need to get a prototype back that has a spare 18F2520 in.
Arranged to pick that up later today, it's overdue coming back
anyway

2008\07\07@095741 by olin piclist

face picon face
David Duffy wrote:
> I still use absolute mode and
> never use the device include files.

Really bad idea.

> I have my own port definitions

At best you won't screw up and then you have something similar to the
Microchip files.  There are subtle differences between PICs and there are
different flavors of some of the peripherals.  The chances are slim that you
get all those things right from PIC to PIC, and silly anyway since Microchip
has already done that for you.

> I also have a boat load of #defines like this:
> #define carry   status,0
> #define zero    status,2
> #define rp0     status,5
> #define rp1     status,6
> #define irp     status,7

I don't think this is such a good idea, but in any case it is independent of
using your own processor include file.  Just defining string substitution
macros for the bits doesn't get you much and will probably get you into more
trouble than it will help with banked SFRs.

Individual SFR bits are rarely manipulated in main code.  Manipulation of a
particular peripheral is generally isolated to the module that deals with
it.  Most of the time you set up the configuration registers once, then
maybe check or clear the interrupt condition bit later.  For initialization,
you want to set up the whole register.  That is best served with a MOVLW,
MOVWF, with each bit of course carefully documented in the comments.

If you want to do something like this, think of the next higher level up
purpose of manipulating a particular bit in main line code.  For example,
you probably read the STATUS,Z bit to implement a conditional like "IF xxx =
0".  I've got macros SKIP_Z and SKIP_NZ for that purpose.  That and other
macros are in STD.INS.ASPIC at http://www.embedinc.com/pic.  In particular,
take a look at SKIP_WGT and SKIP_WLE.  Those are a lot clearer in the code
than any direct manipulation of STATUS,C.

> #define rd      eecon1,0        ;eeprom read bit
> #define wr      eecon1,1        ;eeprom write bit
> #define wren    eecon1,2        ;eeprom write enable
> #define wrerr   eecon1,3        ;eeprom write error
> #define eepgd   eecon1,7        ;eeprom data/program select
>
> I started doing this long ago so that I didn't have to remember what
> register the various bits belonged to.

Really bad idea.  Again, these are bits you only manipulate in special code
just for accessing the EEPROM, so the references are well contained.  But
another issue you have overlooked is that you do still need to know what
register the bits are in because you need to make sure the bank is set
properly before the access.  If I really wanted to do this for some reason,
I would wrap this in a macro like:

ee_write  macro
         dbankif  eecon1       ;make sure bank set properly
         bsf      eecon1, wr   ;start the EEPROM write
         endm

Actually in this case I'd probably encapsulate the whole EEPROM write
process in a macro, including writing the AAh and 55h signatures, etc.

> I had a go last night at using
> the device inc files but of course then all the bit names clashed.

It's going to be tough, but the longer you wait the worse it will be to
eventually fix your mess.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\07@125304 by Bob Ammerman

picon face
The biggest problem with

#define rd eecon1,0

is that, as noted by the OP, you forget which SFR the bit is in. So when
you:

   bsf    rd

you could easily be in the wrong bank.

Whether you are manually doing "bsf/bcf status,rp0/rp1" or using banksel or
even Olin's DBANKIF you would be likely to shoot yourself in the foot here!

-- Bob Ammerman
RAm Systems

2008\07\07@164259 by Christopher Head

picon face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,
Small question about code style here... you seem to mention "carefully
documenting each bit", and I've seen people do something like this to,
for instance, initialize timer 0 on an 18F with a 1:64 prescale:

movlw b'10000101'
movwf T0CON

Am I the only one who writes it like this, to make it a whole lot more
obvious what's going on?

movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
movwf T0CON

This seems to make the code partially self-documenting, since you can
see what each bit is without hopping back to the manual or trusting the
comments. And it's exactly the same opcodes in the hex file too, unlike
using a pile of BSF/BCFs which take more space and time!

Chris

Olin Lathrop wrote:
[snip]
| Individual SFR bits are rarely manipulated in main code.  Manipulation
of a
| particular peripheral is generally isolated to the module that deals with
| it.  Most of the time you set up the configuration registers once, then
| maybe check or clear the interrupt condition bit later.  For
initialization,
| you want to set up the whole register.  That is best served with a MOVLW,
| MOVWF, with each bit of course carefully documented in the comments.
[snip]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhyf1sACgkQiD2svb/jCb4AgQCfeHSRECdyUnFn53c9Ic1TCg9+
M+YAn0R2jVCyn4qmDCX//8gkrQ4pXiUV
=HNn/
-----END PGP SIGNATURE-----

2008\07\07@165756 by olin piclist

face picon face
> movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
> movwf T0CON

This is definitely better than just providing a HEX or even binary value,
but I still don't like it much because the mnemonics can be cryptic and
because:

1 - The mnemonics can by cryptic, so you still have to look them up in the
manual most of the time.

2 - Because of how continuation lines are broken in MPASM, you don't get the
opportunity to comment on each bit.

3 - This only shows the bits that are set to 1, not 0.  The choices you made
that happened to be the default value are not shown.

I document each field, for example:

        dbankif adcon1
        movlw   b'00001000'
                ; XX------  unimplemented
                ; --0-----  use Vss for Vref-
                ; ---0----  use Vdd for Vref+
                ; ----1000  configure AN0-AN6 as analog, rest digital
        movwf   adcon1


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\07@175912 by David Duffy

flavicon
face
Bob Ammerman wrote:
> The biggest problem with
>
> #define rd eecon1,0
>
> is that, as noted by the OP, you forget which SFR the bit is in. So when
> you:
>
>     bsf    rd
>
> you could easily be in the wrong bank.
>  

But if you write:
   bsf  eecon1,0
you still have no indication of what bank it's in. I don't see how
this example is any different with regard to the banking issue.

David...

2008\07\07@180045 by Christopher Head

picon face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Olin Lathrop wrote:
|> movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
|> movwf T0CON
|
| This is definitely better than just providing a HEX or even binary value,
| but I still don't like it much because the mnemonics can be cryptic and
| because:
|
| 1 - The mnemonics can by cryptic, so you still have to look them up in the
| manual most of the time.

Well, for instance, I have no idea what bit 7 means, but it's pretty
obvious without looking in the datasheet (to me anyway) what TMR0ON
means. What you say is certainly true of a question like "what prescale
is 101?", but those bits I reference more frequently are the ones I know
better and won't have to look up.

|
| 2 - Because of how continuation lines are broken in MPASM, you don't
get the
| opportunity to comment on each bit.

Point taken. If you need a lot of documentation for each bit you would
have to find somewhere else to put it, but then your own format doesn't
really do anything differently in this case, since your comments are
also on separate lines - you could just as easily do that with mine.

|
| 3 - This only shows the bits that are set to 1, not 0.  The choices
you made
| that happened to be the default value are not shown.

Point taken again, though I'd probably document anything non-obvious.
For example, if I'm setting T0CON, I won't document the bits I left out,
because they're all just about the timer - and I'll have some
documentation elsewhere about the high-level purpose of TIMER0 in my
application, which will make it obvious for instance whether I'm using
internal or external clock0, so it doesn't need documenting at the
instruction level. If I'm setting something like OPTION, I'll document
anything else important that's set to 0, because OPTION has bits from
all over the place rather than for just one particular module. I also
tend to remember for the most part which bits are in which register, I
just don't remember which bit indices they are or at what addresses the
registers can be found.

|
| I document each field, for example:
|
|          dbankif adcon1
|          movlw   b'00001000'
|                  ; XX------  unimplemented
|                  ; --0-----  use Vss for Vref-
|                  ; ---0----  use Vdd for Vref+
|                  ; ----1000  configure AN0-AN6 as analog, rest digital
|          movwf   adcon1
|

Yes, I saw a couple of code samples of yours like this on piclist.com
and it's definitely tidy and easy-to-read. I guess I'd get slightly
worried about code and comments being desynchronized because "I'll just
change this value quickly to see what happens and change it back right
after, no need to change the comments", but that's always the price you
pay for good documentation. Anyway that's a lot better than a hex
constant (worse than binary IMHO) with no or minimal explanation!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhykWwACgkQiD2svb/jCb6R/ACfVDEqQXOKRKi2cMlbQ7lLIFJy
6wYAoIMGNWu/woJXkOFX2VJONPc2fstR
=a4fl
-----END PGP SIGNATURE-----

2008\07\07@180404 by William \Chops\ Westfield

face picon face
>> movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
>> movwf T0CON

I think the main problem with this WRT microcontrollers, is that  
there is none of the "self-documentation" you speak of for the bits  
whose value is zero, and those are liable to be as important as the  
one bits.  Also, it tends to fall apart when you have bit fields  
instead of individual bits.


> I document each field, for example:
>
>          dbankif adcon1
>          movlw   b'00001000'
>                  ; XX------  unimplemented
>                  ; --0-----  use Vss for Vref-
>                  ; ---0----  use Vdd for Vref+
>                  ; ----1000  configure AN0-AN6 as analog, rest digital

But this has the problem of not using the per-cpu defines for bit  
values. The comments SAY what the programmer THINKS the bits are  
doing, but there's no "support" for that in the form of microchip-
defined symbols.  Assuming that you trust microchip include files.

I used to use an assembler/environment that defined macros for  
setting field values:
       MOVX T2,<FLD(^D36,OF%BSZ)+OF%APP> ; Open for 36 bit append
but that got pretty messy too (especially for 36bits worth of  
field.)  It's not an easy problem, but any real attempt is better  
than nothing.

BillW

2008\07\07@180913 by olin piclist

face picon face
David Duffy wrote:
> But if you write:
>     bsf  eecon1,0
> you still have no indication of what bank it's in. I don't see how
> this example is any different with regard to the banking issue.

At least you can see what bank you should be in, so if you see:

    banksel  eecon1
    bsf      eecon1, wr

You know that banking was correctly taken care of.

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\07@181106 by olin piclist

face picon face
Christopher Head wrote:
> Point taken. If you need a lot of documentation for each bit you would
> have to find somewhere else to put it, but then your own format
> doesn't really do anything differently in this case, since your
> comments are
> also on separate lines - you could just as easily do that with mine.

The problem is that your method is all on one line with no easy wasy to add
a separate comment for each mnemonic.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\07@181531 by Jan-Erik Soderholm

face picon face
David Duffy wrote:
> Bob Ammerman wrote:
>> The biggest problem with
>>
>> #define rd eecon1,0
>>
>> is that, as noted by the OP, you forget which SFR the bit is in. So when
>> you:
>>
>>     bsf    rd
>>
>> you could easily be in the wrong bank.
>>  
>
> But if you write:
>     bsf  eecon1,0
> you still have no indication of what bank it's in.

No, but it might make you think, oh, I need that
"banksel eecon1" also!

When you see just "bsf rd", you might have to look up
somewhere else what that bl--dy register was called... :-)

Jan-Erik.

2008\07\07@181755 by Jan-Erik Soderholm

face picon face
Christopher Head wrote:

> Anyway that's a lot better than a hex
> constant (worse than binary IMHO)...

And both are better then a decimal constant... :-)

Jan-Erik.

2008\07\07@182014 by Chris Emerson

flavicon
face
On Mon, Jul 07, 2008 at 05:00:06PM -0400, Olin Lathrop wrote:
> > movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
> > movwf T0CON
>
> This is definitely better than just providing a HEX or even binary value,
> but I still don't like it much because the mnemonics can be cryptic and
> because:
[snip]
> 3 - This only shows the bits that are set to 1, not 0.  The choices you made
> that happened to be the default value are not shown.

You could in principle specify the 0 bits too:

 movlw (1 << TMR0ON) | (1 << T0PS2) | (0 << T0PS1) | (1 << T0PS0)

and similarly for the other 0 bits, which I haven't got handy.

This doesn't answer any of the other issues, though.

Cheers,

Chris

2008\07\07@182832 by olin piclist

face picon face
William Chops" Westfield" wrote:
>>          dbankif adcon1
>>          movlw   b'00001000'
>>                  ; XX------  unimplemented
>>                  ; --0-----  use Vss for Vref-
>>                  ; ---0----  use Vdd for Vref+
>>                  ; ----1000  configure AN0-AN6 as analog, rest
>> digital
>
> But this has the problem of not using the per-cpu defines for bit
> values. The comments SAY what the programmer THINKS the bits are
> doing, but there's no "support" for that in the form of microchip-
> defined symbols.

This is true, but them I'm providing my code as a example, not asking others
to diagnose a problem for me.

The error I do occasionally make with this method is not getting the bits
wrong.  That's very unlikely since I'm looking at the manual page for the
register while writing the code.  Every once in a while I make a change to
the documented bits which are really comments and forget to make the
corresponding change to the real number above that gets loaded into the
register.  I am aware of this and try to double check myself, but maybe once
a year I still screw up.

However, it's still the best method I have found so far, and I think the
easiest for others to read assuming they trust me to have gotten the bits
right.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\07@183803 by Jinx

face picon face
This, the way I've always done it too,

         dbankif adcon1
         movlw   b'00001000'
                 ; XX------  unimplemented
                 ; --0-----  use Vss for Vref-
                 ; ---0----  use Vdd for Vref+
                 ; ----1000  configure AN0-AN6 as analog, rest digital

is more readable and understandable quickly, than

  movlw (1 << TMR0ON) | (1 << T0PS2) | (0 << T0PS1) | (1 << T0PS0)

This means nothing without any comment at all

movlw 0x08
movwf adcon1



2008\07\07@184838 by Jinx

face picon face
> movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
> movwf T0CON
>
> This seems to make the code partially self-documenting, since you
> can see what each bit is without hopping back to the manual or trusting
> the comments. And it's exactly the same opcodes in the hex file too,
> unlike using a pile of BSF/BCFs which take more space and time!

Chris, I'd see that and might briefly wonder what TOPS is. AYS, it's
partially self-documenting. Adding an extra comment like

;Set pre-scale bits to 101 (1:64, = 100kHz IRQ) and turn TMR0 on

would explain further. Mostly it's really helpful when you come back
in 6 months to edit or re-understand your own code


2008\07\07@185259 by Jinx

face picon face
> The error I do occasionally make with this method is not getting
> the bits wrong

Pretty sure that's not what you meant to say

> Every once in a while I make a change to the documented bits
> which are really comments and forget to make the corresponding
> change to the real number above that gets loaded into the register

I'm glad I'm not the only one that does that. A pity that PICs don't
run on comments sometimes, a real pity

2008\07\07@191659 by cdb

flavicon
face
:: movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)
:::: movwf T0CON
::::
:::: This seems to make the code partially self-documenting, since
:::: you
:::: can see what each bit is without hopping back to the manual or
:::: trusting
:::: the comments. And it's exactly the same opcodes in the hex file
:::: too,
:::: unlike using a pile of BSF/BCFs which take more space and time!
::::
:: Chris, I'd see that and might briefly wonder what TOPS is. AYS,
:: it's
:: partially self-documenting. Adding an extra comment like
::
:: ;Set pre-scale bits to 101 (1:64, = 100kHz IRQ) and turn TMR0 on
::
:: would explain further. Mostly it's really helpful when you come
:: back
:: in 6 months to edit or re-understand your own code


Looks like I'd get the wrath of everybody, I change my  coding style
depending on what the code is supposed to be doing at that instant.

I normally have a speil at the top of a function explaining the
function and pertinent points, but in the body itself, if I am
declaring port directions or maybe even the default state then I'd use
binary -
(pseudo code)
//bits 2,3,5,6 are inputs
portA = 0b01101100

When setting a hardware register I'm more likely to use,

movlw (1 << TMR0ON) | (1 << T0PS2) | (1 << T0PS0)

except I normally use basic or 'c' with a brief explanation just above
the code line.

Colin

--
cdb, spam_OUTcolinTakeThisOuTspambtech-online.co.uk on 8/07/2008

Web presence: http://www.btech-online.co.uk  

Hosted by:  http://www.1and1.co.uk/?k_id=7988359




2008\07\07@194439 by Jinx

face picon face
> Looks like I'd get the wrath of everybody, I change my coding
> style depending on what the code is supposed to be doing at that
> instant

(gasp) You monster. I think I've seen your house on TV. It's the one
with a crowd of angry villagers armed with pitchforks and burning
torches outside isn't it ?

2008\07\07@201608 by David Duffy (AVD)

flavicon
face
Olin Lathrop wrote:
> Individual SFR bits are rarely manipulated in main code.  Manipulation of a
> particular peripheral is generally isolated to the module that deals with
> it.

Actually, that's quite true most of the time. I have set routines that I
use in lots of projects, and converting them to use the proper register
definitions should not be too hard. I'll really get the advantage from
those changes once I move to relocatable code.
David...

2008\07\07@201833 by David Duffy (AVD)

flavicon
face
Olin Lathrop wrote:
> David Duffy wrote:
>  
>> But if you write:
>>     bsf  eecon1,0
>> you still have no indication of what bank it's in. I don't see how
>> this example is any different with regard to the banking issue.
>>    
>
> At least you can see what bank you should be in, so if you see:
>
>      banksel  eecon1
>      bsf      eecon1, wr
>
> You know that banking was correctly taken care of.
>  
Why would seeing the register name make you think more about the
banking? Seeing the actual register name doesn't imply anything about
what bank it's in.
David...

2008\07\07@224952 by cdb

flavicon
face


:: (gasp) You monster. I think I've seen your house on TV. It's the
:: one
:: with a crowd of angry villagers armed with pitchforks and burning
:: torches outside isn't it ?

I insist they queue up with number 1's at the front and those I
consider zero at the back.
--
cdb, .....colinKILLspamspam@spam@btech-online.co.uk on 8/07/2008

Web presence: http://www.btech-online.co.uk  

Hosted by:  http://www.1and1.co.uk/?k_id=7988359

Friendship multiplies the good of life and divides the evil.
Baltasar Gracian





2008\07\07@231438 by Jinx

face picon face
> > (gasp) You monster. I think I've seen your house on TV. It's
> > the one with a crowd of angry villagers armed with pitchforks
> > and burning torches outside isn't it ?
>
> I insist they queue up with number 1's at the front and those I
> consider zero at the back.

If they think you're a number 2, that sounds about right ;-)

Seriously, if you make clear what's intended by any code, however
you do that is better than causing a lot of head-scratching

I've just ported someone else's code from a 16 to an 18 and spent
as much time writing comments as I did adjusting mnemonics. At
least one of us will not be bamboozled in the future, and it might as
well be me

2008\07\08@024311 by David Meiklejohn

face
flavicon
face
Chris wrote:
>
> You could in principle specify the 0 bits too:
>
>   movlw (1 << TMR0ON) | (1 << T0PS2) | (0 << T0PS1) | (1 << T0PS0)
>
> and similarly for the other 0 bits, which I haven't got handy.

I prefer to specify individual bits like this, but leave bit fields (such
as the three prescaler bits here) in binary, as in:

 movlw  1<<TMR0ON | b'101'<<T0PS0   ; turn on TMR0, prescale = 64

I do like Olin's method, but otoh, it seems reasonable to expect that
someone working on the code will have the data sheet at hand.


David Meiklejohn
http://www.gooligum.com.au

2008\07\08@025304 by David Meiklejohn

face
flavicon
face
Jan-Erik Soderholm wrote:
>
> David Duffy wrote:
>
>> Does everyone else write "bsf  eecon1,rd" where I'd write "bsf  rd"?
>
> If I'd do *anything* about that, I'd probably do :
>
> macro   enable_ee_read
>          bsf   eecon1, rd
> endm
>
> and then :
>
>    enable_ee_read
>
> in the actual code.

But then you potentially have a bank selection problem.

You could define your macro as:

macro   enable_ee_read
        banksel eecon1
        bsf     eecon1, rd
endm

But then you'd need be aware that, whenever you use 'enable_ee_read',
you're potentially changing the bank selection.  That's not necessarily a
bad thing, but you'd have to keep it in mind.


David Meiklejohn
http://www.gooligum.com.au

2008\07\08@044510 by Christopher Head

picon face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David Meiklejohn wrote:
| I prefer to specify individual bits like this, but leave bit fields (such
| as the three prescaler bits here) in binary, as in:
|
|   movlw  1<<TMR0ON | b'101'<<T0PS0   ; turn on TMR0, prescale = 64
|
| I do like Olin's method, but otoh, it seems reasonable to expect that
| someone working on the code will have the data sheet at hand.

I like this method, though paranoid as I am I'd probably write in a
compile-time assertion that the bits are actually contiguous in the
register to ease porting (not that I've ever actually ported any code
from one PIC to another... but it seems sensible and it can't possibly
do any harm, since it won't produce any output opcodes).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhzKOoACgkQiD2svb/jCb6/bQCfQ33yNXxyCRDyXuQ2jDPNDcVl
7TkAmgLvu2uN0mmJMG/N9nRz4h1pzcb6
=q7ZU
-----END PGP SIGNATURE-----

2008\07\08@051903 by Xiaofan Chen

face picon face
On Tue, Jul 8, 2008 at 2:42 PM, David Meiklejohn <davidspamKILLspamgooligum.com.au> wrote:
> Chris wrote:
>>
>> You could in principle specify the 0 bits too:
>>
>>   movlw (1 << TMR0ON) | (1 << T0PS2) | (0 << T0PS1) | (1 << T0PS0)
>>
>> and similarly for the other 0 bits, which I haven't got handy.
>
> I prefer to specify individual bits like this, but leave bit fields (such
> as the three prescaler bits here) in binary, as in:
>
>  movlw  1<<TMR0ON | b'101'<<T0PS0   ; turn on TMR0, prescale = 64
>
> I do like Olin's method, but otoh, it seems reasonable to expect that
> someone working on the code will have the data sheet at hand.

I agree that we need to consult the dustsheet. But still I think
Olin's method is much better and clearer. I understand people
who are proficient with C like to use "<<" or ">>" but it is
not as clear in the context of assembly programming.


Xiaofan

2008\07\08@062505 by Alan B. Pearce

face picon face
>I agree that we need to consult the dustsheet.

Yeah, well judging by the number of queries that land here, it seems a lot
of datasheets are gathering dust ... ;))))))

>But still I think Olin's method is much better and clearer.
>I understand people who are proficient with C like to use
>"<<" or ">>" but it is not as clear in the context of
>assembly programming.

Another advantage of Olins method is that you can see what other bits are in
the register, as ALL the bits are laid out. This makes it more suitable for
registers where some bits will get manipulated in one part of the program,
and others get manipulated elsewhere (possibly in another module) and so you
can see where side effects may be generated.

2008\07\08@063141 by Tamas Rudnai

face picon face
> I prefer to specify individual bits like this, but leave bit fields (such
> as the three prescaler bits here) in binary, as in:
>
>  movlw  1<<TMR0ON | b'101'<<T0PS0   ; turn on TMR0, prescale = 64


You can make it even complicated:


ON     equ    1
OFF    equ    0

_T0CON = 0

TMR0     macro    s
           if s == ON
_T0CON |= 1<<TMR0ON
               exitm
           endif
           if s==OFF
_T0CON &= ~(1<<TMR0ON)
               exitm
           endif

       error Invalid parameter to TMR0 macro s
       endm

T0PS     macro    s
_T0CON &= ~(1<<T0PS2 | 1<<T0PS1 | 1<<T0PS0)
_T0CON |= (1<<PSA)
           if s == .1
               exitm
           endif
           if s == .2
_T0CON &= ~(1<<PSA)
_T0CON |= (0<<T0PS2) | (0<<T0PS1) | (0<<T0PS0)
               exitm
           endif
           if s == .4
_T0CON &= ~(1<<PSA)
_T0CON |= (0<<T0PS2) | (0<<T0PS1) | (1<<T0PS0)
               exitm
           endif
           if s == .8
_T0CON &= ~(1<<PSA)
_T0CON |= (0<<T0PS2) | (1<<T0PS1) | (0<<T0PS0)
               exitm
           endif
           if s == .16
_T0CON &= ~(1<<PSA)
_T0CON |= (0<<T0PS2) | (1<<T0PS1) | (1<<T0PS0)
               exitm
           endif
           if s == .32
_T0CON &= ~(1<<PSA)
_T0CON |= (1<<T0PS2) | (0<<T0PS1) | (0<<T0PS0)
               exitm
           endif
           if s == .64
_T0CON &= ~(1<<PSA)
_T0CON |= (1<<T0PS2) | (0<<T0PS1) | (1<<T0PS0)
               exitm
           endif
           if s == .128
_T0CON &= ~(1<<PSA)
_T0CON |= (1<<T0PS2) | (1<<T0PS1) | (0<<T0PS0)
               exitm
           endif
           if s == .256
_T0CON &= ~(1<<PSA)
_T0CON |= (1<<T0PS2) | (1<<T0PS1) | (1<<T0PS0)
               exitm
           endif

       error Invalid parameter to T0PS macro s
       endm


setTMR0 macro
       movlw    _T0CON
       movwf    T0CON
       endm

setTimer0
       ; preparing Timer0 settings
       TMR0(ON)
       T0PS(.256)
       ; make the settings live
       setTMR0

Not sure if that makes things more productive or less error prone - you may
can write extensive macro sets like this which will be MCU independent
however.

Tamas


On Tue, Jul 8, 2008 at 10:18 AM, Xiaofan Chen <.....xiaofancKILLspamspam.....gmail.com> wrote:

{Quote hidden}

> -

2008\07\08@064257 by Jan-Erik Soderholm

face picon face
Alan B. Pearce wrote:
>> I agree that we need to consult the dustsheet.
>
> Yeah, well judging by the number of queries that land here, it seems a lot
> of datasheets are gathering dust ... ;))))))
>
>> But still I think Olin's method is much better and clearer.
>> I understand people who are proficient with C like to use
>> "<<" or ">>" but it is not as clear in the context of
>> assembly programming.
>
> Another advantage of Olins method is that you can see what other bits are in
> the register, as ALL the bits are laid out. This makes it more suitable for
> registers where some bits will get manipulated in one part of the program,
> and others get manipulated elsewhere (possibly in another module) and so you
> can see where side effects may be generated.
>

Olins mathod is OK for one-time initial setup, but for
code that is executed in the main code, BCF/BSF is often
better/easier/clearer, say for clearing/setting some xxIF
or xxIE flags. BCF/BSF (when used for non-PORTx FSR's)
usualy has no side effects.

And I have no idea whatsoever what the "<<" and ">>" means... :-)

Jan-Erik.

2008\07\08@070555 by Alan B. Pearce

face picon face
>And I have no idea whatsoever what the "<<" and ">>" means... :-)

Careful, you'll start the Trolls ... ;)))

2008\07\08@070621 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

{Quote hidden}

FWIW, In C, this can look like this:

#define HLVDCON_INIT ( /* High/Low Voltage Detection                    */\
 (u8) (                                                                  \
   (      0 << 7)     /* (b7) VDIRMAG detection direction (0:det. low)*/\
 | (      0 << 4)     /* (b4) HLVDEN enable detection (1: ena)         */\
 | ( 0b1111 << 0)     /* (b3:0) HLVDL3:0 detection limit (external)    */\
 )                                                                       \
)

Gerhard

2008\07\08@071009 by olin piclist

face picon face
David Duffy (AVD) wrote:
>> At least you can see what bank you should be in, so if you see:
>>
>>      banksel  eecon1
>>      bsf      eecon1, wr
>>
>> You know that banking was correctly taken care of.
>
> Why would seeing the register name make you think more about the
> banking? Seeing the actual register name doesn't imply anything about
> what bank it's in.

I guess you didn't really look at my example above.  You don't need to know
what bank EECON1 is in, but the BANKSEL guarantees the bank is set
correctly.  And this is immediately clear since you can see the BSF
instruction acts on the same address that was just used to set the bank.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@074015 by olin piclist

face picon face
David Meiklejohn wrote:
> macro   enable_ee_read

Should be:

enable_ee_read macro

>          banksel eecon1
>          bsf     eecon1, rd
> endm
>
> But then you'd need be aware that, whenever you use 'enable_ee_read',
> you're potentially changing the bank selection.

This is one of the things my environment handles nicely.  The DBANKIF macro
has the same syntax as BANKSEL, but it only makes the minimum changes to get
from the bank you're in to the bank you want to be in.  It works with the
assembly time bank tracking mechanism.

Since you've got a mechanism for setting banks that is free unless the bank
actually needs to be changed, you can now feel better about using it
liberally.  I would write the macro like:

eeread   macro
        dbankif  eecon1
        bsf      eecon1, rd
        endm

If following code cared about the bank setting, it would use a DBANKIF.  If
that happened to select the same bank EECON1 was in, then no code would get
generated.  In fact, the EEREAD macro would only be a single instruction if
EECON1 was known to be in unbanked memory (like on a PIC 18), or the bank
was already known to be set to the bank EECON1 is in.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@074555 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

{Quote hidden}

That's why I'm trying to write self-documenting code as much as possible. I
just sent how I do it (in C) in another message in this thread:

#define HLVDCON_INIT ( /* High/Low Voltage Detection                    */\
 (u8) (                                                                  \
   (      0 << 7)     /* (b7) VDIRMAG detection direction (0:det. low) */\
 | (      1 << 4)     /* (b4) HLVDEN enable detection (1: ena)         */\
 | ( 0b1111 << 0)     /* (b3:0) HLVDL3:0 detection limit (external)    */\
 )                                                                       \
)

This is very similar to what you're doing -- with the one difference that
the numbers you write in the comments are code, so there's one step less to
get wrong. I still can have the explaining comment different from the
actual bit meaning, but if the bit value on the line with the comment is
correct, the register is being written correctly.

Maybe there is a way to generate the constant for the movlw in a similar
way in MPASM.

Gerhard

2008\07\08@075035 by olin piclist

face picon face
Jan-Erik Soderholm wrote:
> Olins mathod is OK for one-time initial setup, but for
> code that is executed in the main code, BCF/BSF is often
> better/easier/clearer, say for clearing/setting some xxIF
> or xxIE flags.

I agree, and I use BSF/BCF for that.  I was specifically trying to show how
I set up a register that contains various separate fields.  BSF/BCF is best
when you need to manipulate a single bit and there are other unrelated bits
in the same register.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@075454 by David Duffy

flavicon
face
Olin Lathrop wrote:
> David Duffy (AVD) wrote:
>  
>>> At least you can see what bank you should be in, so if you see:
>>>
>>>      banksel  eecon1
>>>      bsf      eecon1, wr
>>>
>>> You know that banking was correctly taken care of.
>>>      
>> Why would seeing the register name make you think more about the
>> banking? Seeing the actual register name doesn't imply anything about
>> what bank it's in.
>>    
>
> I guess you didn't really look at my example above.  You don't need to know
> what bank EECON1 is in, but the BANKSEL guarantees the bank is set
> correctly.  And this is immediately clear since you can see the BSF
> instruction acts on the same address that was just used to set the bank.
>  
As a matter of fact, I did really look at your example.
It's just that it did not convey to me what you meant.

Now that you've explained it I can see what you mean.
That's the problem with explaining things via email.
David...

2008\07\08@075814 by sergio masci

flavicon
face
Complicated macros are like bear traps hiding in your code.

Seriously, how many people actually go to the trouble of debugging their
macros as if they were regular programs - in my experience not many.

Just look at the example below:

_T0CON &= ~(1<<T0PS2 | 1<<T0PS1 | 1<<T0PS0)

and then:

_T0CON |= (0<<T0PS2) | (0<<T0PS1) | (0<<T0PS0)

I strongly belive that once you start trying to get the assembler source
code to be too clever that it is time to use tools with the cleverness
built in.

And personally if I were forced to use bit IDs, I would use something like

CARRY = (STATUS << 3) | C

recovering the bit within the SFR then becomes a simple mater of:

(CARRY & 7)

and recovering the SFR to which the bit belongs becomes:

(CARRY >> 3)

This allows your macros to do RAM page selecting, testing for invalid bit
IDs as params etc.


Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB
optimising PIC compiler, LITE edition free for personal non-commercial use



On Tue, 8 Jul 2008, Tamas Rudnai wrote:

{Quote hidden}

2008\07\08@080026 by olin piclist

face picon face
Gerhard Fiedler wrote:
> I just sent how I do it (in C) in another message in this
> thread:
>
> #define HLVDCON_INIT ( /* High/Low Voltage Detection
>   */\ (u8) (
>     \ (      0 << 7)     /* (b7) VDIRMAG detection direction (0:det.
>   low) */\ | (      1 << 4)     /* (b4) HLVDEN enable detection (1:
>   ena)         */\ | ( 0b1111 << 0)     /* (b3:0) HLVDL3:0 detection
>   limit (external)    */\ )
> \ )

I'd do it differently in other languages too.  You can't do it in MPASM
similarly to what you showed because of how the continuation line mechanism
is broken.  You can't comment continue lines in MPASM.  At least you used to
not be able to a long time ago when I tried it and gave up in disgust.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@082743 by Tomás Ó hÉilidhe

picon face
Gerhard Fiedler wrote:
>> I just sent how I do it (in C) in another message in this
>> thread:
>>
>> #define HLVDCON_INIT ( /* High/Low Voltage Detection
>>   */\ (u8) (
>>     \ (      0 << 7)     /* (b7) VDIRMAG detection direction (0:det.
>>   low) */\ | (      1 << 4)     /* (b4) HLVDEN enable detection (1:
>>   ena)         */\ | ( 0b1111 << 0)     /* (b3:0) HLVDL3:0 detection
>>   limit (external)    */\ )
>> \ )
>

Just a quick point: I'd always advocate using unsigned integer types
when doing bitwise operations in C. In your example above, it doesn't
matter because the amount of places by which you're shifting is less
than "amount of bits in type minus two". If you'd had bigger numbes
though, things would've gotten hairy. But take this example though:

   PORTA &= ~(1u << 3);

If this had instead been:

   PORTA &= ~(1 << 3);

then the following would happen:

1) The signed integer 1 gets shifted three places to become signed integer 8
2) The bits of signed integer 8 get flipped, so 0000000000001000 becomes
1111111111110111  (for a 16-Bit int)
3) At this point, the value of the expression is implementation-defined
depending on whether the machine's number system is one's complement,
two's complement or sign-magnitude.
4) This expression of implementation-defined value must then be
converted to an unsigned char to satisfy the assignment to PORTA.
Conversions from signed types to unsigned types are well-defined in C,
but the problem is that the value we're converting is
implementation-defined.

So, anyway, you might not get what you asked for if you go with:  PORTA
&= ~(1 << 3);

Also to avoid more problems with signed types, I'd always cast types
smaller than int, to unsigned int before doing any operations on them, e.g.:

   char unsigned a = 7, b = 4;

   a = ~b;   /* Might not get what I want if unsigned char promotes to
signed int */

   a = ~(unsigned)b;   /* Guaranteed to work on every system */

I only every use signed integer types when I explicitly want to store a
negative number. They're bad news for bitwise operation.

2008\07\08@083037 by olin piclist

face picon face
sergio masci wrote:
> Complicated macros are like bear traps hiding in your code.
>
> Seriously, how many people actually go to the trouble of debugging
> their macros as if they were regular programs

Of course you have to validate them just like any other code.  The good
thing is that once you've done that your toolbox becomes a little bigger.
Macros also tend to be small code snippets, so it's rather unusual that
there is a bug in one, but it still happens.  You also need to keep in mind
that while a trusted and heavily used macro is unlikely to have a bug, it
can happen, just as with any tool.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@083242 by Jinx

face picon face
> > #define HLVDCON_INIT ( /* High/Low Voltage Detection
> >   */\ (u8) (
> >     \ (      0 << 7)     /* (b7) VDIRMAG detection direction (0:det.
> >   low) */\ | (      1 << 4)     /* (b4) HLVDEN enable detection (1:
> >   ena)         */\ | ( 0b1111 << 0)     /* (b3:0) HLVDL3:0 detection
> >   limit (external)    */\ )
> > \ )

Jeepers. I thought I had a virus messing with the screen !!

2008\07\08@100945 by Tamas Rudnai

face picon face
Tomas,

>    PORTA &= ~(1u << 3);
>
> If this had instead been:
>
>    PORTA &= ~(1 << 3);
>
> then the following would happen:
>
> 1) The signed integer 1 gets shifted three places to become signed integer
8

Nope, MCC18 does not have an integer promotion by default, so '1' and '3'
treated as char.

> 2) The bits of signed integer 8 get flipped, so 0000000000001000 becomes
> 1111111111110111  (for a 16-Bit int)

As it is char it only happens in 8 bits

> 3) At this point, the value of the expression is implementation-defined
> depending on whether the machine's number system is one's complement,
> two's complement or sign-magnitude.

As you have 10 years of superior experience and you have more things to say
than ask just tell me which computer or MCU uses 1's complement or
sign-magnitude nowadays? Also if you can tell me how is this changes the
binary representation of this number? You are doing bitwise operations not
arithmetic. If you set the highest bit nothing else happens but the highest
bit will be set.

> 4) This expression of implementation-defined value must then be
> converted to an unsigned char to satisfy the assignment to PORTA.

So again with your experience, tell me the difference about converting
numbers and casting it? What is a difference in between autocasting and
casting? See, no matter what you do the binary code is still ok when you are
binary manipulating it. There would be one problem, if you are casting a
smaller signed type to a bigger one, like signed char to an integer. (lower
bits would not change in this case either).

> Conversions from signed types to unsigned types are well-defined in C,
> but the problem is that the value we're converting is
> implementation-defined.

There is no conversion, only casting... PORTA would be just fine... The 'u'
you are using as a postfix to the '1' is also only a casting, nothing more.

>    char unsigned a = 7, b = 4;
>
>    a = ~b;   /* Might not get what I want if unsigned char promotes to
> signed int */
>
>    a = ~(unsigned)b;   /* Guaranteed to work on every system */

Why would it promote to signed int? Both of your variable are the same type.
I think you do not know bit manipulation and casting really well.

The road you are walking is very slippery, if I were you would not spend my
time to shouting load how clever I am, and would spend my time on learning
instead. Also if you were just a bit more quiet no one would like to find
mistakes what you say and you may even get some respects if things you are
saying are mostly correct.

Tamas






On Tue, Jul 8, 2008 at 1:27 PM, Tomás Ó hÉilidhe <KILLspamtoeKILLspamspamlavabit.com> wrote:

{Quote hidden}

>

2008\07\08@123658 by Tomás Ó hÉilidhe

picon face


Tamas Rudnai wrote:
> Nope, MCC18 does not have an integer promotion by default, so '1' and '3'
> treated as char.
>  


MCC18 is not a valid implementation of C as defined by any of the ISO
ANSI standards. The C standard of 1989 is very clear about integer
promotion, as is the C standard of 1999.

Telling me that MCC18 is C is like saying a wolf is a dog.


> As it is char it only happens in 8 bits
>  


Fair enough, if that's what happens in MCC18, as distinct from Standard
C of course.


> As you have 10 years of superior experience and you have more things to say
> than ask just tell me which computer or MCU uses 1's complement or
> sign-magnitude nowadays?


I don't go in to such details, because I don't have to go into such
details. I write fully-portable C code that will work on every
conceivable implementation of the C Standard, regardless of endianness,
number system, size of byte, character set.


> Also if you can tell me how is this changes the
> binary representation of this number?


Take the following bit pattern for an 8-Bit signed integer type:

11011010

Tell me what value that is. You can't. Why? Because you don't know what
number system is being used.


>  You are doing bitwise operations not
> arithmetic. If you set the highest bit nothing else happens but the highest
> bit will be set.
>  


The highest bit in an unsigned type corresponds to the "sign bit" in a
signed type. If you set the signed bit, you've got a negative number
(assuming of course that the bit pattern doesn't result in a "trap
representation"). This negative number will be different on different
systems depending on the number system in use.


> So again with your experience, tell me the difference about converting
> numbers and casting it?


Conversions are implicit. Casts are explicit. There's no difference in
the effect under than that sometimes you need a cast because there's no
implicit conversion. Here's an example:

   int a;
  double b;

   int *p = (int*)&b;   /* This won't work without a cast */


> What is a difference in between autocasting and
> casting?


An "auto-cast" tends to be called a conversion. There's no difference
other than that sometimes you need an explicit cast because there's no
implicit conversion.


>  See, no matter what you do the binary code is still ok when you are
> binary manipulating it.


No it's not OK, and this topic was discussed in detail on comp.lang.c a
few months ago. The conclusion was that the following code is unpredictable:

   unsigned char a = 7, b = 4;

   a = ~b;

and that it should be replaced with:

   a = ~(unsigned)b;

> There would be one problem, if you are casting a
> smaller signed type to a bigger one, like signed char to an integer. (lower
> bits would not change in this case either).
>  


Are you talking about something like this:

   short i = 7;

   int j = i;

There is never a problem when going from a smaller signed type to a
bigger signed type, you're always left with the original value. The C
standard guarantees it:

   if (7 != j) puts("The is not a standard compiler.");


> There is no conversion, only casting... PORTA would be just fine... The 'u'
> you are using as a postfix to the '1' is also only a casting, nothing more.
>  


Well I suppose you could consider it a cast -- it makes sure that the
integer literal is of type "unsigned int" rather than "signed int".

If you have code such as the following:

   char unsigned a = 4, b = 7;

   a &= ~b;

then the expression on the right-hand side of the assignment is of type
either "signed int" or "unsigned int" depending on whether INT_MAX is
greater than UCHAR_MAX. On the vast majority of systems, it's "signed
int". When you try to assign the "signed int" to an unsigned char, it
needs to be converted.


{Quote hidden}

An integer expression must undergo promotion before any arithmetic or
bitwise operation can be performed on it.


> The road you are walking is very slippery, if I were you would not spend my
> time to shouting load how clever I am, and would spend my time on learning
> instead. Also if you were just a bit more quiet no one would like to find
> mistakes what you say and you may even get some respects if things you are
> saying are mostly correct.


I'd be delighted if you found mistakes, because then I could learn from
them and improve my knowledge.

2008\07\08@140403 by jim

flavicon
face
A wolf is a dog.


----- Original Message -----
From: "Tomás Ó hÉilidhe" <RemoveMEtoeTakeThisOuTspamlavabit.com>
To: "Microcontroller discussion list - Public." <spamBeGonepiclistspamBeGonespammit.edu>
Sent: Tuesday, July 08, 2008 11:36 AM
Subject: Re: [PIC] Code packing


{Quote hidden}

> -

2008\07\08@140822 by olin piclist

face picon face
Tomás Ó hÉilidhe wrote:
> I write fully-portable C code that will work on every
> conceivable implementation of the C Standard, regardless of
> endianness, number system, size of byte, character set.

Oh, and how do you deal with multiple address spaces?  I thought the C
standard doesn't consider that.  What exactly is a VOID* on a PIC?  If you
really want to force a single descriptor for everything the processor can
address than you have to include bits to identify the address space and
process every indirect reference laboriously at run time.

If your force compilers for machines like PICs to be absolutely standards
compliant (if that is even possible), then you end up with some very
inefficient machine code.  That can be a big deal on small resource-limited
machines like PICs.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@141240 by olin piclist

face picon face
jim wrote:
> A wolf is a dog.

You can make a case for saying dogs are wolves, but all wolves are
definitely not dogs.  (Although this is a side nit that admittedly has no
bearing on the real discussion).


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@155126 by jim

flavicon
face
Wolves do belong to the canine family
Therefore they are dogs


----- Original Message -----
From: "Olin Lathrop" <TakeThisOuTolin_piclistEraseMEspamspam_OUTembedinc.com>
To: "Microcontroller discussion list - Public." <RemoveMEpiclistspamTakeThisOuTmit.edu>
Sent: Tuesday, July 08, 2008 1:14 PM
Subject: Re: [PIC] Code packing


{Quote hidden}

> --

2008\07\08@161105 by olin piclist

face picon face
jim wrote:
> Wolves do belong to the canine family
> Therefore they are dogs

Both dogs and wolves are canines, but wolves are subsets of canines and dogs
are a subset of a particular species of wolf.  Depending on usage, you could
even say that "wolf" refers to the wild animals and not to their dog
descendents.  In particular, common dogs are artificially selected
descendents of Canis lupus, referred to as Canis lupus familiaris.  There
are canines that are not wolves, and wolves that are not ancestors of dogs.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\07\08@162403 by Herbert Graf

flavicon
face
On Tue, 2008-07-08 at 16:13 -0400, Olin Lathrop wrote:
> jim wrote:
> > Wolves do belong to the canine family
> > Therefore they are dogs
>
> Both dogs and wolves are canines, but wolves are subsets of canines and dogs
> are a subset of a particular species of wolf.  Depending on usage, you could
> even say that "wolf" refers to the wild animals and not to their dog
> descendents.  In particular, common dogs are artificially selected
> descendents of Canis lupus, referred to as Canis lupus familiaris.  There
> are canines that are not wolves, and wolves that are not ancestors of dogs.

Jim/Olin/others: There is no reason for this thread to be in the PIC
realm, please move this to OT.

Thanks, TTYL

2008\07\08@181911 by Tomás Ó hÉilidhe

picon face
Olin Lathrop wrote:
> Tomás Ó hÉilidhe wrote:
>  
>> I write fully-portable C code that will work on every
>> conceivable implementation of the C Standard, regardless of
>> endianness, number system, size of byte, character set.
>>    
>
> Oh, and how do you deal with multiple address spaces?  I thought the C
> standard doesn't consider that.


The C Standard only talks about how a program should behave; it doesn't
restrict the way in which the compiler achieves the behaviour. More on
this below.


>   What exactly is a VOID* on a PIC?  If you
> really want to force a single descriptor for everything the processor can
> address than you have to include bits to identify the address space and
> process every indirect reference laboriously at run time.
>  


Let's say we had a pointer variable such as:

   void *p;

If the compiler can see that "p" only ever points to a certain address
space, then it can optimise the code accordingly. If however this
variable is used in one place to store an address within a certain
address space, and then again is used to store a different address in a
different address space, then yes you're correct in saying there'd need
to be extra information to indicate the address space. Perhaps it would
be represented something like:

struct GenericPointer {

   bit address_space;

   union {
       Pointer1 p1;
       Pointer2 p2;
   };
};

Or then again, the compiler might end up creating two code branches, one
for each address space.

Another example of compiler intuition is when it comes to integer
promotion. Take the following for instance

   char unsigned a = 7, b = 2, c = 6;
 
   a = b+c;

A standard-compliant compiler is obliged to implement integer
promotion... but the program only has to behave "as if" the integer
promotion was applied. In the example above, the compiler can work
solely with 8-Bit numbers because it sees that there's no need to use a
16-Bit one. The PIC C compiler does this.


> If your force compilers for machines like PICs to be absolutely standards
> compliant (if that is even possible), then you end up with some very
> inefficient machine code.  That can be a big deal on small resource-limited
> machines like PICs.


You'd be surprised how intuitive a compiler can be. The PIC C one is
particularly good. It can definitely produce better assembler than I can.

2008\07\08@193055 by David Meiklejohn

face
flavicon
face
Olin wrote:
>
> David Meiklejohn wrote:
>> macro   enable_ee_read
>
> Should be:
>
> enable_ee_read macro

D'oh!  That'll teach me to follow on from someone else's code without
noticing about the syntax...


David Meiklejohn
http://www.gooligum.com.au

2008\07\08@232859 by William \Chops\ Westfield

face picon face

On Jul 8, 2008, at 3:31 AM, Tamas Rudnai wrote:

> setTimer0
>         ; preparing Timer0 settings
>         TMR0(ON)
>         T0PS(.256)
>         ; make the settings live
>         setTMR0
>
> Not sure if that makes things more productive or less error prone -  
> you may
> can write extensive macro sets

At some point, you run the risk of making your code unreadable to  
other experienced PIC programmers, just because it is TOO different,  
and doesn't look like "standard PIC assembler."  Neither Olin's per-
bit documentation nor the 1<<standardBitName techniques go too far,  
but when you start defining your own macros to do everything, you're  
starting to make the code obscure to everyone else just to make it  
easier for you to write...

BillW

2008\07\09@050131 by Alan B. Pearce

face picon face
>> Nope, MCC18 does not have an integer promotion by default, so '1' and '3'
>> treated as char.
>
>MCC18 is not a valid implementation of C as defined by any of the ISO
>ANSI standards.

You will find this is the case with many C compilers that are used with
embedded small microprocessors.

2008\07\09@154111 by Gerhard Fiedler

picon face
William "Chops" Westfield wrote:

{Quote hidden}

Unless, of course, you have an editor that understands macros and can show
them while hovering over the macro... :)

Gerhard

More... (looser matching)
- Last day of these posts
- In 2008 , 2009 only
- Today
- New search...