mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-09-30 09:54:44 +00:00
HTML edition of Programming With Ophis 2
This commit is contained in:
parent
ba1720619f
commit
24402e026c
311
book/a1034.html
Normal file
311
book/a1034.html
Normal 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"
|
||||
><<< 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 >>></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
|
||||
> — Only available with 65C02 extensions</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
><I
|
||||
CLASS="EMPHASIS"
|
||||
>(Zero Page Indirect):</I
|
||||
> <TT
|
||||
CLASS="LITERAL"
|
||||
>LDX ($80)</TT
|
||||
> — 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"
|
||||
><<< 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 >>></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"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>Basic arguments</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
185
book/a975.html
Normal file
185
book/a975.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Example: Fibonnacci Numbers</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </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
654
book/book1.html
Normal 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 © 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"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="f10.html"
|
||||
ACCESSKEY="N"
|
||||
>Next >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>Preface</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
215
book/c223.html
Normal file
215
book/c223.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
251
book/c259.html
Normal 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"
|
||||
><<< 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 >>></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—the <TT
|
||||
CLASS="FILENAME"
|
||||
>PRG</TT
|
||||
>
|
||||
information and the BASIC program—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"
|
||||
><<< 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 >>></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
339
book/c319.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
409
book/c353.html
Normal 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"
|
||||
><<< 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 >>></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—we must ensure that no routines step on
|
||||
each other. What we'd really like are two separate program
|
||||
counters—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"
|
||||
><<< 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 >>></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
355
book/c395.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><</TT
|
||||
> and <TT
|
||||
CLASS="LITERAL"
|
||||
>></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 #<_1
|
||||
ldx #>_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"
|
||||
>< ></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"
|
||||
>| & ^</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"
|
||||
><<< 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 >>></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
191
book/c443.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
185
book/c486.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
512
book/c543.html
Normal 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"
|
||||
><<< 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 >>></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—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 < 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—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—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"
|
||||
><<< 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 >>></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
187
book/c55.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
292
book/c748.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
220
book/c816.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
209
book/c900.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
272
book/f10.html
Normal 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"
|
||||
><<< 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 >>></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—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—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—uncreatively
|
||||
dubbed <SPAN
|
||||
CLASS="QUOTE"
|
||||
>"Perl65"</SPAN
|
||||
>—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"
|
||||
><<< 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 >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Programming with Ophis</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </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
190
book/p481.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Where to go from here</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>The Second Step</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
199
book/p50.html
Normal file
199
book/p50.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>About the examples</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>The basics</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
233
book/x1002.html
Normal file
233
book/x1002.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
236
book/x1006.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
240
book/x1010.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
267
book/x1014.html
Normal 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"
|
||||
><<< 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 >>></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 #<_1
|
||||
ldx #>_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"
|
||||
><<< 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 >>></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
224
book/x1018.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
262
book/x1022.html
Normal 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"
|
||||
><<< 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 >>></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 #<_1
|
||||
ldx #>_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"
|
||||
><<< 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 >>></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
395
book/x1026.html
Normal 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"
|
||||
><<< 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 >>></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 <$838,<$618,<$205,<$984,<$724,<$301,<$249,<$946
|
||||
.byte <$925,<$043,<$114,<$697,<$985,<$633,<$312,<$086
|
||||
hb: .byte >$838,>$618,>$205,>$984,>$724,>$301,>$249,>$946
|
||||
.byte >$925,>$043,>$114,>$697,>$985,>$633,>$312,>$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 > 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 #<unsorted'hdr
|
||||
ldx #>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 #<sorted'hdr
|
||||
ldx #>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 </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"
|
||||
><<< 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 >>></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
374
book/x1030.html
Normal 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"
|
||||
><<< 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 >>></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 #<opening ; Print opening text
|
||||
sta fun'args
|
||||
lda #>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 <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 < 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 #<10000
|
||||
sta _step
|
||||
lda #>10000
|
||||
sta _step+1
|
||||
jsr repsub'16
|
||||
lda #<1000
|
||||
sta _step
|
||||
lda #>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"
|
||||
><<< 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 >>></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
309
book/x1101.html
Normal 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"
|
||||
><<< 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 >>></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—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"
|
||||
><<< 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 >>></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
212
book/x1149.html
Normal 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"
|
||||
><<< 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 >>></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 > and <, 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"
|
||||
><$D000+32</TT
|
||||
> evaluates to $20</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
><TT
|
||||
CLASS="LITERAL"
|
||||
>>$D000+32</TT
|
||||
> evaluates to $F0</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
><TT
|
||||
CLASS="LITERAL"
|
||||
>>[$D000+32]</TT
|
||||
> evaluates to $D0</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
><TT
|
||||
CLASS="LITERAL"
|
||||
>>[$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"
|
||||
><<< 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 >>></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
373
book/x1176.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
358
book/x1221.html
Normal 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"
|
||||
><<< 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 >>></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—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 #<_2
|
||||
sta _1
|
||||
lda #>_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"
|
||||
><<< 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 >>></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
568
book/x1261.html
Normal 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"
|
||||
><<< Previous</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="80%"
|
||||
ALIGN="center"
|
||||
VALIGN="bottom"
|
||||
>Ophis Command Reference</TD
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
> </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"
|
||||
><<< 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"
|
||||
> </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"
|
||||
> </TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
206
book/x140.html
Normal file
206
book/x140.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
197
book/x161.html
Normal 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"
|
||||
><<< 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 >>></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—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"
|
||||
><<< 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 >>></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
333
book/x170.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
198
book/x237.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
203
book/x248.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
289
book/x284.html
Normal 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"
|
||||
><<< 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 >>></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—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"
|
||||
><<< 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 >>></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
193
book/x29.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
161
book/x314.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
176
book/x41.html
Normal 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"
|
||||
><<< 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 >>></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
|
||||
>—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"
|
||||
><<< 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 >>></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
321
book/x454.html
Normal 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"
|
||||
><<< 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 >>></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—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"
|
||||
><<< 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 >>></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
162
book/x476.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
166
book/x498.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
267
book/x504.html
Normal 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"
|
||||
><<< 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 >>></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 < 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
|
||||
>= B, and it's clear if A < 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"
|
||||
><<< 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 >>></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
196
book/x527.html
Normal 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"
|
||||
><<< 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 >>></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—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"
|
||||
><<< 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 >>></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
178
book/x537.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
172
book/x597.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
283
book/x603.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
348
book/x621.html
Normal 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"
|
||||
><<< 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 >>></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—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—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"
|
||||
><<< 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 >>></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
449
book/x666.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
431
book/x71.html
Normal 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"
|
||||
><<< 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 >>></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—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—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"
|
||||
><<< 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 >>></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
444
book/x719.html
Normal 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"
|
||||
><<< 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 >>></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 <$838,<$618,<$205,<$984,<$724,<$301,<$249,<$946
|
||||
.byte <$925,<$043,<$114,<$697,<$985,<$633,<$312,<$086
|
||||
hb: .byte >$838,>$618,>$205,>$984,>$724,>$301,>$249,>$946
|
||||
.byte >$925,>$043,>$114,>$697,>$985,>$633,>$312,>$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 < data[i] then begin
|
||||
next[i] := head;
|
||||
head := i;
|
||||
return;
|
||||
end;
|
||||
current := head;
|
||||
while (next[current] <> -1 and val < 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 > 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"
|
||||
><<< 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 >>></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
253
book/x782.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
196
book/x798.html
Normal 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"
|
||||
><<< 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 >>></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—or (Indirect), Y—mode. What about Indexed
|
||||
Indirect—(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—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"
|
||||
><<< 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 >>></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
193
book/x805.html
Normal 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"
|
||||
><<< 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 >>></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—loading <TT
|
||||
CLASS="LITERAL"
|
||||
>*b</TT
|
||||
> into the
|
||||
accumulator—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"
|
||||
><<< 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 >>></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
154
book/x813.html
Normal 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"
|
||||
><<< 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 >>></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—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"
|
||||
><<< 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 >>></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
215
book/x836.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
249
book/x855.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
258
book/x871.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
178
book/x892.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
336
book/x915.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
219
book/x967.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
184
book/x982.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
176
book/x986.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
231
book/x990.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
210
book/x994.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
231
book/x998.html
Normal 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"
|
||||
><<< 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 >>></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"
|
||||
><<< 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 >>></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
|
||||
>
|
Loading…
Reference in New Issue
Block a user