Automatic padding to assemble certain instructions into predetermined addresses

386 Views Asked by At

I'd like to use CA65 to assemble a 6502 ROM that needs to run on its own, i.e. no other kernal available. I would like my program to start at $C000. But this means I'll also need to put $00 $C0 into the reset vector at $FFFC. Is there a way to have CA65 pad my program with zeroes between the end of the program and the reset vector?

i.e. what I'd like to do is write something like

        .org $C000

reset:  ;; Some code from here
        NOP

irq:    ;; more code
        NOP

        .org $FFFC
        ;; What do I put here for padding?!?!

        .addr reset
        .addr irq

and get a .prg file which can directly be used as a continuous ROM area from $C000 all the way to $FFFF.

I guess one thing I could do would be to write

        .repeat 123
        .byte 0
        .endrepeat

but that would mean having to update that number every time I change my program.

2

There are 2 best solutions below

0
On BEST ANSWER

Turns out the CC65 wiki has a page on .ORG that, while trying to dissuade me from doing this, also shows a neat solution using .res and some PC arithmetic:

  .org $C000

reset:  ;; Some code from here
        NOP

irq:    ;; more code
        NOP

        .res $FFFC-*
        .org $FFFC

        .addr reset
        .addr irq
0
On

You can pad empty space until specified address by defining another segment in your ld65 config:

ResetAddress: load=RAM1, type=ro, start=FFFC;

Then in the code, simply do:

.segment "ResetAddress"
.addr reset
.addr irq
.code
.proc reset
    ;Reset code goes here
.endproc
.proc irq
    ;IRQ code goes here
.endproc

Which should just pad with zero (as default) until the specified start address of "ResetAddress" segment is reached. If you just need to align to $100, use align=$100 instead.

The only downside I can see with this approach is, it's probably rather "cc65-specific".

As for the previous .repeat ... .endrepeat answer, wouldn't recommend that, but you can make it more flexible aswell:

.MACRO  PadBlock
.LOCAL start
start:
.REPEAT 256-<start
        .byte $00
.ENDREP
.ENDMACRO