acme/src/cpu.c
marcobaye 294fe25c36 ACME Release 0.96: Added experimental support for instruction sets of Rockwell 65C02, WDC 65C02(S), CSG 65CE02 and CSG 4502.
Stack indexing can now be given either as ",s" or as ",sp" (only relevant for 65816 and 65CE02).


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@78 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-12-28 20:32:00 +00:00

120 lines
3.7 KiB
C

// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2016 Marco Baye
// Have a look at "acme.c" for further info
//
// CPU type stuff
#include "cpu.h"
#include "config.h"
#include "alu.h"
#include "dynabuf.h"
#include "global.h" // FIXME - remove when no longer needed
#include "input.h"
#include "mnemo.h"
#include "output.h"
#include "tree.h"
// constants
static struct cpu_type cpu_type_6502 = {
keyword_is_6502_mnemo,
CPUFLAG_INDIRECTJMPBUGGY, // JMP ($xxFF) is buggy
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_6510 = {
keyword_is_6510_mnemo,
CPUFLAG_INDIRECTJMPBUGGY | CPUFLAG_8B_AND_AB_NEED_0_ARG, // JMP ($xxFF) is buggy, ANE/LXA #$xx are unstable unless arg is $00
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_c64dtv2 = {
keyword_is_c64dtv2_mnemo,
CPUFLAG_INDIRECTJMPBUGGY | CPUFLAG_8B_AND_AB_NEED_0_ARG, // JMP ($xxFF) is buggy, ANE/LXA #$xx are unstable unless arg is $00
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_65c02 = {
keyword_is_65c02_mnemo,
0, // no flags
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_r65c02 = {
keyword_is_r65c02_mnemo,
0, // no flags
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_w65c02 = {
keyword_is_w65c02_mnemo,
0, // no flags
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_65816 = {
keyword_is_65816_mnemo,
CPUFLAG_SUPPORTSLONGREGS, // allows A and XY to be 16bits wide
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_65ce02 = {
keyword_is_65ce02_mnemo,
CPUFLAG_DECIMALSUBTRACTBUGGY, // SBC does not work reliably in decimal mode
234 // !align fills with "NOP"
};
static struct cpu_type cpu_type_4502 = {
keyword_is_4502_mnemo,
CPUFLAG_DECIMALSUBTRACTBUGGY, // SBC does not work reliably in decimal mode
234 // !align fills with "NOP"
};
// variables
// predefined stuff
static struct ronode *cputype_tree = NULL;
static struct ronode cputype_list[] = {
#define KNOWN_TYPES "'6502', '6510', '65c02', 'r65c02', 'w65c02', '65816', '65ce02', '4502', 'c64dtv2'" // shown in CLI error message for unknown types
// PREDEFNODE("z80", &cpu_type_Z80),
PREDEFNODE("6502", &cpu_type_6502),
PREDEFNODE("6510", &cpu_type_6510),
PREDEFNODE("65c02", &cpu_type_65c02),
PREDEFNODE("r65c02", &cpu_type_r65c02),
PREDEFNODE("w65c02", &cpu_type_w65c02),
PREDEFNODE("65816", &cpu_type_65816),
PREDEFNODE("65ce02", &cpu_type_65ce02),
PREDEFNODE("4502", &cpu_type_4502),
PREDEFLAST("c64dtv2", &cpu_type_c64dtv2),
// ^^^^ this marks the last element
};
const char cputype_names[] = KNOWN_TYPES; // string to show if cputype_find() returns NULL
// lookup cpu type held in DynaBuf and return its struct pointer (or NULL on failure)
const struct cpu_type *cputype_find(void)
{
void *node_body;
// make sure tree is initialised
if (cputype_tree == NULL)
Tree_add_table(&cputype_tree, cputype_list);
// perform lookup
if (!Tree_easy_scan(cputype_tree, &node_body, GlobalDynaBuf))
return NULL;
return node_body;
}
// if cpu type and value match, set register length variable to value.
// if cpu type and value don't match, complain instead.
// FIXME - error message might be confusing if it is thrown not because of
// initial change, but because of reverting back to old cpu type after "{}" block!
void vcpu_check_and_set_reg_length(int *var, int make_long)
{
if (((CPU_state.type->flags & CPUFLAG_SUPPORTSLONGREGS) == 0) && make_long)
Throw_error("Chosen CPU does not support long registers.");
else
*var = make_long;
}
// set default values for pass
void cputype_passinit(const struct cpu_type *cpu_type)
{
// handle cpu type (default is 6502)
CPU_state.type = cpu_type ? cpu_type : &cpu_type_6502;
}