--- nono/m680x0/m68030disasm.cpp 2026/04/29 17:04:31 1.1 +++ nono/m680x0/m68030disasm.cpp 2026/04/29 17:05:26 1.1.1.9 @@ -1,15 +1,14 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "m68030disasm.h" -#include "bus.h" -#include "mystring.h" +#include "debugger_memory.h" // コンストラクタ -m680x0disasm::m680x0disasm(DebuggerMD *m) - : inherited(m) +m680x0disasm::m680x0disasm() { } @@ -20,9 +19,9 @@ m680x0disasm::~m680x0disasm() // 逆アセンブルを実行 bool -m680x0disasm::Exec(saddr_t addr) +m680x0disasm::Exec(DebuggerMemoryStream *mem_) { - ExecInit(); + ExecInit(mem_); ir.clear(); name.clear(); @@ -30,10 +29,9 @@ m680x0disasm::Exec(saddr_t addr) src.clear(); dst.clear(); - pc = addr; - pc0 = pc.addr; + pc0 = mem->laddr.Addr(); - switch (fetch16() >> 6) { + switch (fetch2() >> 6) { #include "m68030switch.h" default: __unreachable(); @@ -42,7 +40,7 @@ m680x0disasm::Exec(saddr_t addr) // 出力文字列(ダンプ) for (const auto& i : ir) { dump += string_format("%04x ", i); - } + } if (ir.size() < 5) { dump += std::string(25 - ir.size() * 5, ' '); } @@ -84,43 +82,28 @@ m680x0disasm::Exec(saddr_t addr) // ワードピーク (PCを進めずワードを取得する) uint32 -m680x0disasm::peek16() +m680x0disasm::peek2() { - uint64 paddr; - - if (pc.IsLogical() && md->MMUEnabled()) { - paddr = md->TranslateAddr(pc); - if ((int64)paddr < 0) - return 0xffff; - } else { - paddr = pc.addr; - } - - // 物理空間から読み込む - uint16 data; - data = vm_phys_peek_8(paddr) << 8; - data |= vm_phys_peek_8(paddr + 1); - return data; + return mem->Peek(2); } // ワードフェッチ uint32 -m680x0disasm::fetch16() +m680x0disasm::fetch2() { - uint16 data = peek16(); - // IR に入れて PC を進める + uint16 data = mem->Read(2); + // IR にも入れる ir.push_back(data); - pc.addr += 2; return data; } // ロングワードフェッチ uint32 -m680x0disasm::fetch32() +m680x0disasm::fetch4() { uint32 data; - data = fetch16() << 16; - data |= fetch16(); + data = fetch2() << 16; + data |= fetch2(); return data; } @@ -215,19 +198,19 @@ m680x0disasm::make_ea(uint mmrr) s = make_anpd(rr); break; case 0x28 ... 0x2f: // 5 - s = disp16() + make_anin(rr); + s = disp2() + make_anin(rr); break; case 0x30 ... 0x37: // 6 s = make_eaix(make_an(rr)); break; case 0x38: // Abs.W - s = addr16(); + s = addr2(); break; case 0x39: // Abs.L - s = addr32(); + s = addr4(); break; case 0x3a: // d16(pc) - s = addr32(pc.addr + (int32)(int16)fetch16()) + + s = addr4(mem->laddr.Addr() + (int32)(int16)fetch2()) + "(" + make_reg(Reg::PC) + ")"; break; case 0x3b: // d8(pc,IX) @@ -236,24 +219,24 @@ m680x0disasm::make_ea(uint mmrr) case 0x3c: // imm switch (size) { case Size::B: - s = imm8(); + s = imm1(); break; case Size::W: - s = imm16(); + s = imm2(); break; case Size::L: case Size::S: - s = imm32(); + s = imm4(); break; case Size::D: - s = imm32(); - s += string_format("_%08x", fetch32()); + s = imm4(); + s += string_format("_%08x", fetch4()); break; case Size::X: case Size::P: - s = imm32(); - s += string_format("_%08x", fetch32()); - s += string_format("_%08x", fetch32()); + s = imm4(); + s += string_format("_%08x", fetch4()); + s += string_format("_%08x", fetch4()); break; default: s = "(invalid ea size?)"; @@ -273,7 +256,7 @@ m680x0disasm::make_eaix(std::string base static const char * const scalestr[] = { "", "*2", "*4", "*8", }; - uint16 ext = fetch16(); + uint16 ext = fetch2(); bool full = (ext & 0x0100); uint rn = (ext >> 12); bool wl = (ext & 0x0800); @@ -321,11 +304,11 @@ m680x0disasm::make_eaix(std::string base case 1: // ベースはヌル break; case 2: // ベース.W - bd = disp16(); + bd = disp2(); bd += ","; break; case 3: // ベース.L - bd = disp32(); + bd = disp4(); bd += ","; break; } @@ -337,11 +320,11 @@ m680x0disasm::make_eaix(std::string base break; case 2: // アウター.W od = ","; - od += disp16(); + od += disp2(); break; case 3: // アウター.L od = ","; - od += disp32(); + od += disp4(); break; } @@ -410,7 +393,7 @@ m680x0disasm::make_eaix(std::string base s += ")"; break; default: - return string_format("", iis); + return string_format("", iis); } } } @@ -420,65 +403,65 @@ m680x0disasm::make_eaix(std::string base // addr をワードアドレスとした時の文字列を返す std::string -m680x0disasm::addr16(uint32 addr) +m680x0disasm::addr2(uint32 addr) { return hex16(addr & 0xffff); } // addr をロングワードアドレスとした時の文字列を返す std::string -m680x0disasm::addr32(uint32 addr) +m680x0disasm::addr4(uint32 addr) { return hex32(addr); } // フェッチした値をワードアドレスとして文字列を返す std::string -m680x0disasm::addr16() +m680x0disasm::addr2() { - return addr16(fetch16()); + return addr2(fetch2()); } // フェッチした値をロングワードアドレスとして文字列を返す std::string -m680x0disasm::addr32() +m680x0disasm::addr4() { - return addr32(fetch32()); + return addr4(fetch4()); } // フェッチした値をワードディスプレースメントとして文字列を返す std::string -m680x0disasm::disp16() +m680x0disasm::disp2() { - return shex16(fetch16()); + return shex16(fetch2()); } // フェッチした値をロングワードディスプレースメントとして文字列を返す std::string -m680x0disasm::disp32() +m680x0disasm::disp4() { - return shex32(fetch32()); + return shex32(fetch4()); } // バイト即値 imm を文字列にして返す std::string -m680x0disasm::imm8() +m680x0disasm::imm1() { - return "#" + hex8(fetch16() & 0xff); + return "#" + hex8(fetch2() & 0xff); } // ワード即値 imm を文字列にして返す std::string -m680x0disasm::imm16() +m680x0disasm::imm2() { - return "#" + hex16(fetch16()); + return "#" + hex16(fetch2()); } // ロングワード即値 imm を文字列にして返す std::string -m680x0disasm::imm32() +m680x0disasm::imm4() { - return "#" + hex32(fetch32()); + return "#" + hex32(fetch4()); } // Dn を文字列にして返す。n の上位ビットは無視する。 @@ -554,7 +537,7 @@ m680x0disasm::make_q8() if (q == 0) { q = 8; } - return string_format("#%d", q); + return string_format("#%u", q); } // regno で示されるレジスタ名を返す @@ -615,7 +598,7 @@ m680x0disasm::make_reglist_half(std::str if (top < 0) { // 非表示中ならこのレジスタを出力する。 // 初回以外は区切りを先に出力する。 - if (s.length() != 0) { + if (s.empty() == false) { s += '/'; } s += reg; @@ -656,11 +639,11 @@ m680x0disasm::make_bf() if (offset < 8) { s += make_dn(offset); } else { - s += string_format("", offset); + s += string_format("", offset); } } else { // オフセットは 0..31 - s += string_format("#%d", offset); + s += string_format("#%u", offset); } s += ":"; @@ -670,14 +653,14 @@ m680x0disasm::make_bf() if (width < 8) { s += make_dn(width); } else { - s += string_format("", width); + s += string_format("", width); } } else { // 幅は 0 なら 32 を意味する if (width == 0) { width = 32; } - s += string_format("#%d", width); + s += string_format("#%u", width); } s += "}"; @@ -699,9 +682,9 @@ m680x0disasm::make_fc() case 0x08 ... 0x0f: return make_dn(fc); case 0x10 ... 0x17: - return string_format("#%d", fc & 7); + return string_format("#%u", fc & 7); default: - return string_format("", fc); + return string_format("", fc); } } @@ -864,6 +847,12 @@ m680x0disasm::make_fpnlist() "fpcr", "fpsr", "fpiar", + + "urp", + "itt0", + "itt1", + "dtt0", + "dtt1", }; /*static*/ const char * const m680x0disasm::size_str[] = { @@ -1844,7 +1833,7 @@ OP_DEF(ori_b) { name = "ori"; size = Size::B; - src = imm8(); + src = imm1(); if ((ir[0] & 0x3f) == 0x3c) { dst = make_reg(Reg::CCR); } else { @@ -1858,7 +1847,7 @@ OP_DEF(ori_w) { name = "ori"; size = Size::W; - src = imm16(); + src = imm2(); if ((ir[0] & 0x3f) == 0x3c) { dst = make_reg(Reg::SR); } else { @@ -1871,14 +1860,14 @@ OP_DEF(ori_l) { name = "ori"; size = Size::L; - src = imm32(); + src = imm4(); dst = make_ea(); } void m680x0disasm::ops_cmp2chk2(m680x0disasm::Size sz) { - fetch16(); + fetch2(); if ((ir[1] & 0x0800) == 0) { // CMP2.[BWL] ,Rn name = "cmp2"; @@ -1932,23 +1921,23 @@ m680x0disasm::ops_movep() switch (mode) { case 0: // MOVEP.W (d,Ay),Dx size = Size::W; - src = "(" + addr16() + "," + make_an(ir[0]) + ")"; + src = "(" + addr2() + "," + make_an(ir[0]) + ")"; dst = make_dn(ir[0] >> 9); break; case 1: // MOVEP.L (d,Ay),Dx size = Size::L; - src = "(" + addr16() + "," + make_an(ir[0]) + ")"; + src = "(" + addr2() + "," + make_an(ir[0]) + ")"; dst = make_dn(ir[0] >> 9); break; case 2: // MOVEP.W Dx,(d,Ay) size = Size::W; src = make_dn(ir[0] >> 9); - dst = "(" + addr16() + "," + make_an(ir[0]) + ")"; + dst = "(" + addr2() + "," + make_an(ir[0]) + ")"; break; case 3: // MOVEP.L Dx,(d,Ay) size = Size::L; src = make_dn(ir[0] >> 9); - dst = "(" + addr16() + "," + make_an(ir[0]) + ")"; + dst = "(" + addr2() + "," + make_an(ir[0]) + ")"; break; } } @@ -1991,7 +1980,7 @@ OP_DEF(andi_b) { name = "andi"; size = Size::B; - src = imm8(); + src = imm1(); if ((ir[0] & 0x3f) == 0x3c) { dst = make_reg(Reg::CCR); } else { @@ -2005,7 +1994,7 @@ OP_DEF(andi_w) { name = "andi"; size = Size::W; - src = imm16(); + src = imm2(); if ((ir[0] & 0x3f) == 0x3c) { dst = make_reg(Reg::SR); } else { @@ -2018,7 +2007,7 @@ OP_DEF(andi_l) { name = "andi"; size = Size::L; - src = imm32(); + src = imm4(); dst = make_ea(); } @@ -2033,7 +2022,7 @@ OP_DEF(subi_b) { name = "subi"; size = Size::B; - src = imm8(); + src = imm1(); dst = make_ea(); } @@ -2042,7 +2031,7 @@ OP_DEF(subi_w) { name = "subi"; size = Size::W; - src = imm16(); + src = imm2(); dst = make_ea(); } @@ -2051,7 +2040,7 @@ OP_DEF(subi_l) { name = "subi"; size = Size::L; - src = imm32(); + src = imm4(); dst = make_ea(); } @@ -2066,7 +2055,7 @@ OP_DEF(addi_b) { name = "addi"; size = Size::B; - src = imm8(); + src = imm1(); dst = make_ea(); } @@ -2075,7 +2064,7 @@ OP_DEF(addi_w) { name = "addi"; size = Size::W; - src = imm16(); + src = imm2(); dst = make_ea(); } @@ -2084,10 +2073,26 @@ OP_DEF(addi_l) { name = "addi"; size = Size::L; - src = imm32(); + src = imm4(); dst = make_ea(); } +// %0000_011011_00nnnn RTM Rn +// %0000_011011_mmmrrr CALLM #, +OP_DEF(callm) +{ + uint n = ir[0] & 0x3f; + + if (n < 16) { + name = "rtm"; + src = make_rn(n); + } else { + name = "callm"; + src = imm2(); + dst = make_ea(); + } +} + // BTST,BCHG,BCLR,BSET #, の共通部分。 void m680x0disasm::ops_btst_imm_ea() @@ -2095,15 +2100,15 @@ m680x0disasm::ops_btst_imm_ea() uint n = ir[0] & 0x3f; uint op = (ir[0] >> 6) & 3; - fetch16(); + fetch2(); name = btst_names[op]; if (n < 8) { size = Size::L; - src = string_format("#%d", ir[1] & 31); + src = string_format("#%u", ir[1] & 31); dst = make_dn(n); } else { size = Size::B; - src = string_format("#%d", ir[1] & 7); + src = string_format("#%u", ir[1] & 7); dst = make_ea(); } } @@ -2142,7 +2147,7 @@ OP_DEF(eori_b) { name = "eori"; size = Size::B; - src = imm8(); + src = imm1(); if ((ir[0] & 0x3f) == 0x3c) { dst = make_reg(Reg::CCR); } else { @@ -2156,7 +2161,7 @@ OP_DEF(eori_w) { name = "eori"; size = Size::W; - src = imm16(); + src = imm2(); if ((ir[0] & 0x3f) == 0x3c) { dst = make_reg(Reg::SR); } else { @@ -2169,7 +2174,7 @@ OP_DEF(eori_l) { name = "eori"; size = Size::L; - src = imm32(); + src = imm4(); dst = make_ea(); } @@ -2177,7 +2182,7 @@ OP_DEF(eori_l) void m680x0disasm::ops_cas(m680x0disasm::Size sz) { - fetch16(); + fetch2(); name = "cas"; size = sz; @@ -2193,11 +2198,11 @@ m680x0disasm::ops_cas2(m680x0disasm::Siz { name = "cas2"; size = sz; - fetch16(); + fetch2(); uint dc1 = ir[1] & 7; uint du1 = ir[1] >> 6; uint rn1 = ir[1] >> 12; - fetch16(); + fetch2(); uint dc2 = ir[2] & 7; uint du2 = ir[2] >> 6; uint rn2 = ir[2] >> 12; @@ -2217,7 +2222,7 @@ OP_DEF(cmpi_b) { name = "cmpi"; size = Size::B; - src = imm8(); + src = imm1(); dst = make_ea(); } @@ -2226,7 +2231,7 @@ OP_DEF(cmpi_w) { name = "cmpi"; size = Size::W; - src = imm16(); + src = imm2(); dst = make_ea(); } @@ -2235,7 +2240,7 @@ OP_DEF(cmpi_l) { name = "cmpi"; size = Size::L; - src = imm32(); + src = imm4(); dst = make_ea(); } @@ -2258,7 +2263,7 @@ OP_DEF(cas_w) void m680x0disasm::ops_moves(m680x0disasm::Size sz) { - fetch16(); + fetch2(); name = "moves"; size = sz; @@ -2666,7 +2671,7 @@ OP_DEF(nbcd) name = "link"; size = Size::L; src = make_an(ir[0]); - dst = "#" + disp32(); + dst = "#" + disp4(); } else { // NBCD.B name = "nbcd"; @@ -2690,7 +2695,7 @@ OP_DEF(pea) } else if (n < 16) { // BKPT # name = "bkpt"; - src = string_format("#%d", ir[0] & 7); + src = string_format("#%u", ir[0] & 7); } else { // PEA.L name = "pea"; @@ -2712,7 +2717,7 @@ m680x0disasm::ops_movem_ext(m680x0disasm src = make_dn(ir[0]); } else { // MOVEM.W , - fetch16(); + fetch2(); name = "movem"; src = make_reglist(); dst = make_ea(); @@ -2776,7 +2781,7 @@ OP_DEF(tas) // %0100_110000_mmmrrr MUL{U,S}.L ,Dl OP_DEF(mul) { - fetch16(); + fetch2(); if ((ir[1] & 0x0800) == 0) { name = "mulu"; @@ -2795,7 +2800,7 @@ OP_DEF(mul) // %0100_110001_mmmrrr DIV{U,UL,S,SL}.L ,Dq OP_DEF(div) { - fetch16(); + fetch2(); if ((ir[1] & 0x0800) == 0) { name = "divu"; @@ -2821,7 +2826,7 @@ OP_DEF(div) // %0100_110010_mmmrrr MOVEM.W , OP_DEF(movem_w) { - fetch16(); + fetch2(); name = "movem"; size = Size::W; src = make_ea(); @@ -2831,7 +2836,7 @@ OP_DEF(movem_w) // %0100_110011_mmmrrr MOVEM.L , OP_DEF(movem_l) { - fetch16(); + fetch2(); name = "movem"; size = Size::L; src = make_ea(); @@ -2859,13 +2864,13 @@ OP_DEF(trap) switch (n) { case 0x00 ... 0x0f: // TRAP # name = "trap"; - src = string_format("#%d", n); + src = string_format("#%u", n); break; case 0x10 ... 0x17: // LINK.W Ay,# name = "link"; size = Size::W; src = make_an(ir[0]); - dst = "#" + disp16(); + dst = "#" + disp2(); break; case 0x18 ... 0x1f: // UNLK Ay name = "unlk"; @@ -2891,14 +2896,14 @@ OP_DEF(trap) break; case 0x32: // STOP # name = "stop"; - src = imm16(); + src = imm2(); break; case 0x33: // RTE name = "rte"; break; case 0x34: // RTD # name = "rtd"; - src = imm16(); + src = imm2(); break; case 0x35: // RTS name = "rts"; @@ -2910,14 +2915,14 @@ OP_DEF(trap) name = "rtr"; break; case 0x3a: // MOVEC.L Rc,Rn - fetch16(); + fetch2(); name = "movec"; size = Size::L; src = make_movec(); dst = make_rn(ir[1] >> 12); break; case 0x3b: // MOVEC.L Rn,Rc - fetch16(); + fetch2(); name = "movec"; size = Size::L; src = make_rn(ir[1] >> 12); @@ -2974,9 +2979,13 @@ OP_DEF(addq_l) dst = make_ea(); } -// Scc/SF のメイン部分。 -void -m680x0disasm::ops_scc() +// %0101_cccc11_mmmrrr Scc.B +// %0101_cccc11_001yyy DBcc.W Dy,