initial support for the 65C02 cpu

This commit is contained in:
Bernd Boeckmann
2023-04-29 01:18:12 +02:00
parent b06225f30d
commit ce8d71e13d
4 changed files with 381 additions and 135 deletions

146
asm6502.c
View File

@@ -221,7 +221,8 @@ enum {
ERR_MAX_IF,
ERR_PHASE,
ERR_PHASE_SIZE,
ERR_DIV_BY_ZERO
ERR_DIV_BY_ZERO,
ERR_CPU_UNSUPPORTED
};
static char *err_msg[] = {
@@ -257,7 +258,8 @@ static char *err_msg[] = {
"too many if nesting levels",
"symbol value mismatch between pass one and two",
"pass two code size greater than pass one code size",
"division by zero"
"division by zero",
"CPU not supported"
};
enum {
@@ -545,7 +547,7 @@ static value number( char **p ) {
}
static void ident_( char **p, char *id, int numeric ) {
static void ident( char **p, char *id, int numeric, int uppercase ) {
int i = 0;
if (( !numeric && !isalpha( **p ) && ( **p != '_' ))
@@ -553,7 +555,7 @@ static void ident_( char **p, char *id, int numeric ) {
error( ERR_ID );
do {
*id++ = *( *p )++;
*id++ = (char) ( uppercase ? toupper( *( *p )++ ) : *( *p )++ );
i++;
if ( i >= ID_LEN ) error( ERR_ID_LEN );
} while ( isalnum( **p ) || ( **p == '_' ));
@@ -562,33 +564,6 @@ static void ident_( char **p, char *id, int numeric ) {
}
/* read identifier which may not start with a digit */
static void ident( char **p, char *id ) {
ident_( p, id, 0 );
}
/* read identifier which may start with a digit */
static void numbered_ident( char **p, char *id ) {
ident_( p, id, 1 );
}
/* read identifier and convert to upper case */
static void ident_uppercase( char **p, char *id ) {
int i = 0;
if ( !isalpha( **p )) error( ERR_ID );
do {
*id++ = (char) toupper( *( *p )++ );
i++;
if ( i >= ID_LEN ) error( ERR_ID_LEN );
} while ( isalnum( **p ));
*id = '\0';
}
static value expr( char ** );
@@ -608,7 +583,7 @@ static value primary( char **p ) {
( *p ) += 2;
} else if ( **p == LOCAL_LABEL_LETTER && isalnum( *( *p + 1 ))) { /* local label*/
( *p )++;
numbered_ident( p, id );
ident( p, id, 1, 0 );
sym = lookup( id, current_label->locals );
if ( sym ) {
res = sym->value;
@@ -630,14 +605,14 @@ static value primary( char **p ) {
if ( **p != '\'' ) error( ERR_CHR );
( *p )++;
} else if ( isalpha( **p )) {
ident( p, id );
ident( p, id, 0, 0 );
sym = lookup( id, NULL);
if ( !sym ) sym = reserve_label( id, NULL);
skip_white( p );
if ( **p == LOCAL_LABEL_LETTER ) {
/* qualified identifier: local label or variable */
( *p )++;
numbered_ident( p, id );
ident( p, id, 1, 0 );
local_sym = lookup( id, sym->locals );
if ( !local_sym ) local_sym = reserve_label( id, sym );
res = local_sym->value;
@@ -956,7 +931,7 @@ static void to_uppercase( char *p ) {
static instruction_desc *get_instruction_descr( const char *p ) {
int l = 0, r = sizeof( instruction_tbl ) / sizeof( instruction_desc ), x;
int l = 0, r = instruction_tbl_size, x;
int cmp;
while ( r >= l ) {
@@ -1040,6 +1015,19 @@ static void emit_instr_2( instruction_desc *instr, int am, u16 o ) {
}
/* emit instruction with byte argument */
static void emit_instr_2p( instruction_desc *instr, int am, u8 o, u8 p ) {
if ( pass == 2 ) {
if ( oc < code_size - 2 ) {
code[oc] = instr->op[am];
code[oc + 1] = o;
code[oc + 2] = p;
} else error( ERR_PHASE_SIZE );
}
oc += 3;
}
static int instruction_imp_acc( instruction_desc *instr ) {
int am = AM_INV;
@@ -1068,8 +1056,7 @@ static int instruction_imm( char **p, instruction_desc *instr ) {
}
static int instruction_rel( instruction_desc *instr, value v ) {
int am = AM_REL;
static u16 calculate_offset( value v ) {
u16 pct = pc + 2u;
u16 off;
@@ -1086,9 +1073,14 @@ static int instruction_rel( instruction_desc *instr, value v ) {
}
if ( v.v >= pct ) off = v.v - pct;
else off = (u16) (( ~0u ) - ( pct - v.v - 1u ));
emit_instr_1( instr, am, off & 0xffu );
return off;
}
return am;
static int instruction_rel( instruction_desc *instr, value v ) {
u16 off = calculate_offset( v );
emit_instr_1( instr, AM_REL, off & 0xffu );
return AM_REL;
}
@@ -1105,23 +1097,26 @@ static int instruction_ind( char **p, instruction_desc *instr ) {
/* indirect X addressing mode? */
if ( **p == ',' ) {
skip_curr_and_white( p );
ident_uppercase( p, id );
ident( p, id, 0, 1 );
if ( strcmp( id, "X" ) != 0 ) error( ERR_INX );
am = AM_INX;
if ( AM_VALID( *instr, AM_AIX )) am = AM_AIX;
else am = AM_ZIX;
skip_white( p );
if ( **p != ')' ) error( ERR_CLOSING_PAREN );
skip_curr_and_white( p );
} else {
if ( **p != ')' ) error( ERR_CLOSING_PAREN );
skip_curr_and_white( p );
/* indirect Y addressing mode? */
if ( **p == ',' ) {
skip_curr_and_white( p );
ident_uppercase( p, id );
ident( p, id, 0, 1 );
if ( strcmp( id, "Y" ) != 0 ) error( ERR_INY );
am = AM_INY;
am = AM_ZIY;
} else {
am = AM_IND;
if ( AM_VALID( *instr, AM_ZIN )) am = AM_ZIN;
else am = AM_AIN;
}
}
@@ -1129,11 +1124,12 @@ static int instruction_ind( char **p, instruction_desc *instr ) {
if ( pass == 2 ) {
if ( UNDEFINED( v )) error( ERR_UNDEF );
if ((( am == AM_INX ) || am == ( AM_INY )) && (TYPE( v ) != TYPE_BYTE ))
if (( am == AM_ZIX || am == AM_ZIY || am == AM_ZIN )
&& (TYPE( v ) != TYPE_BYTE ))
error( ERR_ILLEGAL_TYPE );
}
if ( am == AM_IND ) {
if ( am == AM_AIN || am == AM_AIX ) {
emit_instr_2( instr, am, v.v );
} else {
emit_instr_1( instr, am, (u8) v.v );
@@ -1158,7 +1154,7 @@ static int instruction_abxy_zpxy( char **p, instruction_desc *instr, value v ) {
if ( UNDEFINED( v )) error( ERR_UNDEF );
}
ident_uppercase( p, id );
ident( p, id, 0, 1 );
/* test for absolute and zero-page X addressing */
if ( !strcmp( id, "X" )) {
if ((TYPE( v ) == TYPE_BYTE ) && AM_VALID( *instr, AM_ZPX )) am = AM_ZPX;
@@ -1169,7 +1165,7 @@ static int instruction_abxy_zpxy( char **p, instruction_desc *instr, value v ) {
} else error( ERR_AM );
}
/* test for absolute and zero-page Y addressing */
/* test for absolute and zero-page Y addressing */
else if ( !strcmp( id, "Y" )) {
if ((TYPE( v ) == TYPE_BYTE ) && AM_VALID( *instr, AM_ZPY )) am = AM_ZPY;
else if ( AM_VALID( *instr, AM_ABY )) {
@@ -1212,6 +1208,26 @@ static int instruction_abs_zp( instruction_desc *instr, value v ) {
}
/* bit branch, bit set/reset instructions */
static int instruction_zp_rel( char **p, instruction_desc *instr, value v ) {
u16 off;
value rel;
if ( TYPE( v ) != TYPE_BYTE )
error( ERR_BYTE_RANGE );
rel = expr( p );
off = calculate_offset( rel );
if ( pass == 2 ) {
if ( UNDEFINED( v ) || UNDEFINED( rel )) error( ERR_UNDEF );
}
emit_instr_2p( instr, AM_ZPR, (u8) v.v, off );
return AM_ZPR;
}
/* process one instruction */
static void instruction( char **p ) {
char id[ID_LEN];
@@ -1220,7 +1236,7 @@ static void instruction( char **p ) {
value v;
/* first get instruction for given mnemonic */
ident_uppercase( p, id );
ident( p, id, 0, 1 );
instr = get_instruction_descr( id );
if ( !instr ) error( ERR_INSTR );
@@ -1248,7 +1264,8 @@ static void instruction( char **p ) {
/* else we go through the possible absolute addressing modes */
else if ( **p == ',' ) {
skip_curr_and_white( p );
am = instruction_abxy_zpxy( p, instr, v );
if ( AM_VALID( *instr, AM_ZPR )) am = instruction_zp_rel( p, instr, v );
else am = instruction_abxy_zpxy( p, instr, v );
}
/* must be absolute or zero-page addressing */
else {
@@ -1688,12 +1705,27 @@ static void directive_assert( char **p, int on_pass ) {
}
static void directive_cpu( char **p ) {
char cpu_type[ID_LEN];
skip_white(p);
ident( p, cpu_type, 1, 1 );
if ( !strcmp( cpu_type, "6502" )) {
select_6502();
} else if ( !strcmp( cpu_type, "65C02" )) {
select_65c02();
} else {
error( ERR_CPU_UNSUPPORTED );
}
}
static int directive( char **p ) {
char id[ID_LEN];
value v;
int again = 0;
ident_uppercase( p, id );
ident( p, id, 0, 1 );
if ( !strcmp( id, "ORG" )) {
v = expr( p );
@@ -1727,6 +1759,8 @@ static int directive( char **p ) {
} else if ( !strcmp( id, "LIST" )) {
listing = list_statements;
list_skip_one = 1;
} else if ( !strcmp( id, "CPU" )) {
directive_cpu( p );
} else {
error( ERR_NO_DIRECTIVE );
}
@@ -1737,7 +1771,7 @@ static int directive( char **p ) {
static int is_mnemonic( const char *id ) {
char id_uppercase[ID_LEN];
int l = 0, r = sizeof( instruction_tbl ) / sizeof( instruction_desc ), x;
int l = 0, r = instruction_tbl_size, x;
int cmp;
strcpy( id_uppercase, id );
to_uppercase( id_uppercase );
@@ -1770,11 +1804,11 @@ static int statement( char **p ) {
/* first check for variable or label definition */
if ( **p == LOCAL_LABEL_LETTER ) {
( *p )++;
numbered_ident( p, id1 );
ident( p, id1, 1, 0 );
skip_white( p );
label = LOCAL_LABEL;
} else if ( isalpha( **p )) {
ident( p, id1 );
ident( p, id1, 0, 0 );
skip_white( p );
label = GLOBAL_LABEL;
}
@@ -2011,7 +2045,7 @@ static int conditional_statement( char **p ) {
if ( IS_END( **p )) return 0;
if ( **p != DIRECTIVE_LETTER ) return 0;
( *p )++;
ident_uppercase( p, id );
ident( p, id, 0, 1 );
if ( !strcmp( id, "IF" )) {
directive_if( p, 1, 0 );
@@ -2245,6 +2279,8 @@ int main( int argc, char *argv[] ) {
goto ret0;
}
select_6502();
/* first assembler pass */
pass = 1;
source = current_file->text;

View File

@@ -36,38 +36,47 @@ typedef unsigned short u16;
/* addressing modes */
enum {
AM_ACC = 0,
AM_IMP = 1,
AM_IMM = 2,
AM_REL = 3,
AM_ZP = 4,
AM_ZPX = 5,
AM_ZPY = 6,
AM_ABS = 7,
AM_ABX = 8,
AM_ABY = 9,
AM_IND = 10,
AM_INX = 11,
AM_INY = 12,
AM_INV = 13
AM_ACC = 0, /* accumulator */
AM_IMP = 1, /* implied */
AM_IMM = 2, /* # immediate addressing */
AM_REL = 3, /* R program counter relative */
AM_ZP = 4, /* ZP zero-page */
AM_ZPX = 5, /* ZP,X zero-page indexed with X */
AM_ZPY = 6, /* ZP,Y zero-page indexed with Y */
AM_ABS = 7, /* A absolute */
AM_ABX = 8, /* A,X absolute indexed with X */
AM_ABY = 9, /* A,Y absolute indexed with Y */
AM_AIN = 10, /* (A) absolute indirect */
AM_ZIX = 11, /* (ZP,X) zero-page indexed indirect */
AM_ZIY = 12, /* (ZP),Y zero-page indirect indexed with Y */
AM_ZIN = 13, /* (ZP) zero-page indirect */
AM_AIX = 14, /* (ABS,X) absolute indexed indirect */
AM_ZPR = 15, /* ZP,R zero-page, relative */
AM_INV = 16
};
enum {
INV = 0xff
INV = 0xfc
};
typedef struct instruction_desc {
char mn[4];
u8 op[13];
char mn[5];
u8 op[16];
} instruction_desc;
extern instruction_desc instruction_tbl[56];
extern const unsigned itbl_size;
extern u16 am_size[13];
extern instruction_desc *instruction_tbl;
extern instruction_desc itbl_6502[56];
extern instruction_desc itbl_65c02[98];
extern int instruction_tbl_size;
extern u16 am_size[16];
#define AM_VALID( instr, am ) ((instr).op[am] != INV)
#define MAXINT( a, b ) (((b) >= (a)) ? (b) : (a))
void select_6502(void);
void select_65c02(void);
#endif

234
itbl.c
View File

@@ -30,65 +30,181 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "asm6502.h"
u16 am_size[13] = { 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2 };
u16 am_size[16] = { 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 3, 3 };
const unsigned itbl_size = 56;
instruction_desc instruction_tbl[56] = {
{ "ADC", { INV, INV, 0x69, INV, 0x65, 0x75, INV, 0x6d, 0x7d, 0x79, INV, 0x61, 0x71 }},
{ "AND", { INV, INV, 0x29, INV, 0x25, 0x35, INV, 0x2d, 0x3d, 0x39, INV, 0x21, 0x31 }},
{ "ASL", { 0x0a, INV, INV, INV, 0x06, 0x16, INV, 0x0e, 0x1e, INV, INV, INV, INV }},
{ "BCC", { INV, INV, INV, 0x90, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BCS", { INV, INV, INV, 0xb0, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BEQ", { INV, INV, INV, 0xf0, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BIT", { INV, INV, INV, INV, 0x24, INV, INV, 0x2c, INV, INV, INV, INV, INV }},
{ "BMI", { INV, INV, INV, 0x30, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BNE", { INV, INV, INV, 0xd0, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BPL", { INV, INV, INV, 0x10, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BRK", { INV, 0x00, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BVC", { INV, INV, INV, 0x50, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BVS", { INV, INV, INV, 0x70, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLC", { INV, 0x18, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLD", { INV, 0xd8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLI", { INV, 0x58, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLV", { INV, 0xb8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CMP", { INV, INV, 0xc9, INV, 0xc5, 0xd5, INV, 0xcd, 0xdd, 0xd9, INV, 0xc1, 0xd1 }},
{ "CPX", { INV, INV, 0xe0, INV, 0xe4, INV, INV, 0xec, INV, INV, INV, INV, INV }},
{ "CPY", { INV, INV, 0xc0, INV, 0xc4, INV, INV, 0xcc, INV, INV, INV, INV, INV }},
{ "DEC", { INV, INV, INV, INV, 0xc6, 0xd6, INV, 0xce, 0xde, INV, INV, INV, INV }},
{ "DEX", { INV, 0xca, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "DEY", { INV, 0x88, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "EOR", { INV, INV, 0x49, INV, 0x45, 0x55, INV, 0x4d, 0x5d, 0x59, INV, 0x41, 0x51 }},
{ "INC", { INV, INV, INV, INV, 0xe6, 0xf6, INV, 0xee, 0xfe, INV, INV, INV, INV }},
{ "INX", { INV, 0xe8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "INY", { INV, 0xc8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "JMP", { INV, INV, INV, INV, INV, INV, INV, 0x4c, INV, INV, 0x6c, INV, INV }},
{ "JSR", { INV, INV, INV, INV, INV, INV, INV, 0x20, INV, INV, INV, INV, INV }},
{ "LDA", { INV, INV, 0xa9, INV, 0xa5, 0xb5, INV, 0xad, 0xbd, 0xb9, INV, 0xa1, 0xb1 }},
{ "LDX", { INV, INV, 0xa2, INV, 0xa6, INV, 0xb6, 0xae, INV, 0xbe, INV, INV, INV }},
{ "LDY", { INV, INV, 0xa0, INV, 0xa4, 0xb4, INV, 0xac, 0xbc, INV, INV, INV, INV }},
{ "LSR", { 0x4a, INV, INV, INV, 0x46, 0x56, INV, 0x4e, 0x5e, INV, INV, INV, INV }},
{ "NOP", { INV, 0xea, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "ORA", { INV, INV, 0x09, INV, 0x05, 0x15, INV, 0x0d, 0x1d, 0x19, INV, 0x01, 0x11 }},
{ "PHA", { INV, 0x48, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PHP", { INV, 0x08, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLA", { INV, 0x68, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLP", { INV, 0x28, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "ROL", { 0x2a, INV, INV, INV, 0x26, 0x36, INV, 0x2e, 0x3e, INV, INV, INV, INV }},
{ "ROR", { 0x6a, INV, INV, INV, 0x66, 0x76, INV, 0x6e, 0x7e, INV, INV, INV, INV }},
{ "RTI", { INV, 0x40, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RTS", { INV, 0x60, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SBC", { INV, INV, 0xe9, INV, 0xe5, 0xf5, INV, 0xed, 0xfd, 0xf9, INV, 0xe1, 0xf1 }},
{ "SEC", { INV, 0x38, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SED", { INV, 0xf8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SEI", { INV, 0x78, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STA", { INV, INV, INV, INV, 0x85, 0x95, INV, 0x8d, 0x9d, 0x99, INV, 0x81, 0x91 }},
{ "STX", { INV, INV, INV, INV, 0x86, INV, 0x96, 0x8e, INV, INV, INV, INV, INV }},
{ "STY", { INV, INV, INV, INV, 0x84, 0x94, INV, 0x8c, INV, INV, INV, INV, INV }},
{ "TAX", { INV, 0xaa, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TAY", { INV, 0xa8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TSX", { INV, 0xba, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TXA", { INV, 0x8a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TXS", { INV, 0x9a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TYA", { INV, 0x98, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }}
instruction_desc *instruction_tbl;
int instruction_tbl_size;
void select_6502( void ) {
instruction_tbl = itbl_6502;
instruction_tbl_size = sizeof( itbl_6502 ) / sizeof( instruction_desc );
}
void select_65c02( void ) {
instruction_tbl = itbl_65c02;
instruction_tbl_size = sizeof( itbl_65c02 ) / sizeof( instruction_desc );
}
instruction_desc itbl_6502[56] = {
{ "ADC", { INV, INV, 0x69, INV, 0x65, 0x75, INV, 0x6d, 0x7d, 0x79, INV, 0x61, 0x71, INV, INV, INV }},
{ "AND", { INV, INV, 0x29, INV, 0x25, 0x35, INV, 0x2d, 0x3d, 0x39, INV, 0x21, 0x31, INV, INV, INV }},
{ "ASL", { 0x0a, INV, INV, INV, 0x06, 0x16, INV, 0x0e, 0x1e, INV, INV, INV, INV, INV, INV, INV }},
{ "BCC", { INV, INV, INV, 0x90, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BCS", { INV, INV, INV, 0xb0, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BEQ", { INV, INV, INV, 0xf0, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BIT", { INV, INV, INV, INV, 0x24, INV, INV, 0x2c, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BMI", { INV, INV, INV, 0x30, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BNE", { INV, INV, INV, 0xd0, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BPL", { INV, INV, INV, 0x10, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BRK", { INV, 0x00, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BVC", { INV, INV, INV, 0x50, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BVS", { INV, INV, INV, 0x70, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLC", { INV, 0x18, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLD", { INV, 0xd8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLI", { INV, 0x58, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLV", { INV, 0xb8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CMP", { INV, INV, 0xc9, INV, 0xc5, 0xd5, INV, 0xcd, 0xdd, 0xd9, INV, 0xc1, 0xd1, INV, INV, INV }},
{ "CPX", { INV, INV, 0xe0, INV, 0xe4, INV, INV, 0xec, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CPY", { INV, INV, 0xc0, INV, 0xc4, INV, INV, 0xcc, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "DEC", { INV, INV, INV, INV, 0xc6, 0xd6, INV, 0xce, 0xde, INV, INV, INV, INV, INV, INV, INV }},
{ "DEX", { INV, 0xca, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "DEY", { INV, 0x88, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "EOR", { INV, INV, 0x49, INV, 0x45, 0x55, INV, 0x4d, 0x5d, 0x59, INV, 0x41, 0x51, INV, INV, INV }},
{ "INC", { INV, INV, INV, INV, 0xe6, 0xf6, INV, 0xee, 0xfe, INV, INV, INV, INV, INV, INV, INV }},
{ "INX", { INV, 0xe8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "INY", { INV, 0xc8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "JMP", { INV, INV, INV, INV, INV, INV, INV, 0x4c, INV, INV, 0x6c, INV, INV, INV, INV, INV }},
{ "JSR", { INV, INV, INV, INV, INV, INV, INV, 0x20, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "LDA", { INV, INV, 0xa9, INV, 0xa5, 0xb5, INV, 0xad, 0xbd, 0xb9, INV, 0xa1, 0xb1, INV, INV, INV }},
{ "LDX", { INV, INV, 0xa2, INV, 0xa6, INV, 0xb6, 0xae, INV, 0xbe, INV, INV, INV, INV, INV, INV }},
{ "LDY", { INV, INV, 0xa0, INV, 0xa4, 0xb4, INV, 0xac, 0xbc, INV, INV, INV, INV, INV, INV, INV }},
{ "LSR", { 0x4a, INV, INV, INV, 0x46, 0x56, INV, 0x4e, 0x5e, INV, INV, INV, INV, INV, INV, INV }},
{ "NOP", { INV, 0xea, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "ORA", { INV, INV, 0x09, INV, 0x05, 0x15, INV, 0x0d, 0x1d, 0x19, INV, 0x01, 0x11, INV, INV, INV }},
{ "PHA", { INV, 0x48, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PHP", { INV, 0x08, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLA", { INV, 0x68, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLP", { INV, 0x28, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "ROL", { 0x2a, INV, INV, INV, 0x26, 0x36, INV, 0x2e, 0x3e, INV, INV, INV, INV, INV, INV, INV }},
{ "ROR", { 0x6a, INV, INV, INV, 0x66, 0x76, INV, 0x6e, 0x7e, INV, INV, INV, INV, INV, INV, INV }},
{ "RTI", { INV, 0x40, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RTS", { INV, 0x60, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SBC", { INV, INV, 0xe9, INV, 0xe5, 0xf5, INV, 0xed, 0xfd, 0xf9, INV, 0xe1, 0xf1, INV, INV, INV }},
{ "SEC", { INV, 0x38, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SED", { INV, 0xf8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SEI", { INV, 0x78, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STA", { INV, INV, INV, INV, 0x85, 0x95, INV, 0x8d, 0x9d, 0x99, INV, 0x81, 0x91, INV, INV, INV }},
{ "STX", { INV, INV, INV, INV, 0x86, INV, 0x96, 0x8e, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STY", { INV, INV, INV, INV, 0x84, 0x94, INV, 0x8c, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TAX", { INV, 0xaa, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TAY", { INV, 0xa8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TSX", { INV, 0xba, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TXA", { INV, 0x8a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TXS", { INV, 0x9a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TYA", { INV, 0x98, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }}
};
instruction_desc itbl_65c02[98] = {
{ "ADC", { INV, INV, 0x69, INV, 0x65, 0x75, INV, 0x6d, 0x7d, 0x79, INV, 0x61, 0x71, 0x72, INV, INV }},
{ "AND", { INV, INV, 0x29, INV, 0x25, 0x35, INV, 0x2d, 0x3d, 0x39, INV, 0x21, 0x31, 0x32, INV, INV }},
{ "ASL", { 0x0a, INV, INV, INV, 0x06, 0x16, INV, 0x0e, 0x1e, INV, INV, INV, INV, INV, INV, INV }},
{ "BBR0", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x0f }},
{ "BBR1", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x1f }},
{ "BBR2", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x2f }},
{ "BBR3", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x3f }},
{ "BBR4", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x4f }},
{ "BBR5", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x5f }},
{ "BBR6", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x6f }},
{ "BBR7", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x7f }},
{ "BBS0", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x8f }},
{ "BBS1", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0x9f }},
{ "BBS2", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xaf }},
{ "BBS3", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xbf }},
{ "BBS4", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xcf }},
{ "BBS5", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xdf }},
{ "BBS6", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xef }},
{ "BBS7", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xff }},
{ "BCC", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BCS", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BEQ", { INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BIT", { INV, INV, 0x89, INV, 0x24, 0x34, INV, 0x2c, 0x3c, INV, INV, INV, INV, INV, INV, INV }},
{ "BMI", { INV, INV, INV, 0x30, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BNE", { INV, INV, INV, 0xd0, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BPL", { INV, INV, INV, 0x10, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BRA", { INV, INV, INV, 0x80, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BRK", { INV, 0x00, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BVC", { INV, INV, INV, 0x50, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "BVS", { INV, INV, INV, 0x70, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLC", { INV, 0x18, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLD", { INV, 0xd8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLI", { INV, 0x58, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CLV", { INV, 0xb8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CMP", { INV, INV, 0xc9, INV, 0xc5, 0xd5, INV, 0xcd, 0xdd, 0xd9, INV, 0xc1, 0xd1, 0xd2, INV, INV }},
{ "CPX", { INV, INV, 0xe0, INV, 0xe4, INV, INV, 0xec, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "CPY", { INV, INV, 0xc0, INV, 0xc4, INV, INV, 0xcc, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "DEC", { 0x3a, INV, INV, INV, 0xc6, 0xd6, INV, 0xce, 0xde, INV, INV, INV, INV, INV, INV, INV }},
{ "DEX", { INV, 0xca, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "DEY", { INV, 0x88, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "EOR", { INV, INV, 0x49, INV, 0x45, 0x55, INV, 0x4d, 0x5d, 0x59, INV, 0x41, 0x51, 0x52, INV, INV }},
{ "INC", { 0xee, INV, INV, INV, 0xe6, 0xf6, INV, 0xee, 0xfe, INV, INV, INV, INV, INV, INV, INV }},
{ "INX", { INV, 0xe8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "INY", { INV, 0xc8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "JMP", { INV, INV, INV, INV, INV, INV, INV, 0x4c, INV, INV, 0x6c, INV, INV, INV, 0x7c, INV }},
{ "JSR", { INV, INV, INV, INV, INV, INV, INV, 0x20, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "LDA", { INV, INV, 0xa9, INV, 0xa5, 0xb5, INV, 0xad, 0xbd, 0xb9, INV, 0xa1, 0xb1, 0xb2, INV, INV }},
{ "LDX", { INV, INV, 0xa2, INV, 0xa6, INV, 0xb6, 0xae, INV, 0xbe, INV, INV, INV, INV, INV, INV }},
{ "LDY", { INV, INV, 0xa0, INV, 0xa4, 0xb4, INV, 0xac, 0xbc, INV, INV, INV, INV, INV, INV, INV }},
{ "LSR", { 0x4a, INV, INV, INV, 0x46, 0x56, INV, 0x4e, 0x5e, INV, INV, INV, INV, INV, INV, INV }},
{ "NOP", { INV, 0xea, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "ORA", { INV, INV, 0x09, INV, 0x05, 0x15, INV, 0x0d, 0x1d, 0x19, INV, 0x01, 0x11, 0x12, INV, INV }},
{ "PHA", { INV, 0x48, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PHP", { INV, 0x08, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PHX", { INV, 0xda, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PHY", { INV, 0x5a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLA", { INV, 0x68, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLP", { INV, 0x28, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLX", { INV, 0xfa, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "PLY", { INV, 0x7a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB0", { INV, INV, INV, INV, 0x07, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB1", { INV, INV, INV, INV, 0x17, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB2", { INV, INV, INV, INV, 0x27, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB3", { INV, INV, INV, INV, 0x37, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB4", { INV, INV, INV, INV, 0x47, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB5", { INV, INV, INV, INV, 0x57, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB6", { INV, INV, INV, INV, 0x67, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RMB7", { INV, INV, INV, INV, 0x77, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "ROL", { 0x2a, INV, INV, INV, 0x26, 0x36, INV, 0x2e, 0x3e, INV, INV, INV, INV, INV, INV, INV }},
{ "ROR", { 0x6a, INV, INV, INV, 0x66, 0x76, INV, 0x6e, 0x7e, INV, INV, INV, INV, INV, INV, INV }},
{ "RTI", { INV, 0x40, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "RTS", { INV, 0x60, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SBC", { INV, INV, 0xe9, INV, 0xe5, 0xf5, INV, 0xed, 0xfd, 0xf9, INV, 0xe1, 0xf1, 0xf2, INV, INV }},
{ "SEC", { INV, 0x38, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SED", { INV, 0xf8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SEI", { INV, 0x78, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB0", { INV, INV, INV, INV, 0x87, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB1", { INV, INV, INV, INV, 0x97, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB2", { INV, INV, INV, INV, 0xa7, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB3", { INV, INV, INV, INV, 0xb7, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB4", { INV, INV, INV, INV, 0xc7, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB5", { INV, INV, INV, INV, 0xd7, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB6", { INV, INV, INV, INV, 0xe7, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "SMB7", { INV, INV, INV, INV, 0xf7, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STA", { INV, INV, INV, INV, 0x85, 0x95, INV, 0x8d, 0x9d, 0x99, INV, 0x81, 0x91, 0x92, INV, INV }},
{ "STP", { INV, 0xdb, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STX", { INV, INV, INV, INV, 0x86, INV, 0x96, 0x8e, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STY", { INV, INV, INV, INV, 0x84, 0x94, INV, 0x8c, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "STZ", { INV, INV, INV, INV, 0x64, 0x74, INV, 0x9c, 0x9e, INV, INV, INV, INV, INV, INV, INV }},
{ "TAX", { INV, 0xaa, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TAY", { INV, 0xa8, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TRB", { INV, INV, INV, INV, 0x14, INV, INV, 0x1c, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TSB", { INV, INV, INV, INV, 0x04, INV, INV, 0x0c, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TSX", { INV, 0xba, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TXA", { INV, 0x8a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TXS", { INV, 0x9a, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "TYA", { INV, 0x98, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }},
{ "WAI", { INV, 0xcb, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV }}
};

85
tests/wdc65c02.a65 Normal file
View File

@@ -0,0 +1,85 @@
; additional instructions provided by the WDC65C02
; for the other instructions see MOS6502.A65
.cpu 65c02
adc ($11)
and ($11)
bbr0 $47,@
bbr1 $47,@
bbr2 $47,@
bbr3 $47,@
bbr4 $47,@
bbr5 $47,@
bbr6 $47,@
bbr7 $47,@
bbs0 $47,@
bbs1 $47,@
bbs2 $47,@
bbs3 $47,@
bbs4 $47,@
bbs5 $47,@
bbs6 $47,@
bbs7 $47,@
bit $11,x
bit $4711,x
bit #42
bra @
cmp ($11)
dec
eor ($11)
jmp ($4711, X)
lda ($11)
ora ($11)
phx
phy
plx
ply
rmb0 $47
rmb1 $47
rmb2 $47
rmb3 $47
rmb4 $47
rmb5 $47
rmb6 $47
rmb7 $47
sbc ($11)
smb0 $47
smb1 $47
smb2 $47
smb3 $47
smb4 $47
smb5 $47
smb6 $47
smb7 $47
sta ($11)
stp
stz $11
stz $11,x
stz $4711
stz $4711,x
trb $11
trb $4711
tsb $11
tsb $4711
wai