HTML edition of Programming With Ophis 2

This commit is contained in:
Michael Martin 2012-06-16 02:07:47 -07:00
parent ba1720619f
commit 24402e026c
67 changed files with 17883 additions and 0 deletions

311
book/a1034.html Normal file
View File

@ -0,0 +1,311 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Ophis Command Reference</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="PREVIOUS"
TITLE="fibonacci.oph"
HREF="x1030.html"><LINK
REL="NEXT"
TITLE="Basic arguments"
HREF="x1101.html"></HEAD
><BODY
CLASS="APPENDIX"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1030.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1101.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="APPENDIX"
><H1
><A
NAME="REF-LINK"
></A
>Ophis Command Reference</H1
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN1036"
>Command Modes</A
></H1
><P
> These mostly follow the <I
CLASS="EMPHASIS"
>MOS Technology 6500
Microprocessor Family Programming Manual</I
>, except
for the Accumulator mode. Accumulator instructions are written
and interpreted identically to Implied mode instructions.
</P
><P
></P
><UL
><LI
><P
><I
CLASS="EMPHASIS"
>Implied:</I
> <TT
CLASS="LITERAL"
>RTS</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Accumulator:</I
> <TT
CLASS="LITERAL"
>LSR</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Immediate:</I
> <TT
CLASS="LITERAL"
>LDA #$06</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Zero Page:</I
> <TT
CLASS="LITERAL"
>LDA $7C</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Zero Page, X:</I
> <TT
CLASS="LITERAL"
>LDA $7C,X</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Zero Page, Y:</I
> <TT
CLASS="LITERAL"
>LDA $7C,Y</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Absolute:</I
> <TT
CLASS="LITERAL"
>LDA $D020</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Absolute, X:</I
> <TT
CLASS="LITERAL"
>LDA $D000,X</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Absolute, Y:</I
> <TT
CLASS="LITERAL"
>LDA $D000,Y</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>(Zero Page Indirect, X):</I
> <TT
CLASS="LITERAL"
>LDA ($80, X)</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>(Zero Page Indirect), Y:</I
> <TT
CLASS="LITERAL"
>LDA ($80), Y</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>(Absolute Indirect):</I
> <TT
CLASS="LITERAL"
>JMP ($A000)</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Relative:</I
> <TT
CLASS="LITERAL"
>BNE loop</TT
></P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>(Absolute Indirect, X):</I
> <TT
CLASS="LITERAL"
>JMP ($A000, X)</TT
> &#8212; Only available with 65C02 extensions</P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>(Zero Page Indirect):</I
> <TT
CLASS="LITERAL"
>LDX ($80)</TT
> &#8212; Only available with 65C02 extensions</P
></LI
></UL
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1030.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1101.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>fibonacci.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Basic arguments</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

185
book/a975.html Normal file
View File

@ -0,0 +1,185 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Example Programs</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="PREVIOUS"
TITLE="Example: Fibonnacci Numbers"
HREF="x967.html"><LINK
REL="NEXT"
TITLE="hello2.oph"
HREF="x982.html"></HEAD
><BODY
CLASS="APPENDIX"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x967.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x982.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="APPENDIX"
><H1
><A
NAME="AEN975"
></A
>Example Programs</H1
><P
> This Appendix collects all the programs referred to in the course
of this manual.
</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR1-SRC"
><TT
CLASS="FILENAME"
>hello1.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.word $0801
.org $0801
.outfile "hello.prg"
.word next, 10 ; Next line and current line number
.byte $9e," 2064",0 ; SYS 2064
next: .word 0 ; End of program
.advance 2064
ldx #0
loop: lda hello, x
beq done
jsr $ffd2
inx
bne loop
done: rts
hello: .byte "HELLO, WORLD!", 0</PRE
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x967.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x982.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Example: Fibonnacci Numbers</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello2.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

654
book/book1.html Normal file
View File

@ -0,0 +1,654 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Programming with Ophis</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="NEXT"
TITLE="Preface"
HREF="f10.html"></HEAD
><BODY
CLASS="BOOK"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="BOOK"
><A
NAME="AEN1"
></A
><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
><A
NAME="AEN2"
>Programming with Ophis</A
></H1
><H3
CLASS="AUTHOR"
><A
NAME="AEN4"
></A
>Michael Martin</H3
><P
CLASS="COPYRIGHT"
>Copyright &copy; 2006-2012 Michael Martin</P
><HR></DIV
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="f10.html"
>Preface</A
></DT
><DD
><DL
><DT
><A
HREF="f10.html#AEN15"
>History of the project</A
></DT
><DT
><A
HREF="x29.html"
>Getting a copy of Ophis</A
></DT
><DT
><A
HREF="x41.html"
>About the examples</A
></DT
></DL
></DD
><DT
>I. <A
HREF="p50.html"
>Using the Ophis Assembler</A
></DT
><DD
><DL
><DT
><A
HREF="c55.html"
>The basics</A
></DT
><DD
><DL
><DT
><A
HREF="c55.html#AEN68"
>A note on numeric notation</A
></DT
><DT
><A
HREF="x71.html"
>Producing Commodore 64 programs</A
></DT
><DT
><A
HREF="x140.html"
>Related commands and options</A
></DT
><DT
><A
HREF="x161.html"
>Writing the actual code</A
></DT
><DT
><A
HREF="x170.html"
>Assembling the code</A
></DT
></DL
></DD
><DT
><A
HREF="c223.html"
>Labels and aliases</A
></DT
><DD
><DL
><DT
><A
HREF="c223.html#AEN229"
>Temporary labels</A
></DT
><DT
><A
HREF="x237.html"
>Anonymous labels</A
></DT
><DT
><A
HREF="x248.html"
>Aliasing</A
></DT
></DL
></DD
><DT
><A
HREF="c259.html"
>Headers, Libraries, and Macros</A
></DT
><DD
><DL
><DT
><A
HREF="c259.html#AEN263"
>Header files and libraries</A
></DT
><DT
><A
HREF="x284.html"
>Macros</A
></DT
><DT
><A
HREF="x314.html"
>Example code</A
></DT
></DL
></DD
><DT
><A
HREF="c319.html"
>Character maps</A
></DT
><DT
><A
HREF="c353.html"
>Local variables and memory segments</A
></DT
><DT
><A
HREF="c395.html"
>Expressions</A
></DT
><DT
><A
HREF="c443.html"
>Advanced Memory Segments</A
></DT
><DD
><DL
><DT
><A
HREF="c443.html#AEN448"
>The Problem</A
></DT
><DT
><A
HREF="x454.html"
>The Solution</A
></DT
><DT
><A
HREF="x476.html"
>Where to go from here</A
></DT
></DL
></DD
></DL
></DD
><DT
>II. <A
HREF="p481.html"
>To HLL and Back</A
></DT
><DD
><DL
><DT
><A
HREF="c486.html"
>The Second Step</A
></DT
><DD
><DL
><DT
><A
HREF="c486.html#AEN489"
>The problem</A
></DT
><DT
><A
HREF="x498.html"
>The solution</A
></DT
><DT
><A
HREF="x504.html"
>Unsigned arithmetic</A
></DT
><DT
><A
HREF="x527.html"
>16-bit addition and subtraction</A
></DT
><DT
><A
HREF="x537.html"
>16-bit comparisons</A
></DT
></DL
></DD
><DT
><A
HREF="c543.html"
>Structured Programming</A
></DT
><DD
><DL
><DT
><A
HREF="c543.html#AEN548"
>Control constructs</A
></DT
><DT
><A
HREF="x597.html"
>The stack</A
></DT
><DT
><A
HREF="x603.html"
>Procedures and register saving</A
></DT
><DT
><A
HREF="x621.html"
>Variables</A
></DT
><DT
><A
HREF="x666.html"
>Data structures</A
></DT
><DT
><A
HREF="x719.html"
>A modest example: Insertion sort on linked lists</A
></DT
></DL
></DD
><DT
><A
HREF="c748.html"
>Pointers and Indirection</A
></DT
><DD
><DL
><DT
><A
HREF="c748.html#AEN753"
>The absolute basics</A
></DT
><DT
><A
HREF="x782.html"
>Pointer arithmetic</A
></DT
><DT
><A
HREF="x798.html"
>What about Indexed Indirect?</A
></DT
><DT
><A
HREF="x805.html"
>Comparison with the other indexed forms</A
></DT
><DT
><A
HREF="x813.html"
>Conclusion</A
></DT
></DL
></DD
><DT
><A
HREF="c816.html"
>Functionals</A
></DT
><DD
><DL
><DT
><A
HREF="c816.html#AEN821"
>Function Pointers</A
></DT
><DT
><A
HREF="x836.html"
>A quick digression on how subroutines work</A
></DT
><DT
><A
HREF="x855.html"
>Dispatch-on-type and Data-Directed Assembler</A
></DT
><DT
><A
HREF="x871.html"
>VTables and Object-Oriented Assembler</A
></DT
><DT
><A
HREF="x892.html"
>A final reminder</A
></DT
></DL
></DD
><DT
><A
HREF="c900.html"
>Call Stacks</A
></DT
><DD
><DL
><DT
><A
HREF="c900.html#AEN904"
>Recursion</A
></DT
><DT
><A
HREF="x915.html"
>Our Goals</A
></DT
><DT
><A
HREF="x967.html"
>Example: Fibonnacci Numbers</A
></DT
></DL
></DD
></DL
></DD
><DT
><A
HREF="a975.html"
>Example Programs</A
></DT
><DD
><DL
><DT
><A
HREF="a975.html#TUTOR1-SRC"
><TT
CLASS="FILENAME"
>hello1.oph</TT
></A
></DT
><DT
><A
HREF="x982.html"
><TT
CLASS="FILENAME"
>hello2.oph</TT
></A
></DT
><DT
><A
HREF="x986.html"
><TT
CLASS="FILENAME"
>c64-1.oph</TT
></A
></DT
><DT
><A
HREF="x990.html"
><TT
CLASS="FILENAME"
>c64kernal.oph</TT
></A
></DT
><DT
><A
HREF="x994.html"
><TT
CLASS="FILENAME"
>hello3.oph</TT
></A
></DT
><DT
><A
HREF="x998.html"
><TT
CLASS="FILENAME"
>hello4a.oph</TT
></A
></DT
><DT
><A
HREF="x1002.html"
><TT
CLASS="FILENAME"
>hello4b.oph</TT
></A
></DT
><DT
><A
HREF="x1006.html"
><TT
CLASS="FILENAME"
>hello4c.oph</TT
></A
></DT
><DT
><A
HREF="x1010.html"
><TT
CLASS="FILENAME"
>hello5.oph</TT
></A
></DT
><DT
><A
HREF="x1014.html"
><TT
CLASS="FILENAME"
>hello6.oph</TT
></A
></DT
><DT
><A
HREF="x1018.html"
><TT
CLASS="FILENAME"
>c64_0.oph</TT
></A
></DT
><DT
><A
HREF="x1022.html"
><TT
CLASS="FILENAME"
>hello7.oph</TT
></A
></DT
><DT
><A
HREF="x1026.html"
><TT
CLASS="FILENAME"
>structuredemo.oph</TT
></A
></DT
><DT
><A
HREF="x1030.html"
><TT
CLASS="FILENAME"
>fibonacci.oph</TT
></A
></DT
></DL
></DD
><DT
><A
HREF="a1034.html"
>Ophis Command Reference</A
></DT
><DD
><DL
><DT
><A
HREF="a1034.html#AEN1036"
>Command Modes</A
></DT
><DT
><A
HREF="x1101.html"
>Basic arguments</A
></DT
><DD
><DL
><DT
><A
HREF="x1101.html#AEN1104"
>Numeric types</A
></DT
><DT
><A
HREF="x1101.html#AEN1127"
>Label types</A
></DT
><DT
><A
HREF="x1101.html#AEN1140"
>String types</A
></DT
></DL
></DD
><DT
><A
HREF="x1149.html"
>Compound Arguments</A
></DT
><DT
><A
HREF="x1176.html"
>Memory Model</A
></DT
><DD
><DL
><DT
><A
HREF="x1176.html#AEN1179"
>Basic PC tracking</A
></DT
><DT
><A
HREF="x1176.html#AEN1188"
>Basic Segmentation simulation</A
></DT
><DT
><A
HREF="x1176.html#AEN1212"
>General Segmentation Simulation</A
></DT
></DL
></DD
><DT
><A
HREF="x1221.html"
>Macros</A
></DT
><DD
><DL
><DT
><A
HREF="x1221.html#AEN1225"
>Defining Macros</A
></DT
><DT
><A
HREF="x1221.html#AEN1231"
>Invoking Macros</A
></DT
><DT
><A
HREF="x1221.html#AEN1239"
>Passing Arguments to Macros</A
></DT
><DT
><A
HREF="x1221.html#AEN1249"
>Features and Restrictions of the Ophis Macro Model</A
></DT
></DL
></DD
><DT
><A
HREF="x1261.html"
>Assembler directives</A
></DT
></DL
></DD
></DL
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="f10.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Preface</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

215
book/c223.html Normal file
View File

@ -0,0 +1,215 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Labels and aliases</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Assembling the code"
HREF="x170.html"><LINK
REL="NEXT"
TITLE="Anonymous labels"
HREF="x237.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x170.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x237.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN223"
></A
>Labels and aliases</H1
><P
> Labels are an important part of your code. However, since each
label must normally be unique, this can lead to <SPAN
CLASS="QUOTE"
>"namespace
pollution,"</SPAN
> and you'll find yourself going through ever
more contorted constructions to generate unique label names.
Ophis offers two solutions to this: <I
CLASS="EMPHASIS"
>anonymous
labels</I
> and <I
CLASS="EMPHASIS"
>temporary labels</I
>. This
tutorial will cover both of these facilities, and also introduce
the aliasing mechanism.
</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN229"
>Temporary labels</A
></H1
><P
> Temporary labels are the easiest to use. If a label begins with
an underscore, it will only be reachable from inside the
innermost enclosing scope. Scopes begin when
a <TT
CLASS="LITERAL"
>.scope</TT
> statement is encountered. This
produces a new, inner scope if there is another scope in use.
The <TT
CLASS="LITERAL"
>.scend</TT
> command ends the innermost
currently active scope.
</P
><P
> We can thus rewrite our header data using temporary labels, thus
allowing the main program to have a label
named <TT
CLASS="LITERAL"
>next</TT
> if it wants.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.word $0801
.org $0801
.scope
.word _next, 10 ; Next line and current line number
.byte $9e," 2064",0 ; SYS 2064
_next: .word 0 ; End of program
.scend
.advance 2064</PRE
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x170.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x237.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Assembling the code</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Anonymous labels</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

251
book/c259.html Normal file
View File

@ -0,0 +1,251 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Headers, Libraries, and Macros</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Aliasing"
HREF="x248.html"><LINK
REL="NEXT"
TITLE="Macros"
HREF="x284.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x248.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x284.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="CH3-LINK"
></A
>Headers, Libraries, and Macros</H1
><P
> In this chapter we will split away parts of our <SPAN
CLASS="QUOTE"
>"Hello
World"</SPAN
> program into reusable header files and libraries.
We will also abstract away our string printing technique into a
macro which may be invoked at will, on arbitrary strings. We will
then multiply the output of our program tenfold.
</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN263"
>Header files and libraries</A
></H1
><P
> The prelude to our program&#8212;the <TT
CLASS="FILENAME"
>PRG</TT
>
information and the BASIC program&#8212;are going to be the same
in many, many programs. Thus, we should put them into a header
file to be included later. The <TT
CLASS="LITERAL"
>.include</TT
>
directive will load a file and insert it as source at the
designated point.
</P
><P
> A related directive, <TT
CLASS="LITERAL"
>.require</TT
>, will include
the file as long as it hasn't been included yet elsewhere. It
is useful for ensuring a library is linked in.
</P
><P
> For pre-assembled code or raw binary data,
the <TT
CLASS="LITERAL"
>.incbin</TT
> directive lets you include the
contents of a binary file directly in the output. This is handy
for linking in pre-created graphics or sound data.
</P
><P
> If you only wish to include part of a binary
file, <TT
CLASS="LITERAL"
>.incbin</TT
> takes up to two optional
arguments, naming the file offset at which to start reading and
the number of characters to read.
</P
><P
> As a sample library, we will expand the definition of
the <TT
CLASS="LITERAL"
>chrout</TT
> routine to include the standard
names for every KERNAL routine. Our header file will
then <TT
CLASS="LITERAL"
>.require</TT
> it.
</P
><P
> We'll also add some convenience aliases for things like reverse
video, color changes, and shifting between upper case/graphics
and mixed case text. We'd feed those to
the <TT
CLASS="LITERAL"
>chrout</TT
> routine to get their effects.
</P
><P
> Since there have been no interesting changes to the prelude, and
the KERNAL values are standard, we do not reproduce them here.
(The files in question are <A
HREF="x986.html"
><I
><I
>c64-1.oph</I
></I
></A
> and <A
HREF="x990.html"
><I
><I
>c64kernal.oph</I
></I
></A
>.) The <TT
CLASS="FILENAME"
>c64kernal.oph</TT
>
header is likely to be useful in your own projects, and it is
available in the <TT
CLASS="LITERAL"
>platform/</TT
> directory for easy
inclusion.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x248.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x284.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Aliasing</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Macros</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

339
book/c319.html Normal file
View File

@ -0,0 +1,339 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Character maps</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Example code"
HREF="x314.html"><LINK
REL="NEXT"
TITLE="Local variables and memory segments"
HREF="c353.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x314.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c353.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="CH4-LINK"
></A
>Character maps</H1
><P
> Now we will close the gap between the Commodore's
version of ASCII and the real one. We'll also add a time-delay
routine to slow down the output. This routine isn't really of
interest to us right now, so we'll add a subroutine
called <TT
CLASS="LITERAL"
>delay</TT
> that executes 2,560*(accumulator)
<KBD
CLASS="USERINPUT"
>NOP</KBD
>s. By the time the program is finished,
we'll have executed 768,000 no-ops.
</P
><P
> There actually are better ways of getting a time-delay on the
Commodore 64; we'll deal with those in <A
HREF="c353.html"
>the Chapter called <I
>Local variables and memory segments</I
></A
>.
As a result, there isn't really a lot to discuss here. The later
tutorials will be building off of <A
HREF="x998.html"
><I
><I
>hello4a.oph</I
></I
></A
>, so you may want to get familiar with
that. Note also the change to the body of
the <TT
CLASS="LITERAL"
>greet</TT
> macro.
</P
><P
> On to the topic at hand. Let's change the code to use mixed case.
We defined the <TT
CLASS="LITERAL"
>upper'case</TT
>
and <TT
CLASS="LITERAL"
>lower'case</TT
> aliases back
in <A
HREF="c259.html"
>the Chapter called <I
>Headers, Libraries, and Macros</I
></A
> as part of the
standard <A
HREF="x990.html"
><I
><I
>c64kernal.oph</I
></I
></A
>
header, so we can add this before our invocations of
the <TT
CLASS="LITERAL"
>greet</TT
> macro:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> lda #lower'case
jsr chrout</PRE
></TD
></TR
></TABLE
><P
> And that will put us into mixed case mode. So, now we just need
to redefine the data so that it uses the mixed-case:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>hello1: .byte "Hello, ",0
hello2: .byte "!", 13, 0
target1: .byte "programmer", 0
target2: .byte "room", 0
target3: .byte "building", 0
target4: .byte "neighborhood", 0
target5: .byte "city", 0
target6: .byte "nation", 0
target7: .byte "world", 0
target8: .byte "Solar System", 0
target9: .byte "Galaxy", 0
target10: .byte "Universe", 0</PRE
></TD
></TR
></TABLE
><P
> The code that does this is in <A
HREF="x1002.html"
><I
><I
>hello4b.oph</I
></I
></A
>. If you assemble and run it, you will
notice that the output is not what we want. In particular, upper
and lowercase are reversed, so we have messages
like <SAMP
CLASS="COMPUTEROUTPUT"
>hELLO, sOLAR sYSTEM!</SAMP
>. For
the specific case of PETSCII, we can just fix our strings, but
that's less of an option if we're writing for a game console that
puts its letters in arbitrary locations. We need to remap how
strings are turned into byte values.
The <TT
CLASS="LITERAL"
>.charmap</TT
> and <TT
CLASS="LITERAL"
>.charmapbin</TT
>
directives do what we need.
</P
><P
> The <TT
CLASS="LITERAL"
>.charmap</TT
> directive usually takes two
arguments; a byte (usually in character form) indicating the ASCII
value to start remapping from, and then a string giving the new
values. To do our case-swapping, we write two directives before
defining any string constants:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.charmap 'A, "abcdefghijklmnopqrstuvwxyz"
.charmap 'a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"</PRE
></TD
></TR
></TABLE
><P
> Note that the <TT
CLASS="LITERAL"
>'a</TT
> constant in the second
directive refers to the <SPAN
CLASS="QUOTE"
>"a"</SPAN
> character in the source,
not in the current map.
</P
><P
> The fixed code is in <A
HREF="x1006.html"
><I
><I
>hello4c.oph</I
></I
></A
>, and will produce the expected results
when run.
</P
><P
> An alternative is to use a <TT
CLASS="LITERAL"
>.charmapbin</TT
>
directive to replace the entire character map directly. This
specifies an external file, 256 bytes long, that is loaded in at
that point. A binary character map for the Commodore 64 is
provided with the sample programs
as <TT
CLASS="FILENAME"
>petscii.map</TT
>.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x314.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c353.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Example code</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Local variables and memory segments</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

409
book/c353.html Normal file
View File

