Originally Posted by
etech58761
The compiler complained about the noInterrupts() and interrupts() instructions I'd used after seeing mention of these calls somewhere on the interwebs...?
If these functions aren't defined for you, then you'll need to write them yourself. I'd suggest that you create a bunch of "low level" functions in a header file, using the pre-processor to select from different options based on the CPU.
For example, to enable interrupts you might do something like:
Code:
static inline void
enable_interrupts()
{
#if CPU_IS_8051
const u8 enable = (IEFLAGS.EA + IEFLAGS.ES | IEFLAGS.ET0 | IEFLAGS.ET1 | IEFLAGS.EX0 | IEFLAGS.EX1);
INLINE_ASSEMBLY_START
MOV A, enable
MOV EI, A
INLINE_ASSEMBLY_END
#elif CPU_IS_ARDUINO
interrupts(); // ARDUINO library includes this function
#else
#error "Need to port this function to this compiler."
#endif
}
The second thing I'm wondering about is how to handle binary to BCD conversion - there are a number of times where the 6800-class DAA instruction is invoked.
This is a straightforward programming problem. You can have two alternatives: one where there is an opcode, and one where there is not. Write a software function to do the conversion (or, more likely, Ask The Duck to find you someone else's function and copy it) and store that in a routine called "software_toBCD". Then conditionally either call the software version, or call the CPU-specific version that invoked the inline assembly.
There are also a number of occasions where two 8-bit numbers are assembled into a 16-bit number for a bitwise shift (by loading the upper byte into Accumulator A, the lower byte into Accumulator B, and then operating on both as the 16-bit Accumulator D). How do I do this in C++?
Declare a 16-bit number and compute it:
Code:
u8 value_1, value2;
u16 result = value_1 << 8 | value_2;
Another prickly one is the fact that there are a number of ROL and ROR instructions (these rotate the bits in one direction through the carry flag, THEN back into the accumulator or memory location).
In this case, shift the bits, then mask off the non-wanted bits. Then shift the original value the other way, and 'or' the two together:
Code:
#include <ciso646>
u16 input_value;
u16 bottom_2_bits = (input_value & 0x0003) << 14;
u16 top_14_bits = (input_value >> 2) & compl(0x03 << 14);
u16 result = bottom_2_bits | top_14_bits;