From 01357db32b16f9a3b4faf40cb2e131de34a1832f Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Thu, 11 Apr 2024 16:10:11 -0500 Subject: [PATCH] Many overlay tool fixes. --- examples/.gitattributes | 1 + examples/overlay/build.sh | 4 ++ examples/overlay/overlay.c | 9 ++++- f256lib/f256.c | 4 +- f256lib/f_bitmap.c | 1 - tools/overlay/overlay.c | 83 +++++++++++++++++++++++++++++--------- 6 files changed, 77 insertions(+), 25 deletions(-) create mode 100644 examples/.gitattributes diff --git a/examples/.gitattributes b/examples/.gitattributes new file mode 100644 index 0000000..dcd7e5f --- /dev/null +++ b/examples/.gitattributes @@ -0,0 +1 @@ +a23d2/a2-3d/A2-3D2\#066000 filter=lfs diff=lfs merge=lfs -text diff --git a/examples/overlay/build.sh b/examples/overlay/build.sh index e56abc8..f5aba49 100755 --- a/examples/overlay/build.sh +++ b/examples/overlay/build.sh @@ -31,6 +31,10 @@ PATH=${LLVM}/bin:${PATH} CLANG="mos-f256k-clang -I${F256}/include -I${F256}/f256lib -Os" +pushd ${F256} +./build-tools.sh +popd + [[ -d .builddir ]] && rm -rf .builddir mkdir -p .builddir diff --git a/examples/overlay/overlay.c b/examples/overlay/overlay.c index b4be221..ce6810c 100644 --- a/examples/overlay/overlay.c +++ b/examples/overlay/overlay.c @@ -25,12 +25,18 @@ #include "f256.c" +void firstSegment(int arg1, int arg2); +void secondSegment(int arg1, int arg2); +void moreFirstSegment(int arg1, int arg2); + + // This is the first segment we've defined. The linker will place this code in // the first available far memory slot (default 0x10000). #define SEGMENT_FIRST void firstSegment(int arg1, int arg2) { printf("firstSegment = %d\n", arg1 + arg2); + secondSegment(arg1, arg2); } // This is the second segment we've defined. The linker will place this code in @@ -39,6 +45,7 @@ void firstSegment(int arg1, int arg2) { void secondSegment(int arg1, int arg2) { printf("secondSegment = %d\n", arg1 + arg2); + moreFirstSegment(arg1, arg2); } // Back to the first segment. The linker will place this code immediately @@ -57,8 +64,6 @@ int main(int argc, char *argv[]) { // The overlay tool will generate trampoline macros for each function // that is located in a far segment so no code changes are required. firstSegment(1, 2); - secondSegment(3, 4); - moreFirstSegment(5, 6); // Spin. for (;;); diff --git a/f256lib/f256.c b/f256lib/f256.c index 57abeda..c14736f 100644 --- a/f256lib/f256.c +++ b/f256lib/f256.c @@ -130,10 +130,10 @@ uint16_t FAR_PEEKW(uint32_t address) { void *FAR_POINTER(uint32_t address) { - byte block; - // This only works if we use slot 5 and don't restore it after swapping. #if SWAP_SLOT == MMU_MEM_BANK_5 + byte block; + block = address / EIGHTK; address &= 0x1FFF; // Find offset into this block. POKE(SWAP_SLOT, block); diff --git a/f256lib/f_bitmap.c b/f256lib/f_bitmap.c index f2c1f7d..57ae78c 100644 --- a/f256lib/f_bitmap.c +++ b/f256lib/f_bitmap.c @@ -38,7 +38,6 @@ static byte _BITMAP_CLUT[3]; static byte _color; static byte _active; // Current drawing page. -// uint32_t address = _BITMAP_BASE[_active] + (y * _MAX_X + (int32_t)x); \ #define bitmapPutPixelIOSet(x, y) ({ \ uint32_t address = _BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x); \ diff --git a/tools/overlay/overlay.c b/tools/overlay/overlay.c index bca43cb..0b39663 100644 --- a/tools/overlay/overlay.c +++ b/tools/overlay/overlay.c @@ -79,10 +79,13 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo FILE *in; FILE *out; int c; + char arguments[BUFFER_SIZE]; char buffer[BUFFER_SIZE]; - char *temp; + char *functionName; char *start; + char *a; char *b; + bool isPointer; bool found; int x; int line = 1; @@ -174,41 +177,81 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo trimEnd(buffer); // Functions end with a closing parenthesis. if (buffer[strlen(buffer) - 1] == ')') { - // Function. Annotate it! - fprintf(out, "__attribute__((noinline, section(\".block%d\")))\n", _currentBank); - - // Scan forward to find the '(' after the function name. + // Found function! Scan forward to find the '(' after the function name. b = buffer; while (*b != '(') b++; // Now go backwards and look for a space. start = b; while (*start != ' ') start--; // Are they returning a pointer? - found = false; + isPointer = false; if (*(start+1) == '*') { - found = true; + isPointer = true; ++start; *start++ = 0; } else { *start++ = 0; - found = false; + isPointer = false; } + + // 'start' is now at the beginning of the function name. + // 'buffer' is truncated after the return type. + // 'b' is on the argument opening parenthesis. + // 'isPointer' is if the return value is a pointer or not. + // Yank the function name out. *b = 0; - temp = strdup(start); + functionName = strdup(start); *b = '('; + + // Find argument names by scanning from 'b'+1 until we hit a + // comma or closing parenthesis. Then back up until we find + // a space, comma, or opening parenthesis. + b++; + x = 0; + found = false; + while (!found) { + while ((*b != ',') && (*b != ')')) b++; + if (*b == ')') found = true; + a = b - 1; + while ((*a != '(') && (*a != ',') && (*a != ' ')) a--; + a++; + while (a < b) { + arguments[x++] = *a; + a++; + } + if (!found) { + arguments[x++] = ','; + arguments[x++] = ' '; + } + b++; + } + arguments[x++] = 0; + trimEnd(arguments); //***TODO*** Should also trim start. + if (strcmp(arguments, "void") == 0) arguments[0] = 0; + + // Create trampoline function. + fprintf(out, "__attribute__((optnone))\n"); + //fprintf(out, "__attribute__((noinline))\n"); + fprintf(out, "%s%c%s {\n", buffer, isPointer ? '*' : ' ', start); + fprintf(out, "\tvolatile unsigned char ___mmu = (unsigned char)*(volatile unsigned char *)%#06x;\n", swapSlot); + if (strcmp(buffer, "void") != 0) fprintf(out, "\t%s%cr;\n", buffer, isPointer ? '*' : ' '); + fprintf(out, "\t*(volatile unsigned char *)%#06x = %d;\n", swapSlot, _currentBank); + fprintf(out, "\t"); + if (strcmp(buffer, "void") != 0) fprintf(out, "r = "); + fprintf(out, "FAR%d_%s(%s);\n", _currentBank, functionName, arguments); + fprintf(out, "\t*(volatile unsigned char *)%#06x = ___mmu;\n", swapSlot); + if (strcmp(buffer, "void") != 0) fprintf(out, "\treturn r;"); + fprintf(out, "}\n\n"); + // Write out new function definition. - fprintf(out, "%s%cFAR%d_%s {\n", buffer, found ? '*' : ' ', _currentBank, start); + fprintf(out, "__attribute__((noinline, section(\".block%d\")))\n", _currentBank); + fprintf(out, "%s%cFAR%d_%s {\n", buffer, isPointer ? '*' : ' ', _currentBank, start); + // Create trampoline prototype. - fprintf(trampoline, "%s%cFAR%d_%s;\n", buffer, found ? '*' : ' ', _currentBank, start); - // Create trampoline macro. - fprintf(trampoline, "#define %s(...) ({ \\\n" - "\t\tunsigned char ___mmu = (unsigned char)*(volatile unsigned char *)%#06x; \\\n" - "\t\t*(volatile unsigned char *)%#06x = %d; \\\n" - "\t\tFAR%d_%s(__VA_ARGS__); \\\n" - "\t\t*(volatile unsigned char *)%#06x = ___mmu; \\\n" - "\t})\n\n", temp, swapSlot, swapSlot, _currentBank, _currentBank, temp, swapSlot); - free(temp); + fprintf(trampoline, "%s%cFAR%d_%s;\n", buffer, isPointer ? '*' : ' ', _currentBank, start); + + free(functionName); } else { // Not a function. Write as is. (Put the '{' back.) fprintf(out, "%s {\n", buffer); @@ -396,7 +439,7 @@ int main(int argc, char *argv[]) { free(sourceDir); } - fprintf(out, "#endif // TRAMPOLINE_H\n"); + fprintf(out, "\n#endif // TRAMPOLINE_H\n"); fclose(out); free(trampolineFile);