Binary Data
Asar supports a number of commands which allow you to insert binary data directly into the ROM.
Tables
db {value}[,value...]
dw {value}[,value...]
dl {value}[,value...]
dd {value}[,value...]
Table commands let you insert a number or a list of numbers directly into the ROM as raw bytes. Use db
for 8-bit numbers, dw
for 16-bit numbers, dl
for 24-bit numbers and dd
for 32-bit numbers respectively, where value
can be a number literal, a math statement, a label or a Unicode string delimited by double quotes. When using dw
, dl
or dd
, each number is converted to little-endian. Big numbers are truncated to smaller integers as needed.
org $0189AB
Label:
; This will write the following data to the ROM:
; $01 $03 $07 $AB $41 $42 $43
db $01,$0203,$04050607,Label,"ABC"
; This will write the following data to the ROM:
; $01 $00 $03 $02 $07 $06 $AB $89 $41 $00 $42 $00 $43 $00
dw $01,$0203,$04050607,Label,"ABC"
; $01 $00 $00 $03 $02 $00 $07 $06 $05 $AB $89 $01 $41 $00 $00 $42 $00 $00 $43 $00 $00
dl $01,$0203,$04050607,Label,"ABC"
; $01 $00 $00 $00 $03 $02 $00 $00 $07 $06 $05 $04 $AB $89 $01 $00 $41 $00 $00 $00 $42 $00 $00 $00 $43 $00 $00 $00
dd $01,$0203,$04050607,Label,"ABC"
By default, each character in a Unicode string used in a table maps onto the respective Unicode code points it's composed of. This mapping can be customized via character literal assignments:
'{character}' = {value}
Where character
is a Unicode code point and value
is any math expression, specifying what value that code point will be remapped to. Only single code points can be remapped at this time - e.g., a precomposed "Ä" will work, while a split "¨" and an "A" will throw an error.
To reset all mappings to a direct Unicode code point mapping, use the command cleartable
. Additionally, the pushtable
command lets you push all current mappings onto a stack, whereas the pulltable
command lets you restore the mappings from that stack.
; Contents of table1.asm:
;'A' = $1A
;'B' = $1B
;'C' = $1C
;'日' = $2A
;'本' = $2B
;'語' = $2C
; Contents of table2.asm:
;'A' = $1D
;'B' = $1E
;'C' = $1F
;'日' = $2D
;'本' = $2E
;'語' = $2F
; This writes $41 $42 $43 $E5 (from U+65E5) $2C (from U+672C) $9E (from U+8A9E)
db "ABC日本語"
incsrc "table1.asm"
; This writes $1A $1B $1C $2A $2B $2C
db "ABC日本語"
pushtable
incsrc "table2.asm"
; This writes $1D $1E $1F $2D $2E $2F
db "ABC日本語"
pulltable
; This writes $1A $1B $1C $2A $2B $2C
db "ABC日本語"
cleartable
; This writes $41 $42 $43 $E5 $2C $9E
db "ABC日本語"
'A' = $20
'B' = $20+1
'C' = $20+2
'日' = $20+3
'本' = $20+4
'語' = $20+5
; Those both write $20 $21 $22 $23 $24 $25
db "ABC日本語"
db 'A','B','C','日','本','語'
Note that Asar tries to replace defines wherever possible - even inside strings. Sometimes, this might be undesired. In those cases, you can prefix the !
with a \
to escape it. The \
itself can be escaped with another \
. In the case of a "
it can be escaped with an additional "
.
!define = "text"
; This writes "text" to the ROM
db "!define"
; This writes "!define" to the ROM
db "\!define"
; This writes "\text" to the ROM
db "\\!define"
; This writes 'something "cool"' to the ROM
db "something ""cool"""
fillbyte
/ fill
fillbyte {byte}
fill {num}
fill align {alignment} [offset {offset}]
The fillbyte and fill commands let you write a specific byte value to the ROM multiple times. The byte
parameter of fillbyte specifies which value to write, wheres fill writes that value to the output ROM num
times. If alignment
is specified, the value will be written repeatedly until the SNES address has the specified alignment, similar to skip align
.
fillbyte $FF
; This writes $FF $FF $FF $FF $FF $FF $FF $FF
fill 8
org $008005
; this writes $FF until SNES address $00800A (=$8008 + 2)
fill align 8 offset 2
It's also possible to write 16-bit, 24-bit or 32-bit values with the fill command by using fillword
, filllong
or filldword
instead of fillbyte
. Note that the num
parameter of fill still specifies the number of bytes to write in those cases. Values might get truncated as needed to exactly reach the specified number of bytes to write.
padbyte
/ pad
padbyte {byte}
pad {snes_address}
The padbyte
and pad
commands let you write a specific byte value to the ROM until the pc reaches a certain SNES address. The byte
parameter of padbyte specifies which value to write, wheres pad writes that value to the output ROM until the pc reaches snes_address
.
org $008000
padbyte $FF
; This writes $FF $FF $FF $FF
pad $008004
It's also possible to write 16-bit, 24-bit or 32-bit values with the pad command by using padword
, padlong
or paddword
instead of padbyte
. Note that the snes_address
parameter of pad still specifies the end offset of the write in those cases. Values might get truncated as needed to exactly reach the specified end offset.
incbin
incbin {filename}[:range_start..range_end]
The incbin command copies a binary file directly into the output ROM. The filename
parameter specifies which file to copy (enclose in double quotes to use file names with spaces, see section Includes for details on Asar's handling of file names) and the optional range_start
and range_end
parameters are math expressions which specify a range of data to copy from the file (a range_end
of 0 copies data until the end of the file; not specifying a range copies the entire file).
; datafile.bin contains the following bytes:
; $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F
; This writes $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F
incbin "datafile.bin"
; This writes $09 $0A $0B $0C $0D $0E
incbin "datafile.bin":$9..$F
; This writes $01 $02 $03 $04
incbin "datafile.bin":$F-$E..2+3