mirror of
https://github.com/cc65/cc65.git
synced 2025-01-14 00:32:08 +00:00
Added dword tables, char comments etc.
git-svn-id: svn://svn.cc65.org/cc65/trunk@340 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
806461993b
commit
ee084ac224
@ -51,8 +51,9 @@ enum attr_t {
|
||||
atIllegal = 0x02,
|
||||
atByteTab = 0x03, /* Same as illegal */
|
||||
atWordTab = 0x04,
|
||||
atAddrTab = 0x05,
|
||||
atRtsTab = 0x06,
|
||||
atDWordTab = 0x05,
|
||||
atAddrTab = 0x06,
|
||||
atRtsTab = 0x07,
|
||||
|
||||
atStyleMask = 0x0F /* Output style */
|
||||
};
|
||||
|
@ -89,7 +89,7 @@ void LoadCode (const char* Name, unsigned long StartAddress)
|
||||
Error ("Error reading from `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
if (Count == 0) {
|
||||
Error ("File `%s' contains no data", Name);
|
||||
Error ("File `%s' contains no data", Name);
|
||||
}
|
||||
|
||||
/* Set the buffer variables */
|
||||
@ -118,18 +118,36 @@ unsigned GetCodeWord (unsigned Addr)
|
||||
|
||||
|
||||
|
||||
unsigned long GetCodeDWord (unsigned Addr)
|
||||
/* Get a dword from the given address */
|
||||
{
|
||||
unsigned long Lo = GetCodeWord (Addr);
|
||||
unsigned long Hi = GetCodeWord (Addr+2);
|
||||
return Lo | (Hi << 16);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned GetRemainingBytes (void)
|
||||
/* Return the number of remaining code bytes */
|
||||
{
|
||||
if (CodeEnd >= PC) {
|
||||
return (CodeEnd - PC + 1);
|
||||
return (CodeEnd - PC + 1);
|
||||
} else {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int CodeLeft (void)
|
||||
/* Return true if there are code bytes left */
|
||||
{
|
||||
return (PC <= CodeEnd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ResetCode (void)
|
||||
/* Reset the code input to start over for the next pass */
|
||||
{
|
||||
|
@ -66,9 +66,15 @@ unsigned char GetCodeByte (unsigned Addr);
|
||||
unsigned GetCodeWord (unsigned Addr);
|
||||
/* Get a word from the given address */
|
||||
|
||||
unsigned long GetCodeDWord (unsigned Addr);
|
||||
/* Get a dword from the given address */
|
||||
|
||||
unsigned GetRemainingBytes (void);
|
||||
/* Return the number of remaining code bytes */
|
||||
|
||||
int CodeLeft (void);
|
||||
/* Return true if there are code bytes left */
|
||||
|
||||
void ResetCode (void);
|
||||
/* Reset the code input to start over for the next pass */
|
||||
|
||||
|
@ -138,6 +138,7 @@ static void RangeSection (void)
|
||||
{ "CODE", CFGTOK_CODE },
|
||||
{ "BYTETABLE", CFGTOK_BYTETAB },
|
||||
{ "WORDTABLE", CFGTOK_WORDTAB },
|
||||
{ "DWORDTABLE", CFGTOK_DWORDTAB },
|
||||
{ "ADDRTABLE", CFGTOK_ADDRTAB },
|
||||
{ "RTSTABLE", CFGTOK_RTSTAB },
|
||||
};
|
||||
@ -197,6 +198,7 @@ static void RangeSection (void)
|
||||
case CFGTOK_CODE: Type = atCode; break;
|
||||
case CFGTOK_BYTETAB: Type = atByteTab; break;
|
||||
case CFGTOK_WORDTAB: Type = atWordTab; break;
|
||||
case CFGTOK_DWORDTAB: Type = atDWordTab; break;
|
||||
case CFGTOK_ADDRTAB: Type = atAddrTab; break;
|
||||
case CFGTOK_RTSTAB: Type = atRtsTab; break;
|
||||
}
|
||||
|
161
src/da65/data.c
161
src/da65/data.c
@ -35,7 +35,7 @@
|
||||
|
||||
/* da65 */
|
||||
#include "attrtab.h"
|
||||
#include "code.h"
|
||||
#include "code.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "output.h"
|
||||
@ -49,108 +49,110 @@
|
||||
|
||||
|
||||
|
||||
void ByteTable (unsigned RemainingBytes)
|
||||
static unsigned GetSpan (attr_t Style)
|
||||
/* Get the number of bytes for a given style */
|
||||
{
|
||||
/* Get the number of bytes still available */
|
||||
unsigned RemainingBytes = GetRemainingBytes ();
|
||||
|
||||
/* Count how many bytes are available. This number is limited by the
|
||||
* number of remaining bytes, a label, or the end of the given Style
|
||||
* attribute.
|
||||
*/
|
||||
unsigned Count = 1;
|
||||
while (Count < RemainingBytes) {
|
||||
if (HaveLabel(PC+Count) || GetStyle (PC+Count) != Style) {
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
}
|
||||
|
||||
/* Return the number of bytes */
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned))
|
||||
/* 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;
|
||||
unsigned BytesLeft;
|
||||
|
||||
/* Count how many bytes may be output. */
|
||||
unsigned Count = GetSpan (Style);
|
||||
|
||||
/* Make Count an even number of multiples of MemberSize */
|
||||
Count &= ~(MemberSize-1);
|
||||
|
||||
/* Output as many data bytes lines as needed */
|
||||
while (Count > 0) {
|
||||
BytesLeft = Count;
|
||||
while (BytesLeft > 0) {
|
||||
|
||||
/* Calculate the number of bytes for the next line */
|
||||
unsigned Chunk = (Count > BytesPerLine)? BytesPerLine : Count;
|
||||
unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
|
||||
|
||||
/* Output a line with these bytes */
|
||||
DataByteLine (Chunk);
|
||||
TableFunc (Chunk);
|
||||
|
||||
/* Next line */
|
||||
Count -= Chunk;
|
||||
PC += Chunk;
|
||||
BytesLeft -= Chunk;
|
||||
PC += Chunk;
|
||||
}
|
||||
|
||||
/* If the next line is not a byte table line, add a separator */
|
||||
if (RemainingBytes > 0 && GetStyle (PC) != atByteTab) {
|
||||
/* If the next line is not the same style, add a separator */
|
||||
if (CodeLeft() && GetStyle (PC) != Style) {
|
||||
SeparatorLine ();
|
||||
}
|
||||
|
||||
/* Return the number of bytes output */
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WordTable (unsigned RemainingBytes)
|
||||
unsigned ByteTable (void)
|
||||
/* Output a table of bytes */
|
||||
{
|
||||
/* Call the low level function */
|
||||
return DoTable (atByteTab, 1, DataByteLine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned WordTable (void)
|
||||
/* 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 ();
|
||||
}
|
||||
/* Call the low level function */
|
||||
return DoTable (atWordTab, 2, DataWordLine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddrTable (unsigned RemainingBytes)
|
||||
unsigned DWordTable (void)
|
||||
/* Output a table of double words */
|
||||
{
|
||||
/* Call the low level function */
|
||||
return DoTable (atDWordTab, 4, DataDWordLine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned AddrTable (void)
|
||||
/* 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;
|
||||
unsigned BytesLeft;
|
||||
|
||||
/* Count how many bytes may be output. */
|
||||
unsigned Count = GetSpan (atAddrTab);
|
||||
|
||||
/* 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) {
|
||||
*/
|
||||
BytesLeft = Count;
|
||||
while (BytesLeft > 0) {
|
||||
|
||||
/* Get the address */
|
||||
unsigned Addr = GetCodeWord (PC);
|
||||
@ -158,13 +160,13 @@ void AddrTable (unsigned RemainingBytes)
|
||||
/* In pass 1, define a label, in pass 2 output the line */
|
||||
if (Pass == 1) {
|
||||
if (!HaveLabel (Addr)) {
|
||||
AddLabel (Addr, MakeLabelName (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);
|
||||
/* OOPS! Should not happen */
|
||||
Internal ("OOPS - Label for address %04X disappeard!", Addr);
|
||||
}
|
||||
Indent (MIndent);
|
||||
Output (".word");
|
||||
@ -175,14 +177,17 @@ void AddrTable (unsigned RemainingBytes)
|
||||
}
|
||||
|
||||
/* Next line */
|
||||
PC += 2;
|
||||
Count -= 2;
|
||||
PC += 2;
|
||||
BytesLeft -= 2;
|
||||
}
|
||||
|
||||
/* If the next line is not a byte table line, add a separator */
|
||||
if (RemainingBytes > 0 && GetStyle (PC) != atAddrTab) {
|
||||
if (CodeLeft() && GetStyle (PC) != atAddrTab) {
|
||||
SeparatorLine ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the number of bytes output */
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,13 +44,16 @@
|
||||
|
||||
|
||||
|
||||
void ByteTable (unsigned RemainingBytes);
|
||||
unsigned ByteTable (void);
|
||||
/* Output a table of bytes */
|
||||
|
||||
void WordTable (unsigned RemainingBytes);
|
||||
unsigned WordTable (void);
|
||||
/* Output a table of words */
|
||||
|
||||
void AddrTable (unsigned RemainingBytes);
|
||||
unsigned DWordTable (void);
|
||||
/* Output a table of double words */
|
||||
|
||||
unsigned AddrTable (void);
|
||||
/* Output a table of addresses */
|
||||
|
||||
|
||||
|
@ -54,15 +54,17 @@ const char CfgExt[] = ".cfg"; /* Config file extension */
|
||||
/* Flags and other command line stuff */
|
||||
unsigned char Verbosity = 4; /* Verbosity of the output file */
|
||||
unsigned char FormFeeds = 0; /* Add form feeds to the output? */
|
||||
|
||||
unsigned char PassCount = 2; /* How many passed do we do? */
|
||||
|
||||
/* Stuff needed by many routines */
|
||||
unsigned Pass = 0; /* Disassembler pass */
|
||||
unsigned char 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 = 49; /* Comment indent */
|
||||
unsigned TIndent = 81; /* Text bytes indent */
|
||||
unsigned BytesPerLine = 8; /* Max. number of data bytes per line */
|
||||
|
||||
|
||||
|
@ -55,9 +55,10 @@ extern const char CfgExt[]; /* Config file extension */
|
||||
/* Flags and other command line stuff */
|
||||
extern unsigned char Verbosity; /* Verbosity of the output file */
|
||||
extern unsigned char FormFeeds; /* Add form feeds to the output? */
|
||||
extern unsigned char PassCount; /* How many passed do we do? */
|
||||
|
||||
/* Stuff needed by many routines */
|
||||
extern unsigned Pass; /* Disassembler pass */
|
||||
extern unsigned char Pass; /* Disassembler pass */
|
||||
|
||||
/* Page formatting */
|
||||
#define MIN_PAGE_LEN 32
|
||||
@ -66,6 +67,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 TIndent; /* Text bytes indent */
|
||||
extern unsigned BytesPerLine; /* Max. number of data bytes per line */
|
||||
|
||||
|
||||
|
@ -211,15 +211,19 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
break;
|
||||
|
||||
case atByteTab:
|
||||
ByteTable (RemainingBytes);
|
||||
ByteTable ();
|
||||
break;
|
||||
|
||||
case atWordTab:
|
||||
WordTable (RemainingBytes);
|
||||
WordTable ();
|
||||
break;
|
||||
|
||||
case atDWordTab:
|
||||
DWordTable ();
|
||||
break;
|
||||
|
||||
case atAddrTab:
|
||||
AddrTable (RemainingBytes);
|
||||
AddrTable ();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* common */
|
||||
@ -110,7 +111,7 @@ void CloseOutput (void)
|
||||
void Output (const char* Format, ...)
|
||||
/* Write to the output file */
|
||||
{
|
||||
if (Pass > 1) {
|
||||
if (Pass == PassCount) {
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
Col += vfprintf (F, Format, ap);
|
||||
@ -123,7 +124,7 @@ void Output (const char* Format, ...)
|
||||
void Indent (unsigned N)
|
||||
/* Make sure the current line column is at position N (zero based) */
|
||||
{
|
||||
if (Pass > 1) {
|
||||
if (Pass == PassCount) {
|
||||
while (Col < N) {
|
||||
fputc (' ', F);
|
||||
++Col;
|
||||
@ -136,7 +137,7 @@ void Indent (unsigned N)
|
||||
void LineFeed (void)
|
||||
/* Add a linefeed to the output file */
|
||||
{
|
||||
if (Pass > 1) {
|
||||
if (Pass == PassCount) {
|
||||
fputc ('\n', F);
|
||||
if (++Line >= PageLength) {
|
||||
if (FormFeeds) {
|
||||
@ -156,48 +157,72 @@ void DefLabel (const char* Name)
|
||||
/* Define a label with the given name */
|
||||
{
|
||||
Output ("%s:", Name);
|
||||
LineFeed ();
|
||||
/* Don't start a new line if the label is fully in the left column */
|
||||
if (Col >= MIndent-1) {
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataByteLine (unsigned Count)
|
||||
/* Output a line with Count data bytes */
|
||||
void DataByteLine (unsigned ByteCount)
|
||||
/* Output a line with bytes */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
Indent (MIndent);
|
||||
Output (".byte");
|
||||
Indent (AIndent);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
for (I = 0; I < ByteCount; ++I) {
|
||||
if (I > 0) {
|
||||
Output (",$%02X", CodeBuf[PC+I]);
|
||||
} else {
|
||||
Output ("$%02X", CodeBuf[PC+I]);
|
||||
}
|
||||
}
|
||||
LineComment (PC, Count);
|
||||
LineComment (PC, ByteCount);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataWordLine (unsigned Count)
|
||||
/* Output a line with Count data words */
|
||||
void DataWordLine (unsigned ByteCount)
|
||||
/* Output a line with words */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
Indent (MIndent);
|
||||
Output (".word");
|
||||
Indent (AIndent);
|
||||
for (I = 0; I < Count; I += 2) {
|
||||
for (I = 0; I < ByteCount; I += 2) {
|
||||
if (I > 0) {
|
||||
Output (",$%04X", GetCodeWord (PC+I));
|
||||
} else {
|
||||
Output ("$%04X", GetCodeWord (PC+I));
|
||||
}
|
||||
}
|
||||
LineComment (PC, Count);
|
||||
LineComment (PC, ByteCount);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataDWordLine (unsigned ByteCount)
|
||||
/* Output a line with dwords */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
Indent (MIndent);
|
||||
Output (".dword");
|
||||
Indent (AIndent);
|
||||
for (I = 0; I < ByteCount; I += 4) {
|
||||
if (I > 0) {
|
||||
Output (",$%08lX", GetCodeDWord (PC+I));
|
||||
} else {
|
||||
Output ("$%08lX", GetCodeDWord (PC+I));
|
||||
}
|
||||
}
|
||||
LineComment (PC, ByteCount);
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
@ -206,8 +231,10 @@ void DataWordLine (unsigned Count)
|
||||
void SeparatorLine (void)
|
||||
/* Print a separator line */
|
||||
{
|
||||
Output ("; ----------------------------------------------------------------------------");
|
||||
LineFeed ();
|
||||
if (Pass == PassCount && Verbosity >= 1) {
|
||||
Output ("; ----------------------------------------------------------------------------");
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -215,12 +242,24 @@ void SeparatorLine (void)
|
||||
void LineComment (unsigned PC, unsigned Count)
|
||||
/* Add a line comment with the PC and data bytes */
|
||||
{
|
||||
if (Pass > 1 && Verbosity >= 3) {
|
||||
unsigned I;
|
||||
|
||||
if (Pass == PassCount && Verbosity >= 2) {
|
||||
Indent (CIndent);
|
||||
Output ("; %04X", PC);
|
||||
if (Verbosity >= 4) {
|
||||
while (Count--) {
|
||||
Output (" %02X", CodeBuf [PC++]);
|
||||
if (Verbosity >= 3) {
|
||||
for (I = 0; I < Count; ++I) {
|
||||
Output (" %02X", CodeBuf [PC+I]);
|
||||
}
|
||||
if (Verbosity >= 4) {
|
||||
Indent (TIndent);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
unsigned char C = CodeBuf [PC+I];
|
||||
if (!isprint (C)) {
|
||||
C = '.';
|
||||
}
|
||||
Output ("%c", C);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,11 +70,14 @@ 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 DataByteLine (unsigned ByteCount);
|
||||
/* Output a line with bytes */
|
||||
|
||||
void DataWordLine (unsigned Count);
|
||||
/* Output a line with Count data words */
|
||||
void DataWordLine (unsigned ByteCount);
|
||||
/* Output a line with words */
|
||||
|
||||
void DataDWordLine (unsigned ByteCount);
|
||||
/* Output a line with dwords */
|
||||
|
||||
void SeparatorLine (void);
|
||||
/* Print a separator line */
|
||||
|
@ -77,6 +77,7 @@ typedef enum token_t {
|
||||
CFGTOK_CODE,
|
||||
CFGTOK_BYTETAB,
|
||||
CFGTOK_WORDTAB,
|
||||
CFGTOK_DWORDTAB,
|
||||
CFGTOK_ADDRTAB,
|
||||
CFGTOK_RTSTAB,
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user