@ -0,0 +1,409 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Local variables and memory segments</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Character maps"
HREF="c319.html"><LINK
REL="NEXT"
TITLE="Expressions"
HREF="c395.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c319.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c395.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="CH5-LINK"
></A
>Local variables and memory segments</H1
><P
> As mentioned in <A
HREF="c319.html"
>the Chapter called <I
>Character maps</I
></A
>, there are better ways
to handle waiting than just executing vast numbers of NOPs. The
Commodore 64 KERNAL library includes a <TT
CLASS="LITERAL"
>rdtim</TT
>
routine that returns the uptime of the machine, in
60<SUP
>th</SUP
>s of a second, as a 24-bit integer.
The Commodore 64 programmer's guide available online actually has
a bug in it, reversing the significance of the A and Y registers.
The accumulator holds the <I
CLASS="EMPHASIS"
>least</I
> significant
byte, not the most.
</P
><P
> Here's a first shot at a better delay routine:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.scope
; data used by the delay routine
_tmp: .byte 0
_target: .byte 0
delay: sta _tmp ; save argument (rdtim destroys it)
jsr rdtim
clc
adc _tmp ; add current time to get target
sta _target
* jsr rdtim
cmp _target
bmi - ; Buzz until target reached
rts
.scend</PRE
></TD
></TR
></TABLE
><P
> This works, but it eats up two bytes of file space that don't
really need to be specified. Also, it's modifying data inside a
program text area, which isn't good if you're assembling to a ROM
chip. (Since the Commodore 64 stores its programs in RAM, it's
not an issue for us here.) A slightly better solution is to
use <TT
CLASS="LITERAL"
>.alias</TT
> to assign the names to chunks of RAM
somewhere. There's a 4K chunk of RAM from $C000 through $CFFF
between the BASIC ROM and the I/O ROM that should serve our
purposes nicely. We can replace the definitions
of <TT
CLASS="LITERAL"
>_tmp</TT
> and <TT
CLASS="LITERAL"
>_target</TT
> with:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ; data used by the delay routine
.alias _tmp $C000
.alias _target $C001</PRE
></TD
></TR
></TABLE
><P
> This works better, but now we've just added a major bookkeeping
burden upon ourselves&#8212;we must ensure that no routines step on
each other. What we'd really like are two separate program
counters&#8212;one for the program text, and one for our variable
space.
</P
><P
> Ophis lets us do this with the <TT
CLASS="LITERAL"
>.text</TT
>
and <TT
CLASS="LITERAL"
>.data</TT
> commands.
The <TT
CLASS="LITERAL"
>.text</TT
> command switches to the program-text
counter, and the <TT
CLASS="LITERAL"
>.data</TT
> command switches to the
variable-data counter. When Ophis first starts assembling a file,
it starts in <TT
CLASS="LITERAL"
>.text</TT
> mode.
</P
><P
> To reserve space for a variable, use the .space command. This
takes the form:
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.space varname size</PRE
></TD
></TR
></TABLE
>
which assigns the name <TT
CLASS="LITERAL"
>varname</TT
> to the current
program counter, then advances the program counter by the amount
specified in <TT
CLASS="LITERAL"
>size</TT
>. Nothing is output to the
final binary as a result of the <TT
CLASS="LITERAL"
>.space</TT
> command.
</P
><P
> You may not put in any commands that produce output into
a <TT
CLASS="LITERAL"
>.data</TT
> segment. Generally, all you will be
using are <TT
CLASS="LITERAL"
>.org</TT
> and <TT
CLASS="LITERAL"
>.space</TT
>
commands. Ophis will not complain if you
use <TT
CLASS="LITERAL"
>.space</TT
> inside a <TT
CLASS="LITERAL"
>.text</TT
>
segment, but this is nearly always wrong.
</P
><P
> The final version of <TT
CLASS="LITERAL"
>delay</TT
> looks like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>; DELAY routine. Takes values from the Accumulator and pauses
; for that many jiffies (1/60th of a second).
.scope
.data
.space _tmp 1
.space _target 1
.text
delay: sta _tmp ; save argument (rdtim destroys it)
jsr rdtim
clc
adc _tmp ; add current time to get target
sta _target
* jsr rdtim
cmp _target
bmi - ; Buzz until target reached
rts
.scend</PRE
></TD
></TR
></TABLE
><P
> We're not quite done yet, however, because we have to tell the
data segment where to begin. (If we don't, it starts at 0, which
is usually wrong.) We add a very brief data segment to the top of
our code:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data
.org $C000
.text</PRE
></TD
></TR
></TABLE
><P
> This will run. However, we also ought to make sure that we aren't
overstepping any boundaries. Our program text shouldn't run into
the BASIC chip at $A000, and our data shouldn't run into the I/O
region at $D000. The <TT
CLASS="LITERAL"
>.checkpc</TT
> command lets us
assert that the program counter hasn't reached a specific point
yet. We put, at the end of our code:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.checkpc $A000
.data
.checkpc $D000</PRE
></TD
></TR
></TABLE
><P
> The final program is available as <A
HREF="x1010.html"
><I
><I
>hello5.oph</I
></I
></A
>. Note that we based this on the
all-uppercase version from the last section, not any of the
charmapped versions.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c319.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c395.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Character maps</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Expressions</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

355
book/c395.html Normal file
View File

@ -0,0 +1,355 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Expressions</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Local variables and memory segments"
HREF="c353.html"><LINK
REL="NEXT"
TITLE="Advanced Memory Segments"
HREF="c443.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c353.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c443.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN395"
></A
>Expressions</H1
><P
> Ophis permits a reasonably rich set of arithmetic operations to be
done at assemble time. So far, all of our arguments and values
have either been constants or label names. In this chapter, we
will modify the <TT
CLASS="LITERAL"
>print</TT
> macro so that it calls a
subroutine to do the actual printing. This will shrink the final
code size a fair bit.
</P
><P
> Here's our printing routine. It's fairly straightforward.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="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
printstr:
sta $10
stx $11
ldy #$00
_lp: lda ($10), y
beq _done
jsr chrout
iny
bne _lp
_done: rts
.scend</PRE
></TD
></TR
></TABLE
><P
> However, now we are faced with the problem of what to do with
the <TT
CLASS="LITERAL"
>print</TT
> macro. We need to take a 16-bit
value and store it in two 8-bit registers. We can use
the <TT
CLASS="LITERAL"
>&#60;</TT
> and <TT
CLASS="LITERAL"
>&#62;</TT
> operators
to take the low or high byte of a word, respectively.
The <TT
CLASS="LITERAL"
>print</TT
> macro becomes:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.macro print
lda #&#60;_1
ldx #&#62;_1
jsr printstr
.macend</PRE
></TD
></TR
></TABLE
><P
> Also, since BASIC uses the locations $10 and $11, we should really
cache them at the start of the program and restore them at the
end:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data
.org $C000
.space cache 2
.text
; Save the zero page locations that printstr uses.
lda $10
sta cache
lda $11
sta cache+1
; ... main program goes here ...
; Restore the zero page values printstr uses.
lda cache
sta $10
lda cache+1
sta $11</PRE
></TD
></TR
></TABLE
><P
> Note that we only have to name <TT
CLASS="LITERAL"
>cache</TT
> once, but
can use addition to refer to any offset from it.
</P
><P
> Ophis supports following operations, with the following precedence
levels (higher entries bind more tightly):
</P
><DIV
CLASS="TABLE"
><A
NAME="AEN412"
></A
><P
><B
>Table 1. Ophis Operators</B
></P
><TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
CELLSPACING="0"
CELLPADDING="4"
CLASS="CALSTABLE"
><THEAD
><TR
><TH
ALIGN="CENTER"
>Operators</TH
><TH
ALIGN="CENTER"
>Description</TH
></TR
></THEAD
><TBODY
><TR
><TD
><TT
CLASS="LITERAL"
>[ ]</TT
></TD
><TD
>Parenthesized expressions</TD
></TR
><TR
><TD
><TT
CLASS="LITERAL"
>&#60; &#62;</TT
></TD
><TD
>Byte selection (low, high)</TD
></TR
><TR
><TD
><TT
CLASS="LITERAL"
>* /</TT
></TD
><TD
>Multiply, divide</TD
></TR
><TR
><TD
><TT
CLASS="LITERAL"
>+ -</TT
></TD
><TD
>Add, subtract</TD
></TR
><TR
><TD
><TT
CLASS="LITERAL"
>| &#38; ^</TT
></TD
><TD
>Bitwise OR, AND, XOR</TD
></TR
></TBODY
></TABLE
></DIV
><P
> Note that brackets, not parentheses, are used to group arithmetic
operations. This is because parentheses are used for the indirect
addressing modes, and it makes parsing much easier.
</P
><P
> The code for this version of the code is
in <A
HREF="x1014.html"
><I
><I
>hello6.oph</I
></I
></A
>.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c353.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c443.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Local variables and memory segments</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Advanced Memory Segments</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

191
book/c443.html Normal file
View File

@ -0,0 +1,191 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Advanced Memory Segments</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Expressions"
HREF="c395.html"><LINK
REL="NEXT"
TITLE="The Solution"
HREF="x454.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c395.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x454.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN443"
></A
>Advanced Memory Segments</H1
><P
> 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 <TT
CLASS="LITERAL"
>.text</TT
> and <TT
CLASS="LITERAL"
>.data</TT
> commands
as we produce a final set of Commodore 64 header files.
</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN448"
>The Problem</A
></H1
><P
> Our <TT
CLASS="LITERAL"
>print'str</TT
> routine
in <A
HREF="x1014.html"
><I
><I
>hello6.oph</I
></I
></A
> accesses
memory locations $10 and $11 directly. We'd prefer to have
symbolic names for them. This reprises our concerns back in
<A
HREF="c353.html"
>the Chapter called <I
>Local variables and memory segments</I
></A
> 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.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c395.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x454.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Expressions</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The Solution</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

185
book/c486.html Normal file
View File

@ -0,0 +1,185 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>The Second Step</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="To HLL and Back"
HREF="p481.html"><LINK
REL="PREVIOUS"
TITLE="To HLL and Back"
HREF="p481.html"><LINK
REL="NEXT"
TITLE="The solution"
HREF="x498.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="p481.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x498.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="HLL-1"
></A
>The Second Step</H1
><P
> This essay discusses how to do 16-or-more bit addition and
subtraction on the 6502, and how to do unsigned comparisons
properly, thus making 16-bit arithmetic less necessary.</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN489"
>The problem</A
></H1
><P
> The <TT
CLASS="LITERAL"
>ADC</TT
>, <TT
CLASS="LITERAL"
>SBC</TT
>, <TT
CLASS="LITERAL"
>INX</TT
>,
and <TT
CLASS="LITERAL"
>INY</TT
> instructions are the only real
arithmetic instructions the 6502 chip has. In and of themselves,
they aren't too useful for general applications: the accumulator
can only hold 8 bits, and thus can't store any value over 255.
Matters get even worse when we're branching based on
values; <TT
CLASS="LITERAL"
>BMI</TT
> and <TT
CLASS="LITERAL"
>BPL</TT
> hinge on
the seventh (sign) bit of the result, so we can't represent any
value above 127.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x498.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>To HLL and Back</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The solution</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

512
book/c543.html Normal file
View File

