aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-09 12:14:54 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-09 12:14:54 +0100
commit00f66fd0d5de41b4c2fdaa7ec2ddf42d041e6af4 (patch)
tree7421df2a3f7d562a75c7d6ed2143370df32af2d4
parentd49b5caeb379cc2f49f7f3d04035ffc6fd60bf05 (diff)
downloadtr8vm-00f66fd0d5de41b4c2fdaa7ec2ddf42d041e6af4.tar.gz
tr8vm-00f66fd0d5de41b4c2fdaa7ec2ddf42d041e6af4.zip
Implelent proper defines
As oppossed to labels to arbitraty addresses. This also prepares the way to support calculated values.
-rw-r--r--README.md4
-rw-r--r--tr8as.c163
2 files changed, 102 insertions, 65 deletions
diff --git a/README.md b/README.md
index f8eb7e5..79d4049 100644
--- a/README.md
+++ b/README.md
@@ -287,8 +287,8 @@ and `>`for the high byte.
.dw imm [, imm]
Literal word (16-bit value).
-.equ label imm
-Define a label assigning an arbitrary immediate. Because it is a label, the value will be 16-bit unless `<` or `>` are used.
+.equ id value
+Define an ID assigning a constant value. When the id is used, it will be replaced with its value.
.include "filename"
Assemble the file at current position.
diff --git a/tr8as.c b/tr8as.c
index 29ef45c..aa5439d 100644
--- a/tr8as.c
+++ b/tr8as.c
@@ -35,6 +35,7 @@
#define MAX_ID 0x40
#define MAX_LABELS 0x200
#define MAX_REFS 0x1000
+#define MAX_DEFS 0x200
#define FHH 2
#define FHL 1
@@ -71,6 +72,13 @@ typedef struct
typedef struct
{
+ char id[MAX_ID + 1];
+ char value[MAX_ID + 1];
+ Location loc;
+} Define;
+
+typedef struct
+{
uint8_t out[UINT16_MAX + 1];
size_t size;
@@ -82,6 +90,9 @@ typedef struct
Reference refs[MAX_REFS];
uint16_t rcnt;
+
+ Define defs[MAX_DEFS];
+ uint16_t dcnt;
} As;
typedef struct
@@ -166,6 +177,39 @@ static uint8_t isspecial(char c)
return c == '$' || c == '_' || c == '.' || c == '#' || c == '<' || c == '>';
}
+static char * find_define(As *as, char *word, char *found)
+{
+ uint8_t i;
+
+ for (i = 0; i < as->dcnt; i++)
+ if (!strcmp(word, as->defs[i].id))
+ return find_define(as, as->defs[i].value, as->defs[i].value);
+
+ return found;
+}
+
+static uint8_t new_define(As *as, char *id, char *value)
+{
+ if (find_define(as, id, NULL))
+ return error_l("Id redefined", &as->loc, id);
+
+ value = find_define(as, value, value);
+
+ if (!strcmp(id, value))
+ return error_l("Recursive definition", &as->loc, id);
+
+ strcpy(as->defs[as->dcnt].id, id);
+ strcpy(as->defs[as->dcnt].value, value);
+
+ as->defs[as->dcnt].loc.filename = as->loc.filename;
+ as->defs[as->dcnt++].loc.line = as->loc.line;
+
+ if (as->dcnt == MAX_DEFS)
+ return error("Too many definitions", NULL);
+
+ return 1;
+}
+
static uint8_t next_word(As *as, char **c, char *word, uint8_t *wlen)
{
*c = skip_whitespace(*c);
@@ -187,10 +231,28 @@ static uint8_t next_word(As *as, char **c, char *word, uint8_t *wlen)
return 1;
}
-static uint8_t next_imm(char *word, uint16_t *n)
+static uint8_t next_imm(As *as, char *word, uint16_t *n)
{
+ Mod mod = ModNone;
+ char *def;
+
*n = 0;
+ if (*word == '<')
+ {
+ mod = ModLow;
+ word++;
+ }
+ else if (*word == '>')
+ {
+ mod = ModHigh;
+ word++;
+ }
+
+ def = find_define(as, word, NULL);
+ if (def)
+ word = def;
+
if (*word == '0')
{
/* hex */
@@ -210,7 +272,7 @@ static uint8_t next_imm(char *word, uint16_t *n)
word++;
}
- return *word;
+ goto done;
}
/* bin */
else if (word[1] == 'b')
@@ -225,7 +287,7 @@ static uint8_t next_imm(char *word, uint16_t *n)
word++;
}
- return *word;
+ goto done;
}
}
@@ -240,7 +302,18 @@ static uint8_t next_imm(char *word, uint16_t *n)
word++;
}
- return *word;
+done:
+ if (*word == 0)
+ {
+ if (mod == ModLow)
+ *n &= 0xff;
+ else if (mod == ModHigh)
+ *n >>= 8;
+
+ return 1;
+ }
+
+ return 0;
}
static uint8_t parse_register(char *word)
@@ -285,15 +358,6 @@ static uint8_t new_label(As *as, char *word)
return 1;
}
-static uint8_t new_label_imm(As *as, char *word, uint16_t imm)
-{
- if (!new_label(as, word))
- return 1;
-
- as->labels[as->lcnt - 1].addr = imm;
- return 1;
-}
-
static uint8_t new_ref(As *as, char *word, uint16_t mask, uint16_t addr)
{
Mod mod = ModNone;
@@ -405,7 +469,7 @@ static uint8_t parse_org(As *as, char **c)
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
- if (next_imm(word, &as->addr))
+ if (!next_imm(as, word, &as->addr))
return error_l("Syntax error", &as->loc, word);
if (as->addr > as->size)
@@ -573,29 +637,25 @@ static uint8_t parse_incbin(As *as, char **c)
static uint8_t parse_equ(As *as, char **c)
{
- char label[MAX_ID + 1];
- char word[MAX_ID + 1];
+ char id[MAX_ID + 1];
+ char value[MAX_ID + 1];
uint8_t wlen;
- uint16_t imm;
/* .equ label imm */
- if (!next_word(as, c, label, &wlen))
+ if (!next_word(as, c, id, &wlen))
return 0;
if (wlen == 0)
- return error_l("Syntax error", &as->loc, "expected label");
+ return error_l("Syntax error", &as->loc, "expected id");
- if (!next_word(as, c, word, &wlen))
+ if (!next_word(as, c, value, &wlen))
return 0;
if (wlen == 0)
- return error_l("Syntax error", &as->loc, "expected immediate");
+ return error_l("Syntax error", &as->loc, "expected value");
- if (next_imm(word, &imm))
- return error_l("Syntax error", &as->loc, word);
-
- return new_label_imm(as, label, imm);
+ return new_define(as, id, value);
}
static uint8_t parse_db(As *as, char **c)
@@ -614,11 +674,8 @@ static uint8_t parse_db(As *as, char **c)
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
- if (isdigit(*word))
+ if (next_imm(as, word, &imm))
{
- if (next_imm(word, &imm))
- return error_l("Syntax error", &as->loc, word);
-
if (imm > 0xff)
return error_l("Overflow in immediate", &as->loc, word);
}
@@ -656,11 +713,8 @@ static uint8_t parse_dw(As *as, char **c)
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
- if (isdigit(*word))
- {
- if (next_imm(word, &imm))
- return error_l("Syntax error", &as->loc, word);
- }
+ if (next_imm(as, word, &imm))
+ return error_l("Syntax error", &as->loc, word);
else if (!new_ref(as, word, 0xffff, as->addr))
return 0;
@@ -773,11 +827,8 @@ static uint8_t parse_r1_r2_or_imm(As *as, char **c, uint8_t *r1, uint8_t *r2, ui
return 1;
/* ? r1, imm */
- if (isdigit(*word))
+ if (next_imm(as, word, imm))
{
- if (next_imm(word, imm))
- return error_l("Syntax error", &as->loc, word);
-
if (*imm > 0xff)
return error_l("Overflow in immediate", &as->loc, word);
}
@@ -818,7 +869,7 @@ static uint8_t parse_r1_imm(As *as, char **c, uint8_t *r1, uint16_t *imm)
if (!isdigit(*word))
return error_l("Syntax error", &as->loc, "expected immediate");
- if (next_imm(word, imm))
+ if (!next_imm(as, word, imm))
return error_l("Syntax error", &as->loc, word);
return 1;
@@ -1232,10 +1283,7 @@ static uint8_t parse_indirect(As *as, char **c, uint8_t *r1, uint8_t *r2, uint16
if (wlen == 0)
return error_l("Syntax error", &as->loc, "expected immediate");
- if (!isdigit(*word))
- return error_l("Syntax error", &as->loc, "expected immediate");
-
- if (next_imm(word, imm))
+ if (!next_imm(as, word, imm))
return error_l("Syntax error", &as->loc, word);
if (*imm > 0xff)
@@ -1301,14 +1349,10 @@ static uint8_t parse_jmp(As *as, char **c)
return error_l("Syntax error", &as->loc, "expected label or immediate");
/* JMP imm */
- if (isdigit(*word))
- {
- if (next_imm(word, &imm))
- return error_l("Syntax error", &as->loc, word);
- }
- /* JMP label */
- else if (!new_ref(as, word, 0xffff, as->addr + 2))
- return 0;
+ if (!next_imm(as, word, &imm))
+ /* JMP label */
+ if (!new_ref(as, word, 0xffff, as->addr + 2))
+ return 0;
return (emit(as, 9, 0, FHH, FL) && emit_imm(as, imm));
}
@@ -1339,14 +1383,10 @@ static uint8_t parse_call(As *as, char **c)
return error_l("Syntax error", &as->loc, "expected label or immediate");
/* CALL imm */
- if (isdigit(*word))
- {
- if (next_imm(word, &imm))
- return error_l("Syntax error", &as->loc, word);
- }
- /* CALL label */
- else if (!new_ref(as, word, 0xffff, as->addr + 2))
- return 0;
+ if (!next_imm(as, word, &imm))
+ /* CALL label */
+ if (!new_ref(as, word, 0xffff, as->addr + 2))
+ return 0;
return (emit(as, 9, 0, FHH, 0) && emit_imm(as, imm));
}
@@ -1433,11 +1473,8 @@ static uint8_t parse_ld(As *as, char **c)
return emit(as, 1, r1, FHH, (r2 << 6));
/* LD r1, imm */
- if (isdigit(*word))
+ if (next_imm(as, word, &imm))
{
- if (next_imm(word, &imm))
- return error_l("Syntax error", &as->loc, word);
-
if (imm > 0xff)
return error_l("Overflow in immediate", &as->loc, word);
}