Ophis/doc/docbook/tutor7.sgm

144 lines
4.1 KiB
Plaintext
Raw Normal View History

<chapter>
<title>Advanced Memory Segments</title>
<para>
This is the last section of the Ophis tutorial. By now we've
covered the basics of every command in the assembler; in this
final installment we show the full capabilities of
the <literal>.text</literal> and <literal>.data</literal> commands
as we produce a final set of Commodore 64 header files.
</para>
<section>
<title>The Problem</title>
<para>
Our <literal>print'str</literal> routine
in <xref linkend="tutor6-src" endterm="tutor6-fname"> accesses
memory locations $10 and $11 directly. We'd prefer to have
symbolic names for them. This reprises our concerns back in
<xref linkend="ch5-link"> when we concluded that we wanted two
separate program counters. Now we realize that we really need
three; one for the text, one for the data, and one for the zero
page data. And if we're going to allow three, we really should
allow any number.
</para>
</section>
<section>
<title>The Solution</title>
<para>
The <literal>.data</literal> and <literal>.text</literal>
commands can take a label name after them&mdash;this names a new
segment. We'll define a new segment
called <literal>zp</literal> (for <quote>zero page</quote>) and
have our zero-page variables be placed there. We can't actually
use the default origin of $0000 here either, though, because the
Commodore 64 reserves memory locations 0 and 1 to control its
memory mappers:
</para>
<programlisting>
.data zp
.org $0002
</programlisting>
<para>
Now, actually, the rest of the zero page is reserved too:
locations $02-$7F are used by the BASIC interpreter, and
locations $80-$FF are used by the KERNAL. We don't need the
BASIC interpreter, though, so we can back up all of $02-$7F at
the start of our program and restore it all when we're done:
</para>
<programlisting>
.scope
; Cache BASIC's zero page at top of available RAM.
ldx #$7E
* lda $01, x
sta $CF81, x
dex
bne -
jsr _main
; Restore BASIC's zero page and return control.
ldx #$7E
* lda $CF81, x
sta $01, x
dex
bne -
rts
_main:
; _main points at the start of the real program,
; which is actually outside of this scope
.scend
</programlisting>
<para>
The new, improved header file is <xref linkend="c64-2-src"
endterm="c64-2-fname">.
</para>
<para>
Our <literal>print'str</literal> routine is then rewritten to
declare and use a zero-page variable, like so:
</para>
<programlisting>
; PRINTSTR routine. Accumulator stores the low byte of the address,
; X register stores the high byte. Destroys the values of $10 and
; $11.
.scope
.data zp
.space _ptr 2
.text
printstr:
sta _ptr
stx _ptr+1
ldy #$00
_lp: lda (_ptr),y
beq _done
jsr chrout
iny
bne _lp
_done: rts
.scend
</programlisting>
<para>
Also, we ought to put in an extra check to make sure our
zero-page allocations don't overflow, either:
</para>
<programlisting>
.data zp
.checkpc $80
</programlisting>
<para>
That concludes our tour. The final source file
is <xref linkend="tutor7-src" endterm="tutor7-fname">.
</para>
</section>
<section>
<title>Where to go from here</title>
<para>
This tutorial has touched on everything that the assembler can
do, but it's not really well organized as a
reference. <xref linkend="ref-link"> is a better place to look
up matters of syntax or consult lists of available commands.
</para>
<para>
If you're looking for projects to undertake, the Commodore 64
and Atari 2600 development communities are both very strong, and
the Apple II and NES development communities are still alive and
well as well. There's an annual Minigame Competition that's
always looking for new entries.
</para>
</section>
</chapter>