@ -0,0 +1,512 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Structured Programming</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="To HLL and Back"
HREF="p481.html"><LINK
REL="PREVIOUS"
TITLE="16-bit comparisons"
HREF="x537.html"><LINK
REL="NEXT"
TITLE="The stack"
HREF="x597.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x537.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x597.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="HLL2"
></A
>Structured Programming</H1
><P
> This essay discusses the machine language equivalents of the
basic <SPAN
CLASS="QUOTE"
>"structured programming"</SPAN
> concepts that are part
of the <SPAN
CLASS="QUOTE"
>"imperative"</SPAN
> family of programming languages:
if/then/else, for/next, while loops, and procedures. It also
discusses basic use of variables, as well as arrays, multi-byte data
types (records), and sub-byte data types (bitfields). It closes by
hand-compiling pseudo-code for an insertion sort on linked lists
into assembler. A complete Commodore 64 application is included as
a sample with this essay.</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN548"
>Control constructs</A
></H1
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN550"
>Branches: <TT
CLASS="LITERAL"
>if x then y else z</TT
></A
></H2
><P
> This is almost the most basic control construct.
The <I
CLASS="EMPHASIS"
>most</I
> basic is <TT
CLASS="LITERAL"
>if x then
y</TT
>, which is a simple branch instruction
(bcc/bcs/beq/bmi/bne/bpl/bvc/bvs) past the <SPAN
CLASS="QUOTE"
>"then"</SPAN
>
clause if the conditional is false:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> iny
bne no'overflow
inx
no'overflow:
;; rest of code</PRE
></TD
></TR
></TABLE
><P
> This increments the value of the y register, and if it just
wrapped back around to zero, it increments the x register too.
It is basically equivalent to the C statement <TT
CLASS="LITERAL"
>if
((++y)==0) ++x;</TT
>. We need a few more labels to handle
else clauses as well.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ;; Computation of the conditional expression.
;; We assume for the sake of the example that
;; we want to execute the THEN clause if the
;; zero bit is set, otherwise the ELSE
;; clause. This will happen after a CMP,
;; which is the most common kind of 'if'
;; statement anyway.
BNE else'clause
;; THEN clause code goes here.
JMP end'of'if'stmt
else'clause:
;; ELSE clause code goes here.
end'of'if'stmt:
;; ... rest of code.</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN561"
>Free loops: <TT
CLASS="LITERAL"
>while x do y</TT
></A
></H2
><P
> A <I
CLASS="EMPHASIS"
>free loop</I
> is one that might execute any
number of times. These are basically just a combination
of <TT
CLASS="LITERAL"
>if</TT
> and <TT
CLASS="LITERAL"
>goto</TT
>. For
a <SPAN
CLASS="QUOTE"
>"while x do y"</SPAN
> loop, that executes zero or more
times, you'd have code like this...
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>loop'begin:
;; ... computation of condition, setting zero
;; bit if loop is finished...
beq loop'done
;; ... loop body goes here
jmp loop'begin
loop'done:
;; ... rest of program.</PRE
></TD
></TR
></TABLE
><P
> If you want to ensure that the loop body executes at least once
(do y while x), just move the test to the end.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>loop'begin:
;; ... loop body goes here
;; ... computation of condition, setting zero
;; bit if loop is finished...
bne loop'begin
;; ... rest of program.</PRE
></TD
></TR
></TABLE
><P
> The choice of zero bit is kind of arbitrary here. If the
condition involves the carry bit, or overflow, or negative, then
replace the beq with bcs/bvs/bmi appropriately.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN573"
>Bounded loops: <TT
CLASS="LITERAL"
>for i = x to y do z</TT
></A
></H2
><P
> A special case of loops is one where you know exactly how many
times you're going through it&#8212;this is called
a <I
CLASS="EMPHASIS"
>bounded</I
> loop. Suppose you're copying 16
bytes from $C000 to $D000. The C code for that would look
something like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> int *a = 0xC000;
int *b = 0xD000;
int i;
for (i = 0; i &#60; 16; i++) { a[i] = b[i]; }</PRE
></TD
></TR
></TABLE
><P
> C doesn't directly support bounded loops;
its <TT
CLASS="LITERAL"
>for</TT
> statement is just <SPAN
CLASS="QUOTE"
>"syntactic
sugar"</SPAN
> for a while statement. However, we can take
advantage of special purpose machine instructions to get very
straightforward code:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #$00
loop:
lda $c000, x
sta $d000, x
inx
cpx #$10
bmi loop</PRE
></TD
></TR
></TABLE
><P
> However, remember that every arithmetic operation,
including <TT
CLASS="LITERAL"
>inx</TT
> and <TT
CLASS="LITERAL"
>dex</TT
>,
sets the various flags, including the Zero bit. That means that
if we can make our computation <I
CLASS="EMPHASIS"
>end</I
> when the
counter hits zero, we can shave off some bytes:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #$10
loop:
lda #$bfff, x
sta #$cfff, x
dex
bne loop</PRE
></TD
></TR
></TABLE
><P
> Notice that we had to change the addresses we're indexing from,
because x takes a slightly different range of values. The space
savings is small here, and it's become slightly more unclear.
(It also hasn't actually saved any time, because the lda and sta
instructions are crossing a page boundary where they weren't
before&#8212;but if the start or end arrays began at $b020 or
something this wouldn't be an issue.) This tends to work better
when the precise value of the counter isn't used in the
computation&#8212;so let us consider the NES, which uses memory
location $2007 as a port to its video memory. Suppose we wish
to jam 4,096 copies of the hex value $20 into the video memory.
We can write this <I
CLASS="EMPHASIS"
>very</I
> cleanly, using the X
and Y registers as indices in a nested loop.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #$10
ldy #$00
lda #$20
loop:
sta $2007
iny
bne loop
dex
bne loop</PRE
></TD
></TR
></TABLE
><P
> Work through this code. Convince yourself that
the <TT
CLASS="LITERAL"
>sta</TT
> is executed exactly 16*256 = 4096
times.
</P
><P
> This is an example of a <I
CLASS="EMPHASIS"
>nested</I
> loop: a loop
inside a loop. Since our internal loop didn't need the X or Y
registers, we got to use both of them, which is nice, because
they have special incrementing and decrementing instructions.
The accumulator lacks these instructions, so it is a poor choice
to use for index variables. If you have a bounded loop and
don't have access to registers, use memory locations
instead:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> lda #$10
sta counter ; loop 16 times
loop:
;; Do stuff that trashes all the registers
dec counter
bne loop</PRE
></TD
></TR
></TABLE
><P
> That's it! These are the basic control constructs for using
inside of procedures. Before talking about how to organize
procedures, I'll briefly cover the way the 6502 handles its
stack, because stacks and procedures are very tightly
intertwined.
</P
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x537.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x597.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>16-bit comparisons</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The stack</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

187
book/c55.html Normal file
View File

@ -0,0 +1,187 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>The basics</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="PREVIOUS"
TITLE="Using the Ophis Assembler"
HREF="p50.html"><LINK
REL="NEXT"
TITLE="Producing Commodore 64 programs"
HREF="x71.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="p50.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x71.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="PART1"
></A
>The basics</H1
><P
> In this first part of the tutorial we will create a
simple <SPAN
CLASS="QUOTE"
>"Hello World"</SPAN
> program to run on the Commodore
64. This will cover:
<P
></P
><UL
><LI
><P
>How to make programs run on a Commodore 64</P
></LI
><LI
><P
>Writing simple code with labels</P
></LI
><LI
><P
>Numeric and string data</P
></LI
><LI
><P
>Invoking the assembler</P
></LI
></UL
>
</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN68"
>A note on numeric notation</A
></H1
><P
> Throughout these tutorials, I will be using a lot of both
decimal and hexadecimal notation. Hex numbers will have a
dollar sign in front of them. Thus, 100 = $64, and $100 = 256.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x71.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Using the Ophis Assembler</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Producing Commodore 64 programs</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

292
book/c748.html Normal file
View File

@ -0,0 +1,292 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Pointers and Indirection</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="To HLL and Back"
HREF="p481.html"><LINK
REL="PREVIOUS"
TITLE="A modest example: Insertion sort on linked lists"
HREF="x719.html"><LINK
REL="NEXT"
TITLE="Pointer arithmetic"
HREF="x782.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x719.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x782.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="HLL3"
></A
>Pointers and Indirection</H1
><P
> The basics of pointers versus cursors (or, at the 6502 assembler
level, the indirect indexed addressing mode versus the absolute
indexed ones) were covered in <A
HREF="c543.html"
>the Chapter called <I
>Structured Programming</I
></A
> This essay seeks
to explain the uses of the indirect modes, and how to implement
pointer operations with them. It does <I
CLASS="EMPHASIS"
>not</I
> seek to explain
why you'd want to use pointers for something to begin with; for a
tutorial on proper pointer usage, consult any decent C textbook.</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN753"
>The absolute basics</A
></H1
><P
> A pointer is a variable holding the address of a memory location.
Memory locations take 16 bits to represent on the 6502: thus, we
need two bytes to hold it. Any decent assembler will have ways of
taking the high and low bytes of an address; use these to acquire
the raw values you need. The 6502 chip does not have any
simple <SPAN
CLASS="QUOTE"
>"pure"</SPAN
> indirect modes (except
for <TT
CLASS="LITERAL"
>JMP</TT
>, which is a matter for a later essay);
all are indexed, and they're indexed different ways depending on
which index register you use.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN758"
>The simplest example</A
></H2
><P
> When doing a simple, direct dereference (that is, something
equivalent to the C code <TT
CLASS="LITERAL"
>c=*b;</TT
>) the code
looks like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldy #0
lda (b), y
sta c</PRE
></TD
></TR
></TABLE
><P
> Even with this simple example, there are several important
things to notice.
</P
><P
></P
><UL
><LI
><P
> The variable <TT
CLASS="LITERAL"
>b</TT
> <I
CLASS="EMPHASIS"
>must be on the
zero page</I
>, and furthermore, it <I
CLASS="EMPHASIS"
>cannot
be $FF.</I
> All your pointer values need to be
either stored on the zero page to begin with or copied
there before use.
</P
></LI
><LI
><P
> The <TT
CLASS="LITERAL"
>y</TT
> in the <TT
CLASS="LITERAL"
>lda</TT
>
statement must be y. It cannot be x (that's a different
form of indirection), and it cannot be a constant. If
you're doing a lot of indirection, be sure to keep your Y
register free to handle the indexing on the
pointers.
</P
></LI
><LI
><P
> The <TT
CLASS="LITERAL"
>b</TT
> variable is used alone. Statements
like <TT
CLASS="LITERAL"
>lda (b+2), y</TT
> are syntactically valid
and sometimes even correct: it dereferences the value next
to <TT
CLASS="LITERAL"
>b</TT
> after adding y to the value therein.
However, it is almost guaranteed that what you *really*
wanted to do was compute <TT
CLASS="LITERAL"
>*(b+2)</TT
> (that is,
take the address of b, add 2 to <I
CLASS="EMPHASIS"
>that</I
>,
and dereference that value); see the next section for how to
do this properly.
</P
></LI
></UL
><P
> In nearly all cases, it is the Y-register's version (Indirect
Indexed) that you want to use when you're dealing with pointers.
Even though either version could be used for this example, we
use the Y register to establish this habit.
</P
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x719.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x782.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>A modest example: Insertion sort on linked lists</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Pointer arithmetic</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

220
book/c816.html Normal file
View File

@ -0,0 +1,220 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Functionals</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="To HLL and Back"
HREF="p481.html"><LINK
REL="PREVIOUS"
TITLE="Conclusion"
HREF="x813.html"><LINK
REL="NEXT"
TITLE="A quick digression on how subroutines work"
HREF="x836.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x813.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x836.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN816"
></A
>Functionals</H1
><P
> This essay deals with indirect calls. These are the core of an
enormous number of high level languages: LISP's closures, C's
function pointers, C++ and Java's virtual method calls, and some
implementations of the <TT
CLASS="LITERAL"
>switch</TT
> statement.</P
><P
> These techniques vary in complexity, and most will not be
appropriate for large-scale assembler projects. Of them, however,
the Data-Directed approach is the most likely to lead to organized
and maintainable code.</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN821"
>Function Pointers</A
></H1
><P
> Because assembly language is totally untyped, function pointers
are the same as any other sixteen-bit integer. This makes
representing them really quite easy; most assemblers should permit
routines to be declared simply by naming the routine as
a <TT
CLASS="LITERAL"
>.word</TT
> directly.
</P
><P
> To actually invoke these methods, copy them to some sixteen-bit
location (say, <TT
CLASS="LITERAL"
>target</TT
>) and then invoking the
method is a simple matter of the using an indirect jump:
the <TT
CLASS="LITERAL"
>JMP (target)</TT
> instruction.
</P
><P
> There's really only one subtlety here, and it's that the indirect
jump is an indirect <I
CLASS="EMPHASIS"
>jump</I
>, not an
indirect <I
CLASS="EMPHASIS"
>function call</I
>. Thus, if some
function <TT
CLASS="LITERAL"
>A</TT
> makes in indirect jump to some
routine, when that routine returns, it returns to whoever
called <TT
CLASS="LITERAL"
>A</TT
>, not <TT
CLASS="LITERAL"
>A</TT
>
itself.
</P
><P
> There are several ways of dealing with this, but only one correct
way, which is to structure your procedures so that any call
to <TT
CLASS="LITERAL"
>JMP (xxxx)</TT
> occurs at the very
end.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x813.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x836.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Conclusion</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>A quick digression on how subroutines work</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

209
book/c900.html Normal file
View File

@ -0,0 +1,209 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Call Stacks</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="To HLL and Back"
HREF="p481.html"><LINK
REL="PREVIOUS"
TITLE="A final reminder"
HREF="x892.html"><LINK
REL="NEXT"
TITLE="Our Goals"
HREF="x915.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x892.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x915.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN900"
></A
>Call Stacks</H1
><P
> All our previous work has been assuming FORTRAN-style calling
conventions. In this, all procedure-local variables are actually
secretly globals. This means that a function that calls itself will
end up stomping on its previous values, and everything will be
hideously scrambled. Various workarounds for this are covered
in <A
HREF="c543.html"
>the Chapter called <I
>Structured Programming</I
></A
>. Here, we solve the problem fully.</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN904"
>Recursion</A
></H1
><P
> A procedure in C or other similar languages declares a chunk of
storage that's unique to that invocation. This chunk is just
large enough to hold the return address and all the local
variables, and is called the <I
CLASS="EMPHASIS"
>stack frame</I
>.
Stack frames are arranged on a <I
CLASS="EMPHASIS"
>call stack</I
>;
when a function is called, the stack grows with the new frame, and
when that function returns, its frame is destroyed. Once the main
function returns, the stack is empty.
</P
><P
> Most modern architectures are designed to let you implement
variable access like this directly, without touching the registers
at all. The x86 architecture even dedicates a register to
function explicitly as the <I
CLASS="EMPHASIS"
>stack pointer</I
>, and
then one could read, say, the fifth 16-bit variable into the
register AX with the command <TT
CLASS="LITERAL"
>MOV AX, [SP+10]</TT
>.
</P
><P
> As we saw in <A
HREF="c748.html"
>the Chapter called <I
>Pointers and Indirection</I
></A
>, the 6502 isn't nearly as
convenient. We'd need to keep the stack pointer somewhere on the
zero page, then load the Y register with 10, then load the
accumulator with an indexed-indirect call. This is verbose, keeps
trashing our registers, and it's very, very slow.
</P
><P
> So, in the spirit of programmers everywhere, we'll cheat.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x892.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x915.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>A final reminder</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Our Goals</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

272
book/f10.html Normal file
View File

@ -0,0 +1,272 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Preface</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="PREVIOUS"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="NEXT"
TITLE="Getting a copy of Ophis"
HREF="x29.html"></HEAD
><BODY
CLASS="PREFACE"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="book1.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x29.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="PREFACE"
><H1
><A
NAME="AEN10"
></A
>Preface</H1
><P
> Ophis is an assembler for the 6502 microprocessor - the famous
chip used in the vast majority of the classic 8-bit computers and
consoles. Its primary design goals are code readability and output
flexibility - Ophis has successfully been used to create programs
for the Nintendo Entertainment System, the Atari 2600, and the
Commodore 64.
</P
><P
> Ophis's syntax is noticably different from the formats
traditionally used for these chips; it draws its syntactic
inspiration primarily from the assemblers for more modern chips,
where the role of tokens is determined more by what they're made
of and their grammatical location on a line rather than their
absolute position on a line. It also borrows the sophisticated
methods of tracking the location of labels when writing relinkable
code&#8212;Ophis expects that the final output it produces will have
only a vague resemblance to the memory image when loaded. Most of
the alternatives when Ophis was first designed would place
instructions and data into a memory map and then dump that map.
</P
><P
> That said, there remain many actively used 6502 assemblers out
there. If you're already a seasoned 6502 assembly programmer, or
want to get your old sources built again, Ophis is likely not for
you&#8212;however, if you are writing new code, or are new to the
chip while still having other experience, then Ophis is a tool
built with you in mind.
</P
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN15"
>History of the project</A
></H1
><P
> The Ophis project started on a lark back in 2001. My graduate
studies required me to learn Perl and Python, and I'd been
playing around with Commodore 64 emulators in my spare time, so
I decided to learn both languages by writing a simple
cross-assembler for the 6502 chip the C64 used in both.
</P
><P
> The Perl one&#8212;uncreatively
dubbed <SPAN
CLASS="QUOTE"
>"Perl65"</SPAN
>&#8212;was quickly abandoned, but
the Python one saw more work. When it came time to name it, one
of the things I had been hoping to do with the assembler was to
produce working Apple II programs. <SPAN
CLASS="QUOTE"
>"Ophis"</SPAN
> is
Greek for <SPAN
CLASS="QUOTE"
>"snake"</SPAN
>, and a number of traditions also
use it as the actual <I
CLASS="EMPHASIS"
>name</I
> of the serpent in
the Garden of Eden. So, Pythons, snakes, and stories involving
really old Apples all combined to name the
assembler.<A
NAME="AEN23"
HREF="#FTN.AEN23"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
>
</P
><P
> Ophis slowly grew in scope and power over the years, and by 2005
was a very powerful, flexible macro assembler that saw more use
than I'd expect. In 2007 Ophis 1.0 was formally released.
However, Ophis was written for Python 2.1 and this became more
and more untenable as time has gone by. As I started receiving
patches for parts of Ophis, and as I used it for some projects
of my own, it became clear that Ophis needed to be modernized
and to become better able to interoperate with other
toolchains. It was this process that led to Ophis 2.
</P
><P
> This is an updated edition of <I
CLASS="EMPHASIS"
>Programming With
Ophis</I
>, including documentation for all new features
introduced and expanding the examples to include simple
demonstration programs for platforms besides the Commodore
64. It also includes updated versions of the <I
CLASS="EMPHASIS"
>To HLL
and Back</I
> essays I wrote using Ophis and Perl65 as
example languages.
</P
></DIV
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN23"
HREF="f10.html#AEN23"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>Ironically, cross-platform development
for the Apple II is extremely difficult, and while Ophis has
been very successfully used to develop code for the Commodore
64, Nintendo Entertainment System, and Atari 2600, it has yet to
actually be deployed on any of the Apples which inspired its
name.</P
></TD
></TR
></TABLE
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x29.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Programming with Ophis</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Getting a copy of Ophis</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

190
book/p481.html Normal file
View File

@ -0,0 +1,190 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>To HLL and Back</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="PREVIOUS"
TITLE="Where to go from here"
HREF="x476.html"><LINK
REL="NEXT"
TITLE="The Second Step"
HREF="c486.html"></HEAD
><BODY
CLASS="PART"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x476.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c486.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="PART"
><A
NAME="AEN481"
></A
><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
>II. To HLL and Back</H1
><DIV
CLASS="PARTINTRO"
><A
NAME="AEN483"
></A
><P
> This is a compilation of an essay series I wrote from
2002-2005 explaining how to apply HLL constructs from
high-level languages in your assembly language projects.
</P
><P
> The examples have been updated and modernized for Ophis 2, and
while the examples all target the Commodore 64, they are more
generally applicable.
</P
></DIV
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="c486.html"
>The Second Step</A
></DT
><DT
><A
HREF="c543.html"
>Structured Programming</A
></DT
><DT
><A
HREF="c748.html"
>Pointers and Indirection</A
></DT
><DT
><A
HREF="c816.html"
>Functionals</A
></DT
><DT
><A
HREF="c900.html"
>Call Stacks</A
></DT
></DL
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x476.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c486.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Where to go from here</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The Second Step</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

199
book/p50.html Normal file
View File

@ -0,0 +1,199 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Using the Ophis Assembler</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="PREVIOUS"
TITLE="About the examples"
HREF="x41.html"><LINK
REL="NEXT"
TITLE="The basics"
HREF="c55.html"></HEAD
><BODY
CLASS="PART"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x41.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c55.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="PART"
><A
NAME="AEN50"
></A
><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
>I. Using the Ophis Assembler</H1
><DIV
CLASS="PARTINTRO"
><A
NAME="AEN52"
></A
><P
> The chapters in Part 1 are a tutorial guiding you through the
features and programming model of the Ophis assembler. It uses
the Commodore 64 as its target platform.
</P
><P
> This is not a tutorial on 6502 assembly language; those are
available elsewhere.
</P
></DIV
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="c55.html"
>The basics</A
></DT
><DT
><A
HREF="c223.html"
>Labels and aliases</A
></DT
><DT
><A
HREF="c259.html"
>Headers, Libraries, and Macros</A
></DT
><DT
><A
HREF="c319.html"
>Character maps</A
></DT
><DT
><A
HREF="c353.html"
>Local variables and memory segments</A
></DT
><DT
><A
HREF="c395.html"
>Expressions</A
></DT
><DT
><A
HREF="c443.html"
>Advanced Memory Segments</A
></DT
></DL
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x41.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c55.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>About the examples</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The basics</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

233
book/x1002.html Normal file
View File

@ -0,0 +1,233 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello4b.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello4a.oph"
HREF="x998.html"><LINK
REL="NEXT"
TITLE="hello4c.oph"
HREF="x1006.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x998.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1006.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR4B-SRC"
><TT
CLASS="FILENAME"
>hello4b.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "c64-1.oph"
.outfile "hello.prg"
.macro print
ldx #0
_loop: lda _1, x
beq _done
jsr chrout
inx
bne _loop
_done:
.macend
.macro greet
lda #30
jsr delay
`print hello1
`print _1
`print hello2
.macend
lda #147
jsr chrout
lda #lower'case
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
rts
hello1: .byte "Hello, ",0
hello2: .byte "!", 13, 0
target1: .byte "programmer", 0
target2: .byte "room", 0
target3: .byte "building", 0
target4: .byte "neighborhood", 0
target5: .byte "city", 0
target6: .byte "nation", 0
target7: .byte "world", 0
target8: .byte "Solar System", 0
target9: .byte "Galaxy", 0
target10: .byte "Universe", 0
; DELAY routine. Executes 2,560*(A) NOP statements.
delay: tax
ldy #00
* nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
iny
bne -
dex
bne -
rts</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x998.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1006.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello4a.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello4c.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

236
book/x1006.html Normal file
View File

@ -0,0 +1,236 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello4c.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello4b.oph"
HREF="x1002.html"><LINK
REL="NEXT"
TITLE="hello5.oph"
HREF="x1010.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1002.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1010.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR4C-SRC"
><TT
CLASS="FILENAME"
>hello4c.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "c64-1.oph"
.outfile "hello.prg"
.macro print
ldx #0
_loop: lda _1, x
beq _done
jsr chrout
inx
bne _loop
_done:
.macend
.macro greet
lda #30
jsr delay
`print hello1
`print _1
`print hello2
.macend
lda #147
jsr chrout
lda #lower'case
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
rts
.charmap 'A, "abcdefghijklmnopqrstuvwxyz"
.charmap 'a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
hello1: .byte "Hello, ",0
hello2: .byte "!", 13, 0
target1: .byte "programmer", 0
target2: .byte "room", 0
target3: .byte "building", 0
target4: .byte "neighborhood", 0
target5: .byte "city", 0
target6: .byte "nation", 0
target7: .byte "world", 0
target8: .byte "Solar System", 0
target9: .byte "Galaxy", 0
target10: .byte "Universe", 0
; DELAY routine. Executes 2,560*(A) NOP statements.
delay: tax
ldy #00
* nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
iny
bne -
dex
bne -
rts</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1002.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1010.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello4b.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello5.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

240
book/x1010.html Normal file
View File

@ -0,0 +1,240 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello5.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello4c.oph"
HREF="x1006.html"><LINK
REL="NEXT"
TITLE="hello6.oph"
HREF="x1014.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1006.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1014.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR5-SRC"
><TT
CLASS="FILENAME"
>hello5.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "c64-1.oph"
.outfile "hello.prg"
.data
.org $C000
.text
.macro print
ldx #0
_loop: lda _1, x
beq _done
jsr chrout
inx
bne _loop
_done:
.macend
.macro greet
lda #30
jsr delay
`print hello1
`print _1
`print hello2
.macend
lda #147
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
rts
hello1: .byte "HELLO, ",0
hello2: .byte "!", 13, 0
target1: .byte "PROGRAMMER", 0
target2: .byte "ROOM", 0
target3: .byte "BUILDING", 0
target4: .byte "NEIGHBORHOOD", 0
target5: .byte "CITY", 0
target6: .byte "NATION", 0
target7: .byte "WORLD", 0
target8: .byte "SOLAR SYSTEM", 0
target9: .byte "GALAXY", 0
target10: .byte "UNIVERSE", 0
; DELAY routine. Takes values from the Accumulator and pauses
; for that many jiffies (1/60th of a second).
.scope
.data
.space _tmp 1
.space _target 1
.text
delay: sta _tmp ; save argument (rdtim destroys it)
jsr rdtim
clc
adc _tmp ; add current time to get target
sta _target
* jsr rdtim
cmp _target
bmi - ; Buzz until target reached
rts
.scend
.checkpc $A000
.data
.checkpc $D000</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1006.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1014.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello4c.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello6.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

267
book/x1014.html Normal file
View File

@ -0,0 +1,267 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello6.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello5.oph"
HREF="x1010.html"><LINK
REL="NEXT"
TITLE="c64_0.oph"
HREF="x1018.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1010.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1018.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR6-SRC"
><TT
CLASS="FILENAME"
>hello6.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "c64-1.oph"
.outfile "hello.prg"
.data
.org $C000
.space cache 2
.text
.macro print
lda #&#60;_1
ldx #&#62;_1
jsr printstr
.macend
.macro greet
lda #30
jsr delay
`print hello1
`print _1
`print hello2
.macend
; Save the zero page locations that PRINTSTR uses.
lda $10
sta cache
lda $11
sta cache+1
lda #147
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
; Restore the zero page values printstr uses.
lda cache
sta $10
lda cache+1
sta $11
rts
hello1: .byte "HELLO, ",0
hello2: .byte "!", 13, 0
target1: .byte "PROGRAMMER", 0
target2: .byte "ROOM", 0
target3: .byte "BUILDING", 0
target4: .byte "NEIGHBORHOOD", 0
target5: .byte "CITY", 0
target6: .byte "NATION", 0
target7: .byte "WORLD", 0
target8: .byte "SOLAR SYSTEM", 0
target9: .byte "GALAXY", 0
target10: .byte "UNIVERSE", 0
; DELAY routine. Takes values from the Accumulator and pauses
; for that many jiffies (1/60th of a second).
.scope
.data
.space _tmp 1
.space _target 1
.text
delay: sta _tmp ; save argument (rdtim destroys it)
jsr rdtim
clc
adc _tmp ; add current time to get target
sta _target
* jsr rdtim
cmp _target
bmi - ; Buzz until target reached
rts
.scend
; PRINTSTR routine. Accumulator stores the low byte of the address,
; X register stores the high byte. Destroys the values of $10 and
; $11.
.scope
printstr:
sta $10
stx $11
ldy #$00
_lp: lda ($10),y
beq _done
jsr chrout
iny
bne _lp
_done: rts
.scend
.checkpc $A000
.data
.checkpc $D000</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1010.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1018.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello5.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>c64_0.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

224
book/x1018.html Normal file
View File

@ -0,0 +1,224 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>c64_0.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello6.oph"
HREF="x1014.html"><LINK
REL="NEXT"
TITLE="hello7.oph"
HREF="x1022.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1014.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1022.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="C64-2-SRC"
><TT
CLASS="FILENAME"
>c64_0.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Commodore 64 Basic Runtime File
;;
;; Include this at the TOP of your C64 program, and it will handle
;; hiding away the BASIC ROM and data and restoring it at the end.
;;
;; You will have a contiguous block of RAM from $0800 to $CF81, and
;; Zero Page access from $02 to $7F in the segment "zp".
.word $0801
.org $0801
; BASIC program that just calls our machine language code
.scope
.word _next, 10 ; Next line and current line number
.byte $9e," 2062",0 ; SYS 2062
_next: .word 0 ; End of program
.scend
.data zp ; Zero Page memory segment.
.org $0002
.text
.scope
; Cache BASIC zero page at top of available RAM
ldx #$7E
* lda $01, x
sta $CF81, x
dex
bne -
; Swap out the BASIC ROM for RAM
lda $01
and #$fe
ora #$06
sta $01
; Run the real program
jsr _main
; Restore BASIC ROM
lda $01
ora #$07
sta $01
; Restore BASIC zero page
ldx #$7E
* lda $CF81, x
sta $01, x
dex
bne -
; Back to BASIC
rts
_main:
; Program follows...
.scend</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1014.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1022.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello6.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello7.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

262
book/x1022.html Normal file
View File

@ -0,0 +1,262 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello7.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="c64_0.oph"
HREF="x1018.html"><LINK
REL="NEXT"
TITLE="structuredemo.oph"
HREF="x1026.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1018.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1026.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR7-SRC"
><TT
CLASS="FILENAME"
>hello7.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "../platform/c64_0.oph"
.require "../platform/c64kernal.oph"
.outfile "hello.prg"
.data
.org $C000
.text
.macro print
lda #&#60;_1
ldx #&#62;_1
jsr printstr
.macend
.macro greet
lda #30
jsr delay
`print hello1
`print _1
`print hello2
.macend
lda #147
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
rts
hello1: .byte "HELLO, ",0
hello2: .byte "!", 13, 0
target1: .byte "PROGRAMMER", 0
target2: .byte "ROOM", 0
target3: .byte "BUILDING", 0
target4: .byte "NEIGHBORHOOD", 0
target5: .byte "CITY", 0
target6: .byte "NATION", 0
target7: .byte "WORLD", 0
target8: .byte "SOLAR SYSTEM", 0
target9: .byte "GALAXY", 0
target10: .byte "UNIVERSE", 0
; DELAY routine. Takes values from the Accumulator and pauses
; for that many jiffies (1/60th of a second).
.scope
.data
.space _tmp 1
.space _target 1
.text
delay: sta _tmp ; save argument (rdtim destroys it)
jsr rdtim
clc
adc _tmp ; add current time to get target
sta _target
* jsr rdtim
cmp _target
bmi - ; Buzz until target reached
rts
.scend
; 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
.checkpc $A000
.data
.checkpc $D000
.data zp
.checkpc $80</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1018.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1026.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>c64_0.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>structuredemo.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

395
book/x1026.html Normal file
View File

@ -0,0 +1,395 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>structuredemo.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello7.oph"
HREF="x1022.html"><LINK
REL="NEXT"
TITLE="fibonacci.oph"
HREF="x1030.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1022.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1030.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="STRUCTURE-SRC"
><TT
CLASS="FILENAME"
>structuredemo.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "../platform/c64_0.oph"
.require "../platform/c64kernal.oph"
.outfile "structuredemo.prg"
jsr print'unsorted
jsr insertion'sort
jsr print'list
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Linked list data: head, next, lb, hb.
; lb/hb: Low/high bytes of the data array. These are immutable and
; kept with the program text.
; head: Array index of the first element in the list, or #$FF if the
; list is empty
; next: Array of successor indices. If you've just read element X,
; the value of memory location next+X is the index of the
; next element. If next is #$FF, you've reached the end of
; the list.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data
.org $C000
.space head 1
.space next 16
.text
lb: .byte &#60;$838,&#60;$618,&#60;$205,&#60;$984,&#60;$724,&#60;$301,&#60;$249,&#60;$946
.byte &#60;$925,&#60;$043,&#60;$114,&#60;$697,&#60;$985,&#60;$633,&#60;$312,&#60;$086
hb: .byte &#62;$838,&#62;$618,&#62;$205,&#62;$984,&#62;$724,&#62;$301,&#62;$249,&#62;$946
.byte &#62;$925,&#62;$043,&#62;$114,&#62;$697,&#62;$985,&#62;$633,&#62;$312,&#62;$086
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; insertion'sort: Sorts the list defined by head, next, hb, lb.
; Arguments: None.
; Modifies: All registers destroyed, head and next array sorted.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
insertion'sort:
lda #$FF ; Clear list by storing the terminator in 'head'
sta head
ldx #$0 ; Loop through the lb/hb array, adding each
insertion'sort'loop: ; element one at a time
txa
pha
jsr insert_elt
pla
tax
inx
cpx #$10
bne insertion'sort'loop
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; insert_elt: Insert an element into the linked list. Maintains the
; list in sorted, ascending order. Used by
; insertion'sort.
; Arguments: X register holds the index of the element to add.
; Modifies: All registers destroyed; head and next arrays updated
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data
.space lbtoinsert 1
.space hbtoinsert 1
.space indextoinsert 1
.text
insert_elt:
ldy head ; If the list is empty, make
cpy #$FF ; head point at it, and return.
bne insert_elt'list'not'empty
stx head
tya
sta next,x
rts
insert_elt'list'not'empty:
lda lb,x ; Cache the data we're inserting
sta lbtoinsert
lda hb,x
sta hbtoinsert
stx indextoinsert
ldy head ; Compare the first value with
sec ; the data. If the data must
lda lb,y ; be inserted at the front...
sbc lbtoinsert
lda hb,y
sbc hbtoinsert
bmi insert_elt'not'smallest
tya ; Set its next pointer to the
sta next,x ; old head, update the head
stx head ; pointer, and return.
rts
insert_elt'not'smallest:
ldx head
insert_elt'loop: ; At this point, we know that
lda next,x ; argument &#62; data[X].
tay
cpy #$FF ; if next[X] = #$FF, insert arg at end.
beq insert_elt'insert'after'current
lda lb,y ; Otherwise, compare arg to
sec ; data[next[X]]. If we insert
sbc lbtoinsert ; before that...
lda hb,y
sbc hbtoinsert
bmi insert_elt'goto'next
insert_elt'insert'after'current: ; Fix up all the next links
tya
ldy indextoinsert
sta next,y
tya
sta next,x
rts ; and return.
insert_elt'goto'next: ; Otherwise, let X = next[X]
tya ; and go looping again.
tax
jmp insert_elt'loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; print'unsorted: Steps through the data array and prints each value.
; Standalone procedure.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print'unsorted:
lda #&#60;unsorted'hdr
ldx #&#62;unsorted'hdr
jsr put'string
ldy #$00
print'unsorted'loop:
lda hb, Y
jsr print'hex
lda lb, y
jsr print'hex
lda #$20
jsr chrout
iny
cpy #$10
bne print'unsorted'loop
lda #$0D
jsr chrout
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; print'list: Starts at head, and prints out every value in the
; linked list.
; Standalone procedure.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print'list:
lda #&#60;sorted'hdr
ldx #&#62;sorted'hdr
jsr put'string
ldy head
print'list'loop:
cpy #$FF
beq print'list'done
lda hb, y
jsr print'hex
lda lb, y
jsr print'hex
lda #$20
jsr chrout
lda next, Y
tay
jmp print'list'loop
print'list'done:
lda #$0d
jsr chrout
rts
;; String data for the above routines.
unsorted'hdr:
.byte 147 ; Clear screen first!
.byte "UNSORTED DATA:",13,0
sorted'hdr:
.byte "SORTED DATA:",13,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; print'hex: outputs a two-character hex representation of a one-
; byte value.
; Arguments: Byte to print in accumulator
; Modifies: .A and .X
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print'hex:
pha
clc
lsr
lsr
lsr
lsr
tax
lda hexstr,x
jsr chrout
pla
and #$0F
tax
lda hexstr,X
jsr chrout
rts
; Character data array for print'hex.
hexstr: .byte "0123456789ABCDEF"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; put'string: outputs a C-style null terminated string with length
; less than 256 to the screen. If 256 bytes are written
; without finding a terminator, the routine ends quietly.
; Arguments: Low byte of string address in .A, high byte in .X
; Modifies: .A and .Y
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data zp
.space put'string'addr 2
.text
put'string:
sta put'string'addr
stx put'string'addr+1
ldy #$00
put'string'loop:
lda (put'string'addr),y
beq put'string'done
jsr chrout
iny
bne put'string'loop
put'string'done:
rts&#13;</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1022.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1030.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello7.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>fibonacci.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

374
book/x1030.html Normal file
View File

@ -0,0 +1,374 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>fibonacci.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="structuredemo.oph"
HREF="x1026.html"><LINK
REL="NEXT"
TITLE="Ophis Command Reference"
HREF="a1034.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1026.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="a1034.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="FIB-SRC"
><TT
CLASS="FILENAME"
>fibonacci.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "../platform/c64_0.oph"
.require "../platform/c64kernal.oph"
.outfile "fibonacci.prg"
lda #&#60;opening ; Print opening text
sta fun'args
lda #&#62;opening
sta fun'args+1
jsr print'string
lda #$00
sta fun'vars ; Count num from 0 to 19
* lda fun'vars ; Main loop: print num, with leading space if &#60;10
cmp #$09
bcs +
lda #$20
jsr chrout
lda fun'vars
* sta fun'args ; Copy num to args, print it, plus ": "
inc fun'args
lda #$00
sta fun'args+1
jsr print'dec
lda #$3A
jsr chrout
lda #$20
jsr chrout
lda fun'vars ; Copy num to args, call fib, print result
sta fun'args
jsr fib
jsr print'dec
lda #$0D ; Newline
jsr chrout
inc fun'vars ; Increment num; if it's 20, we're done.
lda fun'vars
cmp #20
bne -- ; Otherwise, loop.
rts
opening:
.byte 147, " FIBONACCI SEQUENCE",13,13,0
.scope
; Uint16 fib (Uint8 x): compute Xth fibonnaci number.
; fib(0) = fib(1) = 1.
; Stack usage: 3.
fib: lda #$03
jsr save'stack
lda fun'vars ; If x &#60; 2, goto _base.
cmp #$02
bcc _base
dec fun'args ; Otherwise, call fib(x-1)...
jsr fib
lda fun'args ; Copy the result to local variable...
sta fun'vars+1
lda fun'args+1
sta fun'vars+2
lda fun'vars ; Call fib(x-2)...
sec
sbc #$02
sta fun'args
jsr fib
clc ; And add the old result to it, leaving it
lda fun'args ; in the 'result' location.
adc fun'vars+1
sta fun'args
lda fun'args+1
adc fun'vars+2
sta fun'args+1
jmp _done ; and then we're done.
_base: ldy #$01 ; In the base case, just copy 1 to the
sty fun'args ; result.
dey
sty fun'args+1
_done: lda #$03
jsr restore'stack
rts
.scend
.scope
; Stack routines: init'stack, save'stack, restore'stack
.data zp
.space _sp $02
.space _counter $01
.space fun'args $10
.space fun'vars $40
.text
init'stack:
lda #$00
sta _sp
lda #$A0
sta _sp+1
rts
save'stack:
sta _counter
sec
lda _sp
sbc _counter
sta _sp
lda _sp+1
sbc #$00
sta _sp+1
ldy #$00
* lda fun'vars, y
sta (_sp), y
lda fun'args, y
sta fun'vars, y
iny
dec _counter
bne -
rts
restore'stack:
pha
sta _counter
ldy #$00
* lda (_sp), y
sta fun'vars, y
iny
dec _counter
bne -
pla
clc
adc _sp
sta _sp
lda _sp+1
adc #$00
sta _sp+1
rts
.scend
; Utility functions. print'dec prints an unsigned 16-bit integer.
; It's ugly and long, mainly because we don't bother with niceties
; like "division". print'string prints a zero-terminated string.
.scope
.data
.org fun'args
.space _val 2
.space _step 2
.space _res 1
.space _allowzero 1
.text
print'dec:
lda #$00
sta _allowzero
lda #&#60;10000
sta _step
lda #&#62;10000
sta _step+1
jsr repsub'16
lda #&#60;1000
sta _step
lda #&#62;1000
sta _step+1
jsr repsub'16
lda #0
sta _step+1
lda #100
sta _step
jsr repsub'16
lda #10
sta _step
jsr repsub'16
lda _val
jsr _print
rts
repsub'16:
lda #$00
sta _res
* lda _val
sec
sbc _step
lda _val+1
sbc _step+1
bcc _done
lda _val
sec
sbc _step
sta _val
lda _val+1
sbc _step+1
sta _val+1
inc _res
jmp -
_done: lda _res
ora _allowzero
beq _ret
sta _allowzero
lda _res
_print: clc
adc #'0
jsr chrout
_ret: rts
.scend
print'string:
ldy #$00
* lda (fun'args), y
beq +
jsr chrout
iny
jmp -
* rts</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1026.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>structuredemo.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Ophis Command Reference</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

309
book/x1101.html Normal file
View File

@ -0,0 +1,309 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Basic arguments</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Ophis Command Reference"
HREF="a1034.html"><LINK
REL="PREVIOUS"
TITLE="Ophis Command Reference"
HREF="a1034.html"><LINK
REL="NEXT"
TITLE="Compound Arguments"
HREF="x1149.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="a1034.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Ophis Command Reference</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1149.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN1101"
>Basic arguments</A
></H1
><P
> Most arguments are just a number or label. The formats for
these are below.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1104"
>Numeric types</A
></H2
><P
></P
><UL
><LI
><P
><I
CLASS="EMPHASIS"
>Hex:</I
> <TT
CLASS="LITERAL"
>$41</TT
> (Prefixed with $)</P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Decimal:</I
> <TT
CLASS="LITERAL"
>65</TT
> (No markings)</P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Octal:</I
> <TT
CLASS="LITERAL"
>0101</TT
> (Prefixed with zero)</P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Binary:</I
> <TT
CLASS="LITERAL"
>%01000001</TT
> (Prefixed with %)</P
></LI
><LI
><P
><I
CLASS="EMPHASIS"
>Character:</I
> <TT
CLASS="LITERAL"
>'A</TT
> (Prefixed with single quote)</P
></LI
></UL
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1127"
>Label types</A
></H2
><P
> Normal labels are simply referred to by name. Anonymous
labels may be referenced with strings of - or + signs (the
label <TT
CLASS="LITERAL"
>-</TT
> refers to the immediate
previous anonymous label, <TT
CLASS="LITERAL"
>--</TT
> the
one before that, etc., while <TT
CLASS="LITERAL"
>+</TT
>
refers to the next anonymous label), and the special
label <TT
CLASS="LITERAL"
>^</TT
> refers to the program
counter at the start of the current instruction or directive.
</P
><P
> Normal labels are <I
CLASS="EMPHASIS"
>defined</I
> by
prefixing a line with the label name and then a colon
(e.g., <TT
CLASS="LITERAL"
>label:</TT
>). Anonymous labels
are defined by prefixing a line with an asterisk
(e.g., <TT
CLASS="LITERAL"
>*</TT
>).
</P
><P
> Temporary labels are only reachable from inside the
innermost enclosing <TT
CLASS="LITERAL"
>.scope</TT
>
statement. They are identical to normal labels in every
way, except that they start with an underscore.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1140"
>String types</A
></H2
><P
> Strings are enclosed in double quotation marks. Backslashed
characters (including backslashes and double quotes) are
treated literally, so the string <TT
CLASS="LITERAL"
>"The man said,
\"The \\ character is the backslash.\""</TT
> produces
the ASCII sequence for <TT
CLASS="LITERAL"
>The man said, "The \
character is the backslash."</TT
>
</P
><P
> Strings are generally only used as arguments to assembler
directives&#8212;usually for filenames
(e.g., <TT
CLASS="LITERAL"
>.include</TT
>) but also for string
data (in association with <TT
CLASS="LITERAL"
>.byte</TT
>).
</P
><P
> It is legal, though unusual, to attempt to pass a string to
the other data statements. This will produces a series of
words/dwords where all bytes that aren't least-significant
are zero. Endianness and size will match what the directive
itself indicated.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1149.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Ophis Command Reference</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Compound Arguments</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

212
book/x1149.html Normal file
View File

@ -0,0 +1,212 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Compound Arguments</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Ophis Command Reference"
HREF="a1034.html"><LINK
REL="PREVIOUS"
TITLE="Basic arguments"
HREF="x1101.html"><LINK
REL="NEXT"
TITLE="Memory Model"
HREF="x1176.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1101.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Ophis Command Reference</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1176.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN1149"
>Compound Arguments</A
></H1
><P
> Compound arguments may be built up from simple ones, using the
standard +, -, *, and / operators, which carry the usual
precedence. Also, the unary operators &#62; and &#60;, which
bind more tightly than anything else, provide the high and low
bytes of 16-bit values, respectively.
</P
><P
> Use brackets [ ] instead of parentheses ( ) when grouping
arithmetic operations, as the parentheses are needed for the
indirect addressing modes.
</P
><P
> Examples:
</P
><P
></P
><UL
><LI
><P
><TT
CLASS="LITERAL"
>$D000</TT
> evaluates to $D000</P
></LI
><LI
><P
><TT
CLASS="LITERAL"
>$D000+32</TT
> evaluates to $D020</P
></LI
><LI
><P
><TT
CLASS="LITERAL"
>$D000+$20</TT
> also evaluates to $D020</P
></LI
><LI
><P
><TT
CLASS="LITERAL"
>&#60;$D000+32</TT
> evaluates to $20</P
></LI
><LI
><P
><TT
CLASS="LITERAL"
>&#62;$D000+32</TT
> evaluates to $F0</P
></LI
><LI
><P
><TT
CLASS="LITERAL"
>&#62;[$D000+32]</TT
> evaluates to $D0</P
></LI
><LI
><P
><TT
CLASS="LITERAL"
>&#62;[$D000-275]</TT
> evaluates to $CE</P
></LI
></UL
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1101.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1176.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Basic arguments</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Memory Model</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

373
book/x1176.html Normal file
View File

@ -0,0 +1,373 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Memory Model</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Ophis Command Reference"
HREF="a1034.html"><LINK
REL="PREVIOUS"
TITLE="Compound Arguments"
HREF="x1149.html"><LINK
REL="NEXT"
TITLE="Macros"
HREF="x1221.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1149.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Ophis Command Reference</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1221.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN1176"
>Memory Model</A
></H1
><P
> In order to properly compute the locations of labels and the
like, Ophis must keep track of where assembled code will
actually be sitting in memory, and it strives to do this in a
way that is independent both of the target file and of the
target machine.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1179"
>Basic PC tracking</A
></H2
><P
> The primary technique Ophis uses is <I
CLASS="EMPHASIS"
>program counter
tracking</I
>. As it assembles the code, it keeps
track of a virtual program counter, and uses that to
determine where the labels should go.
</P
><P
> In the absence of an <TT
CLASS="LITERAL"
>.org</TT
> directive, it
assumes a starting PC of zero. <TT
CLASS="LITERAL"
>.org</TT
>
is a simple directive, setting the PC to the value
that <TT
CLASS="LITERAL"
>.org</TT
> specifies. In the simplest
case, one <TT
CLASS="LITERAL"
>.org</TT
> directive appears at the
beginning of the code and sets the location for the rest of
the code, which is one contiguous block.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1188"
>Basic Segmentation simulation</A
></H2
><P
> However, this isn't always practical. Often one wishes to
have a region of memory reserved for data without actually
mapping that memory to the file. On some systems (typically
cartridge-based systems where ROM and RAM are seperate, and
the target file only specifies the ROM image) this is
mandatory. In order to access these variables symbolically,
it's necessary to put the values into the label lookup
table.
</P
><P
> It is possible, but inconvenient, to do this
with <TT
CLASS="LITERAL"
>.alias</TT
>, assigning a specific
memory location to each variable. This requires careful
coordination through your code, and makes creating reusable
libraries all but impossible.
</P
><P
> A better approach is to reserve a section at the beginning
or end of your program, put an <TT
CLASS="LITERAL"
>.org</TT
>
directive in, then use the <TT
CLASS="LITERAL"
>.space</TT
>
directive to divide up the data area. This is still a bit
inconvenient, though, because all variables must be
assigned all at once. What we'd really like is to keep
multiple PC counters, one for data and one for code.
</P
><P
> The <TT
CLASS="LITERAL"
>.text</TT
>
and <TT
CLASS="LITERAL"
>.data</TT
> directives do this. Each
has its own PC that starts at zero, and you can switch
between the two at any point without corrupting the other's
counter. In this way each function can have
a <TT
CLASS="LITERAL"
>.data</TT
> section (filled
with <TT
CLASS="LITERAL"
>.space</TT
> commands) and
a <TT
CLASS="LITERAL"
>.text</TT
> section (that contains the
actual code). This lets our library routines be almost
completely self-contained - we can have one source file
that could be <TT
CLASS="LITERAL"
>.included</TT
> by multiple
projects without getting in anything's way.
</P
><P
> However, any given program may have its own ideas about
where data and code go, and it's good to ensure with
a <TT
CLASS="LITERAL"
>.checkpc</TT
> at the end of your code
that you haven't accidentally overwritten code with data or
vice versa. If your <TT
CLASS="LITERAL"
>.data</TT
>
segment <I
CLASS="EMPHASIS"
>did</I
> start at zero, it's
probably wise to make sure you aren't smashing the stack,
too (which is sitting in the region from $0100 to
$01FF).
</P
><P
> If you write code with no segment-defining statements in
it, the default segment
is <TT
CLASS="LITERAL"
>text</TT
>.
</P
><P
> The <TT
CLASS="LITERAL"
>data</TT
> segment is designed only
for organizing labels. As such, errors will be flagged if
you attempt to actually output information into
a <TT
CLASS="LITERAL"
>data</TT
> segment.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1212"
>General Segmentation Simulation</A
></H2
><P
> One text and data segment each is usually sufficient, but
for the cases where it is not, Ophis allows for user-defined
segments. Putting a label
after <TT
CLASS="LITERAL"
>.text</TT
>
or <TT
CLASS="LITERAL"
>.data</TT
> produces a new segment with
the specified name.
</P
><P
> Say, for example, that we have access to the RAM at the low
end of the address space, but want to reserve the zero page
for truly critical variables, and use the rest of RAM for
everything else. Let's also assume that this is a 6510
chip, and locations $00 and $01 are reserved for the I/O
port. We could start our program off with:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data
.org $200
.data zp
.org $2
.text
.org $800</PRE
></TD
></TR
></TABLE
><P
> And, to be safe, we would probably want to end our code
with checks to make sure we aren't overwriting anything:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data
.checkpc $800
.data zp
.checkpc $100</PRE
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1149.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1221.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Compound Arguments</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Macros</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

358
book/x1221.html Normal file
View File

@ -0,0 +1,358 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Macros</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Ophis Command Reference"
HREF="a1034.html"><LINK
REL="PREVIOUS"
TITLE="Memory Model"
HREF="x1176.html"><LINK
REL="NEXT"
TITLE="Assembler directives"
HREF="x1261.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1176.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Ophis Command Reference</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1261.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN1221"
>Macros</A
></H1
><P
> Assembly language is a powerful tool&#8212;however, there are
many tasks that need to be done repeatedly, and with
mind-numbing minor modifications. Ophis includes a facility
for <I
CLASS="EMPHASIS"
>macros</I
> to allow this. Ophis macros
are very similar in form to function calls in higher level
languages.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1225"
>Defining Macros</A
></H2
><P
> Macros are defined with the <TT
CLASS="LITERAL"
>.macro</TT
>
and <TT
CLASS="LITERAL"
>.macend</TT
> commands. Here's a
simple one that will clear the screen on a Commodore
64:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.macro clr'screen
lda #147
jsr $FFD2
.macend</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1231"
>Invoking Macros</A
></H2
><P
> To invoke a macro, either use
the <TT
CLASS="LITERAL"
>.invoke</TT
> command or backquote the
name of the routine. The previous macro may be expanded
out in either of two ways, at any point in the
source:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.invoke clr'screen</PRE
></TD
></TR
></TABLE
><P
>or</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>`clr'screen</PRE
></TD
></TR
></TABLE
><P
>will work equally well.</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1239"
>Passing Arguments to Macros</A
></H2
><P
> Macros may take arguments. The arguments to a macro are
all of the <SPAN
CLASS="QUOTE"
>"word"</SPAN
> type, though byte values may
be passed and used as bytes as well. The first argument in
an invocation is bound to the label
<TT
CLASS="LITERAL"
>_1</TT
>, the second
to <TT
CLASS="LITERAL"
>_2</TT
>, and so on. Here's a macro
for storing a 16-bit value into a word pointer:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.macro store16 ; `store16 dest, src
lda #&#60;_2
sta _1
lda #&#62;_2
sta _1+1
.macend</PRE
></TD
></TR
></TABLE
><P
> Macro arguments behave, for the most part, as if they were
defined by <TT
CLASS="LITERAL"
>.alias</TT
>
commands <I
CLASS="EMPHASIS"
>in the calling context</I
>.
(They differ in that they will not produce duplicate-label
errors if those names already exist in the calling scope,
and in that they disappear after the call is
completed.)
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN1249"
>Features and Restrictions of the Ophis Macro Model</A
></H2
><P
> Unlike most macro systems (which do textual replacement),
Ophis macros evaluate their arguments and bind them into the
symbol table as temporary labels. This produces some
benefits, but it also puts some restrictions on what kinds of
macros may be defined.
</P
><P
> The primary benefit of this <SPAN
CLASS="QUOTE"
>"expand-via-binding"</SPAN
>
discipline is that there are no surprises in the semantics.
The expression <TT
CLASS="LITERAL"
>_1+1</TT
> in the macro above
will always evaluate to one more than the value that was
passed as the first argument, even if that first argument is
some immensely complex expression that an
expand-via-substitution method may accidentally
mangle.
</P
><P
> The primary disadvantage of the expand-via-binding
discipline is that only fixed numbers of words and bytes
may be passed. A substitution-based system could define a
macro including the line <TT
CLASS="LITERAL"
>LDA _1</TT
> and
accept as arguments both <TT
CLASS="LITERAL"
>$C000</TT
>
(which would put the value of memory location $C000 into
the accumulator) and <TT
CLASS="LITERAL"
>#$40</TT
> (which
would put the immediate value $40 into the accumulator).
If you <I
CLASS="EMPHASIS"
>really</I
> need this kind of
behavior, a run a C preprocessor over your Ophis source,
and use <TT
CLASS="LITERAL"
>#define</TT
> to your heart's
content.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1176.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1261.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Memory Model</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Assembler directives</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

568
book/x1261.html Normal file
View File

@ -0,0 +1,568 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Assembler directives</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Ophis Command Reference"
HREF="a1034.html"><LINK
REL="PREVIOUS"
TITLE="Macros"
HREF="x1221.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1221.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Ophis Command Reference</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
>&nbsp;</TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN1261"
>Assembler directives</A
></H1
><P
> Assembler directives are all instructions to the assembler
that are not actual instructions. Ophis's set of directives
follow.
</P
><P
></P
><UL
><LI
><P
> <TT
CLASS="LITERAL"
>.outfile</TT
> <I
CLASS="EMPHASIS"
>filename</I
>:
Sets the filename for the output binary if one has not
already been set. If no name is ever set, the output will
be written to <TT
CLASS="LITERAL"
>ophis.bin</TT
>.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.advance</TT
> <I
CLASS="EMPHASIS"
>address</I
>
[, <I
CLASS="EMPHASIS"
>filler</I
>]: Forces the program
counter to be <I
CLASS="EMPHASIS"
>address</I
>. Unlike
the <TT
CLASS="LITERAL"
>.org</TT
>
directive, <TT
CLASS="LITERAL"
>.advance</TT
> outputs bytes (the
value of <I
CLASS="EMPHASIS"
>filler</I
>, or zeroes if it is
unspecified) until the program counter reaches a
specified address. Attempting
to <TT
CLASS="LITERAL"
>.advance</TT
> to a point behind the
current program counter is an assemble-time error.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.alias</TT
> <I
CLASS="EMPHASIS"
>label</I
> <I
CLASS="EMPHASIS"
>value</I
>:
The .alias directive assigns an arbitrary value to a
label. This value may be an arbitrary argument, but
cannot reference any label that has not already been
defined (this prevents recursive label
dependencies).
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.byte</TT
> <I
CLASS="EMPHASIS"
>arg</I
> [
, <I
CLASS="EMPHASIS"
>arg</I
>, ... ]: Specifies a series of
arguments, which are evaluated, and strings, which are
included as raw ASCII data. The final results of these
arguments must be one byte in size. Seperate constants
are seperated by comments.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.checkpc</TT
> <I
CLASS="EMPHASIS"
>address</I
>:
Ensures that the program counter is less than or equal to
the address specified, and emits an assemble-time error
if it is not. <I
CLASS="EMPHASIS"
>This produces no code in the
final binary - it is there to ensure that linking a large
amount of data together does not overstep memory
boundaries.</I
>
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.data</TT
> <I
CLASS="EMPHASIS"
>[label]</I
>:
Sets the segment to the segment name specified and
disallows output. If no label is given, switches to the
default data segment.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.incbin</TT
> <I
CLASS="EMPHASIS"
>filename</I
>
[, <I
CLASS="EMPHASIS"
>offset</I
>
[, <I
CLASS="EMPHASIS"
>length</I
>]]: Inserts the contents of
the file specified as binary data. Use it to include
graphics information, precompiled code, or other
non-assembler data. You may also optionally specify an
index to start including from, or a length to only
include a subset.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.include</TT
> <I
CLASS="EMPHASIS"
>filename</I
>:
Includes the entirety of the file specified at that point
in the program. Use this to order your final sources, if
you aren't doing it via the command line.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.org</TT
> <I
CLASS="EMPHASIS"
>address</I
>:
Sets the program counter to the address
specified. <I
CLASS="EMPHASIS"
>This does not emit any code in and
of itself, nor does it overwrite anything that previously
existed.</I
> If you wish to jump ahead in memory,
use <TT
CLASS="LITERAL"
>.advance</TT
>.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.require</TT
> <I
CLASS="EMPHASIS"
>filename</I
>:
Includes the entirety of the file specified at that point
in the program. Unlike <TT
CLASS="LITERAL"
>.include</TT
>,
however, code included with <TT
CLASS="LITERAL"
>.require</TT
>
will only be inserted once.
The <TT
CLASS="LITERAL"
>.require</TT
> directive is useful for
ensuring that certain code libraries are somewhere in the
final binary. They are also very useful for guaranteeing
that macro libraries are available.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.space</TT
> <I
CLASS="EMPHASIS"
>label</I
> <I
CLASS="EMPHASIS"
>size</I
>:
This directive is used to organize global variables. It
defines the label specified to be at the current location
of the program counter, and then advances the program
counter <I
CLASS="EMPHASIS"
>size</I
> steps ahead. No actual
code is produced. This is equivalent to <TT
CLASS="LITERAL"
>label:
.org ^+size</TT
>.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.text</TT
> <I
CLASS="EMPHASIS"
>[label]</I
>:
Sets the segment to the segment name specified and allows
output. If no label is given, switches to the default
text segment.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.word</TT
> <I
CLASS="EMPHASIS"
>arg</I
> [
, <I
CLASS="EMPHASIS"
>arg</I
>, ... ]:
Like <TT
CLASS="LITERAL"
>.byte</TT
>, but values are all treated
as two-byte values and stored low-end first (as is the
6502's wont). Use this to create jump tables (an
unadorned label will evaluate to that label's location)
or otherwise store 16-bit data.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.dword</TT
> <I
CLASS="EMPHASIS"
>arg</I
> [
, <I
CLASS="EMPHASIS"
>arg</I
>, ...]:
Like <TT
CLASS="LITERAL"
>.word</TT
>, but for 32-bit
values.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.wordbe</TT
> <I
CLASS="EMPHASIS"
>arg</I
> [
, <I
CLASS="EMPHASIS"
>arg</I
>, ...]:
Like <TT
CLASS="LITERAL"
>.word</TT
>, but stores the value in a
big-endian format (high byte first).
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.dwordbe</TT
> <I
CLASS="EMPHASIS"
>arg</I
> [
, <I
CLASS="EMPHASIS"
>arg</I
>, ...]:
Like <TT
CLASS="LITERAL"
>.dword</TT
>, but stores the value high
byte first.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.scope</TT
>: Starts a new scope
block. Labels that begin with an underscore are only
reachable from within their innermost
enclosing <TT
CLASS="LITERAL"
>.scope</TT
>
statement.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.scend</TT
>: Ends a scope block. Makes the
temporary labels defined since the
last <TT
CLASS="LITERAL"
>.scope</TT
> statement unreachable, and
permits them to be redefined in a new
scope.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.macro</TT
> <I
CLASS="EMPHASIS"
>name</I
>:
Begins a macro definition block. This is a scope block
that can be inlined at arbitrary points
with <TT
CLASS="LITERAL"
>.invoke</TT
>. Arguments to the macro
will be bound to temporary labels with names like
<TT
CLASS="LITERAL"
>_1</TT
>, <TT
CLASS="LITERAL"
>_2</TT
>, etc.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.macend</TT
>: Ends a macro definition block.
</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>.invoke</TT
> <I
CLASS="EMPHASIS"
>label</I
> [<I
CLASS="EMPHASIS"
>argument</I
> [,
<I
CLASS="EMPHASIS"
>argument</I
> ...]]: invokes (inlines) the
specified macro, binding the values of the arguments to the
ones the macro definition intends to read. A shorthand
for <TT
CLASS="LITERAL"
>.invoke</TT
> is the name of the macro to
invoke, backquoted.
</P
></LI
></UL
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1221.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Macros</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

206
book/x140.html Normal file
View File

@ -0,0 +1,206 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Related commands and options</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The basics"
HREF="c55.html"><LINK
REL="PREVIOUS"
TITLE="Producing Commodore 64 programs"
HREF="x71.html"><LINK
REL="NEXT"
TITLE="Writing the actual code"
HREF="x161.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x71.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The basics</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x161.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN140"
>Related commands and options</A
></H1
><P
> This code includes constants that are both in decimal and in
hex. It is also possible to specify constants in octal, binary,
or with an ASCII character.
<P
></P
><UL
><LI
><P
>To specify decimal constants, simply write the number.</P
></LI
><LI
><P
>To specify hexadecimal constants, put a $ in front.</P
></LI
><LI
><P
>To specify octal constants, put a 0 (zero) in front.</P
></LI
><LI
><P
>To specify binary constants, put a % in front.</P
></LI
><LI
><P
>To specify ASCII constants, put an apostrophe in front.</P
></LI
></UL
>
Example: 65 = $41 = 0101 = %1000001 = 'A
</P
><P
> There are other commands besides <TT
CLASS="LITERAL"
>.byte</TT
>
and <TT
CLASS="LITERAL"
>.word</TT
> to specify data. In particular,
the <TT
CLASS="LITERAL"
>.dword</TT
> command specifies four-byte values
which some applications will find useful. Also, some linking
formats (such as the <TT
CLASS="FILENAME"
>SID</TT
> format) have
header data in big-endian (high byte first) format.
The <TT
CLASS="LITERAL"
>.wordbe</TT
> and <TT
CLASS="LITERAL"
>.dwordbe</TT
>
directives provide a way to specify multibyte constants in
big-endian formats cleanly.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x71.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x161.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Producing Commodore 64 programs</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c55.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Writing the actual code</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

197
book/x161.html Normal file
View File

@ -0,0 +1,197 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Writing the actual code</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The basics"
HREF="c55.html"><LINK
REL="PREVIOUS"
TITLE="Related commands and options"
HREF="x140.html"><LINK
REL="NEXT"
TITLE="Assembling the code"
HREF="x170.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x140.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The basics</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x170.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN161"
>Writing the actual code</A
></H1
><P
> Now that we have our header information, let's actually write
the <SPAN
CLASS="QUOTE"
>"Hello world"</SPAN
> program. It's pretty
short&#8212;a simple loop that steps through a hardcoded array
until it reaches a 0 or outputs 256 characters. It then returns
control to BASIC with an <TT
CLASS="LITERAL"
>RTS</TT
> statement.
</P
><P
> Each character in the array is passed as an argument to a
subroutine at memory location $FFD2. This is part of the
Commodore 64's BIOS software, which its development
documentation calls the KERNAL. Location $FFD2 prints out the
character corresponding to the character code in the
accumulator.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #0
loop: lda hello, x
beq done
jsr $ffd2
inx
bne loop
done: rts
hello: .byte "HELLO, WORLD!", 0
</PRE
></TD
></TR
></TABLE
><P
> The complete, final source is available in
the <A
HREF="a975.html#TUTOR1-SRC"
><I
><I
>hello1.oph</I
></I
></A
> file.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x140.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x170.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Related commands and options</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c55.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Assembling the code</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

333
book/x170.html Normal file
View File

@ -0,0 +1,333 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Assembling the code</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The basics"
HREF="c55.html"><LINK
REL="PREVIOUS"
TITLE="Writing the actual code"
HREF="x161.html"><LINK
REL="NEXT"
TITLE="Labels and aliases"
HREF="c223.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x161.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The basics</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c223.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN170"
>Assembling the code</A
></H1
><P
> The Ophis assembler is a collection of Python modules,
controlled by a master script. On Windows, this should all
have been combined into an executable
file <B
CLASS="COMMAND"
>ophis.exe</B
>; on other platforms, the
Ophis modules should be in the library and
the <B
CLASS="COMMAND"
>ophis</B
> script should be in your path.
Typing <B
CLASS="COMMAND"
>ophis</B
> with no arguments should give a
summary of available command line options.
</P
><P
> Ophis takes a list of source files and produces an output file
based on assembling each file you give it, in order. You can add
a line to your program like this to name the output file:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.outfile "hello.prg"</PRE
></TD
></TR
></TABLE
><P
> Alternately, you can use the <CODE
CLASS="OPTION"
>-o</CODE
> option on the
command line. This will override any <TT
CLASS="LITERAL"
>.outfile</TT
>
directives. If you don't specify any name, it will put the
output into a file named <TT
CLASS="FILENAME"
>ophis.bin</TT
>.
</P
><P
> If you are using Ophis as part of some larger toolchain, you can
also make it run in <I
CLASS="EMPHASIS"
>pipe mode</I
>. If you give
a dash <CODE
CLASS="OPTION"
>-</CODE
> as an input file or as the output
target, Ophis will use standard input or output for
communication.
</P
><DIV
CLASS="TABLE"
><A
NAME="AEN185"
></A
><P
><B
>Table 2. Ophis Options</B
></P
><TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
CELLSPACING="0"
CELLPADDING="4"
CLASS="CALSTABLE"
><THEAD
><TR
><TH
ALIGN="CENTER"
>Option</TH
><TH
ALIGN="CENTER"
>Effect</TH
></TR
></THEAD
><TBODY
><TR
><TD
><CODE
CLASS="OPTION"
>-o FILE</CODE
></TD
><TD
>Overrides the default filename for output.</TD
></TR
><TR
><TD
><CODE
CLASS="OPTION"
>-u</CODE
></TD
><TD
>Allows the 6510 undocumented opcodes as listed in the VICE documentation.</TD
></TR
><TR
><TD
><CODE
CLASS="OPTION"
>-c</CODE
></TD
><TD
>Allows opcodes and addressing modes added by the 65C02.</TD
></TR
><TR
><TD
><CODE
CLASS="OPTION"
>-q</CODE
></TD
><TD
>Quiet operation. Only reports warnings and errors.</TD
></TR
><TR
><TD
><CODE
CLASS="OPTION"
>-v</CODE
></TD
><TD
>Verbose operation. Reports files as they are loaded.</TD
></TR
></TBODY
></TABLE
></DIV
><P
> The only options Ophis demands are an input file and an output
file. Here's a sample session, assembling the tutorial file
here:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="SCREEN"
>localhost$ ophis -v hello1.oph
Loading hello1.oph
Assembly complete: 45 bytes output (14 code, 29 data, 2 filler)
</PRE
></TD
></TR
></TABLE
><P
> This will produce a file named <TT
CLASS="FILENAME"
>hello.prg</TT
>. If
your emulator can run <TT
CLASS="FILENAME"
>PRG</TT
> files directly,
this file will now run (and print <SAMP
CLASS="COMPUTEROUTPUT"
>HELLO,
WORLD!</SAMP
>) as many times as you
type <KBD
CLASS="USERINPUT"
>RUN</KBD
>. Otherwise, use
a <TT
CLASS="FILENAME"
>D64</TT
> management utility to put
the <TT
CLASS="FILENAME"
>PRG</TT
> on a <TT
CLASS="FILENAME"
>D64</TT
>, then
load and run the file off that.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x161.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c223.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Writing the actual code</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c55.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Labels and aliases</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

198
book/x237.html Normal file
View File

@ -0,0 +1,198 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Anonymous labels</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Labels and aliases"
HREF="c223.html"><LINK
REL="PREVIOUS"
TITLE="Labels and aliases"
HREF="c223.html"><LINK
REL="NEXT"
TITLE="Aliasing"
HREF="x248.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c223.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Labels and aliases</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x248.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN237"
>Anonymous labels</A
></H1
><P
> Anonymous labels are a way to handle short-ranged branches
without having to come up with names for the then and else
branches, for brief loops, and other such purposes. To define
an anonymous label, use an asterisk. To refer to an anonymous
label, use a series of <TT
CLASS="LITERAL"
>+</TT
>
or <TT
CLASS="LITERAL"
>-</TT
> signs. <TT
CLASS="LITERAL"
>+</TT
> refers to
the next anonymous label, <TT
CLASS="LITERAL"
>++</TT
> the label
after that, etc. Likewise, <TT
CLASS="LITERAL"
>-</TT
> is the most
recently defined label, <TT
CLASS="LITERAL"
>--</TT
> the one before
that, and so on. The main body of the Hello World program
with anonymous labels would be:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #0
* lda hello, x
beq +
jsr $ffd2
inx
bne -
* rts</PRE
></TD
></TR
></TABLE
><P
> It is worth noting that anonymous labels are globally available.
They are not temporary labels, and they ignore scoping
restrictions.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c223.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x248.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Labels and aliases</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c223.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Aliasing</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

203
book/x248.html Normal file
View File

@ -0,0 +1,203 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Aliasing</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Labels and aliases"
HREF="c223.html"><LINK
REL="PREVIOUS"
TITLE="Anonymous labels"
HREF="x237.html"><LINK
REL="NEXT"
TITLE="Headers, Libraries, and Macros"
HREF="c259.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x237.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Labels and aliases</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c259.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN248"
>Aliasing</A
></H1
><P
> Rather the reverse of anonymous labels, aliases are names
given to specific memory locations. These make it easier to
keep track of important constants or locations. The KERNAL
routines are a good example of constants that deserve names.
To assign the traditional name <TT
CLASS="LITERAL"
>chrout</TT
> to
the routine at $FFD2, simply give the directive:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.alias chrout $ffd2</PRE
></TD
></TR
></TABLE
><P
>And change the <KBD
CLASS="USERINPUT"
>jsr</KBD
> command
to:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> jsr chrout</PRE
></TD
></TR
></TABLE
><P
> The final version of the code is in <A
HREF="x982.html"
><I
><I
>hello2.oph</I
></I
></A
>. It should
assemble to exactly the same program as <A
HREF="a975.html#TUTOR1-SRC"
><I
><I
>hello1.oph</I
></I
></A
>.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x237.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c259.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Anonymous labels</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c223.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Headers, Libraries, and Macros</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

289
book/x284.html Normal file
View File

@ -0,0 +1,289 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Macros</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Headers, Libraries, and Macros"
HREF="c259.html"><LINK
REL="PREVIOUS"
TITLE="Headers, Libraries, and Macros"
HREF="c259.html"><LINK
REL="NEXT"
TITLE="Example code"
HREF="x314.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c259.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Headers, Libraries, and Macros</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x314.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN284"
>Macros</A
></H1
><P
> A macro is a way of expressing a lot of code or data with a
simple shorthand. It's also usually configurable. Traditional
macro systems such as C's <TT
CLASS="LITERAL"
>#define</TT
> mechanic
use <I
CLASS="EMPHASIS"
>textual replacement</I
>: a macro is
expanded before any evaluation or even parsing occurs.
</P
><P
> In contrast, Ophis's macro system uses a <I
CLASS="EMPHASIS"
>call by
value</I
> approach where the arguments to macros are
evaluated to bytes or words before being inserted into the macro
body. This produces effects much closer to those of a
traditional function call. A more detailed discussion of the
tradeoffs may be found in <A
HREF="a1034.html"
>the Appendix called <I
>Ophis Command Reference</I
></A
>.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN292"
>Macro definitions</A
></H2
><P
> A macro definition is a set of statements between
a <TT
CLASS="LITERAL"
>.macro</TT
> statement and
a <TT
CLASS="LITERAL"
>.macend</TT
> statement.
The <TT
CLASS="LITERAL"
>.macro</TT
> statement also names the macro
being defined.
</P
><P
> No global or anonymous labels may be defined inside a macro:
temporary labels only persist in the macro expansion itself.
(Each macro body has its own scope.)
</P
><P
> Arguments to macros are referred to by number: the first is
<TT
CLASS="LITERAL"
>_1</TT
>, the second <TT
CLASS="LITERAL"
>_2</TT
>, and so on.
</P
><P
> Here's a macro that encapsulates the printing routine in our
<SPAN
CLASS="QUOTE"
>"Hello World"</SPAN
> program, with an argument being the
address of the string to print:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.macro print
ldx #0
_loop: lda _1, x
beq _done
jsr chrout
inx
bne _loop
_done:
.macend</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN305"
>Macro invocations</A
></H2
><P
> Macros may be invoked in two ways: one that looks like a
directive, and one that looks like an instruction.
</P
><P
> The most common way to invoke a macro is to backquote the name
of the macro. It is also possible to use
the <TT
CLASS="LITERAL"
>.invoke</TT
> command. These commands look
like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>`print msg
.invoke print msg</PRE
></TD
></TR
></TABLE
><P
> Arguments are passed to the macro as a comma-separated list.
They must all be expressions that evaluate to byte or word
values&#8212;a mechanism similar to <TT
CLASS="LITERAL"
>.alias</TT
>
is used to assign their values to the <TT
CLASS="LITERAL"
>_n</TT
>
names.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c259.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x314.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Headers, Libraries, and Macros</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c259.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Example code</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

193
book/x29.html Normal file
View File

@ -0,0 +1,193 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Getting a copy of Ophis</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Preface"
HREF="f10.html"><LINK
REL="PREVIOUS"
TITLE="Preface"
HREF="f10.html"><LINK
REL="NEXT"
TITLE="About the examples"
HREF="x41.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="f10.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Preface</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x41.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN29"
>Getting a copy of Ophis</A
></H1
><P
> As of this writing, the Ophis assembler is hosted at Github. The
latest downloads and documentation will be available
at <A
HREF="http://github.com/michaelcmartin/Ophis"
TARGET="_top"
>http://github.com/michaelcmartin/Ophis</A
>. If
this is out-of-date, a Web search on <SPAN
CLASS="QUOTE"
>"Ophis 6502
assembler"</SPAN
> (without the quotation marks) should yield its
page.
</P
><P
> Ophis is written entirely in Python and packaged using the
distutils. The default installation script on Unix and Mac OS X
systems should put the files where they need to go. If you are
running it locally, you will need to install
the <TT
CLASS="LITERAL"
>Ophis</TT
> package somewhere in your Python
package path, and then put the <B
CLASS="COMMAND"
>ophis</B
> script
somewhere in your path.
</P
><P
> For Windows users, a prepackaged system made
with <B
CLASS="COMMAND"
>py2exe</B
> is also available. The default
Windows installer will use this. In this case, all you need to
do is have <B
CLASS="COMMAND"
>ophis.exe</B
> in your path.
</P
><P
> If you are working on a system with Python installed but to
which you do not wish to install software, there is also a
standalone pure-Python edition with an ophis.py script. This may
be placed anywhere and running ophis.py will temporarily set the
library path to point to your directory.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="f10.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x41.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Preface</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="f10.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>About the examples</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

161
book/x314.html Normal file
View File

@ -0,0 +1,161 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Example code</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Headers, Libraries, and Macros"
HREF="c259.html"><LINK
REL="PREVIOUS"
TITLE="Macros"
HREF="x284.html"><LINK
REL="NEXT"
TITLE="Character maps"
HREF="c319.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x284.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Headers, Libraries, and Macros</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c319.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN314"
>Example code</A
></H1
><P
> <A
HREF="x994.html"
><I
><I
>hello3.oph</I
></I
></A
> expands our
running example, including the code above and also defining a
new macro <TT
CLASS="LITERAL"
>greet</TT
> that takes a string argument
and prints a greeting to it. It then greets far too many
targets.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x284.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c319.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Macros</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c259.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Character maps</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

176
book/x41.html Normal file
View File

@ -0,0 +1,176 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>About the examples</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Preface"
HREF="f10.html"><LINK
REL="PREVIOUS"
TITLE="Getting a copy of Ophis"
HREF="x29.html"><LINK
REL="NEXT"
TITLE="Using the Ophis Assembler"
HREF="p50.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x29.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Preface</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="p50.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN41"
>About the examples</A
></H1
><P
> Versions of the examples in this book are available from the Ophis site. Windows users will find them packaged with the distribution; all other users can get them as a separate download or pull them directly from github.
</P
><P
> The code in this book is available in
the <TT
CLASS="LITERAL"
>examples/</TT
> subdirectory, while extra
examples will be in subdirectories of their own with brief
descriptions. They are largely all simple <SPAN
CLASS="QUOTE"
>"Hello
world"</SPAN
> applications, designed mainly to demonstrate how
to package assembled binaries into forms that emulators or ROM
loaders can use. They are not primarily intended as tutorials
for writing for the platforms themselves.
</P
><P
> Most examples will require use of <I
CLASS="EMPHASIS"
>platform
headers</I
>&#8212;standardized header files that set
useful constants for the target system and, if needed, contain
small programs to allow the program to be loaded and run. These
are stored in the <TT
CLASS="LITERAL"
>platform/</TT
> subdirectory.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x29.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="p50.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Getting a copy of Ophis</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="f10.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Using the Ophis Assembler</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

321
book/x454.html Normal file
View File

@ -0,0 +1,321 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>The Solution</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Advanced Memory Segments"
HREF="c443.html"><LINK
REL="PREVIOUS"
TITLE="Advanced Memory Segments"
HREF="c443.html"><LINK
REL="NEXT"
TITLE="Where to go from here"
HREF="x476.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c443.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Advanced Memory Segments</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x476.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN454"
>The Solution</A
></H1
><P
> The <TT
CLASS="LITERAL"
>.data</TT
> and <TT
CLASS="LITERAL"
>.text</TT
>
commands can take a label name after them&#8212;this names a new
segment. We'll define a new segment
called <TT
CLASS="LITERAL"
>zp</TT
> (for <SPAN
CLASS="QUOTE"
>"zero page"</SPAN
>) 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:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data zp
.org $0002</PRE
></TD
></TR
></TABLE
><P
> 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.
</P
><P
> In fact, since we're disablng BASIC, we can actually also swap
out its ROM entirely and get a contiguous block of RAM from
$0002 to $CFFF:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.scope
; Cache BASIC zero page at top of available RAM
ldx #$7E
* lda $01, x
sta $CF81, x
dex
bne -
; Swap out the BASIC ROM for RAM
lda $01
and #$fe
ora #$06
sta $01
; Run the real program
jsr _main
; Restore BASIC ROM
lda $01
ora #$07
sta $01
; Restore BASIC zero page
ldx #$7E
* lda $CF81, x
sta $01, x
dex
bne -
; Back to BASIC
rts
_main:
; _main points at the start of the real program,
; which is actually outside of this scope
.scend</PRE
></TD
></TR
></TABLE
><P
> The new, improved header file is <A
HREF="x1018.html"
><I
><I
>c64_0.oph</I
></I
></A
>. This,
like <TT
CLASS="FILENAME"
>c64kernal.oph</TT
>, is available for use in
your own projects in the <TT
CLASS="LITERAL"
>platform/</TT
> directory.
</P
><P
> Our <TT
CLASS="LITERAL"
>print'str</TT
> routine is then rewritten to
declare and use a zero-page variable, like so:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="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</PRE
></TD
></TR
></TABLE
><P
> Also, we ought to put in an extra check to make sure our
zero-page allocations don't overflow, either:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data zp
.checkpc $80</PRE
></TD
></TR
></TABLE
><P
> That concludes our tour. The final source file
is <A
HREF="x1022.html"
><I
><I
>hello7.oph</I
></I
></A
>.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c443.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x476.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Advanced Memory Segments</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c443.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Where to go from here</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

162
book/x476.html Normal file
View File

@ -0,0 +1,162 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Where to go from here</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Advanced Memory Segments"
HREF="c443.html"><LINK
REL="PREVIOUS"
TITLE="The Solution"
HREF="x454.html"><LINK
REL="NEXT"
TITLE="To HLL and Back"
HREF="p481.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x454.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Advanced Memory Segments</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="p481.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN476"
>Where to go from here</A
></H1
><P
> This tutorial has touched on everything that the assembler can
do, but it's not really well organized as a
reference. <A
HREF="a1034.html"
>the Appendix called <I
>Ophis Command Reference</I
></A
> is a better place to look
up matters of syntax or consult lists of available commands.
</P
><P
> 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.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x454.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="p481.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>The Solution</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c443.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>To HLL and Back</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

166
book/x498.html Normal file
View File

@ -0,0 +1,166 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>The solution</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The Second Step"
HREF="c486.html"><LINK
REL="PREVIOUS"
TITLE="The Second Step"
HREF="c486.html"><LINK
REL="NEXT"
TITLE="Unsigned arithmetic"
HREF="x504.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c486.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The Second Step</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x504.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN498"
>The solution</A
></H1
><P
> We have two solutions available to us. First, we can use
the <SPAN
CLASS="QUOTE"
>"unsigned"</SPAN
> discipline, which involves checking
different flags, but lets us deal with values between 0 and 255
instead of -128 to 127. Second, we can trade speed and register
persistence for multiple precision arithmetic, using 16-bit
integers (-32768 to 32767, or 0-65535), 24-bit, or more.
</P
><P
> Multiplication, division, and floating point arithmetic are beyond
the scope of this essay. The best way to deal with those is to
find a math library on the web (I
recommend <A
HREF="http://www.6502.org/"
TARGET="_top"
>http://www.6502.org/</A
>) and use the
routines there.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c486.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x504.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>The Second Step</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c486.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Unsigned arithmetic</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

267
book/x504.html Normal file
View File

@ -0,0 +1,267 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Unsigned arithmetic</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The Second Step"
HREF="c486.html"><LINK
REL="PREVIOUS"
TITLE="The solution"
HREF="x498.html"><LINK
REL="NEXT"
TITLE="16-bit addition and subtraction"
HREF="x527.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x498.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The Second Step</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x527.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN504"
>Unsigned arithmetic</A
></H1
><P
> When writing control code that hinges on numbers, we should always
strive to have our comparison be with zero; that way, no explicit
compare is necessary, and we can branch simply
with <TT
CLASS="LITERAL"
>BEQ/BNE</TT
>, which test the zero flag.
Otherwise, we use <TT
CLASS="LITERAL"
>CMP</TT
>.
The <TT
CLASS="LITERAL"
>CMP</TT
> command subtracts its argument from the
accumulator (without borrow), updates the flags, but throws away
the result. If the value is equal, the result is zero.
(<TT
CLASS="LITERAL"
>CMP</TT
> followed by <TT
CLASS="LITERAL"
>BEQ</TT
>
branches if the argument is equal to the accumulator; this is
probably why it's called <TT
CLASS="LITERAL"
>BEQ</TT
> and not something
like <TT
CLASS="LITERAL"
>BZS</TT
>.)
</P
><P
> Intuitively, then, to check if the accumulator is <I
CLASS="EMPHASIS"
>less
than</I
> some value, we <TT
CLASS="LITERAL"
>CMP</TT
> against that
value and <TT
CLASS="LITERAL"
>BMI</TT
>. The <TT
CLASS="LITERAL"
>BMI</TT
>
command branches based on the Negative Flag, which is equal to the
seventh bit of <TT
CLASS="LITERAL"
>CMP</TT
>'s subtract. That's exactly
what we need, for signed arithmetic. However, this produces
problems if you're writing a boundary detector on your screen or
something and find that 192 &#60; 4. 192 is outside of a signed
byte's range, and is interpreted as if it were -64. This will not
do for most graphics applications, where your values will be
ranging from 0-319 or 0-199 or 0-255.
</P
><P
> Instead, we take advantage of the implied subtraction
that <TT
CLASS="LITERAL"
>CMP</TT
> does. When subtracting, the result's
carry bit starts at 1, and gets borrowed from if necessary. Let
us consider some four-bit subtractions.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>C|3210 C|3210
------ ------
1|1001 9 1|1001 9
|0100 - 4 |1100 -12
------ --- ------ ---
1|0101 5 0|1101 -3</PRE
></TD
></TR
></TABLE
><P
> The <TT
CLASS="LITERAL"
>CMP</TT
> command properly modifies the carry bit
to reflect this. When computing A-B, the carry bit is set if A
&#62;= B, and it's clear if A &#60; B. Consider the following two
code sequences.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> (1) (2)
CMP #$C0 CMP #$C0
BMI label BCC label</PRE
></TD
></TR
></TABLE
><P
> The code in the first column treats the value in the accumulator
as a signed value, and branches if the value is less than -64.
(Because of overflow issues, it will actually branch for
accumulator values between $40 and $BF, even though it *should*
only be doing it for values between $80 and $BF. To see why,
compare $40 to $C0 and look at the result.) The second column
code treats the accumulator as holding an unsigned value, and
branches if the value is less than 192. It will branch for
accumulator values $00-$BF.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x498.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x527.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>The solution</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c486.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>16-bit addition and subtraction</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

196
book/x527.html Normal file
View File

@ -0,0 +1,196 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>16-bit addition and subtraction</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The Second Step"
HREF="c486.html"><LINK
REL="PREVIOUS"
TITLE="Unsigned arithmetic"
HREF="x504.html"><LINK
REL="NEXT"
TITLE="16-bit comparisons"
HREF="x537.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x504.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The Second Step</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x537.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN527"
>16-bit addition and subtraction</A
></H1
><P
> Time to use the carry bit for what it was meant to do. Adding two
8 bit numbers can produce a 9-bit result. That 9th bit is stored
in the carry flag. The <TT
CLASS="LITERAL"
>ADC</TT
> command adds the
carry value to its result, as well. Thus, carries work just as
we'd expect them to. Suppose we're storing two 16-bit values, low
byte first, in $C100-1 and $C102-3. To add them together and
store them in $C104-5, this is very easy:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> CLC
LDA $C100
ADC $C102
STA $C104
LDA $C101
ADC $C103
STA $C105</PRE
></TD
></TR
></TABLE
><P
> Subtraction is identical, but you set the carry bit first
with <TT
CLASS="LITERAL"
>SEC</TT
> (because borrow is the complement of
carry&#8212;think about how the unsigned compare works if this
puzzles you) and, of course, using the <TT
CLASS="LITERAL"
>SBC</TT
>
instruction instead of <TT
CLASS="LITERAL"
>ADC</TT
>.
</P
><P
> The carry/borrow bit is set appropriately to let you continue,
too. As long as you just keep working your way up to bytes of
ever-higher significance, this generalizes to 24 (do it three
times instead of two) or 32 (four, etc.) bit integers.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x504.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x537.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Unsigned arithmetic</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c486.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>16-bit comparisons</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

178
book/x537.html Normal file
View File

@ -0,0 +1,178 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>16-bit comparisons</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The Second Step"
HREF="c486.html"><LINK
REL="PREVIOUS"
TITLE="16-bit addition and subtraction"
HREF="x527.html"><LINK
REL="NEXT"
TITLE="Structured Programming"
HREF="c543.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x527.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The Second Step</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c543.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN537"
>16-bit comparisons</A
></H1
><P
> Doing comparisons on extended precision values is about the same
as doing them on 8-bit values, but you have to have the value you
test in memory, since it won't fit in the accumulator all at once.
You don't have to store the values back anywhere, either, since
all you care about is the final state of the flags. For example,
here's a signed comparison, branching to <TT
CLASS="LITERAL"
>label</TT
>
if the value in $C100-1 is less than 1000 ($03E8):
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> SEC
LDA $C100
SBC #$E8
LDA $C101 ; We only need the carry bit from that subtract
SBC #$03
BMI label</PRE
></TD
></TR
></TABLE
><P
> All the commentary on signed and unsigned compares holds for
16-bit (or higher) integers just as it does for the 8-bit
ones.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x527.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>16-bit addition and subtraction</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c486.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Structured Programming</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

172
book/x597.html Normal file
View File

@ -0,0 +1,172 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>The stack</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Structured Programming"
HREF="c543.html"><LINK
REL="PREVIOUS"
TITLE="Structured Programming"
HREF="c543.html"><LINK
REL="NEXT"
TITLE="Procedures and register saving"
HREF="x603.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c543.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Structured Programming</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x603.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN597"
>The stack</A
></H1
><P
> The 6502 has an onboard stack in page 1. You can modify the stack
pointer by storing values in X register and
using <TT
CLASS="LITERAL"
>txs</TT
>; an <SPAN
CLASS="QUOTE"
>"empty"</SPAN
> stack is
value $FF. Going into a procedure pushes the address of the next
instruction onto the stack, and RTS pops that value off and jumps
there. (Well, not precisely. JSR actually pushes a value that's
one instruction short, and RTS loads the value, increases it by
one, and THEN jumps there. But that's only an issue if you're
using RTS to implement jump tables.) On an interrupt, the next
instruction's address is pushed on the stack, then the process
flags, and it jumps to the handler. The return from interrupt
restores the flags and the PC, just as if nothing had
happened.
</P
><P
> The stack only has 256 possible entries; since addresses take two
bytes to store, that means that if you call something that calls
something that calls something that (etc., etc., 129 times), your
computation will fail. This can happen faster if you save
registers or memory values on the stack (see below).
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x603.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Structured Programming</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Procedures and register saving</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

283
book/x603.html Normal file
View File

@ -0,0 +1,283 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Procedures and register saving</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Structured Programming"
HREF="c543.html"><LINK
REL="PREVIOUS"
TITLE="The stack"
HREF="x597.html"><LINK
REL="NEXT"
TITLE="Variables"
HREF="x621.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x597.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Structured Programming</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x621.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN603"
>Procedures and register saving</A
></H1
><P
> All programming languages are designed around the concept of
procedures.<A
NAME="AEN606"
HREF="#FTN.AEN606"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
>
Procedures let you break a computation up into different parts,
then use them independently. However, compilers do a lot of work
for you behind the scenes to let you think this. Consider the
following assembler code. How many times does the loop
execute?
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>loop: ldx #$10 jsr do'stuff dex bne loop</PRE
></TD
></TR
></TABLE
><P
> The correct answer is <SPAN
CLASS="QUOTE"
>"I don't know, but
it <I
CLASS="EMPHASIS"
>should</I
> be 16."</SPAN
> The reason we don't
know is because we're assuming here that
the <TT
CLASS="LITERAL"
>do'stuff</TT
> routine doesn't change the value
of the X register. If it does, than all sorts of chaos could
result. For major routines that aren't called often but are
called in places where the register state is important, you should
store the old registers on the stack with code like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>do'stuff:
pha
txa
pha
tya
pha
;; Rest of do'stuff goes here
pla
tay
pla
tax
pla
rts</PRE
></TD
></TR
></TABLE
><P
> (Remember, the last item pushed onto the stack is the first one
pulled off, so you have to restore them in reverse order.) That's
three more bytes on the stack, so you don't want to do this if you
don't absolutely have to. If <TT
CLASS="LITERAL"
>do'stuff</TT
>
actually <I
CLASS="EMPHASIS"
>doesn't</I
> touch X, there's no need to
save and restore the value. This technique is
called <I
CLASS="EMPHASIS"
>callee-save</I
>.
</P
><P
> The reverse technique is called <I
CLASS="EMPHASIS"
>caller-save</I
>
and pushes important registers onto the stack before the routine
is called, then restores them afterwards. Each technique has its
advantages and disadvantages. The best way to handle it in your
own code is to mark at the top of each routine which registers
need to be saved by the caller. (It's also useful to note things
like how it takes arguments and how it returns values.)
</P
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN606"
HREF="x603.html#AEN606"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>Yes, all of them. Functional languages
just let you do more things with them, logic programming has
implicit calls to query procedures, and
object-oriented <SPAN
CLASS="QUOTE"
>"methods"</SPAN
> are just normal procedures
that take one extra argument in secret.</P
></TD
></TR
></TABLE
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x597.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x621.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>The stack</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Variables</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

348
book/x621.html Normal file
View File

@ -0,0 +1,348 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Variables</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Structured Programming"
HREF="c543.html"><LINK
REL="PREVIOUS"
TITLE="Procedures and register saving"
HREF="x603.html"><LINK
REL="NEXT"
TITLE="Data structures"
HREF="x666.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x603.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Structured Programming</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x666.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN621"
>Variables</A
></H1
><P
> Variables come in several flavors.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN624"
>Global variables</A
></H2
><P
> Global variables are variables that can be reached from any
point in the program. Since the 6502 has no memory protection,
these are easy to declare. Take some random chunk of unused
memory and declare it to be the global variables area. All
reasonable assemblers have commands that let you give a symbolic
name to a memory location&#8212;you can use this to give your
globals names.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN627"
>Local variables</A
></H2
><P
> All modern languages have some concept of <SPAN
CLASS="QUOTE"
>"local
variables"</SPAN
>, which are data values unique to that
invocation of that procedure. In modern architecures, this data
is stored into and read directly off of the stack. The 6502
doesn't really let you do this cleanly; I'll discuss ways of
handling it in a later essay. If you're implementing a system
from scratch, you can design your memory model to not require
such extreme measures. There are three basic techniques.
</P
><DIV
CLASS="SECTION"
><H3
CLASS="SECTION"
><A
NAME="AEN631"
>Treat local variables like registers</A
></H3
><P
> This means that any memory location you use, you save on the
stack and restore afterwards. This
can <I
CLASS="EMPHASIS"
>really</I
> eat up stack space, and it's
really slow, it's often pointless, and it has a tendency to
overflow the stack. I can't recommend it. But it does let
you do recursion right, if you don't need to save much memory
and you aren't recursing very deep.
</P
></DIV
><DIV
CLASS="SECTION"
><H3
CLASS="SECTION"
><A
NAME="AEN635"
>Procedure-based memory allocation</A
></H3
><P
> With this technique, you give each procedure its own little
chunk of memory for use with its data. All the variables are
still, technically, globals; a
routine <I
CLASS="EMPHASIS"
>could</I
> interfere with another's,
but the discipline of <SPAN
CLASS="QUOTE"
>"only mess with real globals, and
your own locals"</SPAN
> is very, very easy to maintain.
</P
><P
> This has many advantages. It's <I
CLASS="EMPHASIS"
>very</I
>
fast, both to write and to run, because loading a variable is
an Absolute or Zero Page instruction. Also, any procedure may
call any other procedure, as long as it doesn't wind up
calling itself at some point.
</P
><P
> It has two major disadvantages. First, if many routines need
a lot of space, it can consume more memory than it should.
Also, this technique can require significant assembler
support&#8212;you must ensure that no procedure's local
variables are defined in the same place as any other
procedure, and it essentially requires a full symbolic linker
to do right. Ophis includes commands for <I
CLASS="EMPHASIS"
>memory
segmentation simulation</I
> that automate most of this
task, and make writing general libraries feasible.
</P
></DIV
><DIV
CLASS="SECTION"
><H3
CLASS="SECTION"
><A
NAME="AEN644"
>Partition-based memory allocation</A
></H3
><P
> It's not <I
CLASS="EMPHASIS"
>really</I
> necessary that no
procedure overwrite memory used by any other procedure. It's
only required that procedures don't write on the memory that
their <I
CLASS="EMPHASIS"
>callers</I
> use. Suppose that your
program is organized into a bunch of procedures, and each fall
into one of three sets:
</P
><P
></P
><UL
><LI
><P
>Procedures in set A don't call anyone.</P
></LI
><LI
><P
>Procedures in set B only call procedures in set A.</P
></LI
><LI
><P
>Procedures in set C only call procedures in sets A or B.</P
></LI
></UL
><P
> Now, each <I
CLASS="EMPHASIS"
>set</I
> can be given its own chunk
of memory, and we can be absolutely sure that no procedures
overwrite each other. Even if every procedure in set C uses
the <I
CLASS="EMPHASIS"
>same</I
> memory location, they'll never
step on each other, because there's no way to get to any other
routine in set C <I
CLASS="EMPHASIS"
>from</I
> any routine in set
C.
</P
><P
> This has the same time efficiencies as procedure-based memory
allocation, and, given a thoughtful design aimed at using this
technique, also can use significantly less memory at run time.
It's also requires much less assembler support, as addresses
for variables may be assigned by hand without having to worry
about those addresses already being used. However, it does
impose a very tight discipline on the design of the overall
system, so you'll have to do a lot more work before you start
actually writing code.
</P
></DIV
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN661"
>Constants</A
></H2
><P
> Constants are <SPAN
CLASS="QUOTE"
>"variables"</SPAN
> that don't change. If
you know that the value you're using is not going to change, you
should fold it into the code, either as an Immediate operand
wherever it's used, or (if it's more complicated than that)
as <TT
CLASS="LITERAL"
>.byte</TT
> commands in between the procedures.
This is especially important for ROM-based systems such as the
NES; the NES has very little RAM available, so constants should
be kept in the more plentiful ROM wherever possible.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x603.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x666.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Procedures and register saving</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Data structures</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

