Howdy. I started messing with CA65 the other day and I got a little test rom to assemble. I had a few questions about segments and how best to use them.
Question 1: First, let's assume I have a UNROM .cfg layout like this (compliments of SecretServiceDude. Thanks man!):
Now for example's sake, let's say that for some reason or another I want the last byte in each swappable bank (last byte will be at $BFFF) to identify the bank. Bank0 will have a "00" at $BFFF, Bank1 will have "01" at $BFFF, Bank2 will have "02" at BFFF, etc. Should I do something like this:
and add lines like this to the .cfg
or should I do something like this instead:
or something else completely?
Question 2: It seems like they want you to separate CODE and RODATA. Should I do this separation for each bank/module I make? For example, say I'm writing a sound engine. Obviously it needs code and lookup tables. Is it the best practice to make two segments:
or is it more common to just lump it all together:
Just want to know the best way to organize things before I start
Question 1: First, let's assume I have a UNROM .cfg layout like this (compliments of SecretServiceDude. Thanks man!):
Code:
MEMORY {
M_ZEROPAGE: start = $00, size = $100, type = rw;
M_RAM: start = $200, size = $600, type = rw;
M_HEADER: start = $0, size = $10, type = ro, fill = yes, file = "build\ld65\header.bin";
M_WORKRAM: start = $6000, size = $2000, type = rw;
# PRG ROM banks (16 KB each, bank 7 is fixed)
M_PRGBANK0: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank0.prg";
M_PRGBANK1: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank1.prg";
M_PRGBANK2: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank2.prg";
M_PRGBANK3: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank3.prg";
M_PRGBANK4: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank4.prg";
M_PRGBANK5: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank5.prg";
M_PRGBANK6: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank6.prg";
M_PRGFIXED: start = $C000, size = $4000, type = ro, fill = yes, file = "build\ld65\fixed.prg";
}
SEGMENTS {
HEADER: load = M_HEADER, type = ro;
CODE: load = M_PRGFIXED, type = ro, start = $C000;
RODATA: load = M_PRGFIXED, type = ro;
VECTORS: load = M_PRGFIXED, type = ro, start = $FFF0;
ZEROPAGE: load = M_ZEROPAGE, type = zp;
BSS: load = M_RAM, type = bss, align = $100;
PRGBANK0: load = M_PRGBANK0, type = ro, start = $8000;
PRGBANK1: load = M_PRGBANK1, type = ro, start = $8000;
PRGBANK2: load = M_PRGBANK2, type = ro, start = $8000;
PRGBANK3: load = M_PRGBANK3, type = ro, start = $8000;
PRGBANK4: load = M_PRGBANK4, type = ro, start = $8000;
PRGBANK5: load = M_PRGBANK5, type = ro, start = $8000;
PRGBANK6: load = M_PRGBANK6, type = ro, start = $8000;
}
M_ZEROPAGE: start = $00, size = $100, type = rw;
M_RAM: start = $200, size = $600, type = rw;
M_HEADER: start = $0, size = $10, type = ro, fill = yes, file = "build\ld65\header.bin";
M_WORKRAM: start = $6000, size = $2000, type = rw;
# PRG ROM banks (16 KB each, bank 7 is fixed)
M_PRGBANK0: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank0.prg";
M_PRGBANK1: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank1.prg";
M_PRGBANK2: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank2.prg";
M_PRGBANK3: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank3.prg";
M_PRGBANK4: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank4.prg";
M_PRGBANK5: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank5.prg";
M_PRGBANK6: start = $8000, size = $4000, type = ro, fill = yes, file = "build\ld65\bank6.prg";
M_PRGFIXED: start = $C000, size = $4000, type = ro, fill = yes, file = "build\ld65\fixed.prg";
}
SEGMENTS {
HEADER: load = M_HEADER, type = ro;
CODE: load = M_PRGFIXED, type = ro, start = $C000;
RODATA: load = M_PRGFIXED, type = ro;
VECTORS: load = M_PRGFIXED, type = ro, start = $FFF0;
ZEROPAGE: load = M_ZEROPAGE, type = zp;
BSS: load = M_RAM, type = bss, align = $100;
PRGBANK0: load = M_PRGBANK0, type = ro, start = $8000;
PRGBANK1: load = M_PRGBANK1, type = ro, start = $8000;
PRGBANK2: load = M_PRGBANK2, type = ro, start = $8000;
PRGBANK3: load = M_PRGBANK3, type = ro, start = $8000;
PRGBANK4: load = M_PRGBANK4, type = ro, start = $8000;
PRGBANK5: load = M_PRGBANK5, type = ro, start = $8000;
PRGBANK6: load = M_PRGBANK6, type = ro, start = $8000;
}
Now for example's sake, let's say that for some reason or another I want the last byte in each swappable bank (last byte will be at $BFFF) to identify the bank. Bank0 will have a "00" at $BFFF, Bank1 will have "01" at $BFFF, Bank2 will have "02" at BFFF, etc. Should I do something like this:
Code:
.segment "PRGBANK0_ID"
.byte $00
.segment "PRGBANK1_ID"
.byte $01
....
.segment "PRGBANK6_ID"
.byte $06
.byte $00
.segment "PRGBANK1_ID"
.byte $01
....
.segment "PRGBANK6_ID"
.byte $06
and add lines like this to the .cfg
Code:
PRGBANK0_ID: load = M_PRGBANK0, type = ro, start = $BFFF;
PRGBANK1_ID: load = M_PRGBANK1, type = ro, start = $BFFF;
...
PRGBANK6_ID: load = M_PRGBANK6, type = ro, start = $BFFF;
PRGBANK1_ID: load = M_PRGBANK1, type = ro, start = $BFFF;
...
PRGBANK6_ID: load = M_PRGBANK6, type = ro, start = $BFFF;
or should I do something like this instead:
Code:
.segment "PRGBANK0"
.org $BFFF
.byte $00
.segment "PRGBANK1"
.org $BFFF
.byte $01
etc
.org $BFFF
.byte $00
.segment "PRGBANK1"
.org $BFFF
.byte $01
etc
or something else completely?
Question 2: It seems like they want you to separate CODE and RODATA. Should I do this separation for each bank/module I make? For example, say I'm writing a sound engine. Obviously it needs code and lookup tables. Is it the best practice to make two segments:
Code:
.segment "SOUND_ENGINE_CODE"
;
;code here
.segment "SOUND_ENGINE_RODATA"
;
;table here
.segment "SOUND_ENGINE_CODE"
;
;more code
;
;code here
.segment "SOUND_ENGINE_RODATA"
;
;table here
.segment "SOUND_ENGINE_CODE"
;
;more code
or is it more common to just lump it all together:
Code:
.segment "SOUND_ENGINE"
;
;code here
;
;table here
;
;more code
;
;code here
;
;table here
;
;more code
Code:
#this is the SEGMENT section of the linker .cfg file
SOUND_ENGINE: load = M_PRGBANK0, type = ro, start = $8000;
SOUND_ENGINE: load = M_PRGBANK0, type = ro, start = $8000;
Just want to know the best way to organize things before I start