From 41542c8888c68ec0fe4399849c6ac08a2992ee00 Mon Sep 17 00:00:00 2001 From: Hermann Seib Date: Wed, 18 May 2022 12:00:29 +0200 Subject: [PATCH] relc and a crude fix for issue #8 --- Assembler.cpp | 21 +++++++++++ Assembler.h | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ Dasm6309.cpp | 18 ++++++---- Dasm6309.h | 2 +- Dasm6500.cpp | 60 +++++++++++++++++++++++++++---- Dasm6500.h | 2 ++ Dasm6800.cpp | 58 ++++++++++++++++++++++++++++++ Dasm6800.h | 2 ++ Dasm6809.cpp | 57 ++++++++++++++++++++++------- Dasm6809.h | 6 +++- DasmAvr8.h | 4 +++ Disassembler.cpp | 8 +++-- Disassembler.h | 17 +++++++-- Memory.h | 8 +++-- dasmfw.cpp | 8 +++-- dasmfw.h | 2 +- dasmfw.htm | 44 ++++++++++++++++++++--- history.txt | 7 +++- 18 files changed, 372 insertions(+), 45 deletions(-) create mode 100644 Assembler.cpp create mode 100644 Assembler.h diff --git a/Assembler.cpp b/Assembler.cpp new file mode 100644 index 0000000..51d809d --- /dev/null +++ b/Assembler.cpp @@ -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 \ No newline at end of file diff --git a/Assembler.h b/Assembler.h new file mode 100644 index 0000000..483f6dc --- /dev/null +++ b/Assembler.h @@ -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__ diff --git a/Dasm6309.cpp b/Dasm6309.cpp index 86eaa2d..556b0c8 100644 --- a/Dasm6309.cpp +++ b/Dasm6309.cpp @@ -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; @@ -554,7 +554,7 @@ if (T & 0x80) buf = MnemoCase(sformat("[,--W]")); break; default: - return Dasm6809::IndexString(pc); + return Dasm6809::IndexString(smnemo, pc); } break; } @@ -562,7 +562,7 @@ if (T & 0x80) return buf; } -return Dasm6809::IndexString(pc); +return Dasm6809::IndexString(smnemo, pc); } /*****************************************************************************/ @@ -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; @@ -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(), @@ -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++; } diff --git a/Dasm6309.h b/Dasm6309.h index c3b702b..3aff18c 100644 --- a/Dasm6309.h +++ b/Dasm6309.h @@ -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__ diff --git a/Dasm6500.cpp b/Dasm6500.cpp index 89c8ae2..20b2dc5 100644 --- a/Dasm6500.cpp +++ b/Dasm6500.cpp @@ -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++) @@ -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(&Dasm650X::Set6500Option), static_cast(&Dasm650X::Get6500Option)); +AddOption("forcezpgaddr","{string}\tstring pattern to use for forced zero-page addressing", + static_cast(&Dasm650X::Set6500Option), + static_cast(&Dasm650X::Get6500Option)); +AddOption("forceabsaddr","{string}\tstring pattern to use for forced absolute addressing", + static_cast(&Dasm650X::Set6500Option), + static_cast(&Dasm650X::Get6500Option)); } /*****************************************************************************/ @@ -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 */ @@ -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 ""; } @@ -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 */ /*****************************************************************************/ @@ -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) diff --git a/Dasm6500.h b/Dasm6500.h index 289425e..526fd9a 100644 --- a/Dasm6500.h +++ b/Dasm6500.h @@ -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 @@ -200,6 +201,7 @@ class Dasm650X : bool forceExtendedAddr; bool forceDirectAddr; bool useDPLabels; + string textExtendedAddr, textDirectAddr; }; diff --git a/Dasm6800.cpp b/Dasm6800.cpp index eee3914..525098e 100644 --- a/Dasm6800.cpp +++ b/Dasm6800.cpp @@ -276,6 +276,8 @@ forceDirectAddr = true; closeCC = false; #endif useDPLabels = false; +textDirectAddr = "p-<"; +textExtendedAddr = "p->"; mnemo.resize(mnemo6800_count); /* set up mnemonics table */ for (int i = 0; i < mnemo6800_count; i++) @@ -301,6 +303,12 @@ AddOption("dplabel", "{off|on}\tinterpret single-byte data as direct page labels AddOption("forceaddr", "{off|on}\tuse forced addressing where necessary", static_cast(&Dasm6800::Set6800Option), static_cast(&Dasm6800::Get6800Option)); +AddOption("forcediraddr","{string}\tstring pattern to use for forced direct addressing", + static_cast(&Dasm6800::Set6800Option), + static_cast(&Dasm6800::Get6800Option)); +AddOption("forceextaddr","{string}\tstring pattern to use for forced extended addressing", + static_cast(&Dasm6800::Set6800Option), + static_cast(&Dasm6800::Get6800Option)); } /*****************************************************************************/ @@ -350,6 +358,10 @@ else if (lname == "forceaddr") forceExtendedAddr = forceDirectAddr = bnValue; return bIsBool ? 1 : 0; } +else if (lname == "forcediraddr") + textDirectAddr = value; +else if (lname == "forceextaddr") + textExtendedAddr = value; else return 0; /* only name consumed */ @@ -375,6 +387,10 @@ else if (lname == "dplabel") return useDPLabels ? "on" : "off"; else if (lname == "forceaddr") return (forceExtendedAddr || forceDirectAddr) ? "on" : "off"; +else if (lname == "forcediraddr") + return textDirectAddr; +else if (lname == "forceextaddr") + return textExtendedAddr; return ""; } @@ -643,6 +659,41 @@ else /* otherwise */ return s; /* pass back generated string */ } +/*****************************************************************************/ +/* AddForced : add forced direct or extended addressing specifier */ +/*****************************************************************************/ + +void Dasm6800::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 */ /*****************************************************************************/ @@ -1123,6 +1174,12 @@ switch (mode) /* which mode is this? */ if (dp == DEFAULT_ADDRESS) dp = 0; } +#if 1 + if (forceExtendedAddr && (W & (uint16_t)0xff00) == (uint16_t)dp || + GetForcedAddr(PC)) + AddForced(smnemo, slbl, true); + sparm = slbl; +#else if (forceExtendedAddr && (W & (uint16_t)0xff00) == (uint16_t)dp) sparm = ">" + slbl; else @@ -1130,6 +1187,7 @@ switch (mode) /* which mode is this? */ sparm = GetForcedAddr(PC) ? ">" : ""; sparm += slbl; } +#endif PC += 2; } break; diff --git a/Dasm6800.h b/Dasm6800.h index 1509bd1..7941ef4 100644 --- a/Dasm6800.h +++ b/Dasm6800.h @@ -119,6 +119,7 @@ class Dasm6800 : virtual adr_t FetchInstructionDetails(adr_t PC, uint8_t &instpg, uint8_t &instb, uint8_t &mode, int &MI, const char *&I, string *smnemo = NULL); virtual string GetIx8IndexReg(uint8_t instpg) { (void)instpg; return MnemoCase(",X"); } virtual bool SetConvenience(uint8_t instpg, uint16_t u2, string &smnemo, adr_t &PC); + void AddForced(string &smnemo, string &sparm, bool bExtended = true); protected: // 6800 addressing modes @@ -271,6 +272,7 @@ class Dasm6800 : bool forceExtendedAddr; bool forceDirectAddr; bool useDPLabels; + string textExtendedAddr, textDirectAddr; }; diff --git a/Dasm6809.cpp b/Dasm6809.cpp index 09583c2..8c0f678 100644 --- a/Dasm6809.cpp +++ b/Dasm6809.cpp @@ -1466,7 +1466,7 @@ return PC; /* IndexString : converts index to string */ /*****************************************************************************/ -string Dasm6809::IndexString(adr_t &pc) +string Dasm6809::IndexString(string &smnemo, adr_t &pc) { uint8_t T; uint16_t W, Wrel; @@ -1546,15 +1546,21 @@ if (T & 0x80) string slbl = lbl ? lbl->GetText() : Label2String(W, 4, bGetLabel, PC); buf = sformat("%s,%s", slbl.c_str(), MnemoCase(R).c_str()); if (((W < 0x80) || (W >= 0xff80)) && forceExtendedAddr) - buf = ">" + buf; + //buf = ">" + buf; + AddForced(smnemo, buf, true); } else { string slbl; if (((W < 0x80) || (W >= 0xff80)) && forceExtendedAddr) { +#if 1 slbl = lbl ? lbl->GetText() : SignedNumber2String((int)(short)W, 4, PC); + AddForced(smnemo, slbl, true); + buf = sformat("%s,%s", slbl.c_str(), MnemoCase(R).c_str()); +#else buf = sformat(">%s,%s", slbl.c_str(), MnemoCase(R).c_str()); +#endif } else { @@ -1574,16 +1580,21 @@ if (T & 0x80) sprintf(buf,"$%s,PC",signed_string((int)(char)T, 2, (word)PC)); #else if (bGetLabel) - buf = Label2String((uint16_t)((int)((char)T) + PC + 1), 4, - bGetLabel, PC) + MnemoCase(",PCR"); + { + string slbl = Label2String((uint16_t)((int)((char)T) + PC + 1), 4, + bGetLabel, PC); + if (((char)T > 0) && forceDirectAddr) + AddForced(smnemo, slbl, false); + buf = slbl + MnemoCase(",PCR"); + } else { lbl = FindLabel(PC, Const); string slbl = lbl ? lbl->GetText() : Number2String((uint16_t)(int)(char)T, 2, PC); + if (((char)T > 0) && forceDirectAddr) + AddForced(smnemo, slbl, false); buf = slbl + MnemoCase(",PC"); } - if (((char)T > 0) && forceDirectAddr) - buf = "<" + buf; #endif PC++; break; @@ -1596,9 +1607,13 @@ if (T & 0x80) string slbl = lbl ? lbl->GetText() : Label2String((uint16_t)(W + PC), 4, bGetLabel, PC - 2); if (((W < 0x80) || (W >= 0xff80)) && forceExtendedAddr) +#if 1 + AddForced(smnemo, slbl, true); +#else buf = sformat(">%s", slbl.c_str()) + MnemoCase(",PCR"); else - buf = sformat("%s", slbl.c_str()) + MnemoCase(",PCR"); +#endif + buf = sformat("%s", slbl.c_str()) + MnemoCase(",PCR"); } break; case 0x11: @@ -1646,16 +1661,21 @@ if (T & 0x80) T = GetUByte(PC); bGetLabel = !IsConst(PC); if (bGetLabel) - buf = Label2String((uint16_t)((int)((char)T) + PC + 1), 4, - bGetLabel, PC) + MnemoCase(",PCR"); + { + string slbl = Label2String((uint16_t)((int)((char)T) + PC + 1), 4, + bGetLabel, PC); + if (((char)T > 0) && forceDirectAddr) + AddForced(smnemo, slbl, false); + buf = slbl + MnemoCase(",PCR"); + } else { lbl = FindLabel(PC, Const); string slbl = lbl ? lbl->GetText() : Number2String((uint16_t)(int)(char)T, 2, PC); + if (((char)T > 0) && forceDirectAddr) + AddForced(smnemo, slbl, false); buf = slbl + MnemoCase(",PC"); } - if (((char)T > 0) && forceDirectAddr) - buf = "<" + buf; buf = "[" + buf + "]"; PC++; #else @@ -1677,9 +1697,13 @@ if (T & 0x80) string slbl = lbl ? lbl->GetText() : Label2String((uint16_t)(W + PC), 4, bGetLabel, PC - 2); if (((W < 0x80) || (W >= 0xff80)) && forceExtendedAddr) +#if 1 + AddForced(smnemo, slbl, true); +#else buf = sformat("[>%s,%s]", slbl.c_str(), MnemoCase("PCR").c_str()); else - buf = sformat("[%s,%s]", slbl.c_str(), MnemoCase("PCR").c_str()); +#endif + buf = sformat("[%s,%s]", slbl.c_str(), MnemoCase("PCR").c_str()); #else bGetLabel = !IsConst(PC); lbl = bGetLabel ? NULL : FindLabel(PC, Const); @@ -1840,6 +1864,12 @@ switch (mode) /* which mode is this? */ dp = GetDirectPage(addr); if (dp == DEFAULT_ADDRESS) dp = 0; +#if 1 + if (forceExtendedAddr && (W & (uint16_t)0xff00) == (uint16_t)dp || + GetForcedAddr(PC)) + AddForced(smnemo, slbl, true); + sparm = slbl; +#else if (forceExtendedAddr && (W & (uint16_t)0xff00) == (uint16_t)dp) sparm = ">" + slbl; else @@ -1847,6 +1877,7 @@ switch (mode) /* which mode is this? */ sparm = GetForcedAddr(PC) ? ">" : ""; sparm += slbl; } +#endif PC += 2; } break; @@ -1854,7 +1885,7 @@ switch (mode) /* which mode is this? */ case _ind: /* indexed */ if (!useConvenience || !SetConvenience(instpg, (uint16_t)(instb << 8) | GetUByte(PC), smnemo, PC)) - sparm = IndexString(PC); + sparm = IndexString(smnemo, PC); break; case _rew: /* relative word */ diff --git a/Dasm6809.h b/Dasm6809.h index c97a15f..b303b65 100644 --- a/Dasm6809.h +++ b/Dasm6809.h @@ -87,6 +87,10 @@ class MemAttribute6809Handler : public MemAttributeHandler { MemAttribute6809 *pAttr = attr.getat(addr); return pAttr ? pAttr->GetForcedAddr() : false; } virtual void SetForcedAddr(adr_t addr, bool bOn = true) { MemAttribute6809 *pAttr = attr.getat(addr); if (pAttr) pAttr->SetForcedAddr(bOn); } + virtual bool GetRelConst(adr_t addr) + { MemAttribute6809 *pAttr = attr.getat(addr); return pAttr ? pAttr->GetRelConst() : false; } + virtual void SetRelConst(adr_t addr, bool bOn = true) + { MemAttribute6809 *pAttr = attr.getat(addr); if (pAttr) pAttr->SetRelConst(bOn); } virtual uint32_t GetDisassemblyFlags(adr_t addr, uint8_t mem, Label *plbl) { return GetBasicDisassemblyFlags(attr.getat(addr), mem, plbl); } // basic access @@ -312,7 +316,7 @@ class Dasm6809 : public Dasm6800 virtual adr_t FetchInstructionDetails(adr_t PC, uint8_t &instpg, uint8_t &instb, uint8_t &mode, int &MI, const char *&I, string *smnemo = NULL); virtual bool SetConvenience(uint8_t instpg, uint16_t u2, string &smnemo, adr_t &PC); 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); void AddFlexLabels(); }; diff --git a/DasmAvr8.h b/DasmAvr8.h index bf2a721..8308417 100644 --- a/DasmAvr8.h +++ b/DasmAvr8.h @@ -114,6 +114,10 @@ class MemAttributeAvr8Handler : public MemAttributeHandler { MemAttributeAvr8 *pAttr = attr.getat(addr); return pAttr ? pAttr->GetForcedAddr() : false; } virtual void SetForcedAddr(adr_t addr, bool bOn = true) { MemAttributeAvr8 *pAttr = attr.getat(addr); if (pAttr) pAttr->SetForcedAddr(bOn); } + virtual bool GetRelConst(adr_t addr) + { MemAttributeAvr8 *pAttr = attr.getat(addr); return pAttr ? pAttr->GetRelConst() : false; } + virtual void SetRelConst(adr_t addr, bool bOn = true) + { MemAttributeAvr8 *pAttr = attr.getat(addr); if (pAttr) pAttr->SetRelConst(bOn); } virtual uint32_t GetDisassemblyFlags(adr_t addr, uint8_t mem, Label *plbl) { return GetBasicDisassemblyFlags(attr.getat(addr), mem, plbl); } // basic access diff --git a/Disassembler.cpp b/Disassembler.cpp index b2a1eda..f31a43f 100644 --- a/Disassembler.cpp +++ b/Disassembler.cpp @@ -554,6 +554,7 @@ string Disassembler::Label2String { string sOut; adr_t relative = GetRelative(addr, bus); +bool relConst = GetRelConst(addr, bus); adr_t Wrel = (value + relative); adr_t hiaddr = GetHighestBusAddr(bus) + 1; adr_t WrelMod = (hiaddr) ? Wrel % hiaddr : Wrel; @@ -602,16 +603,17 @@ if (relative) /* if it's relative addressing */ int32_t nDiff = Wrel - value; /* get difference */ /* get base name */ - pLbl = (bUseLabel) ? FindLabel(relative, Untyped, bus) : NULL; + bool bRelUseLabel = (relConst) ? false : bUseLabel; + pLbl = (bRelUseLabel) ? FindLabel(relative, Untyped, bus) : NULL; // DefLabel overrides normal labels and is independent of bUseLabel if (!pLbl) pLbl = FindLabel(relative, Const, bus); sLabel = (pLbl) ? pLbl->GetText() : ""; if (sLabel.size()) sAdd += sLabel; - else if (bUseLabel && IsCLabel(relative, bus)) + else if (bRelUseLabel && IsCLabel(relative, bus)) sAdd += UnnamedLabel(relative, true, bus); - else if (bUseLabel && IsDLabel(relative, bus)) + else if (bRelUseLabel && IsDLabel(relative, bus)) sAdd += UnnamedLabel(relative, false, bus); else { diff --git a/Disassembler.h b/Disassembler.h index 9570ce5..b54576d 100644 --- a/Disassembler.h +++ b/Disassembler.h @@ -49,6 +49,8 @@ class MemAttributeHandler virtual void SetBreakBefore(adr_t addr, bool bOn = true) = 0; virtual bool GetForcedAddr(adr_t addr) = 0; virtual void SetForcedAddr(adr_t addr, bool bOn = true) = 0; + virtual bool GetRelConst(adr_t addr) = 0; + virtual void SetRelConst(adr_t addr, bool bOn = true) = 0; virtual uint32_t GetDisassemblyFlags(adr_t addr, uint8_t mem, Label *plbl) = 0; // basic access virtual size_t size() = 0; @@ -112,6 +114,10 @@ class BasicMemAttributeHandler : public MemAttributeHandler { MemAttribute *pAttr = attr.getat(addr); return pAttr ? pAttr->GetForcedAddr() : false; } virtual void SetForcedAddr(adr_t addr, bool bOn = true) { MemAttribute *pAttr = attr.getat(addr); if (pAttr) pAttr->SetForcedAddr(bOn); } + virtual bool GetRelConst(adr_t addr) + { MemAttribute *pAttr = attr.getat(addr); return pAttr ? pAttr->GetRelConst() : false; } + virtual void SetRelConst(adr_t addr, bool bOn = true) + { MemAttribute *pAttr = attr.getat(addr); if (pAttr) pAttr->SetRelConst(bOn); } virtual uint32_t GetDisassemblyFlags(adr_t addr, uint8_t mem, Label *plbl) { return GetBasicDisassemblyFlags(attr.getat(addr), mem, plbl); } // basic access @@ -418,6 +424,10 @@ class Disassembler { return memattr[bus] ? memattr[bus]->GetForcedAddr(addr) : false; } void SetForcedAddr(adr_t addr, bool bOn = true, int bus = BusCode) { if (memattr[bus]) memattr[bus]->SetForcedAddr(addr, bOn); } + bool GetRelConst(adr_t addr, int bus = BusCode) + { return memattr[bus] ? memattr[bus]->GetRelConst(addr) : false; } + void SetRelConst(adr_t addr, bool bOn = true, int bus = BusCode) + { if (memattr[bus]) memattr[bus]->SetRelConst(addr, bOn); } // get/set default cell display format MemAttribute::Display GetDisplay() { return defaultDisplay; } void SetDisplay(MemAttribute::Display newDisp) { defaultDisplay = newDisp; } @@ -458,8 +468,11 @@ class Disassembler { return Relatives[bus].AddMemory(addr, relsize, 0, contents); } adr_t GetRelative(adr_t addr, int bus = BusCode) { adr_t *paddr = Relatives[bus].getat(addr); return paddr ? *paddr : 0; } - void SetRelative(adr_t addr, adr_t rel, int bus = BusCode) - { adr_t *paddr = Relatives[bus].getat(addr); if (paddr) *paddr = rel; } + void SetRelative(adr_t addr, adr_t rel, bool isconst, int bus = BusCode) + { + SetRelConst(addr, isconst, bus); + adr_t *paddr = Relatives[bus].getat(addr); if (paddr) *paddr = rel; + } // Phase handling public: diff --git a/Memory.h b/Memory.h index 71c3e7c..698357b 100644 --- a/Memory.h +++ b/Memory.h @@ -280,6 +280,7 @@ struct MemAttribute unsigned used: 1; /* used (or not) */ unsigned breakBefore: 1; /* line break in disassembly */ unsigned forcedAddr:1; /* forced addressing */ + unsigned relConst:1; /* rel for this is const */ enum Type { @@ -307,11 +308,12 @@ struct MemAttribute Type cellType = UnsignedInt, Display display = DefaultDisplay, bool breakBefore = false, - bool forcedAddr = false + bool forcedAddr = false, + bool relConst = false ) : cellSize(cellSize - 1), memType(memType), cellType(cellType), display(display), used(used), breakBefore(breakBefore), - forcedAddr(forcedAddr) + forcedAddr(forcedAddr), relConst(relConst) { } // MemAttribute Getters / Setters @@ -329,6 +331,8 @@ struct MemAttribute void SetBreakBefore(bool bOn = true) { breakBefore = !!bOn; } bool GetForcedAddr() { return !!forcedAddr; } void SetForcedAddr(bool bOn = true) { forcedAddr = !!bOn; } + bool GetRelConst() { return !!relConst; } + void SetRelConst(bool bOn = true) { relConst = !!bOn; } }; /*****************************************************************************/ diff --git a/dasmfw.cpp b/dasmfw.cpp index 3844eff..d649204 100644 --- a/dasmfw.cpp +++ b/dasmfw.cpp @@ -1208,6 +1208,7 @@ enum InfoCmd infoUnForceAddr, /* UNFORCEADDR addr[-addr] */ // relative address infoRelative, /* RELATIVE addr[-addr] rel */ + infoRelativeConst, /* RELATIVEC addr[-addr] rel */ infoUnRelative, /* UNRELATIVE addr[-addr] */ // label handling infoLabel, /* LABEL addr[-addr] label */ @@ -1302,6 +1303,8 @@ static struct /* structure to convert key to type */ // relative address { "RELATIVE", infoRelative }, { "REL", infoRelative }, + { "RELATIVEC", infoRelativeConst }, + { "RELC", infoRelativeConst }, { "UNRELATIVE", infoUnRelative }, { "UNREL", infoUnRelative }, // label handling @@ -1731,6 +1734,7 @@ do } break; case infoRelative : /* RELATIVE addr[-addr] rel */ + case infoRelativeConst : /* RELATIVEC addr[-addr] rel */ { string range; idx = value.find_first_of(" \t"); @@ -1745,7 +1749,7 @@ do for (adr_t scanned = from; scanned >= from && scanned <= to; scanned += step) - pDasm->SetRelative(scanned, rel, infoBus); + pDasm->SetRelative(scanned, rel, cmdType == infoRelativeConst, infoBus); } } break; @@ -1757,7 +1761,7 @@ do for (adr_t scanned = from; scanned >= from && scanned <= to; scanned += step) - pDasm->SetRelative(scanned, 0, infoBus); + pDasm->SetRelative(scanned, 0, false, infoBus); } } break; diff --git a/dasmfw.h b/dasmfw.h index 29dbfa4..794eaf6 100644 --- a/dasmfw.h +++ b/dasmfw.h @@ -59,7 +59,7 @@ using namespace std; /* Global definitions */ /*****************************************************************************/ -#define DASMFW_VERSION "0.26" +#define DASMFW_VERSION "0.28" // set these to int64_t once 64bit processors become part of the framework typedef uint32_t cadr_t; /* container for maximal code address*/ diff --git a/dasmfw.htm b/dasmfw.htm index 1242dfb..373579d 100644 --- a/dasmfw.htm +++ b/dasmfw.htm @@ -304,10 +304,42 @@

