From dabe59ae6adda06d756a2e29bd5d1995b95e6ff8 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 16 Dec 2024 15:45:10 +0900 Subject: [PATCH] [MC6805] Add MC68HC08 variation --- README.md | 28 +- README_.adoc | 28 +- src/Makefile.arch | 3 +- src/asm_mc6805.cpp | 60 ++++- src/config_mc6805.h | 3 +- src/dis_mc6805.cpp | 49 +++- src/entry_mc6805.h | 21 +- src/insn_mc6805.h | 10 +- src/reg_mc6805.cpp | 11 +- src/reg_mc6805.h | 1 + src/table_mc6805.cpp | 218 ++++++++++++++- src/table_mc6805.h | 1 + src/text_cdp1802.cpp | 2 +- src/text_cdp1802.h | 2 +- src/text_common.cpp | 7 + src/text_common.h | 7 + src/text_mc6800.cpp | 12 +- src/text_mc6800.h | 12 +- src/text_mc6805.cpp | 35 ++- src/text_mc6805.h | 33 +++ test/autogen/gen_mc68hc08.asm | 448 +++++++++++++++++++++++++++++++ test/reference/test_mc68hc05.asm | 235 +--------------- test/reference/test_mc68hc05.inc | 252 +++++++++++++++++ test/reference/test_mc68hc05.s19 | 32 +-- test/reference/test_mc68hc08.asm | 19 ++ test/reference/test_mc68hc08.inc | 111 ++++++++ test/reference/test_mc68hc08.s19 | 42 +++ test/test_asm_mc6805.cpp | 272 +++++++++++++++++-- test/test_dis_mc6805.cpp | 179 ++++++++++-- 29 files changed, 1744 insertions(+), 389 deletions(-) create mode 100644 test/autogen/gen_mc68hc08.asm create mode 100644 test/reference/test_mc68hc05.inc create mode 100644 test/reference/test_mc68hc08.asm create mode 100644 test/reference/test_mc68hc08.inc create mode 100644 test/reference/test_mc68hc08.s19 diff --git a/README.md b/README.md index 03620adb1..ce1abd5f9 100644 --- a/README.md +++ b/README.md @@ -75,13 +75,13 @@ It can generate Intel HEX or Motorola S-Record output. libasm assembler (version 1.6.50) 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 - MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 NS32032 - MN1610 MN1613 MN1613A J11 T11 + MC6800 MB8861 MC6801 HD6301 MC68HC11 MC6805 MC146805 MC68HC05 + MC68HC08 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 MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 + NS32032 MN1610 MN1613 MN1613A J11 T11 -o : output file -l : list file -S[] : output Motorola S-Record format @@ -112,13 +112,13 @@ It can read Intel HEX or Motorola S-Record input. libasm disassembler (version 1.6.50) 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 - MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 NS32032 - MN1610 MN1613 MN1613A J11 T11 + MC6800 MB8861 MC6801 HD6301 MC68HC11 MC6805 MC146805 MC68HC05 + MC68HC08 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 MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 + NS32032 MN1610 MN1613 MN1613A J11 T11 -o : output file -l : list file : file can be Motorola S-Record or Intel HEX format diff --git a/README_.adoc b/README_.adoc index b8a7f41d7..8eb9d3ba5 100644 --- a/README_.adoc +++ b/README_.adoc @@ -79,13 +79,13 @@ It can generate Intel HEX or Motorola S-Record output. libasm assembler (version 1.6.50) 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 - MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 NS32032 - MN1610 MN1613 MN1613A J11 T11 + MC6800 MB8861 MC6801 HD6301 MC68HC11 MC6805 MC146805 MC68HC05 + MC68HC08 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 MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 + NS32032 MN1610 MN1613 MN1613A J11 T11 -o : output file -l : list file -S[] : output Motorola S-Record format @@ -118,13 +118,13 @@ It can read Intel HEX or Motorola S-Record input. libasm disassembler (version 1.6.50) 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 - MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 NS32032 - MN1610 MN1613 MN1613A J11 T11 + MC6800 MB8861 MC6801 HD6301 MC68HC11 MC6805 MC146805 MC68HC05 + MC68HC08 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 MC68010 TMS9900 TMS9980 TMS9995 TMS99105 TMS99110 Z8001 Z8002 + NS32032 MN1610 MN1613 MN1613A J11 T11 -o : output file -l : list file : file can be Motorola S-Record or Intel HEX format diff --git a/src/Makefile.arch b/src/Makefile.arch index 367b7deab..bb85708b6 100644 --- a/src/Makefile.arch +++ b/src/Makefile.arch @@ -60,7 +60,7 @@ TGT_ins8060 = ins8060 TGT_ins8070 = ins8070 TGT_mc68000 = mc68000 mc68010 m68k m68k10 TGT_mc6800 = mc6800 mb8861 mc6801 mc68hc11 hd6301 -TGT_mc6805 = mc68hc05 +TGT_mc6805 = mc68hc05 mc68hc08 TGT_mc6809 = mc6809 hd6309 TGT_mn1610 = mn1610 mn1613 TGT_mos6502 = mos6502 g65sc02 r65c02 w65c02s w65c816 @@ -110,6 +110,7 @@ CPU_mc6800 = 6800 CPU_mc6801 = 6801 CPU_mc6809 = 6809 CPU_mc68hc05 = 68HC05 +CPU_mc68hc08 = 68HC08 CPU_mc68hc11 = 6811 CPU_mn1610 = MN1610 CPU_mn1613 = MN1613 diff --git a/src/asm_mc6805.cpp b/src/asm_mc6805.cpp index 0de724a57..e8d02345c 100644 --- a/src/asm_mc6805.cpp +++ b/src/asm_mc6805.cpp @@ -15,7 +15,6 @@ */ #include "asm_mc6805.h" - #include "reg_mc6805.h" #include "table_mc6805.h" #include "text_common.h" @@ -61,7 +60,7 @@ void AsmMc6805::reset() { } AddressWidth AsmMc6805::addressWidth() const { - return AddressWidth(_pc_bits == 0 ? 13 : _pc_bits); + return cpuType() == MC68HC08 ? ADDRESS_16BIT : AddressWidth(_pc_bits == 0 ? 13 : _pc_bits); } Error AsmMc6805::setPcBits(int32_t value) { @@ -86,14 +85,19 @@ Error AsmMc6805::parseOperand(StrScanner &scan, Operand &op) const { } if (p.expect(',')) { - const auto reg = parseRegName(p); - if (reg == REG_X) { + if (parseRegName(p) == REG_X) { op.mode = M_IX0; scan = p; return OK; } return op.setError(scan, UNKNOWN_OPERAND); } + auto r = p; + if (parseRegName(r) == REG_X) { + op.mode = r.expect('+') ? M_IX0P : M_REGX; + scan = r; + return OK; + } op.size = 0; if (p.expect('<')) { @@ -101,6 +105,7 @@ Error AsmMc6805::parseOperand(StrScanner &scan, Operand &op) const { } else if (p.expect('>')) { op.size = 16; } + const auto disp = p; op.val = parseInteger(p, op); if (op.hasError()) return op.getError(); @@ -109,14 +114,30 @@ Error AsmMc6805::parseOperand(StrScanner &scan, Operand &op) const { if (a.skipSpaces().expect(',')) { const auto reg = parseRegName(a.skipSpaces()); if (reg == REG_X) { + const auto plus = a.expect('+'); if (op.size == 8) { - op.mode = M_IDX; + op.mode = plus ? M_IX1P : M_IX1; } else if (op.size == 16) { op.mode = M_IX2; } else if (op.val.isZero()) { - op.mode = M_IX0; + op.mode = plus ? M_IX0P : M_IX0; + } else if (!op.val.overflow(UINT8_MAX)) { + op.mode = plus ? M_IX1P : M_IX1; } else { - op.mode = op.val.overflow(UINT8_MAX) ? M_IX2 : M_IDX; + op.mode = M_IX2; + } + if (plus && op.mode == M_IX2) + return op.setError(disp, OVERFLOW_RANGE); + scan = a; + return OK; + } + if (reg == REG_SP) { + if (op.size == 8) { + op.mode = M_SP1; + } else if (op.size == 16) { + op.mode = M_SP2; + } else { + op.mode = op.val.overflow(UINT8_MAX) ? M_SP2 : M_SP1; } scan = a; return OK; @@ -171,7 +192,7 @@ void AsmMc6805::emitOperand(AsmInsn &insn, AddrMode mode, const Operand &op) con case M_IX2: insn.embed(0xD0); goto ix2; - case M_IDX: + case M_IX1: insn.embed(0xE0); goto idx; default: // M_IX0 @@ -186,7 +207,7 @@ void AsmMc6805::emitOperand(AsmInsn &insn, AddrMode mode, const Operand &op) con case M_BNO: insn.embed(0x30); goto dir; - case M_IDX: + case M_IX1: insn.embed(0x60); goto idx; default: // M_IX0 @@ -196,13 +217,17 @@ void AsmMc6805::emitOperand(AsmInsn &insn, AddrMode mode, const Operand &op) con break; case M_DIR: dir: - case M_IDX: + case M_IX1: + case M_IX1P: + case M_SP1: idx: if (op.val.overflow(UINT8_MAX)) insn.setErrorIf(op, OVERFLOW_RANGE); insn.emitOperand8(op.val.getUnsigned()); break; case M_IX2: + case M_SP2: + case M_IM16: ix2: insn.emitOperand16(op.val.getUnsigned()); break; @@ -214,13 +239,19 @@ void AsmMc6805::emitOperand(AsmInsn &insn, AddrMode mode, const Operand &op) con break; case M_REL: return emitRelative(insn, op); + case M_SIM8: + if (op.val.overflowInt8()) + insn.setErrorIf(op, OVERFLOW_RANGE); + // Fall-through case M_IMM: imm: if (op.val.overflowUint8()) insn.setErrorIf(op, OVERFLOW_RANGE); insn.emitOperand8(op.val.getUnsigned()); break; - case M_BNO: // handled in encodeImpl(Insn) + case M_BNO: // handled in encodeImpl(Insn) + case M_IX0P: // silently ignore + case M_REGX: // silently ignore default: break; } @@ -254,6 +285,13 @@ Error AsmMc6805::encodeImpl(StrScanner &scan, Insn &_insn) const { return _insn.setError(insn); } +void AsmInsn::emitInsn() { + uint_fast8_t pos = 0; + if (hasPrefix()) + emitByte(prefix(), pos++); + emitByte(opCode(), pos++); +} + } // namespace mc6805 } // namespace libasm diff --git a/src/config_mc6805.h b/src/config_mc6805.h index c211f4c6a..0bc441835 100644 --- a/src/config_mc6805.h +++ b/src/config_mc6805.h @@ -26,9 +26,10 @@ enum CpuType : uint8_t { MC6805, MC146805, MC68HC05, + MC68HC08, }; -struct Config : ConfigImpl { +struct Config : ConfigImpl { Config(const InsnTable &table) : ConfigImpl(table, MC6805) {} }; diff --git a/src/dis_mc6805.cpp b/src/dis_mc6805.cpp index f92b7885b..74fa1f326 100644 --- a/src/dis_mc6805.cpp +++ b/src/dis_mc6805.cpp @@ -15,7 +15,6 @@ */ #include "dis_mc6805.h" - #include "reg_mc6805.h" #include "table_mc6805.h" @@ -85,18 +84,22 @@ void DisMc6805::decodeExtended(DisInsn &insn, StrBuffer &out) const { void DisMc6805::decodeIndexed(DisInsn &insn, StrBuffer &out, AddrMode mode) const { if (mode == M_IX0) { outRegName(out.letter(','), REG_X); - } else if (mode == M_IX2) { - const uint16_t disp16 = insn.readUint16(); - if (disp16 < 0x100) - out.letter('>'); - outAbsAddr(out, disp16, ADDRESS_16BIT).letter(','); - outRegName(out, REG_X); - } else { + } else if (mode == M_IX0P) { + outRegName(out, REG_X).letter('+'); + } else if (mode == M_IX1 || mode == M_IX1P || mode == M_SP1) { const uint8_t disp8 = insn.readByte(); if (disp8 == 0) out.letter('<'); outDec(out, disp8, 8).letter(','); - outRegName(out, REG_X); + outRegName(out, mode == M_SP1 ? REG_SP : REG_X); + if (mode == M_IX1P) + out.letter('+'); + } else if (mode == M_IX2 || mode == M_SP2) { + const uint16_t disp16 = insn.readUint16(); + if (disp16 < 0x100) + out.letter('>'); + outAbsAddr(out, disp16, ADDRESS_16BIT).letter(','); + outRegName(out, mode == M_SP2 ? REG_SP : REG_X); } } @@ -127,7 +130,7 @@ void DisMc6805::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) cons break; case 0x60: case 0xE0: - decodeIndexed(insn, out, M_IDX); + decodeIndexed(insn, out, M_IX1); break; default: decodeIndexed(insn, out, M_IX0); @@ -141,11 +144,18 @@ void DisMc6805::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) cons break; case M_EXT: return decodeExtended(insn, out); - case M_IDX: + case M_IX1: case M_IX0: case M_IX2: + case M_IX0P: + case M_IX1P: + case M_SP1: + case M_SP2: decodeIndexed(insn, out, mode); break; + case M_REGX: + outRegName(out, REG_X); // only for DBNZ X,rel8 + break; case M_REL: decodeRelative(insn, out); break; @@ -153,6 +163,14 @@ void DisMc6805::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) cons out.letter('#'); outHex(out, insn.readByte(), 8); break; + case M_IM16: + out.letter('#'); + outHex(out, insn.readUint16(), 16); + break; + case M_SIM8: + out.letter('#'); + outHex(out, insn.readByte(), -8); + break; case M_BNO: outHex(out, (insn.opCode() >> 1) & 7, 3); break; @@ -163,7 +181,14 @@ void DisMc6805::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) cons Error DisMc6805::decodeImpl(DisMemory &memory, Insn &_insn, StrBuffer &out) const { DisInsn insn(_insn, memory, out); - insn.setOpCode(insn.readByte()); + const auto opc = insn.readByte(); + insn.setOpCode(opc); + if (TABLE.isPrefix(cpuType(), opc)) { + insn.setPrefix(opc); + insn.setOpCode(insn.readByte()); + if (insn.getError()) + return _insn.setError(insn); + } if (TABLE.searchOpCode(cpuType(), insn, out)) return _insn.setError(insn); diff --git a/src/entry_mc6805.h b/src/entry_mc6805.h index bb391b376..690315ddb 100644 --- a/src/entry_mc6805.h +++ b/src/entry_mc6805.h @@ -29,14 +29,21 @@ enum AddrMode : uint8_t { M_NONE = 0, M_DIR = 1, // Direct page M_EXT = 2, // Extended - M_IDX = 3, // Indexed X with 8-bit offset + M_IX1 = 3, // Indexed X with 8-bit offset M_REL = 4, // Relative - M_IMM = 5, // Immediate + M_IMM = 5, // Immediate 8-bit M_IX0 = 6, // Indexed X with no offset M_IX2 = 7, // Indexed X with 16-bit offset M_BNO = 8, // Bit number in opcode - M_GEN = 9, // Generic: M_IMM/M_DIR/M_EXT/M_IDX/M_IX2/M_IX0 - M_MEM = 10, // Generic memory, M_DIR/M_IDX/M_IX0 + M_GEN = 9, // Generic: M_IMM/M_DIR/M_EXT/M_IX1/M_IX2/M_IX0 + M_MEM = 10, // Generic memory, M_DIR/M_IX1/M_IX0 + M_IX0P = 11, // Indexed X with post increment + M_IX1P = 12, // Indexed X with 8-bit offset with post increment + M_SP1 = 13, // Indexed SP with 8-bit offset + M_SP2 = 14, // Indexed SP with 16-bit offset + M_IM16 = 15, // Immediate 16-bit + M_SIM8 = 16, // Signed immediate 8-bit + M_REGX = 17, // Indexed X with no offset (without preceeding ',') }; struct Entry final : entry::Base { @@ -63,10 +70,10 @@ struct Entry final : entry::Base { private: static constexpr int opr1_gp = 0; - static constexpr int opr2_gp = 4; - static constexpr int opr3_gp = 8; + static constexpr int opr2_gp = 5; + static constexpr int opr3_gp = 10; static constexpr int undef_bp = 15; - static constexpr uint8_t mode_gm = 0xF; + static constexpr uint8_t mode_gm = 0x1F; static constexpr uint16_t undef_bm = (1 << undef_bp); }; diff --git a/src/insn_mc6805.h b/src/insn_mc6805.h index 64398dcbf..c81fa9a0a 100644 --- a/src/insn_mc6805.h +++ b/src/insn_mc6805.h @@ -25,7 +25,7 @@ namespace libasm { namespace mc6805 { -struct EntryInsn : EntryInsnBase { +struct EntryInsn : EntryInsnPrefix { AddrMode mode1() const { return flags().mode1(); } AddrMode mode2() const { return flags().mode2(); } AddrMode mode3() const { return flags().mode3(); } @@ -43,16 +43,14 @@ struct AsmInsn final : AsmInsnImpl, EntryInsn { Operand op1, op2, op3; - void emitInsn() { emitByte(opCode(), 0); } + void emitInsn(); void emitOperand8(uint8_t val8) { emitByte(val8, operandPos()); } void emitOperand16(uint16_t val16) { emitUint16(val16, operandPos()); } private: uint8_t operandPos() const { - uint8_t pos = length(); - if (pos == 0) - pos = 1; - return pos; + auto pos = length(); + return pos ? pos : (hasPrefix() ? 2 : 1); } }; diff --git a/src/reg_mc6805.cpp b/src/reg_mc6805.cpp index 32cb74c79..2d877b6ad 100644 --- a/src/reg_mc6805.cpp +++ b/src/reg_mc6805.cpp @@ -15,7 +15,6 @@ */ #include "reg_mc6805.h" - #include "reg_base.h" using namespace libasm::reg; @@ -30,11 +29,19 @@ RegName parseRegName(StrScanner &scan) { scan = p; return REG_X; } + if (p.iexpect('S') && p.iexpect('P') && !isIdLetter(*p)) { + scan = p; + return REG_SP; + } return REG_UNDEF; } StrBuffer &outRegName(StrBuffer &out, RegName name) { - return out.letter(char(name)); + if (name == REG_X) + return out.letter('X'); + if (name == REG_SP) + return out.letter('S').letter('P'); + return out; } } // namespace reg diff --git a/src/reg_mc6805.h b/src/reg_mc6805.h index 4efe8f876..0479ded04 100644 --- a/src/reg_mc6805.h +++ b/src/reg_mc6805.h @@ -28,6 +28,7 @@ namespace mc6805 { enum RegName : int8_t { REG_UNDEF = 0, REG_X = 'X', + REG_SP = 'S', }; namespace reg { diff --git a/src/table_mc6805.cpp b/src/table_mc6805.cpp index c191e3cac..14e5e0f3d 100644 --- a/src/table_mc6805.cpp +++ b/src/table_mc6805.cpp @@ -25,12 +25,11 @@ namespace libasm { namespace mc6805 { #define E3(_opc, _name, _opr1, _opr2, _opr3) \ - { _opc, Entry::Flags::create(_opr1, _opr2, _opr3), _name } + {_opc, Entry::Flags::create(_opr1, _opr2, _opr3), _name} #define E2(_opc, _name, _opr1, _opr2) E3(_opc, _name, _opr1, _opr2, M_NONE) #define E1(_opc, _name, _opr1) E2(_opc, _name, _opr1, M_NONE) #define E0(_opc, _name) E1(_opc, _name, M_NONE) -#define U1(_opc, _name, _opr1) \ - { _opc, Entry::Flags::undef(_opr1), _name } +#define U1(_opc, _name, _opr1) {_opc, Entry::Flags::undef(_opr1), _name} // clang-format off static constexpr Entry MC6805_TABLE[] PROGMEM = { @@ -236,23 +235,211 @@ static constexpr Entry MC68HC05_TABLE[] PROGMEM = { static constexpr uint8_t MC68HC05_INDEX[] PROGMEM = { 0, // TEXT_MUL }; + +static constexpr Entry MC68HC08_TABLE[] PROGMEM = { + E1(0x35, TEXT_STHX, M_DIR), + E1(0x45, TEXT_LDHX, M_IM16), + E1(0x55, TEXT_LDHX, M_DIR), + E1(0x65, TEXT_CPHX, M_IM16), + E1(0x75, TEXT_CPHX, M_DIR), + E2(0x4E, TEXT_MOV, M_DIR, M_DIR), + E2(0x5E, TEXT_MOV, M_DIR, M_IX0P), // for disassembler + E1(0x5E, TEXT_MOV, M_IX1P), // for assembler + E2(0x6E, TEXT_MOV, M_IMM, M_DIR), + E2(0x7E, TEXT_MOV, M_IX0P, M_DIR), + E1(0xA7, TEXT_AIS, M_SIM8), + E1(0xAF, TEXT_AIX, M_SIM8), + E0(0x52, TEXT_DIV), + E0(0x62, TEXT_NSA), + E0(0x72, TEXT_DAA), + E0(0x84, TEXT_TAP), + E0(0x85, TEXT_TPA), + E0(0x86, TEXT_PULA), + E0(0x87, TEXT_PSHA), + E0(0x88, TEXT_PULX), + E0(0x89, TEXT_PSHX), + E0(0x8A, TEXT_PULH), + E0(0x8B, TEXT_PSHH), + E0(0x8C, TEXT_CLRH), + E0(0x94, TEXT_TXS), + E0(0x95, TEXT_TSX), + E1(0x90, TEXT_BGE, M_REL), + E1(0x91, TEXT_BLT, M_REL), + E1(0x92, TEXT_BGT, M_REL), + E1(0x93, TEXT_BLE, M_REL), + E2(0x3B, TEXT_DBNZ, M_DIR, M_REL), + E1(0x4B, TEXT_DBNZA, M_REL), + E1(0x5B, TEXT_DBNZX, M_REL), + E2(0x6B, TEXT_DBNZ, M_IX1, M_REL), + E2(0x7B, TEXT_DBNZ, M_IX0, M_REL), + E2(0x7B, TEXT_DBNZ, M_REGX, M_REL), + E2(0x31, TEXT_CBEQ, M_DIR, M_REL), + E2(0x41, TEXT_CBEQA, M_IMM, M_REL), + E2(0x51, TEXT_CBEQX, M_IMM, M_REL), + E2(0x61, TEXT_CBEQ, M_IX1P, M_REL), + E2(0x71, TEXT_CBEQ, M_IX0P, M_REL), +}; + +static constexpr uint8_t MC68HC08_INDEX[] PROGMEM = { + 10, // TEXT_AIS + 11, // TEXT_AIX + 26, // TEXT_BGE + 28, // TEXT_BGT + 29, // TEXT_BLE + 27, // TEXT_BLT + 36, // TEXT_CBEQ + 39, // TEXT_CBEQ + 40, // TEXT_CBEQ + 37, // TEXT_CBEQA + 38, // TEXT_CBEQX + 23, // TEXT_CLRH + 3, // TEXT_CPHX + 4, // TEXT_CPHX + 14, // TEXT_DAA + 30, // TEXT_DBNZ + 33, // TEXT_DBNZ + 34, // TEXT_DBNZ + 35, // TEXT_DBNZ + 31, // TEXT_DBNZA + 32, // TEXT_DBNZX + 12, // TEXT_DIV + 1, // TEXT_LDHX + 2, // TEXT_LDHX + 5, // TEXT_MOV + 6, // TEXT_MOV + 7, // TEXT_MOV + 8, // TEXT_MOV + 9, // TEXT_MOV + 13, // TEXT_NSA + 18, // TEXT_PSHA + 22, // TEXT_PSHH + 20, // TEXT_PSHX + 17, // TEXT_PULA + 21, // TEXT_PULH + 19, // TEXT_PULX + 0, // TEXT_STHX + 15, // TEXT_TAP + 16, // TEXT_TPA + 25, // TEXT_TSX + 24, // TEXT_TXS +}; + +static constexpr Entry MC68HC08_P9E[] PROGMEM = { + E1(0x60, TEXT_NEG, M_SP1), + E2(0x61, TEXT_CBEQ, M_SP1, M_REL), + E1(0x63, TEXT_COM, M_SP1), + E1(0x64, TEXT_LSR, M_SP1), + E1(0x66, TEXT_ROR, M_SP1), + E1(0x67, TEXT_ASR, M_SP1), + E1(0x68, TEXT_ASL, M_SP1), + E1(0x68, TEXT_LSL, M_SP1), + E1(0x69, TEXT_ROL, M_SP1), + E1(0x6A, TEXT_DEC, M_SP1), + E2(0x6B, TEXT_DBNZ, M_SP1, M_REL), + E1(0x6C, TEXT_INC, M_SP1), + E1(0x6D, TEXT_TST, M_SP1), + E1(0x6F, TEXT_CLR, M_SP1), + E1(0xE0, TEXT_SUB, M_SP1), + E1(0xE1, TEXT_CMP, M_SP1), + E1(0xE2, TEXT_SBC, M_SP1), + E1(0xE3, TEXT_CPX, M_SP1), + E1(0xE4, TEXT_AND, M_SP1), + E1(0xE5, TEXT_BIT, M_SP1), + E1(0xE6, TEXT_LDA, M_SP1), + E1(0xE7, TEXT_STA, M_SP1), + E1(0xE8, TEXT_EOR, M_SP1), + E1(0xE9, TEXT_ADC, M_SP1), + E1(0xEA, TEXT_ORA, M_SP1), + E1(0xEB, TEXT_ADD, M_SP1), + E1(0xEE, TEXT_LDX, M_SP1), + E1(0xEF, TEXT_STX, M_SP1), + E1(0xD0, TEXT_SUB, M_SP2), + E1(0xD1, TEXT_CMP, M_SP2), + E1(0xD2, TEXT_SBC, M_SP2), + E1(0xD3, TEXT_CPX, M_SP2), + E1(0xD4, TEXT_AND, M_SP2), + E1(0xD5, TEXT_BIT, M_SP2), + E1(0xD6, TEXT_LDA, M_SP2), + E1(0xD7, TEXT_STA, M_SP2), + E1(0xD8, TEXT_EOR, M_SP2), + E1(0xD9, TEXT_ADC, M_SP2), + E1(0xDA, TEXT_ORA, M_SP2), + E1(0xDB, TEXT_ADD, M_SP2), + E1(0xDE, TEXT_LDX, M_SP2), + E1(0xDF, TEXT_STX, M_SP2), +}; + +static constexpr uint8_t MC68HC08_I9E[] PROGMEM = { + 23, // TEXT_ADC + 37, // TEXT_ADC + 25, // TEXT_ADD + 39, // TEXT_ADD + 18, // TEXT_AND + 32, // TEXT_AND + 6, // TEXT_ASL + 5, // TEXT_ASR + 19, // TEXT_BIT + 33, // TEXT_BIT + 1, // TEXT_CBEQ + 13, // TEXT_CLR + 15, // TEXT_CMP + 29, // TEXT_CMP + 2, // TEXT_COM + 17, // TEXT_CPX + 31, // TEXT_CPX + 10, // TEXT_DBNZ + 9, // TEXT_DEC + 22, // TEXT_EOR + 36, // TEXT_EOR + 11, // TEXT_INC + 20, // TEXT_LDA + 34, // TEXT_LDA + 26, // TEXT_LDX + 40, // TEXT_LDX + 7, // TEXT_LSL + 3, // TEXT_LSR + 0, // TEXT_NEG + 24, // TEXT_ORA + 38, // TEXT_ORA + 8, // TEXT_ROL + 4, // TEXT_ROR + 16, // TEXT_SBC + 30, // TEXT_SBC + 21, // TEXT_STA + 35, // TEXT_STA + 27, // TEXT_STX + 41, // TEXT_STX + 14, // TEXT_SUB + 28, // TEXT_SUB + 12, // TEXT_TST +}; + // clang-format on -using EntryPage = entry::TableBase; +using EntryPage = entry::PrefixTableBase; static constexpr EntryPage MC6805_PAGES[] PROGMEM = { - {ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, + {0x00, ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, }; static constexpr EntryPage MC146805_PAGES[] PROGMEM = { - {ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, - {ARRAY_RANGE(MC146805_TABLE), ARRAY_RANGE(MC146805_INDEX)}, + {0x00, ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, + {0x00, ARRAY_RANGE(MC146805_TABLE), ARRAY_RANGE(MC146805_INDEX)}, }; static constexpr EntryPage MC68HC05_PAGES[] PROGMEM = { - {ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, - {ARRAY_RANGE(MC146805_TABLE), ARRAY_RANGE(MC146805_INDEX)}, - {ARRAY_RANGE(MC68HC05_TABLE), ARRAY_RANGE(MC68HC05_INDEX)}, + {0x00, ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, + {0x00, ARRAY_RANGE(MC146805_TABLE), ARRAY_RANGE(MC146805_INDEX)}, + {0x00, ARRAY_RANGE(MC68HC05_TABLE), ARRAY_RANGE(MC68HC05_INDEX)}, +}; + +static constexpr EntryPage MC68HC08_PAGES[] PROGMEM = { + {0x00, ARRAY_RANGE(MC68HC08_TABLE), ARRAY_RANGE(MC68HC08_INDEX)}, + // Above definitions overrides unknown instructions defined below. + {0x00, ARRAY_RANGE(MC6805_TABLE), ARRAY_RANGE(MC6805_INDEX)}, + {0x00, ARRAY_RANGE(MC146805_TABLE), ARRAY_RANGE(MC146805_INDEX)}, + {0x00, ARRAY_RANGE(MC68HC05_TABLE), ARRAY_RANGE(MC68HC05_INDEX)}, + {0x9E, ARRAY_RANGE(MC68HC08_P9E), ARRAY_RANGE(MC68HC08_I9E)}, }; using Cpu = entry::CpuBase; @@ -261,6 +448,7 @@ static constexpr Cpu CPU_TABLE[] PROGMEM = { {MC6805, TEXT_CPU_6805, ARRAY_RANGE(MC6805_PAGES)}, {MC146805, TEXT_CPU_146805, ARRAY_RANGE(MC146805_PAGES)}, {MC68HC05, TEXT_CPU_68HC05, ARRAY_RANGE(MC68HC05_PAGES)}, + {MC68HC08, TEXT_CPU_68HC08, ARRAY_RANGE(MC68HC08_PAGES)}, }; static const Cpu *cpu(CpuType cpuType) { @@ -280,14 +468,16 @@ static bool acceptMode(AddrMode opr, AddrMode table) { if (opr == table) return true; if (table == M_GEN) - return opr == M_BNO || opr == M_IMM || opr == M_DIR || opr == M_EXT || opr == M_IDX || + return opr == M_BNO || opr == M_IMM || opr == M_DIR || opr == M_EXT || opr == M_IX1 || opr == M_IX0 || opr == M_IX2; if (table == M_MEM) - return opr == M_BNO || opr == M_DIR || opr == M_IDX || opr == M_IX0; + return opr == M_BNO || opr == M_DIR || opr == M_IX1 || opr == M_IX0; if (opr == M_EXT) return table == M_REL; if (opr == M_DIR) return table == M_REL || table == M_EXT; + if (opr == M_IMM) + return table == M_IM16 || table == M_SIM8; if (opr == M_BNO) return table == M_REL || table == M_DIR || table == M_EXT; return false; @@ -334,6 +524,10 @@ Error TableMc6805::searchOpCode(CpuType cpuType, DisInsn &insn, StrBuffer &out) return insn.getError(); } +bool TableMc6805::isPrefix(CpuType cpuType, Config::opcode_t code) const { + return cpu(cpuType)->isPrefix(code); +} + const /*PROGMEM*/ char *TableMc6805::listCpu_P() const { return TEXT_MC6805_LIST; } diff --git a/src/table_mc6805.h b/src/table_mc6805.h index 1740e95c6..5d053e163 100644 --- a/src/table_mc6805.h +++ b/src/table_mc6805.h @@ -31,6 +31,7 @@ struct TableMc6805 final : InsnTable { bool hasOperand(CpuType, AsmInsn &insn) const; Error searchName(CpuType, AsmInsn &insn) const; Error searchOpCode(CpuType, DisInsn &insn, StrBuffer &out) const; + bool isPrefix(CpuType, Config::opcode_t code) const; }; extern const TableMc6805 TABLE; diff --git a/src/text_cdp1802.cpp b/src/text_cdp1802.cpp index bf8c0e2b6..988ec1564 100644 --- a/src/text_cdp1802.cpp +++ b/src/text_cdp1802.cpp @@ -150,7 +150,7 @@ constexpr char TEXT_DACI[] PROGMEM = "DACI"; constexpr char TEXT_DADC[] PROGMEM = "DADC"; constexpr char TEXT_DADD[] PROGMEM = "DADD"; constexpr char TEXT_DADI[] PROGMEM = "DADI"; -constexpr char TEXT_DBNZ[] PROGMEM = "DBNZ"; +// constexpr char TEXT_DBNZ[] PROGMEM = "DBNZ"; constexpr char TEXT_DSAV[] PROGMEM = "DSAV"; constexpr char TEXT_DSBI[] PROGMEM = "DSBI"; constexpr char TEXT_DSM[] PROGMEM = "DSM"; diff --git a/src/text_cdp1802.h b/src/text_cdp1802.h index e1af3da74..24ae8e256 100644 --- a/src/text_cdp1802.h +++ b/src/text_cdp1802.h @@ -151,7 +151,7 @@ extern const char TEXT_DACI[] PROGMEM; extern const char TEXT_DADC[] PROGMEM; extern const char TEXT_DADD[] PROGMEM; extern const char TEXT_DADI[] PROGMEM; -extern const char TEXT_DBNZ[] PROGMEM; +using common::TEXT_DBNZ; extern const char TEXT_DSAV[] PROGMEM; extern const char TEXT_DSBI[] PROGMEM; extern const char TEXT_DSM[] PROGMEM; diff --git a/src/text_common.cpp b/src/text_common.cpp index a94830412..d611ca0aa 100644 --- a/src/text_common.cpp +++ b/src/text_common.cpp @@ -152,6 +152,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_DBNZ[] PROGMEM = "DBNZ"; constexpr char TEXT_DECA[] PROGMEM = "DECA"; constexpr char TEXT_DECB[] PROGMEM = "DECB"; constexpr char TEXT_DECD[] PROGMEM = "DECD"; @@ -321,6 +322,10 @@ constexpr char TEXT_OUTS[] PROGMEM = "OUTS"; constexpr char TEXT_PEA[] PROGMEM = "PEA"; constexpr char TEXT_POPF[] PROGMEM = "POPF"; constexpr char TEXT_POP[] PROGMEM = "POP"; +constexpr char TEXT_PSHA[] PROGMEM = "PSHA"; +constexpr char TEXT_PSHX[] PROGMEM = "PSHX"; +constexpr char TEXT_PULA[] PROGMEM = "PULA"; +constexpr char TEXT_PULX[] PROGMEM = "PULX"; constexpr char TEXT_PUSHF[] PROGMEM = "PUSHF"; constexpr char TEXT_PUSH[] PROGMEM = "PUSH"; constexpr char TEXT_RAL[] PROGMEM = "RAL"; @@ -413,9 +418,11 @@ constexpr char TEXT_SUBW[] PROGMEM = "SUBW"; constexpr char TEXT_SVC[] PROGMEM = "SVC"; constexpr char TEXT_SWAP[] PROGMEM = "SWAP"; constexpr char TEXT_SWI[] PROGMEM = "SWI"; +constexpr char TEXT_TAP[] PROGMEM = "TAP"; constexpr char TEXT_TAX[] PROGMEM = "TAX"; constexpr char TEXT_TEST[] PROGMEM = "TEST"; constexpr char TEXT_TIM[] PROGMEM = "TIM"; +constexpr char TEXT_TPA[] PROGMEM = "TPA"; constexpr char TEXT_TRAP[] PROGMEM = "TRAP"; constexpr char TEXT_TSET[] PROGMEM = "TSET"; constexpr char TEXT_TSTA[] PROGMEM = "TSTA"; diff --git a/src/text_common.h b/src/text_common.h index 4ba10e650..938e2424f 100644 --- a/src/text_common.h +++ b/src/text_common.h @@ -155,6 +155,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_DBNZ[] PROGMEM; extern const char TEXT_DECA[] PROGMEM; extern const char TEXT_DECB[] PROGMEM; extern const char TEXT_DECD[] PROGMEM; @@ -324,6 +325,10 @@ extern const char TEXT_OUTS[] PROGMEM; extern const char TEXT_PEA[] PROGMEM; extern const char TEXT_POPF[] PROGMEM; extern const char TEXT_POP[] PROGMEM; +extern const char TEXT_PSHA[] PROGMEM; +extern const char TEXT_PSHX[] PROGMEM; +extern const char TEXT_PULA[] PROGMEM; +extern const char TEXT_PULX[] PROGMEM; extern const char TEXT_PUSHF[] PROGMEM; extern const char TEXT_PUSH[] PROGMEM; extern const char TEXT_RAL[] PROGMEM; @@ -416,9 +421,11 @@ extern const char TEXT_SUBW[] PROGMEM; extern const char TEXT_SVC[] PROGMEM; extern const char TEXT_SWAP[] PROGMEM; extern const char TEXT_SWI[] PROGMEM; +extern const char TEXT_TAP[] PROGMEM; extern const char TEXT_TAX[] PROGMEM; extern const char TEXT_TEST[] PROGMEM; extern const char TEXT_TIM[] PROGMEM; +extern const char TEXT_TPA[] PROGMEM; extern const char TEXT_TRAP[] PROGMEM; extern const char TEXT_TSET[] PROGMEM; extern const char TEXT_TSTA[] PROGMEM; diff --git a/src/text_mc6800.cpp b/src/text_mc6800.cpp index 564192725..a9c53eb8e 100644 --- a/src/text_mc6800.cpp +++ b/src/text_mc6800.cpp @@ -117,10 +117,10 @@ constexpr char TEXT_LDAB[] PROGMEM = "LDAB"; constexpr char TEXT_ORAA[] PROGMEM = "ORAA"; constexpr char TEXT_ORAB[] PROGMEM = "ORAB"; constexpr char TEXT_PSH[] PROGMEM = "PSH"; -constexpr char TEXT_PSHA[] PROGMEM = "PSHA"; +// constexpr char TEXT_PSHA[] PROGMEM = "PSHA"; constexpr char TEXT_PSHB[] PROGMEM = "PSHB"; constexpr char TEXT_PUL[] PROGMEM = "PUL"; -constexpr char TEXT_PULA[] PROGMEM = "PULA"; +// constexpr char TEXT_PULA[] PROGMEM = "PULA"; constexpr char TEXT_PULB[] PROGMEM = "PULB"; // constexpr char TEXT_ROL[] PROGMEM = "ROL"; // constexpr char TEXT_ROLA[] PROGMEM = "ROLA"; @@ -147,9 +147,9 @@ constexpr char TEXT_STAB[] PROGMEM = "STAB"; // constexpr char TEXT_SUBB[] PROGMEM = "SUBB"; // constexpr char TEXT_SWI[] PROGMEM = "SWI"; constexpr char TEXT_TAB[] PROGMEM = "TAB"; -constexpr char TEXT_TAP[] PROGMEM = "TAP"; +// constexpr char TEXT_TAP[] PROGMEM = "TAP"; constexpr char TEXT_TBA[] PROGMEM = "TBA"; -constexpr char TEXT_TPA[] PROGMEM = "TPA"; +// constexpr char TEXT_TPA[] PROGMEM = "TPA"; // constexpr char TEXT_TST[] PROGMEM = "TST"; // constexpr char TEXT_TSTA[] PROGMEM = "TSTA"; // constexpr char TEXT_TSTB[] PROGMEM = "TSTB"; @@ -174,8 +174,8 @@ constexpr char TEXT_XIM[] PROGMEM = "XIM"; // constexpr char TEXT_MUL[] PROGMEM = "MUL"; // constexpr char TEXT_STD[] PROGMEM = "STD"; // constexpr char TEXT_SUBD[] PROGMEM = "SUBD"; -constexpr char TEXT_PSHX[] PROGMEM = "PSHX"; -constexpr char TEXT_PULX[] PROGMEM = "PULX"; +// constexpr char TEXT_PSHX[] PROGMEM = "PSHX"; +// constexpr char TEXT_PULX[] PROGMEM = "PULX"; // HD6301 // constexpr char TEXT_AIM[] PROGMEM = "AIM"; diff --git a/src/text_mc6800.h b/src/text_mc6800.h index c090d0452..e81004188 100644 --- a/src/text_mc6800.h +++ b/src/text_mc6800.h @@ -120,10 +120,10 @@ using common::TEXT_ORA; extern const char TEXT_ORAA[] PROGMEM; extern const char TEXT_ORAB[] PROGMEM; extern const char TEXT_PSH[] PROGMEM; -extern const char TEXT_PSHA[] PROGMEM; +using common::TEXT_PSHA; extern const char TEXT_PSHB[] PROGMEM; extern const char TEXT_PUL[] PROGMEM; -extern const char TEXT_PULA[] PROGMEM; +using common::TEXT_PULA; extern const char TEXT_PULB[] PROGMEM; using common::TEXT_ROL; using common::TEXT_ROLA; @@ -150,9 +150,9 @@ using common::TEXT_SUBA; using common::TEXT_SUBB; using common::TEXT_SWI; extern const char TEXT_TAB[] PROGMEM; -extern const char TEXT_TAP[] PROGMEM; +using common::TEXT_TAP; extern const char TEXT_TBA[] PROGMEM; -extern const char TEXT_TPA[] PROGMEM; +using common::TEXT_TPA; using common::TEXT_TST; using common::TEXT_TSTA; using common::TEXT_TSTB; @@ -177,8 +177,8 @@ using common::TEXT_LSRD; using common::TEXT_MUL; using common::TEXT_STD; using common::TEXT_SUBD; -extern const char TEXT_PSHX[] PROGMEM; -extern const char TEXT_PULX[] PROGMEM; +using common::TEXT_PSHX; +using common::TEXT_PULX; // HD6301 using common::TEXT_AIM; diff --git a/src/text_mc6805.cpp b/src/text_mc6805.cpp index 72d1a35b4..b9797b35f 100644 --- a/src/text_mc6805.cpp +++ b/src/text_mc6805.cpp @@ -21,10 +21,11 @@ namespace text { namespace mc6805 { // clang-format off -constexpr char TEXT_MC6805_LIST[] PROGMEM = "MC6805, MC146805, MC68HC05"; +constexpr char TEXT_MC6805_LIST[] PROGMEM = "MC6805, MC146805, MC68HC05, MC68HC08"; constexpr char TEXT_CPU_6805[] PROGMEM = "6805"; constexpr char TEXT_CPU_146805[] PROGMEM = "146805"; constexpr char TEXT_CPU_68HC05[] PROGMEM = "68HC05"; +constexpr char TEXT_CPU_68HC08[] PROGMEM = "68HC08"; // constexpr char TEXT_ADC[] PROGMEM = "ADC"; // constexpr char TEXT_ADD[] PROGMEM = "ADD"; @@ -115,6 +116,38 @@ constexpr char TEXT_RSP[] PROGMEM = "RSP"; constexpr char TEXT_TSTX[] PROGMEM = "TSTX"; // constexpr char TEXT_TXA[] PROGMEM = "TXA"; // constexpr char TEXT_WAIT[] PROGMEM = "WAIT"; + +// MC68HC08 +constexpr char TEXT_AIS[] PROGMEM = "AIS"; +constexpr char TEXT_AIX[] PROGMEM = "AIX"; +// constexpr char TEXT_BGE[] PROGMEM = "BGE"; +// constexpr char TEXT_BGT[] PROGMEM = "BGT"; +// constexpr char TEXT_BLE[] PROGMEM = "BLE"; +// constexpr char TEXT_BLT[] PROGMEM = "BLT"; +constexpr char TEXT_CBEQA[] PROGMEM = "CBEQA"; +constexpr char TEXT_CBEQ[] PROGMEM = "CBEQ"; +constexpr char TEXT_CBEQX[] PROGMEM = "CBEQX"; +constexpr char TEXT_CLRH[] PROGMEM = "CLRH"; +constexpr char TEXT_CPHX[] PROGMEM = "CPHX"; +// constexpr char TEXT_DAA[] PROGMEM = "DAA"; +// constexpr char TEXT_DBNZ[] PROGMEM = "DBNZ"; +constexpr char TEXT_DBNZA[] PROGMEM = "DBNZA"; +constexpr char TEXT_DBNZX[] PROGMEM = "DBNZX"; +// constexpr char TEXT_DIV[] PROGMEM = "DIV"; +constexpr char TEXT_LDHX[] PROGMEM = "LDHX"; +// constexpr char TEXT_MOV[] PROGMEM = "MOV"; +constexpr char TEXT_NSA[] PROGMEM = "NSA"; +// constexpr char TEXT_PSHA[] PROGMEM = "PSHA"; +constexpr char TEXT_PSHH[] PROGMEM = "PSHH"; +// constexpr char TEXT_PSHX[] PROGMEM = "PSHX"; +// constexpr char TEXT_PULA[] PROGMEM = "PULA"; +constexpr char TEXT_PULH[] PROGMEM = "PULH"; +// constexpr char TEXT_PULX[] PROGMEM = "PULX"; +constexpr char TEXT_STHX[] PROGMEM = "STHX"; +// constexpr char TEXT_TAP[] PROGMEM = "TAP"; +// constexpr char TEXT_TPA[] PROGMEM = "TPA"; +// constexpr char TEXT_TSX[] PROGMEM = "TSX"; +// constexpr char TEXT_TXS[] PROGMEM = "TXS"; // clang-format on } // namespace mc6805 diff --git a/src/text_mc6805.h b/src/text_mc6805.h index 1ac5d9510..0cfeb595f 100644 --- a/src/text_mc6805.h +++ b/src/text_mc6805.h @@ -28,6 +28,7 @@ extern const char TEXT_MC6805_LIST[] PROGMEM; extern const char TEXT_CPU_6805[] PROGMEM; extern const char TEXT_CPU_146805[] PROGMEM; extern const char TEXT_CPU_68HC05[] PROGMEM; +extern const char TEXT_CPU_68HC08[] PROGMEM; using common::TEXT_ADC; using common::TEXT_ADD; @@ -118,6 +119,38 @@ using common::TEXT_TSTA; extern const char TEXT_TSTX[] PROGMEM; using common::TEXT_TXA; using common::TEXT_WAIT; + +// MC68HC08 +extern const char TEXT_AIS[] PROGMEM; +extern const char TEXT_AIX[] PROGMEM; +using common::TEXT_BGE; +using common::TEXT_BGT; +using common::TEXT_BLE; +using common::TEXT_BLT; +extern const char TEXT_CBEQA[] PROGMEM; +extern const char TEXT_CBEQ[] PROGMEM; +extern const char TEXT_CBEQX[] PROGMEM; +extern const char TEXT_CLRH[] PROGMEM; +extern const char TEXT_CPHX[] PROGMEM; +using common::TEXT_DAA; +using common::TEXT_DBNZ; +extern const char TEXT_DBNZA[] PROGMEM; +extern const char TEXT_DBNZX[] PROGMEM; +using common::TEXT_DIV; +extern const char TEXT_LDHX[] PROGMEM; +using common::TEXT_MOV; +extern const char TEXT_NSA[] PROGMEM; +using common::TEXT_PSHA; +extern const char TEXT_PSHH[] PROGMEM; +using common::TEXT_PSHX; +using common::TEXT_PULA; +extern const char TEXT_PULH[] PROGMEM; +using common::TEXT_PULX; +extern const char TEXT_STHX[] PROGMEM; +using common::TEXT_TAP; +using common::TEXT_TPA; +using common::TEXT_TSX; +using common::TEXT_TXS; // clang-format on } // namespace mc6805 diff --git a/test/autogen/gen_mc68hc08.asm b/test/autogen/gen_mc68hc08.asm new file mode 100644 index 000000000..7c2e5d795 --- /dev/null +++ b/test/autogen/gen_mc68hc08.asm @@ -0,0 +1,448 @@ +;;; AUTO GENERATED FILE +;;; generated by: gen_mc6805 -u -C 68HC08 -o gen_mc68hc08.asm -l gen_mc68hc08.lst + CPU 68HC08 + ORG $0100 + BRSET 0, $01, *+5 + BRSET 0, $01, *-125 + BRSET 0, $01, * + BRCLR 0, $02, *+6 + BRCLR 0, $02, *-125 + BRCLR 0, $02, * + BSET 0, $11 + BCLR 0, $12 + BRA *+35 + BRA *-126 + BRA * + BRN *+36 + BRN *-126 + BRN * + BHI *+37 + BHI *-126 + BHI * + BLS *+38 + BLS *-126 + BLS * + BHS *+39 + BHS *-126 + BHS * + BLO *+40 + BLO *-126 + BLO * + BNE *+41 + BNE *-126 + BNE * + BEQ *+42 + BEQ *-126 + BEQ * + BHCC *+43 + BHCC *-126 + BHCC * + BHCS *+44 + BHCS *-126 + BHCS * + BPL *+45 + BPL *-126 + BPL * + BMI *+46 + BMI *-126 + BMI * + BMC *+47 + BMC *-126 + BMC * + BMS *+48 + BMS *-126 + BMS * + BIL *+49 + BIL *-126 + BIL * + BIH *+50 + BIH *-126 + BIH * + NEG $31 + CBEQ $32, *+54 + CBEQ $32, *-125 + CBEQ $32, * + COM $34 + LSR $35 + STHX $36 + ROR $37 + ASR $38 + ASL $39 + ROL $3A + DEC $3B + DBNZ $3C, *+64 + DBNZ $3C, *-125 + DBNZ $3C, * + INC $3D + TST $3E + CLR $40 + NEGA + CBEQA #$42, *+70 + CBEQA #$42, *-125 + CBEQA #$42, * + MUL + COMA + LSRA + LDHX #$4647 + RORA + ASRA + ASLA + ROLA + DECA + DBNZA *+78 + DBNZA *-126 + DBNZA * + INCA + TSTA + MOV $4F, $50 + CLRA + NEGX + CBEQX #$52, *+86 + CBEQX #$52, *-125 + CBEQX #$52, * + DIV + COMX + LSRX + LDHX $56 + RORX + ASRX + ASLX + ROLX + DECX + DBNZX *+94 + DBNZX *-126 + DBNZX * + INCX + TSTX + MOV $5F, X+ + CLRX + NEG 97,X + NEG <0,X + CBEQ 98,X+, *+102 + CBEQ 98,X+, *-125 + CBEQ 98,X+, * + CBEQ <0,X+, *+4 + CBEQ <0,X+, *-125 + CBEQ <0,X+, * + NSA + COM 100,X + COM <0,X + LSR 101,X + LSR <0,X + CPHX #$6667 + ROR 103,X + ROR <0,X + ASR 104,X + ASR <0,X + ASL 105,X + ASL <0,X + ROL 106,X + ROL <0,X + DEC 107,X + DEC <0,X + DBNZ 108,X, *+112 + DBNZ 108,X, *-125 + DBNZ 108,X, * + DBNZ <0,X, *+4 + DBNZ <0,X, *-125 + DBNZ <0,X, * + INC 109,X + INC <0,X + TST 110,X + TST <0,X + MOV #$6F, $70 + CLR 112,X + CLR <0,X + NEG ,X + CBEQ X+, *+116 + CBEQ X+, *-126 + CBEQ X+, * + DAA + COM ,X + LSR ,X + CPHX $76 + ROR ,X + ASR ,X + ASL ,X + ROL ,X + DEC ,X + DBNZ ,X, *+126 + DBNZ ,X, *-126 + DBNZ ,X, * + INC ,X + TST ,X + MOV X+, $7F + CLR ,X + RTI + RTS + SWI + TAP + TPA + PULA + PSHA + PULX + PSHX + PULH + PSHH + CLRH + STOP + WAIT + BGE *-109 + BGE * + BGE *+1 + BLT *-108 + BLT * + BLT *+1 + BGT *-107 + BGT * + BGT *+1 + BLE *-106 + BLE * + BLE *+1 + TXS + TSX + TAX + CLC + SEC + CLI + SEI + RSP + NOP + SUB $D1D2,SP + SUB >$0001,SP + CMP $D2D3,SP + CMP >$0001,SP + SBC $D3D4,SP + SBC >$0001,SP + CPX $D4D5,SP + CPX >$0001,SP + AND $D5D6,SP + AND >$0001,SP + BIT $D6D7,SP + BIT >$0001,SP + LDA $D7D8,SP + LDA >$0001,SP + STA $D8D9,SP + STA >$0001,SP + EOR $D9DA,SP + EOR >$0001,SP + ADC $DADB,SP + ADC >$0001,SP + ORA $DBDC,SP + ORA >$0001,SP + ADD $DCDD,SP + ADD >$0001,SP + LDX $DFE0,SP + LDX >$0001,SP + STX $E0E1,SP + STX >$0001,SP + SUB 225,SP + SUB <0,SP + CMP 226,SP + CMP <0,SP + SBC 227,SP + SBC <0,SP + CPX 228,SP + CPX <0,SP + AND 229,SP + AND <0,SP + BIT 230,SP + BIT <0,SP + LDA 231,SP + LDA <0,SP + STA 232,SP + STA <0,SP + EOR 233,SP + EOR <0,SP + ADC 234,SP + ADC <0,SP + ORA 235,SP + ORA <0,SP + ADD 236,SP + ADD <0,SP + LDX 239,SP + LDX <0,SP + STX 240,SP + STX <0,SP + NEG 97,SP + NEG <0,SP + CBEQ 98,SP, *+103 + CBEQ 98,SP, *-124 + CBEQ 98,SP, * + CBEQ <0,SP, *+5 + CBEQ <0,SP, *-124 + CBEQ <0,SP, * + COM 100,SP + COM <0,SP + LSR 101,SP + LSR <0,SP + ROR 103,SP + ROR <0,SP + ASR 104,SP + ASR <0,SP + ASL 105,SP + ASL <0,SP + ROL 106,SP + ROL <0,SP + DEC 107,SP + DEC <0,SP + DBNZ 108,SP, *+113 + DBNZ 108,SP, *-124 + DBNZ 108,SP, * + DBNZ <0,SP, *+5 + DBNZ <0,SP, *-124 + DBNZ <0,SP, * + INC 109,SP + INC <0,SP + TST 110,SP + TST <0,SP + CLR 112,SP + CLR <0,SP + TXA + SUB #$A1 + CMP #$A2 + SBC #$A3 + CPX #$A4 + AND #$A5 + BIT #$A6 + LDA #$A7 + AIS #-$58 + AIS #0 + EOR #$A9 + ADC #$AA + ORA #$AB + ADD #$AC + BSR *-80 + BSR * + BSR *+1 + LDX #$AF + AIX #-$50 + AIX #0 + SUB $B1 + CMP $B2 + SBC $B3 + CPX $B4 + AND $B5 + BIT $B6 + LDA $B7 + STA $B8 + EOR $B9 + ADC $BA + ORA $BB + ADD $BC + JMP $BD + JSR $BE + LDX $BF + STX $C0 + SUB >$0001 + SUB $0102 + CMP >$0001 + CMP $0102 + SBC >$0001 + SBC $0102 + CPX >$0001 + CPX $0102 + AND >$0001 + AND $0102 + BIT >$0001 + BIT $0102 + LDA >$0001 + LDA $0102 + STA >$0001 + STA $0102 + EOR >$0001 + EOR $0102 + ADC >$0001 + ADC $0102 + ORA >$0001 + ORA $0102 + ADD >$0001 + ADD $0102 + JMP >$0001 + JMP $0102 + JSR >$0001 + JSR $0102 + LDX >$0001 + LDX $0102 + STX >$0001 + STX $0102 + SUB $D1D2,X + SUB >$0001,X + CMP $D2D3,X + CMP >$0001,X + SBC $D3D4,X + SBC >$0001,X + CPX $D4D5,X + CPX >$0001,X + AND $D5D6,X + AND >$0001,X + BIT $D6D7,X + BIT >$0001,X + LDA $D7D8,X + LDA >$0001,X + STA $D8D9,X + STA >$0001,X + EOR $D9DA,X + EOR >$0001,X + ADC $DADB,X + ADC >$0001,X + ORA $DBDC,X + ORA >$0001,X + ADD $DCDD,X + ADD >$0001,X + JMP $DDDE,X + JMP >$0001,X + JSR $DEDF,X + JSR >$0001,X + LDX $DFE0,X + LDX >$0001,X + STX $E0E1,X + STX >$0001,X + SUB 225,X + SUB <0,X + CMP 226,X + CMP <0,X + SBC 227,X + SBC <0,X + CPX 228,X + CPX <0,X + AND 229,X + AND <0,X + BIT 230,X + BIT <0,X + LDA 231,X + LDA <0,X + STA 232,X + STA <0,X + EOR 233,X + EOR <0,X + ADC 234,X + ADC <0,X + ORA 235,X + ORA <0,X + ADD 236,X + ADD <0,X + JMP 237,X + JMP <0,X + JSR 238,X + JSR <0,X + LDX 239,X + LDX <0,X + STX 240,X + STX <0,X + SUB ,X + CMP ,X + SBC ,X + CPX ,X + AND ,X + BIT ,X + LDA ,X + STA ,X + EOR ,X + ADC ,X + ORA ,X + ADD ,X + JMP ,X + JSR ,X + LDX ,X + STX ,X diff --git a/test/reference/test_mc68hc05.asm b/test/reference/test_mc68hc05.asm index 0b0861ff2..064c2ceda 100644 --- a/test/reference/test_mc68hc05.asm +++ b/test/reference/test_mc68hc05.asm @@ -14,236 +14,5 @@ cpu 68HC05 org $0100 -;;; 0X - brset 0,$01, *+5 - brclr 0,$02, *+6 - brset 1,$03, *+7 - brclr 1,$04, *+8 - brset 2,$05, *+9 - brclr 2,$06, *+10 - brset 3,$07, *+11 - brclr 3,$08, *+12 - brset 4,$09, *+13 - brclr 4,$0a, *+14 - brset 5,$0b, *+15 - brclr 5,$0c, *+16 - brset 6,$0d, *+17 - brclr 6,$0e, *+18 - brset 7,$0f, *+19 - brclr 7,$10, *+20 -;;; 1X - bset 0,$11 - bclr 0,$12 - bset 1,$13 - bclr 1,$14 - bset 2,$15 - bclr 2,$16 - bset 3,$17 - bclr 3,$18 - bset 4,$19 - bclr 4,$1a - bset 5,$1b - bclr 5,$1c - bset 6,$1d - bclr 6,$1e - bset 7,$1f - bclr 7,$20 -;;; 2X - bra *+$23 - brn *+$23 - bhi *+$25 - bls *+$26 - bcc *+$27 - bcs *+$28 - bhs *+$27 - blo *+$28 - bne *+$29 - beq *+$2a - bhcc *+$2b - bhcs *+$2c - bpl *+$2d - bmi *+$2e - bmc *+$2f - bms *+$30 - bil *+$31 - bih *+$32 -;;; 3X - neg $31 - com $34 - lsr $35 - ror $37 - asr $38 - lsl $39 - asl $39 - rol $3a - dec $3b - inc $3d - tst $3e - clr $40 -;;; 4X - nega - mul - coma - lsra - rora - asra - lsla - asla - rola - deca - inca - tsta - clra -;;; 5X - negx - comx - lsrx - rorx - asrx - lslx - aslx - rolx - decx - incx - tstx - clrx -;;; 6X - neg 0,x - com 0,x - lsr 1,x - ror 6,x - asr 8,x - lsl 9,x - asl 9,x - rol 10,x - dec 11,x - inc 13,x - tst 14,x - clr 255,x -;;; 7X - neg ,x - com ,x - lsr ,x - ror ,x - asr ,x - lsl ,x - asl ,x - rol ,x - dec ,x - inc ,x - tst ,x - clr ,x -;;; 8X - rti - rts - swi - stop - wait -;;; 9X - tax - clc - sec - cli - sei - rsp - nop - txa -;;; AX - sub #$a1 - cmp #$a2 - sbc #$a3 - cpx #$a4 - and #$a5 - bit #$a6 - lda #$a7 - eor #$a9 - adc #$aa - ora #$ab - add #$ac - bsr *-80 - ldx #$af -;;; BX - sub $b1 - cmp $b2 - sbc $b3 - cpx $b4 - and $b5 - bit $b6 - lda $b7 - sta $b8 - eor $b9 - adc $ba - ora $bb - add $bc - jmp $bd - jsr $be - ldx $bf - stx $c0 -;;; CX - sub $11c2 - cmp $12c3 - sbc $13c4 - cpx $14c5 - and $15c6 - bit $16c7 - lda $17c8 - sta $18c9 - eor $19ca - adc $1acb - ora $1bcc - add $1ccd - jmp $1dce - jsr $1ecf - ldx $1fd0 - stx $10d1 -;;; DX - sub $d1d2,x - cmp $d2d3,x - sbc $d3d4,x - cpx $d4d5,x - and $d5d6,x - bit $d6d7,x - lda $d7d8,x - sta $d8d9,x - eor $d9da,x - adc $dadb,x - ora $dbdc,x - add $dcdd,x - jmp $ddde,x - jsr $dedf,x - ldx $dfe0,x - stx $e0e1,x -;;; EX - sub $e1,x - cmp $e2,x - sbc $e3,x - cpx $e4,x - and $e5,x - bit $e6,x - lda $e7,x - sta $e8,x - eor $e9,x - adc $ea,x - ora $eb,x - add $ec,x - jmp $ed,x - jsr $ee,x - ldx $ef,x - stx $f0,x -;;; FX - sub ,x - cmp ,x - sbc ,x - cpx ,x - and ,x - bit ,x - lda ,x - sta ,x - eor ,x - adc ,x - ora ,x - add ,x - jmp ,x - jsr ,x - ldx ,x - stx ,x +abs: equ $1000 + include "test_mc68hc05.inc" diff --git a/test/reference/test_mc68hc05.inc b/test/reference/test_mc68hc05.inc new file mode 100644 index 000000000..361009af7 --- /dev/null +++ b/test/reference/test_mc68hc05.inc @@ -0,0 +1,252 @@ +;;; Copyright 2021 Tadashi G. Takaoka +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; 0X + brset 0,$01, *+5 + brclr 0,$02, *+6 + brset 1,$03, *+7 + brclr 1,$04, *+8 + brset 2,$05, *+9 + brclr 2,$06, *+10 + brset 3,$07, *+11 + brclr 3,$08, *+12 + brset 4,$09, *+13 + brclr 4,$0a, *+14 + brset 5,$0b, *+15 + brclr 5,$0c, *+16 + brset 6,$0d, *+17 + brclr 6,$0e, *+18 + brset 7,$0f, *+19 + brclr 7,$10, *+20 +;;; 1X + bset 0,$11 + bclr 0,$12 + bset 1,$13 + bclr 1,$14 + bset 2,$15 + bclr 2,$16 + bset 3,$17 + bclr 3,$18 + bset 4,$19 + bclr 4,$1a + bset 5,$1b + bclr 5,$1c + bset 6,$1d + bclr 6,$1e + bset 7,$1f + bclr 7,$20 +;;; 2X + bra *+$23 + brn *+$23 + bhi *+$25 + bls *+$26 + bcc *+$27 + bcs *+$28 + bhs *+$27 + blo *+$28 + bne *+$29 + beq *+$2a + bhcc *+$2b + bhcs *+$2c + bpl *+$2d + bmi *+$2e + bmc *+$2f + bms *+$30 + bil *+$31 + bih *+$32 +;;; 3X + neg $31 + com $34 + lsr $35 + ror $37 + asr $38 + lsl $39 + asl $39 + rol $3a + dec $3b + inc $3d + tst $3e + clr $40 +;;; 4X + nega + mul + coma + lsra + rora + asra + lsla + asla + rola + deca + inca + tsta + clra +;;; 5X + negx + comx + lsrx + rorx + asrx + lslx + aslx + rolx + decx + incx + tstx + clrx +;;; 6X + neg $61,x + com $64,x + lsr $65,x + ror $67,x + asr $68,x + lsl $69,x + asl $69,x + rol $6a,x + dec $6b,x + inc $6d,x + tst $6e,x + clr $70,x +;;; 7X + neg ,x + com ,x + lsr ,x + ror ,x + asr ,x + lsl ,x + asl ,x + rol ,x + dec ,x + inc ,x + tst ,x + clr ,x +;;; 8X + rti + rts + swi + stop + wait +;;; 9X + tax + clc + sec + cli + sei + rsp + nop + txa +;;; AX + sub #$a1 + cmp #$a2 + sbc #$a3 + cpx #$a4 + and #$a5 + bit #$a6 + lda #$a7 + eor #$a9 + adc #$aa + ora #$ab + add #$ac + bsr *-80 + ldx #$af +;;; BX + sub $b1 + cmp $b2 + sbc $b3 + cpx $b4 + and $b5 + bit $b6 + lda $b7 + sta $b8 + eor $b9 + adc $ba + ora $bb + add $bc + jmp $bd + jsr $be + ldx $bf + stx $c0 +;;; CX + sub abs+$01c2 + cmp abs+$02c3 + sbc abs+$03c4 + cpx abs+$04c5 + and abs+$05c6 + bit abs+$06c7 + lda abs+$07c8 + sta abs+$08c9 + eor abs+$09ca + adc abs+$0acb + ora abs+$0bcc + add abs+$0ccd + jmp abs+$0dce + jsr abs+$0ecf + ldx abs+$0fd0 + stx abs+$00d1 +;;; DX + sub $d1d2,x + cmp $d2d3,x + sbc $d3d4,x + cpx $d4d5,x + and $d5d6,x + bit $d6d7,x + lda $d7d8,x + sta $d8d9,x + eor $d9da,x + adc $dadb,x + ora $dbdc,x + add $dcdd,x + jmp $ddde,x + jsr $dedf,x + ldx $dfe0,x + stx $e0e1,x +;;; EX + sub $e1,x + cmp $e2,x + sbc $e3,x + cpx $e4,x + and $e5,x + bit $e6,x + lda $e7,x + sta $e8,x + eor $e9,x + adc $ea,x + ora $eb,x + add $ec,x + jmp $ed,x + jsr $ee,x + ldx $ef,x + stx $f0,x +;;; FX + sub ,x + cmp ,x + sbc ,x + cpx ,x + and ,x + bit ,x + lda ,x + sta ,x + eor ,x + adc ,x + ora ,x + add ,x + jmp ,x + jsr ,x + ldx ,x + stx ,x + +;;; Local Variables: +;;; mode: asm +;;; End: +;;; vim: set ft=asm: diff --git a/test/reference/test_mc68hc05.s19 b/test/reference/test_mc68hc05.s19 index 9ca1ef317..09e9b36d3 100644 --- a/test/reference/test_mc68hc05.s19 +++ b/test/reference/test_mc68hc05.s19 @@ -9,20 +9,20 @@ S1130160262727282829292A2A2B2B2C2C2D2D2EEB S11301702E2F2F3030313334343536373738383941 S11301803839393A3A3B3C3D3D3E3F404042434496 S113019046474848494A4C4D4F505354565758586F -S11301A0595A5C5D5F707364016606670868096884 -S11301B009690A6A0B6C0D6D0E6FFF7073747677A4 -S11301C07878797A7C7D7F8081838E8F9798999ACD -S11301D09B9C9D9FA0A1A1A2A2A3A3A4A4A5A5A604 -S11301E0A6A7A8A9A9AAAAABABACADAEAEAFB0B155 -S11301F0B1B2B2B3B3B4B4B5B5B6B6B7B7B8B8B9AB -S1130200B9BABABBBBBCBCBDBDBEBEBFBFC0C011CA -S1130210C2C112C3C213C4C314C5C415C6C516C70C -S1130220C617C8C718C9C819CAC91ACBCA1BCCCBA8 -S11302301CCDCC1DCECD1ECFCE1FD0CF10D1D0D152 -S1130240D2D1D2D3D2D3D4D3D4D5D4D5D6D5D6D76C -S1130250D6D7D8D7D8D9D8D9DAD9DADBDADBDCDB08 -S1130260DCDDDCDDDEDDDEDFDEDFE0DFE0E1E0E1A2 -S1130270E1E2E2E3E3E4E4E5E5E6E6E7E7E8E8E92A -S1130280E9EAEAEBEBECECEDEDEEEEEFEFF0F0F19A -S1110290F2F3F4F5F6F7F8F9FAFBFCFDFEFFC5 +S11301A0595A5C5D5F60616364646566676768682B +S11301B0696869696A6A6B6C6D6D6E6F707073746F +S11301C076777878797A7C7D7F8081838E8F979813 +S11301D0999A9B9C9D9FA0A1A1A2A2A3A3A4A4A51C +S11301E0A5A6A6A7A8A9A9AAAAABABACADAEAEAF6B +S11301F0B0B1B1B2B2B3B3B4B4B5B5B6B6B7B7B8BB +S1130200B8B9B9BABABBBBBCBCBDBDBEBEBFBFC02A +S1130210C011C2C112C3C213C4C314C5C415C6C518 +S113022016C7C617C8C718C9C819CAC91ACBCA1B62 +S1130230CCCB1CCDCC1DCECD1ECFCE1FD0CF10D15C +S1130240D0D1D2D1D2D3D2D3D4D3D4D5D4D5D6D578 +S1130250D6D7D6D7D8D7D8D9D8D9DAD9DADBDADB12 +S1130260DCDBDCDDDCDDDEDDDEDFDEDFE0DFE0E1AC +S1130270E0E1E1E2E2E3E3E4E4E5E5E6E6E7E7E83A +S1130280E8E9E9EAEAEBEBECECEDEDEEEEEFEFF0AA +S1130290F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFFE2 S9030000FC diff --git a/test/reference/test_mc68hc08.asm b/test/reference/test_mc68hc08.asm new file mode 100644 index 000000000..967fa7ccb --- /dev/null +++ b/test/reference/test_mc68hc08.asm @@ -0,0 +1,19 @@ +;;; Copyright 2024 Tadashi G. Takaoka +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + + cpu 68HC08 + org $0100 +abs: equ $C000 + include "test_mc68hc05.inc" + include "test_mc68hc08.inc" diff --git a/test/reference/test_mc68hc08.inc b/test/reference/test_mc68hc08.inc new file mode 100644 index 000000000..bd6ad9616 --- /dev/null +++ b/test/reference/test_mc68hc08.inc @@ -0,0 +1,111 @@ +;;; Copyright 2024 Tadashi G. Takaoka +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; X1 + cbeq $32, *+$36 + cbeqa #$42, *+$46 + cbeqx #$52, *+$56 + cbeq $62,x+, *+$66 + cbeq x+, *+$74 +;;; X2 + div + nsa + daa +;;; X5 + sthx $36 + ldhx #$4647 + ldhx $56 + cphx #$6667 + cphx $76 +;;; XB + dbnz $3c, *+$40 + dbnza *+$4e + dbnzx *+$5e + dbnz $6c,x, *+$70 + dbnz ,x, *+$7e +;;; XE + mov $4f, $50 + mov $5f, x+ + mov #$6f, $70 + mov x+, $7f +;;; 8X + tap + tpa + pula + psha + pulx + pshx + pulh + pshh + clrh +;;; 9X + bge *-$6d + blt *-$6c + bgt *-$6b + ble *-$6a + txs + tsx +;;; AX + ais #-$58 + aix #-$50 +;;; 9E 6X + neg $61,sp + cbeq $62,sp, *+$67 + com $64,sp + lsr $65,sp + ror $67,sp + asr $68,sp + lsl $69,sp + asl $69,sp + rol $6a,sp + dec $6b,sp + dbnz $6c,sp, *+$71 + inc $6d,sp + tst $6e,sp + clr $70,sp +;;; 9E DX + sub $d1d2,sp + cmp $d2d3,sp + sbc $d3d4,sp + cpx $d4d5,sp + and $d5d6,sp + bit $d6d7,sp + lda $d7d8,sp + sta $d8d9,sp + eor $d9da,sp + adc $dadb,sp + ora $dbdc,sp + add $dcdd,sp + ldx $dfe0,sp + stx $e0e1,sp +;;; 9E EX + sub $e1,sp + cmp $e2,sp + sbc $e3,sp + cpx $e4,sp + and $e5,sp + bit $e6,sp + lda $e7,sp + sta $e8,sp + eor $e9,sp + adc $ea,sp + ora $eb,sp + add $ec,sp + ldx $ef,sp + stx $f0,sp + +;;; Local Variables: +;;; mode: asm +;;; End: +;;; vim: set ft=asm: diff --git a/test/reference/test_mc68hc08.s19 b/test/reference/test_mc68hc08.s19 new file mode 100644 index 000000000..2600effed --- /dev/null +++ b/test/reference/test_mc68hc08.s19 @@ -0,0 +1,42 @@ +S0030000FC +S113010000010201020302030403040504050605B9 +S1130110060706070807080908090A090A0B0A0B53 +S11301200C0B0C0D0C0D0E0D0E0F0E0F100F1011ED +S1130130101111121213131414151516161717187B +S11301401819191A1A1B1B1C1C1D1D1E1E1F1F20EB +S11301502021212122232324242525262425252664 +S1130160262727282829292A2A2B2B2C2C2D2D2EEB +S11301702E2F2F3030313334343536373738383941 +S11301803839393A3A3B3C3D3D3E3F404042434496 +S113019046474848494A4C4D4F505354565758586F +S11301A0595A5C5D5F60616364646566676768682B +S11301B0696869696A6A6B6C6D6D6E6F707073746F +S11301C076777878797A7C7D7F8081838E8F979813 +S11301D0999A9B9C9D9FA0A1A1A2A2A3A3A4A4A51C +S11301E0A5A6A6A7A8A9A9AAAAABABACADAEAEAF6B +S11301F0B0B1B1B2B2B3B3B4B4B5B5B6B6B7B7B8BB +S1130200B8B9B9BABABBBBBCBCBDBDBEBEBFBFC02A +S1130210C0C1C2C1C2C3C2C3C4C3C4C5C4C5C6C5A8 +S1130220C6C7C6C7C8C7C8C9C8C9CAC9CACBCACB42 +S1130230CCCBCCCDCCCDCECDCECFCECFD0CFC0D1EC +S1130240D0D1D2D1D2D3D2D3D4D3D4D5D4D5D6D578 +S1130250D6D7D6D7D8D7D8D9D8D9DAD9DADBDADB12 +S1130260DCDBDCDDDCDDDEDDDEDFDEDFE0DFE0E1AC +S1130270E0E1E1E2E2E3E3E4E4E5E5E6E6E7E7E83A +S1130280E8E9E9EAEAEBEBECECEDEDEEEEEFEFF0AA +S1130290F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFFE2 +S11302A0313233414243515253616263717252623B +S11302B0723536454647555665666775763B3C3D0F +S11302C04B4C5B5C6B6C6D7B7C4E4F505E5F6E6F1A +S11302D0707E7F8485868788898A8B8C90919192A1 +S11302E0929393949495A7A8AFB09E60619E616227 +S11302F0639E63649E64659E66679E67689E686984 +S11303009E68699E696A9E6A6B9E6B6C6D9E6C6D3D +S11303109E6D6E9E6F709ED0D1D29ED1D2D39ED24E +S1130320D3D49ED3D4D59ED4D5D69ED5D6D79ED657 +S1130330D7D89ED7D8D99ED8D9DA9ED9DADB9EDA17 +S1130340DBDC9EDBDCDD9EDEDFE09EDFE0E19EE0C9 +S1130350E19EE1E29EE2E39EE3E49EE4E59EE5E6BF +S11303609EE6E79EE7E89EE8E99EE9EA9EEAEB9EC0 +S10B0370EBEC9EEEEF9EEFF0B2 +S9030000FC diff --git a/test/test_asm_mc6805.cpp b/test/test_asm_mc6805.cpp index 3a7481867..664a1c9aa 100644 --- a/test/test_asm_mc6805.cpp +++ b/test/test_asm_mc6805.cpp @@ -32,6 +32,10 @@ static bool m68hc05() { return strcmp_P("68HC05", assembler.config().cpu_P()) == 0; } +static bool m68hc08() { + return strcmp_P("68HC08", assembler.config().cpu_P()) == 0; +} + static void set_up() { assembler.reset(); } @@ -51,6 +55,9 @@ void test_cpu() { EQUALS("cpu 68HC05", true, assembler.setCpu("68hc05")); EQUALS_P("cpu 68HC05", "68HC05", assembler.config().cpu_P()); + EQUALS("cpu 68HC08", true, assembler.setCpu("68hc08")); + EQUALS_P("cpu 68HC08", "68HC08", assembler.config().cpu_P()); + EQUALS("cpu MC6805", true, assembler.setCpu("mc6805")); EQUALS_P("cpu MC6805", "6805", assembler.config().cpu_P()); @@ -59,6 +66,9 @@ void test_cpu() { EQUALS("cpu MC68HC05", true, assembler.setCpu("mc68hc05")); EQUALS_P("cpu MC68HC05", "68HC05", assembler.config().cpu_P()); + + EQUALS("cpu MC68HC08", true, assembler.setCpu("mc68hc08")); + EQUALS_P("cpu MC68HC08", "68HC08", assembler.config().cpu_P()); } static void test_inherent() { @@ -73,8 +83,7 @@ static void test_inherent() { TEST("SWI", 0x83); TEST("TAX", 0x97); TEST("TXA", 0x9F); - if (m146805() || m68hc05()) { - // MC146805/MC68HC05 + if (m146805() || m68hc05() || m68hc08()) { TEST("WAIT", 0x8F); } else { ERUI("WAIT"); @@ -104,22 +113,37 @@ static void test_inherent() { TEST("TSTX", 0x5D); TEST("CLRX", 0x5F); - if (m68hc05()) { - // MC68HC05 + if (m68hc05() || m68hc08()) { TEST("MUL", 0x42); } else { ERUI("MUL"); } - if (m146805() || m68hc05()) { - // MC146805/MC68HC05 + if (m146805() || m68hc05() || m68hc08()) { TEST("STOP", 0x8E); } else { ERUI("STOP"); } + if (m68hc08()) { + TEST("DIV", 0x52); + TEST("NSA", 0x62); + TEST("DAA", 0x72); + TEST("TAP", 0x84); + TEST("TPA", 0x85); + TEST("PULA", 0x86); + TEST("PSHA", 0x87); + TEST("PULX", 0x88); + TEST("PSHX", 0x89); + TEST("PULH", 0x8A); + TEST("PSHH", 0x8B); + TEST("CLRH", 0x8C); + TEST("TXS", 0x94); + TEST("TSX", 0x95); + } } static void test_relative() { ATEST(0x1000, "BRA $1002", 0x20, 0x00); + ATEST(0x1000, "BRN $1081", 0x21, 0x7F); ATEST(0x1000, "BHI $1004", 0x22, 0x02); ATEST(0x1000, "BLS $0F82", 0x23, 0x80); ATEST(0x1000, "BHS $1081", 0x24, 0x7F); @@ -140,8 +164,25 @@ static void test_relative() { ATEST(0x1000, "BSR $1042", 0xAD, 0x40); ATEST(0x1000, "BSR *+$42", 0xAD, 0x40); - AERRT(0x1FF0, "BRA $2000", OVERFLOW_RANGE, "$2000", 0x20, 0x0E); - ATEST(0x1000, "BRN $1081", 0x21, 0x7F); + if (m68hc08()) { + ATEST(0x1000, "BGE $1081", 0x90, 0x7F); + ATEST(0x1000, "BLT $0F82", 0x91, 0x80); + ATEST(0x1000, "BGT $1081", 0x92, 0x7F); + ATEST(0x1000, "BLE $0F82", 0x93, 0x80); + + ATEST(0x1000, "CBEQ $90, $1003", 0x31, 0x90, 0x00); + ATEST(0x1000, "CBEQA #$90, $1082", 0x41, 0x90, 0x7F); + ATEST(0x1000, "CBEQX #$90, $0F83", 0x51, 0x90, 0x80); + ATEST(0x1000, "CBEQ 144,X+, $1004", 0x61, 0x90, 0x01); + ATEST(0x1000, "CBEQ X+, $1000", 0x71, 0xFE); + + ATEST(0x1000, "DBNZ $90, $1003", 0x3B, 0x90, 0x00); + ATEST(0x1000, "DBNZA $1081", 0x4B, 0x7F); + ATEST(0x1000, "DBNZX $0F82", 0x5B, 0x80); + ATEST(0x1000, "DBNZ 144,X, $1004", 0x6B, 0x90, 0x01); + ATEST(0x1000, "DBNZ ,X, $1000", 0x7B, 0xFE); + ATEST(0x1000, "DBNZ X, $1000", 0x7B, 0xFE); + } symtab.intern(0x0F82, "sub0F82"); symtab.intern(0x1081, "sub1081"); @@ -170,6 +211,21 @@ static void test_immediate() { TEST("LDX #$90", 0xAE, 0x90); ERRT("STX #$90", OPERAND_NOT_ALLOWED, "#$90"); + if (m68hc08()) { + TEST("LDHX #$1234", 0x45, 0x12, 0x34); + TEST("CPHX #$1234", 0x65, 0x12, 0x34); + TEST("AIS #2", 0xA7, 0x02); + TEST("AIX #1", 0xAF, 0x01); + TEST("AIS #-2", 0xA7, 0xFE); + TEST("AIX #-1", 0xAF, 0xFF); + TEST("AIS #$7F", 0xA7, 0x7F); + TEST("AIX #$7F", 0xAF, 0x7F); + TEST("AIS #-$80", 0xA7, 0x80); + TEST("AIX #-$80", 0xAF, 0x80); + ERRT("AIS #128", OVERFLOW_RANGE, "#128", 0xA7, 0x80); + ERRT("AIX #-129", OVERFLOW_RANGE, "#-129", 0xAF, 0x7F); + } + ERRT("BSR #$90", OPERAND_NOT_ALLOWED, "#$90"); ERRT("JSR #$90", OPERAND_NOT_ALLOWED, "#$90"); ERRT("JMP #$90", OPERAND_NOT_ALLOWED, "#$90"); @@ -211,6 +267,16 @@ static void test_direct() { TEST("LDX $90", 0xBE, 0x90); TEST("STX $90", 0xBF, 0x90); + if (m68hc08()) { + TEST("STHX $90", 0x35, 0x90); + TEST("LDHX $90", 0x55, 0x90); + TEST("CPHX $90", 0x75, 0x90); + TEST("MOV $90, $40", 0x4E, 0x90, 0x40); + TEST("MOV $90, X+", 0x5E, 0x90); + TEST("MOV #$90, $40", 0x6E, 0x90, 0x40); + TEST("MOV X+, $40", 0x7E, 0x40); + } + TEST("JSR $90", 0xBD, 0x90); symtab.intern(0x10, "dir_10"); @@ -249,7 +315,13 @@ static void test_extended() { TEST("ADC >$0090", 0xC9, 0x00, 0x90); TEST("ORA >$0090", 0xCA, 0x00, 0x90); TEST("ADD $1FFF", 0xCB, 0x1F, 0xFF); - ERRT("SUB $2000", OVERFLOW_RANGE, "$2000", 0xC0, 0x20, 0x00); + if (m68hc08()) { + TEST("SUB $2000", 0xC0, 0x20, 0x00); + TEST("ADD $FFFF", 0xCB, 0xFF, 0xFF); + } else { + ERRT("SUB $2000", OVERFLOW_RANGE, "$2000", 0xC0, 0x20, 0x00); + ERRT("ADD $FFFF", OVERFLOW_RANGE, "$FFFF", 0xCB, 0xFF, 0xFF); + } TEST("CPX $1ABC", 0xC3, 0x1A, 0xBC); TEST("LDX $1ABC", 0xCE, 0x1A, 0xBC); @@ -258,9 +330,15 @@ static void test_extended() { TEST("JMP >$0034", 0xCC, 0x00, 0x34); TEST("JSR $1234", 0xCD, 0x12, 0x34); - ERRT("CPX $2000", OVERFLOW_RANGE, "$2000", 0xC3, 0x20, 0x00); - ERRT("JMP $4000", OVERFLOW_RANGE, "$4000", 0xCC, 0x40, 0x00); - ERRT("JSR $8000", OVERFLOW_RANGE, "$8000", 0xCD, 0x80, 0x00); + if (m68hc08()) { + TEST("CPX $2000", 0xC3, 0x20, 0x00); + TEST("JMP $4000", 0xCC, 0x40, 0x00); + TEST("JSR $8000", 0xCD, 0x80, 0x00); + } else { + ERRT("CPX $2000", OVERFLOW_RANGE, "$2000", 0xC3, 0x20, 0x00); + ERRT("JMP $4000", OVERFLOW_RANGE, "$4000", 0xCC, 0x40, 0x00); + ERRT("JSR $8000", OVERFLOW_RANGE, "$8000", 0xCD, 0x80, 0x00); + } symtab.intern(0x0090, "ext0090"); symtab.intern(0x1ABC, "ext1ABC"); @@ -277,22 +355,42 @@ static void test_extended() { TEST("JSR ext0090", 0xBD, 0x90); TEST(R"(option "pc-bits", "11")"); // MC68HC05J for instance - TEST( "LDA $07FF", 0xC6, 0x07, 0xFF); - ERRT( "LDA $0800", OVERFLOW_RANGE, "$0800", 0xC6, 0x08, 0x00); - ATEST(0x07F0, "BSR $07FF", 0xAD, 0x0D); - AERRT(0x07F0, "BSR $0800", OVERFLOW_RANGE, "$0800", 0xAD, 0x0E); + if (m68hc08()) { + TEST( "LDA $0800", 0xC6, 0x08, 0x00); + ATEST(0x07F0, "BSR $0800", 0xAD, 0x0E); + } else { + TEST( "LDA $07FF", 0xC6, 0x07, 0xFF); + ERRT( "LDA $0800", OVERFLOW_RANGE, "$0800", 0xC6, 0x08, 0x00); + ATEST(0x07F0, "BSR $07FF", 0xAD, 0x0D); + AERRT(0x07F0, "BSR $0800", OVERFLOW_RANGE, "$0800", 0xAD, 0x0E); + } TEST(R"(option "pc-bits", 0)"); // Most of MC68HC05 has 13bits PC. - TEST( "LDA $1FFF", 0xC6, 0x1F, 0xFF); - ERRT( "LDA $2000", OVERFLOW_RANGE, "$2000", 0xC6, 0x20, 0x00); - ATEST(0x1FF0, "BSR $1FFF", 0xAD, 0x0D); - AERRT(0x1FF0, "BSR $2000", OVERFLOW_RANGE, "$2000", 0xAD, 0x0E); + if (m68hc08()) { + TEST( "LDA $2000", 0xC6, 0x20, 0x00); + ATEST(0x1FF0, "BSR $2000", 0xAD, 0x0E); + } else { + TEST( "LDA $1FFF", 0xC6, 0x1F, 0xFF); + ERRT( "LDA $2000", OVERFLOW_RANGE, "$2000", 0xC6, 0x20, 0x00); + ATEST(0x1FF0, "BSR $1FFF", 0xAD, 0x0D); + AERRT(0x1FF0, "BSR $2000", OVERFLOW_RANGE, "$2000", 0xAD, 0x0E); + } assembler.setOption("pc-bits", "14"); // MC68HC05X for instance - TEST( "LDA $3FFF", 0xC6, 0x3F, 0xFF); - ERRT( "LDA $4000", OVERFLOW_RANGE, "$4000", 0xC6, 0x40, 0x00); - ATEST(0x3FF0, "BSR $3FFF", 0xAD, 0x0D); - AERRT(0x3FF0, "BSR $4000", OVERFLOW_RANGE, "$4000", 0xAD, 0x0E); + if (m68hc08()) { + TEST( "LDA $4000", 0xC6, 0x40, 0x00); + ATEST(0x3FF0, "BSR $4000", 0xAD, 0x0E); + } else { + TEST( "LDA $3FFF", 0xC6, 0x3F, 0xFF); + ERRT( "LDA $4000", OVERFLOW_RANGE, "$4000", 0xC6, 0x40, 0x00); + ATEST(0x3FF0, "BSR $3FFF", 0xAD, 0x0D); + AERRT(0x3FF0, "BSR $4000", OVERFLOW_RANGE, "$4000", 0xAD, 0x0E); + } + + if (m68hc08()) { + TEST( "LDA $FFFF", 0xC6, 0xFF, 0xFF); + AERRT(0xFFF0, "BSR $0000", OVERFLOW_RANGE, "$0000", 0xAD, 0x0E); + } } static void test_indexed() { @@ -384,6 +482,56 @@ static void test_indexed() { TEST("JMP <0,X", 0xEC, 0x00); TEST("JSR 255,X", 0xED, 0xFF); + if (m68hc08()) { + TEST("NEG 0,SP", 0x9E, 0x60, 0x00); + TEST("NEG <0,SP", 0x9E, 0x60, 0x00); + ERRT("NEG >0,SP", OPERAND_NOT_ALLOWED, ">0,SP"); + TEST("COM 255,SP", 0x9E, 0x63, 0xFF); + ERRT("COM 256,SP", OPERAND_NOT_ALLOWED, "256,SP"); + TEST("LSR 1,SP", 0x9E, 0x64, 0x01); + TEST("ROR 2,SP", 0x9E, 0x66, 0x02); + TEST("ASR 3,SP", 0x9E, 0x67, 0x03); + TEST("ASL 4,SP", 0x9E, 0x68, 0x04); + TEST("ROL 5,SP", 0x9E, 0x69, 0x05); + TEST("DEC 6,SP", 0x9E, 0x6A, 0x06); + TEST("INC 127,SP", 0x9E, 0x6C, 0x7F); + TEST("TST 128,SP", 0x9E, 0x6D, 0x80); + TEST("CLR 255,SP", 0x9E, 0x6F, 0xFF); + + TEST("SUB 0,SP", 0x9E, 0xE0, 0x00); + TEST("SUB <0,SP", 0x9E, 0xE0, 0x00); + TEST("SUB >0,SP", 0x9E, 0xD0, 0x00, 0x00); + TEST("CMP 255,SP", 0x9E, 0xE1, 0xFF); + TEST("CMP 256,SP", 0x9E, 0xD1, 0x01, 0x00); + TEST("SBC 1,SP", 0x9E, 0xE2, 0x01); + TEST("AND 2,SP", 0x9E, 0xE4, 0x02); + TEST("BIT 3,SP", 0x9E, 0xE5, 0x03); + TEST("LDA 4,SP", 0x9E, 0xE6, 0x04); + TEST("STA 5,SP", 0x9E, 0xE7, 0x05); + TEST("EOR 6,SP", 0x9E, 0xE8, 0x06); + TEST("ADC 127,SP", 0x9E, 0xE9, 0x7F); + TEST("ORA 128,SP", 0x9E, 0xEA, 0x80); + TEST("ADD 255,SP", 0x9E, 0xEB, 0xFF); + TEST("CPX 127,SP", 0x9E, 0xE3, 0x7F); + TEST("LDX 128,SP", 0x9E, 0xEE, 0x80); + TEST("STX 255,SP", 0x9E, 0xEF, 0xFF); + + TEST("SUB >$000,SP", 0x9E, 0xD0, 0x00, 0x00); + TEST("CMP >$0FF,SP", 0x9E, 0xD1, 0x00, 0xFF); + TEST("SBC $0100,SP", 0x9E, 0xD2, 0x01, 0x00); + TEST("AND $0200,SP", 0x9E, 0xD4, 0x02, 0x00); + TEST("BIT $0400,SP", 0x9E, 0xD5, 0x04, 0x00); + TEST("LDA $0800,SP", 0x9E, 0xD6, 0x08, 0x00); + TEST("STA $1000,SP", 0x9E, 0xD7, 0x10, 0x00); + TEST("EOR $2000,SP", 0x9E, 0xD8, 0x20, 0x00); + TEST("ADC $4000,SP", 0x9E, 0xD9, 0x40, 0x00); + TEST("ORA $8000,SP", 0x9E, 0xDA, 0x80, 0x00); + TEST("ADD $FFFF,SP", 0x9E, 0xDB, 0xFF, 0xFF); + TEST("CPX >$0000,SP", 0x9E, 0xD3, 0x00, 0x00); + TEST("LDX >$0000,SP", 0x9E, 0xDE, 0x00, 0x00); + TEST("STX >$0002,SP", 0x9E, 0xDF, 0x00, 0x02); + } + symtab.intern(0, ".offset0"); symtab.intern(128, "offset128"); symtab.intern(255, "offset255"); @@ -458,6 +606,82 @@ static void test_undef() { ERUS("BRA UNDEF+2", "UNDEF+2", 0x20, 0x00); ERUS("BRA 2+UNDEF", "UNDEF", 0x20, 0x00); ERUS("BSR UNDEF", "UNDEF", 0xAD, 0x00); + ERUS("BSET UNDEF,$23", "UNDEF,$23", 0x10, 0x23); + ERUS("BCLR UNDEF,$23", "UNDEF,$23", 0x11, 0x23); + ERUS("BSET 7,UNDEF", "UNDEF", 0x1E, 0x00); + ERUS("BCLR 7,UNDEF", "UNDEF", 0x1F, 0x00); + ERUS("BSET UNDEF,UNDEF", "UNDEF,UNDEF", 0x10, 0x00); + ERUS("BCLR UNDEF,UNDEF", "UNDEF,UNDEF", 0x11, 0x00); + AERRT(0x1000, "BRCLR UNDEF,$23,$0F83", + UNDEFINED_SYMBOL, "UNDEF,$23,$0F83", 0x01, 0x23, 0x80); + AERRT(0x1000, "BRSET UNDEF,$23,$1082", + UNDEFINED_SYMBOL, "UNDEF,$23,$1082", 0x00, 0x23, 0x7F); + AERRT(0x1000, "BRSET 1,UNDEF,$1082", + UNDEFINED_SYMBOL, "UNDEF,$1082", 0x02, 0x00, 0x7F); + AERRT(0x1000, "BRSET 2,$23,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x04, 0x23, 0x00); + AERRT(0x1000, "BRSET UNDEF,UNDEF,$1082", + UNDEFINED_SYMBOL, "UNDEF,UNDEF,$1082", 0x00, 0x00, 0x7F); + AERRT(0x1000, "BRSET UNDEF,$23,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,$23,UNDEF", 0x00, 0x23, 0x00); + AERRT(0x1000, "BRSET 3,UNDEF,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,UNDEF", 0x06, 0x00, 0x00); + AERRT(0x1000, "BRSET UNDEF,UNDEF,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,UNDEF,UNDEF", 0x00, 0x00, 0x00); + + if (m68hc08()) { + ERUS("LDHX #UNDEF", "UNDEF", 0x45, 0x00, 0x00); + ERUS("AIX #UNDEF", "UNDEF", 0xAF, 0x00); + ERUS("MOV UNDEF,$40", "UNDEF,$40", 0x4E, 0x00, 0x40); + ERUS("MOV $90,UNDEF", "UNDEF", 0x4E, 0x90, 0x00); + ERUS("MOV UNDEF,UNDEF", "UNDEF,UNDEF", 0x4E, 0x00, 0x00); + ERUS("MOV #UNDEF,$40", "UNDEF,$40", 0x6E, 0x00, 0x40); + ERUS("MOV #$90,UNDEF", "UNDEF", 0x6E, 0x90, 0x00); + ERUS("MOV #UNDEF,UNDEF", "UNDEF,UNDEF", 0x6E, 0x00, 0x00); + ERUS("MOV UNDEF,X+", "UNDEF,X+", 0x5E, 0x00); + ERUS("MOV X+,UNDEF", "UNDEF", 0x7E, 0x00); + AERRT(0x1000, "CBEQ UNDEF,$1082", + UNDEFINED_SYMBOL, "UNDEF,$1082", 0x31, 0x00, 0x7F); + AERRT(0x1000, "CBEQ $90,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x31, 0x90, 0x00); + AERRT(0x1000, "CBEQ UNDEF,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,UNDEF", 0x31, 0x00, 0x00); + AERRT(0x1000, "CBEQA #UNDEF,$1082", + UNDEFINED_SYMBOL, "UNDEF,$1082", 0x41, 0x00, 0x7F); + AERRT(0x1000, "CBEQA #$90,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x41, 0x90, 0x00); + AERRT(0x1000, "CBEQA #UNDEF,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,UNDEF", 0x41, 0x00, 0x00); + AERRT(0x1000, "CBEQX #UNDEF,$1082", + UNDEFINED_SYMBOL, "UNDEF,$1082", 0x51, 0x00, 0x7F); + AERRT(0x1000, "CBEQX #$90,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x51, 0x90, 0x00); + AERRT(0x1000, "CBEQX #UNDEF,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,UNDEF", 0x51, 0x00, 0x00); + AERRT(0x1000, "CBEQ UNDEF,X+,$1082", + UNDEFINED_SYMBOL, "UNDEF,X+,$1082", 0x61, 0x00, 0x7F); + AERRT(0x1000, "CBEQ $90,X+,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x61, 0x90, 0x00); + AERRT(0x1000, "CBEQ UNDEF,X+,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,X+,UNDEF", 0x61, 0x00, 0x00); + AERRT(0x1000, "CBEQ X+,UNDEF", UNDEFINED_SYMBOL, "UNDEF", 0x71, 0x00); + + AERRT(0x1000, "DBNZ UNDEF,$1082", + UNDEFINED_SYMBOL, "UNDEF,$1082", 0x3B, 0x00, 0x7F); + AERRT(0x1000, "DBNZ $90,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x3B, 0x90, 0x00); + AERRT(0x1000, "DBNZ UNDEF,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,UNDEF", 0x3B, 0x00, 0x00); + AERRT(0x1000, "DBNZ UNDEF,X,$1082", + UNDEFINED_SYMBOL, "UNDEF,X,$1082", 0x6B, 0x00, 0x7F); + AERRT(0x1000, "DBNZ $90,X,UNDEF", + UNDEFINED_SYMBOL, "UNDEF", 0x6B, 0x90, 0x00); + AERRT(0x1000, "DBNZ UNDEF,X,UNDEF", + UNDEFINED_SYMBOL, "UNDEF,X,UNDEF", 0x6B, 0x00, 0x00); + AERRT(0x1000, "DBNZA UNDEF", UNDEFINED_SYMBOL, "UNDEF", 0x4B, 0x00); + AERRT(0x1000, "DBNZX UNDEF", UNDEFINED_SYMBOL, "UNDEF", 0x5B, 0x00); + AERRT(0x1000, "DBNZ X,UNDEF", UNDEFINED_SYMBOL, "UNDEF", 0x7B, 0x00); + } } static void test_data_constant() { diff --git a/test/test_dis_mc6805.cpp b/test/test_dis_mc6805.cpp index a02590940..ad5e3c9cc 100644 --- a/test/test_dis_mc6805.cpp +++ b/test/test_dis_mc6805.cpp @@ -33,6 +33,10 @@ static bool m68hc05() { return strcmp_P("68HC05", disassembler.config().cpu_P()) == 0; } +static bool m68hc08() { + return strcmp_P("68HC08", disassembler.config().cpu_P()) == 0; +} + static void set_up() { disassembler.reset(); disassembler.setOption("relative", "no"); @@ -53,6 +57,9 @@ void test_cpu() { EQUALS("cpu 68HC05", true, disassembler.setCpu("68HC05")); EQUALS_P("cpu 68GC05", "68HC05", disassembler.config().cpu_P()); + EQUALS("cpu 68HC08", true, disassembler.setCpu("68HC08")); + EQUALS_P("cpu 68GC08", "68HC08", disassembler.config().cpu_P()); + EQUALS("cpu MC6805", true, disassembler.setCpu("MC6805")); EQUALS_P("cpu MC6805", "6805", disassembler.config().cpu_P()); @@ -61,6 +68,9 @@ void test_cpu() { EQUALS("cpu MC68HC05", true, disassembler.setCpu("MC68HC05")); EQUALS_P("cpu MC68GC05", "68HC05", disassembler.config().cpu_P()); + + EQUALS("cpu MC68HC08", true, disassembler.setCpu("MC68HC08")); + EQUALS_P("cpu MC68GC08", "68HC08", disassembler.config().cpu_P()); } static void test_inherent() { @@ -76,9 +86,25 @@ static void test_inherent() { TEST("TAX", "", 0x97); TEST("TXA", "", 0x9F); - if (m146805() || m68hc05()) { - // MC146805/MC68HC05 + if (m146805() || m68hc05() || m68hc08()) TEST("WAIT", "", 0x8F); + if (m68hc05() || m68hc08()) + TEST("MUL", "", 0x42); + if (m68hc08()) { + TEST("DIV", "", 0x52); + TEST("NSA", "", 0x62); + TEST("DAA", "", 0x72); + TEST("TAP", "", 0x84); + TEST("TPA", "", 0x85); + TEST("PULA", "", 0x86); + TEST("PSHA", "", 0x87); + TEST("PULX", "", 0x88); + TEST("PSHX", "", 0x89); + TEST("PULH", "", 0x8A); + TEST("PSHH", "", 0x8B); + TEST("CLRH", "", 0x8C); + TEST("TXS", "", 0x94); + TEST("TSX", "", 0x95); } TEST("NEGA", "", 0x40); @@ -122,6 +148,19 @@ static void test_immediate() { TEST("CPX", "#$90", 0xA3, 0x90); TEST("LDX", "#$90", 0xAE, 0x90); + if (m68hc08()) { + TEST("LDHX", "#$1234", 0x45, 0x12, 0x34); + TEST("CPHX", "#$1234", 0x65, 0x12, 0x34); + TEST("AIS", "#2", 0xA7, 0x02); + TEST("AIX", "#1", 0xAF, 0x01); + TEST("AIS", "#-2", 0xA7, 0xFE); + TEST("AIX", "#-1", 0xAF, 0xFF); + TEST("AIS", "#$7F", 0xA7, 0x7F); + TEST("AIX", "#$7F", 0xAF, 0x7F); + TEST("AIS", "#-$80", 0xA7, 0x80); + TEST("AIX", "#-$80", 0xAF, 0x80); + } + symtab.intern(0x90, "dir90"); symtab.intern(0x90A0, "dir90A0"); @@ -160,6 +199,18 @@ static void test_direct() { TEST("LDX", "$90", 0xBE, 0x90); TEST("STX", "$90", 0xBF, 0x90); + if (m68hc08()) { + TEST("STHX", "$90", 0x35, 0x90); + TEST("LDHX", "$90", 0x55, 0x90); + TEST("CPHX", "$90", 0x75, 0x90); + TEST("MOV", "$90, $40", 0x4E, 0x90, 0x40); + TEST("MOV", "$90, X+", 0x5E, 0x90); + TEST("MOV", "#$90, $40", 0x6E, 0x90, 0x40); + TEST("MOV", "X+, $40", 0x7E, 0x40); + } + + TEST("JSR", "$90", 0xBD, 0x90); + symtab.intern(0x10, "dir10"); symtab.intern(0x22, "dir22"); symtab.intern(0x90, "dir90"); @@ -303,6 +354,50 @@ static void test_indexed() { TEST("JMP", ">$0000,X", 0xDC, 0x00, 0x00); TEST("JSR", ">$00FF,X", 0xDD, 0x00, 0xFF); + if (m68hc08()) { + TEST("NEG", "<0,SP", 0x9E, 0x60, 0x00); + TEST("COM", "<0,SP", 0x9E, 0x63, 0x00); + TEST("LSR", "1,SP", 0x9E, 0x64, 0x01); + TEST("ROR", "2,SP", 0x9E, 0x66, 0x02); + TEST("ASR", "3,SP", 0x9E, 0x67, 0x03); + TEST("ASL", "4,SP", 0x9E, 0x68, 0x04); + TEST("ROL", "5,SP", 0x9E, 0x69, 0x05); + TEST("DEC", "6,SP", 0x9E, 0x6A, 0x06); + TEST("INC", "127,SP", 0x9E, 0x6C, 0x7F); + TEST("TST", "128,SP", 0x9E, 0x6D, 0x80); + TEST("CLR", "255,SP", 0x9E, 0x6F, 0xFF); + + TEST("SUB", "<0,SP", 0x9E, 0xE0, 0x00); + TEST("CMP", "<0,SP", 0x9E, 0xE1, 0x00); + TEST("SBC", "1,SP", 0x9E, 0xE2, 0x01); + TEST("AND", "2,SP", 0x9E, 0xE4, 0x02); + TEST("BIT", "3,SP", 0x9E, 0xE5, 0x03); + TEST("LDA", "4,SP", 0x9E, 0xE6, 0x04); + TEST("STA", "5,SP", 0x9E, 0xE7, 0x05); + TEST("EOR", "6,SP", 0x9E, 0xE8, 0x06); + TEST("ADC", "127,SP", 0x9E, 0xE9, 0x7F); + TEST("ORA", "128,SP", 0x9E, 0xEA, 0x80); + TEST("ADD", "255,SP", 0x9E, 0xEB, 0xFF); + TEST("CPX", "127,SP", 0x9E, 0xE3, 0x7F); + TEST("LDX", "128,SP", 0x9E, 0xEE, 0x80); + TEST("STX", "255,SP", 0x9E, 0xEF, 0xFF); + + TEST("SUB", ">$0000,SP", 0x9E, 0xD0, 0x00, 0x00); + TEST("CMP", ">$00FF,SP", 0x9E, 0xD1, 0x00, 0xFF); + TEST("SBC", "$0100,SP", 0x9E, 0xD2, 0x01, 0x00); + TEST("AND", "$0200,SP", 0x9E, 0xD4, 0x02, 0x00); + TEST("BIT", "$0400,SP", 0x9E, 0xD5, 0x04, 0x00); + TEST("LDA", "$0800,SP", 0x9E, 0xD6, 0x08, 0x00); + TEST("STA", "$1000,SP", 0x9E, 0xD7, 0x10, 0x00); + TEST("EOR", "$2000,SP", 0x9E, 0xD8, 0x20, 0x00); + TEST("ADC", "$4000,SP", 0x9E, 0xD9, 0x40, 0x00); + TEST("ORA", "$8000,SP", 0x9E, 0xDA, 0x80, 0x00); + TEST("ADD", "$FFFF,SP", 0x9E, 0xDB, 0xFF, 0xFF); + TEST("CPX", ">$0000,SP", 0x9E, 0xD3, 0x00, 0x00); + TEST("LDX", ">$0000,SP", 0x9E, 0xDE, 0x00, 0x00); + TEST("STX", ">$0002,SP", 0x9E, 0xDF, 0x00, 0x02); + } + symtab.intern(0, "offset0"); symtab.intern(128, "offset128"); symtab.intern(255, "offset255"); @@ -343,6 +438,25 @@ static void test_relative() { ATEST(0x1000, "BSR", "$1042", 0xAD, 0x40); + if (m68hc08()) { + ATEST(0x1000, "BGE", "$1081", 0x90, 0x7F); + ATEST(0x1000, "BLT", "$0F82", 0x91, 0x80); + ATEST(0x1000, "BGT", "$1081", 0x92, 0x7F); + ATEST(0x1000, "BLE", "$0F82", 0x93, 0x80); + + ATEST(0x1000, "CBEQ", "$90, $1003", 0x31, 0x90, 0x00); + ATEST(0x1000, "CBEQA", "#$90, $1082", 0x41, 0x90, 0x7F); + ATEST(0x1000, "CBEQX", "#$90, $0F83", 0x51, 0x90, 0x80); + ATEST(0x1000, "CBEQ", "144,X+, $1004", 0x61, 0x90, 0x01); + ATEST(0x1000, "CBEQ", "X+, $1000", 0x71, 0xFE); + + ATEST(0x1000, "DBNZ", "$90, $1003", 0x3B, 0x90, 0x00); + ATEST(0x1000, "DBNZA", "$1081", 0x4B, 0x7F); + ATEST(0x1000, "DBNZX", "$0F82", 0x5B, 0x80); + ATEST(0x1000, "DBNZ", "144,X, $1004", 0x6B, 0x90, 0x01); + ATEST(0x1000, "DBNZ", ",X, $1000", 0x7B, 0xFE); + } + symtab.intern(0x0F82, "sub0F82"); symtab.intern(0x1081, "sub1081"); @@ -389,26 +503,49 @@ static void test_bit_ops() { } static void test_illegal() { - static constexpr Config::opcode_t illegals[] = { - 0x31, 0x32, 0x35, 0x3B, 0x3E, - 0x41, 0x45, 0x4B, 0x4E, - 0x51, 0x52, 0x55, 0x5B, 0x5E, - 0x61, 0x62, 0x65, 0x6B, 0x6E, - 0x71, 0x72, 0x75, 0x7B, 0x7E, - 0x82, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x9E, - 0xA7, 0xAC, 0xAF, - }; - for (const auto opc : illegals) - UNKN(opc); - if (m68hc05()) { - return; - } else if (m146805()) { - UNKN(0x42); // MUL + if (m68hc08()) { + static constexpr Config::opcode_t illegals[] = { + 0x32, 0x3E, 0x82, 0x8D, 0x96, 0xAC, + }; + for (const auto opc : illegals) + UNKN(opc); + UNKN(0x9E, 0x62); + UNKN(0x9E, 0x65); + UNKN(0x9E, 0x6E); + UNKN(0x9E, 0xDC); + UNKN(0x9E, 0xDD); + UNKN(0x9E, 0xEC); + UNKN(0x9E, 0xED); + for (auto msn = 0x00; msn < 0x100; msn += 0x10) { + if (msn == 0x60 || msn == 0xD0 || msn == 0xE0) + continue; + for (auto lsn = 0; lsn < 0x10; lsn++) { + const Config::opcode_t opc = msn | lsn; + UNKN(0x9E, opc); + } + } } else { - UNKN(0x42); // MUL - UNKN(0x8E); // STOP - UNKN(0x8F); // WAIT + static constexpr Config::opcode_t illegals[] = { + 0x31, 0x32, 0x35, 0x3B, 0x3E, + 0x41, 0x45, 0x4B, 0x4E, + 0x51, 0x52, 0x55, 0x5B, 0x5E, + 0x61, 0x62, 0x65, 0x6B, 0x6E, + 0x71, 0x72, 0x75, 0x7B, 0x7E, + 0x82, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x9E, + 0xA7, 0xAC, 0xAF, + }; + for (const auto opc : illegals) + UNKN(opc); + if (m68hc05()) { + return; + } else if (m146805()) { + UNKN(0x42); // MUL + } else { + UNKN(0x42); // MUL + UNKN(0x8E); // STOP + UNKN(0x8F); // WAIT + } } } // clang-format on