1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +00:00

Some basic support for the 65C02 CPU.

Use the command line module from common/ and support long options.
Rename the include module to incpath (as in the assembler).


git-svn-id: svn://svn.cc65.org/cc65/trunk@67 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-06-14 08:18:19 +00:00
parent f1feae3a97
commit 114bc5a370
15 changed files with 561 additions and 189 deletions

View File

@@ -41,6 +41,7 @@
#include "asmcode.h" #include "asmcode.h"
#include "asmlabel.h" #include "asmlabel.h"
#include "check.h" #include "check.h"
#include "cpu.h"
#include "error.h" #include "error.h"
#include "global.h" #include "global.h"
#include "io.h" #include "io.h"
@@ -157,6 +158,11 @@ void g_preamble (void)
AddCodeLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"", VER_MAJOR, VER_MINOR, VER_PATCH); AddCodeLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"", VER_MAJOR, VER_MINOR, VER_PATCH);
AddEmptyLine (); AddEmptyLine ();
/* If we're producing code for some other CPU, switch the command set */
if (CPU == CPU_65C02) {
AddCodeLine (".pc02");
}
/* Allow auto import for runtime library routines */ /* Allow auto import for runtime library routines */
AddCodeLine (".autoimport\ton"); AddCodeLine (".autoimport\ton");
@@ -920,7 +926,7 @@ void g_getind (unsigned flags, unsigned offs)
} }
void g_leasp (int offs) void g_leasp (int offs)
/* Fetch the address of the specified symbol into the primary register */ /* Fetch the address of the specified symbol into the primary register */
{ {
@@ -3096,14 +3102,26 @@ void g_inc (unsigned flags, unsigned long val)
case CF_CHAR: case CF_CHAR:
if (flags & CF_FORCECHAR) { if (flags & CF_FORCECHAR) {
AddCodeLine ("\tclc"); if (CPU == CPU_65C02 && val <= 2) {
AddCodeLine ("\tadc\t#$%02X", val & 0xFF); while (val--) {
AddCodeLine ("\tina");
}
} else {
AddCodeLine ("\tclc");
AddCodeLine ("\tadc\t#$%02X", val & 0xFF);
}
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
case CF_INT: case CF_INT:
if (FavourSize) { if (CPU == CPU_65C02 && val == 1) {
AddCodeLine ("\tina");
AddCodeLine ("\tbne\t*+3");
AddCodeLine ("\tinx");
/* Tell the optimizer that the X register may be invalid */
AddCodeHint ("x:!");
} else if (FavourSize) {
/* Use jsr calls */ /* Use jsr calls */
if (val <= 8) { if (val <= 8) {
AddCodeLine ("\tjsr\tincax%u", val); AddCodeLine ("\tjsr\tincax%u", val);
@@ -3172,8 +3190,14 @@ void g_dec (unsigned flags, unsigned long val)
case CF_CHAR: case CF_CHAR:
if (flags & CF_FORCECHAR) { if (flags & CF_FORCECHAR) {
AddCodeLine ("\tsec"); if (CPU == CPU_65C02 && val <= 2) {
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF); while (val--) {
AddCodeLine ("\tdea");
}
} else {
AddCodeLine ("\tsec");
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
}
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */

View File

@@ -44,7 +44,7 @@
#include "expr.h" #include "expr.h"
#include "function.h" #include "function.h"
#include "global.h" #include "global.h"
#include "include.h" #include "incpath.h"
#include "io.h" #include "io.h"
#include "litpool.h" #include "litpool.h"
#include "macrotab.h" #include "macrotab.h"

50
src/cc65/cpu.c Normal file
View File

@@ -0,0 +1,50 @@
/*****************************************************************************/
/* */
/* cpu.c */
/* */
/* CPU type definitions */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include "cpu.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Current CPU */
CPUType CPU = CPU_6502;

63
src/cc65/cpu.h Normal file
View File

@@ -0,0 +1,63 @@
/*****************************************************************************/
/* */
/* cpu.h */
/* */
/* CPU type definitions */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef CPU_H
#define CPU_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Supported CPUs */
typedef enum CPUType {
CPU_6502,
CPU_65C02
} CPUType;
/* Current CPU */
extern CPUType CPU;
/* End of cpu.h */
#endif

View File

@@ -1,45 +0,0 @@
/*
* include.h - Include file handling for cc65
*
* Ullrich von Bassewitz, 18.08.1998
*/
#ifndef INCLUDE_H
#define INCLUDE_H
/*****************************************************************************/
/* data */
/*****************************************************************************/
#define INC_SYS 0x0001 /* Add to system include path */
#define INC_USER 0x0002 /* Add to user include path */
/*****************************************************************************/
/* code */
/*****************************************************************************/
void AddIncludePath (const char* NewPath, unsigned Where);
/* Add a new include path to the existing one */
char* FindInclude (const char* Name, unsigned Where);
/* Find an include file. Return a pointer to a malloced area that contains
* the complete path, if found, return 0 otherwise.
*/
/* End of include.h */
#endif

View File

@@ -1,8 +1,35 @@
/* /*****************************************************************************/
* include.c - Include file handling for cc65 /* */
* /* incpath.c */
* Ullrich von Bassewitz, 18.08.1998 /* */
*/ /* Include path handling for cc65 */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
@@ -18,12 +45,12 @@
#endif #endif
#include "mem.h" #include "mem.h"
#include "include.h" #include "incpath.h"
/*****************************************************************************/ /*****************************************************************************/
/* data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@@ -34,7 +61,7 @@ static char* UserIncludePath = 0;
/*****************************************************************************/ /*****************************************************************************/
/* code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@@ -161,4 +188,3 @@ char* FindInclude (const char* Name, unsigned Where)

72
src/cc65/incpath.h Normal file
View File

@@ -0,0 +1,72 @@
/*****************************************************************************/
/* */
/* incpath.h */
/* */
/* Include path handling for cc65 */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef INCPATH_H
#define INCPATH_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
#define INC_SYS 0x0001 /* Add to system include path */
#define INC_USER 0x0002 /* Add to user include path */
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void AddIncludePath (const char* NewPath, unsigned Where);
/* Add a new include path to the existing one */
char* FindInclude (const char* Name, unsigned Where);
/* Find an include file. Return a pointer to a malloced area that contains
* the complete path, if found, return 0 otherwise.
*/
/* End of incpath.h */
#endif

View File

@@ -112,7 +112,7 @@ static void CloseInclude (void)
int readline (void) int NextLine (void)
/* Get a line from the current input. Returns -1 on end of file. */ /* Get a line from the current input. Returns -1 on end of file. */
{ {
unsigned Len; unsigned Len;

View File

@@ -73,7 +73,7 @@ int gch (void);
* pointer (no end of line check is performed). * pointer (no end of line check is performed).
*/ */
int readline (void); int NextLine (void);
/* Get a line from the current input. Returns -1 on end of file. */ /* Get a line from the current input. Returns -1 on end of file. */

View File

@@ -1,4 +1,37 @@
/* CC65 main program */ /*****************************************************************************/
/* */
/* main.c */
/* */
/* cc65 main program */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -6,13 +39,15 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include "../common/cmdline.h"
#include "../common/version.h" #include "../common/version.h"
#include "asmcode.h" #include "asmcode.h"
#include "compile.h" #include "compile.h"
#include "cpu.h"
#include "error.h" #include "error.h"
#include "global.h" #include "global.h"
#include "include.h" #include "incpath.h"
#include "io.h" #include "io.h"
#include "macrotab.h" #include "macrotab.h"
#include "mem.h" #include "mem.h"
@@ -50,57 +85,46 @@ static const char* TargetNames [] = {
static void usage (int ExitCode) static void Usage (void)
{ {
fputs ("Usage: cc65 [options] file\n" fprintf (stderr,
"\t-d\t\tDebug mode\n" "Usage: cc65 [options] file\n"
"\t-g\t\tAdd debug info to object files\n" "Short options:\n"
"\t-h\t\tPrint this help\n" " -d\t\t\tDebug mode\n"
"\t-j\t\tDefault characters are signed\n" " -g\t\t\tAdd debug info to object file\n"
"\t-o name\t\tName the output file\n" " -h\t\t\tPrint this help\n"
"\t-tx\t\tSet target system x\n" " -j\t\t\tDefault characters are signed\n"
"\t-v\t\tVerbose mode\n" " -o name\t\tName the output file\n"
"\t-A\t\tStrict ANSI mode\n" " -t sys\t\tSet the target system\n"
"\t-Cl\t\tMake local variables static\n" " -v\t\t\tIncrease verbosity\n"
"\t-Dsym[=defn]\tDefine a symbol\n" " -A\t\t\tStrict ANSI mode\n"
"\t-I path\t\tSet include directory\n" " -Cl\t\t\tMake local variables static\n"
"\t-O\t\tOptimize code\n" " -Dsym[=defn]\t\tDefine a symbol\n"
"\t-Oi\t\tOptimize code, inline more code\n" " -I path\t\tSet an include directory search path\n"
"\t-Or\t\tEnable register variables\n" " -O\t\t\tOptimize code\n"
"\t-Os\t\tInline some known functions\n" " -Oi\t\t\tOptimize code, inline more code\n"
"\t-T\t\tInclude source as comment\n" " -Or\t\t\tEnable register variables\n"
"\t-V\t\tPrint version number\n" " -Os\t\t\tInline some known functions\n"
"\t-W\t\tSuppress warnings\n", " -T\t\t\tInclude source as comment\n"
stderr); " -V\t\t\tPrint the compiler version number\n"
exit (ExitCode); " -W\t\t\tSuppress warnings\n"
"\n"
"Long options:\n"
" --ansi\t\tStrict ANSI mode\n"
" --cpu type\t\tSet cpu type\n"
" --debug-info\t\tAdd debug info to object file\n"
" --help\t\tHelp (this text)\n"
" --include-dir dir\tSet an include directory search path\n"
" --signed-chars\tDefault characters are signed\n"
" --target sys\t\tSet the target system\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the compiler version number\n");
} }
static char* GetArg (int* ArgNum, char* argv [], unsigned Len)
/* Get an option argument */
{
char* Arg = argv [*ArgNum];
if (Arg [Len] != '\0') {
/* Argument appended */
return Arg + Len;
} else {
/* Separate argument */
Arg = argv [*ArgNum + 1];
if (Arg == 0) {
/* End of arguments */
fprintf (stderr, "Option requires an argument: %s\n", argv [*ArgNum]);
exit (EXIT_FAILURE);
}
++(*ArgNum);
return Arg;
}
}
/* Define a CBM system */
static void cbmsys (const char* sys) static void cbmsys (const char* sys)
/* Define a CBM system */
{ {
AddNumericMacro ("__CBM__", 1); AddNumericMacro ("__CBM__", 1);
AddNumericMacro (sys, 1); AddNumericMacro (sys, 1);
@@ -133,8 +157,8 @@ static int MapSys (const char* Name)
/* Define a target system */
static void SetSys (const char* Sys) static void SetSys (const char* Sys)
/* Define a target system */
{ {
switch (Target = MapSys (Sys)) { switch (Target = MapSys (Sys)) {
@@ -142,7 +166,7 @@ static void SetSys (const char* Sys)
break; break;
case TGT_ATARI: case TGT_ATARI:
AddNumericMacro ("__ATARI__", 1); AddNumericMacro ("__ATARI__", 1);
break; break;
case TGT_C64: case TGT_C64:
@@ -184,21 +208,12 @@ static void SetSys (const char* Sys)
default: default:
fputs ("Unknown system type\n", stderr); fputs ("Unknown system type\n", stderr);
usage (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
static void InvSym (const char* Def)
/* Print an error about an invalid macro definition and die */
{
fprintf (stderr, "Invalid macro definition: `%s'\n", Def);
exit (EXIT_FAILURE);
}
static void DefineSym (const char* Def) static void DefineSym (const char* Def)
/* Define a symbol on the command line */ /* Define a symbol on the command line */
{ {
@@ -206,7 +221,7 @@ static void DefineSym (const char* Def)
/* The symbol must start with a character or underline */ /* The symbol must start with a character or underline */
if (Def [0] != '_' && !isalpha (Def [0])) { if (Def [0] != '_' && !isalpha (Def [0])) {
InvSym (Def); InvDef (Def);
} }
/* Check the symbol name */ /* Check the symbol name */
@@ -217,7 +232,7 @@ static void DefineSym (const char* Def)
/* Do we have a value given? */ /* Do we have a value given? */
if (*P != '=') { if (*P != '=') {
if (*P != '\0') { if (*P != '\0') {
InvSym (Def); InvDef (Def);
} }
/* No value given. Define the macro with the value 1 */ /* No value given. Define the macro with the value 1 */
AddNumericMacro (Def, 1); AddNumericMacro (Def, 1);
@@ -236,29 +251,147 @@ static void DefineSym (const char* Def)
/* Define this as a macro */ /* Define this as a macro */
AddTextMacro (S, Q); AddTextMacro (S, Q);
/* Release the allocated memory */ /* Release the allocated memory */
xfree (S); xfree (S);
} }
} }
int main (int argc, char **argv) static void OptAnsi (const char* Opt, const char* Arg)
/* Compile in strict ANSI mode */
{ {
int i; ANSI = 1;
char *argp; }
static void OptCPU (const char* Opt, const char* Arg)
/* Handle the --cpu option */
{
if (Arg == 0) {
NeedArg (Opt);
}
if (strcmp (Arg, "6502") == 0) {
CPU = CPU_6502;
} else if (strcmp (Arg, "65C02") == 0) {
CPU = CPU_65C02;
} else {
fprintf (stderr, "Invalid CPU: `%s'\n", Arg);
exit (EXIT_FAILURE);
}
}
static void OptDebugInfo (const char* Opt, const char* Arg)
/* Add debug info to the object file */
{
DebugInfo = 1;
}
static void OptHelp (const char* Opt, const char* Arg)
/* Print usage information and exit */
{
Usage ();
exit (EXIT_SUCCESS);
}
static void OptIncludeDir (const char* Opt, const char* Arg)
/* Add an include search path */
{
if (Arg == 0) {
NeedArg (Opt);
}
AddIncludePath (Arg, INC_SYS | INC_USER);
}
static void OptSignedChars (const char* Opt, const char* Arg)
/* Make default characters signed */
{
SignedChars = 1;
}
static void OptTarget (const char* Opt, const char* Arg)
/* Set the target system */
{
if (Arg == 0) {
NeedArg (Opt);
}
SetSys (Arg);
}
static void OptVerbose (const char* Opt, const char* Arg)
/* Increase verbosity */
{
++Verbose;
}
static void OptVersion (const char* Opt, const char* Arg)
/* Print the assembler version */
{
fprintf (stderr,
"cc65 V%u.%u.%u\n",
VER_MAJOR, VER_MINOR, VER_PATCH);
}
int main (int argc, char* argv[])
{
/* Program long options */
static const LongOpt OptTab[] = {
{ "--ansi", 0, OptAnsi },
{ "--cpu", 1, OptCPU },
{ "--debug-info", 0, OptDebugInfo },
{ "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir },
{ "--signed-chars", 0, OptSignedChars },
{ "--target", 1, OptTarget },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
};
int I;
char out_name [256]; char out_name [256];
char* p;
/* Initialize the output file name */ /* Initialize the output file name */
out_name [0] = '\0'; out_name [0] = '\0';
fin = NULL; fin = NULL;
/* Initialize the cmdline module */
InitCmdLine (argc, argv);
/* Parse the command line */ /* Parse the command line */
for (i = 1; i < argc; i++) { I = 1;
if (*(argp = argv[i]) == '-') { while (I < argc) {
switch (argp[1]) {
const char* P;
/* Get the argument */
const char* Arg = argv [I];
/* Check for an option */
if (Arg [0] == '-') {
switch (Arg [1]) {
case '-':
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
break;
case 'd': /* debug mode */ case 'd': /* debug mode */
Debug = 1; Debug = 1;
@@ -266,68 +399,68 @@ int main (int argc, char **argv)
case 'h': case 'h':
case '?': case '?':
usage (EXIT_SUCCESS); OptHelp (Arg, 0);
break; break;
case 'g': case 'g':
DebugInfo = 1; OptDebugInfo (Arg, 0);
break; break;
case 'j': case 'j':
SignedChars = 1; OptSignedChars (Arg, 0);
break; break;
case 'o': case 'o':
strcpy (out_name, GetArg (&i, argv, 2)); strcpy (out_name, GetArg (&I, 2));
break; break;
case 't': case 't':
SetSys (GetArg (&i, argv, 2)); OptTarget (Arg, GetArg (&I, 2));
break; break;
case 'v': case 'v':
++Verbose; OptVerbose (Arg, 0);
break; break;
case 'A': case 'A':
ANSI = 1; OptAnsi (Arg, 0);
break; break;
case 'C': case 'C':
p = argp + 2; P = Arg + 2;
while (*p) { while (*P) {
switch (*p++) { switch (*P++) {
case 'l': case 'l':
LocalsAreStatic = 1; LocalsAreStatic = 1;
break; break;
} }
} }
break; break;
case 'D': case 'D':
DefineSym (GetArg (&i, argv, 2)); DefineSym (GetArg (&I, 2));
break; break;
case 'I': case 'I':
AddIncludePath (GetArg (&i, argv, 2), INC_SYS | INC_USER); OptIncludeDir (Arg, GetArg (&I, 2));
break; break;
case 'O': case 'O':
Optimize = 1; Optimize = 1;
p = argp + 2; P = Arg + 2;
while (*p) { while (*P) {
switch (*p++) { switch (*P++) {
case 'f': case 'f':
sscanf (p, "%lx", (long*) &OptDisable); sscanf (P, "%lx", (long*) &OptDisable);
break; break;
case 'i': case 'i':
FavourSize = 0; FavourSize = 0;
break; break;
case 'r': case 'r':
EnableRegVars = 1; EnableRegVars = 1;
break; break;
case 's': case 's':
InlineStdFuncs = 1; InlineStdFuncs = 1;
break; break;
} }
} }
@@ -338,8 +471,7 @@ int main (int argc, char **argv)
break; break;
case 'V': case 'V':
fprintf (stderr, "cc65 V%u.%u.%u\n", OptVersion (Arg, 0);
VER_MAJOR, VER_MINOR, VER_PATCH);
break; break;
case 'W': case 'W':
@@ -347,21 +479,26 @@ int main (int argc, char **argv)
break; break;
default: default:
fprintf (stderr, "Invalid option %s\n", argp); UnknownOption (Arg);
usage (EXIT_FAILURE); break;
} }
} else { } else {
if (fin) { if (fin) {
fprintf (stderr, "additional file specs ignored\n"); fprintf (stderr, "additional file specs ignored\n");
} else { } else {
fin = xstrdup (argp); fin = xstrdup (Arg);
inp = fopen (fin, "r"); inp = fopen (fin, "r");
if (inp == 0) { if (inp == 0) {
Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno)); Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno));
} }
} }
} }
/* Next argument */
++I;
} }
/* Did we have a file spec on the command line? */
if (!fin) { if (!fin) {
fprintf (stderr, "%s: No input files\n", argv [0]); fprintf (stderr, "%s: No input files\n", argv [0]);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
@@ -370,8 +507,10 @@ int main (int argc, char **argv)
/* Create the output file name. We should really have /* Create the output file name. We should really have
* some checks for string overflow, but I'll drop this because of the * some checks for string overflow, but I'll drop this because of the
* additional code size it would need (as in other places). Sigh. * additional code size it would need (as in other places). Sigh.
* #### To be removed
*/ */
if (out_name [0] == '\0') { if (out_name [0] == '\0') {
char* p;
/* No output name given, create default */ /* No output name given, create default */
strcpy (out_name, fin); strcpy (out_name, fin);
if ((p = strrchr (out_name, '.'))) { if ((p = strrchr (out_name, '.'))) {
@@ -414,3 +553,4 @@ int main (int argc, char **argv)
} }

View File

@@ -16,6 +16,7 @@ OBJS = anonname.o \
check.o \ check.o \
codegen.o \ codegen.o \
compile.o \ compile.o \
cpu.o \
ctrans.o \ ctrans.o \
datatype.o \ datatype.o \
declare.o \ declare.o \
@@ -26,7 +27,7 @@ OBJS = anonname.o \
global.o \ global.o \
goto.o \ goto.o \
ident.o \ ident.o \
include.o \ incpath.o \
io.o \ io.o \
litpool.o \ litpool.o \
locals.o \ locals.o \

View File

@@ -70,6 +70,7 @@ OBJS = anonname.obj \
check.obj \ check.obj \
codegen.obj \ codegen.obj \
compile.obj \ compile.obj \
cpu.obj \
ctrans.obj \ ctrans.obj \
datatype.obj \ datatype.obj \
declare.obj \ declare.obj \
@@ -80,7 +81,7 @@ OBJS = anonname.obj \
global.obj \ global.obj \
goto.obj \ goto.obj \
ident.obj \ ident.obj \
include.obj \ incpath.obj \
io.obj \ io.obj \
litpool.obj \ litpool.obj \
locals.obj \ locals.obj \
@@ -126,6 +127,7 @@ FILE asmline.obj
FILE check.obj FILE check.obj
FILE codegen.obj FILE codegen.obj
FILE compile.obj FILE compile.obj
FILE cpu.obj
FILE ctrans.obj FILE ctrans.obj
FILE datatype.obj FILE datatype.obj
FILE declare.obj FILE declare.obj
@@ -136,7 +138,7 @@ FILE function.obj
FILE global.obj FILE global.obj
FILE goto.obj FILE goto.obj
FILE ident.obj FILE ident.obj
FILE include.obj FILE incpath.obj
FILE io.obj FILE io.obj
FILE litpool.obj FILE litpool.obj
FILE locals.obj FILE locals.obj

View File

@@ -40,6 +40,7 @@
#include "asmlabel.h" #include "asmlabel.h"
#include "asmline.h" #include "asmline.h"
#include "check.h" #include "check.h"
#include "cpu.h"
#include "error.h" #include "error.h"
#include "global.h" #include "global.h"
#include "io.h" #include "io.h"
@@ -123,10 +124,14 @@ static const struct {
{ "\tcmp\t", 0, REG_A, REG_NONE }, { "\tcmp\t", 0, REG_A, REG_NONE },
{ "\tcpx\t", 0, REG_X, REG_NONE }, { "\tcpx\t", 0, REG_X, REG_NONE },
{ "\tcpy\t", 0, REG_Y, REG_NONE }, { "\tcpy\t", 0, REG_Y, REG_NONE },
{ "\tdea", 1, REG_A, REG_NONE },
{ "\tdec\ta", 1, REG_A, REG_NONE },
{ "\tdec\t", 0, REG_NONE, REG_NONE }, { "\tdec\t", 0, REG_NONE, REG_NONE },
{ "\tdex", 1, REG_X, REG_NONE }, { "\tdex", 1, REG_X, REG_NONE },
{ "\tdey", 1, REG_Y, REG_NONE }, { "\tdey", 1, REG_Y, REG_NONE },
{ "\teor\t", 0, REG_A, REG_NONE }, { "\teor\t", 0, REG_A, REG_NONE },
{ "\tina", 1, REG_A, REG_NONE },
{ "\tinc\ta", 1, REG_A, REG_NONE },
{ "\tinc\t", 0, REG_NONE, REG_NONE }, { "\tinc\t", 0, REG_NONE, REG_NONE },
{ "\tinx", 1, REG_X, REG_NONE }, { "\tinx", 1, REG_X, REG_NONE },
{ "\tiny", 1, REG_Y, REG_NONE }, { "\tiny", 1, REG_Y, REG_NONE },
@@ -164,6 +169,7 @@ static const struct {
{ "\tsta\t", 0, REG_A, REG_NONE }, { "\tsta\t", 0, REG_A, REG_NONE },
{ "\tstx\t", 0, REG_X, REG_NONE }, { "\tstx\t", 0, REG_X, REG_NONE },
{ "\tsty\t", 0, REG_Y, REG_NONE }, { "\tsty\t", 0, REG_Y, REG_NONE },
{ "\tstz\t", 0, REG_NONE, REG_NONE },
{ "\ttax", 1, REG_A, REG_X }, { "\ttax", 1, REG_A, REG_X },
{ "\ttay", 1, REG_A, REG_Y }, { "\ttay", 1, REG_A, REG_Y },
{ "\ttsx", 1, REG_NONE, REG_X }, { "\ttsx", 1, REG_NONE, REG_X },
@@ -559,7 +565,7 @@ static int IsCondJump (Line* L)
static int IsXIndAddrMode (Line* L) static int IsXAddrMode (Line* L)
/* Return true if the given line does use the X register */ /* Return true if the given line does use the X register */
{ {
unsigned Len = strlen (L->Line); unsigned Len = strlen (L->Line);
@@ -569,15 +575,15 @@ static int IsXIndAddrMode (Line* L)
static int NoXIndAddrMode (Line* L) static int NoXAddrMode (Line* L)
/* Return true if the given line does use the X register */ /* Return true if the given line does use the X register */
{ {
return !IsXIndAddrMode (L); return !IsXAddrMode (L);
} }
static int IsYIndAddrMode (Line* L) static int IsYAddrMode (Line* L)
/* Return true if the given line does use the Y register */ /* Return true if the given line does use the Y register */
{ {
unsigned Len = strlen (L->Line); unsigned Len = strlen (L->Line);
@@ -779,7 +785,13 @@ static unsigned EstimateDataSize (Line* L, unsigned Chunk)
static unsigned EstimateSize (Line* L) static unsigned EstimateSize (Line* L)
/* Estimate the size of an instruction */ /* Estimate the size of an instruction */
{ {
static const char* Transfers [] = { static const char* OneByteCmds [] = {
"\tdea",
"\tdex",
"\tdey",
"\tina",
"\tinx",
"\tiny"
"\ttax", "\ttax",
"\ttay", "\ttay",
"\ttsx", "\ttsx",
@@ -819,7 +831,7 @@ static unsigned EstimateSize (Line* L)
if (LineMatchX (L, LongBranches) >= 0) { if (LineMatchX (L, LongBranches) >= 0) {
return 5; return 5;
} }
if (LineMatchX (L, Transfers) >= 0) { if (LineMatchX (L, OneByteCmds) >= 0) {
return 1; return 1;
} }
return 3; return 3;
@@ -1141,9 +1153,9 @@ static unsigned RVUInt2 (Line* L,
/* Evaluate the use flags, check for addressing modes */ /* Evaluate the use flags, check for addressing modes */
R = CmdDesc[I].Use; R = CmdDesc[I].Use;
if (IsXIndAddrMode (L)) { if (IsXAddrMode (L)) {
R |= REG_X; R |= REG_X;
} else if (IsYIndAddrMode (L)) { } else if (IsYAddrMode (L)) {
R |= REG_Y; R |= REG_Y;
} }
if (R) { if (R) {
@@ -1323,7 +1335,7 @@ static void OptCompares1 (void)
(Cond = TosCmpFunc (L2[4])) >= 0) { (Cond = TosCmpFunc (L2[4])) >= 0) {
/* Replace it */ /* Replace it */
if (IsXIndAddrMode (L2[0])) { if (IsXAddrMode (L2[0])) {
/* The load is X indirect, so we may not remove the load /* The load is X indirect, so we may not remove the load
* of the X register. * of the X register.
*/ */
@@ -1377,7 +1389,7 @@ static void OptCompares1 (void)
Offs = GetHexNum (L2[2]->Line+7) - 2; Offs = GetHexNum (L2[2]->Line+7) - 2;
/* Replace it */ /* Replace it */
if (IsXIndAddrMode (L2[0])) { if (IsXAddrMode (L2[0])) {
/* The load is X indirect, so we may not remove the load /* The load is X indirect, so we may not remove the load
* of the X register. * of the X register.
*/ */
@@ -1637,7 +1649,7 @@ static void OptLoads (void)
LineFullMatch (L2 [1], "\tjsr\tpushax")) { LineFullMatch (L2 [1], "\tjsr\tpushax")) {
/* Be sure, X is not used in the load */ /* Be sure, X is not used in the load */
if (NoXIndAddrMode (L2 [0])) { if (NoXAddrMode (L2 [0])) {
/* Replace the subroutine call */ /* Replace the subroutine call */
L2 [1] = ReplaceLine (L2 [1], "\tjsr\tpusha0"); L2 [1] = ReplaceLine (L2 [1], "\tjsr\tpusha0");
@@ -1667,7 +1679,7 @@ static void OptLoads (void)
LineMatch (L2 [1], "\tcmp\t#$")) { LineMatch (L2 [1], "\tcmp\t#$")) {
/* Be sure, X is not used in the load */ /* Be sure, X is not used in the load */
if (NoXIndAddrMode (L2 [0])) { if (NoXAddrMode (L2 [0])) {
/* Remove the unnecessary load */ /* Remove the unnecessary load */
FreeLine (L); FreeLine (L);
@@ -1693,7 +1705,7 @@ static void OptLoads (void)
LineFullMatch (L2 [1], "\tjsr\tbnega")) { LineFullMatch (L2 [1], "\tjsr\tbnega")) {
/* Be sure, X is not used in the load */ /* Be sure, X is not used in the load */
if (NoXIndAddrMode (L2 [0])) { if (NoXAddrMode (L2 [0])) {
/* Remove the unnecessary load */ /* Remove the unnecessary load */
FreeLine (L); FreeLine (L);
@@ -3630,12 +3642,16 @@ static Line* OptOneBlock (Line* L)
if (A != -1) { if (A != -1) {
A = (A << 1) & 0xFF; A = (A << 1) & 0xFF;
} }
} else if (CPU == CPU_65C02 && LineFullMatch (L, "\tdea")) {
DEC (A, 1);
} else if (LineFullMatch (L, "\tdex")) { } else if (LineFullMatch (L, "\tdex")) {
DEC (X, 1); DEC (X, 1);
} else if (LineFullMatch (L, "\tdey")) { } else if (LineFullMatch (L, "\tdey")) {
DEC (Y, 1); DEC (Y, 1);
} else if (LineMatch (L, "\teor")) { } else if (LineMatch (L, "\teor")) {
A = -1; A = -1;
} else if (CPU == CPU_65C02 && LineFullMatch (L, "\tina")) {
INC (A, 1);
} else if (LineFullMatch (L, "\tinx")) { } else if (LineFullMatch (L, "\tinx")) {
INC (X, 1); INC (X, 1);
} else if (LineFullMatch (L, "\tiny")) { } else if (LineFullMatch (L, "\tiny")) {
@@ -3949,7 +3965,7 @@ static Line* OptOneBlock (Line* L)
/* The value loaded is not used later, remove it */ /* The value loaded is not used later, remove it */
Delete = 1; Delete = 1;
} else if (LineMatch (L, "\tlda\t(")) { } else if (LineMatch (L, "\tlda\t(")) {
if (IsXIndAddrMode (L)) { if (IsXAddrMode (L)) {
/* lda (zp,x) - if Y and X are both zero, replace by /* lda (zp,x) - if Y and X are both zero, replace by
* load indirect y and save one cycle in some cases. * load indirect y and save one cycle in some cases.
*/ */
@@ -3982,6 +3998,13 @@ static Line* OptOneBlock (Line* L)
} else if (NewVal == Y) { } else if (NewVal == Y) {
/* Requested value is already in Y */ /* Requested value is already in Y */
L = ReplaceLine (L, "\ttya"); L = ReplaceLine (L, "\ttya");
} else if (CPU == CPU_65C02 && A != -1) {
/* Try ina/dea operators of 65C02 */
if (NewVal == ((A - 1) & 0xFF)) {
L = ReplaceLine (L, "\tdea");
} else if (NewVal == ((A + 1) & 0xFF)) {
L = ReplaceLine (L, "\tina");
}
} }
/* Anyway, the new value is now in A */ /* Anyway, the new value is now in A */
A = NewVal; A = NewVal;
@@ -4066,6 +4089,22 @@ static Line* OptOneBlock (Line* L)
A = X = Y = -1; A = X = Y = -1;
} else if (LineMatch (L, "\tsbc\t")) { } else if (LineMatch (L, "\tsbc\t")) {
A = -1; A = -1;
} else if (CPU == CPU_65C02 && LineMatch (L, "\tst")) {
/* Try to replace by stz if possible */
if (A == 0 && LineMatch (L, "\tsta\t")) {
/* Not indirect and not Y allowed */
if (L->Line[5] != '(' && !IsYAddrMode (L)) {
L->Line[3] = 'z';
}
} else if (X == 0 && LineMatch (L, "\tstx\t")) {
/* absolute,y not allowed */
if (!IsYAddrMode (L)) {
L->Line[3] = 'z';
}
} else if (Y == 0 && LineMatch (L, "\tsty\t")) {
/* sty and stz share all addressing modes */
L->Line[3] = 'z';
}
} else if (LineFullMatch (L, "\ttax")) { } else if (LineFullMatch (L, "\ttax")) {
if (A != -1 && X == A) { if (A != -1 && X == A) {
/* Load has no effect */ /* Load has no effect */

View File

@@ -12,7 +12,7 @@
#include "expr.h" #include "expr.h"
#include "global.h" #include "global.h"
#include "ident.h" #include "ident.h"
#include "include.h" #include "incpath.h"
#include "io.h" #include "io.h"
#include "macrotab.h" #include "macrotab.h"
#include "mem.h" #include "mem.h"
@@ -89,7 +89,7 @@ static void comment (void)
gch (); gch ();
while (*lptr != '*' || nch () != '/') { while (*lptr != '*' || nch () != '/') {
if (*lptr == '\0') { if (*lptr == '\0') {
if (readline () == 0) { if (NextLine () == 0) {
PPError (ERR_EOF_IN_COMMENT, StartingLine); PPError (ERR_EOF_IN_COMMENT, StartingLine);
return; return;
} }
@@ -283,7 +283,7 @@ static int MacroCall (Macro* M)
skipblank (); skipblank ();
} else if (C == '\0') { } else if (C == '\0') {
/* End of line inside macro argument list - read next line */ /* End of line inside macro argument list - read next line */
if (readline () == 0) { if (NextLine () == 0) {
return 0; return 0;
} }
} else { } else {
@@ -864,7 +864,7 @@ void preprocess (void)
} }
} }
if (readline () == 0) { if (NextLine () == 0) {
if (i_ifdef >= 0) { if (i_ifdef >= 0) {
PPError (ERR_CPP_ENDIF_EXPECTED); PPError (ERR_CPP_ENDIF_EXPECTED);
} }

View File

@@ -137,7 +137,7 @@ static int skipwhite (void)
{ {
while (1) { while (1) {
while (*lptr == 0) { while (*lptr == 0) {
if (readline () == 0) { if (NextLine () == 0) {
return 0; return 0;
} }
preprocess (); preprocess ();