[comp.sys.cbm] Commodore Macro Assembler -- long review

doug@edge.UUCP (Doug Pardee) (08/11/87)

Well, I finally needed to get an assembler for the ol' 64.  After looking
all over town, the only one available off-the-shelf was Commodore's Macro
Assembler.  It lists for $39.95, but the discount price was $19.95.  Since I
needed an assembler, and a couple of netters had indicated that it wasn't as
bad as you'd expect from Commodore, and $20 ain't too much, I went with it.

I've completed my first application with it, and so here are my initial
thoughts.  Note that my perspective is that of a professional assembly
programmer -- I've been doing this stuff for 17 years on micros, minis,
small and large mainframes, and custom bit-slice engines.  I tend to want
features that a lot of people never thought of...

Overall, it's just what it claims to be.  It provides a reasonable (but not
great) environment for serious programming in 6502 assembly language.

My major unsatisfied desire is for some real support to let me assemble
modules separately and link them together.  A minor gripe is that a lot of
typos get through without complaint; I got burnt by this twice.

Here's my list of features I consider desirable in an assembler, and how the
Commodore Macro Assembler (CMA) stacks up.

a) [For those which include an editor] full screen editing:  CMA includes
   a program they call an editor which simply patches the BASIC editor so
   that you can save text de-tokenized without line numbers, and to load
   and auto-number unnumbered text.  And adds a couple of features like
   renumber and global search and replace.  You get the same "full-screen"
   edit capabilities that you get with BASIC:  the big annoyances are
   having to list lines before you can edit them, and having to use the
   shift-space in order to indent lines which have no label.

b) Mnemonics, pseudos, and overall syntax conforms to recognized standards:
   CMA basically does -- I'm not knowledgeable on the more exotic standards
   like macro definition syntax for the 6502.

c) Character constants:  Yes.

d) String data definitions:  Yes.

e) Expressions in operands:  CMA allows simple expressions with +-*/ only,
   evaluated left-to-right, no precedence nor parentheses recognized.

f) Literals: No.

g) Ability to "include" source from another file:  CMA allows one level of
   include, and unlimited chaining at either include or base file level
   (it's limited by the 1541's inability to keep many files open at once).

h) Code libraries:  No; each included code segment is in its own file.

i) Conditional assembly:  No.

j) Macros:  CMA has rudimentary macros.  Up to 9 positional parameters,
   and 4-character local symbols are generated for any unspecified
   parameters.  Lack of conditional assembly means that all invocations
   must give the same instruction sequence.  No "repeat" mini-macro such
   as Microsoft likes to put into their assemblers.  Cannot call a macro
   with an indexed operand -- the comma marks the end of the parameter.

k) Macro libraries:  No.

l) Symbol attributes:  No, but then they wouldn't be very useful without
   conditional assembly anyway.

m) Dsects:  No, but not very important on a 6502 because of its limited
   addressing modes.

n) Listing with generated code:  Yes.  Text is reformatted, with labels,
   opcodes, operands, and comments put into predefined columns.

o) Listing control:  CMA provides pseudos for titling, page-ejecting,
   and line skipping.  An "option" pseudo controls whether the entire
   code for string data is printed, or just the first few bytes.  It
   also controls listing on/off, and printing of an errors-only listing.
   Conflicting documentation suggests it might also be able to control
   printing of the symbol table.  No control of macro expansion listing.

p) Cross-reference:  Yes.  (I haven't run this yet, so this is based on
   what the manual says).  Requires a second assembly run (1541 can't have
   source, include, object, and 2 cross-ref files all open at once).  Then
   you run a separate cross-ref program.

q) Register cross-ref:  I doubt it; but on a 6502 it'd be superfluous.

r) Relocatable object code:  No.  CMA does generate its own form of object
   code which allows scatter loading, but by absolute address only.  The
   assembler comes with loaders for this format, and monitors which can
   dump memory to disk in a form which the LOAD command can then process.

s) Symbolic linking of externals:  No.

t) Subroutine libraries:  No; wouldn't be useful without relocatable object
   and symbolic linking anyway.

