Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.apple2.programmer > #5841 > unrolled thread

I/O Buffer on Page Boundary

Started byBill Chatfield <billchatfield1@gmail.com>
First post2021-08-13 22:47 -0700
Last post2021-08-16 18:11 -0700
Articles 7 — 5 participants

Back to article view | Back to comp.sys.apple2.programmer


Contents

  I/O Buffer on Page Boundary Bill Chatfield <billchatfield1@gmail.com> - 2021-08-13 22:47 -0700
    Re: I/O Buffer on Page Boundary fadden <fadden@fadden.com> - 2021-08-14 07:41 -0700
    Re: I/O Buffer on Page Boundary qkumba <peter.ferrie@gmail.com> - 2021-08-14 16:08 -0700
      Re: I/O Buffer on Page Boundary Hugh Hood <hughhood@earthlink.net> - 2021-08-14 23:11 -0500
        Re: I/O Buffer on Page Boundary qkumba <peter.ferrie@gmail.com> - 2021-08-14 21:33 -0700
    Re: I/O Buffer on Page Boundary Michael J. Mahon <mjmahon@aol.com> - 2021-08-15 01:39 -0500
      Re: I/O Buffer on Page Boundary Bill Chatfield <billchatfield1@gmail.com> - 2021-08-16 18:11 -0700

#5841 — I/O Buffer on Page Boundary

FromBill Chatfield <billchatfield1@gmail.com>
Date2021-08-13 22:47 -0700
SubjectI/O Buffer on Page Boundary
Message-ID<3597472c-de7a-486c-ae21-b6450a772935n@googlegroups.com>
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?

[toc] | [next] | [standalone]


#5842

Fromfadden <fadden@fadden.com>
Date2021-08-14 07:41 -0700
Message-ID<4c7fc9a1-7334-4a20-a035-126f6469c214n@googlegroups.com>
In reply to#5841
On Friday, August 13, 2021 at 10:47:09 PM UTC-7, billcha...@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 alignment directives are useful for stuff defined inside your program, because some instructions cost an extra cycle when they cross page boundaries.  You can allocate the buffer outside the program's binary (in C terms, use malloc() instead of a static buffer).  This is probably a better idea anyway since buffers declared inside the program take up space on disk.

If you really want to make it part of the code, a general approach is to over-allocate the buffer by 255 bytes, and then pass a pointer to a location inside the buffer instead of the start.  If it starts at an unaligned address (say $1234), you'd inc the high byte and zero the low byte, to get $1300.  This wastes up to 255 bytes of space in the binary... but so does an alignment directive.  You're just aligning at run-time instead of assembly time.

[toc] | [prev] | [next] | [standalone]


#5843

Fromqkumba <peter.ferrie@gmail.com>
Date2021-08-14 16:08 -0700
Message-ID<d5088dd5-a8cd-485b-a78b-beb2202ab61cn@googlegroups.com>
In reply to#5841
If your assembler can adjust the position using arithmetic, you can do the equivalent of "var=(*+255) & -256)", where '*' denotes the current location in memory.

[toc] | [prev] | [next] | [standalone]


#5844

FromHugh Hood <hughhood@earthlink.net>
Date2021-08-14 23:11 -0500
Message-ID<88ydnVBoJZlrDoX8nZ2dnUU7-RudnZ2d@earthlink.com>
In reply to#5843
On 8/14/2021 6:08 PM, qkumba wrote:
> If your assembler can adjust the position using arithmetic, you can
> do the equivalent of "var=(*+255) & -256)", where '*' denotes the
> current location in memory.
> 

Very clever. I'm curious, does Merlin allow the AND of a negative number 
like that?




Hugh Hood

[toc] | [prev] | [next] | [standalone]


#5845

Fromqkumba <peter.ferrie@gmail.com>
Date2021-08-14 21:33 -0700
Message-ID<c5263b3b-11a0-4508-a716-5a68e5b6e4afn@googlegroups.com>
In reply to#5844
If not, then perhaps 0FF00h or 65280.

[toc] | [prev] | [next] | [standalone]


#5846

FromMichael J. Mahon <mjmahon@aol.com>
Date2021-08-15 01:39 -0500
Message-ID<PvadncoOVfQ9K4X8nZ2dnUU7-SPNnZ2d@giganews.com>
In reply to#5841
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

[toc] | [prev] | [next] | [standalone]


#5848

FromBill Chatfield <billchatfield1@gmail.com>
Date2021-08-16 18:11 -0700
Message-ID<273ad3ef-e3ce-4871-946f-4c4aba4b0a71n@googlegroups.com>
In reply to#5846
Great ideas. Thank you everyone. I wish I was smart enough to think of them myself. :-)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.sys.apple2.programmer


csiph-web