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