Disassembler Options

Since this is a bit hairy, default is off.
forceaddr on|off
If the targeted processor (and assembler, if available) can handle - forced direct / extended addressing, dasmfw tries its best to determine - whether adding the required < and > marks is necessary; in very rare - occasions, this may fail. If you build the "RB" variant, it isn't done by default; + forced direct / extended addressing (zero-page and absolute for 650X), dasmfw tries + its best to determine whether adding the required marks is necessary; + in very rare occasions, this may fail. If you build the "RB" variant, it isn't done by default; normally, it is. This option can be used to change the behavior.
+
forcezpgaddr pattern
+
For 6500-based disassemblers only.
+ This defines a string pattern to use for forced zero-page addressing. The pattern consists of + 3 parts, which have to be given in order: +
    +
  • m or p defines whether the modification is done to the + mnemonic or the parameter
  • +
  • - or + (only to be given if preced by m or p) defines whether + the following text is prepended (-) or appended(+) to the mnemonic or parameter
  • +
  • text which is a free-form text to denote the modification. Can be empty, if the assembler + only accepts one kind of forced addressing.
  • +
+ Default value is an A09-compatible (although A09 doesn't support 650X yet ;-) p-< +
+
forceabsaddr pattern
+
For 6500-based disassemblers only.
+ This defines a string pattern to use for forced absolute addressing; + see forcezpgaddr above for details on the pattern.
+ Default value is an A09-compatible (although A09 doesn't support 650X yet ;-) p-> +
+
forcediraddr pattern
+
For 6800-based disassemblers only.
+ This defines a string pattern to use for forced direct (zero-page for 6800) addressing; + see forcezpgaddr above for details on the pattern.
+ Default value is an A09-compatible p-< +
+
forceextaddr pattern
+
For 6800-based disassemblers only.
+ This defines a string pattern to use for forced extended addressing; + see forcezpgaddr above for details on the pattern.
+ Default value is an A09-compatible p-> +
undef on|off
noundef
Some processors (currently 6501 and 6502-based) support additional, but pretty well understood officially undefined opcodes. These can be made available; however, @@ -618,9 +650,11 @@

Global Info File Instructions

rel[ative] addr[-addr] baseaddr
This can be used to make instructions with indexed addressing easier to read.
- +
rel[ative]c addr[-addr] baseindex
+
This can be used to make instructions with indexed addressing easier + to read.
unrel[ative] addr[-addr[/step]]
-
cancels the effect of relative instructions.
+
cancels the effect of relative and relativec instructions.
remap addr[-addr[/step]] offset
This is a tricky instruction that only makes sense in very special diff --git a/history.txt b/history.txt index 212d349..cf35bd5 100644 --- a/history.txt +++ b/history.txt @@ -75,4 +75,9 @@ v0.25 2022-05-06 [no]code option documented neither "option cchar *" nor "option cchar \*" worked ... now it should work as documented and it's "option cchar \*" v0.26 2022-05-09 upmnemo option now also influences register names - Updates to 6502 disassembler \ No newline at end of file + Updates to 6502 disassembler +v0.27 2022-05-10 relc directive added +v0.28 2022-05-18 crude fix for https://github.com/Arakula/dasmfw/issues/8 + added 2 options for the 680X and 650X disassemblers to set + up a pattern for forced direct(zeropage) and extended(absolute) + addressing \ No newline at end of file