X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=samples%2Fmultidemo.c;h=396d7344a1b6dfacd9348e3052a5b6314006aeb4;hb=1a5fa6dc512221490c5547505668a78308f904a8;hp=e780e07a20699d8322e681eef9521ec2d7ebf531;hpb=2d97630d030c905f97dfef8fb8dab41bd5c71993;p=cc65 diff --git a/samples/multidemo.c b/samples/multidemo.c index e780e07a2..396d7344a 100644 --- a/samples/multidemo.c +++ b/samples/multidemo.c @@ -1,29 +1,37 @@ /* - * Minimalistic overlay demo program. - * - * 2012-17-07, Oliver Schmidt (ol.sc@web.de) - * - */ +** Extended memory overlay demo program. +** +** Shows how to combine multiple cc65 features +** incl. overlays and extended memory drivers. +** +** 2012-17-07, Oliver Schmidt (ol.sc@web.de) +** +*/ #include #include -#include -#include +#include #include #include -#include +#include +#ifndef __CBM__ +#include +#include +#else +#include +#include +#endif /* The symbols _OVERLAY?_LOAD__ and _OVERLAY?_SIZE__ were generated by the - * linker. They contain the overlay area address and size specific to a - * certain program. - */ -extern void _OVERLAY1_LOAD__, _OVERLAY1_SIZE__; -extern void _OVERLAY2_LOAD__, _OVERLAY2_SIZE__; -extern void _OVERLAY3_LOAD__, _OVERLAY3_SIZE__; -extern void _OVERLAY4_LOAD__, _OVERLAY4_SIZE__; +** linker. They contain the overlay area address and size specific to a +** certain program. +*/ +extern void _OVERLAY1_LOAD__[], _OVERLAY1_SIZE__[]; +extern void _OVERLAY2_LOAD__[], _OVERLAY2_SIZE__[]; +extern void _OVERLAY3_LOAD__[], _OVERLAY3_SIZE__[]; struct { char *name; @@ -31,37 +39,31 @@ struct { void *addr; unsigned size; } overlay[] = - {{"multdemo.1", -1, &_OVERLAY1_LOAD__, (unsigned)&_OVERLAY1_SIZE__}, - {"multdemo.2", -1, &_OVERLAY2_LOAD__, (unsigned)&_OVERLAY2_SIZE__}, - {"multdemo.3", -1, &_OVERLAY3_LOAD__, (unsigned)&_OVERLAY3_SIZE__}, - {"multdemo.4", -1, &_OVERLAY4_LOAD__, (unsigned)&_OVERLAY4_SIZE__}}; + {{"multdemo.1", -1, _OVERLAY1_LOAD__, (unsigned)_OVERLAY1_SIZE__}, + {"multdemo.2", -1, _OVERLAY2_LOAD__, (unsigned)_OVERLAY2_SIZE__}, + {"multdemo.3", -1, _OVERLAY3_LOAD__, (unsigned)_OVERLAY3_SIZE__}}; -/* Copy overlays into extended memory up to overlay 3. Overlay 4 is known to - * to be loaded only once for onetime initialization purposes so there's no - * use in allocating extended memory for it. - */ -#define MAX_EM_OVERLAY 3 /* Functions resident in an overlay can call back functions resident in the - * main program at any time without any precautions. The function log() is - * an example for such a function resident in the main program. - */ +** main program at any time without any precautions. The function log() is +** an example for such a function resident in the main program. +*/ void log (char *msg) { /* Functions resident in an overlay can access all program variables and - * constants at any time without any precautions because those are never - * placed in overlays. The string constant below is an example for such - * a constant resident in the main program. - */ + ** constants at any time without any precautions because those are never + ** placed in overlays. The string constant below is an example for such + ** a constant resident in the main program. + */ printf ("Log: %s\n", msg); } /* In a real-world overlay program one would probably not use a #pragma but - * rather place the all the code of certain source files into the overlay by - * compiling them with --code-name OVERLAY1. - */ +** rather place all the code of certain source files into the overlay by +** compiling them with --code-name OVERLAY1. +*/ #pragma code-name (push, "OVERLAY1"); void foo (void) @@ -92,12 +94,13 @@ void foobar (void) #pragma code-name(pop); -#pragma code-name (push, "OVERLAY4"); - unsigned char loademdriver (void) { - DIR* dir; - struct dirent* ent; + DIR *dir; + struct dirent *ent; + char *emd = NULL; + unsigned char max = 0; + unsigned char num; printf ("Dbg: Searching for emdrivers\n"); dir = opendir ("."); @@ -119,72 +122,36 @@ unsigned char loademdriver (void) continue; } - printf ("Dbg: Trying emdriver %s\n", ent->d_name); - if (em_load_driver (ent->d_name) == EM_ERR_OK) { - printf ("Dbg: Loaded emdriver %s\n", ent->d_name); - break; - } - - printf ("Dbg: Emdriver %s failed\n", ent->d_name); + printf ("Dbg: Memorizing file %s\n", ent->d_name); + emd = realloc (emd, FILENAME_MAX * (max + 1)); + strcpy (emd + FILENAME_MAX * max++, ent->d_name); } - closedir (dir); - return ent != NULL; -} -void copyoverlays (void) -{ - unsigned page = 0; - unsigned char num; + for (num = 0; num < max; ++num) { + char *drv; - for (num = 0; num < MAX_EM_OVERLAY; ++num) { - int file; - int size; - - if ((overlay[num].size + EM_PAGE_SIZE - 1) / EM_PAGE_SIZE > - em_pagecount () - page) { - printf ("Dbg: Not enough memory for overlay %u\n", num + 1); - continue; + drv = emd + FILENAME_MAX * num; + printf ("Dbg: Trying emdriver %s\n", drv); + if (em_load_driver (drv) == EM_ERR_OK) { + printf ("Dbg: Loaded emdriver %s\n", drv); + free (emd); + return 1; } - printf ("Dbg: Reading overlay file %s\n", overlay[num].name); - file = open (overlay[num].name, O_RDONLY); - if (file == -1) { - log ("Opening overlay file failed"); - continue; - } - - overlay[num].page = page; - size = overlay[num].size; - while (size) { - void *buf; - - /* In general one could as well use em_copyto() to copy a fully - * loaded overlay into extended memory in one step. However the - * "streaming" of an overlay from disk to extended memory shown - * here has two advantages: - * - It can be done from another overlay (like done here). - * - It avoids unnecessary double buffering with emdrivers that - * provide a hardware memory window. - */ - buf = em_use (page++); - size -= read (file, buf, EM_PAGE_SIZE); - em_commit (); - } - - printf ("Dbg: Stored overlay %u in pages %u-%u\n", - num + 1, overlay[num].page, page - 1); - - close (file); + printf ("Dbg: Emdriver %s failed\n", drv); } -} -#pragma code-name(pop); + free (emd); + return 0; +} unsigned char loadoverlay (unsigned char num) { if (overlay[num - 1].page < 0) { +#ifndef __CBM__ + int file; printf ("Dbg: Loading overlay %u from file\n", num); @@ -196,6 +163,15 @@ unsigned char loadoverlay (unsigned char num) read (file, overlay[num - 1].addr, overlay[num - 1].size); close (file); + +#else + + if (cbm_load (overlay[num - 1].name, getcurrentdevice (), NULL) == 0) { + log ("Loading overlay file failed"); + return 0; + } + +#endif return 1; } else { struct em_copy copyinfo; @@ -210,34 +186,65 @@ unsigned char loadoverlay (unsigned char num) } } -void main (void) + +void copyoverlays (void) { - if (loadoverlay (4)) { - log ("Loading extended memory driver"); - if (loademdriver ()) { - log ("Copying overlays into ext. memory"); - copyoverlays (); - } else { - log ("No extended memory driver found"); + unsigned page = 0; + unsigned char num; + + for (num = 0; num < sizeof (overlay) / sizeof (overlay[0]); ++num) { + struct em_copy copyinfo; + unsigned size = (overlay[num].size + EM_PAGE_SIZE - 1) / EM_PAGE_SIZE; + + if (size > em_pagecount () - page) { + printf ("Dbg: Not enough memory for overlay %u\n", num + 1); + continue; } + + if (loadoverlay (num + 1) == 0) + continue; + + copyinfo.offs = 0; + copyinfo.page = page; + copyinfo.buf = overlay[num].addr; + copyinfo.count = overlay[num].size; + em_copyto (©info); + + overlay[num].page = page; + page += size; + + printf ("Dbg: Stored overlay %u in pages %u-%u\n", + num + 1, overlay[num].page, page - 1); + } +} + + +void main (void) +{ + log ("Loading extended memory driver"); + if (loademdriver ()) { + log ("Copying overlays into ext. memory"); + copyoverlays (); + } else { + log ("No extended memory driver found"); } log ("Press any key..."); - cgetc (); + getchar (); if (loadoverlay (1)) { log ("Calling overlay 1 from main"); /* The linker makes sure that the call to foo() ends up at the right mem - * addr. However it's up to user to make sure that the - right - overlay - * is actually loaded before making the the call. - */ + ** addr. However it's up to user to make sure that the - right - overlay + ** is actually loaded before making the the call. + */ foo (); } /* Replacing one overlay with another one can only happen from the main - * program. This implies that an overlay can never load another overlay. - */ + ** program. This implies that an overlay can never load another overlay. + */ if (loadoverlay (2)) { log ("Calling overlay 2 from main"); bar (); @@ -248,6 +255,8 @@ void main (void) foobar (); } - log ("Press any key..."); - cgetc (); + if (doesclrscrafterexit ()) { + log ("Press any key..."); + getchar (); + } }