add GS/OS, P16, P8 macro support.

since nifty list uses the same names for all (with GS/P16/P8 prefixes which are stripped), P16 and P8 macros are more or less unavailable.
This commit is contained in:
Kelvin Sherlock 2019-04-18 21:58:28 -04:00
parent 13b78fb412
commit 379784c757

View File

@ -91,6 +91,7 @@ struct cookie {
unsigned opcode; unsigned opcode;
unsigned operand; unsigned operand;
unsigned pc; unsigned pc;
unsigned extra;
}; };
@ -392,6 +393,8 @@ static int find_opcode(struct cookie *cookie) {
unsigned mode = cookie->mode; unsigned mode = cookie->mode;
if (cookie->mnemonic >= MNEMONIC_LAST) return -1;
const struct opcode_entry *iter = opcode_table_index[cookie->mnemonic]; const struct opcode_entry *iter = opcode_table_index[cookie->mnemonic];
const struct opcode_entry *end = opcode_table_index[cookie->mnemonic + 1]; const struct opcode_entry *end = opcode_table_index[cookie->mnemonic + 1];
@ -427,7 +430,7 @@ static int find_opcode(struct cookie *cookie) {
static const char *parse_mx(const char *cp, struct cookie *cookie) { static const char *parse_mx(const char *cp, struct cookie *cookie) {
unsigned rv = 0; unsigned rv = 0;
char c; char c;
for( ; c = *cp; ++cp) { for( ; (c = *cp); ++cp) {
if (isspace(c)) break; if (isspace(c)) break;
if (c == ',') continue; if (c == ',') continue;
c = toupper(c); c = toupper(c);
@ -446,13 +449,14 @@ static const char *parse_expr(const char *cp, struct cookie *cookie) {
const char *YYCURSOR = cp; const char *YYCURSOR = cp;
const char *YYMARKER = NULL; const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL; const char *YYCTXMARKER = NULL;
unsigned mask = 0xffffff;
if (!cp) return NULL; if (!cp) return NULL;
cookie->size = 0; cookie->size = 0;
switch(*cp) { switch(*cp) {
case '|': ++cp; cookie->size = 2; break; case '<': ++cp; cookie->size = 1; mask = 0xff; break;
case '>': ++cp; cookie->size = 3; break; case '|': ++cp; cookie->size = 2; mask = 0xffff; break;
case '<': ++cp; cookie->size = 1; break; case '>': ++cp; cookie->size = 3; mask = 0xffffff; break;
} }
YYCURSOR = cp; YYCURSOR = cp;
@ -472,7 +476,7 @@ static const char *parse_expr(const char *cp, struct cookie *cookie) {
} }
x{1,6} { x{1,6} {
cookie->operand = to_hex(cp, YYCURSOR); cookie->operand = to_hex(cp, YYCURSOR) & mask;
if (!cookie->size) cookie->size = ((YYCURSOR - cp + 1) & ~1)>>1; if (!cookie->size) cookie->size = ((YYCURSOR - cp + 1) & ~1)>>1;
return YYCURSOR; return YYCURSOR;
} }
@ -539,7 +543,6 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) {
const char *YYMARKER = NULL; const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL; const char *YYCTXMARKER = NULL;
/* todo -- long m|x, short m|x, _toolcall */
/*!re2c /*!re2c
* { return NULL; } * { return NULL; }
@ -548,17 +551,22 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) {
extern int lookup_tool_number(const char *name, unsigned vector); extern int lookup_tool_number(const char *name, unsigned vector);
char name[20]; char name[20];
int tool; int i;
memcpy(name, cp, YYCURSOR - cp); memcpy(name, cp, YYCURSOR - cp);
name[YYCURSOR - cp] = 0; name[YYCURSOR - cp] = 0;
tool = lookup_tool_number(name, 0xe10000); for (i = 0; i < 3; ++i) {
if (tool <= 0) return NULL; static unsigned vectors[] = { 0xe10000, 0xe100a8, 0xbf00 };
static unsigned types[] = { TOOL_CALL, GSOS_CALL, MLI_CALL };
cookie->mnemonic = TOOL_CALL; int tool = lookup_tool_number(name, vectors[i]);
cookie->operand = tool; if (tool <= 0) continue;
cookie->mnemonic = types[i];
return ltrim(YYCURSOR); cookie->extra = tool;
return ltrim(YYCURSOR);
}
return NULL;
} }
'long' / (ws|eol) { 'long' / (ws|eol) {
@ -728,19 +736,6 @@ static int parse_line(const char *cp, uint32_t *pc) {
if (!cp) return error(offset, "bad opcode"); if (!cp) return error(offset, "bad opcode");
offset = cp - start; offset = cp - start;
if (cookie.mnemonic == TOOL_CALL) {
if (*cp) return error(offset, "invalid address mode");
if (g_disasm_psr & 0x30) return error(0, "8-bit m/x");
set_memory_c(addr++, 0xa2, 0);
set_memory_c(addr++, cookie.operand >> 0, 0);
set_memory_c(addr++, cookie.operand >> 8, 0);
set_memory_c(addr++, 0x22, 0);
set_memory_c(addr++, 0x00, 0);
set_memory_c(addr++, 0x00, 0);
set_memory_c(addr++, 0xe1, 0);
goto out;
}
if (cookie.mnemonic == LONG_SHORT) { if (cookie.mnemonic == LONG_SHORT) {
@ -772,6 +767,58 @@ static int parse_line(const char *cp, uint32_t *pc) {
if (*cp) return error(offset, "bad operand"); if (*cp) return error(offset, "bad operand");
if (cookie.mnemonic == TOOL_CALL) {
if (cookie.mode != IMPLIED) return error(offset, "invalid address mode");
if (g_disasm_psr & 0x30) return error(0, "8-bit m/x");
set_memory_c(addr++, 0xa2, 0);
set_memory_c(addr++, cookie.extra >> 0, 0);
set_memory_c(addr++, cookie.extra >> 8, 0);
set_memory_c(addr++, 0x22, 0);
set_memory_c(addr++, 0x00, 0);
set_memory_c(addr++, 0x00, 0);
set_memory_c(addr++, 0xe1, 0);
goto out;
}
if (cookie.mnemonic == GSOS_CALL) {
if (cookie.mode != DP && cookie.mode != ABS && cookie.mode != ABS_LONG)
return error(offset, "invalid address mode");
if (g_disasm_psr & 0x30) return error(0, "8-bit m/x");
set_memory_c(addr++, 0x22, 0);
set_memory_c(addr++, 0xa8, 0);
set_memory_c(addr++, 0x00, 0);
set_memory_c(addr++, 0xe1, 0);
set_memory_c(addr++, cookie.extra >> 0, 0);
set_memory_c(addr++, cookie.extra >> 8, 0);
set_memory_c(addr++, cookie.operand >> 0, 0);
set_memory_c(addr++, cookie.operand >> 8, 0);
set_memory_c(addr++, cookie.operand >> 16, 0);
set_memory_c(addr++, cookie.operand >> 24, 0);
goto out;
}
if (cookie.mnemonic == MLI_CALL) {
if (cookie.mode != DP && cookie.mode != ABS)
return error(offset, "invalid address mode");
if ((g_disasm_psr & 0x30) != 0x30) return error(0, "16-bit m/x");
if (addr >> 16) return error(0, "invalid bank");
set_memory_c(addr++, 0x20, 0);
set_memory_c(addr++, 0xbf, 0);
set_memory_c(addr++, 0x00, 0);
set_memory_c(addr++, cookie.extra >> 0, 0);
set_memory_c(addr++, cookie.operand >> 0, 0);
set_memory_c(addr++, cookie.operand >> 8, 0);
goto out;
}
if (find_opcode(&cookie) < 0) return error(offset, "invalid address mode"); if (find_opcode(&cookie) < 0) return error(offset, "invalid address mode");
/* clean up relative */ /* clean up relative */