Ophis Assembler Tutorial

Part 6: Expressions

Ophis permits a reasonably rich set of arithmetic operations to be
done at assemble time.  To date, all of our arguments and values
have either been constants in decimal or hexadecimal or label names.
In this lesson we will modify the "print" macro so that it calls a
subroutine to do the actual printing.  This will shrink the final
code size a fair bit.

Here's our printing routine.  It's fairly straightforward.

; 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

However, now we are faced with the problem of what to do with the
"print" macro.  We need to take a 16-bit value and store it in two
8-bit registers.  We can use the < and > operators to take the low
or high byte of a word, respectively.  The "print" macro becomes:

.macro print
	lda #<_1
	ldx #>_1
	jsr printstr
.macend

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.

That code looks vaguely like this:

.data
.org $C000
.space cache 2
.text

	; ... macro definitions here ...

	; 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

	; ... data and subroutines here ...

Note that we only have to name cache once, but can use addition to
refer to any offset from it.

Ophis supports following operations, with the following precedence
levels (higher entries bind more tightly):

	[ ]	Parenthesized expressions
	< >	Byte selection (low, high)
	* /	Multiply, divide
	+ -	Add, subtract
	| & ^	Bitwise OR, AND, XOR

Note that braces, 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.

The code for this version of the code is in tutor6.p65.