mirror of
https://github.com/cc65/cc65.git
synced 2025-02-25 01:29:04 +00:00
Completed the coding of da65's SEGMENT feature.
Before this commit, we could define segment ranges; but, the disassembler wouldn't do anything with those definitions. Now, da65 will put ".segment" directives into its output. Fixed da65's document.
This commit is contained in:
parent
5b55fa4500
commit
0ee891c106
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
<article>
|
<article>
|
||||||
<title>da65 Users Guide
|
<title>da65 Users Guide
|
||||||
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
|
<author>
|
||||||
<date>2003-08-08
|
<url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
|
||||||
|
<url url="mailto:greg.king5@verizon.net" name="Greg King">
|
||||||
|
<date>2014-11-23
|
||||||
|
|
||||||
<abstract>
|
<abstract>
|
||||||
da65 is a 6502/65C02 disassembler that is able to read user supplied
|
da65 is a 6502/65C02 disassembler that is able to read user-supplied
|
||||||
information about its input data for better results. The output is ready for
|
information about its input data, for better results. The output is ready for
|
||||||
feeding into ca65, the macro assembler supplied with the cc65 C compiler.
|
feeding into ca65, the macro assembler supplied with the cc65 C compiler.
|
||||||
</abstract>
|
</abstract>
|
||||||
|
|
||||||
@ -23,7 +25,7 @@ the cc65 C compiler and generates output that is suitable for the ca65
|
|||||||
macro assembler.
|
macro assembler.
|
||||||
|
|
||||||
Besides generating output for ca65, one of the design goals was that the user
|
Besides generating output for ca65, one of the design goals was that the user
|
||||||
is able to feed additional information about the code into the disassembler
|
is able to feed additional information about the code into the disassembler,
|
||||||
for improved results. This information may include the location and size of
|
for improved results. This information may include the location and size of
|
||||||
tables, and their format.
|
tables, and their format.
|
||||||
|
|
||||||
@ -106,11 +108,16 @@ Here is a description of all the command line options:
|
|||||||
<tag><tt>--cpu type</tt></tag>
|
<tag><tt>--cpu type</tt></tag>
|
||||||
|
|
||||||
Set the CPU type. The option takes a parameter, which may be one of
|
Set the CPU type. The option takes a parameter, which may be one of
|
||||||
|
<itemize>
|
||||||
|
<item>6502
|
||||||
|
<item>6502x
|
||||||
|
<item>65sc02
|
||||||
|
<item>65c02
|
||||||
|
<item>huc6280
|
||||||
|
</itemize>
|
||||||
|
|
||||||
6502, 6502x, 65sc02, 65c02, huc6280
|
6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of
|
||||||
|
the PC engine. Support for the 65816 currently is not available.
|
||||||
6502x is the NMOS 6502 with illegal opcodes. huc6280 is the CPU of the PC
|
|
||||||
engine. Support for the 65816 is currently not available.
|
|
||||||
|
|
||||||
|
|
||||||
<label id="option--formfeeds">
|
<label id="option--formfeeds">
|
||||||
@ -125,7 +132,7 @@ Here is a description of all the command line options:
|
|||||||
<tag><tt>-g, --debug-info</tt></tag>
|
<tag><tt>-g, --debug-info</tt></tag>
|
||||||
|
|
||||||
This option adds the <tt/.DEBUGINFO/ command to the output file, so the
|
This option adds the <tt/.DEBUGINFO/ command to the output file, so the
|
||||||
assembler will generate debug information when reassembling the generated
|
assembler will generate debug information when re-assembling the generated
|
||||||
output.
|
output.
|
||||||
|
|
||||||
|
|
||||||
@ -241,7 +248,7 @@ unsupported.
|
|||||||
The disassembler works by creating an attribute map for the whole address
|
The disassembler works by creating an attribute map for the whole address
|
||||||
space ($0000 - $FFFF). Initially, all attributes are cleared. Then, an
|
space ($0000 - $FFFF). Initially, all attributes are cleared. Then, an
|
||||||
external info file (if given) is read. Disassembly is done in several passes.
|
external info file (if given) is read. Disassembly is done in several passes.
|
||||||
In all passes with the exception of the last one, information about the
|
In all passes, with the exception of the last one, information about the
|
||||||
disassembled code is gathered and added to the symbol and attribute maps. The
|
disassembled code is gathered and added to the symbol and attribute maps. The
|
||||||
last pass generates output using the information from the maps.
|
last pass generates output using the information from the maps.
|
||||||
|
|
||||||
@ -275,7 +282,7 @@ braces. Attributes have a name followed by a value. The syntax of the value
|
|||||||
depends on the type of the attribute. String attributes are places in double
|
depends on the type of the attribute. String attributes are places in double
|
||||||
quotes, numeric attributes may be specified as decimal numbers or hexadecimal
|
quotes, numeric attributes may be specified as decimal numbers or hexadecimal
|
||||||
with a leading dollar sign. There are also attributes where the attribute
|
with a leading dollar sign. There are also attributes where the attribute
|
||||||
value is a keyword, in this case the keyword is given as is (without quotes or
|
value is a keyword; in this case, the keyword is given as-is (without quotes or
|
||||||
anything). Each attribute is terminated by a semicolon.
|
anything). Each attribute is terminated by a semicolon.
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
@ -285,9 +292,9 @@ anything). Each attribute is terminated by a semicolon.
|
|||||||
|
|
||||||
<sect1>Comments<p>
|
<sect1>Comments<p>
|
||||||
|
|
||||||
Comments start with a hash mark (<tt/#/) and extend from the position of
|
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
|
the mark to the end of the current line. Hash marks inside of strings will
|
||||||
of course <em/not/ start a comment.
|
<em/not/ start a comment, of course.
|
||||||
|
|
||||||
|
|
||||||
<sect1>Specifying global options<label id="global-options"><p>
|
<sect1>Specifying global options<label id="global-options"><p>
|
||||||
@ -543,18 +550,17 @@ disassembled code. The following attributes are recognized:
|
|||||||
|
|
||||||
<tag><tt>END</tt></tag>
|
<tag><tt>END</tt></tag>
|
||||||
Followed by a numerical value. Specifies the end address of the segment. The
|
Followed by a numerical value. Specifies the end address of the segment. The
|
||||||
end address is last the address that is part of the segment.
|
end address is the last address that is a part of the segment.
|
||||||
|
|
||||||
<tag><tt>NAME</tt></tag>
|
<tag><tt>NAME</tt></tag>
|
||||||
The attribute is followed by a string value which gives the name of the
|
The attribute is followed by a string value which gives the name of the
|
||||||
segment.
|
segment.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
All attributes are mandatory. Segments may not overlap. Since there is no
|
All attributes are mandatory. Segments must not overlap. The disassembler will
|
||||||
explicit "end this segment" pseudo op, the disassembler cannot notify the
|
change back to the (default) <tt/.code/ segment after the end of each defined
|
||||||
assembler that one segment has ended. This may lead to errors if you don't
|
segment. That might not be what you want. As a rule of thumb, if you're using
|
||||||
define your segments carefully. As a rule of thumb, if you're using segments,
|
segments, you should define segments for all disassembled code.
|
||||||
your should define segments for all disassembled code.
|
|
||||||
|
|
||||||
|
|
||||||
<sect1>Specifying Assembler Includes<label id="infofile-asminc"><p>
|
<sect1>Specifying Assembler Includes<label id="infofile-asminc"><p>
|
||||||
@ -613,7 +619,7 @@ directives explained above:
|
|||||||
};
|
};
|
||||||
|
|
||||||
# One segment for the whole stuff
|
# One segment for the whole stuff
|
||||||
SEGMENT { START $E000; END $FFFF; NAME kernal; };
|
SEGMENT { START $E000; END $FFFF; NAME "kernal"; };
|
||||||
|
|
||||||
RANGE { START $E612; END $E631; TYPE Code; };
|
RANGE { START $E612; END $E631; TYPE Code; };
|
||||||
RANGE { START $E632; END $E640; TYPE ByteTable; };
|
RANGE { START $E632; END $E640; TYPE ByteTable; };
|
||||||
@ -621,7 +627,7 @@ directives explained above:
|
|||||||
RANGE { START $EC6C; END $ECAB; TYPE RtsTable; };
|
RANGE { START $EC6C; END $ECAB; TYPE RtsTable; };
|
||||||
RANGE { START $ED08; END $ED11; TYPE AddrTable; };
|
RANGE { START $ED08; END $ED11; TYPE AddrTable; };
|
||||||
|
|
||||||
# Zero page variables
|
# Zero-page variables
|
||||||
LABEL { NAME "fnadr"; ADDR $90; SIZE 3; };
|
LABEL { NAME "fnadr"; ADDR $90; SIZE 3; };
|
||||||
LABEL { NAME "sal"; ADDR $93; };
|
LABEL { NAME "sal"; ADDR $93; };
|
||||||
LABEL { NAME "sah"; ADDR $94; };
|
LABEL { NAME "sah"; ADDR $94; };
|
||||||
@ -649,12 +655,10 @@ directives explained above:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<sect>Copyright<p>
|
<sect>Copyright<p>
|
||||||
|
|
||||||
da65 (and all cc65 binutils) are (C) Copyright 1998-2007 Ullrich von
|
da65 (and all cc65 binutils) is (C) Copyright 1998-2011, Ullrich von
|
||||||
Bassewitz. For usage of the binaries and/or sources the following
|
Bassewitz. For usage of the binaries and/or sources, the following
|
||||||
conditions do apply:
|
conditions do apply:
|
||||||
|
|
||||||
This software is provided 'as-is', without any expressed or implied
|
This software is provided 'as-is', without any expressed or implied
|
||||||
@ -679,7 +683,3 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -66,6 +66,18 @@ void AddrCheck (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
attr_t GetAttr (unsigned Addr)
|
||||||
|
/* Return the attribute for the given address */
|
||||||
|
{
|
||||||
|
/* Check the given address */
|
||||||
|
AddrCheck (Addr);
|
||||||
|
|
||||||
|
/* Return the attribute */
|
||||||
|
return AttrTab[Addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int SegmentDefined (unsigned Start, unsigned End)
|
int SegmentDefined (unsigned Start, unsigned End)
|
||||||
/* Return true if the atSegment bit is set somewhere in the given range */
|
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||||
{
|
{
|
||||||
@ -79,14 +91,26 @@ int SegmentDefined (unsigned Start, unsigned End)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int HaveSegmentChange (unsigned Addr)
|
int IsSegmentEnd (unsigned Addr)
|
||||||
/* Return true if the segment change attribute is set for the given address */
|
/* Return true if a segment ends at the given address */
|
||||||
{
|
{
|
||||||
/* Check the given address */
|
return (GetAttr (Addr) & atSegmentEnd) != 0x0000;
|
||||||
AddrCheck (Addr);
|
}
|
||||||
|
|
||||||
/* Return the attribute */
|
|
||||||
return (AttrTab[Addr] & atSegmentChange) != 0;
|
|
||||||
|
int IsSegmentStart (unsigned Addr)
|
||||||
|
/* Return true if a segment starts at the given address */
|
||||||
|
{
|
||||||
|
return (GetAttr (Addr) & atSegmentStart) != 0x0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int HaveSegmentChange (unsigned Addr)
|
||||||
|
/* Return true if the segment change attributes are set for the given address */
|
||||||
|
{
|
||||||
|
return (GetAttr (Addr) & (atSegmentStart | atSegmentEnd)) != 0x0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -145,18 +169,6 @@ void MarkAddr (unsigned Addr, attr_t Attr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
attr_t GetAttr (unsigned Addr)
|
|
||||||
/* Return the attribute for the given address */
|
|
||||||
{
|
|
||||||
/* Check the given address */
|
|
||||||
AddrCheck (Addr);
|
|
||||||
|
|
||||||
/* Return the attribute */
|
|
||||||
return AttrTab[Addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
attr_t GetStyleAttr (unsigned Addr)
|
attr_t GetStyleAttr (unsigned Addr)
|
||||||
/* Return the style attribute for the given address */
|
/* Return the style attribute for the given address */
|
||||||
{
|
{
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@ -73,7 +73,8 @@ typedef enum attr_t {
|
|||||||
|
|
||||||
/* Segment */
|
/* Segment */
|
||||||
atSegment = 0x0100, /* Code is in a segment */
|
atSegment = 0x0100, /* Code is in a segment */
|
||||||
atSegmentChange = 0x0200, /* Either segment start or segment end */
|
atSegmentEnd = 0x0200, /* Segment end */
|
||||||
|
atSegmentStart = 0x0400, /* Segment start */
|
||||||
} attr_t;
|
} attr_t;
|
||||||
|
|
||||||
|
|
||||||
@ -87,11 +88,20 @@ typedef enum attr_t {
|
|||||||
void AddrCheck (unsigned Addr);
|
void AddrCheck (unsigned Addr);
|
||||||
/* Check if the given address has a valid range */
|
/* Check if the given address has a valid range */
|
||||||
|
|
||||||
|
attr_t GetAttr (unsigned Addr);
|
||||||
|
/* Return the attribute for the given address */
|
||||||
|
|
||||||
int SegmentDefined (unsigned Start, unsigned End);
|
int SegmentDefined (unsigned Start, unsigned End);
|
||||||
/* Return true if the atSegment bit is set somewhere in the given range */
|
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||||
|
|
||||||
|
int IsSegmentEnd (unsigned Addr);
|
||||||
|
/* Return true if a segment ends at the given address */
|
||||||
|
|
||||||
|
int IsSegmentStart (unsigned Addr);
|
||||||
|
/* Return true if a segment starts at the given address */
|
||||||
|
|
||||||
int HaveSegmentChange (unsigned Addr);
|
int HaveSegmentChange (unsigned Addr);
|
||||||
/* Return true if the segment change attribute is set for the given address */
|
/* Return true if the segment change attributes are set for the given address */
|
||||||
|
|
||||||
unsigned GetGranularity (attr_t Style);
|
unsigned GetGranularity (attr_t Style);
|
||||||
/* Get the granularity for the given style */
|
/* Get the granularity for the given style */
|
||||||
@ -102,9 +112,6 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr);
|
|||||||
void MarkAddr (unsigned Addr, attr_t Attr);
|
void MarkAddr (unsigned Addr, attr_t Attr);
|
||||||
/* Mark an address with an attribute */
|
/* Mark an address with an attribute */
|
||||||
|
|
||||||
attr_t GetAttr (unsigned Addr);
|
|
||||||
/* Return the attribute for the given address */
|
|
||||||
|
|
||||||
attr_t GetStyleAttr (unsigned Addr);
|
attr_t GetStyleAttr (unsigned Addr);
|
||||||
/* Return the style attribute for the given address */
|
/* Return the style attribute for the given address */
|
||||||
|
|
||||||
@ -114,5 +121,4 @@ attr_t GetLabelAttr (unsigned Addr);
|
|||||||
|
|
||||||
|
|
||||||
/* End of attrtab.h */
|
/* End of attrtab.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -70,7 +70,7 @@ static unsigned GetSpan (attr_t Style)
|
|||||||
if ((Attr & atStyleMask) != Style) {
|
if ((Attr & atStyleMask) != Style) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((Attr & atSegmentChange)) {
|
if ((Attr & (atSegmentStart | atSegmentEnd))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++Count;
|
++Count;
|
||||||
|
@ -748,9 +748,6 @@ static void SegmentSection (void)
|
|||||||
if (Start < 0) {
|
if (Start < 0) {
|
||||||
InfoError ("Start address is missing");
|
InfoError ("Start address is missing");
|
||||||
}
|
}
|
||||||
if (Start == End) {
|
|
||||||
InfoError ("Segment is empty");
|
|
||||||
}
|
|
||||||
if (Start > End) {
|
if (Start > End) {
|
||||||
InfoError ("Start address of segment is greater than end address");
|
InfoError ("Start address of segment is greater than end address");
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
/* (C) 1998-2014, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -60,6 +60,7 @@
|
|||||||
#include "opctable.h"
|
#include "opctable.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
|
#include "segment.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -356,6 +357,14 @@ static void OneOpcode (unsigned RemainingBytes)
|
|||||||
/* Get the output style for the current PC */
|
/* Get the output style for the current PC */
|
||||||
attr_t Style = GetStyleAttr (PC);
|
attr_t Style = GetStyleAttr (PC);
|
||||||
|
|
||||||
|
/* If a segment begins here, then name that segment.
|
||||||
|
** Note that the segment is named even if its code is being skipped,
|
||||||
|
** because some of its later code might not be skipped.
|
||||||
|
*/
|
||||||
|
if (IsSegmentStart (PC)) {
|
||||||
|
StartSegment (GetSegmentStartName (PC), GetSegmentAddrSize (PC));
|
||||||
|
}
|
||||||
|
|
||||||
/* If we have a label at this address, output the label and an attached
|
/* If we have a label at this address, output the label and an attached
|
||||||
** comment, provided that we aren't in a skip area.
|
** comment, provided that we aren't in a skip area.
|
||||||
*/
|
*/
|
||||||
@ -371,7 +380,7 @@ static void OneOpcode (unsigned RemainingBytes)
|
|||||||
** - ...if we have enough bytes remaining for the code at this address.
|
** - ...if we have enough bytes remaining for the code at this address.
|
||||||
** - ...if the current instruction is valid for the given CPU.
|
** - ...if the current instruction is valid for the given CPU.
|
||||||
** - ...if there is no label somewhere between the instruction bytes.
|
** - ...if there is no label somewhere between the instruction bytes.
|
||||||
** If any of these conditions is false, switch to data mode.
|
** If any of those conditions is false, switch to data mode.
|
||||||
*/
|
*/
|
||||||
if (Style == atDefault) {
|
if (Style == atDefault) {
|
||||||
if (D->Size > RemainingBytes) {
|
if (D->Size > RemainingBytes) {
|
||||||
@ -383,7 +392,14 @@ static void OneOpcode (unsigned RemainingBytes)
|
|||||||
} else {
|
} else {
|
||||||
unsigned I;
|
unsigned I;
|
||||||
for (I = 1; I < D->Size; ++I) {
|
for (I = 1; I < D->Size; ++I) {
|
||||||
if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) {
|
if (HaveLabel (PC+I)) {
|
||||||
|
Style = atIllegal;
|
||||||
|
MarkAddr (PC, Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (I = 1; I < D->Size - 1u; ++I) {
|
||||||
|
if (HaveSegmentChange (PC+I)) {
|
||||||
Style = atIllegal;
|
Style = atIllegal;
|
||||||
MarkAddr (PC, Style);
|
MarkAddr (PC, Style);
|
||||||
break;
|
break;
|
||||||
@ -455,6 +471,10 @@ static void OneOpcode (unsigned RemainingBytes)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsSegmentEnd (PC - 1)) {
|
||||||
|
EndSegment ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2009, Ullrich von Bassewitz */
|
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -63,6 +63,8 @@ static unsigned Col = 1; /* Current column */
|
|||||||
static unsigned Line = 0; /* Current line on page */
|
static unsigned Line = 0; /* Current line on page */
|
||||||
static unsigned Page = 1; /* Current output page */
|
static unsigned Page = 1; /* Current output page */
|
||||||
|
|
||||||
|
static const char* SegmentName = 0; /* Name of current segment */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -223,23 +225,6 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void StartSegment (const char* Name, unsigned AddrSize)
|
|
||||||
/* Start a segment */
|
|
||||||
{
|
|
||||||
if (Pass == PassCount) {
|
|
||||||
Output (".segment");
|
|
||||||
Indent (ACol);
|
|
||||||
if (AddrSize == ADDR_SIZE_DEFAULT) {
|
|
||||||
Output ("\"%s\"", Name);
|
|
||||||
} else {
|
|
||||||
Output ("\"%s\": %s", Name, AddrSizeToStr (AddrSize));
|
|
||||||
}
|
|
||||||
LineFeed ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DataByteLine (unsigned ByteCount)
|
void DataByteLine (unsigned ByteCount)
|
||||||
/* Output a line with bytes */
|
/* Output a line with bytes */
|
||||||
{
|
{
|
||||||
@ -335,6 +320,39 @@ void SeparatorLine (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void StartSegment (const char* Name, unsigned AddrSize)
|
||||||
|
/* Start a segment */
|
||||||
|
{
|
||||||
|
if (Pass == PassCount) {
|
||||||
|
LineFeed ();
|
||||||
|
Output (".segment");
|
||||||
|
Indent (ACol);
|
||||||
|
SegmentName = Name;
|
||||||
|
Output ("\"%s\"", Name);
|
||||||
|
if (AddrSize != ADDR_SIZE_DEFAULT) {
|
||||||
|
Output (": %s", AddrSizeToStr (AddrSize));
|
||||||
|
}
|
||||||
|
LineFeed ();
|
||||||
|
LineFeed ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void EndSegment (void)
|
||||||
|
/* End a segment */
|
||||||
|
{
|
||||||
|
LineFeed ();
|
||||||
|
Output ("; End of \"%s\" segment", SegmentName);
|
||||||
|
LineFeed ();
|
||||||
|
SeparatorLine ();
|
||||||
|
Output (".code");
|
||||||
|
LineFeed ();
|
||||||
|
LineFeed ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UserComment (const char* Comment)
|
void UserComment (const char* Comment)
|
||||||
/* Output a comment line */
|
/* Output a comment line */
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -75,12 +75,6 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs);
|
|||||||
void DefConst (const char* Name, const char* Comment, unsigned Addr);
|
void DefConst (const char* Name, const char* Comment, unsigned Addr);
|
||||||
/* Define an address constant */
|
/* Define an address constant */
|
||||||
|
|
||||||
void StartSegment (const char* Name, unsigned AddrSize);
|
|
||||||
/* Start a segment */
|
|
||||||
|
|
||||||
void EndSegment (void);
|
|
||||||
/* End a segment */
|
|
||||||
|
|
||||||
void OneDataByte (void);
|
void OneDataByte (void);
|
||||||
/* Output a .byte line with the current code byte */
|
/* Output a .byte line with the current code byte */
|
||||||
|
|
||||||
@ -99,6 +93,12 @@ void DataDWordLine (unsigned ByteCount);
|
|||||||
void SeparatorLine (void);
|
void SeparatorLine (void);
|
||||||
/* Print a separator line */
|
/* Print a separator line */
|
||||||
|
|
||||||
|
void StartSegment (const char* Name, unsigned AddrSize);
|
||||||
|
/* Start a segment */
|
||||||
|
|
||||||
|
void EndSegment (void);
|
||||||
|
/* End a segment */
|
||||||
|
|
||||||
void UserComment (const char* Comment);
|
void UserComment (const char* Comment);
|
||||||
/* Output a comment line */
|
/* Output a comment line */
|
||||||
|
|
||||||
@ -111,5 +111,4 @@ void OutputSettings (void);
|
|||||||
|
|
||||||
|
|
||||||
/* End of output.h */
|
/* End of output.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2007 Ullrich von Bassewitz */
|
/* (C) 2007-2014, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -58,18 +58,15 @@
|
|||||||
typedef struct Segment Segment;
|
typedef struct Segment Segment;
|
||||||
struct Segment {
|
struct Segment {
|
||||||
Segment* NextStart; /* Pointer to next segment */
|
Segment* NextStart; /* Pointer to next segment */
|
||||||
Segment* NextEnd; /* Pointer to next segment */
|
|
||||||
unsigned long Start;
|
unsigned long Start;
|
||||||
unsigned long End;
|
|
||||||
unsigned AddrSize;
|
unsigned AddrSize;
|
||||||
char Name[1]; /* Name, dynamically allocated */
|
char Name[1]; /* Name, dynamically allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tables containing the segments. A segment is inserted using it's hash
|
/* Table containing the segments. A segment is inserted using its hash
|
||||||
** value. Collision is done by single linked lists.
|
** value. Collisions are handled by single-linked lists.
|
||||||
*/
|
*/
|
||||||
static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */
|
static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */
|
||||||
static Segment* EndTab[HASH_SIZE]; /* Table containing segment ends */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -90,20 +87,53 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
|
|||||||
|
|
||||||
/* Fill in the data */
|
/* Fill in the data */
|
||||||
S->Start = Start;
|
S->Start = Start;
|
||||||
S->End = End;
|
|
||||||
S->AddrSize = ADDR_SIZE_ABS;
|
S->AddrSize = ADDR_SIZE_ABS;
|
||||||
memcpy (S->Name, Name, Len + 1);
|
memcpy (S->Name, Name, Len + 1);
|
||||||
|
|
||||||
/* Insert the segment into the hash tables */
|
/* Insert the segment into the hash table */
|
||||||
S->NextStart = StartTab[Start % HASH_SIZE];
|
S->NextStart = StartTab[Start % HASH_SIZE];
|
||||||
StartTab[Start % HASH_SIZE] = S;
|
StartTab[Start % HASH_SIZE] = S;
|
||||||
S->NextEnd = EndTab[End % HASH_SIZE];
|
|
||||||
EndTab[End % HASH_SIZE] = S;
|
|
||||||
|
|
||||||
/* Mark start and end of the segment */
|
/* Mark start and end of the segment */
|
||||||
MarkAddr (Start, atSegmentChange);
|
MarkAddr (Start, atSegmentStart);
|
||||||
MarkAddr (End, atSegmentChange);
|
MarkAddr (End, atSegmentEnd);
|
||||||
|
|
||||||
/* Mark the addresses within the segment */
|
/* Mark the addresses within the segment */
|
||||||
MarkRange (Start, End, atSegment);
|
MarkRange (Start, End, atSegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char* GetSegmentStartName (unsigned Addr)
|
||||||
|
/* Return the name of the segment which starts at the given address */
|
||||||
|
{
|
||||||
|
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||||
|
|
||||||
|
/* Search the collision list for the exact address */
|
||||||
|
while (S != 0) {
|
||||||
|
if (S->Start == Addr) {
|
||||||
|
return S->Name;
|
||||||
|
}
|
||||||
|
S = S->NextStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned GetSegmentAddrSize (unsigned Addr)
|
||||||
|
/* Return the address size of the segment which starts at the given address */
|
||||||
|
{
|
||||||
|
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||||
|
|
||||||
|
/* Search the collision list for the exact address */
|
||||||
|
while (S != 0) {
|
||||||
|
if (S->Start == Addr) {
|
||||||
|
return S->AddrSize;
|
||||||
|
}
|
||||||
|
S = S->NextStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2007 Ullrich von Bassewitz */
|
/* (C) 2007-2014, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -47,8 +47,13 @@
|
|||||||
void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
|
void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
|
||||||
/* Add an absolute segment to the segment table */
|
/* Add an absolute segment to the segment table */
|
||||||
|
|
||||||
|
char* GetSegmentStartName (unsigned Addr);
|
||||||
|
/* Return the name of the segment which starts at the given address */
|
||||||
|
|
||||||
|
unsigned GetSegmentAddrSize (unsigned Addr);
|
||||||
|
/* Return the address size of the segment which starts at the given address */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of segment.h */
|
/* End of segment.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user