Re: [cc65] Addressing resident code question

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2004-09-06 12:25:49
On Mon, Sep 06, 2004 at 12:03:28PM +0300, Karri Kaksonen wrote:
> What I would like to do is to create a small set of resident functions in
> a segment and be able to access these routines from my code in another
> segment that gets switched in and out during the play.
[...]
> How do I tell the compiler what the starting address of level_one will be?
> Do I have to do it manually in the lynx.cfg file or is there a way to find
> out this from the compilation of the resident_code part.

Code placement is done by the linker. For your purpose, you will probably have
to use memory areas, which unfortunately means that the start address of the
banked areas cannot be floating.

> How do I find the entry addresses of my resident routines (play_tune,
> read_file_from_cart) when I link my game at level_one or level_two?

Symbol values are resolved by the linker. This means that you don't have to
care about the addresses of the routines, because the linker will resolve
them. The only thing you have to guarantee is that your code doesn't call
routines that aren't loaded.

> Or do I have to write a jump table at the start of the module to all
> routines I want to access in another code segment?

Are you talking about loadable modules? If the load address of a piece of code
is known in advance (as in your case) I wouldn't use loadable modules, but
simple binary images created by the linker. In the latter case, all symbols
are resolved by the linker at link time, because it knows at which address the
code is loaded. Your own code is responsible for loading the levels at
runtime.

Here is a small example for such a memory configuration:

MEMORY {
    ZP: start = $00, size = $1A, type = rw, define = yes;
    RESIDENT: start = $1000, size = $3000, define = yes, file = "resident.bin";
    BANK1: start = $4000, size = $4000, define = yes, file = "bank1.bin";
    BANK2: start = $4000, size = $4000, define = yes, file = "bank2.bin";
}
SEGMENTS {
    STARTUP: load = RESIDENT, type = wprot;
    LOWCODE: load = RESIDENT, type = wprot, optional = yes;
    CODE: load = RESIDENT, type = wprot;
    RODATA: load = RESIDENT, type = wprot;
    DATA: load = RESIDENT, type = rw;
    BSS: load = RESIDENT, type = bss, define = yes;
    ZEROPAGE: load = ZP, type = zp;

    # Bank1 stuff
    CODE_1: load = BANK1, type = wprot;
    RODATA_1: load = BANK1, type = wprot;
    DATA_1: load = BANK1, type = rw;
    BSS_1: load = BANK1, type = bss, define = yes;

    # Bank2 stuff
    CODE_2: load = BANK2, type = wprot;
    RODATA_2: load = BANK2, type = wprot;
    DATA_2: load = BANK2, type = rw;
    BSS_2: load = BANK2, type = bss, define = yes;

}
FEATURES {
    CONDES: segment = RODATA,
	    type = constructor,
	    label = __CONSTRUCTOR_TABLE__,
	    count = __CONSTRUCTOR_COUNT__;
    CONDES: segment = RODATA,
	    type = destructor,
	    label = __DESTRUCTOR_TABLE__,
	    count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
    __STACKSIZE__ = $800;	# 2K stack
}

Using this config, the linker will generate three output files: One named
resident.bin that must be loaded at $1000, and two others named bank1.bin and
bank2.bin that must be loaded at $4000. Runtime and C library support goes
into the RESIDENT memory area and is used by both overlays. All symbols are
resolved by the linker, so all code can freely call each other (of course no
routine can be called when it is not loaded).

If you're using C code in the banked areas, static variables will loose their
values when reloaded. This can be avoided by placing the data and bss segments
of the banked code into the resident memory area.

Regards


        Uz


-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Mon Sep 6 12:25:53 2004

This archive was generated by hypermail 2.1.8 : 2004-09-06 12:26:02 CEST