mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-04-13 08:37:03 +00:00
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:
parent
b11d8771e6
commit
b451573f00
@ -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.
|
||||
|
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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]();
|
||||
|
@ -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,
|
||||
|
@ -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])
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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])
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user