449
book/x666.html Normal file
View File

@ -0,0 +1,449 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Data structures</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Structured Programming"
HREF="c543.html"><LINK
REL="PREVIOUS"
TITLE="Variables"
HREF="x621.html"><LINK
REL="NEXT"
TITLE="A modest example: Insertion sort on linked lists"
HREF="x719.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x621.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Structured Programming</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x719.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN666"
>Data structures</A
></H1
><P
> So far, we've been treating data as a bunch of one-byte values.
There really isn't a lot you can do just with bytes. This section
talks about how to deal with larger and smaller elements.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN669"
>Arrays</A
></H2
><P
> An <I
CLASS="EMPHASIS"
>array</I
> is a bunch of data elements in a
row. An array of bytes is very easy to handle with the 6502
chip, because the various indexed addressing modes handle it for
you. Just load the index into the X or Y register and do an
absolute indexed load. In general, these are going to be
zero-indexed (that is, a 32-byte array is indexed from 0 to 31.)
This code would initialize a byte array with 32 entries to
0:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> lda #$00
tax
loop:
sta array,x
inx
cpx #$20
bne loop</PRE
></TD
></TR
></TABLE
><P
> (If you count down to save instructions, remember to adjust the
base address so that it's still writing the same memory
location.)
</P
><P
> This approach to arrays has some limits. Primary among them is
that we can't have arrays of size larger than 256; we can't fit
our index into the index register. In order to address larger
arrays, we need to use the indirect indexed addressing mode. We
use 16-bit addition to add the offset to the base pointer, then
set the Y register to 0 and then load the value
with <TT
CLASS="LITERAL"
>lda (ptr),y</TT
>.
</P
><P
> Well, actually, we can do better than that. Suppose we want to
clear out 8K of ram, from $2000 to $4000. We can use the Y
register to hold the low byte of our offset, and only update the
high bit when necessary. That produces the following
loop:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> lda #$00 ; Set pointer value to base ($2000)
sta ptr
lda #$20
sta ptr+1
lda #$00 ; Storing a zero
ldx #$20 ; 8,192 ($2000) iterations: high byte
ldy #$00 ; low byte.
loop:
sta (ptr),y
iny
bne loop ; If we haven't wrapped around, go back
inc ptr+1 ; Otherwise update high byte
dex ; bump counter
bne loop ; and continue if we aren't done</PRE
></TD
></TR
></TABLE
><P
> This code could be optimized further; the loop prelude in
particular loads a lot of redundant values that could be
compressed down further:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> lda #$00
tay
ldx #$20
sta ptr
stx ptr+1</PRE
></TD
></TR
></TABLE
><P
> That's not directly relevant to arrays, but these sorts of
things are good things to keep in mind when writing your code.
Done well, they can make it much smaller and faster; done
carelessly, they can force a lot of bizarre dependencies on your
code and make it impossible to modify later.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN682"
>Records</A
></H2
><P
> A <I
CLASS="EMPHASIS"
>record</I
> is a collection of values all
referred to as one variable. This has no immediate
representation in assembler. If you have a global variable
that's two bytes and a code pointer, this is exactly equivalent
to three seperate variables. You can just put one label in
front of it, and refer to the first byte
as <TT
CLASS="LITERAL"
>label</TT
>, the second
as <TT
CLASS="LITERAL"
>label+1</TT
>, and the code pointer
a <TT
CLASS="LITERAL"
>label+2</TT
>.
</P
><P
> This really applies to all data structures that take up more
than one byte. When dealing with the pointer, a 16-bit value,
we refer to the low byte as <TT
CLASS="LITERAL"
>ptr</TT
>
(or <TT
CLASS="LITERAL"
>label+2</TT
>, in the example above), and the
high byte as <TT
CLASS="LITERAL"
>ptr+1</TT
>
(or <TT
CLASS="LITERAL"
>label+3</TT
>).
</P
><P
> Arrays of records are more interesting. There are two
possibilities for these. The way most high level languages
treat it is by keeping the records contiguous. If you have an
array of two sixteen bit integers, then the records are stored
in order, one at a time. The first is in location $1000, the
next in $1004, the next in $1008, and so on. You can do this
with the 6502, but you'll probably have to use the indirect
indexed mode if you want to be able to iterate
conveniently.
</P
><P
> Another, more unusual, but more efficient approach is to keep
each byte as a seperate array, just like in the arrays example
above. To illustrate, here's a little bit of code to go through
a contiguous array of 16 bit integers, adding their values to
some <TT
CLASS="LITERAL"
>total</TT
> variable:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #$10 ; Number of elements in the array
ldy #$00 ; Byte index from array start
loop:
clc
lda array, y ; Low byte
adc total
sta total
lda array+1, y ; High byte
adc total+1
sta total+1
iny ; Jump ahead to next entry
iny
dex ; Check for loop termination
bne loop</PRE
></TD
></TR
></TABLE
><P
> And here's the same loop, keeping the high and low bytes in
seperate arrays:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> ldx #$00
loop:
clc
lda lowbyte,x
adc total
sta total
lda highbyte,x
adc total+1
sta total+1
inx
cpx #$10
bne loop</PRE
></TD
></TR
></TABLE
><P
> Which approach is the right one depends on what you're doing.
For large arrays, the first approach is better, as you only need
to maintain one base pointer. For smaller arrays, the easier
indexing makes the second approach more convenient.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN701"
>Bitfields</A
></H2
><P
> To store values that are smaller than a byte, you can save space
by putting multiple values in a byte. To extract a sub-byte
value, use the bitmasking commands:
</P
><P
></P
><UL
><LI
><P
>To set bits, use the <TT
CLASS="LITERAL"
>ORA</TT
> command. <TT
CLASS="LITERAL"
>ORA #$0F</TT
> sets the lower four bits to 1 and leaves the rest unchanged.</P
></LI
><LI
><P
>To clear bits, use the <TT
CLASS="LITERAL"
>AND</TT
> command. <TT
CLASS="LITERAL"
>AND #$F0</TT
> sets the lower four bits to 0 and leaves the rest unchanged.</P
></LI
><LI
><P
>To reverse bits, use the <TT
CLASS="LITERAL"
>EOR</TT
> command. <TT
CLASS="LITERAL"
>EOR #$0F</TT
> reverses the lower four bits and leaves the rest unchanged.</P
></LI
><LI
><P
>To test if a bit is 0, AND away everything but that bit, then see if the Zero bit was set. If the bit is in the top two bits of a memory location, you can use the BIT command instead (which stores bit 7 in the Negative bit, and bit 6 in the Overflow bit).</P
></LI
></UL
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x621.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x719.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Variables</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>A modest example: Insertion sort on linked lists</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

