It's a bit strange that you'd contact the author of a piece of software about something you deem a problem/annoyance without actually understanding why you're having to do what you're doing. I don't think that conversation will end well. :P
Direct page on the 65816 is relocatable via the D register. However, opcodes using direct page (just like 6502/65c02 zero page) are 2 bytes in size (1 byte for opcode, 1 byte for operand/effective address), e.g.
lda $10. Assuming 8-bit registers (to make this example simple), if D=$2000, then
lda $10 will read from $2010. If D=$0000, then
lda $10 will read from $0010.
I cannot find anything in the ca65 manual that denotes what
a: prefix represents, but I'm willing to bet it's forcing absolute addressing (full 16-bit address, e.g.
lda $0010) rather than direct page addressing. The closest documentation for this syntax I could find
was here, with the only example I could find
being at the end here, which seems to imply
a: forces 16-bit absolute addressing (thus has nothing to do with direct page).
Rephrased/rewritten:
The assembler very likely assumes that if the effective address you've written is within $00-FF (i.e. direct page, or zero page on 6502/65c02) then you probably want the direct page version of the opcode that correlates with it. For example,
lda $10 could either be $A510 (opcode $A5 (LDA direct page), address $10), or -- if this is what you want -- it could be $AD1000 (opcode $AD (LDA absolute), address $0010).
This becomes a serious problem/complexity when you start using indexed addressing modes on top of that. Sticking with the examples:
lda $10,x could be either $B510 (opcode $B5 (LDA direct page indexed X), address $10) or $BD1000 (opcode $BD (LDA absolute indexed X), address $0010). What happens in both of these cases when X exceeds $EF? The former (direct page) will wrap back around to $00 ($FF->$00), while the latter would read from $0100 ($00FF -> $0100).
This is why you need a way to tell the assembler which addressing mode you want to use, and (I believe it looks like) the
a: prefix forces it to use absolute addressing.
Verify it yourself: look at the assembly listing of some code you write where the address is within $00-FF range, both with and without the
a: prefix. I bet you'll find without the prefix, the entire instruction uses direct page (is 2 bytes long), while with the prefix it uses absolute addressing (is 3 bytes long), and that the opcodes differ (they would have to).