barrym95838 wrote:
BigDumbDinosaur wrote:
... A powerful technique with the '816 is to reserve some stack space for whatever number of DP locations you need and then point DP at the bottom of that space. When the function that is using that ephemeral DP space is done with it a stack cleanup gets rid of it ...
You are describing a technique similar to what I learned to call a "stack frame pointer" technique ... different because the classical stack frame pointer used positive offsets for the function "arguments" and negative offsets for the "local variables". This worked in a more human-readable manner when the local variable space grew dynamically during the function execution, because the stack pointer would move but the frame pointer wouldn't ... the compilers didn't care, because they could easily keep track of the changing offsets, so as long as the stack pointer and the frame pointer had equal indexing abilities, it was pretty much a non-issue. With the 65c816's stack-pointer-relative addressing modes like d,S and (d,S),Y available, I don't see the use of DP in the manner you describe as being quite as big of an advantage as it would be without them. I see the 65xx DP as more of a "global" area, but that's just me ...
An ephemeral direct page has plenty of uses. For example, consider an operating system function that maintains a software clock in direct page, said clock driven by a jiffy IRQ. Those bytes could be stashed in some out of the way location in absolute bank $00 RAM, and only when they need to be read (get the time) or written (update or set the time) would
DP be pointed at them. An interrupt handler would take care of the updates and kernel calls would take care of the read and set operations, in all cases by temporarily pointing
DP at the base location of the clock. The read or write code will execute faster without having valuable direct page memory constantly allocated to timekeeping. My POC V2 preliminary firmware does exactly what I described—kernel direct page is actually at $00D800, which is that
RAM island Jeff noted in a post about V2's memory map.
Another case is long addressing via pointers,
[<dp>] and
[<dp>],Y. If you combine that with
DP being ephemeral in nature, a called function can set up pointer space on the stack that will allow the function to touch any part of the 65C816's address space with no boundaries. In contrast,
<offset>,S and
(<offset>,S),Y are limited to 64KB contiguous bytes, starting in the bank currently loaded into
DB.
Dr Jefyll wrote:
d,S and (d,S),Y modes restrict you to 64K (unless there's diddling with the DBR -- something usually worth avoiding, IMO).
Yep! Fooling around with
DB is not convenient, as the only way to access the register is via the stack. In contrast,
DP can be directly transferred to and from the accumulator, as well as pushed and pulled. There are occasions where faster and more succinct code can be written by saving the current value of
DB and temporarily changing it. However, I've not encountered such a need to date, and I've written quite a bit of '816 code.
———————————————————————————————
Edit: Added a missing link.