[cc65] Overlay Demo: C64 Port ?

From: Oliver Schmidt <ol.sc1web.de>
Date: 2009-10-01 23:29:18
Hi,

Several times cc65 users asked about overlay support in cc65. In order
to react on that interest I created an small overlay demo that I'd
like to add to the samples coming with the cc65 doc package.

Such a demo makes especially sense because users tend to think in the
direction of cc65 loadable modules when it comes to overlays, although
the "single link to multiple output files" approach is way better
suited to overlays. Right now the demo only works on Apple2 machines
but I'd really like to see it run at least on the C64 too. Therefore I
ask for your help...

The question is basically where to place the overlays in memory
whithout the need to modify/replace any part of the C-library. The
goal is to get along with just a custom linker config. On the Apple2
the start address of programs is variable so one can simply move the
start address upwards and place the overlays below the program...

Please find below the (hopfully portable) source code and Apple2 linker config.

Thanks in advance, Oliver

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

extern void _OVL1CODE_LOAD__, _OVL1CODE_SIZE__;
extern void _OVL2CODE_LOAD__, _OVL2CODE_SIZE__;
extern void _OVL3CODE_LOAD__, _OVL3CODE_SIZE__;

void log(char *msg)
{
  printf("Log: %s\n", msg);
}

#pragma codeseg(push, "OVL1CODE");
void foo(void)
{
  log("Calling main from overlay 1");
}
#pragma codeseg(pop);

#pragma codeseg(push, "OVL2CODE");
void bar(void)
{
  log("Calling main from overlay 2");
}
#pragma codeseg(pop);

#pragma codeseg(push, "OVL3CODE");
void foobar(void)
{
  log("Calling main from overlay 3");
}
#pragma codeseg(pop);

void loadfile(char *name, void *addr, void *size)
{
  int file = open(name, O_RDONLY);
  read(file, addr, (unsigned)size);
  close(file);
}

void main(void)
{
  log("Calling overlay 1 from main");
  loadfile("overlaydemo.1", &_OVL1CODE_LOAD__, &_OVL1CODE_SIZE__);
  foo();

  log("Calling overlay 2 from main");
  loadfile("overlaydemo.2", &_OVL2CODE_LOAD__, &_OVL2CODE_SIZE__);
  bar();

  log("Calling overlay 3 from main");
  loadfile("overlaydemo.3", &_OVL3CODE_LOAD__, &_OVL3CODE_SIZE__);
  foobar();

  log("Press any key");
  getchar();
}

MEMORY {
    ZP:     start = $0080, size = $001A,            define = yes;
    HEADER: start = $0000, size = $0004, file = "";
    OVLAY1: start = $0800, size = $1800, file = "overlaydemo.1"; # Added
    OVLAY2: start = $0800, size = $1800, file = "overlaydemo.2"; # Added
    OVLAY3: start = $0800, size = $1800, file = "overlaydemo.3"; # Added
    RAM:    start = $2000, size = $9F00, file = %O, define = yes;
    MOVE:   start = $0000, size = $FFFF, file = %O, define = yes;
    LC:     start = $D400, size = $0C00,            define = yes;
}
SEGMENTS {
    ZEROPAGE: load = ZP,              type = zp;
    EXEHDR:   load = HEADER,          type = ro;
    STARTUP:  load = RAM,             type = ro;
    LOWCODE:  load = RAM,             type = ro;
    CODE:     load = RAM,             type = ro;
    OVL1CODE: load = OVLAY1,          type = ro, define   = yes; # Added
    OVL2CODE: load = OVLAY2,          type = ro, define   = yes; # Added
    OVL3CODE: load = OVLAY3,          type = ro, define   = yes; # Added
    RODATA:   load = RAM,             type = ro;
    DATA:     load = RAM,             type = rw;
    ZPSAVE:   load = RAM,             type = bss, define   = yes;
    BSS:      load = RAM,             type = bss, define   = yes;
    INIT:     load = MOVE, run = RAM, type = ro,  define   = yes;
    HIGHCODE: load = MOVE, run = LC,  type = ro,  optional = yes;
}
FEATURES {
    CONDES: segment = INIT,
            type    = constructor,
            label   = __CONSTRUCTOR_TABLE__,
            count   = __CONSTRUCTOR_COUNT__;
    CONDES: segment = RODATA,
            type    = destructor,
            label   = __DESTRUCTOR_TABLE__,
            count   = __DESTRUCTOR_COUNT__;
    CONDES: type    = interruptor,
            segment = RODATA,
            label   = __INTERRUPTOR_TABLE__,
            count   = __INTERRUPTOR_COUNT__;
}
SYMBOLS {
    __STACKSIZE__: value = $0800, weak = yes; # 2k stack
}
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Thu Oct 1 23:29:25 2009

This archive was generated by hypermail 2.1.8 : 2009-10-01 23:29:28 CEST