mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-01-13 11:29:52 +00:00
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:
parent
c1d8f90fae
commit
8eddb4f4bc
@ -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
|
||||
};
|
||||
|
160
src/mnemo.c
160
src/mnemo.c
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user