Skip to content

Commit

Permalink
relc and a crude fix for issue #8
Browse files Browse the repository at this point in the history
  • Loading branch information
Arakula committed May 18, 2022
1 parent ae59477 commit 41542c8
Show file tree
Hide file tree
Showing 18 changed files with 372 additions and 45 deletions.
21 changes: 21 additions & 0 deletions Assembler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/***************************************************************************
* dasmfw -- Disassembler Framework *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
***************************************************************************/

#include "Assembler.h"

// Nuttin' yet
93 changes: 93 additions & 0 deletions Assembler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/***************************************************************************
* dasmfw -- Disassembler Framework *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
***************************************************************************/

/*****************************************************************************/
/* Assembler.h : definition of the Assembler class */
/*****************************************************************************/

#ifndef __Assembler_h_defined__
#define __Assembler_h_defined__

#include "Disassembler.h"

#if 0
Right now, this is just a scratch pad for gathering ideas.

The basic idea is to provide a class that formats any output according to
the capabilities of a specific assembler.

The disassemblers would then format a line's contents as an array of items
and pass that to the Assembler class to format the output into lines matching
the selected assembler's methods.

Possible Items:
===============

text {cchar}
Text covering the rest of the line.
cchar would be a boolean that defines whether a leading comment
character is to be printed.
This item, if there, has to be the last in the array.

label {ldchar}
label for the current instruction.
ldchar would be a boolean that can be used to force output of the label
delimiter character. This can be overridden if a hypothetical
assembler always requires or doesn't support a label delimiter
character.

instruction
Assembler instruction (mnemonic or pseudo-op) to use.
I'm not sure yet how this could be realized in a way that's useful, but
does not overcomplicate everything. Would it be better to just pass the
ID of a specific instruction and let the Assembler class generate the
matching instruction, or should the mnemonic text be passed, and the
output formatter only decides on upper- and lowercase?
Presumably the first is better, but configuring that might become a
nightmare.
Possible solution: each disassembler for a specific processor gets a
companion class that subclasses Assembler with a defined set of IDs and
a default set of mnemonics which could be overridden in a configuration
file if needed. Doesn't look too bad.

parameter
One of the parameters used by the instruction.
This is even trickier than mnemonic above. Not yet sure how to capture
all the possible ways such a parameter can be passed. Also, what
exactly is a parameter? Looking at the simple 6809 instruction
LDA Base+1
... is that one parameter, or two with a given concatenation character,
or is that a set of 3 parameters, the middle one defining an addition?
Or, if "Base" is a known 16-bit word ... what is this then? A parameter
plus an offset, or a reference to the low byte of the parameter? Some
assemblers would be able to handle that, whereas others would require
the "+1" semantic.
Also, the addressing mode would have to be passed; this, however, can
define how to output one parameter or a complete set of parameters -
but not necessarily all of them.
Another uncomfortable thing: forced addressing. This can, depending on
the processor and the assembler, take some quite "interesting" forms,
where either the mnemonic or the parameter is decorated in some way,
or even both (like "an add instruction taking an 8- and a 16-bit
parameter storing the result in a 32-bit register").
Hmmm. Not easy. Obviously, some kind of hierarchy is needed.

#endif


#endif // __Assembler_h_defined__
18 changes: 11 additions & 7 deletions Dasm6309.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ return Dasm6809::IndexParse(MI, pc, instaddr);
/* IndexString : converts index to string */
/*****************************************************************************/

string Dasm6309::IndexString(adr_t &pc)
string Dasm6309::IndexString(string &smnemo, adr_t &pc)
{
uint8_t T;
uint16_t W;
Expand Down Expand Up @@ -554,15 +554,15 @@ if (T & 0x80)
buf = MnemoCase(sformat("[,--W]"));
break;
default:
return Dasm6809::IndexString(pc);
return Dasm6809::IndexString(smnemo, pc);
}
break;
}
pc = PC;
return buf;
}

return Dasm6809::IndexString(pc);
return Dasm6809::IndexString(smnemo, pc);
}

/*****************************************************************************/
Expand Down Expand Up @@ -772,7 +772,7 @@ switch (mode) /* which mode is this? */
string scn = lbl ? lbl->GetText() : Number2String(T, 2, PC);
PC++;
sparm = sformat("#%s,", I, scn.c_str());
sparm += IndexString(PC);
sparm += IndexString(smnemo, PC);
}
break;

Expand All @@ -791,9 +791,12 @@ switch (mode) /* which mode is this? */
if ((dp != NO_ADDRESS) &&
((W & (uint16_t)0xff00) == (uint16_t)dp) &&
(forceExtendedAddr || GetForcedAddr(PC)))
sparm = sformat("#%s,>%s",
{
AddForced(smnemo, slbl, true);
sparm = sformat("#%s,%s",
snum.c_str(),
slbl.c_str());
}
else
sparm = sformat("#%s,%s",
snum.c_str(),
Expand All @@ -811,11 +814,12 @@ switch (mode) /* which mode is this? */
lbl = FindLabel(PC, Const, bus);
T = GetUByte(PC);
string slbl = lbl ? lbl->GetText() : Number2String(T, 2, PC);
sparm = sformat("%s,%d,%s,%s%s",
if (forceDirectAddr || GetForcedAddr(PC))
AddForced(smnemo, slbl, false);
sparm = sformat("%s,%d,%s,%s",
MnemoCase(bit_r[M >> 6]).c_str(),
(M >> 3) & 7,
snum.c_str(),
(forceDirectAddr || GetForcedAddr(PC)) ? "<" : "",
slbl.c_str());
PC++;
}
Expand Down
2 changes: 1 addition & 1 deletion Dasm6309.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class Dasm6309 : public Dasm6809

protected:
virtual adr_t IndexParse(int MI, adr_t pc, adr_t instaddr = NO_ADDRESS);
virtual string IndexString(adr_t &pc);
virtual string IndexString(string &smnemo, adr_t &pc);
};

#endif // __Dasm6309_h_defined__
60 changes: 53 additions & 7 deletions Dasm6500.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ forceExtendedAddr = true;
forceDirectAddr = true;
closeCC = false;
useDPLabels = false;
textDirectAddr = "p-<";
textExtendedAddr = "p->";

mnemo.resize(mnemo6500_count); /* set up mnemonics table */
for (int i = 0; i < mnemo6500_count; i++)
Expand All @@ -303,6 +305,12 @@ AddOption("dplabel", "{off|on}\tinterpret single-byte data as direct page labels
AddOption("forceaddr", "{off|on}\tuse forced addressing where necessary",
static_cast<PSetter>(&Dasm650X::Set6500Option),
static_cast<PGetter>(&Dasm650X::Get6500Option));
AddOption("forcezpgaddr","{string}\tstring pattern to use for forced zero-page addressing",
static_cast<PSetter>(&Dasm650X::Set6500Option),
static_cast<PGetter>(&Dasm650X::Get6500Option));
AddOption("forceabsaddr","{string}\tstring pattern to use for forced absolute addressing",
static_cast<PSetter>(&Dasm650X::Set6500Option),
static_cast<PGetter>(&Dasm650X::Get6500Option));
}

/*****************************************************************************/
Expand Down Expand Up @@ -347,6 +355,10 @@ else if (lname == "forceaddr")
forceExtendedAddr = forceDirectAddr = bnValue;
return bIsBool ? 1 : 0;
}
else if (lname == "forcezpgaddr")
textDirectAddr = value;
else if (lname == "forceabsaddr")
textExtendedAddr = value;
else
return 0; /* only name consumed */

Expand All @@ -370,6 +382,10 @@ else if (lname == "dplabel")
return useDPLabels ? "on" : "off";
else if (lname == "forceaddr")
return (forceExtendedAddr || forceDirectAddr) ? "on" : "off";
else if (lname == "forcezpgaddr")
return textDirectAddr;
else if (lname == "forceabsaddr")
return textExtendedAddr;

return "";
}
Expand Down Expand Up @@ -502,6 +518,41 @@ else /* otherwise */
return s; /* pass back generated string */
}

/*****************************************************************************/
/* AddForced : add forced direct or extended addressing specifier */
/*****************************************************************************/

void Dasm650X::AddForced(string &smnemo, string &sparm, bool bExtended)
{
string sf = bExtended ? textExtendedAddr : textDirectAddr;
bool bMnemo = false;
bool bAppend = false;
int txtat = 0;
char c = tolower(sf[0]);
if (c == 'm' || c == 'p')
{
bMnemo = (c == 'm');
c = tolower(sf[++txtat]);
if (c == '-' || c == '+')
{
bAppend = (c == '+');
++txtat;
}
}
if (bMnemo)
{
smnemo = (bAppend) ?
smnemo + sf.substr(txtat) :
sf.substr(txtat) + smnemo;
}
else
{
sparm = (bAppend) ?
sparm + sf.substr(txtat) :
sf.substr(txtat) + sparm;
}
}

/*****************************************************************************/
/* InitParse : initialize parsing */
/*****************************************************************************/
Expand Down Expand Up @@ -967,13 +1018,8 @@ switch (mode) /* which mode is this? */
if (forceExtendedAddr &&
(W & (uint16_t)0xff00) == (uint16_t)dp &&
!(mode & _nof))
#if 1
smnemo += ".A";
#else
sparm = ">" + slbl;
else
#endif
sparm = slbl;
AddForced(smnemo, slbl, true);
sparm = slbl;
if (mode == _abx)
sparm += MnemoCase(",X");
else if (mode == _aby)
Expand Down
2 changes: 2 additions & 0 deletions Dasm6500.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class Dasm650X :
virtual string Address2String(adr_t addr, int bus = BusCode)
{ (void)bus; return sformat("$%04X", addr); }
virtual adr_t FetchInstructionDetails(adr_t PC, uint8_t &instpg, uint8_t &instb, uint8_t &mode, int &MI, const char *&I, string *smnemo = NULL);
void AddForced(string &smnemo, string &sparm, bool bExtended = true);

protected:
// 6500 addressing modes
Expand Down Expand Up @@ -200,6 +201,7 @@ class Dasm650X :
bool forceExtendedAddr;
bool forceDirectAddr;
bool useDPLabels;
string textExtendedAddr, textDirectAddr;
};


Expand Down
Loading

0 comments on commit 41542c8

Please sign in to comment.