431
book/x71.html Normal file
View File

@ -0,0 +1,431 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Producing Commodore 64 programs</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="The basics"
HREF="c55.html"><LINK
REL="PREVIOUS"
TITLE="The basics"
HREF="c55.html"><LINK
REL="NEXT"
TITLE="Related commands and options"
HREF="x140.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c55.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>The basics</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x140.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN71"
>Producing Commodore 64 programs</A
></H1
><P
> Commodore 64 programs are stored in
the <TT
CLASS="FILENAME"
>PRG</TT
> format on disk. Some emulators
(such as CCS64 or VICE) can run <TT
CLASS="FILENAME"
>PRG</TT
>
programs directly; others need them to be transferred to
a <TT
CLASS="FILENAME"
>D64</TT
> image first.
</P
><P
> The <TT
CLASS="FILENAME"
>PRG</TT
> format is ludicrously simple. It
has two bytes of header data: This is a little-endian number
indicating the starting address. The rest of the file is a
single continuous chunk of data loaded into memory, starting at
that address. BASIC memory starts at memory location 2048, and
that's probably where we'll want to start.
</P
><P
> Well, not quite. We want our program to be callable from BASIC,
so we should have a BASIC program at the start. We guess the
size of a simple one line BASIC program to be about 16 bytes.
Thus, we start our program at memory location 2064 ($0810), and
the BASIC program looks like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>10 SYS 2064
</PRE
></TD
></TR
></TABLE
><P
> We <KBD
CLASS="USERINPUT"
>SAVE</KBD
> this program to a file, then
study it in a debugger. It's 15 bytes long:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="SCREEN"
>1070:0100 01 08 0C 08 0A 00 9E 20-32 30 36 34 00 00 00
</PRE
></TD
></TR
></TABLE
><P
> The first two bytes are the memory location: $0801. The rest of
the data breaks down as follows:
</P
><DIV
CLASS="TABLE"
><A
NAME="AEN85"
></A
><P
><B
>Table 1. BASIC program breakdown</B
></P
><TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
CELLSPACING="0"
CELLPADDING="4"
CLASS="CALSTABLE"
><THEAD
><TR
><TH
ALIGN="CENTER"
>Memory Locations</TH
><TH
ALIGN="CENTER"
>Value</TH
></TR
></THEAD
><TBODY
><TR
><TD
>$0801-$0802</TD
><TD
>2-byte pointer to the next line of BASIC code ($080C).</TD
></TR
><TR
><TD
>$0803-$0804</TD
><TD
>2-byte line number ($000A = 10).</TD
></TR
><TR
><TD
>$0805</TD
><TD
>Byte code for the <KBD
CLASS="USERINPUT"
>SYS</KBD
> command.</TD
></TR
><TR
><TD
>$0806-$080A</TD
><TD
>The rest of the line, which is just the string <SPAN
CLASS="QUOTE"
>" 2064"</SPAN
>.</TD
></TR
><TR
><TD
>$080B</TD
><TD
>Null byte, terminating the line.</TD
></TR
><TR
><TD
>$080C-$080D</TD
><TD
>2-byte pointer to the next line of BASIC code ($0000 = end of program).</TD
></TR
></TBODY
></TABLE
></DIV
><P
> That's 13 bytes. We started at 2049, so we need 2 more bytes of
filler to make our code actually start at location 2064. These
17 bytes will give us the file format and the BASIC code we need
to have our machine language program run.
</P
><P
> These are just bytes&#8212;indistinguishable from any other sort of
data. In Ophis, bytes of data are specified with
the <TT
CLASS="LITERAL"
>.byte</TT
> command. We'll also have to tell
Ophis what the program counter should be, so that it knows what
values to assign to our labels. The <TT
CLASS="LITERAL"
>.org</TT
>
(origin) command tells Ophis this. Thus, the Ophis code for our
header and linking info is:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.byte $01, $08, $0C, $08, $0A, $00, $9E, $20
.byte $32, $30, $36, $34, $00, $00, $00, $00
.byte $00, $00
.org $0810
</PRE
></TD
></TR
></TABLE
><P
> This gets the job done, but it's completely incomprehensible,
and it only uses two directives&#8212;not very good for a
tutorial. Here's a more complicated, but much clearer, way of
saying the same thing.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.word $0801
.org $0801
.word next, 10 ; Next line and current line number
.byte $9e," 2064",0 ; SYS 2064
next: .word 0 ; End of program
.advance 2064
</PRE
></TD
></TR
></TABLE
><P
> This code has many advantages over the first.
<P
></P
><UL
><LI
><P
> It describes better what is actually
happening. The <TT
CLASS="LITERAL"
>.word</TT
> directive at the
beginning indicates a 16-bit value stored in the typical
65xx way (small byte first). This is followed by
an <TT
CLASS="LITERAL"
>.org</TT
> statement, so we let the
assembler know right away where everything is supposed to
be.
</P
></LI
><LI
><P
> Instead of hardcoding in the value $080C, we instead use a
label to identify the location it's pointing to. Ophis
will compute the address of <TT
CLASS="LITERAL"
>next</TT
> and
put that value in as data. We also describe the line
number in decimal since BASIC line numbers
generally <I
CLASS="EMPHASIS"
>are</I
> in decimal. Labels are
defined by putting their name, then a colon, as seen in
the definition of <TT
CLASS="LITERAL"
>next</TT
>.
</P
></LI
><LI
><P
> Instead of putting in the hex codes for the string part of
the BASIC code, we included the string directly. Each
character in the string becomes one byte.
</P
></LI
><LI
><P
> Instead of adding the buffer ourselves, we
used <TT
CLASS="LITERAL"
>.advance</TT
>, which outputs zeros until
the specified address is reached. Attempting
to <TT
CLASS="LITERAL"
>.advance</TT
> backwards produces an
assemble-time error. (If we wanted to output something
besides zeros, we could add it as a second
argument: <TT
CLASS="LITERAL"
>.advance 2064,$FF</TT
>, for
instance.)
</P
></LI
><LI
><P
> It has comments that explain what the data are for. The
semicolon is the comment marker; everything from a semicolon
to the end of the line is ignored.
</P
></LI
></UL
>
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c55.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x140.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>The basics</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c55.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Related commands and options</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

