diff options
author | Ian C <ianc@noddybox.co.uk> | 2016-04-28 14:58:38 +0100 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2016-04-28 14:58:38 +0100 |
commit | 6b970e749e720404d08cec565fe0157d20fdeaef (patch) | |
tree | dc80919782dcd3d7da2bca104a85adde996cac94 | |
parent | 239edccf43ff39e93a96c4c75af9e6772f55efe2 (diff) |
First pass of compilable 65c816 mode.
-rwxr-xr-x | src/65c816.c | 1245 | ||||
-rw-r--r-- | src/casm.c | 7 | ||||
-rw-r--r-- | src/test/65c816 | 548 | ||||
-rw-r--r-- | src/util.c | 6 | ||||
-rw-r--r-- | src/util.h | 6 |
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 */ @@ -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 @@ -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) @@ -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. */ |