Bill Chatfield <
billchatfield1@gmail.com> wrote:
ProDOS requires a file I/O buffer to start on a page boundary. Merlin has syntax for filling to the next page boundary to make this easy. But, what
if my assembler did not support "fill to next page boundary"? Is there a technique that can be used with a more basic assembler to position a
variable on a page boundary?
The problem can be solved pretty easily in any assembler that supports
integer arithmetic expressions.
First, it’s necessary to determine which page the location counter is currently on, then add one to it and cause the location counter to advance
to the first byte of that page. In many assemblers this is as simple as ORGing to the next page, but in some assemblers, including Merlin, ORG doesn’t work that way (ORG just informs the assembler that the code that follows will be executed at the ORG address, and then it continues to
assemble code and data “in-line” at the original address).
OK, so let’s compute the current page by dividing the value of the current location counter (usually represented by “*”) by 256. Then add one to it (to get the next page) and multiply by 256 to get the desired location.
A special case that needs handling is the case when the location counter is *already* page aligned. To avoid wasting a page in that case, we need to subtract one from the original value of the location counter before doing
the divide. So:
<new location counter> = ((* - 1)/256 + 1) * 256
As noted, in some assemblers, just ORG to the new location counter value.
In Merlin ORG won’t do what’s needed, but you can get the desired effect by DSing a number of bytes equal to the new location counter value minus the current location counter, like so:
ds *-1/256+1*256-*
It looks a little confusing, but since Merlin evaluates expressions from
left to right that does exactly what I described! (Note that the “*” between the “1” and “256” means “multiply”, not “current location counter”.)
Strictly speaking, this isn’t required in Merlin since it has a built-in “page align” capability, but this technique can be used to align to *any* boundary if you substitute the desired boundary value for 256.
I usually define a macro “align” to do this, where the macro parameter takes the place of 256.
It has the advantage that it never wastes more space than is actually
required to align to the desired boundary, which is half the boundary value
on average, and therefore practically insignificant.
--
-michael - NadaNet 3.1 and AppleCrate II:
http://michaeljmahon.com
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)