Merge pull request #2728 from kugelfuhr/kugelfuhr/da65-improvements
Cleanup for the da65 code base
This commit is contained in:
@@ -248,8 +248,8 @@ With the command line option <tt><ref id="option--cpu" name="--cpu"></tt>, the
|
|||||||
disassembler may be told which CPU to support:
|
disassembler may be told which CPU to support:
|
||||||
|
|
||||||
<itemize>
|
<itemize>
|
||||||
<item><ref id="6502-mode" name="6502 mode"> - NMOS 6502 (all legal instructions)
|
<item><ref id="6502-mode" name="6502"> - NMOS 6502 (all legal instructions)
|
||||||
<item><ref id="6502X-mode" name="6502X mode"> - NMOS 6502 with all undocumented instructions
|
<item><ref id="6502X-mode" name="6502X"> - NMOS 6502 with all undocumented instructions
|
||||||
<item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device
|
<item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device
|
||||||
<item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation, no wai/stp)
|
<item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation, no wai/stp)
|
||||||
<item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation and wai/stp)
|
<item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation and wai/stp)
|
||||||
|
|||||||
@@ -33,6 +33,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* da65 */
|
/* da65 */
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -46,14 +51,78 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Attribute table */
|
/* Attribute structure how it is found in the attribute table */
|
||||||
static unsigned short AttrTab[0x10000];
|
typedef struct Attribute Attribute;
|
||||||
|
struct Attribute {
|
||||||
|
struct Attribute* Next; /* Next entry in linked list */
|
||||||
|
uint32_t Addr; /* The full address */
|
||||||
|
attr_t Attr; /* Actual attribute */
|
||||||
|
};
|
||||||
|
|
||||||
/* 65816 attribute table */
|
/* Attributes use a hash table and a linear list for collision resolution. The
|
||||||
#define MAX_LONG_ATTRS 256
|
** hash function is easy and effective. It evaluates just the lower bits of
|
||||||
static unsigned short LongAttrVal[MAX_LONG_ATTRS];
|
** the address.
|
||||||
static unsigned LongAttrAddr[MAX_LONG_ATTRS];
|
*/
|
||||||
static unsigned LongAttrsUsed;
|
#define ATTR_HASH_SIZE 8192u /* Must be power of two */
|
||||||
|
static Attribute* AttributeTab[ATTR_HASH_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* struct Attribute */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Attribute* NewAttribute (uint32_t Addr, attr_t Attr)
|
||||||
|
/* Create a new attribute structure and return it */
|
||||||
|
{
|
||||||
|
/* Create a new attribute */
|
||||||
|
Attribute* A = xmalloc (sizeof (Attribute));
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
A->Next = 0;
|
||||||
|
A->Addr = Addr;
|
||||||
|
A->Attr = Attr;
|
||||||
|
|
||||||
|
/* Return the attribute just created */
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t GetAttributeHash (uint32_t Addr)
|
||||||
|
/* Get the hash for an attribute at the given address */
|
||||||
|
{
|
||||||
|
return (Addr & (ATTR_HASH_SIZE - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Attribute* FindAttribute (uint32_t Addr)
|
||||||
|
/* Search for an attribute for the given address and return it. Returns NULL
|
||||||
|
** if no attribute exists for the address.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Attribute* A = AttributeTab[GetAttributeHash (Addr)];
|
||||||
|
while (A) {
|
||||||
|
if (A->Addr == Addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
A = A->Next;
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void InsertAttribute (Attribute* A)
|
||||||
|
/* Insert an attribute into the hash table */
|
||||||
|
{
|
||||||
|
uint32_t Hash = GetAttributeHash (A->Addr);
|
||||||
|
A->Next = AttributeTab[Hash];
|
||||||
|
AttributeTab[Hash] = A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -63,51 +132,43 @@ static unsigned LongAttrsUsed;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddrCheck (unsigned Addr)
|
void AddrCheck (uint32_t Addr)
|
||||||
/* Check if the given address has a valid range */
|
/* Check if the given address has a valid range */
|
||||||
{
|
{
|
||||||
if (Addr >= 0x10000 && CPU != CPU_65816) {
|
if (Addr >= 0x10000 && CPU != CPU_65816) {
|
||||||
Error ("Address out of range: %08X", Addr);
|
Error ("Address out of range: $%04" PRIX32, Addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned char IsLongAddr (unsigned Addr)
|
|
||||||
/* Is it 24-bit? */
|
|
||||||
{
|
|
||||||
return Addr >= 0x10000 && CPU == CPU_65816;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
attr_t GetAttr (uint32_t Addr)
|
||||||
|
|
||||||
attr_t GetAttr (unsigned Addr)
|
|
||||||
/* Return the attribute for the given address */
|
/* Return the attribute for the given address */
|
||||||
{
|
{
|
||||||
|
/* As a small optimization we cache the last used attribute so when the
|
||||||
|
** function is called several times with the same address we do already
|
||||||
|
** know it.
|
||||||
|
*/
|
||||||
|
static const Attribute* A = 0;
|
||||||
|
if (A != 0 && A->Addr == Addr) {
|
||||||
|
return A->Attr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the given address */
|
/* Check the given address */
|
||||||
AddrCheck (Addr);
|
AddrCheck (Addr);
|
||||||
|
|
||||||
if (IsLongAddr (Addr)) {
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < LongAttrsUsed; i++) {
|
|
||||||
if (LongAttrAddr[i] == Addr) {
|
|
||||||
return LongAttrVal[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the attribute */
|
/* Return the attribute */
|
||||||
return AttrTab[Addr];
|
A = FindAttribute (Addr);
|
||||||
|
return A? A->Attr : atDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int SegmentDefined (unsigned Start, unsigned End)
|
int SegmentDefined (uint32_t Start, uint32_t 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 */
|
||||||
{
|
{
|
||||||
while (Start <= End) {
|
while (Start <= End) {
|
||||||
if (AttrTab[Start++] & atSegment) {
|
if (GetAttr (Start++) & atSegment) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +177,7 @@ int SegmentDefined (unsigned Start, unsigned End)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsSegmentEnd (unsigned Addr)
|
int IsSegmentEnd (uint32_t Addr)
|
||||||
/* Return true if a segment ends at the given address */
|
/* Return true if a segment ends at the given address */
|
||||||
{
|
{
|
||||||
return (GetAttr (Addr) & atSegmentEnd) != 0x0000;
|
return (GetAttr (Addr) & atSegmentEnd) != 0x0000;
|
||||||
@@ -124,7 +185,7 @@ int IsSegmentEnd (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsSegmentStart (unsigned Addr)
|
int IsSegmentStart (uint32_t Addr)
|
||||||
/* Return true if a segment starts at the given address */
|
/* Return true if a segment starts at the given address */
|
||||||
{
|
{
|
||||||
return (GetAttr (Addr) & atSegmentStart) != 0x0000;
|
return (GetAttr (Addr) & atSegmentStart) != 0x0000;
|
||||||
@@ -155,7 +216,7 @@ unsigned GetGranularity (attr_t Style)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MarkRange (unsigned Start, unsigned End, attr_t Attr)
|
void MarkRange (uint32_t Start, uint32_t End, attr_t Attr)
|
||||||
/* Mark a range with the given attribute */
|
/* Mark a range with the given attribute */
|
||||||
{
|
{
|
||||||
/* Do it easy here... */
|
/* Do it easy here... */
|
||||||
@@ -166,53 +227,33 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MarkAddr (unsigned Addr, attr_t Attr)
|
void MarkAddr (uint32_t Addr, attr_t Attr)
|
||||||
/* Mark an address with an attribute */
|
/* Mark an address with an attribute */
|
||||||
{
|
{
|
||||||
/* Check the given address */
|
/* Check the given address */
|
||||||
AddrCheck (Addr);
|
AddrCheck (Addr);
|
||||||
|
|
||||||
if (IsLongAddr (Addr)) {
|
/* Get an existing attribute entry */
|
||||||
unsigned i;
|
Attribute* A = FindAttribute (Addr);
|
||||||
for (i = 0; i < LongAttrsUsed; i++) {
|
|
||||||
if (LongAttrAddr[i] == Addr) {
|
|
||||||
|
|
||||||
/* We must not have more than one style bit */
|
/* We must not have more than one style bit */
|
||||||
if (Attr & atStyleMask) {
|
if (A != 0 && (Attr & atStyleMask) != 0) {
|
||||||
if (LongAttrVal[i] & atStyleMask) {
|
if ((A->Attr & atStyleMask) != 0) {
|
||||||
Error ("Duplicate style for long address %06X", Addr);
|
Error ("Duplicate style for address %04" PRIX32, Addr);
|
||||||
}
|
|
||||||
}
|
|
||||||
LongAttrVal[i] |= Attr;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LongAttrsUsed >= MAX_LONG_ATTRS) {
|
|
||||||
Error ("Too many long addresses");
|
|
||||||
}
|
|
||||||
LongAttrVal[LongAttrsUsed] |= Attr;
|
|
||||||
LongAttrAddr[LongAttrsUsed] = Addr;
|
|
||||||
LongAttrsUsed++;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
/* Set the style */
|
||||||
AttrTab[Addr] |= Attr;
|
if (A) {
|
||||||
|
A->Attr |= Attr;
|
||||||
|
} else {
|
||||||
|
InsertAttribute (NewAttribute (Addr, Attr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
attr_t GetStyleAttr (unsigned Addr)
|
attr_t GetStyleAttr (uint32_t Addr)
|
||||||
/* Return the style attribute for the given address */
|
/* Return the style attribute for the given address */
|
||||||
{
|
{
|
||||||
/* Check the given address */
|
/* Check the given address */
|
||||||
@@ -224,7 +265,7 @@ attr_t GetStyleAttr (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
attr_t GetLabelAttr (unsigned Addr)
|
attr_t GetLabelAttr (uint32_t Addr)
|
||||||
/* Return the label attribute for the given address */
|
/* Return the label attribute for the given address */
|
||||||
{
|
{
|
||||||
/* Check the given address */
|
/* Check the given address */
|
||||||
|
|||||||
@@ -38,6 +38,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -95,37 +99,37 @@ typedef enum attr_t {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddrCheck (unsigned Addr);
|
void AddrCheck (uint32_t Addr);
|
||||||
/* Check if the given address has a valid range */
|
/* Check if the given address has a valid range */
|
||||||
|
|
||||||
unsigned char IsLongAddr (unsigned Addr);
|
unsigned char IsLongAddr (uint32_t Addr);
|
||||||
/* Check if the given address is 24-bit */
|
/* Check if the given address is 24-bit */
|
||||||
|
|
||||||
attr_t GetAttr (unsigned Addr);
|
attr_t GetAttr (uint32_t Addr);
|
||||||
/* Return the attribute for the given address */
|
/* Return the attribute for the given address */
|
||||||
|
|
||||||
int SegmentDefined (unsigned Start, unsigned End);
|
int SegmentDefined (uint32_t 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);
|
int IsSegmentEnd (uint32_t Addr);
|
||||||
/* Return true if a segment ends at the given address */
|
/* Return true if a segment ends at the given address */
|
||||||
|
|
||||||
int IsSegmentStart (unsigned Addr);
|
int IsSegmentStart (uint32_t Addr);
|
||||||
/* Return true if a segment starts at the given address */
|
/* Return true if a segment starts at 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 */
|
||||||
|
|
||||||
void MarkRange (unsigned Start, unsigned End, attr_t Attr);
|
void MarkRange (uint32_t Start, uint32_t End, attr_t Attr);
|
||||||
/* Mark a range with the given attribute */
|
/* Mark a range with the given attribute */
|
||||||
|
|
||||||
void MarkAddr (unsigned Addr, attr_t Attr);
|
void MarkAddr (uint32_t Addr, attr_t Attr);
|
||||||
/* Mark an address with an attribute */
|
/* Mark an address with an attribute */
|
||||||
|
|
||||||
attr_t GetStyleAttr (unsigned Addr);
|
attr_t GetStyleAttr (uint32_t Addr);
|
||||||
/* Return the style attribute for the given address */
|
/* Return the style attribute for the given address */
|
||||||
|
|
||||||
attr_t GetLabelAttr (unsigned Addr);
|
attr_t GetLabelAttr (uint32_t Addr);
|
||||||
/* Return the label attribute for the given address */
|
/* Return the label attribute for the given address */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,10 +53,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char CodeBuf [0x10000]; /* Code buffer */
|
uint8_t CodeBuf[0x10000]; /* Code buffer */
|
||||||
unsigned long CodeStart; /* Start address */
|
uint32_t CodeStart; /* Start address */
|
||||||
unsigned long CodeEnd; /* End address */
|
uint32_t CodeEnd; /* End address */
|
||||||
unsigned long PC; /* Current PC */
|
uint32_t PC; /* Current PC */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -117,12 +117,13 @@ void LoadCode (void)
|
|||||||
** 0x10000 - Size. This is a reasonable default assuming that the file
|
** 0x10000 - Size. This is a reasonable default assuming that the file
|
||||||
** is a ROM that contains the hardware vectors at $FFFA.
|
** is a ROM that contains the hardware vectors at $FFFA.
|
||||||
*/
|
*/
|
||||||
if (StartAddr < 0) {
|
if (!HaveStartAddr) {
|
||||||
if (Size > 0x10000) {
|
if (Size > 0x10000) {
|
||||||
StartAddr = 0;
|
StartAddr = 0;
|
||||||
} else {
|
} else {
|
||||||
StartAddr = 0x10000 - Size;
|
StartAddr = 0x10000 - Size;
|
||||||
}
|
}
|
||||||
|
HaveStartAddr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the maximum code size */
|
/* Calculate the maximum code size */
|
||||||
@@ -155,7 +156,7 @@ void LoadCode (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char GetCodeByte (unsigned Addr)
|
uint8_t GetCodeByte (uint32_t Addr)
|
||||||
/* Get a byte from the given address */
|
/* Get a byte from the given address */
|
||||||
{
|
{
|
||||||
PRECONDITION (Addr <= CodeEnd);
|
PRECONDITION (Addr <= CodeEnd);
|
||||||
@@ -164,48 +165,48 @@ unsigned char GetCodeByte (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetCodeDByte (unsigned Addr)
|
uint16_t GetCodeDByte (uint32_t Addr)
|
||||||
/* Get a dbyte from the given address */
|
/* Get a dbyte from the given address */
|
||||||
{
|
{
|
||||||
unsigned Lo = GetCodeByte (Addr);
|
uint16_t Lo = GetCodeByte (Addr);
|
||||||
unsigned Hi = GetCodeByte (Addr+1);
|
uint16_t Hi = GetCodeByte (Addr+1);
|
||||||
return (Lo <<8) | Hi;
|
return (Lo <<8) | Hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetCodeWord (unsigned Addr)
|
uint16_t GetCodeWord (uint32_t Addr)
|
||||||
/* Get a word from the given address */
|
/* Get a word from the given address */
|
||||||
{
|
{
|
||||||
unsigned Lo = GetCodeByte (Addr);
|
uint16_t Lo = GetCodeByte (Addr);
|
||||||
unsigned Hi = GetCodeByte (Addr+1);
|
uint16_t Hi = GetCodeByte (Addr+1);
|
||||||
return Lo | (Hi << 8);
|
return Lo | (Hi << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long GetCodeDWord (unsigned Addr)
|
uint32_t GetCodeDWord (uint32_t Addr)
|
||||||
/* Get a dword from the given address */
|
/* Get a dword from the given address */
|
||||||
{
|
{
|
||||||
unsigned long Lo = GetCodeWord (Addr);
|
uint32_t Lo = GetCodeWord (Addr);
|
||||||
unsigned long Hi = GetCodeWord (Addr+2);
|
uint32_t Hi = GetCodeWord (Addr+2);
|
||||||
return Lo | (Hi << 16);
|
return Lo | (Hi << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetCodeLongAddr (unsigned Addr)
|
uint32_t GetCodeLongAddr (uint32_t Addr)
|
||||||
/* Get a word from the given address */
|
/* Get a word from the given address */
|
||||||
{
|
{
|
||||||
unsigned Lo = GetCodeByte (Addr);
|
uint32_t Lo = GetCodeByte (Addr);
|
||||||
unsigned Mid = GetCodeByte (Addr+1);
|
uint32_t Mid = GetCodeByte (Addr+1);
|
||||||
unsigned Hi = GetCodeByte (Addr+2);
|
uint32_t Hi = GetCodeByte (Addr+2);
|
||||||
return Lo | (Mid << 8) | (Hi << 16);
|
return Lo | (Mid << 8) | (Hi << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetRemainingBytes (void)
|
uint32_t GetRemainingBytes (void)
|
||||||
/* Return the number of remaining code bytes */
|
/* Return the number of remaining code bytes */
|
||||||
{
|
{
|
||||||
if (CodeEnd >= PC) {
|
if (CodeEnd >= PC) {
|
||||||
|
|||||||
@@ -38,16 +38,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern unsigned char CodeBuf [0x10000]; /* Code buffer */
|
extern uint8_t CodeBuf[0x10000]; /* Code buffer */
|
||||||
extern unsigned long CodeStart; /* Start address */
|
extern uint32_t CodeStart; /* Start address */
|
||||||
extern unsigned long CodeEnd; /* End address */
|
extern uint32_t CodeEnd; /* End address */
|
||||||
extern unsigned long PC; /* Current PC */
|
extern uint32_t PC; /* Current PC */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -60,22 +64,22 @@ extern unsigned long PC; /* Current PC */
|
|||||||
void LoadCode (void);
|
void LoadCode (void);
|
||||||
/* Load the code from the given file */
|
/* Load the code from the given file */
|
||||||
|
|
||||||
unsigned char GetCodeByte (unsigned Addr);
|
uint8_t GetCodeByte (uint32_t Addr);
|
||||||
/* Get a byte from the given address */
|
/* Get a byte from the given address */
|
||||||
|
|
||||||
unsigned GetCodeDByte (unsigned Addr);
|
uint16_t GetCodeDByte (uint32_t Addr);
|
||||||
/* Get a dbyte from the given address */
|
/* Get a dbyte from the given address */
|
||||||
|
|
||||||
unsigned GetCodeWord (unsigned Addr);
|
uint16_t GetCodeWord (uint32_t Addr);
|
||||||
/* Get a word from the given address */
|
/* Get a word from the given address */
|
||||||
|
|
||||||
unsigned long GetCodeDWord (unsigned Addr);
|
uint32_t GetCodeDWord (uint32_t Addr);
|
||||||
/* Get a dword from the given address */
|
/* Get a dword from the given address */
|
||||||
|
|
||||||
unsigned GetCodeLongAddr (unsigned Addr);
|
uint32_t GetCodeLongAddr (uint32_t Addr);
|
||||||
/* Get a 24-bit address from the given address */
|
/* Get a 24-bit address from the given address */
|
||||||
|
|
||||||
unsigned GetRemainingBytes (void);
|
uint32_t GetRemainingBytes (void);
|
||||||
/* Return the number of remaining code bytes */
|
/* Return the number of remaining code bytes */
|
||||||
|
|
||||||
int CodeLeft (void);
|
int CodeLeft (void);
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
@@ -49,13 +52,82 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment table */
|
/* Comment structure how it is found in the comment table */
|
||||||
static const char* CommentTab[0x10000];
|
typedef struct Comment Comment;
|
||||||
|
struct Comment {
|
||||||
|
struct Comment* Next; /* Next entry in linked list */
|
||||||
|
uint32_t Addr; /* The full address */
|
||||||
|
char Text[1]; /* Text, dynamically allocated */
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_LONG_COMMENTS 256
|
/* Comments use a hash table and a linear list for collision resolution. The
|
||||||
static const char* LongCommentVal[MAX_LONG_COMMENTS];
|
** hash function is easy and effective. It evaluates just the lower bits of
|
||||||
static unsigned LongCommentAddr[MAX_LONG_COMMENTS];
|
** the address. Since we don't expect many comments, we can keep the table
|
||||||
static unsigned LongCommentsUsed;
|
** small.
|
||||||
|
*/
|
||||||
|
#define COMMENT_HASH_SIZE 256u /* Must be power of two */
|
||||||
|
static Comment* CommentTab[COMMENT_HASH_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* struct Comment */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Comment* NewComment (uint32_t Addr, const char* Text)
|
||||||
|
/* Create a new comment structure and return it */
|
||||||
|
{
|
||||||
|
/* Get the length of the text */
|
||||||
|
unsigned Len = strlen (Text);
|
||||||
|
|
||||||
|
/* Create a new comment */
|
||||||
|
Comment* C = xmalloc (sizeof (Comment) + Len);
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
C->Next = 0;
|
||||||
|
C->Addr = Addr;
|
||||||
|
memcpy (C->Text, Text, Len + 1);
|
||||||
|
|
||||||
|
/* Return the comment just created */
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t GetCommentHash (uint32_t Addr)
|
||||||
|
/* Get the hash for a comment at the given address */
|
||||||
|
{
|
||||||
|
return (Addr & (COMMENT_HASH_SIZE - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Comment* FindComment (uint32_t Addr)
|
||||||
|
/* Search for a comment for the given address and return it. Returns NULL if
|
||||||
|
** no comment exists for the address.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Comment* C = CommentTab[GetCommentHash (Addr)];
|
||||||
|
while (C) {
|
||||||
|
if (C->Addr == Addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
C = C->Next;
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void InsertComment (Comment* C)
|
||||||
|
/* Insert a comment into the hash table */
|
||||||
|
{
|
||||||
|
uint32_t Hash = GetCommentHash (C->Addr);
|
||||||
|
C->Next = CommentTab[Hash];
|
||||||
|
CommentTab[Hash] = C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -65,62 +137,30 @@ static unsigned LongCommentsUsed;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned FindLongIndex (unsigned Addr)
|
void SetComment (uint32_t Addr, const char* Text)
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < LongCommentsUsed; i++) {
|
|
||||||
if (LongCommentAddr[i] == Addr) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetComment (unsigned Addr, const char* Comment)
|
|
||||||
/* Set a comment for the given address */
|
/* Set a comment for the given address */
|
||||||
{
|
{
|
||||||
/* Check the given address */
|
/* Check the given address */
|
||||||
AddrCheck (Addr);
|
AddrCheck (Addr);
|
||||||
|
|
||||||
if (IsLongAddr (Addr)) {
|
|
||||||
if (FindLongIndex (Addr)) {
|
|
||||||
Warning ("Duplicate comment for address $%06X", Addr);
|
|
||||||
} else {
|
|
||||||
if (LongCommentsUsed >= MAX_LONG_COMMENTS) {
|
|
||||||
Error("Too many long-address comments");
|
|
||||||
}
|
|
||||||
LongCommentVal[LongCommentsUsed] = xstrdup (Comment);
|
|
||||||
LongCommentAddr[LongCommentsUsed] = Addr;
|
|
||||||
LongCommentsUsed++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* If we do already have a comment, warn and ignore the new one */
|
/* If we do already have a comment, warn and ignore the new one */
|
||||||
if (CommentTab[Addr]) {
|
Comment* C = FindComment (Addr);
|
||||||
Warning ("Duplicate comment for address $%04X", Addr);
|
if (C) {
|
||||||
|
Warning ("Duplicate comment for address $%04" PRIX32, Addr);
|
||||||
} else {
|
} else {
|
||||||
CommentTab[Addr] = xstrdup (Comment);
|
InsertComment (NewComment (Addr, Text));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetComment (unsigned Addr)
|
const char* GetComment (uint32_t Addr)
|
||||||
/* Return the comment for an address */
|
/* Return the comment for an address */
|
||||||
{
|
{
|
||||||
/* Check the given address */
|
/* Check the given address */
|
||||||
AddrCheck (Addr);
|
AddrCheck (Addr);
|
||||||
|
|
||||||
if (IsLongAddr (Addr)) {
|
/* Check for a comment and return it */
|
||||||
const unsigned i = FindLongIndex (Addr);
|
const Comment* C = FindComment (Addr);
|
||||||
if (i < LongCommentsUsed) {
|
return C? C->Text : 0;
|
||||||
return LongCommentVal[i];
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the label if any */
|
|
||||||
return CommentTab[Addr];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* da65 */
|
||||||
#include "attrtab.h"
|
#include "attrtab.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -48,10 +51,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetComment (unsigned Addr, const char* Comment);
|
void SetComment (uint32_t Addr, const char* Text);
|
||||||
/* Set a comment for the given address */
|
/* Set a comment for the given address */
|
||||||
|
|
||||||
const char* GetComment (unsigned Addr);
|
const char* GetComment (uint32_t Addr);
|
||||||
/* Return the comment for an address */
|
/* Return the comment for an address */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,17 +50,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned GetSpan (attr_t Style)
|
static uint32_t GetSpan (attr_t Style)
|
||||||
/* Get the number of bytes for a given style */
|
/* Get the number of bytes for a given style */
|
||||||
{
|
{
|
||||||
/* Get the number of bytes still available */
|
/* Get the number of bytes still available */
|
||||||
unsigned RemainingBytes = GetRemainingBytes ();
|
uint32_t RemainingBytes = GetRemainingBytes ();
|
||||||
|
|
||||||
/* Count how many bytes are available. This number is limited by the
|
/* Count how many bytes are available. This number is limited by the
|
||||||
** number of remaining bytes, a label, a segment change, or the end of
|
** number of remaining bytes, a label, a segment change, or the end of
|
||||||
** the given Style attribute.
|
** the given Style attribute.
|
||||||
*/
|
*/
|
||||||
unsigned Count = 1;
|
uint32_t Count = 1;
|
||||||
while (Count < RemainingBytes) {
|
while (Count < RemainingBytes) {
|
||||||
attr_t Attr;
|
attr_t Attr;
|
||||||
if (MustDefLabel(PC+Count)) {
|
if (MustDefLabel(PC+Count)) {
|
||||||
@@ -85,10 +85,10 @@ static unsigned GetSpan (attr_t Style)
|
|||||||
static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned))
|
static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned))
|
||||||
/* Output a table of bytes */
|
/* Output a table of bytes */
|
||||||
{
|
{
|
||||||
unsigned BytesLeft;
|
uint32_t BytesLeft;
|
||||||
|
|
||||||
/* Count how many bytes may be output. */
|
/* Count how many bytes may be output. */
|
||||||
unsigned Count = GetSpan (Style);
|
uint32_t Count = GetSpan (Style);
|
||||||
|
|
||||||
/* If the count is less than the member size, print a row of Count data
|
/* If the count is less than the member size, print a row of Count data
|
||||||
** bytes. We assume here that there is no member with a size that is less
|
** bytes. We assume here that there is no member with a size that is less
|
||||||
@@ -108,7 +108,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u
|
|||||||
while (BytesLeft > 0) {
|
while (BytesLeft > 0) {
|
||||||
|
|
||||||
/* Calculate the number of bytes for the next line */
|
/* Calculate the number of bytes for the next line */
|
||||||
unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
|
uint32_t Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft;
|
||||||
|
|
||||||
/* Output a line with these bytes */
|
/* Output a line with these bytes */
|
||||||
TableFunc (Chunk);
|
TableFunc (Chunk);
|
||||||
@@ -129,7 +129,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned ByteTable (void)
|
uint32_t ByteTable (void)
|
||||||
/* Output a table of bytes */
|
/* Output a table of bytes */
|
||||||
{
|
{
|
||||||
/* Call the low level function */
|
/* Call the low level function */
|
||||||
@@ -138,7 +138,7 @@ unsigned ByteTable (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned DByteTable (void)
|
uint32_t DByteTable (void)
|
||||||
/* Output a table of dbytes */
|
/* Output a table of dbytes */
|
||||||
{
|
{
|
||||||
/* Call the low level function */
|
/* Call the low level function */
|
||||||
@@ -147,7 +147,7 @@ unsigned DByteTable (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned WordTable (void)
|
uint32_t WordTable (void)
|
||||||
/* Output a table of words */
|
/* Output a table of words */
|
||||||
{
|
{
|
||||||
/* Call the low level function */
|
/* Call the low level function */
|
||||||
@@ -156,7 +156,7 @@ unsigned WordTable (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned DWordTable (void)
|
uint32_t DWordTable (void)
|
||||||
/* Output a table of double words */
|
/* Output a table of double words */
|
||||||
{
|
{
|
||||||
/* Call the low level function */
|
/* Call the low level function */
|
||||||
@@ -165,18 +165,18 @@ unsigned DWordTable (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned AddrTable (void)
|
uint32_t AddrTable (void)
|
||||||
/* Output a table of addresses */
|
/* Output a table of addresses */
|
||||||
{
|
{
|
||||||
unsigned long BytesLeft = GetRemainingBytes ();
|
uint32_t BytesLeft = GetRemainingBytes ();
|
||||||
unsigned long Start = PC;
|
uint32_t Start = PC;
|
||||||
|
|
||||||
/* Loop while table bytes left and we don't need to create a label at the
|
/* Loop while table bytes left and we don't need to create a label at the
|
||||||
** current position.
|
** current position.
|
||||||
*/
|
*/
|
||||||
while (BytesLeft && GetStyleAttr (PC) == atAddrTab) {
|
while (BytesLeft && GetStyleAttr (PC) == atAddrTab) {
|
||||||
|
|
||||||
unsigned Addr;
|
uint32_t Addr;
|
||||||
|
|
||||||
/* If just one byte is left, define it and bail out */
|
/* If just one byte is left, define it and bail out */
|
||||||
if (BytesLeft == 1 || GetStyleAttr (PC+1) != atAddrTab) {
|
if (BytesLeft == 1 || GetStyleAttr (PC+1) != atAddrTab) {
|
||||||
@@ -231,18 +231,18 @@ unsigned AddrTable (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned RtsTable (void)
|
uint32_t RtsTable (void)
|
||||||
/* Output a table of RTS addresses (address - 1) */
|
/* Output a table of RTS addresses (address - 1) */
|
||||||
{
|
{
|
||||||
unsigned long BytesLeft = GetRemainingBytes ();
|
uint32_t BytesLeft = GetRemainingBytes ();
|
||||||
unsigned long Start = PC;
|
uint32_t Start = PC;
|
||||||
|
|
||||||
/* Loop while table bytes left and we don't need to create a label at the
|
/* Loop while table bytes left and we don't need to create a label at the
|
||||||
** current position.
|
** current position.
|
||||||
*/
|
*/
|
||||||
while (BytesLeft && GetStyleAttr (PC) == atRtsTab) {
|
while (BytesLeft && GetStyleAttr (PC) == atRtsTab) {
|
||||||
|
|
||||||
unsigned Addr;
|
uint32_t Addr;
|
||||||
|
|
||||||
/* If just one byte is left, define it and bail out */
|
/* If just one byte is left, define it and bail out */
|
||||||
if (BytesLeft == 1 || GetStyleAttr (PC+1) != atRtsTab) {
|
if (BytesLeft == 1 || GetStyleAttr (PC+1) != atRtsTab) {
|
||||||
@@ -297,14 +297,14 @@ unsigned RtsTable (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned TextTable (void)
|
uint32_t TextTable (void)
|
||||||
/* Output a table of text messages */
|
/* Output a table of text messages */
|
||||||
{
|
{
|
||||||
/* Count how many bytes may be output. */
|
/* Count how many bytes may be output. */
|
||||||
unsigned ByteCount = GetSpan (atTextTab);
|
uint32_t ByteCount = GetSpan (atTextTab);
|
||||||
|
|
||||||
/* Output as many data bytes lines as needed. */
|
/* Output as many data bytes lines as needed. */
|
||||||
unsigned BytesLeft = ByteCount;
|
uint32_t BytesLeft = ByteCount;
|
||||||
while (BytesLeft > 0) {
|
while (BytesLeft > 0) {
|
||||||
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
@@ -312,7 +312,7 @@ unsigned TextTable (void)
|
|||||||
/* Count the number of characters that can be output as such */
|
/* Count the number of characters that can be output as such */
|
||||||
unsigned Count = 0;
|
unsigned Count = 0;
|
||||||
while (Count < BytesLeft && Count < BytesPerLine*4-1) {
|
while (Count < BytesLeft && Count < BytesPerLine*4-1) {
|
||||||
unsigned char C = GetCodeByte (PC + Count);
|
uint8_t C = GetCodeByte (PC + Count);
|
||||||
if (C >= 0x20 && C <= 0x7E && C != '\"') {
|
if (C >= 0x20 && C <= 0x7E && C != '\"') {
|
||||||
++Count;
|
++Count;
|
||||||
} else {
|
} else {
|
||||||
@@ -348,7 +348,7 @@ unsigned TextTable (void)
|
|||||||
/* Count the number of bytes that must be output as bytes */
|
/* Count the number of bytes that must be output as bytes */
|
||||||
Count = 0;
|
Count = 0;
|
||||||
while (Count < BytesLeft && Count < BytesPerLine) {
|
while (Count < BytesLeft && Count < BytesPerLine) {
|
||||||
unsigned char C = GetCodeByte (PC + Count);
|
uint8_t C = GetCodeByte (PC + Count);
|
||||||
if (C < 0x20 || C > 0x7E || C == '\"') {
|
if (C < 0x20 || C > 0x7E || C == '\"') {
|
||||||
++Count;
|
++Count;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -44,25 +44,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned ByteTable (void);
|
uint32_t ByteTable (void);
|
||||||
/* Output a table of bytes */
|
/* Output a table of bytes */
|
||||||
|
|
||||||
unsigned DByteTable (void);
|
uint32_t DByteTable (void);
|
||||||
/* Output a table of dbytes */
|
/* Output a table of dbytes */
|
||||||
|
|
||||||
unsigned WordTable (void);
|
uint32_t WordTable (void);
|
||||||
/* Output a table of words */
|
/* Output a table of words */
|
||||||
|
|
||||||
unsigned DWordTable (void);
|
uint32_t DWordTable (void);
|
||||||
/* Output a table of double words */
|
/* Output a table of double words */
|
||||||
|
|
||||||
unsigned AddrTable (void);
|
uint32_t AddrTable (void);
|
||||||
/* Output a table of addresses */
|
/* Output a table of addresses */
|
||||||
|
|
||||||
unsigned RtsTable (void);
|
uint32_t RtsTable (void);
|
||||||
/* Output a table of RTS addresses (address - 1) */
|
/* Output a table of RTS addresses (address - 1) */
|
||||||
|
|
||||||
unsigned TextTable (void);
|
uint32_t TextTable (void);
|
||||||
/* Output a table of text messages */
|
/* Output a table of text messages */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ unsigned char UseHexOffs = 0; /* Use hexadecimal label offsets */
|
|||||||
unsigned char PassCount = 2; /* How many passed do we do? */
|
unsigned char PassCount = 2; /* How many passed do we do? */
|
||||||
signed char NewlineAfterJMP = -1; /* Add a newline after a JMP insn? */
|
signed char NewlineAfterJMP = -1; /* Add a newline after a JMP insn? */
|
||||||
signed char NewlineAfterRTS = -1; /* Add a newline after a RTS insn? */
|
signed char NewlineAfterRTS = -1; /* Add a newline after a RTS insn? */
|
||||||
long StartAddr = -1L; /* Start/load address of the program */
|
unsigned char HaveStartAddr = 0; /* Flag for start address given */
|
||||||
|
uint32_t StartAddr = 0; /* Start/load address of the program */
|
||||||
unsigned char SyncLines = 0; /* Accept line markers in the info file */
|
unsigned char SyncLines = 0; /* Accept line markers in the info file */
|
||||||
long InputOffs = -1L; /* Offset into input file */
|
long InputOffs = -1L; /* Offset into input file */
|
||||||
long InputSize = -1L; /* Number of bytes to read from input */
|
long InputSize = -1L; /* Number of bytes to read from input */
|
||||||
|
|||||||
@@ -38,6 +38,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -59,7 +63,8 @@ extern unsigned char UseHexOffs; /* Use hexadecimal label offsets */
|
|||||||
extern unsigned char PassCount; /* How many passed do we do? */
|
extern unsigned char PassCount; /* How many passed do we do? */
|
||||||
extern signed char NewlineAfterJMP;/* Add a newline after a JMP insn? */
|
extern signed char NewlineAfterJMP;/* Add a newline after a JMP insn? */
|
||||||
extern signed char NewlineAfterRTS;/* Add a newline after a RTS insn? */
|
extern signed char NewlineAfterRTS;/* Add a newline after a RTS insn? */
|
||||||
extern long StartAddr; /* Start/load address of the program */
|
extern unsigned char HaveStartAddr; /* Flag for start address given */
|
||||||
|
extern uint32_t StartAddr; /* Start/load address of the program */
|
||||||
extern unsigned char SyncLines; /* Accept line markers in the info file */
|
extern unsigned char SyncLines; /* Accept line markers in the info file */
|
||||||
extern long InputOffs; /* Offset into input file */
|
extern long InputOffs; /* Offset into input file */
|
||||||
extern long InputSize; /* Number of bytes to read from input */
|
extern long InputSize; /* Number of bytes to read from input */
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
@@ -95,7 +96,7 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char* GetAbsOverride (unsigned Flags, unsigned Addr)
|
static const char* GetAbsOverride (unsigned Flags, uint32_t Addr)
|
||||||
/* If the instruction requires an abs override modifier, return the necessary
|
/* If the instruction requires an abs override modifier, return the necessary
|
||||||
** string, otherwise return the empty string.
|
** string, otherwise return the empty string.
|
||||||
*/
|
*/
|
||||||
@@ -111,7 +112,7 @@ static const char* GetAbsOverride (unsigned Flags, unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char* GetAddrArg (unsigned Flags, unsigned Addr)
|
static const char* GetAddrArg (unsigned Flags, uint32_t Addr)
|
||||||
/* Return an address argument - a label if we have one, or the address itself */
|
/* Return an address argument - a label if we have one, or the address itself */
|
||||||
{
|
{
|
||||||
const char* Label = 0;
|
const char* Label = 0;
|
||||||
@@ -123,11 +124,9 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr)
|
|||||||
} else {
|
} else {
|
||||||
static char Buf [32];
|
static char Buf [32];
|
||||||
if (Addr < 0x100) {
|
if (Addr < 0x100) {
|
||||||
xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
|
xsprintf (Buf, sizeof (Buf), "$%02" PRIX32, Addr);
|
||||||
} else if (Addr < 0x10000) {
|
|
||||||
xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
|
|
||||||
} else {
|
} else {
|
||||||
xsprintf (Buf, sizeof (Buf), "$%06X", Addr);
|
xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr);
|
||||||
}
|
}
|
||||||
return Buf;
|
return Buf;
|
||||||
}
|
}
|
||||||
@@ -135,7 +134,7 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void GenerateLabel (unsigned Flags, unsigned Addr)
|
static void GenerateLabel (unsigned Flags, uint32_t Addr)
|
||||||
/* Generate a label in pass one if requested */
|
/* Generate a label in pass one if requested */
|
||||||
{
|
{
|
||||||
/* Generate labels in pass #1, and only if we don't have a label already */
|
/* Generate labels in pass #1, and only if we don't have a label already */
|
||||||
@@ -305,7 +304,7 @@ void OH_Implicit_42_45GS02 (const OpcDesc* D)
|
|||||||
|
|
||||||
void OH_Immediate (const OpcDesc* D)
|
void OH_Immediate (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
OneLine (D, "#$%02X", GetCodeByte (PC+1));
|
OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -313,9 +312,9 @@ void OH_Immediate (const OpcDesc* D)
|
|||||||
void OH_Immediate65816M (const OpcDesc* D)
|
void OH_Immediate65816M (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
if (GetAttr (PC) & atMem16) {
|
if (GetAttr (PC) & atMem16) {
|
||||||
OneLine (D, "#$%04X", GetCodeWord (PC+1));
|
OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1));
|
||||||
} else {
|
} else {
|
||||||
OneLine (D, "#$%02X", GetCodeByte (PC+1));
|
OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +323,9 @@ void OH_Immediate65816M (const OpcDesc* D)
|
|||||||
void OH_Immediate65816X (const OpcDesc* D)
|
void OH_Immediate65816X (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
if (GetAttr (PC) & atIdx16) {
|
if (GetAttr (PC) & atIdx16) {
|
||||||
OneLine (D, "#$%04X", GetCodeWord (PC+1));
|
OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1));
|
||||||
} else {
|
} else {
|
||||||
OneLine (D, "#$%02X", GetCodeByte (PC+1));
|
OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +333,7 @@ void OH_Immediate65816X (const OpcDesc* D)
|
|||||||
|
|
||||||
void OH_ImmediateWord (const OpcDesc* D)
|
void OH_ImmediateWord (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
OneLine (D, "#$%04X", GetCodeWord (PC+1));
|
OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -342,7 +341,7 @@ void OH_ImmediateWord (const OpcDesc* D)
|
|||||||
void OH_Direct (const OpcDesc* D)
|
void OH_Direct (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -370,7 +369,7 @@ void OH_Direct_Q (const OpcDesc* D)
|
|||||||
void OH_DirectX (const OpcDesc* D)
|
void OH_DirectX (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -398,7 +397,7 @@ void OH_DirectX_Q (const OpcDesc* D)
|
|||||||
void OH_DirectY (const OpcDesc* D)
|
void OH_DirectY (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -412,7 +411,7 @@ void OH_DirectY (const OpcDesc* D)
|
|||||||
void OH_Absolute (const OpcDesc* D)
|
void OH_Absolute (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+1);
|
uint32_t Addr = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -440,7 +439,7 @@ void OH_Absolute_Q (const OpcDesc* D)
|
|||||||
void OH_AbsoluteX (const OpcDesc* D)
|
void OH_AbsoluteX (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+1);
|
uint32_t Addr = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -468,7 +467,7 @@ void OH_AbsoluteX_Q (const OpcDesc* D)
|
|||||||
void OH_AbsoluteY (const OpcDesc* D)
|
void OH_AbsoluteY (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+1);
|
uint32_t Addr = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -482,7 +481,7 @@ void OH_AbsoluteY (const OpcDesc* D)
|
|||||||
void OH_AbsoluteLong (const OpcDesc* D attribute ((unused)))
|
void OH_AbsoluteLong (const OpcDesc* D attribute ((unused)))
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeLongAddr (PC+1);
|
uint32_t Addr = GetCodeLongAddr (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -496,7 +495,7 @@ void OH_AbsoluteLong (const OpcDesc* D attribute ((unused)))
|
|||||||
void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused)))
|
void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused)))
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeLongAddr (PC+1);
|
uint32_t Addr = GetCodeLongAddr (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -513,7 +512,7 @@ void OH_Relative (const OpcDesc* D)
|
|||||||
signed char Offs = GetCodeByte (PC+1);
|
signed char Offs = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Calculate the target address */
|
/* Calculate the target address */
|
||||||
unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF;
|
uint32_t Addr = (((int) PC+2) + Offs) & 0xFFFF;
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -535,7 +534,7 @@ void OH_RelativeLong (const OpcDesc* D attribute ((unused)))
|
|||||||
signed short Offs = GetCodeWord (PC+1);
|
signed short Offs = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Calculate the target address */
|
/* Calculate the target address */
|
||||||
unsigned Addr = (((int) PC+3) + Offs) & 0xFFFF;
|
uint32_t Addr = (((int) PC+3) + Offs) & 0xFFFF;
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -552,7 +551,7 @@ void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused)))
|
|||||||
signed short Offs = GetCodeWord (PC+1);
|
signed short Offs = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Calculate the target address */
|
/* Calculate the target address */
|
||||||
unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF;
|
uint32_t Addr = (((int) PC+2) + Offs) & 0xFFFF;
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -566,7 +565,7 @@ void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused)))
|
|||||||
void OH_DirectIndirect (const OpcDesc* D)
|
void OH_DirectIndirect (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -580,7 +579,7 @@ void OH_DirectIndirect (const OpcDesc* D)
|
|||||||
void OH_DirectIndirectY (const OpcDesc* D)
|
void OH_DirectIndirectY (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -594,7 +593,7 @@ void OH_DirectIndirectY (const OpcDesc* D)
|
|||||||
void OH_DirectIndirectZ (const OpcDesc* D)
|
void OH_DirectIndirectZ (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -622,7 +621,7 @@ void OH_DirectIndirectZ_Q (const OpcDesc* D)
|
|||||||
void OH_DirectXIndirect (const OpcDesc* D)
|
void OH_DirectXIndirect (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -636,7 +635,7 @@ void OH_DirectXIndirect (const OpcDesc* D)
|
|||||||
void OH_AbsoluteIndirect (const OpcDesc* D)
|
void OH_AbsoluteIndirect (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+1);
|
uint32_t Addr = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -652,11 +651,11 @@ void OH_BitBranch (const OpcDesc* D)
|
|||||||
char* BranchLabel;
|
char* BranchLabel;
|
||||||
|
|
||||||
/* Get the operands */
|
/* Get the operands */
|
||||||
unsigned char TestAddr = GetCodeByte (PC+1);
|
uint32_t TestAddr = GetCodeByte (PC+1);
|
||||||
signed char BranchOffs = GetCodeByte (PC+2);
|
int8_t BranchOffs = GetCodeByte (PC+2);
|
||||||
|
|
||||||
/* Calculate the target address for the branch */
|
/* Calculate the target address for the branch */
|
||||||
unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
|
uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
|
||||||
|
|
||||||
/* Generate labels in pass 1. The bit branch codes are special in that
|
/* Generate labels in pass 1. The bit branch codes are special in that
|
||||||
** they don't really match the remainder of the 6502 instruction set (they
|
** they don't really match the remainder of the 6502 instruction set (they
|
||||||
@@ -686,11 +685,11 @@ void OH_BitBranch_m740 (const OpcDesc* D)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* unsigned Bit = GetCodeByte (PC) >> 5; */
|
/* unsigned Bit = GetCodeByte (PC) >> 5; */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
signed char BranchOffs = GetCodeByte (PC+2);
|
int8_t BranchOffs = (int8_t) GetCodeByte (PC+2);
|
||||||
|
|
||||||
/* Calculate the target address for the branch */
|
/* Calculate the target address for the branch */
|
||||||
unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
|
uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -700,10 +699,12 @@ void OH_BitBranch_m740 (const OpcDesc* D)
|
|||||||
OneLine (D, "%s, %s", GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr));
|
OneLine (D, "%s, %s", GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OH_ImmediateDirect (const OpcDesc* D)
|
void OH_ImmediateDirect (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+2);
|
uint32_t Addr = GetCodeByte (PC+2);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -717,7 +718,7 @@ void OH_ImmediateDirect (const OpcDesc* D)
|
|||||||
void OH_ImmediateDirectX (const OpcDesc* D)
|
void OH_ImmediateDirectX (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+2);
|
uint32_t Addr = GetCodeByte (PC+2);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -731,7 +732,7 @@ void OH_ImmediateDirectX (const OpcDesc* D)
|
|||||||
void OH_ImmediateAbsolute (const OpcDesc* D)
|
void OH_ImmediateAbsolute (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+2);
|
uint32_t Addr = GetCodeWord (PC+2);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -745,7 +746,7 @@ void OH_ImmediateAbsolute (const OpcDesc* D)
|
|||||||
void OH_ImmediateAbsoluteX (const OpcDesc* D)
|
void OH_ImmediateAbsoluteX (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+2);
|
uint32_t Addr = GetCodeWord (PC+2);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -790,7 +791,7 @@ void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused)))
|
|||||||
void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused)))
|
void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused)))
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -804,7 +805,7 @@ void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused)))
|
|||||||
void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
|
void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -820,9 +821,9 @@ void OH_BlockMove (const OpcDesc* D)
|
|||||||
char* DstLabel;
|
char* DstLabel;
|
||||||
|
|
||||||
/* Get source operand */
|
/* Get source operand */
|
||||||
unsigned Src = GetCodeWord (PC+1);
|
uint32_t Src = GetCodeWord (PC+1);
|
||||||
/* Get destination operand */
|
/* Get destination operand */
|
||||||
unsigned Dst = GetCodeWord (PC+3);
|
uint32_t Dst = GetCodeWord (PC+3);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Src);
|
GenerateLabel (D->Flags, Src);
|
||||||
@@ -835,7 +836,7 @@ void OH_BlockMove (const OpcDesc* D)
|
|||||||
DstLabel = xstrdup (GetAddrArg (D->Flags, Dst));
|
DstLabel = xstrdup (GetAddrArg (D->Flags, Dst));
|
||||||
|
|
||||||
/* Output the line */
|
/* Output the line */
|
||||||
OneLine (D, "%s%s,%s%s,$%04X",
|
OneLine (D, "%s%s,%s%s,$%04" PRIX16,
|
||||||
GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src),
|
GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src),
|
||||||
GetAbsOverride (D->Flags, Dst), DstLabel,
|
GetAbsOverride (D->Flags, Dst), DstLabel,
|
||||||
GetCodeWord (PC+5));
|
GetCodeWord (PC+5));
|
||||||
@@ -848,12 +849,12 @@ void OH_BlockMove (const OpcDesc* D)
|
|||||||
void OH_BlockMove65816 (const OpcDesc* D)
|
void OH_BlockMove65816 (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get source operand */
|
/* Get source operand */
|
||||||
unsigned Src = GetCodeByte (PC+2);
|
uint8_t Src = GetCodeByte (PC+2);
|
||||||
/* Get destination operand */
|
/* Get destination operand */
|
||||||
unsigned Dst = GetCodeByte (PC+1);
|
uint8_t Dst = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Output the line */
|
/* Output the line */
|
||||||
OneLine (D, "#$%02X, #$%02X", Src, Dst);
|
OneLine (D, "#$%02" PRIX8 ", #$%02" PRIX8, Src, Dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -861,7 +862,7 @@ void OH_BlockMove65816 (const OpcDesc* D)
|
|||||||
void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
|
void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeWord (PC+1);
|
uint32_t Addr = GetCodeWord (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -875,7 +876,7 @@ void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
|
|||||||
void OH_DirectImmediate (const OpcDesc* D)
|
void OH_DirectImmediate (const OpcDesc* D)
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -891,7 +892,7 @@ void OH_ZeroPageBit (const OpcDesc* D)
|
|||||||
** NOTE: currently <bit> is part of the instruction
|
** NOTE: currently <bit> is part of the instruction
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned Addr = GetCodeByte (PC+1);
|
uint32_t Addr = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -917,10 +918,10 @@ void OH_AccumulatorBitBranch (const OpcDesc* D)
|
|||||||
** NOTE: currently <bit> is part of the instruction
|
** NOTE: currently <bit> is part of the instruction
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
signed char BranchOffs = GetCodeByte (PC+1);
|
int8_t BranchOffs = GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Calculate the target address for the branch */
|
/* Calculate the target address for the branch */
|
||||||
unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
|
uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
|
||||||
|
|
||||||
/* Generate labels in pass 1 */
|
/* Generate labels in pass 1 */
|
||||||
GenerateLabel (flLabel, BranchAddr);
|
GenerateLabel (flLabel, BranchAddr);
|
||||||
@@ -945,7 +946,7 @@ void OH_SpecialPage (const OpcDesc* D)
|
|||||||
/* m740 "special page" address mode */
|
/* m740 "special page" address mode */
|
||||||
{
|
{
|
||||||
/* Get the operand */
|
/* Get the operand */
|
||||||
unsigned Addr = 0xFF00 + GetCodeByte (PC+1);
|
uint32_t Addr = 0xFF00 + GetCodeByte (PC+1);
|
||||||
|
|
||||||
/* Generate a label in pass 1 */
|
/* Generate a label in pass 1 */
|
||||||
GenerateLabel (D->Flags, Addr);
|
GenerateLabel (D->Flags, Addr);
|
||||||
@@ -1004,16 +1005,13 @@ void OH_JsrAbsolute (const OpcDesc* D)
|
|||||||
unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)];
|
unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)];
|
||||||
OH_Absolute (D);
|
OH_Absolute (D);
|
||||||
if (ParamSize > 0) {
|
if (ParamSize > 0) {
|
||||||
unsigned RemainingBytes;
|
uint32_t RemainingBytes;
|
||||||
unsigned BytesLeft;
|
uint32_t BytesLeft;
|
||||||
PC += D->Size;
|
PC += D->Size;
|
||||||
RemainingBytes = GetRemainingBytes ();
|
RemainingBytes = GetRemainingBytes ();
|
||||||
if (RemainingBytes < ParamSize) {
|
BytesLeft = (RemainingBytes < ParamSize)? RemainingBytes : ParamSize;
|
||||||
ParamSize = RemainingBytes;
|
|
||||||
}
|
|
||||||
BytesLeft = ParamSize;
|
|
||||||
while (BytesLeft > 0) {
|
while (BytesLeft > 0) {
|
||||||
unsigned Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft;
|
uint32_t Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft;
|
||||||
DataByteLine (Chunk);
|
DataByteLine (Chunk);
|
||||||
BytesLeft -= Chunk;
|
BytesLeft -= Chunk;
|
||||||
PC += Chunk;
|
PC += Chunk;
|
||||||
@@ -1024,7 +1022,7 @@ void OH_JsrAbsolute (const OpcDesc* D)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetSubroutineParamSize (unsigned Addr, unsigned Size)
|
void SetSubroutineParamSize (uint32_t Addr, unsigned Size)
|
||||||
{
|
{
|
||||||
SubroutineParamSize[Addr] = Size;
|
SubroutineParamSize[Addr] = Size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "attrib.h"
|
#include "attrib.h"
|
||||||
|
|
||||||
@@ -119,7 +121,7 @@ void OH_JmpAbsoluteIndirect (const OpcDesc* D);
|
|||||||
void OH_JmpAbsoluteXIndirect (const OpcDesc* D);
|
void OH_JmpAbsoluteXIndirect (const OpcDesc* D);
|
||||||
void OH_JsrAbsolute (const OpcDesc*);
|
void OH_JsrAbsolute (const OpcDesc*);
|
||||||
|
|
||||||
void SetSubroutineParamSize (unsigned Addr, unsigned Size);
|
void SetSubroutineParamSize (uint32_t Addr, unsigned Size);
|
||||||
|
|
||||||
|
|
||||||
/* End of handler.h */
|
/* End of handler.h */
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_ARGUMENT_COLUMN:
|
case INFOTOK_ARGUMENT_COLUMN:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (MIN_ACOL, MAX_ACOL);
|
InfoRangeCheck ("ARGUMENTCOLUMN", MIN_ACOL, MAX_ACOL);
|
||||||
ACol = InfoIVal;
|
ACol = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -227,7 +227,7 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_COMMENT_COLUMN:
|
case INFOTOK_COMMENT_COLUMN:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (MIN_CCOL, MAX_CCOL);
|
InfoRangeCheck ("COMMENTCOLUMN", MIN_CCOL, MAX_CCOL);
|
||||||
CCol = InfoIVal;
|
CCol = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -235,7 +235,7 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_COMMENTS:
|
case INFOTOK_COMMENTS:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS);
|
InfoRangeCheck ("COMMENTS", MIN_COMMENTS, MAX_COMMENTS);
|
||||||
Comments = InfoIVal;
|
Comments = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -281,7 +281,7 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_INPUTSIZE:
|
case INFOTOK_INPUTSIZE:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (1, 0x10000);
|
InfoRangeCheck ("INPUTSIZE", 1, 0x10000);
|
||||||
InputSize = InfoIVal;
|
InputSize = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -289,7 +289,7 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_LABELBREAK:
|
case INFOTOK_LABELBREAK:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0, UCHAR_MAX);
|
InfoRangeCheck ("LABELBREAK", 0, UCHAR_MAX);
|
||||||
LBreak = (unsigned char) InfoIVal;
|
LBreak = (unsigned char) InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -297,7 +297,7 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_MNEMONIC_COLUMN:
|
case INFOTOK_MNEMONIC_COLUMN:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (MIN_MCOL, MAX_MCOL);
|
InfoRangeCheck ("MNEMONICCOLUMN", MIN_MCOL, MAX_MCOL);
|
||||||
MCol = InfoIVal;
|
MCol = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -336,7 +336,7 @@ static void GlobalSection (void)
|
|||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
if (InfoIVal != 0) {
|
if (InfoIVal != 0) {
|
||||||
InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
|
InfoRangeCheck ("PAGELENGTH", MIN_PAGE_LEN, MAX_PAGE_LEN);
|
||||||
}
|
}
|
||||||
PageLength = InfoIVal;
|
PageLength = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
@@ -345,15 +345,16 @@ static void GlobalSection (void)
|
|||||||
case INFOTOK_STARTADDR:
|
case INFOTOK_STARTADDR:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0x0000, 0xFFFF);
|
InfoRangeCheck ("STARTADDR", 0x0000, 0xFFFF);
|
||||||
StartAddr = InfoIVal;
|
StartAddr = InfoIVal;
|
||||||
|
HaveStartAddr = 1;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFOTOK_TEXT_COLUMN:
|
case INFOTOK_TEXT_COLUMN:
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (MIN_TCOL, MAX_TCOL);
|
InfoRangeCheck ("TEXTCOLUMN", MIN_TCOL, MAX_TCOL);
|
||||||
TCol = InfoIVal;
|
TCol = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -413,7 +414,7 @@ static void LabelSection (void)
|
|||||||
InfoError ("Value already given");
|
InfoError ("Value already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0, 0xFFFF);
|
InfoRangeCheck ("ADDR", 0, 0xFFFF);
|
||||||
Value = InfoIVal;
|
Value = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -447,7 +448,7 @@ static void LabelSection (void)
|
|||||||
InfoError ("Size already given");
|
InfoError ("Size already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (1, 0x10000);
|
InfoRangeCheck ("SIZE", 1, 0x10000);
|
||||||
Size = InfoIVal;
|
Size = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -458,7 +459,7 @@ static void LabelSection (void)
|
|||||||
InfoError ("ParamSize already given");
|
InfoError ("ParamSize already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (1, 0x10000);
|
InfoRangeCheck ("PARAMSIZE", 1, 0x10000);
|
||||||
ParamSize = InfoIVal;
|
ParamSize = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -559,8 +560,8 @@ static void RangeSection (void)
|
|||||||
unsigned Attributes = tNone;
|
unsigned Attributes = tNone;
|
||||||
|
|
||||||
/* Locals - initialize to avoid gcc warnings */
|
/* Locals - initialize to avoid gcc warnings */
|
||||||
unsigned Start = 0;
|
uint32_t Start = 0;
|
||||||
unsigned End = 0;
|
uint32_t End = 0;
|
||||||
unsigned char Type = 0;
|
unsigned char Type = 0;
|
||||||
unsigned AddrMode = 0;
|
unsigned AddrMode = 0;
|
||||||
char* Name = 0;
|
char* Name = 0;
|
||||||
@@ -599,17 +600,18 @@ static void RangeSection (void)
|
|||||||
case INFOTOK_END:
|
case INFOTOK_END:
|
||||||
AddAttr ("END", &Attributes, tEnd);
|
AddAttr ("END", &Attributes, tEnd);
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
|
|
||||||
if (InfoTok == INFOTOK_OFFSET_INTCON) {
|
if (InfoTok == INFOTOK_OFFSET_INTCON) {
|
||||||
InfoRangeCheck (0x0000, 0xFFFF);
|
InfoRangeCheck ("END", 0x0000, 0xFFFF);
|
||||||
if (!(Attributes & tStart))
|
if ((Attributes & tStart) == 0) {
|
||||||
InfoError ("When using End with an offset, Start must be specified before");
|
InfoError ("When using End with an offset, Start must be specified before");
|
||||||
|
}
|
||||||
End = Start + InfoIVal - 1;
|
End = Start + InfoIVal - 1;
|
||||||
if (End > 0xFFFF)
|
if (End > 0xFFFF) {
|
||||||
InfoError ("Range error");
|
InfoError ("Range error");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0x0000, 0xFFFF);
|
InfoRangeCheck ("END", 0x0000, 0xFFFF);
|
||||||
End = InfoIVal;
|
End = InfoIVal;
|
||||||
}
|
}
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
@@ -631,7 +633,7 @@ static void RangeSection (void)
|
|||||||
AddAttr ("START", &Attributes, tStart);
|
AddAttr ("START", &Attributes, tStart);
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0x0000, 0xFFFF);
|
InfoRangeCheck ("START", 0x0000, 0xFFFF);
|
||||||
Start = InfoIVal;
|
Start = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -689,7 +691,7 @@ static void RangeSection (void)
|
|||||||
AddAttr ("UNIT", &Attributes, tUnit);
|
AddAttr ("UNIT", &Attributes, tUnit);
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0x0002, 0xFFFF);
|
InfoRangeCheck ("UNIT", 0x0002, 0xFFFF);
|
||||||
Unit = InfoIVal;
|
Unit = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -807,7 +809,7 @@ static void SegmentSection (void)
|
|||||||
InfoError ("Value already given");
|
InfoError ("Value already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0, 0xFFFF);
|
InfoRangeCheck ("END", 0, 0xFFFF);
|
||||||
End = InfoIVal;
|
End = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
@@ -828,7 +830,7 @@ static void SegmentSection (void)
|
|||||||
InfoError ("Value already given");
|
InfoError ("Value already given");
|
||||||
}
|
}
|
||||||
InfoAssureInt ();
|
InfoAssureInt ();
|
||||||
InfoRangeCheck (0, 0xFFFF);
|
InfoRangeCheck ("START", 0, 0xFFFF);
|
||||||
Start = InfoIVal;
|
Start = InfoIVal;
|
||||||
InfoNextTok ();
|
InfoNextTok ();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -33,15 +33,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "coll.h"
|
||||||
|
#include "strbuf.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "xsprintf.h"
|
#include "xsprintf.h"
|
||||||
|
|
||||||
/* da65 */
|
/* da65 */
|
||||||
#include "attrtab.h"
|
|
||||||
#include "code.h"
|
#include "code.h"
|
||||||
#include "comments.h"
|
#include "comments.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -57,14 +59,82 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Symbol table */
|
/* Label structure how it is found in the label table */
|
||||||
static const char* SymTab[0x10000];
|
typedef struct Label Label;
|
||||||
|
struct Label {
|
||||||
|
struct Label* Next; /* Next entry in linked list */
|
||||||
|
uint32_t Addr; /* The full address */
|
||||||
|
char Name[1]; /* Symbol name, dynamically allocated */
|
||||||
|
};
|
||||||
|
|
||||||
/* 65816 symbol table */
|
/* Labels use a hash table and a linear list for collision resolution. The
|
||||||
#define MAX_LONG_LABELS 256
|
** hash function is easy and effective. It evaluates just the lower bits of
|
||||||
static const char* LongSymVal[MAX_LONG_LABELS];
|
** the address.
|
||||||
static unsigned LongSymAddr[MAX_LONG_LABELS];
|
*/
|
||||||
static unsigned LongLabelsUsed;
|
#define LABEL_HASH_SIZE 4096u /* Must be power of two */
|
||||||
|
static Label* LabelTab[LABEL_HASH_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* struct Label */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Label* NewLabel (uint32_t Addr, const char* Name)
|
||||||
|
/* Create a new label structure and return it */
|
||||||
|
{
|
||||||
|
/* Get the length of the name */
|
||||||
|
unsigned Len = strlen (Name);
|
||||||
|
|
||||||
|
/* Create a new label */
|
||||||
|
Label* L = xmalloc (sizeof (Label) + Len);
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
L->Next = 0;
|
||||||
|
L->Addr = Addr;
|
||||||
|
memcpy (L->Name, Name, Len + 1);
|
||||||
|
|
||||||
|
/* Return the label just created */
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t GetLabelHash (uint32_t Addr)
|
||||||
|
/* Get the hash for a label at the given address */
|
||||||
|
{
|
||||||
|
return (Addr & (LABEL_HASH_SIZE - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Label* FindLabel (uint32_t Addr)
|
||||||
|
/* Search for a label for the given address and return it. Returns NULL if
|
||||||
|
** no label exists for the address.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Label* L = LabelTab[GetLabelHash (Addr)];
|
||||||
|
while (L) {
|
||||||
|
if (L->Addr == Addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
L = L->Next;
|
||||||
|
}
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void InsertLabel (Label* L)
|
||||||
|
/* Insert a label into the tables */
|
||||||
|
{
|
||||||
|
/* Insert into hash table */
|
||||||
|
uint32_t Hash = GetLabelHash (L->Addr);
|
||||||
|
L->Next = LabelTab[Hash];
|
||||||
|
LabelTab[Hash] = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -74,34 +144,19 @@ static unsigned LongLabelsUsed;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char* MakeLabelName (unsigned Addr)
|
static const char* MakeLabelName (uint32_t Addr)
|
||||||
/* Make the default label name from the given address and return it in a
|
/* Make the default label name from the given address and return it in a
|
||||||
** static buffer.
|
** static buffer.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static char LabelBuf [32];
|
static char LabelBuf [32];
|
||||||
xsprintf (LabelBuf, sizeof (LabelBuf),
|
xsprintf (LabelBuf, sizeof (LabelBuf), "L%04" PRIX32, Addr);
|
||||||
IsLongAddr (Addr) ? "L%06X" : "L%04X", Addr);
|
|
||||||
return LabelBuf;
|
return LabelBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned FindLongIndex (unsigned Addr)
|
static void AddLabel (uint32_t Addr, attr_t Attr, const char* Name)
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < LongLabelsUsed; i++) {
|
|
||||||
if (LongSymAddr[i] == Addr) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
|
||||||
/* Add a label */
|
/* Add a label */
|
||||||
{
|
{
|
||||||
/* Get an existing label attribute */
|
/* Get an existing label attribute */
|
||||||
@@ -109,43 +164,25 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
|||||||
|
|
||||||
/* Must not have two symbols for one address */
|
/* Must not have two symbols for one address */
|
||||||
if (ExistingAttr != atNoLabel) {
|
if (ExistingAttr != atNoLabel) {
|
||||||
/* Allow redefinition if identical. Beware: Unnamed labels don't
|
/* Allow redefinition if identical. Beware: Unnamed labels do not
|
||||||
** have a name (you guessed that, didn't you?).
|
** have an entry in the label table.
|
||||||
*/
|
*/
|
||||||
if (IsLongAddr (Addr)) {
|
Label* L = FindLabel (Addr);
|
||||||
const unsigned i = FindLongIndex (Addr);
|
|
||||||
if (ExistingAttr == Attr &&
|
if (ExistingAttr == Attr &&
|
||||||
((Name == 0 && LongSymVal[i] == 0) ||
|
((Name == 0 && L == 0) ||
|
||||||
(Name != 0 && LongSymVal[i] != 0 &&
|
(Name != 0 && L != 0 && strcmp (Name, L->Name) == 0))) {
|
||||||
strcmp (LongSymVal[i], Name) == 0))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Error ("Duplicate label for address $%06X (%s): '%s'", Addr,
|
|
||||||
LongSymVal[i] == 0 ? "<unnamed label>" : LongSymVal[i],
|
|
||||||
Name == 0 ? "<unnamed label>" : Name);
|
|
||||||
} else {
|
|
||||||
if (ExistingAttr == Attr &&
|
|
||||||
((Name == 0 && SymTab[Addr] == 0) ||
|
|
||||||
(Name != 0 && SymTab[Addr] != 0 &&
|
|
||||||
strcmp (SymTab[Addr], Name) == 0))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Error ("Duplicate label for address $%04X (%s): '%s'", Addr,
|
Error ("Duplicate label for address $%04X (%s): '%s'", Addr,
|
||||||
SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr],
|
L? L->Name : "<unnamed label>",
|
||||||
Name == 0 ? "<unnamed label>" : Name);
|
Name? Name : "<unnamed label>");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new label (xstrdup will return NULL if input NULL) */
|
/* If this is not an unnamed label, create a new label entry and
|
||||||
if (IsLongAddr (Addr)) {
|
** insert it.
|
||||||
if (LongLabelsUsed >= MAX_LONG_LABELS) {
|
*/
|
||||||
Error ("Too many long labels");
|
if (Name != 0) {
|
||||||
}
|
InsertLabel (NewLabel (Addr, Name));
|
||||||
LongSymAddr[LongLabelsUsed] = Addr;
|
|
||||||
LongSymVal[LongLabelsUsed] = xstrdup (Name);
|
|
||||||
LongLabelsUsed++;
|
|
||||||
} else {
|
|
||||||
SymTab[Addr] = xstrdup (Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the attribute */
|
/* Remember the attribute */
|
||||||
@@ -154,7 +191,7 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddIntLabel (unsigned Addr)
|
void AddIntLabel (uint32_t Addr)
|
||||||
/* Add an internal label using the address to generate the name. */
|
/* Add an internal label using the address to generate the name. */
|
||||||
{
|
{
|
||||||
AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
|
AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
|
||||||
@@ -162,7 +199,7 @@ void AddIntLabel (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddExtLabel (unsigned Addr, const char* Name)
|
void AddExtLabel (uint32_t Addr, const char* Name)
|
||||||
/* Add an external label */
|
/* Add an external label */
|
||||||
{
|
{
|
||||||
AddLabel (Addr, atExtLabel, Name);
|
AddLabel (Addr, atExtLabel, Name);
|
||||||
@@ -170,7 +207,7 @@ void AddExtLabel (unsigned Addr, const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddUnnamedLabel (unsigned Addr)
|
void AddUnnamedLabel (uint32_t Addr)
|
||||||
/* Add an unnamed label */
|
/* Add an unnamed label */
|
||||||
{
|
{
|
||||||
AddLabel (Addr, atUnnamedLabel, 0);
|
AddLabel (Addr, atUnnamedLabel, 0);
|
||||||
@@ -178,11 +215,27 @@ void AddUnnamedLabel (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs)
|
void AddDepLabel (uint32_t Addr, attr_t Attr, const char* BaseName, unsigned Offs)
|
||||||
/* Add a dependent label at the given address using "basename+Offs" as the new
|
/* Add a dependent label at the given address using "basename+Offs" as the new
|
||||||
** name.
|
** name.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
/* Create the new name in the buffer */
|
||||||
|
StrBuf Name = AUTO_STRBUF_INITIALIZER;
|
||||||
|
if (UseHexOffs) {
|
||||||
|
SB_Printf (&Name, "%s+$%02X", BaseName, Offs);
|
||||||
|
} else {
|
||||||
|
SB_Printf (&Name, "%s+%u", BaseName, Offs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define the labels */
|
||||||
|
AddLabel (Addr, Attr | atDepLabel, SB_GetConstBuf (&Name));
|
||||||
|
|
||||||
|
/* Free the name buffer */
|
||||||
|
SB_Done (&Name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Allocate memory for the dependent label name */
|
/* Allocate memory for the dependent label name */
|
||||||
unsigned NameLen = strlen (BaseName);
|
unsigned NameLen = strlen (BaseName);
|
||||||
char* DepName = xmalloc (NameLen + 7); /* "+$ABCD\0" */
|
char* DepName = xmalloc (NameLen + 7); /* "+$ABCD\0" */
|
||||||
@@ -203,7 +256,7 @@ void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Off
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void AddLabelRange (unsigned Addr, attr_t Attr,
|
static void AddLabelRange (uint32_t Addr, attr_t Attr,
|
||||||
const char* Name, unsigned Count)
|
const char* Name, unsigned Count)
|
||||||
/* Add a label for a range. The first entry gets the label "Name" while the
|
/* Add a label for a range. The first entry gets the label "Name" while the
|
||||||
** others get "Name+offs".
|
** others get "Name+offs".
|
||||||
@@ -241,7 +294,7 @@ static void AddLabelRange (unsigned Addr, attr_t Attr,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
void AddIntLabelRange (uint32_t Addr, const char* Name, unsigned Count)
|
||||||
/* Add an internal label for a range. The first entry gets the label "Name"
|
/* Add an internal label for a range. The first entry gets the label "Name"
|
||||||
** while the others get "Name+offs".
|
** while the others get "Name+offs".
|
||||||
*/
|
*/
|
||||||
@@ -252,7 +305,7 @@ void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
void AddExtLabelRange (uint32_t Addr, const char* Name, unsigned Count)
|
||||||
/* Add an external label for a range. The first entry gets the label "Name"
|
/* Add an external label for a range. The first entry gets the label "Name"
|
||||||
** while the others get "Name+offs".
|
** while the others get "Name+offs".
|
||||||
*/
|
*/
|
||||||
@@ -263,7 +316,7 @@ void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int HaveLabel (unsigned Addr)
|
int HaveLabel (uint32_t Addr)
|
||||||
/* Check if there is a label for the given address */
|
/* Check if there is a label for the given address */
|
||||||
{
|
{
|
||||||
/* Check for a label */
|
/* Check for a label */
|
||||||
@@ -272,7 +325,7 @@ int HaveLabel (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int MustDefLabel (unsigned Addr)
|
int MustDefLabel (uint32_t Addr)
|
||||||
/* Return true if we must define a label for this address, that is, if there
|
/* Return true if we must define a label for this address, that is, if there
|
||||||
** is a label at this address, and it is an external or internal label.
|
** is a label at this address, and it is an external or internal label.
|
||||||
*/
|
*/
|
||||||
@@ -286,7 +339,7 @@ int MustDefLabel (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetLabelName (unsigned Addr)
|
const char* GetLabelName (uint32_t Addr)
|
||||||
/* Return the label name for an address */
|
/* Return the label name for an address */
|
||||||
{
|
{
|
||||||
/* Get the label attribute */
|
/* Get the label attribute */
|
||||||
@@ -297,19 +350,16 @@ const char* GetLabelName (unsigned Addr)
|
|||||||
*/
|
*/
|
||||||
if (A == atUnnamedLabel) {
|
if (A == atUnnamedLabel) {
|
||||||
return "";
|
return "";
|
||||||
} else if (IsLongAddr (Addr)) {
|
|
||||||
/* Return the label if any */
|
|
||||||
const unsigned i = FindLongIndex (Addr);
|
|
||||||
return i < LongLabelsUsed ? LongSymVal[i] : NULL;
|
|
||||||
} else {
|
} else {
|
||||||
/* Return the label if any */
|
/* Return the label if any */
|
||||||
return SymTab[Addr];
|
const Label* L = FindLabel (Addr);
|
||||||
|
return L? L->Name : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
const char* GetLabel (uint32_t Addr, uint32_t RefFrom)
|
||||||
/* Return the label name for an address, as it is used in a label reference.
|
/* Return the label name for an address, as it is used in a label reference.
|
||||||
** RefFrom is the address the label is referenced from. This is needed in case
|
** RefFrom is the address the label is referenced from. This is needed in case
|
||||||
** of unnamed labels, to determine the name.
|
** of unnamed labels, to determine the name.
|
||||||
@@ -339,7 +389,7 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
|||||||
*/
|
*/
|
||||||
if (Addr <= RefFrom) {
|
if (Addr <= RefFrom) {
|
||||||
/* Search backwards */
|
/* Search backwards */
|
||||||
unsigned I = RefFrom;
|
uint32_t I = RefFrom;
|
||||||
while (Addr < I) {
|
while (Addr < I) {
|
||||||
--I;
|
--I;
|
||||||
A = GetLabelAttr (I);
|
A = GetLabelAttr (I);
|
||||||
@@ -357,7 +407,7 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Search forwards */
|
/* Search forwards */
|
||||||
unsigned I = RefFrom;
|
uint32_t I = RefFrom;
|
||||||
while (Addr > I) {
|
while (Addr > I) {
|
||||||
++I;
|
++I;
|
||||||
A = GetLabelAttr (I);
|
A = GetLabelAttr (I);
|
||||||
@@ -373,26 +423,22 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
|||||||
/* Return the label name */
|
/* Return the label name */
|
||||||
return FwdLabels[Count-1];
|
return FwdLabels[Count-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (IsLongAddr (Addr)) {
|
|
||||||
/* Return the label if any */
|
|
||||||
const unsigned i = FindLongIndex (Addr);
|
|
||||||
return i < LongLabelsUsed ? LongSymVal[i] : NULL;
|
|
||||||
} else {
|
} else {
|
||||||
/* Return the label if any */
|
/* Return the label if any */
|
||||||
return SymTab[Addr];
|
const Label* L = FindLabel (Addr);
|
||||||
|
return L? L->Name : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ForwardLabel (unsigned Offs)
|
void ForwardLabel (uint32_t Offs)
|
||||||
/* If necessary, output a forward label, one that is within the next few
|
/* If necessary, output a forward label, one that is within the next few
|
||||||
** bytes and is therefore output as "label = * + x".
|
** bytes and is therefore output as "label = * + x".
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Calculate the actual address */
|
/* Calculate the actual address */
|
||||||
unsigned long Addr = PC + Offs;
|
uint32_t Addr = PC + Offs;
|
||||||
|
|
||||||
/* Get the type of the label */
|
/* Get the type of the label */
|
||||||
attr_t A = GetLabelAttr (Addr);
|
attr_t A = GetLabelAttr (Addr);
|
||||||
@@ -406,7 +452,7 @@ void ForwardLabel (unsigned Offs)
|
|||||||
** an error.
|
** an error.
|
||||||
*/
|
*/
|
||||||
if (A == atUnnamedLabel) {
|
if (A == atUnnamedLabel) {
|
||||||
Error ("Cannot define unnamed label at address $%04lX", Addr);
|
Error ("Cannot define unnamed label at address $%04" PRIX32, Addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output the label */
|
/* Output the label */
|
||||||
@@ -415,24 +461,33 @@ void ForwardLabel (unsigned Offs)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DefOutOfRangeLabel (unsigned long Addr)
|
static int CompareLabels (void* Data attribute ((unused)),
|
||||||
|
const void* L1, const void* L2)
|
||||||
|
/* Compare functions for sorting the out-of-range labels */
|
||||||
|
{
|
||||||
|
if (((const Label*) L1)->Addr < ((const Label*) L2)->Addr) {
|
||||||
|
return -1;
|
||||||
|
} else if (((const Label*) L1)->Addr > ((const Label*) L2)->Addr) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void DefOutOfRangeLabel (const Label* L)
|
||||||
/* Define one label that is outside code range. */
|
/* Define one label that is outside code range. */
|
||||||
{
|
{
|
||||||
switch (GetLabelAttr (Addr)) {
|
switch (GetLabelAttr (L->Addr)) {
|
||||||
|
|
||||||
case atIntLabel:
|
case atIntLabel:
|
||||||
case atExtLabel:
|
case atExtLabel:
|
||||||
if (IsLongAddr (Addr)) {
|
DefConst (L->Name, GetComment (L->Addr), L->Addr);
|
||||||
const unsigned i = FindLongIndex (Addr);
|
|
||||||
DefConst (i < LongLabelsUsed ? LongSymVal[i] : NULL,
|
|
||||||
GetComment (Addr), Addr);
|
|
||||||
} else {
|
|
||||||
DefConst (SymTab[Addr], GetComment (Addr), Addr);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case atUnnamedLabel:
|
case atUnnamedLabel:
|
||||||
Error ("Cannot define unnamed label at address $%04lX", Addr);
|
Error ("Cannot define unnamed label at address $%04" PRIX32, L->Addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -446,34 +501,40 @@ static void DefOutOfRangeLabel (unsigned long Addr)
|
|||||||
void DefOutOfRangeLabels (void)
|
void DefOutOfRangeLabels (void)
|
||||||
/* Output any labels that are out of the loaded code range */
|
/* Output any labels that are out of the loaded code range */
|
||||||
{
|
{
|
||||||
unsigned long Addr;
|
unsigned I;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
|
/* This requires somewhat more effort since the labels output should be
|
||||||
|
** sorted by address for better readability. This is not directly
|
||||||
|
** possible when using a hash table, so an intermediate data structure
|
||||||
|
** is required. It is not possible to collect out-of-range labels while
|
||||||
|
** generating them, since they may come from an info file and are added
|
||||||
|
** while no input file was read. Which means it cannot be determined at
|
||||||
|
** that point if they're out-of-range or not.
|
||||||
|
*/
|
||||||
|
Collection Labels = AUTO_COLLECTION_INITIALIZER;
|
||||||
|
CollGrow (&Labels, 128);
|
||||||
|
|
||||||
|
/* Walk over the hash and copy all out-of-range labels */
|
||||||
|
for (I = 0; I < LABEL_HASH_SIZE; ++I) {
|
||||||
|
Label* L = LabelTab[I];
|
||||||
|
while (L) {
|
||||||
|
if (L->Addr < CodeStart || L->Addr > CodeEnd) {
|
||||||
|
CollAppend (&Labels, L);
|
||||||
|
}
|
||||||
|
L = L->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort the out-of-range labels by address */
|
||||||
|
CollSort (&Labels, CompareLabels, 0);
|
||||||
|
|
||||||
|
/* Output the labels */
|
||||||
|
SeparatorLine ();
|
||||||
|
for (I = 0; I < CollCount (&Labels); ++I) {
|
||||||
|
DefOutOfRangeLabel (CollConstAt (&Labels, I));
|
||||||
|
}
|
||||||
SeparatorLine ();
|
SeparatorLine ();
|
||||||
|
|
||||||
/* Low range */
|
/* Free allocated storage */
|
||||||
Addr = 0;
|
DoneCollection (&Labels);
|
||||||
while (Addr < CodeStart) {
|
|
||||||
DefOutOfRangeLabel (Addr++);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip areas in code range */
|
|
||||||
while (Addr <= CodeEnd) {
|
|
||||||
if (GetStyleAttr (Addr) == atSkip) {
|
|
||||||
DefOutOfRangeLabel (Addr);
|
|
||||||
}
|
|
||||||
++Addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* High range */
|
|
||||||
while (Addr < 0x10000) {
|
|
||||||
DefOutOfRangeLabel (Addr++);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 65816 long range */
|
|
||||||
for (i = 0; i < LongLabelsUsed; i++) {
|
|
||||||
DefOutOfRangeLabel (LongSymAddr[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
SeparatorLine ();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* da65 */
|
||||||
#include "attrtab.h"
|
#include "attrtab.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -48,42 +51,42 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddIntLabel (unsigned Addr);
|
void AddIntLabel (uint32_t Addr);
|
||||||
/* Add an internal label using the address to generate the name. */
|
/* Add an internal label using the address to generate the name. */
|
||||||
|
|
||||||
void AddExtLabel (unsigned Addr, const char* Name);
|
void AddExtLabel (uint32_t Addr, const char* Name);
|
||||||
/* Add an external label */
|
/* Add an external label */
|
||||||
|
|
||||||
void AddUnnamedLabel (unsigned Addr);
|
void AddUnnamedLabel (uint32_t Addr);
|
||||||
/* Add an unnamed label */
|
/* Add an unnamed label */
|
||||||
|
|
||||||
void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs);
|
void AddDepLabel (uint32_t Addr, attr_t Attr, const char* BaseName, unsigned Offs);
|
||||||
/* Add a dependent label at the given address using "base name+Offs" as the new
|
/* Add a dependent label at the given address using "base name+Offs" as the new
|
||||||
** name.
|
** name.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count);
|
void AddIntLabelRange (uint32_t Addr, const char* Name, unsigned Count);
|
||||||
/* Add an internal label for a range. The first entry gets the label "Name"
|
/* Add an internal label for a range. The first entry gets the label "Name"
|
||||||
** while the others get "Name+offs".
|
** while the others get "Name+offs".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count);
|
void AddExtLabelRange (uint32_t Addr, const char* Name, unsigned Count);
|
||||||
/* Add an external label for a range. The first entry gets the label "Name"
|
/* Add an external label for a range. The first entry gets the label "Name"
|
||||||
** while the others get "Name+offs".
|
** while the others get "Name+offs".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int HaveLabel (unsigned Addr);
|
int HaveLabel (uint32_t Addr);
|
||||||
/* Check if there is a label for the given address */
|
/* Check if there is a label for the given address */
|
||||||
|
|
||||||
int MustDefLabel (unsigned Addr);
|
int MustDefLabel (uint32_t Addr);
|
||||||
/* Return true if we must define a label for this address, that is, if there
|
/* Return true if we must define a label for this address, that is, if there
|
||||||
** is a label at this address, and it is an external or internal label.
|
** is a label at this address, and it is an external or internal label.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char* GetLabelName (unsigned Addr);
|
const char* GetLabelName (uint32_t Addr);
|
||||||
/* Return the label name for an address */
|
/* Return the label name for an address */
|
||||||
|
|
||||||
const char* GetLabel (unsigned Addr, unsigned RefFrom);
|
const char* GetLabel (uint32_t Addr, uint32_t RefFrom);
|
||||||
/* Return the label name for an address, as it is used in a label reference.
|
/* Return the label name for an address, as it is used in a label reference.
|
||||||
** RefFrom is the address the label is referenced from. This is needed in case
|
** RefFrom is the address the label is referenced from. This is needed in case
|
||||||
** of unnamed labels, to determine the name.
|
** of unnamed labels, to determine the name.
|
||||||
|
|||||||
@@ -313,7 +313,8 @@ static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg
|
|||||||
static void OptStartAddr (const char* Opt, const char* Arg)
|
static void OptStartAddr (const char* Opt, const char* Arg)
|
||||||
/* Set the default start address */
|
/* Set the default start address */
|
||||||
{
|
{
|
||||||
StartAddr = CvtNumber (Opt, Arg);
|
StartAddr = (uint32_t) CvtNumber (Opt, Arg);
|
||||||
|
HaveStartAddr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -409,11 +410,11 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC)
|
|||||||
static void OneOpcode (unsigned RemainingBytes)
|
static void OneOpcode (unsigned RemainingBytes)
|
||||||
/* Disassemble one opcode */
|
/* Disassemble one opcode */
|
||||||
{
|
{
|
||||||
unsigned I;
|
uint32_t I;
|
||||||
unsigned OldPC = PC;
|
uint32_t OldPC = PC;
|
||||||
|
|
||||||
/* Get the opcode from the current address */
|
/* Get the opcode from the current address */
|
||||||
unsigned char OPC = GetCodeByte (PC);
|
uint8_t OPC = GetCodeByte (PC);
|
||||||
|
|
||||||
/* Get the opcode description for the opcode byte */
|
/* Get the opcode description for the opcode byte */
|
||||||
const OpcDesc* D = &OpcTable[OPC];
|
const OpcDesc* D = &OpcTable[OPC];
|
||||||
@@ -574,7 +575,7 @@ static void OneOpcode (unsigned RemainingBytes)
|
|||||||
static void OnePass (void)
|
static void OnePass (void)
|
||||||
/* Make one pass through the code */
|
/* Make one pass through the code */
|
||||||
{
|
{
|
||||||
unsigned Count;
|
uint32_t Count;
|
||||||
|
|
||||||
PrevAddrMode = 0;
|
PrevAddrMode = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -208,13 +209,13 @@ 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, uint32_t Addr)
|
||||||
/* Define an address constant */
|
/* Define an address constant */
|
||||||
{
|
{
|
||||||
if (Pass == PassCount) {
|
if (Pass == PassCount) {
|
||||||
Output ("%s", Name);
|
Output ("%s", Name);
|
||||||
Indent (ACol);
|
Indent (ACol);
|
||||||
Output (":= $%04X", Addr);
|
Output (":= $%04" PRIX32, Addr);
|
||||||
if (Comment) {
|
if (Comment) {
|
||||||
Indent (CCol);
|
Indent (CCol);
|
||||||
Output ("; %s", Comment);
|
Output ("; %s", Comment);
|
||||||
@@ -225,19 +226,19 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DataByteLine (unsigned ByteCount)
|
void DataByteLine (uint32_t ByteCount)
|
||||||
/* Output a line with bytes */
|
/* Output a line with bytes */
|
||||||
{
|
{
|
||||||
unsigned I;
|
uint32_t I;
|
||||||
|
|
||||||
Indent (MCol);
|
Indent (MCol);
|
||||||
Output (".byte");
|
Output (".byte");
|
||||||
Indent (ACol);
|
Indent (ACol);
|
||||||
for (I = 0; I < ByteCount; ++I) {
|
for (I = 0; I < ByteCount; ++I) {
|
||||||
if (I > 0) {
|
if (I > 0) {
|
||||||
Output (",$%02X", CodeBuf[PC+I]);
|
Output (",$%02" PRIX8, CodeBuf[PC+I]);
|
||||||
} else {
|
} else {
|
||||||
Output ("$%02X", CodeBuf[PC+I]);
|
Output ("$%02" PRIX8, CodeBuf[PC+I]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LineComment (PC, ByteCount);
|
LineComment (PC, ByteCount);
|
||||||
@@ -246,19 +247,19 @@ void DataByteLine (unsigned ByteCount)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DataDByteLine (unsigned ByteCount)
|
void DataDByteLine (uint32_t ByteCount)
|
||||||
/* Output a line with dbytes */
|
/* Output a line with dbytes */
|
||||||
{
|
{
|
||||||
unsigned I;
|
uint32_t I;
|
||||||
|
|
||||||
Indent (MCol);
|
Indent (MCol);
|
||||||
Output (".dbyt");
|
Output (".dbyt");
|
||||||
Indent (ACol);
|
Indent (ACol);
|
||||||
for (I = 0; I < ByteCount; I += 2) {
|
for (I = 0; I < ByteCount; I += 2) {
|
||||||
if (I > 0) {
|
if (I > 0) {
|
||||||
Output (",$%04X", GetCodeDByte (PC+I));
|
Output (",$%04" PRIX16, GetCodeDByte (PC+I));
|
||||||
} else {
|
} else {
|
||||||
Output ("$%04X", GetCodeDByte (PC+I));
|
Output ("$%04" PRIX16, GetCodeDByte (PC+I));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LineComment (PC, ByteCount);
|
LineComment (PC, ByteCount);
|
||||||
@@ -267,19 +268,19 @@ void DataDByteLine (unsigned ByteCount)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DataWordLine (unsigned ByteCount)
|
void DataWordLine (uint32_t ByteCount)
|
||||||
/* Output a line with words */
|
/* Output a line with words */
|
||||||
{
|
{
|
||||||
unsigned I;
|
uint32_t I;
|
||||||
|
|
||||||
Indent (MCol);
|
Indent (MCol);
|
||||||
Output (".word");
|
Output (".word");
|
||||||
Indent (ACol);
|
Indent (ACol);
|
||||||
for (I = 0; I < ByteCount; I += 2) {
|
for (I = 0; I < ByteCount; I += 2) {
|
||||||
if (I > 0) {
|
if (I > 0) {
|
||||||
Output (",$%04X", GetCodeWord (PC+I));
|
Output (",$%04" PRIX16, GetCodeWord (PC+I));
|
||||||
} else {
|
} else {
|
||||||
Output ("$%04X", GetCodeWord (PC+I));
|
Output ("$%04" PRIX16, GetCodeWord (PC+I));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LineComment (PC, ByteCount);
|
LineComment (PC, ByteCount);
|
||||||
@@ -288,19 +289,19 @@ void DataWordLine (unsigned ByteCount)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DataDWordLine (unsigned ByteCount)
|
void DataDWordLine (uint32_t ByteCount)
|
||||||
/* Output a line with dwords */
|
/* Output a line with dwords */
|
||||||
{
|
{
|
||||||
unsigned I;
|
uint32_t I;
|
||||||
|
|
||||||
Indent (MCol);
|
Indent (MCol);
|
||||||
Output (".dword");
|
Output (".dword");
|
||||||
Indent (ACol);
|
Indent (ACol);
|
||||||
for (I = 0; I < ByteCount; I += 4) {
|
for (I = 0; I < ByteCount; I += 4) {
|
||||||
if (I > 0) {
|
if (I > 0) {
|
||||||
Output (",$%08lX", GetCodeDWord (PC+I));
|
Output (",$%08" PRIX32, GetCodeDWord (PC+I));
|
||||||
} else {
|
} else {
|
||||||
Output ("$%08lX", GetCodeDWord (PC+I));
|
Output ("$%08" PRIX32, GetCodeDWord (PC+I));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LineComment (PC, ByteCount);
|
LineComment (PC, ByteCount);
|
||||||
@@ -372,12 +373,12 @@ void LineComment (unsigned PC, unsigned Count)
|
|||||||
Output ("; %04X", PC);
|
Output ("; %04X", PC);
|
||||||
if (Comments >= 3) {
|
if (Comments >= 3) {
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
Output (" %02X", CodeBuf [PC+I]);
|
Output (" %02" PRIX8, CodeBuf [PC+I]);
|
||||||
}
|
}
|
||||||
if (Comments >= 4) {
|
if (Comments >= 4) {
|
||||||
Indent (TCol);
|
Indent (TCol);
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
unsigned char C = CodeBuf [PC+I];
|
uint8_t C = CodeBuf [PC+I];
|
||||||
if (!isprint (C)) {
|
if (!isprint (C)) {
|
||||||
C = '.';
|
C = '.';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,22 +72,22 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs);
|
|||||||
** current PC.
|
** current PC.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void DefConst (const char* Name, const char* Comment, unsigned Addr);
|
void DefConst (const char* Name, const char* Comment, uint32_t Addr);
|
||||||
/* Define an address constant */
|
/* Define an address constant */
|
||||||
|
|
||||||
void OneDataByte (void);
|
void OneDataByte (void);
|
||||||
/* Output a .byte line with the current code byte */
|
/* Output a .byte line with the current code byte */
|
||||||
|
|
||||||
void DataByteLine (unsigned ByteCount);
|
void DataByteLine (uint32_t ByteCount);
|
||||||
/* Output a line with bytes */
|
/* Output a line with bytes */
|
||||||
|
|
||||||
void DataDByteLine (unsigned ByteCount);
|
void DataDByteLine (uint32_t ByteCount);
|
||||||
/* Output a line with dbytes */
|
/* Output a line with dbytes */
|
||||||
|
|
||||||
void DataWordLine (unsigned ByteCount);
|
void DataWordLine (uint32_t ByteCount);
|
||||||
/* Output a line with words */
|
/* Output a line with words */
|
||||||
|
|
||||||
void DataDWordLine (unsigned ByteCount);
|
void DataDWordLine (uint32_t ByteCount);
|
||||||
/* Output a line with dwords */
|
/* Output a line with dwords */
|
||||||
|
|
||||||
void SeparatorLine (void);
|
void SeparatorLine (void);
|
||||||
|
|||||||
@@ -600,11 +600,11 @@ void InfoAssureIdent (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InfoRangeCheck (long Lo, long Hi)
|
void InfoRangeCheck (const char* Attr, long Lo, long Hi)
|
||||||
/* Check the range of InfoIVal */
|
/* Check the range of InfoIVal */
|
||||||
{
|
{
|
||||||
if (InfoIVal < Lo || InfoIVal > Hi) {
|
if (InfoIVal < Lo || InfoIVal > Hi) {
|
||||||
InfoError ("Range error");
|
InfoError ("Range error for attribute %s", Attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ void InfoAssureChar (void);
|
|||||||
void InfoAssureIdent (void);
|
void InfoAssureIdent (void);
|
||||||
/* Make sure the next token is an identifier */
|
/* Make sure the next token is an identifier */
|
||||||
|
|
||||||
void InfoRangeCheck (long Lo, long Hi);
|
void InfoRangeCheck (const char* Attr, long Lo, long Hi);
|
||||||
/* Check the range of InfoIVal */
|
/* Check the range of InfoIVal */
|
||||||
|
|
||||||
void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name);
|
void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
typedef struct Segment Segment;
|
typedef struct Segment Segment;
|
||||||
struct Segment {
|
struct Segment {
|
||||||
Segment* NextStart; /* Pointer to next segment */
|
Segment* NextStart; /* Pointer to next segment */
|
||||||
unsigned long Start;
|
uint32_t Start;
|
||||||
unsigned AddrSize;
|
unsigned AddrSize;
|
||||||
char Name[1]; /* Name, dynamically allocated */
|
char Name[1]; /* Name, dynamically allocated */
|
||||||
};
|
};
|
||||||
@@ -76,7 +76,7 @@ static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
|
void AddAbsSegment (uint32_t Start, uint32_t End, const char* Name)
|
||||||
/* Add an absolute segment to the segment table */
|
/* Add an absolute segment to the segment table */
|
||||||
{
|
{
|
||||||
/* Get the length of the name */
|
/* Get the length of the name */
|
||||||
@@ -104,7 +104,7 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* GetSegmentStartName (unsigned Addr)
|
char* GetSegmentStartName (uint32_t Addr)
|
||||||
/* Return the name of the segment which starts at the given address */
|
/* Return the name of the segment which starts at the given address */
|
||||||
{
|
{
|
||||||
Segment* S = StartTab[Addr % HASH_SIZE];
|
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||||
@@ -122,7 +122,7 @@ char* GetSegmentStartName (unsigned Addr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetSegmentAddrSize (unsigned Addr)
|
unsigned GetSegmentAddrSize (uint32_t Addr)
|
||||||
/* Return the address size of the segment which starts at the given address */
|
/* Return the address size of the segment which starts at the given address */
|
||||||
{
|
{
|
||||||
Segment* S = StartTab[Addr % HASH_SIZE];
|
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||||
|
|||||||
@@ -44,13 +44,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
|
void AddAbsSegment (uint32_t Start, uint32_t End, const char* Name);
|
||||||
/* Add an absolute segment to the segment table */
|
/* Add an absolute segment to the segment table */
|
||||||
|
|
||||||
char* GetSegmentStartName (unsigned Addr);
|
char* GetSegmentStartName (uint32_t Addr);
|
||||||
/* Return the name of the segment which starts at the given address */
|
/* Return the name of the segment which starts at the given address */
|
||||||
|
|
||||||
unsigned GetSegmentAddrSize (unsigned Addr);
|
unsigned GetSegmentAddrSize (uint32_t Addr);
|
||||||
/* Return the address size of the segment which starts at the given address */
|
/* Return the address size of the segment which starts at the given address */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user