444
book/x719.html Normal file
View File

@ -0,0 +1,444 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>A modest example: Insertion sort on linked lists</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Structured Programming"
HREF="c543.html"><LINK
REL="PREVIOUS"
TITLE="Data structures"
HREF="x666.html"><LINK
REL="NEXT"
TITLE="Pointers and Indirection"
HREF="c748.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x666.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Structured Programming</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c748.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN719"
>A modest example: Insertion sort on linked lists</A
></H1
><P
> To demonstrate these techniques, we will now produce code to
perform insertion sort on a linked list. We'll start by defining
our data structure, then defining the routines we want to write,
then producing actual code for those routines. A downloadable
version that will run unmodified on a Commodore 64 closes the
chapter.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN722"
>The data structure</A
></H2
><P
> We don't really want to have to deal with pointers if we can
possibly avoid it, but it's hard to do a linked list without
them. Instead of pointers, we will
use <I
CLASS="EMPHASIS"
>cursors</I
>: small integers that represent
the index into the array of values. This lets us use the
many-small-byte-arrays technique for our data. Furthermore, our
random data that we're sorting never has to move, so we may
declare it as a constant and only bother with changing the
values of <TT
CLASS="LITERAL"
>head</TT
> and
the <TT
CLASS="LITERAL"
>next</TT
> arrays. The data record definition
looks like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> head : byte;
data : const int[16] = [838, 618, 205, 984, 724, 301, 249, 946,
925, 43, 114, 697, 985, 633, 312, 86];
next : byte[16];</PRE
></TD
></TR
></TABLE
><P
> Exactly how this gets represented will vary from assembler to
assembler. Ophis does it like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.data
.space head 1
.space next 16
.text
lb: .byte &#60;$838,&#60;$618,&#60;$205,&#60;$984,&#60;$724,&#60;$301,&#60;$249,&#60;$946
.byte &#60;$925,&#60;$043,&#60;$114,&#60;$697,&#60;$985,&#60;$633,&#60;$312,&#60;$086
hb: .byte &#62;$838,&#62;$618,&#62;$205,&#62;$984,&#62;$724,&#62;$301,&#62;$249,&#62;$946
.byte &#62;$925,&#62;$043,&#62;$114,&#62;$697,&#62;$985,&#62;$633,&#62;$312,&#62;$086</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN731"
>Doing an insertion sort</A
></H2
><P
> To do an insertion sort, we clear the list by setting the 'head'
value to -1, and then insert each element into the list one at a
time, placing each element in its proper order in the list. We
can consider the lb/hb structure alone as an array of 16
integers, and just insert each one into the list one at a
time.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>procedure insertion_sort
head := -1;
for i := 0 to 15 do
insert_elt i
end
end</PRE
></TD
></TR
></TABLE
><P
> This translates pretty directly. We'll have insert_elt take its
argument in the X register, and loop with that. However, given
that insert_elt is going to be a complex procedure, we'll save
the value first. The assembler code becomes:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; insertion'sort: Sorts the list defined by head, next, hb, lb.
; Arguments: None.
; Modifies: All registers destroyed, head and next array sorted.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
insertion'sort:
lda #$FF ; Clear list by storing the terminator in 'head'
sta head
ldx #$0 ; Loop through the lb/hb array, adding each
insertion'sort'loop: ; element one at a time
txa
pha
jsr insert_elt
pla
tax
inx
cpx #$10
bne insertion'sort'loop
rts</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN737"
>Inserting an element</A
></H2
><P
> The pseudocode for inserting an element is a bit more
complicated. If the list is empty, or the value we're inserting
goes at the front, then we have to update the value
of <TT
CLASS="LITERAL"
>head</TT
>. Otherwise, we can iterate through
the list until we find the element that our value fits in after
(so, the first element whose successor is larger than our
value). Then we update the next pointers directly and exit.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>procedure insert_elt i
begin
if head = -1 then begin
head := i;
next[i] := -1;
return;
end;
val := data[i];
if val &#60; data[i] then begin
next[i] := head;
head := i;
return;
end;
current := head;
while (next[current] &#60;&#62; -1 and val &#60; data[next[current]]) do
current := next[current];
end;
next[i] := next[current];
next[current] := i;
end;</PRE
></TD
></TR
></TABLE
><P
> This produces the following rather hefty chunk of code:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; insert_elt: Insert an element into the linked list. Maintains the
; list in sorted, ascending order. Used by
; insertion'sort.
; Arguments: X register holds the index of the element to add.
; Modifies: All registers destroyed; head and next arrays updated
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data
.space lbtoinsert 1
.space hbtoinsert 1
.space indextoinsert 1
.text
insert_elt:
ldy head ; If the list is empty, make
cpy #$FF ; head point at it, and return.
bne insert_elt'list'not'empty
stx head
tya
sta next,x
rts
insert_elt'list'not'empty:
lda lb,x ; Cache the data we're inserting
sta lbtoinsert
lda hb,x
sta hbtoinsert
stx indextoinsert
ldy head ; Compare the first value with
sec ; the data. If the data must
lda lb,y ; be inserted at the front...
sbc lbtoinsert
lda hb,y
sbc hbtoinsert
bmi insert_elt'not'smallest
tya ; Set its next pointer to the
sta next,x ; old head, update the head
stx head ; pointer, and return.
rts
insert_elt'not'smallest:
ldx head
insert_elt'loop: ; At this point, we know that
lda next,x ; argument &#62; data[X].
tay
cpy #$FF ; if next[X] = #$FF, insert arg at end.
beq insert_elt'insert'after'current
lda lb,y ; Otherwise, compare arg to
sec ; data[next[X]]. If we insert
sbc lbtoinsert ; before that...
lda hb,y
sbc hbtoinsert
bmi insert_elt'goto'next
insert_elt'insert'after'current: ; Fix up all the next links
tya
ldy indextoinsert
sta next,y
tya
sta next,x
rts ; and return.
insert_elt'goto'next: ; Otherwise, let X = next[X]
tya ; and go looping again.
tax
jmp insert_elt'loop</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN744"
>The complete application</A
></H2
><P
> The full application, which deals with interfacing with CBM
BASIC and handles console I/O and such, is
in <A
HREF="x1026.html"
><I
><I
>structuredemo.oph</I
></I
></A
>.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x666.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c748.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Data structures</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c543.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Pointers and Indirection</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

253
book/x782.html Normal file
View File

@ -0,0 +1,253 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Pointer arithmetic</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Pointers and Indirection"
HREF="c748.html"><LINK
REL="PREVIOUS"
TITLE="Pointers and Indirection"
HREF="c748.html"><LINK
REL="NEXT"
TITLE="What about Indexed Indirect?"
HREF="x798.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c748.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Pointers and Indirection</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x798.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN782"
>Pointer arithmetic</A
></H1
><P
> Pointer arithmetic is an obscenely powerful and dangerous
technique. However, it's the most straightforward way to deal
with enormous arrays, structs, indexable stacks, and nearly
everything you do in C. (C has no native array or string types
primarily because it allows arbitrary pointer arithmetic, which is
strong enough to handle all of those without complaint and at
blazing speed. It also allows for all kinds of buffer overrun
security holes, but let's face it, who's going to be cracking root
on your Apple II?) There are a number of ways to implement this
on the 6502. We'll deal with them in increasing order of design
complexity.
</P
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN785"
>The straightforward, slow way</A
></H2
><P
> When computing a pointer value, you simply treat the pointer as
if it were a 16-bit integer. Do all the math you need, then
when the time comes to dereference it, simply do a direct
dereference as above. This is definitely doable, and it's not
difficult. However, it is costly in both space and time.
</P
><P
> When dealing with arbitrary indices large enough that they won't
fit in the Y register, or when creating values that you don't
intend to dereference (such as subtracting two pointers to find
the length of a string), this is also the only truly usable
technique.
</P
></DIV
><DIV
CLASS="SECTION"
><H2
CLASS="SECTION"
><A
NAME="AEN789"
>The clever fast way</A
></H2
><P
> But wait, you say. Often when we compute a value, at least one
of the operations is going to be an addition, and we're almost
certain to have that value be less than 256! Surely we may save
ourselves an operation by loading that value into the Y register
and having the load operation itself perform the final
addition!
</P
><P
> Very good. This is the fastest technique, and sometimes it's
even the most readable. These cases usually involve repeated
reading of various fields from a structure or record. The base
pointer always points to the base of the structure (or the top
of the local variable list, or what have you) and the Y register
takes values that index into that structure. This lets you keep
the pointer variable in memory largely static and requires no
explicit arithmetic instructions at all.
</P
><P
> However, this technique is highly opaque and should always be
well documented, indicating exactly what you think you're
pointing at. Then, when you get garbage results, you can
compare your comments and the resulting Y values with the actual
definition of the structure to see who's screwing up.
</P
><P
> For a case where we still need to do arithmetic, consider the
classic case of needing to clear out a large chunk of memory.
The following code fills the 4KB of memory between $C000 and
$D000 with zeroes:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> lda #$C0 ; Store #$C000 in mem (low byte first)
sta mem+1
lda #$00
sta mem
ldx #$04 ; x holds number of times to execute outer loop
tay ; accumulator and y are both 0
loop: sta (mem), y
iny
bne loop ; Inner loop ends when y wraps around to 0
inc mem+1 ; "Carry" from the iny to the core pointer
dex ; Decrement outer loop count, quit if done
bne loop</PRE
></TD
></TR
></TABLE
><P
> Used carefully, proper use of the Y register can make your code
smaller, faster, <I
CLASS="EMPHASIS"
>and</I
> more readable. Used
carelessly it can make your code an unreadable, unmaintainable
mess. Use it wisely, and with care, and it will be your
greatest ally in writing flexible code.
</P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c748.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x798.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Pointers and Indirection</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c748.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>What about Indexed Indirect?</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

196
book/x798.html Normal file
View File

@ -0,0 +1,196 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>What about Indexed Indirect?</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Pointers and Indirection"
HREF="c748.html"><LINK
REL="PREVIOUS"
TITLE="Pointer arithmetic"
HREF="x782.html"><LINK
REL="NEXT"
TITLE="Comparison with the other indexed forms"
HREF="x805.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x782.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Pointers and Indirection</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x805.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN798"
>What about Indexed Indirect?</A
></H1
><P
> This essay has concerned itself almost exclusively with the
Indirect Indexed&#8212;or (Indirect), Y&#8212;mode. What about Indexed
Indirect&#8212;(Indirect, X)? This is a <I
CLASS="EMPHASIS"
>much</I
>
less useful mode than the Y register's version. While the Y
register indirection lets you implement pointers and arrays in
full generality, the X register is useful for pretty much only one
application: lookup tables for single byte values.
</P
><P
> Even coming up with a motivating example for this is difficult,
but here goes. Suppose you have multiple, widely disparate
sections of memory that you're watching for signals. The
following routine takes a resource index in the accumulator and
returns the status byte for the corresponding resource.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>; This data is sitting on the zero page somewhere
resource_status_table: .word resource0_status, resource1_status,
.word resource2_status, resource3_status,
; etc. etc. etc.
; This is the actual program code
.text
getstatus:
clc ; Multiply argument by 2 before putting it in X, so that it
asl ; produces a value that's properly word-indexed
tax
lda (resource_status_table, x)
rts</PRE
></TD
></TR
></TABLE
><P
> Why having a routine such as this is better than just having the
calling routine access resourceN_status itself as an absolute
memory load is left as an exercise for the reader. That aside,
this code fragment does serve as a reminder that when indexing an
array of anything other than bytes, you must multiply your index
by the size of the objects you want to index. C does this
automatically&#8212;assembler does not. Stay sharp.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x782.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x805.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Pointer arithmetic</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c748.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Comparison with the other indexed forms</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

193
book/x805.html Normal file
View File

@ -0,0 +1,193 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Comparison with the other indexed forms</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Pointers and Indirection"
HREF="c748.html"><LINK
REL="PREVIOUS"
TITLE="What about Indexed Indirect?"
HREF="x798.html"><LINK
REL="NEXT"
TITLE="Conclusion"
HREF="x813.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x798.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Pointers and Indirection</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x813.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN805"
>Comparison with the other indexed forms</A
></H1
><P
> Pointers are slow. It sounds odd saying this, when C is the
fastest language around on modern machines precisely because of
its powerful and extensive use of pointers. However, modern
architectures are designed to be optimized for C-style code (as an
example, the x86 architecture allows statements like <TT
CLASS="LITERAL"
>mov
eax, [bs+bx+4*di]</TT
> as a single instruction), while the
6502 is not. An (Indirect, Y) operation can take up to 6 cycles
to complete just on its own, while the preparation of that command
costs additional time <I
CLASS="EMPHASIS"
>and</I
> scribbles over a
bunch of registers, meaning memory operations to save the values
and yet more time spent. The simple code given at the beginning
of this essay&#8212;loading <TT
CLASS="LITERAL"
>*b</TT
> into the
accumulator&#8212;takes 7 cycles, not counting the 6 it takes to
load b with the appropriate value to begin with. If b is known to
contain a specific value, we can write a single Absolute mode
instruction to load its value, which takes only 4 cycles and also
preserves the value in the Y register. Clearly, Absolute mode
should be used whenever possible.
</P
><P
> One might be tempted to use self-modifying code to solve this
problem. This actually doesn't pay off near enough for the hassle
it generates; for self-modifying code, the address must be
generated, then stored in the instruction, and then the data must
be loaded. Cost: 16 cycles for 2 immediate loads, 2 absolute
stores, and 1 absolute load. For the straight pointer
dereference, we generate the address, store it in the pointer,
clear the index, then dereference that. Cost: 17 cycles for 3
immediate loads, 2 zero page stores, and 1 indexed indirect load.
Furthermore, unlike in the self-modifying case, loops where simple
arithmetic is being continuously performed only require repeating
the final load instruction, which allows for much greater time
savings over an equivalent self-modifying loop.
</P
><P
> (This point is also completely moot for NES programmers or anyone
else whose programs are sitting in ROM, because programs stored on
a ROM cannot modify themselves.)
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x798.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x813.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>What about Indexed Indirect?</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c748.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Conclusion</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

154
book/x813.html Normal file
View File

@ -0,0 +1,154 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Conclusion</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Pointers and Indirection"
HREF="c748.html"><LINK
REL="PREVIOUS"
TITLE="Comparison with the other indexed forms"
HREF="x805.html"><LINK
REL="NEXT"
TITLE="Functionals"
HREF="c816.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x805.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Pointers and Indirection</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c816.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN813"
>Conclusion</A
></H1
><P
> That's pretty much it for pointers. Though they tend to make
programs hairy, and learning how to properly deal with pointers is
what separates real C programmers from the novices, the basic
mechanics of them are not complex. With pointers you can do
efficient passing of large structures, pass-by-reference,
complicated return values, and dynamic memory management&#8212;and
now these wondrous toys may be added to your assembler programs,
too (assuming you have that kind of space to play with).
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x805.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c816.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Comparison with the other indexed forms</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c748.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Functionals</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

215
book/x836.html Normal file
View File

@ -0,0 +1,215 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>A quick digression on how subroutines work</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Functionals"
HREF="c816.html"><LINK
REL="PREVIOUS"
TITLE="Functionals"
HREF="c816.html"><LINK
REL="NEXT"
TITLE="Dispatch-on-type and Data-Directed Assembler"
HREF="x855.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c816.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Functionals</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x855.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN836"
>A quick digression on how subroutines work</A
></H1
><P
> Ordinarily, subroutines are called with <TT
CLASS="LITERAL"
>JSR</TT
> and
finished with <TT
CLASS="LITERAL"
>RTS</TT
>. The <TT
CLASS="LITERAL"
>JSR</TT
>
instruction takes its own address, adds 2 to it, and pushes this
16-bit value on the stack, high byte first, then low byte (so that
the low byte will be popped off first).
</P
><P
> But wait, you may object. All <TT
CLASS="LITERAL"
>JSR</TT
> instructions
are three bytes long. This <SPAN
CLASS="QUOTE"
>"return address"</SPAN
> is in
the middle of the instruction. And you would be quite right;
the <TT
CLASS="LITERAL"
>RTS</TT
> instruction pops off the 16-bit
address, adds one to it, and <I
CLASS="EMPHASIS"
>then</I
> sets the
program counter to that value.
</P
><P
> So it <I
CLASS="EMPHASIS"
>is</I
> possible to set up
a <SPAN
CLASS="QUOTE"
>"<TT
CLASS="LITERAL"
>JSR</TT
> indirect"</SPAN
> kind of operation
by adding two to the indirect jump's address and then pushing that
value onto the stack before making the jump; however, you wouldn't
want to do this. It takes six bytes and trashes your accumulator,
and you can get the same functionality with half the space and
with no register corruption by simply defining the indirect jump
to be a one-instruction routine and <TT
CLASS="LITERAL"
>JSR</TT
>-ing to
it directly. As an added bonus, that way if you have multiple
indirect jumps through the same pointer, you don't need to
duplicate the jump instruction.
</P
><P
> Does this mean that abusing <TT
CLASS="LITERAL"
>JSR</TT
>
and <TT
CLASS="LITERAL"
>RTS</TT
> is a dead-end, though? Not at all...
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c816.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x855.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Functionals</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c816.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Dispatch-on-type and Data-Directed Assembler</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

249
book/x855.html Normal file
View File

@ -0,0 +1,249 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Dispatch-on-type and Data-Directed Assembler</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Functionals"
HREF="c816.html"><LINK
REL="PREVIOUS"
TITLE="A quick digression on how subroutines work"
HREF="x836.html"><LINK
REL="NEXT"
TITLE="VTables and Object-Oriented Assembler"
HREF="x871.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x836.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Functionals</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x871.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN855"
>Dispatch-on-type and Data-Directed Assembler</A
></H1
><P
> Most of the time, you care about function pointers because you've
arranged them in some kind of table. You hand it an index
representing the type of your argument, or which method it is
you're calling, or some other determinator, and then you index
into an array of routines and execute the right one.
</P
><P
> Writing a generic routine to do this is kind of a pain. First you
have to pass a 16-bit pointer in, then you have to dereference it
to figure out where your table is, then you have to do an indexed
dereference on <I
CLASS="EMPHASIS"
>that</I
> to get the routine you
want to run, then you need to copy it out to somewhere fixed so
that you can write your jump instruction. And making this
non-generic doesn't help a whole lot, since that only saves you
the first two steps, but now you have to write them out in every
single indexed jump instruction. If only there were some way to
easily and quickly pass in a local pointer directly...
</P
><P
> Something, say, like the <TT
CLASS="LITERAL"
>JSR</TT
> instruction, only not for
program code.
</P
><P
> Or we could just use the <TT
CLASS="LITERAL"
>JSR</TT
> statement itself,
but only call this routine at the ends of other routines, much
like we were organizing for indirect jumps to begin with. This
lets us set up routines that look like this:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>jump'table'alpha:
jsr do'jump'table
.word alpha'0, alpha'1, alpha'2</PRE
></TD
></TR
></TABLE
><P
> Where the <TT
CLASS="LITERAL"
>alpha'x</TT
> routines are the ones to be
called when the index has that value. This leaves the
implementation of do'jump'table, which in this case uses the Y
register to hold the index:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>do'jump'table:
sta _scratch
pla
sta _jmpptr
pla
sta _jmpptr+1
tya
asl
tay
iny
lda (_jmpptr), y
sta _target
iny
lda (_jmpptr), y
sta _target+1
lda _scratch
jmp (_target)</PRE
></TD
></TR
></TABLE
><P
> The <TT
CLASS="LITERAL"
>TYA:ASL:TAY:INY</TT
> sequence can actually be
omitted if you don't mind having your Y indices be 1, 3, 5, 7, 9,
etc., instead of 0, 1, 2, 3, 4, etc. Likewise, the instructions
dealing with <TT
CLASS="LITERAL"
>_scratch</TT
> can be omitted if you
don't mind trashing the accumulator. Keeping the accumulator and
X register pristine for the target call comes in handy, though,
because it means we can pass in a pointer argument purely in
registers. This will come in handy soon...
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x836.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x871.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>A quick digression on how subroutines work</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c816.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>VTables and Object-Oriented Assembler</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

258
book/x871.html Normal file
View File

@ -0,0 +1,258 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>VTables and Object-Oriented Assembler</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Functionals"
HREF="c816.html"><LINK
REL="PREVIOUS"
TITLE="Dispatch-on-type and Data-Directed Assembler"
HREF="x855.html"><LINK
REL="NEXT"
TITLE="A final reminder"
HREF="x892.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x855.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Functionals</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x892.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN871"
>VTables and Object-Oriented Assembler</A
></H1
><P
> The usual technique for getting something that looks
object-oriented in non-object-oriented languages is to fill a
structure with function pointers, and have those functions take
the structure itself as an argument. This works just fine in
assembler, of course (and doesn't really require anything more
than your traditional jump-indirects), but it's also possible to
use a lot of the standard optimizations that languages such as C++
provide.
</P
><P
> The most important of these is the <I
CLASS="EMPHASIS"
>vtable</I
>.
Each object type has its own vtable, and it's a list of function
pointers for all the methods that type provides. This is a space
savings over the traditional structs-with-function-pointers
approach because when you have many objects of the same class, you
only have to represent the vtable once. So that all objects may
be treated identically, the vtable location is traditionally fixed
as being the first entry in the corresponding structure.
</P
><P
> Virtual method invocation takes an object pointer (traditionally
called <TT
CLASS="LITERAL"
>self</TT
> or <TT
CLASS="LITERAL"
>this</TT
>) and a
method index and invokes the approprate method on that object.
Gee, where have we seen that before?
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>sprite'vtable:
jsr do'jump'table
.word sprite'init, sprite'update, sprite'render</PRE
></TD
></TR
></TABLE
><P
> We mentioned before that vtables are generally the first entries
in objects. We can play another nasty trick here, paying an
additional byte per object to have the vtable be not merely a
pointer to its vtable routine, but an actual jump instruction to
it. (That is, if an object is at location X, then location X is
the byte value <TT
CLASS="LITERAL"
>$4C</TT
>,
representing <TT
CLASS="LITERAL"
>JMP</TT
>, location X+1 is the low byte
of the vtable, and location X+2 is the high byte of the vtable.)
Given that, our <TT
CLASS="LITERAL"
>invokevirtual</TT
> function becomes
very simple indeed:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>invokevirtual:
sta this
stx this+1
jmp (this)</PRE
></TD
></TR
></TABLE
><P
> Which, combined with all our previous work here, takes
the <TT
CLASS="LITERAL"
>this</TT
> pointer in <TT
CLASS="LITERAL"
>.AX</TT
> and
a method identifier in <TT
CLASS="LITERAL"
>.Y</TT
> and invokes that
method on that object. Arguments besides <TT
CLASS="LITERAL"
>this</TT
>
need to be set up before the call
to <TT
CLASS="LITERAL"
>invokevirtual</TT
>, probably in some global
argument array somewhere as discussed back in <A
HREF="c543.html"
>the Chapter called <I
>Structured Programming</I
></A
>.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x855.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x892.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Dispatch-on-type and Data-Directed Assembler</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c816.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>A final reminder</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

178
book/x892.html Normal file
View File

@ -0,0 +1,178 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>A final reminder</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Functionals"
HREF="c816.html"><LINK
REL="PREVIOUS"
TITLE="VTables and Object-Oriented Assembler"
HREF="x871.html"><LINK
REL="NEXT"
TITLE="Call Stacks"
HREF="c900.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x871.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Functionals</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c900.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN892"
>A final reminder</A
></H1
><P
> We've been talking about all these routines as if they could be
copy-pasted or hand-compiled from C++ or Java code. This isn't
really the case, primarily because <SPAN
CLASS="QUOTE"
>"local variables"</SPAN
>
in your average assembler routines aren't really local, so
multiple calls to the same method will tend to trash the program
state. And since a lot of the machinery described here shares a
lot of memory (in particular, every single method invocation
everywhere shares a <TT
CLASS="LITERAL"
>this</TT
>), attempting to shift
over standard OO code into this format is likely to fail
miserably.
</P
><P
> You can get an awful lot of flexibility out of even just one layer
of method-calls, though, given a thoughtful
design. The <TT
CLASS="LITERAL"
>do'jump'table</TT
> routine, or one very
like it, was extremely common in NES games in the mid-1980s and
later, usually as the beginning of the frame-update loop.
</P
><P
> If you find you really need multiple layers of method calls,
though, then you really are going to need a full-on program stack,
and that's going to be several kinds of mess. That's the topic
for the final chapter.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x871.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c900.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>VTables and Object-Oriented Assembler</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c816.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Call Stacks</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

336
book/x915.html Normal file
View File

@ -0,0 +1,336 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Our Goals</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Call Stacks"
HREF="c900.html"><LINK
REL="PREVIOUS"
TITLE="Call Stacks"
HREF="c900.html"><LINK
REL="NEXT"
TITLE="Example: Fibonnacci Numbers"
HREF="x967.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c900.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Call Stacks</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x967.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN915"
>Our Goals</A
></H1
><P
> The system we develop should have all of the following
characteristics.
</P
><P
></P
><UL
><LI
><P
>It should be <I
CLASS="EMPHASIS"
>intuitive to program for</I
>. The procedure bodies should be easily readable and writable by humans, even in assembler form.</P
></LI
><LI
><P
>It should be <I
CLASS="EMPHASIS"
>efficient</I
>. Variable accesses are very common, so procedures shouldn't cost much to run.</P
></LI
><LI
><P
>It should allow <I
CLASS="EMPHASIS"
>multiple arity</I
> in both arguments and return values. We won't require that an unlimited amount of information be passable, but it should allow more than the three bytes the registers give us.</P
></LI
><LI
><P
>It should permit <I
CLASS="EMPHASIS"
>tail call elimination</I
>, an optimization that will allow certain forms of recursion to actually not grow the stack.</P
></LI
></UL
><P
> Here is a system that meets all these properties.
</P
><P
></P
><UL
><LI
><P
>Reserve two bytes of the zero page for a stack pointer. At the beginning of the program, set it to the top of memory.</P
></LI
><LI
><P
>Divide the remainder of Zero Page into two parts:
<P
></P
><UL
><LI
><P
>The <I
CLASS="EMPHASIS"
>scratch space</I
>, which is where arguments and return values go, and which may be scrambled by any function call, and</P
></LI
><LI
><P
>The <I
CLASS="EMPHASIS"
>local area</I
>, which all functions must restore to their initial state once finished.</P
></LI
></UL
>
</P
></LI
><LI
><P
>Assign to each procedure a <I
CLASS="EMPHASIS"
>frame size</I
> S, which is a maximum size on the amount of the local area the procedure can use. The procedure's variables will sit in the first S bytes of the local area.</P
></LI
><LI
><P
>Upon entering the procedure, push the first S bytes of the local area onto the stack; upon exit, pop hose S bytes back on top of the local area.</P
></LI
><LI
><P
>While the procedure is running, only touch the local area and the scratch space.</P
></LI
></UL
><P
>This meets our design criteria neatly:</P
><P
></P
><UL
><LI
><P
>It's as intuitive as such a system will get. You have to call <TT
CLASS="LITERAL"
>init'stack</TT
> at the beginning, and you need to ensure that <TT
CLASS="LITERAL"
>save'stack</TT
> and <TT
CLASS="LITERAL"
>restore'stack</TT
> are called right. The procedure's program text can pretend that it's just referring to its own variables, just like with the old style. If a procedure doesn't call <I
CLASS="EMPHASIS"
>anyone</I
>, then it can just do all its work in the scratch space.</P
></LI
><LI
><P
>It's efficient; the inside of the procedure is likely to be faster and smaller than its FORTRAN-style counterpart, because all variable references are on the Zero Page.</P
></LI
><LI
><P
>Both arguments and return values can be as large as the scratch space. It's not infinite, but it's probably good enough.</P
></LI
><LI
><P
>Tail call elimination is possible; just restore the stack before making the JMP to the tail call target.</P
></LI
></UL
><P
> The necessary support code is pretty straightforward. The stack
modification routines take the size of the frame in the
accumulator, and while saving the local area, it copies over the
corresponding values from the scratch space. (This is because
most functions will be wanting to keep their arguments around
across calls.)
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.scope
; Stack routines
.data zp
.space _sp $02
.space _counter $01
.space fun'args $10
.space fun'vars $40
.text
init'stack:
lda #$00
sta _sp
lda #$A0
sta _sp+1
rts
save'stack:
sta _counter
sec
lda _sp
sbc _counter
sta _sp
lda _sp+1
sbc #$00
sta _sp+1
ldy #$00
* lda fun'vars, y
sta (_sp), y
lda fun'args, y
sta fun'vars, y
iny
dec _counter
bne -
rts
restore'stack:
pha
sta _counter
ldy #$00
* lda (_sp), y
sta fun'vars, y
iny
dec _counter
bne -
pla
clc
adc _sp
sta _sp
lda _sp+1
adc #$00
sta _sp+1
rts
.scend</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c900.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x967.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Call Stacks</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c900.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Example: Fibonnacci Numbers</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

219
book/x967.html Normal file
View File

@ -0,0 +1,219 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Example: Fibonnacci Numbers</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Call Stacks"
HREF="c900.html"><LINK
REL="PREVIOUS"
TITLE="Our Goals"
HREF="x915.html"><LINK
REL="NEXT"
TITLE="Example Programs"
HREF="a975.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x915.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Call Stacks</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="a975.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="AEN967"
>Example: Fibonnacci Numbers</A
></H1
><P
> About the simplest <SPAN
CLASS="QUOTE"
>"interesting"</SPAN
> recursive function
is the Fibonacci numbers. The function fib(x) is defined as being
1 if x is 0 or 1, and being fib(x-2)+fib(x-1) otherwise.
</P
><P
> Actually expressing it like that directly produces a very
inefficient implementation, but it's a simple demonstration of the
system. Here's code for expressing the fib function:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.scope
; Uint16 fib (Uint8 x): compute Xth fibonnaci number.
; fib(0) = fib(1) = 1.
; Stack usage: 3.
fib: lda #$03
jsr save'stack
lda fun'vars
cmp #$02
bcc _base
dec fun'args
jsr fib
lda fun'args
sta fun'vars+1
lda fun'args+1
sta fun'vars+2
lda fun'vars
sec
sbc #$02
sta fun'args
jsr fib
clc
lda fun'args
adc fun'vars+1
sta fun'args
lda fun'args+1
adc fun'vars+2
sta fun'args+1
jmp _done
_base: ldy #$01
sty fun'args
dey
sty fun'args+1
_done: lda #$03
jsr restore'stack
rts
.scend</PRE
></TD
></TR
></TABLE
><P
> The full application, which deals with interfacing with CBM BASIC
and handles console I/O and such, is in <A
HREF="x1030.html"
><I
><I
>fibonacci.oph</I
></I
></A
>.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x915.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Our Goals</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c900.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Example Programs</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

184
book/x982.html Normal file
View File

@ -0,0 +1,184 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello2.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="NEXT"
TITLE="c64-1.oph"
HREF="x986.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="a975.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x986.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR2-SRC"
><TT
CLASS="FILENAME"
>hello2.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.word $0801
.org $0801
.outfile "hello.prg"
.scope
.word _next, 10 ; Next line and current line number
.byte $9e," 2064",0 ; SYS 2064
_next: .word 0 ; End of program
.scend
.advance 2064
.alias chrout $ffd2
ldx #0
* lda hello, x
beq +
jsr chrout
inx
bne -
* rts
hello: .byte "HELLO, WORLD!", 0</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x986.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Example Programs</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>c64-1.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

176
book/x986.html Normal file
View File

@ -0,0 +1,176 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>c64-1.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello2.oph"
HREF="x982.html"><LINK
REL="NEXT"
TITLE="c64kernal.oph"
HREF="x990.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x982.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x990.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="C64-1-SRC"
><TT
CLASS="FILENAME"
>c64-1.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.word $0801
.org $0801
.scope
.word _next, 10 ; Next line and current line number
.byte $9e," 2064",0 ; SYS 2064
_next: .word 0 ; End of program
.scend
.advance 2064
.require "../platform/c64kernal.oph"</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x982.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x990.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello2.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>c64kernal.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

231
book/x990.html Normal file
View File

@ -0,0 +1,231 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>c64kernal.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="c64-1.oph"
HREF="x986.html"><LINK
REL="NEXT"
TITLE="hello3.oph"
HREF="x994.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x986.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x994.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="KERNAL-SRC"
><TT
CLASS="FILENAME"
>c64kernal.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>; KERNAL routine aliases (C64)
.alias acptr $ffa5
.alias chkin $ffc6
.alias chkout $ffc9
.alias chrin $ffcf
.alias chrout $ffd2
.alias ciout $ffa8
.alias cint $ff81
.alias clall $ffe7
.alias close $ffc3
.alias clrchn $ffcc
.alias getin $ffe4
.alias iobase $fff3
.alias ioinit $ff84
.alias listen $ffb1
.alias load $ffd5
.alias membot $ff9c
.alias memtop $ff99
.alias open $ffc0
.alias plot $fff0
.alias ramtas $ff87
.alias rdtim $ffde
.alias readst $ffb7
.alias restor $ff8a
.alias save $ffd8
.alias scnkey $ff9f
.alias screen $ffed
.alias second $ff93
.alias setlfs $ffba
.alias setmsg $ff90
.alias setnam $ffbd
.alias settim $ffdb
.alias settmo $ffa2
.alias stop $ffe1
.alias talk $ffb4
.alias tksa $ff96
.alias udtim $ffea
.alias unlsn $ffae
.alias untlk $ffab
.alias vector $ff8d
; Character codes for the colors.
.alias color'0 144
.alias color'1 5
.alias color'2 28
.alias color'3 159
.alias color'4 156
.alias color'5 30
.alias color'6 31
.alias color'7 158
.alias color'8 129
.alias color'9 149
.alias color'10 150
.alias color'11 151
.alias color'12 152
.alias color'13 153
.alias color'14 154
.alias color'15 155
; ...and reverse video
.alias reverse'on 18
.alias reverse'off 146
; ...and character set
.alias upper'case 142
.alias lower'case 14</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x986.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x994.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>c64-1.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello3.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

210
book/x994.html Normal file
View File

@ -0,0 +1,210 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello3.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="c64kernal.oph"
HREF="x990.html"><LINK
REL="NEXT"
TITLE="hello4a.oph"
HREF="x998.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x990.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x998.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR3-SRC"
><TT
CLASS="FILENAME"
>hello3.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "c64-1.oph"
.outfile "hello.prg"
.macro print
ldx #0
_loop: lda _1, x
beq _done
jsr chrout
inx
bne _loop
_done:
.macend
.macro greet
`print hello1
`print _1
`print hello2
.macend
lda #147
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
rts
hello1: .byte "HELLO, ",0
hello2: .byte "!", 13, 0
target1: .byte "PROGRAMMER", 0
target2: .byte "ROOM", 0
target3: .byte "BUILDING", 0
target4: .byte "NEIGHBORHOOD", 0
target5: .byte "CITY", 0
target6: .byte "NATION", 0
target7: .byte "WORLD", 0
target8: .byte "SOLAR SYSTEM", 0
target9: .byte "GALAXY", 0
target10: .byte "UNIVERSE", 0</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x990.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x998.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>c64kernal.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello4a.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

231
book/x998.html Normal file
View File

@ -0,0 +1,231 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hello4a.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="hello3.oph"
HREF="x994.html"><LINK
REL="NEXT"
TITLE="hello4b.oph"
HREF="x1002.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x994.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1002.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="TUTOR4A-SRC"
><TT
CLASS="FILENAME"
>hello4a.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "c64-1.oph"
.outfile "hello.prg"
.macro print
ldx #0
_loop: lda _1, x
beq _done
jsr chrout
inx
bne _loop
_done:
.macend
.macro greet
lda #30
jsr delay
`print hello1
`print _1
`print hello2
.macend
lda #147
jsr chrout
`greet target1
`greet target2
`greet target3
`greet target4
`greet target5
`greet target6
`greet target7
`greet target8
`greet target9
`greet target10
rts
hello1: .byte "HELLO, ",0
hello2: .byte "!", 13, 0
target1: .byte "PROGRAMMER", 0
target2: .byte "ROOM", 0
target3: .byte "BUILDING", 0
target4: .byte "NEIGHBORHOOD", 0
target5: .byte "CITY", 0
target6: .byte "NATION", 0
target7: .byte "WORLD", 0
target8: .byte "SOLAR SYSTEM", 0
target9: .byte "GALAXY", 0
target10: .byte "UNIVERSE", 0
; DELAY routine. Executes 2,560*(A) NOP statements.
delay: tax
ldy #00
* nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
iny
bne -
dex
bne -
rts</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x994.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1002.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello3.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><TT
CLASS="FILENAME"
>hello4b.oph</TT
></TD
></TR
></TABLE
></DIV
></BODY
></HTML
>