Several small changes and additions (see CHANGELOG.)

Fixed the SC/MP (INS8060) target to properly handle EA overflows.
This commit is contained in:
waltje
2023-09-06 21:58:03 -04:00
parent ac564869c5
commit d96647d62f
14 changed files with 269 additions and 57 deletions

View File

@@ -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.

View File

@@ -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, <waltje@varcem.com>
* Bernd B”ckmann, <https://codeberg.org/boeckmann/asm6502>
@@ -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);

View File

@@ -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, <waltje@varcem.com>
*
@@ -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 }
};

View File

@@ -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, <waltje@varcem.com>
*
@@ -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;

View File

@@ -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, <waltje@varcem.com>
#
@@ -110,7 +110,7 @@ ifndef SCMP
endif
ifeq ($(SCMP), y)
DEFS += -DUSE_SCMP
TARGETS += scmp.o
TARGETS += ins8060.o
endif
ifndef SCN2650

View File

@@ -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, <waltje@varcem.com>
#
@@ -110,7 +110,7 @@ ifndef SCMP
endif
ifeq ($(SCMP), y)
DEFS += -DUSE_SCMP
TARGETS += scmp.o
TARGETS += ins8060.o
endif
ifndef SCN2650

View File

@@ -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, <waltje@varcem.com>
#
@@ -110,7 +110,7 @@ ifndef SCMP
endif
ifeq ($(SCMP), y)
DEFS += -DUSE_SCMP
TARGETS += scmp.o
TARGETS += ins8060.o
endif
ifndef SCN2650

View File

@@ -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, <waltje@varcem.com>
#
@@ -110,7 +110,7 @@ ifndef SCMP
endif
ifeq ($(SCMP), y)
DEFS += -DUSE_SCMP
TARGETS += scmp.obj
TARGETS += ins8060.obj
endif
ifndef SCN2650

View File

@@ -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, <waltje@varcem.com>
#
@@ -110,7 +110,7 @@ ifndef SCMP
endif
ifeq ($(SCMP), y)
DEFS += -DUSE_SCMP
TARGETS += scmp.o
TARGETS += ins8060.o
endif
ifndef SCN2650

View File

@@ -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, <waltje@varcem.com>
#
@@ -110,7 +110,7 @@ ifndef SCMP
endif
ifeq ($(SCMP), y)
DEFS += -DUSE_SCMP
TARGETS += scmp.o
TARGETS += ins8060.o
endif
ifndef SCN2650

View File

@@ -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, <waltje@varcem.com>
* Bernd B”ckmann, <https://codeberg.org/boeckmann/asm6502>
@@ -95,6 +95,26 @@ string_lit(char **p, char *buf, int bufsize, int quot)
}
/* The ".addr <expr>" 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 [<count>]" directive. */
static char *
do_align(char **p, int pass)
@@ -1265,7 +1285,36 @@ do_word(char **p, int pass)
}
/* The ".wordbe <data>[,<data>,...]" 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 }
};

View File

@@ -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, <waltje@varcem.com>
*

View File

@@ -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, <waltje@varcem.com>
*
@@ -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
* 30p XPAL ptr
*
* This was originally a macro in the NSC cross assembler.
*/
static int
grp_ldpi(char **p, int pass, const opcode_t *instr)
{
value_t v;
int ptr;
/* Get the pointer register. */
ptr = get_ptr(p);
if (ptr < 0)
error(ERR_PTR, NULL);
/* Skip the comma. */
if (**p != ',')
error(ERR_COMMA, NULL);
(*p)++;
/* Grab the expression. */
skip_white(p);
v = expr(p);
if (pass == 2) {
if (UNDEFINED(v))
error(ERR_UNDEF, NULL);
}
/* Generate the code for this. */
emit_byte(0xc4, pass); // LDI >expr
emit_byte((v.v >> 8), pass);
emit_byte(0x34 + ptr, pass); // XPAH ptr
emit_byte(0xc4, pass); // LDI <expr
emit_byte((v.v & 0xff), pass);
emit_byte(0x30 + ptr, pass); // XPAL ptr
return 6;
}
#endif
#if 0
@@ -723,16 +796,24 @@ t_instr(const target_t *trg, char **p, int pass)
bytes = grp_mem(p, pass, op);
break;
#if USE_JS
case GRP_JS:
bytes = grp_js(p, pass, op);
break;
#endif
#if USE_LDPI
case GRP_LDPI:
bytes = grp_ldpi(p, pass, op);
break;
#endif
#if 0
case AM_ABS:
bytes = op_abs(p, pass, op);
break;
#endif
case GRP_JS:
bytes = grp_js(p, pass, op);
break;
default:
emit_byte(op->opcode, pass);
bytes = 1;

View File

@@ -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, <waltje@varcem.com>
*
@@ -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