From d23db09f7f424ae837b2cabaa1f57506073044e9 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Thu, 25 Feb 2016 12:40:31 -0800 Subject: [PATCH 1/2] Add optional feature to use brackets instead of parens for 6502 indirect addressing. --- doc/ca65.sgml | 14 ++++++++++++ src/ca65/ea65.c | 56 +++++++++++++++++++++++++++++----------------- src/ca65/feature.c | 2 ++ src/ca65/feature.h | 1 + src/ca65/global.c | 1 + src/ca65/global.h | 1 + 6 files changed, 55 insertions(+), 20 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 213033cd4..f863e7e10 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2699,6 +2699,20 @@ Here's a list of all control commands and a description, what they do: at character is not allowed to start an identifier, even with this feature enabled. + bracket_as_indirect + + Use [] intead of () for the indirect addressing mode. + Example: + + + lda [$82] + lda [$82,x] + lda [$82],y + + / for more information. + c_comments Allow C like comments using /* and */ as left and right diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 5f76f2966..69468c072 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -40,6 +40,7 @@ #include "expr.h" #include "instr.h" #include "nexttok.h" +#include "global.h" @@ -53,6 +54,20 @@ void GetEA (EffAddr* A) /* Parse an effective address, return the result in A */ { unsigned long Restrictions; + token_t IndirectEnter; + token_t IndirectLeave; + const char* IndirectExpect; + + /* Choose syntax for indirection */ + if (BracketAsIndirect) { + IndirectEnter = TOK_LBRACK; + IndirectLeave = TOK_RBRACK; + IndirectExpect = "']' expected"; + } else { + IndirectEnter = TOK_LPAREN; + IndirectLeave = TOK_RPAREN; + IndirectExpect = "')' expected"; + } /* Clear the output struct */ A->AddrModeSet = 0; @@ -97,23 +112,7 @@ void GetEA (EffAddr* A) NextTok (); A->AddrModeSet = AM65_ACCU; - } else if (CurTok.Tok == TOK_LBRACK) { - - /* [dir] or [dir],y */ - NextTok (); - A->Expr = Expression (); - Consume (TOK_RBRACK, "']' expected"); - if (CurTok.Tok == TOK_COMMA) { - /* [dir],y */ - NextTok (); - Consume (TOK_Y, "`Y' expected"); - A->AddrModeSet = AM65_DIR_IND_LONG_Y; - } else { - /* [dir] */ - A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG; - } - - } else if (CurTok.Tok == TOK_LPAREN) { + } else if (CurTok.Tok == IndirectEnter) { /* One of the indirect modes */ NextTok (); @@ -127,12 +126,12 @@ void GetEA (EffAddr* A) /* (adr,x) */ NextTok (); A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND; - ConsumeRParen (); + Consume (IndirectLeave, IndirectExpect); } else if (CurTok.Tok == TOK_S) { /* (rel,s),y */ NextTok (); A->AddrModeSet = AM65_STACK_REL_IND_Y; - ConsumeRParen (); + Consume (IndirectLeave, IndirectExpect); ConsumeComma (); Consume (TOK_Y, "`Y' expected"); } else { @@ -142,7 +141,7 @@ void GetEA (EffAddr* A) } else { /* (adr) or (adr),y */ - ConsumeRParen (); + Consume (IndirectLeave, IndirectExpect); if (CurTok.Tok == TOK_COMMA) { /* (adr),y */ NextTok (); @@ -154,6 +153,23 @@ void GetEA (EffAddr* A) } } + } else if (CurTok.Tok == TOK_LBRACK) { + + /* Never executed if BracketAsIndirect feature is enabled. */ + /* [dir] or [dir],y */ + NextTok (); + A->Expr = Expression (); + Consume (TOK_RBRACK, "']' expected"); + if (CurTok.Tok == TOK_COMMA) { + /* [dir],y */ + NextTok (); + Consume (TOK_Y, "`Y' expected"); + A->AddrModeSet = AM65_DIR_IND_LONG_Y; + } else { + /* [dir] */ + A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG; + } + } else { /* Remaining stuff: diff --git a/src/ca65/feature.c b/src/ca65/feature.c index 3462d5501..35bdf4b98 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -64,6 +64,7 @@ static const char* FeatureKeys[FEAT_COUNT] = { "force_range", "underline_in_numbers", "addrsize", + "bracket_as_indirect", }; @@ -121,6 +122,7 @@ feature_t SetFeature (const StrBuf* Key) case FEAT_FORCE_RANGE: ForceRange = 1; break; case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break; case FEAT_ADDRSIZE: AddrSize = 1; break; + case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break; default: /* Keep gcc silent */ break; } diff --git a/src/ca65/feature.h b/src/ca65/feature.h index 3a520a54a..050c197f0 100644 --- a/src/ca65/feature.h +++ b/src/ca65/feature.h @@ -66,6 +66,7 @@ typedef enum { FEAT_FORCE_RANGE, FEAT_UNDERLINE_IN_NUMBERS, FEAT_ADDRSIZE, + FEAT_BRACKET_AS_INDIRECT, /* Special value: Number of features available */ FEAT_COUNT diff --git a/src/ca65/global.c b/src/ca65/global.c index e77b9201c..31e599f00 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -83,4 +83,5 @@ unsigned char CComments = 0; /* Allow C like comments */ unsigned char ForceRange = 0; /* Force values into expected range */ unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */ unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */ +unsigned char BracketAsIndirect = 0; /* Use '[]' not '()' for indirection */ diff --git a/src/ca65/global.h b/src/ca65/global.h index fb254f835..397d9221b 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -85,6 +85,7 @@ extern unsigned char CComments; /* Allow C like comments */ extern unsigned char ForceRange; /* Force values into expected range */ extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */ extern unsigned char AddrSize; /* Allow .ADDRSIZE function */ +extern unsigned char BracketAsIndirect; /* Use '[]' not '()' for indirection */ From ef153364eab92e2124035e5555b8c5cfbfa6e5b4 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Fri, 26 Feb 2016 08:10:11 -0800 Subject: [PATCH 2/2] Add indirect JMP examples and fix typos in the documentation. --- doc/ca65.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index f863e7e10..14fe8714f 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2701,13 +2701,15 @@ Here's a list of all control commands and a description, what they do: bracket_as_indirect - Use [] intead of () for the indirect addressing mode. + Use [] instead of () for the indirect addressing modes. Example: lda [$82] lda [$82,x] lda [$82],y + jmp [$fffe] + jmp [table,x]