What is the best way to create a 32K program using CA65?
The normal generation of a .prg won't work as the memory map is not contiguous, having the upper 8K block at $A000.
I'm guessing I would need to write a two stage loader to first move an 8K block of code/data up to block 5 and then load in blocks 1/2/3?
Presumably CA65 needs to output two separate binaries, so I need a seperate link comand for the upper block? Hoping that during development I can just attach the second binary at $A000 using a command line parameter to VICE..
32k
Moderator: Moderators
Re: 32k
Maybe using block 1-3 for program code and block 5 for program data?
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Re: 32k
CA65 supports different ways to use disconnected memory regions.
The easiest way would be to use the RAM area at $A000 (block 5) for unitialized data.
In the linker definition file you have to declare the memory in the MEMORY section:
and to use it in CA65 declare a segment in the SEGMENT section:
with "type = bss" you tell the linker to not include the area in the output file.
You cannot declare initial values for the data in that segment, so you have to make sure to initialize the data at runtime.
Other options are:
- let ld65 write the data in the segment into a separate file and load it in your startup code ("file = " in the MEMORY section)
- let ld65 link for the target area but put it in an area that is part of your program and move it to the target area in your startup code (option load = RAM, run = A000 in the SEGMENTS section, assuming that you have declared memory for RAM)
The easiest way would be to use the RAM area at $A000 (block 5) for unitialized data.
In the linker definition file you have to declare the memory in the MEMORY section:
Code: Select all
MEMORY {
... other RAM areas ...
A000: start = $A000, size = $2000, type = rw, define = yes;
}
Code: Select all
SEGMENTS {
... your other segments ...
BSS: load = A000, type = bss;
}
You cannot declare initial values for the data in that segment, so you have to make sure to initialize the data at runtime.
Other options are:
- let ld65 write the data in the segment into a separate file and load it in your startup code ("file = " in the MEMORY section)
- let ld65 link for the target area but put it in an area that is part of your program and move it to the target area in your startup code (option load = RAM, run = A000 in the SEGMENTS section, assuming that you have declared memory for RAM)
Buy the new Bug-Wizard, the first 100 bugs are free!
Re: 32k
Thanks, I think this will be the best option as I don't have 8K of uninitialised memory. Presumably if I load this file (from device in my loader routine, (and it's located in the output directory) VICE will pick it up?Kananga wrote: - let ld65 write the data in the segment into a separate file and load it in your startup code ("file = " in the MEMORY section)
Re: 32k
Thanks for the heads-up.
I managed to get this working eventually. Here is the code in case it's useful for anyone else:
.config file
the above places some char data that needs to be dynamically swapped into on-board RAM into BLK5. In code I access it like this...
and here is the code to load the file
One extra thing, I had to set the AutoStart parameter in Vice to "Virtual File System" (VFS) otherwise it didn't see the additional file in the compilation output folder.
I managed to get this working eventually. Here is the code in case it's useful for anyone else:
.config file
Code: Select all
MEMORY {
<...other entries>
RAM2: start = $A000, size = $2000, type = rw, file = "BLOCK5.a0"; #blk 5
}
SEGMENTS {
CHARBANK: load = RAM2, type = ro, define = yes, optional = no;#load swappable char data to BLK5
}
Code: Select all
.segment "CHARBANK"
CharBank0:
udc33: .byte $FF,$F3,$FF,$3F,$FF,$FF,$CF,$FF
udc34: .byte $55,$55,$AD,$AC,$AC,$AC,$0C,$0C
<..etc>
Code: Select all
;
;==== load extra code into block 5
;
LOAD = $FFD5
SETLFS = $FFBA
SETNAM = $FFBD
; Load the segment into RAM AT $A000
lda #1
ldx #8
ldy #0
jsr SETLFS
; set the file name
lda #<(A0FilePathEnd - A0FilePathStart)
ldx #<A0FilePathStart
ldy #>A0FilePathStart
jsr SETNAM
; load the file
lda #0
ldx #$02
ldy #$A0
jsr LOAD
A0FilePathStart:
.byte "BLOCK5.a0"
A0FilePathEnd: