@DATABASE "ESA v0.9 Documentation"

*******************************************************************************
@NODE MAIN "ESA v0.9 doc (15.07.1998)"

               @{b}Extended Syntax Assembly v0.9 (15.07.1998)@{ub}

                        © 1998 Simone Bevilacqua

 @{" VERY IMPORTANT! READ THIS BEFORE ANYTHING ELSE!!! " link uncomplete}
                       
 @{" DISCLAIMER & Distribution   " link DISCLAIMER} some legal stuff
 @{" Requirements & Installation " link Requirements_&_Installation} did you buy another 32Mb Simm?
 @{" Introduction                " link Intro} why this?!?
 @{" Features                    " link Features} what can it do?
 @{" Usage                       " link Usage} how to use it?
 @{" Grammar & Constructions     " link Grammar} what you can write and what you can't
 @{" General Notes               " link genotes} things you have to know
 @{" Error Messages              " link errmsg} what's wrong, now?!?
 @{" Bugs                        " link Bugs} oh, no!
 @{" History                     " link History} what has happened till now
 @{" Future                      " link Future} what's still to be done?
 @{" Author                      " link Author} some notes about me...
 @{" Greetz & Thanx              " link Greetz} ciao!
@ENDNODE

*******************************************************************************
@NODE uncomplete "Something's missing..."

@{b}@{u}Something's missing...@{ub}@{uu}

Due to time reasons, this version comes *without* a couple of features
(as indicated in their own sections). The last time I worked on this
project was May 25... and since I'm going back home (to study, indeed...
no vacations this summer!!!) I won't be able to finish it before autumn.
I decided to upload it now because I feared that by that time it would be
too late and because I want *your* feedback. So @{"write to me" link Author}, but don't
wait for replies to come before Semptember, when I'll be back.
A finished version (v1.0) will come (hopefully... but I'm not making pro-
mises!) in September/October (to avoid any misunderstanding: this version
will soon or later be released, apart from what I say in the @{"future" link future}
section).


@ENDNODE

*******************************************************************************
@NODE DISCLAIMER "DISCLAIMER and Distribution"
   
    @{b}@{u}DISCLAIMER@{ub}@{uu}

    **********************************************************************
    * THIS PROGRAM IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND      *
    * EITHER EXPRESSED OR IMPLIED.                                       *
    * @{"I" Link Author} ACCEPT NO RESPONSABILITY OR LIABILITY FOR ANY DAMAGE OR PROBLEM *
    * DERIVING FROM THE USE OF THIS PROGRAM:  USE AT YOUR OWN RISK!!!    *
    **********************************************************************

    @{b}@{u}Distribution@{ub}@{uu}

    This program is FREEWARE, therefore IT CANNOT BE SOLD FOR PROFIT.
    So, only the distribution charges (i.e. disk, postage, handling,
    etc.) can be applied.

    No fee is required from @{"me" link Author}, but donations of any kind (so-
    mething like the 1st original tankobon of "Dr.Slump & Arale chan"
    would be just a dream... ;) will be gladly accepted.

    If distributed on a coverdisk, please send a copy of the mag!!!
@ENDNODE

*******************************************************************************
@NODE Requirements_&_Installation "Requirements & Installation"

@{b}@{u}Requirements & Installation@{ub}@{uu}

ESA requires a 020+ CPU.
It should work also on KS1.3, but I can give no guarantee.

It doesn't need to be installed, just put it anywhere on your HD.
@ENDNODE

*******************************************************************************
@NODE Usage "Using ESA"

@{b}@{u}Using ESA@{ub}@{uu}

Run it from both CLI or WB, but tooltypes aren't supported (do you really
wanna launch it from icon?!? I can't believe it!!!).

 @{b}SYNTAX@{ub}
         esa [@{b}OPTIONS@{ub}] @{b}source@{ub} [@{b}dest@{ub}]

 @{b}ARGS
         source@{ub}    : asm source file to convert
         @{b}dest@{ub}      : output filename (def.: source="file.esa" -> "file.s"
                                            source="anything" -> "anything.s")

 @{b}OPTIONS@{ub}
         -@{b}s@{ub}S    {S}: 'S' is the instructions' separator (def.: S='§')
                     with this you can decide how to separate @{"two or" link separator}
                     @{"more instructions on the same line" link separator}

         -@{b}c@{ub}     {D}: include comments in the output file
                     (normally they are omitted)

         -@{b}l@{ub}C    {D}: 'C'=first char of labels (def.: '.')
                     each label produced by ESA will start with 'C'

         -@{b}b@{ub}SIZE {M}: work buffer of SIZE bytes (SIZE=>2048 - def.: 10Kb)
                     (the bigger the faster... less accesses to disk!)

         -@{b}q@{ub}     {M}: quiet mode (no messages will be given)

 @{b}NOTES@{ub}
         - {S}=source option, {D}=dest option, {M}=misc option
         - the options can be placed anywhere in the command line
         - the options and their args can be separated by spaces
         - press CTRL-C to break execution anytime
@ENDNODE

*******************************************************************************
@NODE Intro "Introduction"

@{b}@{u}Introduction@{ub}@{uu}

Oh... so you're wondering why I wrote this prog...
No special purpose indeed... I came from a long period during which
I just studied and didn't code anything (coding is kinda disease...
you know when you start, but don't know when you'll finish... sadly
this doesn't help with exams...). At the end of this interminable
period of forced coding inactivity, I would've coded just anything.
And that's what happened. ESA was the 1st idea which came to my mind
and so I immediately started it, getting up in the depths of night.
OK, I guess you can imagine perfectly how I felt like, so I'll try
to be brief.
Between one project and another, I continued (slowly) developing
this program, even though, when the "creative attack" was over, I
was no longer much convinced about it. Yes, an interesting piece of
software to produce, but - I was wondering - will it somehow come in
handy? I didn't find an answer... I wish that somebody of you will
find it useful or (this would please me even more) that it will
help someone to approach the assembly language... @{"what do you think" link author}
@{"about it?!?" link Author} I wouldn't be surprised of hearing comments of the kind:
«Junk. Afraid of asm? Stop complaining about its "difficulty" and go
on with an high level language. No need of this "extension" at all.»
No. I wouldn't be surprised, because that's EXACTLY what *I* think.
Can't believe it? It doesn't matter. The only other thing, apart from
the pleasure of coding a program that I personally found interesting
to code, which pushed me to complete my work is the fact that I've
learned that in this world there's always somebody who likes what you
wouldn't have ever believed that could appeal to anyone (phew! Correct?
If not, I hope you can get the general sense the same!!!).
@ENDNODE

*******************************************************************************
@NODE errmsg "Error Messages"

@{b}@{u}Error Messages@{ub}@{uu}

As you may have guessed, this section covers the errors reported by
ESA and all the related stuff. I've not been too fussy, so the same
error could be given for a number of different mistakes. My advice
is to check the syntax, the prob is almost always there!

Error reports take the form of:

 "ERROR " ERRNO ": " ERRTEXT " at line " LINENO " of " FILENAME ":"
 ">" CODELINE

where:

 - ERRNO is the number of the error found
 - ERRTEXT is the concise explanation of what happened
 - LINENO is the line which the error occurred at
 - FILENAME is the file which contains the error (only the file
   part of the path is printed)
 - CODELINE is the wrong line in the source

(sometimes the report stops at the end of ERRTEXT).

Errors are grouped into 3 classes:

 @{" pass 1 " link e_pass1} reports during pass 1
 @{" pass 2 " link e_pass2} reports during pass 2
 @{" misc   " link e_misc} general messages

 @{" global " link e_global} ordered list of all messages

No description is given for self-explaining messages.
@ENDNODE

*******************************************************************************
@NODE e_pass1 "Pass 1 Errors"

@{b}@{u}Pass 1 Errors@{ub}@{uu}

 0: user break
    - this is your own business...
 1: couldn't load source file
 3: not enough memory
    - ESA either didn't find enough room to load a source file or failed
      to allocate dinamically one of the little structures used for
      @{"procedures" link ProcDef} and @{"functions" link FuncDef} definitions!
11: wrong syntax in procedure declaration
12: wrong syntax in function declaration
23: too many @{"nested includes" link includes}
    - max recursion degree for include files is 64 - you've just passed beyond!
24: couldn't access source directory
    - ESA couldn't lock the directory of any of the @{"source/include files" link includes}
32: directory not found
    - @{"incdir" link includes} specifies a directory which cannot be reached from
      the current directory
33: @{"SORRY, FEATURE NOT IMPLEMENTED IN THIS VERSION" link uncomplete}
    - incdir is unimplemented in v0.9
