aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2016-04-28 14:58:38 +0100
committerIan C <ianc@noddybox.co.uk>2016-04-28 14:58:38 +0100
commit6b970e749e720404d08cec565fe0157d20fdeaef (patch)
treedc80919782dcd3d7da2bca104a85adde996cac94 /src
parent239edccf43ff39e93a96c4c75af9e6772f55efe2 (diff)
First pass of compilable 65c816 mode.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/65c816.c1245
-rw-r--r--src/casm.c7
-rw-r--r--src/test/65c816548
-rw-r--r--src/util.c6
-rw-r--r--src/util.h6
5 files changed, 1285 insertions, 527 deletions
diff --git a/src/65c816.c b/src/65c816.c
index d6473a8..6305dd0 100755
--- a/src/65c816.c
+++ b/src/65c816.c
@@ -85,7 +85,7 @@ typedef enum
RELATIVE_LONG, /* rrrr */
STACK_RELATIVE_INDIRECT_INDEX_Y, /* (sr,S),Y */
STACK_RELATIVE, /* sr,S */
- STACK_IMMEDIATE /* #$nnnn */
+ STACK_IMMEDIATE, /* #$nnnn */
STACK_DIRECT_PAGE_INDIRECT, /* ($nn) */
STACK_PC_LONG, /* #$nnnn */
ADDR_MODE_ERROR,
@@ -119,7 +119,7 @@ static const char *address_mode_name[ADDR_MODE_UNKNOWN+1] =
"Stack Relative",
"Stack Immediate",
"Stack Direct Page Indirect",
- "Stack Program Counter Relative Long:,
+ "Stack Program Counter Relative Long",
"Address Mode Error",
"Address Mode Unknown"
};
@@ -146,11 +146,11 @@ do \
#define CMD_RANGE_ADDR_MODE(mode, dp_mode, norm_mode, long_mode, value) \
do \
{ \
- if (value >= 0 && value <= 0xff) \
+ if (*value >= 0 && *value <= 0xff) \
{ \
*mode = dp_mode; \
} \
- else if (value > 0xffff) \
+ else if (*value > 0xffff) \
{ \
*mode = long_mode; \
} \
@@ -158,11 +158,74 @@ do \
{ \
*mode = norm_mode; \
} \
+ if (*mode == ADDR_MODE_ERROR && IsFinalPass()) \
+ { \
+ snprintf(err, errsize, "%s: value %d out of range of allowable "\
+ "addressing modes", argv[1], *value); \
+ } \
} while (0)
/* ---------------------------------------- PRIVATE FUNCTIONS
*/
+static void PCWrite24(int val)
+{
+ val = ExprConvert(24, val);
+ PCWrite(val);
+ PCWriteWord(val >> 8);
+}
+
+
+static void PCWrite8_16_A(int val)
+{
+ if (option.a16)
+ {
+ PCWriteWord(val);
+ }
+ else
+ {
+ PCWrite(val);
+ }
+}
+
+
+static void PCWrite8_16_XY(int val)
+{
+ if (option.i16)
+ {
+ PCWriteWord(val);
+ }
+ else
+ {
+ PCWrite(val);
+ }
+}
+
+
+static char *HasIndex(const char *str, char *index_char)
+{
+ char *comma;
+
+ comma = strchr(str, ',');
+
+ if (comma)
+ {
+ char *a;
+
+ a = DupStr(str);
+ comma = strchr(a, ',');
+
+ *comma++ = 0;
+ *index_char = *comma;
+
+ return a;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
static void CalcAddressMode(int argc, char *argv[], int quoted[],
char *err, size_t errsize,
address_mode_t *mode, int *address)
@@ -170,7 +233,7 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
*mode = ADDR_MODE_UNKNOWN;
*address = 0;
- /* Implied
+ /* Handle: IMPLIED
*/
if (argc == 1)
{
@@ -178,7 +241,7 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
return;
}
- /* Accumulator
+ /* Handle: ACCUMULATOR
*/
if (argc == 2 && CompareString(argv[1], "A"))
{
@@ -186,7 +249,9 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
return;
}
- /* Immediate
+ /* Handle: IMMEDIATE
+ Handle: STACK_IMMEDIATE
+ Handle: STACK_PC_LONG
*/
if (argc == 2 && argv[1][0] == '#')
{
@@ -203,7 +268,9 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
}
- /* Absolute
+ /* Handle: ABSOLUTE
+ Handle: ABSOLUTE_LONG
+ Handle: DIRECT_PAGE
*/
if (argc == 2 && !quoted[1])
{
@@ -225,21 +292,58 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
}
- /* Absolute Indirect
+ /* Handle: ABSOLUTE_INDIRECT
+ Handle: DIRECT_PAGE_INDIRECT
+ Handle: STACK_DIRECT_PAGE_INDIRECT
+ Handle: ABSOLUTE_INDEX_X_INDIRECT
+ Handle: DIRECT_PAGE_INDEX_X_INDIRECT
*/
- if (argc == 1 && quoted[1] == '(')
+ if (argc == 2 && quoted[1] == '(')
{
- if (!ExprEval(argv[1], address))
+ char *new;
+ char index;
+
+ if (!(new = HasIndex(argv[1], &index)))
+ {
+ if (!ExprEval(argv[1], address))
+ {
+ snprintf(err, errsize, "%s: expression error: %s",
+ argv[1], ExprError());
+ *mode = ADDR_MODE_ERROR;
+ return;
+ }
+
+ CMD_RANGE_ADDR_MODE(mode,
+ DIRECT_PAGE_INDIRECT,
+ ABSOLUTE_INDIRECT,
+ ADDR_MODE_ERROR,
+ address);
+
+ return;
+ }
+
+ if (!CompareChar(index, 'x'))
+ {
+ snprintf(err, errsize, "illegal index register '%s'", argv[1]);
+ *mode = ADDR_MODE_ERROR;
+ free(new);
+ return;
+ }
+
+ if (!ExprEval(new, address))
{
snprintf(err, errsize, "%s: expression error: %s",
- argv[1], ExprError());
+ new, ExprError());
*mode = ADDR_MODE_ERROR;
+ free(new);
return;
}
+ free(new);
+
CMD_RANGE_ADDR_MODE(mode,
- DIRECT_PAGE_INDIRECT,
- ABSOLUTE_INDIRECT,
+ DIRECT_PAGE_INDEX_X_INDIRECT,
+ ABSOLUTE_INDEX_X_INDIRECT,
ADDR_MODE_ERROR,
address);
@@ -247,9 +351,10 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
}
- /* Absolute Indirect Long
+ /* Handle: ABSOLUTE_INDIRECT_LONG
+ Handle: DIRECT_PAGE_INDIRECT_LONG
*/
- if (argc == 1 && quoted[1] == '[')
+ if (argc == 2 && quoted[1] == '[')
{
if (!ExprEval(argv[1], address))
{
@@ -269,7 +374,12 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
}
- /* Absolute,[XY]
+ /* Handle: DIRECT_PAGE_INDEX_X
+ Handle: ABSOLUTE_INDEX_X
+ Handle: ABSOLUTE_LONG_INDEX_X
+ Handle: DIRECT_PAGE_INDEX_Y
+ Handle: ABSOLUTE_INDEX_Y
+ Handle: STACK_RELATIVE
*/
if (argc == 3 && !quoted[1])
{
@@ -292,11 +402,15 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
else if (CompareString(argv[2], "Y"))
{
CMD_RANGE_ADDR_MODE(mode,
- DIRECT_PAGE_INDEX_X,
- ABSOLUTE_INDEX_X,
- ABSOLUTE_LONG_INDEX_X,
+ DIRECT_PAGE_INDEX_Y,
+ ABSOLUTE_INDEX_Y,
+ ADDR_MODE_ERROR,
address);
}
+ else if (CompareString(argv[2], "S"))
+ {
+ *mode = STACK_RELATIVE;
+ }
else
{
snprintf(err, errsize, "unknown index register '%s'", argv[2]);
@@ -308,80 +422,82 @@ static void CalcAddressMode(int argc, char *argv[], int quoted[],
}
- /* (zp,x) or (ind)
+ /* Handle: DIRECT_PAGE_INDEX_Y_INDIRECT
+ Handle: DIRECT_PAGE_INDEX_Y_INDIRECT_LONG
+ Handle: STACK_RELATIVE_INDIRECT_INDEX_Y
*/
- if (argc == 2 && quoted[1] == '(')
+ if (argc == 3 && (quoted[1] == '(' || quoted[1] == '['))
{
- char *addr;
-
- if (!CompareEnd(argv[1], ",x"))
- {
- if (!ExprEval(argv[1], address))
- {
- snprintf(err, errsize, "%s: expression error: %s",
- argv[1], ExprError());
- *mode = ADDR_MODE_ERROR;
- return;
- }
-
- *mode = INDIRECT;
- return;
- }
-
- *mode = ZERO_PAGE_INDIRECT_X;
-
- addr = DupStr(argv[1]);
- *strchr(addr, ',') = 0;
-
- if (!ExprEval(addr, address))
+ if (!CompareString(argv[2], "y"))
{
- snprintf(err, errsize, "%s: expression error: %s",
- addr, ExprError());
+ snprintf(err, errsize, "illegal index register '%s' used for "
+ "addressing mode", argv[2]);
*mode = ADDR_MODE_ERROR;
- free(addr);
return;
}
- free(addr);
-
- if (*address < 0 || *address > 255)
+ if (quoted[1] == '(')
{
- snprintf(err, errsize, "value %d outside of zero page", *address);
- *mode = ADDR_MODE_ERROR;
- return;
- }
+ char index;
+ char *new;
- return;
- }
+ if (!(new = HasIndex(argv[1], &index)))
+ {
+ if (!ExprEval(argv[1], address))
+ {
+ snprintf(err, errsize, "%s: expression error: %s",
+ argv[1], ExprError());
+ *mode = ADDR_MODE_ERROR;
+ return;
+ }
+
+ CMD_RANGE_ADDR_MODE(mode,
+ DIRECT_PAGE_INDEX_Y_INDIRECT,
+ ADDR_MODE_ERROR,
+ ADDR_MODE_ERROR,
+ address);
+ return;
+ }
- /* (zp),y
- */
- if (argc == 3 && quoted[1] == '(')
- {
- *mode = ZERO_PAGE_INDIRECT_Y;
+ if (!CompareChar(index, 's'))
+ {
+ snprintf(err, errsize, "illegal index register '%c'", index);
+ *mode = ADDR_MODE_ERROR;
+ free(new);
+ return;
+ }
- if (!CompareString(argv[2], "y"))
- {
- snprintf(err, errsize, "illegal index register '%s' used for "
- "zero-page indirect", argv[2]);
- *mode = ADDR_MODE_ERROR;
- return;
- }
+ if (!ExprEval(new, address))
+ {
+ snprintf(err, errsize, "%s: expression error: %s",
+ new, ExprError());
+ *mode = ADDR_MODE_ERROR;
+ free(new);
+ return;
+ }
- if (!ExprEval(argv[1], address))
- {
- snprintf(err, errsize, "%s: expression error: %s",
- argv[1], ExprError());
- *mode = ADDR_MODE_ERROR;
- return;
+ CMD_RANGE_ADDR_MODE(mode,
+ STACK_RELATIVE_INDIRECT_INDEX_Y,
+ ADDR_MODE_ERROR,
+ ADDR_MODE_ERROR,
+ address);
}
-
- if (*address < 0 || *address > 255)
+ else
{
- snprintf(err, errsize, "value %d outside of zero page", *address);
- *mode = ADDR_MODE_ERROR;
- return;
+ if (!ExprEval(argv[1], address))
+ {
+ snprintf(err, errsize, "%s: expression error: %s",
+ argv[1], ExprError());
+ *mode = ADDR_MODE_ERROR;
+ return;
+ }
+
+ CMD_RANGE_ADDR_MODE(mode,
+ DIRECT_PAGE_INDEX_Y_INDIRECT_LONG,
+ ADDR_MODE_ERROR,
+ ADDR_MODE_ERROR,
+ address);
}
return;
@@ -431,7 +547,7 @@ static CommandStatus MX8_16(const char *label, int argc, char *argv[],
CMD_EXPR(argv[1], asize);
CMD_EXPR(argv[2], isize);
- if ((asize !=8 && asize != 8) || (isize != 8 && isize != 16))
+ if ((asize !=8 && asize != 16) || (isize != 8 && isize != 16))
{
snprintf(err, errsize, "%s: unsupported regsiter sizes %s,%s",
argv[0], argv[1], argv[2]);
@@ -450,67 +566,112 @@ static CommandStatus MX8_16(const char *label, int argc, char *argv[],
return CMD_FAILED;
}
+#define COMMON(base) \
+do { \
+ address_mode_t mode; \
+ int address; \
+ \
+ CMD_ADDRESS_MODE(mode, address); \
+ \
+ switch(mode) \
+ { \
+ case DIRECT_PAGE_INDEX_X_INDIRECT: \
+ PCWrite(base + 0x01); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case STACK_RELATIVE: \
+ PCWrite(base + 0x03); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case DIRECT_PAGE: \
+ PCWrite(base + 0x05); \
+ PCWrite(address); \
+ break; \
+ \
+ case DIRECT_PAGE_INDIRECT_LONG: \
+ PCWrite(base + 0x07); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case IMMEDIATE: \
+ PCWrite(base + 0x09); \
+ PCWrite8_16_A(address); \
+ return CMD_OK; \
+ \
+ case ABSOLUTE: \
+ PCWrite(base + 0x0d); \
+ PCWriteWord(address); \
+ return CMD_OK; \
+ \
+ case ABSOLUTE_LONG: \
+ PCWrite(base + 0x0f); \
+ PCWrite24(address); \
+ return CMD_OK; \
+ \
+ case DIRECT_PAGE_INDEX_Y_INDIRECT: \
+ PCWrite(base + 0x11); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case DIRECT_PAGE_INDIRECT: \
+ PCWrite(base + 0x12); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case STACK_RELATIVE_INDIRECT_INDEX_Y: \
+ PCWrite(base + 0x13); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case DIRECT_PAGE_INDEX_X: \
+ PCWrite(base + 0x15); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case DIRECT_PAGE_INDEX_Y_INDIRECT_LONG: \
+ PCWrite(base + 0x17); \
+ PCWrite(address); \
+ return CMD_OK; \
+ \
+ case ABSOLUTE_INDEX_Y: \
+ PCWrite(base + 0x19); \
+ PCWriteWord(address); \
+ return CMD_OK; \
+ \
+ case ABSOLUTE_INDEX_X: \
+ PCWrite(base + 0x1d); \
+ PCWriteWord(address); \
+ return CMD_OK; \
+ \
+ case ABSOLUTE_LONG_INDEX_X: \
+ PCWrite(base + 0x1f); \
+ PCWrite24(address); \
+ return CMD_OK; \
+ \
+ default: \
+ snprintf(err, errsize, "%s: unsupported addressing mode %s",\
+ argv[0], address_mode_name[mode]);\
+ return CMD_FAILED; \
+ } \
+} while(0)
+
static CommandStatus ADC(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
- address_mode_t mode;
- int address;
-
- CMD_ADDRESS_MODE(mode, address);
-
- switch(mode)
- {
- case IMMEDIATE:
- PCWrite(0x69);
- PCWrite(address);
- return CMD_OK;
-
- case ABSOLUTE:
- PCWrite(0x6d);
- PCWriteWord(address);
- return CMD_OK;
-
- case ZERO_PAGE:
- PCWrite(0x65);
- PCWrite(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_X:
- PCWrite(0x7d);
- PCWriteWord(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0x79);
- PCWriteWord(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x75);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0x61);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0x71);
- PCWrite(address);
- return CMD_OK;
-
- default:
- snprintf(err, errsize, "%s: unsupported addressing mode %s",
- argv[0], address_mode_name[mode]);
- return CMD_FAILED;
- }
+ COMMON(0x60);
}
static CommandStatus AND(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
+ COMMON(0x20);
+}
+
+static CommandStatus ASL(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
address_mode_t mode;
int address;
@@ -518,47 +679,31 @@ static CommandStatus AND(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMMEDIATE:
- PCWrite(0x29);
+ case DIRECT_PAGE:
+ PCWrite(0x06);
PCWrite(address);
return CMD_OK;
+ case IMPLIED:
+ case ACCUMULATOR:
+ PCWrite(0x0a);
+ return CMD_OK;
+
case ABSOLUTE:
- PCWrite(0x2d);
+ PCWrite(0x0e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x25);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x16);
PCWrite(address);
return CMD_OK;
case ABSOLUTE_INDEX_X:
- PCWrite(0x3d);
- PCWriteWord(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0x39);
+ PCWrite(0x1e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x35);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0x21);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0x31);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -566,7 +711,7 @@ static CommandStatus AND(const char *label, int argc, char *argv[],
}
}
-static CommandStatus ASL(const char *label, int argc, char *argv[],
+static CommandStatus BIT(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -576,29 +721,29 @@ static CommandStatus ASL(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMPLIED:
- case ACCUMULATOR:
- PCWrite(0x0a);
+ case DIRECT_PAGE:
+ PCWrite(0x24);
+ PCWrite(address);
return CMD_OK;
case ABSOLUTE:
- PCWrite(0x0e);
+ PCWrite(0x2c);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x06);
- PCWrite(address);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x34);
+ PCWriteWord(address);
return CMD_OK;
case ABSOLUTE_INDEX_X:
- PCWrite(0x1e);
+ PCWrite(0x3c);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x16);
- PCWrite(address);
+ case IMMEDIATE:
+ PCWrite(0x89);
+ PCWrite8_16_A(address);
return CMD_OK;
default:
@@ -608,7 +753,7 @@ static CommandStatus ASL(const char *label, int argc, char *argv[],
}
}
-static CommandStatus BIT(const char *label, int argc, char *argv[],
+static CommandStatus TRB(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -618,14 +763,14 @@ static CommandStatus BIT(const char *label, int argc, char *argv[],
switch(mode)
{
- case ABSOLUTE:
- PCWrite(0x2c);
- PCWriteWord(address);
+ case DIRECT_PAGE:
+ PCWrite(0x14);
+ PCWrite(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x24);
- PCWrite(address);
+ case ABSOLUTE:
+ PCWrite(0x1c);
+ PCWriteWord(address);
return CMD_OK;
default:
@@ -635,7 +780,7 @@ static CommandStatus BIT(const char *label, int argc, char *argv[],
}
}
-static CommandStatus CMP(const char *label, int argc, char *argv[],
+static CommandStatus TSB(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -645,47 +790,16 @@ static CommandStatus CMP(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMMEDIATE:
- PCWrite(0xc9);
+ case DIRECT_PAGE:
+ PCWrite(0x04);
PCWrite(address);
return CMD_OK;
case ABSOLUTE:
- PCWrite(0xcd);
+ PCWrite(0x0c);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0xc5);
- PCWrite(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_X:
- PCWrite(0xdd);
- PCWriteWord(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0xd9);
- PCWriteWord(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDEX_X:
- PCWrite(0xd5);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0xc1);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0xd1);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -693,6 +807,12 @@ static CommandStatus CMP(const char *label, int argc, char *argv[],
}
}
+static CommandStatus CMP(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ COMMON(0xc0);
+}
+
static CommandStatus CPX(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
@@ -705,7 +825,7 @@ static CommandStatus CPX(const char *label, int argc, char *argv[],
{
case IMMEDIATE:
PCWrite(0xe0);
- PCWrite(address);
+ PCWrite8_16_XY(address);
return CMD_OK;
case ABSOLUTE:
@@ -713,7 +833,7 @@ static CommandStatus CPX(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
+ case DIRECT_PAGE:
PCWrite(0xe4);
PCWrite(address);
return CMD_OK;
@@ -737,7 +857,7 @@ static CommandStatus CPY(const char *label, int argc, char *argv[],
{
case IMMEDIATE:
PCWrite(0xc0);
- PCWrite(address);
+ PCWrite8_16_XY(address);
return CMD_OK;
case ABSOLUTE:
@@ -745,7 +865,7 @@ static CommandStatus CPY(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
+ case DIRECT_PAGE:
PCWrite(0xc4);
PCWrite(address);
return CMD_OK;
@@ -767,26 +887,31 @@ static CommandStatus DEC(const char *label, int argc, char *argv[],
switch(mode)
{
- case ABSOLUTE:
- PCWrite(0xce);
- PCWriteWord(address);
+ case IMPLIED:
+ case ACCUMULATOR:
+ PCWrite(0x3a);
return CMD_OK;
- case ZERO_PAGE:
+ case DIRECT_PAGE:
PCWrite(0xc6);
PCWrite(address);
return CMD_OK;
- case ABSOLUTE_INDEX_X:
- PCWrite(0xde);
+ case ABSOLUTE:
+ PCWrite(0xce);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
+ case DIRECT_PAGE_INDEX_X:
PCWrite(0xd6);
PCWrite(address);
return CMD_OK;
+ case ABSOLUTE_INDEX_X:
+ PCWrite(0xce);
+ PCWriteWord(address);
+ return CMD_OK;
+
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -797,6 +922,12 @@ static CommandStatus DEC(const char *label, int argc, char *argv[],
static CommandStatus EOR(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
+ COMMON(0x40);
+}
+
+static CommandStatus INC(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
address_mode_t mode;
int address;
@@ -804,47 +935,31 @@ static CommandStatus EOR(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMMEDIATE:
- PCWrite(0x49);
+ case IMPLIED:
+ case ACCUMULATOR:
+ PCWrite(0x1a);
+ return CMD_OK;
+
+ case DIRECT_PAGE:
+ PCWrite(0xe6);
PCWrite(address);
return CMD_OK;
case ABSOLUTE:
- PCWrite(0x4d);
+ PCWrite(0xee);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x45);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0xf6);
PCWrite(address);
return CMD_OK;
case ABSOLUTE_INDEX_X:
- PCWrite(0x5d);
- PCWriteWord(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0x59);
+ PCWrite(0xfe);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x55);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0x41);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0x51);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -852,7 +967,7 @@ static CommandStatus EOR(const char *label, int argc, char *argv[],
}
}
-static CommandStatus INC(const char *label, int argc, char *argv[],
+static CommandStatus JMP(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -862,51 +977,29 @@ static CommandStatus INC(const char *label, int argc, char *argv[],
switch(mode)
{
+ case DIRECT_PAGE:
case ABSOLUTE:
- PCWrite(0xee);
+ PCWrite(0x4c);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0xe6);
- PCWrite(address);
+ case ABSOLUTE_LONG:
+ PCWrite(0x5c);
+ PCWrite24(address);
return CMD_OK;
- case ABSOLUTE_INDEX_X:
- PCWrite(0xfe);
+ case ABSOLUTE_INDIRECT:
+ PCWrite(0x6c);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0xf6);
- PCWrite(address);
- return CMD_OK;
-
- default:
- snprintf(err, errsize, "%s: unsupported addressing mode %s",
- argv[0], address_mode_name[mode]);
- return CMD_FAILED;
- }
-}
-
-static CommandStatus JMP(const char *label, int argc, char *argv[],
- int quoted[], char *err, size_t errsize)
-{
- address_mode_t mode;
- int address;
-
- CMD_ADDRESS_MODE(mode, address);
-
- switch(mode)
- {
- case ABSOLUTE:
- case ZERO_PAGE:
- PCWrite(0x4c);
+ case ABSOLUTE_INDEX_X_INDIRECT:
+ PCWrite(0x7c);
PCWriteWord(address);
return CMD_OK;
- case INDIRECT:
- PCWrite(0x6c);
+ case ABSOLUTE_INDIRECT_LONG:
+ PCWrite(0xdc);
PCWriteWord(address);
return CMD_OK;
@@ -917,7 +1010,7 @@ static CommandStatus JMP(const char *label, int argc, char *argv[],
}
}
-static CommandStatus JSR(const char *label, int argc, char *argv[],
+static CommandStatus JSL(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -927,10 +1020,11 @@ static CommandStatus JSR(const char *label, int argc, char *argv[],
switch(mode)
{
+ case DIRECT_PAGE:
case ABSOLUTE:
- case ZERO_PAGE:
- PCWrite(0x20);
- PCWriteWord(address);
+ case ABSOLUTE_LONG:
+ PCWrite(0x22);
+ PCWrite24(address);
return CMD_OK;
default:
@@ -940,7 +1034,7 @@ static CommandStatus JSR(const char *label, int argc, char *argv[],
}
}
-static CommandStatus LDA(const char *label, int argc, char *argv[],
+static CommandStatus JSR(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -950,47 +1044,17 @@ static CommandStatus LDA(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMMEDIATE:
- PCWrite(0xa9);
- PCWrite(address);
- return CMD_OK;
-
case ABSOLUTE:
- PCWrite(0xad);
- PCWriteWord(address);
- return CMD_OK;
-
- case ZERO_PAGE:
- PCWrite(0xa5);
- PCWrite(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_X:
- PCWrite(0xbd);
+ case DIRECT_PAGE:
+ PCWrite(0x20);
PCWriteWord(address);
return CMD_OK;
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0xb9);
+ case ABSOLUTE_INDEX_X_INDIRECT:
+ PCWrite(0xfc);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0xb5);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0xa1);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0xb1);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -998,6 +1062,12 @@ static CommandStatus LDA(const char *label, int argc, char *argv[],
}
}
+static CommandStatus LDA(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ COMMON(0xa0);
+}
+
static CommandStatus LDX(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
@@ -1010,6 +1080,11 @@ static CommandStatus LDX(const char *label, int argc, char *argv[],
{
case IMMEDIATE:
PCWrite(0xa2);
+ PCWrite8_16_XY(address);
+ return CMD_OK;
+
+ case DIRECT_PAGE:
+ PCWrite(0xa6);
PCWrite(address);
return CMD_OK;
@@ -1018,8 +1093,8 @@ static CommandStatus LDX(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0xa6);
+ case DIRECT_PAGE_INDEX_Y:
+ PCWrite(0xb6);
PCWrite(address);
return CMD_OK;
@@ -1028,11 +1103,6 @@ static CommandStatus LDX(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0xb6);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -1052,6 +1122,11 @@ static CommandStatus LDY(const char *label, int argc, char *argv[],
{
case IMMEDIATE:
PCWrite(0xa0);
+ PCWrite8_16_XY(address);
+ return CMD_OK;
+
+ case DIRECT_PAGE:
+ PCWrite(0xa4);
PCWrite(address);
return CMD_OK;
@@ -1060,8 +1135,8 @@ static CommandStatus LDY(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0xa4);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0xb4);
PCWrite(address);
return CMD_OK;
@@ -1070,11 +1145,6 @@ static CommandStatus LDY(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0xb4);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -1092,6 +1162,11 @@ static CommandStatus LSR(const char *label, int argc, char *argv[],
switch(mode)
{
+ case DIRECT_PAGE:
+ PCWrite(0x46);
+ PCWrite(address);
+ return CMD_OK;
+
case IMPLIED:
case ACCUMULATOR:
PCWrite(0x4a);
@@ -1102,8 +1177,8 @@ static CommandStatus LSR(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x46);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x56);
PCWrite(address);
return CMD_OK;
@@ -1112,11 +1187,6 @@ static CommandStatus LSR(const char *label, int argc, char *argv[],
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x56);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -1127,6 +1197,12 @@ static CommandStatus LSR(const char *label, int argc, char *argv[],
static CommandStatus ORA(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
+ COMMON(0x00);
+}
+
+static CommandStatus ROL(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
address_mode_t mode;
int address;
@@ -1134,47 +1210,31 @@ static CommandStatus ORA(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMMEDIATE:
- PCWrite(0x09);
+ case DIRECT_PAGE:
+ PCWrite(0x26);
PCWrite(address);
return CMD_OK;
+ case IMPLIED:
+ case ACCUMULATOR:
+ PCWrite(0x2a);
+ return CMD_OK;
+
case ABSOLUTE:
- PCWrite(0x0d);
+ PCWrite(0x2e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x05);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x36);
PCWrite(address);
return CMD_OK;
case ABSOLUTE_INDEX_X:
- PCWrite(0x1d);
- PCWriteWord(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0x19);
+ PCWrite(0x3e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x15);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0x01);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0x11);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -1182,7 +1242,7 @@ static CommandStatus ORA(const char *label, int argc, char *argv[],
}
}
-static CommandStatus ROL(const char *label, int argc, char *argv[],
+static CommandStatus ROR(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -1192,31 +1252,31 @@ static CommandStatus ROL(const char *label, int argc, char *argv[],
switch(mode)
{
+ case DIRECT_PAGE:
+ PCWrite(0x66);
+ PCWrite(address);
+ return CMD_OK;
+
case IMPLIED:
case ACCUMULATOR:
- PCWrite(0x2a);
+ PCWrite(0x6a);
return CMD_OK;
case ABSOLUTE:
- PCWrite(0x2e);
+ PCWrite(0x6e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x26);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x76);
PCWrite(address);
return CMD_OK;
case ABSOLUTE_INDEX_X:
- PCWrite(0x3e);
+ PCWrite(0x7e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x36);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -1224,7 +1284,19 @@ static CommandStatus ROL(const char *label, int argc, char *argv[],
}
}
-static CommandStatus ROR(const char *label, int argc, char *argv[],
+static CommandStatus SBC(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ COMMON(0xe0);
+}
+
+static CommandStatus STA(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ COMMON(0x80);
+}
+
+static CommandStatus STX(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -1234,28 +1306,18 @@ static CommandStatus ROR(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMPLIED:
- case ACCUMULATOR:
- PCWrite(0x6a);
- return CMD_OK;
-
- case ABSOLUTE:
- PCWrite(0x6e);
- PCWriteWord(address);
- return CMD_OK;
-
- case ZERO_PAGE:
- PCWrite(0x66);
+ case DIRECT_PAGE:
+ PCWrite(0x86);
PCWrite(address);
return CMD_OK;
- case ABSOLUTE_INDEX_X:
- PCWrite(0x7e);
+ case ABSOLUTE:
+ PCWrite(0x8e);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x76);
+ case DIRECT_PAGE_INDEX_Y:
+ PCWrite(0x96);
PCWrite(address);
return CMD_OK;
@@ -1266,7 +1328,7 @@ static CommandStatus ROR(const char *label, int argc, char *argv[],
}
}
-static CommandStatus SBC(const char *label, int argc, char *argv[],
+static CommandStatus STY(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -1276,45 +1338,56 @@ static CommandStatus SBC(const char *label, int argc, char *argv[],
switch(mode)
{
- case IMMEDIATE:
- PCWrite(0xe9);
+ case DIRECT_PAGE:
+ PCWrite(0x84);
PCWrite(address);
return CMD_OK;
case ABSOLUTE:
- PCWrite(0xed);
+ PCWrite(0x8c);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0xe5);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x94);
PCWrite(address);
return CMD_OK;
- case ABSOLUTE_INDEX_X:
- PCWrite(0xfd);
- PCWriteWord(address);
- return CMD_OK;
+ default:
+ snprintf(err, errsize, "%s: unsupported addressing mode %s",
+ argv[0], address_mode_name[mode]);
+ return CMD_FAILED;
+ }
+}
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0xf9);
- PCWriteWord(address);
- return CMD_OK;
+static CommandStatus STZ(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ address_mode_t mode;
+ int address;
+
+ CMD_ADDRESS_MODE(mode, address);
- case ZERO_PAGE_INDEX_X:
- PCWrite(0xf5);
+ switch(mode)
+ {
+ case DIRECT_PAGE:
+ PCWrite(0x64);
PCWrite(address);
return CMD_OK;
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0xe1);
+ case DIRECT_PAGE_INDEX_X:
+ PCWrite(0x74);
PCWrite(address);
return CMD_OK;
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0xf1);
- PCWrite(address);
+ case ABSOLUTE:
+ PCWrite(0x9c);
+ PCWriteWord(address);
+ return CMD_OK;
+
+ case ABSOLUTE_INDEX_X:
+ PCWrite(0x9e);
+ PCWriteWord(address);
return CMD_OK;
default:
@@ -1324,7 +1397,7 @@ static CommandStatus SBC(const char *label, int argc, char *argv[],
}
}
-static CommandStatus STA(const char *label, int argc, char *argv[],
+static CommandStatus COP(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -1334,39 +1407,55 @@ static CommandStatus STA(const char *label, int argc, char *argv[],
switch(mode)
{
- case ABSOLUTE:
- PCWrite(0x8d);
- PCWriteWord(address);
- return CMD_OK;
-
- case ZERO_PAGE:
- PCWrite(0x85);
+ case DIRECT_PAGE:
+ case IMMEDIATE:
+ PCWrite(0x02);
PCWrite(address);
return CMD_OK;
- case ABSOLUTE_INDEX_X:
- PCWrite(0x9d);
- PCWriteWord(address);
- return CMD_OK;
+ default:
+ snprintf(err, errsize, "%s: unsupported addressing mode %s",
+ argv[0], address_mode_name[mode]);
+ return CMD_FAILED;
+ }
+}
- case ABSOLUTE_INDEX_Y:
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0x99);
- PCWriteWord(address);
- return CMD_OK;
+static CommandStatus REP(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ address_mode_t mode;
+ int address;
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x95);
- PCWrite(address);
- return CMD_OK;
+ CMD_ADDRESS_MODE(mode, address);
- case ZERO_PAGE_INDIRECT_X:
- PCWrite(0x81);
+ switch(mode)
+ {
+ case DIRECT_PAGE:
+ case IMMEDIATE:
+ PCWrite(0xc2);
PCWrite(address);
return CMD_OK;
- case ZERO_PAGE_INDIRECT_Y:
- PCWrite(0x91);
+ default:
+ snprintf(err, errsize, "%s: unsupported addressing mode %s",
+ argv[0], address_mode_name[mode]);
+ return CMD_FAILED;
+ }
+}
+
+static CommandStatus SEP(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ address_mode_t mode;
+ int address;
+
+ CMD_ADDRESS_MODE(mode, address);
+
+ switch(mode)
+ {
+ case DIRECT_PAGE:
+ case IMMEDIATE:
+ PCWrite(0xe2);
PCWrite(address);
return CMD_OK;
@@ -1377,7 +1466,64 @@ static CommandStatus STA(const char *label, int argc, char *argv[],
}
}
-static CommandStatus STX(const char *label, int argc, char *argv[],
+static CommandStatus MVN_MVP(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ /* This opcode uses two distinct arguments, rather than a single addressing
+ mode
+ */
+ address_mode_t mode1;
+ address_mode_t mode2;
+ int address1;
+ int address2;
+
+ CMD_ARGC_CHECK(3);
+
+ CalcAddressMode(2, argv, quoted, err, errsize, &mode1, &address1);
+
+ if (mode1 == ADDR_MODE_UNKNOWN)
+ {
+ snprintf(err, errsize, "%s: couldn't work out "
+ "addressing mode", argv[0]);
+ return CMD_FAILED;
+ }
+ \
+ CalcAddressMode(2, argv + 1, quoted + 1, err, errsize, &mode2, &address2);
+
+ if (mode2 == ADDR_MODE_UNKNOWN)
+ {
+ snprintf(err, errsize, "%s: couldn't work out "
+ "addressing mode", argv[0]);
+ return CMD_FAILED;
+ }
+ \
+ if (mode1 == ADDR_MODE_ERROR || mode2 == ADDR_MODE_ERROR)
+ {
+ return CMD_FAILED;
+ }
+
+ if (mode1 == IMMEDIATE && mode2 == IMMEDIATE)
+ {
+ if (CompareString(argv[0], "MVN"))
+ {
+ PCWrite(0x54);
+ }
+ else
+ {
+ PCWrite(0x44);
+ }
+
+ PCWrite(address1);
+ PCWrite(address2);
+ return CMD_OK;
+ }
+
+ snprintf(err, errsize, "%s: unsupported addressing mode(s) %s, %s",
+ argv[0], argv[1], argv[2]);
+ return CMD_FAILED;
+}
+
+static CommandStatus PEA(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -1387,30 +1533,32 @@ static CommandStatus STX(const char *label, int argc, char *argv[],
switch(mode)
{
+ case DIRECT_PAGE:
+ case IMMEDIATE:
case ABSOLUTE:
- PCWrite(0x8e);
+ PCWrite(0xf4);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x86);
- PCWrite(address);
- return CMD_OK;
+ default:
+ snprintf(err, errsize, "%s: unsupported addressing mode %s",
+ argv[0], address_mode_name[mode]);
+ return CMD_FAILED;
+ }
+}
- case ABSOLUTE_INDEX_Y:
- if (address < 0 || address > 255)
- {
- snprintf(err, errsize, "%s: value %d outside of zero page",
- argv[0], address);
- return CMD_FAILED;
- }
+static CommandStatus PEI(const char *label, int argc, char *argv[],
+ int quoted[], char *err, size_t errsize)
+{
+ address_mode_t mode;
+ int address;
- PCWrite(0x96);
- PCWrite(address);
- return CMD_OK;
+ CMD_ADDRESS_MODE(mode, address);
- case ZERO_PAGE_INDEX_Y:
- PCWrite(0x96);
+ switch(mode)
+ {
+ case DIRECT_PAGE:
+ PCWrite(0xd4);
PCWrite(address);
return CMD_OK;
@@ -1421,7 +1569,7 @@ static CommandStatus STX(const char *label, int argc, char *argv[],
}
}
-static CommandStatus STY(const char *label, int argc, char *argv[],
+static CommandStatus PER(const char *label, int argc, char *argv[],
int quoted[], char *err, size_t errsize)
{
address_mode_t mode;
@@ -1431,33 +1579,13 @@ static CommandStatus STY(const char *label, int argc, char *argv[],
switch(mode)
{
+ case DIRECT_PAGE:
+ case IMMEDIATE:
case ABSOLUTE:
- PCWrite(0x8c);
+ PCWrite(0x62);
PCWriteWord(address);
return CMD_OK;
- case ZERO_PAGE:
- PCWrite(0x84);
- PCWrite(address);
- return CMD_OK;
-
- case ABSOLUTE_INDEX_X:
- if (address < 0 || address > 255)
- {
- snprintf(err, errsize, "%s: value %d outside of zero page",
- argv[0], address);
- return CMD_FAILED;
- }
-
- PCWrite(0x94);
- PCWrite(address);
- return CMD_OK;
-
- case ZERO_PAGE_INDEX_X:
- PCWrite(0x94);
- PCWrite(address);
- return CMD_OK;
-
default:
snprintf(err, errsize, "%s: unsupported addressing mode %s",
argv[0], address_mode_name[mode]);
@@ -1481,43 +1609,60 @@ typedef struct
static const OpcodeTable implied_opcodes[] =
{
- {"NOP", 0xea},
- {"TXS", 0x9a},
- {"TSX", 0xba},
-
- {"PHA", 0x48},
- {"PHX", 0xda},
- {"PHY", 0x5a},
- {"PHB", 0x8b},
- {"PHD", 0x0b},
- {"PHK", 0x4b},
- {"PHP", 0x08},
-
- {"PLA", 0x68},
- {"PLX", 0xfa},
- {"PLY", 0x7a},
- {"PLB", 0xab},
- {"PLD", 0x2b},
- {"PLP", 0x28},
-
- {"CLC", 0x18},
- {"SEC", 0x38},
- {"CLI", 0x58},
- {"SEI", 0x78},
- {"CLV", 0xb8},
- {"CLD", 0xd8},
- {"SED", 0xf8},
- {"BRK", 0x00},
- {"TAX", 0xaa},
- {"TXA", 0x8a},
- {"DEX", 0xca},
- {"INX", 0xe8},
- {"TAY", 0xa8},
- {"TYA", 0x98},
- {"DEY", 0x88},
- {"INY", 0xc8},
- {"RTI", 0x40},
- {"RTS", 0x60},
+ {"NOP", 0xea},
+
+ {"TAX", 0xaa},
+ {"TXA", 0x8a},
+ {"TAY", 0xa8},
+ {"TYA", 0x98},
+ {"TXS", 0x9a},
+ {"TSX", 0xba},
+ {"TXA", 0x8a},
+ {"TXY", 0x9b},
+ {"TYX", 0xbb},
+
+ {"TCD", 0x5b},
+ {"TCS", 0x1b},
+ {"TDC", 0x7b},
+ {"TSC", 0x3b},
+
+ {"XBA", 0xeb},
+ {"XCE", 0xfb},
+
+ {"DEX", 0xca},
+ {"DEY", 0x88},
+ {"INX", 0xe8},
+ {"INY", 0xc8},
+
+ {"PHA", 0x48},
+ {"PHX", 0xda},
+ {"PHY", 0x5a},
+ {"PHB", 0x8b},
+ {"PHD", 0x0b},
+ {"PHK", 0x4b},
+ {"PHP", 0x08},
+
+ {"PLA", 0x68},
+ {"PLX", 0xfa},
+ {"PLY", 0x7a},
+ {"PLB", 0xab},
+ {"PLD", 0x2b},
+ {"PLP", 0x28},
+
+ {"CLC", 0x18},
+ {"SEC", 0x38},
+ {"CLI", 0x58},
+ {"SEI", 0x78},
+ {"CLV", 0xb8},
+ {"CLD", 0xd8},
+ {"SED", 0xf8},
+ {"BRK", 0x00},
+ {"RTI", 0x40},
+ {"RTL", 0x6b},
+ {"RTS", 0x60},
+ {"WDM", 0x42},
+ {"STP", 0xdb},
+ {"WAI", 0xcb},
{NULL}
};
@@ -1532,6 +1677,14 @@ static const OpcodeTable branch_opcodes[] =
{"BCS", 0xB0},
{"BNE", 0xD0},
{"BEQ", 0xF0},
+ {"BRA", 0x80},
+ {NULL}
+};
+
+
+static const OpcodeTable long_branch_opcodes[] =
+{
+ {"BRL", 0x82},
{NULL}
};
@@ -1553,6 +1706,8 @@ static const HandlerTable handler_table[] =
{"AND", AND},
{"ASL", ASL},
{"BIT", BIT},
+ {"TRB", TRB},
+ {"TSB", TSB},
{"CMP", CMP},
{"CPX", CPX},
{"CPY", CPY},
@@ -1560,6 +1715,7 @@ static const HandlerTable handler_table[] =
{"EOR", EOR},
{"INC", INC},
{"JMP", JMP},
+ {"JSL", JSL},
{"JSR", JSR},
{"LDA", LDA},
{"LDX", LDX},
@@ -1572,6 +1728,15 @@ static const HandlerTable handler_table[] =
{"STA", STA},
{"STX", STX},
{"STY", STY},
+ {"STZ", STZ},
+ {"COP", COP},
+ {"REP", REP},
+ {"SEP", SEP},
+ {"MVN", MVN_MVP},
+ {"MVP", MVN_MVP},
+ {"PEA", PEA},
+ {"PER", PER},
+ {"PEI", PEI},
{NULL}
};
@@ -1660,6 +1825,32 @@ CommandStatus Handler_65c816(const char *label, int argc, char *argv[],
}
}
+ for(f = 0; long_branch_opcodes[f].op; f++)
+ {
+ if (CompareString(argv[0], long_branch_opcodes[f].op))
+ {
+ int offset;
+
+ CMD_ARGC_CHECK(2);
+
+ CMD_EXPR(argv[1], offset);
+
+ offset = offset - (PC() + 3);
+
+ if (IsFinalPass() && (offset < -32768 || offset > 32767))
+ {
+ snprintf(err, errsize, "%s: Branch offset (%d) too big",
+ argv[1], offset);
+ return CMD_FAILED;
+ }
+
+ PCWrite(long_branch_opcodes[f].code);
+ PCWriteWord(offset);
+
+ return CMD_OK;
+ }
+ }
+
/* Check for other opcodes
*/
diff --git a/src/casm.c b/src/casm.c
index 6733ad5..2643a02 100644
--- a/src/casm.c
+++ b/src/casm.c
@@ -47,6 +47,7 @@
#include "z80.h"
#include "6502.h"
#include "gbcpu.h"
+#include "65c816.h"
/* ---------------------------------------- MACROS
@@ -107,6 +108,12 @@ static const CPU cpu_table[]=
LSB_Word,
Init_GBCPU, Options_GBCPU, SetOption_GBCPU, Handler_GBCPU
},
+ {
+ "65c816",
+ 0x10000,
+ LSB_Word,
+ Init_65c816, Options_65c816, SetOption_65c816, Handler_65c816
+ },
{NULL}
};
diff --git a/src/test/65c816 b/src/test/65c816
new file mode 100644
index 0000000..73a7e5b
--- /dev/null
+++ b/src/test/65c816
@@ -0,0 +1,548 @@
+ cpu 65c816
+
+ org $8000
+
+ clc
+ xce
+
+ mx 16,16
+ rep #$30
+
+ adc ($10,x)
+ adc $32,s
+ adc $10
+ adc [$10]
+ adc #$54
+ adc $9876
+ adc $fedbca
+ adc ($10),y
+ adc ($10)
+ adc ($32,s),y
+ adc $10,x
+ adc [$10],y
+ adc $9876,y
+ adc $9876,x
+ adc $fedcba,x
+ sbc ($10,x)
+ sbc $32,s
+ sbc $10
+ sbc [$10]
+ sbc #$54
+ sbc $9876
+ sbc $fedbca
+ sbc ($10),y
+ sbc ($10)
+ sbc ($32,s),y
+ sbc $10,x
+ sbc [$10],y
+ sbc $9876,y
+ sbc $9876,x
+ sbc $fedcba,x
+ cmp ($10,x)
+ cmp $32,s
+ cmp $10
+ cmp [$10]
+ cmp #$54
+ cmp $9876
+ cmp $fedbca
+ cmp ($10),y
+ cmp ($10)
+ cmp ($32,s),y
+ cmp $10,x
+ cmp [$10],y
+ cmp $9876,y
+ cmp $9876,x
+ cmp $fedcba,x
+ cpx #$54
+ cpx $10
+ cpx $9876
+ cpy #$54
+ cpy $10
+ cpy $9876
+ dec
+ dec $10
+ dec $9876
+ dec $10,x
+ dec $9876,x
+ dex
+ dey
+ inc
+ inc $10
+ inc $9876
+ inc $10,x
+ inc $9876,x
+ inx
+ iny
+ and ($10,x)
+ and $32,s
+ and $10
+ and [$10]
+ and #$54
+ and $9876
+ and $fedbca
+ and ($10),y
+ and ($10)
+ and ($32,s),y
+ and $10,x
+ and [$10],y
+ and $9876,y
+ and $9876,x
+ and $fedcba,x
+ eor ($10,x)
+ eor $32,s
+ eor $10
+ eor [$10]
+ eor #$54
+ eor $9876
+ eor $fedbca
+ eor ($10),y
+ eor ($10)
+ eor ($32,s),y
+ eor $10,x
+ eor [$10],y
+ eor $9876,y
+ eor $9876,x
+ eor $fedcba,x
+ ora ($10,x)
+ ora $32,s
+ ora $10
+ ora [$10]
+ ora #$54
+ ora $9876
+ ora $fedbca
+ ora ($10),y
+ ora ($10)
+ ora ($32,s),y
+ ora $10,x
+ ora [$10],y
+ ora $9876,y
+ ora $9876,x
+ ora $fedcba,x
+ bit $10
+ bit $9876
+ bit $10,x
+ bit $9876,x
+ bit #$54
+ trb $10
+ trb $9876
+ tsb $10
+ tsb $9876
+ asl $10
+ asl
+ asl $9876
+ asl $10,x
+ asl $9876,x
+ lsr $10
+ lsr
+ lsr $9876
+ lsr $10,x
+ lsr $9876,x
+ rol $10
+ rol
+ rol $9876
+ rol $10,x
+ rol $9876,x
+ ror $10
+ ror
+ ror $9876
+ ror $10,x
+ ror $9876,x
+ bcc label1
+ bcs label1
+ beq label1
+ bmi label1
+ bne label1
+ bpl label1
+ bra label1
+ bvc label1
+ bvs label1
+ brl label1
+ brl label2
+
+label1:
+ nop
+ brk
+ .byte 255
+ nop
+ brk
+ .byte $e5
+
+
+ jmp $1234
+ jmp $fedcba
+ jmp ($1234)
+ jmp ($1234,x)
+ jmp [$1234]
+ jsl $123456
+ jsr $1234
+ jsr ($1234,x)
+ rtl
+ rts
+ brk
+ cop #$12
+ rti
+ clc
+ cld
+ cli
+ clv
+ sec
+ sed
+ sei
+ rep #$12
+ sep #$12
+ lda ($10,x)
+ lda $32,s
+ lda $10
+ lda [$10]
+ lda #$54
+ lda $9876
+ lda $fedbca
+ lda ($10),y
+ lda ($10)
+ lda ($32,s),y
+ lda $10,x
+ lda [$10],y
+ lda $9876,y
+ lda $9876,x
+ lda $fedcba,x
+ ldx #$54
+ ldx $10
+ ldx $9876
+ ldx $10,y
+ ldx $9876,y
+ ldy #$54
+ ldy $10
+ ldy $9876
+ ldy $10,x
+ ldy $9876,x
+ sta ($10,x)
+ sta $32,s
+ sta $10
+ sta [$10]
+ sta $9876
+ sta $fedbca
+ sta ($10),y
+ sta ($10)
+ sta ($32,s),y
+ sta $10,x
+ sta [$10],y
+ sta $9876,y
+ sta $9876,x
+ sta $fedcba,x
+ stx $10
+ stx $9876
+ stx $10,y
+ sty $10
+ sty $9876
+ sty $10,x
+ stz $10
+ stz $10,x
+ stz $9876
+ stz $9876,x
+ mvn #$12,#$34
+ mvp #$12,#$34
+ nop
+ wdm
+ pea #$1234
+ pei $12
+ per label1
+ pha
+ phx
+ phy
+ pla
+ plx
+ ply
+ phb
+ phd
+ phk
+ php
+ plb
+ pld
+ plp
+ stp
+ wai
+ tax
+ tay
+ tsx
+ txa
+ txs
+ txy
+ tya
+ tyx
+ tcd
+ tcs
+ tdc
+ tsc
+ xba
+ xce
+
+
+ mx 8,8
+ sep #$30
+
+ adc ($10,x)
+ adc $32,s
+ adc $10
+ adc [$10]
+ adc #$54
+ adc $9876
+ adc $fedbca
+ adc ($10),y
+ adc ($10)
+ adc ($32,s),y
+ adc $10,x
+ adc [$10],y
+ adc $9876,y
+ adc $9876,x
+ adc $fedcba,x
+ sbc ($10,x)
+ sbc $32,s
+ sbc $10
+ sbc [$10]
+ sbc #$54
+ sbc $9876
+ sbc $fedbca
+ sbc ($10),y
+ sbc ($10)
+ sbc ($32,s),y
+ sbc $10,x
+ sbc [$10],y
+ sbc $9876,y
+ sbc $9876,x
+ sbc $fedcba,x
+ cmp ($10,x)
+ cmp $32,s
+ cmp $10
+ cmp [$10]
+ cmp #$54
+ cmp $9876
+ cmp $fedbca
+ cmp ($10),y
+ cmp ($10)
+ cmp ($32,s),y
+ cmp $10,x
+ cmp [$10],y
+ cmp $9876,y
+ cmp $9876,x
+ cmp $fedcba,x
+ cpx #$54
+ cpx $10
+ cpx $9876
+ cpy #$54
+ cpy $10
+ cpy $9876
+ dec
+ dec $10
+ dec $9876
+ dec $10,x
+ dec $9876,x
+ dex
+ dey
+ inc
+ inc $10
+ inc $9876
+ inc $10,x
+ inc $9876,x
+ inx
+ iny
+ and ($10,x)
+ and $32,s
+ and $10
+ and [$10]
+ and #$54
+ and $9876
+ and $fedbca
+ and ($10),y
+ and ($10)
+ and ($32,s),y
+ and $10,x
+ and [$10],y
+ and $9876,y
+ and $9876,x
+ and $fedcba,x
+ eor ($10,x)
+ eor $32,s
+ eor $10
+ eor [$10]
+ eor #$54
+ eor $9876
+ eor $fedbca
+ eor ($10),y
+ eor ($10)
+ eor ($32,s),y
+ eor $10,x
+ eor [$10],y
+ eor $9876,y
+ eor $9876,x
+ eor $fedcba,x
+ ora ($10,x)
+ ora $32,s
+ ora $10
+ ora [$10]
+ ora #$54
+ ora $9876
+ ora $fedbca
+ ora ($10),y
+ ora ($10)
+ ora ($32,s),y
+ ora $10,x
+ ora [$10],y
+ ora $9876,y
+ ora $9876,x
+ ora $fedcba,x
+ bit $10
+ bit $9876
+ bit $10,x
+ bit $9876,x
+ bit #$54
+ trb $10
+ trb $9876
+ tsb $10
+ tsb $9876
+ asl $10
+ asl
+ asl $9876
+ asl $10,x
+ asl $9876,x
+ lsr $10
+ lsr
+ lsr $9876
+ lsr $10,x
+ lsr $9876,x
+ rol $10
+ rol
+ rol $9876
+ rol $10,x
+ rol $9876,x
+ ror $10
+ ror
+ ror $9876
+ ror $10,x
+ ror $9876,x
+ bcc label2
+ bcs label2
+ beq label2
+ bmi label2
+ bne label2
+ bpl label2
+ bra label2
+ bvc label2
+ bvs label2
+ brl label1
+ brl label2
+
+label2:
+ nop
+ brk
+ .byte 0
+ nop
+ brk
+ .byte $e5
+
+ jmp $1234
+ jmp $fedcba
+ jmp ($1234)
+ jmp ($1234,x)
+ jmp [$1234]
+ jsl $123456
+ jsr $1234
+ jsr ($1234,x)
+ rtl
+ rts
+ brk
+ cop #$12
+ rti
+ clc
+ cld
+ cli
+ clv
+ sec
+ sed
+ sei
+ rep #$12
+ sep #$12
+ lda ($10,x)
+ lda $32,s
+ lda $10
+ lda [$10]
+ lda #$54
+ lda $9876
+ lda $fedbca
+ lda ($10),y
+ lda ($10)
+ lda ($32,s),y
+ lda $10,x
+ lda [$10],y
+ lda $9876,y
+ lda $9876,x
+ lda $fedcba,x
+ ldx #$54
+ ldx $10
+ ldx $9876
+ ldx $10,y
+ ldx $9876,y
+ ldy #$54
+ ldy $10
+ ldy $9876
+ ldy $10,x
+ ldy $9876,x
+ sta ($10,x)
+ sta $32,s
+ sta $10
+ sta [$10]
+ sta $9876
+ sta $fedbca
+ sta ($10),y
+ sta ($10)
+ sta ($32,s),y
+ sta $10,x
+ sta [$10],y
+ sta $9876,y
+ sta $9876,x
+ sta $fedcba,x
+ stx $10
+ stx $9876
+ stx $10,y
+ sty $10
+ sty $9876
+ sty $10,x
+ stz $10
+ stz $10,x
+ stz $9876
+ stz $9876,x
+ mvn #$12,#$34
+ mvp #$12,#$34
+ nop
+ wdm
+ pea #$1234
+ pei $12
+ per label2
+ pha
+ phx
+ phy
+ pla
+ plx
+ ply
+ phb
+ phd
+ phk
+ php
+ plb
+ pld
+ plp
+ stp
+ wai
+ tax
+ tay
+ tsx
+ txa
+ txs
+ txy
+ tya
+ tyx
+ tcd
+ tcs
+ tdc
+ tsc
+ xba
+ xce
diff --git a/src/util.c b/src/util.c
index 0068540..bf065ef 100644
--- a/src/util.c
+++ b/src/util.c
@@ -136,6 +136,12 @@ int CompareString(const char *a, const char *b)
}
+int CompareChar(char a, char b)
+{
+ return tolower((unsigned char)a) == tolower((unsigned char)b);
+}
+
+
int CompareStart(const char *a, const char *b)
{
while(*a && *b)
diff --git a/src/util.h b/src/util.h
index 7222dce..e00f68d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -64,6 +64,12 @@ char *Trim(char *p);
int CompareString(const char *a, const char *b);
+/* Compare a character, but case insensitive. Returns TRUE for match, otherwise
+ FALSE.
+*/
+int CompareChar(char a, char b);
+
+
/* Compare the start of a string 'a' starts with string 'b', but case
insensitive. Returns TRUE for match, otherwise FALSE.
*/