diff --git a/CHANGELOG b/CHANGELOG index f833186..d52f599 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -136,3 +136,5 @@ + Fixed issue in output.c (not resetting orgdone per pass.) + Implemented SET directive (alias to .EQU) + Implemented macros using the .MACRO .. .ENDM directives. ++ Implemented .ADDR,.DBYTE directives (for SC/MP.) ++ Implemented functions H(), HI(), L() and LO() for expressions. diff --git a/src/expr.c b/src/expr.c index 7a6d783..31faf30 100644 --- a/src/expr.c +++ b/src/expr.c @@ -8,7 +8,7 @@ * * General expression handler. * - * Version: @(#)expr.c 1.0.10 2023/06/17 + * Version: @(#)expr.c 1.0.11 2023/08/20 * * Authors: Fred N. van Kempen, * Bernd B”ckmann, @@ -153,6 +153,11 @@ do_bin: } else { *p = pt; + if (**p == '0') { + /* Old code uses 0xx as meaning HEX. */ + goto do_hex; + } + /* No explicit radix specifier present, go with the default. */ switch (radix) { case 2: @@ -192,6 +197,7 @@ do_bin: * * the current PC * $ the current PC * 'x' single character x + * funcname(...) calling a function * ident a symbol * number a number, see number() above * @@ -330,24 +336,43 @@ program_counter: } else if (isalpha(**p)) { /* Symbol reference. */ nident(p, id); - sym = sym_lookup(id, NULL); - if (sym == NULL) { - /* Forward reference, remember it. */ - sym = sym_aquire(id, NULL); - if (DEFINED(sym->value)) - error(ERR_REDEF, id); + pt = *p; + if (**p == '(') { + /* We have an alnum AND a (, could be function. */ + (*p)++; - /* Set the correct type. */ - if (label) { - sym->kind = KIND_LBL; - sym->value.t = TYPE_WORD; - } else { - sym->kind = KIND_VAR; - sym->value.t = TYPE_BYTE; + /* Execute function. */ + res = function(id, p); + if (res.t == TYPE_NONE) { + /* Hmm, was not a function! */ + *p = pt; + goto no_func; } - sym->value.v = 0; + + if (**p != ')') + error(ERR_OPER, NULL); + (*p)++; + } else { +no_func: + sym = sym_lookup(id, NULL); + if (sym == NULL) { + /* Forward reference, remember it. */ + sym = sym_aquire(id, NULL); + if (DEFINED(sym->value)) + error(ERR_REDEF, id); + + /* Set the correct type. */ + if (label) { + sym->kind = KIND_LBL; + sym->value.t = TYPE_WORD; + } else { + sym->kind = KIND_VAR; + sym->value.t = TYPE_BYTE; + } + sym->value.v = 0; + } + res = sym->value; } - res = sym->value; } else { /* Must be just a number, but do mind the radix! */ res = number(p); diff --git a/src/func.c b/src/func.c index 00c21b0..3805b60 100644 --- a/src/func.c +++ b/src/func.c @@ -8,7 +8,7 @@ * * Handle all functions. * - * Version: @(#)func.c 1.0.4 2023/06/15 + * Version: @(#)func.c 1.0.5 2023/08/20 * * Author: Fred N. van Kempen, * @@ -79,10 +79,47 @@ do_def(char **p) sym->value.t = TYPE_BYTE; sym->value.v = 0; } - res = sym->value; if (IS_END(**p)) error(ERR_EOL, NULL); + res = sym->value; + + return res; +} + + +/* Implement the "HI(symbol)" function. */ +static value_t +do_high(char **p) +{ + value_t res; + + res = expr(p); + if (IS_END(**p)) + error(ERR_EOL, NULL); + + res.v = (res.v >> 8) & 0xff; + res.t = TYPE_BYTE; + SET_DEFINED(res); + + return res; +} + + +/* Implement the "LO(symbol)" function. */ +static value_t +do_low(char **p) +{ + value_t res; + + res = expr(p); + if (IS_END(**p)) + error(ERR_EOL, NULL); + + res.v = (res.v & 0xff); + res.t = TYPE_BYTE; + SET_DEFINED(res); + return res; } @@ -125,6 +162,10 @@ do_sum(char **p) static const func_t functions[] = { { "DEF", do_def }, { "DEFINED", do_def }, + { "H", do_high }, + { "HI", do_high }, + { "L", do_low }, + { "LO", do_low }, { "SUM", do_sum }, { NULL } }; diff --git a/src/macro.c b/src/macro.c index b1b7782..a0b739a 100644 --- a/src/macro.c +++ b/src/macro.c @@ -8,7 +8,7 @@ * * Handle macros. * - * Version: @(#)macro.c 1.0.1 2023/06/23 + * Version: @(#)macro.c 1.0.1 2023/08/20 * * Author: Fred N. van Kempen, * @@ -195,10 +195,12 @@ macro_add(const char *p) while (*xx && (*xx == ' ' || *xx == '\t')) xx++; + if (*xx == '.') + xx++; # ifdef _MSC_VER - if (!strncmp(xx, ".endm", 5) || !strncmp(xx, ".ENDM", 5)) + if (!strncmp(xx, "endm", 4) || !strncmp(xx, "ENDM", 4)) # else - if (!strncasecmp(xx, ".endm", 5)) + if (!strncasecmp(xx, "endm", 4)) # endif return; #endif @@ -238,11 +240,19 @@ macro_exec(const char *name, char **p, char **newp, int pass) return; curmac = m; - /* Save actual parameters. */ + /* Save actual parameters, but do not keep comments. */ sp = curmac->actual; while (! IS_END(**p)) { - *sp++ = **p; - (*p)++; + if (**p != COMMENT_CHAR) { + *sp++ = **p; + (*p)++; + } else { + /* See if we can remove trailing whitespace. */ + while (IS_SPACE(*(sp-1))) + *(--sp) = '\0'; + + skip_white_and_comment(p); + } } *sp = '\0'; @@ -263,9 +273,11 @@ macro_exec(const char *name, char **p, char **newp, int pass) *sp++ = *curmac->defptr; } while (*curmac->defptr && *curmac->defptr++ != '\n'); *sp = '\0'; +//printf("ORIG: '%s'\n", temp); /* Expand the copy. */ subst(curmac, temp); +//printf("EXP: '%s'\n", temp); /* Copy expanded line to data. */ sp = temp; diff --git a/src/plat/mac/Makefile.mac b/src/plat/mac/Makefile.mac index 9dedb69..b6f9c13 100644 --- a/src/plat/mac/Makefile.mac +++ b/src/plat/mac/Makefile.mac @@ -8,7 +8,7 @@ # # Makefile for macOS systems using the Xcode environment. # -# Version: @(#)Makefile.mac 1.2.0 2023/06/23 +# Version: @(#)Makefile.mac 1.2.0 2023/08/20 # # Author: Fred N. van Kempen, # @@ -110,7 +110,7 @@ ifndef SCMP endif ifeq ($(SCMP), y) DEFS += -DUSE_SCMP - TARGETS += scmp.o + TARGETS += ins8060.o endif ifndef SCN2650 diff --git a/src/plat/unix/Makefile.GCC b/src/plat/unix/Makefile.GCC index 660021d..7d2ae17 100644 --- a/src/plat/unix/Makefile.GCC +++ b/src/plat/unix/Makefile.GCC @@ -8,7 +8,7 @@ # # Makefile for UNIX-like systems using the GCC environment. # -# Version: @(#)Makefile.GCC 1.2.0 2023/06/23 +# Version: @(#)Makefile.GCC 1.2.0 2023/08/20 # # Author: Fred N. van Kempen, # @@ -110,7 +110,7 @@ ifndef SCMP endif ifeq ($(SCMP), y) DEFS += -DUSE_SCMP - TARGETS += scmp.o + TARGETS += ins8060.o endif ifndef SCN2650 diff --git a/src/plat/unix/Makefile.TCC b/src/plat/unix/Makefile.TCC index 5664d2f..5be9ac6 100644 --- a/src/plat/unix/Makefile.TCC +++ b/src/plat/unix/Makefile.TCC @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the TCC environment. # -# Version: @(#)Makefile.TCC 1.2.0 2023/06/23 +# Version: @(#)Makefile.TCC 1.2.0 2023/08/20 # # Author: Fred N. van Kempen, # @@ -110,7 +110,7 @@ ifndef SCMP endif ifeq ($(SCMP), y) DEFS += -DUSE_SCMP - TARGETS += scmp.o + TARGETS += ins8060.o endif ifndef SCN2650 diff --git a/src/plat/win/Makefile.MSVC b/src/plat/win/Makefile.MSVC index 3f88dab..9ac5620 100644 --- a/src/plat/win/Makefile.MSVC +++ b/src/plat/win/Makefile.MSVC @@ -8,7 +8,7 @@ # # Makefile for Windows using Visual Studio 2019. # -# Version: @(#)Makefile.MSVC 1.2.0 2023/06/23 +# Version: @(#)Makefile.MSVC 1.2.0 2023/08/20 # # Author: Fred N. van Kempen, # @@ -110,7 +110,7 @@ ifndef SCMP endif ifeq ($(SCMP), y) DEFS += -DUSE_SCMP - TARGETS += scmp.obj + TARGETS += ins8060.obj endif ifndef SCN2650 diff --git a/src/plat/win/Makefile.MinGW b/src/plat/win/Makefile.MinGW index d946ec2..83bff76 100644 --- a/src/plat/win/Makefile.MinGW +++ b/src/plat/win/Makefile.MinGW @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the MinGW-w64 environment. # -# Version: @(#)Makefile.MinGW 1.2.0 2023/06/21 +# Version: @(#)Makefile.MinGW 1.2.0 2023/08/20 # # Author: Fred N. van Kempen, # @@ -110,7 +110,7 @@ ifndef SCMP endif ifeq ($(SCMP), y) DEFS += -DUSE_SCMP - TARGETS += scmp.o + TARGETS += ins8060.o endif ifndef SCN2650 diff --git a/src/plat/win/Makefile.TCC b/src/plat/win/Makefile.TCC index 234942e..e73953f 100644 --- a/src/plat/win/Makefile.TCC +++ b/src/plat/win/Makefile.TCC @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the TCC environment. # -# Version: @(#)Makefile.TCC 1.2.0 2023/06/23 +# Version: @(#)Makefile.TCC 1.2.0 2023/08/20 # # Author: Fred N. van Kempen, # @@ -110,7 +110,7 @@ ifndef SCMP endif ifeq ($(SCMP), y) DEFS += -DUSE_SCMP - TARGETS += scmp.o + TARGETS += ins8060.o endif ifndef SCN2650 diff --git a/src/pseudo.c b/src/pseudo.c index be5a340..ffe97e7 100644 --- a/src/pseudo.c +++ b/src/pseudo.c @@ -8,7 +8,7 @@ * * Handle directives and pseudo-ops. * - * Version: @(#)pseudo.c 1.0.10 2023/06/23 + * Version: @(#)pseudo.c 1.0.10 2023/06/24 * * Authors: Fred N. van Kempen, * Bernd B”ckmann, @@ -95,6 +95,26 @@ string_lit(char **p, char *buf, int bufsize, int quot) } +/* The ".addr " directive. */ +static char * +do_addr(char **p, int pass) +{ + value_t v; + + v = expr(p); + if ((pass == 2) && UNDEFINED(v)) + error(ERR_UNDEF, NULL); + + /* Decrement one, but mind the mod-4096 stuff. */ + v.v = (v.v & ~0x0fff) | ((v.v & 0x0fff) - 1); + + emit_word_be(v.v & 0xffff, pass); + pc += 2; + + return NULL; +} + + /* The ".align []" directive. */ static char * do_align(char **p, int pass) @@ -1265,7 +1285,36 @@ do_word(char **p, int pass) } +/* The ".wordbe [,,...]" directive. */ +static char * +do_wordbe(char **p, int pass) +{ + value_t v; + int next; + + do { + next = 0; + skip_white(p); + + v = expr(p); + if ((pass == 2) && UNDEFINED(v)) + error(ERR_UNDEF, NULL); + emit_word_be(v.v & 0xffff, pass); + pc += 2; + + skip_white(p); + if (**p == ',') { + skip_curr_and_white(p); + next = 1; + } + } while (next); + + return NULL; +} + + static const pseudo_t pseudos[] = { + { "ADDR", 0, 1, do_addr, NULL }, // SC/MP { "ALIGN", 0, 0, do_align, NULL }, { "ASCII", 0, 1, do_byte, NULL }, { "ASCIIZ", 0, 1, do_asciz, NULL }, @@ -1277,6 +1326,7 @@ static const pseudo_t pseudos[] = { { "CPU", 0, 1, do_cpu, NULL }, { "DATA", 0, 1, do_byte, NULL }, { "DB", 0, 0, do_byte, NULL }, + { "DBYTE", 0, 0, do_wordbe, NULL }, // SC/MP { "DEFINE", 0, 0, do_define, do_define_list }, { "DL", 0, 0, do_dword, NULL }, { "DS", 0, 0, do_fill, NULL }, @@ -1299,7 +1349,7 @@ static const pseudo_t pseudos[] = { { "IFN", 1, 0, do_ifn, NULL }, { "IFNDEF", 1, 0, do_ifndef, NULL }, { "INCLUDE", 0, 0, do_include, NULL }, - { "LOCAL", 0, 1, do_local, NULL }, + { "LOCAL", 0, 1, do_local, NULL }, // SC/MP { "MACRO", 0, 0, do_macro, NULL }, { "NOFILL", 0, 0, do_nofill, NULL }, { "ORG", 0, 0, do_org, do_org_list }, @@ -1320,6 +1370,7 @@ static const pseudo_t pseudos[] = { { "WARNING", 0, 1, do_warn, NULL }, { "WIDTH", 0, 0, do_width, NULL }, { "WORD", 0, 0, do_word, NULL }, + { "WORDBE", 0, 0, do_wordbe, NULL }, { NULL } }; diff --git a/src/target.c b/src/target.c index 33d8068..7304335 100644 --- a/src/target.c +++ b/src/target.c @@ -8,7 +8,7 @@ * * Handle selection of a target device. * - * Version: @(#)target.c 1.0.5 2023/06/05 + * Version: @(#)target.c 1.0.6 2023/08/20 * * Author: Fred N. van Kempen, * diff --git a/src/targets/scmp.c b/src/targets/ins8060.c similarity index 91% rename from src/targets/scmp.c rename to src/targets/ins8060.c index e309470..9289cd7 100644 --- a/src/targets/scmp.c +++ b/src/targets/ins8060.c @@ -21,7 +21,7 @@ * less power. Other than instruction timings, everything else * was the same, so for code, nothing changed. * - * Version: @(#)scmp.c 1.0.1 2023/06/19 + * Version: @(#)ins8060.c 1.0.2 2023/09/06 * * Author: Fred N. van Kempen, * @@ -67,6 +67,10 @@ #include "../target.h" +#define USE_JS 0 // include "JS" pseudo +#define USE_LDPI 0 // include "LDPI" pseudo + + typedef enum { GRP_IMP = 0, // implied GRP_IMM, // $12 @@ -74,6 +78,7 @@ typedef enum { GRP_REL, // relative (disp) or pointer disp(ptr) GRP_MEM, // relative,auto-ptr @disp(ptr) GRP_JS, // JS pseudo + GRP_LDPI, // LDPI pseudo GRP_ABS // $1234 (807x models) } trg_groups_t; @@ -126,11 +131,16 @@ static const opcode_t opcodes[] = { { "JMP", CPU_0, 0x90, GRP_REL }, { "JNZ", CPU_0, 0x9c, GRP_REL }, { "JP", CPU_0, 0x94, GRP_REL }, +#if USE_JS { "JS", CPU_0, 0xff, GRP_JS }, +#endif { "JZ", CPU_0, 0x98, GRP_REL }, { "LD", CPU_0, 0xc0, GRP_MEM }, { "LDE", CPU_0, 0x40, GRP_IMP }, { "LDI", CPU_0, 0xc4, GRP_IMM }, +#if USE_LDPI + { "LDPI", CPU_0, 0xff, GRP_LDPI }, +#endif { "MPY", CPU_B, 0x2c, GRP_IMP }, { "NOP", CPU_0, 0x08, GRP_IMP }, { "OR", CPU_0, 0xd8, GRP_MEM }, @@ -190,11 +200,12 @@ get_ptr(char **p) } +static int foo = 0; static int get_ea(uint16_t addr, int pass) { - uint16_t pct, off; - int16_t disp; + uint16_t pct; + int16_t disp, off; /* Sign-extend the (12-bit) target if needed. */ if (addr & 0x0800) @@ -202,16 +213,19 @@ get_ea(uint16_t addr, int pass) disp = (int16_t)addr; pct = pc + 1; - off = disp - pct; + if (disp >= pct) { + off = (disp - pct); - if (pass == 2) { - if (disp >= pct) { - if (off > 0x7f) - error(ERR_RELRNG, NULL); - } else { - if (off < 0x80) - error(ERR_RELRNG, NULL); - } + if (pass == 2 && off > 128) + error(ERR_RELRNG, NULL); + } else { + if (disp > 0) + off = -(pct - disp); + else + off = (disp - pct); + + if (pass == 2 && off < -127) + error(ERR_RELRNG, NULL); } return off; @@ -332,6 +346,11 @@ grp_rel(char **p, int pass, const opcode_t *instr) (*p)++; } + if (instr->opcode != 0xa8 && instr->opcode != 0xb8) +foo = 1; +else +foo = 0; + if (ptr == 0) off = get_ea((uint16_t)v.v, pass); else @@ -417,6 +436,7 @@ grp_mem(char **p, int pass, const opcode_t *instr) } +#if USE_JS /* * Handle the JS pseudo. * @@ -471,6 +491,59 @@ grp_js(char **p, int pass, const opcode_t *instr) return 7; } +#endif + + +#if USE_LDPI +/* + * Handle the LDPI pseudo. + * + * LDPI ptr,expr + * + * Generated code: + * + * C4 hh LDI >expr + * 34p XPAH ptr + * C4 ll LDI expr + emit_byte((v.v >> 8), pass); + emit_byte(0x34 + ptr, pass); // XPAH ptr + emit_byte(0xc4, pass); // LDI opcode, pass); bytes = 1; diff --git a/src/version.h b/src/version.h index bbbae9b..4ce6a41 100644 --- a/src/version.h +++ b/src/version.h @@ -8,7 +8,7 @@ * * Define application version and build info. * - * Version: @(#)version.h 1.0.9 2023/06/21 + * Version: @(#)version.h 1.0.10 2023/09/06 * * Author: Fred N. van Kempen, * @@ -55,7 +55,7 @@ /* Version info. */ #define APP_VER_MAJOR 1 #define APP_VER_MINOR 0 -#define APP_VER_REV 18 +#define APP_VER_REV 20 #define APP_VER_PATCH 0