@ENDNODE

*******************************************************************************
@NODE e_pass2 "Pass 2 Errors"

@{b}@{u}Pass 2 Errors@{ub}@{uu}

 0: user break
    - this is your own business...
 4: unexpected end of file
    - there is a construction of the type: "begin"..."end" which
      hasn't been closed (i.e. "end" part missing) before the end
      of the source file
 5: unexpected end mark
    - ESA met an "end" statement used for the constructions of the
      kind: "begin"..."end" which wasn't the one it was waiting for.
      Pay attention to the @{"nested constructions" link Features 34} in your source
 6: unsignificant string after ESA declaration
    - side comments must start with ';'
    - no string is allowed after an ESA construction, unless separated
      by the @{"separator char" link separator}
 7: wrong syntax in @{"boolexpr" link boolexpr}
 8: wrong syntax in @{"bool" link bool} declaration
 9: wrong syntax in @{"expire" link expire} declaration
10: wrong syntax in @{"nexp" link expire} declaration
13: wrong size in @{"exit" link PFExit} declaration
14: exit statement not inside a @{"procedure" link ProcDef}/@{"function" link FuncDef}
    - "exit" doesn't work for loops
15: unknown procedure
16: unknown function
    - actually, this error is never reported!!! If a function name is
      somehow wrong (thus the function cannot be found in the internal
      list), it's treated like a 68k addressing mode with displacement,
      to save (quite useless) checks on this kind of EAs...
17: wrong syntax in @{"procedure call" link DefProcCall}
18: wrong syntax in @{"function call" link DefProcCall}
19: arguments mismatch in procedure/function call
    - you passed less or more arguments than expected from the decla-
      ration of the procedure/function
20: wrong syntax in @{"until" link repeat} declaration
21: wrong syntax in @{"while" link while} declaration
22: wrong syntax in @{"when" link when} declaration
25: wrong syntax in on...@{"goto" link ongoto}/@{"gosub" link ongosub}... declaration
26: wrong syntax in @{"for...to...step" link for} declaration
27: byte size in conjunction with address register
    - CTR size in the for...to...step declaration is byte and END or STP
      is an address register (this applies also to func's return values!)
28: wrong size in @{"next" link for} declaration
29: @{"othw" link when} not inside when...ewhen
30: wrong syntax in @{"switch" link switch} declaration
31: value declaration expected after @{"->" link switch}
33: @{"SORRY, FEATURE NOT IMPLEMENTED IN THIS VERSION" link uncomplete}
    - switch is unimplemented in v0.9
@ENDNODE

*******************************************************************************
@NODE e_misc "General Errors"

@{b}@{u}General Errors@{ub}@{uu}

 2: couldn't open dest file
 3: not enough memory
    - ESA failed to allocate the work buffers.
      Try freeing some memory or decreasing the @{"work buffer size" link Usage 25}
@ENDNODE

*******************************************************************************
@NODE e_global "Errors List"

@{b}@{u}Errors List@{ub}@{uu}

@{u}no class   text                                                     @{uu}

 0 @{"1" link e_pass1}@{"2" link e_pass2}  : user break
 1 @{"1" link e_pass1}    : couldn't load source file
 2     @{"m" link e_misc}: couldn't open dest file
 3 @{"1" link e_pass1}  @{"m" link e_misc}: not enough memory
 4   @{"2" link e_pass2}  : unexpected end of file
 5   @{"2" link e_pass2}  : unexpected end mark
 6   @{"2" link e_pass2}  : unsignificant string after ESA declaration
 7   @{"2" link e_pass2}  : wrong syntax in boolexpr
 8   @{"2" link e_pass2}  : wrong syntax in bool declaration
 9   @{"2" link e_pass2}  : wrong syntax in expire declaration
10   @{"2" link e_pass2}  : wrong syntax in nexp declaration
11 @{"1" link e_pass1}    : wrong syntax in procedure declaration
12 @{"1" link e_pass1}    : wrong syntax in function declaration
13   @{"2" link e_pass2}  : wrong size in exit declaration
14   @{"2" link e_pass2}  : exit statement not inside a procedure/function
15   @{"2" link e_pass2}  : unknown procedure
16   @{"2" link e_pass2}  : unknown function
17   @{"2" link e_pass2}  : wrong syntax in procedure call
18   @{"2" link e_pass2}  : wrong syntax in function call
19   @{"2" link e_pass2}  : arguments mismatch in procedure/function call
20   @{"2" link e_pass2}  : wrong syntax in until declaration
21   @{"2" link e_pass2}  : wrong syntax in while declaration
22   @{"2" link e_pass2}  : wrong syntax in when declaration
23 @{"1" link e_pass1}    : too many nested includes
24 @{"1" link e_pass1}    : couldn't access source directory
25   @{"2" link e_pass2}  : wrong syntax in on...goto/gosub... declaration
26   @{"2" link e_pass2}  : wrong syntax in for...to...step declaration
27   @{"2" link e_pass2}  : byte size in conjunction with address register
28   @{"2" link e_pass2}  : wrong size in next declaration
29   @{"2" link e_pass2}  : othw not inside when...ewhen
30   @{"2" link e_pass2}  : wrong syntax in switch declaration
31   @{"2" link e_pass2}  : value declaration expected after ->
32 @{"1" link e_pass1}    : directory not found
33 @{"1" link e_pass1}@{"2" link e_pass2}  : @{"SORRY, FEATURE NOT IMPLEMENTED IN THIS VERSION" link uncomplete}
@ENDNODE

*******************************************************************************
@NODE Bugs "Bugs"

@{b}@{u}Bugs@{ub}@{uu}

ESA has been tested (not so deeply) on:

- Unexpanded A1200
- A1200 + BZ1230-IV + 16MB
- A4000/040 + 16MB

No known bug at the moment.

If you think you have found any, please @{"send me" link Author} a detailed bug report.
Don't send in info about your machine (unless your machine gurus, halts,
resets, etc...), the most important thing is the part of code which you
think to be responsible for the bad behaviour of ESA and the code gene-
rated till that moment.

After this, just hope for a prompt fix!!!
@ENDNODE

*******************************************************************************
@NODE History "History"

@{b}@{u}History@{ub}@{uu}

@{b}v0.9 (15.07.1998)@{ub}

 First public release.
 For time reasons @{"switch" link switch} and @{"incdir" link includes} couldn't be implemented.
@ENDNODE

*******************************************************************************
@NODE Future "Future"

@{b}@{u}Future@{ub}@{uu}

First, let me say that I don't think I'll have much time to spend
on improving this program. Too bad this doesn't depend on me.
I just can ensure that I'll do my best to fix all the @{"bugs" link Bugs} you
will find (as soon as I'll have the time) and add those easy, mi-
nor improvements which could make ESA a little more friendly.

Speaking about "real" additions/expansions or whatever...

To be honest, I'm not willing at all to add more constructions,
for one simple, plain reason: I don't wanna end up writing a new
language. If you need to pass to an higher level, than switch to
C or E or anything else. ESA has already a few features which at
the beginning I didn't plan nor want to implement (which ones?
procedures, functions... and something else), 'coz I considered
too "advanced"... well, now you got'em, enjoy and let's forget
about this. But, pleeeeeze, don't ask me to add other magic com-
mands, unless they're are really something special...
However, don't be discouraged by what I just said. Got an idea?
Just @{"gimme a call" link Author} and let's see if I fancy it. Maybe it turns
out to be that damn nice feature ESA was missing!
@ENDNODE

*******************************************************************************
@NODE Author "Hi there!"

@{b}@{u}Hi there!@{ub}@{uu}

    I do want your feedback.
    Let me know what you think and if you have any problems/ideas.

    I can be reached by snail mail at these addresses:

                    Simone Bevilacqua        <--during uni vacation periods
                      Via A.Volta 6
                   86010 Ferrazzano (CB)
                          ITALY
   
                           or

                    Simone Bevilacqua        <--during normal periods
                    P.za  Garibaldi 9
                     56100 Pisa (PI)
                          ITALY


    or by e-mail:  bevilacq@cli.di.unipi.it  <--obviously recommended!!!
@ENDNODE

*******************************************************************************
@NODE Greetz "Greetz and Thanx"

@{b}@{u}Greetz and Thanx@{ub}@{uu}

Thanks for his kind testing to Michele Berionne.

Thanks to all the Amiga coders still around and in particular to
Frank Wille for his magic PhxAss (v4.38 used for ESA)!!!

