Many overlay tool fixes.
This commit is contained in:
parent
cd27a5061a
commit
01357db32b
6 changed files with 77 additions and 25 deletions
1
examples/.gitattributes
vendored
Normal file
1
examples/.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
a23d2/a2-3d/A2-3D2\#066000 filter=lfs diff=lfs merge=lfs -text
|
|
@ -31,6 +31,10 @@ PATH=${LLVM}/bin:${PATH}
|
||||||
|
|
||||||
CLANG="mos-f256k-clang -I${F256}/include -I${F256}/f256lib -Os"
|
CLANG="mos-f256k-clang -I${F256}/include -I${F256}/f256lib -Os"
|
||||||
|
|
||||||
|
pushd ${F256}
|
||||||
|
./build-tools.sh
|
||||||
|
popd
|
||||||
|
|
||||||
[[ -d .builddir ]] && rm -rf .builddir
|
[[ -d .builddir ]] && rm -rf .builddir
|
||||||
mkdir -p .builddir
|
mkdir -p .builddir
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,18 @@
|
||||||
#include "f256.c"
|
#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
|
// This is the first segment we've defined. The linker will place this code in
|
||||||
// the first available far memory slot (default 0x10000).
|
// the first available far memory slot (default 0x10000).
|
||||||
#define SEGMENT_FIRST
|
#define SEGMENT_FIRST
|
||||||
|
|
||||||
void firstSegment(int arg1, int arg2) {
|
void firstSegment(int arg1, int arg2) {
|
||||||
printf("firstSegment = %d\n", arg1 + 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
|
// 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) {
|
void secondSegment(int arg1, int arg2) {
|
||||||
printf("secondSegment = %d\n", arg1 + arg2);
|
printf("secondSegment = %d\n", arg1 + arg2);
|
||||||
|
moreFirstSegment(arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back to the first segment. The linker will place this code immediately
|
// 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
|
// The overlay tool will generate trampoline macros for each function
|
||||||
// that is located in a far segment so no code changes are required.
|
// that is located in a far segment so no code changes are required.
|
||||||
firstSegment(1, 2);
|
firstSegment(1, 2);
|
||||||
secondSegment(3, 4);
|
|
||||||
moreFirstSegment(5, 6);
|
|
||||||
|
|
||||||
// Spin.
|
// Spin.
|
||||||
for (;;);
|
for (;;);
|
||||||
|
|
|
@ -130,10 +130,10 @@ uint16_t FAR_PEEKW(uint32_t address) {
|
||||||
|
|
||||||
|
|
||||||
void *FAR_POINTER(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.
|
// This only works if we use slot 5 and don't restore it after swapping.
|
||||||
#if SWAP_SLOT == MMU_MEM_BANK_5
|
#if SWAP_SLOT == MMU_MEM_BANK_5
|
||||||
|
byte block;
|
||||||
|
|
||||||
block = address / EIGHTK;
|
block = address / EIGHTK;
|
||||||
address &= 0x1FFF; // Find offset into this block.
|
address &= 0x1FFF; // Find offset into this block.
|
||||||
POKE(SWAP_SLOT, block);
|
POKE(SWAP_SLOT, block);
|
||||||
|
|
|
@ -38,7 +38,6 @@ static byte _BITMAP_CLUT[3];
|
||||||
static byte _color;
|
static byte _color;
|
||||||
static byte _active; // Current drawing page.
|
static byte _active; // Current drawing page.
|
||||||
|
|
||||||
// uint32_t address = _BITMAP_BASE[_active] + (y * _MAX_X + (int32_t)x); \
|
|
||||||
|
|
||||||
#define bitmapPutPixelIOSet(x, y) ({ \
|
#define bitmapPutPixelIOSet(x, y) ({ \
|
||||||
uint32_t address = _BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x); \
|
uint32_t address = _BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x); \
|
||||||
|
|
|
@ -79,10 +79,13 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
||||||
FILE *in;
|
FILE *in;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
int c;
|
int c;
|
||||||
|
char arguments[BUFFER_SIZE];
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
char *temp;
|
char *functionName;
|
||||||
char *start;
|
char *start;
|
||||||
|
char *a;
|
||||||
char *b;
|
char *b;
|
||||||
|
bool isPointer;
|
||||||
bool found;
|
bool found;
|
||||||
int x;
|
int x;
|
||||||
int line = 1;
|
int line = 1;
|
||||||
|
@ -174,41 +177,81 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
||||||
trimEnd(buffer);
|
trimEnd(buffer);
|
||||||
// Functions end with a closing parenthesis.
|
// Functions end with a closing parenthesis.
|
||||||
if (buffer[strlen(buffer) - 1] == ')') {
|
if (buffer[strlen(buffer) - 1] == ')') {
|
||||||
// Function. Annotate it!
|
// Found function! Scan forward to find the '(' after the function name.
|
||||||
fprintf(out, "__attribute__((noinline, section(\".block%d\")))\n", _currentBank);
|
|
||||||
|
|
||||||
// Scan forward to find the '(' after the function name.
|
|
||||||
b = buffer;
|
b = buffer;
|
||||||
while (*b != '(') b++;
|
while (*b != '(') b++;
|
||||||
// Now go backwards and look for a space.
|
// Now go backwards and look for a space.
|
||||||
start = b;
|
start = b;
|
||||||
while (*start != ' ') start--;
|
while (*start != ' ') start--;
|
||||||
// Are they returning a pointer?
|
// Are they returning a pointer?
|
||||||
found = false;
|
isPointer = false;
|
||||||
if (*(start+1) == '*') {
|
if (*(start+1) == '*') {
|
||||||
found = true;
|
isPointer = true;
|
||||||
++start;
|
++start;
|
||||||
*start++ = 0;
|
*start++ = 0;
|
||||||
} else {
|
} else {
|
||||||
*start++ = 0;
|
*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.
|
// Yank the function name out.
|
||||||
*b = 0;
|
*b = 0;
|
||||||
temp = strdup(start);
|
functionName = strdup(start);
|
||||||
*b = '(';
|
*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.
|
// 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.
|
// Create trampoline prototype.
|
||||||
fprintf(trampoline, "%s%cFAR%d_%s;\n", buffer, found ? '*' : ' ', _currentBank, start);
|
fprintf(trampoline, "%s%cFAR%d_%s;\n", buffer, isPointer ? '*' : ' ', _currentBank, start);
|
||||||
// Create trampoline macro.
|
|
||||||
fprintf(trampoline, "#define %s(...) ({ \\\n"
|
free(functionName);
|
||||||
"\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);
|
|
||||||
} else {
|
} else {
|
||||||
// Not a function. Write as is. (Put the '{' back.)
|
// Not a function. Write as is. (Put the '{' back.)
|
||||||
fprintf(out, "%s {\n", buffer);
|
fprintf(out, "%s {\n", buffer);
|
||||||
|
@ -396,7 +439,7 @@ int main(int argc, char *argv[]) {
|
||||||
free(sourceDir);
|
free(sourceDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(out, "#endif // TRAMPOLINE_H\n");
|
fprintf(out, "\n#endif // TRAMPOLINE_H\n");
|
||||||
fclose(out);
|
fclose(out);
|
||||||
free(trampolineFile);
|
free(trampolineFile);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue