mirror of
https://github.com/cc65/cc65.git
synced 2024-12-25 02:29:52 +00:00
commit
cce119a9e7
@ -115,14 +115,14 @@ Here is a description of all the command line options:
|
||||
<item>6502dtv
|
||||
<item>65sc02
|
||||
<item>65c02
|
||||
<item>65816
|
||||
<item>huc6280
|
||||
<item>4510
|
||||
</itemize>
|
||||
|
||||
6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the
|
||||
emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine.
|
||||
4510 is the CPU of the Commodore C65. Support for the 65816 currently
|
||||
is not available.
|
||||
4510 is the CPU of the Commodore C65. 65816 is the CPU of the SNES.
|
||||
|
||||
|
||||
<label id="option--formfeeds">
|
||||
@ -263,8 +263,9 @@ can produce output that can not be re-assembled, when one or more of those
|
||||
branches point outside of the disassembled memory. This can happen when text
|
||||
or binary data is processed.
|
||||
|
||||
While there is some code for the 65816 in the sources, it is currently
|
||||
unsupported.
|
||||
The 65816 support requires annotating ranges with the M and X flag states.
|
||||
This can be recorded with an emulator that supports Code and Data Logging,
|
||||
for example. Disassemble one bank at a time.
|
||||
|
||||
|
||||
<sect1>Attribute map<p>
|
||||
@ -521,6 +522,11 @@ following attributes are recognized:
|
||||
|
||||
</descrip>
|
||||
|
||||
<tag><tt>ADDRMODE</tt></tag>
|
||||
When disassembling 65816 code, this specifies the M and X flag states
|
||||
for this range. It's a string argument of the form "mx", capital letters
|
||||
mean the flag is enabled.
|
||||
|
||||
</descrip>
|
||||
|
||||
|
||||
@ -693,6 +699,20 @@ directives explained above:
|
||||
|
||||
|
||||
|
||||
<sect>Helper scripts<p>
|
||||
|
||||
<tt>util/parse-bsnes-log.awk</tt> is a supplied script for 65816 disassembly,
|
||||
to parse bsnes-plus Code-Data log files and output the RANGE sections
|
||||
for your info file. For typical usage, you'd check the S-CPU log and trace
|
||||
log mask boxes in the bsnes-plus debugger, play through the game, then grep
|
||||
for the bank you're disassembling, and pass that to this script.
|
||||
|
||||
<tscreen><verb>
|
||||
grep ^83 my-game-log | parse-bsnes-log.awk
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
|
||||
<sect>Copyright<p>
|
||||
|
||||
da65 (and all cc65 binutils) is (C) Copyright 1998-2011, Ullrich von
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
|
||||
/* da65 */
|
||||
#include "cpu.h"
|
||||
#include "error.h"
|
||||
#include "attrtab.h"
|
||||
|
||||
@ -48,6 +49,12 @@
|
||||
/* Attribute table */
|
||||
static unsigned short AttrTab[0x10000];
|
||||
|
||||
/* 65816 attribute table */
|
||||
#define MAX_LONG_ATTRS 256
|
||||
static unsigned short LongAttrVal[MAX_LONG_ATTRS];
|
||||
static unsigned LongAttrAddr[MAX_LONG_ATTRS];
|
||||
static unsigned LongAttrsUsed;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -59,12 +66,19 @@ static unsigned short AttrTab[0x10000];
|
||||
void AddrCheck (unsigned Addr)
|
||||
/* Check if the given address has a valid range */
|
||||
{
|
||||
if (Addr >= 0x10000) {
|
||||
if (Addr >= 0x10000 && CPU != CPU_65816) {
|
||||
Error ("Address out of range: %08X", Addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned char IsLongAddr (unsigned Addr)
|
||||
/* Is it 24-bit? */
|
||||
{
|
||||
return Addr >= 0x10000 && CPU == CPU_65816;
|
||||
}
|
||||
|
||||
|
||||
|
||||
attr_t GetAttr (unsigned Addr)
|
||||
/* Return the attribute for the given address */
|
||||
@ -72,6 +86,17 @@ attr_t GetAttr (unsigned Addr)
|
||||
/* Check the given address */
|
||||
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 AttrTab[Addr];
|
||||
}
|
||||
@ -148,6 +173,33 @@ void MarkAddr (unsigned Addr, attr_t Attr)
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
if (IsLongAddr (Addr)) {
|
||||
unsigned i;
|
||||
for (i = 0; i < LongAttrsUsed; i++) {
|
||||
if (LongAttrAddr[i] == Addr) {
|
||||
|
||||
/* We must not have more than one style bit */
|
||||
if (Attr & atStyleMask) {
|
||||
if (LongAttrVal[i] & atStyleMask) {
|
||||
Error ("Duplicate style for long address %06X", 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) {
|
||||
@ -168,7 +220,7 @@ attr_t GetStyleAttr (unsigned Addr)
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return (AttrTab[Addr] & atStyleMask);
|
||||
return (GetAttr (Addr) & atStyleMask);
|
||||
}
|
||||
|
||||
|
||||
@ -180,5 +232,5 @@ attr_t GetLabelAttr (unsigned Addr)
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return (AttrTab[Addr] & atLabelMask);
|
||||
return (GetAttr (Addr) & atLabelMask);
|
||||
}
|
||||
|
@ -66,15 +66,22 @@ typedef enum attr_t {
|
||||
atDepLabel = 0x0040, /* Dependent label */
|
||||
atUnnamedLabel = 0x0080, /* Unnamed label */
|
||||
|
||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0, /* Label information */
|
||||
|
||||
/* Segment */
|
||||
atSegment = 0x0100, /* Code is in a segment */
|
||||
atSegmentEnd = 0x0200, /* Segment end */
|
||||
atSegmentStart = 0x0400, /* Segment start */
|
||||
|
||||
/* 65816 addressing mode */
|
||||
atMem8 = 0x1000, /* M flag enabled, 8-bit */
|
||||
atMem16 = 0x2000, /* M flag disabled, 16-bit */
|
||||
atIdx8 = 0x4000, /* X flag enabled, 8-bit */
|
||||
atIdx16 = 0x8000, /* X flag disabled, 16-bit */
|
||||
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0, /* Label information */
|
||||
atSegmentMask = 0x0F00, /* Segment information */
|
||||
at65816Mask = 0xF000, /* 65816 information */
|
||||
|
||||
} attr_t;
|
||||
|
||||
|
||||
@ -88,6 +95,9 @@ typedef enum attr_t {
|
||||
void AddrCheck (unsigned Addr);
|
||||
/* Check if the given address has a valid range */
|
||||
|
||||
unsigned char IsLongAddr (unsigned Addr);
|
||||
/* Check if the given address is 24-bit */
|
||||
|
||||
attr_t GetAttr (unsigned Addr);
|
||||
/* Return the attribute for the given address */
|
||||
|
||||
|
@ -194,6 +194,17 @@ unsigned long GetCodeDWord (unsigned Addr)
|
||||
|
||||
|
||||
|
||||
unsigned GetCodeLongAddr (unsigned Addr)
|
||||
/* Get a word from the given address */
|
||||
{
|
||||
unsigned Lo = GetCodeByte (Addr);
|
||||
unsigned Mid = GetCodeByte (Addr+1);
|
||||
unsigned Hi = GetCodeByte (Addr+2);
|
||||
return Lo | (Mid << 8) | (Hi << 16);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned GetRemainingBytes (void)
|
||||
/* Return the number of remaining code bytes */
|
||||
{
|
||||
|
@ -72,6 +72,9 @@ unsigned GetCodeWord (unsigned Addr);
|
||||
unsigned long GetCodeDWord (unsigned Addr);
|
||||
/* Get a dword from the given address */
|
||||
|
||||
unsigned GetCodeLongAddr (unsigned Addr);
|
||||
/* Get a 24-bit address from the given address */
|
||||
|
||||
unsigned GetRemainingBytes (void);
|
||||
/* Return the number of remaining code bytes */
|
||||
|
||||
|
@ -52,6 +52,11 @@
|
||||
/* Comment table */
|
||||
static const char* CommentTab[0x10000];
|
||||
|
||||
#define MAX_LONG_COMMENTS 256
|
||||
static const char* LongCommentVal[MAX_LONG_COMMENTS];
|
||||
static unsigned LongCommentAddr[MAX_LONG_COMMENTS];
|
||||
static unsigned LongCommentsUsed;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -60,17 +65,43 @@ static const char* CommentTab[0x10000];
|
||||
|
||||
|
||||
|
||||
static unsigned FindLongIndex (unsigned Addr)
|
||||
{
|
||||
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 */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* If we do already have a comment, warn and ignore the new one */
|
||||
if (CommentTab[Addr]) {
|
||||
Warning ("Duplicate comment for address $%04X", 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 {
|
||||
CommentTab[Addr] = xstrdup (Comment);
|
||||
/* If we do already have a comment, warn and ignore the new one */
|
||||
if (CommentTab[Addr]) {
|
||||
Warning ("Duplicate comment for address $%04X", Addr);
|
||||
} else {
|
||||
CommentTab[Addr] = xstrdup (Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +113,14 @@ const char* GetComment (unsigned Addr)
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
if (IsLongAddr (Addr)) {
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
if (i < LongCommentsUsed) {
|
||||
return LongCommentVal[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the label if any */
|
||||
return CommentTab[Addr];
|
||||
}
|
||||
|
@ -99,7 +99,9 @@ static const char* GetAbsOverride (unsigned Flags, unsigned Addr)
|
||||
** string, otherwise return the empty string.
|
||||
*/
|
||||
{
|
||||
if ((Flags & flAbsOverride) != 0 && Addr < 0x100) {
|
||||
if ((Flags & flFarOverride) != 0 && Addr < 0x10000) {
|
||||
return "f:";
|
||||
} else if ((Flags & flAbsOverride) != 0 && Addr < 0x100) {
|
||||
return "a:";
|
||||
} else {
|
||||
return "";
|
||||
@ -121,8 +123,10 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr)
|
||||
static char Buf [32];
|
||||
if (Addr < 0x100) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
|
||||
} else {
|
||||
} else if (Addr < 0x10000) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
|
||||
} else {
|
||||
xsprintf (Buf, sizeof (Buf), "$%06X", Addr);
|
||||
}
|
||||
return Buf;
|
||||
}
|
||||
@ -229,6 +233,28 @@ void OH_Immediate (const OpcDesc* D)
|
||||
|
||||
|
||||
|
||||
void OH_Immediate65816M (const OpcDesc* D)
|
||||
{
|
||||
if (GetAttr (PC) & atMem16) {
|
||||
OneLine (D, "#$%04X", GetCodeWord (PC+1));
|
||||
} else {
|
||||
OneLine (D, "#$%02X", GetCodeByte (PC+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OH_Immediate65816X (const OpcDesc* D)
|
||||
{
|
||||
if (GetAttr (PC) & atIdx16) {
|
||||
OneLine (D, "#$%04X", GetCodeWord (PC+1));
|
||||
} else {
|
||||
OneLine (D, "#$%02X", GetCodeByte (PC+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OH_ImmediateWord (const OpcDesc* D)
|
||||
{
|
||||
OneLine (D, "#$%04X", GetCodeWord (PC+1));
|
||||
@ -322,14 +348,28 @@ void OH_AbsoluteY (const OpcDesc* D)
|
||||
|
||||
void OH_AbsoluteLong (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeLongAddr (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D->Flags, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D, "%s%s", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeLongAddr (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D->Flags, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D, "%s%s,x", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
|
||||
}
|
||||
|
||||
|
||||
@ -358,7 +398,17 @@ void OH_Relative (const OpcDesc* D)
|
||||
|
||||
void OH_RelativeLong (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
/* Get the operand */
|
||||
signed short Offs = GetCodeWord (PC+1);
|
||||
|
||||
/* Calculate the target address */
|
||||
unsigned Addr = (((int) PC+3) + Offs) & 0xFFFF;
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D->Flags, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
|
||||
}
|
||||
|
||||
|
||||
@ -541,14 +591,15 @@ void OH_ImmediateAbsoluteX (const OpcDesc* D)
|
||||
|
||||
void OH_StackRelative (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
/* Output the line */
|
||||
OneLine (D, "$%02X,s", GetCodeByte (PC+1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OH_DirectIndirectLongX (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
Error ("Not implemented %s", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
@ -571,14 +622,28 @@ void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused)))
|
||||
|
||||
void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D->Flags, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D, "[%s]", GetAddrArg (D->Flags, Addr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
Error ("Not implemented");
|
||||
/* Get the operand */
|
||||
unsigned Addr = GetCodeByte (PC+1);
|
||||
|
||||
/* Generate a label in pass 1 */
|
||||
GenerateLabel (D->Flags, Addr);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D, "[%s],y", GetAddrArg (D->Flags, Addr));
|
||||
}
|
||||
|
||||
|
||||
@ -613,6 +678,19 @@ void OH_BlockMove (const OpcDesc* D)
|
||||
|
||||
|
||||
|
||||
void OH_BlockMove65816 (const OpcDesc* D)
|
||||
{
|
||||
/* Get source operand */
|
||||
unsigned Src = GetCodeByte (PC+2);
|
||||
/* Get destination operand */
|
||||
unsigned Dst = GetCodeByte (PC+1);
|
||||
|
||||
/* Output the line */
|
||||
OneLine (D, "#$%02X, #$%02X", Src, Dst);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
|
||||
{
|
||||
/* Get the operand */
|
||||
|
@ -57,6 +57,8 @@ void OH_Illegal (const OpcDesc* D attribute ((unused)));
|
||||
void OH_Accumulator (const OpcDesc*);
|
||||
void OH_Implicit (const OpcDesc*);
|
||||
void OH_Immediate (const OpcDesc*);
|
||||
void OH_Immediate65816M (const OpcDesc*);
|
||||
void OH_Immediate65816X (const OpcDesc*);
|
||||
void OH_ImmediateWord (const OpcDesc*);
|
||||
void OH_Direct (const OpcDesc*);
|
||||
void OH_DirectX (const OpcDesc*);
|
||||
@ -89,6 +91,7 @@ void OH_StackRelativeIndirectY4510 (const OpcDesc*);
|
||||
void OH_DirectIndirectLong (const OpcDesc*);
|
||||
void OH_DirectIndirectLongY (const OpcDesc*);
|
||||
void OH_BlockMove (const OpcDesc*);
|
||||
void OH_BlockMove65816 (const OpcDesc*);
|
||||
void OH_AbsoluteXIndirect (const OpcDesc*);
|
||||
|
||||
/* Mitsubishi 740 */
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#if defined(_MSC_VER)
|
||||
/* Microsoft compiler */
|
||||
@ -521,11 +522,12 @@ static void RangeSection (void)
|
||||
/* Parse a range section */
|
||||
{
|
||||
static const IdentTok RangeDefs[] = {
|
||||
{ "COMMENT", INFOTOK_COMMENT },
|
||||
{ "END", INFOTOK_END },
|
||||
{ "NAME", INFOTOK_NAME },
|
||||
{ "START", INFOTOK_START },
|
||||
{ "TYPE", INFOTOK_TYPE },
|
||||
{ "COMMENT", INFOTOK_COMMENT },
|
||||
{ "END", INFOTOK_END },
|
||||
{ "NAME", INFOTOK_NAME },
|
||||
{ "START", INFOTOK_START },
|
||||
{ "TYPE", INFOTOK_TYPE },
|
||||
{ "ADDRMODE", INFOTOK_ADDRMODE },
|
||||
};
|
||||
|
||||
static const IdentTok TypeDefs[] = {
|
||||
@ -543,12 +545,13 @@ static void RangeSection (void)
|
||||
|
||||
/* Which values did we get? */
|
||||
enum {
|
||||
tNone = 0x00,
|
||||
tStart = 0x01,
|
||||
tEnd = 0x02,
|
||||
tType = 0x04,
|
||||
tName = 0x08,
|
||||
tComment= 0x10,
|
||||
tNone = 0x00,
|
||||
tStart = 0x01,
|
||||
tEnd = 0x02,
|
||||
tType = 0x04,
|
||||
tName = 0x08,
|
||||
tComment = 0x10,
|
||||
tAddrMode = 0x20,
|
||||
tNeeded = (tStart | tEnd | tType)
|
||||
};
|
||||
unsigned Attributes = tNone;
|
||||
@ -557,6 +560,7 @@ static void RangeSection (void)
|
||||
unsigned Start = 0;
|
||||
unsigned End = 0;
|
||||
unsigned char Type = 0;
|
||||
unsigned AddrMode = 0;
|
||||
char* Name = 0;
|
||||
char* Comment = 0;
|
||||
unsigned MemberSize = 0;
|
||||
@ -647,6 +651,37 @@ static void RangeSection (void)
|
||||
InfoNextTok ();
|
||||
break;
|
||||
|
||||
case INFOTOK_ADDRMODE:
|
||||
AddAttr ("ADDRMODE", &Attributes, tAddrMode);
|
||||
InfoNextTok ();
|
||||
InfoAssureStr ();
|
||||
if (InfoSVal[0] == '\0') {
|
||||
InfoError ("AddrMode may not be empty");
|
||||
}
|
||||
if (InfoSVal[1] == '\0') {
|
||||
InfoError ("AddrMode must be two characters long");
|
||||
}
|
||||
if (tolower(InfoSVal[0]) == 'm') {
|
||||
if (InfoSVal[0] == 'm') {
|
||||
AddrMode = atMem16;
|
||||
} else {
|
||||
AddrMode = atMem8;
|
||||
}
|
||||
} else {
|
||||
InfoError ("AddrMode syntax: mx");
|
||||
}
|
||||
if (tolower(InfoSVal[1]) == 'x') {
|
||||
if (InfoSVal[1] == 'x') {
|
||||
AddrMode |= atIdx16;
|
||||
} else {
|
||||
AddrMode |= atIdx8;
|
||||
}
|
||||
} else {
|
||||
InfoError ("AddrMode syntax: mx");
|
||||
}
|
||||
InfoNextTok ();
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Unexpected token: %u", InfoTok);
|
||||
}
|
||||
@ -661,6 +696,15 @@ static void RangeSection (void)
|
||||
InfoError ("Required values missing from this section");
|
||||
}
|
||||
|
||||
if (CPU == CPU_65816) {
|
||||
if (Type == atCode && !(Attributes & tAddrMode)) {
|
||||
InfoError ("65816 code sections require addressing mode");
|
||||
}
|
||||
if (Type != atCode && (Attributes & tAddrMode)) {
|
||||
InfoError ("AddrMode is only valid for code sections");
|
||||
}
|
||||
}
|
||||
|
||||
/* Start must be less than end */
|
||||
if (Start > End) {
|
||||
InfoError ("Start value must not be greater than end value");
|
||||
@ -672,7 +716,7 @@ static void RangeSection (void)
|
||||
}
|
||||
|
||||
/* Set the range */
|
||||
MarkRange (Start, End, Type);
|
||||
MarkRange (Start, End, Type | AddrMode);
|
||||
|
||||
/* Do we have a label? */
|
||||
if (Attributes & tName) {
|
||||
|
@ -60,6 +60,12 @@
|
||||
/* Symbol table */
|
||||
static const char* SymTab[0x10000];
|
||||
|
||||
/* 65816 symbol table */
|
||||
#define MAX_LONG_LABELS 256
|
||||
static const char* LongSymVal[MAX_LONG_LABELS];
|
||||
static unsigned LongSymAddr[MAX_LONG_LABELS];
|
||||
static unsigned LongLabelsUsed;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -74,12 +80,27 @@ static const char* MakeLabelName (unsigned Addr)
|
||||
*/
|
||||
{
|
||||
static char LabelBuf [32];
|
||||
xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
|
||||
xsprintf (LabelBuf, sizeof (LabelBuf),
|
||||
IsLongAddr (Addr) ? "L%06X" : "L%04X", Addr);
|
||||
return LabelBuf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned FindLongIndex (unsigned Addr)
|
||||
{
|
||||
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 */
|
||||
{
|
||||
@ -91,19 +112,41 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
|
||||
/* Allow redefinition if identical. Beware: Unnamed labels don't
|
||||
** have a name (you guessed that, didn't you?).
|
||||
*/
|
||||
if (ExistingAttr == Attr &&
|
||||
((Name == 0 && SymTab[Addr] == 0) ||
|
||||
(Name != 0 && SymTab[Addr] != 0 &&
|
||||
strcmp (SymTab[Addr], Name) == 0))) {
|
||||
return;
|
||||
if (IsLongAddr (Addr)) {
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
if (ExistingAttr == Attr &&
|
||||
((Name == 0 && LongSymVal[i] == 0) ||
|
||||
(Name != 0 && LongSymVal[i] != 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;
|
||||
}
|
||||
Error ("Duplicate label for address $%04X (%s): '%s'", Addr,
|
||||
SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr],
|
||||
Name == 0 ? "<unnamed label>" : Name);
|
||||
}
|
||||
Error ("Duplicate label for address $%04X (%s): '%s'", Addr,
|
||||
SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr],
|
||||
Name == 0 ? "<unnamed label>" : Name);
|
||||
}
|
||||
|
||||
/* Create a new label (xstrdup will return NULL if input NULL) */
|
||||
SymTab[Addr] = xstrdup (Name);
|
||||
if (IsLongAddr (Addr)) {
|
||||
if (LongLabelsUsed >= MAX_LONG_LABELS) {
|
||||
Error ("Too many long labels");
|
||||
}
|
||||
LongSymAddr[LongLabelsUsed] = Addr;
|
||||
LongSymVal[LongLabelsUsed] = xstrdup (Name);
|
||||
LongLabelsUsed++;
|
||||
} else {
|
||||
SymTab[Addr] = xstrdup (Name);
|
||||
}
|
||||
|
||||
/* Remember the attribute */
|
||||
MarkAddr (Addr, Attr);
|
||||
@ -254,6 +297,10 @@ const char* GetLabelName (unsigned Addr)
|
||||
*/
|
||||
if (A == atUnnamedLabel) {
|
||||
return "";
|
||||
} else if (IsLongAddr (Addr)) {
|
||||
/* Return the label if any */
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
return i < LongLabelsUsed ? LongSymVal[i] : NULL;
|
||||
} else {
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr];
|
||||
@ -327,6 +374,10 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom)
|
||||
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 {
|
||||
/* Return the label if any */
|
||||
return SymTab[Addr];
|
||||
@ -371,7 +422,13 @@ static void DefOutOfRangeLabel (unsigned long Addr)
|
||||
|
||||
case atIntLabel:
|
||||
case atExtLabel:
|
||||
DefConst (SymTab[Addr], GetComment (Addr), Addr);
|
||||
if (IsLongAddr (Addr)) {
|
||||
const unsigned i = FindLongIndex (Addr);
|
||||
DefConst (i < LongLabelsUsed ? LongSymVal[i] : NULL,
|
||||
GetComment (Addr), Addr);
|
||||
} else {
|
||||
DefConst (SymTab[Addr], GetComment (Addr), Addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case atUnnamedLabel:
|
||||
@ -390,6 +447,7 @@ void DefOutOfRangeLabels (void)
|
||||
/* Output any labels that are out of the loaded code range */
|
||||
{
|
||||
unsigned long Addr;
|
||||
unsigned i;
|
||||
|
||||
SeparatorLine ();
|
||||
|
||||
@ -412,5 +470,10 @@ void DefOutOfRangeLabels (void)
|
||||
DefOutOfRangeLabel (Addr++);
|
||||
}
|
||||
|
||||
/* 65816 long range */
|
||||
for (i = 0; i < LongLabelsUsed; i++) {
|
||||
DefOutOfRangeLabel (LongSymAddr[i]);
|
||||
}
|
||||
|
||||
SeparatorLine ();
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "data.h"
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "handler.h"
|
||||
#include "infofile.h"
|
||||
#include "labels.h"
|
||||
#include "opctable.h"
|
||||
@ -63,6 +64,8 @@
|
||||
#include "segment.h"
|
||||
|
||||
|
||||
static unsigned PrevAddrMode;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
@ -427,8 +430,13 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
switch (Style) {
|
||||
|
||||
case atDefault:
|
||||
D->Handler (D);
|
||||
PC += D->Size;
|
||||
if (CPU == CPU_65816) {
|
||||
DataByteLine (1);
|
||||
++PC;
|
||||
} else {
|
||||
D->Handler (D);
|
||||
PC += D->Size;
|
||||
}
|
||||
break;
|
||||
|
||||
case atCode:
|
||||
@ -436,12 +444,36 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
** following insn, fall through to byte mode.
|
||||
*/
|
||||
if (D->Size <= RemainingBytes) {
|
||||
if (CPU == CPU_65816) {
|
||||
const unsigned AddrMode = GetAttr (PC) & at65816Mask;
|
||||
if (PrevAddrMode != AddrMode) {
|
||||
if ((PrevAddrMode & atMem8) != (AddrMode & atMem8) ||
|
||||
(PrevAddrMode & atMem16) != (AddrMode & atMem16)) {
|
||||
OutputMFlag(!!(AddrMode & atMem8));
|
||||
}
|
||||
if ((PrevAddrMode & atIdx8) != (AddrMode & atIdx8) ||
|
||||
(PrevAddrMode & atIdx16) != (AddrMode & atIdx16)) {
|
||||
OutputXFlag(!!(AddrMode & atIdx8));
|
||||
}
|
||||
|
||||
PrevAddrMode = AddrMode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output labels within the next insn */
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
ForwardLabel (I);
|
||||
}
|
||||
/* Output the insn */
|
||||
D->Handler (D);
|
||||
if (CPU == CPU_65816 && (D->Flags & flSizeChanges)) {
|
||||
if ((D->Handler == OH_Immediate65816M &&
|
||||
GetAttr (PC) & atMem16) ||
|
||||
(D->Handler == OH_Immediate65816X &&
|
||||
GetAttr (PC) & atIdx16)) {
|
||||
PC++;
|
||||
}
|
||||
}
|
||||
PC += D->Size;
|
||||
break;
|
||||
}
|
||||
@ -503,6 +535,8 @@ static void OnePass (void)
|
||||
{
|
||||
unsigned Count;
|
||||
|
||||
PrevAddrMode = 0;
|
||||
|
||||
/* Disassemble until nothing left */
|
||||
while ((Count = GetRemainingBytes()) > 0) {
|
||||
OneOpcode (Count);
|
||||
|
@ -56,13 +56,13 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "asl", 2, flUseLabel, OH_Direct }, /* $06 */
|
||||
{ "ora", 2, flUseLabel, OH_DirectIndirectLong }, /* $07 */
|
||||
{ "php", 1, flNone, OH_Implicit }, /* $08 */
|
||||
{ "ora", 2, flNone, OH_Immediate }, /* $09 */
|
||||
{ "ora", 2, flSizeChanges, OH_Immediate65816M }, /* $09 */
|
||||
{ "asl", 1, flNone, OH_Accumulator }, /* $0a */
|
||||
{ "phd", 1, flNone, OH_Implicit }, /* $0b */
|
||||
{ "tsb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */
|
||||
{ "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */
|
||||
{ "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */
|
||||
{ "ora", 4, flUseLabel, OH_AbsoluteLong }, /* $0f */
|
||||
{ "ora", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $0f */
|
||||
{ "bpl", 2, flLabel, OH_Relative }, /* $10 */
|
||||
{ "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */
|
||||
{ "ora", 2, flUseLabel, OH_DirectIndirect }, /* $12 */
|
||||
@ -78,23 +78,23 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "trb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $1c */
|
||||
{ "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */
|
||||
{ "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */
|
||||
{ "ora", 4, flUseLabel, OH_AbsoluteLongX }, /* $1f */
|
||||
{ "ora", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $1f */
|
||||
{ "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */
|
||||
{ "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */
|
||||
{ "jsl", 3, flLabel, OH_AbsoluteLong }, /* $22 */
|
||||
{ "jsl", 4, flLabel|flFarOverride, OH_AbsoluteLong }, /* $22 */
|
||||
{ "and", 2, flNone, OH_StackRelative }, /* $23 */
|
||||
{ "bit", 2, flUseLabel, OH_Direct }, /* $24 */
|
||||
{ "and", 2, flUseLabel, OH_Direct }, /* $25 */
|
||||
{ "rol", 2, flUseLabel, OH_Direct }, /* $26 */
|
||||
{ "and", 2, flUseLabel, OH_DirectIndirectLong }, /* $27 */
|
||||
{ "plp", 1, flNone, OH_Implicit }, /* $28 */
|
||||
{ "and", 2, flNone, OH_Immediate }, /* $29 */
|
||||
{ "and", 2, flSizeChanges, OH_Immediate65816M }, /* $29 */
|
||||
{ "rol", 1, flNone, OH_Accumulator }, /* $2a */
|
||||
{ "pld", 1, flNone, OH_Implicit }, /* $2b */
|
||||
{ "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */
|
||||
{ "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */
|
||||
{ "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */
|
||||
{ "and", 4, flUseLabel, OH_AbsoluteLong }, /* $2f */
|
||||
{ "and", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $2f */
|
||||
{ "bmi", 2, flLabel, OH_Relative }, /* $30 */
|
||||
{ "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */
|
||||
{ "and", 2, flUseLabel, OH_DirectIndirect }, /* $32 */
|
||||
@ -110,28 +110,28 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "bit", 3, flUseLabel, OH_AbsoluteX }, /* $3c */
|
||||
{ "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */
|
||||
{ "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */
|
||||
{ "and", 4, flUseLabel, OH_AbsoluteLongX }, /* $3f */
|
||||
{ "and", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $3f */
|
||||
{ "rti", 1, flNone, OH_Rts }, /* $40 */
|
||||
{ "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */
|
||||
{ "wdm", 2, flNone, OH_Implicit }, /* $42 */
|
||||
{ "eor", 2, flNone, OH_StackRelative }, /* $43 */
|
||||
{ "mvp", 3, flNone, OH_BlockMove }, /* $44 */
|
||||
{ "mvp", 3, flNone, OH_BlockMove65816 }, /* $44 */
|
||||
{ "eor", 2, flUseLabel, OH_Direct }, /* $45 */
|
||||
{ "lsr", 2, flUseLabel, OH_Direct }, /* $46 */
|
||||
{ "eor", 2, flUseLabel, OH_DirectIndirectLong }, /* $47 */
|
||||
{ "pha", 1, flNone, OH_Implicit }, /* $48 */
|
||||
{ "eor", 2, flNone, OH_Immediate }, /* $49 */
|
||||
{ "eor", 2, flSizeChanges, OH_Immediate65816M }, /* $49 */
|
||||
{ "lsr", 1, flNone, OH_Accumulator }, /* $4a */
|
||||
{ "phk", 1, flNone, OH_Implicit }, /* $4b */
|
||||
{ "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */
|
||||
{ "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */
|
||||
{ "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */
|
||||
{ "eor", 4, flUseLabel, OH_AbsoluteLong }, /* $4f */
|
||||
{ "eor", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $4f */
|
||||
{ "bvc", 2, flLabel, OH_Relative }, /* $50 */
|
||||
{ "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */
|
||||
{ "eor", 2, flUseLabel, OH_DirectIndirect }, /* $52 */
|
||||
{ "eor", 2, flNone, OH_StackRelativeIndirectY}, /* $53 */
|
||||
{ "mvn", 3, flNone, OH_BlockMove }, /* $54 */
|
||||
{ "mvn", 3, flNone, OH_BlockMove65816 }, /* $54 */
|
||||
{ "eor", 2, flUseLabel, OH_DirectX }, /* $55 */
|
||||
{ "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */
|
||||
{ "eor", 2, flUseLabel, OH_DirectIndirectLongY }, /* $57 */
|
||||
@ -139,10 +139,10 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */
|
||||
{ "phy", 1, flNone, OH_Implicit }, /* $5a */
|
||||
{ "tcd", 1, flNone, OH_Implicit }, /* $5b */
|
||||
{ "jml", 4, flLabel, OH_AbsoluteLong }, /* $5c */
|
||||
{ "jml", 4, flLabel|flFarOverride, OH_AbsoluteLong }, /* $5c */
|
||||
{ "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */
|
||||
{ "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */
|
||||
{ "eor", 4, flUseLabel, OH_AbsoluteLongX }, /* $5f */
|
||||
{ "eor", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $5f */
|
||||
{ "rts", 1, flNone, OH_Rts }, /* $60 */
|
||||
{ "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */
|
||||
{ "per", 3, flLabel, OH_RelativeLong }, /* $62 */
|
||||
@ -152,13 +152,13 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "ror", 2, flUseLabel, OH_Direct }, /* $66 */
|
||||
{ "adc", 2, flUseLabel, OH_DirectIndirectLong }, /* $67 */
|
||||
{ "pla", 1, flNone, OH_Implicit }, /* $68 */
|
||||
{ "adc", 2, flNone, OH_Immediate }, /* $69 */
|
||||
{ "adc", 2, flSizeChanges, OH_Immediate65816M }, /* $69 */
|
||||
{ "ror", 1, flNone, OH_Accumulator }, /* $6a */
|
||||
{ "rtl", 1, flNone, OH_Implicit }, /* $6b */
|
||||
{ "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */
|
||||
{ "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */
|
||||
{ "ror", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6e */
|
||||
{ "adc", 4, flUseLabel, OH_AbsoluteLong }, /* $6f */
|
||||
{ "adc", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $6f */
|
||||
{ "bvs", 2, flLabel, OH_Relative }, /* $70 */
|
||||
{ "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */
|
||||
{ "adc", 2, flUseLabel, OH_DirectIndirect }, /* $72 */
|
||||
@ -174,7 +174,7 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "jmp", 3, flLabel, OH_AbsoluteXIndirect }, /* $7c */
|
||||
{ "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */
|
||||
{ "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */
|
||||
{ "adc", 4, flUseLabel, OH_AbsoluteLongX }, /* $7f */
|
||||
{ "adc", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $7f */
|
||||
{ "bra", 2, flLabel, OH_Relative }, /* $80 */
|
||||
{ "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */
|
||||
{ "brl", 3, flLabel, OH_RelativeLong }, /* $82 */
|
||||
@ -184,13 +184,13 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "stx", 2, flUseLabel, OH_Direct }, /* $86 */
|
||||
{ "sta", 2, flUseLabel, OH_DirectIndirectLong }, /* $87 */
|
||||
{ "dey", 1, flNone, OH_Implicit }, /* $88 */
|
||||
{ "bit", 2, flNone, OH_Immediate }, /* $89 */
|
||||
{ "bit", 2, flSizeChanges, OH_Immediate65816M }, /* $89 */
|
||||
{ "txa", 1, flNone, OH_Implicit }, /* $8a */
|
||||
{ "phb", 1, flNone, OH_Implicit }, /* $8b */
|
||||
{ "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */
|
||||
{ "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */
|
||||
{ "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */
|
||||
{ "sta", 4, flUseLabel, OH_AbsoluteLong }, /* $8f */
|
||||
{ "sta", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $8f */
|
||||
{ "bcc", 2, flLabel, OH_Relative }, /* $90 */
|
||||
{ "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */
|
||||
{ "sta", 2, flUseLabel, OH_DirectIndirect }, /* $92 */
|
||||
@ -206,23 +206,23 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "stz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $9c */
|
||||
{ "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */
|
||||
{ "stz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9e */
|
||||
{ "sta", 4, flUseLabel, OH_AbsoluteLongX }, /* $9f */
|
||||
{ "ldy", 2, flNone, OH_Immediate }, /* $a0 */
|
||||
{ "sta", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $9f */
|
||||
{ "ldy", 2, flSizeChanges, OH_Immediate65816X }, /* $a0 */
|
||||
{ "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */
|
||||
{ "ldx", 2, flNone, OH_Immediate }, /* $a2 */
|
||||
{ "ldx", 2, flSizeChanges, OH_Immediate65816X }, /* $a2 */
|
||||
{ "lda", 2, flNone, OH_StackRelative }, /* $a3 */
|
||||
{ "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */
|
||||
{ "lda", 2, flUseLabel, OH_Direct }, /* $a5 */
|
||||
{ "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */
|
||||
{ "lda", 2, flUseLabel, OH_DirectIndirectLong }, /* $a7 */
|
||||
{ "tay", 1, flNone, OH_Implicit }, /* $a8 */
|
||||
{ "lda", 2, flNone, OH_Immediate }, /* $a9 */
|
||||
{ "lda", 2, flSizeChanges, OH_Immediate65816M }, /* $a9 */
|
||||
{ "tax", 1, flNone, OH_Implicit }, /* $aa */
|
||||
{ "plb", 1, flNone, OH_Implicit }, /* $ab */
|
||||
{ "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */
|
||||
{ "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */
|
||||
{ "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */
|
||||
{ "lda", 4, flUseLabel, OH_AbsoluteLong }, /* $af */
|
||||
{ "lda", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $af */
|
||||
{ "bcs", 2, flLabel, OH_Relative }, /* $b0 */
|
||||
{ "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */
|
||||
{ "lda", 2, flUseLabel, OH_DirectIndirect }, /* $b2 */
|
||||
@ -238,8 +238,8 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */
|
||||
{ "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */
|
||||
{ "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */
|
||||
{ "lda", 4, flUseLabel, OH_AbsoluteLongX }, /* $bf */
|
||||
{ "cpy", 2, flNone, OH_Immediate }, /* $c0 */
|
||||
{ "lda", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $bf */
|
||||
{ "cpy", 2, flSizeChanges, OH_Immediate65816X }, /* $c0 */
|
||||
{ "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */
|
||||
{ "rep", 2, flNone, OH_Immediate }, /* $c2 */
|
||||
{ "cmp", 2, flNone, OH_StackRelative }, /* $c3 */
|
||||
@ -248,18 +248,18 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "dec", 2, flUseLabel, OH_Direct }, /* $c6 */
|
||||
{ "cmp", 2, flUseLabel, OH_DirectIndirectLong }, /* $c7 */
|
||||
{ "iny", 1, flNone, OH_Implicit }, /* $c8 */
|
||||
{ "cmp", 2, flNone, OH_Immediate }, /* $c9 */
|
||||
{ "cmp", 2, flSizeChanges, OH_Immediate65816M }, /* $c9 */
|
||||
{ "dex", 1, flNone, OH_Implicit }, /* $ca */
|
||||
{ "wai", 1, flNone, OH_Implicit }, /* $cb */
|
||||
{ "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */
|
||||
{ "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */
|
||||
{ "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */
|
||||
{ "cmp", 4, flUseLabel, OH_AbsoluteLong }, /* $cf */
|
||||
{ "cmp", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $cf */
|
||||
{ "bne", 2, flLabel, OH_Relative }, /* $d0 */
|
||||
{ "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */
|
||||
{ "cmp", 2, flUseLabel, OH_DirectIndirect }, /* $d2 */
|
||||
{ "cmp", 2, flNone, OH_StackRelativeIndirectY}, /* $d3 */
|
||||
{ "pei", 2, flUseLabel, OH_Direct }, /* $d4 */
|
||||
{ "pei", 2, flUseLabel, OH_DirectIndirect }, /* $d4 */
|
||||
{ "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */
|
||||
{ "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */
|
||||
{ "cmp", 2, flUseLabel, OH_DirectIndirectLongY }, /* $d7 */
|
||||
@ -270,8 +270,8 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "jml", 3, flLabel, OH_AbsoluteIndirect }, /* $dc */
|
||||
{ "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */
|
||||
{ "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */
|
||||
{ "cmp", 4, flUseLabel, OH_AbsoluteLongX }, /* $df */
|
||||
{ "cpx", 2, flNone, OH_Immediate }, /* $e0 */
|
||||
{ "cmp", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $df */
|
||||
{ "cpx", 2, flSizeChanges, OH_Immediate65816X }, /* $e0 */
|
||||
{ "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */
|
||||
{ "sep", 2, flNone, OH_Immediate }, /* $e2 */
|
||||
{ "sbc", 2, flNone, OH_StackRelative }, /* $e3 */
|
||||
@ -280,13 +280,13 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "inc", 2, flUseLabel, OH_Direct }, /* $e6 */
|
||||
{ "sbc", 2, flUseLabel, OH_DirectIndirectLong }, /* $e7 */
|
||||
{ "inx", 1, flNone, OH_Implicit }, /* $e8 */
|
||||
{ "sbc", 2, flNone, OH_Immediate }, /* $e9 */
|
||||
{ "sbc", 2, flSizeChanges, OH_Immediate65816M }, /* $e9 */
|
||||
{ "nop", 1, flNone, OH_Implicit }, /* $ea */
|
||||
{ "xba", 1, flNone, OH_Implicit }, /* $eb */
|
||||
{ "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */
|
||||
{ "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */
|
||||
{ "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */
|
||||
{ "sbc", 4, flUseLabel, OH_AbsoluteLong }, /* $ef */
|
||||
{ "sbc", 4, flUseLabel|flFarOverride, OH_AbsoluteLong }, /* $ef */
|
||||
{ "beq", 2, flLabel, OH_Relative }, /* $f0 */
|
||||
{ "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */
|
||||
{ "sbc", 2, flUseLabel, OH_DirectIndirect }, /* $f2 */
|
||||
@ -302,5 +302,5 @@ const OpcDesc OpcTable_65816[256] = {
|
||||
{ "jsr", 3, flLabel, OH_AbsoluteXIndirect }, /* $fc */
|
||||
{ "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */
|
||||
{ "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */
|
||||
{ "sbc", 4, flUseLabel, OH_AbsoluteLongX }, /* $ff */
|
||||
{ "sbc", 4, flUseLabel|flFarOverride, OH_AbsoluteLongX }, /* $ff */
|
||||
};
|
||||
|
@ -53,7 +53,8 @@ enum {
|
||||
flLabel = flUseLabel|flGenLabel, /* Generate and use a label */
|
||||
flIllegal = 0x10, /* Illegal instruction */
|
||||
flAbsOverride = 0x20, /* Need a: override */
|
||||
flFarOverride = 0x40 /* Need f: override */
|
||||
flFarOverride = 0x40, /* Need f: override */
|
||||
flSizeChanges = 0x80 /* 65816: size may change */
|
||||
};
|
||||
|
||||
/* Forward/typedef for struct OpcDesc */
|
||||
|
@ -74,6 +74,7 @@ void SetOpcTable (cpu_t CPU)
|
||||
case CPU_6502DTV: OpcTable = OpcTable_6502DTV; break;
|
||||
case CPU_65SC02: OpcTable = OpcTable_65SC02; break;
|
||||
case CPU_65C02: OpcTable = OpcTable_65C02; break;
|
||||
case CPU_65816: OpcTable = OpcTable_65816; break;
|
||||
case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break;
|
||||
case CPU_M740: OpcTable = OpcTable_M740; break;
|
||||
case CPU_4510: OpcTable = OpcTable_4510; break;
|
||||
|
@ -401,3 +401,23 @@ void OutputSettings (void)
|
||||
LineFeed ();
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OutputMFlag (unsigned char enabled)
|
||||
/* Output the 65816 M-flag state */
|
||||
{
|
||||
Indent (MCol);
|
||||
Output (enabled ? ".a8" : ".a16");
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OutputXFlag (unsigned char enabled)
|
||||
/* Output the 65816 X-flag state */
|
||||
{
|
||||
Indent (MCol);
|
||||
Output (enabled ? ".i8" : ".i16");
|
||||
LineFeed ();
|
||||
}
|
||||
|
@ -108,6 +108,12 @@ void LineComment (unsigned PC, unsigned Count);
|
||||
void OutputSettings (void);
|
||||
/* Output CPU and other settings */
|
||||
|
||||
void OutputMFlag (unsigned char enabled);
|
||||
/* Output the 65816 M-flag state */
|
||||
|
||||
void OutputXFlag (unsigned char enabled);
|
||||
/* Output the 65816 X-flag state */
|
||||
|
||||
|
||||
|
||||
/* End of output.h */
|
||||
|
@ -90,6 +90,7 @@ typedef enum token_t {
|
||||
INFOTOK_START,
|
||||
INFOTOK_END,
|
||||
INFOTOK_TYPE,
|
||||
INFOTOK_ADDRMODE,
|
||||
|
||||
INFOTOK_CODE,
|
||||
INFOTOK_BYTETAB,
|
||||
|
7
test/dasm/65816.cfg
Normal file
7
test/dasm/65816.cfg
Normal file
@ -0,0 +1,7 @@
|
||||
MEMORY {
|
||||
ROM: start = $8000, size = $8000;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
CODE: load = ROM;
|
||||
}
|
7
test/dasm/65816.info
Normal file
7
test/dasm/65816.info
Normal file
@ -0,0 +1,7 @@
|
||||
GLOBAL {
|
||||
startaddr $8000;
|
||||
};
|
||||
|
||||
RANGE { START $8000; END $8229; ADDRMODE "MX"; TYPE Code;};
|
||||
RANGE { START $822a; END $824b; ADDRMODE "mx"; TYPE Code;};
|
||||
|
@ -19,6 +19,8 @@ ifdef QUIET
|
||||
endif
|
||||
|
||||
CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
CA65 := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
LD65 := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65)
|
||||
|
||||
WORKDIR = ../../testwrk/dasm
|
||||
@ -33,7 +35,7 @@ START = --start-addr 0x8000
|
||||
.PHONY: all clean
|
||||
|
||||
SOURCES := $(wildcard *.s)
|
||||
BINS = $(SOURCES:%disass.s=$(WORKDIR)/%reass.bin)
|
||||
BINS = $(SOURCES:%disass.s=$(WORKDIR)/%reass.bin) $(WORKDIR)/65816-reass.bin
|
||||
CPUS = $(SOURCES:%-disass.s=%)
|
||||
|
||||
all: $(BINS)
|
||||
@ -61,5 +63,18 @@ endef # DISASS_template
|
||||
|
||||
$(foreach cpu,$(CPUS),$(eval $(call DISASS_template,$(cpu))))
|
||||
|
||||
$(WORKDIR)/test65816.bin: test65816.s | $(WORKDIR)
|
||||
$(CA65) -o $(WORKDIR)/test65816.o $<
|
||||
$(LD65) -o $@ -C 65816.cfg $(WORKDIR)/test65816.o
|
||||
|
||||
$(WORKDIR)/65816-reass.s: $(WORKDIR)/test65816.bin
|
||||
$(DA65) --cpu 65816 -i 65816.info -o $@ $<
|
||||
|
||||
$(WORKDIR)/65816-reass.bin: $(WORKDIR)/65816-reass.s $(ISEQUAL)
|
||||
$(if $(QUIET),echo dasm/65816-reass.bin)
|
||||
$(CA65) -o $(WORKDIR)/65816-reass.o $<
|
||||
$(LD65) -o $@ -C 65816.cfg $(WORKDIR)/65816-reass.o
|
||||
$(ISEQUAL) --binary $(WORKDIR)/test65816.bin $@
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
273
test/dasm/test65816.s
Normal file
273
test/dasm/test65816.s
Normal file
@ -0,0 +1,273 @@
|
||||
.setcpu "65816"
|
||||
|
||||
ADC ($10,X)
|
||||
ADC $32,S
|
||||
ADC $10
|
||||
ADC [$10]
|
||||
ADC #$54
|
||||
ADC $9876
|
||||
ADC $FEDBCA
|
||||
ADC ($10),Y
|
||||
ADC ($10)
|
||||
ADC ($32,S),Y
|
||||
ADC $10,X
|
||||
ADC [$10],Y
|
||||
ADC $9876,Y
|
||||
ADC $9876,X
|
||||
ADC $FEDCBA,X
|
||||
SBC ($10,X)
|
||||
SBC $32,S
|
||||
SBC $10
|
||||
SBC [$10]
|
||||
SBC #$54
|
||||
SBC $9876
|
||||
SBC $FEDBCA
|
||||
SBC ($10),Y
|
||||
SBC ($10)
|
||||
SBC ($32,S),Y
|
||||
SBC $10,X
|
||||
SBC [$10],Y
|
||||
SBC $9876,Y
|
||||
SBC $9876,X
|
||||
SBC $FEDCBA,X
|
||||
CMP ($10,X)
|
||||
CMP $32,S
|
||||
CMP $10
|
||||
CMP [$10]
|
||||
CMP #$54
|
||||
CMP $9876
|
||||
CMP $FEDBCA
|
||||
CMP ($10),Y
|
||||
CMP ($10)
|
||||
CMP ($32,S),Y
|
||||
CMP $10,X
|
||||
CMP [$10],Y
|
||||
CMP $9876,Y
|
||||
CMP $9876,X
|
||||
CMP $FEDCBA,X
|
||||
CPX #$54
|
||||
CPX $10
|
||||
CPX $9876
|
||||
CPY #$54
|
||||
CPY $10
|
||||
CPY $9876
|
||||
DEC
|
||||
DEC $10
|
||||
DEC $9876
|
||||
DEC $10,X
|
||||
DEC $9876,X
|
||||
DEX
|
||||
DEY
|
||||
INC
|
||||
INC $10
|
||||
INC $9876
|
||||
INC $10,X
|
||||
INC $9876,X
|
||||
INX
|
||||
INY
|
||||
AND ($10,X)
|
||||
AND $32,S
|
||||
AND $10
|
||||
AND [$10]
|
||||
AND #$54
|
||||
AND $9876
|
||||
AND $FEDBCA
|
||||
AND ($10),Y
|
||||
AND ($10)
|
||||
AND ($32,S),Y
|
||||
AND $10,X
|
||||
AND [$10],Y
|
||||
AND $9876,Y
|
||||
AND $9876,X
|
||||
AND $FEDCBA,X
|
||||
EOR ($10,X)
|
||||
EOR $32,S
|
||||
EOR $10
|
||||
EOR [$10]
|
||||
EOR #$54
|
||||
EOR $9876
|
||||
EOR $FEDBCA
|
||||
EOR ($10),Y
|
||||
EOR ($10)
|
||||
EOR ($32,S),Y
|
||||
EOR $10,X
|
||||
EOR [$10],Y
|
||||
EOR $9876,Y
|
||||
EOR $9876,X
|
||||
EOR $FEDCBA,X
|
||||
ORA ($10,X)
|
||||
ORA $32,S
|
||||
ORA $10
|
||||
ORA [$10]
|
||||
ORA #$54
|
||||
ORA $9876
|
||||
ORA $FEDBCA
|
||||
ORA ($10),Y
|
||||
ORA ($10)
|
||||
ORA ($32,S),Y
|
||||
ORA $10,X
|
||||
ORA [$10],Y
|
||||
ORA $9876,Y
|
||||
ORA $9876,X
|
||||
ORA $FEDCBA,X
|
||||
BIT $10
|
||||
BIT $9876
|
||||
BIT $10,X
|
||||
BIT $9876,X
|
||||
BIT #$54
|
||||
TRB $10
|
||||
TRB $9876
|
||||
TSB $10
|
||||
TSB $9876
|
||||
ASL $10
|
||||
ASL
|
||||
ASL $9876
|
||||
ASL $10,X
|
||||
ASL $9876,X
|
||||
LSR $10
|
||||
LSR
|
||||
LSR $9876
|
||||
LSR $10,X
|
||||
LSR $9876,X
|
||||
ROL $10
|
||||
ROL
|
||||
ROL $9876
|
||||
ROL $10,X
|
||||
ROL $9876,X
|
||||
ROR $10
|
||||
ROR
|
||||
ROR $9876
|
||||
ROR $10,X
|
||||
ROR $9876,X
|
||||
LABEL:
|
||||
BCC LABEL
|
||||
BCS LABEL
|
||||
BEQ LABEL
|
||||
BMI LABEL
|
||||
BNE LABEL
|
||||
BPL LABEL
|
||||
BRA LABEL
|
||||
BVC LABEL
|
||||
BVS LABEL
|
||||
BRL LABEL
|
||||
JMP $1234
|
||||
JMP $FEDCBA
|
||||
JMP ($1234)
|
||||
JMP ($1234,X)
|
||||
JMP [$1234]
|
||||
JSL $123456
|
||||
JSR $1234
|
||||
JSR ($1234,X)
|
||||
RTL
|
||||
RTS
|
||||
BRK
|
||||
RTI
|
||||
CLC
|
||||
CLD
|
||||
CLI
|
||||
CLV
|
||||
SEC
|
||||
SED
|
||||
SEI
|
||||
REP #$12
|
||||
SEP #$12
|
||||
LDA ($10,X)
|
||||
LDA $32,S
|
||||
LDA $10
|
||||
LDA [$10]
|
||||
LDA #$54
|
||||
LDA $9876
|
||||
LDA $FEDBCA
|
||||
LDA ($10),Y
|
||||
LDA ($10)
|
||||
LDA ($32,S),Y
|
||||
LDA $10,X
|
||||
LDA [$10],Y
|
||||
LDA $9876,Y
|
||||
LDA $9876,X
|
||||
LDA $FEDCBA,X
|
||||
LDX #$54
|
||||
LDX $10
|
||||
LDX $9876
|
||||
LDX $10,Y
|
||||
LDX $9876,Y
|
||||
LDY #$54
|
||||
LDY $10
|
||||
LDY $9876
|
||||
LDY $10,X
|
||||
LDY $9876,X
|
||||
STA ($10,X)
|
||||
STA $32,S
|
||||
STA $10
|
||||
STA [$10]
|
||||
STA $9876
|
||||
STA $FEDBCA
|
||||
STA ($10),Y
|
||||
STA ($10)
|
||||
STA ($32,S),Y
|
||||
STA $10,X
|
||||
STA [$10],Y
|
||||
STA $9876,Y
|
||||
STA $9876,X
|
||||
STA $FEDCBA,X
|
||||
STX $10
|
||||
STX $9876
|
||||
STX $10,Y
|
||||
STY $10
|
||||
STY $9876
|
||||
STY $10,X
|
||||
STZ $10
|
||||
STZ $10,X
|
||||
STZ $9876
|
||||
STZ $9876,X
|
||||
MVN #$12,#$34
|
||||
MVP #$12,#$34
|
||||
NOP
|
||||
PEA $1234
|
||||
PEI ($12)
|
||||
PER LABEL
|
||||
PHA
|
||||
PHX
|
||||
PHY
|
||||
PLA
|
||||
PLX
|
||||
PLY
|
||||
PHB
|
||||
PHD
|
||||
PHK
|
||||
PHP
|
||||
PLB
|
||||
PLD
|
||||
PLP
|
||||
STP
|
||||
WAI
|
||||
TAX
|
||||
TAY
|
||||
TSX
|
||||
TXA
|
||||
TXS
|
||||
TXY
|
||||
TYA
|
||||
TYX
|
||||
TCD
|
||||
TCS
|
||||
TDC
|
||||
TSC
|
||||
XBA
|
||||
XCE
|
||||
|
||||
.a16
|
||||
.i16
|
||||
longs:
|
||||
ADC #$5432
|
||||
SBC #$5432
|
||||
CMP #$5432
|
||||
CPX #$5432
|
||||
CPY #$5432
|
||||
AND #$5432
|
||||
EOR #$5432
|
||||
ORA #$5432
|
||||
BIT #$5432
|
||||
LDA #$5432
|
||||
LDX #$5432
|
||||
LDY #$5432
|
61
util/parse-bsnes-log.awk
Executable file
61
util/parse-bsnes-log.awk
Executable file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/awk -nf
|
||||
#
|
||||
# Parse the bsnes-plus cpu log for the 65816 address mode ranges.
|
||||
# Since the log doesn't show the op size, we have to be careful
|
||||
# and add +3 to the range end - this may need manual cleanup.
|
||||
#
|
||||
# Grep the input for only one bank's content beforehand.
|
||||
#
|
||||
# (C) Lauri Kasanen, under the cc65 license
|
||||
#
|
||||
|
||||
{
|
||||
addr = $1
|
||||
|
||||
IGNORECASE = 1
|
||||
if ($9 ~ /^nv/) {
|
||||
val = $9
|
||||
} else if ($10 ~ /^nv/) {
|
||||
val = $10
|
||||
} else {
|
||||
val = $11
|
||||
}
|
||||
IGNORECASE = 0
|
||||
|
||||
val = substr(val, 3, 2)
|
||||
if (val == "1B") # emulation mode
|
||||
val = "MX"
|
||||
|
||||
addrs["0x" substr(addr, 3)] = val
|
||||
}
|
||||
|
||||
END {
|
||||
PROCINFO["sorted_in"] = "@ind_num_asc"
|
||||
|
||||
start = -1
|
||||
prevval = ""
|
||||
|
||||
for (addr in addrs) {
|
||||
cur = addrs[addr]
|
||||
if (start == -1) { # first range
|
||||
start = addr
|
||||
} else {
|
||||
if (prevval != cur || addr - prevaddr > 4) { # start a new range
|
||||
#print "diff " addr - prevaddr ", addr " addr ", pa " prevaddr
|
||||
if (prevaddr + 3 >= addr + 0)
|
||||
fmt = sprintf("%04x", addr - 1)
|
||||
else
|
||||
fmt = sprintf("%04x", prevaddr + 3)
|
||||
print "RANGE { START $" substr(start, 3) "; END $" fmt "; ADDRMODE \"" prevval "\"; TYPE Code;};"
|
||||
start = addr
|
||||
}
|
||||
}
|
||||
#print "\t" addr " " addrs[addr]
|
||||
|
||||
prevval = cur
|
||||
prevaddr = addr
|
||||
}
|
||||
|
||||
fmt = sprintf("%04x", prevaddr + 3)
|
||||
print "RANGE { START $" substr(start, 3) "; END $" fmt "; ADDRMODE \"" prevval "\"; TYPE Code;};"
|
||||
}
|
Loading…
Reference in New Issue
Block a user