From 7572834ebf5db5f5b0a594863d684a65a97b123d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Wed, 29 May 2013 01:12:24 +0200 Subject: [PATCH] Use cbm_load() to load overlays on CBMs. --- cfg/c128-overlay.cfg | 19 ++++++ cfg/c64-overlay.cfg | 19 ++++++ libsrc/cbm/overlayaddr.s | 47 ++++++++++++++ samples/multidemo.c | 131 ++++++++++++++++++--------------------- samples/overlaydemo.c | 18 +++++- 5 files changed, 161 insertions(+), 73 deletions(-) create mode 100644 libsrc/cbm/overlayaddr.s diff --git a/cfg/c128-overlay.cfg b/cfg/c128-overlay.cfg index 811e099ef..e16ad4b2e 100644 --- a/cfg/c128-overlay.cfg +++ b/cfg/c128-overlay.cfg @@ -1,6 +1,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; + __OVERLAYADDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2k stack __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay } @@ -9,14 +10,23 @@ MEMORY { LOADADDR: file = %O, start = $1BFF, size = $0002; HEADER: file = %O, start = $1C01, size = $000C; RAM: file = %O, define = yes, start = $1C0D, size = $A3F3 - __OVERLAYSIZE__ - __STACKSIZE__; + OVL1ADDR: file = "%O.1", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL1: file = "%O.1", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL2ADDR: file = "%O.2", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL2: file = "%O.2", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL3ADDR: file = "%O.3", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL3: file = "%O.3", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL4ADDR: file = "%O.4", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL4: file = "%O.4", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL5ADDR: file = "%O.5", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL5: file = "%O.5", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL6ADDR: file = "%O.6", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL6: file = "%O.6", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL7ADDR: file = "%O.7", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL7: file = "%O.7", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL8ADDR: file = "%O.8", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL8: file = "%O.8", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL9ADDR: file = "%O.9", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL9: file = "%O.9", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; } SEGMENTS { @@ -31,14 +41,23 @@ SEGMENTS { ZPSAVE: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; ZEROPAGE: load = ZP, type = zp; + OVL1ADDR: load = OVL1ADDR, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; + OVL2ADDR: load = OVL2ADDR, type = ro; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; + OVL3ADDR: load = OVL3ADDR, type = ro; OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; + OVL4ADDR: load = OVL4ADDR, type = ro; OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVL5ADDR: load = OVL5ADDR, type = ro; OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVL6ADDR: load = OVL6ADDR, type = ro; OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVL7ADDR: load = OVL7ADDR, type = ro; OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVL8ADDR: load = OVL8ADDR, type = ro; OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVL9ADDR: load = OVL9ADDR, type = ro; OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { diff --git a/cfg/c64-overlay.cfg b/cfg/c64-overlay.cfg index c5e9e070c..2f7693e6e 100644 --- a/cfg/c64-overlay.cfg +++ b/cfg/c64-overlay.cfg @@ -1,6 +1,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; + __OVERLAYADDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2k stack __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay } @@ -9,14 +10,23 @@ MEMORY { LOADADDR: file = %O, start = $07FF, size = $0002; HEADER: file = %O, start = $0801, size = $000C; RAM: file = %O, define = yes, start = $080D, size = $C7F3 - __OVERLAYSIZE__ - __STACKSIZE__; + OVL1ADDR: file = "%O.1", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL1: file = "%O.1", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL2ADDR: file = "%O.2", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL2: file = "%O.2", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL3ADDR: file = "%O.3", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL3: file = "%O.3", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL4ADDR: file = "%O.4", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL4: file = "%O.4", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL5ADDR: file = "%O.5", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL5: file = "%O.5", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL6ADDR: file = "%O.6", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL6: file = "%O.6", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL7ADDR: file = "%O.7", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL7: file = "%O.7", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL8ADDR: file = "%O.8", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL8: file = "%O.8", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; + OVL9ADDR: file = "%O.9", start = $CFFE - __OVERLAYSIZE__, size = $0002; OVL9: file = "%O.9", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; } SEGMENTS { @@ -31,14 +41,23 @@ SEGMENTS { ZPSAVE: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; ZEROPAGE: load = ZP, type = zp; + OVL1ADDR: load = OVL1ADDR, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; + OVL2ADDR: load = OVL2ADDR, type = ro; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; + OVL3ADDR: load = OVL3ADDR, type = ro; OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; + OVL4ADDR: load = OVL4ADDR, type = ro; OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVL5ADDR: load = OVL5ADDR, type = ro; OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVL6ADDR: load = OVL6ADDR, type = ro; OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVL7ADDR: load = OVL7ADDR, type = ro; OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVL8ADDR: load = OVL8ADDR, type = ro; OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVL9ADDR: load = OVL9ADDR, type = ro; OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { diff --git a/libsrc/cbm/overlayaddr.s b/libsrc/cbm/overlayaddr.s new file mode 100644 index 000000000..c0756b378 --- /dev/null +++ b/libsrc/cbm/overlayaddr.s @@ -0,0 +1,47 @@ +; +; Oliver Schmidt, 2013-05-28 +; +; This module supplies the load addresses that are expected by Commodore +; machines in the first two bytes of overlay disk files. +; + + + ; The following symbol is used by linker config to force the module + ; to get included into the output file + .export __OVERLAYADDR__: absolute = 1 + +.segment "OVL1ADDR" + + .addr *+2 + +.segment "OVL2ADDR" + + .addr *+2 + +.segment "OVL3ADDR" + + .addr *+2 + +.segment "OVL4ADDR" + + .addr *+2 + +.segment "OVL5ADDR" + + .addr *+2 + +.segment "OVL6ADDR" + + .addr *+2 + +.segment "OVL7ADDR" + + .addr *+2 + +.segment "OVL8ADDR" + + .addr *+2 + +.segment "OVL9ADDR" + + .addr *+2 diff --git a/samples/multidemo.c b/samples/multidemo.c index e44a34b96..6585b2057 100644 --- a/samples/multidemo.c +++ b/samples/multidemo.c @@ -8,13 +8,17 @@ #include +#include #include -#include -#include -#include #include +#include #include -#include +#ifndef __CBM__ +#include +#include +#else +#include +#endif /* The symbols _OVERLAY?_LOAD__ and _OVERLAY?_SIZE__ were generated by the @@ -24,7 +28,6 @@ extern void _OVERLAY1_LOAD__[], _OVERLAY1_SIZE__[]; extern void _OVERLAY2_LOAD__[], _OVERLAY2_SIZE__[]; extern void _OVERLAY3_LOAD__[], _OVERLAY3_SIZE__[]; -extern void _OVERLAY4_LOAD__[], _OVERLAY4_SIZE__[]; struct { char *name; @@ -34,14 +37,7 @@ struct { } 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__}}; - -/* 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 + {"multdemo.3", -1, _OVERLAY3_LOAD__, (unsigned)_OVERLAY3_SIZE__}}; @@ -94,8 +90,6 @@ void foobar (void) #pragma code-name(pop); -#pragma code-name (push, "OVERLAY4"); - unsigned char loademdriver (void) { DIR *dir; @@ -148,59 +142,12 @@ unsigned char loademdriver (void) return 0; } -void copyoverlays (void) -{ - unsigned page = 0; - unsigned char num; - - 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; - } - - 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); - } -} - -#pragma code-name(pop); - 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); @@ -212,6 +159,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; @@ -226,16 +182,47 @@ 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..."); diff --git a/samples/overlaydemo.c b/samples/overlaydemo.c index 70a35f11d..8e67d771c 100644 --- a/samples/overlaydemo.c +++ b/samples/overlaydemo.c @@ -9,8 +9,12 @@ #include #include +#ifndef __CBM__ #include #include +#else +#include +#endif extern void _OVERLAY1_LOAD__[], _OVERLAY1_SIZE__[]; @@ -69,14 +73,26 @@ void foobar (void) unsigned char loadfile (char *name, void *addr, void *size) { +#ifndef __CBM__ + int file = open (name, O_RDONLY); if (file == -1) { log ("Opening overlay file failed"); return 0; } - read (file, addr, (unsigned) size); close (file); + +#else + + /* Avoid compiler warnings about unused parameters. */ + (void) addr; (void) size; + if (cbm_load (name, getcurrentdevice (), NULL) == 0) { + log ("Loading overlay file failed"); + return 0; + } + +#endif return 1; } -- 2.39.5