1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-11 05:29:33 +00:00

First da65 version

git-svn-id: svn://svn.cc65.org/cc65/trunk@332 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-09-24 15:55:57 +00:00
parent c05f6064a4
commit 5a90b5a58c
18 changed files with 3986 additions and 0 deletions

177
src/da65/attrtab.c Normal file
View File

@ -0,0 +1,177 @@
/*****************************************************************************/
/* */
/* attrtab.c */
/* */
/* Disassembler attribute table */
/* */
/* */
/* */
/* (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>
/* common */
#include "xmalloc.h"
#include "xsprintf.h"
/* da65 */
#include "error.h"
#include "attrtab.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Attribute table */
static unsigned char AttrTab [0x10000];
/* Symbol table */
static const char* SymTab [0x10000];
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void AddrCheck (unsigned Addr)
/* Check if the given address has a valid range */
{
if (Addr >= 0x10000) {
Error ("Address out of range: %08X", Addr);
}
}
void MarkRange (unsigned Start, unsigned End, attr_t Attr)
/* Mark a range with the given attribute */
{
/* Do it easy here... */
while (Start <= End) {
MarkAddr (Start++, Attr);
}
}
void MarkAddr (unsigned Addr, attr_t Attr)
/* Mark an address with an attribute */
{
/* Check the given address */
AddrCheck (Addr);
/* We must not have more than one style bit */
if (Attr & atStyleMask) {
if (AttrTab[Addr] & atStyleMask) {
Error ("Duplicate style for address %04X", Addr);
}
}
/* Set the style */
AttrTab[Addr] |= Attr;
}
const char* MakeLabelName (unsigned Addr)
/* Make the default label name from the given address and return it in a
* static buffer.
*/
{
static char LabelBuf [32];
xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
return LabelBuf;
}
void AddLabel (unsigned Addr, const char* Name)
/* Add a label */
{
/* Check the given address */
AddrCheck (Addr);
/* Must not have two symbols for one address */
if (SymTab[Addr] != 0) {
if (strcmp (SymTab[Addr], Name) == 0) {
/* Allow label if it has the same name */
return;
}
Error ("Duplicate label for address %04X: %s/%s", Addr, SymTab[Addr], Name);
}
/* Create a new label */
SymTab[Addr] = xstrdup (Name);
}
int HaveLabel (unsigned Addr)
/* Check if there is a label for the given address */
{
/* Check the given address */
AddrCheck (Addr);
/* Check for a label */
return (SymTab[Addr] != 0);
}
const char* GetLabel (unsigned Addr)
/* Return the label for an address */
{
/* Check the given address */
AddrCheck (Addr);
/* Return the label if any */
return SymTab[Addr];
}
unsigned char GetStyle (unsigned Addr)
/* Return the style attribute for the given address */
{
/* Check the given address */
AddrCheck (Addr);
/* Return the attribute */
return (AttrTab[Addr] & atStyleMask);
}

97
src/da65/attrtab.h Normal file
View File

@ -0,0 +1,97 @@
/*****************************************************************************/
/* */
/* attrtab.h */
/* */
/* Disassembler attribute table */
/* */
/* */
/* */
/* (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 ATTRTAB_H
#define ATTRTAB_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
typedef enum attr_t attr_t;
enum attr_t {
atDefault = 0x00, /* Default style */
atCode = 0x01,
atIllegal = 0x02,
atByteTab = 0x02, /* Same as illegal */
atWordTab = 0x04,
atRtsTab = 0x08,
atLabel = 0x80,
atStyleMask = 0x0F /* Output style */
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void MarkRange (unsigned Start, unsigned End, attr_t Attr);
/* Mark a range with the given attribute */
void MarkAddr (unsigned Addr, attr_t Attr);
/* Mark an address with an attribute */
const char* MakeLabelName (unsigned Addr);
/* Make the default label name from the given address and return it in a
* static buffer.
*/
void AddLabel (unsigned Addr, const char* Name);
/* Add a label */
int HaveLabel (unsigned Addr);
/* Check if there is a label for the given address */
const char* GetLabel (unsigned Addr);
/* Return the label for an address */
unsigned char GetStyle (unsigned Addr);
/* Return the style attribute for the given address */
/* End of attrtab.h */
#endif

