mini assembler

This commit is contained in:
Kelvin Sherlock 2019-04-14 17:41:46 -04:00
parent e23f4494ca
commit ac1b76753d
4 changed files with 837 additions and 2 deletions

View File

@ -119,6 +119,13 @@ add_custom_command(
MAIN_DEPENDENCY debug_sweet16.re2c
)
add_custom_command(
OUTPUT debug_miniasm.c
COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_miniasm.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_miniasm.re2c"
MAIN_DEPENDENCY debug_miniasm.re2c
)
if (WITH_STATIC)
if(__CLANG__ OR __GCC__)
#add_link_options(-static) # 3.13
@ -175,6 +182,7 @@ add_executable(GSplus WIN32 MACOSX_BUNDLE
debug_shell.c
debug_template.c
debug_sweet16.c
debug_miniasm.c
$<$<BOOL:${WITH_DEBUGGER}>:debug.c>
$<$<BOOL:${WITH_HOST_FST}>:${host_fst_code}>

730
src/debug_miniasm.re2c Normal file
View File

@ -0,0 +1,730 @@
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdint.h>
#include "defc.h"
extern int g_disasm_psr;
static uint32_t to_hex(const char *iter, const char *end) {
uint32_t rv = 0;
while(iter != end) {
char c = *iter++;
rv <<= 4;
if (isdigit(c)) rv |= c - '0';
else rv |= (c | 0x20) - 'a' + 10;
}
return rv;
}
static const char *ltrim(const char *cp) {
while (isspace(*cp)) ++cp;
return cp;
}
/*!re2c
re2c:define:YYCTYPE = char;
re2c:yyfill:enable = 0;
eol = "\x00";
ws = [ \t];
x = [A-Fa-f0-9];
*/
/* address modes */
/* INDIR_LONG_X present for +1/+2 symmetry */
#define _x 1
#define _y 2
enum {
IMPLIED,
DP, DP_X, DP_Y,
ABS, ABS_X, ABS_Y,
ABS_LONG, ABS_LONG_X, ABS_LONG_Y,
INDIR, INDIR_X, INDIR_Y,
INDIR_LONG, INDIR_LONG_X, INDIR_LONG_Y,
SR, SR_Y,
IMMEDIATE,
RELATIVE,
INTERRUPT,
BLOCK,
};
enum {
MNEMONIC_NONE,
#define x(a) a,
#include "mnemonics.x"
#undef x
MNEMONIC_LAST
};
struct mnemonic_entry {
const char *name;
int value;
unsigned mnemonic;
};
struct mnemonic_entry mnemonic_table[] = {
{ NULL, 0 },
#define x(a) { #a, (#a[0] << 16)| (#a[1] << 8) | (#a[2]), a },
#include "mnemonics.x"
#undef x
};
struct cookie {
unsigned mnemonic;
unsigned mode;
unsigned size;
unsigned opcode;
unsigned operand;
unsigned pc;
};
struct opcode_entry {
unsigned mnemonic;
unsigned mode;
unsigned opcode;
unsigned size; /* of operand */
};
/* 4 = 1/2 depending on M. 5 = 1/2 depending on X */
struct opcode_entry opcode_table[] = {
{ ADC, INDIR_X , 0x61, 1 },
{ ADC, SR , 0x63, 1 },
{ ADC, DP , 0x65, 1 },
{ ADC, INDIR_LONG , 0x67, 1 },
{ ADC, IMMEDIATE , 0x69, 4 },
{ ADC, ABS , 0x6d, 2 },
{ ADC, ABS_LONG , 0x6f, 3 },
{ ADC, INDIR_Y , 0x71, 1 },
{ ADC, INDIR , 0x72, 1 },
{ ADC, SR_Y , 0x73, 1 },
{ ADC, DP_X , 0x75, 1 },
{ ADC, INDIR_LONG_Y, 0x77, 1 },
{ ADC, ABS_Y , 0x79, 2 },
{ ADC, ABS_X , 0x7d, 2 },
{ ADC, ABS_LONG_X , 0x7f, 3 },
{ AND, INDIR_X , 0x21, 1 },
{ AND, SR , 0x23, 1 },
{ AND, DP , 0x25, 1 },
{ AND, INDIR_LONG , 0x27, 1 },
{ AND, IMMEDIATE , 0x29, 4 },
{ AND, ABS , 0x2d, 2 },
{ AND, ABS_LONG , 0x2f, 3 },
{ AND, INDIR_Y , 0x31, 1 },
{ AND, INDIR , 0x32, 1 },
{ AND, SR_Y , 0x33, 1 },
{ AND, DP_X , 0x35, 1 },
{ AND, INDIR_LONG_Y, 0x37, 1 },
{ AND, ABS_Y , 0x39, 2 },
{ AND, ABS_X , 0x3d, 2 },
{ AND, ABS_LONG_X , 0x3f, 3 },
{ ASL, DP , 0x06, 1 },
{ ASL, IMPLIED , 0x0a, 0 },
{ ASL, ABS , 0x0e, 2 },
{ ASL, DP_X , 0x16, 1 },
{ ASL, ABS_X , 0x1e, 2 },
{ BCC, RELATIVE , 0x90, 1 },
{ BCS, RELATIVE , 0xb0, 1 },
{ BEQ, RELATIVE , 0xf0, 1 },
{ BIT, DP , 0x24, 1 },
{ BIT, ABS , 0x2c, 2 },
{ BIT, DP_X , 0x34, 1 },
{ BIT, ABS_X , 0x3c, 2 },
{ BIT, IMMEDIATE , 0x89, 4 },
{ BMI, RELATIVE , 0x30, 1 },
{ BNE, RELATIVE , 0xd0, 1 },
{ BPL, RELATIVE , 0x10, 1 },
{ BRA, RELATIVE , 0x80, 1 },
/* brk dp, #imm */
{ BRK, INTERRUPT , 0x00, 1 }, { BRK, DP , 0x00, 1 }, { BRK, IMMEDIATE , 0x00, 1 },
{ BRL, RELATIVE , 0x82, 2 },
{ BVC, RELATIVE , 0x50, 1 },
{ BVS, RELATIVE , 0x70, 1 },
{ CLC, IMPLIED , 0x18, 0 },
{ CLD, IMPLIED , 0xd8, 0 },
{ CLI, IMPLIED , 0x58, 0 },
{ CLV, IMPLIED , 0xb8, 0 },
{ CMP, INDIR_X , 0xc1, 1 },
{ CMP, SR , 0xc3, 1 },
{ CMP, DP , 0xc5, 1 },
{ CMP, INDIR_LONG , 0xc7, 1 },
{ CMP, IMMEDIATE , 0xc9, 4 },
{ CMP, ABS , 0xcd, 2 },
{ CMP, ABS_LONG , 0xcf, 3 },
{ CMP, INDIR_Y , 0xd1, 1 },
{ CMP, INDIR , 0xd2, 1 },
{ CMP, SR_Y , 0xd3, 1 },
{ CMP, DP_X , 0xd5, 1 },
{ CMP, INDIR_LONG_Y, 0xd7, 1 },
{ CMP, ABS_Y , 0xd9, 2 },
{ CMP, ABS_X , 0xdd, 2 },
{ CMP, ABS_LONG_X , 0xdf, 3 },
/* COP dp, #imm */
{ COP, INTERRUPT , 0x02, 1 }, { COP, DP , 0x02, 1 }, { COP, IMMEDIATE , 0x02, 1 },
{ CPX, IMMEDIATE , 0xe0, 5 },
{ CPX, DP , 0xe4, 1 },
{ CPX, ABS , 0xec, 2 },
{ CPY, IMMEDIATE , 0xc0, 5 },
{ CPY, DP , 0xc4, 1 },
{ CPY, ABS , 0xcc, 2 },
{ DEC, IMPLIED , 0x3a, 0 },
{ DEC, DP , 0xc6, 1 },
{ DEC, ABS , 0xce, 2 },
{ DEC, DP_X , 0xd6, 1 },
{ DEC, ABS_X , 0xde, 2 },
{ DEX, IMPLIED , 0xca, 0 },
{ DEY, IMPLIED , 0x88, 0 },
{ EOR, INDIR_X , 0x41, 1 },
{ EOR, SR , 0x43, 1 },
{ EOR, DP , 0x45, 1 },
{ EOR, INDIR_LONG , 0x47, 1 },
{ EOR, IMMEDIATE , 0x49, 4 },
{ EOR, ABS , 0x4d, 2 },
{ EOR, ABS_LONG , 0x4f, 3 },
{ EOR, INDIR_Y , 0x51, 1 },
{ EOR, INDIR , 0x52, 1 },
{ EOR, SR_Y , 0x53, 1 },
{ EOR, DP_X , 0x55, 1 },
{ EOR, INDIR_LONG_Y, 0x57, 1 },
{ EOR, ABS_Y , 0x59, 2 },
{ EOR, ABS_X , 0x5d, 2 },
{ EOR, ABS_LONG_X , 0x5f, 3 },
{ INC, IMPLIED , 0x1a, 0 },
{ INC, DP , 0xe6, 1 },
{ INC, ABS , 0xee, 2 },
{ INC, DP_X , 0xf6, 1 },
{ INC, ABS_X , 0xfe, 2 },
{ INX, IMPLIED , 0xe8, 0 },
{ INY, IMPLIED , 0xc8, 0 },
{ JML, ABS_LONG , 0x5c, 3 },
{ JML, INDIR_LONG , 0xdc, 2 },
{ JMP, ABS , 0x4c, 2 },
{ JMP, INDIR , 0x6c, 2 },
{ JMP, INDIR_X , 0x7c, 2 },
{ JSL, ABS_LONG , 0x22, 3 },
{ JSR, ABS , 0x20, 2 },
{ JSR, INDIR_X , 0xfc, 2 },
{ LDA, INDIR_X , 0xa1, 1 },
{ LDA, SR , 0xa3, 1 },
{ LDA, DP , 0xa5, 1 },
{ LDA, INDIR_LONG , 0xa7, 1 },
{ LDA, IMMEDIATE , 0xa9, 4 },
{ LDA, ABS , 0xad, 2 },
{ LDA, ABS_LONG , 0xaf, 3 },
{ LDA, INDIR_Y , 0xb1, 1 },
{ LDA, INDIR , 0xb2, 1 },
{ LDA, SR_Y , 0xb3, 1 },
{ LDA, DP_X , 0xb5, 1 },
{ LDA, INDIR_LONG_Y, 0xb7, 1 },
{ LDA, ABS_Y , 0xb9, 2 },
{ LDA, ABS_X , 0xbd, 2 },
{ LDA, ABS_LONG_X , 0xbf, 3 },
{ LDX, IMMEDIATE , 0xa2, 5 },
{ LDX, DP , 0xa6, 1 },
{ LDX, ABS , 0xae, 2 },
{ LDX, DP_Y , 0xb6, 1 },
{ LDX, ABS_Y , 0xbe, 2 },
{ LDY, IMMEDIATE , 0xa0, 5 },
{ LDY, DP , 0xa4, 1 },
{ LDY, ABS , 0xac, 2 },
{ LDY, DP_X , 0xb4, 1 },
{ LDY, ABS_X , 0xbc, 2 },
{ LSR, DP , 0x46, 1 },
{ LSR, IMPLIED , 0x4a, 0 },
{ LSR, ABS , 0x4e, 2 },
{ LSR, DP_X , 0x56, 1 },
{ LSR, ABS_X , 0x5e, 2 },
{ MVN, BLOCK , 0x54, 2 },
{ MVP, BLOCK , 0x44, 2 },
{ NOP, IMPLIED , 0xea, 0 },
{ ORA, INDIR_X , 0x01, 1 },
{ ORA, SR , 0x03, 1 },
{ ORA, DP , 0x05, 1 },
{ ORA, INDIR_LONG , 0x07, 1 },
{ ORA, IMMEDIATE , 0x09, 4 },
{ ORA, ABS , 0x0d, 2 },
{ ORA, ABS_LONG , 0x0f, 3 },
{ ORA, INDIR_Y , 0x11, 1 },
{ ORA, INDIR , 0x12, 1 },
{ ORA, SR_Y , 0x13, 1 },
{ ORA, DP_X , 0x15, 1 },
{ ORA, INDIR_LONG_Y, 0x17, 1 },
{ ORA, ABS_Y , 0x19, 2 },
{ ORA, ABS_X , 0x1d, 2 },
{ ORA, ABS_LONG_X , 0x1f, 3 },
/* pea abs or pea #imm */
{ PEA, ABS , 0xf4, 2 }, { PEA, IMMEDIATE , 0xf4, 2 },
/* pei (dp) or pei dp */
{ PEI, INDIR , 0xd4, 1 }, { PEI, DP , 0xd4, 1 },
{ PER, RELATIVE , 0x62, 2 },
{ PHA, IMPLIED , 0x48, 0 },
{ PHB, IMPLIED , 0x8b, 0 },
{ PHD, IMPLIED , 0x0b, 0 },
{ PHK, IMPLIED , 0x4b, 0 },
{ PHP, IMPLIED , 0x08, 0 },
{ PHX, IMPLIED , 0xda, 0 },
{ PHY, IMPLIED , 0x5a, 0 },
{ PLA, IMPLIED , 0x68, 0 },
{ PLB, IMPLIED , 0xab, 0 },
{ PLD, IMPLIED , 0x2b, 0 },
{ PLP, IMPLIED , 0x28, 0 },
{ PLX, IMPLIED , 0xfa, 0 },
{ PLY, IMPLIED , 0x7a, 0 },
{ REP, IMMEDIATE , 0xc2, 1 },
{ ROL, DP , 0x26, 1 },
{ ROL, IMPLIED , 0x2a, 0 },
{ ROL, ABS , 0x2e, 2 },
{ ROL, DP_X , 0x36, 1 },
{ ROL, ABS_X , 0x3e, 2 },
{ ROR, DP , 0x66, 1 },
{ ROR, IMPLIED , 0x6a, 0 },
{ ROR, ABS , 0x6e, 2 },
{ ROR, DP_X , 0x76, 1 },
{ ROR, ABS_X , 0x7e, 2 },
{ RTI, IMPLIED , 0x40, 0 },
{ RTL, IMPLIED , 0x6b, 0 },
{ RTS, IMPLIED , 0x60, 0 },
{ SBC, INDIR_X , 0xe1, 1 },
{ SBC, SR , 0xe3, 1 },
{ SBC, DP , 0xe5, 1 },
{ SBC, INDIR_LONG , 0xe7, 1 },
{ SBC, IMMEDIATE , 0xe9, 4 },
{ SBC, ABS , 0xed, 2 },
{ SBC, ABS_LONG , 0xef, 3 },
{ SBC, INDIR_Y , 0xf1, 1 },
{ SBC, INDIR , 0xf2, 1 },
{ SBC, SR_Y , 0xf3, 1 },
{ SBC, DP_X , 0xf5, 1 },
{ SBC, INDIR_LONG_Y, 0xf7, 1 },
{ SBC, ABS_Y , 0xf9, 2 },
{ SBC, ABS_X , 0xfd, 2 },
{ SBC, ABS_LONG_X , 0xff, 3 },
{ SEC, IMPLIED , 0x38, 0 },
{ SED, IMPLIED , 0xf8, 0 },
{ SEI, IMPLIED , 0x78, 0 },
{ SEP, IMMEDIATE , 0xe2, 1 },
{ STA, INDIR_X , 0x81, 1 },
{ STA, SR , 0x83, 1 },
{ STA, DP , 0x85, 1 },
{ STA, INDIR_LONG , 0x87, 1 },
{ STA, ABS , 0x8d, 2 },
{ STA, ABS_LONG , 0x8f, 3 },
{ STA, INDIR_Y , 0x91, 1 },
{ STA, INDIR , 0x92, 1 },
{ STA, SR_Y , 0x93, 1 },
{ STA, DP_X , 0x95, 1 },
{ STA, INDIR_LONG_Y, 0x97, 1 },
{ STA, ABS_Y , 0x99, 2 },
{ STA, ABS_X , 0x9d, 2 },
{ STA, ABS_LONG_X , 0x9f, 3 },
{ STP, IMPLIED , 0xdb, 0 },
{ STX, DP , 0x86, 1 },
{ STX, ABS , 0x8e, 2 },
{ STX, DP_Y , 0x96, 1 },
{ STY, DP , 0x84, 1 },
{ STY, ABS , 0x8c, 2 },
{ STY, DP_X , 0x94, 1 },
{ STZ, DP , 0x64, 1 },
{ STZ, DP_X , 0x74, 1 },
{ STZ, ABS , 0x9c, 2 },
{ STZ, ABS_X , 0x9e, 2 },
{ TAX, IMPLIED , 0xaa, 0 },
{ TAY, IMPLIED , 0xa8, 0 },
{ TCD, IMPLIED , 0x5b, 0 },
{ TCS, IMPLIED , 0x1b, 0 },
{ TDC, IMPLIED , 0x7b, 0 },
{ TRB, DP , 0x14, 1 },
{ TRB, ABS , 0x1c, 2 },
{ TSB, DP , 0x04, 1 },
{ TSB, ABS , 0x0c, 2 },
{ TSC, IMPLIED , 0x3b, 0 },
{ TSX, IMPLIED , 0xba, 0 },
{ TXA, IMPLIED , 0x8a, 0 },
{ TXS, IMPLIED , 0x9a, 0 },
{ TXY, IMPLIED , 0x9b, 0 },
{ TYA, IMPLIED , 0x98, 0 },
{ TYX, IMPLIED , 0xbb, 0 },
{ WAI, IMPLIED , 0xcb, 0 },
{ WDM, INTERRUPT , 0x42, 1 },
{ XBA, IMPLIED , 0xeb, 0 },
{ XCE, IMPLIED , 0xfb, 0 },
};
/* generate an index of mnemonics to opcodes in the opcode_table */
struct opcode_entry *opcode_table_index[MNEMONIC_LAST] = { 0 };
static void init_table_index(void) {
unsigned i;
unsigned prev = 0;
opcode_table_index[0] = &opcode_table[0];
for (i = 1; i < sizeof(opcode_table) / sizeof(opcode_table[0]); ++i) {
if (opcode_table[i].mnemonic != prev) {
prev = opcode_table[i].mnemonic;
opcode_table_index[prev] = &opcode_table[i];
}
}
opcode_table_index[++prev] = &opcode_table[i];
}
static int find_opcode(struct cookie *cookie) {
unsigned mode = cookie->mode;
const struct opcode_entry *iter = opcode_table_index[cookie->mnemonic];
const struct opcode_entry *end = opcode_table_index[cookie->mnemonic + 1];
/* special case for relative */
if (iter->mode == RELATIVE) {
if (mode == DP || mode == ABS) {
cookie->mode = RELATIVE;
cookie->size = iter->size;
return cookie->opcode = iter->opcode;
}
return -1;
}
for ( ; iter != end; ++iter) {
if (mode == iter->mode) break;
}
if (iter == end) return -1;
cookie->size = iter->size;
if (iter->size == 4) {
cookie->size = g_disasm_psr & 0x20 ? 1 : 2;
}
if (iter->size == 5) {
cookie->size = g_disasm_psr & 0x10 ? 1 : 2;
}
return cookie->opcode = iter->opcode;
}
static const char *parse_expr(const char *cp, struct cookie *cookie) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
if (!cp) return NULL;
cookie->size = 0;
switch(*cp) {
case '|': ++cp; cookie->size = 2; break;
case '>': ++cp; cookie->size = 3; break;
case '<': ++cp; cookie->size = 1; break;
}
/*!re2c
* { return NULL; }
'*' {
cookie->operand = cookie->pc;
if (!cookie->size) cookie->size = 2;
return YYCURSOR;
}
'*' [+-] x{1,4} {
int tmp = to_hex(cp + 2, YYCURSOR);
if (cp[1] == '-') tmp = -tmp;
cookie->operand = cookie->pc + tmp;
if (!cookie->size) cookie->size = 2;
return YYCURSOR;
}
x{1,6} {
cookie->operand = to_hex(cp, YYCURSOR);
if (!cookie->size) cookie->size = ((YYCURSOR - cp + 1) & ~1)>>1;
return YYCURSOR;
}
*/
}
static const char *parse_tail(const char *cp, struct cookie *cookie) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
if (!cp) return cp;
/*!re2c
"" { return cp; }
',s' { cookie->mode = SR; return YYCURSOR; }
',x' { cookie->mode += _x; return YYCURSOR; }
',y' { cookie->mode += _y; return YYCURSOR; }
*/
}
static const char *parse_paren_tail(const char *cp, struct cookie *cookie) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
if (!cp) return cp;
/*!re2c
* { return NULL; }
")" { return cp; }
"),y" { cookie->mode += _y; return YYCURSOR; }
",x)" { cookie->mode += _x; return YYCURSOR; }
",s),y" { cookie->mode = SR_Y; return YYCURSOR; }
*/
}
static const char *parse_bracket_tail(const char *cp, struct cookie *cookie) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
if (!cp) return cp;
/*!re2c
* { return NULL; }
"]" { return YYCURSOR; }
"],y" { cookie->mode += _y; return YYCURSOR; }
*/
}
static int mnemonic_cmp(const void *a, const void *b) {
int key = (unsigned)(uintptr_t)a;
const struct mnemonic_entry *e = b;
return key - e->value;
}
static const char *parse_opcode(const char *cp, struct cookie *cookie) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
/* todo -- long m|x, short m|x, _toolcall */
/*!re2c
* { return NULL; }
[A-Za-z]{3} / (ws|eol) {
uint32_t tmp = 0;
struct mnemonic_entry *e;
unsigned i;
for (i = 0; i < 3; ++i) { tmp <<= 8; tmp |= (cp[i] & ~0x20); }
e = bsearch((void *)(uintptr_t)tmp, mnemonic_table,
sizeof(mnemonic_table) / sizeof(mnemonic_table[0]),
sizeof(mnemonic_table[0]), mnemonic_cmp);
if (!e) return NULL;
cookie->mnemonic = e->mnemonic;
cookie->mode = IMPLIED;
cookie->operand = 0;
cookie->size = 0;
return ltrim(YYCURSOR);
}
*/
}
static const char *parse_operand(const char *cp, struct cookie *cookie) {
if (!cp) return NULL;
/* special case for MVN/MVP */
if (cookie->mnemonic == MVN || cookie->mnemonic == MVP) {
unsigned tmp;
cp = parse_expr(cp, cookie);
if (!cp) return NULL;
if (*cp++ != ',') return NULL;
tmp = cookie->operand & 0xff;
cp = parse_expr(cp, cookie);
if (*cp && !isspace(*cp)) return NULL;
cookie->mode = BLOCK;
cookie->operand &= 0xff;
cookie->operand |= tmp << 8;
cookie->size = 2;
return ltrim(cp);
}
/* special case for mli/gsos calls [?] */
switch (*cp) {
case '#':
cookie->mode = IMMEDIATE;
cp = parse_expr(cp + 1, cookie);
break;
case '(':
cookie->mode = INDIR;
cp = parse_expr(cp+1, cookie);
cp = parse_paren_tail(cp, cookie);
break;
case '[':
cookie->mode = INDIR_LONG;
cp = parse_expr(cp + 1, cookie);
cp = parse_bracket_tail(cp, cookie);
break;
default:
cookie->mode = ABS;
cp = parse_expr(cp, cookie);
switch(cookie->size) {
case 1: cookie->mode = DP; break;
case 3: cookie->mode = ABS_LONG; break;
}
cp = parse_tail(cp, cookie);
break;
}
if (*cp && !isspace(*cp)) return NULL;
return ltrim(cp);
}
extern uint32_t do_list(uint32_t address, int lines);
extern char *x_readline(const char *prompt);
static int error(int offset, const char *msg) {
while (offset > 0) { fputc(' ', stderr); --offset; }
fputs(" ^", stderr);
fputs(msg, stderr);
fputc('\n', stderr);
return -1;
}
static const char *parse_pc(const char *cp, uint32_t *pc) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
if (isspace(*cp)) return ltrim(cp);
/*!re2c
* { return NULL; }
x{4} ':' {
*pc &= 0xff0000;
*pc |= to_hex(cp, YYCURSOR - 1);
goto next;
}
x{6} ':' {
*pc = to_hex(cp, YYCURSOR - 1);
goto next;
}
x{2} '/' x{4} ':' {
uint32_t tmp = to_hex(cp, cp + 2) << 16;
tmp |= to_hex(cp + 3, YYCURSOR - 1);
*pc = tmp;
goto next;
}
*/
next:
return ltrim(YYCURSOR);
}
static int parse_line(const char *cp, uint32_t *pc) {
struct cookie cookie = { 0 };
unsigned offset = 0;
uint32_t addr = *pc;
const char *start = cp;
unsigned i;
cp = parse_pc(cp, &addr);
if (!cp) return error(0, "error");
offset = cp - start;
/* label only? */
if (!*cp) {
*pc = addr;
return 0;
}
/* address ... */
cookie.pc = *pc;
cp = parse_opcode(cp, &cookie);
if (!cp) return error(offset, "bad opcode");
offset = cp - start;
if (*cp) {
parse_operand(cp, &cookie);
if (!cp) return error(offset, "bad operand");
//offset = cp - start;
}
if (*cp) return error(offset, "bad operand");
if (find_opcode(&cookie) < 0) return error(offset, "invalid address mode");
/* clean up relative */
if (cookie.mode == RELATIVE) {
int pc = (cookie.pc + 1 + cookie.size) & 0xffff;
int tmp = (int16_t)(cookie.operand & 0xffff);
int offset = tmp - pc;
if (cookie.size == 1) {
if (tmp < -128 || tmp > 127) return error(offset, "out of range");
tmp &= 0xff;
}
else tmp &= 0xffff;
cookie.operand = tmp;
}
set_memory_c(addr, cookie.opcode, 0);
unsigned operand = cookie.operand;
for (i = 0; i < cookie.size; ++i) {
set_memory_c(addr, operand & 0xff, 0);
operand >>= 8;
}
fputs("\r\x1b[A\x1b[K", stdout);
do_list(addr, 1);
*pc = addr + 1 + cookie.size;
return 1;
}
uint32_t mini_asm_shell(uint32_t addr) {
static int init = 0;
if (!init) {
init_table_index();
init = 1;
}
for(;;) {
const char *cp = x_readline("!");
if (!cp || !*cp) return addr;
parse_line(cp, &addr);
}
}

View File

@ -420,7 +420,7 @@ static int is_jsr_bf00(word32 address) {
get_memory16_c(address + 1, 0) == 0xbf00;
}
static int g_disasm_psr;
int g_disasm_psr;
static const char *get_inline_debug_name(word32 address) {
static char buffer[256];
@ -1434,7 +1434,12 @@ static int parse_command(const char *cp) {
"!!" eol {
extern uint32_t sweet16_asm_shell(uint32_t addr);
sweet16_asm_shell(0x300);
addr = sweet16_asm_shell(addr);
return 0;
}
"!" eol {
extern uint32_t mini_asm_shell(uint32_t addr);
addr = mini_asm_shell(addr);
return 0;
}

92
src/mnemonics.x Normal file
View File

@ -0,0 +1,92 @@
x(ADC)
x(AND)
x(ASL)
x(BCC)
x(BCS)
x(BEQ)
x(BIT)
x(BMI)
x(BNE)
x(BPL)
x(BRA)
x(BRK)
x(BRL)
x(BVC)
x(BVS)
x(CLC)
x(CLD)
x(CLI)
x(CLV)
x(CMP)
x(COP)
x(CPX)
x(CPY)
x(DEC)
x(DEX)
x(DEY)
x(EOR)
x(INC)
x(INX)
x(INY)
x(JML)
x(JMP)
x(JSL)
x(JSR)
x(LDA)
x(LDX)
x(LDY)
x(LSR)
x(MVN)
x(MVP)
x(NOP)
x(ORA)
x(PEA)
x(PEI)
x(PER)
x(PHA)
x(PHB)
x(PHD)
x(PHK)
x(PHP)
x(PHX)
x(PHY)
x(PLA)
x(PLB)
x(PLD)
x(PLP)
x(PLX)
x(PLY)
x(REP)
x(ROL)
x(ROR)
x(RTI)
x(RTL)
x(RTS)
x(SBC)
x(SEC)
x(SED)
x(SEI)
x(SEP)
x(STA)
x(STP)
x(STX)
x(STY)
x(STZ)
x(TAX)
x(TAY)
x(TCD)
x(TCS)
x(TDC)
x(TRB)
x(TSB)
x(TSC)
x(TSX)
x(TXA)
x(TXS)
x(TXY)
x(TYA)
x(TYX)
x(WAI)
x(WDM)
x(XBA)
x(XCE)