From c9f242e566f5a86c0bf4809aa5f1e2ddbc617b63 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Wed, 5 May 2021 14:42:29 +0200 Subject: [PATCH 1/6] Extend #pragma wrapped-call to support "bank" argument --- src/cc65/declare.c | 4 +++- src/cc65/expr.c | 13 ++++++++++--- src/cc65/funcdesc.h | 1 + src/cc65/pragma.c | 10 +++++++--- src/cc65/wrappedcall.c | 9 +++++---- src/cc65/wrappedcall.h | 4 ++-- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0868c2082..0b705a320 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1739,6 +1739,7 @@ static FuncDesc* ParseFuncDecl (void) SymEntry* Sym; SymEntry* WrappedCall; unsigned char WrappedCallData; + int WrappedCallUseBank; /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1791,10 +1792,11 @@ static FuncDesc* ParseFuncDecl (void) RememberFunctionLevel (F); /* Did we have a WrappedCall for this function? */ - GetWrappedCall((void **) &WrappedCall, &WrappedCallData); + GetWrappedCall((void **) &WrappedCall, &WrappedCallData, &WrappedCallUseBank); if (WrappedCall) { F->WrappedCall = WrappedCall; F->WrappedCallData = WrappedCallData; + F->WrappedCallUseBank = WrappedCallUseBank; } /* Return the function descriptor */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index bc277f13b..d2cd4ca5c 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -997,9 +997,16 @@ static void FunctionCall (ExprDesc* Expr) char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - /* Store the WrappedCall data in tmp4 */ - sprintf(tmp, "ldy #%u", Func->WrappedCallData); - SB_AppendStr (&S, tmp); + if (Func->WrappedCallUseBank) { + /* Store the bank attribute in tmp4 */ + SB_AppendStr (&S, "ldy #<.bank(_"); + SB_AppendStr (&S, (const char*) Expr->Name); + SB_AppendChar (&S, ')'); + } else { + /* Store the WrappedCall data in tmp4 */ + sprintf(tmp, "ldy #%u", Func->WrappedCallData); + SB_AppendStr (&S, tmp); + } g_asmcode (&S); SB_Clear(&S); diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 423e7621f..5875723fb 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -72,6 +72,7 @@ struct FuncDesc { struct FuncDesc* FuncDef; /* Descriptor used in definition */ struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ unsigned char WrappedCallData;/* The WrappedCall's user data */ + int WrappedCallUseBank;/* Flag: does WrappedCall use .bank() or literal value */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index f0f7ed36f..249e4f1b4 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -497,6 +497,7 @@ static void WrappedCallPragma (StrBuf* B) const char *Name; long Val; SymEntry *Entry; + int UseBank = 0; /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { @@ -535,12 +536,15 @@ static void WrappedCallPragma (StrBuf* B) goto ExitPoint; } - if (!GetNumber (B, &Val)) { + /* Next must be either a numeric value, or "bank" */ + if (HasStr (B, "bank")) { + UseBank = 1; + } else if (!GetNumber (B, &Val)) { Error ("Value required for wrapped-call identifier"); goto ExitPoint; } - if (Val < 0 || Val > 255) { + if (!UseBank && (Val < 0 || Val > 255)) { Error ("Identifier must be between 0-255"); goto ExitPoint; } @@ -552,7 +556,7 @@ static void WrappedCallPragma (StrBuf* B) /* Check if the name is valid */ if (Entry && (Entry->Flags & SC_FUNC) == SC_FUNC) { - PushWrappedCall(Entry, (unsigned char) Val); + PushWrappedCall(Entry, (unsigned char) Val, UseBank); Entry->Flags |= SC_REF; GetFuncDesc (Entry->Type)->Flags |= FD_CALL_WRAPPER; diff --git a/src/cc65/wrappedcall.c b/src/cc65/wrappedcall.c index 18cb507ac..a67f9815d 100644 --- a/src/cc65/wrappedcall.c +++ b/src/cc65/wrappedcall.c @@ -64,13 +64,13 @@ static IntPtrStack WrappedCalls; -void PushWrappedCall (void *Ptr, unsigned char Val) +void PushWrappedCall (void *Ptr, unsigned char Val, int UseBank) /* Push the current WrappedCall */ { if (IPS_IsFull (&WrappedCalls)) { Error ("WrappedCall stack overflow"); } else { - IPS_Push (&WrappedCalls, Val, Ptr); + IPS_Push (&WrappedCalls, Val | (UseBank << 8), Ptr); } } @@ -88,7 +88,7 @@ void PopWrappedCall (void) -void GetWrappedCall (void **Ptr, unsigned char *Val) +void GetWrappedCall (void **Ptr, unsigned char *Val, int *UseBank) /* Get the current WrappedCall */ { if (IPS_GetCount (&WrappedCalls) < 1) { @@ -97,6 +97,7 @@ void GetWrappedCall (void **Ptr, unsigned char *Val) } else { long Temp; IPS_Get (&WrappedCalls, &Temp, Ptr); - *Val = (unsigned char) Temp; + *UseBank = (int) Temp >> 8; + *Val = (unsigned char) Temp & 0xff; } } diff --git a/src/cc65/wrappedcall.h b/src/cc65/wrappedcall.h index 3517c2465..ddf6dd2b9 100644 --- a/src/cc65/wrappedcall.h +++ b/src/cc65/wrappedcall.h @@ -50,13 +50,13 @@ -void PushWrappedCall (void *Ptr, unsigned char Val); +void PushWrappedCall (void *Ptr, unsigned char Val, int usebank); /* Push the current WrappedCall */ void PopWrappedCall (void); /* Pop the current WrappedCall */ -void GetWrappedCall (void **Ptr, unsigned char *Val); +void GetWrappedCall (void **Ptr, unsigned char *Val, int *usebank); /* Get the current WrappedCall, if any */ From 729690e9e97a9eefa06d744fb1762caa3351f548 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Wed, 5 May 2021 16:07:47 +0200 Subject: [PATCH 2/6] document the wrapped-call extension --- doc/cc65.sgml | 5 ++++- doc/ld65.sgml | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index dc754cb31..f4b31b8bc 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1388,7 +1388,10 @@ parameter with the operator will be used + to determine the number from the bank attribute defined in the linker config, + see . The address of a wrapped function is passed in Other MEMORY area attributes

