mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-04-08 20:37:20 +00:00
Release 0.95.3: Added support for C64DTV, MSVC error output and VICE label dump.
Added "c64dtv2" cpu type so you can use its SIR, SAC and BRA opcodes; along with the undocumented ("illegal") opcodes of the 6510. Added Martin Piper's "--msvc" patch so error output can be configured to be in Visual Studio format. Thanks Martin! Merged third-party patch of unknown origin to output label dump in VICE format. Still needs work to be configurable about the types of symbols actually output. git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@41 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
af1bd69455
commit
0e66c1fcb2
@ -764,6 +764,7 @@ Parameters: KEYWORD: Currently valid keywords are:
|
||||
6502 allows official mnemonics and addressing modes
|
||||
6510 adds mnemonics for some undocumented opcodes
|
||||
(but includes all the official 6502 stuff)
|
||||
c64dtv2 allows DTV2 extensions (includes 6510)
|
||||
65c02 allows official 65c02 stuff (includes 6502)
|
||||
65816 allows official 65816 stuff (includes 65c02)
|
||||
BLOCK: A block of assembler statements.
|
||||
|
@ -12,6 +12,19 @@ platform used. There should be another help file in this archive
|
||||
outlining the platform specific changes.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Section: New in release 0.95.3
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Added "c64dtv2" cpu type so you can use its SIR, SAC and BRA opcodes;
|
||||
along with the undocumented ("illegal") opcodes of the 6510.
|
||||
Added Martin Piper's "--msvc" patch so error output can be configured
|
||||
to be in Visual Studio format.
|
||||
Merged third-party patch (who wrote it?) to output label dump in VICE
|
||||
format. Still needs work to be configurable about the types of
|
||||
symbols actually output.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Section: New in release 0.95.2
|
||||
----------------------------------------------------------------------
|
||||
|
@ -28,3 +28,6 @@ Just in case you wonder:
|
||||
"macedit" is an unusably bad text editor for the C128. The source
|
||||
code is not meant to be a good example of ACME's capabilities.
|
||||
Please *don't* look at it. :)
|
||||
|
||||
"trigono.o" is a simple example written to test the floating-point
|
||||
capabilities.
|
||||
|
@ -40,7 +40,8 @@ Section: Introduction
|
||||
ACME is a crossassembler for the 65xx range of processors. It knows
|
||||
about the standard 6502, the 65c02 and the 65816. It also supports
|
||||
the undocumented ("illegal") opcodes of the 6510 processor (a 6502-
|
||||
variant that is used in the Commodore C=64).
|
||||
variant that is used in the Commodore C=64), and the extensions added
|
||||
in the C64DTV2.
|
||||
|
||||
This text and the other files in the same directory only describe the
|
||||
basic functions independent of the platform used. There should be
|
||||
|
@ -7,8 +7,14 @@
|
||||
--- Undocumented ("illegal") opcodes ---
|
||||
|
||||
|
||||
Since release 0.87, ACME contains support for some of the undocumented
|
||||
opcodes of the 6502 processor. Here they are:
|
||||
In release 0.87, support for some of the undocumented opcodes of the
|
||||
6502 processor was added.
|
||||
In release 0.89, some more were added.
|
||||
In release 0.94.8, another one was added (lxa).
|
||||
In release 0.95.3, C64DTV2 support was added, which includes these
|
||||
opcodes as well.
|
||||
|
||||
Here are the mnemonics, addressing modes and generated opcodes:
|
||||
|
||||
| addressing mode |
|
||||
Mnemo | 8 8,x 8,y 16 16,x 16,y (8,x) (8),y | performs:
|
||||
@ -22,8 +28,6 @@ Mnemo | 8 8,x 8,y 16 16,x 16,y (8,x) (8),y | performs:
|
||||
dcp | c7 d7 -- cf df db c3 d3 | dec + cmp
|
||||
isc | e7 f7 -- ef ff fb e3 f3 | inc + sbc
|
||||
|
||||
In release 0.89, more were added; and in 0.94.8, another one (lxa):
|
||||
|
||||
| addressing mode |
|
||||
Mnemo | implied #8 8 8,x 16 16,x | performs:
|
||||
------+-------------------------------------+------------------------
|
||||
@ -43,7 +47,7 @@ Example:
|
||||
|
||||
*) Up until ACME version 0.95.1, anc#8 generated opcode 0x2b. Since
|
||||
ACME version 0.95.2, anc#8 generates opcode 0x0b. Both opcodes work
|
||||
the same way.
|
||||
the same way on a 6510. I am told 0x2b does not work on the C64DTV2.
|
||||
|
||||
**) Note that "dop" and "top" can be used with implied addressing, but
|
||||
the generated opcodes are those for immediate and 16-bit absolute
|
||||
@ -70,19 +74,19 @@ people use different names for them. I hope my choices are not too
|
||||
exotic for your taste.
|
||||
|
||||
Just for the sake of completeness: Here are all the remaining opcodes
|
||||
(the ones ACME won't generate):
|
||||
(the ones ACME won't generate even with "6510" cpu):
|
||||
|
||||
Opcode| Description
|
||||
Opcode| Description C64DTV2
|
||||
------+--------------------------------------------------------------
|
||||
12 | same as 02 and others jam CRASH
|
||||
12 | same as 02 and others jam CRASH bra rel
|
||||
1a | same as (*legal*) ea nop
|
||||
22 | same as 02 and others jam CRASH
|
||||
2b | same as 0b anc #8
|
||||
32 | same as 02 and others jam CRASH
|
||||
2b | same as 0b anc #8 dop
|
||||
32 | same as 02 and others jam CRASH sac #8
|
||||
34 | same as 14 and others dop 8,x
|
||||
3a | same as (*legal*) ea nop
|
||||
3c | same as 1c and others top 16,x
|
||||
42 | same as 02 and others jam CRASH
|
||||
42 | same as 02 and others jam CRASH sir #8
|
||||
44 | same as 04 dop 8
|
||||
52 | same as 02 and others jam CRASH
|
||||
54 | same as 14 and others dop 8,x
|
||||
|
33
src/acme.c
33
src/acme.c
@ -15,9 +15,9 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#define RELEASE "0.95.2" // update before release (FIXME)
|
||||
#define RELEASE "0.95.3" // update before release (FIXME)
|
||||
#define CODENAME "Fenchurch" // update before release
|
||||
#define CHANGE_DATE "22 Nov" // update before release
|
||||
#define CHANGE_DATE "23 Nov" // update before release
|
||||
#define CHANGE_YEAR "2014" // update before release
|
||||
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
|
||||
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
||||
@ -51,12 +51,14 @@ static const char FILE_WRITEBINARY[] = "wb";
|
||||
static const char name_outfile[] = "output filename";
|
||||
static const char arg_symbollist[] = "symbol list filename";
|
||||
static const char arg_reportfile[] = "report filename";
|
||||
static const char arg_vicelabels[] = "VICE labels filename";
|
||||
// long options
|
||||
#define OPTION_HELP "help"
|
||||
#define OPTION_FORMAT "format"
|
||||
#define OPTION_OUTFILE "outfile"
|
||||
#define OPTION_LABELDUMP "labeldump" // old
|
||||
#define OPTION_SYMBOLLIST "symbollist" // new
|
||||
#define OPTION_VICELABELS "vicelabels"
|
||||
#define OPTION_REPORT "report"
|
||||
#define OPTION_SETPC "setpc"
|
||||
#define OPTION_CPU "cpu"
|
||||
@ -65,6 +67,7 @@ static const char arg_reportfile[] = "report filename";
|
||||
#define OPTION_MAXDEPTH "maxdepth"
|
||||
#define OPTION_USE_STDOUT "use-stdout"
|
||||
#define OPTION_VERSION "version"
|
||||
#define OPTION_MSVC "msvc"
|
||||
// options for "-W"
|
||||
#define OPTIONWNO_LABEL_INDENT "no-label-indent"
|
||||
#define OPTIONWNO_OLD_FOR "no-old-for"
|
||||
@ -79,6 +82,7 @@ static signed long start_address = ILLEGAL_START_ADDRESS;
|
||||
static signed long fill_value = MEMINIT_USE_DEFAULT;
|
||||
static const struct cpu_type *default_cpu = NULL;
|
||||
const char *symbollist_filename = NULL;
|
||||
const char *vicelabels_filename = NULL;
|
||||
const char *output_filename = NULL;
|
||||
const char *report_filename = NULL;
|
||||
// maximum recursion depth for macro calls and "!source"
|
||||
@ -124,6 +128,7 @@ static void show_help_and_exit(void)
|
||||
" -r, --" OPTION_REPORT " FILE set report file name\n"
|
||||
" -l, --" OPTION_SYMBOLLIST " FILE set symbol list file name\n"
|
||||
" --" OPTION_LABELDUMP " (old name for --" OPTION_SYMBOLLIST ")\n"
|
||||
" --" OPTION_VICELABELS " FILE set file name for label dump in VICE format\n"
|
||||
" --" OPTION_SETPC " NUMBER set program counter\n"
|
||||
" --" OPTION_CPU " CPU set target processor\n"
|
||||
" --" OPTION_INITMEM " NUMBER define 'empty' memory\n"
|
||||
@ -139,6 +144,7 @@ static void show_help_and_exit(void)
|
||||
// when there are more, use next line and add a separate function:
|
||||
//" -W show warning level options\n"
|
||||
" --" OPTION_USE_STDOUT " fix for 'Relaunch64' IDE (see docs)\n"
|
||||
" --" OPTION_MSVC " set output error message format to that of MS Visual Studio\n"
|
||||
PLATFORM_OPTION_HELP
|
||||
" -V, --" OPTION_VERSION " show version and exit\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
@ -186,11 +192,23 @@ int ACME_finalize(int exit_code)
|
||||
if (fd) {
|
||||
symbols_list(fd);
|
||||
fclose(fd);
|
||||
PLATFORM_SETFILETYPE_TEXT(symbollist_filename);
|
||||
} else {
|
||||
fprintf(stderr, "Error: Cannot open symbol list file \"%s\".\n", symbollist_filename);
|
||||
exit_code = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (vicelabels_filename) {
|
||||
fd = fopen(vicelabels_filename, FILE_WRITETEXT);
|
||||
if (fd) {
|
||||
symbols_vicelabels(fd);
|
||||
fclose(fd);
|
||||
PLATFORM_SETFILETYPE_TEXT(vicelabels_filename);
|
||||
} else {
|
||||
fprintf(stderr, "Error: Cannot open VICE label dump file \"%s\".\n", vicelabels_filename);
|
||||
exit_code = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
@ -316,7 +334,8 @@ static void set_output_format(void)
|
||||
{
|
||||
keyword_to_dynabuf(cliargs_safe_get_next("output format"));
|
||||
if (!Output_set_output_format()) {
|
||||
// FIXME - define error message near the actual format list, so they match!
|
||||
// FIXME - list actual formats instead of outputting a fixed list!
|
||||
// FIXME - or AT LEAST define error message near the actual format list, so they match!
|
||||
fprintf(stderr, "%sUnknown output format (use 'cbm', 'plain' or 'apple').\n", cliargs_error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -328,7 +347,9 @@ static void set_starting_cpu(void)
|
||||
{
|
||||
keyword_to_dynabuf(cliargs_safe_get_next("CPU type"));
|
||||
if (!CPU_find_cpu_struct(&default_cpu)) {
|
||||
fprintf(stderr, "%sUnknown CPU type (use 6502, 6510, 65c02 or 65816).\n", cliargs_error);
|
||||
// FIXME - list actual types instead of outputting a fixed list!
|
||||
// FIXME - or AT LEAST define error message near the actual type list, so they match!
|
||||
fprintf(stderr, "%sUnknown CPU type (use 6502, 6510, c64dtv2, 65c02 or 65816).\n", cliargs_error);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@ -425,6 +446,8 @@ static const char *long_option(const char *string)
|
||||
symbollist_filename = cliargs_safe_get_next(arg_symbollist);
|
||||
else if (strcmp(string, OPTION_SYMBOLLIST) == 0) // new
|
||||
symbollist_filename = cliargs_safe_get_next(arg_symbollist);
|
||||
else if (strcmp(string, OPTION_VICELABELS) == 0)
|
||||
vicelabels_filename = cliargs_safe_get_next(arg_vicelabels);
|
||||
else if (strcmp(string, OPTION_REPORT) == 0)
|
||||
report_filename = cliargs_safe_get_next(arg_reportfile);
|
||||
else if (strcmp(string, OPTION_SETPC) == 0)
|
||||
@ -441,6 +464,8 @@ static const char *long_option(const char *string)
|
||||
// strict_syntax = TRUE;
|
||||
else if (strcmp(string, OPTION_USE_STDOUT) == 0)
|
||||
msg_stream = stdout;
|
||||
else if (strcmp(string, OPTION_MSVC) == 0)
|
||||
format_msvc = TRUE;
|
||||
PLATFORM_LONGOPTION_CODE
|
||||
else if (strcmp(string, OPTION_VERSION) == 0)
|
||||
show_version(TRUE);
|
||||
|
@ -26,6 +26,12 @@ static struct cpu_type cpu_type_6510 = {
|
||||
CPUFLAG_AB_NEEDS_0_ARG, // LXA #$xx is unstable unless arg is $00
|
||||
234 // !align fills with "NOP"
|
||||
};
|
||||
static struct cpu_type cpu_type_c64dtv2 = {
|
||||
keyword_is_c64dtv2mnemo,
|
||||
CPUFLAG_INDIRECTJMPBUGGY | // JMP ($xxFF) is buggy
|
||||
CPUFLAG_AB_NEEDS_0_ARG, // LXA #$xx is unstable unless arg is $00 (FIXME - correct?)
|
||||
234 // !align fills with "NOP"
|
||||
};
|
||||
static struct cpu_type cpu_type_65c02 = {
|
||||
keyword_is_65c02mnemo,
|
||||
0, // no flags
|
||||
@ -59,6 +65,7 @@ static struct node_t CPUs[] = {
|
||||
// PREDEFNODE("z80", &cpu_type_Z80),
|
||||
PREDEFNODE("6502", &cpu_type_6502),
|
||||
PREDEFNODE("6510", &cpu_type_6510),
|
||||
PREDEFNODE("c64dtv2", &cpu_type_c64dtv2),
|
||||
PREDEFNODE("65c02", &cpu_type_65c02),
|
||||
// PREDEFNODE("Rockwell65c02", &cpu_type_Rockwell65c02),
|
||||
// PREDEFNODE("WDC65c02", &cpu_type_WDC65c02),
|
||||
|
15
src/global.c
15
src/global.c
@ -7,6 +7,7 @@
|
||||
// 22 Nov 2007 Added warn_on_indented_labels
|
||||
// 2 Jun 2014 Added warn_on_old_for and warn_on_type_mismatch
|
||||
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
|
||||
// 23 Nov 2014 Merged Martin Piper's "--msvc" error output patch
|
||||
#include <stdio.h>
|
||||
#include "platform.h"
|
||||
#include "acme.h"
|
||||
@ -28,6 +29,7 @@ const char s_65816[] = "65816";
|
||||
const char s_and[] = "and";
|
||||
const char s_asl[] = "asl";
|
||||
const char s_asr[] = "asr";
|
||||
const char s_bra[] = "bra";
|
||||
const char s_brl[] = "brl";
|
||||
const char s_cbm[] = "cbm";
|
||||
const char s_eor[] = "eor";
|
||||
@ -108,6 +110,7 @@ int pass_undefined_count; // "NeedValue" type errors
|
||||
int pass_real_errors; // Errors yet
|
||||
signed long max_errors = MAXERRORS; // errors before giving up
|
||||
FILE *msg_stream = NULL; // set to stdout by --use-stdout
|
||||
int format_msvc = FALSE; // actually bool, enabled by --msvc
|
||||
struct report *report = NULL;
|
||||
|
||||
|
||||
@ -334,10 +337,14 @@ int Parse_optional_block(void)
|
||||
// context: file name, line number, source type and source title.
|
||||
static void throw_message(const char *message, const char *type)
|
||||
{
|
||||
fprintf(msg_stream, "%s - File %s, line %d (%s %s): %s\n", type,
|
||||
Input_now->original_filename, Input_now->line_number,
|
||||
Section_now->type, Section_now->title,
|
||||
message);
|
||||
if (format_msvc)
|
||||
fprintf(msg_stream, "%s(%d) : %s (%s %s): %s\n",
|
||||
Input_now->original_filename, Input_now->line_number,
|
||||
type, Section_now->type, Section_now->title, message);
|
||||
else
|
||||
fprintf(msg_stream, "%s - File %s, line %d (%s %s): %s\n",
|
||||
type, Input_now->original_filename, Input_now->line_number,
|
||||
Section_now->type, Section_now->title, message);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
//
|
||||
// Global stuff - things that are needed by several modules
|
||||
// 19 Nov 2014 Merged Johann Klasek's report listing generator patch
|
||||
// 23 Nov 2014 Merged Martin Piper's "--msvc" error output patch
|
||||
#ifndef global_H
|
||||
#define global_H
|
||||
|
||||
@ -24,6 +25,7 @@ extern const char s_65816[];
|
||||
extern const char s_and[];
|
||||
extern const char s_asl[];
|
||||
extern const char s_asr[];
|
||||
extern const char s_bra[];
|
||||
extern const char s_brl[];
|
||||
extern const char s_cbm[];
|
||||
extern const char s_eor[];
|
||||
@ -74,6 +76,7 @@ extern int pass_undefined_count; // "NeedValue" type errors in current pass
|
||||
extern int pass_real_errors; // Errors yet
|
||||
extern signed long max_errors; // errors before giving up
|
||||
extern FILE *msg_stream; // set to stdout by --errors_to_stdout
|
||||
extern int format_msvc; // actually bool, enabled by --msvc
|
||||
|
||||
// report stuff
|
||||
#define REPORT_ASCBUFSIZE 1024
|
||||
|
47
src/mnemo.c
47
src/mnemo.c
@ -109,13 +109,13 @@ SCB accu_lindy8[] = { 0, 0, 0, 0, 0, 0, 0,
|
||||
// mnemotable), the assembler finds out the column to use here. The row
|
||||
// depends on the used addressing mode. A zero entry in these tables means
|
||||
// that the combination of mnemonic and addressing mode is illegal.
|
||||
// | 6502 | 65c02 | 65816 | 6510 illegals |
|
||||
enum { IDX_BIT,IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_STY,IDX_STX,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_DEC,IDX_INC,IDXcTSB,IDXcTRB,IDXcBIT,IDXcDEC,IDXcINC,IDXcSTZ,IDX816COP,IDX816REP,IDX816SEP,IDX816PEA,IDX_ANC,IDX_ASR,IDX_ARR,IDX_SBX,IDX_DOP,IDX_TOP,IDX_JAM,IDX_LXA};
|
||||
SCS misc_abs[] = { 0x2c24, 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0x8c84, 0x8e86, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0xcec6, 0xeee6, 0x0c04, 0x1c14, 0x2c24, 0xcec6, 0xeee6, 0x9c64, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0}; // $ff $ffff
|
||||
SCS misc_xabs[] = { 0, 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0x94, 0, 0xbcb4, 0, 0, 0, 0xded6, 0xfef6, 0, 0, 0x3c34, 0xded6, 0xfef6, 0x9e74, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0}; // $ff,x $ffff,x
|
||||
SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0, 0x96, 0, 0xbeb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,y $ffff,y
|
||||
SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab}; // #$ff
|
||||
SCB misc_impl[] = { 0, 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x1a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0}; // implied/accu
|
||||
// | 6502 | 65c02 | 65816 | 6510 illegals | C64DTV2 |
|
||||
enum { IDX_BIT,IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_STY,IDX_STX,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_DEC,IDX_INC,IDXcTSB,IDXcTRB,IDXcBIT,IDXcDEC,IDXcINC,IDXcSTZ,IDX816COP,IDX816REP,IDX816SEP,IDX816PEA,IDX_ANC,IDX_ASR,IDX_ARR,IDX_SBX,IDX_DOP,IDX_TOP,IDX_JAM,IDX_LXA,IDX_SAC,IDX_SIR};
|
||||
SCS misc_abs[] = { 0x2c24, 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0x8c84, 0x8e86, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0xcec6, 0xeee6, 0x0c04, 0x1c14, 0x2c24, 0xcec6, 0xeee6, 0x9c64, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x04, 0x0c00, 0, 0, 0, 0}; // $ff $ffff
|
||||
SCS misc_xabs[] = { 0, 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0x94, 0, 0xbcb4, 0, 0, 0, 0xded6, 0xfef6, 0, 0, 0x3c34, 0xded6, 0xfef6, 0x9e74, 0, 0, 0, 0, 0, 0, 0, 0, 0x14, 0x1c00, 0, 0, 0, 0}; // $ff,x $ffff,x
|
||||
SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0, 0x96, 0, 0xbeb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff,y $ffff,y
|
||||
SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0, 0, 0xab, 0x32, 0x42}; // #$ff
|
||||
SCB misc_impl[] = { 0, 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x1a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0c, 0x02, 0, 0, 0}; // implied/accu
|
||||
|
||||
// Code tables for group GROUP_ALLJUMPS:
|
||||
// These tables are needed for finding out the correct code when the mnemonic
|
||||
@ -146,6 +146,7 @@ static struct dynabuf *mnemo_dyna_buf; // dynamic buffer for mnemonics
|
||||
// predefined stuff
|
||||
static struct node_t *mnemo_6502_tree = NULL; // holds 6502 mnemonics
|
||||
static struct node_t *mnemo_6510_tree = NULL; // holds 6510 extensions
|
||||
static struct node_t *mnemo_c64dtv2_tree = NULL; // holds C64DTV2 extensions
|
||||
static struct node_t *mnemo_65c02_tree = NULL; // holds 65c02 extensions
|
||||
//static struct node_t *mnemo_Rockwell65c02_tree = NULL; // Rockwell
|
||||
static struct node_t *mnemo_WDC65c02_tree = NULL; // WDC's "stp"/"wai"
|
||||
@ -241,6 +242,13 @@ static struct node_t mnemos_6510[] = {
|
||||
// ^^^^ this marks the last element
|
||||
};
|
||||
|
||||
static struct node_t mnemos_c64dtv2[] = {
|
||||
PREDEFNODE(s_bra, MERGE(GROUP_RELATIVE8, 0x12)), // branch always
|
||||
PREDEFNODE("sac", MERGE(GROUP_MISC, IDX_SAC)), // set accumulator mapping
|
||||
PREDEFLAST("sir", MERGE(GROUP_MISC, IDX_SIR)), // set index register mapping
|
||||
// ^^^^ this marks the last element
|
||||
};
|
||||
|
||||
static struct node_t mnemos_65c02[] = {
|
||||
PREDEFNODE("ora", MERGE(GROUP_ACCU, IDXcORA | IMM_ACCU)),
|
||||
PREDEFNODE(s_and, MERGE(GROUP_ACCU, IDXcAND | IMM_ACCU)),
|
||||
@ -254,7 +262,7 @@ static struct node_t mnemos_65c02[] = {
|
||||
PREDEFNODE("bit", MERGE(GROUP_MISC, IDXcBIT | IMM_ACCU)),
|
||||
PREDEFNODE("dec", MERGE(GROUP_MISC, IDXcDEC)),
|
||||
PREDEFNODE("inc", MERGE(GROUP_MISC, IDXcINC)),
|
||||
PREDEFNODE("bra", MERGE(GROUP_RELATIVE8, 128)),
|
||||
PREDEFNODE(s_bra, MERGE(GROUP_RELATIVE8, 128)),
|
||||
PREDEFNODE("phy", MERGE(GROUP_IMPLIEDONLY, 90)),
|
||||
PREDEFNODE("ply", MERGE(GROUP_IMPLIEDONLY, 122)),
|
||||
PREDEFNODE("phx", MERGE(GROUP_IMPLIEDONLY, 218)),
|
||||
@ -356,6 +364,7 @@ void Mnemo_init(void)
|
||||
mnemo_dyna_buf = DynaBuf_create(MNEMO_DYNABUF_INITIALSIZE);
|
||||
Tree_add_table(&mnemo_6502_tree, mnemos_6502);
|
||||
Tree_add_table(&mnemo_6510_tree, mnemos_6510);
|
||||
Tree_add_table(&mnemo_c64dtv2_tree, mnemos_c64dtv2);
|
||||
Tree_add_table(&mnemo_65c02_tree, mnemos_65c02);
|
||||
// Tree_add_table(&mnemo_Rockwell65c02_tree, mnemos_Rockwell65c02);
|
||||
Tree_add_table(&mnemo_WDC65c02_tree, mnemos_WDC65c02);
|
||||
@ -888,7 +897,27 @@ int keyword_is_6510mnemo(int length)
|
||||
|
||||
// make lower case version of mnemonic in local dynamic buffer
|
||||
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
|
||||
// first check extensions...
|
||||
// first check undocumented ("illegal") opcodes...
|
||||
if (check_mnemo_tree(mnemo_6510_tree, mnemo_dyna_buf))
|
||||
return TRUE;
|
||||
|
||||
// ...then check original opcodes
|
||||
return check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
// Check whether mnemonic in GlobalDynaBuf is supported by C64DTV2 cpu.
|
||||
int keyword_is_c64dtv2mnemo(int length)
|
||||
{
|
||||
if (length != 3)
|
||||
return FALSE;
|
||||
|
||||
// make lower case version of mnemonic in local dynamic buffer
|
||||
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
|
||||
// first check C64DTV2 extensions...
|
||||
if (check_mnemo_tree(mnemo_c64dtv2_tree, mnemo_dyna_buf))
|
||||
return TRUE;
|
||||
|
||||
// ...then check undocumented ("illegal") opcodes...
|
||||
if (check_mnemo_tree(mnemo_6510_tree, mnemo_dyna_buf))
|
||||
return TRUE;
|
||||
|
||||
|
@ -15,6 +15,8 @@ extern void Mnemo_init(void);
|
||||
extern int keyword_is_6502mnemo(int length);
|
||||
// Check whether mnemonic in GlobalDynaBuf is supported by 6510 cpu.
|
||||
extern int keyword_is_6510mnemo(int length);
|
||||
// Check whether mnemonic in GlobalDynaBuf is supported by C64DTV2 cpu.
|
||||
extern int keyword_is_c64dtv2mnemo(int length);
|
||||
// Check whether mnemonic in GlobalDynaBuf is supported by 65c02 cpu.
|
||||
extern int keyword_is_65c02mnemo(int length);
|
||||
// Check whether mnemonic in GlobalDynaBuf is supported by Rockwell 65c02 cpu.
|
||||
|
54
src/symbol.c
54
src/symbol.c
@ -6,6 +6,7 @@
|
||||
//
|
||||
// 22 Nov 2007 "warn on indented labels" is now a CLI switch
|
||||
// 25 Sep 2011 Fixed bug in !sl (colons in filename could be interpreted as EOS)
|
||||
// 23 Nov 2014 Added label output in VICE format
|
||||
#include <stdio.h>
|
||||
#include "acme.h"
|
||||
#include "alu.h"
|
||||
@ -66,6 +67,41 @@ static void dump_one_symbol(struct node_ra_t *node, FILE *fd)
|
||||
}
|
||||
|
||||
|
||||
// output symbols in VICE format (example: "al C:09ae .nmi1")
|
||||
static void dump_vice_address(struct node_ra_t *node, FILE *fd)
|
||||
{
|
||||
struct symbol *symbol = node->body;
|
||||
|
||||
// dump address symbols even if they are not used
|
||||
if ((symbol->result.flags & MVALUE_DEFINED)
|
||||
&& !(symbol->result.flags & MVALUE_IS_FP)
|
||||
&& (symbol->result.addr_refs == 1))
|
||||
fprintf(fd, "al C:%04x .%s\n", (unsigned) symbol->result.val.intval, node->id_string);
|
||||
}
|
||||
static void dump_vice_usednonaddress(struct node_ra_t *node, FILE *fd)
|
||||
{
|
||||
struct symbol *symbol = node->body;
|
||||
|
||||
// dump non-addresses that are used
|
||||
if (symbol->usage
|
||||
&& (symbol->result.flags & MVALUE_DEFINED)
|
||||
&& !(symbol->result.flags & MVALUE_IS_FP)
|
||||
&& (symbol->result.addr_refs != 1))
|
||||
fprintf(fd, "al C:%04x .%s\n", (unsigned) symbol->result.val.intval, node->id_string);
|
||||
}
|
||||
static void dump_vice_unusednonaddress(struct node_ra_t *node, FILE *fd)
|
||||
{
|
||||
struct symbol *symbol = node->body;
|
||||
|
||||
// dump non-addresses that are unused
|
||||
if (!symbol->usage
|
||||
&& (symbol->result.flags & MVALUE_DEFINED)
|
||||
&& !(symbol->result.flags & MVALUE_IS_FP)
|
||||
&& (symbol->result.addr_refs != 1))
|
||||
fprintf(fd, "al C:%04x .%s\n", (unsigned) symbol->result.val.intval, node->id_string);
|
||||
}
|
||||
|
||||
|
||||
// search for symbol. create if nonexistant. if created, give it flags "flags".
|
||||
// the symbol name must be held in GlobalDynaBuf.
|
||||
struct symbol *symbol_find(zone_t zone, int flags)
|
||||
@ -112,9 +148,7 @@ void symbol_set_value(struct symbol *symbol, struct result *new_value, int chang
|
||||
// symbol is already defined, so compare new and old values
|
||||
// if different type OR same type but different value, complain
|
||||
if (((oldflags ^ new_value->flags) & MVALUE_IS_FP)
|
||||
|| ((oldflags & MVALUE_IS_FP)
|
||||
? (symbol->result.val.fpval != new_value->val.fpval)
|
||||
: (symbol->result.val.intval != new_value->val.intval)))
|
||||
|| ((oldflags & MVALUE_IS_FP) ? (symbol->result.val.fpval != new_value->val.fpval) : (symbol->result.val.intval != new_value->val.intval)))
|
||||
Throw_error("Symbol already defined.");
|
||||
} else {
|
||||
// symbol is not defined yet OR redefinitions are allowed
|
||||
@ -272,10 +306,22 @@ void symbol_define(intval_t value)
|
||||
void symbols_list(FILE *fd)
|
||||
{
|
||||
Tree_dump_forest(symbols_forest, ZONE_GLOBAL, dump_one_symbol, fd);
|
||||
PLATFORM_SETFILETYPE_TEXT(symbollist_filename);
|
||||
}
|
||||
|
||||
|
||||
void symbols_vicelabels(FILE *fd)
|
||||
{
|
||||
// the order of dumped labels is important because VICE will prefer later defined labels
|
||||
// dump unused labels
|
||||
Tree_dump_forest(symbols_forest, ZONE_GLOBAL, dump_vice_unusednonaddress, fd);
|
||||
fputc('\n', fd);
|
||||
// dump other used labels
|
||||
Tree_dump_forest(symbols_forest, ZONE_GLOBAL, dump_vice_usednonaddress, fd);
|
||||
fputc('\n', fd);
|
||||
// dump address symbols
|
||||
Tree_dump_forest(symbols_forest, ZONE_GLOBAL, dump_vice_address, fd);
|
||||
}
|
||||
|
||||
// clear symbols forest (is done early)
|
||||
void symbols_clear_init(void)
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ extern struct symbol *symbol_find(zone_t, int flags);
|
||||
extern void symbol_define(intval_t value);
|
||||
// dump global symbols to file
|
||||
extern void symbols_list(FILE *fd);
|
||||
// dump global labels to file in VICE format
|
||||
extern void symbols_vicelabels(FILE *fd);
|
||||
// fix name of anonymous forward label (held in GlobalDynaBuf, NOT TERMINATED!)
|
||||
// so it references the *next* anonymous forward label definition.
|
||||
extern void symbol_fix_forward_anon_name(int increment);
|
||||
|
Loading…
x
Reference in New Issue
Block a user