157
src/da65/code.c Normal file
View File

@ -0,0 +1,157 @@
/*****************************************************************************/
/* */
/* code.c */
/* */
/* Binary code management */
/* */
/* */
/* */
/* (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>
#include <errno.h>
/* common */
#include "check.h"
/* da65 */
#include "error.h"
#include "code.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
static unsigned char CodeBuf [0x10000]; /* Code buffer */
static unsigned long CodeStart; /* Start address */
static unsigned long CodeEnd; /* End address */
static unsigned long PC; /* Current PC */
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void LoadCode (const char* Name, unsigned long StartAddress)
/* Load the code from the given file */
{
unsigned Count, MaxCount;
FILE* F;
PRECONDITION (StartAddress < 0x10000);
/* Calculate the maximum code size */
MaxCount = 0x10000 - StartAddress;
/* Open the file */
F = fopen (Name, "rb");
if (F == 0) {
Error ("Cannot open `%s': %s", Name, strerror (errno));
}
/* Read from the file and remember the number of bytes read */
Count = fread (CodeBuf + StartAddress, 1, MaxCount, F);
if (ferror (F)) {
Error ("Error reading from `%s': %s", Name, strerror (errno));
}
if (Count == 0) {
Error ("File `%s' contains no data", Name);
}
/* Set the buffer variables */
CodeStart = PC = StartAddress;
CodeEnd = CodeStart + Count - 1; /* CodeEnd is inclusive */
}
unsigned GetPC (void)
/* Get the current program counter */
{
return PC;
}
unsigned char PeekCodeByte (void)
/* Peek at the byte at the current PC */
{
PRECONDITION (PC <= CodeEnd);
return CodeBuf [PC];
}
unsigned char GetCodeByte (void)
/* Get a byte from the PC and increment it */
{
PRECONDITION (PC <= CodeEnd);
return CodeBuf [PC++];
}
unsigned GetCodeWord (void)
/* Get a word from the current PC and increment it */
{
unsigned Lo = GetCodeByte ();
unsigned Hi = GetCodeByte ();
return Lo | (Hi << 8);
}
unsigned GetRemainingBytes (void)
/* Return the number of remaining code bytes */
{
if (CodeEnd >= PC) {
return (CodeEnd - PC + 1);
} else {
return 0;
}
}
void ResetCode (void)
/* Reset the code input to start over for the next pass */
{
PC = CodeStart;
}

74
src/da65/code.h Normal file
View File

@ -0,0 +1,74 @@
/*****************************************************************************/
/* */
/* code.h */
/* */
/* Binary code management */
/* */
/* */
/* */
/* (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 CODE_H
#define CODE_H
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void LoadCode (const char* Name, unsigned long StartAddress);
/* Load the code from the given file */
unsigned GetPC (void);
/* Get the current program counter */
unsigned char PeekCodeByte (void);
/* Peek at the byte at the current PC */
unsigned char GetCodeByte (void);
/* Get a byte from the PC and increment it */
unsigned GetCodeWord (void);
/* Get a word from the current PC and increment it */
unsigned GetRemainingBytes (void);
/* Return the number of remaining code bytes */
void ResetCode (void);
/* Reset the code input to start over for the next pass */
/* End of code.h */
#endif

66
src/da65/cpu.c Normal file
View File

@ -0,0 +1,66 @@
/*****************************************************************************/
/* */
/* 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;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void SetCPU (CPUType NewCPU)
/* Set a new CPU */
{
CPU = NewCPU;
}

75
src/da65/cpu.h Normal file
View File

@ -0,0 +1,75 @@
/*****************************************************************************/
/* */
/* 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,
CPU_65816
} CPUType;
/* Current CPU */
extern CPUType CPU;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void SetCPU (CPUType NewCPU);
/* Set a new CPU */
/* End of cpu.h */
#endif

91
src/da65/error.c Normal file
View File

