diff --git a/Tools/Breakasm/asm.cpp b/Tools/Breakasm/asm.cpp
index 3f98cf7..347d6b0 100644
--- a/Tools/Breakasm/asm.cpp
+++ b/Tools/Breakasm/asm.cpp
@@ -504,9 +504,21 @@ static void parse_line (char **text, line& ln)
// ****************************************************************
+int emit_mode = 1; // 1: output byte stream; 0: just change origin
+
+void set_emit_mode(int mode)
+{
+ emit_mode = mode;
+}
+
void emit (uint8_t b)
{
- PRG[org++] = b;
+ if (emit_mode) {
+ PRG[org++] = b;
+ }
+ else {
+ org++;
+ }
}
static oplink optab[] = {
@@ -577,9 +589,58 @@ static void cleanup (void)
}
}
-int assemble (char *text, char* source_name, uint8_t *prg)
+static void assemble_text(char* text)
{
+ oplink* opl;
line l;
+ int listing = 0;
+
+ while (1) {
+ if (*text == 0) break;
+ parse_line(&text, l);
+
+ // Add label
+ if (strlen(l.label) > 1) {
+ add_label(l.label, org);
+ }
+
+ long org_before = org;
+
+ // Execute command
+ if (strlen(l.cmd) > 1) {
+ opl = optab;
+ while (1) {
+ if (opl->name == NULL) {
+ printf("ERROR(%s,%i): Unknown command %s\n", get_source_name().c_str(), get_linenum(), l.cmd);
+ break;
+ }
+ else if (!_stricmp(opl->name, l.cmd)) {
+ _strupr(l.cmd);
+ opl->handler(l.cmd, l.op);
+ break;
+ }
+ opl++;
+ }
+ if (stop) break;
+ }
+
+ // Listing
+ if (listing) {
+ printf("0x%08X: ", org_before);
+ int num_bytes = org - org_before;
+ for (int i = 0; i < num_bytes; i++) {
+ printf("%02X ", PRG[org_before + i]);
+ }
+ printf("%s: \'%s\' \'%s\'\n", l.label, l.cmd, l.op);
+ printf("\n");
+ }
+
+ nextline();
+ }
+}
+
+int assemble (char *text, char* source_name, uint8_t *prg)
+{
oplink *opl;
PRG = prg;
org = 0;
@@ -603,36 +664,7 @@ int assemble (char *text, char* source_name, uint8_t *prg)
}
nextline();
- while (1) {
- if (*text == 0) break;
- parse_line (&text, l);
-
- //printf ( "%s: \'%s\' \'%s\'\n", l.label, l.cmd, l.op );
-
- // Add label
- if ( strlen (l.label) > 1 ) {
- add_label ( l.label, org );
- }
-
- // Execute command
- if ( strlen (l.cmd) > 1 ) {
- opl = optab;
- while (1) {
- if ( opl->name == NULL ) {
- printf ("ERROR(%s,%i): Unknown command %s\n", get_source_name().c_str(), get_linenum(), l.cmd);
- break;
- }
- else if ( !_stricmp (opl->name, l.cmd) ) {
- _strupr (l.cmd);
- opl->handler (l.cmd, l.op);
- break;
- }
- opl++;
- }
- if (stop) break;
- }
- nextline();
- }
+ assemble_text(text);
// Patch jump/branch offsets.
do_expr_labels();
@@ -656,42 +688,10 @@ int assemble (char *text, char* source_name, uint8_t *prg)
/// Source file name
void assemble_include(char* text, char* source_name)
{
- line l;
- oplink* opl;
-
source_name_stack.push_back(source_name);
linenum_stack.push_back(1);
- while (1) {
- if (*text == 0) break;
- parse_line(&text, l);
-
- //printf ( "%s: \'%s\' \'%s\'\n", l.label, l.cmd, l.op );
-
- // Add label
- if (strlen(l.label) > 1) {
- add_label(l.label, org);
- }
-
- // Execute command
- if (strlen(l.cmd) > 1) {
- opl = optab;
- while (1) {
- if (opl->name == NULL) {
- printf("ERROR(%s,%i): Unknown command %s\n", get_source_name().c_str(), get_linenum(), l.cmd);
- break;
- }
- else if (!_stricmp(opl->name, l.cmd)) {
- _strupr(l.cmd);
- opl->handler(l.cmd, l.op);
- break;
- }
- opl++;
- }
- if (stop) break;
- }
- nextline();
- }
+ assemble_text(text);
source_name_stack.pop_back();
linenum_stack.pop_back();
diff --git a/Tools/Breakasm/asmexpr.cpp b/Tools/Breakasm/asmexpr.cpp
index ad1b9a8..7f797ed 100644
--- a/Tools/Breakasm/asmexpr.cpp
+++ b/Tools/Breakasm/asmexpr.cpp
@@ -359,7 +359,7 @@ static node_t* addnode(std::list& tree, token_t* token, int depth)
}
// executing the tree (semantic analysis)
-static node_t * evaluate (std::list& tree, node_t * expr, long *lvalue, bool quiet)
+static node_t * evaluate (std::list& tree, node_t * expr, long *lvalue, bool quiet, bool& syntax_error)
{
node_t * curr;
long rvalue = 0, mvalue;
@@ -379,6 +379,7 @@ static node_t * evaluate (std::list& tree, node_t * expr, long *lvalue,
token = curr->token;
if ( token->type == TOKEN_OP && isunary(token->op) ) {
if (curr->rvalue == NULL) {
+ syntax_error = true;
if (!quiet) {
printf("Missing identifier\n");
errors++;
@@ -401,7 +402,7 @@ static node_t * evaluate (std::list& tree, node_t * expr, long *lvalue,
if ( curr->depth > expr->depth ) { // nested expression
if (debug) printf ( "SUBEVAL " );
- curr = evaluate (tree, curr, &mvalue, quiet);
+ curr = evaluate (tree, curr, &mvalue, quiet, syntax_error);
//printf ( "SUB LVALUE : %i\n", mvalue.num.value );
}
else if ( token->type == TOKEN_IDENT) {
@@ -413,10 +414,11 @@ static node_t * evaluate (std::list& tree, node_t * expr, long *lvalue,
}
else {
label_s* label = label_lookup(token->string);
- if (label) {
+ if (label && label->orig != UNDEF && !label->composite) {
mvalue = label->orig;
}
else {
+ syntax_error = true;
if (!quiet) {
printf("Undefined identifier: %s", token->string);
errors++;
@@ -468,6 +470,7 @@ static node_t * evaluate (std::list& tree, node_t * expr, long *lvalue,
else rvalue = mvalue;
}
else {
+ syntax_error = true;
if (!quiet) {
printf("Identifier required\n");
errors++;
@@ -583,7 +586,13 @@ long eval_expr(char* text, bool debug, bool quiet)
// Execute the tree
long result = 0;
- evaluate(tree.nodes, root->rvalue->rvalue, &result, quiet);
+ bool syntax_error = false;
+ if (root) {
+ evaluate(tree.nodes, root->rvalue->rvalue, &result, quiet, syntax_error);
+ }
+ if (syntax_error) {
+ result = 0;
+ }
if (debug)
printf("Source expression: %s, result: %d (0x%08X)\n", text, result, result);