I'd have liked to put also Amiga Int./Inc. in this thx list, but
I can't do it just now. I hope that in my next doc I'll have more
than one reason to do it.

Finally, Mega greetings to all my friends (no list to save some MBs...)!!!
@ENDNODE

*******************************************************************************
@NODE Features "Features"

@{b}@{u}Features@{ub}@{uu}

The job of this program is to take an asm source and "convert" it to
another one, ready to be assembled by your favourite assembler.
A kinda asm-preprocessor, in short.

So now - you're surely wondering - what can this prog do, precisely?
Well, as its name suggests, it accepts "extended" assembly sources
(read below to see how), so that, in the end, it can be said that a
new, enriched (you can also read this, if you like, as: "at an higher
level" - but that's *not* what I want at all) assembly language comes
out of it.
In few words: ESA takes an "extended" asm source as input and outputs
a standard 020+ asm source.

The most stupid feature is that it allows you to write @{"several asm in-" link separator}
@{"structions on a single line" link separator}. While this doesn't ease the reading, so-
metimes it can help since it allows to have more code on a single page.

Surely this is not all that ESA can offer.
In fact, it allows you to use some constructions for the program flow
control, which are typical of high-level languages.
Normally you have inline asm inside C, Pascal, Basic, etc.;
ESA, instead, gives inline C, Pascal, Basic, etc. inside asm, with all
the consequent advantages (yeah! we can mess around with CPU's and HW's
registers, variables, the stack, etc. in total freedom!).

Besides, there are also some facilities to help the design of the program
structure: yes, I'm referring to procedures and functions...
All I'm talking about is described in detail @{"here" link Grammar}, but you'd better have
a look at the @{"general notes" link genotes} and in particular to the @{"misc ones" link h_notes}, first.

Obviously, any construction can be used in nested form (there's only a
@{"very loose limitation..." link h_cuse 14})!

Finally, ESA offers a "special" support for the include files of any
kind (it's well worth having a look at @{"these info about this" link includes}...)
@ENDNODE

*******************************************************************************
@NODE includes "Include Files Handling"

******************************************************
* WARNING!                                           *
* "INCDIR" HANDLING IS STILL UNIMPLEMENTED!!!        *
* READ @{"HERE" link uncomplete} FOR MORE INFO!                          *
******************************************************

@{b}@{u}Include Files Handling@{ub}@{uu}

ESA processes the include files listed in the source so that you can
freely build your own "libraries" of functions/procedures.
It will recursively (max depth: 64) parse the includes, producing a
single output file without *any* include statement. Of course, each
include file will only be included and compiled just once. 
Please note that "IF" directives are simply ignored, so this kind of
declarations:

	IFND	EXEC_TYPES_I
	INCLUDE	"exec/types.i"
	ENDC

would be compiled as:

	IFND	EXEC_TYPES_I

	ENDC

if "exec/types.i" has already been included.

The directory which will be scanned to find the include files listed
in a source is the source's one (when no full path is declared - this
applies recursively also to includes).
@ENDNODE

*******************************************************************************
@NODE separator "Multiple Instructions on a Single Line"

@{b}@{u}Multiple Instructions on a Single Line@{ub}@{uu}

ESA allows you to put several instructions and/or ESA commands (with their
arguments, if required), separated by a special char, on a single line.

Let's make an example:

         lea.l buffer,a0 § bool d1=d2,d0.b § add.b d0,d0

I stopped at the third instruction, but there can be as many instructions
as you want... but then you'll find yourself scrolling the screen horizon-
tally rather than vertically! Not a great deal!!!

As you can see, the instructions are separated by " §" (note: the leading
' ' is compulsory, the following not), which is the default separator.
If you wish to change it, use the @{"-s option" link Usage 15}.

Warning: don't put labels after an instruction using the separator
         (they would be exchanged for instructions)!
@ENDNODE

*******************************************************************************
@NODE genotes "General Notes"

@{b}@{u}General Notes@{ub}@{uu}

This section gives you a few hints about:

 @{" correct use " link h_cuse} problems with generated code
 @{" speed       " link h_speed} performance of generated code
 @{" misc  notes " link h_notes} interesting things
@ENDNODE

*******************************************************************************
@NODE h_cuse "Correct Use"

@{b}@{u}Correct Use@{ub}@{uu}

The most important thing you have to bear in mind in order to get fully
working code is that you can't use the stack pointer (sp) freely inside
@{"ESA constructions" link Grammar}(avoid "dirty" sp tricks!): in fact, the code produced
needs to mess a lot with the sp, so don't be surprised if crashes happen
when (sp)-like modes are used inside expressions. Just think about some-
thing else and let ESA take total control of the sp inside its own con-
structions.

Remember: the stack is heavily used by ESA generated code!

Another thing to remember is that constructions nesting is permitted to
a certain degree: the biggest nest possible is 64 entries long.
Pay attention! There is *no* check... instead of inserting checks, I'd
prefer to enlarge the internal stack (even doubled would be still small)
used for this purpose in order to avoid the consequent slowdown.
@{"Let me know" link Author} if you feel too constrained.
@ENDNODE

*******************************************************************************
@NODE h_notes "Miscellaneous Notes"

@{b}@{u}Miscellaneous Notes@{ub}@{uu}

 - some constructions produce jumps to labels generated automatically:
   if they are local (=start with '.') and if between these jumps you
   use any global definition, probably the assembler will fail with an
   error of the kind: "undefined symbol"
 - default size is ".l" (except where differently stated);
 - place spaces/TABs wherever you want, except between the arguments
   and their own sizes;
 - remember that ESA makes mainly *syntactical* checks, *semantics* is
   left to the assembler: so, if you write an invalid expression, ESA
   won't warn you at all (give a look at @{"this simple example" link mathexpr})!!!
 - since @{"var and val" link conventions 24} accept almost anything, it's up to you to avoid
   weird things...
 - ESA is *case sensitive* for speed's sake!
 - remarks must start with '*' or ';' if they are at the beginning of
   a line or are not preceded by any instruction/directive;
   otherwise ';' is the only char which marks a comment (in this case
   it has to be used after a TAB or space);
 - comments can be put only at the end of any @{"sequence of instructions" link separator};
 - all spaces and TABs in the arguments will be removed (except if en-
   closed between "" or '');
 - when ESA is halted by @{"an error during pass 2" link e_pass2}, the output file holds
   all the code generated until that moment
 - as shown in the examples scattered in the @{"grammar" link Grammar} chapter, sometimes
   ESA doesn't seem able to align properly the asm instructions in their
   column... weird, huh?!? Well, this is not a bug, it's another "tribute"
   to speed!!! For the same reason, a negated exclusive or (~eor) makes
   some capitalized letters appear in the code ("EOR")!!!
 - the labels generated by ESA have this format: CXXXXXXX, where XXXXXXX
   is a number in hexadecimal notation and C is generally '.' (or the char
   you have selected with the @{"-l option" link Usage 22}); otherwise, it can be either 'p'
   for @{"global procedures" link ProcDef 35} or 'f' for @{"global functions" link FuncDef 36}.
   In theory, up to 3*268435456 different labels can be generated, but once
   passed the 268435455 mark, it's highly likely to produce repetitions...
   but who's gonna pass it, anyway?!?
@ENDNODE

*******************************************************************************
@NODE h_speed "How Do I Get the Best Performance?"

@{b}@{u}How Do I Get the Best Performance?@{ub}@{uu}

Basic, simple, speedy, flexible... but hard to work with due to
the length of the use procedures.

This applies to almost everything in this world.
And particularly to the hardware/software worlds.
Often, to make things a little bit shorter, simplicity, speed and
flexibility are sacrificed.
And this is exactly what (naturally) happens with ESA.

@{b}********************************************************************
WHEN WRITING TIME-CRITIC ROUTINES, DON'T RELY ON ESA CODE'S SPEED!!!
********************************************************************@{ub}

There's not much to add. You gotta write them by hand (and that's not
so much bad...).
The reason is that to allow total flexibility to the various constru-
ctions, the code has got to be as much general as possible, and,
consequently, slower than it could be if hand written.

ESA's @{"add-ons" link Grammar} affect the speed in different degrees:

- @{"procedures" link ProcDef} and @{"functions" link FuncDef} cause a very little speed loss (sometimes
  no loss at all)

- the @{"for" link for} and @{"expire" link expire} constructions also cause a minor speed loss,
  ("expire", in particular, thanks to its nature (simple), is often
  as fast as hand written code). Be careful, though, when using a
  variable for the counter of for...next: in small loops the overhead
  could be quite heavy!

