From cd6982e5da1f5facdc1e0154b3a27c01e8b076c9 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Wed, 27 Jan 2021 13:42:57 -0500 Subject: - Fixed some bugs in the emulator. - Started work on implementing the Super VIA emulation. - Added support for disabling disassembly per instruction, when in debug mode. - Did some more work on rewriting the SuB Suite to work with the new calling convention. - Rewrote the symbol handling code in the emulator's assembler, to make it both simpler, and to add support for arbitrarily deep symbol scopes. - Added support for arbitrarily deep local symbol scopes. For example, to declare a symbol of depth 2, you add two '@' characters to the start of the symbol name. In other words, the number of '@' characters before the symbol name is what determines the scope of that symbol. And to use a symbol thats outside the current scope, you would use the same syntax as using a struct member, so you would do `global.local`. --- assemble.c | 57 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 12 deletions(-) (limited to 'assemble.c') diff --git a/assemble.c b/assemble.c index 91972eb..f4de278 100644 --- a/assemble.c +++ b/assemble.c @@ -479,8 +479,10 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t }*/ for (; t && i < 2; t = t->next) { + reg = (old_i != i) ? 0 : reg; + got_value = (old_i != i) ? 0 : got_value; if (t->subtype == TOK_IND) { - brack_done = 1; + brack_done = (t->id == TOK_REG) ? 2 : 1; } switch (t->id) { case TOK_HEX : @@ -544,8 +546,8 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t } else { if (op[i].type == 1) { if (op[i].id == MEM_IND) { - op[i].id = (!brack_done && got_value) ? MEM_ZRIND : MEM_RIND; - op[i].id = (brack_done && got_value) ? MEM_ZINDR : op[i].id; + op[i].id = ((!brack_done || brack_done == 2) && got_value) ? MEM_ZRIND : MEM_RIND; + op[i].id = (brack_done == 1 && got_value) ? MEM_ZINDR : op[i].id; brack_done = 0; } else { op[i].id = (got_value) ? MEM_ZMR : op[i].id; @@ -578,7 +580,6 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t op[0].cc = t->byte; i = 3; break; - } if (!t) { break; @@ -737,6 +738,13 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, i = 8; for (; i <= 64; i += 8, j++) { max_val |= ((uint64_t)1 << (i-1)); + /*int64_t tmp_val = (int64_t)op[0].value; + int is_pos = (tmp_val >= 0); + int is_neg = (tmp_val < 0); + if ((is_pos && tmp_val <= ~(int64_t)(max_val)) || (is_neg && tmp_val >= (int64_t)(max_val))) { + opsize = j; + break; + }*/ if ((int64_t)op[0].value >= ~(int64_t)(max_val) || (int64_t)op[0].value <= (int64_t)(max_val)) { opsize = j; break; @@ -917,6 +925,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, if (op[0].cc != 0xFF && op[0].cc < 8) { opcode |= (op[0].cc << 5); } + uint8_t tmp_size = 0; for (int i = 0; i < 2 && op[i].type != 0xFF; i++) { int i2 = 0; int j = 0; @@ -936,17 +945,20 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, if (op[i].id != MEM_IND && op[i].id != 0xFF) { max_val = 0; for (i2 = 8, j = 1; i2 <= 64; i2 += 8, j++) { - max_val |= ((uint64_t)1 << (i2-1)); - if ((int64_t)op[i].value >= ~(int64_t)(max_val) || (int64_t)op[i].value <= (int64_t)(max_val)) { + max_val = ((uint64_t)1 << (i2-1)); + int64_t tmp_val = (int64_t)op[i].value; + int is_pos = (tmp_val >= 0); + int is_neg = (tmp_val < 0); + if ((is_pos && tmp_val <= (int64_t)(max_val-1)) || (is_neg && tmp_val >= -(int64_t)(max_val))) { opsize = j; break; } } } else { max_val = 0; - for (i2 = 8, j = 1; i2 <= 64; i2 += 8, j++) { + for (i2 = 0, j = 1; i2 <= 64; i2 += 8, j++) { max_val |= (0xFF << i2); - if (op[0].value <= max_val) { + if (op[i].value <= max_val) { opsize = j; break; } @@ -965,13 +977,14 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, } if (opsize) { uint8_t is_abs = (type == ABS); - if (!is_abs) { + /*if (!is_abs) { switch (opsize) { case 2: opsize = 3; break; case 5: opsize = 6; break; } - } + }*/ prefix |= amp[opsize-1]; + /*tmp_size = (opsize >= tmp_size) ? opsize : tmp_size;*/ } op_size[i] = opsize; if (isasm && dbg) { @@ -981,6 +994,11 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, } } } + /*if (tmp_size) { + prefix |= amp[tmp_size-1]; + }*/ + /*op_size[0] = tmp_size; + op_size[1] = tmp_size;*/ } inst_size = write_inst(prefix, ext_prefix, opcode, op, address, op_size, isasm, dbg); address += inst_size; @@ -1218,7 +1236,7 @@ void fix_symtree(line *l) { } } -static inline void free_tokens(token *t) { +static void free_tokens(token *t) { token *tok; if (t != NULL) { tok = t; @@ -1257,7 +1275,7 @@ static void free_symbols(symbol *s) { } } -static inline void free_fixups(fixup *f) { +static void free_fixups(fixup *f) { fixup *fix; if (f != NULL) { fix = f; @@ -1268,6 +1286,17 @@ static inline void free_fixups(fixup *f) { } } +static inline void free_tmp_symtab(tmp_symtab *st) { + tmp_symtab *tmp; + if (st != NULL) { + tmp = st; + st = st->next; + free(tmp); + tmp = NULL; + free_tmp_symtab(st); + } +} + uint64_t get_tokmem(token *t) { uint64_t i = 0; for (; t; t = t->next, i++); @@ -1298,6 +1327,10 @@ void cleanup() { free_fixups(fixups); fixups = NULL; } + if (tmp_sym_table) { + free_tmp_symtab(tmp_sym_table); + tmp_sym_table = NULL; + } while (i < stridx || i < comidx) { if (i < stridx && string[i]) { free(string[i]); -- cgit v1.2.3-13-gbd6f