1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Merge remote-tracking branch 'upstream/master' into cbmkernal_stage2

This commit is contained in:
Olli Savia 2018-06-29 22:50:02 +03:00
commit 42e9b971c5
15 changed files with 433 additions and 46 deletions

View File

@ -53,6 +53,7 @@ Short options:
-o name Name the output file
-v Increase verbosity
-F Add formfeeds to the output
-s Accept line markers in the info file
-S addr Set the start/load address
-V Print the disassembler version
@ -70,6 +71,7 @@ Long options:
--mnemonic-column n Specify mnemonic start column
--pagelength n Set the page length for the listing
--start-addr addr Set the start/load address
--sync-lines Accept line markers in the info file
--text-column n Specify text start column
--verbose Increase verbosity
--version Print the disassembler version
@ -205,6 +207,17 @@ Here is a description of all the command line options:
start address is specified, $10000 minus the size of the input file is used.
<label id="option--sync-lines">
<tag><tt>-s, --sync-lines</tt></tag>
Accept line markers in the info file in the following syntax:
<tscreen><verb>
#line <lineno> ["<filename>"]
# <lineno> "<filename>" [<flag>] ...
</verb></tscreen>
This option is intended for preprocessing info files with "cpp" or "m4".
<label id="option--text-column">
<tag><tt>--text-column n</tt></tag>
@ -299,9 +312,10 @@ anything). Each attribute is terminated by a semicolon.
<sect1>Comments<p>
Comments start with a hash mark (<tt/#/); and, extend from the position of
the mark to the end of the current line. Hash marks inside of strings will
<em/not/ start a comment, of course.
Comments start with a hash mark (<tt/#/) or a double slash (<tt>//</tt>);
and, extend from the position of the mark to the end of the current line.
Hash marks or double slashes inside of strings will <em/not/ start a comment,
of course.
<sect1>Specifying global options<label id="global-options"><p>

View File

@ -626,7 +626,7 @@ XCONT2: dex
lsr CHUNK ;Advance to last point
jsr LINEPLOT ;Plot the last chunk
EXIT: lda #$36
lda #$36
sta $01
cli
rts

View File

@ -59,6 +59,7 @@ unsigned char PassCount = 2; /* How many passed do we do? */
signed char NewlineAfterJMP = -1; /* Add a newline after a JMP insn? */
signed char NewlineAfterRTS = -1; /* Add a newline after a RTS insn? */
long StartAddr = -1L; /* Start/load address of the program */
unsigned char SyncLines = 0; /* Accept line markers in the info file */
long InputOffs = -1L; /* Offset into input file */
long InputSize = -1L; /* Number of bytes to read from input */

View File

@ -60,6 +60,7 @@ extern unsigned char PassCount; /* How many passed do we do? */
extern signed char NewlineAfterJMP;/* Add a newline after a JMP insn? */
extern signed char NewlineAfterRTS;/* Add a newline after a RTS insn? */
extern long StartAddr; /* Start/load address of the program */
extern unsigned char SyncLines; /* Accept line markers in the info file */
extern long InputOffs; /* Offset into input file */
extern long InputSize; /* Number of bytes to read from input */

View File

@ -82,6 +82,7 @@ static void Usage (void)
" -v\t\t\tIncrease verbosity\n"
" -F\t\t\tAdd formfeeds to the output\n"
" -S addr\t\tSet the start/load address\n"
" -s\t\t\tAccept line markers in the info file\n"
" -V\t\t\tPrint the disassembler version\n"
"\n"
"Long options:\n"
@ -98,6 +99,7 @@ static void Usage (void)
" --mnemonic-column n\tSpecify mnemonic start column\n"
" --pagelength n\tSet the page length for the listing\n"
" --start-addr addr\tSet the start/load address\n"
" --sync-lines\t\tAccept line markers in the info file\n"
" --text-column n\tSpecify text start column\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the disassembler version\n",
@ -312,6 +314,15 @@ static void OptStartAddr (const char* Opt, const char* Arg)
static void OptSyncLines (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Handle the --sync-lines option */
{
SyncLines = 1;
}
static void OptTextColumn (const char* Opt, const char* Arg)
/* Handle the --text-column option */
{
@ -539,6 +550,7 @@ int main (int argc, char* argv [])
{ "--mnemonic-column", 1, OptMnemonicColumn },
{ "--pagelength", 1, OptPageLength },
{ "--start-addr", 1, OptStartAddr },
{ "--sync-lines", 0, OptSyncLines },
{ "--text-column", 1, OptTextColumn },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
@ -589,6 +601,10 @@ int main (int argc, char* argv [])
OptStartAddr (Arg, GetArg (&I, 2));
break;
case 's':
OptSyncLines (Arg, 0);
break;
case 'V':
OptVersion (Arg, 0);
break;

View File

@ -41,6 +41,8 @@
/* common */
#include "chartype.h"
#include "xsprintf.h"
#include "xmalloc.h"
#include "strbuf.h"
/* ld65 */
#include "global.h"
@ -72,6 +74,7 @@ static int C = ' ';
static unsigned InputLine = 1;
static unsigned InputCol = 0;
static FILE* InputFile = 0;
static char* InputSrcName = 0;
@ -91,7 +94,8 @@ void InfoWarning (const char* Format, ...)
xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
Warning ("%s(%u): %s", InfoFile, InfoErrorLine, Buf);
fprintf (stderr, "%s(%u): Warning: %s\n",
InputSrcName, InfoErrorLine, Buf);
}
@ -106,11 +110,14 @@ void InfoError (const char* Format, ...)
xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
Error ("%s(%u): %s", InfoFile, InfoErrorLine, Buf);
fprintf (stderr, "%s(%u): Error: %s\n",
InputSrcName, InfoErrorLine, Buf);
exit (EXIT_FAILURE);
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -149,17 +156,179 @@ static unsigned DigitVal (int C)
static void SkipBlanks (int SingleLine)
{
while (C != EOF && (!SingleLine || C != '\n') && IsSpace (C)) {
NextChar ();
}
}
static long GetDecimalToken (void)
{
long Value = 0;
while (C != EOF && IsDigit (C)) {
Value = Value * 10 + DigitVal (C);
NextChar ();
}
return Value;
}
static int GetEncodedChar (char* Buf, unsigned* IPtr, unsigned Size)
{
char Decoded = 0;
int Count;
if (C == EOF) {
return -1;
} else if (C != '\\') {
Decoded = C;
NextChar ();
goto Store;
}
NextChar (); /* consume '\\' */
if (C == EOF) {
return -1;
} else if (IsODigit (C)) {
Count = 3;
do {
Decoded = Decoded * 8 + DigitVal (C);
NextChar ();
--Count;
} while (Count > 0 && C != EOF && IsODigit (C));
} else if (C == 'x') {
NextChar (); /* consume 'x' */
Count = 2;
while (Count > 0 && C != EOF && IsXDigit (C)) {
Decoded = Decoded * 16 + DigitVal (C);
NextChar ();
--Count;
}
} else {
switch (C) {
case '"': case '\'': case '\\':
Decoded = C; break;
case 't': Decoded = '\t'; break;
case 'r': Decoded = '\r'; break;
case 'n': Decoded = '\n'; break;
default: return -1;
}
NextChar ();
}
Store:
if (*IPtr < Size - 1) {
Buf [(*IPtr)++] = Decoded;
}
Buf [*IPtr] = 0;
return 0;
}
static void LineMarkerOrComment ()
/* Handle a line beginning with '#'. Possible interpretations are:
** - #line <lineno> ["<filename>"] (C preprocessor input)
** - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output)
** - #<comment>
*/
{
unsigned long LineNo = 0;
int LineDirective = 0;
StrBuf SrcNameBuf = AUTO_STRBUF_INITIALIZER;
/* Skip the first "# " */
NextChar ();
SkipBlanks (1);
/* Check "line" */
if (C == 'l') {
char MaybeLine [6];
unsigned I;
for (I = 0; I < sizeof MaybeLine - 1 && C != EOF && IsAlNum (C); ++I) {
MaybeLine [I] = C;
NextChar ();
}
MaybeLine [I] = 0;
if (strcmp (MaybeLine, "line") != 0) {
goto NotMarker;
}
LineDirective = 1;
SkipBlanks (1);
}
/* Get line number */
if (C == EOF || !IsDigit (C)) {
goto NotMarker;
}
LineNo = GetDecimalToken ();
SkipBlanks (1);
/* Get the source file name */
if (C != '\"') {
/* The source file name is missing */
if (LineDirective && C == '\n') {
/* got #line <lineno> */
NextChar ();
InputLine = LineNo;
goto Last;
} else {
goto NotMarker;
}
}
NextChar ();
while (C != EOF && C != '\n' && C != '\"') {
char DecodeBuf [2];
unsigned I = 0;
if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0) {
goto BadMarker;
}
SB_AppendBuf (&SrcNameBuf, DecodeBuf, I);
}
if (C != '\"') {
goto BadMarker;
}
NextChar ();
/* Ignore until the end of line */
while (C != EOF && C != '\n') {
NextChar ();
}
/* Accepted a line marker */
SB_Terminate (&SrcNameBuf);
xfree (InputSrcName);
InputSrcName = SB_GetBuf (&SrcNameBuf);
SB_Init (&SrcNameBuf);
InputLine = (unsigned)LineNo;
NextChar ();
goto Last;
BadMarker:
InfoWarning ("Bad line marker");
NotMarker:
while (C != EOF && C != '\n') {
NextChar ();
}
NextChar ();
Last:
SB_Done (&SrcNameBuf);
}
void InfoNextTok (void)
/* Read the next token from the input stream */
{
unsigned I;
int Esc;
char DecodeBuf [2];
Again:
/* Skip whitespace */
while (IsSpace (C)) {
NextChar ();
}
SkipBlanks (0);
/* Remember the current position */
InfoErrorLine = InputLine;
@ -198,11 +367,7 @@ Again:
/* Decimal number? */
if (IsDigit (C)) {
InfoIVal = 0;
while (IsDigit (C)) {
InfoIVal = InfoIVal * 10 + DigitVal (C);
NextChar ();
}
InfoIVal = GetDecimalToken ();
InfoTok = INFOTOK_INTCON;
return;
}
@ -248,38 +413,31 @@ Again:
case '\"':
NextChar ();
I = 0;
while (C != '\"') {
Esc = (C == '\\');
if (Esc) {
NextChar ();
}
if (C == EOF || C == '\n') {
InfoError ("Unterminated string");
}
if (Esc) {
switch (C) {
case '\"': C = '\"'; break;
case '\'': C = '\''; break;
default: InfoError ("Invalid escape char: %c", C);
while (C != EOF && C != '\"') {
if (GetEncodedChar (InfoSVal, &I, sizeof InfoSVal) < 0) {
if (C == EOF) {
InfoError ("Unterminated string");
} else {
InfoError ("Invalid escape char: %c", C);
}
}
if (I < CFG_MAX_IDENT_LEN) {
InfoSVal [I++] = C;
}
NextChar ();
}
if (C != '\"') {
InfoError ("Unterminated string");
}
NextChar ();
InfoSVal [I] = '\0';
InfoTok = INFOTOK_STRCON;
break;
case '\'':
NextChar ();
if (C == EOF || IsControl (C)) {
if (C == EOF || IsControl (C) || C == '\'') {
InfoError ("Invalid character constant");
}
InfoIVal = C;
NextChar ();
if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0 || I != 1) {
InfoError ("Invalid character constant");
}
InfoIVal = DecodeBuf [0];
if (C != '\'') {
InfoError ("Unterminated character constant");
}
@ -288,8 +446,13 @@ Again:
break;
case '#':
/* Comment */
while (C != '\n' && C != EOF) {
/* # lineno "sourcefile" or # comment */
if (SyncLines && InputCol == 1) {
LineMarkerOrComment ();
} else {
do {
NextChar ();
} while (C != EOF && C != '\n');
NextChar ();
}
if (C != EOF) {
@ -298,6 +461,21 @@ Again:
InfoTok = INFOTOK_EOF;
break;
case '/':
/* C++ style comment */
NextChar ();
if (C != '/') {
InfoError ("Invalid token `/'");
}
do {
NextChar ();
} while (C != '\n' && C != EOF);
if (C != EOF) {
goto Again;
}
InfoTok = INFOTOK_EOF;
break;
case EOF:
InfoTok = INFOTOK_EOF;
break;
@ -484,14 +662,8 @@ void InfoSetName (const char* Name)
/* Set a name for a config file */
{
InfoFile = Name;
}
const char* InfoGetName (void)
/* Get the name of the config file */
{
return InfoFile? InfoFile : "";
xfree(InputSrcName);
InputSrcName = xstrdup(Name);
}

2
testcode/disasm/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.s
image.bin

16
testcode/disasm/bank0.da Normal file
View File

@ -0,0 +1,16 @@
// Da65 input file before preprocessed by cpp
// Bank0 ROM map
#define TARGET_BANK 0
global {
inputoffs $00010;
inputsize $4000;
startaddr $8000;
cpu "6502";
};
#include "fixed.da"
label { addr $8000; name "Bank0ProcA"; };
label { addr $8123; name "Bank0ProcB"; };
range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; };

33
testcode/disasm/bank0.dai Normal file
View File

@ -0,0 +1,33 @@
# 1 "bank0.da"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "bank0.da"
global {
inputoffs $00010;
inputsize $4000;
startaddr $8000;
cpu "6502";
};
# 1 "fixed.da" 1
# 18 "fixed.da"
label { addr $00; name "VariableA"; };
label { addr $01; name "VariableB"; };
label { addr $0100; name "Stack"; size $0100; };
label { addr $C000; name "CommonProcA"; };
label { addr $C123; name "CommonProcB"; };
range { start $E123; end $FFFF; name "CommonData"; type ByteTable; };
# 13 "bank0.da" 2
label { addr $8000; name "Bank0ProcA"; };
label { addr $8123; name "Bank0ProcB"; };
range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; };

16
testcode/disasm/bank1.da Normal file
View File

@ -0,0 +1,16 @@
// Da65 input file before preprocessed by cpp
// Bank1 ROM map
#define TARGET_BANK 1
global {
inputoffs $04010;
inputsize $4000;
startaddr $8000;
cpu "6502";
};
#include "fixed.da"
range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; };
label { addr $B000; name "Bank1ProcA"; };
label { addr $B123; name "Bank1ProcB"; };

33
testcode/disasm/bank1.dai Normal file
View File

@ -0,0 +1,33 @@
# 1 "bank1.da"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "bank1.da"
global {
inputoffs $04010;
inputsize $4000;
startaddr $8000;
cpu "6502";
};
# 1 "fixed.da" 1
# 18 "fixed.da"
label { addr $00; name "VariableA"; };
label { addr $01; name "VariableB"; };
label { addr $0100; name "Stack"; size $0100; };
label { addr $C000; name "CommonProcA"; };
label { addr $C123; name "CommonProcB"; };
range { start $E123; end $FFFF; name "CommonData"; type ByteTable; };
# 13 "bank1.da" 2
range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; };
label { addr $B000; name "Bank1ProcA"; };
label { addr $B123; name "Bank1ProcB"; };

30
testcode/disasm/fixed.da Normal file
View File

@ -0,0 +1,30 @@
// Da65 input file before preprocessed by cpp
// RAM and Fixed ROM map
#ifndef FIXED_DA_INCLUDED
#define FIXED_DA_INCLUDED
#ifndef TARGET_BANK
#define TARGET_BANK -1
global {
inputoffs $1C010;
inputsize $4000;
startaddr $C000;
cpu "6502";
};
#endif /* !defined(TARGET_BANK) */
// ---- RAM map ----
label { addr $00; name "VariableA"; };
label { addr $01; name "VariableB"; };
label { addr $0100; name "Stack"; size $0100; };
#if defined(TEST_ERROR) && TARGET_BANK == 0
erroneous_line;
#endif
// ---- Fixed ROM map ----
label { addr $C000; name "CommonProcA"; };
label { addr $C123; name "CommonProcB"; };
range { start $E123; end $FFFF; name "CommonData"; type ByteTable; };
#endif /* !defined(FIXED_DA_INCLUDED) */

25
testcode/disasm/fixed.dai Normal file
View File

@ -0,0 +1,25 @@
# 1 "fixed.da"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "fixed.da"
# 9 "fixed.da"
global {
inputoffs $1C010;
inputsize $4000;
startaddr $C000;
cpu "6502";
};
label { addr $00; name "VariableA"; };
label { addr $01; name "VariableB"; };
label { addr $0100; name "Stack"; size $0100; };
label { addr $C000; name "CommonProcA"; };
label { addr $C123; name "CommonProcB"; };
range { start $E123; end $FFFF; name "CommonData"; type ByteTable; };

View File

@ -0,0 +1,28 @@
# Sample makefile using a preprocessor against info files
# and the --sync-lines option
CPP = env LANG=C cpp
CPPFLAGS = # -DTEST_ERROR
ASMS = fixed.s bank0.s bank1.s
DAIS = fixed.dai bank0.dai bank1.dai
.SUFFIXES: .da .dai .s
.PHONY: all clean maintainer-clean
.SECONDARY: $(DAIS)
.da.dai:
$(CPP) -o $@ $(CPPFLAGS) $<
.dai.s:
da65 --sync-lines -o $@ -i $< image.bin
all: $(ASMS)
clean:
rm -f $(ASMS)
maintainer-clean: clean
rm -f $(DAIS)
$(DAIS): fixed.da