From a71fae5bb1777a6c4bc9aee55c3a5a1534cea09a Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:10:47 +0200 Subject: [PATCH] Add template based bank switch proxy code --- include/c64/easyflash.h | 40 ++++++++ samples/memmap/build.sh | 1 + samples/memmap/easyflashcall.cpp | 158 +++++++++++++++++++++++++++++++ samples/memmap/make.bat | 1 + 4 files changed, 200 insertions(+) create mode 100644 samples/memmap/easyflashcall.cpp diff --git a/include/c64/easyflash.h b/include/c64/easyflash.h index 35e43491..137667c1 100644 --- a/include/c64/easyflash.h +++ b/include/c64/easyflash.h @@ -18,6 +18,46 @@ struct EasyFlash #define eflash (*(EasyFlash *)0xde00) +#ifdef __cplusplus + +#ifdef EFPROX_SECTION +#pragma code(EFPROX_SECTION) +#endif + +template +__noinline auto ef_call_p(P... p) +{ + if (back != __bankof(fn)) + eflash.bank = __bankof(fn); + auto r = fn(p...); + if (back != 0xff && back != __bankof(fn)) + eflash.bank = back; + return r; +} + +#ifdef EFPROX_SECTION +#pragma code(code) +#endif + +template +class EFlashCall +{ +public: + template + __forceinline auto operator()(P ... p) const + { + switch(__bankof(0)) + { +#for(i,64) case i: return ef_call_p(p...); + default: + return ef_call_p<0xff, fn, P...>(p...); + } + } +}; + +#define EF_CALL(fn) EFlashCall fn + +#endif #endif diff --git a/samples/memmap/build.sh b/samples/memmap/build.sh index da7133a8..ba499cfe 100755 --- a/samples/memmap/build.sh +++ b/samples/memmap/build.sh @@ -9,5 +9,6 @@ ../../bin/oscar64 easyflash.c -n -tf=crt ../../bin/oscar64 easyflashreloc.c -n -tf=crt ../../bin/oscar64 easyflashshared.c -n -tf=crt +../../bin/oscar64 easyflashcall.cpp -n -tf=crt ../../bin/oscar64 tsr.c -n -dNOFLOAT -dNOLONG ../../bin/oscar64 overlay.c -n -d64=overlay.d64 diff --git a/samples/memmap/easyflashcall.cpp b/samples/memmap/easyflashcall.cpp new file mode 100644 index 00000000..420a8188 --- /dev/null +++ b/samples/memmap/easyflashcall.cpp @@ -0,0 +1,158 @@ +#include +#include +#include +#include +#include + +// Shared code/data region, copied from easyflash bank 0 to ram during startup + +#pragma region( main, 0x0900, 0x8000, , , { code, data, bss, heap, stack } ) + +// Section and region for first easyflash bank + +#pragma section( bcode1, 0 ) +#pragma section( bdata1, 0 ) +#pragma region(bank1, 0x8000, 0xc000, , 1, { bcode1, bdata1 } ) + +// Section and region for second easyflash bank + +#pragma section( bcode2, 0 ) +#pragma section( bdata2, 0 ) +#pragma region(bank2, 0x8000, 0xc000, , 2, { bcode2, bdata2 } ) + +#pragma section( bcode3, 0 ) +#pragma section( bdata3, 0 ) +#pragma region(bank3, 0x8000, 0xc000, , 3, { bcode3, bdata3 } ) + +#pragma section( bcode4, 0 ) +#pragma section( bdata4, 0 ) +#pragma region(bank4, 0x8000, 0xc000, , 4, { bcode4, bdata4 } ) + +#pragma section( bcode5, 0 ) +#pragma section( bdata5, 0 ) +#pragma region(bank5, 0x8000, 0xc000, , 5, { bcode5, bdata5 } ) + +#pragma section( bcode6, 0 ) +#pragma section( bdata6, 0 ) +#pragma region(bank6, 0x8000, 0xc000, , 6, { bcode6, bdata6 } ) + +// Charwin in shared memory section + +CharWin cw; + +// Now switch code generation to bank 1 + +#pragma code ( bcode1 ) +#pragma data ( bdata1 ) + +// Print into shared charwin + +void print1_p(void) +{ + cwin_put_string(&cw, p"This is first bank", 7); + cwin_cursor_newline(&cw); +} + +// Now switch code generation to bank 2 + +#pragma code ( bcode2 ) +#pragma data ( bdata2 ) + +void print2_p(const char * p) +{ + cwin_put_string(&cw, p"This is second bank:", 7); + cwin_put_string(&cw, p, 1); + cwin_cursor_newline(&cw); +} + +#pragma code ( bcode3 ) +#pragma data ( bdata3 ) + +void print3_p(void) +{ + cwin_put_string(&cw, p"This is third bank", 7); + cwin_cursor_newline(&cw); +} + +#pragma code ( bcode4 ) +#pragma data ( bdata4 ) + +void print4_p(int x, int y) +{ + cwin_cursor_move(&cw, x, y); + cwin_put_string(&cw, p"This is fourth bank", 7); + cwin_cursor_newline(&cw); +} + +#pragma code ( bcode5 ) +#pragma data ( bdata5 ) + +void print5_p(void) +{ + cwin_put_string(&cw, p"This is fifth bank", 7); + cwin_cursor_newline(&cw); +} + +void print5a_p(void) +{ + cwin_put_string(&cw, p"This is fifth bank second", 14); + cwin_cursor_newline(&cw); +} + +// Switching code generation back to shared section + +#pragma code ( code ) +#pragma data ( data ) + + +EF_CALL(print1); +EF_CALL(print2); +EF_CALL(print3); +EF_CALL(print4); +EF_CALL(print5); +EF_CALL(print5a); + +#pragma code ( bcode6 ) +#pragma data ( bdata6 ) + +void print6_p(void) +{ + cwin_put_string(&cw, p"This is sixth bank", 7); + cwin_cursor_newline(&cw); + print5a(); + cwin_put_string(&cw, p"This is sixth bank again", 7); +} + +#pragma code ( code ) +#pragma data ( data ) + +EF_CALL(print6); + +int main(void) +{ + // Enable ROM + mmap_set(MMAP_ROM); + + // Init CIAs (no kernal rom was executed so far) + cia_init(); + + // Init VIC + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1800); + + // Prepare output window + cwin_init(&cw, (char *)0x0400, 0, 0, 40, 25); + cwin_clear(&cw); + + print1(); + print2("hello"); + print3(); + print4(5, 8); + print5(); + print6(); + + // Loop forever + while (true) + ; + + return 0; +} diff --git a/samples/memmap/make.bat b/samples/memmap/make.bat index 2c03d0ab..d9dbb627 100644 --- a/samples/memmap/make.bat +++ b/samples/memmap/make.bat @@ -9,6 +9,7 @@ call ..\..\bin\oscar64 easyflash.c -n -tf=crt call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt call ..\..\bin\oscar64 easyflashlow.c -n -tf=crt +call ..\..\bin\oscar64 easyflashcall.cpp -n -tf=crt call ..\..\bin\oscar64 tsr.c -n -dNOFLOAT -dNOLONG call ..\..\bin\oscar64 overlay.c -n -d64=overlay.d64 call ..\..\bin\oscar64 magicdesk.c -n -tf=crt8 -cid=19