mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-29 04:49:20 +00:00
A bit more refactoring; no change in functionality.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@50 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
e042ec8602
commit
913d8cb005
@ -17,7 +17,7 @@
|
||||
|
||||
#define RELEASE "0.95.4" // update before release (FIXME)
|
||||
#define CODENAME "Fenchurch" // update before release
|
||||
#define CHANGE_DATE "4 Dec" // update before release
|
||||
#define CHANGE_DATE "5 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
|
||||
@ -246,7 +246,7 @@ static int perform_pass(void)
|
||||
// if start address was given on command line, use it:
|
||||
if (start_address != ILLEGAL_START_ADDRESS)
|
||||
vcpu_set_pc(start_address, 0);
|
||||
Encoding_passinit(); // set default encoding
|
||||
encoding_passinit(); // set default encoding
|
||||
Section_passinit(); // set initial zone (untitled)
|
||||
// init variables
|
||||
pass_undefined_count = 0; // no "NeedValue" errors yet
|
||||
|
@ -350,7 +350,7 @@ static void parse_quoted_character(char closing_quote)
|
||||
}
|
||||
|
||||
// parse character
|
||||
value = (intval_t) Encoding_encode_char(GotByte);
|
||||
value = (intval_t) encoding_encode_char(GotByte);
|
||||
// Read closing quote (hopefully)
|
||||
if (GetQuotedByte() == closing_quote)
|
||||
GetByte(); // if length == 1, proceed with next byte
|
||||
|
319
src/encoding.c
319
src/encoding.c
@ -16,43 +16,101 @@
|
||||
#include "tree.h"
|
||||
|
||||
|
||||
// Encoder function type definition
|
||||
typedef char (*encoder_t)(char) ;
|
||||
// struct definition
|
||||
struct encoder {
|
||||
char (*fn)(char);
|
||||
// maybe add table pointer?
|
||||
};
|
||||
|
||||
|
||||
// Constants
|
||||
// constants
|
||||
static const char s_pet[] = "pet";
|
||||
static const char s_raw[] = "raw";
|
||||
static const char s_scr[] = "scr";
|
||||
|
||||
|
||||
// Variables
|
||||
static char outermost_table[256]; // space for encoding table...
|
||||
static char *loaded_table = outermost_table; // ...loaded from file
|
||||
// predefined stuff
|
||||
static struct ronode *encoder_tree = NULL; // tree to hold encoders
|
||||
// variables
|
||||
static char outermost_table[256]; // space for encoding table...
|
||||
static char *loaded_table = outermost_table; // ...loaded from file
|
||||
static struct encoder *current_encoder; // gets set before each pass
|
||||
|
||||
|
||||
// Functions
|
||||
// encoder functions:
|
||||
|
||||
// convert character using current encoding
|
||||
// Conversion function pointer. No init needed: gets set before each pass.
|
||||
char (*Encoding_encode_char)(char);
|
||||
|
||||
// Insert string(s)
|
||||
static enum eos encode_string(encoder_t inner_encoder, char xor)
|
||||
// convert raw to raw (do not convert at all)
|
||||
static char encoderfn_raw(char byte)
|
||||
{
|
||||
encoder_t outer_encoder = Encoding_encode_char; // buffer encoder
|
||||
return byte;
|
||||
}
|
||||
// convert raw to petscii
|
||||
static char encoderfn_pet(char byte)
|
||||
{
|
||||
if ((byte >= 'A') && (byte <= 'Z'))
|
||||
return (char) (byte | 0x80); // FIXME - check why SAS-C
|
||||
if ((byte >= 'a') && (byte <= 'z')) // wants these casts.
|
||||
return (char) (byte - 32); // There are more below.
|
||||
return byte;
|
||||
}
|
||||
// convert raw to C64 screencode
|
||||
static char encoderfn_scr(char byte)
|
||||
{
|
||||
if ((byte >= 'a') && (byte <= 'z'))
|
||||
return (char) (byte - 96); // shift uppercase down
|
||||
if ((byte >= '[') && (byte <= '_'))
|
||||
return (char) (byte - 64); // shift [\]^_ down
|
||||
if (byte == '`')
|
||||
return 64; // shift ` down
|
||||
if (byte == '@')
|
||||
return 0; // shift @ down
|
||||
return byte;
|
||||
}
|
||||
// convert raw to whatever is defined in table
|
||||
static char encoderfn_file(char byte)
|
||||
{
|
||||
return loaded_table[(unsigned char) byte];
|
||||
}
|
||||
|
||||
|
||||
// predefined encoder structs:
|
||||
|
||||
|
||||
static struct encoder encoder_raw = {
|
||||
encoderfn_raw
|
||||
};
|
||||
static struct encoder encoder_pet = {
|
||||
encoderfn_pet
|
||||
};
|
||||
static struct encoder encoder_scr = {
|
||||
encoderfn_scr
|
||||
};
|
||||
static struct encoder encoder_file = {
|
||||
encoderfn_file
|
||||
};
|
||||
|
||||
|
||||
// functions
|
||||
|
||||
// convert character using current encoding (exported for use by alu.c)
|
||||
char encoding_encode_char(char byte)
|
||||
{
|
||||
return current_encoder->fn(byte);
|
||||
}
|
||||
|
||||
// insert string(s)
|
||||
static enum eos encode_string(struct encoder *inner_encoder, char xor)
|
||||
{
|
||||
struct encoder *outer_encoder = current_encoder; // buffer encoder
|
||||
|
||||
// make given encoder the current one (for ALU-parsed values)
|
||||
Encoding_encode_char = inner_encoder;
|
||||
current_encoder = inner_encoder;
|
||||
do {
|
||||
if (GotByte == '"') {
|
||||
// read initial character
|
||||
GetQuotedByte();
|
||||
// send characters until closing quote is reached
|
||||
while (GotByte && (GotByte != '"')) {
|
||||
output_8(xor ^ Encoding_encode_char(GotByte));
|
||||
output_8(xor ^ current_encoder->fn(GotByte));
|
||||
GetQuotedByte();
|
||||
}
|
||||
if (GotByte == CHAR_EOS)
|
||||
@ -67,99 +125,18 @@ static enum eos encode_string(encoder_t inner_encoder, char xor)
|
||||
output_8(ALU_any_int());
|
||||
}
|
||||
} while (Input_accept_comma());
|
||||
Encoding_encode_char = outer_encoder; // reactivate buffered encoder
|
||||
current_encoder = outer_encoder; // reactivate buffered encoder
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
// Insert text string (default format)
|
||||
static enum eos PO_text(void)
|
||||
{
|
||||
return encode_string(Encoding_encode_char, 0);
|
||||
}
|
||||
|
||||
// convert raw to raw (do not convert at all)
|
||||
static char encoder_raw(char byte)
|
||||
{
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Insert raw string
|
||||
static enum eos PO_raw(void)
|
||||
{
|
||||
return encode_string(encoder_raw, 0);
|
||||
}
|
||||
|
||||
// convert raw to petscii
|
||||
static char encoder_pet(char byte)
|
||||
{
|
||||
if ((byte >= 'A') && (byte <= 'Z'))
|
||||
return (char) (byte | 0x80); // FIXME - check why SAS-C
|
||||
if ((byte >= 'a') && (byte <= 'z')) // wants these casts.
|
||||
return (char) (byte - 32); // There are more below.
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Insert PetSCII string
|
||||
static enum eos PO_pet(void)
|
||||
{
|
||||
return encode_string(encoder_pet, 0);
|
||||
}
|
||||
|
||||
// convert raw to C64 screencode
|
||||
static char encoder_scr(char byte)
|
||||
{
|
||||
if ((byte >= 'a') && (byte <= 'z'))
|
||||
return (char) (byte - 96); // shift uppercase down
|
||||
if ((byte >= '[') && (byte <= '_'))
|
||||
return (char) (byte - 64); // shift [\]^_ down
|
||||
if (byte == '`')
|
||||
return 64; // shift ` down
|
||||
if (byte == '@')
|
||||
return 0; // shift @ down
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Insert screencode string
|
||||
static enum eos PO_scr(void)
|
||||
{
|
||||
return encode_string(encoder_scr, 0);
|
||||
}
|
||||
|
||||
// Insert screencode string, XOR'd
|
||||
static enum eos PO_scrxor(void)
|
||||
{
|
||||
intval_t num = ALU_any_int();
|
||||
|
||||
if (Input_accept_comma())
|
||||
return encode_string(encoder_scr, num);
|
||||
Throw_error(exception_syntax);
|
||||
return SKIP_REMAINDER;
|
||||
}
|
||||
|
||||
// "!cbm" pseudo opcode (now obsolete)
|
||||
static enum eos PO_cbm(void)
|
||||
{
|
||||
Throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead.");
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
//
|
||||
static char encoder_file(char byte)
|
||||
{
|
||||
return loaded_table[(unsigned char) byte];
|
||||
}
|
||||
|
||||
// read encoding table from file
|
||||
static enum eos user_defined_encoding(void)
|
||||
{
|
||||
FILE *fd;
|
||||
char local_table[256],
|
||||
*buffered_table = loaded_table;
|
||||
encoder_t buffered_encoder = Encoding_encode_char;
|
||||
struct encoder *buffered_encoder = current_encoder;
|
||||
|
||||
// if file name is missing, don't bother continuing
|
||||
if (Input_read_filename(TRUE))
|
||||
return SKIP_REMAINDER;
|
||||
fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY);
|
||||
if (fd) {
|
||||
if (fread(local_table, sizeof(char), 256, fd) != 256)
|
||||
@ -168,88 +145,146 @@ static enum eos user_defined_encoding(void)
|
||||
} else {
|
||||
Throw_error(exception_cannot_open_input_file);
|
||||
}
|
||||
Encoding_encode_char = encoder_file; // activate new encoding
|
||||
current_encoder = &encoder_file; // activate new encoding
|
||||
loaded_table = local_table; // activate local table
|
||||
// If there's a block, parse that and then restore old values
|
||||
if (Parse_optional_block())
|
||||
Encoding_encode_char = buffered_encoder;
|
||||
else
|
||||
if (Parse_optional_block()) {
|
||||
current_encoder = buffered_encoder;
|
||||
} else {
|
||||
// if there's *no* block, the table must be used from now on.
|
||||
// copy the local table to the "outer" table
|
||||
memcpy(buffered_table, local_table, 256);
|
||||
}
|
||||
// re-activate "outer" table (it might have been changed by memcpy())
|
||||
loaded_table = buffered_table;
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
// keywords for "!convtab" pseudo opcode
|
||||
static struct ronode *encoder_tree = NULL; // tree to hold encoders
|
||||
static struct ronode encoder_list[] = {
|
||||
//no! PREDEFNODE("file", &encoder_file), "!ct file" is not needed; just use {} after initial loading of table!
|
||||
PREDEFNODE(s_pet, &encoder_pet),
|
||||
PREDEFNODE(s_raw, &encoder_raw),
|
||||
PREDEFLAST(s_scr, &encoder_scr),
|
||||
// ^^^^ this marks the last element
|
||||
};
|
||||
|
||||
|
||||
// use one of the pre-defined encodings (raw, pet, scr)
|
||||
static enum eos predefined_encoding(void)
|
||||
{
|
||||
void *node_body;
|
||||
char local_table[256],
|
||||
*buffered_table = loaded_table;
|
||||
encoder_t buffered_encoder = Encoding_encode_char;
|
||||
struct encoder *buffered_encoder = current_encoder;
|
||||
|
||||
// use one of the pre-defined encodings
|
||||
if (Input_read_and_lower_keyword()) {
|
||||
// search for tree item
|
||||
if (Tree_easy_scan(encoder_tree, &node_body, GlobalDynaBuf))
|
||||
Encoding_encode_char = (encoder_t) node_body; // activate new encoder
|
||||
else
|
||||
// make sure tree is initialised
|
||||
if (encoder_tree == NULL)
|
||||
Tree_add_table(&encoder_tree, encoder_list);
|
||||
// perform lookup
|
||||
if (Tree_easy_scan(encoder_tree, &node_body, GlobalDynaBuf)) {
|
||||
current_encoder = (struct encoder *) node_body; // activate new encoder
|
||||
} else {
|
||||
Throw_error("Unknown encoding.");
|
||||
}
|
||||
}
|
||||
loaded_table = local_table; // activate local table
|
||||
// If there's a block, parse that and then restore old values
|
||||
if (Parse_optional_block())
|
||||
Encoding_encode_char = buffered_encoder;
|
||||
current_encoder = buffered_encoder;
|
||||
// re-activate "outer" table
|
||||
loaded_table = buffered_table;
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
// Set current encoding ("!convtab" pseudo opcode)
|
||||
static enum eos PO_convtab(void)
|
||||
|
||||
// exported functions
|
||||
|
||||
// set "raw" as default encoding
|
||||
void encoding_passinit(void)
|
||||
{
|
||||
if ((GotByte == '<') || (GotByte == '"'))
|
||||
current_encoder = &encoder_raw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// FIXME - move this to pseudoopcodes.c:
|
||||
|
||||
// insert text string (default format)
|
||||
static enum eos po_text(void)
|
||||
{
|
||||
return encode_string(current_encoder, 0);
|
||||
}
|
||||
|
||||
// insert raw string
|
||||
static enum eos po_raw(void)
|
||||
{
|
||||
return encode_string(&encoder_raw, 0);
|
||||
}
|
||||
|
||||
// insert PetSCII string
|
||||
static enum eos po_pet(void)
|
||||
{
|
||||
return encode_string(&encoder_pet, 0);
|
||||
}
|
||||
|
||||
// insert screencode string
|
||||
static enum eos po_scr(void)
|
||||
{
|
||||
return encode_string(&encoder_scr, 0);
|
||||
}
|
||||
|
||||
// insert screencode string, XOR'd
|
||||
static enum eos po_scrxor(void)
|
||||
{
|
||||
intval_t num = ALU_any_int();
|
||||
|
||||
if (Input_accept_comma() == FALSE) {
|
||||
Throw_error(exception_syntax);
|
||||
return SKIP_REMAINDER;
|
||||
}
|
||||
return encode_string(&encoder_scr, num);
|
||||
}
|
||||
|
||||
// "!cbm" pseudo opcode (now obsolete)
|
||||
static enum eos po_cbm(void)
|
||||
{
|
||||
Throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead.");
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
// Set current encoding ("!convtab" pseudo opcode)
|
||||
static enum eos po_convtab(void)
|
||||
{
|
||||
if ((GotByte == '<') || (GotByte == '"')) {
|
||||
// if file name is missing, don't bother continuing
|
||||
if (Input_read_filename(TRUE))
|
||||
return SKIP_REMAINDER;
|
||||
return user_defined_encoding();
|
||||
else
|
||||
} else {
|
||||
return predefined_encoding();
|
||||
}
|
||||
}
|
||||
|
||||
// pseudo opcode table
|
||||
static struct ronode pseudo_opcodes[] = {
|
||||
PREDEFNODE(s_cbm, PO_cbm),
|
||||
PREDEFNODE("ct", PO_convtab),
|
||||
PREDEFNODE("convtab", PO_convtab),
|
||||
PREDEFNODE(s_pet, PO_pet),
|
||||
PREDEFNODE(s_raw, PO_raw),
|
||||
PREDEFNODE(s_scr, PO_scr),
|
||||
PREDEFNODE(s_scrxor, PO_scrxor),
|
||||
PREDEFNODE("text", PO_text),
|
||||
PREDEFLAST("tx", PO_text),
|
||||
PREDEFNODE(s_cbm, po_cbm),
|
||||
PREDEFNODE("ct", po_convtab),
|
||||
PREDEFNODE("convtab", po_convtab),
|
||||
PREDEFNODE(s_pet, po_pet),
|
||||
PREDEFNODE(s_raw, po_raw),
|
||||
PREDEFNODE(s_scr, po_scr),
|
||||
PREDEFNODE(s_scrxor, po_scrxor),
|
||||
PREDEFNODE("text", po_text),
|
||||
PREDEFLAST("tx", po_text),
|
||||
// ^^^^ this marks the last element
|
||||
};
|
||||
|
||||
// keywords for "!convtab" pseudo opcode
|
||||
static struct ronode encoders[] = {
|
||||
PREDEFNODE(s_pet, encoder_pet),
|
||||
PREDEFNODE(s_raw, encoder_raw),
|
||||
PREDEFLAST(s_scr, encoder_scr),
|
||||
// ^^^^ this marks the last element
|
||||
};
|
||||
|
||||
|
||||
// Exported functions
|
||||
|
||||
// register pseudo opcodes and build keyword tree for encoders
|
||||
// register pseudo opcodes
|
||||
void Encoding_init(void)
|
||||
{
|
||||
Tree_add_table(&encoder_tree, encoders);
|
||||
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);
|
||||
}
|
||||
|
||||
// Set "raw" as default encoding
|
||||
void Encoding_passinit(void)
|
||||
{
|
||||
Encoding_encode_char = encoder_raw;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ACME - a crossassembler for producing 6502/65c02/65816 code.
|
||||
// Copyright (C) 1998-2009 Marco Baye
|
||||
// Copyright (C) 1998-2014 Marco Baye
|
||||
// Have a look at "acme.c" for further info
|
||||
//
|
||||
// Character encoding stuff
|
||||
@ -7,14 +7,14 @@
|
||||
#define encoding_H
|
||||
|
||||
|
||||
// Prototypes
|
||||
// prototypes
|
||||
|
||||
// register pseudo opcodes and build keyword tree for encoders
|
||||
// register pseudo opcodes (FIXME - remove!)
|
||||
extern void Encoding_init(void);
|
||||
// convert character using current encoding
|
||||
extern char (*Encoding_encode_char)(char);
|
||||
// Set "raw" as default encoding
|
||||
extern void Encoding_passinit(void);
|
||||
extern char encoding_encode_char(char);
|
||||
// set "raw" as default encoding
|
||||
extern void encoding_passinit(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -59,8 +59,6 @@ static struct output *out = &default_output;
|
||||
struct vcpu CPU_state; // current CPU state
|
||||
|
||||
// FIXME - move file format stuff to some other .c file!
|
||||
// predefined stuff
|
||||
static struct ronode *file_format_tree = NULL; // tree to hold output formats
|
||||
// possible file formats
|
||||
enum output_format {
|
||||
OUTPUT_FORMAT_UNSPECIFIED, // default (uses "plain" actually)
|
||||
@ -68,7 +66,9 @@ enum output_format {
|
||||
OUTPUT_FORMAT_CBM, // load address, code (default for "!to" pseudo opcode)
|
||||
OUTPUT_FORMAT_PLAIN // code only
|
||||
};
|
||||
static struct ronode file_formats[] = {
|
||||
// predefined stuff
|
||||
static struct ronode *file_format_tree = NULL; // tree to hold output formats
|
||||
static struct ronode file_format_list[] = {
|
||||
PREDEFNODE("apple", OUTPUT_FORMAT_APPLE),
|
||||
PREDEFNODE(s_cbm, OUTPUT_FORMAT_CBM),
|
||||
// PREDEFNODE("o65", OUTPUT_FORMAT_O65),
|
||||
@ -269,7 +269,7 @@ int output_set_output_format(void)
|
||||
|
||||
// make sure tree is initialised
|
||||
if (file_format_tree == NULL)
|
||||
Tree_add_table(&file_format_tree, file_formats);
|
||||
Tree_add_table(&file_format_tree, file_format_list);
|
||||
// perform lookup
|
||||
if (!Tree_easy_scan(file_format_tree, &node_body, GlobalDynaBuf))
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user