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
|
the previously chosen CPU value is restored
|
||||||
afterwards.
|
afterwards.
|
||||||
Parameters: KEYWORD: Currently valid keywords are:
|
Parameters: KEYWORD: Currently valid keywords are:
|
||||||
6502 allows official mnemonics and addressing modes
|
6502 mnemonics and addressing modes of 6502 cpu
|
||||||
6510 adds mnemonics for some undocumented opcodes
|
65c02 superset of 6502, adds 65c02 extensions
|
||||||
(but includes all the official 6502 stuff)
|
65816 superset of 65c02, adds 65816 extensions
|
||||||
c64dtv2 allows DTV2 extensions (includes 6510)
|
6510 superset of 6502, adds mnemonics for
|
||||||
65c02 allows official 65c02 stuff (includes 6502)
|
undocumented opcodes
|
||||||
65816 allows official 65816 stuff (includes 65c02)
|
c64dtv2 superset of 6510, adds mnemonics for DTV2
|
||||||
|
extensions (BRA/SAC/SIR)
|
||||||
BLOCK: A block of assembler statements.
|
BLOCK: A block of assembler statements.
|
||||||
Examples: !if cputype = $65c02 {
|
Examples: !if cputype = $65c02 {
|
||||||
!cpu 65c02 { ; temporarily allow 65c02 stuff
|
!cpu 65c02 { ; temporarily allow 65c02 stuff
|
||||||
|
14
src/Makefile
14
src/Makefile
@ -8,7 +8,7 @@ RM = rm
|
|||||||
PROGS = acme
|
PROGS = acme
|
||||||
BINDIR = /usr/local/bin
|
BINDIR = /usr/local/bin
|
||||||
USERBIN = $(HOME)/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)
|
all: $(PROGS)
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ acme: $(OBJS)
|
|||||||
strip acme
|
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
|
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
|
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
|
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
|
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
|
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
|
tree.o: config.h dynabuf.h global.h symbol.h tree.h tree.c
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ RM = rm
|
|||||||
PROGS = acme
|
PROGS = acme
|
||||||
#BINDIR = /usr/local/bin
|
#BINDIR = /usr/local/bin
|
||||||
#USERBIN = $(HOME)/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)
|
all: $(PROGS)
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ acme: $(OBJS)
|
|||||||
djp acme.exe
|
djp acme.exe
|
||||||
djp acmepmod.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
|
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
|
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
|
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
|
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
|
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
|
tree.o: config.h dynabuf.h global.h symbol.h tree.h tree.c
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ USERBIN = $(HOME)/bin
|
|||||||
|
|
||||||
all: $(PROGS)
|
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
|
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 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
|
$(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
|
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
|
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
|
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
|
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
|
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
|
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
|
tree.o: config.h dynabuf.h global.h symbol.h tree.h tree.c
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ RM = rm
|
|||||||
PROGS = acme
|
PROGS = acme
|
||||||
#BINDIR = /usr/local/bin
|
#BINDIR = /usr/local/bin
|
||||||
#USERBIN = $(HOME)/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)
|
all: $(PROGS)
|
||||||
|
|
||||||
@ -16,12 +16,10 @@ acme: $(OBJS)
|
|||||||
$(CC) $(CFLAGS) -o !Unsqueezed $(OBJS) $(LIBS)
|
$(CC) $(CFLAGS) -o !Unsqueezed $(OBJS) $(LIBS)
|
||||||
Squeeze -f -v !Unsqueezed !ACME.!RunImage
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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 RELEASE "0.95.4" // update before release (FIXME)
|
||||||
#define CODENAME "Fenchurch" // update before release
|
#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 CHANGE_YEAR "2014" // update before release
|
||||||
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
|
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
|
||||||
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
||||||
@ -27,7 +27,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "acme.h"
|
#include "acme.h"
|
||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "basics.h"
|
|
||||||
#include "cliargs.h"
|
#include "cliargs.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
@ -40,6 +39,7 @@
|
|||||||
#include "mnemo.h"
|
#include "mnemo.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "pseudoopcodes.h"
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ static void keyword_to_dynabuf(const char keyword[])
|
|||||||
static void set_output_format(void)
|
static void set_output_format(void)
|
||||||
{
|
{
|
||||||
keyword_to_dynabuf(cliargs_safe_get_next("output format"));
|
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 - list actual formats instead of outputting a fixed list!
|
||||||
// FIXME - or AT LEAST define error message near the actual format list, so they match!
|
// 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);
|
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
|
// For example, this could read the library path from an
|
||||||
// environment variable, which in turn may need DynaBuf already.
|
// environment variable, which in turn may need DynaBuf already.
|
||||||
PLATFORM_INIT;
|
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
|
// prepare a buffer large enough to hold pointers to "-D" switch values
|
||||||
// cli_defines = safe_malloc(argc * sizeof(*cli_defines));
|
// cli_defines = safe_malloc(argc * sizeof(*cli_defines));
|
||||||
// handle command line arguments
|
// 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");
|
cliargs_get_rest(&toplevel_src_count, &toplevel_sources, "No top level sources given");
|
||||||
// Init modules (most of them will just build keyword trees)
|
// Init modules (most of them will just build keyword trees)
|
||||||
ALU_init();
|
ALU_init();
|
||||||
Basics_init();
|
|
||||||
CPU_init();
|
CPU_init();
|
||||||
Encoding_init();
|
Encoding_init();
|
||||||
Flow_init();
|
Flow_init();
|
||||||
@ -566,6 +561,7 @@ int main(int argc, const char *argv[])
|
|||||||
Macro_init();
|
Macro_init();
|
||||||
Mnemo_init();
|
Mnemo_init();
|
||||||
Output_init(fill_value);
|
Output_init(fill_value);
|
||||||
|
pseudoopcodes_init(); // setup keyword tree for pseudo opcodes
|
||||||
Section_init();
|
Section_init();
|
||||||
if (do_actual_work())
|
if (do_actual_work())
|
||||||
save_output_file();
|
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 "alu.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "global.h"
|
#include "global.h" // FIXME - remove when no longer needed
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "mnemo.h"
|
#include "mnemo.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ static enum eos PO_align(void)
|
|||||||
else
|
else
|
||||||
fill = CPU_state.type->default_align_value;
|
fill = CPU_state.type->default_align_value;
|
||||||
while ((test++ & and) != equal)
|
while ((test++ & and) != equal)
|
||||||
Output_8b(fill);
|
output_8(fill);
|
||||||
return ENSURE_EOS;
|
return ENSURE_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +112,10 @@ int CPU_find_cpu_struct(const struct cpu_type **target)
|
|||||||
{
|
{
|
||||||
void *node_body;
|
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))
|
if (!Tree_easy_scan(CPU_tree, &node_body, GlobalDynaBuf))
|
||||||
return 0;
|
return 0;
|
||||||
*target = node_body;
|
*target = node_body;
|
||||||
@ -119,7 +124,7 @@ int CPU_find_cpu_struct(const struct cpu_type **target)
|
|||||||
|
|
||||||
|
|
||||||
// select CPU ("!cpu" pseudo opcode)
|
// select CPU ("!cpu" pseudo opcode)
|
||||||
// FIXME - move to basics.c
|
// FIXME - move to pseudoopcodes.c
|
||||||
static enum eos PO_cpu(void)
|
static enum eos PO_cpu(void)
|
||||||
{
|
{
|
||||||
const struct cpu_type *cpu_buffer = CPU_state.type; // remember current cpu
|
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
|
// start offset assembly
|
||||||
// FIXME - split into PO (move to basics.c) and backend (move to output.c)
|
// 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)
|
static enum eos PO_pseudopc(void)
|
||||||
{
|
{
|
||||||
// FIXME - read pc using a function call!
|
// 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)
|
// register pseudo opcodes (done later)
|
||||||
// FIXME - move to basics.c
|
// FIXME - move to basics.c
|
||||||
void CPU_init(void)
|
void CPU_init(void)
|
||||||
|
@ -22,8 +22,6 @@ struct cpu_type {
|
|||||||
#define CPUFLAG_SUPPORTSLONGREGS (1u << 1) // allow "!al" and "!rl" pseudo opcodes
|
#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
|
#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)
|
// register pseudo opcodes (done later)
|
||||||
extern void CPU_init(void);
|
extern void CPU_init(void);
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
#include "acme.h"
|
#include "acme.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "global.h"
|
#include "global.h" // FIXME - remove when no longer needed
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ static enum eos encode_string(encoder_t inner_encoder, char xor)
|
|||||||
GetQuotedByte();
|
GetQuotedByte();
|
||||||
// send characters until closing quote is reached
|
// send characters until closing quote is reached
|
||||||
while (GotByte && (GotByte != '"')) {
|
while (GotByte && (GotByte != '"')) {
|
||||||
Output_8b(xor ^ Encoding_encode_char(GotByte));
|
output_8(xor ^ Encoding_encode_char(GotByte));
|
||||||
GetQuotedByte();
|
GetQuotedByte();
|
||||||
}
|
}
|
||||||
if (GotByte == CHAR_EOS)
|
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
|
// Parse value. No problems with single characters
|
||||||
// because the current encoding is
|
// because the current encoding is
|
||||||
// temporarily set to the given one.
|
// temporarily set to the given one.
|
||||||
Output_8b(ALU_any_int());
|
output_8(ALU_any_int());
|
||||||
}
|
}
|
||||||
} while (Input_accept_comma());
|
} while (Input_accept_comma());
|
||||||
Encoding_encode_char = outer_encoder; // reactivate buffered encoder
|
Encoding_encode_char = outer_encoder; // reactivate buffered encoder
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "global.h"
|
#include "global.h" // FIXME - remove when no longer needed
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "mnemo.h"
|
#include "mnemo.h"
|
||||||
|
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "pseudoopcodes.h"
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
@ -98,7 +99,6 @@ const char Byte_flags[256] = {
|
|||||||
|
|
||||||
|
|
||||||
// variables
|
// 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)
|
int pass_count; // number of current pass (starts 0)
|
||||||
char GotByte; // Last byte read (processed)
|
char GotByte; // Last byte read (processed)
|
||||||
int Process_verbosity = 0; // Level of additional output
|
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
|
// re-definitions of program counter change segment
|
||||||
if (GotByte == '=') {
|
if (GotByte == '=') {
|
||||||
GetByte(); // proceed with next char
|
GetByte(); // proceed with next char
|
||||||
PO_setpc();
|
notreallypo_setpc();
|
||||||
Input_ensure_EOS();
|
Input_ensure_EOS();
|
||||||
} else {
|
} else {
|
||||||
Throw_error(exception_syntax);
|
Throw_error(exception_syntax);
|
||||||
@ -155,6 +155,8 @@ static void parse_pseudo_opcode(void) // Now GotByte = "!"
|
|||||||
GetByte(); // read next byte
|
GetByte(); // read next byte
|
||||||
// on missing keyword, return (complaining will have been done)
|
// on missing keyword, return (complaining will have been done)
|
||||||
if (Input_read_and_lower_keyword()) {
|
if (Input_read_and_lower_keyword()) {
|
||||||
|
|
||||||
|
// move this to pseudoopcodes.c:
|
||||||
// search for tree item
|
// search for tree item
|
||||||
if ((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
|
if ((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
|
||||||
&& node_body) {
|
&& node_body) {
|
||||||
|
@ -54,9 +54,6 @@ extern const char Byte_flags[];
|
|||||||
// bits 2, 1 and 0 are currently unused
|
// 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
|
// structures
|
||||||
// different ways to handle end-of-statement:
|
// different ways to handle end-of-statement:
|
||||||
enum eos {
|
enum eos {
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "global.h"
|
#include "global.h" // FIXME - remove when no longer needed
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
#include "tree.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);
|
Output_byte(opcode);
|
||||||
// this fn has its own range check (see above).
|
// this fn has its own range check (see above).
|
||||||
// No reason to irritate the user with another error message,
|
// No reason to irritate the user with another error message,
|
||||||
// so use Output_byte() instead of Output_8b()
|
// so use Output_byte() instead of output_8()
|
||||||
//Output_8b(offset);
|
//output_8(offset);
|
||||||
Output_byte(offset);
|
Output_byte(offset);
|
||||||
Input_ensure_EOS();
|
Input_ensure_EOS();
|
||||||
}
|
}
|
||||||
@ -653,7 +653,7 @@ static void group_only_relative16_addressing(int opcode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Output_byte(opcode);
|
Output_byte(opcode);
|
||||||
Output_16b(offset);
|
output_le16(offset);
|
||||||
Input_ensure_EOS();
|
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)) {
|
switch (calc_arg_size(force_bit, result, addressing_modes)) {
|
||||||
case MVALUE_FORCE08:
|
case MVALUE_FORCE08:
|
||||||
Output_byte(opcodes & 255);
|
Output_byte(opcodes & 255);
|
||||||
Output_8b(result->val.intval);
|
output_8(result->val.intval);
|
||||||
break;
|
break;
|
||||||
case MVALUE_FORCE16:
|
case MVALUE_FORCE16:
|
||||||
Output_byte((opcodes >> 8) & 255);
|
Output_byte((opcodes >> 8) & 255);
|
||||||
Output_16b(result->val.intval);
|
output_le16(result->val.intval);
|
||||||
break;
|
break;
|
||||||
case MVALUE_FORCE24:
|
case MVALUE_FORCE24:
|
||||||
Output_byte((opcodes >> 16) & 255);
|
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()) {
|
if (Input_accept_comma()) {
|
||||||
target = ALU_any_int(); // machine language:
|
target = ALU_any_int(); // machine language:
|
||||||
Output_byte(opcode); // opcode
|
Output_byte(opcode); // opcode
|
||||||
Output_8b(target); // target
|
output_8(target); // target
|
||||||
Output_8b(source); // source
|
output_8(source); // source
|
||||||
Input_ensure_EOS();
|
Input_ensure_EOS();
|
||||||
} else {
|
} else {
|
||||||
Throw_error(exception_syntax);
|
Throw_error(exception_syntax);
|
||||||
|
149
src/output.c
149
src/output.c
@ -46,13 +46,10 @@ struct output {
|
|||||||
struct {
|
struct {
|
||||||
intval_t start; // start of current segment (or NO_SEGMENT_START)
|
intval_t start; // start of current segment (or NO_SEGMENT_START)
|
||||||
intval_t max; // highest address segment may use
|
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
|
struct segment list_head; // head element of doubly-linked ring list
|
||||||
} segment;
|
} 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
|
// variables
|
||||||
@ -187,7 +184,7 @@ void Output_fake(int size)
|
|||||||
|
|
||||||
|
|
||||||
// output 8-bit value with range check
|
// output 8-bit value with range check
|
||||||
void Output_8b(intval_t value)
|
void output_8(intval_t value)
|
||||||
{
|
{
|
||||||
if ((value <= 0xff) && (value >= -0x80))
|
if ((value <= 0xff) && (value >= -0x80))
|
||||||
Output_byte(value);
|
Output_byte(value);
|
||||||
@ -197,7 +194,7 @@ void Output_8b(intval_t value)
|
|||||||
|
|
||||||
|
|
||||||
// output 16-bit value with range check
|
// output 16-bit value with range check
|
||||||
void Output_16b(intval_t value)
|
void output_le16(intval_t value)
|
||||||
{
|
{
|
||||||
if ((value <= 0xffff) && (value >= -0x8000)) {
|
if ((value <= 0xffff) && (value >= -0x8000)) {
|
||||||
Output_byte(value);
|
Output_byte(value);
|
||||||
@ -209,7 +206,7 @@ void Output_16b(intval_t value)
|
|||||||
|
|
||||||
|
|
||||||
// output 24-bit value with range check
|
// output 24-bit value with range check
|
||||||
void Output_24b(intval_t value)
|
void output_le24(intval_t value)
|
||||||
{
|
{
|
||||||
if ((value <= 0xffffff) && (value >= -0x800000)) {
|
if ((value <= 0xffffff) && (value >= -0x800000)) {
|
||||||
Output_byte(value);
|
Output_byte(value);
|
||||||
@ -222,7 +219,7 @@ void Output_24b(intval_t value)
|
|||||||
|
|
||||||
|
|
||||||
// output 32-bit value (without range check)
|
// output 32-bit value (without range check)
|
||||||
void Output_32b(intval_t value)
|
void output_le32(intval_t value)
|
||||||
{
|
{
|
||||||
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
|
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
|
||||||
Output_byte(value);
|
Output_byte(value);
|
||||||
@ -243,26 +240,16 @@ static void fill_completely(char value)
|
|||||||
|
|
||||||
|
|
||||||
// define default value for empty memory ("!initmem" pseudo opcode)
|
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||||
// FIXME - move to basics.c
|
// returns zero if ok, nonzero if already set
|
||||||
static enum eos PO_initmem(void)
|
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 MemInit flag is already set, complain
|
||||||
if (out->initvalue_set) {
|
if (out->initvalue_set) {
|
||||||
Throw_warning("Memory already initialised.");
|
Throw_warning("Memory already initialised.");
|
||||||
return SKIP_REMAINDER;
|
return 1; // failed
|
||||||
}
|
}
|
||||||
// set MemInit flag
|
// set MemInit flag
|
||||||
out->initvalue_set = TRUE;
|
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
|
// init memory
|
||||||
fill_completely(content);
|
fill_completely(content);
|
||||||
// enforce another pass
|
// 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
|
// 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.
|
// 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
|
// 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.
|
// try to set output format held in DynaBuf. Returns zero on success.
|
||||||
// FIXME - move to basics.c?
|
int output_set_output_format(void)
|
||||||
int Output_set_output_format(void)
|
|
||||||
{
|
{
|
||||||
void *node_body;
|
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))
|
if (!Tree_easy_scan(file_format_tree, &node_body, GlobalDynaBuf))
|
||||||
return FALSE;
|
return 1;
|
||||||
|
|
||||||
output_format = (enum output_format) node_body;
|
output_format = (enum output_format) node_body;
|
||||||
return TRUE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if file format was already chosen, returns zero.
|
||||||
// select output file and format ("!to" pseudo opcode)
|
// if file format isn't set, chooses CBM and returns 1.
|
||||||
// FIXME - move to basics.c
|
int output_prefer_cbm_file_format(void)
|
||||||
static enum eos PO_to(void)
|
|
||||||
{
|
{
|
||||||
// bugfix: first read filename, *then* check for first pass.
|
if (output_format != OUTPUT_FORMAT_UNSPECIFIED)
|
||||||
// if skipping right away, quoted colons might be misinterpreted as EOS
|
return 0;
|
||||||
// FIXME - why not just fix the skipping code to handle quotes? :)
|
output_format = OUTPUT_FORMAT_CBM;
|
||||||
// "!sl" has been fixed as well
|
return 1;
|
||||||
|
}
|
||||||
// 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;
|
|
||||||
|
|
||||||
|
// 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 file already chosen, complain and exit
|
||||||
if (output_filename) {
|
if (output_filename) {
|
||||||
Throw_warning("Output file already chosen.");
|
Throw_warning("Output file already chosen.");
|
||||||
return SKIP_REMAINDER;
|
return 1; // failed
|
||||||
}
|
}
|
||||||
|
|
||||||
// get malloc'd copy of filename
|
// get malloc'd copy of filename
|
||||||
output_filename = DynaBuf_get_copy(GlobalDynaBuf);
|
output_filename = DynaBuf_get_copy(GlobalDynaBuf);
|
||||||
// select output format
|
return 0; // ok
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// pseudo ocpode table
|
// init output struct (done later)
|
||||||
// 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)
|
|
||||||
void Output_init(signed long fill_value)
|
void Output_init(signed long fill_value)
|
||||||
{
|
{
|
||||||
out->buffer = safe_malloc(OUTBUFFERSIZE);
|
out->buffer = safe_malloc(OUTBUFFERSIZE);
|
||||||
@ -369,7 +316,6 @@ void Output_init(signed long fill_value)
|
|||||||
}
|
}
|
||||||
// init output buffer (fill memory with initial value)
|
// init output buffer (fill memory with initial value)
|
||||||
fill_completely(fill_value & 0xff);
|
fill_completely(fill_value & 0xff);
|
||||||
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);
|
|
||||||
// init ring list of segments
|
// init ring list of segments
|
||||||
out->segment.list_head.next = &out->segment.list_head;
|
out->segment.list_head.next = &out->segment.list_head;
|
||||||
out->segment.list_head.prev = &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!)
|
// 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.
|
// 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".
|
// 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
|
// get program counter
|
||||||
void vcpu_read_pc(struct result *target)
|
void vcpu_read_pc(struct result *target)
|
||||||
{
|
{
|
||||||
|
29
src/output.h
29
src/output.h
@ -13,6 +13,9 @@
|
|||||||
|
|
||||||
// constants
|
// constants
|
||||||
#define MEMINIT_USE_DEFAULT 256
|
#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
|
// current CPU state
|
||||||
@ -33,9 +36,7 @@ extern struct vcpu CPU_state; // current CPU state
|
|||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
|
|
||||||
// Init file format tree (is done early)
|
// alloc and init mem buffer (done later)
|
||||||
extern void Outputfile_init(void);
|
|
||||||
// alloc and init mem buffer, register pseudo opcodes (done later)
|
|
||||||
extern void Output_init(signed long fill_value);
|
extern void Output_init(signed long fill_value);
|
||||||
// clear segment list and disable output
|
// clear segment list and disable output
|
||||||
extern void Output_passinit(void);
|
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
|
// Send low byte of arg to output buffer and advance pointer
|
||||||
extern void (*Output_byte)(intval_t);
|
extern void (*Output_byte)(intval_t);
|
||||||
// Output 8-bit value with range check
|
// 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
|
// 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
|
// 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)
|
// Output 32-bit value (without range check)
|
||||||
extern void Output_32b(intval_t);
|
extern void output_le32(intval_t);
|
||||||
// Try to set output format held in DynaBuf. Returns whether succeeded.
|
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||||
extern int Output_set_output_format(void);
|
// 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
|
// write smallest-possible part of memory buffer to file
|
||||||
extern void Output_save_file(FILE *fd);
|
extern void Output_save_file(FILE *fd);
|
||||||
// Call when "* = EXPRESSION" is parsed
|
|
||||||
extern void PO_setpc(void);
|
|
||||||
// change output pointer and enable output
|
// change output pointer and enable output
|
||||||
extern void Output_start_segment(intval_t address_change, int segment_flags);
|
extern void Output_start_segment(intval_t address_change, int segment_flags);
|
||||||
// Show start and end of current segment
|
// Show start and end of current segment
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
// Copyright (C) 1998-2014 Marco Baye
|
// Copyright (C) 1998-2014 Marco Baye
|
||||||
// Have a look at "acme.c" for further info
|
// Have a look at "acme.c" for further info
|
||||||
//
|
//
|
||||||
// basic assembly stuff
|
// pseudo opcode stuff
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
//#include "acme.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "basics.h"
|
|
||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
@ -15,21 +15,111 @@
|
|||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "typesystem.h"
|
#include "typesystem.h"
|
||||||
|
#include "pseudoopcodes.h"
|
||||||
|
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
#define USERMSG_DYNABUF_INITIALSIZE 80
|
|
||||||
static const char s_08[] = "08";
|
static const char s_08[] = "08";
|
||||||
#define s_8 (s_08 + 1) // Yes, I know I'm sick
|
#define s_8 (s_08 + 1) // Yes, I know I'm sick
|
||||||
#define s_16 (s_65816 + 3) // Yes, I know I'm sick
|
#define s_16 (s_65816 + 3) // Yes, I know I'm sick
|
||||||
|
|
||||||
|
|
||||||
// variables
|
// 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
|
// 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
|
do
|
||||||
fn(ALU_any_int());
|
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)
|
// 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)
|
// 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)
|
// 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)
|
// 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
|
// Include binary file ("!binary" pseudo opcode)
|
||||||
static enum eos PO_binary(void)
|
// FIXME - split this into "parser" and "worker" fn and move worker fn somewhere else.
|
||||||
|
static enum eos po_binary(void)
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
int byte;
|
int byte;
|
||||||
@ -127,7 +218,7 @@ static enum eos PO_binary(void)
|
|||||||
|
|
||||||
|
|
||||||
// Reserve space by sending bytes of given value ("!fi" / "!fill" pseudo opcode)
|
// 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,
|
intval_t fill = FILLVALUE_FILL,
|
||||||
size = ALU_defined_int();
|
size = ALU_defined_int();
|
||||||
@ -135,13 +226,13 @@ static enum eos PO_fill(void)
|
|||||||
if (Input_accept_comma())
|
if (Input_accept_comma())
|
||||||
fill = ALU_any_int();
|
fill = ALU_any_int();
|
||||||
while (size--)
|
while (size--)
|
||||||
Output_8b(fill);
|
output_8(fill);
|
||||||
return ENSURE_EOS;
|
return ENSURE_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// force explicit label definitions to set "address" flag ("!addr"). Has to be re-entrant.
|
// 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();
|
SKIPSPACE();
|
||||||
if (GotByte == CHAR_SOB) {
|
if (GotByte == CHAR_SOB) {
|
||||||
@ -152,8 +243,23 @@ static enum eos PO_addr(void) // Now GotByte = illegal char
|
|||||||
return PARSE_REMAINDER;
|
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 *))
|
static enum eos throw_string(const char prefix[], void (*fn)(const char *))
|
||||||
{
|
{
|
||||||
struct result result;
|
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_debug(void)
|
||||||
//static enum eos PO_info(void)
|
//static enum eos po_info(void)
|
||||||
//{
|
//{
|
||||||
// return throw_string();
|
// return throw_string();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
// throw warning as given in source code
|
// 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);
|
return throw_string("!warn: ", Throw_warning);
|
||||||
|
|
||||||
@ -225,47 +331,50 @@ static enum eos PO_warn(void)
|
|||||||
|
|
||||||
|
|
||||||
// throw error as given in source code
|
// 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);
|
return throw_string("!error: ", Throw_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// throw serious error as given in source code
|
// 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);
|
return throw_string("!serious: ", Throw_serious_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// pseudo ocpode table
|
// pseudo opcode table
|
||||||
static struct ronode pseudo_opcodes[] = {
|
static struct ronode pseudo_opcodes[] = {
|
||||||
PREDEFNODE(s_08, PO_8),
|
PREDEFNODE("initmem", po_initmem),
|
||||||
PREDEFNODE(s_8, PO_8),
|
PREDEFNODE("to", po_to),
|
||||||
PREDEFNODE("by", PO_8),
|
PREDEFNODE(s_08, po_8),
|
||||||
PREDEFNODE("byte", PO_8),
|
PREDEFNODE(s_8, po_8),
|
||||||
PREDEFNODE(s_16, PO_16),
|
PREDEFNODE("by", po_8),
|
||||||
PREDEFNODE("wo", PO_16),
|
PREDEFNODE("byte", po_8),
|
||||||
PREDEFNODE("word", PO_16),
|
PREDEFNODE(s_16, po_16),
|
||||||
PREDEFNODE("24", PO_24),
|
PREDEFNODE("wo", po_16),
|
||||||
PREDEFNODE("32", PO_32),
|
PREDEFNODE("word", po_16),
|
||||||
PREDEFNODE("bin", PO_binary),
|
PREDEFNODE("24", po_24),
|
||||||
PREDEFNODE("binary", PO_binary),
|
PREDEFNODE("32", po_32),
|
||||||
PREDEFNODE("fi", PO_fill),
|
PREDEFNODE("bin", po_binary),
|
||||||
PREDEFNODE("fill", PO_fill),
|
PREDEFNODE("binary", po_binary),
|
||||||
PREDEFNODE("addr", PO_addr),
|
PREDEFNODE("fi", po_fill),
|
||||||
PREDEFNODE("address", PO_addr),
|
PREDEFNODE("fill", po_fill),
|
||||||
// PREDEFNODE("debug", PO_debug),
|
PREDEFNODE("addr", po_addr),
|
||||||
// PREDEFNODE("info", PO_info),
|
PREDEFNODE("address", po_addr),
|
||||||
PREDEFNODE("warn", PO_warn),
|
// PREDEFNODE("skip", po_skip),
|
||||||
PREDEFNODE(s_error, PO_error),
|
// PREDEFNODE("debug", po_debug),
|
||||||
PREDEFLAST("serious", PO_serious),
|
// PREDEFNODE("info", po_info),
|
||||||
|
PREDEFNODE("warn", po_warn),
|
||||||
|
PREDEFNODE(s_error, po_error),
|
||||||
|
PREDEFLAST("serious", po_serious),
|
||||||
// ^^^^ this marks the last element
|
// ^^^^ this marks the last element
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// register pseudo opcodes and create dynamic buffer
|
// register pseudo opcodes and create dynamic buffer
|
||||||
void Basics_init(void)
|
void pseudoopcodes_init(void)
|
||||||
{
|
{
|
||||||
user_message = DynaBuf_create(USERMSG_DYNABUF_INITIALSIZE);
|
user_message = DynaBuf_create(USERMSG_DYNABUF_INITIALSIZE);
|
||||||
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);
|
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
|
// Section stuff
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "global.h"
|
#include "global.h" // FIXME - remove when no longer needed
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
|
|
||||||
|
17
src/symbol.c
17
src/symbol.c
@ -11,10 +11,11 @@
|
|||||||
#include "acme.h"
|
#include "acme.h"
|
||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "dynabuf.h"
|
#include "dynabuf.h"
|
||||||
#include "global.h"
|
#include "global.h" // FIXME - remove when no longer needed
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "pseudoopcodes.h" // FIXME - remove when no longer needed
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
@ -26,7 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// variables
|
// 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
|
// 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);
|
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)
|
// register pseudo opcodes (done later)
|
||||||
void symbols_register_init(void)
|
void symbols_register_init(void)
|
||||||
|
@ -22,8 +22,6 @@ struct symbol {
|
|||||||
extern struct rwnode *symbols_forest[]; // trees (because of 8-bit hash)
|
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)
|
// register pseudo opcodes (done later)
|
||||||
extern void symbols_register_init(void);
|
extern void symbols_register_init(void);
|
||||||
// function acts upon the symbol's flag bits and produces an error if needed.
|
// function acts upon the symbol's flag bits and produces an error if needed.
|
||||||
|
Loading…
Reference in New Issue
Block a user