LUnix-Assembler (luna)
version: Feb 18 2000
Many people would like to write some code for the little C64/128 but don't have
the equipment to do so. So i decided to write a small (and therefore very portable)
assembler in a subset of ansi-C. This assembler compiles without modifications
on every (GNU-) C-compiler.
Additional this assembler is optimized to generate LUnix-applications. This is
done by including a LUnix-binary-header-generator. This is why all new LUnix-applications will be in
luna-format. Also the next version of the LUnix-kernel will be in this format (4400 lines yet! :-)
The sourcecode is around 1800 lines of C.
If you have compiled luna on an other system, especially systems that come without
a c-compiler, please email me the executable, to include it here.
How to use luna:
Luna just assembles a source (text) file into a destination (binary) file which
is executable on a C64/128. There is no editor included! The inputfile may be
written with every text-editor that saves files in plain ascii-format.
Source-format: (look into the ascii documentation for more)
- Comments are seperated by a leading ";"
- Label definitions look like
- <label>:
- <label> equ <expression>
- Expressions look like
- <value>[{+,-,<,>,&,|}<value>]*
- with <value>={[#]decimal,$hex,%bin,<label>,"<char>",*}
Expressions may be preceeded by "<" to select the lower byte, or ">" to
select the higher byte of a 16bit-expression.
- Special assembler-commands
- .byte <expression>[,<expression>]*
- .word <expression>[,<expression>]*
- .longword <expression>[,<expression>]*
- .asc "string\n\0"
- .head "cmd-name" [<ZP-label>[,<ZP-label>]*] - insert LUnix-header and switch to LUnix-mode
- .org <expression> - sets start address
- .buf <expression> - insert #n (empty) bytes
- .code - enter code-area (only in LUnix-mode)
- .data - enter data-area (only in LUnix-mode)
- .endofcode - no more code (enter data-area, only in LUnix-mode)
- .newpage - align to start of (next) page
- .global - declare a label global, a list of all globals and their value will be saved after compilation.
- Special labels (only used in LUnix-mode)
- _base - Startaddress of codesegment
- _init - Must point to init-routine
- _cleanup - Can point to a cleanup-routine (called by kill)
- _sig.killedparent - Can point to a handler
- _sig.killedchild - Can point to a handler
- _sig.userbreak - Can point to a handler
- Shortrange labels can be defined by a leading "+" for
forward or "-" for backward references (leading a assembler command). So "jmp +"
will jump to the next "+"-reference and "jmp -" to the latest "-"-reference.
The same way "jmp ++" will jump to the second next "+"-marker and so on.
A simple example
The classic example is the "Hello World"-program, so this is my first example
for luna also.
This is the sourcecode located in a file named "hello.a" :
; This is a simple "hello world" program
; for LUnix
.header "hello" ; "hello" is the name that will be displayed
; by "ps" in LUnix
strout equ $905d ; value of the 2 used system-vectors
bye equ $9018
stdout equ _base+2 ; _base is startadress of codesegment
; and will be initialized by the assembler.
_init: ldx stdout ; load standard output-stream-ID
jsr strout ; call "string output"
bit text_hello ; pass text-pointer to strout
lda #0 ; exitcode 0 (no error)
jmp bye ; end program
.endofcode ; end of code
text_hello:
.asc "Hello, world!\n\0"
Running the assembler by typing "luna hello.a hello"
will produce this output:
> luna hello.a hello
Pass 1
Pass 2
Final pass
note: ignored unused system vector "_sig.userbreak"
note: ignored unused system vector "_sig.killedparent"
note: ignored unused system vector "_sig.killedchild"
note: ignored unused system vector "_cleanup"
done, 6 labels, 41 bytes labelspace, 102 bytes of code
> _
This is the code generated by luna (in file "hello"):
The lines marked with "*" are generated automatically by luna, they realize
the header that Lunix needs to load and run a program.
* FF FF (Pseodo-Startaddress for load)
*$1000) 00 01 01 00 C8 D9 00 00 1C 40 00 00 00 00 00 00 ;....HY...@......
*$1010) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ;................
*$1020) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ;................
*$1030) 00 00 00 00 00 00 00 00 68 65 6C 6C 6F 00 00 00 ;........HELLO...
*$1040) LDA #$10
*$1042) JSR $9051
*$1045) JMP $1048
($1048) LDX $1002
($104B) JSR $905D
($104E) BIT $1057
($1051) LDA #$00
($1053) JMP $9018
($1056) 02 (end of code)
($1057) 68 45 4C 4C 4F 2C 20 57 4F 52 4C 44 21 0D 00 ;Hello, world!.
The program "hello" can now be started by the LUnix-shell by just typing
"hello":
@> hello
Hello, world!
@> _
If you have suggestions or comments contact me