- the real beasts are all the others, as they include the evaluation
  of @{"boolean expressions" link boolexpr}.
  Here I'd like to spend a couple of words (you can skip this...):
  writing code which automatically generates pieces of code to evalu-
  ate (almost) all kinds of boolean expressions, *without* having the
  possibility of using registers, is a tough thing (I looked at it as
  a challenge... I really enjoyed writing the code about this part -
  - I wonder if there's any theory about this... if you know, please
  @{"contact me" link Author}); it isn't easy to get rid of the difficulties that this
  problem presents (mainly because there is no availability of regi-
  sters), since not only variables (like in high level languages) but
  also the registers themselves have to be handled (carefully) as bo-
  olean and integer variables in the expressions.
  The result is that the code produced for boolean expressions' evalua-
  tion looks ugly (and it is, indeed), altough I put in as many opti-
  mizations as possible (for example: "not" ("@{"~" link logop}") is treated in a very
  smart way, making large use of the "De Morgan" rules): so,if you need
  speed, avoid automatically generated boolean expressions.

My advice is: use procs, funcs, fors on so on almost everywhere, but
*do* pay attention when a boolean expression pops up!!!
@ENDNODE

*******************************************************************************
@NODE Grammar "ESA Grammar & Constructions - back to school..."

@{b}@{u}ESA Grammar & Constructions - back to school...@{ub}@{uu}

Urgh... quite hard to explain clearly and deeply how the syntax works...
Anyway, once you've understood the general sense, everything should come
easy (at least I hope).
To start, I advice you to have a good look at @{"this quite formal listing" link conventions}
@{"of the valid types" link conventions} of the grammar: if something somewhere is not clear,
go on the same (don't worry!) and have a couple of glances at the examples
in any of the sections below, and then go back for better understanding.

     logic: @{" bool                       " link bool} evaluation of boolean expressions

 decisions: @{" when ... othw ... ewhen    " link when} "if" .. "else" .. "end if"
            @{" on ... goto ...            " link ongoto} jump table (normal branches)
            @{" on ... gosub ...           " link ongosub} jump table (subroutines)
            @{" switch ... -> ... eswitch  " link switch} better than C's (Pascal's "case")

     loops: @{" repeat ... until ...       " link repeat} ?!?
            @{" while ... ewhile           " link while} ?!?
            @{" for .. to ..  step .. next " link for} ?!?
            @{" expire ... nexp            " link expire} 68k "dbra"

procedures: @{" procedure ... eproc        " link ProcDef} defining procedures
            @{" PROCNAME()                 " link DefProcCall} calling procedures
            @{" exit                       " link PFExit} leaving procedures

 functions: @{" function ... efunc         " link FuncDef} defining functions
            @{" FUNCNAME()                 " link DefFuncCall} calling functions
            @{" exit                       " link PFExit} leaving functions
@ENDNODE

*******************************************************************************
@NODE conventions "Conventions"

@{b}@{u}Conventions@{ub}@{uu}

@{b}CONVENTIONS USED IN THE WHOLE TEXT@{ub}

 ...        = ESA and/or asm code
 [xyz]      = xyz is optional
 ID:type    = ID is an identifier of the type specified

Also, have a look at the @{"misc notes" link h_notes}.


@{b}TYPES@{ub}

  0.@{" logop    " link logop}:  "&" | "|" | "^"
  1.@{" cmpop    " link cmpop}:  "<" | ">" | "<=" | ">=" | "=" |
                  "«" | "»" | "«=" | "»=" | "<>"
  2.@{" matop    " link matop}:  "+" | "-" | "*" | "/" | "//" | "<<" | ">>"
  3.@{" size     " link size}:  ".s" | ".b" | ".w" | ".l"
  4. dreg      :  "d0" | "d1" | ... | "d7" | dreg size
  5. areg      :  "a0" | "a1" | ... | "a7" | areg".w" | areg".l"
  6.@{" reg      " link reg}:  dreg | areg
  7.@{" regslist " link regslist}:  reg | reg"/"regslist |
                  dreg"-"dreg | dreg"-"dreg"/"regslist |
                  areg"-"areg | areg"-"areg"/"regslist
  8.@{" sym      " link sym}:  any symbol accepted by the assembler
  9. var       :  @{"ea" link ea}[size] except imm
 10.@{" boolexpr " link boolexpr}:  rval | rval cmpop rval | imm cmpop rval | "{"boolexpr"}" |
                  "@{"~" link logop}"boolexpr  | boolexpr logop boolexpr
 11.@{" mathexpr "link mathexpr}:  sym matop sym | sym matop mathexpr | mathexpr matop sym |
                  mathexpr matop mathexpr | "(" mathexpr ")"
 12. imm       :  "#"sym | "#"mathexpr
 13. val       :  imm | var | func
 14.@{" rval     " link rval}:  var | func
 15. args      :  val | args "," args
 16.@{" func     " link DefFuncCall}:  any valid ESA function call
 17. cc        :  "eq" | "ne" | "vc" | "vs" | "pl" | "mi" |
                  "lo" | "ls" | "hi" | "hs" | "cc" | "cs" |
                  "lt" | "le" | "gt" | "ge" | "t"  | "f"
@ENDNODE

*******************************************************************************
@NODE ea "Effective Address"

@{b}@{u}Effective Address@{ub}@{uu}

 ea = any valid addressing mode

ESA won't make any check on several addressing modes,
so eas correctness is in your hands. 
@ENDNODE

*******************************************************************************
@NODE logop "Logical Operators"

@{b}@{u}Logical Operators@{ub}@{uu}

 "&" = and
 "|" = or
 "^" = exclusive or

These operators work on boolean basis: they are *not* bitwise
operators, they just know 0 and <>0.

Please note that "~" (not), being an unary logic operator, can
be used only in some positions in @{"boolean expressions" link boolexpr}.
@ENDNODE

*******************************************************************************
@NODE cmpop "Comparison Operators"

@{b}@{u}Comparison Operators@{ub}@{uu}

 op     cc    meaning

 "="    eq    equal to
 "<>"   ne    not equal
 "<"    lt    less than        (signed)
 ">"    gt    greater than     (signed)
 "<="   le    less or equal    (signed)
 ">="   ge    greater or equal (signed)
 "«"    lo    lower than       (unsigned)
 "»"    hi    higher than      (unsigned)
 "«="   ls    lower or same    (unsigned)
 "»="   hs    higher or same   (unsigned)
@ENDNODE

*******************************************************************************
@NODE matop "Mathemathical Operators"

@{b}@{u}Mathemathical Operators@{ub}@{uu}

 "+"  = addition
 "-"  = subtraction
 "*"  = multiplication
 "/"  = division
 "//" = modulo
 "<<" = shift left
 ">>" = shift right

These are the ones accepted by PhxAss.
@ENDNODE

*******************************************************************************
@NODE size "Sizes"

@{b}@{u}Sizes@{ub}@{uu}

 ".s", ".b" = byte
 ".w"       = word
 ".l"       = long

Oh-oh-oh!!!
@ENDNODE

*******************************************************************************
@NODE reg "Registers"

@{b}@{u}Registers@{ub}@{uu}

Only data & address registers can be used, sorry.
(For now) forget about ssp, sr, and so on...
if you try to use one of them, it will be treated just like
a normal symbol!

@ENDNODE

*******************************************************************************
@NODE regslist "Registers Lists"

@{b}@{u}Registers Lists@{ub}@{uu}

This is the type used for movems in 68k asm.
With ESA it assumes a more versatile aspect: in fact you can declare
also the size of any argument.
This, obviously, doesn't applies to movems (sizes are discarded, ".l"
is used as default), but has a great importance in @{"procs" link DefProcCall} and @{"funcs" link DefFuncCall}
calls.

A declaration of the kind: "a0.w/d3.b-d5" is perfectly legal and means,
if included in a call:

 - load a0 with a 2 bytes long value
 - load d3, d4, d5 with 1 byte long values

The same would have happened if the declaration had been: "a0.w/d3.b-d5.w",
since only the 1st size, in "dx.y-di.j" or "ax.y-ai.j" statementes, is taken
into account (y here).

Moreover, as the syntax shows, it's possible to mix in any order aregs
and dregs: "a3.w / d0-d2 / a5 - a7 / d5 / a1" is still valid (but *NO*
check is performed on repetitions! An "a5" in the place of "a1" would
not cause any error!).
@ENDNODE

*******************************************************************************
@NODE sym "Symbols"

@{b}@{u}Symbols@{ub}@{uu}

Here are listed all the characters which can be used in symbols.
If you think that someone is missing, just @{"drop me a line" link Author}.

 0 1 2 3 4 5 6 7 8 9
 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
 a b c d e f g h i j k l m n o p q r s t u v w x y z
 @ $ \ _ ¹ ² ³ ¢ ¼ ½ ¾ · ì è à ù § ò å ° © ® þ ¤ µ ¡
 ø ¶ æ ß ð £ £ ± × ç ª º

 The char '.' is allowed only at the beginning of a symbol (label).

ESA will only partially check the correctness of symbols,
so it can happen that unvalid symbols are used without any warning.
@ENDNODE

*******************************************************************************
@NODE boolexpr "Boolean Expressions"

@{b}@{u}Boolean Expressions@{ub}@{uu}

@{"Click here" link h_speed} for some hints on how to use these expressions
in the most effective way.
Also have a look at the @{"boolean" link logop} and @{"comparison" link cmpop} operators.

The arguments of boolean expressions are treated in this way:
false=0, true<>0.
Yet, after the execution of the evaluation code, it will always be:
false=0, true=-1 (255);
that's why it's possible to write expressions like: "a0.w & Sendo.b",
whose code would be:

           cmpa.w     #0,a0
           sne.b      -(sp)
           tst.b      Sendo
           sne.b      -(sp)
           move.l     d0,(-4,sp)
           move.b     (sp)+,d0
           and.b      d0,(sp)
           move.l     (-6,sp),d0

The size used in comparisons is the one of the 1st register or,
when there's no reg, of the 1st argument:

  code produced for "Hanamichi.w=Kaede.b":

           move.l     d0,(-5,sp)
           move.w     Hanamichi,d0
            cmp.w     Kaede,d0
           seq.b      -(sp)
           move.l     (-4,sp),d0

  code produced for "d5.b=Haruko.l" or "Haruko.l=d5.b":

            cmp.b     Haruko,d5
           seq.b      -(sp)

As an additional note, when an argument is an address register
only ".w" and ".l" can be used, thus it's impossible to write
something like "a5.b = Senbe"; on the other hand, a statement
of the kind "d0.b > a3.w" will make use of ".w", since aregs
have priority over dregs.

OK. Why don't you use the same size in both arguments ;)

As you can see, the best code is obtained  when at least one
argument is a register:

  code produced for "Ronzaman<d1":

            cmp.l     Ronzaman,d1
           sgt.b      -(sp)

  code produced for "a5.w »= Suppaman":

           cmpa.w     Suppaman,a5
           shs.b      -(sp)

  code produced for "Suppaman.b »= Ronzaman":

           move.l     d0,(-6,sp)
           move.b     Suppaman,d0
            cmp.b     Ronzaman,d0
           shs.b      -(sp)
           move.l     (-4,sp),d0
@ENDNODE

*******************************************************************************
@NODE mathexpr "Mathemathical Expressions"

@{b}@{u}Mathemathical Expressions@{ub}@{uu}

