(*
This is a simple demonstration file for the Zeus assembler.
If you want more sustantial files they're available at www.desdes.com

NOTE - I'm seriously thinking about changing the conditional assembly

Predefined labels


Zeus defines some labels before the start. they are as follows (currently)

true		equ 1
TRUE		equ 1
false	 	equ 0
FALSE		equ 0
ZEUSZ80		equ 1
ZEUSVER		equ 8	; This will increment as/when I release versions.


Variables.


Zeus distinguishes between labels and variables. A label is any symbol declared using
the 'EQU' statement, or any symbol automatically declared by putting it before an
instruction. A variable is any symbol declared using an '='...

Look at these, all legal statements:

Fred	equ 42		; Fred is given the value 42, Fred cannot be changed later
Bert	nop		; Bert is given the address of an instruction

zeusprint Fred		; This will show 42
zeusprint Bert		; This will show the memory address of the nop 

Mary	= 42		; Mary is given the value 42, but '=' means she can change
zeusprint Mary		; This will show 42
Mary    = 43		; Mary is changed to 43, she is a variable so this is OK
zeusprint Mary		; This will show 43


Incidentally, Bert above might change while the assembler is performing passes
because the lengths of some instructions might change, but you won't see that because
Zeus will hide it behind your back. You're not allowed to explicitly change it is the
point. 

Once a name has been used as a variable or a label the type is fixed, so you can't
change that later. This is not a restriction imposed by accident; it's a way to avoid
users making some hard to diagnose bugs. BTDT.

Fred 	= 0		; Declare Fred as a variable.

Fred 	nop		; Error! Fred is a variable, can't use it as a label

If you wanted Fred set to an address, do the following:

Fred 	= .		; '.' Is the current memory address
	nop		; So that will be the address of the instruction following.


"So what? What use are variables, then?"

I'm getting to that. Give me a break... Right. Variables come into their own when
used with conditional assembly. Suppose we wanted to fill an area of memory with a
pattern of incrementing bytes. What would be nice is if we could do something like
this:

Value = 0			; Set up a variable
	repeat			; Loop
  	  db Value		; Plant the current value
          Value = Value + 1	; Increment it
	until Value > $100	; Go back until we've done enough

Well, you can. That's perfectly legal in Zeus.

You can also do it like this:

Value = 0			; Set up a variable
	while Value < $100	; Loop
  	  db Value		; Plant the current value
          Value = Value + 1	; Increment it
          wend			; Note the while .. wend

Sometimes it's nice to just be able to do something a number of times, but you don't
need access to the loop variable. For that case zeus has a loop .. lend structure:

	loop 256		; Loop 256 times
	  nop			; Plant a nop
	  lend			;

You can, of course, nest multiple loops.


Conditional assembly.


Sometimes we want to have optional parts of a source... Maybe we want to have
different graphics depending on the release. Forbidden Planet was released with
Krell-style power meters, but only an assembly option away were trumpeting elephants.

Regard the following code, it should be obvious what it does:

WantElephants	equ true	; Could also be a variable

	if WantElephants
DrawThem	call DrawElephants
	else	
DrawThem	call DrawKrell
	endif

You can nest if statements, if you really want to confuse yourself.

	if WantElephants
          if WantBIGElephants
DrawThem	call DrawBigElephants
          else
DrawThem	call DrawSmallElephants
          endif
	else	
DrawThem	call DrawKrell
	endif

Zeus also supports if/elseif/else/endif

	if WantElephants
DrawThem	call DrawElephants
	elseif WantRhinos	
DrawThem	call DrawRhinos
	else
DrawThem	call DrawKrell
	endif

Note that elseif is a single word, "else if" is a different animal - it's all down to
avoiding leaving else dangling - she doesn't like it.


I tend to use the 'DEF' operator with conditional assembly so I'd better explain it. 
DEF is short for defined - a label is defined if you've mentioned it and not defined 
if you haven't.

Fred	equ 1		; Fred is now defined.

Bert and Mary aren't, unless they're at it somewhere off the top of the screen.

So, the expression "def Fred" would return true, where as "def Mary" would return
false. "What are true and false?" I hear you ask. Zeus regards any value other
than zero as true. Zeus itself returns the value 1 for any conditional expression.
I used to prefer conditionals returning -1, suitable for masks, but I suppose it's
time to bow to the pressure from this new-fangled C stuff...
*)

; Show zem. Show zem all...

zeusprint "true is ",true,"false is ",false, "Zeus version is ",ZEUSVER