A few CMA-specific comments...  one of the reviews posted previously by a
netter said that there was a lot of disk swapping required because the
assembler's disk is full.  I found this not the case -- the assembler is
<10K long, and there are a half-dozen <1K utilities also on the disk.  I
copied them over to a working disk (no copy protection), and have plenty of
room on that working disk without disk swapping... so far, at least.

The documentation was adequate, covering the subject but not going into much
depth.  It did mention a hardware bug in the 6502 I'd never heard of: the
status byte pushed by the PHP instruction has the "B" bit turned on.  As
with every assembler for every machine I've seen, the manual is not even
close to a tutorial; novice assembly programmers should buy a textbook too.

The monitor supplied is pretty simplistic.  I mean, it doesn't even have a
"breakpoint" command.  You want breakpoints?  Just patch in a 00 byte at the
appropriate spot (after writing down the original contents so you can patch
it back).  It also mangles the system vectors such that the only way to exit
the monitor is to do a hard reset; this is unnecessarily primitive.

The two uncaught typos that skewered me:  my first program was converted
from a different assembler, which used "<symbol" instead of "#<symbol".  CMA
didn't object to this non-standard coding, but counted 3 bytes in pass 1 and
2 bytes in pass 2, resulting in a phase error which the assembler should
have caught but didn't.  A side effect was that garbage was also generated
at each label thereafter.

The second problem occurred when my flying fingers typed "RST" instead of
"RTS".  The assembler simply took that as being a label, and generated no
code and no diagnostic.  Yeah, I know that's what the book says it'll do,
but that's why most assemblers either require labels to start in column 1
or to be followed by a colon.  Gonna hafta be careful, I guess.
-- 
Doug Pardee, Edge Computer Corp; ihnp4!mot!edge!doug, seismo!ism780c!edge!doug

gary@ruby.UUCP (08/18/87)

Favorite color: blue

[ if you can see this, there is a bug in your line-eater]
 
   Interesting to see that someone is still using the good 'ol Commodore
Macro Assembler.  I kinda like it; it's quaint, and inexpensive (I think I
paid $12 for it a few years ago - before it got marked up to $30, and then
back down).  Anyway, conditional assembly DOES exist, if you're willing to
put up with some slightly bizarre syntax.  Below is a list of some features
that didn't seem to make it into the documentation that came with the
package. I think that there might be one or two other things hidden in there;
look through the binary till you find the token tables - I think there's
a couple of alternate names for existing pseudo-ops or somesuch. Enjoy.

     -=+=-=+=--=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-

               UNDOCUMENTED COMMODORE ASSEMBLER FEATURES
                      Gary Hanson (rev 16-Aug-85)


       Undocumented Pseudo-ops

  .LIST Turn on listing
  .NOLIST Turn off listing

       
       Undocumented Option
   
  .OPT NOSYM  Turn off symbol table on lineprinter

       This option suppresses the listing of the symbol table on the line-
  printer. The option to enable the symbol table list is .OPT SYM  There is
  no way to get a symbol table on the screen, only the lineprinter.



       Conditional Assembly

  .IFE <expr> assemble if expression equals zero
  .IFN <expr> assemble if expression not equals zero

  Syntax:
 
  .IFE expr <
       (whatever)
  >

     There must be a less-than sign (<) on the line with the  pseudo-op,  and
the  block  to be conditionally assembled must end with a greater-than in the
first character (leave the rest of the line blank).

       Example

  1000 DEBUG = 0
  1010       LDA  33
  1020       STA CHAR
  1030       .IFN DEBUG <
  1040       JSR CHROUT
  1050       RTS
  1060 >
  1070       JMP DOMORE

     The two lines JSR CHROUT / RTS would not be assembled unless  the  value
of the DEBUG flag was nonzero.


       Usage Hints

     When going from the editor to the  assembler,  always  KILL  the  editor
first.   I'm  not sure that this is really necessary, but it seems to avoid a
condition where some of the system pointers get messed up.   Also,  when  the
assembler  asks  whether  you  want a listing, type N to get a listing on the
screen, or <CR> to get a listing on the printer.  Unplug the printer  to  get
no listing.  This is not explained well in the documentation.

     -=+=-=+=--=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-

    Gary Hanson   Tektronix IDG    ...!tektronix!ruby!gary
                                   gary@zarquon.GWD.TEK.COM

    No mice allowed in my house - that's why I have a cat.

