Re: A86:OnTemp.asm


[Prev][Next][Index][Thread]

Re: A86:OnTemp.asm




> The only reason these might not work is that a compiler sometimes has
trouble
> figuring out what the parenthesis mean (whether you're accessing memory or
> just performing order of operations).  It's easier to just do code like
this:

In cases like he posted, there should be no ambiguity.  With an assembler
that uses a TASM table like format, it uses simple (heh...) pattern matching
to find the correct instruction.

 ld hl,foo+(4*bar)

In this case, the starting character of the expression, 'f', would not match
anything in the table, so it uses the version that uses an expression.
Reversing that example makes it quite different:

 ld hl,(4*bar)+foo

This seems a little trickier upon first examination.  The opening
parenthesis matches the version in the table for indirection.  After this an
expression is expected, so '4*bar' is parsed as an expression.  The closing
parenthesis ends the expression, because it does not match with an opening
parenthesis.  It does match the closing parenthesis for the indirection
version in the table.  However, when the plus character is encountered, it
does not match the table.  The next version that matches is the constant
load version, so the entire line is treated as an expression, which works
without problems.

However, the problem here is if the '+foo' was eliminated:

 ld hl,(4*bar)

The parser will be able to match the indirection version with '4*bar' as an
expression, and can match the constant load version with '(4*bar)' as an
expression.  Both are legal, and the one that is matched depends on the
order that they occur in the table.  The rules for a legal table would
dictate that the indirection version come first, however.

There are two ways that I know of to solve this problem.  The first way is
to not enclose an expression in an outer layer of parenthesis unless the
instruction uses indirection.  To do a constant load, it could be written as
follows:

 ld hl,(4*bar)+0

This has the same effect, but eliminates the ambiguity.  The other way is to
not use parenthesis for indirection.  Many assemblers I've seen for x86 use
brackets for this purpose, as do many other assemblers.  It is easy to
modify the TASM table to allow this, and if versions for brackets were added
instead of replacing the ones with parenthesis, it would support both.  In
fact, the tasm69.tab file (the table for Game Boy) does this.

I've always used parenthesis and not brackets, so it seems natural.  But
brackets do actually seem to make more sense, and are possibly easier to
type (since they don't require the shift key).  That's the nice thing about
having a loadable table for an assembler, because you can change the
instruction format to whatever suits you best (of course, for something like
the calc, this would not be good, for the purposes of standards and such).

> Of course, there are much more efficient ways of getting checksums, but...

I might have screwed this up a bit, it's been a while and I did this from
memory.  This should be the most efficient way to calculate checksums.  Note
that the ROM uses the method you posted: loading constant values into HL (of
course it does it backwards).

CalcChecksum:
 ld hl,alt_on_exec
 ld a,(hl)
 dec hl
 ld b,5
 ld de,$28
@loop:
 add hl,de
 add a,(hl)
 djnz @loop
 ld (alt_on_chksum),a




References: