diff --git a/README.adoc b/README.adoc index 9fc85a68..3643530c 100644 --- a/README.adoc +++ b/README.adoc @@ -81,12 +81,12 @@ usage: asm [-o ] [-l ] -C : 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 file -l : list file -S[] : output Motorola S-Record format @@ -126,12 +126,12 @@ usage: dis -C [-o ] [-l ] -C : 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 file -l : list file : file can be Motorola S-Record or Intel HEX format diff --git a/src/asm_mos6502.cpp b/src/asm_mos6502.cpp index 60cf37ad..ed11cd7c 100644 --- a/src/asm_mos6502.cpp +++ b/src/asm_mos6502.cpp @@ -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; } @@ -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()) diff --git a/src/config_mos6502.h b/src/config_mos6502.h index a10cebc8..16173392 100644 --- a/src/config_mos6502.h +++ b/src/config_mos6502.h @@ -28,6 +28,7 @@ enum CpuType : uint8_t { R65C02, W65C02S, W65C816, + SWEET16, }; struct Config : ConfigImpl { diff --git a/src/dis_mos6502.cpp b/src/dis_mos6502.cpp index e616db92..80a7a3dd 100644 --- a/src/dis_mos6502.cpp +++ b/src/dis_mos6502.cpp @@ -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); @@ -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: @@ -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(']'); diff --git a/src/entry_mos6502.h b/src/entry_mos6502.h index 35fcb4f3..4cef9184 100644 --- a/src/entry_mos6502.h +++ b/src/entry_mos6502.h @@ -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 { diff --git a/src/reg_mos6502.cpp b/src/reg_mos6502.cpp index 94188294..5e67b285 100644 --- a/src/reg_mos6502.cpp +++ b/src/reg_mos6502.cpp @@ -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 diff --git a/src/reg_mos6502.h b/src/reg_mos6502.h index a84728b8..fbb940ac 100644 --- a/src/reg_mos6502.h +++ b/src/reg_mos6502.h @@ -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 diff --git a/src/table_mos6502.cpp b/src/table_mos6502.cpp index 5eccc0f7..56f89a31 100644 --- a/src/table_mos6502.cpp +++ b/src/table_mos6502.cpp @@ -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_BRK), + E0(0x0B, TEXT_RS), + E1(0x0C, TEXT_BS, M_REL), +}; +static constexpr uint8_t SWEET16_INDEX[] PROGMEM = { + 9, // TEXT_ADD + 18, // TEXT_BC + 20, // TEXT_BM + 23, // TEXT_BM1 + 17, // TEXT_BNC + 24, // TEXT_BNM1 + 22, // TEXT_BNZ + 19, // TEXT_BP + 16, // TEXT_BR + 25, // TEXT_BRK + 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; @@ -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; @@ -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) { @@ -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) @@ -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; } diff --git a/src/text_common.cpp b/src/text_common.cpp index e5b42139..7645f3ff 100644 --- a/src/text_common.cpp +++ b/src/text_common.cpp @@ -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"; @@ -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"; @@ -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"; @@ -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"; @@ -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"; diff --git a/src/text_common.h b/src/text_common.h index 1cc778fc..c01ca2d3 100644 --- a/src/text_common.h +++ b/src/text_common.h @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; diff --git a/src/text_f3850.cpp b/src/text_f3850.cpp index 08d400fa..244076de 100644 --- a/src/text_f3850.cpp +++ b/src/text_f3850.cpp @@ -33,10 +33,10 @@ constexpr char TEXT_CPU_3850[] PROGMEM = "3850"; constexpr char TEXT_AMD[] PROGMEM = "AMD"; constexpr char TEXT_AS[] PROGMEM = "AS"; constexpr char TEXT_ASD[] PROGMEM = "ASD"; -constexpr char TEXT_BC[] PROGMEM = "BC"; +// constexpr char TEXT_BC[] PROGMEM = "BC"; constexpr char TEXT_BF[] PROGMEM = "BF"; // constexpr char TEXT_BM[] PROGMEM = "BM"; -constexpr char TEXT_BNC[] PROGMEM = "BNC"; +// constexpr char TEXT_BNC[] PROGMEM = "BNC"; constexpr char TEXT_BNO[] PROGMEM = "BNO"; // constexpr char TEXT_BNZ[] PROGMEM = "BNZ"; // constexpr char TEXT_BP[] PROGMEM = "BP"; diff --git a/src/text_f3850.h b/src/text_f3850.h index fcd5a44c..6357030b 100644 --- a/src/text_f3850.h +++ b/src/text_f3850.h @@ -36,10 +36,10 @@ using common::TEXT_AM; extern const char TEXT_AMD[] PROGMEM; extern const char TEXT_AS[] PROGMEM; extern const char TEXT_ASD[] PROGMEM; -extern const char TEXT_BC[] PROGMEM; +using common::TEXT_BC; extern const char TEXT_BF[] PROGMEM; using common::TEXT_BM; -extern const char TEXT_BNC[] PROGMEM; +using common::TEXT_BNC; extern const char TEXT_BNO[] PROGMEM; using common::TEXT_BNZ; using common::TEXT_BP; diff --git a/src/text_i8080.cpp b/src/text_i8080.cpp index 457203c1..e5637f16 100644 --- a/src/text_i8080.cpp +++ b/src/text_i8080.cpp @@ -47,13 +47,13 @@ constexpr char TEXT_CPO[] PROGMEM = "CPO"; constexpr char TEXT_CZ[] PROGMEM = "CZ"; // constexpr char TEXT_DAA[] PROGMEM = "DAA"; // constexpr char TEXT_DAD[] PROGMEM = "DAD"; -constexpr char TEXT_DCR[] PROGMEM = "DCR"; +// constexpr char TEXT_DCR[] PROGMEM = "DCR"; constexpr char TEXT_DCX[] PROGMEM = "DCX"; // constexpr char TEXT_DI[] PROGMEM = "DI"; // constexpr char TEXT_EI[] PROGMEM = "EI"; // constexpr char TEXT_HLT[] PROGMEM = "HLT"; // constexpr char TEXT_IN[] PROGMEM = "IN"; -constexpr char TEXT_INR[] PROGMEM = "INR"; +// constexpr char TEXT_INR[] PROGMEM = "INR"; // constexpr char TEXT_INX[] PROGMEM = "INX"; // constexpr char TEXT_JC[] PROGMEM = "JC"; constexpr char TEXT_JM[] PROGMEM = "JM"; diff --git a/src/text_i8080.h b/src/text_i8080.h index e91c1cd4..1058c6d1 100644 --- a/src/text_i8080.h +++ b/src/text_i8080.h @@ -50,13 +50,13 @@ extern const char TEXT_CPO[] PROGMEM; extern const char TEXT_CZ[] PROGMEM; using common::TEXT_DAA; using common::TEXT_DAD; -extern const char TEXT_DCR[] PROGMEM; +using common::TEXT_DCR; extern const char TEXT_DCX[] PROGMEM; using common::TEXT_DI; using common::TEXT_EI; using common::TEXT_HLT; using common::TEXT_IN; -extern const char TEXT_INR[] PROGMEM; +using common::TEXT_INR; using common::TEXT_INX; using common::TEXT_JC; extern const char TEXT_JM[] PROGMEM; diff --git a/src/text_mos6502.cpp b/src/text_mos6502.cpp index 9334c29f..1d9e1a6d 100644 --- a/src/text_mos6502.cpp +++ b/src/text_mos6502.cpp @@ -21,7 +21,7 @@ namespace text { namespace mos6502 { // clang-format off -constexpr char TEXT_MOS6502_LIST[] PROGMEM = "MOS6502, R65C02, G65SC02, W65C02S, W65C816S"; +constexpr char TEXT_MOS6502_LIST[] PROGMEM = "MOS6502, R65C02, G65SC02, W65C02S, W65C816S, SWEET16"; constexpr char TEXT_CPU_6502[] PROGMEM = "6502"; constexpr char TEXT_CPU_65SC02[] PROGMEM = "65SC02"; constexpr char TEXT_CPU_65C02[] PROGMEM = "65C02"; @@ -32,6 +32,7 @@ constexpr char TEXT_CPU_R65C02[] PROGMEM = "R65C02"; constexpr char TEXT_CPU_G65SC02[] PROGMEM = "G65SC02"; constexpr char TEXT_CPU_65C816[] PROGMEM = "65C816"; constexpr char TEXT_CPU_65C816S[] PROGMEM = "65C816S"; +constexpr char TEXT_CPU_SWEET16[] PROGMEM = "SWEET16"; // MOS6502 instructions // constexpr char TEXT_ADC[] PROGMEM = "ADC"; @@ -182,6 +183,15 @@ constexpr char TEXT_ORAL[] PROGMEM = "ORAL"; constexpr char TEXT_SBCL[] PROGMEM = "SBCL"; constexpr char TEXT_STAL[] PROGMEM = "STAL"; +constexpr char TEXT_BM1[] PROGMEM = "BM1"; +constexpr char TEXT_BNM1[] PROGMEM = "BNM1"; +constexpr char TEXT_BR[] PROGMEM = "BR"; +constexpr char TEXT_BS[] PROGMEM = "BS"; +constexpr char TEXT_CPR[] PROGMEM = "CPR"; +constexpr char TEXT_POPD[] PROGMEM = "POPD"; +constexpr char TEXT_RS[] PROGMEM = "RS"; +constexpr char TEXT_RTN[] PROGMEM = "RTN"; + constexpr char OPT_BOOL_LONGA[] PROGMEM = "longa"; constexpr char OPT_DESC_LONGA[] PROGMEM = "enable 16-bit accumulator"; constexpr char OPT_BOOL_LONGI[] PROGMEM = "longi"; diff --git a/src/text_mos6502.h b/src/text_mos6502.h index 0d2e7d6a..c29cf9e1 100644 --- a/src/text_mos6502.h +++ b/src/text_mos6502.h @@ -35,6 +35,7 @@ extern const char TEXT_CPU_R65C02[] PROGMEM; extern const char TEXT_CPU_G65SC02[] PROGMEM; extern const char TEXT_CPU_65C816[] PROGMEM; extern const char TEXT_CPU_65C816S[] PROGMEM; +extern const char TEXT_CPU_SWEET16[] PROGMEM; // MOS6502 instructions using common::TEXT_ADC; @@ -142,7 +143,7 @@ extern const char TEXT_SMB7[] PROGMEM; // W65C02 instructions -extern const char TEXT_STP[] PROGMEM; +extern const char TEXT_STP[] PROGMEM; using common::TEXT_WAI; // W65C816 instructions @@ -185,6 +186,31 @@ extern const char TEXT_ORAL[] PROGMEM; extern const char TEXT_SBCL[] PROGMEM; extern const char TEXT_STAL[] PROGMEM; +using common::TEXT_ADD; +using common::TEXT_BC; +extern const char TEXT_BM1[] PROGMEM; +using common::TEXT_BM; +using common::TEXT_BNC; +extern const char TEXT_BNM1[] PROGMEM; +using common::TEXT_BNZ; +using common::TEXT_BP; +extern const char TEXT_BR[] PROGMEM; +extern const char TEXT_BS[] PROGMEM; +using common::TEXT_BZ; +extern const char TEXT_CPR[] PROGMEM; +using common::TEXT_DCR; +using common::TEXT_INR; +using common::TEXT_LDD; +using common::TEXT_LD; +extern const char TEXT_POPD[] PROGMEM; +using common::TEXT_POP; +extern const char TEXT_RS[] PROGMEM; +extern const char TEXT_RTN[] PROGMEM; +using common::TEXT_SET; +using common::TEXT_STD; +using common::TEXT_ST; +using common::TEXT_SUB; + extern const char OPT_BOOL_LONGA[] PROGMEM; extern const char OPT_DESC_LONGA[] PROGMEM; extern const char OPT_BOOL_LONGI[] PROGMEM; diff --git a/test/test_asm_mos6502.cpp b/test/test_asm_mos6502.cpp index b6399512..064e5be5 100644 --- a/test/test_asm_mos6502.cpp +++ b/test/test_asm_mos6502.cpp @@ -40,6 +40,10 @@ static bool w65c816() { return strcmp_P("65816", assembler.config().cpu_P()) == 0; } +static bool sweet16() { + return strcmp_P("SWEET16", assembler.config().cpu_P()) == 0; +} + static void set_up() { assembler.reset(); } @@ -1098,6 +1102,55 @@ static void test_error() { } } +static void test_sweet16() { + TEST("RTN", 0x00); + TEST("BRK", 0x0A); + TEST("RS", 0x0B); + + ATEST(0x1000, "BR $1002", 0x01, 0x00); + ATEST(0x1000, "BNC $1000", 0x02, 0xFE); + ATEST(0x1000, "BC $1004", 0x03, 0x02); + ATEST(0x1000, "BP $1081", 0x04, 0x7F); + ATEST(0x1000, "BM $0F82", 0x05, 0x80); + ATEST(0x1000, "BZ $1081", 0x06, 0x7F); + ATEST(0x1000, "BNZ $0F82", 0x07, 0x80); + ATEST(0x1000, "BM1 $1081", 0x08, 0x7F); + ATEST(0x1000, "BNM1 $0F82", 0x09, 0x80); + AERRT(0x0000, "BR $FF82", OVERFLOW_RANGE, "$FF82", 0x01, 0x80); + AERRT(0xFFFE, "BNC $0000", OVERFLOW_RANGE, "$0000", 0x02, 0x00); + AERRT(0xFFF0, "BC $0071", OVERFLOW_RANGE, "$0071", 0x03, 0x7F); + AERRT(0x0000, "BP *-126", OVERFLOW_RANGE, "*-126", 0x04, 0x80); + AERRT(0xFFFE, "BM *+2", OVERFLOW_RANGE, "*+2", 0x05, 0x00); + AERRT(0xFFF0, "BZ *+129", OVERFLOW_RANGE, "*+129", 0x06, 0x7F); + + TEST("SET R0, $1234", 0x10, 0x34, 0x12); + TEST("SET R1, 0", 0x11, 0x00, 0x00); + TEST("SET R2, 65535", 0x12, 0xFF, 0xFF); + TEST("SET R3, $FFFF", 0x13, 0xFF, 0xFF); + ERRT("SET R4, 65536", OVERFLOW_RANGE, "65536", 0x14, 0x00, 0x00); + ERRT("SET R5, $10000", OVERFLOW_RANGE, "$10000", 0x15, 0x00, 0x00); + TEST("SET R6, -32768", 0x16, 0x00, 0x80); + ERRT("SET R7, -32769", OVERFLOW_RANGE, "-32769", 0x17, 0xFF, 0x7F); + TEST("SET R8, -1", 0x18, 0xFF, 0xFF); + TEST("SET R15, $1234", 0x1F, 0x34, 0x12); + ERRT("SET R16, 0", OPERAND_NOT_ALLOWED, "R16, 0"); + + TEST("LD R0", 0x20); + TEST("ST R1", 0x31); + TEST("LD @R2", 0x42); + TEST("ST @R3", 0x53); + TEST("LDD @R4", 0x64); + TEST("STD @R5", 0x75); + TEST("POP @R6", 0x86); + TEST("STP @R7", 0x97); + TEST("ADD R8", 0xA8); + TEST("SUB R9", 0xB9); + TEST("POPD @R10", 0xCA); + TEST("CPR R11", 0xDB); + TEST("INR R12", 0xEC); + TEST("DCR R13", 0xFD); +} + static void test_data_constant() { TEST(".BYTE -128, 255", 0x80, 0xFF); TEST(".BYTE 'A', '\"'", 0x41, 0x22); @@ -1162,27 +1215,31 @@ static void test_data_constant() { void run_tests(const char *cpu) { assembler.setCpu(cpu); - RUN_TEST(test_impl); - RUN_TEST(test_accm); - RUN_TEST(test_imm); - RUN_TEST(test_zpg); - RUN_TEST(test_zpg_indexed); - RUN_TEST(test_zpg_long); - RUN_TEST(test_sp_rel); - RUN_TEST(test_abs); - RUN_TEST(test_abs_long); - RUN_TEST(test_abs_indexed); - RUN_TEST(test_abs_idir); - RUN_TEST(test_zpg_idir); - RUN_TEST(test_abs_indexed_idir); - RUN_TEST(test_zpg_indexed_idir); - RUN_TEST(test_zpg_idir_indexed); - RUN_TEST(test_rel); - RUN_TEST(test_bitop); - RUN_TEST(test_zpg_rel); - RUN_TEST(test_comment); - RUN_TEST(test_undef); - RUN_TEST(test_error); + if (sweet16()) { + RUN_TEST(test_sweet16); + } else { + RUN_TEST(test_impl); + RUN_TEST(test_accm); + RUN_TEST(test_imm); + RUN_TEST(test_zpg); + RUN_TEST(test_zpg_indexed); + RUN_TEST(test_zpg_long); + RUN_TEST(test_sp_rel); + RUN_TEST(test_abs); + RUN_TEST(test_abs_long); + RUN_TEST(test_abs_indexed); + RUN_TEST(test_abs_idir); + RUN_TEST(test_zpg_idir); + RUN_TEST(test_abs_indexed_idir); + RUN_TEST(test_zpg_indexed_idir); + RUN_TEST(test_zpg_idir_indexed); + RUN_TEST(test_rel); + RUN_TEST(test_bitop); + RUN_TEST(test_zpg_rel); + RUN_TEST(test_comment); + RUN_TEST(test_undef); + RUN_TEST(test_error); + } RUN_TEST(test_data_constant); } diff --git a/test/test_dis_mos6502.cpp b/test/test_dis_mos6502.cpp index d9f3a648..86eeb5f8 100644 --- a/test/test_dis_mos6502.cpp +++ b/test/test_dis_mos6502.cpp @@ -44,6 +44,10 @@ static bool w65c816() { return strcmp_P("65816", disassembler.config().cpu_P()) == 0; } +static bool sweet16() { + return strcmp_P("SWEET16", disassembler.config().cpu_P()) == 0; +} + static void set_up() { disassembler.reset(); disassembler.setOption("relative", "no"); @@ -1005,37 +1009,94 @@ static void test_illegal_w65c02s() { for (const auto opc : illegals) UNKN(opc); } + +static void test_sweet16() { + TEST("RTN", "", 0x00); + TEST("BRK", "", 0x0A); + TEST("RS", "", 0x0B); + + ATEST(0x1000, "BR", "$1002", 0x01, 0x00); + ATEST(0x1000, "BNC", "$1000", 0x02, 0xFE); + ATEST(0x1000, "BC", "$1004", 0x03, 0x02); + ATEST(0x1000, "BP", "$1081", 0x04, 0x7F); + ATEST(0x1000, "BM", "$0F82", 0x05, 0x80); + ATEST(0x1000, "BZ", "$1081", 0x06, 0x7F); + ATEST(0x1000, "BNZ", "$0F82", 0x07, 0x80); + ATEST(0x1000, "BM1", "$1081", 0x08, 0x7F); + ATEST(0x1000, "BNM1", "$0F82", 0x09, 0x80); + AERRT(0x0000, "BR", "$FF82", OVERFLOW_RANGE, "$FF82", 0x01, 0x80); + AERRT(0xFFFE, "BNC", "$0000", OVERFLOW_RANGE, "$0000", 0x02, 0x00); + AERRT(0xFFF0, "BC", "$0071", OVERFLOW_RANGE, "$0071", 0x03, 0x7F); + AERRT(0x0000, "BP", "$FF82", OVERFLOW_RANGE, "$FF82", 0x04, 0x80); + AERRT(0xFFFE, "BM", "$0000", OVERFLOW_RANGE, "$0000", 0x05, 0x00); + AERRT(0xFFF0, "BZ", "$0071", OVERFLOW_RANGE, "$0071", 0x06, 0x7F); + + TEST("SET", "R0, $1234", 0x10, 0x34, 0x12); + TEST("SET", "R1, 0", 0x11, 0x00, 0x00); + TEST("SET", "R2, $FFFF", 0x12, 0xFF, 0xFF); + TEST("SET", "R3, $FFFF", 0x13, 0xFF, 0xFF); + TEST("SET", "R6, $8000", 0x16, 0x00, 0x80); + TEST("SET", "R7, $7FFF", 0x17, 0xFF, 0x7F); + TEST("SET", "R8, $FFFF", 0x18, 0xFF, 0xFF); + TEST("SET", "R15, $1234", 0x1F, 0x34, 0x12); + + TEST("LD", "R0", 0x20); + TEST("ST", "R1", 0x31); + TEST("LD", "@R2", 0x42); + TEST("ST", "@R3", 0x53); + TEST("LDD", "@R4", 0x64); + TEST("STD", "@R5", 0x75); + TEST("POP", "@R6", 0x86); + TEST("STP", "@R7", 0x97); + TEST("ADD", "R8", 0xA8); + TEST("SUB", "R9", 0xB9); + TEST("POPD", "@R10", 0xCA); + TEST("CPR", "R11", 0xDB); + TEST("INR", "R12", 0xEC); + TEST("DCR", "R13", 0xFD); +} + +static void test_sweet16_illegal() { + UNKN(0x0D); + UNKN(0x0E); + UNKN(0x0F); +} // clang-format on void run_tests(const char *cpu) { disassembler.setCpu(cpu); - RUN_TEST(test_impl); - RUN_TEST(test_accm); - RUN_TEST(test_imm); - RUN_TEST(test_long_imm); - RUN_TEST(test_zpg); - RUN_TEST(test_zpg_indexed); - RUN_TEST(test_abs); - RUN_TEST(test_sp_rel); - RUN_TEST(test_zpg_long); - RUN_TEST(test_abs_long); - RUN_TEST(test_abs_indexed); - RUN_TEST(test_abs_idir); - RUN_TEST(test_zpg_idir); - RUN_TEST(test_abs_indexed_idir); - RUN_TEST(test_zpg_indexed_idir); - RUN_TEST(test_zpg_idir_indexed); - RUN_TEST(test_rel); - RUN_TEST(test_bitop); - RUN_TEST(test_zpg_rel); - if (m6502()) - RUN_TEST(test_illegal_mos6502); - if (g65sc02()) - RUN_TEST(test_illegal_g65sc02); - if (r65c02()) - RUN_TEST(test_illegal_r65c02); - if (w65c02s()) - RUN_TEST(test_illegal_w65c02s); + if (sweet16()) { + RUN_TEST(test_sweet16); + RUN_TEST(test_sweet16_illegal); + } else { + RUN_TEST(test_impl); + RUN_TEST(test_accm); + RUN_TEST(test_imm); + RUN_TEST(test_long_imm); + RUN_TEST(test_zpg); + RUN_TEST(test_zpg_indexed); + RUN_TEST(test_abs); + RUN_TEST(test_sp_rel); + RUN_TEST(test_zpg_long); + RUN_TEST(test_abs_long); + RUN_TEST(test_abs_indexed); + RUN_TEST(test_abs_idir); + RUN_TEST(test_zpg_idir); + RUN_TEST(test_abs_indexed_idir); + RUN_TEST(test_zpg_indexed_idir); + RUN_TEST(test_zpg_idir_indexed); + RUN_TEST(test_rel); + RUN_TEST(test_bitop); + RUN_TEST(test_zpg_rel); + if (m6502()) + RUN_TEST(test_illegal_mos6502); + if (g65sc02()) + RUN_TEST(test_illegal_g65sc02); + if (r65c02()) + RUN_TEST(test_illegal_r65c02); + if (w65c02s()) + RUN_TEST(test_illegal_w65c02s); + } } // Local Variables: