Skip to content

Commit

Permalink
[MC68000] Add MC68010 variant
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Oct 20, 2024
1 parent 0a50263 commit 9648e09
Show file tree
Hide file tree
Showing 22 changed files with 38,721 additions and 160 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ It can generate Intel HEX or Motorola S-Record output.
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 J11 T11
MC68010 TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002 NS32032 MN1610
MN1613 MN1613A J11 T11
-o <output> : output file
-l <list> : list file
-S[<bytes>] : output Motorola S-Record format
Expand Down Expand Up @@ -122,8 +122,8 @@ It can read Intel HEX or Motorola S-Record input.
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 J11 T11
MC68010 TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002 NS32032 MN1610
MN1613 MN1613A J11 T11
-o <output> : output file
-l <list> : list file
<input> : file can be Motorola S-Record or Intel HEX format
Expand Down
8 changes: 4 additions & 4 deletions README_.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ usage: asm [-o <output>] [-l <list>] <input>
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 J11 T11
MC68010 TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002 NS32032 MN1610
MN1613 MN1613A J11 T11
-o <output> : output file
-l <list> : list file
-S[<bytes>] : output Motorola S-Record format
Expand Down Expand Up @@ -128,8 +128,8 @@ usage: dis -C <CPU> [-o <output>] [-l <list>] <input>
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 J11 T11
MC68010 TMS9900 TMS9980 TMS9995 TMS99105 Z8001 Z8002 NS32032 MN1610
MN1613 MN1613A J11 T11
-o <output> : output file
-l <list> : list file
<input> : file can be Motorola S-Record or Intel HEX format
Expand Down
4 changes: 3 additions & 1 deletion src/Makefile.arch
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ TGT_i8086 = i8086 i80186 v30
TGT_i8096 = i8096
TGT_ins8060 = ins8060
TGT_ins8070 = ins8070
TGT_mc68000 = mc68000 m68k
TGT_mc68000 = mc68000 mc68010 m68k m68k10
TGT_mc6800 = mc6800 mb8861 mc6801 mc68hc11 hd6301
TGT_mc6805 = mc68hc05
TGT_mc6809 = mc6809 hd6309
Expand Down Expand Up @@ -102,8 +102,10 @@ CPU_ins8060 = SC/MP
CPU_ins8070 = 8070
CPU_j11 = J11
CPU_m68k = 68000
CPU_m68k10 = 68010
CPU_mb8861 = MB8861
CPU_mc68000 = 68000
CPU_mc68010 = 68010
CPU_mc6800 = 6800
CPU_mc6801 = 6801
CPU_mc6809 = 6809
Expand Down
21 changes: 17 additions & 4 deletions src/asm_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ int8_t modePos(OprPos pos) {
// clang-format off
static constexpr int8_t BITNO[] PROGMEM = {
3, 6, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1,
};
// clang-format on
return static_cast<int8_t>(pgm_read_byte(&BITNO[pos]));
Expand All @@ -120,7 +120,7 @@ int8_t regPos(OprPos pos) {
// clang-format off
static constexpr int8_t BITNO[] PROGMEM = {
0, 9, 0, 9, -1,
-1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1,
};
// clang-format on
return static_cast<int8_t>(pgm_read_byte(&BITNO[pos]));
Expand All @@ -130,7 +130,7 @@ int8_t postPos(OprPos pos) {
// clang-format off
static constexpr int8_t BITNO[] PROGMEM = {
-1, -1, -1, -1, -1,
10, 7, 7, 0, 4, 0, 4,
10, 7, 7, 0, 4, 0, 4, 12, 0,
};
// clang-format on
return static_cast<int8_t>(pgm_read_byte(&BITNO[pos]));
Expand Down Expand Up @@ -387,10 +387,16 @@ Error AsmMc68000::encodeOperand(
if (size == SZ_DUBL || size == SZ_XTND || size == SZ_PBCD)
insn.setErrorIf(op, ILLEGAL_SIZE);
}
if (post_gp >= 0)
insn.embedPostfix(encodeGeneralRegNo(op.reg) << post_gp);
break;
case M_AREG:
if (size == SZ_BYTE)
if (post_gp >= 0) {
// MOVES.B An is OK
insn.embedPostfix(encodeGeneralRegNo(op.reg) << post_gp);
} else if (size == SZ_BYTE) {
insn.setErrorIf(op, OPERAND_NOT_ALLOWED);
}
break;
case M_INDX:
encodeBriefExtension(insn, op, static_cast<Config::ptrdiff_t>(val32));
Expand Down Expand Up @@ -488,6 +494,11 @@ Error AsmMc68000::encodeOperand(
case M_FCMLT:
encodeFloatControlList(insn, op);
break;
case M_USP:
case M_CREG:
if (post_gp == 0)
insn.embedPostfix(encodeControlRegNo(op.reg));
break;
default:
break;
}
Expand Down Expand Up @@ -791,6 +802,8 @@ Error AsmMc68000::parseOperand(StrScanner &scan, Operand &op) const {
op.mode = M_FPSR;
} else if (op.reg == REG_FPIAR) {
op.mode = M_FPIAR;
} else if (isControlReg(op.reg)) {
op.mode = M_CREG;
} else {
return op.setError(p, REGISTER_NOT_ALLOWED);
}
Expand Down
1 change: 1 addition & 0 deletions src/config_mc68000.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace mc68000 {

enum CpuType : uint8_t {
MC68000,
MC68010,
};

enum FpuType : uint8_t {
Expand Down
7 changes: 7 additions & 0 deletions src/dis_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@ uint8_t regVal(const DisInsn &insn, OprPos pos) {
case EX_DL:
case EX_DK:
return (post >> 4) & 7;
case EX_RR:
return (post >> 12) & 7;
default:
return 0;
}
Expand Down Expand Up @@ -531,6 +533,7 @@ void DisMc68000::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode, Opr
if (size == SZ_DUBL || size == SZ_XTND || size == SZ_PBCD)
insn.setErrorIf(out, ILLEGAL_SIZE);
}
RegName reg;
switch (mode) {
case M_AREG:
case M_PDEC:
Expand Down Expand Up @@ -648,6 +651,10 @@ void DisMc68000::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode, Opr
case M_IMROM:
outHex(out.letter('#'), insn.postfix() & 0x7F, 7, false);
break;
case M_CREG:
if ((reg = decodeControlReg(insn.postfix())) == REG_UNDEF)
insn.setErrorIf(out, ILLEGAL_REGISTER);
outRegName(out, reg);
default:
break;
}
Expand Down
125 changes: 99 additions & 26 deletions src/entry_mc68000.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ enum AddrMode : uint8_t {
M_IMDAT = 8 + 4, // #imm: Immediate Data

M_ERROR = 64, // TODO: Remove
M_LABEL = 65, // label

// for assembler operand parsing
M_NONE = 16, // no operand
Expand All @@ -94,35 +93,41 @@ enum AddrMode : uint8_t {
M_IM8 = 34, // 8-bit Immediate
M_IMVEC = 35, // 3-bit Trap Vector
M_IMDSP = 36, // 16-bit Signed Displacement
M_LABEL = 37, // label

// MC68010
M_CREG = 38, // Control register: SFC, DFC, USP, VBR

// MC68881
M_FPREG = 37, // FPn: Floatng point data register
M_FPMLT = 38, // FMOVEM.X register list; FPn
M_FCMLT = 39, // FMOVEM.L register list; FPCR/FPSR/FPIAR
M_FSICO = 40, // FPSINCOS FPc:FPs
M_KDREG = 41, // <ea>{Dn}
M_KFACT = 42, // <ea>{#k}
M_FPCR = 43, // FPCR register
M_FPSR = 44, // FPSR register
M_FPIAR = 45, // FPIAR register
M_IMROM = 46, // MC68881 ROM constant
M_REL32 = 47, // 32-bit Relative; 1111|ccc|01s|___|___: s=0 16bit, s=1 32bit
M_IMFLT = 48, // Floating point immediate
M_FPREG = 39, // FPn: Floatng point data register
M_FPMLT = 40, // FMOVEM.X register list; FPn
M_FCMLT = 41, // FMOVEM.L register list; FPCR/FPSR/FPIAR
M_FSICO = 42, // FPSINCOS FPc:FPs
M_KDREG = 43, // <ea>{Dn}
M_KFACT = 44, // <ea>{#k}
M_FPCR = 45, // FPCR register
M_FPSR = 46, // FPSR register
M_FPIAR = 47, // FPIAR register
M_IMROM = 48, // MC68881 ROM constant
M_REL32 = 49, // 32-bit Relative; 1111|ccc|01s|___|___: s=0 16bit, s=1 32bit
M_IMFLT = 50, // Floating point immediate
};

enum OprPos : uint8_t {
OP_10 = 0, // __LIBASM___|___|___|mmm|rrr
OP_23 = 1, // __LIBASM___|rrr|mmm|___|___
OP__0 = 2, // __LIBASM___|___|___|___|rrr
OP__3 = 3, // __LIBASM___|rrr|___|___|___
OP___ = 4, // __LIBASM___|___|___|___|___
EX_RX = 5, // __LIBASM__|xxx|___|_______ : format or source register
EX_RY = 6, // __LIBASM__|___|yyy|_______ : destination register
EX_SC = 7, // __LIBASM__|___|sss|____ccc : FPSINCOS
EX_SL = 8, // __LIBASM__|___|__|ffffffff : static register list
EX_DL = 9, // __LIBASM__|___|___|rrr____ : dynamic register list
EX_SK = 10, // __LIBASM__|___|___|kkkkkkk : static k-factor
EX_DK = 11, // __LIBASM__|___|___|rrr____ : dynamic k-factor
OP_10 = 0, // __|___|___|mmm|rrr
OP_23 = 1, // __|rrr|mmm|___|___
OP__0 = 2, // __|___|___|___|rrr
OP__3 = 3, // __|rrr|___|___|___
OP___ = 4, // __|___|___|___|___
EX_RX = 5, // __|xxx|___|_______ : format or source register
EX_RY = 6, // __|___|yyy|_______ : destination register
EX_SC = 7, // __|___|sss|____ccc : FPSINCOS
EX_SL = 8, // __|___|__|ffffffff : static register list
EX_DL = 9, // __|___|___|rrr____ : dynamic register list
EX_SK = 10, // __|___|___|kkkkkkk : static k-factor
EX_DK = 11, // __|___|___|rrr____ : dynamic k-factor
EX_RR = 12, // a|rrr|____________ : Dn/An
EX_RC = 13, // _____|cccccccccccc : Control register
};

struct Entry final : entry::Base<Config::opcode_t> {
Expand Down Expand Up @@ -159,8 +164,76 @@ struct Entry final : entry::Base<Config::opcode_t> {
_dst = static_cast<uint8_t>(dst);
}
void setInsnSize(InsnSize size) { _attr = _size(oprSize(), size); }
Config::opcode_t insnMask() const {
return insnMask(dst()) | insnMask(src()) | insnMask(dstPos()) | insnMask(srcPos()) |
insnMask(oprSize());
}
Config::opcode_t postMask() const { return postMask(dstPos()) | postMask(srcPos()); }
static Config::opcode_t postMask(OprPos pos);

static Config::opcode_t insnMask(AddrMode mode) {
if (mode == M_IM8 || mode == M_REL8)
return 0xFF;
if (mode == M_IMVEC)
return 0xF;
if (mode == M_IM3)
return 07000;
if (mode == M_KFACT || mode == M_KDREG)
return 00077; // OP_10
return 0;
}

static Config::opcode_t insnMask(OprSize size) {
switch (size) {
case SZ_DATA:
return (3 << 6);
case SZ_ADDR:
return (1 << 6);
case SZ_ADR8:
return (1 << 8);
default:
return 0;
}
}

static Config::opcode_t insnMask(OprPos pos) {
static constexpr Config::opcode_t BITS[] PROGMEM = {
00077, // OP_10 = 0, // ____|___|___|mmm|rrr
07700, // OP_23 = 1, // ____|rrr|mmm|___|___
00007, // OP__0 = 2, // ____|___|___|___|rrr
07000, // OP__3 = 3, // ____|rrr|___|___|___
00000, // OP___ = 4, // ____|___|___|___|___
00000, // EX_RX = 5, // ___|xxx|___|_______ : format or source register
00000, // EX_RY = 6, // ___|___|yyy|_______ : destination register
00000, // EX_SC = 7, // ___|___|sss|____ccc : FPSINCOS
00000, // EX_SL = 8, // ___|___|__|ffffffff : static register list
00000, // EX_DL = 9, // ___|___|___|rrr____ : dynamic register list/k-factor
00000, // EX_SK = 10, // ___|___|___|kkkkkkk : static k-factor
00000, // EX_DK = 11, // ___|___|___|rrr____ : dynamic register list/k-factor
00000, // EX_RR = 12, // a|rrr|_____________ : Dn/An
00000, // EX_RC = 13, // _____|ccccccccccccc : Control register
};
return pgm_read_word(&BITS[pos]);
}

static Config::opcode_t postMask(OprPos pos) {
static constexpr Config::opcode_t BITS[] PROGMEM = {
0x0000, // OP_10 = 0, // ____|___|___|mmm|rrr
0x0000, // OP_23 = 1, // ____|rrr|mmm|___|___
0x0000, // OP__0 = 2, // ____|___|___|___|rrr
0x0000, // OP__3 = 3, // ____|rrr|___|___|___
0x0000, // OP___ = 4, // ____|___|___|___|___
0x1C00, // EX_RX = 5, // ___|xxx|___|_______ : format or source register
0x0380, // EX_RY = 6, // ___|___|yyy|_______ : destination register
0x0387, // EX_SC = 7, // ___|___|sss|____ccc : FPSINCOS
0x00FF, // EX_SL = 8, // ___|___|__|ffffffff : static register list
0x0070, // EX_DL = 9, // ___|___|___|rrr____ : dynamic register list/k-factor
0x007F, // EX_SK = 10, // ___|___|___|kkkkkkk : static k-factor
0x0070, // EX_DK = 11, // ___|___|___|rrr____ : dynamic register list/k-factor
0x7000, // EX_RR = 12, // a|rrr|_____________ : Dn/An
0x0FFF, // EX_RC = 13, // _____|ccccccccccccc : Control register
};
return pgm_read_word(&BITS[pos]);
}

private:
static constexpr uint8_t _pos(OprPos src, OprPos dst) {
Expand Down
6 changes: 6 additions & 0 deletions src/reg_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "reg_base.h"
#include <ctype.h>
#include <string.h>
#include "str_buffer.h"
#include "str_scanner.h"

namespace libasm {
namespace reg {
Expand Down Expand Up @@ -50,6 +52,10 @@ bool isPrefixLetter(char c) {

} // namespace

StrBuffer &NameEntry::outText(StrBuffer &out) const {
return out.text_P(text_P());
}

const NameEntry *NameTable::searchName(int8_t name) const {
return _table.linearSearch(name, nameMatcher, 0);
}
Expand Down
9 changes: 5 additions & 4 deletions src/reg_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
#define __LIBASM_REG_BASE_H__

#include <ctype.h>

#include "config_host.h"
#include "str_buffer.h"
#include "str_scanner.h"
#include "table_base.h"

namespace libasm {

struct StrBuffer;
struct StrScanner;

namespace reg {

static inline bool isIdLetter(char c) {
Expand All @@ -43,7 +44,7 @@ struct NameEntry {
}
int8_t name() const { return pgm_read_byte(&_name_P); }

StrBuffer &outText(StrBuffer &out) const { return out.text_P(text_P()); }
StrBuffer &outText(StrBuffer &out) const;

private:
const /*PROGMEM*/ char *const _text_P;
Expand Down
Loading

0 comments on commit 9648e09

Please sign in to comment.