as64 is a two pass cross-assembler for 6510 CPU systems, mainly the Commodore 64. as64 is free software and is licensed under the GNU General Public License (GPL).
Version 0.9 of as64 is avaliable for download:
as64 has been tested and run on GNU/Linux and FreeBSD. Moreover, as64 0.9 is quite stable and works fine for me, but if you encounter a bug, send me an email about it and I will see what I can do.
I once wrote a short as64 tutorial:
Due to the fact that I am used to programming in Turbo Assembler, as64 has adopted it's syntax. Semicolons precedes comment lines, high and low bytes of a label is extracted with the > and < operators and bytes, words and ASCII-text is marked with the .byte, .word and .text keywords. The things that differ is that constant mathematical expressions aren't always correctly evaluated, labels can have an optional trailing colon (this is since emacs indents lines with a colon differently in asm-mode) and that as64 features a module system.
Constant expressions, like 2 + 3 * 4 or 4 * 3 + 2 are not evaluated correctly. The operators have no precedence over each other; instead expressions are evaluated from left to right. For example, 1 + 2 * 3 is interpreted as (1 + 2) * 3, which calculates as 9, and not the mathematically correct 1 + (2 * 3), which is 7. This normally is not a problem for me, as I seldom use any larger expressions, but you should be very awary of this if you decide to use as64. Be also aware that this might change in future versions, so don't depend on this errorneous behaviour.
The modularity is achieved though the use of the keywords module and export. Symbols (labels) can be exported from each module (typically a module consists of a file). The qualified keyword indicates that the variable name should be preceeded by the module name. Let's have a look at an example:
In the file reset.S you find these statements:
;; reset.S ;; ;; functions for resetting the computer to normal c64-mode module reset export qualified all reset: sei jsr $fda3 jsr $fd15 jsr $ff5b cli jmp $e397 error_reset: sei jsr $fda3 jsr $fd15 jsr $ff5b cli inc $d020 jmp $e397
First we see a few lines begining with a semicolon. These are treated like a comment and are ignored by the assembler. (You can use standard C-comments /* */ aswell.) After that a module definition comes. This is necessary if you want to export symbols qualified.
The next line contains the statement export qualified all which makes all symbols to be exported with the module name preceding them. In this case, the global symbol table would contain the following entries:
Note that the export qualified all keywords has to appear in that order. If they don't, unexpected results might follow.
These qualified exported symbols can be imported into a local symbol table by using the keyword import. In this case, suppose a file called boot.S includes the following lines:
;; boot.S ;; ;; administers the bootup procedure of osT ;; module boot import reset export qualified boot: sei jsr process.init bcs boot_error jsr malloc.init bcs boot_error jsr proctable.init bcs boot_error jsr zeropage.init bcs boot_error jsr scheduler.init bcs boot_error jsr process.add cli clc rts boot_error: jmp error_reset
Here, the jmp error_reset causes a jump to the error_reset subroutine that was defined in reset.S. (Here, it would not have been a good idea to import the modules process, malloc, proctable, zeropage or scheduler, since they all export an init-label. No warings are issued if this would happen, and it would lead to unexpected results.)
Generally, it is not necessary, and is not recommended, to import symbols from other modules. The reson for the import function to be included in as64 is so that you can have a header file with definitions for constant values, tables and such that you don't want to have in the actual source file. Let's have a look at an example:
The file process.h consists of the following lines:
;; process.h ;; ;; defines constant values for process statuses etc module process export qualified all DEAD = 0 RUNNING = 1 WAITING = 2 ZOMBIE = 3 STOPPED = 4 STARTING = 5 EXITING = 6 current .byte 0 next .byte 0
And in the file process.S these lines are to be found:
;; process.S ;; ;; code for process control module process import process export qualified getpid: lda current rts
Here, the lda current loads the value from the current defined in process.h. Other modules (that doesn't import process) refers to this address with process.current. The constants can be used in a similar way, like lda #process.RUNNING.
$Date: 2002/07/20 10:04:20 $