@ -0,0 +1,91 @@
/*****************************************************************************/
/* */
/* error.c */
/* */
/* Error handling */
/* */
/* */
/* */
/* (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 <stdlib.h>
#include <stdarg.h>
/* da65 */
#include "error.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void Warning (const char* Format, ...)
/* Print a warning message */
{
va_list ap;
va_start (ap, Format);
fprintf (stderr, "Warning: ");
vfprintf (stderr, Format, ap);
putc ('\n', stderr);
va_end (ap);
}
void Error (const char* Format, ...)
/* Print an error message and die */
{
va_list ap;
va_start (ap, Format);
fprintf (stderr, "Error: ");
vfprintf (stderr, Format, ap);
putc ('\n', stderr);
va_end (ap);
exit (EXIT_FAILURE);
}
void Internal (const char* Format, ...)
/* Print an internal error message and die */
{
va_list ap;
va_start (ap, Format);
fprintf (stderr, "Internal error: ");
vfprintf (stderr, Format, ap);
putc ('\n', stderr);
va_end (ap);
exit (EXIT_FAILURE);
}

68
src/da65/error.h Normal file
View File

@ -0,0 +1,68 @@
/*****************************************************************************/
/* */
/* error.h */
/* */
/* Error handling */
/* */
/* */
/* */
/* (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 ERROR_H
#define ERROR_H
/* common */
#include "attrib.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void Warning (const char* Format, ...) attribute((format(printf,1,2)));
/* Print a warning message */
void Error (const char* Format, ...) attribute((format(printf,1,2)));
/* Print an error message and die */
void Internal (const char* Format, ...) attribute((format(printf,1,2)));
/* Print an internal error message and die */
/* End of error.h */
#endif

67
src/da65/global.c Normal file
View File

@ -0,0 +1,67 @@
/*****************************************************************************/
/* */
/* global.c */
/* */
/* Global variables for the da65 disassembler */
/* */
/* */
/* */
/* (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 "global.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* File names */
const char* InFile = 0; /* Name of input file */
const char* OutFile = 0; /* Name of output file */
/* Default extensions */
const char ObjExt[] = ".o"; /* Default object extension */
const char ListExt[] = ".lst"; /* Default listing extension */
/* Flags and other command line stuff */
unsigned char Verbose = 2; /* Verbosity of the output file */
/* Stuff needed by many routines */
unsigned Pass = 0; /* Disassembler pass */
/* Page formatting */
int PageLength = -1; /* Length of a listing page */
unsigned MIndent = 9; /* Mnemonic indent */
unsigned AIndent = 17; /* Argument indent */
unsigned CIndent = 33; /* Comment indent */

76
src/da65/global.h Normal file
View File

@ -0,0 +1,76 @@
/*****************************************************************************/
/* */
/* global.h */
/* */
/* Global variables for the da65 disassembler */
/* */
/* */
/* */
/* (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 GLOBAL_H
#define GLOBAL_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* File names */
extern const char* InFile; /* Name of input file */
extern const char* OutFile; /* Name of output file */
/* Default extensions */
extern const char ObjExt[]; /* Default object extension */
extern const char ListExt[]; /* Default listing extension */
/* Flags and other command line stuff */
extern unsigned char Verbose; /* Verbosity of the output file */
/* Stuff needed by many routines */
extern unsigned Pass; /* Disassembler pass */
/* Page formatting */
#define MIN_PAGE_LEN 32
#define MAX_PAGE_LEN 127
extern int PageLength; /* Length of a listing page */
extern unsigned MIndent; /* Mnemonic indent */
extern unsigned AIndent; /* Argument indent */
extern unsigned CIndent; /* Comment indent */
/* End of global.h */
#endif

392
src/da65/handler.c Normal file
View File

