home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-23 | 46.3 KB | 1,364 lines |
- ----------------------------------------------------------------------
- Copyright (C) 1990 by Natürlich!
- This file is copyrighted!
- Refer to the documentation for details.
- ----------------------------------------------------------------------
-
- NASM65 --- an Atari 8-Bit Crossassembler for the Atari ST (et al.)
-
-
- Manual V1.8 for NASM65
- Currently not quite up to date
-
- Copyright © 1992 by Natürlich!
- on sources, binaries and manuals
-
-
- »» Bang that Bit that doesn't Bang ««
-
-
-
-
- I n t r o d u c t i o n
-
- NASM65 is a <portable> single-pass cross-assembler that produces 6502
- code. NASM65 currently runs on 680x0 Ataris under TOS, on the AMIGA
- and apparently under UNIX. It its conceivably portable to MSDOS.
- The assembler produces two kinds of output, directly executable code
- for the Atari 8-Bit computer (FF FF headers and all that...) or
- linkable modules to be used with NLINK65. Instantly executable code
- (furtheron referred to as "runnable") is non-relocatable and
- non-linkable. The other kind of output are relocatable and linkable
- object files. That production mode is further on referred to as
- "relocatable". NASM65 is closely compatible to MAC65 from OSS
- (now ICD), but not 100%. The differences will be noted later on.
- Compatibility worsens somewhat when relocatable output is produced.
- (Apple and C64 users, have a peek at XTRCTBIN)
-
-
-
- U s a g e
-
- nasm65 [-{rwbqx}][-{tn}][-e number][-o binary][-h includedir] <source>
-
- -t TOS switch, wait for a keypress after running
-
- -w The "what the ...." switch, even though errors occured an output
- file is generated.
-
- -r The runnable switch. NASM65 will create an Atari 8-Bit binary
- file for direct execution
-
- -h Supply alternate header directory (Default is taken from the
- Environment variable >INCLUDE<)
-
- -e Limit the number of errors: 0 = show all
-
- -o Specify alternate output file pathname (or filename)
-
- -b Don't emulate MAC/65 too closely (will improve output in the
- runnable mode)
-
- -x List all global variables. Defined globals appear with a '*'
- in front.
-
- -q Quiet flag, probably turns up the volume
-
- -n Noisy tokenization. Try it on your ST.
-
- There is no order in which switches or the source file have to appear.
-
-
-
- C r e a t i n g r u n n a b l e A T A R I 8 - B i t f i l e s
-
- Type from a shell:
- nasm65 -r <source.s65>
-
- That will create a output file {source}.COM
- Transfer this file (with NASTY for instance) to a 8-Bit Atari computer
- and execute it there.
-
-
-
- C r e a t i n g l i n k a b l e m o d u l e s
-
- Type from a shell
- nasm65 <source.s65>
- That will create a output file {source}.o65, that can then be linked
- together with other relocatable output files.
-
-
-
- H o w N A S M 6 5 f i n d s i t s f i l e s
-
- Source files:
-
- NASM65 first looks in the current directory for the file you specified
- on the command line. After that it tries again by replacing the filename
- extension with .S65. If that doesn't work either, NASM65 signals an
- error. This means if you type "nasm65 foo" and you have a file FOO and a
- file FOO.S65, the file "FOO" will be loaded.
-
-
- Include files:
-
- If the extension has been omitted and it looks like a filename,
- not a pathname, NASM65 will append the default extension .H65 and
- insert the default header path at the front.
- Else NASM65 looks first in the current directory for the include file.
- Afterwards NASM65 replaces the extension with .H65 and it will look
- in the directory given either by the environment variable INCLUDE or
- by the command option '-h'.
- If NASM65 fails again, it will try last to open the file without the
- .H65 extension.
-
-
-
- S o u r c e c o d e f o r N A S M 6 5
-
- Generally speaking MAC65 style code w i l l work with NASM65. Other
- assemblers' source (like SYNASM or MAE) might need to be converted to
- NASM65 syntax before assembly [a SED script might be helpful...].
- Problems may appear because of the single-pass structure of the
- assembler. Conventional assemblers use two passes, one pass collects
- all the symbols and if possible assigns values to them. The second pass
- actually produces the code. NASM65 tries to do it all in one pass.
- Of course there is the problem with forward references f.e.:
- ...
- bne bar
- inx
- bar clc
- ...
-
- When the assembler encounters "bne bar" it doesn't yet know, what
- value "bar" has and so can't produce proper code for that branch
- yet. Only when the bar label is encountered is generation possible.
- Therefore NASM65 has some limitations on the code that it can produce.
- You will find out about it...
-
-
-
- A f e w g o l d e n r u l e s
-
- [Take those marked with a ! really seriously]
-
- 1! Don't produce code for zeropage ($00-$FF), be careful of
- wraparounds $FFFF-$00 if you assemble ROM-code.
-
- 2! Define macros and equates EARLY! the sooner the better.
-
- 3. The fewer forward references you use, the less trouble you and
- NASM65 will have. Forward references are neccessary only for
- »Branches«, »Subroutines« and »Data«. Coding like this
- lda #$40
- sta nmien
- nmien = $D40E
- is not only in bad style, it's screamingly inefficient and doesn't
- work with NASM65 in the module mode.
-
- 4! In the "relocatable" mode, all label settings that are not PC-
- relative (f.e. `FOO=$D4' but not `FOO: LDA #2') must be
- done before the label is used.
- <label> = <value>
-
- 5! Never put macro definitions after their first invocation.
-
- 6. Try to define everything ahead of its first usage
-
- 7. Put macros and equates, especially if they are used in several
- different sources, in common include files. Never mind that
- file foo.s65 needs only one of the 100 macro definitions of
- "macro.h65" and 10 of the 500 equates of "defines.h65", NASM65 will
- be grateful! Be sure to keep PC-relative labels out of the
- include files as MUCH AS POSSIBLE. It makes for better style and
- also keeps the error count down, when linking your objects.
-
- 8. Always remember that MAC65 is a three/two-pass NASM65 is a
- single-pass assembler.
-
- 9. Always define everyting ahead of its usage, except PC-relative
- labels like branch, subroutine and data labels.
-
- 10. Use local labels as much as possible. Use global labels only for
- system equates and subroutines and data that are accessed by out-
- side files.
-
- 11! If you are into conditional assembly and you like to control that
- with a central include file, be sure to use non-PC relative labels
- as switches.
- e.g.
- "header.h65"
- errorchecking
-
- "source.s65"
- .if .def errorchecking
- ...
- .endif
-
- will **FAIL**, when two files using the same include file are lin-
- ked together. Rather use
-
- "header.h65"
- errorchecking = 1
-
- "source.s65"
- .if .def errorchecking
- ...
- .endif
- or even better
- .if errorchecking
- ...
- .endif
-
- 12! Undefine forward referenced labels in .MACRO definitions. It pays!
-
- 13. Apple and C64 users oughta ensure that addresses in their object
- files are ascending from start to end. No code like this will
- work for you:
-
- *=$4000
- clc
- bcc foo
- *=$30F0
- foo rts
-
-
- T h e " r e l o c a t a b l e " m o d e
-
- The relocatable mode is the default mode, you did not supply a -r
- switch on the command line. That means NASM65 will produce an object
- file suitably for linking and relocation at runtime. The relocatable
- mode imposes some restrictions on your source code.
-
- Forward references can only be made to PC-relative addresses, that
- means that all System-equates like (STACK=$100) have to be done before
- they are used the first time. This is not really a problem since it is
- good style to use a central include file for global symbols that
- is read in at the beginning of the source. Since the linker can also
- only link PC-relative global symbols (local symbols and not PC-relative
- labels are not saved in the object file) NASM65 makes it a necessity.
- There is one exception to this rule, see 'Linking Zeropage-labels'.
-
- e.g.
- File "sys.h65" :
-
- NMIEN = $D40E
- STACK = $100
-
-
- File "s1.s65":
-
- .include #sys.h65
-
- foo:
- lda #$C0
- sta NMIEN ;; from sys.h65
- jsr bar ;; not in s1.65 or sys.s65 !! -> open reference
- bcc foo
- rts
-
-
- File "s2.s65":
-
- .include #sys.h65
-
- bar: ;; here it gets defined. NLINK s1 s2 would
- lda STACK ;; produce a file with bar in s1 correctly
- clc ;; set to the address of bar in s2
- adc STACK+1
- rts
-
- The second goal that was set for NASM65 (apart from being a MAC65
- compatible cross-assembler) was relocatability and linkability. And
- as far as *I* know, no assembler exists that does produce run-time
- relocatable 6502 code. The greatest problem with relocating 6502 code
- is with source code like this:
-
- lda #>foo ; get 16-Bit address into A an X
- ldy #bar-foo ; get length in Y
- ldx #<foo
- jsr print ; JSR to some routine
- bcc out
-
- foo: .byte "F.T.O.E. coming soon.." ; the message to be printed
- bar:
-
- Now for you the human, it's quite easy to figure out that the
- "lda" and "ldx" belong together, but for the relocating code it's not
- so easy. Semantic checking of this kind easily slides into the black
- magic dept. of computer science (--> A.I.) and that would be just
- overkill.
- Ok so there are some limitations in what you can do, here are a
- couple of things to know about NASM65.
-
- 0. Linkable labels are:
- ZEROpage labels declared with ==
- All PC-relative global labels
- All PC-relative macro labels, except those starting with @
-
-
- 1. Arithmetic with relative addresses is a tricky thing, since
- you don't know at assembly time, what the value is. Therefore
- many operations don't make sense any more. There are only a few
- operations you _can_ use with PC-relative labels. This does not
- apply to the runnable mode by the way.
- Coming up the only valid operations possible in the relocatable
- mode. Refer to the appendix for <words>...
-
- <value> <operation> <value> -> <value>
- <operation> <value> -> <value>
-
- <address> '+' <value> -> <address>
- <address> '-' <value> -> <address>
- <value> '+' <address> -> <address>
- <address> '-' <address> -> <value>
-
- '<' <address> -> <saddress> (* careful!! *)
- '>' <address> -> <saddress> (* careful!! *)
-
- For example:
-
- bput 1,:header,:l_header,X_IS_READY
- :header .byte "Starting off with this little test...",155
- :l_header = *-:header
-
- That ain't working...
- This will give a warning (not an error, although that might
- be changed in the future), because :l_header was assumed to
- be an address, but is in fact a value.
-
- bput 1,:header,:e_header-:header,X_IS_READY
- :header .byte "Starting off with this little test...",155
- :e_header
-
- THAT's the way you do it.
-
- 2. An immediate expression that takes either the LSB or the MSB of an
- PC-relative address like this
-
- lda #>bar ; grab MSB of `bar'
- bar:
- lda #<bar ; grab LSB of `bar'
-
- must start off with a '>' (that is "#>foo" or "#>[foo+1]")
- or with a '<'. Although in MAC65 "lda #LABEL" and "lda #<LABEL" is
- the same, it isn't for NASM65. Actually the same code will be
- assembled, but relocatability and linkability will be impaired.
- Note that there has been a change in operator precedence from MAC65
- concerning the unary '>' and '<' operators. Refer to the table in
- the appendix. MAC65 treated "lda #>foo-2" as "lda #[>foo]-2, but
- NASM65 treats it as lda #>[foo-2]. This might make recoding of some
- old code necessary.
-
- 3. .DS works very much different in the relocatable mode than in the
- runnable mode (see also "Other Useful Stuff To Know"). Since you
- can't use *= anyway, this is not the way to define zeropage labels
- or any other non-PC relative labels for that matter. Like
-
- *=$F0 ;;; WRONG
- SRC .ds 2
- *=$2000
- etc.
-
- 4. .= works different from the way it does in the runnable mode. MAC/65
- allows pass conditional assembly like this:
- pass .= pass + 1
- .if pass=1
- .include ...
- .endif
-
- Since NASM65 is single-pass, this isn't a useful technique anymore.
- Normally NASM65 would think that 'pass' on the right side of .= is
- a forward reference. But in the runnable, for enhanced com-
- patibility with MAC/65, pass will get the value of the program
- counter.
- In the relocatable mode, 'pass' on the right side of .= WILL be
- treated as a forward reference, resulting in numerous errors.
-
-
-
- L i n k i n g Z e r o p a g e - l a b e l s
-
-
- There is a way to link zeropage labels with NASM65, so that for
- example common vectors can be shared. As you have come to like
- it, here is an example to make the point:
-
- "a.s65"
- foo == $88 ; declare this 0-page label as linkable
-
- lda #>BAR ; just some stuff to fill up space
- sta FOO+1 ; simple expressions are OK
- lda #<BAR
- sta FOO
- jmp FUBAR
-
- bar: .byte $74
-
-
- "b.s65"
- .zext foo ; tell that foo is an external 1 byte address
- ; that shouldn't be relocated
- fubar:
- ldy #0 ; Let's use FOO
- lda (FOO),y
- sta $2C8
- rts
-
- NASM65 won't mind some simple arithemtic, as long as you don't use
- PC relative addresses. Note that $45 + $120 = $65 and not $165. Don't
- try to be overly clever with this feature, keep it simple and stupid
- and be happy that this works at all.
-
- What you must not do by the way is this:
-
- .ZEXT FOO ; that's ok
-
- FOOLSB = FOO ; but this and
- FOOMSB = FOO + 1 ; that won't work
-
- .ZEXT is more or a less a hack and conflicts with the generality of
- the rest of NASM65. Sorry. But doing this right would require
- a whole new internal assembler structure.
-
-
-
- D i f f e r e n c e s b e t w e e n M A C 6 5 a n d N A S M 6 5
-
- Text after a correctly parsed instruction is assumed to be part of the
- comment field by MAC65. NASM65 treats this as garbage. Every comment
- has to start with a semicolon ';'.
- f.e.
- lda #2loser comment w/NASM65
- is treated by MAC65 as
- lda #2 loser comment w/NASM65
- but generates an error with NASM65.
-
- obsolete directives
- .PAGE
- .TITLE
- .SET
- .OPT
- .TAB
- are parsed but nothing will happen.
-
- '>' and '<' (unary) have lower precedence.
-
- MAC65 generates a new binary header at least every 252 bytes (don't
- ask me why). You can check with CHKFFFF that actually the same amount
- of code (in the runnable mode of course) was generated by NASM65 but
- with much less headers. That makes by the way loading of binary files
- much faster and decreases overall size.
-
- The include syntax is similiar, but adjusts to your kind of OS. So
- you can't expect to assemble instructions like
- .include #D3:foo.bar
- properly on the ST for instance.
-
- NASM65 currently produces no listing file!
-
- .REF may now be used anywhere in an expression, whereas MAC65
- allowed .REF only in .IF expressions.
-
- .SET doesn't work anymore. Compiling with an offset must be (clumsily ?)
- simulated by using the linker.
-
- Due to the single-pass nature of NASM65, NASM65 does not do a third
- pass over macros like MAC65 does. For example:
-
- .macro bar
- jmp foo
- foo
- .endm
-
- *=$2000
- bar
- bar
- bar
-
- MAC/65 produces: NASM65 produces:
- $2000 jmp $2003 jmp $2003
- $2003 jmp $2006 jmp $2003
- $2006 jmp $2009 jmp $2006
-
-
- To alleviate this problem rewrite the macro as:
-
- .macro bar
- .if .def foo
- .undef foo
- .endif
- jmp foo
- foo
- .endm
-
-
-
- O t h e r u s e f u l s t u f f t o k n o w
-
- When assembling in the runnable mode, NASM defines a label "__RUN"
- for you. This way you can with the use of a simple .IF statement
- have a file that can be both, assembled as a standalone program and
- as a linkable module.
- e.g.:
- .if .def __RUN
- *=$3000
- .endif
-
- You have one new directive at your disposal. It's called .ALIGN and
- aligns the module on a given boundary (like a page f.i.).
-
- Also NASM always defines the label __NASM65, for conditional assembly
- depending on the assembler used for example.
-
-
-
- U s i n g r u n t i m e r e l o c a t i o n
-
- The bad news is that the mover isn't quite as smart as the linker
- and can't properly move all the code there is. To keep the MOVER happy
- you should obey these golden rules:
-
- |R_START means beginning of your code. This is the first assembled
- byte of the first object file linked.
- |R_END means end of your code. This is the last assembled byte of
- the last object file or library. (Excluding the mover)
-
- 1. The MOVER fixes all addresses that point into the program space
- starting from |R_START - 1 to |R_END, If you somehow managed to
- convince NASM65 to assemble |R_START-$100, you will surely lose.
- Also bad is coding like this:
-
- start:
- jmp *+40
- .byte "Fooble"
- end:
-
- This probably won't work anyway, but the MOVERs sure won't relocate
- it as well.
-
- 2. The MOVER needs some information about the program it has to move.
- This is done with the aid of two tables. I won't discuss the makeup
- of these tables, as it would be too much type work. But you can
- keep the size of these tables down, by keeping data and code as
- seperate as possible. But this is something you should only consider,
- if your program needs 32K file space.
-
- 3. Don't expect to get 65C02 insructions relocated correctly. 65C02
- compatibility was a last ditch effort on my part. Since the Atari
- 8-Bit doesn't have a 65C02 this isn't really a problem. Try it out
- though, maybe it will even work.
-
-
-
- E r r o r s
-
- Yes it can happen to the best of us. Errors in the source code. NASM65
- will try to tell you as clearly as possibly in 1000 words or less, where
- and why you lost. The form of the message is in most cases, something
- like this:
-
- "source filename"[ linenumber in source], <continued>
- macroname[ linenumber in macro], ... "Error [error message]"
-
- There are several different error levels
- a) normal errors -- f.e. syntax, undefined macro...
- b) fatal errors -- f.i. out of memory. file not found...
- c) internal errors -- this shouldn't happen
- d) serious ....up errors -- NASM65 crashed downright. VERY VERY BAD!
-
- You can fix errors of type 'a' and 'b', they are your problem. Errors
- of type 'c' and 'd' are NASM65's problem, there is probably nothing you
- can do.
-
- "Expression must be preceded by '<' or '>'" [relocatable only]
- This occurs when you tried to assemble either .BYTE <expr> or an
- immediate instruction like ADC #<expr> and <expr> is PC-relative.
- In this case you must specify, whether to use the MSB '<' or the
- LSB '>' of the value.
- Ex.
- .BYTE B8 ;; **ERROR** B8 undefined -> PC-relative fwd ref
- .BYTE <B8 ;; OK!
-
-
-
- W a r n i n g s
-
- Warnings aren't errors 'cause there is a good chance that the assembler
- will actually do what you want to happen. BUT if things go wrong it
- isn't a bad idea to look at the warnings.
-
-
-
-
-
-
-
-
-
-
- A p p e n d i x
-
-
-
- M e m o r y r e q u i r e m e n t s
-
- NASM65 is memory hungry. Although it does use dynamic memory allocation
- instead of fixed tables it needs after its load about 150K space to
- work in. For larger files figure about 1/4 MB. There is a real, true,
- honest-to-goodness garbage collector coming up in version 3.0 (sorry).
- (Well just maybe *NOT*)
-
-
-
- S o u r c e C o d e
-
- The lines of source must adhere to some positional restrictions as
- you may easily figure out from the schemata below. Just in case you
- never saw an assembler before.
-
- Beforehand introducing a few shortcuts
- [..] = optional something '..' enclosed in square brackets
- ^ = Start of line
- $ = End of line
- . = any number of SPACE or TAB but at least one
- _ = any number of SPACE or TAB possibly none
- X = any characters except LF possibly none
- other characters represent themselves
-
- ^_[;X]$
- ^[label]_;[X]$
- ^[label].[instruction.[#][_expr]]_[;X]$
- ^[label].[directive.[stuff][,stuff]*]_[;X]$
- ^[label].[macroname.[parameter][_,_parameter]*]_[;X]$
- ^[label].[assignment.[expr]]_[;X]$
-
- Examples:
- foo
- inx
- foo inx
- lda foo
- foo lda foo
- lda #2
- foo lda #2 ; this is a comment
- .byte 2
- foo .byte 2
- .byte 2,"FOO"
- foo .byte 2,"FOO"
- foo POKE foo,3
- foo = 34
-
-
-
- S p e c i a l s
-
- *
- * denotes the program counter or PC, and can be used in expressions
- like any other label.
-
- A
- Used by ROL ROR LSL LSR to indicate usage of the 6502 A-register.
- Therefore you can't use A as a label.
-
- X
- Y
- Used by indexed or indirect instruction such as LDA (FOO,X) or
- STA BAR,Y. Don't use X or Y as labels as well.
-
-
-
- I d e n t i f i e r
-
- An identifier is either a label or a macroname. The morphological
- structure of an identifier is simply any string of characters that
- is taken from this character set [A-Z a-z 0-9 $ @ _ . : ?].
- An identifier may not begin with a number. Non macro identifiers should
- not begin with a '@' and user identifiers should generally not start
- with a '_' (underscore), but this isn't enforced. An identifier must
- not just be "A" or "a", "X" or "x", "Y" or "y". Internally all
- identifiers are converted to uppercase, so that there is no difference
- between "small" and "SMALL". A label that begins with a ':' or '?' is
- always a local label.
- Label definitions may optionally be directly followed by a ':', which
- isn't part of the label. An <equate> is a label that gets its value
- by a '=' assignment.
-
- Examples:
- A = 45 ;; wrong!, you can't use A as a label name
- FOO = 23 ;; OK!
- FOO: inx ;; OK global label = "FOO"
- Foo:: inx ;; OK global label = "FOO:"
- :FoO: inx ;; OK local label = ":FOO"
- FoO:: inx ;; WRONG! This is the same label as the one two lines up
- ?_:_: DEX ;; OK local label = "?_:_"
- 01234 ;; WRONG! label would start off with a digit
- ?01234 ;; OK local label = "?01234"
- :01234 ;; OK local label = ":01234"
- ?01234 ;; WRONG! label is already defined (two lines up)
- .macro FOO ;; OK. Macros may have the same name as labels!
-
-
-
- A s s i g n m e n t s
-
- There are four different possibilities to assign a value to a label.
- Note that '^' denotes the beginning of a source line (as above). Also
- be aware that some of these <labels> are <equates>. The distinction
- is important when you look at macros.
-
- Type A:
- ^<label> = <expr>
- This assigns the value of <expr> to <label>. You can't overload
- this label with another assignment.
- Examples:
- foo = 2 ;; lda #foo would assemble to A9 02
- bar = *+foo ;; bar = PC + 2. PC-relative!
- NMIEN=$D40E ;; sta NMIEN would assemble to 8D 0E D4
- foo = 3 ;; doesn't work, cause foo is already defined!
-
- Type B
- ^<label> .= <expr>
- This is almost the same as <label> = <expr> with the difference
- that you can overload <label> again! Using .= with forward references
- is possibly dangerous.
- Examples:
- foo .= 2 ;; lda #foo would assemble to A9 02 <-+
- bar .= *+foo ;; bar = PC + 2. PC-relative! |
- NMIEN.=$D40E ;; sta NMIEN would assemble to 8D 0E D4 |
- foo .= 3 ;; Works fine, cause its a .= assignment -+
-
- Type C
- ^<label> == <expr>
- This is used in conjunction with .ZEXT. Tells the assembler to
- include this zeropage! label in the list of linkable symbols.
- Examples:
- foo == $56 ;; OK!
- foo == $456 ;; WRONG! only zeropage allowed
-
- Type D
- ^<label>
- A label that isn't followed by '==', '=' or '.=' takes on the
- value of *, the program counter.
- Example:
- foo jmp foo ;; endless loop!
-
-
-
- O p e r a t o r s
-
- [<expr>] Parenthesis (actually brackets)
- <expr> + <expr> Addition
- <expr> - <expr> Subtraction
- - <expr> Minus
- <expr> * <expr> Multiplication
- <expr> / <expr> Division
- <expr> \ <expr> Modulo
- These are the normal operators for unsigned 16-Bit values, that you
- know from C. And they behave that way too, 'cause NASM65 is written
- in C. Note that 16-Bits overflow after 65535 to 0.
- Some examples of results to expect
- 5/3=1 5/2=2 5/1=5 5/2*2=4 4+1-6=65535
- 4-2+2=4 4-[2+2]=0 4-2*2=0 5\3=1 8\2=0
- -1=65535 8+[-1]=7
-
- <expr> .NOT <expr> Boolean negation
- <expr> .AND <expr> Boolean AND
- <expr> .OR <expr> Boolean OR
- <expr> = <expr> Equality
- <expr> <> <expr> Inequality
- <expr> < <expr> Less than
- <expr> > <expr> More than
- <expr> >= <expr> More or equal
- <expr> <= <expr> Less or equal
- These too are quite like C. Everything which isn't 0 is taken to
- be 'true'. 0 therefore means 'false'.
- .NOT 0 = 1 0 .AND -2 = 0 1 .AND 1 = 1
- 5 .OR 0 = 1 0 .OR 0 = 0 .NOT 1 .OR .NOT 0 .AND .1 = 0
- 43 > 43 = 0 43 > -1 = 0 43 > 0 = 1
- 43 < 43 = 1 43 < -1 = 1 43 < 0 = 0
- 43 >= 43 = 1 43 >= -1 = 0 43 >= 0 = 1
- 43 <= 43 = 1 43 <= -1 = 1 43 <= 0 = 0
- 43 = 43 = 1 43 = -1 = 0 43 = 0 = 0
- 43 <> 43 = 0 43 <> -1 = 1 43 <> 0 = 1
-
- <expr> & <expr> Bitwise AND
- <expr> ! <expr> Bitwise OR
- <expr> ^ <expr> Bitwise EOR
- These are your regular bitwise operators, what is there to say ?
- Some examples just for fun:
- $0001 & $FFFE = $0000 $5AF0 & $5555 = $5050
- $0001 ! $FFFE = $FFFF $5AF0 ! $5555 = $5FF5
- $0001 ^ $FFFE = $FFFF $5AF0 ^ $5555 = $0FA5
-
- .DEF <label> Label defined ?
- .REF <label> Label referenced ?
- .DEF and .REF can be used to determine, whether a label has already
- been defined or whether it has been referenced already. There is
- unlike MAC65 no restriction on usage.
- Examples:
- .if .not .def foobar
- .error "Should have included fooble.foobar first!"
- .endif
- lda #.ref leopold * 6 ;; senseless, but it works!
-
-
-
- O p e r a t o r p r e c e d e n c e
-
- Associativity Precedence level Operator Description
-
- - 9 .DEF Special
- - 9 .REF Special
-
- L 8 - Unary minus
- L 8 .NOT Boolean NOT
-
- L 7 * Multiplication
- L 7 / Division
- L 7 \ Modulo
-
- L 6 + Addition
- L 6 - Subtraction
-
- L 5 ! Bitwise OR
- L 5 ^ Bitwise EOR
- L 5 & Bitwise AND
-
- L 4 < Most significant byte
- L 4 > Least significant byte
-
- - 3 <= Less or equal
- - 3 >= Greater or equal
- - 3 = Equal
- - 3 <> Not equal
- - 3 > Greater than
- - 3 < Less than
-
- L 2 .AND Boolean AND
-
- L 1 .OR Boolean OR
-
- L 0 , Seperator
-
-
-
- D i r e c t i v e s
-
- 1. A s s e m b l e r D i r e c t i v e s
-
- .ALIGN <expr>
- This is a special directive, that only works in the relocatable
- mode and only if no code yet has been generated! The point is
- that you sometimes want to align code on a page boundary for
- example display lists or display list interrupt routines.
-
- Aligns code to the next boundary given by <expr>.
- 0x1 == word align (2 bytes)
- 0x3 == lword align (4 bytes)
- 0xFF == page align (256 bytes)
- f.e.
- .align $FF
-
-
- .CALL <macroname> *** unimplemented, sorry ***
- This special directive may only be used IN macro definitions. It
- acts like a regular macro call, except that all the parameters of
- the macro, that does the call, are passed over to the newly called
- macro.
- Ex.:
- .macro x
- .dbyte %1,%2
- .endm
- .macro y
- .call x
- .endm
- y $0123,$4567
- produces, predictably, 01 23 45 67
-
-
- .END
- When NASM65 encounters this directive, the processing of source
- code is preempted.
-
-
- .IF <bexpr>
- <lines>
- .ELSE
- <lines>
- .ENDIF
- These directives provide the ability to selectively assemble some
- parts of the program and to leave some parts out. The use for this
- feature lies most importantly in macros as you can see in the
- supplied "MACROS.H65" file.
- This for example is the macro code, for the "generic" store
- absolute instruction. Actually only one of STA STX or STY will
- be assembled.
-
- .macro @stt
- @0 .= @a
- .if %0 = 2
- @0 .= %2
- .endif
- .if @0 = @a
- sta %1
- .else
- .if @0 = @x
- stx %1
- .else
- sty %1
- .endif
- .endif
- .endm
-
- Note that for .IF there has to be an .ENDIF and at most one .ELSE.
-
-
- .LOCAL
- Tells the assembler to "forget" all local labels up to this point.
- This means that the following will get you an error with a .LOCAL,
-
- ; Start of file
- jmp :foo
- .local
- :foo
- ; end of file
-
- whereas the second piece of code, will only work with the .LOCAL.
- Else you would have a doubly defined label.
-
- ; Start of file
- :loop dex
- bne :loop
- .local
- :loop inx
- bne :loop
- ; End of file
-
-
- .INCLUDE #<filename>
- Reads in the file specified by <filename> and treats this input as
- if it would have appeared in the original file. Technically you first
- .INCLUDE is your source!
-
-
- .ERROR <string>
- Creates a user error. This is like any other error that NASM65
- generates, but you can supply the error string (required). This may
- be useful, when writing .MACROs and you want to check that certain
- values are in the required range. This feature isn't really all that
- useful as OSS thinks it is. The assembler catches for example
- missing parameter errors anyway. MAC65 did too...
-
-
- .MACRO <macroname>
- <lines>
- .ENDM
- All <lines> are saved in an internal buffer and released upon
- invocation of <macroname>. f.e.
-
- LEOPOLD = $1234
- lda #0 ;; gets assembled as A9 00
- .macro foo ;; start of macro definition called "FOO"
- sta LEOPOLD ;; this will not be assembled at this time
- .endm ;; end of macro definition. Continue assembly
- nop ;; NOP gives an EA
- foo ;; Assembles now STA LEOPOLD into 8D 34 12
-
- The interesting thing about macros is that you can pass values to
- them. These are accessed with the % placeholder. Lets consider an
- example
-
- ;; simple POKE à la ATARI BASIC "POKE address,value"
- .macro poke
- lda #%2 ;; %2 means value from second parameter
- sta %1 ;; %1 means value from first parameter
- .endm
- ;; macro invocation
- poke $4000,124 ;; will assemble as LDA #124 STA $4000
-
- %0 contains the number of arguments passed to the macro.
-
- You can not only pass values but also strings to a macro. These
- are accessed with %$.
- f.e:
- .macro drop_printable
- .byte %$1,155,0 ;; Parameter %1 as string
- .endm
-
- drop_printable "Foo" ;; converts to .BYTE "Foo",155,0
-
- Parameters can have these four forms:
- %<value> ;; <value> gives index of integer parameter
- %(<label>) ;; value of label gives index of integer parameter
- %$<value> ;; <value> gives index of string parameter
- %$(<label>) ;; value of <label> gives index of string parameter
-
- No forward referencing is allowed with %[$](<label>). The label
- you use there must already be defined.
-
- Another example:
- .macro foo
- which .= %2 ;; use '.=' NOT '=' !!
- .byte %1
- .byte %$1
- .byte %(WHICH)
- .byte %$(WHICH)
- .endm
- MAGIC = $12
- foo MAGIC,4,"UNUSED","Hello"
-
- would be expanded to
-
- which .= 4 ;; which has value of 4
- .byte $12 ;; MAGIC (=$12) was passed as the first parameter
- .byte "MAGIC" ;; Yup! Useless but it works!
- .byte 5 ;; String length of "Hello World"
- .byte "Hello" ;; String of "Hello"
-
-
- Type D labels that appear in macro definitions can be reused again.
- The next example will not give errors on compilation, since "LEO" is
- reset every time foo is called.
-
- .macro foo
- leo inx
- .endm
- foo
- foo ;; OK!
- foo ;; OK!
-
- "LEO" is visible for code outside the macro after an invocation of
- "FOO". Forward references to labels in macros are OK! You should not
- put local variables in macros.
-
-
- .REPT <expr> <macroname> [parameter[,<parameter>]*]
-
- This is a recent addition to NASM65, inspired by the 68000
- assemblers. It repeatedly calls a macro (optionally with parameters).
- The <expr> contains the number of repetitions.
- Ex: REPT 3 LSL.W $3000 ; calls the MACRO `LSL.W' 3 times
-
-
- .WARNING <string>
- Creates a user warning. This is much more useful than the .ERROR
- directive. For instance in macros you can explain possible hazards.
- Ex: .WARNING "The world comes to an end soon!"
-
-
- .ZEXT <label>
- If you want to link two files together that share zeropage labels
- and you don't want to use a central include file to share zero
- page symbols, as would be inconvenient for library files that
- already exist in assembled form, you need to declare in one file
- the zeropage labels as external and in the other file as linkable
- zeropage labels. As usual an example will clear up things...
- File #1:
- .ZEXT src ;; tells NASM65 that src, dst
- .ZEXT dst ;; are zeropage addresses.
- ;; Call with amount to move in X
- move: ldy #0 ;; this isn't a very good mover
- :loop lda (src),y ;; but this is just for illustrating
- sta (src),y ;; a point
- iny
- dex
- bne :loop
- rts
-
- File #2:
- SRC==$F0 ;; == means declare as linkable zeropage
- DST==$F2
-
- ROM=$FF02
- RAM=$0610
-
- start ldx #56
- lda #<ROM
- sta SRC
- lda #>ROM
- sta SRC+1
- lda #<RAM
- sta DST
- lda #>RAM
- sta DST+1
- ldx #16
- jmp move
- brk
-
- When linking the values of SRC and DST of file #1 will be set to
- those of file #2.
-
-
- .ORG <value>
- *=<value>
- This can only be used in the runnable mode to set the assembly
- program counter. f.e:
- *=$600
- lda #0 ;; useless ditty in PAGE 6
- sta $2F4
- rts
-
- .org $3000 ;; main program in PAGE $30
- jsr $600
- nop
-
- *=RUNAD ;; let DOS start program @$3000
- .word $3000
- Using .ORG in the relocatable mode yields an error.
-
-
-
- 2. C o d e p r o d u c i n g d i r e c t i v e s
-
- .BYTE [+offset,][[<string>],[<expr>]]* ;; incorrect! guess the meaning
- Deposits BYTE values in memory. Strings are treated as arrays
- of ATASCII characters. There is no '\0' implicitly appended
- after a string like in C.
-
- .SBYTE [+offset,][[<string>],[<expr>]]* ;; Comment as above
- Same as above, except that bytes are converted for direct screen
- representation. (if you wanted to poke "HELLO WORLD" directly
- into screen memory.)
-
- .CBYTE [+offset,][[<string>],[<expr>]]* ;; Comment as above
- Same as .BYTE except that the last byte of a <string> is EORed with
- $80. This is supposedly useful, when you wan't to check for EOS with
- BMI.
-
- .WORD <expr>[,<expr>]* ;; that's correct
- Deposits words (LSB MSB) in memory.
-
- .DBYTE <expr>[,<expr>]*
- Deposits 16Bit values in MSB LSB order.
-
- .FLOAT <float>[,<float>]*
- Deposits floating point exprs into memory. Expressions are not
- allowed with floats. This is only kept in NASM65 for MAC65
- compatibility.
-
- .DS <expr>
- Reserves <expr> bytes of memory. Not that useful in relocatable
- mode (see elsewhere). This is quite like writing *=*+<expr>.
- .DS is a code producing directive in relocatable mode.
-
-
- 3. O b s o l e t e D i r e c t i v e s
-
- .TITLE <string>
- .PAGE <string>
- .SET <expr>,<expr>
- .OPT [NO]<option>[,[NO]<option>]*
- .TAB <expr>
- These are all obsolete. The SET directive had some influence on
- code generation, but is NOT SUPPORTED anymore.
-
-
-
- E r r o r s a n d W a r n i n g s
-
- These are some errors and warnings that may need a bit more
- explanation:
-
- Error: "Label still has open references"
- This could happen like this:
- foo .= s1
- lda foo
- foo .= s2 ; ERROR
- lda foo
- s1:
- s2:
- NASM65 is single pass. On line 1 FOO is set to a forward as of yet
- unknown reference. In line 3 the value in FOO is overwritten although,
- we didn't yet had a chance to resolve the earlier forward reference.
-
-
- Warning: "Some labels non PC-relative labels point into code"
- If you used any of these labels to access memory, you might
- get into trouble. If you used those labels for benign purposes
- such as those from STDDEF, you can ignore those warnings"
-
-
-
- T h i n g s y o u s a w e n c l o s e d i n ' < > '
-
- address : means a PC-relative address like foo in "foo: inx".
-
- bexpr : Boolean expression. 0 is considered to mean 'false' and
- everything else means 'true'.
-
- continued: Just means next line should actually stand where you found
- continued
-
- equate : This is a label, that has come into existance via a '='
- assignment.
-
- expr : Arithmetic expression, like 4 + 5, [2 .AND 4] * [300 & 20]
-
- filename : System dependent character-string, that represents a path
- to a file in your filesystem.
- f.e. TOS ..\mystuff\n65\foo.h65
- UNIX /usr/lib/n65/fo.h65
- A filename can contain any characters that are valid for
- your filesystem. Note that this will bring in a slight
- source incompatibility between systems!
-
- float : Atari's own fun floating point format. 6 Bytes. BCD.
- Avoid! E.g.: -3.123E+24, +23.0, 0.1E-1
-
- label : A label is a character string that represents an address or
- a value. You define labels by putting them in the first
- column of your source code. f.e.
- label = 45
- - or -
- label .= 2
- - or -
- label lda #2 ;; here label gets the value of *
- Labels have the same characterwise restriction as
- <macroname>s
-
- lines : zero or more lines of ASCII/ATASCII text.
-
- macroname: Any character string derived from the following character
- set [A-Z,a-z,0-9,$,@,_,.]. Cannot start of with a digit!
-
-
- operation: Either an arithmetic operation ( * + - & etc.) or a
- boolean operation (.AND .NOT etc.)
-
- option : ¡Obsolete! Any of the following list
- (LIST CLIST OBJ MLIST XREF NUM EJECT)
-
- parameter: a macro parameter. In POKE 2300,23 the numbers 2300 and
- 23 which are passed to the macro as arguments are called
- parameters.
-
- portable : Portability is a relative thing. NASM65 will probably go
- belly up on anything with 7-Bit chars or EBCDIC.
-
- saddress : means a short PC-relative address that can't be used
- in another expression. For example the least
- significant of a PC-relative address is a saddress.
-
- source : The <filename> of the source file.
-
- string : Any number of characters enclosed inbetween >"<.
-
- value : means numbers or non-PC-relative labels like
- STACK=$100 or expressions made of the two like
- 4*5, STACK/4, 2*STACK, STACK-STACK+1...
-
-
-
- G l o s s a r y
-
- ACK Acknowledgement
-
- ASCII ASCII != EBCDIC. 7-bit really
-
- Assembler Go back to your wordprocessor, you are reading the wrong
- file.
-
- ATASCII Atari extension of ASCII. 8-Bit
-
- BMI .. ..
- LDA .... 6502 .... What LDA #<expr> = A9 ..
- STA .... mnemos .... else ? STA <word> = 8D .. ..
- NOP .. ..
-
- Byte 8 bits unsigned
-
- CR Carriage Return, '\r', ASCII 13
-
- EOS End of string
-
- ICD ? . Just as great as OSS. Hardware mostly though. Bought
- OSS.
-
- Linker A program that produces an executable program from one
- or more object files and libraries of object files.
-
- LSB Least significant byte of a word -> $12[34]
- LSB MSB order would be [34]12
-
- LF Linefeed, '\n', ASCII 10
-
- MAC65 Assembler distributed by OSS.
-
- MSB Most significant byte of a word -> $[12]34
- MSB LSB order would be [12]34
-
- OS Operating System
-
- OSS Optimized Systems Software. Makers of great Software for
- the Atari 8-Bit. You could buy their stuff eyes closed.
-
- PC Program counter
-
- REF Reference
-
- SPACE Space, ' ', ASCII 32
-
- TAB Tabulator, '\t', ASCII 9
-
- THANX Thanks
-
- TOS Takes up 192K ROM-space in the ST. Contains fragments of
- OS-code.
-
- UNIX An OS.
-
- WORD 16 bits 8 of them comprise the LSB the other 8 the MSB
-
-
-
- B U G S ( k n o w n )
- There is a serious bug in the documentation, which doesn't properly
- follow thru with the distinction of <equate> and <label>.
-
- The assembler does not print linenumber and filename, when the
- error or warning occurred on the last line.
-
- The assembler does no checking for overflow of it's program
- buffer space (assuming that noone would assemble more than
- 48K in one run anyway). There is a limit imposed on many
- data structures in the object file, by virtue of using unsigned
- integers instead of lwords. If ANYONE runs into problems please
- tell me, changing stuff to LWORDs isn't that big a deal, it just
- wastes more filespace.
-
- On UNIX systems all include files must start with a lowercase
- character.
-
-
- A C K S , R E F S & T H A N X (nö special order)
-
- Werner (Ex-Meister) für moralische Unterstützung
- Dinadan for porting this to the AMIGA and finding
- some bugs, that escaped me
- J. Richter for helping to debug the MSDOS code and lending
- me his KONTRON AT for a few days.
- Matthias Reichel for making a valiant (and successful) attempt
- at porting 2.0 to the PC
-
- Harbison/Steele C - A Reference Manual Second Edition
- Poole/McNiff/Cook Your Atari Computer
- Chadwick Mapping the Atari
- Dripke 6502 Assembler Kurs für Beginner
- OSS MAC/65™ Manual
- Lawrow MAC/65
- Wilkinson Atari Basic Source Book (?)
-
- Van Halen (everything 'xcept maybe OU812) read the
- Metallica (everything) sources
- Megadeth (RIP *GREAT*, SFSG...SW? PS...BWIB? *GREAT*) to
- Chris Poland (RTM) find some
- Joe Satriani (everything) of
- Steve Vai (P&W) the hidden
- The Police (RDB TGH) capabilities
- David Lee Roth (ALAE *WHOA*) like
- Steve Morse (SS *MASTERPIECE*) in the
- Suicidal Tendencies (LCR) linker (har har) (is that outdated? nat/92)
- Front 242 (*FBF*)
- for continous (I mean continous) entertainment
-