These are made of constats/symbols and @{"math operators" link matop}.
As always, ESA will check only their syntactical correctness:

 - ((say+hello-to-Pippo)

   this will be reported as wrong (and, if you're a very curios dude, FYI:
   (say+hello-to-Pippo) will be accepted and used. Upon completion of all
   the operations with it, going on with the parsing, the 2nd ')' will not
   be found and an error will be generated);

 - ApplePie/0

   this, instead, won't cause any warning, even if the assembler will
   clearly scream out loud that divisions by 0 are a little hard to do...
@ENDNODE

*******************************************************************************
@NODE rval "Restricted Values"

@{b}@{u}Restricted Values@{ub}@{uu}

This type is defined for exclusive use in @{"boolexprs" link boolexpr}.
As the name suggests, it's a restricted version of val, lacking
of the imm type.
@ENDNODE

*******************************************************************************
@NODE repeat "repeat ... until ..."

@{b}@{u}repeat ... until ...@{ub}@{uu}

@{b}SYNTAX@{ub}

 "repeat"
     ...
     ...
     ...
 "until"[SZ:size] BL:boolexpr


@{b}MEANING@{ub}

 1. executes the code "..."
 2. evaluates BL
 3. if BL is false, goes to 1, else exits


@{b}NOTES@{ub}

 - the code is always executed at least once;
 - SZ is the size of the bcc instruction used (default: none);


@{b}EXAMPLE@{ub}

 ESA asm:

           moveq.l    #1,d0
           repeat
           add.b      d0,d0
           until.s    #16=d0.b      ;silly, but works...

 68k asm:

           moveq.l    #1,d0

.000000A
           add.b      d0,d0
           cmpi.b     #16,d0
           seq.b      -(sp)         ;BL evaluation
           tst.b      (sp)+
           bne.s      .000000A      ;until
@ENDNODE

*******************************************************************************
@NODE while "while ... ewhile"

@{b}@{u}while ... ewhile@{ub}@{uu}

@{b}SYNTAX@{ub}

 "while"[SZ:size] BL:boolexpr
     ...
     ...
     ...
 "ewhile"


@{b}MEANING@{ub}

 1. evaluates BL
 2. if BL is false, goes to 5
 3. executes the code "..."
 4. goes to 1
 5. 1st instruction after "ewhile"


@{b}NOTES@{ub}

 - if the 1st time BL is false, the code is never executed;
 - SZ is the size of the bcc instruction used (default: none);


@{b}EXAMPLE@{ub}

 ESA asm:

            while.s   {Arale<d7.w}&{#Gacchan>d3}
            addq.l    #1,Arale
            add.l     Arale,d3
            ewhile                  ;no meaning... don't try to find one...

 68k asm:

.000000D     cmp.w    Arale,d7
            sgt.b     -(sp)
            cmpi.l    #Gacchan,d3
            slt.b     -(sp)
            move.l    d0,(-4,sp)
            move.b    (sp)+,d0
            and.b     d0,(sp)
            move.l    (-6,sp),d0       ;BL evaluation
            tst.b     (sp)+
            beq.s     .000000E         ;if while fails...
            addq.l    #1,Arale
            add.l     Arale,d3
            bra.s     .000000D         ;repeat loop
.000000E
@ENDNODE

*******************************************************************************
@NODE for "for ... to ... step ... next"

@{b}@{u}for ... to ... step ... next@{ub}@{uu}

@{b}SYNTAX@{ub}

 "for" CTR:var "=" ST:val "upto"|"dwto" END:val ["step" STP:val]
     ...
     ...
     ...
 "next"[SZ:size]


@{b}MEANING 0@{ub} ("upto", STP>0)

 1. assigns the value of ST to the counter CTR
 2. if CTR>END, goes to 6
 3. executes the code "..."
 4. adds STP to CTR
 5. goes to 2
 6. first instruction after "next"


@{b}MEANING 1@{ub} ("dwto", STP<0)

 2. if CTR<END, goes to 6


@{b}NOTES@{ub}

 - STP=1 as default
 - *NEVER* use STP=0!!! No check!
 - SZ is the size of the bcc instruction used (default: none);
 - size of CTR is its own;
   size of ST, END and STP is forced to be equal to CTR's;
 - never use "upto" with negative STP or "dwto" with positive STP!
 - it is necessary to declare the direction with "upto"/"dwto"
   because statically STP's sign is unknown. Direct checks in the
   generated code would produce even more unefficient code...


@{b}EXAMPLE 0@{ub}

 ESA asm:

           for        d4.b=#100 upto d6
           clr.l      (a0)+
           next.s

 68k asm:

           move.b     #100,d4            ;load CTR with ST
           move.b     d6,.0000002        ;store END
           move.b     #1,.0000002+4      ;default STP
           bra.s      .0000003
.0000002   dc.l	      0,0                ;local variables (END,STP)
.0000003   cmp.b      .0000002,d4        ;compare CTR with END
           bgt        .0000004           ;exit if CTR>END
           clr.l      (a0)+
           add.b      .0000002+4,d4      ;update CTR
           bra.s      .0000003           ;repeat the loop
.0000004


@{b}EXAMPLE 1@{ub}

 ESA asm:

           for        tmp.w = d3 dwto #23 step NegStep()
           move.l     (a1)+,(a2)+
           next

           function NegStep():d1
           bsr        _rnd
           neg.l      d0
           efunc

 68k asm:

           move.w     d3,tmp             ;load CTR with ST
           move.w     #23,.0000002       ;store END
           bsr        f0000000           ;call NegStep()
           move.w     d1,.0000002+4      ;store function result (STP)
           bra.s      .0000003
.0000002   dc.l       0,0                ;local variables (END,STP)
.0000003   move.l     a0,-(sp)           ;this quite complex way of
           exg.l      d0,a0              ;performing the boundary
           move.w     tmp,d0             ;check is caused by the fact
           cmp.w      .0000002,d0        ;that CTR is not a reg!
           exg.l      d0,a0
           movea.l    (sp)+,a0
           blt        .0000004           ;exit if CTR<END
           move.l     (a1)+,(a2)+
           move.l     d0,-(sp)           ;again, things get complicated...
           move.w     tmp,d0             ;using a reg for CTR would
           add.w      .0000002+4,d0      ;noticeably speed up this
           move.w     d0,tmp             ;part (see above)!
           move.l     (sp)+,d0
           bra        .0000003
.0000004
           bra        WhoKnowsWhere

f0000000                                 ;NegStep()
           bsr        _rnd
           neg.l      d0
f0000001   rts
@ENDNODE

*******************************************************************************
@NODE expire "68k 'dbra'"

@{b}@{u}expire ... nexp@{ub}@{uu}

@{b}SYNTAX@{ub}

 "expire" DX:dreg "=" ST:val
     ...
     ...
     ...
 "nexp" ["," COND:cc]


@{b}MEANING 0@{ub} (when COND not declared)

 1. assigns to DX the value of ST
 2. executes the code
 3. decrements DX by 1
 4. if DX=>0, goes to 2


@{b}MEANING 1@{ub} (when COND declared)

 1. assigns to DX the value of ST
 2. executes the code
 3. if COND is satisfied then the execution contines with the first
    instruction after "nexp"
 4. else decrements DX by 1
 5. if DX=>0, goes to 2


@{b}NOTES@{ub}

 - since the instruction used is dbcc, the size of DX and ST is always
   word (any specification is ignored);
 - if DX=ST, no assignment is done, so that you can use a register ini-
   tialized externally


@{b}EXAMPLE 0@{ub}

 ESA asm:

           lea.l      Buffer,a0
.air       expire     d7 = BufLen
           clr.b      (a0)+
           nexp

 68k asm:

           lea.l      Buffer,a0
.air       move.w     BufLen,d7     ;counter initialization
.0000000
           clr.b      (a0)+
           dbra       d7,.0000000


@{b}EXAMPLE 1@{ub}

 ESA asm:

           expire     d3=d3
           nop § nop § tst.l d1     ;ran out of fantasy...
           nexp,pl

 68k asm:

.0000001
           nop                      ;no init here!
           nop
           tst.l      d1
           dbpl       d3,.0000001   ;dbra with COND

@ENDNODE

*******************************************************************************
@NODE when "'if' ... 'else' ... 'end if'"

@{b}@{u}when ... othw ... ewhen@{ub}@{uu}

@{b}SYNTAX@{ub}

 "when"[SZ:size] BL:boolexpr
     ...
     ...
     ...
 ["othw"]
     ...
     ...
     ...
 "ewhen"


@{b}MEANING 0@{ub} ("othw" not specified)

 1. evaluates BL
 2. if BL is true, executes the code between "when" and "ewhen"


@{b}MEANING 1@{ub} ("othw" specified)

 1. evaluates BL
 2. if BL is true, executes the code between "when" and "othw"
    and then goes to the first instruction after "ewhen"
    if BL is false, executes the code between "othw" and "ewhen"
    and then goes to the first instruction after "ewhen"


@{b}NOTES@{ub}

 - SZ is the size to be used for branches (bccs - default: none)


@{b}EXAMPLE 0@{ub}

 ESA asm:

           when.s     ~{d0.w ^ ~d1.b}
           bsr        OhDamn
           ewhen

 68k asm:

           tst.w      d0
           seq.b      -(sp)
           tst.b      d1
           sne.b      -(sp)
           move.l     d0,(-4,sp)
           move.b     (sp)+,d0
           EOR.b      d0,(sp)
           not.b      (sp)
           move.l     (-6,sp),d0       ;BL evaluation
           tst.b      (sp)+
           beq.s      .000000F         ;if false condition...
           bsr        OhDamn
.000000F                               ;...jump here!


@{b}EXAMPLE 1@{ub}

 ESA asm:

           when       rain
           bsr        OpenUmbrella
           othw
           bsr        PutOnSunGlasses
           ewhen

 68k asm:

           tst.l      rain
           sne.b      -(sp)            ;BL evaluation
           tst.b      (sp)+
           beq        .0000010         ;jump performed when false
           bsr        OpenUmbrella
           bra        .0000011         ;skip "othw" section
.0000010
           bsr        PutOnSunGlasses
.0000011
@ENDNODE

*******************************************************************************
@NODE switch "better than C's (Pascal's 'case')..."

******************************************************
* WARNING!                                           *
* THIS IS ONE OF THE STILL UNIMPLEMENTED FEATURES!!! *
* READ @{"HERE" link uncomplete} FOR MORE INFO!                          *
******************************************************

@{b}@{u}switch ... -> ... eswitch@{ub}@{uu}

@{b}SYNTAX@{ub}

 "switch"[SZ:size] SW:var
 "->"V1:val ( ... )
 "->"V2:val ( ... )
    ...
 "->" VN:val ( ... )
 ["def" ( ... )]
 "eswitch"


@{b}MEANING@{ub}

 1. executes the code contained between the brackets whose VX
    is equal to SW;
    if no VX matches SW, the default code is executed (if "def" declared)
 2. jumps to the 1st instruction after "eswitch"


@{b}NOTES@{ub}

 - if one or more VX equal one another (and match SW's value), only
   the code of the 1st one (starting from the top) is executed;
 - SZ is the size to be used for branches (bccs - default: none);


@{b}EXAMPLE@{ub}

 ESA asm:

           switch ManLaMis.w
           -> #2 (lea.l  PorcaVacca,a0
                  bsr    Say)
           -> a0 (lea.l  Okkebbello,a0
                  bsr    Say)
           -> xz (bsr    GetUpset)
           def (move.l #"OKOK",Risposta)
           eswitch
@ENDNODE

*******************************************************************************
@NODE ongoto "Jump Table (normal branches)"

@{b}@{u}on ... goto ... @{ub}@{uu}

@{b}SYNTAX@{ub}

 "on" V:val "," RX:reg "goto" ["safe"](S0:sym, S1:sym, ... , Sn:sym)


@{b}MEANING 0@{ub} ("safe" not declared)

 1. evaluates V
 2. V=x and x<=n: the execution continues at the address Sx
    V=x and x>n : get ready for a GURU!!!


@{b}MEANING 1@{ub} ("safe" declared)

 1. evaluates V
 2. V=x and x<=n: the execution continues atthe address Sx
    V=x and x>n : jumps to the first instruction after "on ... goto"


@{b}NOTES@{ub}

 - RX is the register which can be freely trashed to perform the jump;
 - RX's size is discarded;
 - V is loaded to RX only if V<>RX (obvious enough...);
 - the size of V can be only ".w" and ".l" (def.: ".w");
 - no check is done on SXes...


@{b}EXAMPLE 0@{ub}

 ESA asm:

           on d5,a6 goto (.shoot, .block, .pass, .jump
                          .steal, .dunk, .run, .fly )  ;this is very legal!

 68k asm:

           move.w     d5,a6                      ;get V
           jmp        ([.0000000,pc,a6.w*4])
.0000000   dc.l       .shoot,.block,.pass,.jump,.steal,.dunk,.run,.fly


@{b}EXAMPLE 1@{ub}

 ESA asm:

           on UnitID.w,a2 goto safe (68k,Copper,Blitter,Paula)

 68k asm:

           move.w     UnitID,a2                ;get V
           cmp.w      #$0004,a2                ;is it valid?
           bhs        .0000001                 ;if not...
           jmp        ([.0000002,pc,a2.l*4])
.0000002   dc.l       68k,Copper,Blitter,Paula
.0000001
@ENDNODE

*******************************************************************************
@NODE ongosub "Jump Table (subroutines)"

@{b}@{u}on ... gosub ...@{ub}@{uu}

@{b}SYNTAX@{ub}

 "on" V:var","RX:reg "gosub" ["safe"](S0:sym, S1:sym, ... , Sn:sym)


@{b}MEANING 0@{ub} ("safe" not declared)

 1. evaluates V
 2. V=x and x<=n: jumps to the subroutine indicated by Sx
    V=x and x>n : get ready for a GURU!!!
 3. the code at the address Sx is expected to return with an "rts"
 4. execution goes on with the first instruction after "on ... gosub"


@{b}MEANING 1@{ub} ("safe" declared)

 1. evaluates V
 2. V=x and x<=n: jumps to the subroutine indicated by Sx
    V=x and x>n : goes to 4
 3. the code at the address Sx is expected to return with an "rts"
 4. execution goes on with the first instruction after "on ... gosub"


@{b}NOTES@{ub}

 - RX is the register which can be freely trashed to perform the jump;
 - RX's size is discarded;
 - the size of V can be only ".w" and ".l" (def.:".w");
 - no check is done on SXes...


@{b}EXAMPLE 0@{ub}

 ESA asm:

Mangas     on Rumiko.w,a0 gosub (.ataru, .akane, .lum, .ranma)

 68k asm:

Mangas     move.w     Rumiko,a0
           jsr        ([.0000003,pc,a0.w*4])
           bra        .0000004                  ;skip jump table and continue
.0000003   dc.l       .ataru,.akane,.lum,.ranma
.0000004


@{b}EXAMPLE 1@{ub}

 ESA asm:

            on fool.l,a3 gosub safe(
                                this
                                is
                                unquestionably
                                silly
                               )

 68k asm:

            move.l    fool,a3                 ;".l" is almost always useless!!!
            cmp.l     #$00000004,a3           ;safety check
            bhs       .0000005
            jsr       ([.0000006,pc,a3.l*4])
            bra       .0000005
.0000006    dc.l      this,is,unquestionably,silly
.0000005


@{b}EXAMPLE 2@{ub}

 ESA asm:

MyLife      on WhatIWillDo(),d0 gosub (code,PlayBBall,
                                       sleep,eat,study)
            bra.s     MyLife

            function WhatIWillDo():d0    ;d0 will get the default size (".l")
            repeat
            bsr _rnd
            until #4<>d0                 ;eh, eh...
            efunc

 68k asm:

MyLife      bsr       f0000000                  ;call the func - no RX loading!!!
            jsr       ([.000000C,pc,d0.l*4])    ;note also the size!!!
            bra       .000000D
.000000C    dc.l      code,PlayBBall,sleep,eat,study
.000000D
            bra.s     MyLife

f0000000                                        ;nothing here because I
                                                ;didn't save any reg
.000000E
            bsr       _rnd
            cmpi.l    #4,d0
            sne.b     -(sp)
            tst.b     (sp)+
            bne       .000000E
f0000001    rts
@ENDNODE

*******************************************************************************
@NODE bool "Evaluation of Boolean Expressions"

@{b}@{u}bool@{ub}@{uu}

@{b}SYNTAX@{ub}

 "bool" BL:boolexpr "," DEST:var


@{b}MEANING@{ub}

 1. evaluates BL
 2. writes its value (true, false) to DEST


@{b}NOTES@{ub}

 - the default size used for DEST is *byte*
 - to obtain the fastest results, use the default size, especially
   if DEST is not a dreg (see below)


@{b}EXAMPLE 0@{ub}

 ESA asm:

           bool       { {Suppaman=d4} & Slump} | {~{d4=d5}}, d2.l

 68k asm:

            cmp.l     Suppaman,d4
           seq.b      -(sp)
           tst.l      Slump
           sne.b      -(sp)
           move.l     d0,(-4,sp)
           move.b     (sp)+,d0
           and.b      d0,(sp)
           move.l     (-6,sp),d0
            cmp.l     d5,d4
           sne.b      -(sp)
           move.l     d0,(-4,sp)
           move.b     (sp)+,d0
            or.b      d0,(sp)
           move.l     (-6,sp),d0           ;BL evaluation
           move.b     (sp)+,d2             ;.l size doesn't affect
           extb.l     d2                   ;much the speed...


@{b}EXAMPLE 1@{ub}

 ESA asm:

           bool       Makusa,ObabaHaru.w

           bool       Makusa,ObabaHaru.b   ;default size

 68k asm:	

           tst.l      Makusa               ;1st "bool"
           sne.b      -(sp)
           move.l     d0,(-4,sp)
           move.b     (sp)+,d0
           extb.l     d0
           move.w     d0,ObabaHaru
           move.l     (-6,sp),d0           ;slooow...

           tst.l      Makusa               ;2nd "bool"
           sne.b      -(sp)
           move.b     (sp)+,ObabaHaru      ;much faster, huh?!?
@ENDNODE

*******************************************************************************
@NODE ProcDef "Defining Procedures"

@{b}@{u}Defining a Procedure@{ub}@{uu}

@{b}SYNTAX@{ub}

 "procedure" NAME:sym [",loc"] "(" [RL1:regslist] ")" ["," RL2:regslist]
     ...
     ...
     ...
 "eproc"


@{b}MEANING@{ub}

 1. a label is defined as the entry point of the procedure
 2. if RL2 is declared, the registers are stored in the stack with a
    movem
 3. the code "..." is copied (and processed, of course)
 4. if RL2 is specified, the registers are restored from the values
    previously saved in the stack (another movem)
 5. rts is put at the end of the procedure


@{b}NOTES@{ub}

 - RL1 tells ESA how to assign the parameters when this procedure
   is @{"called" link DefProcCall};
 - movems size is always long;
 - size of RL2 is always ".l";
 - "procedure" must be separated from NAME by one or more spaces
   or TABs, otherwise "procedureNAME" would be acknowledged as
   an instruction/macro/etc...
 - the exit point of the procedure is marked by a label to allow the
   @{"forced exit from the proc" link PFExit};
 - normally procedures' labels are global (@{"whatever char has been" link Usage 22}
   @{"chosen" link Usage 22} for labels); instead, if "loc" is declared, the procedure
   definition will be "local", i.e. its labels will start with '.';
 - NAME can be up to 30 char long;
 - don't put a label on the same line of "procedure" (why should you
   enter a proc in that way?!?);
 - ESA won't check for repetitions of procedure names (to avoid speed loss)


@{b}EXAMPLE 0@{ub}

 ESA asm:

           procedure  WaitMouse,loc()
.w         btst.b     #6,$bfe001
           bne.s      .w
           eproc

 68k asm:

.0000002                            ;local labels
.w         btst.b     #6,$bfe001
           bne.s      .w
.0000003   rts


@{b}EXAMPLE 1@{ub}

 ESA asm:

           procedure  SlowClr(a0/d0.b),a0/d1
           move.l     d0,d1
           lsr.l      #2,d1
           subq.l     #1,d1
.c         clr.l      (a0)+
           dbra       d1,.c         ;from "Writing Bad Code", Chapter 1...
           eproc

 68k asm:

p0000000   movem.l    a0/d1,-(sp)   ;save regs in RL2
           move.l     d0,d1
           lsr.l      #2,d1
           subq.l     #1,d1
.c         clr.l      (a0)+
           dbra       d1,.c
p0000001   movem.l    (sp)+,a0/d1
           rts


@{b}EXAMPLE 2@{ub}

 Go @{"here" link PFExit 55} to learn a way of using local definitions.
@ENDNODE

*******************************************************************************
@NODE DefProcCall "Calling Procedures"

@{b}@{u}Calling a Procedure@{ub}@{uu}

@{b}SYNTAX@{ub}

 NAME:sym [SZ:size] "(" [ ["sav:"] PARAMS:args] ")"


@{b}MEANING@{ub}

 1. if "sav:" is declared, stores the RL1 registers (declared in the
    @{"procedure definition" link ProcDef}) in the stack
 2. loads to RL1 the values of the parameters passed inside the brackets
 3. executes the proc code
 4. after the execution of NAME (if "sav:" is declared, the registers of
    RL1 are restored) the program continues with the 1st instruction
    after this call


@{b}NOTES@{ub}

 - procedure calls can only be put in the instruction field;
 - SZ is the size to be used for the bsr (default: none);
 - when SZ=".l", the instruction jsr is used instead of bsr.l, to easily
   allow calls to other code sections;
 - if one of the args matches exactly the corrispondent destination register
   in RL1, no "move" is done!


@{b}EXAMPLE 0@{ub}

 ESA asm:

           WaitMouse.s()
           bra        SomewhereElse       ;avoid "collisions" with procs...

           procedure  WaitMouse,loc()
.w         btst.b     #6,$bfe001
           bne.s      .w
           eproc

 68k asm:

           bsr.s      .0000000
           bra        SomewhereElse

.0000000
.w         btst.b     #6,$bfe001
           bne.s      .w
.0000001   rts


@{b}EXAMPLE 1@{ub}

 ESA asm:

           SlowClr( sav: #buffer , d1)
           bra        SomewhereElse

           procedure  SlowClr(a0/d0.b),a0/d1
           move.l     d0,d1
           lsr.l      #2,d1
           subq.l     #1,d1
.c         clr.l      (a0)+
           dbra       d1,.c         ;from "Writing Bad Code", Chapter 1...
           eproc

 68k asm:

           movem.l    a0/d0,-(sp)   ;"sav:" -> save regs in RL1
           move.l     #buffer,a0
           move.b     d1,d0         ;.b according to declaration
           bsr        p0000000      ;call proc
           movem.l    (sp)+,a0/d0
           bra        SomewhereElse

p0000000   movem.l    a0/d1,-(sp)
           move.l     d0,d1
           lsr.l      #2,d1
           subq.l     #1,d1
.c         clr.l      (a0)+
           dbra       d1,.c
p0000001   movem.l    (sp)+,a0/d1
           rts


@{b}EXAMPLE 2@{ub}

 ESA asm:

           SlowClr.l(sav:#Buffer,d0)     ;same proc as above

 68k asm:

           movem.l  a0/d0,-(sp)
           move.l   #Buffer,a0           ;only a0 loaded!
           jsr      p0000002             ;jsr instead of bsr
           movem.l  (sp)+,a0/d0
@ENDNODE

*******************************************************************************
@NODE PFExit "Premature Exit from a Procedure or Function"

@{b}@{u}exit@{ub}@{uu}

@{b}SYNTAX@{ub}

 "exit"[SZ:size]


@{b}MEANING@{ub}

 1. the last procedure/function being defined is forced to terminate
    (a jump to the end label is performed)


@{b}NOTES@{ub}

 - SZ is the size to be used for the bra (default: none);
 - make sure that the sp is in the same position when the proc/func
   was entered, otherwise a crash is almost sure!
 - if inside a func, don't forget about the return value...


@{b}EXAMPLE 0@{ub}

 ESA asm:

           procedure  UpperCase(a0/d0),d0-d1/a0
           IFNE       TEST_ON                   ;if we're in test mode,
           exit.s                               ;we wanna do nothing...
           ENDIF
           moveq.l    #$ef,d1
           subq.l     #1,d0
           expire     d0=d0
           and.b      d1,(a0)+
           nexp,eq
           eproc

 68k asm:

p0000000   movem.l    d0-d1/a0,-(sp)
           IFNE       TEST_ON
           bra.s      p0000001                  ;jump to exit label
           ENDIF
           moveq.l    #$ef,d1
           subq.l     #1,d0

.0000002
           and.b      d1,(a0)+
           dbeq       d0,.0000002
p0000001   movem.l    (sp)+,d0-d1/a0
           rts


@{b}EXAMPLE 1@{ub}

 ESA asm:

           procedure  StrangePlot(a0),d0-d1/a0

           expire     d0=#199
           move.b     fx(d0),(a0)+
           nexp

           exit                                   ;fx *MUST* be skipped!!!

           function   fx,loc(d1):d1               ;local function definition:
           mulu.w     d1,d1                       ;since StrangePlot() is
           eori.l     RndSeed,d1                  ;global, fx() isn't visible
           efunc                                  ;externally

           eproc

 68k asm:

p0000000   movem.l    d0-d1/a0,-(sp)

           move.w     #199,d0
.0000004
           move.l     d0,d1
           bsr        .0000002
           move.b     d1,(a0)+
           dbra       d0,.0000004 

           bra        p0000001

.0000002
           mulu.w     d1,d1
           eori.l     RndSeed,d1
.0000003   rts

p0000001   movem.l    (sp)+,d0-d1/a0
           rts
@ENDNODE

*******************************************************************************
@NODE FuncDef "Defining Functions"

@{b}@{u}Defining a Function@{ub}@{uu}

@{b}SYNTAX@{ub}

 "function" NAME:sym [",loc"] "(" [RL1:regslist] ")" ["," RL2:regslist] ":" OUT:var
     ...
     ...
     ...
 "efunc"


@{b}MEANING@{ub}

 1. a label is defined as the entry point of the function
 2. if RL2 is declared, the registers are stored in the stack with a
    movem
 3. the code "..." is copied (and processed, of course)
 4. if RL2 is specified, the registers are restored from the values
    previously saved in the stack (another movem)
 5. rts is put at the end of the function


@{b}NOTES@{ub}

 - RL1 tells ESA how to assign the arguments when this function
   is @{"called" link DefFuncCall};
 - OUT tells ESA where to get the function's result from;
 - pay attention to RL2 and OUT!!! RL2 *SHOULD NOT* contain OUT,
   if OUT is a reg (*no* check)!!!
 - "function" must be separated from NAME by one or more spaces
   or TABs, otherwise "functionNAME" would be acknowledged as
   an instruction/macro/etc...
 - the exit point of the function is marked by a label to allow the
   @{"forced exit from the func" link PFExit};
 - normally functions' labels are global (@{"whatever char has been" link Usage 22}
   @{"chosen" link Usage 22} for labels); instead, if "loc" is declared, the function
   definition will be "local", i.e. its labels will start with '.';
 - NAME can be up to 30 char long;
 - don't put a label on the same line of "function" (why should you
   enter a func in that way?!?);
 - size of OUT is used only if inside a boolexpr;
 - ESA won't check for repetitions of function names (to avoid speed loss)


@{b}EXAMPLE 0@{ub}

 ESA asm:

           function   SetDMA(d0.w),d1:d0
           move.w     $dff002,d1
           ori.w      #$8000,d0
           move.w     d0,$dff096
           move.w     d1,d0
           efunc

 68k asm:

f0000000   movem.l    d1,-(sp)            ;save regs in RL2
           move.w     $dff002,d1
           ori.w      #$8000,d0
           move.w     d0,$dff096
           move.w     d1,d0
f0000001   movem.l    (sp)+,d1
           rts


@{b}EXAMPLE 1@{ub}

 ESA asm:

           function   GetMess(), d0-d7/a0-a6 :MessAmount
           lea.l      TileTable,a0
           bsr        MessWithRegs
           move.b     (a5),MessAmount
           efunc

 68k asm:

f0000002   movem.l     d0-d7/a0-a6,-(sp)
           lea.l       TileTable,a0
           bsr         MessWithRegs
           move.b      (a5),MessAmount
f0000003   movem.l     (sp)+,d0-d7/a0-a6
           rts


@{b}EXAMPLE 2@{ub}

 Go @{"here" link PFExit 55} to learn a way of using local definitions.
@ENDNODE

*******************************************************************************
@NODE DefFuncCall "Calling Functions"

@{b}@{u}Calling a Function@{ub}@{uu}

@{b}SYNTAX@{ub}

 NAME:sym [SZ:size] "(" [ ["sav:"] PARAMS:args] ")"


@{b}MEANING@{ub}

 1. if "sav:" is declared, stores the RL1 registers (declared in the
    @{"function definition" link FuncDef}) in the stack
 2. loads to RL1 the values of the parameters passed inside the brackets
 3. executes function code
 4. after the execution of NAME (if "sav:" is declared, the registers of
    RL1 are restored) the program continues with the 1st instruction
    after this call


@{b}NOTES@{ub}

 - a function can be called only as an argument of an asm instruction or ESA
   construction, i.e. you can't put it in the label/instruction fields;
 - SZ is the size to be used for the bsr (default: none);
 - when SZ=".l", the instruction jsr is used instead of bsr.l, to easily
   allow calls to other code sections;
 - since ESA is fully orthogonal, functions can be used everywhere their
   return type is expected to be found;
 - when "sav:" declared make sure that OUT (returned by the function),
   if reg, is not included in RL1;
 - be extremely cautious when calling functions inside other ESA constructs,
   as you could accidentally trash some variables/registers!


@{b}EXAMPLE 0@{ub}

 (refer to @{"these examples" link FuncDef 46})

 ESA asm:

           move.w     SetDMA.l(#$f),OldDMA       ;1st
           move.w     SetDMA(sav:#$f),OldDMA     ;2nd

 68k asm:

           move.w     #$f,d0              ;load arg
           jsr        f0000000
           move.w     d0,OldDMA           ;1st OK!
           movem.l    d0,-(sp)            ;"sav:" used in the 2nd
           move.w     #$f,d0
           bsr        f0000000
           movem.l    (sp)+,d0            ;WRONG! the result
           move.w     d0,OldDMA           ;is lost!!!


@{b}EXAMPLE 1@{ub}

 ESA asm:

           bool       #24=GetMess(),d7  ;complicated one this...

 69k asm:

           bsr        f0000002          ;execute function
           cmpi.b     #24,MessAmount
           seq.b      -(sp)             ;BL evaluation
           move.b     (sp)+,d7          ;result
@ENDNODE
