I've been playing a little with the sdcc compiler; it's not bad at first glance but it's missing some obvious optimisations:
Code:
// pointers to the ACIA registers
volatile char * const ACIAStatus = 0xa000;
volatile char * const ACIAData = 0xa001;
int putchar(int ch)
{
// blocking write to the serial port
while ((*ACIAStatus) & 0x02) {}
*ACIAData = (char)ch;
return ch;
}
Those ACIA pointers should be constant pointers to a volatile char - the register content. However, it produces the following assembly:
Code:
_putchar:
sta _putchar_ch_65536_38
stx (_putchar_ch_65536_38 + 1)
; monitor.c: 35: while ((*ACIAStatus) & 0x02) {}
00101$:
lda _ACIAStatus
sta *(__TEMP+0)
lda (_ACIAStatus + 1)
sta *(__TEMP+1)
ldy #0x00
lda [__TEMP+0],y
and #0x02
bne 00101$
; monitor.c: 36: *ACIAData = (char)ch;
lda _ACIAData
sta *_putchar_sloc0_1_0
lda (_ACIAData + 1)
sta *(_putchar_sloc0_1_0 + 1)
lda _putchar_ch_65536_38
sta [*_putchar_sloc0_1_0],y
; monitor.c: 37: return ch;
ldx (_putchar_ch_65536_38 + 1)
lda _putchar_ch_65536_38
; monitor.c: 38: }
rts
where it has obviously defined the pointer as a word in memory; it copies it to a temporary word, and reads the byte using (abs),y. It also loops back and loads the pointer address every time. This is obviously generic so a pointer can change between calls - but one might have hoped that the const keyword would have allowed it to avoid the indirect load and the repeated load. Indeed, the ideal optimisation is perhaps a simple lda abs to the register... oh well, the whole point of C is that you don't have to worry about these things
Another bit which is somewhat confusing this early in the morning is if one replaces the
Code:
while ((*ACIAStatus) & 0x02) {}
with the hopefully more self-documenting but theoretically identical operation
Code:
while (0x02 == (*ACIAStatus) & 0x02) {}
which changes the generated assembly to
Code:
00101$:
lda _ACIAStatus
sta *(__TEMP+0)
lda (_ACIAStatus + 1)
sta *(__TEMP+1)
ldy #0x00
lda [__TEMP+0],y
ldx #0x00
and #0x02
pha
pla
cmp #0x02
bne 00115$
cpx #0x00
beq 00101$
Which includes the requested test but leaves an unnecessary pha/pla hanging around.
All very interesting, but this is the first release. At present there is zero documentation either in the installed codebase or on the wiki page associated; I may have to join their forum so at least I can ask some questions.
I think I'll knock up a quick monitor and see how that works. I've got lots of eeprom space
Neil