Thank you all who commented!
I don't see a 16-bit pointer, just a 16-bit instruction
Padauk's documentation is a bit scattered and that part is actually in the help of the IDE (which is where their C dialect is documented). The recommended way to implement pointers is (as weird as it may seem) by declaring a WORD and using it like a pointer:
WORD ptr;
BYTE b, buf[16];
ptr = &buf[0];
ptr = ptr + 5;
b = *ptr; // buf[5] is assigned to b
I had a look at the compiled code and indeed, a pointer assignment like
ptr = &buf[0] compiles into four instructions, namely
- moving the address of buf into the accumulator (the address at this point is an immediate operand, i.e. a constant - this is probably the reason why the compiler insists that arrays must be global variables, so it can allocate static memory addresses to it which are known at compile time
- moving the accumulator value into the low byte of the pointer
- moving 0 into the accumulator
- moving the accumulator value into the high byte of the pointer
Now the interesting part is: an indirect read using the pointer (i.e.
b = *ptr) is in fact compiled into an IDXM instruction (as you correctly assumed), and just a single one. So clearly, the high byte of the pointer is just wasted. Any assignment will write 0 to it (which is also a waste of program memory and processing time) and the value will never even be read.
What if we try to use a BYTE as a pointer? -> Syntax error. Using it in this way
*ptr is only permitted with words, not with bytes.
So those 16-bit pointers are related to Padauk's Mini-C compiler, not to the architecture itself. By using assembly, you can get by with just a byte as a pointer. And that makes no sense whatsoever. I almost believe they inherited the compiler from someone who wrote it for 16-bit architectures and either didn't bother adapting this part or ran into problems and decided not to bother. I consider this a bug. Sure it's fine to encourage code to be easily portable to chips with more than 256 bytes of RAM (which Padauk doesn't have), but on an architecture with 8-bit memory addresses, the compiler should really not insist on 16-bit pointers, especially since it compiles read operations with such pointers into single 8-bit operations.
So my conclusion is: as long as I have enough RAM, I can use a WORD as a pointer. When I have to optimize for every byte, I need to code these parts in assembly and use a byte.
So the Padauk micro is unable to read program memory through code? That seems very limiting.
Exactly. As others have already said, the Padauk has a RET instruction with an immediate operand. It loads the accumulator with the immediate operand and returns from a call. You can use it together with the PCADD instruction (which adds its immediate operand to the program counter) to implement a constant table in program memory. It's neither efficient nor convenient... but it has its use cases. I needed to implement a simple lookup table with 8 entries. Using an array in RAM was not an option due to limited RAM, using a SWITCH statement worked but resulted in an endless sequence of loads, compares and jumps, so did it with PCADD and RET Imm. Although you have to use a CALL first (to then return from) and it looks a bit ugly, it was still the best way to do it. And you are right it's very limiting - but then again, that's the 3 cent microcontroller
The dual-core Padauk devices have two instructions called LDTABL and LDTABH which allow reading a byte from program memory in the accumulator. I haven't looked more into it since the chips I am working with don't support it, but according to Free PDK, the address is stored in 9 bits of the opcode. Since there are two instructions, that would mean you can address up to 1KB. The program memory is up to 4KB, so 1KB is not enough and I assume that such tables must be in the last quarter of the ROM or something like that. Again, quirky compromises, but cheap silicon. In any case, this is not related to the question of 16-bit pointers, as LDTAB works only with constant addresses, not with pointer variables.