Refactoring only; no change in functionality.

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@47 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2014-12-03 22:18:06 +00:00
parent bff56ae803
commit c53505915d
22 changed files with 298 additions and 275 deletions

View File

@ -761,12 +761,13 @@ Purpose: Select the processor to produce code for. If this PO
the previously chosen CPU value is restored
afterwards.
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)
6502 mnemonics and addressing modes of 6502 cpu
65c02 superset of 6502, adds 65c02 extensions
65816 superset of 65c02, adds 65816 extensions
6510 superset of 6502, adds mnemonics for
undocumented opcodes
c64dtv2 superset of 6510, adds mnemonics for DTV2
extensions (BRA/SAC/SIR)
BLOCK: A block of assembler statements.
Examples: !if cputype = $65c02 {
!cpu 65c02 { ; temporarily allow 65c02 stuff

View File

@ -8,7 +8,7 @@ RM = rm
PROGS = acme
BINDIR = /usr/local/bin
USERBIN = $(HOME)/bin
OBJS = acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o section.o symbol.o tree.o typesystem.o
OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o pseudoopcodes.o section.o symbol.o tree.o typesystem.o
all: $(PROGS)
@ -17,7 +17,7 @@ acme: $(OBJS)
strip acme
acme.o: config.h platform.h acme.h alu.h basics.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h section.h symbol.h acme.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -29,11 +29,11 @@ dynabuf.o: config.h acme.h global.h input.h dynabuf.h dynabuf.c
encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h encoding.h encoding.c
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h macro.h mnemo.h tree.h symbol.h flow.h flow.c
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h macro.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -43,9 +43,11 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h output.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h mnemo.h section.h tree.h symbol.h symbol.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c
tree.o: config.h dynabuf.h global.h symbol.h tree.h tree.c

View File

@ -8,7 +8,7 @@ RM = rm
PROGS = acme
#BINDIR = /usr/local/bin
#USERBIN = $(HOME)/bin
OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o section.o symbol.o tree.o typesystem.o
OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o pseudoopcodes.o section.o symbol.o tree.o typesystem.o
all: $(PROGS)
@ -18,7 +18,7 @@ acme: $(OBJS)
djp acme.exe
djp acmepmod.exe
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h section.h symbol.h acme.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -32,9 +32,9 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h macro.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -44,9 +44,11 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h output.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h mnemo.h section.h tree.h symbol.h symbol.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c
tree.o: config.h dynabuf.h global.h symbol.h tree.h tree.c

View File

@ -15,13 +15,13 @@ USERBIN = $(HOME)/bin
all: $(PROGS)
acme.exe: acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o section.o symbol.o tree.o typesystem.o _dos.o resource.res
$(CC) $(LIBS) $(CFLAGS) -o acme acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o section.o symbol.o tree.o typesystem.o resource.res
acme.exe: acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o pseudoopcodes.o section.o symbol.o tree.o typesystem.o _dos.o resource.res
$(CC) $(LIBS) $(CFLAGS) -o acme acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o pseudoopcodes.o section.o symbol.o tree.o typesystem.o resource.res
strip acme.exe
acme.o: config.h platform.h acme.h alu.h basics.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h section.h symbol.h acme.h _dos.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h _dos.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -35,9 +35,9 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h macro.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -47,9 +47,11 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h output.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h mnemo.h section.h tree.h symbol.h symbol.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c
tree.o: config.h dynabuf.h global.h symbol.h tree.h tree.c

View File

@ -8,7 +8,7 @@ RM = rm
PROGS = acme
#BINDIR = /usr/local/bin
#USERBIN = $(HOME)/bin
OBJS = acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o section.o symbol.o tree.o typesystem.o
OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o macro.o mnemo.o output.o platform.o pseudoopcodes.o section.o symbol.o tree.o typesystem.o
all: $(PROGS)
@ -16,12 +16,10 @@ acme: $(OBJS)
$(CC) $(CFLAGS) -o !Unsqueezed $(OBJS) $(LIBS)
Squeeze -f -v !Unsqueezed !ACME.!RunImage
acme.o: config.h platform.h acme.h alu.h basics.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h section.h symbol.h acme.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
basics.o: config.h alu.h cpu.h dynabuf.h input.h global.h output.h tree.h basics.h basics.c
cliargs.o: cliargs.h cliargs.c
cpu.o: config.h alu.h dynabuf.h global.h input.h mnemo.h output.h tree.h cpu.h cpu.c
@ -32,7 +30,7 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h macro.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h output.h section.h symbol.h tree.h global.h global.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
@ -44,6 +42,8 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h output.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c

View File

@ -17,7 +17,7 @@
#define RELEASE "0.95.4" // update before release (FIXME)
#define CODENAME "Fenchurch" // update before release
#define CHANGE_DATE "30 Nov" // update before release
#define CHANGE_DATE "3 Dec" // 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
@ -27,7 +27,6 @@
#include <string.h>
#include "acme.h"
#include "alu.h"
#include "basics.h"
#include "cliargs.h"
#include "config.h"
#include "cpu.h"
@ -40,6 +39,7 @@
#include "mnemo.h"
#include "output.h"
#include "platform.h"
#include "pseudoopcodes.h"
#include "section.h"
#include "symbol.h"
@ -333,7 +333,7 @@ static void keyword_to_dynabuf(const char keyword[])
static void set_output_format(void)
{
keyword_to_dynabuf(cliargs_safe_get_next("output format"));
if (!Output_set_output_format()) {
if (output_set_output_format()) {
// 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);
@ -545,10 +545,6 @@ int main(int argc, const char *argv[])
// For example, this could read the library path from an
// environment variable, which in turn may need DynaBuf already.
PLATFORM_INIT;
// init some keyword trees needed for argument handling
CPUtype_init();
symbols_clear_init(); // needed so
Outputfile_init();
// prepare a buffer large enough to hold pointers to "-D" switch values
// cli_defines = safe_malloc(argc * sizeof(*cli_defines));
// handle command line arguments
@ -557,7 +553,6 @@ int main(int argc, const char *argv[])
cliargs_get_rest(&toplevel_src_count, &toplevel_sources, "No top level sources given");
// Init modules (most of them will just build keyword trees)
ALU_init();
Basics_init();
CPU_init();
Encoding_init();
Flow_init();
@ -566,6 +561,7 @@ int main(int argc, const char *argv[])
Macro_init();
Mnemo_init();
Output_init(fill_value);
pseudoopcodes_init(); // setup keyword tree for pseudo opcodes
Section_init();
if (do_actual_work())
save_output_file();

View File

@ -1,17 +0,0 @@
// ACME - a crossassembler for producing 6502/65c02/65816 code.
// Copyright (C) 1998-2009 Marco Baye
// Have a look at "acme.c" for further info
//
// basic assembly stuff
#ifndef basics_H
#define basics_H
#include "config.h"
// register pseudo opcodes and create dynamic buffer
extern void Basics_init(void);
#endif

View File

@ -7,10 +7,11 @@
#include "alu.h"
#include "cpu.h"
#include "dynabuf.h"
#include "global.h"
#include "global.h" // FIXME - remove when no longer needed
#include "input.h"
#include "mnemo.h"
#include "output.h"
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
#include "tree.h"
@ -100,7 +101,7 @@ static enum eos PO_align(void)
else
fill = CPU_state.type->default_align_value;
while ((test++ & and) != equal)
Output_8b(fill);
output_8(fill);
return ENSURE_EOS;
}
@ -111,6 +112,10 @@ int CPU_find_cpu_struct(const struct cpu_type **target)
{
void *node_body;
// make sure tree is initialised
if (CPU_tree == NULL)
Tree_add_table(&CPU_tree, CPUs);
// perform lookup
if (!Tree_easy_scan(CPU_tree, &node_body, GlobalDynaBuf))
return 0;
*target = node_body;
@ -119,7 +124,7 @@ int CPU_find_cpu_struct(const struct cpu_type **target)
// select CPU ("!cpu" pseudo opcode)
// FIXME - move to basics.c
// FIXME - move to pseudoopcodes.c
static enum eos PO_cpu(void)
{
const struct cpu_type *cpu_buffer = CPU_state.type; // remember current cpu
@ -149,7 +154,7 @@ static enum eos PO_realpc(void)
// start offset assembly
// FIXME - split into PO (move to basics.c) and backend (move to output.c)
// TODO - add a label argument to assign the block size afterwards (for assemble-to-end-address)
// TODO - maybe add a label argument to assign the block size afterwards (for assemble-to-end-address) (or add another pseudo opcode)
static enum eos PO_pseudopc(void)
{
// FIXME - read pc using a function call!
@ -251,13 +256,6 @@ void CPU_passinit(const struct cpu_type *cpu_type)
}
// create cpu type tree (is done early)
void CPUtype_init(void)
{
Tree_add_table(&CPU_tree, CPUs);
}
// register pseudo opcodes (done later)
// FIXME - move to basics.c
void CPU_init(void)

View File

@ -22,8 +22,6 @@ struct cpu_type {
#define CPUFLAG_SUPPORTSLONGREGS (1u << 1) // allow "!al" and "!rl" pseudo opcodes
#define CPUFLAG_8B_AND_AB_NEED_0_ARG (1u << 2) // warn if "ane/lxa #$xx" uses non-zero arg
// create cpu type tree (is done early)
extern void CPUtype_init(void);
// register pseudo opcodes (done later)
extern void CPU_init(void);

View File

@ -9,8 +9,9 @@
#include "acme.h"
#include "dynabuf.h"
#include "encoding.h"
#include "global.h"
#include "global.h" // FIXME - remove when no longer needed
#include "output.h"
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
#include "input.h"
#include "tree.h"
@ -51,7 +52,7 @@ static enum eos encode_string(encoder_t inner_encoder, char xor)
GetQuotedByte();
// send characters until closing quote is reached
while (GotByte && (GotByte != '"')) {
Output_8b(xor ^ Encoding_encode_char(GotByte));
output_8(xor ^ Encoding_encode_char(GotByte));
GetQuotedByte();
}
if (GotByte == CHAR_EOS)
@ -63,7 +64,7 @@ static enum eos encode_string(encoder_t inner_encoder, char xor)
// Parse value. No problems with single characters
// because the current encoding is
// temporarily set to the given one.
Output_8b(ALU_any_int());
output_8(ALU_any_int());
}
} while (Input_accept_comma());
Encoding_encode_char = outer_encoder; // reactivate buffered encoder

View File

@ -16,10 +16,11 @@
#include "alu.h"
#include "config.h"
#include "dynabuf.h"
#include "global.h"
#include "global.h" // FIXME - remove when no longer needed
#include "input.h"
#include "macro.h"
#include "mnemo.h"
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
#include "symbol.h"
#include "tree.h"

View File

@ -17,6 +17,7 @@
#include "input.h"
#include "macro.h"
#include "output.h"
#include "pseudoopcodes.h"
#include "section.h"
#include "symbol.h"
#include "tree.h"
@ -98,7 +99,6 @@ const char Byte_flags[256] = {
// variables
struct ronode *pseudo_opcode_tree = NULL; // tree to hold pseudo opcodes (FIXME - move when grouping all POs)
int pass_count; // number of current pass (starts 0)
char GotByte; // Last byte read (processed)
int Process_verbosity = 0; // Level of additional output
@ -136,7 +136,7 @@ static void parse_pc_def(void) // Now GotByte = "*"
// re-definitions of program counter change segment
if (GotByte == '=') {
GetByte(); // proceed with next char
PO_setpc();
notreallypo_setpc();
Input_ensure_EOS();
} else {
Throw_error(exception_syntax);
@ -155,6 +155,8 @@ static void parse_pseudo_opcode(void) // Now GotByte = "!"
GetByte(); // read next byte
// on missing keyword, return (complaining will have been done)
if (Input_read_and_lower_keyword()) {
// move this to pseudoopcodes.c:
// search for tree item
if ((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
&& node_body) {

View File

@ -54,9 +54,6 @@ extern const char Byte_flags[];
// bits 2, 1 and 0 are currently unused
// Variables
extern struct ronode *pseudo_opcode_tree; // tree to hold pseudo opcodes (FIXME - move when grouping all POs)
// structures
// different ways to handle end-of-statement:
enum eos {

View File

@ -7,9 +7,10 @@
#include "config.h"
#include "alu.h"
#include "dynabuf.h"
#include "global.h"
#include "global.h" // FIXME - remove when no longer needed
#include "input.h"
#include "platform.h"
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
#include "section.h"
#include "tree.h"

View File

@ -629,8 +629,8 @@ static void group_only_relative8_addressing(int opcode)
Output_byte(opcode);
// this fn has its own range check (see above).
// No reason to irritate the user with another error message,
// so use Output_byte() instead of Output_8b()
//Output_8b(offset);
// so use Output_byte() instead of output_8()
//output_8(offset);
Output_byte(offset);
Input_ensure_EOS();
}
@ -653,7 +653,7 @@ static void group_only_relative16_addressing(int opcode)
}
}
Output_byte(opcode);
Output_16b(offset);
output_le16(offset);
Input_ensure_EOS();
}
@ -672,15 +672,15 @@ static void make_command(int force_bit, struct result *result, unsigned long opc
switch (calc_arg_size(force_bit, result, addressing_modes)) {
case MVALUE_FORCE08:
Output_byte(opcodes & 255);
Output_8b(result->val.intval);
output_8(result->val.intval);
break;
case MVALUE_FORCE16:
Output_byte((opcodes >> 8) & 255);
Output_16b(result->val.intval);
output_le16(result->val.intval);
break;
case MVALUE_FORCE24:
Output_byte((opcodes >> 16) & 255);
Output_24b(result->val.intval);
output_le24(result->val.intval);
}
}
@ -809,8 +809,8 @@ static void group_move(int opcode)
if (Input_accept_comma()) {
target = ALU_any_int(); // machine language:
Output_byte(opcode); // opcode
Output_8b(target); // target
Output_8b(source); // source
output_8(target); // target
output_8(source); // source
Input_ensure_EOS();
} else {
Throw_error(exception_syntax);

View File

@ -46,13 +46,10 @@ struct output {
struct {
intval_t start; // start of current segment (or NO_SEGMENT_START)
intval_t max; // highest address segment may use
int flags; // segment flags ("overlay" and "invisible", see below)
int flags; // segment flags ("overlay" and "invisible", see header file)
struct segment list_head; // head element of doubly-linked ring list
} segment;
};
// segment flags (FIXME - move to header file when setpc() is moved to pseudo_opcodes.c):
#define SEGMENT_FLAG_OVERLAY (1u << 0) // do not warn about this segment overwriting another one
#define SEGMENT_FLAG_INVISIBLE (1u << 1) // do not warn about other segments overwriting this one
// variables
@ -187,7 +184,7 @@ void Output_fake(int size)
// output 8-bit value with range check
void Output_8b(intval_t value)
void output_8(intval_t value)
{
if ((value <= 0xff) && (value >= -0x80))
Output_byte(value);
@ -197,7 +194,7 @@ void Output_8b(intval_t value)
// output 16-bit value with range check
void Output_16b(intval_t value)
void output_le16(intval_t value)
{
if ((value <= 0xffff) && (value >= -0x8000)) {
Output_byte(value);
@ -209,7 +206,7 @@ void Output_16b(intval_t value)
// output 24-bit value with range check
void Output_24b(intval_t value)
void output_le24(intval_t value)
{
if ((value <= 0xffffff) && (value >= -0x800000)) {
Output_byte(value);
@ -222,7 +219,7 @@ void Output_24b(intval_t value)
// output 32-bit value (without range check)
void Output_32b(intval_t value)
void output_le32(intval_t value)
{
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
Output_byte(value);
@ -243,26 +240,16 @@ static void fill_completely(char value)
// define default value for empty memory ("!initmem" pseudo opcode)
// FIXME - move to basics.c
static enum eos PO_initmem(void)
// returns zero if ok, nonzero if already set
int output_initmem(char content)
{
intval_t content;
// ignore in all passes but in first
if (pass_count)
return SKIP_REMAINDER;
// if MemInit flag is already set, complain
if (out->initvalue_set) {
Throw_warning("Memory already initialised.");
return SKIP_REMAINDER;
return 1; // failed
}
// set MemInit flag
out->initvalue_set = TRUE;
// get value and init memory
content = ALU_defined_int();
if ((content > 0xff) || (content < -0x80))
Throw_error(exception_number_out_of_range);
// init memory
fill_completely(content);
// enforce another pass
@ -271,93 +258,53 @@ static enum eos PO_initmem(void)
// FIXME - enforcing another pass is not needed if there hasn't been any
// output yet. But that's tricky to detect without too much overhead.
// The old solution was to add &&(out->lowest_written < out->highest_written+1) to "if" above
return ENSURE_EOS;
return 0; // ok
}
// try to set output format held in DynaBuf. Returns whether succeeded.
// FIXME - move to basics.c?
int Output_set_output_format(void)
// try to set output format held in DynaBuf. Returns zero on success.
int output_set_output_format(void)
{
void *node_body;
// make sure tree is initialised
if (file_format_tree == NULL)
Tree_add_table(&file_format_tree, file_formats);
// perform lookup
if (!Tree_easy_scan(file_format_tree, &node_body, GlobalDynaBuf))
return FALSE;
return 1;
output_format = (enum output_format) node_body;
return TRUE;
return 0;
}
// select output file and format ("!to" pseudo opcode)
// FIXME - move to basics.c
static enum eos PO_to(void)
// if file format was already chosen, returns zero.
// if file format isn't set, chooses CBM and returns 1.
int output_prefer_cbm_file_format(void)
{
// bugfix: first read filename, *then* check for first pass.
// if skipping right away, quoted colons might be misinterpreted as EOS
// FIXME - why not just fix the skipping code to handle quotes? :)
// "!sl" has been fixed as well
// read filename to global dynamic buffer
// if no file name given, exit (complaining will have been done)
if (Input_read_filename(FALSE))
return SKIP_REMAINDER;
// only act upon this pseudo opcode in first pass
if (pass_count)
return SKIP_REMAINDER;
if (output_format != OUTPUT_FORMAT_UNSPECIFIED)
return 0;
output_format = OUTPUT_FORMAT_CBM;
return 1;
}
// select output file ("!to" pseudo opcode)
// returns zero on success, nonzero if already set
int output_set_output_filename(void)
{
// if output file already chosen, complain and exit
if (output_filename) {
Throw_warning("Output file already chosen.");
return SKIP_REMAINDER;
return 1; // failed
}
// get malloc'd copy of filename
output_filename = DynaBuf_get_copy(GlobalDynaBuf);
// select output format
// if no comma found, use default file format
if (Input_accept_comma() == FALSE) {
if (output_format == OUTPUT_FORMAT_UNSPECIFIED) {
output_format = OUTPUT_FORMAT_CBM;
// output deprecation warning
Throw_warning("Used \"!to\" without file format indicator. Defaulting to \"cbm\".");
}
return ENSURE_EOS;
}
// parse output format name
// if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER;
if (Output_set_output_format())
return ENSURE_EOS; // success
// error occurred
Throw_error("Unknown output format.");
return SKIP_REMAINDER;
return 0; // ok
}
// pseudo ocpode table
// FIXME - move to basics.c
static struct ronode pseudo_opcodes[] = {
PREDEFNODE("initmem", PO_initmem),
PREDEFLAST("to", PO_to),
// ^^^^ this marks the last element
};
// init file format tree (is done early, because it is needed for CLI argument parsing)
// FIXME - move to some other file
void Outputfile_init(void)
{
Tree_add_table(&file_format_tree, file_formats);
}
// init output struct, register pseudo opcodes (done later)
// init output struct (done later)
void Output_init(signed long fill_value)
{
out->buffer = safe_malloc(OUTBUFFERSIZE);
@ -369,7 +316,6 @@ void Output_init(signed long fill_value)
}
// init output buffer (fill memory with initial value)
fill_completely(fill_value & 0xff);
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);
// init ring list of segments
out->segment.list_head.next = &out->segment.list_head;
out->segment.list_head.prev = &out->segment.list_head;
@ -551,9 +497,6 @@ void Output_start_segment(intval_t address_change, int segment_flags)
}
// TODO - add "!skip AMOUNT" pseudo opcode as alternative to "* = * + AMOUNT" (needed for assemble-to-end-address)
// the new pseudo opcode would skip the given amount of bytes without starting a new segment
// set program counter to defined value (FIXME - allow for undefined!)
// if start address was given on command line, main loop will call this before each pass.
// in addition to that, it will be called on each "* = VALUE".
@ -598,34 +541,6 @@ Maybe like this:
*/
// called when "* = EXPRESSION" is parsed
// setting program counter via "* = VALUE"
// FIXME - move to basics.c
void PO_setpc(void)
{
int segment_flags = 0;
intval_t new_addr = ALU_defined_int();
// check for modifiers
while (Input_accept_comma()) {
// parse modifier
// if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
return;
if (strcmp(GlobalDynaBuf->buffer, "overlay") == 0) {
segment_flags |= SEGMENT_FLAG_OVERLAY;
} else if (strcmp(GlobalDynaBuf->buffer, "invisible") == 0) {
segment_flags |= SEGMENT_FLAG_INVISIBLE;
} else {
Throw_error("Unknown \"* =\" segment modifier.");
return;
}
}
vcpu_set_pc(new_addr, segment_flags);
}
// get program counter
void vcpu_read_pc(struct result *target)
{

View File

@ -13,6 +13,9 @@
// constants
#define MEMINIT_USE_DEFAULT 256
// segment flags
#define SEGMENT_FLAG_OVERLAY (1u << 0) // do not warn about this segment overwriting another one
#define SEGMENT_FLAG_INVISIBLE (1u << 1) // do not warn about other segments overwriting this one
// current CPU state
@ -33,9 +36,7 @@ extern struct vcpu CPU_state; // current CPU state
// Prototypes
// Init file format tree (is done early)
extern void Outputfile_init(void);
// alloc and init mem buffer, register pseudo opcodes (done later)
// alloc and init mem buffer (done later)
extern void Output_init(signed long fill_value);
// clear segment list and disable output
extern void Output_passinit(void);
@ -44,19 +45,25 @@ extern void Output_fake(int size);
// Send low byte of arg to output buffer and advance pointer
extern void (*Output_byte)(intval_t);
// Output 8-bit value with range check
extern void Output_8b(intval_t);
extern void output_8(intval_t);
// Output 16-bit value with range check
extern void Output_16b(intval_t);
extern void output_le16(intval_t);
// Output 24-bit value with range check
extern void Output_24b(intval_t);
extern void output_le24(intval_t);
// Output 32-bit value (without range check)
extern void Output_32b(intval_t);
// Try to set output format held in DynaBuf. Returns whether succeeded.
extern int Output_set_output_format(void);
extern void output_le32(intval_t);
// define default value for empty memory ("!initmem" pseudo opcode)
// returns zero if ok, nonzero if already set
extern int output_initmem(char content);
// try to set output format held in DynaBuf. Returns zero on success.
extern int output_set_output_format(void);
// if file format was already chosen, returns zero.
// if file format isn't set, chooses CBM and returns 1.
extern int output_prefer_cbm_file_format(void);
// try to set output file name held in DynaBuf. Returns zero on success.
extern int output_set_output_filename(void);
// write smallest-possible part of memory buffer to file
extern void Output_save_file(FILE *fd);
// Call when "* = EXPRESSION" is parsed
extern void PO_setpc(void);
// change output pointer and enable output
extern void Output_start_segment(intval_t address_change, int segment_flags);
// Show start and end of current segment

View File

@ -2,12 +2,12 @@
// Copyright (C) 1998-2014 Marco Baye
// Have a look at "acme.c" for further info
//
// basic assembly stuff
// pseudo opcode stuff
#include <stdlib.h>
#include <stdio.h>
//#include "acme.h"
#include "config.h"
#include "cpu.h"
#include "basics.h"
#include "alu.h"
#include "dynabuf.h"
#include "input.h"
@ -15,21 +15,111 @@
#include "output.h"
#include "tree.h"
#include "typesystem.h"
#include "pseudoopcodes.h"
// constants
#define USERMSG_DYNABUF_INITIALSIZE 80
static const char s_08[] = "08";
#define s_8 (s_08 + 1) // Yes, I know I'm sick
#define s_16 (s_65816 + 3) // Yes, I know I'm sick
// variables
static struct dynabuf *user_message; // dynamic buffer (!warn/error/serious)
struct ronode *pseudo_opcode_tree = NULL; // tree to hold pseudo opcodes
// not really a pseudo opcode, but close enough to be put here:
// called when "* = EXPRESSION" is parsed
// setting program counter via "* = VALUE"
void notreallypo_setpc(void)
{
int segment_flags = 0;
intval_t new_addr = ALU_defined_int();
// check for modifiers
while (Input_accept_comma()) {
// parse modifier. if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
return;
if (strcmp(GlobalDynaBuf->buffer, "overlay") == 0) {
segment_flags |= SEGMENT_FLAG_OVERLAY;
} else if (strcmp(GlobalDynaBuf->buffer, "invisible") == 0) {
segment_flags |= SEGMENT_FLAG_INVISIBLE;
} else {
Throw_error("Unknown \"* =\" segment modifier.");
return;
}
}
vcpu_set_pc(new_addr, segment_flags);
}
// define default value for empty memory ("!initmem" pseudo opcode)
static enum eos po_initmem(void)
{
intval_t content;
// ignore in all passes but in first
if (pass_count)
return SKIP_REMAINDER;
// get value
content = ALU_defined_int();
if ((content > 0xff) || (content < -0x80))
Throw_error(exception_number_out_of_range);
if (output_initmem(content & 0xff))
return SKIP_REMAINDER;
return ENSURE_EOS;
}
// select output file and format ("!to" pseudo opcode)
static enum eos po_to(void)
{
// bugfix: first read filename, *then* check for first pass.
// if skipping right away, quoted colons might be misinterpreted as EOS
// FIXME - fix the skipping code to handle quotes! :)
// "!sl" has been fixed as well
// read filename to global dynamic buffer
// if no file name given, exit (complaining will have been done)
if (Input_read_filename(FALSE))
return SKIP_REMAINDER;
// only act upon this pseudo opcode in first pass
if (pass_count)
return SKIP_REMAINDER;
if (output_set_output_filename())
return SKIP_REMAINDER;
// select output format
// if no comma found, use default file format
if (Input_accept_comma() == FALSE) {
if (output_prefer_cbm_file_format()) {
// output deprecation warning
Throw_warning("Used \"!to\" without file format indicator. Defaulting to \"cbm\".");
}
return ENSURE_EOS;
}
// parse output format name
// if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER;
if (output_set_output_format()) {
// error occurred
Throw_error("Unknown output format.");
return SKIP_REMAINDER;
}
return ENSURE_EOS; // success
}
// helper function for !8, !16, !24 and !32 pseudo opcodes
static enum eos output_objects(void (*fn)(intval_t))
static enum eos iterate(void (*fn)(intval_t))
{
do
fn(ALU_any_int());
@ -39,35 +129,36 @@ static enum eos output_objects(void (*fn)(intval_t))
// Insert 8-bit values ("!08" / "!8" / "!by" / "!byte" pseudo opcode)
static enum eos PO_8(void)
static enum eos po_8(void)
{
return output_objects(Output_8b);
return iterate(output_8);
}
// Insert 16-bit values ("!16" / "!wo" / "!word" pseudo opcode)
static enum eos PO_16(void)
static enum eos po_16(void)
{
return output_objects(Output_16b);
return iterate(output_le16);
}
// Insert 24-bit values ("!24" pseudo opcode)
static enum eos PO_24(void)
static enum eos po_24(void)
{
return output_objects(Output_24b);
return iterate(output_le24);
}
// Insert 32-bit values ("!32" pseudo opcode)
static enum eos PO_32(void)
static enum eos po_32(void)
{
return output_objects(Output_32b);
return iterate(output_le32);
}
// Include binary file
static enum eos PO_binary(void)
// Include binary file ("!binary" pseudo opcode)
// FIXME - split this into "parser" and "worker" fn and move worker fn somewhere else.
static enum eos po_binary(void)
{
FILE *fd;
int byte;
@ -127,7 +218,7 @@ static enum eos PO_binary(void)
// Reserve space by sending bytes of given value ("!fi" / "!fill" pseudo opcode)
static enum eos PO_fill(void)
static enum eos po_fill(void)
{
intval_t fill = FILLVALUE_FILL,
size = ALU_defined_int();
@ -135,13 +226,13 @@ static enum eos PO_fill(void)
if (Input_accept_comma())
fill = ALU_any_int();
while (size--)
Output_8b(fill);
output_8(fill);
return ENSURE_EOS;
}
// force explicit label definitions to set "address" flag ("!addr"). Has to be re-entrant.
static enum eos PO_addr(void) // Now GotByte = illegal char
static enum eos po_addr(void) // now GotByte = illegal char
{
SKIPSPACE();
if (GotByte == CHAR_SOB) {
@ -152,8 +243,23 @@ static enum eos PO_addr(void) // Now GotByte = illegal char
return PARSE_REMAINDER;
}
/*
// TODO - add "!skip AMOUNT" pseudo opcode as alternative to "* = * + AMOUNT" (needed for assemble-to-end-address)
// the new pseudo opcode would skip the given amount of bytes without starting a new segment
static enum eos po_skip(void) // now GotByte = illegal char
{
}
*/
// show user-defined message
// constants
#define USERMSG_DYNABUF_INITIALSIZE 80
// variables
static struct dynabuf *user_message; // dynamic buffer (!warn/error/serious)
// helper function to show user-defined messages
static enum eos throw_string(const char prefix[], void (*fn)(const char *))
{
struct result result;
@ -209,15 +315,15 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
////
//static enum eos PO_debug(void)
//static enum eos PO_info(void)
//static enum eos po_debug(void)
//static enum eos po_info(void)
//{
// return throw_string();
//}
// throw warning as given in source code
static enum eos PO_warn(void)
static enum eos po_warn(void)
{
return throw_string("!warn: ", Throw_warning);
@ -225,47 +331,50 @@ static enum eos PO_warn(void)
// throw error as given in source code
static enum eos PO_error(void)
static enum eos po_error(void)
{
return throw_string("!error: ", Throw_error);
}
// throw serious error as given in source code
static enum eos PO_serious(void)
static enum eos po_serious(void)
{
return throw_string("!serious: ", Throw_serious_error);
}
// pseudo ocpode table
// pseudo opcode table
static struct ronode pseudo_opcodes[] = {
PREDEFNODE(s_08, PO_8),
PREDEFNODE(s_8, PO_8),
PREDEFNODE("by", PO_8),
PREDEFNODE("byte", PO_8),
PREDEFNODE(s_16, PO_16),
PREDEFNODE("wo", PO_16),
PREDEFNODE("word", PO_16),
PREDEFNODE("24", PO_24),
PREDEFNODE("32", PO_32),
PREDEFNODE("bin", PO_binary),
PREDEFNODE("binary", PO_binary),
PREDEFNODE("fi", PO_fill),
PREDEFNODE("fill", PO_fill),
PREDEFNODE("addr", PO_addr),
PREDEFNODE("address", PO_addr),
// PREDEFNODE("debug", PO_debug),
// PREDEFNODE("info", PO_info),
PREDEFNODE("warn", PO_warn),
PREDEFNODE(s_error, PO_error),
PREDEFLAST("serious", PO_serious),
PREDEFNODE("initmem", po_initmem),
PREDEFNODE("to", po_to),
PREDEFNODE(s_08, po_8),
PREDEFNODE(s_8, po_8),
PREDEFNODE("by", po_8),
PREDEFNODE("byte", po_8),
PREDEFNODE(s_16, po_16),
PREDEFNODE("wo", po_16),
PREDEFNODE("word", po_16),
PREDEFNODE("24", po_24),
PREDEFNODE("32", po_32),
PREDEFNODE("bin", po_binary),
PREDEFNODE("binary", po_binary),
PREDEFNODE("fi", po_fill),
PREDEFNODE("fill", po_fill),
PREDEFNODE("addr", po_addr),
PREDEFNODE("address", po_addr),
// PREDEFNODE("skip", po_skip),
// PREDEFNODE("debug", po_debug),
// PREDEFNODE("info", po_info),
PREDEFNODE("warn", po_warn),
PREDEFNODE(s_error, po_error),
PREDEFLAST("serious", po_serious),
// ^^^^ this marks the last element
};
// register pseudo opcodes and create dynamic buffer
void Basics_init(void)
void pseudoopcodes_init(void)
{
user_message = DynaBuf_create(USERMSG_DYNABUF_INITIALSIZE);
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);

20
src/pseudoopcodes.h Normal file
View File

@ -0,0 +1,20 @@
// ACME - a crossassembler for producing 6502/65c02/65816 code.
// Copyright (C) 1998-2014 Marco Baye
// Have a look at "acme.c" for further info
//
// pseudo opcode stuff
#ifndef pseudoopcodes_H
#define pseudoopcodes_H
// FIXME - after grouping all pseudo opcodes in .c file, make this static:
extern struct ronode *pseudo_opcode_tree; // tree to hold pseudo opcodes
// call when "* = EXPRESSION" is parsed
extern void notreallypo_setpc(void);
// register pseudo opcodes
extern void pseudoopcodes_init(void);
#endif

View File

@ -5,8 +5,9 @@
// Section stuff
#include "config.h"
#include "dynabuf.h"
#include "global.h"
#include "global.h" // FIXME - remove when no longer needed
#include "input.h"
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
#include "tree.h"
#include "section.h"

View File

@ -11,10 +11,11 @@
#include "acme.h"
#include "alu.h"
#include "dynabuf.h"
#include "global.h"
#include "global.h" // FIXME - remove when no longer needed
#include "input.h"
#include "output.h"
#include "platform.h"
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
#include "section.h"
#include "symbol.h"
#include "tree.h"
@ -26,7 +27,7 @@
// variables
struct rwnode *symbols_forest[256]; // ... (because of 8-bit hash)
struct rwnode *symbols_forest[256] = { NULL }; // because of 8-bit hash - must be (at least partially) pre-defined so array will be zeroed!
// Dump symbol value and flags to dump file
@ -322,18 +323,6 @@ void symbols_vicelabels(FILE *fd)
Tree_dump_forest(symbols_forest, ZONE_GLOBAL, dump_vice_address, fd);
}
// clear symbols forest (is done early)
void symbols_clear_init(void)
{
struct rwnode **ptr;
int ii;
// cut down all the trees (clear pointer table)
ptr = symbols_forest;
for (ii = 255; ii >= 0; --ii)
*ptr++ = NULL;
}
// register pseudo opcodes (done later)
void symbols_register_init(void)

View File

@ -22,8 +22,6 @@ struct symbol {
extern struct rwnode *symbols_forest[]; // trees (because of 8-bit hash)
// clear symbol forest (is done early)
extern void symbols_clear_init(void);
// register pseudo opcodes (done later)
extern void symbols_register_init(void);
// function acts upon the symbol's flag bits and produces an error if needed.