elg@killer.UUCP (Eric Green) (08/23/87)

in article <894@edge.UUCP>, doug@edge.UUCP (Doug Pardee) says:
> a) [For those which include an editor] full screen editing:  CMA includes
>    a program they call an editor which simply patches the BASIC editor so
>    that you can save text de-tokenized without line numbers, and to load
>    and auto-number unnumbered text.  

I always used Easy Script to write my Commodore assembler files. In fact,
that's the only reason I bought Easy Script (this was way back in the dark
ages) -- it produces standard Commodore ASCII files. In reality, any word
processor capable of exporting data as a standard Commodore ASCII file, can be
used to write Commodore assembler code.

> b) Mnemonics, pseudos, and overall syntax conforms to recognized standards:
>    CMA basically does -- I'm not knowledgeable on the more exotic standards
>    like macro definition syntax for the 6502.

You better bet it does. The assembler documentation is only barely translated
from the documentation of the MOS mainframe cross-assembler. I remember being
amused by the mainframisms that had escaped the editor.

> The monitor supplied is pretty simplistic.  I mean, it doesn't even have a
> "breakpoint" command.  You want breakpoints?  Just patch in a 00 byte at the
> appropriate spot (after writing down the original contents so you can patch
> it back).  It also mangles the system vectors such that the only way to exit
> the monitor is to do a hard reset; this is unnecessarily primitive.

Use a "g e39b" to do a warmstart of BASIC. or whatever 64738 is for a cold
start. The problem is that it uses zero page locations that BASIC also uses,
FUBAR'ing the BASIC interpreter. But there's no zero page locations that BASIC
does NOT use! :-). 

Actually, I'm surprised you didn't mention the biggest and main drawback of
the Commodore assembler -- 6 character labels. Yeah, I know IBM people think 6
characters is enough to write Shakespeare in, but us ordinary folks have
trouble thinking up meaningful 6-character label names. Leading to the
situation where you have 10 labels in a row named "loop1" "loop2" ...
"loop10". 6 significant characters is OK if it allows labels longer, but lops
off the excess. But the CMA won't generate code if there's a 7-character label
-- it barfs (Bad ARgument Function, for Maclispers :-). That was what led to
me getting the Merlin assembler -- it was non-standard, but at least it
allowed 12-character labels, and had some rudimentary macro capabilities. 

The three C-64 assemblers I've had much experience with are CMA, Merlin, and
PAL. PAL is a pile of garbage, I can't believe anybody ever paid money for
that thing, but Steve Punter's file-transfer code is written with it, so I
gotta use it for that. Merlin is non-standard, but usable -- my biggest
problem was finding a text editor that'd edit its files (finally, I settled on
the full-screen editor that comes with the PROMAL compiler). CMA has that
problem with 6-character labels (I prefer "stringmovlp" to "loop23" :-).
Although there is a hacked CMA going about that allows 12-character labels
(courtesy of the guys at Fiscal Information, who accidently left it on one of
their early hard drives when it was shipped -- Xetec markets their hard drive
now). 

The assembler I use now is CASM under the C-Power environment in Commodore-128
mode. It produces relocatable code, and has most of the features of the CBM
assembler (minus macros). Nice to only re-assemble one 500-line file instead
of having to assemble 3,000 lines spread over 5 files all at one time....
like the C-Power full-screen editor, too.

The all-time winner seems to be the assembler that Fred Bowen promised us, a
CBM assembler for the 128 mode, which produces relocatable code, AND has all
the macro etc.  capabilities.... and speed, too (CASM, since it is written in
"C", is kinda sluggish, if ya know what I mean). Unfortunately, that's
currently vapor-ware (C'mon, Fred, tell QA to hurry up!). We'll have to see...
but I do know that my check (well, Bayou Telecommunication's check) is going
in the mail as soon as that li'l baby is announced (why not, I've collected
just about every other assembler worth collecting!).
--
Eric Green   elg%usl.CSNET     Ollie North for President:
{cbosgd,ihnp4}!killer!elg      A man we can believe (in).
Snail Mail P.O. Box 92191      
Lafayette, LA 70509            BBS phone #: 318-984-3854  300/1200 baud