mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-11-05 17:07:33 +00:00
397 lines
5.8 KiB
HTML
397 lines
5.8 KiB
HTML
<!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="p51.html"><LINK
|
|
REL="PREVIOUS"
|
|
TITLE="Local variables and memory segments"
|
|
HREF="c367.html"><LINK
|
|
REL="NEXT"
|
|
TITLE="Advanced Memory Segments"
|
|
HREF="c460.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="c367.html"
|
|
ACCESSKEY="P"
|
|
><<< Previous</A
|
|
></TD
|
|
><TD
|
|
WIDTH="80%"
|
|
ALIGN="center"
|
|
VALIGN="bottom"
|
|
></TD
|
|
><TD
|
|
WIDTH="10%"
|
|
ALIGN="right"
|
|
VALIGN="bottom"
|
|
><A
|
|
HREF="c460.html"
|
|
ACCESSKEY="N"
|
|
>Next >>></A
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><HR
|
|
ALIGN="LEFT"
|
|
WIDTH="100%"></DIV
|
|
><DIV
|
|
CLASS="CHAPTER"
|
|
><H1
|
|
><A
|
|
NAME="AEN409"
|
|
></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.<A
|
|
NAME="AEN425"
|
|
HREF="#FTN.AEN425"
|
|
><SPAN
|
|
CLASS="footnote"
|
|
>[1]</SPAN
|
|
></A
|
|
>
|
|
</P
|
|
><P
|
|
> Ophis supports following operations, with the following precedence
|
|
levels (higher entries bind more tightly):
|
|
</P
|
|
><DIV
|
|
CLASS="TABLE"
|
|
><A
|
|
NAME="AEN429"
|
|
></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="x1151.html"
|
|
><I
|
|
><I
|
|
>hello6.oph</I
|
|
></I
|
|
></A
|
|
>.
|
|
</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.AEN425"
|
|
HREF="c409.html#AEN425"
|
|
><SPAN
|
|
CLASS="footnote"
|
|
>[1]</SPAN
|
|
></A
|
|
></TD
|
|
><TD
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
WIDTH="95%"
|
|
><P
|
|
>We
|
|
could spare ourselves some trouble here and use $fb instead of
|
|
$10, which BASIC does <I
|
|
CLASS="EMPHASIS"
|
|
>not</I
|
|
> use, but the
|
|
example is more thorough this way.</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="c367.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="c460.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="p51.html"
|
|
ACCESSKEY="U"
|
|
>Up</A
|
|
></TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
>Advanced Memory Segments</TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></BODY
|
|
></HTML
|
|
> |