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:
marcobaye 2014-11-23 23:40:01 +00:00
parent af1bd69455
commit 0e66c1fcb2
13 changed files with 176 additions and 33 deletions

View File

@ -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.

View File

@ -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
----------------------------------------------------------------------

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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),

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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)
{

View File

@ -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);