@ -0,0 +1,392 @@
/*****************************************************************************/
/* */
/* handler.c */
/* */
/* Opcode handler functions for the disassembler */
/* */
/* */
/* */
/* (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 <stdarg.h>
/* common */
#include "xsprintf.h"
/* da65 */
#include "attrtab.h"
#include "code.h"
#include "error.h"
#include "global.h"
#include "opctable.h"
#include "output.h"
#include "handler.h"
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
static void Mnemonic (const char* M)
/* Indent and output a mnemonic */
{
Indent (MIndent);
Output ("%s", M);
}
static void OneLine (const char* Mnemo, const char* Arg, ...) attribute ((format(printf, 2, 3)));
static void OneLine (const char* Mnemo, const char* Arg, ...)
/* Output one line with the given mnemonic and argument */
{
char Buf [256];
va_list ap;
/* Mnemonic */
Mnemonic (Mnemo);
/* Argument */
va_start (ap, Arg);
xvsprintf (Buf, sizeof (Buf), Arg, ap);
va_end (ap);
Indent (AIndent);
Output (Buf);
/* End the line */
LineFeed ();
}
static const char* GetAddrArg (const OpcDesc* D, unsigned Addr)
/* Return an address argument - a label if we have one, or the address itself */
{
const char* Label = 0;
if (D->LabelFlag & lfUseLabel) {
Label = GetLabel (Addr);
}
if (Label) {
return Label;
} else {
static char Buf [32];
if (Addr < 0x100) {
xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
} else {
xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
}
return Buf;
}
}
static void GenerateLabel (const OpcDesc* D, unsigned Addr)
/* Generate a label in pass one if requested */
{
if (Pass == 1 && !HaveLabel (Addr) && (D->LabelFlag & lfGenLabel) != 0) {
AddLabel (Addr, MakeLabelName (Addr));
}
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void OH_Accumulator (const OpcDesc* D)
{
OneLine (D->Mnemo, "a");
}
void OH_Implicit (const OpcDesc* D)
{
Mnemonic (D->Mnemo);
LineFeed ();
}
void OH_Immidiate (const OpcDesc* D)
{
OneLine (D->Mnemo, "#$%02X", GetCodeByte ());
}
void OH_Direct (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
}
void OH_DirectX (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
}
void OH_DirectY (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
}
void OH_Absolute (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeWord ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
}
void OH_AbsoluteX (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeWord ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s,x", GetAddrArg (D, Addr));
}
void OH_AbsoluteY (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeWord ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
}
void OH_AbsoluteLong (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_AbsoluteLongX (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_Relative (const OpcDesc* D)
{
/* Get the operand */
signed char Offs = GetCodeByte ();
/* Calculate the target address */
unsigned Addr = (unsigned) (((int) GetPC()) + Offs);
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
}
void OH_RelativeLong (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_DirectIndirect (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "(%s)", GetAddrArg (D, Addr));
}
void OH_DirectIndirectY (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "(%s),y", GetAddrArg (D, Addr));
}
void OH_DirectXIndirect (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "(%s,x)", GetAddrArg (D, Addr));
}
void OH_AbsoluteIndirect (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeWord ();
/* Generate a label in pass 1 */
GenerateLabel (D, Addr);
/* Output the line */
OneLine (D->Mnemo, "(%s)", GetAddrArg (D, Addr));
}
void OH_StackRelative (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_DirectIndirectLongX (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_StackRelativeIndirectY (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_DirectIndirectLong (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_DirectIndirectLongY (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_BlockMove (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_AbsoluteXIndirect (const OpcDesc* D)
{
Error ("Not implemented");
}
void OH_Rts (const OpcDesc* D)
{
OH_Implicit (D);
SeparatorLine();
}
void OH_JmpAbsolute (const OpcDesc* D)
{
OH_Absolute (D);
SeparatorLine ();
}

88
src/da65/handler.h Normal file
View File

@ -0,0 +1,88 @@
/*****************************************************************************/
/* */
/* handler.h */
/* */
/* Opcode handler functions for the disassembler */
/* */
/* */
/* */
/* (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 HANDLER_H
#define HANDLER_H
#include "opctable.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
/* Generic handlers */
void OH_Accumulator (const OpcDesc*);
void OH_Implicit (const OpcDesc*);
void OH_Immidiate (const OpcDesc*);
void OH_Direct (const OpcDesc*);
void OH_DirectX (const OpcDesc*);
void OH_DirectY (const OpcDesc*);
void OH_Absolute (const OpcDesc*);
void OH_AbsoluteX (const OpcDesc*);
void OH_AbsoluteY (const OpcDesc*);
void OH_AbsoluteLong (const OpcDesc*);
void OH_AbsoluteLongX (const OpcDesc*);
void OH_Relative (const OpcDesc*);
void OH_RelativeLong (const OpcDesc*);
void OH_DirectIndirect (const OpcDesc*);
void OH_DirectIndirectY (const OpcDesc*);
void OH_DirectXIndirect (const OpcDesc*);
void OH_AbsoluteIndirect (const OpcDesc*);
void OH_StackRelative (const OpcDesc*);
void OH_DirectIndirectLongX (const OpcDesc*);
void OH_StackRelativeIndirectY (const OpcDesc*);
void OH_DirectIndirectLong (const OpcDesc*);
void OH_DirectIndirectLongY (const OpcDesc*);
void OH_BlockMove (const OpcDesc*);
void OH_AbsoluteXIndirect (const OpcDesc*);
/* Handlers for special instructions */
void OH_Rts (const OpcDesc*);
void OH_JmpAbsolute (const OpcDesc*);
/* End of handler.h */
#endif

334
src/da65/main.c Normal file
View File

@ -0,0 +1,334 @@
/*****************************************************************************/
/* */
/* main.c */
/* */
/* Main program for the da65 disassembler */
/* */
/* */
/* */
/* (C) 1998-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 <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
/* common */
#include "abend.h"
#include "cmdline.h"
#include "fname.h"
#include "version.h"
/* da65 */
#include "attrtab.h"
#include "code.h"
#include "cpu.h"
#include "global.h"
#include "opctable.h"
#include "output.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static void Usage (void)
/* Print usage information and exit */
{
fprintf (stderr,
"Usage: %s [options] file\n"
"Short options:\n"
" -g\t\t\tAdd debug info to object file\n"
" -h\t\t\tHelp (this text)\n"
" -i\t\t\tIgnore case of symbols\n"
" -l\t\t\tCreate a listing if assembly was ok\n"
" -o name\t\tName the output file\n"
" -s\t\t\tEnable smart mode\n"
" -t sys\t\tSet the target system\n"
" -v\t\t\tIncrease verbosity\n"
" -D name[=value]\tDefine a symbol\n"
" -I dir\t\tSet an include directory search path\n"
" -U\t\t\tMark unresolved symbols as import\n"
" -V\t\t\tPrint the assembler version\n"
" -W n\t\t\tSet warning level n\n"
"\n"
"Long options:\n"
" --auto-import\t\tMark unresolved symbols as import\n"
" --cpu type\t\tSet cpu type\n"
" --debug-info\t\tAdd debug info to object file\n"
" --feature name\tSet an emulation feature\n"
" --help\t\tHelp (this text)\n"
" --ignore-case\t\tIgnore case of symbols\n"
" --include-dir dir\tSet an include directory search path\n"
" --listing\t\tCreate a listing if assembly was ok\n"
" --pagelength n\tSet the page length for the listing\n"
" --smart\t\tEnable smart mode\n"
" --target sys\t\tSet the target system\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the assembler version\n",
ProgName);
}
static void OptCPU (const char* Opt, const char* Arg)
/* Handle the --cpu option */
{
if (Arg == 0) {
NeedArg (Opt);
}
if (strcmp (Arg, "6502") == 0) {
SetCPU (CPU_6502);
} else if (strcmp (Arg, "65C02") == 0) {
SetCPU (CPU_65C02);
} else if (strcmp (Arg, "65816") == 0) {
SetCPU (CPU_65816);
#ifdef SUNPLUS
} else if (strcmp (Arg, "sunplus") == 0) {
SetCPU (CPU_SUNPLUS);
#endif
} else {
AbEnd ("Invalid CPU: `%s'", Arg);
}
}
static void OptHelp (const char* Opt, const char* Arg)
/* Print usage information and exit */
{
Usage ();
exit (EXIT_SUCCESS);
}
static void OptPageLength (const char* Opt, const char* Arg)
/* Handle the --pagelength option */
{
int Len;
if (Arg == 0) {
NeedArg (Opt);
}
Len = atoi (Arg);
if (Len != -1 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) {
AbEnd ("Invalid page length: %d", Len);
}
PageLength = Len;
}
static void OptVerbose (const char* Opt, const char* Arg)
/* Increase verbosity */
{
++Verbose;
}
static void OptVersion (const char* Opt, const char* Arg)
/* Print the disassembler version */
{
fprintf (stderr,
"da65 V%u.%u.%u - (C) Copyright 2000 Ullrich von Bassewitz\n",
VER_MAJOR, VER_MINOR, VER_PATCH);
}
static void OneOpcode (unsigned RemainingBytes)
/* Disassemble one opcode */
{
/* Get the current PC */
unsigned PC = GetPC ();
/* Get the attribute for the current address */
unsigned char Style = GetStyle (PC);
/* Get the opcode from the current address */
unsigned char OPC = PeekCodeByte ();
/* Get the opcode description for the opcode byte */
const OpcDesc* D = &OpcTable[OPC];
/* If we have a label at this address, output the label */
const char* Label = GetLabel (PC);
if (Label) {
DefLabel (Label);
}
/* Check if we have enough bytes remaining for the code at this address. */
if (D->Size > RemainingBytes) {
OneDataByte ();
return;
}
/* Also check if there are any labels that point into this instruction.
* If so, disassemble one byte as data.
*/
/* ### */
/* Disassemble the line */
GetCodeByte ();
D->Handler (D);
}
static void OnePass (void)
/* Make one pass through the code */
{
unsigned Count;
/* Disassemble until nothing left */
while ((Count = GetRemainingBytes()) > 0) {
OneOpcode (Count);
}
}
static void Disassemble (void)
/* Disassemble the code */
{
/* Pass 1 */
Pass = 1;
OnePass ();
Output ("---------------------------");
LineFeed ();
/* Pass 2 */
ResetCode ();
Pass = 2;
OnePass ();
}
int main (int argc, char* argv [])
/* Assembler main program */
{
/* Program long options */
static const LongOpt OptTab[] = {
{ "--cpu", 1, OptCPU },
{ "--help", 0, OptHelp },
{ "--pagelength", 1, OptPageLength },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
};
int I;
/* Initialize the cmdline module */
InitCmdLine (argc, argv, "da65");
/* Check the parameters */
I = 1;
while (I < argc) {
/* 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 'h':
OptHelp (Arg, 0);
break;
case 'o':
OutFile = GetArg (&I, 2);
break;
case 'v':
OptVerbose (Arg, 0);
break;
case 'V':
OptVersion (Arg, 0);
break;
default:
UnknownOption (Arg);
break;
}
} else {
/* Filename. Check if we already had one */
if (InFile) {
fprintf (stderr, "%s: Don't know what to do with `%s'\n",
ProgName, Arg);
exit (EXIT_FAILURE);
} else {
InFile = Arg;
}
}
/* Next argument */
++I;
}
/* Must have an input file */
if (InFile == 0) {
AbEnd ("No input file");
}
/* Make the output file name from the input file name if none was given */
if (OutFile == 0) {
OutFile = MakeFilename (InFile, ".dis");
}
/* Load the input file */
LoadCode (InFile, 0xE000); /* ### */
/* Open the output file */
OpenOutput (OutFile);
/* Disassemble the code */
Disassemble ();
/* Close the output file */
CloseOutput ();
/* Done */
return EXIT_SUCCESS;
}

56
src/da65/make/gcc.mak Normal file
View File

@ -0,0 +1,56 @@
#
# gcc Makefile for da65
#
# Library dir
COMMON = ../common
CFLAGS = -g -O2 -Wall -I$(COMMON)
CC=gcc
LDFLAGS=
OBJS = attrtab.o \
code.o \
cpu.o \
error.o \
global.o \
handler.o \
main.o \
opctable.o \
output.o
LIBS = $(COMMON)/common.a
EXECS = da65
.PHONY: all
ifeq (.depend,$(wildcard .depend))
all : $(EXECS)
include .depend
else
all: depend
@$(MAKE) -f make/gcc.mak all
endif
da65: $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
clean:
rm -f *~ core *.map
zap: clean
rm -f *.o $(EXECS) .depend
# ------------------------------------------------------------------------------
# Make the dependencies
.PHONY: depend dep
depend dep: $(OBJS:.o=.c)
@echo "Creating dependency information"
$(CC) -I$(COMMON) -MM $^ > .depend

1843
src/da65/opctable.c Normal file

File diff suppressed because it is too large Load Diff

87
src/da65/opctable.h Normal file
View File

@ -0,0 +1,87 @@
/*****************************************************************************/
/* */
/* opctable.h */
/* */
/* Disassembler opcode description table */
/* */
/* */
/* */
/* (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 OPCTABLE_H
#define OPCTABLE_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Constants for LabelFlag */
enum {
lfNoLabel = 0x00, /* Don't use a label */
lfGenLabel = 0x01, /* Generate a label */
lfUseLabel = 0x02, /* Use a label if there is one */
lfLabel = lfUseLabel|lfGenLabel /* Generate and use a label */
};
/* Constants for the CPU type */
enum {
cpu6502 = 0x01,
cpu65C02 = 0x02,
cpu65816 = 0x04,
cpuAll = 0x07,
};
/* Forward/typedef for struct OpcDesc */
typedef struct OpcDesc OpcDesc;
/* Type of pointer to a function that handles opcode output */
typedef void (*OpcHandler) (const OpcDesc*);
/* Description for one opcode */
struct OpcDesc {
char Mnemo [4]; /* Mnemonic */
unsigned char Size; /* Size of this command */
unsigned char LabelFlag; /* Generate/use label? */
unsigned char CPU; /* Available for which CPU? */
OpcHandler Handler; /* Handler routine */
};
/* Descriptions for all opcodes */
extern const OpcDesc OpcTable[256];
/* End of opctable.h */
#endif

155
src/da65/output.c Normal file
View File

@ -0,0 +1,155 @@
/*****************************************************************************/
/* */
/* output.c */
/* */
/* Disassembler output routines */
/* */
/* */
/* */
/* (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 <stdarg.h>
#include <string.h>
#include <errno.h>
/* da65 */
#include "code.h"
#include "error.h"
#include "global.h"
#include "output.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
static FILE* F = 0; /* Output stream */
static unsigned Col = 1; /* Current column */
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void OpenOutput (const char* Name)
/* Open the given file for output */
{
/* Open the output file */
F = fopen (Name, "w");
if (F == 0) {
Error ("Cannot open `%s': %s", Name, strerror (errno));
}
}
void CloseOutput (void)
/* Close the output file */
{
if (fclose (F) != 0) {
Error ("Error closing output file: %s", strerror (errno));
}
}
void Output (const char* Format, ...)
/* Write to the output file */
{
if (Pass > 1) {
va_list ap;
va_start (ap, Format);
Col += vfprintf (F, Format, ap);
va_end (ap);
}
}
void Indent (unsigned N)
/* Make sure the current line column is at position N (zero based) */
{
if (Pass > 1) {
while (Col < N) {
fputc (' ', F);
++Col;
}
}
}
void LineFeed (void)
/* Add a linefeed to the output file */
{
if (Pass > 1) {
fputc ('\n', F);
Col = 1;
}
}
void DefLabel (const char* Name)
/* Define a label with the given name */
{
Output ("%s:", Name);
LineFeed ();
}
void OneDataByte (void)
/* Output a .byte line with the current code byte */
{
if (Pass > 1) {
Indent (MIndent);
Output (".byte");
Indent (AIndent);
Output ("$%02X", GetCodeByte());
LineFeed ();
}
}
void SeparatorLine (void)
/* Print a separator line */
{
Output ("; -------------------------------------------------------------------------");
LineFeed ();
}

83
src/da65/output.h Normal file
View File

@ -0,0 +1,83 @@
/*****************************************************************************/
/* */
/* output.h */
/* */
/* Disassembler output routines */
/* */
/* */
/* */
/* (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 OUTPUT_H
#define OUTPUT_H
/* common */
#include "attrib.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void OpenOutput (const char* Name);
/* Open the given file for output */
void CloseOutput (void);
/* Close the output file */
void Output (const char* Format, ...) attribute ((format(printf, 1, 2)));
/* Write to the output file */
void Indent (unsigned N);
/* Make sure the current line column is at position N (zero based) */
void LineFeed (void);
/* Add a linefeed to the output file */
void DefLabel (const char* Name);
/* Define a label with the given name */
void OneDataByte (void);
/* Output a .byte line with the current code byte */
void SeparatorLine (void);
/* Print a separator line */
/* End of output.h */
#endif