Working with banks — #bankdef, #bank - hlorenzi/customasm GitHub Wiki
By default, every source file is processed by the assembler as
beginning at address 0. With banks, you can set the
starting address value and also configure how the resulting bits
are placed into the output file.
First, define one or more banks as follows:
#bankdef mybank
{
bits = 8
addr = 0x8000
size = 0x4000
outp = 8 * 0x10
}
This specifies that the bank named mybank starts at logical address 0x8000 and
that it can hold 0x4000 addresses.
Also, it specifies that the output bits should be
placed starting at position 8 * 0x10 in the output file (as in, 0x10 8-bit bytes from
the beginning of the file). Currently, outp is specified in bits, but that may change in the future.
The bits field specifies the minimum addressable unit in this bank -- each addressable
location will contain this many bits. This field is optional and defaults to 8, the
standard for most current machines.
The #bankdef directive automatically switches to assembling at the newly defined bank, but if
you define more banks, you can switch between them with the following:
#bank mybank
When you switch banks, the assembler remembers the address where it left off, so you can interleave code from different banks in your source file.
Specifying the ending address instead of a size
You can use the addr_end field to specify the ending address of the bank instead of using the size field, if that would be more convenient. This ending address is
exclusive, so the last valid address in this bank is one less than the given value.
Automatic label alignment
You can include a labelalign = X field to have every global label defined in that bank
to be automatically aligned, as if #align X had been used immediately before each
one.
Non-Writable Banks
If you define a bank without an outp field, it will be treated as non-writable:
you won't be able to write data to it, only allocate space (e.g. through the #res
directive). It also won't take up any space in the output file. Useful for mapping out
RAM banks.
Fill
If you define a bank with a fill field such as the following:
#bankdef mybank
{
addr = 0x8000
size = 0x4000
outp = 8 * 0x10
fill = true
}
...then remaining space in the bank will be filled with zeroes. Without this field, the assembler may truncate the output file to only the used bits and ignore leftover space.
The bankof() built-in function
You can access information about a bank in expression contexts by using
a bankof() call. You can supply a label as an argument or the current address $.
#bankdef mybank
{
addr = 0x8000
size = 0x4000
outp = 0
}
label:
#d bankof(label).addr
#d bankof(label).outp
#d bankof(label).size ; The bank size in address units
#d bankof(label).size_b ; The bank size in bits
#d bankof(label).bits
Custom data
You can specify a data field to hold arbitrary data that you can access
later through bankof().
#bankdef mybank
{
addr = 0x8000
size = 0x4000
outp = 8 * 0x10
data = 0x7777
}
label:
#d bankof(label).data ; this will output 0x7777
A struct expression might be useful if you need to hold more than
one value:
#bankdef mybank
{
addr = 0x8000
size = 0x4000
outp = 8 * 0x10
data = struct {
unlucky_number = 13
lucky_number = 0x7777
}
}
label:
#d bankof(label).data.lucky_number ; this will output 0x7777