Flash said:
Francois said:
Just to give a little more background: in my case, "x" is a
peripheral computing CRC (declared volatile). Bytes enter the CRC
>> when written to x, and reading x returns some of the CRC (not the
>> last byte fed). I'm actually doing something in the tune of
vOr |= x = dst[j] = src[j];
I would split the above in to two lines not because of problems in the
code, but because I think it would make it easier for a person to read
it, *especially* if x is volatile and you won't get back what you wrote in!
What's actually writen is closer to
// HAL.h
(..)
#ifdef ON_THAT_PLATFORM
#include "HAL_for_that_platform.h"
#endif
(..)
// enter byte into CRC, return byte
#ifndef EnterCrc
unsigned char EnterCrc(unsigned char byte);
#endif
// HAL_for_that_platform.h
(..)
// CRC hardware
volatile unsigned char CRCREG @0x12;
(..)
// enter byte into CRC, return byte, which is evaluated once
#define EnterCrc(byte) \
((unsigned char)(CRCREG =(unsigned char)(byte)))
// memutils.c
(..)
// copy one byte from src to dst, enter it into CRC, and into vOr
vOr |= EnterCrc( dst[j] = src[j] );
(..)
so the code is readable enough to my standards. It is
Sometimes it's not worth working out whether something is guaranteed to
work, because if you can't work it out someone looking at the code next
year will *also* have trouble working it out!
Of course I can use a temp but I guess the performance will
suffer measurably, and I need either a global temp in EnterCrc,
or change the interface of EnterCrc and change several pieces of
perfectly fine code. "inline" is not an option (my compiler
at best ignores it), and I find no way to declare a temp in
macro returning a value with that compiler. So it will probably
end up using an idiom of that (Cosmic) compiler:
// enter byte into CRC, return byte, which is evaluated once
#define EnterCrc(byte) \
((unsigned char)_asm(" LD _CRCREG,A")(unsigned char)(byte))
// we use an assembly language macro to avoid a temp for byte
Francois Grieu