mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-25 23:49:25 +00:00
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:
parent
bff56ae803
commit
c53505915d
@ -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
|
||||
|
14
src/Makefile
14
src/Makefile
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
12
src/acme.c
12
src/acme.c
@ -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();
|
||||
|
17
src/basics.h
17
src/basics.h
@ -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
|
20
src/cpu.c
20
src/cpu.c
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
||||
|
16
src/mnemo.c
16
src/mnemo.c
@ -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);
|
||||
|
149
src/output.c
149
src/output.c
@ -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)
|
||||
{
|
||||
|
29
src/output.h
29
src/output.h
@ -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
|
||||
|
@ -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
20
src/pseudoopcodes.h
Normal 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
|
@ -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"
|
||||
|
||||
|
17
src/symbol.c
17
src/symbol.c
@ -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)
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user