started suuport for MEGA65 cpu (not finished yet)

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@184 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-05-21 19:36:59 +00:00
parent c1d8f90fae
commit 8eddb4f4bc
4 changed files with 118 additions and 54 deletions

View File

@ -60,6 +60,11 @@ static struct cpu_type cpu_type_4502 = {
CPUFLAG_DECIMALSUBTRACTBUGGY, // SBC does not work reliably in decimal mode
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_m65 = {
keyword_is_m65_mnemo,
CPUFLAG_DECIMALSUBTRACTBUGGY, // SBC does not work reliably in decimal mode FIXME - is this correct? has this been fixed?
234 // !align fills with "NOP"
};
// variables
@ -67,7 +72,7 @@ static struct cpu_type cpu_type_4502 = {
// predefined stuff
static struct ronode *cputype_tree = NULL;
static struct ronode cputype_list[] = {
#define KNOWN_TYPES "'6502', '6510', '65c02', 'r65c02', 'w65c02', '65816', '65ce02', '4502', 'c64dtv2'" // shown in CLI error message for unknown types
#define KNOWN_TYPES "'6502', '6510', '65c02', 'r65c02', 'w65c02', '65816', '65ce02', '4502', 'm65', 'c64dtv2'" // shown in CLI error message for unknown types
// PREDEFNODE("z80", &cpu_type_Z80),
PREDEFNODE("6502", &cpu_type_6502),
PREDEFNODE("6510", &cpu_type_6510),
@ -77,6 +82,7 @@ static struct ronode cputype_list[] = {
PREDEFNODE("65816", &cpu_type_65816),
PREDEFNODE("65ce02", &cpu_type_65ce02),
PREDEFNODE("4502", &cpu_type_4502),
PREDEFNODE("m65", &cpu_type_m65),
PREDEFLAST("c64dtv2", &cpu_type_c64dtv2),
// ^^^^ this marks the last element
};

View File

@ -25,7 +25,7 @@
#define INDEX_S 1 // stack-indexed (",s" or ",sp"), for 65816 and 65ce02
#define INDEX_X 2 // x-indexed (",x")
#define INDEX_Y 3 // y-indexed (",y")
#define INDEX_Z 4 // z-indexed (",z"), only for 65ce02
#define INDEX_Z 4 // z-indexed (",z"), only for 65ce02/4502/m65
// 5..7 are left for future expansion, 8 would need the AMB_INDEX macro below to be adjusted!
// adress mode bits:
#define AMB_IMPLIED (1u << 0) // no value given
@ -44,14 +44,16 @@
#define INDIRECT_ADDRESSING AMB_INDIRECT
#define X_INDEXED_INDIRECT_ADDRESSING (AMB_PREINDEX(INDEX_X) | AMB_INDIRECT)
#define INDIRECT_Y_INDEXED_ADDRESSING (AMB_INDIRECT | AMB_INDEX(INDEX_Y))
// only for 65ce02:
// only for 65ce02/4502/m65:
#define INDIRECT_Z_INDEXED_ADDRESSING (AMB_INDIRECT | AMB_INDEX(INDEX_Z))
// for 65816 and 65ce02:
// for 65816 and 65ce02/4502:
#define STACK_INDEXED_INDIRECT_Y_INDEXED_ADDRESSING (AMB_PREINDEX(INDEX_S) | AMB_INDIRECT | AMB_INDEX(INDEX_Y))
// only for 65816:
#define STACK_INDEXED_ADDRESSING AMB_INDEX(INDEX_S)
#define LONG_INDIRECT_ADDRESSING AMB_LONGINDIRECT
#define LONG_INDIRECT_Y_INDEXED_ADDRESSING (AMB_LONGINDIRECT | AMB_INDEX(INDEX_Y))
// only for m65:
#define LONG_INDIRECT_Z_INDEXED_ADDRESSING (AMB_LONGINDIRECT | AMB_INDEX(INDEX_Z))
// Constant values, used to mark the possible parameter lengths of commands.
// Not all of the eight possible combinations are actually used, however (because of the supported CPUs).
@ -71,7 +73,7 @@ enum mnemogroup {
GROUP_REL16_2, // 16bit relative to pc+2 Byte value = opcode
GROUP_REL16_3, // 16bit relative to pc+3 Byte value = opcode
GROUP_BOTHMOVES, // the "move" commands MVP and MVN Byte value = opcode
GROUP_ZPONLY // rmb0..7 and smb0..7 Byte value = opcode FIXME - use for IDX816COP,IDXeDEW,IDXeINW as well!
GROUP_ZPONLY // rmb0..7 and smb0..7 Byte value = opcode FIXME - use for IDX16COP,IDXeDEW,IDXeINW as well!
};
// save some space
@ -85,20 +87,21 @@ enum mnemogroup {
// column to use here. The row depends on the used addressing mode. A zero
// entry in these tables means that the combination of mnemonic and addressing
// mode is illegal.
// | 6502/65c02/65816/65ce02 | 65816 | 6510 illegals |
enum { IDX_ORA,IDXcORA,IDX816ORA,IDXeORA,IDX_AND,IDXcAND,IDX816AND,IDXeAND,IDX_EOR,IDXcEOR,IDX816EOR,IDXeEOR,IDX_ADC,IDXcADC,IDX816ADC,IDXeADC,IDX_STA,IDXcSTA,IDX816STA,IDXeSTA,IDX_LDA,IDXcLDA,IDX816LDA,IDXeLDA,IDX_CMP,IDXcCMP,IDX816CMP,IDXeCMP,IDX_SBC,IDXcSBC,IDX816SBC,IDXeSBC,IDX816PEI,IDX_SLO,IDX_RLA,IDX_SRE,IDX_RRA,IDX_SAX,IDX_LAX,IDX_DCP,IDX_ISC,IDX_SHA};
SCB accu_imm[] = { 0x09, 0x09, 0x09, 0x09, 0x29, 0x29, 0x29, 0x29, 0x49, 0x49, 0x49, 0x49, 0x69, 0x69, 0x69, 0x69, 0, 0, 0, 0, 0xa9, 0xa9, 0xa9, 0xa9, 0xc9, 0xc9, 0xc9, 0xc9, 0xe9, 0xe9, 0xe9, 0xe9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // #$ff #$ffff
SCL accu_abs[] = { 0x0d05, 0x0d05, 0x0f0d05, 0x0d05, 0x2d25, 0x2d25, 0x2f2d25, 0x2d25, 0x4d45, 0x4d45, 0x4f4d45, 0x4d45, 0x6d65, 0x6d65, 0x6f6d65, 0x6d65, 0x8d85, 0x8d85, 0x8f8d85, 0x8d85, 0xada5, 0xada5, 0xafada5, 0xada5, 0xcdc5, 0xcdc5, 0xcfcdc5, 0xcdc5, 0xede5, 0xede5, 0xefede5, 0xede5, 0, 0x0f07, 0x2f27, 0x4f47, 0x6f67, 0x8f87, 0xafa7, 0xcfc7, 0xefe7, 0}; // $ff $ffff $ffffff
SCL accu_xabs[] = { 0x1d15, 0x1d15, 0x1f1d15, 0x1d15, 0x3d35, 0x3d35, 0x3f3d35, 0x3d35, 0x5d55, 0x5d55, 0x5f5d55, 0x5d55, 0x7d75, 0x7d75, 0x7f7d75, 0x7d75, 0x9d95, 0x9d95, 0x9f9d95, 0x9d95, 0xbdb5, 0xbdb5, 0xbfbdb5, 0xbdb5, 0xddd5, 0xddd5, 0xdfddd5, 0xddd5, 0xfdf5, 0xfdf5, 0xfffdf5, 0xfdf5, 0, 0x1f17, 0x3f37, 0x5f57, 0x7f77, 0, 0, 0xdfd7, 0xfff7, 0}; // $ff,x $ffff,x $ffffff,x
SCS accu_yabs[] = { 0x1900, 0x1900, 0x1900, 0x1900, 0x3900, 0x3900, 0x3900, 0x3900, 0x5900, 0x5900, 0x5900, 0x5900, 0x7900, 0x7900, 0x7900, 0x7900, 0x9900, 0x9900, 0x9900, 0x9900, 0xb900, 0xb900, 0xb900, 0xb900, 0xd900, 0xd900, 0xd900, 0xd900, 0xf900, 0xf900, 0xf900, 0xf900, 0, 0x1b00, 0x3b00, 0x5b00, 0x7b00, 0x97, 0xbfb7, 0xdb00, 0xfb00, 0x9f00}; // $ff,y $ffff,y
SCB accu_xind8[] = { 0x01, 0x01, 0x01, 0x01, 0x21, 0x21, 0x21, 0x21, 0x41, 0x41, 0x41, 0x41, 0x61, 0x61, 0x61, 0x61, 0x81, 0x81, 0x81, 0x81, 0xa1, 0xa1, 0xa1, 0xa1, 0xc1, 0xc1, 0xc1, 0xc1, 0xe1, 0xe1, 0xe1, 0xe1, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3, 0}; // ($ff,x)
SCB accu_indy8[] = { 0x11, 0x11, 0x11, 0x11, 0x31, 0x31, 0x31, 0x31, 0x51, 0x51, 0x51, 0x51, 0x71, 0x71, 0x71, 0x71, 0x91, 0x91, 0x91, 0x91, 0xb1, 0xb1, 0xb1, 0xb1, 0xd1, 0xd1, 0xd1, 0xd1, 0xf1, 0xf1, 0xf1, 0xf1, 0, 0x13, 0x33, 0x53, 0x73, 0, 0xb3, 0xd3, 0xf3, 0x93}; // ($ff),y
SCB accu_ind8[] = { 0, 0x12, 0x12, 0, 0, 0x32, 0x32, 0, 0, 0x52, 0x52, 0, 0, 0x72, 0x72, 0, 0, 0x92, 0x92, 0, 0, 0xb2, 0xb2, 0, 0, 0xd2, 0xd2, 0, 0, 0xf2, 0xf2, 0, 0xd4, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff)
SCB accu_sabs8[] = { 0, 0, 0x03, 0, 0, 0, 0x23, 0, 0, 0, 0x43, 0, 0, 0, 0x63, 0, 0, 0, 0x83, 0, 0, 0, 0xa3, 0, 0, 0, 0xc3, 0, 0, 0, 0xe3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,s
SCB accu_sindy8[] = { 0, 0, 0x13, 0, 0, 0, 0x33, 0, 0, 0, 0x53, 0, 0, 0, 0x73, 0, 0, 0, 0x93, 0x82, 0, 0, 0xb3, 0xe2, 0, 0, 0xd3, 0, 0, 0, 0xf3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff,s),y
SCB accu_lind8[] = { 0, 0, 0x07, 0, 0, 0, 0x27, 0, 0, 0, 0x47, 0, 0, 0, 0x67, 0, 0, 0, 0x87, 0, 0, 0, 0xa7, 0, 0, 0, 0xc7, 0, 0, 0, 0xe7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff]
SCB accu_lindy8[] = { 0, 0, 0x17, 0, 0, 0, 0x37, 0, 0, 0, 0x57, 0, 0, 0, 0x77, 0, 0, 0, 0x97, 0, 0, 0, 0xb7, 0, 0, 0, 0xd7, 0, 0, 0, 0xf7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff],y
SCB accu_indz8[] = { 0, 0, 0, 0x12, 0, 0, 0, 0x32, 0, 0, 0, 0x52, 0, 0, 0, 0x72, 0, 0, 0, 0x92, 0, 0, 0, 0xb2, 0, 0, 0, 0xd2, 0, 0, 0, 0xf2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff),z
// | 6502/65c02/65816/65ce02/4502/m65 | 65816 | 6510 illegals |
enum { IDX_ORA,IDXcORA,IDX16ORA,IDXeORA,IDXmORA,IDX_AND,IDXcAND,IDX16AND,IDXeAND,IDXmAND,IDX_EOR,IDXcEOR,IDX16EOR,IDXeEOR,IDXmEOR,IDX_ADC,IDXcADC,IDX16ADC,IDXeADC,IDXmADC,IDX_STA,IDXcSTA,IDX16STA,IDXeSTA,IDXmSTA,IDX_LDA,IDXcLDA,IDX16LDA,IDXeLDA,IDXmLDA,IDX_CMP,IDXcCMP,IDX16CMP,IDXeCMP,IDXmCMP,IDX_SBC,IDXcSBC,IDX16SBC,IDXeSBC,IDXmSBC,IDX16PEI,IDX_SLO,IDX_RLA,IDX_SRE,IDX_RRA,IDX_SAX,IDX_LAX,IDX_DCP,IDX_ISC,IDX_SHA};
SCB accu_imm[] = { 0x09, 0x09, 0x09, 0x09, 0x09, 0x29, 0x29, 0x29, 0x29, 0x29, 0x49, 0x49, 0x49, 0x49, 0x49, 0x69, 0x69, 0x69, 0x69, 0x69, 0, 0, 0, 0, 0, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // #$ff #$ffff
SCL accu_abs[] = { 0x0d05, 0x0d05,0x0f0d05, 0x0d05, 0x0d05, 0x2d25, 0x2d25,0x2f2d25, 0x2d25, 0x2d25, 0x4d45, 0x4d45,0x4f4d45, 0x4d45, 0x4d45, 0x6d65, 0x6d65,0x6f6d65, 0x6d65, 0x6d65, 0x8d85, 0x8d85,0x8f8d85, 0x8d85, 0x8d85, 0xada5, 0xada5,0xafada5, 0xada5, 0xada5, 0xcdc5, 0xcdc5,0xcfcdc5, 0xcdc5, 0xcdc5, 0xede5, 0xede5,0xefede5, 0xede5, 0xede5, 0, 0x0f07, 0x2f27, 0x4f47, 0x6f67, 0x8f87, 0xafa7, 0xcfc7, 0xefe7, 0}; // $ff $ffff $ffffff
SCL accu_xabs[] = { 0x1d15, 0x1d15,0x1f1d15, 0x1d15, 0x1d15, 0x3d35, 0x3d35,0x3f3d35, 0x3d35, 0x3d35, 0x5d55, 0x5d55,0x5f5d55, 0x5d55, 0x5d55, 0x7d75, 0x7d75,0x7f7d75, 0x7d75, 0x7d75, 0x9d95, 0x9d95,0x9f9d95, 0x9d95, 0x9d95, 0xbdb5, 0xbdb5,0xbfbdb5, 0xbdb5, 0xbdb5, 0xddd5, 0xddd5,0xdfddd5, 0xddd5, 0xddd5, 0xfdf5, 0xfdf5,0xfffdf5, 0xfdf5, 0xfdf5, 0, 0x1f17, 0x3f37, 0x5f57, 0x7f77, 0, 0, 0xdfd7, 0xfff7, 0}; // $ff,x $ffff,x $ffffff,x
SCS accu_yabs[] = { 0x1900, 0x1900, 0x1900, 0x1900, 0x1900, 0x3900, 0x3900, 0x3900, 0x3900, 0x3900, 0x5900, 0x5900, 0x5900, 0x5900, 0x5900, 0x7900, 0x7900, 0x7900, 0x7900, 0x7900, 0x9900, 0x9900, 0x9900, 0x9900, 0x9900, 0xb900, 0xb900, 0xb900, 0xb900, 0xb900, 0xd900, 0xd900, 0xd900, 0xd900, 0xd900, 0xf900, 0xf900, 0xf900, 0xf900, 0xf900, 0, 0x1b00, 0x3b00, 0x5b00, 0x7b00, 0x97, 0xbfb7, 0xdb00, 0xfb00, 0x9f00}; // $ff,y $ffff,y
SCB accu_xind8[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x21, 0x21, 0x21, 0x21, 0x21, 0x41, 0x41, 0x41, 0x41, 0x41, 0x61, 0x61, 0x61, 0x61, 0x61, 0x81, 0x81, 0x81, 0x81, 0x81, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3, 0}; // ($ff,x)
SCB accu_indy8[] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x31, 0x31, 0x31, 0x31, 0x31, 0x51, 0x51, 0x51, 0x51, 0x51, 0x71, 0x71, 0x71, 0x71, 0x71, 0x91, 0x91, 0x91, 0x91, 0x91, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0, 0x13, 0x33, 0x53, 0x73, 0, 0xb3, 0xd3, 0xf3, 0x93}; // ($ff),y
SCB accu_ind8[] = { 0, 0x12, 0x12, 0, 0, 0, 0x32, 0x32, 0, 0, 0, 0x52, 0x52, 0, 0, 0, 0x72, 0x72, 0, 0, 0, 0x92, 0x92, 0, 0, 0, 0xb2, 0xb2, 0, 0, 0, 0xd2, 0xd2, 0, 0, 0, 0xf2, 0xf2, 0, 0, 0xd4, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff)
SCB accu_sabs8[] = { 0, 0, 0x03, 0, 0, 0, 0, 0x23, 0, 0, 0, 0, 0x43, 0, 0, 0, 0, 0x63, 0, 0, 0, 0, 0x83, 0, 0, 0, 0, 0xa3, 0, 0, 0, 0, 0xc3, 0, 0, 0, 0, 0xe3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,s
SCB accu_sindy8[] = { 0, 0, 0x13, 0, 0, 0, 0, 0x33, 0, 0, 0, 0, 0x53, 0, 0, 0, 0, 0x73, 0, 0, 0, 0, 0x93, 0x82, 0x82, 0, 0, 0xb3, 0xe2, 0xe2, 0, 0, 0xd3, 0, 0, 0, 0, 0xf3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff,s),y
SCB accu_lind8[] = { 0, 0, 0x07, 0, 0, 0, 0, 0x27, 0, 0, 0, 0, 0x47, 0, 0, 0, 0, 0x67, 0, 0, 0, 0, 0x87, 0, 0, 0, 0, 0xa7, 0, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0xe7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff]
SCB accu_lindy8[] = { 0, 0, 0x17, 0, 0, 0, 0, 0x37, 0, 0, 0, 0, 0x57, 0, 0, 0, 0, 0x77, 0, 0, 0, 0, 0x97, 0, 0, 0, 0, 0xb7, 0, 0, 0, 0, 0xd7, 0, 0, 0, 0, 0xf7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff],y
SCB accu_indz8[] = { 0, 0, 0, 0x12, 0x12, 0, 0, 0, 0x32, 0x32, 0, 0, 0, 0x52, 0x52, 0, 0, 0, 0x72, 0x72, 0, 0, 0, 0x92, 0x92, 0, 0, 0, 0xb2, 0xb2, 0, 0, 0, 0xd2, 0xd2, 0, 0, 0, 0xf2, 0xf2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ($ff),z
SCB accu_lindz8[] = { 0, 0, 0, 0, 0x12, 0, 0, 0, 0, 0x32, 0, 0, 0, 0, 0x52, 0, 0, 0, 0, 0x72, 0, 0, 0, 0, 0x92, 0, 0, 0, 0, 0xb2, 0, 0, 0, 0, 0xd2, 0, 0, 0, 0, 0xf2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [$ff],z (encoded as a NOP plus ($ff),z)
// Code tables for group GROUP_MISC:
// These tables are needed for finding out the correct code in cases when
@ -106,13 +109,13 @@ SCB accu_indz8[] = { 0, 0, 0, 0x12, 0, 0, 0
// mnemotable), the assembler finds out the column to use here. The row
// depends on the used addressing mode. A zero entry in these tables means
// that the combination of mnemonic and addressing mode is illegal.
// | 6502 | 6502/65c02/65ce02 | 65c02 | 65ce02 | 65816 | 6510 illegals | C64DTV2 |
enum { IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_BIT,IDXcBIT,IDX_STX,IDXeSTX,IDX_STY,IDXeSTY,IDX_DEC,IDXcDEC,IDX_INC,IDXcINC,IDXcTSB,IDXcTRB,IDXcSTZ,IDXeASR,IDXeASW,IDXeCPZ,IDXeDEW,IDXeINW,IDXeLDZ,IDXePHW,IDXeROW,IDXeRTN,IDX816COP,IDX816REP,IDX816SEP,IDX816PEA,IDX_ANC,IDX_ASR,IDX_ARR,IDX_SBX,IDX_DOP,IDX_TOP,IDX_JAM,IDX_LXA,IDX_ANE,IDX_LAS,IDX_TAS,IDX_SHX,IDX_SHY,IDX_SAC,IDX_SIR};
SCB misc_impl[] = { 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0, 0x1a, 0, 0, 0, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0, 0, 0, 0, 0, 0, 0, 0}; // implied/accu
SCB misc_imm[] = { 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc2, 0, 0, 0xa3, 0xf4, 0, 0x62, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab, 0x8b, 0, 0, 0, 0, 0x32, 0x42}; // #$ff #$ffff
SCS misc_abs[] = { 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0x2c24, 0x2c24, 0x8e86, 0x8e86, 0x8c84, 0x8c84, 0xcec6, 0xcec6, 0xeee6, 0xeee6, 0x0c04, 0x1c14, 0x9c64, 0x44, 0xcb00, 0xdcd4, 0xc3, 0xe3, 0xab00, 0xfc00, 0xeb00, 0, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff $ffff
SCS misc_xabs[] = { 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0xbcb4, 0, 0, 0, 0, 0x3c34, 0, 0, 0x94, 0x8b94, 0xded6, 0xded6, 0xfef6, 0xfef6, 0, 0, 0x9e74, 0x54, 0, 0, 0, 0, 0xbb00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0, 0, 0, 0, 0, 0x9c00, 0, 0}; // $ff,x $ffff,x
SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0xbeb6, 0, 0, 0, 0, 0x96, 0x9b96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xbb00, 0x9b00, 0x9e00, 0, 0, 0}; // $ff,y $ffff,y
// | 6502 | 6502/65c02/65ce02 | 65c02 | 65ce02 | 65816 | 6510 illegals | C64DTV2 |
enum { IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_BIT,IDXcBIT,IDX_STX,IDXeSTX,IDX_STY,IDXeSTY,IDX_DEC,IDXcDEC,IDX_INC,IDXcINC,IDXcTSB,IDXcTRB,IDXcSTZ,IDXeASR,IDXeASW,IDXeCPZ,IDXeDEW,IDXeINW,IDXeLDZ,IDXePHW,IDXeROW,IDXeRTN,IDX16COP,IDX16REP,IDX16SEP,IDX16PEA,IDX_ANC,IDX_ASR,IDX_ARR,IDX_SBX,IDX_DOP,IDX_TOP,IDX_JAM,IDX_LXA,IDX_ANE,IDX_LAS,IDX_TAS,IDX_SHX,IDX_SHY,IDX_SAC,IDX_SIR};
SCB misc_impl[] = { 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0, 0x1a, 0, 0, 0, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0, 0, 0, 0, 0, 0, 0, 0}; // implied/accu
SCB misc_imm[] = { 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc2, 0, 0, 0xa3, 0xf4, 0, 0x62, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab, 0x8b, 0, 0, 0, 0, 0x32, 0x42}; // #$ff #$ffff
SCS misc_abs[] = { 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0x2c24, 0x2c24, 0x8e86, 0x8e86, 0x8c84, 0x8c84, 0xcec6, 0xcec6, 0xeee6, 0xeee6, 0x0c04, 0x1c14, 0x9c64, 0x44, 0xcb00, 0xdcd4, 0xc3, 0xe3, 0xab00, 0xfc00, 0xeb00, 0, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff $ffff
SCS misc_xabs[] = { 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0xbcb4, 0, 0, 0, 0, 0x3c34, 0, 0, 0x94, 0x8b94, 0xded6, 0xded6, 0xfef6, 0xfef6, 0, 0, 0x9e74, 0x54, 0, 0, 0, 0, 0xbb00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0, 0, 0, 0, 0, 0x9c00, 0, 0}; // $ff,x $ffff,x
SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0xbeb6, 0, 0, 0, 0, 0x96, 0x9b96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xbb00, 0x9b00, 0x9e00, 0, 0, 0}; // $ff,y $ffff,y
// Code tables for group GROUP_ALLJUMPS:
// These tables are needed for finding out the correct code when the mnemonic
@ -121,12 +124,12 @@ SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0xbeb6, 0,
// finds out the column to use here. The row depends on the used addressing
// mode. A zero entry in these tables means that the combination of mnemonic
// and addressing mode is illegal.
// | 6502/65c02/65816/65ce02 | 65816 |
enum { IDX_JMP,IDXcJMP,IDX816JMP,IDX_JSR,IDXeJSR,IDX816JSR,IDX816JML,IDX816JSL};
SCL jump_abs[] = { 0x4c00, 0x4c00, 0x5c4c00, 0x2000, 0x2000, 0x222000, 0x5c0000, 0x220000}; // $ffff $ffffff
SCS jump_ind[] = { 0x6c00, 0x6c00, 0x6c00, 0, 0x2200, 0, 0, 0}; // ($ffff)
SCS jump_xind[] = { 0, 0x7c00, 0x7c00, 0, 0x2300, 0xfc00, 0, 0}; // ($ffff,x)
SCS jump_lind[] = { 0, 0, 0xdc00, 0, 0, 0, 0xdc00, 0}; // [$ffff]
// | 6502/65c02/65816/65ce02 | 65816 |
enum { IDX_JMP,IDXcJMP,IDX16JMP,IDX_JSR,IDXeJSR,IDX16JSR,IDX16JML,IDX16JSL};
SCL jump_abs[] = { 0x4c00, 0x4c00,0x5c4c00, 0x2000, 0x2000,0x222000,0x5c0000,0x220000}; // $ffff $ffffff
SCS jump_ind[] = { 0x6c00, 0x6c00, 0x6c00, 0, 0x2200, 0, 0, 0}; // ($ffff)
SCS jump_xind[] = { 0, 0x7c00, 0x7c00, 0, 0x2300, 0xfc00, 0, 0}; // ($ffff,x)
SCS jump_lind[] = { 0, 0, 0xdc00, 0, 0, 0, 0xdc00, 0}; // [$ffff]
#undef SCB
#undef SCS
@ -152,6 +155,7 @@ static struct ronode *mnemo_65816_tree = NULL; // WDC 65816 extensions
static struct ronode *mnemo_65ce02_tree = NULL; // CSG 65ce02/4502 extensions
static struct ronode *mnemo_aug_tree = NULL; // CSG 65ce02's "aug" instruction
static struct ronode *mnemo_map_eom_tree = NULL; // CSG 4502's "map" and "eom" instructions
static struct ronode *mnemo_m65_tree = NULL; // MEGA65 extensions
// Command's code and group values are stored together in a single integer.
// To extract the code, use "& CODEMASK".
@ -347,28 +351,28 @@ static struct ronode mnemos_65816[] = {
PREDEFNODE("cpx", MERGE(GROUP_MISC, IDX_CPX | IM_INDEXREGS)),
PREDEFNODE("bit", MERGE(GROUP_MISC, IDXcBIT | IM_ACCUMULATOR)),
// more addressing modes for some mnemonics:
PREDEFNODE("ora", MERGE(GROUP_ACCU, IDX816ORA | IM_ACCUMULATOR)),
PREDEFNODE(s_and, MERGE(GROUP_ACCU, IDX816AND | IM_ACCUMULATOR)),
PREDEFNODE(s_eor, MERGE(GROUP_ACCU, IDX816EOR | IM_ACCUMULATOR)),
PREDEFNODE("adc", MERGE(GROUP_ACCU, IDX816ADC | IM_ACCUMULATOR)),
PREDEFNODE("sta", MERGE(GROUP_ACCU, IDX816STA)),
PREDEFNODE("lda", MERGE(GROUP_ACCU, IDX816LDA | IM_ACCUMULATOR)),
PREDEFNODE("cmp", MERGE(GROUP_ACCU, IDX816CMP | IM_ACCUMULATOR)),
PREDEFNODE("sbc", MERGE(GROUP_ACCU, IDX816SBC | IM_ACCUMULATOR)),
PREDEFNODE("jmp", MERGE(GROUP_ALLJUMPS, IDX816JMP)),
PREDEFNODE("jsr", MERGE(GROUP_ALLJUMPS, IDX816JSR)),
PREDEFNODE("ora", MERGE(GROUP_ACCU, IDX16ORA | IM_ACCUMULATOR)),
PREDEFNODE(s_and, MERGE(GROUP_ACCU, IDX16AND | IM_ACCUMULATOR)),
PREDEFNODE(s_eor, MERGE(GROUP_ACCU, IDX16EOR | IM_ACCUMULATOR)),
PREDEFNODE("adc", MERGE(GROUP_ACCU, IDX16ADC | IM_ACCUMULATOR)),
PREDEFNODE("sta", MERGE(GROUP_ACCU, IDX16STA)),
PREDEFNODE("lda", MERGE(GROUP_ACCU, IDX16LDA | IM_ACCUMULATOR)),
PREDEFNODE("cmp", MERGE(GROUP_ACCU, IDX16CMP | IM_ACCUMULATOR)),
PREDEFNODE("sbc", MERGE(GROUP_ACCU, IDX16SBC | IM_ACCUMULATOR)),
PREDEFNODE("jmp", MERGE(GROUP_ALLJUMPS, IDX16JMP)),
PREDEFNODE("jsr", MERGE(GROUP_ALLJUMPS, IDX16JSR)),
//
PREDEFNODE("pei", MERGE(GROUP_ACCU, IDX816PEI)),
PREDEFNODE("jml", MERGE(GROUP_ALLJUMPS, IDX816JML)),
PREDEFNODE("jsl", MERGE(GROUP_ALLJUMPS, IDX816JSL)),
PREDEFNODE("pei", MERGE(GROUP_ACCU, IDX16PEI)),
PREDEFNODE("jml", MERGE(GROUP_ALLJUMPS, IDX16JML)),
PREDEFNODE("jsl", MERGE(GROUP_ALLJUMPS, IDX16JSL)),
PREDEFNODE("mvp", MERGE(GROUP_BOTHMOVES, 0x44)),
PREDEFNODE("mvn", MERGE(GROUP_BOTHMOVES, 0x54)),
PREDEFNODE("per", MERGE(GROUP_REL16_3, 98)),
PREDEFNODE(s_brl, MERGE(GROUP_REL16_3, 130)),
PREDEFNODE("cop", MERGE(GROUP_MISC, IDX816COP)),
PREDEFNODE("rep", MERGE(GROUP_MISC, IDX816REP)),
PREDEFNODE("sep", MERGE(GROUP_MISC, IDX816SEP)),
PREDEFNODE("pea", MERGE(GROUP_MISC, IDX816PEA)),
PREDEFNODE("cop", MERGE(GROUP_MISC, IDX16COP)),
PREDEFNODE("rep", MERGE(GROUP_MISC, IDX16REP)),
PREDEFNODE("sep", MERGE(GROUP_MISC, IDX16SEP)),
PREDEFNODE("pea", MERGE(GROUP_MISC, IDX16PEA)),
PREDEFNODE("phd", MERGE(GROUP_IMPLIEDONLY, 11)),
PREDEFNODE("tcs", MERGE(GROUP_IMPLIEDONLY, 27)),
PREDEFNODE("pld", MERGE(GROUP_IMPLIEDONLY, 43)),
@ -454,6 +458,21 @@ static struct ronode mnemos_map_eom[] = {
// ^^^^ this marks the last element
};
// m65 has a few extensions using prefix codes:
static struct ronode mnemos_m65[] = {
// a NOP prefix changes ($ff),z from using 16-bit pointers to using 32-bit pointers:
PREDEFNODE("ora", MERGE(GROUP_ACCU, IDXmORA)),
PREDEFNODE(s_and, MERGE(GROUP_ACCU, IDXmAND)),
PREDEFNODE(s_eor, MERGE(GROUP_ACCU, IDXmEOR)),
PREDEFNODE("adc", MERGE(GROUP_ACCU, IDXmADC)),
PREDEFNODE("sta", MERGE(GROUP_ACCU, IDXmSTA)),
PREDEFNODE("lda", MERGE(GROUP_ACCU, IDXmLDA)),
PREDEFNODE("cmp", MERGE(GROUP_ACCU, IDXmCMP)),
PREDEFLAST("sbc", MERGE(GROUP_ACCU, IDXmSBC)),
// ^^^^ this marks the last element
// TODO - add the "load/store all registers in one go" stuff!
};
// Functions
// create dynamic buffer, build keyword trees
@ -471,6 +490,7 @@ void Mnemo_init(void)
Tree_add_table(&mnemo_65ce02_tree, mnemos_65ce02);
Tree_add_table(&mnemo_aug_tree, mnemos_aug);
Tree_add_table(&mnemo_map_eom_tree, mnemos_map_eom);
Tree_add_table(&mnemo_m65_tree, mnemos_m65);
}
@ -885,19 +905,23 @@ static void group_main(int index, int immediate_mode)
make_command(force_bit, &result, accu_indy8[index]);
check_zp_wraparound(&result);
break;
case INDIRECT_Z_INDEXED_ADDRESSING: // ($ff),z
case INDIRECT_Z_INDEXED_ADDRESSING: // ($ff),z only for 65ce02/4502/m65
make_command(force_bit, &result, accu_indz8[index]);
check_zp_wraparound(&result);
break;
case LONG_INDIRECT_ADDRESSING: // [$ff]
case LONG_INDIRECT_ADDRESSING: // [$ff] only for 65816
make_command(force_bit, &result, accu_lind8[index]);
break;
case LONG_INDIRECT_Y_INDEXED_ADDRESSING: // [$ff],y
case LONG_INDIRECT_Y_INDEXED_ADDRESSING: // [$ff],y only for 65816
make_command(force_bit, &result, accu_lindy8[index]);
break;
case STACK_INDEXED_INDIRECT_Y_INDEXED_ADDRESSING: // ($ff,s),y
case STACK_INDEXED_INDIRECT_Y_INDEXED_ADDRESSING: // ($ff,s),y only for 65816 and 65ce02/4502/m65
make_command(force_bit, &result, accu_sindy8[index]);
break;
case LONG_INDIRECT_Z_INDEXED_ADDRESSING: // [$ff],z only for m65, encoded as NOP + ($ff),z
Output_byte(234);
make_command(force_bit, &result, accu_lindz8[index]);
break;
default: // other combinations are illegal
Throw_error(exception_illegal_combination);
}
@ -1257,6 +1281,38 @@ boolean keyword_is_4502_mnemo(int length)
return check_mnemo_tree(mnemo_map_eom_tree, mnemo_dyna_buf) ? TRUE : FALSE;
}
// check whether mnemonic in GlobalDynaBuf is supported by MEGA65 cpu.
boolean keyword_is_m65_mnemo(int length)
{
if ((length != 3) && (length != 4))
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check m65 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_m65_tree, mnemo_dyna_buf))
return TRUE;
// ...then check 65ce02 extensions because of the same reason...
if (check_mnemo_tree(mnemo_65ce02_tree, mnemo_dyna_buf))
return TRUE;
// ...then check 65c02 extensions because of the same reason...
if (check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf))
return TRUE;
// ...then check original opcodes...
if (check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf))
return TRUE;
// ...then check Rockwell extensions (rmb, smb, bbr, bbs)...
if (check_mnemo_tree(mnemo_bitmanips_tree, mnemo_dyna_buf))
return TRUE;
// ...then check "map" and "eom"
return check_mnemo_tree(mnemo_map_eom_tree, mnemo_dyna_buf) ? TRUE : FALSE;
}
// check whether mnemonic in GlobalDynaBuf is supported by 65816 cpu.
boolean keyword_is_65816_mnemo(int length)
{

View File

@ -30,6 +30,8 @@ extern boolean keyword_is_65816_mnemo(int length);
extern boolean keyword_is_65ce02_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by CSG 4502 cpu.
extern boolean keyword_is_4502_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by MEGA65 cpu.
extern boolean keyword_is_m65_mnemo(int length);
#endif

View File

@ -9,7 +9,7 @@
#define RELEASE "0.96.5" // update before release FIXME
#define CODENAME "Fenchurch" // update before release
#define CHANGE_DATE "20 May" // update before release FIXME
#define CHANGE_DATE "21 May" // update before release FIXME
#define CHANGE_YEAR "2020" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME