1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-28 19:29:53 +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 "asmlabel.h"
#include "check.h"
#include "cpu.h"
#include "error.h"
#include "global.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);
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 */
AddCodeLine (".autoimport\ton");
@ -920,7 +926,7 @@ void g_getind (unsigned flags, unsigned offs)
}
void g_leasp (int offs)
/* 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:
if (flags & CF_FORCECHAR) {
AddCodeLine ("\tclc");
AddCodeLine ("\tadc\t#$%02X", val & 0xFF);
if (CPU == CPU_65C02 && val <= 2) {
while (val--) {
AddCodeLine ("\tina");
}
} else {
AddCodeLine ("\tclc");
AddCodeLine ("\tadc\t#$%02X", val & 0xFF);
}
break;
}
/* FALLTHROUGH */
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 */
if (val <= 8) {
AddCodeLine ("\tjsr\tincax%u", val);
@ -3172,8 +3190,14 @@ void g_dec (unsigned flags, unsigned long val)
case CF_CHAR:
if (flags & CF_FORCECHAR) {
AddCodeLine ("\tsec");
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
if (CPU == CPU_65C02 && val <= 2) {
while (val--) {
AddCodeLine ("\tdea");
}
} else {
AddCodeLine ("\tsec");
AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
}
break;
}
/* FALLTHROUGH */

View File

@ -44,7 +44,7 @@
#include "expr.h"
#include "function.h"
#include "global.h"
#include "include.h"
#include "incpath.h"
#include "io.h"
#include "litpool.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
*
* Ullrich von Bassewitz, 18.08.1998
*/
/*****************************************************************************/
/* */
/* incpath.c */
/* */
/* 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
#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. */
{
unsigned Len;

View File

@ -73,7 +73,7 @@ int gch (void);
* 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. */

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 <string.h>
@ -6,13 +39,15 @@
#include <ctype.h>
#include <errno.h>
#include "../common/cmdline.h"
#include "../common/version.h"
#include "asmcode.h"
#include "compile.h"
#include "cpu.h"
#include "error.h"
#include "global.h"
#include "include.h"
#include "incpath.h"
#include "io.h"
#include "macrotab.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"
"\t-d\t\tDebug mode\n"
"\t-g\t\tAdd debug info to object files\n"
"\t-h\t\tPrint this help\n"
"\t-j\t\tDefault characters are signed\n"
"\t-o name\t\tName the output file\n"
"\t-tx\t\tSet target system x\n"
"\t-v\t\tVerbose mode\n"
"\t-A\t\tStrict ANSI mode\n"
"\t-Cl\t\tMake local variables static\n"
"\t-Dsym[=defn]\tDefine a symbol\n"
"\t-I path\t\tSet include directory\n"
"\t-O\t\tOptimize code\n"
"\t-Oi\t\tOptimize code, inline more code\n"
"\t-Or\t\tEnable register variables\n"
"\t-Os\t\tInline some known functions\n"
"\t-T\t\tInclude source as comment\n"
"\t-V\t\tPrint version number\n"
"\t-W\t\tSuppress warnings\n",
stderr);
exit (ExitCode);
fprintf (stderr,
"Usage: cc65 [options] file\n"
"Short options:\n"
" -d\t\t\tDebug mode\n"
" -g\t\t\tAdd debug info to object file\n"
" -h\t\t\tPrint this help\n"
" -j\t\t\tDefault characters are signed\n"
" -o name\t\tName the output file\n"
" -t sys\t\tSet the target system\n"
" -v\t\t\tIncrease verbosity\n"
" -A\t\t\tStrict ANSI mode\n"
" -Cl\t\t\tMake local variables static\n"
" -Dsym[=defn]\t\tDefine a symbol\n"
" -I path\t\tSet an include directory search path\n"
" -O\t\t\tOptimize code\n"
" -Oi\t\t\tOptimize code, inline more code\n"
" -Or\t\t\tEnable register variables\n"
" -Os\t\t\tInline some known functions\n"
" -T\t\t\tInclude source as comment\n"
" -V\t\t\tPrint the compiler version number\n"
" -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)
/* Define a CBM system */
{
AddNumericMacro ("__CBM__", 1);
AddNumericMacro (sys, 1);
@ -133,8 +157,8 @@ static int MapSys (const char* Name)
/* Define a target system */
static void SetSys (const char* Sys)
/* Define a target system */
{
switch (Target = MapSys (Sys)) {
@ -142,7 +166,7 @@ static void SetSys (const char* Sys)
break;
case TGT_ATARI:
AddNumericMacro ("__ATARI__", 1);
AddNumericMacro ("__ATARI__", 1);
break;
case TGT_C64:
@ -184,21 +208,12 @@ static void SetSys (const char* Sys)
default:
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)
/* 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 */
if (Def [0] != '_' && !isalpha (Def [0])) {
InvSym (Def);
InvDef (Def);
}
/* Check the symbol name */
@ -217,7 +232,7 @@ static void DefineSym (const char* Def)
/* Do we have a value given? */
if (*P != '=') {
if (*P != '\0') {
InvSym (Def);
InvDef (Def);
}
/* No value given. Define the macro with the value 1 */
AddNumericMacro (Def, 1);
@ -236,29 +251,147 @@ static void DefineSym (const char* Def)
/* Define this as a macro */
AddTextMacro (S, Q);
/* Release the allocated memory */
xfree (S);
/* Release the allocated memory */
xfree (S);
}
}
int main (int argc, char **argv)
static void OptAnsi (const char* Opt, const char* Arg)
/* Compile in strict ANSI mode */
{
int i;
char *argp;
ANSI = 1;
}
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* p;
/* Initialize the output file name */
out_name [0] = '\0';
fin = NULL;
/* Initialize the cmdline module */
InitCmdLine (argc, argv);
/* Parse the command line */
for (i = 1; i < argc; i++) {
if (*(argp = argv[i]) == '-') {
switch (argp[1]) {
I = 1;
while (I < argc) {
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 */
Debug = 1;
@ -266,68 +399,68 @@ int main (int argc, char **argv)
case 'h':
case '?':
usage (EXIT_SUCCESS);
OptHelp (Arg, 0);
break;
case 'g':
DebugInfo = 1;
OptDebugInfo (Arg, 0);
break;
case 'j':
SignedChars = 1;
OptSignedChars (Arg, 0);
break;
case 'o':
strcpy (out_name, GetArg (&i, argv, 2));
case 'o':
strcpy (out_name, GetArg (&I, 2));
break;
case 't':
SetSys (GetArg (&i, argv, 2));
OptTarget (Arg, GetArg (&I, 2));
break;
case 'v':
++Verbose;
OptVerbose (Arg, 0);
break;
case 'A':
ANSI = 1;
OptAnsi (Arg, 0);
break;
case 'C':
p = argp + 2;
while (*p) {
switch (*p++) {
case 'l':
LocalsAreStatic = 1;
break;
}
P = Arg + 2;
while (*P) {
switch (*P++) {
case 'l':
LocalsAreStatic = 1;
break;
}
}
break;
case 'D':
DefineSym (GetArg (&i, argv, 2));
DefineSym (GetArg (&I, 2));
break;
case 'I':
AddIncludePath (GetArg (&i, argv, 2), INC_SYS | INC_USER);
OptIncludeDir (Arg, GetArg (&I, 2));
break;
case 'O':
Optimize = 1;
p = argp + 2;
while (*p) {
switch (*p++) {
case 'f':
sscanf (p, "%lx", (long*) &OptDisable);
break;
case 'i':
FavourSize = 0;
break;
case 'r':
EnableRegVars = 1;
P = Arg + 2;
while (*P) {
switch (*P++) {
case 'f':
sscanf (P, "%lx", (long*) &OptDisable);
break;
case 'i':
FavourSize = 0;
break;
case 'r':
EnableRegVars = 1;
break;
case 's':
InlineStdFuncs = 1;
InlineStdFuncs = 1;
break;
}
}
@ -338,8 +471,7 @@ int main (int argc, char **argv)
break;
case 'V':
fprintf (stderr, "cc65 V%u.%u.%u\n",
VER_MAJOR, VER_MINOR, VER_PATCH);
OptVersion (Arg, 0);
break;
case 'W':
@ -347,21 +479,26 @@ int main (int argc, char **argv)
break;
default:
fprintf (stderr, "Invalid option %s\n", argp);
usage (EXIT_FAILURE);
UnknownOption (Arg);
break;
}
} else {
if (fin) {
fprintf (stderr, "additional file specs ignored\n");
} else {
fin = xstrdup (argp);
fin = xstrdup (Arg);
inp = fopen (fin, "r");
if (inp == 0) {
Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno));
}
}
}
/* Next argument */
++I;
}
/* Did we have a file spec on the command line? */
if (!fin) {
fprintf (stderr, "%s: No input files\n", argv [0]);
exit (EXIT_FAILURE);
@ -370,8 +507,10 @@ int main (int argc, char **argv)
/* Create the output file name. We should really have
* some checks for string overflow, but I'll drop this because of the
* additional code size it would need (as in other places). Sigh.
* #### To be removed
*/
if (out_name [0] == '\0') {
char* p;
/* No output name given, create default */
strcpy (out_name, fin);
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 \
codegen.o \
compile.o \
cpu.o \
ctrans.o \
datatype.o \
declare.o \
@ -26,7 +27,7 @@ OBJS = anonname.o \
global.o \
goto.o \
ident.o \
include.o \
incpath.o \
io.o \
litpool.o \
locals.o \

View File

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

View File

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

View File

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

View File

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