Skip to content

Commit

Permalink
[MOS6502] Add SWEET16 support
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Jan 16, 2024
1 parent 4899e14 commit 0127d16
Show file tree
Hide file tree
Showing 18 changed files with 379 additions and 82 deletions.
24 changes: 12 additions & 12 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ usage: asm [-o <output>] [-l <list>] <input>
-C <CPU> : target CPU
MC6800 MB8861 MC6801 HD6301 MC68HC11 MC6805 MC146805
MC68HC05 MC6809 HD6309 MOS6502 R65C02 G65SC02 W65C02S
W65C816S i8039 i8048 i80C39 i80C48 MSM80C39 MSM80C48 i8051
i8080 i8085 V30EMU Z80 Z8 Z86C Z88 TLCS90 INS8060 INS8070
CDP1802 CDP1804 CDP1804A SCN2650 F3850 IM6100 HD6120
TMS7000 TMS32010 TMS32015 i8086 i80186 V30 i8096 MC68000
TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002 NS32032 MN1610
MN1613 MN1613A
W65C816S SWEET16 i8039 i8048 i80C39 i80C48 MSM80C39
MSM80C48 i8051 i8080 i8085 V30EMU Z80 Z8 Z86C Z88 TLCS90
INS8060 INS8070 CDP1802 CDP1804 CDP1804A SCN2650 F3850
IM6100 HD6120 TMS7000 TMS32010 TMS32015 i8086 i80186 V30
i8096 MC68000 TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002
NS32032 MN1610 MN1613 MN1613A
-o <output> : output file
-l <list> : list file
-S[<bytes>] : output Motorola S-Record format
Expand Down Expand Up @@ -126,12 +126,12 @@ usage: dis -C <CPU> [-o <output>] [-l <list>] <input>
-C <CPU> : target CPU
MC6800 MB8861 MC6801 HD6301 MC68HC11 MC6805 MC146805
MC68HC05 MC6809 HD6309 MOS6502 R65C02 G65SC02 W65C02S
W65C816S i8039 i8048 i80C39 i80C48 MSM80C39 MSM80C48 i8051
i8080 i8085 V30EMU Z80 Z8 Z86C Z88 TLCS90 INS8060 INS8070
CDP1802 CDP1804 CDP1804A SCN2650 F3850 IM6100 HD6120
TMS7000 TMS32010 TMS32015 i8086 i80186 V30 i8096 MC68000
TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002 NS32032 MN1610
MN1613 MN1613A
W65C816S SWEET16 i8039 i8048 i80C39 i80C48 MSM80C39
MSM80C48 i8051 i8080 i8085 V30EMU Z80 Z8 Z86C Z88 TLCS90
INS8060 INS8070 CDP1802 CDP1804 CDP1804A SCN2650 F3850
IM6100 HD6120 TMS7000 TMS32010 TMS32015 i8086 i80186 V30
i8096 MC68000 TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002
NS32032 MN1610 MN1613 MN1613A
-o <output> : output file
-l <list> : list file
<input> : file can be Motorola S-Record or Intel HEX format
Expand Down
18 changes: 18 additions & 0 deletions src/asm_mos6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,17 @@ void AsmMos6502::encodeOperand(AsmInsn &insn, AddrMode modeAndFlags, const Opera
case M_IM8:
emitImmediate(insn, op, false);
break;
case M_IM16:
emitImmediate(insn, op, true);
break;
case M_REL:
case M_LREL:
encodeRelative(insn, mode, op);
break;
case M_REGR:
case I_REGR:
insn.embed(op.val32 & 0xF);
break;
default:
break;
}
Expand Down Expand Up @@ -326,6 +333,17 @@ Error AsmMos6502::parseOperand(StrScanner &scan, Operand &op, char &indirect) co
if (reg != REG_UNDEF) {
op.mode = regName2AddrMode(reg);
} else {
if (cpuType() == SWEET16) {
auto r = p;
const auto indirectR = r.expect('@');
const auto regr = parseRegR(r);
if (regr != REG_UNDEF) {
op.mode = indirectR ? I_REGR : M_REGR;
op.val32 = regr - REG_R0;
scan = r;
return OK;
}
}
const auto size = parseSizeOverride(p);
op.val32 = parseExpr32(p, op, indirect);
if (op.hasError())
Expand Down
1 change: 1 addition & 0 deletions src/config_mos6502.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum CpuType : uint8_t {
R65C02,
W65C02S,
W65C816,
SWEET16,
};

struct Config : ConfigImpl<CpuType, ADDRESS_24BIT, ADDRESS_BYTE, OPCODE_8BIT, ENDIAN_LITTLE, 4, 4> {
Expand Down
15 changes: 11 additions & 4 deletions src/dis_mos6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ bool DisMos6502::longImmediate(AddrMode mode) const {
if (mode == M_IMX)
return _longIndex;
}
return false;
return mode == M_IM16;
}

void DisMos6502::decodeImmediate(DisInsn &insn, StrBuffer &out, AddrMode mode) const {
out.letter('#');
out.letter(mode == M_IM16 ? ' ' : '#');
const auto imm16 = longImmediate(mode);
const uint16_t val = imm16 ? insn.readUint16() : insn.readByte();
outHex(out, val, imm16 ? 16 : 8);
Expand Down Expand Up @@ -188,9 +188,16 @@ void DisMos6502::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode modeAndFl
case M_REGS:
outRegName(out, REG_S);
break;
case I_REGR:
out.letter('@');
/* Fall-through */
case M_REGR:
outRegR(out, insn.opCode());
break;
case M_IMA:
case M_IMX:
case M_IM8:
case M_IM16:
decodeImmediate(insn, out, mode);
break;
case M_ABS:
Expand Down Expand Up @@ -228,13 +235,13 @@ Error DisMos6502::decodeImpl(DisMemory &memory, Insn &_insn, StrBuffer &out) con
const auto indir1 = DisInsn::indirect(mode1);
const auto longi1 = DisInsn::longIndirect(mode1);
if (indir1)
out.letter('(');
out.letter(mode1 == I_REGR ? '@' : '(');
if (longi1)
out.letter('[');
decodeOperand(insn, out, mode1);
const auto indir2 = DisInsn::indirect(mode2);
const auto longi2 = DisInsn::longIndirect(mode2);
if (indir1 && !indir2)
if (indir1 && !indir2 && mode1 != I_REGR)
out.letter(')');
if (longi1 && !longi2)
out.letter(']');
Expand Down
3 changes: 3 additions & 0 deletions src/entry_mos6502.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ enum AddrMode : uint8_t {
// Direct page indirect long: L_DPG, M_NONE, M_NONE: ___L (d)
// Direct page indirect long indexed: L_DPG, M_REGY, M_NONE: ___L (d),Y
// Block move: M_BANK, M_BANK, M_NONE: k8,k8
M_REGR = 14, // Register Rn
I_REGR = 14 | indir_bm, // Indirect R: @Rn
M_IM16 = 15, // Immediate word: #nnnn
};

struct Entry final : entry::Base<Config::opcode_t> {
Expand Down
16 changes: 16 additions & 0 deletions src/reg_mos6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ StrBuffer &outRegName(StrBuffer &out, RegName name) {
return entry ? entry->outText(out) : out;
}

RegName parseRegR(StrScanner &scan) {
auto p = scan;
if (p.iexpect('R')) {
const auto num = parseRegNumber(p);
if (num >= 0 && num < 16) {
scan = p;
return RegName(num);
}
}
return REG_UNDEF;
}

StrBuffer &outRegR(StrBuffer &out, uint8_t opc) {
return out.letter('R').uint8(opc & 0xF);
}

} // namespace reg
} // namespace mos6502
} // namespace libasm
Expand Down
20 changes: 19 additions & 1 deletion src/reg_mos6502.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,35 @@ namespace libasm {
namespace mos6502 {

enum RegName : int8_t {
REG_UNDEF = 0,
REG_UNDEF = -1,
REG_A = 'A',
REG_X = 'X',
REG_Y = 'Y',
REG_S = 'S',
REG_R0 = 0,
REG_R1 = 1,
REG_R2 = 2,
REG_R3 = 3,
REG_R4 = 4,
REG_R5 = 5,
REG_R6 = 6,
REG_R7 = 7,
REG_R8 = 8,
REG_R9 = 9,
REG_R10 = 10,
REG_R11 = 11,
REG_R12 = 12,
REG_R13 = 13,
REG_R14 = 14,
REG_R15 = 15,
};

namespace reg {

RegName parseRegName(StrScanner &scan);
StrBuffer &outRegName(StrBuffer &out, RegName name);
RegName parseRegR(StrScanner &scan);
StrBuffer &outRegR(StrBuffer &out, uint8_t opc);

} // namespace reg
} // namespace mos6502
Expand Down
82 changes: 75 additions & 7 deletions src/table_mos6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,67 @@ static constexpr uint8_t W65C816_INDEX[] PROGMEM = {
12, // TEXT_XBA
13, // TEXT_XCE
};

static constexpr Entry SWEET16_TABLE[] PROGMEM = {
E2(0x10, TEXT_SET, M_REGR, M_IM16),
E1(0x20, TEXT_LD, M_REGR),
E1(0x30, TEXT_ST, M_REGR),
E1(0x40, TEXT_LD, I_REGR),
E1(0x50, TEXT_ST, I_REGR),
E1(0x60, TEXT_LDD, I_REGR),
E1(0x70, TEXT_STD, I_REGR),
E1(0x80, TEXT_POP, I_REGR),
E1(0x90, TEXT_STP, I_REGR),
E1(0xA0, TEXT_ADD, M_REGR),
E1(0xB0, TEXT_SUB, M_REGR),
E1(0xC0, TEXT_POPD, I_REGR),
E1(0xD0, TEXT_CPR, M_REGR),
E1(0xE0, TEXT_INR, M_REGR),
E1(0xF0, TEXT_DCR, M_REGR),
E0(0x00, TEXT_RTN),
E1(0x01, TEXT_BR, M_REL),
E1(0x02, TEXT_BNC, M_REL),
E1(0x03, TEXT_BC, M_REL),
E1(0x04, TEXT_BP, M_REL),
E1(0x05, TEXT_BM, M_REL),
E1(0x06, TEXT_BZ, M_REL),
E1(0x07, TEXT_BNZ, M_REL),
E1(0x08, TEXT_BM1, M_REL),
E1(0x09, TEXT_BNM1, M_REL),
E0(0x0A, TEXT_BK),
E0(0x0B, TEXT_RS),
E1(0x0C, TEXT_BS, M_REL),
};
static constexpr uint8_t SWEET16_INDEX[] PROGMEM = {
9, // TEXT_ADD
18, // TEXT_BC
25, // TEXT_BK
20, // TEXT_BM
23, // TEXT_BM1
17, // TEXT_BNC
24, // TEXT_BNM1
22, // TEXT_BNZ
19, // TEXT_BP
16, // TEXT_BR
27, // TEXT_BS
21, // TEXT_BZ
12, // TEXT_CPR
14, // TEXT_DCR
13, // TEXT_INR
1, // TEXT_LD
3, // TEXT_LD
5, // TEXT_LDD
7, // TEXT_POP
11, // TEXT_POPD
26, // TEXT_RS
15, // TEXT_RTN
0, // TEXT_SET
2, // TEXT_ST
4, // TEXT_ST
6, // TEXT_STD
8, // TEXT_STP
10, // TEXT_SUB
};
// clang-format on

using EntryPage = entry::TableBase<Entry>;
Expand Down Expand Up @@ -699,6 +760,9 @@ static constexpr EntryPage W65C816_PAGES[] PROGMEM = {
{ARRAY_RANGE(W65C02S_TABLE), ARRAY_RANGE(W65C02S_INDEX)},
{ARRAY_RANGE(W65C816_TABLE), ARRAY_RANGE(W65C816_INDEX)},
};
static constexpr EntryPage SWEET16_PAGES[] PROGMEM = {
{ARRAY_RANGE(SWEET16_TABLE), ARRAY_RANGE(SWEET16_INDEX)},
};

using Cpu = entry::CpuBase<CpuType, EntryPage>;

Expand All @@ -708,6 +772,7 @@ static constexpr Cpu CPU_TABLE[] PROGMEM = {
{R65C02, TEXT_CPU_65C02, ARRAY_RANGE(R65C02_PAGES)},
{W65C02S, TEXT_CPU_W65C02S, ARRAY_RANGE(W65C02S_PAGES)},
{W65C816, TEXT_CPU_65816, ARRAY_RANGE(W65C816_PAGES)},
{SWEET16, TEXT_CPU_SWEET16, ARRAY_RANGE(SWEET16_PAGES)},
};

static const Cpu *cpu(CpuType cpuType) {
Expand All @@ -721,11 +786,12 @@ static bool acceptMode(AddrMode opr, AddrMode table) {
return table == M_IMX || table == M_IM8;
if (opr == M_DPG)
return table == M_ABS || table == M_REL || table == M_ABSL || table == M_LREL ||
table == M_BANK;
table == M_BANK || table == M_IM16;
if (opr == M_ABS)
return table == M_REL || table == M_ABSL || table == M_LREL || table == M_BANK;
return table == M_REL || table == M_ABSL || table == M_LREL || table == M_BANK ||
table == M_IM16;
if (opr == M_ABSL)
return table == M_REL || table == M_LREL || table == M_BANK;
return table == M_REL || table == M_LREL || table == M_BANK || table == M_IM16;
if (opr == I_DPG)
return table == I_ABS;
if (opr == L_DPG)
Expand All @@ -746,11 +812,13 @@ Error TableMos6502::searchName(CpuType cpuType, AsmInsn &insn) const {

static bool matchOpCode(DisInsn &insn, const Entry *entry, const EntryPage *page) {
UNUSED(page);
const auto opCode = entry->opCode();
if (insn.opCode() != opCode || opCode == TableMos6502::WDM)
auto opc = insn.opCode();
const auto mode1 = entry->flags().mode1();
if (mode1 == M_REGR || mode1 == I_REGR)
opc &= ~0xF;
if (opc != entry->opCode() || opc == TableMos6502::WDM)
return false;
const auto mode = entry->flags().mode1();
if (mode == L_ABS || mode == L_DPG)
if (mode1 == L_ABS || mode1 == L_DPG)
return insn.allowIndirectLong();
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions src/text_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ constexpr char TEXT_ASRA[] PROGMEM = "ASRA";
constexpr char TEXT_ASRB[] PROGMEM = "ASRB";
constexpr char TEXT_ASR[] PROGMEM = "ASR";
constexpr char TEXT_BAND[] PROGMEM = "BAND";
constexpr char TEXT_BC[] PROGMEM = "BC";
constexpr char TEXT_BCC[] PROGMEM = "BCC";
constexpr char TEXT_BCLR[] PROGMEM = "BCLR";
constexpr char TEXT_BCS[] PROGMEM = "BCS";
Expand All @@ -79,6 +80,7 @@ constexpr char TEXT_BLS[] PROGMEM = "BLS";
constexpr char TEXT_BLT[] PROGMEM = "BLT";
constexpr char TEXT_BMI[] PROGMEM = "BMI";
constexpr char TEXT_BM[] PROGMEM = "BM";
constexpr char TEXT_BNC[] PROGMEM = "BNC";
constexpr char TEXT_BNE[] PROGMEM = "BNE";
constexpr char TEXT_BNZ[] PROGMEM = "BNZ";
constexpr char TEXT_BOR[] PROGMEM = "BOR";
Expand Down Expand Up @@ -143,6 +145,7 @@ constexpr char TEXT_DAA[] PROGMEM = "DAA";
constexpr char TEXT_DAD[] PROGMEM = "DAD";
constexpr char TEXT_DA[] PROGMEM = "DA";
constexpr char TEXT_DAS[] PROGMEM = "DAS";
constexpr char TEXT_DCR[] PROGMEM = "DCR";
constexpr char TEXT_DECA[] PROGMEM = "DECA";
constexpr char TEXT_DECB[] PROGMEM = "DECB";
constexpr char TEXT_DECD[] PROGMEM = "DECD";
Expand Down Expand Up @@ -206,6 +209,7 @@ constexpr char TEXT_INDR[] PROGMEM = "INDR";
constexpr char TEXT_INI[] PROGMEM = "INI";
constexpr char TEXT_INIR[] PROGMEM = "INIR";
constexpr char TEXT_IN[] PROGMEM = "IN";
constexpr char TEXT_INR[] PROGMEM = "INR";
constexpr char TEXT_INSB[] PROGMEM = "INSB";
constexpr char TEXT_INS[] PROGMEM = "INS";
constexpr char TEXT_INSW[] PROGMEM = "INSW";
Expand Down Expand Up @@ -373,6 +377,7 @@ constexpr char TEXT_STC[] PROGMEM = "STC";
constexpr char TEXT_STD[] PROGMEM = "STD";
constexpr char TEXT_STOP[] PROGMEM = "STOP";
constexpr char TEXT_ST[] PROGMEM = "ST";
constexpr char TEXT_STP[] PROGMEM = "STP";
constexpr char TEXT_STR[] PROGMEM = "STR";
constexpr char TEXT_STS[] PROGMEM = "STS";
constexpr char TEXT_STX[] PROGMEM = "STX";
Expand Down
5 changes: 5 additions & 0 deletions src/text_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ extern const char TEXT_ASRA[] PROGMEM;
extern const char TEXT_ASRB[] PROGMEM;
extern const char TEXT_ASR[] PROGMEM;
extern const char TEXT_BAND[] PROGMEM;
extern const char TEXT_BC[] PROGMEM;
extern const char TEXT_BCC[] PROGMEM;
extern const char TEXT_BCLR[] PROGMEM;
extern const char TEXT_BCS[] PROGMEM;
Expand All @@ -82,6 +83,7 @@ extern const char TEXT_BLS[] PROGMEM;
extern const char TEXT_BLT[] PROGMEM;
extern const char TEXT_BMI[] PROGMEM;
extern const char TEXT_BM[] PROGMEM;
extern const char TEXT_BNC[] PROGMEM;
extern const char TEXT_BNE[] PROGMEM;
extern const char TEXT_BNZ[] PROGMEM;
extern const char TEXT_BOR[] PROGMEM;
Expand Down Expand Up @@ -146,6 +148,7 @@ extern const char TEXT_DAA[] PROGMEM;
extern const char TEXT_DAD[] PROGMEM;
extern const char TEXT_DA[] PROGMEM;
extern const char TEXT_DAS[] PROGMEM;
extern const char TEXT_DCR[] PROGMEM;
extern const char TEXT_DECA[] PROGMEM;
extern const char TEXT_DECB[] PROGMEM;
extern const char TEXT_DECD[] PROGMEM;
Expand Down Expand Up @@ -209,6 +212,7 @@ extern const char TEXT_INDR[] PROGMEM;
extern const char TEXT_INI[] PROGMEM;
extern const char TEXT_INIR[] PROGMEM;
extern const char TEXT_IN[] PROGMEM;
extern const char TEXT_INR[] PROGMEM;
extern const char TEXT_INSB[] PROGMEM;
extern const char TEXT_INS[] PROGMEM;
extern const char TEXT_INSW[] PROGMEM;
Expand Down Expand Up @@ -376,6 +380,7 @@ extern const char TEXT_STC[] PROGMEM;
extern const char TEXT_STD[] PROGMEM;
extern const char TEXT_STOP[] PROGMEM;
extern const char TEXT_ST[] PROGMEM;
extern const char TEXT_STP[] PROGMEM;
extern const char TEXT_STR[] PROGMEM;
extern const char TEXT_STS[] PROGMEM;
extern const char TEXT_STX[] PROGMEM;
Expand Down

0 comments on commit 0127d16

Please sign in to comment.