Skip to content

Working with banks β€” #bankdef, #bank

Lorenzi edited this page Jun 4, 2023 · 3 revisions

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
{
    #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 bytes from the beginning of the file). #outp is specified in bits, disregarding any value set by the #bits directive.

This 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.

Overriding #bits for a bank

The global #bits directive can be overridden in specific banks. This can be useful if, for example, you have multiple address spaces in your machine with different access granularities.

For example:

#bits 16

#bankdef program
{
    #addr 0x0000
    #size 0x8000
    #outp 0
}

#bankdef data
{
    #bits 8
    #addr 0x0000
    #size 0x8000
    #outp 16 * 0x8000
}

Similarly, the global #labelalign directive can also be overridden in specific banks.

Automatic label alignment

You can specify #labelalign X 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.

Fill Attribute

If you define a bank with a #fill attribute such as the following:

#bankdef mybank
{
    #addr 0x8000
    #size 0x4000
    #outp 8 * 0x10
    #fill
}

...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.