Working
git-svn-id: svn://svn.cc65.org/cc65/trunk@338 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
16bc247cbf
commit
42fb5661f1
14 changed files with 549 additions and 98 deletions
|
@ -41,7 +41,10 @@
|
|||
#include "xsprintf.h"
|
||||
|
||||
/* da65 */
|
||||
#include "code.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "output.h"
|
||||
#include "attrtab.h"
|
||||
|
||||
|
||||
|
@ -175,3 +178,40 @@ unsigned char GetStyle (unsigned Addr)
|
|||
|
||||
|
||||
|
||||
static void DefineConst (unsigned Addr)
|
||||
/* Define an address constant */
|
||||
{
|
||||
Output ("%s", SymTab [Addr]);
|
||||
Indent (AIndent);
|
||||
Output ("= $%04X", Addr);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DefOutOfRangeLabels (void)
|
||||
/* Output any labels that are out of the loaded code range */
|
||||
{
|
||||
unsigned long Addr;
|
||||
|
||||
SeparatorLine ();
|
||||
|
||||
/* Low range */
|
||||
for (Addr = 0; Addr < CodeStart; ++Addr) {
|
||||
if (SymTab [Addr]) {
|
||||
DefineConst (Addr);
|
||||
}
|
||||
}
|
||||
|
||||
/* High range */
|
||||
for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) {
|
||||
if (SymTab [Addr]) {
|
||||
DefineConst (Addr);
|
||||
}
|
||||
}
|
||||
|
||||
SeparatorLine ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -49,10 +49,10 @@ enum attr_t {
|
|||
atDefault = 0x00, /* Default style */
|
||||
atCode = 0x01,
|
||||
atIllegal = 0x02,
|
||||
atByteTab = 0x02, /* Same as illegal */
|
||||
atByteTab = 0x03, /* Same as illegal */
|
||||
atWordTab = 0x04,
|
||||
atRtsTab = 0x08,
|
||||
atLabel = 0x80,
|
||||
atAddrTab = 0x05,
|
||||
atRtsTab = 0x06,
|
||||
|
||||
atStyleMask = 0x0F /* Output style */
|
||||
};
|
||||
|
@ -88,6 +88,9 @@ const char* GetLabel (unsigned Addr);
|
|||
unsigned char GetStyle (unsigned Addr);
|
||||
/* Return the style attribute for the given address */
|
||||
|
||||
void DefOutOfRangeLabels (void);
|
||||
/* Output any labels that are out of the loaded code range */
|
||||
|
||||
|
||||
|
||||
/* End of attrtab.h */
|
||||
|
|
|
@ -52,10 +52,10 @@
|
|||
|
||||
|
||||
|
||||
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 */
|
||||
unsigned char CodeBuf [0x10000]; /* Code buffer */
|
||||
unsigned long CodeStart; /* Start address */
|
||||
unsigned long CodeEnd; /* End address */
|
||||
unsigned long PC; /* Current PC */
|
||||
|
||||
|
||||
|
||||
|
@ -99,37 +99,20 @@ void LoadCode (const char* Name, unsigned long StartAddress)
|
|||
|
||||
|
||||
|
||||
unsigned GetPC (void)
|
||||
/* Get the current program counter */
|
||||
unsigned char GetCodeByte (unsigned Addr)
|
||||
/* Get a byte from the given address */
|
||||
{
|
||||
return PC;
|
||||
PRECONDITION (Addr <= CodeEnd);
|
||||
return CodeBuf [Addr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char PeekCodeByte (void)
|
||||
/* Peek at the byte at the current PC */
|
||||
unsigned GetCodeWord (unsigned Addr)
|
||||
/* Get a word from the given address */
|
||||
{
|
||||
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 ();
|
||||
unsigned Lo = GetCodeByte (Addr);
|
||||
unsigned Hi = GetCodeByte (Addr+1);
|
||||
return Lo | (Hi << 8);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,20 @@
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
extern unsigned char CodeBuf [0x10000]; /* Code buffer */
|
||||
extern unsigned long CodeStart; /* Start address */
|
||||
extern unsigned long CodeEnd; /* End address */
|
||||
extern unsigned long PC; /* Current PC */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -47,17 +60,11 @@
|
|||
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 GetCodeByte (unsigned Addr);
|
||||
/* Get a byte from the given address */
|
||||
|
||||
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 GetCodeWord (unsigned Addr);
|
||||
/* Get a word from the given address */
|
||||
|
||||
unsigned GetRemainingBytes (void);
|
||||
/* Return the number of remaining code bytes */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************/
|
||||
/* */
|
||||
/* config.c */
|
||||
/* config.c */
|
||||
/* */
|
||||
/* Disassembler configuration file handling */
|
||||
/* */
|
||||
|
@ -45,6 +45,8 @@
|
|||
#include "xmalloc.h"
|
||||
|
||||
/* da65 */
|
||||
#include "attrtab.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "scanner.h"
|
||||
#include "config.h"
|
||||
|
@ -127,11 +129,34 @@ static void RangeSection (void)
|
|||
/* Parse a range section */
|
||||
{
|
||||
static const IdentTok RangeDefs[] = {
|
||||
{ "START", CFGTOK_START },
|
||||
{ "END", CFGTOK_END },
|
||||
{ "START", CFGTOK_START },
|
||||
{ "END", CFGTOK_END },
|
||||
{ "TYPE", CFGTOK_TYPE },
|
||||
};
|
||||
|
||||
static const IdentTok TypeDefs[] = {
|
||||
{ "CODE", CFGTOK_CODE },
|
||||
{ "BYTETABLE", CFGTOK_BYTETAB },
|
||||
{ "WORDTABLE", CFGTOK_WORDTAB },
|
||||
{ "ADDRTABLE", CFGTOK_ADDRTAB },
|
||||
{ "RTSTABLE", CFGTOK_RTSTAB },
|
||||
};
|
||||
|
||||
|
||||
/* Which values did we get? */
|
||||
enum {
|
||||
tNone = 0x00,
|
||||
tStart = 0x01,
|
||||
tEnd = 0x02,
|
||||
tType = 0x04,
|
||||
tAll = 0x07
|
||||
} Needed = tNone;
|
||||
|
||||
/* Locals - initialize to avoid gcc warnings */
|
||||
unsigned Start = 0;
|
||||
unsigned End = 0;
|
||||
unsigned char Type = 0;
|
||||
|
||||
/* Skip the token */
|
||||
CfgNextTok ();
|
||||
|
||||
|
@ -141,9 +166,63 @@ static void RangeSection (void)
|
|||
/* Look for section tokens */
|
||||
while (CfgTok != CFGTOK_RCURLY) {
|
||||
|
||||
/* Convert to special token */
|
||||
CfgSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
|
||||
|
||||
/* Look at the token */
|
||||
switch (CfgTok) {
|
||||
|
||||
case CFGTOK_START:
|
||||
CfgNextTok ();
|
||||
CfgAssureInt ();
|
||||
CfgRangeCheck (0x0000, 0xFFFF);
|
||||
Start = CfgIVal;
|
||||
Needed |= tStart;
|
||||
CfgNextTok ();
|
||||
break;
|
||||
|
||||
case CFGTOK_END:
|
||||
CfgNextTok ();
|
||||
CfgAssureInt ();
|
||||
CfgRangeCheck (0x0000, 0xFFFF);
|
||||
End = CfgIVal;
|
||||
Needed |= tEnd;
|
||||
CfgNextTok ();
|
||||
break;
|
||||
|
||||
case CFGTOK_TYPE:
|
||||
CfgNextTok ();
|
||||
CfgSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_CODE: Type = atCode; break;
|
||||
case CFGTOK_BYTETAB: Type = atByteTab; break;
|
||||
case CFGTOK_WORDTAB: Type = atWordTab; break;
|
||||
case CFGTOK_ADDRTAB: Type = atAddrTab; break;
|
||||
case CFGTOK_RTSTAB: Type = atRtsTab; break;
|
||||
}
|
||||
Needed |= tType;
|
||||
CfgNextTok ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Directive is followed by a semicolon */
|
||||
CfgConsumeSemi ();
|
||||
|
||||
}
|
||||
|
||||
/* Did we get all required values? */
|
||||
if (Needed != tAll) {
|
||||
Error ("Required values missing from this section");
|
||||
}
|
||||
|
||||
/* Start must be less than end */
|
||||
if (Start > End) {
|
||||
Error ("Start value must not be greater than end value");
|
||||
}
|
||||
|
||||
/* Set the range */
|
||||
MarkRange (Start, End, Type);
|
||||
|
||||
/* Consume the closing brace */
|
||||
CfgConsumeRCurly ();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ const char OutExt[] = ".dis"; /* Output file extension */
|
|||
const char CfgExt[] = ".cfg"; /* Config file extension */
|
||||
|
||||
/* Flags and other command line stuff */
|
||||
unsigned char Verbosity = 2; /* Verbosity of the output file */
|
||||
unsigned char Verbosity = 4; /* Verbosity of the output file */
|
||||
|
||||
/* Stuff needed by many routines */
|
||||
unsigned Pass = 0; /* Disassembler pass */
|
||||
|
@ -61,7 +61,8 @@ unsigned Pass = 0; /* Disassembler pass */
|
|||
int PageLength = -1; /* Length of a listing page */
|
||||
unsigned MIndent = 9; /* Mnemonic indent */
|
||||
unsigned AIndent = 17; /* Argument indent */
|
||||
unsigned CIndent = 33; /* Comment indent */
|
||||
unsigned CIndent = 49; /* Comment indent */
|
||||
unsigned BytesPerLine = 8; /* Max. number of data bytes per line */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ extern int PageLength; /* Length of a listing page */
|
|||
extern unsigned MIndent; /* Mnemonic indent */
|
||||
extern unsigned AIndent; /* Argument indent */
|
||||
extern unsigned CIndent; /* Comment indent */
|
||||
extern unsigned BytesPerLine; /* Max. number of data bytes per line */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -64,15 +64,15 @@ static void Mnemonic (const char* M)
|
|||
|
||||
|
||||
|
||||
static void OneLine (const char* Mnemo, const char* Arg, ...) attribute ((format(printf, 2, 3)));
|
||||
static void OneLine (const char* Mnemo, const char* Arg, ...)
|
||||
static void OneLine (const OpcDesc* D, const char* Arg, ...) attribute ((format(printf, 2, 3)));
|
||||
static void OneLine (const OpcDesc* D, const char* Arg, ...)
|
||||
/* Output one line with the given mnemonic and argument */
|
||||
{
|
||||
char Buf [256];
|
||||
va_list ap;
|
||||
|
||||
/* Mnemonic */
|
||||
Mnemonic (Mnemo);
|
||||
Mnemonic (D->Mnemo);
|
||||
|
||||
/* Argument */
|
||||
va_start (ap, Arg);
|
||||
|
@ -81,6 +81,9 @@ static void OneLine (const char* Mnemo, const char* Arg, ...)
|
|||
Indent (AIndent);
|
||||
Output (Buf);
|
||||
|
||||
/* Add the code stuff as comment */
|
||||
LineComment (PC, D->Size);
|
||||
|
||||
/* End the line */
|
||||
LineFeed ();
|
||||
}
|
||||
|
@ -112,8 +115,11 @@ static const char* GetAddrArg (const OpcDesc* D, unsigned Addr)
|
|||
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));
|
||||
if (Pass == 1 && !HaveLabel (Addr)) {
|
||||
if ((D->LabelFlag & lfGenLabel) != 0 ||
|
||||
((D->LabelFlag & lfUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) {
|
||||
AddLabel (Addr, MakeLabelName (Addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +133,7 @@ static void GenerateLabel (const OpcDesc* D, unsigned Addr)
|
|||
|
||||
void OH_Accumulator (const OpcDesc* D)
|
||||
{
|
||||
OneLine (D->Mnemo, "a");
|
||||
OneLine (D, "a");
|
||||
}
|
||||
|
||||
|
||||
|
@ -135,6 +141,7 @@ void OH_Accumulator (const OpcDesc* D)
|
|||
void OH_Implicit (const OpcDesc* D)
|
||||
{
|
||||
Mnemonic (D->Mnemo);
|
||||
LineComment (PC, D->Size);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
@ -142,7 +149,7 @@ void OH_Implicit (const OpcDesc* D)
|
|||
|
||||
void OH_Immidiate (const OpcDesc* D)
|
||||
{
|
||||
OneLine (D->Mnemo, "#$%02X", GetCodeByte ());
|
||||
OneLine (D, "#$%02X", GetCodeByte (PC+1));
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,13 +157,13 @@ void OH_Immidiate (const OpcDesc* D)
|
|||
void OH_Direct (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte ();
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,13 +171,13 @@ void OH_Direct (const OpcDesc* D)
|
|||
void OH_DirectX (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte ();
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s,y", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -178,13 +185,13 @@ void OH_DirectX (const OpcDesc* D)
|
|||
void OH_DirectY (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte ();
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s,y", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,13 +199,13 @@ void OH_DirectY (const OpcDesc* D)
|
|||
void OH_Absolute (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeWord ();
|
||||
unsigned Addr = GetCodeWord (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,13 +213,13 @@ void OH_Absolute (const OpcDesc* D)
|
|||
void OH_AbsoluteX (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeWord ();
|
||||
unsigned Addr = GetCodeWord (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s,x", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s,x", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,13 +227,13 @@ void OH_AbsoluteX (const OpcDesc* D)
|
|||
void OH_AbsoluteY (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeWord ();
|
||||
unsigned Addr = GetCodeWord (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s,y", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s,y", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -248,16 +255,16 @@ void OH_AbsoluteLongX (const OpcDesc* D)
|
|||
void OH_Relative (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
signed char Offs = GetCodeByte ();
|
||||
signed char Offs = GetCodeByte (PC+1);
|
||||
|
||||
/* Calculate the target address */
|
||||
unsigned Addr = (unsigned) (((int) GetPC()) + Offs);
|
||||
unsigned Addr = (unsigned) (((int) PC+2) + Offs);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "%s", GetAddrArg (D, Addr));
|
||||
OneLine (D, "%s", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,13 +279,13 @@ void OH_RelativeLong (const OpcDesc* D)
|
|||
void OH_DirectIndirect (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte ();
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "(%s)", GetAddrArg (D, Addr));
|
||||
OneLine (D, "(%s)", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -286,13 +293,13 @@ void OH_DirectIndirect (const OpcDesc* D)
|
|||
void OH_DirectIndirectY (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte ();
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "(%s),y", GetAddrArg (D, Addr));
|
||||
OneLine (D, "(%s),y", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -300,13 +307,13 @@ void OH_DirectIndirectY (const OpcDesc* D)
|
|||
void OH_DirectXIndirect (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte ();
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "(%s,x)", GetAddrArg (D, Addr));
|
||||
OneLine (D, "(%s,x)", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,13 +321,13 @@ void OH_DirectXIndirect (const OpcDesc* D)
|
|||
void OH_AbsoluteIndirect (const OpcDesc* D)
|
||||
{
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeWord ();
|
||||
unsigned Addr = GetCodeWord (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D->Mnemo, "(%s)", GetAddrArg (D, Addr));
|
||||
OneLine (D, "(%s)", GetAddrArg (D, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
@ -390,3 +397,4 @@ void OH_JmpAbsolute (const OpcDesc* D)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
164
src/da65/main.c
164
src/da65/main.c
|
@ -50,6 +50,7 @@
|
|||
#include "code.h"
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "opctable.h"
|
||||
#include "output.h"
|
||||
|
@ -168,14 +169,149 @@ static void OptVersion (const char* Opt, const char* Arg)
|
|||
|
||||
|
||||
|
||||
static void ByteTable (unsigned RemainingBytes)
|
||||
/* Output a table of bytes */
|
||||
{
|
||||
/* Count how many bytes may be output. This number is limited by the
|
||||
* number of remaining bytes, a label, or the end of the ByteTable
|
||||
* attribute.
|
||||
*/
|
||||
unsigned Count = 1;
|
||||
while (Count < RemainingBytes) {
|
||||
if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atByteTab) {
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
}
|
||||
RemainingBytes -= Count;
|
||||
|
||||
/* Output as many data bytes lines as needed */
|
||||
while (Count > 0) {
|
||||
|
||||
/* Calculate the number of bytes for the next line */
|
||||
unsigned Chunk = (Count > BytesPerLine)? BytesPerLine : Count;
|
||||
|
||||
/* Output a line with these bytes */
|
||||
DataByteLine (Chunk);
|
||||
|
||||
/* Next line */
|
||||
Count -= Chunk;
|
||||
PC += Chunk;
|
||||
}
|
||||
|
||||
/* If the next line is not a byte table line, add a separator */
|
||||
if (RemainingBytes > 0 && GetStyle (PC) != atByteTab) {
|
||||
SeparatorLine ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void WordTable (unsigned RemainingBytes)
|
||||
/* Output a table of words */
|
||||
{
|
||||
/* Count how many bytes may be output. This number is limited by the
|
||||
* number of remaining bytes, a label, or the end of the WordTable
|
||||
* attribute.
|
||||
*/
|
||||
unsigned Count = 1;
|
||||
while (Count < RemainingBytes) {
|
||||
if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atWordTab) {
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
}
|
||||
RemainingBytes -= Count;
|
||||
|
||||
/* Make the given number even */
|
||||
Count &= ~1U;
|
||||
|
||||
/* Output as many data word lines as needed */
|
||||
while (Count > 0) {
|
||||
|
||||
/* Calculate the number of bytes for the next line */
|
||||
unsigned Chunk = (Count > BytesPerLine)? BytesPerLine : Count;
|
||||
|
||||
/* Output a line with these bytes */
|
||||
DataWordLine (Chunk);
|
||||
|
||||
/* Next line */
|
||||
PC += Chunk;
|
||||
Count -= Chunk;
|
||||
}
|
||||
|
||||
/* If the next line is not a byte table line, add a separator */
|
||||
if (RemainingBytes > 0 && GetStyle (PC) != atWordTab) {
|
||||
SeparatorLine ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void AddrTable (unsigned RemainingBytes)
|
||||
/* Output a table of addresses */
|
||||
{
|
||||
/* Count how many bytes may be output. This number is limited by the
|
||||
* number of remaining bytes, a label, or the end of the WordTable
|
||||
* attribute.
|
||||
*/
|
||||
unsigned Count = 1;
|
||||
while (Count < RemainingBytes) {
|
||||
if (HaveLabel(PC+Count) || GetStyle (PC+Count) != atAddrTab) {
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
}
|
||||
RemainingBytes -= Count;
|
||||
|
||||
/* Make the given number even */
|
||||
Count &= ~1U;
|
||||
|
||||
/* Output as many data bytes lines as needed. For addresses, each line
|
||||
* will hold just one address.
|
||||
*/
|
||||
while (Count > 0) {
|
||||
|
||||
/* Get the address */
|
||||
unsigned Addr = GetCodeWord (PC);
|
||||
|
||||
/* In pass 1, define a label, in pass 2 output the line */
|
||||
if (Pass == 1) {
|
||||
if (!HaveLabel (Addr)) {
|
||||
AddLabel (Addr, MakeLabelName (Addr));
|
||||
}
|
||||
} else {
|
||||
const char* Label = GetLabel (Addr);
|
||||
if (Label == 0) {
|
||||
/* OOPS! Should not happen */
|
||||
Internal ("OOPS - Label for address %04X disappeard!", Addr);
|
||||
}
|
||||
Indent (MIndent);
|
||||
Output (".word");
|
||||
Indent (AIndent);
|
||||
Output ("%s", Label);
|
||||
LineComment (PC, 2);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
/* Next line */
|
||||
PC += 2;
|
||||
Count -= 2;
|
||||
}
|
||||
|
||||
/* If the next line is not a byte table line, add a separator */
|
||||
if (RemainingBytes > 0 && GetStyle (PC) != atAddrTab) {
|
||||
SeparatorLine ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OneOpcode (unsigned RemainingBytes)
|
||||
/* Disassemble one opcode */
|
||||
{
|
||||
/* Get the current PC */
|
||||
unsigned PC = GetPC ();
|
||||
|
||||
/* Get the opcode from the current address */
|
||||
unsigned char OPC = PeekCodeByte ();
|
||||
unsigned char OPC = GetCodeByte (PC);
|
||||
|
||||
/* Get the opcode description for the opcode byte */
|
||||
const OpcDesc* D = &OpcTable[OPC];
|
||||
|
@ -213,12 +349,25 @@ static void OneOpcode (unsigned RemainingBytes)
|
|||
|
||||
case atDefault:
|
||||
case atCode:
|
||||
GetCodeByte ();
|
||||
D->Handler (D);
|
||||
PC += D->Size;
|
||||
break;
|
||||
|
||||
case atByteTab:
|
||||
ByteTable (RemainingBytes);
|
||||
break;
|
||||
|
||||
case atWordTab:
|
||||
WordTable (RemainingBytes);
|
||||
break;
|
||||
|
||||
case atAddrTab:
|
||||
AddrTable (RemainingBytes);
|
||||
break;
|
||||
|
||||
default:
|
||||
OneDataByte ();
|
||||
DataByteLine (1);
|
||||
++PC;
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -250,8 +399,9 @@ static void Disassemble (void)
|
|||
LineFeed ();
|
||||
|
||||
/* Pass 2 */
|
||||
Pass = 2;
|
||||
ResetCode ();
|
||||
Pass = 2;
|
||||
DefOutOfRangeLabels ();
|
||||
OnePass ();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ all : $(EXECS)
|
|||
include .depend
|
||||
else
|
||||
all: depend
|
||||
@$(MAKE) -f make/gcc.mak all
|
||||
@$(MAKE) -f make/gcc.mak all
|
||||
endif
|
||||
|
||||
|
||||
|
|
123
src/da65/make/watcom.mak
Normal file
123
src/da65/make/watcom.mak
Normal file
|
@ -0,0 +1,123 @@
|
|||
#
|
||||
# da65 Makefile for the Watcom compiler
|
||||
#
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Generic stuff
|
||||
|
||||
.AUTODEPEND
|
||||
.SUFFIXES .ASM .C .CC .CPP
|
||||
.SWAP
|
||||
|
||||
AR = WLIB
|
||||
LD = WLINK
|
||||
|
||||
!if !$d(TARGET)
|
||||
!if $d(__OS2__)
|
||||
TARGET = OS2
|
||||
!else
|
||||
TARGET = NT
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# target specific macros.
|
||||
!if $(TARGET)==OS2
|
||||
|
||||
# --------------------- OS2 ---------------------
|
||||
SYSTEM = os2v2
|
||||
CC = WCC386
|
||||
CCCFG = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
|
||||
|
||||
!elif $(TARGET)==DOS32
|
||||
|
||||
# -------------------- DOS4G --------------------
|
||||
SYSTEM = dos4g
|
||||
CC = WCC386
|
||||
CCCFG = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
|
||||
|
||||
!elif $(TARGET)==DOS
|
||||
|
||||
# --------------------- DOS ---------------------
|
||||
SYSTEM = dos
|
||||
CC = WCC
|
||||
CCCFG = -bt=$(TARGET) -d1 -onatx -zp2 -2 -ml -zq -w2
|
||||
|
||||
!elif $(TARGET)==NT
|
||||
|
||||
# --------------------- NT ----------------------
|
||||
SYSTEM = nt
|
||||
CC = WCC386
|
||||
CCCFG = -bt=$(TARGET) -d1 -onatx -zp4 -5 -zq -w2
|
||||
|
||||
!else
|
||||
!error
|
||||
!endif
|
||||
|
||||
# Add the include dir
|
||||
CCCFG = $(CCCFG) -i=..\common
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Implicit rules
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CCCFG) $<
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# All OBJ files
|
||||
|
||||
OBJS = attrtab.obj \
|
||||
code.obj \
|
||||
config.obj \
|
||||
cpu.obj \
|
||||
error.obj \
|
||||
global.obj \
|
||||
handler.obj \
|
||||
main.obj \
|
||||
opctable.obj \
|
||||
output.obj \
|
||||
scanner.obj
|
||||
|
||||
|
||||
LIBS = ..\common\common.lib
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Main targets
|
||||
|
||||
all: da65
|
||||
|
||||
da65: da65.exe
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Other targets
|
||||
|
||||
|
||||
da65.exe: $(OBJS) $(LIBS)
|
||||
$(LD) system $(SYSTEM) @&&|
|
||||
DEBUG ALL
|
||||
OPTION QUIET
|
||||
NAME $<
|
||||
FILE attrtab.obj
|
||||
FILE code.obj
|
||||
FILE config.obj
|
||||
FILE cpu.obj
|
||||
FILE error.obj
|
||||
FILE global.obj
|
||||
FILE handler.obj
|
||||
FILE main.obj
|
||||
FILE opctable.obj
|
||||
FILE output.obj
|
||||
FILE scanner.obj
|
||||
LIBRARY ..\common\common.lib
|
||||
|
|
||||
|
||||
clean:
|
||||
@if exist *.obj del *.obj
|
||||
@if exist *.obj del da65.exe
|
||||
|
||||
strip:
|
||||
@-wstrip da65.exe
|
||||
|
|
@ -130,18 +130,44 @@ void DefLabel (const char* Name)
|
|||
|
||||
|
||||
|
||||
void OneDataByte (void)
|
||||
/* Output a .byte line with the current code byte */
|
||||
void DataByteLine (unsigned Count)
|
||||
/* Output a line with Count data bytes */
|
||||
{
|
||||
unsigned char B = GetCodeByte ();
|
||||
unsigned I;
|
||||
|
||||
if (Pass > 1) {
|
||||
Indent (MIndent);
|
||||
Output (".byte");
|
||||
Indent (AIndent);
|
||||
Output ("$%02X", B);
|
||||
LineFeed ();
|
||||
Indent (MIndent);
|
||||
Output (".byte");
|
||||
Indent (AIndent);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
if (I > 0) {
|
||||
Output (",$%02X", CodeBuf[PC+I]);
|
||||
} else {
|
||||
Output ("$%02X", CodeBuf[PC+I]);
|
||||
}
|
||||
}
|
||||
LineComment (PC, Count);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataWordLine (unsigned Count)
|
||||
/* Output a line with Count data words */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
Indent (MIndent);
|
||||
Output (".word");
|
||||
Indent (AIndent);
|
||||
for (I = 0; I < Count; I += 2) {
|
||||
if (I > 0) {
|
||||
Output (",$%04X", GetCodeWord (PC+I));
|
||||
} else {
|
||||
Output ("$%04X", GetCodeWord (PC+I));
|
||||
}
|
||||
}
|
||||
LineComment (PC, Count);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,10 +175,25 @@ void OneDataByte (void)
|
|||
void SeparatorLine (void)
|
||||
/* Print a separator line */
|
||||
{
|
||||
Output ("; -------------------------------------------------------------------------");
|
||||
Output ("; ----------------------------------------------------------------------------");
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LineComment (unsigned PC, unsigned Count)
|
||||
/* Add a line comment with the PC and data bytes */
|
||||
{
|
||||
if (Pass > 1 && Verbosity >= 3) {
|
||||
Indent (CIndent);
|
||||
Output ("; %04X", PC);
|
||||
if (Verbosity >= 4) {
|
||||
while (Count--) {
|
||||
Output (" %02X", CodeBuf [PC++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -70,9 +70,18 @@ void DefLabel (const char* Name);
|
|||
void OneDataByte (void);
|
||||
/* Output a .byte line with the current code byte */
|
||||
|
||||
void DataByteLine (unsigned Count);
|
||||
/* Output a line with Count data bytes */
|
||||
|
||||
void DataWordLine (unsigned Count);
|
||||
/* Output a line with Count data words */
|
||||
|
||||
void SeparatorLine (void);
|
||||
/* Print a separator line */
|
||||
|
||||
void LineComment (unsigned PC, unsigned Count);
|
||||
/* Add a line comment with the PC and data bytes */
|
||||
|
||||
|
||||
|
||||
/* End of output.h */
|
||||
|
|
|
@ -74,6 +74,12 @@ typedef enum token_t {
|
|||
CFGTOK_END,
|
||||
CFGTOK_TYPE,
|
||||
|
||||
CFGTOK_CODE,
|
||||
CFGTOK_BYTETAB,
|
||||
CFGTOK_WORDTAB,
|
||||
CFGTOK_ADDRTAB,
|
||||
CFGTOK_RTSTAB,
|
||||
|
||||
/* Label section */
|
||||
|
||||
|
||||
|
@ -87,7 +93,7 @@ typedef enum token_t {
|
|||
typedef struct IdentTok_ IdentTok;
|
||||
struct IdentTok_ {
|
||||
const char* Ident; /* Identifier */
|
||||
token_t Tok; /* Token for identifier */
|
||||
token_t Tok; /* Token for identifier */
|
||||
};
|
||||
#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0]))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue