xkas -o output.bin input.asm [second-input.asm ...]
If the output file exists, xkas will assemble the source file on top of this file. If it does not exist, xkas will create the file.
Passing the -ips
switch will generate an IPS patch instead of
creating or modifying a binary.
Passing the -e filename
switch will output an additional file
containing all defines and labels from the input. Supported formats are:
• *.asm (assembly include)
• *.ram.nl (FCEUX debug symbols, labels only)
• *.vs (VICE debug symbols, labels only)
Usage examples:
xkas -o output.bin input.asm
xkas -o output.bin input1.asm input2.asm
xkas input1.asm input2.asm -o output.bin
xkas -ips -o output.ips input.asm
xkas -o output.bin -e export.asm input.asm
Select processor architecture.
Supported values:
none
- None; uses base commands onlygba.thumb
- GBA THUMB CPU (ARM7TDMI THUMB)snes.cpu
/ 65816
- SNES CPU (WDC 65816)snes.smp
/ spc700
- SNES SMP (Sony SPC700)nes.cpu
/ 6502
- NES CPU (MOS 6502)tg16.cpu
/ pce.cpu
/ huc6280
- TG-16 / PC Engine CPU (Hudson HuC6280)65c02
- WDC 65C02 / 65SC0265ce02
- CSG 65CE02Manually specify processor endian. This will affect dw, dl and dd commands. Note that selecting a processor architecture will automatically select endian. This is intended to be used for "arch none" only.
Supported values:
lsb
- Little endianmsb
- Big endianInclude additional source file. Note that this command is infinitely recursive. Eg file1.asm can incsrc file2.asm, which can incsrc file3.asm. Recursion is only limited to available memory. The state will remain unchanged, eg all defines and labels will remain in-tact.
Insert binary file directly into output.
Seek to specified offset. Offset address relativity to output file is based upon the current architecture. Eg if arch = snes.cpu, org should be an SNES-memory-mapped offset. For arch = none, this is a literal offset into the output file.
Override internal org address when computing eg labels. This is useful for relocatable code and custom address mapping.
Usage example:
org $c02000; base $7f0000
lda #$00
loop:
jml loop //will assemble as jml $7f0002; while writing to pc($c02002)
These two directives control the mapping between physical and logical addresses for systems which use bank-switched memory (such as most NES games).
banksize sets the size of each program bank (default/maximum $10000), and bank selects a program bank to use. For example:
banksize $2000
bank 0
org $8000 // assembles to file offset $0000
org $9000 // assembles to file offset $1000
bank 1
org $8000 // assembles to file offset $2000
org $9000 // assembles to file offset $3000
org $a000 // assembles to file offset $2000 (not $4000!)
Note that for 65816 / snes.cpu, the bank and banksize settings are only relevant when the standard lorom, hirom, etc. address mapping modes aren't in effect (so that you can work with less common addressing setups, like with the SA-1).
Emits an error if the current output address (using CPU addressing) is higher than or equal to a specified address.
Write 0x00s until offset is evenly divisible by modulus. Eg if offset is $8011, "align 4" will write three 0x00s, aligning offset to a 4-byte boundary; in this case, $8014.
Simple binary data insertion. These commands additionaly support quote-delimited strings.
db
- Data byte (8-bits)dw
- Data word (16-bits)dl
- Data long (24-bits)dd
- Data double word (32-bits)Writes "length" number of bytes to output file. If value is not specified, write value is 0x00.
Writes until "offset" is reached. If value is not specified, write value is 0x00 (or another default value, see below).
Sets a new default value for fill and fillto / pad.
Creates a new define, or overrides a previous define by the same name. Quotes are only needed if space is needed inside the define.
Usage example:
define add "clc; adc"
define health_bonus 32
{add}.w #{health_bonus} //will assemble as clc; adc.w #32
Redefine character table entry. "char" must be exactly one 8-bit character in length, and "value" must resolve to an integer.
Usage example:
define 'C' $1234 //value can be up to 64-bits in length
lda.b #'C' //will assemble as lda.b #$34
lda.w #'C' //will assemble as lda.w #$1234
dw "C" //will write #$1234 to output
Uses a table file to redefine the values of multiple characters at once. The file is a plain text file with one character per line, following either of two possible formats:
21=A
22=B
23=C
24=D
A=21
B=22
C=23
D=24
The format can be detected automatically, but you may also specify a format by appending ,ltr (val=char) or ,rtl (char=val) to the file name.
As with using define to specify character values, the character must be a single byte, and the value can be any 64-bit integer.
Restores the default character table, undoing any characters that were defined using define or table.
Creates a new label. Can start with _[A-Za-z], can contain _[A-Za-z0-9].
Creates a new sublabel. Must start with ., can contain _[A-Za-z0-9]. Sublabel is automatically prefixed with the most recently specified label. Example:
label:
.sublabel: //will assemble as label.sublabel
Creates a nameless label. Will ignore active namespace. + is used to point to a label after the current code position, - is used to point before the current position. Can be redefined at any point in the code. Example:
-; dex; beq +; ...; bra -
+; rts
Sets the active namespace. When a label, sublabel or define is specified without a namespace prefix, it is automatically prefixed by the active namespace. This defaults to "global". Note that unlike C++ namespaces, this function is not recursive. There is only one namespace level. Example:
namespace global
label:
.sublabel:
define def "0"
dw label, .sublabel, custom::label, custom::label.sublabel, {def}, {custom::def}
namespace custom
label:
.sublabel:
define def "1"
dw label, .sublabel, global::label, global::label.sublabel, {def}, {global::def}
Prints specified message to the terminal. Example:
org $8000
label1:
print "label1 offset = ", org //prints "label1 offset = 0x8000"