+Other MEMORY area attributes

There are some other attributes not covered above. Before starting the reference section, I will discuss the remaining things here. @@ -822,7 +822,6 @@ that has a segment reference (for example a symbol). The result of this function is the value of the bank attribute for the run memory area of the segment. - Other SEGMENT attributes

Segments may be aligned to some memory boundary. Specify " Date: Tue, 11 May 2021 13:36:30 +0200 Subject: [PATCH 3/6] use url instead of htmlurl, add note on least significant 8bits of the bank value --- doc/cc65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index f4b31b8bc..7912b85a9 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1389,9 +1389,11 @@ parameter with the operator will be used + is "bank", then a operator will be used to determine the number from the bank attribute defined in the linker config, - see . + see . Note that + this currently implies that only the least significant 8 bits of the bank attribute + can be used. The address of a wrapped function is passed in Date: Tue, 11 May 2021 13:37:53 +0200 Subject: [PATCH 4/6] improve error message --- src/cc65/pragma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 249e4f1b4..84869e60f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -532,7 +532,7 @@ static void WrappedCallPragma (StrBuf* B) /* Skip the following comma */ if (!GetComma (B)) { /* Error already flagged by GetComma */ - Error ("Value required for wrapped-call identifier"); + Error ("Value or the word 'bank' required for wrapped-call identifier"); goto ExitPoint; } From 18f94d1fe0b2b04c723419a4df9078f77c88c0a0 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Tue, 11 May 2021 14:00:49 +0200 Subject: [PATCH 5/6] rework to use a magic value instead of a flag, as suggested by Oliver --- src/cc65/declare.c | 6 ++---- src/cc65/expr.c | 2 +- src/cc65/funcdesc.h | 5 ++--- src/cc65/pragma.c | 7 +++---- src/cc65/wrappedcall.c | 9 ++++----- src/cc65/wrappedcall.h | 4 ++-- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0b705a320..8879c46d8 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1738,8 +1738,7 @@ static FuncDesc* ParseFuncDecl (void) { SymEntry* Sym; SymEntry* WrappedCall; - unsigned char WrappedCallData; - int WrappedCallUseBank; + unsigned int WrappedCallData; /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1792,11 +1791,10 @@ static FuncDesc* ParseFuncDecl (void) RememberFunctionLevel (F); /* Did we have a WrappedCall for this function? */ - GetWrappedCall((void **) &WrappedCall, &WrappedCallData, &WrappedCallUseBank); + GetWrappedCall((void **) &WrappedCall, &WrappedCallData); if (WrappedCall) { F->WrappedCall = WrappedCall; F->WrappedCallData = WrappedCallData; - F->WrappedCallUseBank = WrappedCallUseBank; } /* Return the function descriptor */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d2cd4ca5c..01bebf18e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -997,7 +997,7 @@ static void FunctionCall (ExprDesc* Expr) char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - if (Func->WrappedCallUseBank) { + if (Func->WrappedCallData == WRAPPED_CALL_USE_BANK) { /* Store the bank attribute in tmp4 */ SB_AppendStr (&S, "ldy #<.bank(_"); SB_AppendStr (&S, (const char*) Expr->Name); diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 5875723fb..305fd14f5 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -58,7 +58,7 @@ /* Bits that must be ignored when comparing funcs */ #define FD_IGNORE (FD_INCOMPLETE_PARAM | FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) - +#define WRAPPED_CALL_USE_BANK 0x0100U /* WrappedCall uses .bank() */ /* Function descriptor */ typedef struct FuncDesc FuncDesc; @@ -71,8 +71,7 @@ struct FuncDesc { struct SymEntry* LastParam; /* Pointer to last parameter */ struct FuncDesc* FuncDef; /* Descriptor used in definition */ struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ - unsigned char WrappedCallData;/* The WrappedCall's user data */ - int WrappedCallUseBank;/* Flag: does WrappedCall use .bank() or literal value */ + unsigned int WrappedCallData;/* The WrappedCall's user data */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 84869e60f..e4bb4cdeb 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -497,7 +497,6 @@ static void WrappedCallPragma (StrBuf* B) const char *Name; long Val; SymEntry *Entry; - int UseBank = 0; /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { @@ -538,13 +537,13 @@ static void WrappedCallPragma (StrBuf* B) /* Next must be either a numeric value, or "bank" */ if (HasStr (B, "bank")) { - UseBank = 1; + Val = WRAPPED_CALL_USE_BANK; } else if (!GetNumber (B, &Val)) { Error ("Value required for wrapped-call identifier"); goto ExitPoint; } - if (!UseBank && (Val < 0 || Val > 255)) { + if (!(Val == WRAPPED_CALL_USE_BANK) && (Val < 0 || Val > 255)) { Error ("Identifier must be between 0-255"); goto ExitPoint; } @@ -556,7 +555,7 @@ static void WrappedCallPragma (StrBuf* B) /* Check if the name is valid */ if (Entry && (Entry->Flags & SC_FUNC) == SC_FUNC) { - PushWrappedCall(Entry, (unsigned char) Val, UseBank); + PushWrappedCall(Entry, (unsigned int) Val); Entry->Flags |= SC_REF; GetFuncDesc (Entry->Type)->Flags |= FD_CALL_WRAPPER; diff --git a/src/cc65/wrappedcall.c b/src/cc65/wrappedcall.c index a67f9815d..ecf2c3a53 100644 --- a/src/cc65/wrappedcall.c +++ b/src/cc65/wrappedcall.c @@ -64,13 +64,13 @@ static IntPtrStack WrappedCalls; -void PushWrappedCall (void *Ptr, unsigned char Val, int UseBank) +void PushWrappedCall (void *Ptr, unsigned int Val) /* Push the current WrappedCall */ { if (IPS_IsFull (&WrappedCalls)) { Error ("WrappedCall stack overflow"); } else { - IPS_Push (&WrappedCalls, Val | (UseBank << 8), Ptr); + IPS_Push (&WrappedCalls, Val, Ptr); } } @@ -88,7 +88,7 @@ void PopWrappedCall (void) -void GetWrappedCall (void **Ptr, unsigned char *Val, int *UseBank) +void GetWrappedCall (void **Ptr, unsigned int *Val) /* Get the current WrappedCall */ { if (IPS_GetCount (&WrappedCalls) < 1) { @@ -97,7 +97,6 @@ void GetWrappedCall (void **Ptr, unsigned char *Val, int *UseBank) } else { long Temp; IPS_Get (&WrappedCalls, &Temp, Ptr); - *UseBank = (int) Temp >> 8; - *Val = (unsigned char) Temp & 0xff; + *Val = (unsigned int) Temp; } } diff --git a/src/cc65/wrappedcall.h b/src/cc65/wrappedcall.h index ddf6dd2b9..9a1bb51bf 100644 --- a/src/cc65/wrappedcall.h +++ b/src/cc65/wrappedcall.h @@ -50,13 +50,13 @@ -void PushWrappedCall (void *Ptr, unsigned char Val, int usebank); +void PushWrappedCall (void *Ptr, unsigned int Val); /* Push the current WrappedCall */ void PopWrappedCall (void); /* Pop the current WrappedCall */ -void GetWrappedCall (void **Ptr, unsigned char *Val, int *usebank); +void GetWrappedCall (void **Ptr, unsigned int *Val); /* Get the current WrappedCall, if any */ From 07dd1e3849672f8c1487ef652611f745a96a90da Mon Sep 17 00:00:00 2001 From: mrdudz Date: Tue, 11 May 2021 14:14:44 +0200 Subject: [PATCH 6/6] fix formatting --- src/cc65/funcdesc.c | 16 ++++++++-------- src/cc65/funcdesc.h | 34 +++++++++++++++++----------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 4c959fb6c..2291b35ee 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -54,14 +54,14 @@ FuncDesc* NewFuncDesc (void) FuncDesc* F = (FuncDesc*) xmalloc (sizeof (FuncDesc)); /* Nullify the fields */ - F->Flags = 0; - F->SymTab = 0; - F->TagTab = 0; - F->ParamCount = 0; - F->ParamSize = 0; - F->LastParam = 0; - F->FuncDef = 0; - F->WrappedCall = 0; + F->Flags = 0; + F->SymTab = 0; + F->TagTab = 0; + F->ParamCount = 0; + F->ParamSize = 0; + F->LastParam = 0; + F->FuncDef = 0; + F->WrappedCall = 0; F->WrappedCallData = 0; /* Return the new struct */ diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 305fd14f5..e065c7602 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -45,15 +45,15 @@ /* Masks for the Flags field in FuncDesc */ -#define FD_NONE 0x0000U /* No flags */ -#define FD_EMPTY 0x0001U /* Function with empty param list */ -#define FD_VOID_PARAM 0x0002U /* Function with a void param list */ -#define FD_VARIADIC 0x0004U /* Function with variable param list */ +#define FD_NONE 0x0000U /* No flags */ +#define FD_EMPTY 0x0001U /* Function with empty param list */ +#define FD_VOID_PARAM 0x0002U /* Function with a void param list */ +#define FD_VARIADIC 0x0004U /* Function with variable param list */ #define FD_INCOMPLETE_PARAM 0x0008U /* Function with param of unknown size */ -#define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ -#define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ -#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ -#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ +#define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ +#define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ +#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ +#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ /* Bits that must be ignored when comparing funcs */ #define FD_IGNORE (FD_INCOMPLETE_PARAM | FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) @@ -63,15 +63,15 @@ /* Function descriptor */ typedef struct FuncDesc FuncDesc; struct FuncDesc { - unsigned Flags; /* Bitmapped flags FD_... */ - struct SymTable* SymTab; /* Symbol table */ - struct SymTable* TagTab; /* Symbol table for structs/enums */ - unsigned ParamCount; /* Number of parameters */ - unsigned ParamSize; /* Size of the parameters */ - struct SymEntry* LastParam; /* Pointer to last parameter */ - struct FuncDesc* FuncDef; /* Descriptor used in definition */ - struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ - unsigned int WrappedCallData;/* The WrappedCall's user data */ + unsigned Flags; /* Bitmapped flags FD_... */ + struct SymTable* SymTab; /* Symbol table */ + struct SymTable* TagTab; /* Symbol table for structs/enums */ + unsigned ParamCount; /* Number of parameters */ + unsigned ParamSize; /* Size of the parameters */ + struct SymEntry* LastParam; /* Pointer to last parameter */ + struct FuncDesc* FuncDef; /* Descriptor used in definition */ + struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ + unsigned int WrappedCallData; /* The WrappedCall's user data */ };