updated "toacme" sources to version 0.11 from 2012-10-08 (source cleanup)

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@59 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2015-02-12 00:43:02 +00:00
parent b11d8771e6
commit b451573f00
26 changed files with 826 additions and 752 deletions

View File

@ -1,4 +1,8 @@
2012-10-08
Release 0.11
Beautified source, and added space after ',' in addressing modes.
2006-10-04
Release 0.10
Adjusted support for illegals to latest changes in ACME.

View File

@ -11,9 +11,9 @@
#include "scr2iso.h"
// Constants
// constants
// Generate error/warning messages
// generate error/warning messages
const char error_unknown_addressing[] = "Conversion failed: AssBlaster file contains unknown addressing mode.\n";
const char error_unknown_compression[] = "Conversion failed: AssBlaster file contains unknown number compression.\n";
const char warning_unknown_number_format[] = "Warning: AssBlaster file uses unknown number format. Fallback to hexadecimal.\n";
@ -43,19 +43,19 @@ const char warning_unknown_number_format[] = "Warning: AssBlaster file uses unkn
// after mnemonic or pseudo opcode, numbers may follow:
#define AB_NUMVAL_FLAGBIT 0x80 // indicates packed number
// Pre- and postfixes for addressing modes
// Don't care whether argument is 8, 16 or 24 bits wide
const char* addressing_modes[][2] = {
// pre- and postfixes for addressing modes
// don't care whether argument is 8, 16 or 24 bits wide
const char *addressing_modes[][2] = {
{"", "" }, // ($00=%.....) implied
{" ", "" }, // ($01=%....1) absolute
{" ", ",x" }, // ($02=%...1.) absolute,x
{" ", ",y" }, // ($03=%...11) absolute,y
{" ", ", x" }, // ($02=%...1.) absolute,x
{" ", ", y" }, // ($03=%...11) absolute,y
{" #", "" }, // ($04=%..1..) immediate
{NULL, NULL }, // ($05=%..1.1) unused (indirect-y)
{NULL, NULL }, // ($06=%..11.) unused (indirect-y)
{NULL, NULL }, // ($07=%..111) unused (indirect-y)
{" (", "),y" }, // ($08=%.1...) indirect-y
{" (", ",x)" }, // ($09=%.1..1) indirect-x
{" (", "), y" }, // ($08=%.1...) indirect-y
{" (", ", x)" }, // ($09=%.1..1) indirect-x
{" ", "" }, // ($0a=%.1.1.) relative (=absolute, actually)
{" (", ")" }, // ($0b=%.1.11) indirect
// above: used by both AB3 and F8AB (except $0a, which is no longer
@ -71,10 +71,10 @@ const char* addressing_modes[][2] = {
#define MVP_MVN_ADDRMODE 0x10
{NULL, NULL }, // ($11=%1...1) unused (indirect)
{NULL, NULL }, // ($12=%1..1.) unused (indirect long)
{" [", "],y" }, // ($13=%1..11) indirect-y long
{" [", "], y" }, // ($13=%1..11) indirect-y long
{NULL, NULL }, // ($14=%1.1..) unused (absolute)
{" ", ",s" }, // ($15=%1.1.1) stack-relative
{" (", ",s),y" }, // ($16=%1.11.) stack-relative-indirect-y
{" ", ", s" }, // ($15=%1.1.1) stack-relative
{" (", ", s), y" }, // ($16=%1.11.) stack-relative-indirect-y
// from here on, unused (indirect-y)
// addressing mode $10 (for MVP/MVN) is displayed and stored by F8AB
// as "arg1.arg2" instead of "arg1,arg2". Therefore the following
@ -82,150 +82,170 @@ const char* addressing_modes[][2] = {
};
// Variables
struct ab_t* conf;
// variables
struct ab *conf;
// Functions
// functions
//
static void generate_errors(int err_bits) {
if(err_bits & AB_ERRBIT_UNKNOWN_ADDRMODE) {
static void generate_errors(int err_bits)
{
if (err_bits & AB_ERRBIT_UNKNOWN_ADDRMODE) {
fputs(error_unknown_addressing, stderr);
fprintf(global_output_stream, "; ToACME: %s", error_unknown_addressing);
}
if(err_bits & AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION) {
if (err_bits & AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION) {
fputs(error_unknown_compression, stderr);
fprintf(global_output_stream, "; ToACME: %s", error_unknown_compression);
}
if(err_bits & AB_ERRBIT_UNKNOWN_NUMBER_FORMAT) {
if (err_bits & AB_ERRBIT_UNKNOWN_NUMBER_FORMAT) {
fputs(warning_unknown_number_format, stderr);
fprintf(global_output_stream, "; ToACME: %s", warning_unknown_number_format);
}
}
// Convert macro/label name character.
// convert macro/label name character.
// AssBlaster allows '^', '[' and ']' in names, so replace these chars.
static char conv_name_char(char byte) {
static char conv_name_char(char byte)
{
byte = SCR2ISO(byte);
switch(byte) {
case 0x40:
return(AB_LABELSPECIAL_NUL);
case '[':
return(AB_LABELSPECIAL_LEFT);
case '\\':
return(AB_LABELSPECIAL_BACK);
case ']':
return(AB_LABELSPECIAL_RIGHT);
case '^':
return(AB_LABELSPECIAL_UP);
default:
return(byte);
switch (byte) {
case 0x40:
return AB_LABELSPECIAL_NUL;
case '[':
return AB_LABELSPECIAL_LEFT;
case '\\':
return AB_LABELSPECIAL_BACK;
case ']':
return AB_LABELSPECIAL_RIGHT;
case '^':
return AB_LABELSPECIAL_UP;
default:
return byte;
}
}
// Output binary representation of value
void AB_output_binary(unsigned long int value) {
// output binary representation of value
void AB_output_binary(unsigned long int value)
{
int mask = 128;
if(value > 0xff)
if (value > 0xff)
AB_output_binary(value >> 8);
value &= 0xff;
while(mask) {
while (mask) {
IO_put_byte((value & mask) ? '1' : '0');
mask >>= 1;
}
}
// Output hex representation of value
void AB_output_hexadecimal(unsigned long int value) {
if(value > 0xff)
// output hex representation of value
void AB_output_hexadecimal(unsigned long int value)
{
if (value > 0xff)
AB_output_hexadecimal(value >> 8);
IO_put_low_byte_hex(value);
}
// Convert and send macro/label name (until illegal character comes along)
static void pipe_global_name(void) {
while((GotByte < 0x20) || ((GotByte >= '0') && (GotByte <= '9'))) {
// convert and send macro/label name (until illegal character comes along)
static void pipe_global_name(void)
{
while ((GotByte < 0x20) || ((GotByte >= '0') && (GotByte <= '9'))) {
IO_put_byte(conv_name_char(GotByte));
IO_get_byte();
}
}
// Convert and send label name (until illegal character comes along)
// Level 1
static void pipe_name(void) {
// convert and send label name (until illegal character comes along)
// level 1
static void pipe_name(void)
{
// Dieser kleine Hack macht alle lokalen ABL-Labels
// Auch unter ACME lokal. nur mit '^' global markierte
// Labels werden auch global übernommen ...
if(GotByte == SCREENCODE_UPARROW)
if (GotByte == SCREENCODE_UPARROW)
IO_get_byte(); // global: ^witharrow => witharrow
else
IO_put_byte('.'); // local: allothers => .allothers
pipe_global_name(); // this does exactly what is needed
}
// Parse quoted strings
static void parse_quoted(void) {// now GotByte = unhandled opening quote
// parse quoted strings
static void parse_quoted(void) // now GotByte = unhandled opening quote
{
IO_put_byte('"');
IO_get_byte();
while((GotByte != AB_ENDOFLINE) && (GotByte != '"')) {
while ((GotByte != AB_ENDOFLINE) && (GotByte != '"')) {
IO_put_byte(SCR2ISO(GotByte));
IO_get_byte();
}
IO_put_byte('"');
// Closing quote is handled, but EndOfLine must remain unhandled
if(GotByte == '"')
// closing quote is handled, but EndOfLine must remain unhandled
if (GotByte == '"')
IO_get_byte();
}
// Parse label names, quoted strings, operators, literal values etc.
// Read until AB_ENDOFLINE or AB_COMMENT. Returns error bits.
// Level 1
// parse label names, quoted strings, operators, literal values etc.
// read until AB_ENDOFLINE or AB_COMMENT. Returns error bits.
// level 1
// AB uses a full stop character ('.') in some inconvenient places, for example
// after macro names (at definitions and calls) and in the MVP/MVN addressing
// mode. The kluge variable "dot_replacement" is used to replace the '.'
// character with the correct character for ACME.
static int parse_unspecified(char dot_replacement) {
static int parse_unspecified(char dot_replacement)
{
int err_bits = 0;
while((GotByte != AB_ENDOFLINE) && (GotByte != AB_COMMENT)) {
while ((GotByte != AB_ENDOFLINE) && (GotByte != AB_COMMENT)) {
// kluge: replace '.' character with current replacement and
// remember not to replace anymore from now on.
if(GotByte == '.') {
if (GotByte == '.') {
GotByte = dot_replacement; // use replacement
dot_replacement = '.'; // in future, keep
}
if(GotByte & AB_NUMVAL_FLAGBIT)
if (GotByte & AB_NUMVAL_FLAGBIT) {
err_bits |= conf->number_parser();
else {
if(GotByte < 0x20)
pipe_name();
else {
if(GotByte == '"')
parse_quoted();
else {
IO_put_byte(SCR2ISO(GotByte));
IO_get_byte();
}
}
continue;
}
if (GotByte < 0x20) {
pipe_name();
continue;
}
if (GotByte == '"') {
parse_quoted();
continue;
}
IO_put_byte(SCR2ISO(GotByte));
IO_get_byte();
}
return(err_bits);
return err_bits;
}
// Parse macro call or start of definition (beware of full stops).
// Returns error bits.
static int parse_macro_stuff(void) { // now GotByte = unhandled byte
// parse macro call or start of definition (beware of full stops).
// returns error bits.
static int parse_macro_stuff(void) // now GotByte = unhandled byte
{
// I guess local macros are useless, so don't
// do the scope fixing as for macro names!
pipe_global_name();
return(parse_unspecified(SPACE)); // output macro arguments
return parse_unspecified(SPACE); // output macro arguments
}
// Process mnemonics (real opcodes). Returns error bits.
// Level 1
static int parse_mnemo(int mnemonic_offset) {
// process mnemonics (real opcodes). returns error bits.
// level 1
static int parse_mnemo(int mnemonic_offset)
{
const char *mnemonic,
*pre,
*post;
@ -236,16 +256,16 @@ static int parse_mnemo(int mnemonic_offset) {
addressing_mode = IO_get_byte(); // get addressing mode
IO_get_byte(); // and fetch next (not handled here)
mnemonic = conf->mnemonics[mnemonic_offset];
if(mnemonic == NULL) {
if (mnemonic == NULL) {
fputs("Found unused mnemo code in input file.\n", stderr);
mnemonic = "!error \"ToACME found unused mnemo code in input file\":";
}
fprintf(global_output_stream, "\t\t%s", mnemonic);
// determine prefix and postfix of addressing mode
if(addressing_mode < conf->address_mode_count) {
if (addressing_mode < conf->address_mode_count) {
pre = addressing_modes[addressing_mode][0];
post = addressing_modes[addressing_mode][1];
if(addressing_mode == MVP_MVN_ADDRMODE)
if (addressing_mode == MVP_MVN_ADDRMODE)
dot_replacement = ','; // replace '.' with ','
} else {
pre = NULL;
@ -253,132 +273,127 @@ static int parse_mnemo(int mnemonic_offset) {
}
// if addressing mode is invalid, set error bit
// output prefix (or space if invalid)
if((pre == NULL) || (post == NULL)) {
if ((pre == NULL) || (post == NULL)) {
err_bits |= AB_ERRBIT_UNKNOWN_ADDRMODE;
fprintf(stderr, "Found an unknown addressing mode bit pattern ($%x). Please tell my programmer.\n", addressing_mode);
}
if(pre)
if (pre)
IO_put_string(pre);
else
IO_put_byte(SPACE);
err_bits |= parse_unspecified(dot_replacement); // output arg
if(post) {
if (post)
IO_put_string(post);
}
return(err_bits);
return err_bits;
}
// Process pseudo opcodes. Returns error bits.
// Level 1
static int parse_pseudo_opcode(int pseudo_offset) {
const char* pseudo_opcode;
// process pseudo opcodes. returns error bits.
// level 1
static int parse_pseudo_opcode(int pseudo_offset)
{
const char *pseudo_opcode;
int err_bits = 0;
IO_get_byte(); // and fetch next (not handled here)
IO_put_string("\t\t");
pseudo_opcode = conf->pseudo_opcodes[pseudo_offset];
if(pseudo_opcode)
if (pseudo_opcode)
IO_put_string(pseudo_opcode);
// check for special cases
switch(pseudo_offset) {
case AB_PSEUDOOFFSET_MACROCALL: // (in ACME: '+')
switch (pseudo_offset) {
case AB_PSEUDOOFFSET_MACROCALL: // (in ACME: '+')
// ACME does not like spaces after the macro call char
err_bits |= parse_macro_stuff();
break;
case AB_PSEUDOOFFSET_MACRODEF: // macro definition
IO_put_byte(SPACE);// but here a space looks good :)
case AB_PSEUDOOFFSET_MACRODEF: // macro definition
IO_put_byte(SPACE); // but here a space looks good :)
err_bits |= parse_macro_stuff();
IO_put_string(" {");
break;
case AB_PSEUDOOFFSET_OUTFILE: // outfile selection
IO_put_byte(SPACE);// but here a space looks good :)
case AB_PSEUDOOFFSET_OUTFILE: // outfile selection
IO_put_byte(SPACE); // but here a space looks good :)
err_bits |= parse_unspecified('.'); // output arg(s)
IO_put_string(ACME_cbmformat);
break;
default: // all other pseudo opcodes
if((pseudo_opcode)
default: // all other pseudo opcodes
if ((pseudo_opcode)
&& (GotByte != AB_ENDOFLINE)
&& (GotByte != AB_COMMENT))
IO_put_byte(SPACE);// but here a space looks good :)
IO_put_byte(SPACE); // but here a space looks good :)
err_bits |= parse_unspecified('.'); // output pseudo opcode's arg(s)
}
return(err_bits);
return err_bits;
}
// Main routine for AssBlaster conversion (works for both AB3 and F8AB).
// Call with first byte of first line pre-read (in GotByte)!
void AB_main(struct ab_t* client_config) {
// main routine for AssBlaster conversion (works for both AB3 and F8AB).
// call with first byte of first line pre-read (in GotByte)!
void AB_main(struct ab *client_config)
{
int err_bits;
const char *comment_indent;
conf = client_config;
ACME_switch_to_pet();
// convert lines until EndOfFile
while(!IO_reached_eof) {
while (!IO_reached_eof) {
err_bits = 0; // no errors yet (in this line)
comment_indent = "\t";
if(GotByte < AB_FIRST_MNEMONIC) {
switch(GotByte) {
case 0: // empty line
if (GotByte < AB_FIRST_MNEMONIC) {
switch (GotByte) {
case 0: // empty line
IO_get_byte(); // skip this byte
break;
case AB_COMMENT: // early comment
case AB_COMMENT: // early comment
comment_indent = "";
break; // ignore now, act later
case AB_SPACE: // empty line or late comment
case AB_SPACE: // empty line or late comment
comment_indent = "\t\t\t\t";
IO_get_byte(); // skip this space
// output whatever found
err_bits |= parse_unspecified('.');
break;
default: // implied label definition
default: // implied label definition
pipe_name();
}
} else if(GotByte < conf->first_pseudo_opcode) {
} else if (GotByte < conf->first_pseudo_opcode) {
err_bits |= parse_mnemo(GotByte - AB_FIRST_MNEMONIC);
} else if(GotByte < conf->first_unused_byte_value) {
} else if (GotByte < conf->first_unused_byte_value) {
err_bits |= parse_pseudo_opcode(GotByte - conf->first_pseudo_opcode);
} else if(GotByte != AB_ENDOFLINE) {
} else if (GotByte != AB_ENDOFLINE) {
fprintf(global_output_stream, "; ToACME: AssBlaster file used unknown code ($%x). ", GotByte);
IO_get_byte(); // fetch next
err_bits |= parse_unspecified('.');// output remainder
err_bits |= parse_unspecified('.'); // output remainder
}
// everything might be followed by a comment, so check
if(GotByte == AB_COMMENT) {
if (GotByte == AB_COMMENT) {
// skip empty comments by checking next byte
if(IO_get_byte() != AB_ENDOFLINE) {
if (IO_get_byte() != AB_ENDOFLINE) {
// something's there, so pipe until end of line
IO_put_string(comment_indent);
IO_put_byte(';');
do
IO_put_byte(SCR2ISO(GotByte));
while(IO_get_byte() != AB_ENDOFLINE);
while (IO_get_byte() != AB_ENDOFLINE);
}
}
// now check whether line generated any errors
if(err_bits)
if (err_bits)
generate_errors(err_bits);
// if not at end-of-line, something's fishy
if(GotByte != AB_ENDOFLINE) {
if(GotByte == '\0')
if (GotByte != AB_ENDOFLINE) {
if (GotByte == '\0') {
IO_put_string("; ToACME: found $00 - looks like end-of-file marker.");
else {
} else {
fputs("Found data instead of end-of-line indicator!?.\n", stderr);
IO_put_string("; ToACME: Garbage at end-of-line:");
do
IO_put_byte(SCR2ISO(GotByte));
while(IO_get_byte() != AB_ENDOFLINE);
while (IO_get_byte() != AB_ENDOFLINE);
}
}
IO_put_byte('\n');

View File

@ -6,14 +6,15 @@
#ifndef ab_H
#define ab_H
#include "config.h"
// Definition of "Type of AssBlaster" structure
struct ab_t {
int (*number_parser)(void);
const char** pseudo_opcodes;
const char** mnemonics;
struct ab {
int (*number_parser) (void);
const char **pseudo_opcodes;
const char **mnemonics;
int address_mode_count;
int first_pseudo_opcode;
int first_unused_byte_value;
@ -25,7 +26,7 @@ struct ab_t {
// meaning of internal error word. errors are collected until *after* a line
// has been finished so the warning messages don't interfere with the generated
// source code.
#define AB_ERRBIT_UNKNOWN_ADDRMODE (1u)
#define AB_ERRBIT_UNKNOWN_ADDRMODE (1u << 0)
#define AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION (1u << 1) // SIZEMASK invalid
#define AB_ERRBIT_UNKNOWN_NUMBER_FORMAT (1u << 2) // FORMATMASK invalid
@ -33,6 +34,7 @@ struct ab_t {
// Prototypes
extern void AB_output_binary(unsigned long int value);
extern void AB_output_hexadecimal(unsigned long int value);
extern void AB_main(struct ab_t* client_config);
extern void AB_main(struct ab *client_config);
#endif

View File

@ -14,12 +14,12 @@
#include "scr2iso.h"
// Constants
// constants
#define AB3_ADDRESSING_MODES 12
// Mnemonic table in AssBlaster 3.x order
static const char* mnemonic_table[] = {
static const char *mnemonic_table[] = {
NULL, // $80 unused
MnemonicCPX, // $81
MnemonicCPY, // $82
@ -72,8 +72,9 @@ static const char* mnemonic_table[] = {
MnemonicTXA, MnemonicTXS, MnemonicTYA, // $c5-$c7
};
// PseudoOpcode table in AssBlaster 3.x order
static const char* pseudo_opcode_table[] = {
static const char *pseudo_opcode_table[] = {
#define AB3_FIRST_PSEUDO_OPCODE 0xc8
NULL, // (la) $c8
// NULL because ACME does not need a pseudo opcode for label defs
@ -94,44 +95,42 @@ static const char* pseudo_opcode_table[] = {
// 0xd5-0xfe are unused in AB3
};
// Parse AssBlaster's packed number format. Returns error bits.
// parse AssBlaster's packed number format. returns error bits.
//#define AB_NUMVAL_FLAGBIT 0x80 // 10000000 indicates packed number
#define AB3_NUMVAL_ADD_1 0x40 // 01000000
#define AB3_NUMVAL_ADD_256 0x20 // 00100000
#define AB3_NUMVAL_FORMATMASK 0x1a // 00011010
#define AB3_NUMVAL__FORMAT_HEX 0x10 // 00010000=16 (oh my god, the base is
#define AB3_NUMVAL__FORMAT_HEX 0x10 // 00010000=16 (oh bob, the base is
#define AB3_NUMVAL__FORMAT_DEC 0x0a // 00001010=10 given directly, without
#define AB3_NUMVAL__FORMAT_BIN 0x02 // 00000010= 2 any encoding... :))
#define AB3_NUMVAL_SIZEMASK 0x05 // 00000101
#define AB3_NUMVAL__SIZE_0 0x01 // 00000001
#define AB3_NUMVAL__SIZE_1 0x04 // 00000100
#define AB3_NUMVAL__SIZE_2 0x00 // 00000000
static int parse_number(void) { // now GotByte = first byte of packed number
static int parse_number(void) // now GotByte = first byte of packed number
{
int flags = GotByte,
err_bits = 0;
unsigned long int value = 0,
add = 0;
// decode value
if(flags & AB3_NUMVAL_ADD_1)
if (flags & AB3_NUMVAL_ADD_1)
add += 1;
if(flags & AB3_NUMVAL_ADD_256)
if (flags & AB3_NUMVAL_ADD_256)
add += 256;
switch(flags & AB3_NUMVAL_SIZEMASK) {
case AB3_NUMVAL__SIZE_0:// no bytes follow (0, 1, 256, 257)
switch (flags & AB3_NUMVAL_SIZEMASK) {
case AB3_NUMVAL__SIZE_0: // no bytes follow (0, 1, 256, 257)
value = add;
break;
case AB3_NUMVAL__SIZE_1:// one byte follows (2 to 511)
case AB3_NUMVAL__SIZE_1: // one byte follows (2 to 511)
value = add + IO_get_byte();
break;
case AB3_NUMVAL__SIZE_2:// two bytes follow (512 to 65535)
case AB3_NUMVAL__SIZE_2: // two bytes follow (512 to 65535)
value = add + IO_get_le16();
break;
default: // unknown number compression
default: // unknown number compression
// remember to generate error
err_bits |= AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION;
}
@ -139,32 +138,29 @@ static int parse_number(void) { // now GotByte = first byte of packed number
IO_get_byte();
// decode output format
switch(flags & AB3_NUMVAL_FORMATMASK) {
case AB3_NUMVAL__FORMAT_BIN:
switch (flags & AB3_NUMVAL_FORMATMASK) {
case AB3_NUMVAL__FORMAT_BIN:
IO_put_byte('%');
AB_output_binary(value);
break;
case AB3_NUMVAL__FORMAT_DEC:
case AB3_NUMVAL__FORMAT_DEC:
fprintf(global_output_stream, "%lu", value);
break;
case AB3_NUMVAL__FORMAT_HEX:
case AB3_NUMVAL__FORMAT_HEX:
hex_fallback: IO_put_byte('$');
AB_output_hexadecimal(value);
break;
default: // unknown output format
default: // unknown output format
// remember to warn
err_bits |= AB_ERRBIT_UNKNOWN_NUMBER_FORMAT;
goto hex_fallback;
}
return(err_bits);
return err_bits;
}
// config struct for shared ab code
struct ab_t ab3_conf = {
struct ab ab3_conf = {
parse_number,
pseudo_opcode_table,
mnemonic_table,
@ -174,8 +170,10 @@ struct ab_t ab3_conf = {
AB3_FIRST_UNUSED_CODE,
};
// main
void ab3_main(void) {
void ab3_main(void)
{
IO_set_input_padding(AB_ENDOFLINE);
IO_put_string(
"; ToACME: Adding pseudo opcode to enable undocumented (\"illegal\") opcodes:\n"
@ -189,10 +187,11 @@ void ab3_main(void) {
);
IO_process_load_address();
// first byte after load address should be AB_ENDOFLINE in AB3 sources
if(IO_get_byte() == AB_ENDOFLINE) {
if (IO_get_byte() == AB_ENDOFLINE) {
IO_get_byte(); // skip it and pre-read first valid byte
fputs("Input has AB3 header.\n", stderr);
} else
} else {
fputs("Input does not have any known AB3 header.\n", stderr);
}
AB_main(&ab3_conf);
}

View File

@ -8,9 +8,9 @@
#include "io.h"
// Constants
// constants
// Pseudo opcodes
// pseudo opcodes
const char ACME_po_to[] = "!to";
const char ACME_cbmformat[] = ", cbm";
const char ACME_po_sl[] = "!sl";
@ -28,17 +28,18 @@ const char ACME_po_if[] = "!if";
const char ACME_else[] = "} else {";
const char ACME_endif[] = "}; (end of conditional assembly)\n";
const char ACME_po_eof[] = "!eof";
// Pseudo opcodes for 65816 (used by Flash8-AssBlaster)
// pseudo opcodes for 65816 (used by Flash8-AssBlaster)
const char ACME_po_al[] = "!al";
const char ACME_po_as[] = "!as";
const char ACME_po_rl[] = "!rl";
const char ACME_po_rs[] = "!rs";
// Functions
// functions
// Output pseudo opcode to make ACME use PetSCII encoding
void ACME_switch_to_pet(void) {
// output pseudo opcode to make ACME use PetSCII encoding
void ACME_switch_to_pet(void)
{
IO_put_string(
"; ToACME: Adding pseudo opcode to use PetSCII encoding by default:\n"
"!convtab pet\n"

View File

@ -7,7 +7,7 @@
#define acme_H
// Constants
// constants
// pseudo opcodes and related keywords
extern const char ACME_po_to[];
@ -34,8 +34,8 @@ extern const char ACME_po_rl[];
extern const char ACME_po_rs[];
// Prototypes
extern void ACME_switch_to_pet(void);
// prototypes
extern void ACME_switch_to_pet(void);
#endif

View File

@ -8,7 +8,7 @@
#define config_H
// Constants
// constants
#define SPACE 0x20
#define SHIFTSPACE 0xa0
@ -18,4 +18,5 @@ typedef int bool;
#define TRUE 1
#endif
#endif

View File

@ -14,12 +14,12 @@
#include "scr2iso.h"
// Constants
// constants
#define F8AB_ADDRESSING_MODES 23 // (FIXME - check back later!)
// Mnemonic table in Flash8-AssBlaster order (without: JML, WDM)
static const char* mnemonic_table[] = {
// mnemonic table in Flash8-AssBlaster order (without: JML, WDM)
static const char *mnemonic_table[] = {
MnemonicADC, // $80 6502
MnemonicAND, // $81 6502
MnemonicASL, // $82 6502
@ -116,8 +116,9 @@ static const char* mnemonic_table[] = {
MnemonicXCE, // $db 65816
};
// PseudoOpcode table in Flash8-AssBlaster order
static const char* pseudo_opcode_table[] = {
static const char *pseudo_opcode_table[] = {
#define F8AB_FIRST_PSEUDO_OPCODE 0xdc
NULL, // (la) $dc
// NULL because ACME does not need a pseudo opcode for label defs
@ -145,7 +146,8 @@ static const char* pseudo_opcode_table[] = {
// (FIXME - true? I only checked 0xed)
};
// Parse AssBlaster's packed number format. Returns error bits.
// parse AssBlaster's packed number format. returns error bits.
//#define AB_NUMVAL_FLAGBIT 0x80 // 10000000 indicates packed number
#define F8AB_NUMVAL_ADD_65536 0x40 // 01000000
#define F8AB_NUMVAL_ADD_256 0x20 // 00100000
@ -160,67 +162,60 @@ static const char* pseudo_opcode_table[] = {
#define F8AB_NUMVAL__SIZE_1 0x01 // 00000001
#define F8AB_NUMVAL__SIZE_2 0x02 // 00000010
#define F8AB_NUMVAL__SIZE_3 0x03 // 00000011
static int parse_number(void) { // now GotByte = first byte of packed number
static int parse_number(void) // now GotByte = first byte of packed number
{
int flags = GotByte,
err_bits = 0;
unsigned long int value = 0,
add = 0;
// decode value
if(flags & F8AB_NUMVAL_ADD_65536)
if (flags & F8AB_NUMVAL_ADD_65536)
add += 65536;
if(flags & F8AB_NUMVAL_ADD_256)
if (flags & F8AB_NUMVAL_ADD_256)
add += 256;
if(flags & F8AB_NUMVAL_ADD_1)
if (flags & F8AB_NUMVAL_ADD_1)
add += 1;
switch(flags & F8AB_NUMVAL_SIZEMASK) {
case F8AB_NUMVAL__SIZE_0:// no bytes follow (0, 1, 256, 257)
switch (flags & F8AB_NUMVAL_SIZEMASK) {
case F8AB_NUMVAL__SIZE_0: // no bytes follow (0, 1, 256, 257)
value = add;
break;
case F8AB_NUMVAL__SIZE_1:// one byte follows (2 to 511)
case F8AB_NUMVAL__SIZE_1: // one byte follows (2 to 511)
value = add + IO_get_byte();
break;
case F8AB_NUMVAL__SIZE_2:// two bytes follow (512 to 65535)
case F8AB_NUMVAL__SIZE_2: // two bytes follow (512 to 65535)
value = add + IO_get_le16();
break;
case F8AB_NUMVAL__SIZE_3:// three bytes follow (anything else)
case F8AB_NUMVAL__SIZE_3: // three bytes follow (anything else)
value = add + IO_get_le24();
}
// continue parsing on next byte
IO_get_byte();
// decode output format
switch(flags & F8AB_NUMVAL_FORMATMASK) {
case F8AB_NUMVAL__FORMAT_BIN:
switch (flags & F8AB_NUMVAL_FORMATMASK) {
case F8AB_NUMVAL__FORMAT_BIN:
IO_put_byte('%');
AB_output_binary(value);
break;
case F8AB_NUMVAL__FORMAT_DEC:
case F8AB_NUMVAL__FORMAT_DEC:
fprintf(global_output_stream, "%lu", value);
break;
case F8AB_NUMVAL__FORMAT_HEX:
case F8AB_NUMVAL__FORMAT_HEX:
hex_fallback: IO_put_byte('$');
AB_output_hexadecimal(value);
break;
default: // unknown output format
default: // unknown output format
// remember to warn
err_bits |= AB_ERRBIT_UNKNOWN_NUMBER_FORMAT;
goto hex_fallback;
}
return(err_bits);
return err_bits;
}
// config struct for shared ab code
struct ab_t f8ab_conf = {
struct ab f8ab_conf = {
parse_number,
pseudo_opcode_table,
mnemonic_table,
@ -230,9 +225,10 @@ struct ab_t f8ab_conf = {
F8AB_FIRST_UNUSED_CODE,
};
// main
void f8ab_main(void) {
const char* header_message;
const char *header_message;
header_message = "Input does not have any known F8AB header.\n";
IO_set_input_padding(AB_ENDOFLINE);
@ -253,11 +249,11 @@ void f8ab_main(void) {
// load_address_low, load_address_high, AB_ENDOFLINE, actual content
// newer versions of F8AB seem to use this:
// $ff, $00, $00, $03, AB_ENDOFLINE, actual content
if(IO_get_byte() == AB_ENDOFLINE) {
if (IO_get_byte() == AB_ENDOFLINE) {
IO_get_byte(); // skip it and pre-read first valid byte
header_message = "Input has F8AB 1.0 header.\n";
} else {
if((GotByte == 0)
if ((GotByte == 0)
&& (IO_get_byte() == 3)
&& (IO_get_byte() == AB_ENDOFLINE)) {
IO_get_byte();// skip and pre-read first valid byte

View File

@ -13,10 +13,10 @@
#include "pet2iso.h"
// Constants
// constants
// token-to-(pseudo)opcode conversion table (FIXME)
const char* giga_token[] = {
const char *giga_token[] = {
"FIXME-CALL", // $a0 .CALL
ACME_po_macro, // $a1 .MACRO (see MACRO_DEF_TOKEN below)
ACME_endmacro, // $a2 .ENDMACRO
@ -118,80 +118,79 @@ const char* giga_token[] = {
};
// Functions
// functions
// I don't know whether it's correct, but I had to start somewhere
#define FIRST_TOKEN 0xa0
#define MACRO_DEF_TOKEN 0xa1 // ugly kluge to add '{' at end of statement
#define MACRO_TEXT 0xa8 // ugly kluge for giga string specialties
#define MACRO_OUTFILE 0xa9 // ugly kluge for adding outfile format
// Process opcode or pseudo opcode (tokenized)
static int process_tokenized(void) {
const char* token;
// process opcode or pseudo opcode (tokenized)
static int process_tokenized(void)
{
const char *token;
int flags = 0;
if(GotByte < FIRST_TOKEN) {
if (GotByte < FIRST_TOKEN) {
// macro call?
IO_put_byte('+'); // add macro call character
// fprintf(global_output_stream, "small value:$%x", GotByte);
} else {
switch(GotByte) {
case MACRO_DEF_TOKEN:
switch (GotByte) {
case MACRO_DEF_TOKEN:
flags |= FLAG_ADD_LEFT_BRACE;
break;
case MACRO_TEXT:
case MACRO_TEXT:
flags |= FLAG_ADD_ZERO | FLAG_CHANGE_LEFTARROW;
break;
case MACRO_OUTFILE:
case MACRO_OUTFILE:
flags |= FLAG_ADD_CBM;
}
flags |= FLAG_INSERT_SPACE;
token = giga_token[GotByte - FIRST_TOKEN];
if(token != NULL)
if (token != NULL)
IO_put_string(token);
IO_get_byte();
}
return(flags);
return flags;
}
// When tokens are known, maybe use the PseudoOpcode function from hypra?
// ...for now deleted
// [...]
// Main routine for GigaAss conversion
void giga_main(void) {
// main routine for GigaAss conversion
void giga_main(void)
{
int indent;
IO_set_input_padding(0);
IO_process_load_address();
ACME_switch_to_pet();
// loop: once for every line in the file
while(!IO_reached_eof) {
while (!IO_reached_eof) {
// skip link pointer (if it's zero, report as end marker)
if(IO_get_le16() == 0)
if (IO_get_le16() == 0)
IO_put_string("; ToACME: Found BASIC end marker.\n");
IO_get_le16(); // skip line number
// process line
IO_get_byte();
if((GotByte == SPACE) || (GotByte == ';')
if ((GotByte == SPACE) || (GotByte == ';')
|| (GotByte == '\0') || (GotByte > 0x7f))
indent = 0;
else
indent = GigaHypra_label_definition();
// skip spaces
while(GotByte == SPACE)
while (GotByte == SPACE)
IO_get_byte();
// if there is an opcode, process it
if((GotByte != ';') && (GotByte != '\0')) {
if ((GotByte != ';') && (GotByte != '\0')) {
GigaHypra_indent(indent);
GigaHypra_argument(process_tokenized());
}
// skip comment, if there is one
if(GotByte == ';')
if (GotByte == ';')
GigaHypra_comment();
// end of line
IO_put_byte('\n');

View File

@ -11,49 +11,45 @@
// called with GotByte == ';'
void GigaHypra_comment(void) {
void GigaHypra_comment(void)
{
// check whether anything follows (empty comments => empty lines)
if(IO_get_byte()) {
if (IO_get_byte()) {
IO_put_byte(';');
do
IO_put_byte(PET2ISO(GotByte));
while(IO_get_byte());
while (IO_get_byte());
}
}
// Process operator
void GigaHypra_operator(void) {// '!' was last read
// process operator
void GigaHypra_operator(void) // '!' was last read
{
char middle = PET2ISO(IO_get_byte());
if((middle != ';') && (middle != '\0')) {
if(IO_get_byte() == '!') {
switch(middle) {
case 'n':
if ((middle != ';') && (middle != '\0')) {
if (IO_get_byte() == '!') {
switch (middle) {
case 'n':
IO_put_byte('!');
break;
case 'o':
case 'o':
IO_put_byte('|');
break;
case 'a':
case 'a':
IO_put_byte('&');
break;
case '=':
case '=':
IO_put_byte('=');
break;
case '<':
case '<':
IO_put_string(" < ");
break;
case '>':
case '>':
IO_put_string(" > ");
break;
default:
default:
IO_put_byte('!');
IO_put_byte(middle);
IO_put_byte('!');
@ -63,36 +59,41 @@ void GigaHypra_operator(void) {// '!' was last read
IO_put_byte('!');
IO_put_byte(middle);
}
} else
} else {
IO_put_byte('!');
}
// exit with unused byte pre-read
}
// output one or two TABs
void GigaHypra_indent(int indent) {
if(indent < 8)
void GigaHypra_indent(int indent)
{
if (indent < 8)
IO_put_byte('\t');
IO_put_byte('\t');
}
// Process opcode and arguments
void GigaHypra_argument(int flags) {
void GigaHypra_argument(int flags)
{
int paren = 0; // number of open parentheses (to close)
// if needed, add separating space between opcode and argument
if((flags & FLAG_INSERT_SPACE) && (GotByte != SPACE)
if ((flags & FLAG_INSERT_SPACE) && (GotByte != SPACE)
&& (GotByte != ';') && (GotByte != '\0'))
IO_put_byte(SPACE);
// character loop
while((GotByte != ';') && (GotByte != '\0')) {
if(GotByte == '!')
while ((GotByte != ';') && (GotByte != '\0')) {
if (GotByte == '!')
GigaHypra_operator();
if(GotByte == '"') {
if (GotByte == '"') {
// don't parse inside quotes
IO_put_byte(GotByte);
IO_get_byte();
while((GotByte != '\0') && (GotByte != '"')) {
if((GotByte == 0x5f)
while ((GotByte != '\0') && (GotByte != '"')) {
if ((GotByte == 0x5f)
&& (flags & FLAG_CHANGE_LEFTARROW))
IO_put_string("\", 13,\"");
else
@ -100,18 +101,17 @@ void GigaHypra_argument(int flags) {
IO_get_byte();
}
IO_put_byte('"');
if(GotByte == '"') {
if (GotByte == '"') {
IO_get_byte();
if((GotByte == '\0')
if ((GotByte == '\0')
&& (flags & FLAG_ADD_ZERO))
IO_put_string(", 0");
}
} else {
// most characters go here
switch(GotByte) {
case '(':
if(flags & FLAG_SKIP_OPENING) {
switch (GotByte) {
case '(':
if (flags & FLAG_SKIP_OPENING) {
flags &= ~FLAG_SKIP_OPENING;
flags |= FLAG_SKIP_CLOSING;
} else {
@ -119,42 +119,40 @@ void GigaHypra_argument(int flags) {
IO_put_byte(PET2ISO(GotByte));
}
break;
case ')':
if((flags & FLAG_SKIP_CLOSING) && (paren == 0))
case ')':
if ((flags & FLAG_SKIP_CLOSING) && (paren == 0)) {
flags &= ~FLAG_SKIP_CLOSING;
else {
} else {
paren--;
IO_put_byte(PET2ISO(GotByte));
}
break;
case SHIFTSPACE:
case SHIFTSPACE:
IO_put_byte(SPACE);
break;
default:
default:
IO_put_byte(PET2ISO(GotByte));
}
IO_get_byte();
}
}
if(flags & FLAG_ADD_CBM)
if (flags & FLAG_ADD_CBM)
IO_put_string(ACME_cbmformat);
if(flags & FLAG_ADD_LEFT_BRACE)
if (flags & FLAG_ADD_LEFT_BRACE)
IO_put_byte('{');
}
// Convert and send label name.
// Returns length (for proper indentation).
int GigaHypra_label_definition(void) {
// convert and send label name.
// returns length (for proper indentation).
int GigaHypra_label_definition(void)
{
int count = 0;
do {
IO_put_byte(PET2ISO(GotByte));
count++;
IO_get_byte();
} while((GotByte != SPACE) && (GotByte != ';') && (GotByte != '\0'));
return(count);
} while ((GotByte != SPACE) && (GotByte != ';') && (GotByte != '\0'));
return count;
}

View File

@ -6,6 +6,7 @@
#ifndef gigahypra_H
#define gigahypra_H
#include "config.h"
@ -22,11 +23,11 @@
// Prototypes
extern void GigaHypra_comment(void);
extern void GigaHypra_operator(void);
extern void GigaHypra_indent(int indent);
extern void GigaHypra_argument(int flags);
extern int GigaHypra_label_definition(void);
extern void GigaHypra_comment(void);
extern void GigaHypra_operator(void);
extern void GigaHypra_indent(int indent);
extern void GigaHypra_argument(int flags);
extern int GigaHypra_label_definition(void);
#endif

View File

@ -12,203 +12,206 @@
#include "pet2iso.h"
// Functions
// functions
// complain about unknown pseudo opcodes
static void complain(char a, char b) {
static void complain(char a, char b)
{
IO_put_string("; ToACME: .");
if(a)
if (a)
IO_put_byte(a);
if(b)
if (b)
IO_put_byte(b);
IO_put_string(" cannot be converted\n");
}
// handle ".ba" and ".by"
static int process_po_b(char second) {
static int process_po_b(char second)
{
int flags = 0;
switch(second) {
case 'a': // ".ba" = set base address
switch (second) {
case 'a': // ".ba" = set base address
IO_put_string(ACME_set_pc);
break;
case 'y': // ".by" = insert bytes
case 'y': // ".by" = insert bytes
IO_put_string(ACME_po_byte);
flags |= FLAG_INSERT_SPACE;
break;
default:
default:
complain('b', second);
}
return(flags);
return flags;
}
// handle ".ei", ".el", ".en" and ".eq"
static int process_po_e(char second) {
static int process_po_e(char second)
{
int flags = 0;
switch(second) {
case 'i': // ".ei" = endif
switch (second) {
case 'i': // ".ei" = endif
IO_put_string(ACME_endif);
break;
case 'l': // ".el" = else
case 'l': // ".el" = else
IO_put_string(ACME_else);
break;
case 'n': // ".en" = end
case 'n': // ".en" = end
IO_put_string(ACME_po_eof);
flags |= FLAG_INSERT_SPACE;
break;
case 'q': // ".eq" = label def
case 'q': // ".eq" = label def
break;
default:
default:
complain('e', second);
}
return(flags);
return flags;
}
// handle ".tx" and ".ts"
static int process_po_t(char second) {
static int process_po_t(char second)
{
int flags = 0;
switch(second) {
case 'x': // ".tx" = insert string
switch (second) {
case 'x': // ".tx" = insert string
IO_put_string(ACME_po_pet);
flags |= FLAG_INSERT_SPACE;
break;
case 's': // ".ts" = screen code string
case 's': // ".ts" = screen code string
IO_put_string(ACME_po_scr);
flags |= FLAG_INSERT_SPACE;
break;
default:
default:
complain('t', second);
}
return(flags);
return flags;
}
#define ARE(a, b) ((first == a) && (second == b))
// Process pseudo opcode
static int process_pseudo_opcode(void) {// '.' was last read
// process pseudo opcode
static int process_pseudo_opcode(void) // '.' was last read
{
int first,
second;
// get first byte. if illegal, complain and exit immediately
first = PET2ISO(IO_get_byte());
if((first == SPACE) || (first == ';') || (first == '\0')) {
if ((first == SPACE) || (first == ';') || (first == '\0')) {
complain(first, '\0');
return(0);
return 0;
}
// get second byte. if illegal, complain and exit immediately
second = PET2ISO(IO_get_byte());
if((second == SPACE) || (second == ';') || (second == '\0')) {
if ((second == SPACE) || (second == ';') || (second == '\0')) {
complain(first, second);
return(0);
return 0;
}
IO_get_byte();// pre-read unused byte
// check pseudo opcodes (switch/case was actually harder to read)
if(first == 'b') { // handle ".ba" and ".by"
if (first == 'b') { // handle ".ba" and ".by"
process_po_b(second);
return(FLAG_INSERT_SPACE);
return FLAG_INSERT_SPACE;
}
if(first == 'e') // handle ".ei", ".el", ".en" and ".eq"
return(process_po_e(second));
if(first == 't') // handle ".tx" and ".ts"
return(process_po_t(second));
if(ARE('.', '.')) { // "..." = macro call
if (first == 'e') // handle ".ei", ".el", ".en" and ".eq"
return process_po_e(second);
if (first == 't') // handle ".tx" and ".ts"
return process_po_t(second);
if (ARE('.', '.')) { // "..." = macro call
IO_put_string(ACME_macro_call);
return(FLAG_INSERT_SPACE | FLAG_SKIP_OPENING);
return FLAG_INSERT_SPACE | FLAG_SKIP_OPENING;
}
if(ARE('m', 'a')) { // ".ma" = macro definition
if (ARE('m', 'a')) { // ".ma" = macro definition
IO_put_string(ACME_po_macro);
return(FLAG_INSERT_SPACE|FLAG_SKIP_OPENING|FLAG_ADD_LEFT_BRACE);
return FLAG_INSERT_SPACE | FLAG_SKIP_OPENING | FLAG_ADD_LEFT_BRACE;
}
if(ARE('o', 'b')) { // ".ob" = output to file
if (ARE('o', 'b')) { // ".ob" = output to file
IO_put_string(ACME_po_to);
return(FLAG_INSERT_SPACE | FLAG_ADD_CBM);
return FLAG_INSERT_SPACE | FLAG_ADD_CBM;
}
if(ARE('s', 'y')) { // ".sy" = symbol dump
if (ARE('s', 'y')) { // ".sy" = symbol dump
IO_put_string(ACME_po_sl);
IO_put_string("\"symboldump.txt\";");
return(0);
return 0;
}
if(ARE('i', 'f')) { // ".if" = cond. assembly
if (ARE('i', 'f')) { // ".if" = cond. assembly
IO_put_string(ACME_po_if);
return(FLAG_INSERT_SPACE | FLAG_ADD_LEFT_BRACE);
return FLAG_INSERT_SPACE | FLAG_ADD_LEFT_BRACE;
}
if(ARE('g', 'l')) // ".gl" = global label def
return(0);
if(ARE('a', 'p')) // ".ap" = append source
if (ARE('g', 'l')) // ".gl" = global label def
return 0;
if (ARE('a', 'p')) // ".ap" = append source
IO_put_string(ACME_po_source);
else if(ARE('r', 't')) // ".rt" = end of macro def
else if (ARE('r', 't')) // ".rt" = end of macro def
IO_put_string(ACME_endmacro);
else if(ARE('w', 'o')) // ".wo" = insert words
else if (ARE('w', 'o')) // ".wo" = insert words
IO_put_string(ACME_po_word);
else
complain(first, second);
return(FLAG_INSERT_SPACE);
return FLAG_INSERT_SPACE;
}
// Process opcode
static void real_opcode(void) {// character was last read
// process opcode
static void real_opcode(void) // character was last read
{
IO_put_byte(PET2ISO(GotByte));
IO_get_byte();
if((GotByte == SPACE) || (GotByte == ';') || (GotByte == '\0'))
if ((GotByte == SPACE) || (GotByte == ';') || (GotByte == '\0'))
return;
IO_put_byte(PET2ISO(GotByte));
IO_get_byte();
if((GotByte == SPACE) || (GotByte == ';') || (GotByte == '\0'))
if ((GotByte == SPACE) || (GotByte == ';') || (GotByte == '\0'))
return;
IO_put_byte(PET2ISO(GotByte));
IO_get_byte();// exit with unused byte pre-read
return;
IO_get_byte(); // exit with unused byte pre-read
}
// Main routine for HypraAss conversion
void hypra_main(void) {
// main routine for HypraAss conversion
void hypra_main(void)
{
int indent;
IO_set_input_padding(0);
IO_process_load_address();
ACME_switch_to_pet();
// loop: once for every line in the file
while(!IO_reached_eof) {
while (!IO_reached_eof) {
// skip link pointer (if it's zero, report as end marker)
if(IO_get_le16() == 0)
if (IO_get_le16() == 0)
IO_put_string("; ToACME: Found BASIC end marker.\n");
IO_get_le16(); // skip line number
// process line
IO_get_byte();
indent = 0;
if((GotByte != SPACE) && (GotByte != ';') && (GotByte != '\0'))
if ((GotByte != SPACE) && (GotByte != ';') && (GotByte != '\0'))
indent = GigaHypra_label_definition();
// skip spaces
while(GotByte == SPACE)
while (GotByte == SPACE)
IO_get_byte();
// if there is an opcode, process it
if((GotByte != ';') && (GotByte != '\0')) {
if ((GotByte != ';') && (GotByte != '\0')) {
GigaHypra_indent(indent);
// branch to relevant routine
if(GotByte == '.')
if (GotByte == '.') {
GigaHypra_argument(process_pseudo_opcode());
else {
} else {
real_opcode();
GigaHypra_argument(FLAG_INSERT_SPACE);
}
}
// skip comment, if there is one
if(GotByte == ';')
if (GotByte == ';')
GigaHypra_comment();
// end of line
IO_put_byte('\n');

View File

@ -9,7 +9,7 @@
#include "io.h"
// Variables
// variables
int padding_value;
FILE *global_input_stream;
FILE *global_output_stream;
@ -17,78 +17,98 @@ int GotByte = 0;
bool IO_reached_eof = FALSE;
// Input functions
// input functions
// Set byte sent after EOF
inline void IO_set_input_padding(int pad) {
// set byte sent after EOF
inline void IO_set_input_padding(int pad)
{
padding_value = pad;
}
// Fetch and buffer byte
int IO_get_byte(void) {
// fetch and buffer byte
int IO_get_byte(void)
{
int w;
if(IO_reached_eof)
if (IO_reached_eof) {
GotByte = padding_value;
else {
} else {
w = getc(global_input_stream);
if(w == EOF)
if (w == EOF)
IO_reached_eof = TRUE;
GotByte = w;
}
return(GotByte);
return GotByte;
}
// Read little-endian 16-bit value
unsigned int IO_get_le16(void) {
// read little-endian 16-bit value
unsigned int IO_get_le16(void)
{
unsigned int result = IO_get_byte();
// CAUTION! using
// return(IO_get_byte() | (IO_get_byte() << 8));
// would be compiler-dependent
return(result | (IO_get_byte() << 8));
return result | (IO_get_byte() << 8);
}
// Read little-endian 24-bit value
unsigned int IO_get_le24(void) {
// read little-endian 24-bit value
unsigned int IO_get_le24(void)
{
unsigned int result = IO_get_le16();
// CAUTION! see above
return(result | (IO_get_byte() << 16));
return result | (IO_get_byte() << 16);
}
// Output functions
// output functions
// output string
inline void IO_put_string(const char string[]) {
inline void IO_put_string(const char string[])
{
fputs(string, global_output_stream);
}
// Write byte to output file
inline void IO_put_byte(char b) {
// write byte to output file
inline void IO_put_byte(char b)
{
putc(b, global_output_stream);
}
// output low nibble of argument as hexadecimal digit
static void put_low_nibble_hex(int v) {
static void put_low_nibble_hex(int v)
{
putc("0123456789abcdef"[v & 15], global_output_stream);
}
// output low byte of argument as two hexadecimal digits
void IO_put_low_byte_hex(int v) {
void IO_put_low_byte_hex(int v)
{
put_low_nibble_hex(v >> 4);
put_low_nibble_hex(v);
}
// output low 16 bits of arg as four hexadecimal digits
void IO_put_low_16b_hex(int w) {
void IO_put_low_16b_hex(int w)
{
IO_put_low_byte_hex(w >> 8);
IO_put_low_byte_hex(w);
}
// read load address from input file and write as comment to output file
void IO_process_load_address(void) {
void IO_process_load_address(void)
{
int load_address;
load_address = IO_get_le16();

View File

@ -6,27 +6,28 @@
#ifndef io_H
#define io_H
#include <stdio.h>
#include "config.h"
// Variables
// variables
extern int GotByte;
extern bool IO_reached_eof;
extern FILE *global_input_stream;
extern FILE *global_output_stream;
// Prototypes
extern void IO_set_input_padding(int);
extern int IO_get_byte(void);
extern unsigned int IO_get_le16(void);// get little-endian 16-bit value
extern unsigned int IO_get_le24(void);// get little-endian 24-bit value
extern void IO_put_string(const char string[]);
extern void IO_put_byte(char b);
extern void IO_put_low_byte_hex(int v);
extern void IO_put_low_16b_hex(int w);
extern void IO_process_load_address(void);
// prototypes
extern void IO_set_input_padding(int);
extern int IO_get_byte(void);
extern unsigned int IO_get_le16(void); // get little-endian 16-bit value
extern unsigned int IO_get_le24(void); // get little-endian 24-bit value
extern void IO_put_string(const char string[]);
extern void IO_put_byte(char b);
extern void IO_put_low_byte_hex(int v);
extern void IO_put_low_16b_hex(int w);
extern void IO_process_load_address(void);
#endif

View File

@ -1,5 +1,5 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Copyright (C) 1999-2012 Marco Baye
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -26,45 +26,46 @@
#include "version.h"
// Guess what
int main(int argc, char *argv[]) {
// guess what
int main(int argc, char *argv[])
{
// handle "toacme -h" and "toacme --help" just like "toacme"
if(argc == 2) {
if((strcmp(argv[1], "-h") == 0)
if (argc == 2) {
if ((strcmp(argv[1], "-h") == 0)
|| (strcmp(argv[1], "--help") == 0))
argc = 1;
}
// "toacme" without any switches gives info and exits successfully
if(argc == 1) {
if (argc == 1) {
version_show_info(argv[0]);
return(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
// check argument count
if(argc != 4) {
if (argc != 4) {
fputs("Wrong number of arguments.\n", stderr);
return(EXIT_FAILURE);
return EXIT_FAILURE;
}
// check format id
if(version_parse_id(argv[1])) {
if (version_parse_id(argv[1])) {
fputs("Unknown format id.\n", stderr);
return(EXIT_FAILURE);
return EXIT_FAILURE;
}
// be nice and ensure input and output are different
if(strcmp(argv[2], argv[3]) == 0) {
if (strcmp(argv[2], argv[3]) == 0) {
fputs("Input and output files must be different.\n", stderr);
return(EXIT_FAILURE);
return EXIT_FAILURE;
}
// try to open input file
global_input_stream = fopen(argv[2], "rb");
if(global_input_stream == NULL) {
if (global_input_stream == NULL) {
fputs("Cannot open input file.\n", stderr);
return(EXIT_FAILURE);
return EXIT_FAILURE;
}
// try to open output file
global_output_stream = fopen(argv[3], "w");
if(global_output_stream == NULL) {
if (global_output_stream == NULL) {
fputs("Cannot open output file.\n", stderr);
return(EXIT_FAILURE);
return EXIT_FAILURE;
}
// do the actual work
version_main();
@ -72,5 +73,5 @@ int main(int argc, char *argv[]) {
fclose(global_output_stream);
PLATFORM_SETFILETYPE_TEXT(argv[3]);
fclose(global_input_stream);
return(EXIT_SUCCESS);
return EXIT_SUCCESS;
}

View File

@ -4,117 +4,118 @@
//
// assembler mnemonics
// Mnemonics of legal 6502 instructions
const char MnemonicADC[] = "adc";
const char MnemonicAND[] = "and";
const char MnemonicASL[] = "asl";
const char MnemonicBCC[] = "bcc";
const char MnemonicBCS[] = "bcs";
const char MnemonicBEQ[] = "beq";
const char MnemonicBIT[] = "bit";
const char MnemonicBMI[] = "bmi";
const char MnemonicBNE[] = "bne";
const char MnemonicBPL[] = "bpl";
const char MnemonicBRK[] = "brk";
const char MnemonicBVC[] = "bvc";
const char MnemonicBVS[] = "bvs";
const char MnemonicCLC[] = "clc";
const char MnemonicCLD[] = "cld";
const char MnemonicCLI[] = "cli";
const char MnemonicCLV[] = "clv";
const char MnemonicCMP[] = "cmp";
const char MnemonicCPX[] = "cpx";
const char MnemonicCPY[] = "cpy";
const char MnemonicDEC[] = "dec";
const char MnemonicDEX[] = "dex";
const char MnemonicDEY[] = "dey";
const char MnemonicEOR[] = "eor";
const char MnemonicINC[] = "inc";
const char MnemonicINX[] = "inx";
const char MnemonicINY[] = "iny";
const char MnemonicJMP[] = "jmp";
const char MnemonicJSR[] = "jsr";
const char MnemonicLDA[] = "lda";
const char MnemonicLDX[] = "ldx";
const char MnemonicLDY[] = "ldy";
const char MnemonicLSR[] = "lsr";
const char MnemonicNOP[] = "nop";
const char MnemonicORA[] = "ora";
const char MnemonicPHA[] = "pha";
const char MnemonicPHP[] = "php";
const char MnemonicPLA[] = "pla";
const char MnemonicPLP[] = "plp";
const char MnemonicROL[] = "rol";
const char MnemonicROR[] = "ror";
const char MnemonicRTI[] = "rti";
const char MnemonicRTS[] = "rts";
const char MnemonicSBC[] = "sbc";
const char MnemonicSEC[] = "sec";
const char MnemonicSED[] = "sed";
const char MnemonicSEI[] = "sei";
const char MnemonicSTA[] = "sta";
const char MnemonicSTX[] = "stx";
const char MnemonicSTY[] = "sty";
const char MnemonicTAX[] = "tax";
const char MnemonicTAY[] = "tay";
const char MnemonicTSX[] = "tsx";
const char MnemonicTXA[] = "txa";
const char MnemonicTXS[] = "txs";
const char MnemonicTYA[] = "tya";
// mnemonics of legal 6502 instructions
const char MnemonicADC[] = "adc",
MnemonicAND[] = "and",
MnemonicASL[] = "asl",
MnemonicBCC[] = "bcc",
MnemonicBCS[] = "bcs",
MnemonicBEQ[] = "beq",
MnemonicBIT[] = "bit",
MnemonicBMI[] = "bmi",
MnemonicBNE[] = "bne",
MnemonicBPL[] = "bpl",
MnemonicBRK[] = "brk",
MnemonicBVC[] = "bvc",
MnemonicBVS[] = "bvs",
MnemonicCLC[] = "clc",
MnemonicCLD[] = "cld",
MnemonicCLI[] = "cli",
MnemonicCLV[] = "clv",
MnemonicCMP[] = "cmp",
MnemonicCPX[] = "cpx",
MnemonicCPY[] = "cpy",
MnemonicDEC[] = "dec",
MnemonicDEX[] = "dex",
MnemonicDEY[] = "dey",
MnemonicEOR[] = "eor",
MnemonicINC[] = "inc",
MnemonicINX[] = "inx",
MnemonicINY[] = "iny",
MnemonicJMP[] = "jmp",
MnemonicJSR[] = "jsr",
MnemonicLDA[] = "lda",
MnemonicLDX[] = "ldx",
MnemonicLDY[] = "ldy",
MnemonicLSR[] = "lsr",
MnemonicNOP[] = "nop",
MnemonicORA[] = "ora",
MnemonicPHA[] = "pha",
MnemonicPHP[] = "php",
MnemonicPLA[] = "pla",
MnemonicPLP[] = "plp",
MnemonicROL[] = "rol",
MnemonicROR[] = "ror",
MnemonicRTI[] = "rti",
MnemonicRTS[] = "rts",
MnemonicSBC[] = "sbc",
MnemonicSEC[] = "sec",
MnemonicSED[] = "sed",
MnemonicSEI[] = "sei",
MnemonicSTA[] = "sta",
MnemonicSTX[] = "stx",
MnemonicSTY[] = "sty",
MnemonicTAX[] = "tax",
MnemonicTAY[] = "tay",
MnemonicTSX[] = "tsx",
MnemonicTXA[] = "txa",
MnemonicTXS[] = "txs",
MnemonicTYA[] = "tya";
// Mnemonics of undocumented ("illegal") 6502 instructions
const char MnemonicSLO[] = " SLO";
const char MnemonicRLA[] = " RLA";
const char MnemonicSRE[] = " SRE";
const char MnemonicRRA[] = " RRA";
const char MnemonicSAX[] = " SAX";
const char MnemonicLAX[] = " LAX";
const char MnemonicDCP[] = " DCP";
const char MnemonicISC[] = " ISC";
const char MnemonicANC[] = " ANC";
const char MnemonicARR[] = " ARR";
const char MnemonicASR[] = " ASR";
const char MnemonicSBX[] = " SBX";
const char MnemonicDOP[] = " DOP";
const char MnemonicTOP[] = " TOP";
const char MnemonicJAM[] = " JAM";
// Mnemonics of 65c02 instructions
const char MnemonicBRA[] = "bra";
const char MnemonicPHX[] = "phx";
const char MnemonicPHY[] = "phy";
const char MnemonicPLX[] = "plx";
const char MnemonicPLY[] = "ply";
const char MnemonicSTZ[] = "stz";
const char MnemonicTRB[] = "trb";
const char MnemonicTSB[] = "tsb";
// mnemonics of undocumented ("illegal") 6502 instructions
const char MnemonicSLO[] = " SLO",
MnemonicRLA[] = " RLA",
MnemonicSRE[] = " SRE",
MnemonicRRA[] = " RRA",
MnemonicSAX[] = " SAX",
MnemonicLAX[] = " LAX",
MnemonicDCP[] = " DCP",
MnemonicISC[] = " ISC",
MnemonicANC[] = " ANC",
MnemonicARR[] = " ARR",
MnemonicASR[] = " ASR",
MnemonicSBX[] = " SBX",
MnemonicDOP[] = " DOP",
MnemonicTOP[] = " TOP",
MnemonicJAM[] = " JAM";
// Mnemonics of 65816 instructions
const char MnemonicJML[] = "jml";
const char MnemonicJSL[] = "jsl";
const char MnemonicMVN[] = "mvn";
const char MnemonicMVP[] = "mvp";
const char MnemonicPEI[] = "pei";
const char MnemonicBRL[] = "brl";
const char MnemonicPER[] = "per";
const char MnemonicCOP[] = "cop";
const char MnemonicPEA[] = "pea";
const char MnemonicREP[] = "rep";
const char MnemonicSEP[] = "sep";
const char MnemonicPHB[] = "phb";
const char MnemonicPHD[] = "phd";
const char MnemonicPHK[] = "phk";
const char MnemonicPLB[] = "plb";
const char MnemonicPLD[] = "pld";
const char MnemonicRTL[] = "rtl";
const char MnemonicSTP[] = "stp";
const char MnemonicTCD[] = "tcd";
const char MnemonicTCS[] = "tcs";
const char MnemonicTDC[] = "tdc";
const char MnemonicTSC[] = "tsc";
const char MnemonicTXY[] = "txy";
const char MnemonicTYX[] = "tyx";
const char MnemonicWAI[] = "wai";
const char MnemonicWDM[] = "wdm";
const char MnemonicXBA[] = "xba";
const char MnemonicXCE[] = "xce";
// mnemonics of 65c02 instructions
const char MnemonicBRA[] = "bra",
MnemonicPHX[] = "phx",
MnemonicPHY[] = "phy",
MnemonicPLX[] = "plx",
MnemonicPLY[] = "ply",
MnemonicSTZ[] = "stz",
MnemonicTRB[] = "trb",
MnemonicTSB[] = "tsb";
// mnemonics of 65816 instructions
const char MnemonicJML[] = "jml",
MnemonicJSL[] = "jsl",
MnemonicMVN[] = "mvn",
MnemonicMVP[] = "mvp",
MnemonicPEI[] = "pei",
MnemonicBRL[] = "brl",
MnemonicPER[] = "per",
MnemonicCOP[] = "cop",
MnemonicPEA[] = "pea",
MnemonicREP[] = "rep",
MnemonicSEP[] = "sep",
MnemonicPHB[] = "phb",
MnemonicPHD[] = "phd",
MnemonicPHK[] = "phk",
MnemonicPLB[] = "plb",
MnemonicPLD[] = "pld",
MnemonicRTL[] = "rtl",
MnemonicSTP[] = "stp",
MnemonicTCD[] = "tcd",
MnemonicTCS[] = "tcs",
MnemonicTDC[] = "tdc",
MnemonicTSC[] = "tsc",
MnemonicTXY[] = "txy",
MnemonicTYX[] = "tyx",
MnemonicWAI[] = "wai",
MnemonicWDM[] = "wdm",
MnemonicXBA[] = "xba",
MnemonicXCE[] = "xce";

View File

@ -6,7 +6,8 @@
#ifndef mnemo_H
#define mnemo_H
// Mnemonics of legal 6502 instructions
// mnemonics of legal 6502 instructions
extern const char MnemonicADC[], MnemonicSBC[];
extern const char MnemonicAND[], MnemonicEOR[], MnemonicORA[];
extern const char MnemonicASL[], MnemonicLSR[];
@ -31,21 +32,21 @@ extern const char MnemonicSTA[], MnemonicSTX[], MnemonicSTY[];
extern const char MnemonicTSX[], MnemonicTXA[], MnemonicTAY[];
extern const char MnemonicTYA[], MnemonicTAX[], MnemonicTXS[];
// Mnemonics of undocumented ("illegal") 6502 instructions
// mnemonics of undocumented ("illegal") 6502 instructions
extern const char MnemonicANC[], MnemonicARR[], MnemonicASR[];
extern const char MnemonicDCP[], MnemonicDOP[], MnemonicISC[];
extern const char MnemonicJAM[], MnemonicLAX[], MnemonicRLA[];
extern const char MnemonicRRA[], MnemonicSAX[], MnemonicSBX[];
extern const char MnemonicSLO[], MnemonicSRE[], MnemonicTOP[];
// Mnemonics of 65c02 instructions
// mnemonics of 65c02 instructions
extern const char MnemonicBRA[];
extern const char MnemonicPHX[], MnemonicPHY[];
extern const char MnemonicPLX[], MnemonicPLY[];
extern const char MnemonicSTZ[];
extern const char MnemonicTRB[], MnemonicTSB[];
// Mnemonics of 65816 instructions
// mnemonics of 65816 instructions
extern const char MnemonicJML[], MnemonicJSL[];
extern const char MnemonicMVN[], MnemonicMVP[];
extern const char MnemonicPEI[];
@ -68,4 +69,5 @@ extern const char MnemonicWAI[];
extern const char MnemonicWDM[];
extern const char MnemonicXBA[], MnemonicXCE[];
#endif

View File

@ -11,90 +11,95 @@
#include "io.h"
// Constants
// constants
// 6502 code table (mnemonics only) *illegals*
const char* mnemo_of_code[] = {
MnemonicBRK, MnemonicORA, " JAM;0x02", MnemonicSLO, // $00-$03
" DOP;0x04", MnemonicORA, MnemonicASL, MnemonicSLO, // $04-$07
MnemonicPHP, MnemonicORA, MnemonicASL, "!by$0b;ANC#", // $08-$0b
" TOP;0x0c", MnemonicORA, MnemonicASL, MnemonicSLO, // $0c-$0f
MnemonicBPL, MnemonicORA, " JAM;0x12", MnemonicSLO, // $10-$13
" DOP;0x14", MnemonicORA, MnemonicASL, MnemonicSLO, // $14-$17
MnemonicCLC, MnemonicORA, " NOP;0x1a", MnemonicSLO, // $18-$1b
" TOP;0x1c", MnemonicORA, MnemonicASL, MnemonicSLO, // $1c-$1f
MnemonicJSR, MnemonicAND, " JAM;0x22", MnemonicRLA, // $20-$23
MnemonicBIT, MnemonicAND, MnemonicROL, MnemonicRLA, // $24-$27
MnemonicPLP, MnemonicAND, MnemonicROL, "!by$2b;ANC#", // $28-$2b
MnemonicBIT, MnemonicAND, MnemonicROL, MnemonicRLA, // $2c-$2f
MnemonicBMI, MnemonicAND, " JAM;0x32", MnemonicRLA, // $30-$33
" DOP;0x34", MnemonicAND, MnemonicROL, MnemonicRLA, // $34-$37
MnemonicSEC, MnemonicAND, " NOP;0x3a", MnemonicRLA, // $38-$3b
" TOP;0x3c", MnemonicAND, MnemonicROL, MnemonicRLA, // $3c-$3f
MnemonicRTI, MnemonicEOR, " JAM;0x42", MnemonicSRE, // $40-$43
" DOP;0x44", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $44-$47
MnemonicPHA, MnemonicEOR, MnemonicLSR, MnemonicASR, // $48-$4b
MnemonicJMP, MnemonicEOR, MnemonicLSR, MnemonicSRE, // $4c-$4f
MnemonicBVC, MnemonicEOR, " JAM;0x52", MnemonicSRE, // $50-$53
" DOP;0x54", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $54-$57
MnemonicCLI, MnemonicEOR, " NOP;0x5a", MnemonicSRE, // $58-$5b
" TOP;0x5c", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $5c-$5f
MnemonicRTS, MnemonicADC, " JAM;0x62", MnemonicRRA, // $60-$63
" DOP;0x64", MnemonicADC, MnemonicROR, MnemonicRRA, // $64-$67
MnemonicPLA, MnemonicADC, MnemonicROR, MnemonicARR, // $68-$6b
MnemonicJMP, MnemonicADC, MnemonicROR, MnemonicRRA, // $6c-$6f
MnemonicBVS, MnemonicADC, " JAM;0x72", MnemonicRRA, // $70-$73
" DOP;0x74", MnemonicADC, MnemonicROR, MnemonicRRA, // $74-$77
MnemonicSEI, MnemonicADC, " NOP;0x7a", MnemonicRRA, // $78-$7b
" TOP;0x7c", MnemonicADC, MnemonicROR, MnemonicRRA, // $7c-$7f
" DOP;0x80", MnemonicSTA, " DOP;0x82", MnemonicSAX, // $80-$83
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $84-$87
MnemonicDEY, " DOP;0x89", MnemonicTXA, NULL, // $88-$8b
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $8c-$8f
MnemonicBCC, MnemonicSTA, " JAM;0x92", NULL, // $90-$93
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $94-$97
MnemonicTYA, MnemonicSTA, MnemonicTXS, NULL, // $98-$9b
NULL, MnemonicSTA, NULL, NULL, // $9c-$9f
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $a0-$a3
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $a4-$a7
MnemonicTAY, MnemonicLDA, MnemonicTAX, NULL, // $a8-$ab
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $ac-$af
MnemonicBCS, MnemonicLDA, " JAM;0xb2", MnemonicLAX, // $b0-$b3
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $b4-$b7
MnemonicCLV, MnemonicLDA, MnemonicTSX, NULL, // $b8-$bb
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $bc-$bf
MnemonicCPY, MnemonicCMP, " DOP;0xc2", MnemonicDCP, // $c0-$c3
MnemonicCPY, MnemonicCMP, MnemonicDEC, MnemonicDCP, // $c4-$c7
MnemonicINY, MnemonicCMP, MnemonicDEX, MnemonicSBX, // $c8-$cb
MnemonicCPY, MnemonicCMP, MnemonicDEC, MnemonicDCP, // $cc-$cf
MnemonicBNE, MnemonicCMP, " JAM;0xd2", MnemonicDCP, // $d0-$d3
" DOP;0xd4", MnemonicCMP, MnemonicDEC, MnemonicDCP, // $d4-$d7
MnemonicCLD, MnemonicCMP, " NOP;0xda", MnemonicDCP, // $d8-$db
" TOP;0xdc", MnemonicCMP, MnemonicDEC, MnemonicDCP, // $dc-$df
MnemonicCPX, MnemonicSBC, " DOP;0xe2", MnemonicISC, // $e0-$e3
MnemonicCPX, MnemonicSBC, MnemonicINC, MnemonicISC, // $e4-$e7
MnemonicINX, MnemonicSBC, MnemonicNOP, "!by$eb;SBC#", // $e8-$eb
MnemonicCPX, MnemonicSBC, MnemonicINC, MnemonicISC, // $ec-$ef
MnemonicBEQ, MnemonicSBC, " JAM;0xf2", MnemonicISC, // $f0-$f3
" DOP;0xf4", MnemonicSBC, MnemonicINC, MnemonicISC, // $f4-$f7
MnemonicSED, MnemonicSBC, " NOP;0xfa", MnemonicISC, // $f8-$fb
" TOP;0xfc", MnemonicSBC, MnemonicINC, MnemonicISC, // $fc-$ff
// 6502 code table (mnemonics only) *illegals*
const char *mnemo_of_code[] = {
MnemonicBRK, MnemonicORA, " JAM;0x02", MnemonicSLO, // $00-$03
" DOP;0x04", MnemonicORA, MnemonicASL, MnemonicSLO, // $04-$07
MnemonicPHP, MnemonicORA, MnemonicASL, "!by$0b;ANC#", // $08-$0b
" TOP;0x0c", MnemonicORA, MnemonicASL, MnemonicSLO, // $0c-$0f
MnemonicBPL, MnemonicORA, " JAM;0x12", MnemonicSLO, // $10-$13
" DOP;0x14", MnemonicORA, MnemonicASL, MnemonicSLO, // $14-$17
MnemonicCLC, MnemonicORA, " NOP;0x1a", MnemonicSLO, // $18-$1b
" TOP;0x1c", MnemonicORA, MnemonicASL, MnemonicSLO, // $1c-$1f
MnemonicJSR, MnemonicAND, " JAM;0x22", MnemonicRLA, // $20-$23
MnemonicBIT, MnemonicAND, MnemonicROL, MnemonicRLA, // $24-$27
MnemonicPLP, MnemonicAND, MnemonicROL, "!by$2b;ANC#", // $28-$2b
MnemonicBIT, MnemonicAND, MnemonicROL, MnemonicRLA, // $2c-$2f
MnemonicBMI, MnemonicAND, " JAM;0x32", MnemonicRLA, // $30-$33
" DOP;0x34", MnemonicAND, MnemonicROL, MnemonicRLA, // $34-$37
MnemonicSEC, MnemonicAND, " NOP;0x3a", MnemonicRLA, // $38-$3b
" TOP;0x3c", MnemonicAND, MnemonicROL, MnemonicRLA, // $3c-$3f
MnemonicRTI, MnemonicEOR, " JAM;0x42", MnemonicSRE, // $40-$43
" DOP;0x44", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $44-$47
MnemonicPHA, MnemonicEOR, MnemonicLSR, MnemonicASR, // $48-$4b
MnemonicJMP, MnemonicEOR, MnemonicLSR, MnemonicSRE, // $4c-$4f
MnemonicBVC, MnemonicEOR, " JAM;0x52", MnemonicSRE, // $50-$53
" DOP;0x54", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $54-$57
MnemonicCLI, MnemonicEOR, " NOP;0x5a", MnemonicSRE, // $58-$5b
" TOP;0x5c", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $5c-$5f
MnemonicRTS, MnemonicADC, " JAM;0x62", MnemonicRRA, // $60-$63
" DOP;0x64", MnemonicADC, MnemonicROR, MnemonicRRA, // $64-$67
MnemonicPLA, MnemonicADC, MnemonicROR, MnemonicARR, // $68-$6b
MnemonicJMP, MnemonicADC, MnemonicROR, MnemonicRRA, // $6c-$6f
MnemonicBVS, MnemonicADC, " JAM;0x72", MnemonicRRA, // $70-$73
" DOP;0x74", MnemonicADC, MnemonicROR, MnemonicRRA, // $74-$77
MnemonicSEI, MnemonicADC, " NOP;0x7a", MnemonicRRA, // $78-$7b
" TOP;0x7c", MnemonicADC, MnemonicROR, MnemonicRRA, // $7c-$7f
" DOP;0x80", MnemonicSTA, " DOP;0x82", MnemonicSAX, // $80-$83
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $84-$87
MnemonicDEY, " DOP;0x89", MnemonicTXA, NULL, // $88-$8b
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $8c-$8f
MnemonicBCC, MnemonicSTA, " JAM;0x92", NULL, // $90-$93
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $94-$97
MnemonicTYA, MnemonicSTA, MnemonicTXS, NULL, // $98-$9b
NULL, MnemonicSTA, NULL, NULL, // $9c-$9f
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $a0-$a3
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $a4-$a7
MnemonicTAY, MnemonicLDA, MnemonicTAX, NULL, // $a8-$ab
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $ac-$af
MnemonicBCS, MnemonicLDA, " JAM;0xb2", MnemonicLAX, // $b0-$b3
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $b4-$b7
MnemonicCLV, MnemonicLDA, MnemonicTSX, NULL, // $b8-$bb
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $bc-$bf
MnemonicCPY, MnemonicCMP, " DOP;0xc2", MnemonicDCP, // $c0-$c3
MnemonicCPY, MnemonicCMP, MnemonicDEC, MnemonicDCP, // $c4-$c7
MnemonicINY, MnemonicCMP, MnemonicDEX, MnemonicSBX, // $c8-$cb
MnemonicCPY, MnemonicCMP, MnemonicDEC, MnemonicDCP, // $cc-$cf
MnemonicBNE, MnemonicCMP, " JAM;0xd2", MnemonicDCP, // $d0-$d3
" DOP;0xd4", MnemonicCMP, MnemonicDEC, MnemonicDCP, // $d4-$d7
MnemonicCLD, MnemonicCMP, " NOP;0xda", MnemonicDCP, // $d8-$db
" TOP;0xdc", MnemonicCMP, MnemonicDEC, MnemonicDCP, // $dc-$df
MnemonicCPX, MnemonicSBC, " DOP;0xe2", MnemonicISC, // $e0-$e3
MnemonicCPX, MnemonicSBC, MnemonicINC, MnemonicISC, // $e4-$e7
MnemonicINX, MnemonicSBC, MnemonicNOP, "!by$eb;SBC#", // $e8-$eb
MnemonicCPX, MnemonicSBC, MnemonicINC, MnemonicISC, // $ec-$ef
MnemonicBEQ, MnemonicSBC, " JAM;0xf2", MnemonicISC, // $f0-$f3
" DOP;0xf4", MnemonicSBC, MnemonicINC, MnemonicISC, // $f4-$f7
MnemonicSED, MnemonicSBC, " NOP;0xfa", MnemonicISC, // $f8-$fb
" TOP;0xfc", MnemonicSBC, MnemonicINC, MnemonicISC, // $fc-$ff
};
// output 2-digit hex argument with correct addressing mode
static void put_argument2(const char pre[], int byte, const char post[]) {
static void put_argument2(const char pre[], int byte, const char post[])
{
IO_put_string(pre);
IO_put_low_byte_hex(byte);
IO_put_string(post);
}
// output 4-digit hex argument with correct addressing mode
static void put_argument4(const char pre[], int word, const char post[]) {
static void put_argument4(const char pre[], int word, const char post[])
{
IO_put_string(pre);
IO_put_low_16b_hex(word);
IO_put_string(post);
}
static int pc; // needed by "relative" addressing mode handler
// addressing mode handler functions
@ -102,149 +107,165 @@ static int pc; // needed by "relative" addressing mode handler
// to the program counter
// addressing mode handler function for 1-byte-instructions
static int am_implied(void) {
return(1);
static int am_implied(void)
{
return 1;
}
// addressing mode handler functions for 2-byte-instructions
static int am_immediate(void) {
static int am_immediate(void)
{
put_argument2(" #$", IO_get_byte(), "");
if(GotByte > 15) {
if (GotByte > 15) {
fprintf(global_output_stream, " ; (= %d", GotByte);
if((GotByte > 31) && (GotByte != 127))
if ((GotByte > 31) && (GotByte != 127))
fprintf(global_output_stream, " = '%c'", GotByte);
IO_put_byte(')');
}
return(2);
return 2;
}
static int am_absolute8(void) {
static int am_absolute8(void)
{
put_argument2(" $", IO_get_byte(), "");
return(2);
return 2;
}
static int am_abs_x8(void) {
put_argument2(" $", IO_get_byte(), ",x");
return(2);
static int am_abs_x8(void)
{
put_argument2(" $", IO_get_byte(), ", x");
return 2;
}
static int am_abs_y8(void) {
put_argument2(" $", IO_get_byte(), ",y");
return(2);
static int am_abs_y8(void)
{
put_argument2(" $", IO_get_byte(), ", y");
return 2;
}
static int am_indirect_x(void) {
put_argument2(" ($", IO_get_byte(), ",x)");
return(2);
static int am_indirect_x(void)
{
put_argument2(" ($", IO_get_byte(), ", x)");
return 2;
}
static int am_indirect_y(void) {
put_argument2(" ($", IO_get_byte(), "),y");
return(2);
static int am_indirect_y(void)
{
put_argument2(" ($", IO_get_byte(), "), y");
return 2;
}
static int am_relative(void) {
static int am_relative(void)
{
put_argument4(" L", pc + 2 + (signed char) IO_get_byte(), "");
return(2);
return 2;
}
// addressing mode handler functions for 3-byte-instructions
static int am_absolute16(void) {
static int am_absolute16(void)
{
put_argument4(" L", IO_get_le16(), "");
return(3);
return 3;
}
static int am_abs_x16(void) {
put_argument4(" L", IO_get_le16(), ",x");
return(3);
static int am_abs_x16(void)
{
put_argument4(" L", IO_get_le16(), ", x");
return 3;
}
static int am_abs_y16(void) {
put_argument4(" L", IO_get_le16(), ",y");
return(3);
static int am_abs_y16(void)
{
put_argument4(" L", IO_get_le16(), ", y");
return 3;
}
static int am_indirect16(void) {
static int am_indirect16(void)
{
put_argument4(" (L", IO_get_le16(), ")");
return(3);
return 3;
}
// 6502 code table (addressing mode handler functions)
// all ANC/DOP/TOP are given as "implied", so the argument is not processed
int (*addressing_mode_of_code[])(void) = {
am_implied, am_indirect_x, am_implied, am_indirect_x, // $00-$03
am_implied, am_absolute8, am_absolute8, am_absolute8, // $04-$07
am_implied, am_immediate, am_implied, am_implied, // $08-$0b
am_implied, am_absolute16, am_absolute16, am_absolute16, // $0c-$0f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $10-$13
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $14-$17
am_implied, am_abs_y16, am_implied, am_abs_y16, // $18-$1b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $1c-$1f
am_absolute16, am_indirect_x, am_implied, am_indirect_x, // $20-$23
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $24-$27
am_implied, am_immediate, am_implied, am_implied, // $28-$2b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $2c-$2f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $30-$33
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $34-$37
am_implied, am_abs_y16, am_implied, am_abs_y16, // $38-$3b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $3c-$3f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $40-$43
am_implied, am_absolute8, am_absolute8, am_absolute8, // $44-$47
am_implied, am_immediate, am_implied, am_immediate, // $48-$4b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $4c-$4f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $50-$53
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $54-$57
am_implied, am_abs_y16, am_implied, am_abs_y16, // $58-$5b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $5c-$5f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $60-$63
am_implied, am_absolute8, am_absolute8, am_absolute8, // $64-$67
am_implied, am_immediate, am_implied, am_immediate, // $68-$6b
am_indirect16, am_absolute16, am_absolute16, am_absolute16, // $6c-$6f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $70-$73
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $74-$77
am_implied, am_abs_y16, am_implied, am_abs_y16, // $78-$7b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $7c-$7f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $80-$83
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $84-$87
am_implied, am_implied, am_implied, am_implied, // $88-$8b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $8c-$8f
am_relative, am_indirect_y, am_implied, am_implied, // $90-$93
am_abs_x8, am_abs_x8, am_abs_y8, am_abs_y8, // $94-$97
am_implied, am_abs_y16, am_implied, am_implied, // $98-$9b
am_implied, am_abs_x16, am_implied, am_implied, // $9c-$9f
am_immediate, am_indirect_x, am_immediate, am_indirect_x, // $a0-$a3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $a4-$a7
am_implied, am_immediate, am_implied, am_implied, // $a8-$ab
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $ac-$af
am_relative, am_indirect_y, am_implied, am_indirect_y, // $b0-$b3
am_abs_x8, am_abs_x8, am_abs_y8, am_abs_y8, // $b4-$b7
am_implied, am_abs_y16, am_implied, am_implied, // $b8-$bb
am_abs_x16, am_abs_x16, am_abs_y16, am_abs_y16, // $bc-$bf
am_immediate, am_indirect_x, am_implied, am_indirect_x, // $c0-$c3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $c4-$c7
am_implied, am_immediate, am_implied, am_immediate, // $c8-$cb
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $cc-$cf
am_relative, am_indirect_y, am_implied, am_indirect_y, // $d0-$d3
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $d4-$d7
am_implied, am_abs_y16, am_implied, am_abs_y16, // $d8-$db
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $dc-$df
am_immediate, am_indirect_x, am_implied, am_indirect_x, // $e0-$e3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $e4-$e7
am_implied, am_immediate, am_implied, am_implied, // $e8-$eb
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $ec-$ef
am_relative, am_indirect_y, am_implied, am_indirect_y, // $f0-$f3
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $f4-$f7
am_implied, am_abs_y16, am_implied, am_abs_y16, // $f8-$fb
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $fc-$ff
am_implied, am_indirect_x, am_implied, am_indirect_x, // $00-$03
am_implied, am_absolute8, am_absolute8, am_absolute8, // $04-$07
am_implied, am_immediate, am_implied, am_implied, // $08-$0b
am_implied, am_absolute16, am_absolute16, am_absolute16, // $0c-$0f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $10-$13
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $14-$17
am_implied, am_abs_y16, am_implied, am_abs_y16, // $18-$1b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $1c-$1f
am_absolute16, am_indirect_x, am_implied, am_indirect_x, // $20-$23
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $24-$27
am_implied, am_immediate, am_implied, am_implied, // $28-$2b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $2c-$2f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $30-$33
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $34-$37
am_implied, am_abs_y16, am_implied, am_abs_y16, // $38-$3b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $3c-$3f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $40-$43
am_implied, am_absolute8, am_absolute8, am_absolute8, // $44-$47
am_implied, am_immediate, am_implied, am_immediate, // $48-$4b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $4c-$4f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $50-$53
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $54-$57
am_implied, am_abs_y16, am_implied, am_abs_y16, // $58-$5b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $5c-$5f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $60-$63
am_implied, am_absolute8, am_absolute8, am_absolute8, // $64-$67
am_implied, am_immediate, am_implied, am_immediate, // $68-$6b
am_indirect16, am_absolute16, am_absolute16, am_absolute16, // $6c-$6f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $70-$73
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $74-$77
am_implied, am_abs_y16, am_implied, am_abs_y16, // $78-$7b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $7c-$7f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $80-$83
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $84-$87
am_implied, am_implied, am_implied, am_implied, // $88-$8b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $8c-$8f
am_relative, am_indirect_y, am_implied, am_implied, // $90-$93
am_abs_x8, am_abs_x8, am_abs_y8, am_abs_y8, // $94-$97
am_implied, am_abs_y16, am_implied, am_implied, // $98-$9b
am_implied, am_abs_x16, am_implied, am_implied, // $9c-$9f
am_immediate, am_indirect_x, am_immediate, am_indirect_x, // $a0-$a3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $a4-$a7
am_implied, am_immediate, am_implied, am_implied, // $a8-$ab
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $ac-$af
am_relative, am_indirect_y, am_implied, am_indirect_y, // $b0-$b3
am_abs_x8, am_abs_x8, am_abs_y8, am_abs_y8, // $b4-$b7
am_implied, am_abs_y16, am_implied, am_implied, // $b8-$bb
am_abs_x16, am_abs_x16, am_abs_y16, am_abs_y16, // $bc-$bf
am_immediate, am_indirect_x, am_implied, am_indirect_x, // $c0-$c3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $c4-$c7
am_implied, am_immediate, am_implied, am_immediate, // $c8-$cb
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $cc-$cf
am_relative, am_indirect_y, am_implied, am_indirect_y, // $d0-$d3
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $d4-$d7
am_implied, am_abs_y16, am_implied, am_abs_y16, // $d8-$db
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $dc-$df
am_immediate, am_indirect_x, am_implied, am_indirect_x, // $e0-$e3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $e4-$e7
am_implied, am_immediate, am_implied, am_implied, // $e8-$eb
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $ec-$ef
am_relative, am_indirect_y, am_implied, am_indirect_y, // $f0-$f3
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $f4-$f7
am_implied, am_abs_y16, am_implied, am_abs_y16, // $f8-$fb
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $fc-$ff
};
// output mnemonic of given byte
static void output_mnemonic(int byte) {
const char* mnemo = mnemo_of_code[byte];
if(mnemo)
// output mnemonic of given byte
static void output_mnemonic(int byte)
{
const char *mnemo = mnemo_of_code[byte];
if (mnemo)
IO_put_string(mnemo);
else
put_argument2("$", byte, "");
}
// Main routine for disassembly
void obj_main(void) {
// main routine for disassembly
void obj_main(void)
{
IO_set_input_padding(0);
// process load address
pc = IO_get_le16();
put_argument4("\t\t*=$", pc, "\n");
IO_get_byte();
while(!IO_reached_eof) {
while (!IO_reached_eof) {
put_argument4("L", pc, "\t\t");
output_mnemonic(GotByte);
pc += addressing_mode_of_code[GotByte]();

View File

@ -7,9 +7,9 @@
#include "pet2iso.h"
// Constants
// constants
// Conversion table
// conversion table
const char PET2ISO_table[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,

View File

@ -6,11 +6,12 @@
#ifndef pet2iso_H
#define pet2iso_H
#include "config.h"
// Constants
extern const char PET2ISO_table[256]; // Conversion table
// constants
extern const char PET2ISO_table[256]; // conversion table
#define PET2ISO(v) (PET2ISO_table[(unsigned char) v])

View File

@ -14,8 +14,9 @@
#include <kernel.h> // defines _kernel_swi_regs
#define OS_FILE 0x00008 // constant to call relevant SWI
// Setting the created files' types
void Platform_set_file_type_text(const char *filename) {
// setting the created files' types
void platform_set_file_type_text(const char *filename)
{
_kernel_swi_regs register_set;
register_set.r[0] = 18;// = SetFileType
@ -29,4 +30,5 @@ void Platform_set_file_type_text(const char *filename) {
// other OS (not that much here)
//
#endif

View File

@ -10,8 +10,8 @@
// check for RISC OS
#ifdef __riscos__
#define PLATFORM_VERSION "Ported to RISC OS by Marco Baye."
#define PLATFORM_SETFILETYPE_TEXT(a) Platform_set_file_type_text(a);
extern void Platform_set_file_type_text(const char *filename);
#define PLATFORM_SETFILETYPE_TEXT(a) platform_set_file_type_text(a);
extern void platform_set_file_type_text(const char *filename);
#endif
// all other platforms

View File

@ -7,9 +7,9 @@
#include "scr2iso.h"
// Constants
// constants
// Conversion table
// conversion table
const char SCR2ISO_table[256] = {
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,

View File

@ -9,7 +9,7 @@
#include "config.h"
// Constants
// constants
extern const char SCR2ISO_table[256]; // Conversion table
#define SCR2ISO(v) (SCR2ISO_table[(unsigned char) v])

View File

@ -4,11 +4,11 @@
//
// Version
#define RELEASE_NUMBER "0.10" // change before release (FIXME)
#define CHANGE_DATE "4 Oct" // change before release
#define CHANGE_YEAR "2006" // change before release
#define RELEASE_NUMBER "0.11" // change before release (FIXME)
#define CHANGE_DATE "8 Oct" // change before release
#define CHANGE_YEAR "2012" // change before release
#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define FILE_TAG ";ACME 0.93" // check before release
#define FILE_TAG ";ACME 0.94.2" // check before release
#include <stdio.h>
#include <string.h>
@ -16,25 +16,25 @@
#include "platform.h"
// Variables
// variables
void (*client_main)(void) = NULL;
// Functions
// functions
// show version info and usage
void version_show_info(const char program_name[]) {
printf(
"\n"
"ToACME - converts other assemblers' source codes to ACME format.\n"
"Release "RELEASE_NUMBER" ("CHANGE_DATE" "CHANGE_YEAR"), Copyright (C) 1999-"CHANGE_YEAR" Marco Baye.\n"
PLATFORM_VERSION"\n"
"Thanks to "STEFAN" for fixing the AssBlaster macro conversion code.\n"
"Release " RELEASE_NUMBER " (" CHANGE_DATE " " CHANGE_YEAR "), Copyright (C) 1999-" CHANGE_YEAR " Marco Baye.\n"
PLATFORM_VERSION "\n"
"Thanks to " STEFAN " for fixing the AssBlaster macro conversion code.\n"
"Thanks to Andreas Paul for helping with the Giga-Assembler mode.\n"
"Thanks to Arndt Dettke for helping with the Hypra-Assembler mode.\n"
"\n"
"The newest version can be found at the ACME homepage:\n"
HOME_PAGE"\n"
HOME_PAGE "\n"
"\n"
"ToACME comes with ABSOLUTELY NO WARRANTY; for details read the help file.\n"
"This is free software, and you are welcome to redistribute it under\n"
@ -53,28 +53,34 @@ HOME_PAGE"\n"
, program_name);
}
extern void ab3_main(void);
extern void f8ab_main(void);
extern void giga_main(void);
extern void hypra_main(void);
extern void obj_main(void);
// Check id string. Returns whether illegal.
int version_parse_id(const char id[]) {
if(strcmp(id, "ab3") == 0)
// check id string. returns whether illegal.
int version_parse_id(const char id[])
{
if (strcmp(id, "ab3") == 0)
client_main = ab3_main;
else if(strcmp(id, "f8ab") == 0)
else if (strcmp(id, "f8ab") == 0)
client_main = f8ab_main;
else if(strcmp(id, "giga") == 0)
else if (strcmp(id, "giga") == 0)
client_main = giga_main;
else if(strcmp(id, "hypra") == 0)
else if (strcmp(id, "hypra") == 0)
client_main = hypra_main;
else if(strcmp(id, "object") == 0)
else if (strcmp(id, "object") == 0)
client_main = obj_main;
return(client_main ? 0 : 1);
return client_main ? 0 : 1;
}
// do the actual work
void version_main(void) {
void version_main(void)
{
IO_put_string(
FILE_TAG "\n"
"; ToACME: Converted by ToACME, release " RELEASE_NUMBER ".\n"

View File

@ -7,10 +7,10 @@
#define version_H
// Prototypes
extern void version_show_info(const char[]);
extern int version_parse_id(const char[]);
extern void version_main(void);
// prototypes
extern void version_show_info(const char[]);
extern int version_parse_id(const char[]);
extern void version_main(void);
#endif