mirror of
https://github.com/libretro/Mu.git
synced 2026-02-13 21:24:19 +00:00
Compare commits
1 Commits
serial
...
musashiUpg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df927c1e45 |
@@ -210,6 +210,7 @@ INCLUDEPATH += $$PWD/qt-common/include
|
||||
|
||||
SOURCES += \
|
||||
../../src/ads7846.c \
|
||||
../../src/armv5te/disasm.c \
|
||||
../../src/audio/blip_buf.c \
|
||||
../../src/dbvz.c \
|
||||
../../src/debug/sandbox.c \
|
||||
@@ -219,9 +220,6 @@ SOURCES += \
|
||||
../../src/m515Bus.c \
|
||||
../../src/m68k/m68kcpu.c \
|
||||
../../src/m68k/m68kdasm.c \
|
||||
../../src/m68k/m68kopac.c \
|
||||
../../src/m68k/m68kopdm.c \
|
||||
../../src/m68k/m68kopnz.c \
|
||||
../../src/m68k/m68kops.c \
|
||||
../../src/pdiUsbD12.c \
|
||||
../../src/sdCard.c \
|
||||
@@ -237,6 +235,7 @@ SOURCES += \
|
||||
|
||||
HEADERS += \
|
||||
../../src/ads7846.h \
|
||||
../../src/armv5te/disasm.h \
|
||||
../../src/audio/blip_buf.h \
|
||||
../../src/dbvz.h \
|
||||
../../src/dbvzRegisterAccessors.c.h \
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
extern "C"{
|
||||
#include "../../src/flx68000.h"
|
||||
#include "../../src/m68k/m68k.h"
|
||||
#include "../../src/pxa260/pxa260.h"
|
||||
#include "../../src/armv5te/disasm.h"
|
||||
#include "../../src/debug/sandbox.h"
|
||||
}
|
||||
|
||||
@@ -528,3 +530,18 @@ uint64_t EmuWrapper::debugGetEmulatorMemory(uint32_t address, uint8_t size){
|
||||
return pxa260ReadArbitraryMemory(address, size);
|
||||
return flx68000ReadArbitraryMemory(address, size);
|
||||
}
|
||||
|
||||
QString EmuWrapper::debugGetEmulatorDisassemble(uint32_t address, uint32_t opcodes){
|
||||
QString output = "";
|
||||
|
||||
if(palmEmulatingTungstenT3){
|
||||
|
||||
}
|
||||
else{
|
||||
for(uint32_t index = 0; index < opcodes; index++){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -81,4 +81,5 @@ public:
|
||||
QVector<uint64_t>& debugGetDuplicateLogEntryCount();
|
||||
QString debugGetCpuRegisterString();
|
||||
uint64_t debugGetEmulatorMemory(uint32_t address, uint8_t size);
|
||||
QString debugGetEmulatorDisassemble(uint32_t address, uint32_t opcodes);
|
||||
};
|
||||
|
||||
551
src/armv5te/disasm.c
Normal file
551
src/armv5te/disasm.c
Normal file
@@ -0,0 +1,551 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "disasm.h"
|
||||
#include "emu.h"
|
||||
|
||||
static char *strcpy2(char *dest, const char *src) {
|
||||
while ((*dest = *src)) { dest++; src++; }
|
||||
return dest;
|
||||
}
|
||||
|
||||
const char reg_name[16][4] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"
|
||||
};
|
||||
|
||||
static const char condcode[16][3] = {
|
||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
||||
"hi", "ls", "ge", "lt", "gt", "le", "", "2"
|
||||
};
|
||||
|
||||
enum suffix {
|
||||
none_,
|
||||
XY, // halfword signed mul
|
||||
Y, // halfword signed mul
|
||||
S, // Bit 20 S: alu, MUL etc
|
||||
B, // Bit 22 B: LDR/STR, SWP
|
||||
BT, // Bit 21 T: LDR/STR with postindex (bit 24=0)
|
||||
M, // Bit 23-24 DA/IA/DB/IB
|
||||
H, // H/SB/SH
|
||||
D, // double-word insn
|
||||
L, // Bit 22 L: LDC/STC
|
||||
};
|
||||
|
||||
enum operand {
|
||||
none,
|
||||
REG0, // Bits 0-3 specify register
|
||||
REG8, // Bits 8-11 specify register
|
||||
REG12, // Bits 12-15 specify register
|
||||
REG16, // Bits 16-19 specify register
|
||||
PSR,
|
||||
SHFOP, // Bits 0-11 specify shifted reg or immediate
|
||||
IMMED, // Bits 0-11 specify rotated immediate
|
||||
MEM,
|
||||
MEMH,
|
||||
MEM16,
|
||||
MULTI,
|
||||
BRCH, // Bits 0-23 specify branch target
|
||||
BRCHT, // Bits 0-24 specify branch target for THUMB code
|
||||
COPR, // Bits 8-11 specify coprocessor number
|
||||
CDP, MRC, MRRC, MEMC,
|
||||
BKPT, SWI,
|
||||
};
|
||||
|
||||
static const struct arm_insn {
|
||||
uint32_t mask;
|
||||
uint32_t value;
|
||||
char name[7];
|
||||
uint8_t suffix;
|
||||
uint8_t op1, op2, op3, op4;
|
||||
} table[] = {
|
||||
{0xFD70F000,0xF550F000, "pld", 0, MEM, none, none, none },
|
||||
{0xFE000000,0xFA000000, "blx", 0, BRCHT, none, none, none },
|
||||
|
||||
/* Coprocessor instructions may have any condition field */
|
||||
{ 0xFF00000, 0xC400000, "mcrr", 0, COPR, MRRC, none, none },
|
||||
{ 0xFF00000, 0xC500000, "mrrc", 0, COPR, MRRC, none, none },
|
||||
{ 0xE100000, 0xC000000, "stc", L, COPR, MEMC, none, none },
|
||||
{ 0xE100000, 0xC100000, "ldc", L, COPR, MEMC, none, none },
|
||||
{ 0xF000010, 0xE000000, "cdp", 0, COPR, CDP, none, none },
|
||||
{ 0xF100010, 0xE000010, "mcr", 0, COPR, MRC, none, none },
|
||||
{ 0xF100010, 0xE100010, "mrc", 0, COPR, MRC, none, none },
|
||||
|
||||
/* No other instructions are valid with condition field 1111 */
|
||||
{0xF0000000,0xF0000000, "???", 0, none, none, none, none },
|
||||
|
||||
{ 0xFE0F0F0, 0x0000090, "mul", S, REG16, REG0, REG8, none },
|
||||
{ 0xFE000F0, 0x0200090, "mla", S, REG16, REG0, REG8, REG12 },
|
||||
{ 0xFE000F0, 0x0800090, "umull", S, REG12, REG16, REG0, REG8 },
|
||||
{ 0xFE000F0, 0x0A00090, "umlal", S, REG12, REG16, REG0, REG8 },
|
||||
{ 0xFE000F0, 0x0C00090, "smull", S, REG12, REG16, REG0, REG8 },
|
||||
{ 0xFE000F0, 0x0E00090, "smlal", S, REG12, REG16, REG0, REG8 },
|
||||
{ 0xFB00FF0, 0x1000090, "swp", B, REG12, REG0, MEM16, none },
|
||||
{ 0xE0000F0, 0x0000090, "???", 0, none, none, none, none },
|
||||
|
||||
{ 0xE1000F0, 0x00000B0, "str", H, REG12, MEMH, none, none },
|
||||
{ 0xE1010F0, 0x00000D0, "ldr", D, REG12, MEMH, none, none },
|
||||
{ 0xE1010F0, 0x00000F0, "str", D, REG12, MEMH, none, none },
|
||||
{ 0xE1000F0, 0x01000B0, "ldr", H, REG12, MEMH, none, none },
|
||||
{ 0xE1000F0, 0x01000D0, "ldr", H, REG12, MEMH, none, none },
|
||||
{ 0xE1000F0, 0x01000F0, "ldr", H, REG12, MEMH, none, none },
|
||||
|
||||
{ 0xFBF0FFF, 0x10F0000, "mrs", 0, REG12, PSR, none, none },
|
||||
{ 0xFB0FFF0, 0x120F000, "msr", 0, PSR, REG0, none, none },
|
||||
{ 0xFF00FF0, 0x1000050, "qadd", 0, REG12, REG0, REG16, none },
|
||||
{ 0xFF00FF0, 0x1200050, "qsub", 0, REG12, REG0, REG16, none },
|
||||
{ 0xFF00FF0, 0x1400050, "qdadd", 0, REG12, REG0, REG16, none },
|
||||
{ 0xFF00FF0, 0x1600050, "qdsub", 0, REG12, REG0, REG16, none },
|
||||
{0xFFF000F0,0xE1200070, "bkpt", 0, BKPT, none, none, none },
|
||||
|
||||
{ 0xFB0F000, 0x320F000, "msr", 0, PSR, IMMED, none, none },
|
||||
|
||||
{ 0xFF00090, 0x1000080, "smla", XY,REG16, REG0, REG8, REG12 },
|
||||
{ 0xFF000B0, 0x1200080, "smlaw", Y, REG16, REG0, REG8, REG12 },
|
||||
{ 0xFF0F0B0, 0x12000A0, "smulw", Y, REG16, REG0, REG8, none },
|
||||
{ 0xFF00090, 0x1400080, "smlal", XY,REG12, REG16, REG0, REG8 },
|
||||
{ 0xFF0F090, 0x1600080, "smul", XY,REG16, REG0, REG8, none },
|
||||
|
||||
{ 0xFFFFFF0, 0x12FFF10, "bx", 0, REG0, none, none, none },
|
||||
{ 0xFFFFFF0, 0x12FFF20, "bxj", 0, REG0, none, none, none },
|
||||
{ 0xFFFFFF0, 0x12FFF30, "blx", 0, REG0, none, none, none },
|
||||
|
||||
{ 0xFFF0FF0, 0x16F0F10, "clz", 0, REG12, REG0, none, none },
|
||||
|
||||
{ 0xDE00000, 0x0000000, "and", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0200000, "eor", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0400000, "sub", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0600000, "rsb", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0800000, "add", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0A00000, "adc", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0C00000, "sbc", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDE00000, 0x0E00000, "rsc", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDF0F000, 0x1100000, "tst", 0, REG16, SHFOP, none, none },
|
||||
{ 0xDF0F000, 0x1300000, "teq", 0, REG16, SHFOP, none, none },
|
||||
{ 0xDF0F000, 0x1500000, "cmp", 0, REG16, SHFOP, none, none },
|
||||
{ 0xDF0F000, 0x1700000, "cmn", 0, REG16, SHFOP, none, none },
|
||||
{ 0xDE00000, 0x1800000, "orr", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDEF0000, 0x1A00000, "mov", S, REG12, SHFOP, none, none },
|
||||
{ 0xDE00000, 0x1C00000, "bic", S, REG12, REG16, SHFOP, none },
|
||||
{ 0xDEF0000, 0x1E00000, "mvn", S, REG12, SHFOP, none, none },
|
||||
|
||||
/* 4000000-9FFFFFF: word-sized memory accesses */
|
||||
{ 0xD100000, 0x4000000, "str", BT,REG12, MEM, none, none },
|
||||
{ 0xD100000, 0x4100000, "ldr", BT,REG12, MEM, none, none },
|
||||
{ 0xD100000, 0x5000000, "str", B, REG12, MEM, none, none },
|
||||
{ 0xD100000, 0x5100000, "ldr", B, REG12, MEM, none, none },
|
||||
{ 0xE100000, 0x8000000, "stm", M, MULTI, none, none, none },
|
||||
{ 0xE100000, 0x8100000, "ldm", M, MULTI, none, none, none },
|
||||
|
||||
/* A000000-BFFFFFF: branches */
|
||||
{ 0xF000000, 0xA000000, "b", 0, BRCH, none, none, none },
|
||||
{ 0xF000000, 0xB000000, "bl", 0, BRCH, none, none, none },
|
||||
|
||||
/* F000000-FFFFFFF: software interrupt */
|
||||
{ 0xF000000, 0xF000000, "swi", 0, SWI, none, none, none },
|
||||
|
||||
/* Catch-all */
|
||||
{ 0x0000000, 0x0000000, "???", 0, none, none, none, none },
|
||||
};
|
||||
|
||||
static char *do_shift(char *out, uint32_t insn) {
|
||||
static const char shifts[4][4] = { "lsl", "lsr", "asr", "ror" };
|
||||
int shift = insn >> 7 & 31;
|
||||
int stype = insn >> 5 & 3;
|
||||
|
||||
out = strcpy2(out, reg_name[insn & 15]);
|
||||
if (insn & 0x10) {
|
||||
// shift by register (for data processing only, not load/store)
|
||||
if (shift & 1) {
|
||||
*out++ = '?';
|
||||
return out;
|
||||
}
|
||||
out += sprintf(out, " %s %s", shifts[stype], reg_name[shift >> 1]);
|
||||
} else {
|
||||
// shift by immediate
|
||||
int shift = insn >> 7 & 31;
|
||||
int stype = insn >> 5 & 3;
|
||||
if (shift == 0) {
|
||||
if (stype == 0) {
|
||||
// lsl #0 is a no-op
|
||||
return out;
|
||||
} else if (stype == 3) {
|
||||
// ror #0
|
||||
return strcpy2(out, " rrx");
|
||||
} else {
|
||||
// lsr #0 and asr #0 act like shift of 32
|
||||
shift = 32;
|
||||
}
|
||||
}
|
||||
out += sprintf(out, " %s #%d", shifts[stype], shift);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static char *do_reglist(char *out, int regs) {
|
||||
int i;
|
||||
*out++ = '{';
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (regs >> i & 1) {
|
||||
out = strcpy2(out, reg_name[i]);
|
||||
if (regs >> i & 2) {
|
||||
*out++ = '-';
|
||||
while (regs >> ++i & 1);
|
||||
out = strcpy2(out, reg_name[i-1]);
|
||||
}
|
||||
*out++ = ',';
|
||||
}
|
||||
}
|
||||
out[-1] = '}';
|
||||
*out = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
uint32_t disasm_arm_insn(uint32_t pc) {
|
||||
uint32_t *pc_ptr = virt_mem_ptr(pc, 4);
|
||||
if(!pc_ptr)
|
||||
return 0;
|
||||
|
||||
return disasm_arm_insn2(pc, pc_ptr);
|
||||
}
|
||||
|
||||
uint32_t disasm_arm_insn2(uint32_t pc, uint32_t *pc_ptr) {
|
||||
char buf[80];
|
||||
|
||||
uint32_t insn = *pc_ptr;
|
||||
char *out = buf + sprintf(buf, "%08x: %08x\t", pc, insn);
|
||||
|
||||
int i;
|
||||
|
||||
const struct arm_insn *t = table;
|
||||
while ((insn & t->mask) != t->value)
|
||||
t++;
|
||||
|
||||
out = strcpy2(out, t->name);
|
||||
|
||||
switch (t->suffix) {
|
||||
case XY:
|
||||
*out++ = (insn & (1 << 5)) ? 't' : 'b';
|
||||
/* fallthrough */
|
||||
case Y:
|
||||
*out++ = (insn & (1 << 6)) ? 't' : 'b';
|
||||
}
|
||||
|
||||
if (!(t->mask & 0xF0000000))
|
||||
out = strcpy2(out, condcode[insn >> 28]);
|
||||
|
||||
switch (t->suffix) {
|
||||
case S:
|
||||
if (insn & (1 << 20)) *out++ = 's';
|
||||
break;
|
||||
case B:
|
||||
if (insn & (1 << 22)) *out++ = 'b';
|
||||
break;
|
||||
case BT:
|
||||
if (insn & (1 << 22)) *out++ = 'b';
|
||||
if (insn & (1 << 21)) *out++ = 't';
|
||||
break;
|
||||
case M:
|
||||
*out++ = (insn & (1 << 23)) ? 'i' : 'd';
|
||||
*out++ = (insn & (1 << 24)) ? 'b' : 'a';
|
||||
break;
|
||||
case H:
|
||||
if (insn & (1 << 6)) *out++ = 's';
|
||||
*out++ = (insn & (1 << 5)) ? 'h' : 'b';
|
||||
break;
|
||||
case D:
|
||||
*out++ = 'd';
|
||||
break;
|
||||
case L:
|
||||
if (insn & (1 << 22)) *out++ = 'l';
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4 && (&t->op1)[i] != none; i++) {
|
||||
*out++ = i ? ',' : '\t';
|
||||
switch ((&t->op1)[i]) {
|
||||
case REG0: out = strcpy2(out, reg_name[insn & 15]); break;
|
||||
case REG8: out = strcpy2(out, reg_name[insn >> 8 & 15]); break;
|
||||
case REG12: out = strcpy2(out, reg_name[insn >> 12 & 15]); break;
|
||||
case REG16: out = strcpy2(out, reg_name[insn >> 16 & 15]); break;
|
||||
case SHFOP:
|
||||
if (!(insn & (1 << 25))) {
|
||||
out = do_shift(out, insn);
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case IMMED: {
|
||||
uint32_t imm = insn & 255, shift = insn >> 7 & 30;
|
||||
out += sprintf(out, "%08x", imm >> shift | imm << (32 - shift));
|
||||
break;
|
||||
}
|
||||
case PSR:
|
||||
*out++ = (insn & (1 << 22)) ? 's' : 'c';
|
||||
*out++ = 'p'; *out++ = 's'; *out++ = 'r';
|
||||
if (~insn >> 16 & 15) {
|
||||
*out++ = '_';
|
||||
if (insn & (1 << 19)) *out++ = 'f';
|
||||
if (insn & (1 << 18)) *out++ = 's';
|
||||
if (insn & (1 << 17)) *out++ = 'x';
|
||||
if (insn & (1 << 16)) *out++ = 'c';
|
||||
}
|
||||
break;
|
||||
case MEM:
|
||||
*out++ = '[';
|
||||
out = strcpy2(out, reg_name[insn >> 16 & 15]);
|
||||
if ((insn & 0x32F0000) == 0x10F0000) {
|
||||
// immediate, offset mode, PC relative
|
||||
int addr = insn & 0xFFF;
|
||||
if (!(insn & (1 << 23))) addr = -addr;
|
||||
addr += pc + 8;
|
||||
out -= 2;
|
||||
out += sprintf(out, "%08x]", addr);
|
||||
uint32_t *ptr = virt_mem_ptr(addr, 4);
|
||||
if (ptr)
|
||||
out += sprintf(out, " = %08x", *ptr);
|
||||
} else {
|
||||
if (!(insn & (1 << 24))) // post-index
|
||||
*out++ = ']';
|
||||
*out++ = ' ';
|
||||
*out++ = (insn & (1 << 23)) ? '+' : '-';
|
||||
*out++ = ' ';
|
||||
if (insn & (1 << 25)) {
|
||||
// register offset
|
||||
if (insn & 0x10) {
|
||||
// register shifted by register not allowed
|
||||
*out++ = '?';
|
||||
} else {
|
||||
out = do_shift(out, insn);
|
||||
}
|
||||
} else {
|
||||
// immediate offset
|
||||
if ((insn & 0xFFF) || !(insn & (1 << 23)))
|
||||
out += sprintf(out, "%03x", insn & 0xFFF);
|
||||
else
|
||||
// don't display an added offset of 0
|
||||
out -= 3;
|
||||
}
|
||||
if (insn & (1 << 24)) { // pre-index
|
||||
*out++ = ']';
|
||||
if (insn & (1 << 21)) // writeback
|
||||
*out++ = '!';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MEMH:
|
||||
*out++ = '[';
|
||||
out = strcpy2(out, reg_name[insn >> 16 & 15]);
|
||||
if (!(insn & (1 << 24))) // post-index
|
||||
*out++ = ']';
|
||||
*out++ = ' ';
|
||||
*out++ = (insn & (1 << 23)) ? '+' : '-';
|
||||
*out++ = ' ';
|
||||
if (insn & (1 << 22)) {
|
||||
// immediate offset
|
||||
uint32_t imm = (insn & 0x0F) | (insn >> 4 & 0xF0);
|
||||
if (imm || !(insn & (1 << 23)))
|
||||
out += sprintf(out, "%03x", imm);
|
||||
else
|
||||
// don't display an added offset of 0
|
||||
out -= 3;
|
||||
} else {
|
||||
// register offset
|
||||
out = strcpy2(out, reg_name[insn & 15]);
|
||||
}
|
||||
if (insn & (1 << 24)) { // pre-index
|
||||
*out++ = ']';
|
||||
if (insn & (1 << 21)) // writeback
|
||||
*out++ = '!';
|
||||
} else { // post-index
|
||||
// writeback assumed, setting W bit is invalid.
|
||||
if (insn & (1 << 21))
|
||||
*out++ = '?';
|
||||
}
|
||||
break;
|
||||
case MEM16:
|
||||
out += sprintf(out, "[%s]", reg_name[insn >> 16 & 15]);
|
||||
break;
|
||||
case MULTI:
|
||||
out = strcpy2(out, reg_name[insn >> 16 & 15]);
|
||||
if (insn & (1 << 21)) // Writeback
|
||||
*out++ = '!';
|
||||
*out++ = ',';
|
||||
out = do_reglist(out, insn & 0xFFFF);
|
||||
if (insn & (1 << 22)) // Load PSR or force user mode
|
||||
*out++ = '^';
|
||||
break;
|
||||
case BRCH:
|
||||
out += sprintf(out, "%08x", pc + 8 + ((int)insn << 8 >> 6));
|
||||
break;
|
||||
case BRCHT:
|
||||
out += sprintf(out, "%08x", pc + 8 + ((int)insn << 8 >> 6 | (insn >> 23 & 2)));
|
||||
break;
|
||||
case COPR:
|
||||
out += sprintf(out, "p%d", insn >> 8 & 15);
|
||||
break;
|
||||
case CDP:
|
||||
out += sprintf(out, "%d,c%d,c%d,c%d,%d", insn >> 20 & 15,
|
||||
insn >> 12 & 15, insn >> 16 & 15, insn & 15, insn >> 5 & 7);
|
||||
break;
|
||||
case MRC:
|
||||
out += sprintf(out, "%d,%s,c%d,c%d,%d", insn >> 21 & 7,
|
||||
reg_name[insn >> 12 & 15], insn >> 16 & 15, insn & 15, insn >> 5 & 7);
|
||||
break;
|
||||
case MRRC:
|
||||
out += sprintf(out, "%d,%s,%s,c%d", insn >> 4 & 15,
|
||||
reg_name[insn >> 12 & 15], reg_name[insn >> 16 & 15], insn & 15);
|
||||
break;
|
||||
case MEMC:
|
||||
out += sprintf(out, "c%d,[%s", insn >> 12 & 15,
|
||||
reg_name[insn >> 16 & 15]);
|
||||
if (!(insn & (1 << 24))) { // Post-indexed or unindexed
|
||||
*out++ = ']';
|
||||
if (!(insn & (1 << 21))) {
|
||||
// Unindexed addressing
|
||||
if (!(insn & (1 << 23)))
|
||||
*out++ = '?';
|
||||
out += sprintf(out, ",{%02x}", insn & 0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(insn & (1 << 23)) || insn & 0xFF)
|
||||
out += sprintf(out, " %c %03x",
|
||||
(insn & (1 << 23)) ? '+' : '-',
|
||||
(insn & 0xFF) << 2);
|
||||
if (insn & (1 << 24)) { // Pre-indexed or offset
|
||||
*out++ = ']';
|
||||
if (insn & (1 << 21)) // Writeback (pre-indexed)
|
||||
*out++ = '!';
|
||||
}
|
||||
break;
|
||||
case BKPT:
|
||||
out += sprintf(out, "%04x", (insn >> 4 & 0xFFF0) | (insn & 0x0F));
|
||||
break;
|
||||
case SWI:
|
||||
out += sprintf(out, "%06x", insn & 0xFFFFFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*out = '\0';
|
||||
gui_debug_printf(buf);
|
||||
gui_debug_printf("\n");
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint32_t disasm_thumb_insn(uint32_t pc) {
|
||||
char buf[80];
|
||||
uint16_t *pc_ptr = virt_mem_ptr(pc, 2);
|
||||
if (!pc_ptr)
|
||||
return 0;
|
||||
|
||||
uint16_t insn = *pc_ptr;
|
||||
char *out = buf + sprintf(buf, "%08x: %04x \t", pc, insn);
|
||||
|
||||
if (insn < 0x1800) {
|
||||
static const char name[][4] = { "lsl", "lsr", "asr" };
|
||||
sprintf(out, "%s\tr%d,r%d,%02x", name[insn >> 11],
|
||||
insn & 7, insn >> 3 & 7, insn >> 6 & 31);
|
||||
} else if (insn < 0x2000) {
|
||||
sprintf(out, "%s\tr%d,r%d,%s%d",
|
||||
(insn & 0x0200) ? "sub" : "add",
|
||||
insn & 7, insn >> 3 & 7,
|
||||
(insn & 0x400) ? "" : "r", insn >> 6 & 7);
|
||||
} else if (insn < 0x4000) {
|
||||
static const char name[][4] = { "mov", "cmp", "add", "sub" };
|
||||
sprintf(out, "%s\tr%d,%02x", name[insn >> 11 & 3],
|
||||
insn >> 8 & 7, insn & 0xFF);
|
||||
} else if (insn < 0x4400) {
|
||||
static const char name[][4] = {
|
||||
"and", "eor", "lsl", "lsr", "asr", "adc", "sbc", "ror",
|
||||
"tst", "neg", "cmp", "cmn", "orr", "mul", "bic", "mvn"
|
||||
};
|
||||
sprintf(out, "%s\tr%d,r%d", name[insn >> 6 & 15], insn & 7, insn >> 3 & 7);
|
||||
} else if (insn < 0x4700) {
|
||||
static const char name[][4] = { "add", "cmp", "mov" };
|
||||
int rd = (insn & 7) | (insn >> 4 & 8);
|
||||
int rn = insn >> 3 & 15;
|
||||
if (!((rd | rn) & 8))
|
||||
goto invalid;
|
||||
sprintf(out, "%s\t%s,%s", name[insn >> 8 & 3], reg_name[rd], reg_name[rn]);
|
||||
} else if (insn < 0x4800) {
|
||||
if (insn & 7)
|
||||
goto invalid;
|
||||
sprintf(out, "%s\t%s", (insn & 0x80) ? "blx" : "bx", reg_name[insn >> 3 & 15]);
|
||||
} else if (insn < 0x5000) {
|
||||
int addr = ((pc + 4) & -4) + ((insn & 0xFF) << 2);
|
||||
out += sprintf(out, "ldr\tr%d,[%08x]", insn >> 8 & 7, addr);
|
||||
uint32_t *ptr = virt_mem_ptr(addr, 4);
|
||||
if (ptr)
|
||||
sprintf(out, " = %08x", *ptr);
|
||||
} else if (insn < 0x6000) {
|
||||
static const char name[][6] = {
|
||||
"str", "strh", "strb", "ldrsb",
|
||||
"ldr", "ldrh", "ldrb", "ldrsh"
|
||||
};
|
||||
sprintf(out, "%s\tr%d,[r%d + r%d]", name[insn >> 9 & 7],
|
||||
insn & 7, insn >> 3 & 7, insn >> 6 & 7);
|
||||
} else if (insn < 0x9000) {
|
||||
static const char name[][5] = { "str", "ldr", "strb", "ldrb", "strh", "ldrh" };
|
||||
int type = (insn - 0x6000) >> 11;
|
||||
sprintf(out, "%s\tr%d,[r%d + %03x]", name[type],
|
||||
insn & 7, insn >> 3 & 7,
|
||||
(insn >> 6 & 31) << (0x12 >> (type & 6) & 3));
|
||||
} else if (insn < 0xA000) {
|
||||
sprintf(out, "%s\tr%d,[sp + %03x]",
|
||||
(insn & 0x800) ? "ldr" : "str",
|
||||
insn >> 8 & 7, (insn & 0xFF) << 2);
|
||||
} else if (insn < 0xB000) {
|
||||
sprintf(out, "add\tr%d,%s,%03x",
|
||||
insn >> 8 & 7,
|
||||
(insn & 0x800) ? "sp" : "pc", (insn & 0xFF) << 2);
|
||||
} else if (insn < 0xB100) {
|
||||
sprintf(out, "%s\tsp,%03x",
|
||||
(insn & 0x80) ? "sub" : "add", (insn & 0x7F) << 2);
|
||||
} else if (insn < 0xB400) {
|
||||
goto invalid;
|
||||
} else if (insn < 0xB600) {
|
||||
out = strcpy2(out, "push\t");
|
||||
do_reglist(out, (insn & 0xFF) | (insn & 0x100) << (14 - 8));
|
||||
} else if (insn < 0xBC00) {
|
||||
goto invalid;
|
||||
} else if (insn < 0xBE00) {
|
||||
out = strcpy2(out, "pop\t");
|
||||
do_reglist(out, (insn & 0xFF) | (insn & 0x100) << (15 - 8));
|
||||
} else if (insn < 0xBF00) {
|
||||
sprintf(out, "bkpt\t%02x", insn & 0xFF);
|
||||
} else if (insn < 0xC000) {
|
||||
goto invalid;
|
||||
} else if (insn < 0xD000) {
|
||||
out += sprintf(out, "%smia\tr%d!,", (insn & 0x800) ? "ld" : "st", insn >> 8 & 7);
|
||||
do_reglist(out, insn & 0xFF);
|
||||
} else if (insn < 0xDE00) {
|
||||
sprintf(out, "b%s\t%08x", condcode[insn >> 8 & 15], pc + 4 + ((int8_t)insn << 1));
|
||||
} else if (insn < 0xDF00) {
|
||||
invalid:
|
||||
sprintf(out, "???");
|
||||
} else if (insn < 0xE000) {
|
||||
sprintf(out, "swi\t%02x", insn & 0xFF);
|
||||
} else if (insn < 0xE800) {
|
||||
sprintf(out, "b\t%08x", pc + 4 + ((int32_t)insn << 21 >> 20));
|
||||
} else if (insn < 0xF000) {
|
||||
sprintf(out, "(blx\tlr + %03x)", (insn & 0x7FF) << 1);
|
||||
} else if (insn < 0xF800) {
|
||||
int32_t target = (int32_t)insn << 21 >> 9;
|
||||
/* Check next instruction to see if this is part of a BL or BLX pair */
|
||||
pc_ptr = virt_mem_ptr(pc + 2, 2);
|
||||
if (pc_ptr && ((insn = *pc_ptr) & 0xE800) == 0xE800) {
|
||||
/* It is; show both instructions combined as one */
|
||||
target += pc + 4 + ((insn & 0x7FF) << 1);
|
||||
if (!(insn & 0x1000)) target &= ~3;
|
||||
sprintf(out - 5, "%04x\t%s\t%08x", insn,
|
||||
(insn & 0x1000) ? "bl" : "blx", target);
|
||||
gui_debug_printf("%s\n", buf);
|
||||
return 4;
|
||||
}
|
||||
sprintf(out, "(add\tlr,pc,%08x)", target);
|
||||
} else {
|
||||
sprintf(out, "(bl\tlr + %03x)", (insn & 0x7FF) << 1);
|
||||
}
|
||||
gui_debug_printf("%s\n", buf);
|
||||
return 2;
|
||||
}
|
||||
18
src/armv5te/disasm.h
Normal file
18
src/armv5te/disasm.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _H_DISASM
|
||||
#define _H_DISASM
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char reg_name[16][4];
|
||||
|
||||
uint32_t disasm_arm_insn(uint32_t pc);
|
||||
uint32_t disasm_arm_insn2(uint32_t pc, uint32_t *pc_ptr);
|
||||
uint32_t disasm_thumb_insn(uint32_t pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -84,9 +84,7 @@ void flx68000Reset(void){
|
||||
|
||||
if(!inited){
|
||||
m68k_init();
|
||||
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
||||
|
||||
CPU_ADDRESS_MASK = 0xFFFFFFFF;
|
||||
m68k_set_cpu_type(M68K_CPU_TYPE_DBVZ);
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,8 @@ enum
|
||||
M68K_CPU_TYPE_68EC020,
|
||||
M68K_CPU_TYPE_68020,
|
||||
M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_68040, /* Supported by disassembler ONLY */
|
||||
M68K_CPU_TYPE_DBVZ
|
||||
};
|
||||
|
||||
/* Registers used by m68k_get_reg() and m68k_set_reg() */
|
||||
@@ -217,7 +218,6 @@ void m68k_write_memory_32_pd(uint32_t address, uint32_t value);
|
||||
*/
|
||||
void m68k_set_int_ack_callback(int32_t (*callback)(int32_t int_level));
|
||||
|
||||
|
||||
/* Set the callback for a breakpoint acknowledge (68010+).
|
||||
* You must enable M68K_EMULATE_BKPT_ACK in m68kconf.h.
|
||||
* The CPU will call the callback with whatever was in the data field of the
|
||||
@@ -226,7 +226,6 @@ void m68k_set_int_ack_callback(int32_t (*callback)(int32_t int_level));
|
||||
*/
|
||||
void m68k_set_bkpt_ack_callback(void (*callback)(uint32_t data));
|
||||
|
||||
|
||||
/* Set the callback for the RESET instruction.
|
||||
* You must enable M68K_EMULATE_RESET in m68kconf.h.
|
||||
* The CPU calls this callback every time it encounters a RESET instruction.
|
||||
@@ -234,7 +233,6 @@ void m68k_set_bkpt_ack_callback(void (*callback)(uint32_t data));
|
||||
*/
|
||||
void m68k_set_reset_instr_callback(void (*callback)(void));
|
||||
|
||||
|
||||
/* Set the callback for informing of a large PC change.
|
||||
* You must enable M68K_MONITOR_PC in m68kconf.h.
|
||||
* The CPU calls this callback with the new PC value every time the PC changes
|
||||
@@ -243,6 +241,20 @@ void m68k_set_reset_instr_callback(void (*callback)(void));
|
||||
*/
|
||||
void m68k_set_pc_changed_callback(void (*callback)(uint32_t new_pc));
|
||||
|
||||
/* Set the callback for the TAS instruction.
|
||||
* You must enable M68K_TAS_HAS_CALLBACK in m68kconf.h.
|
||||
* The CPU calls this callback every time it encounters a TAS instruction.
|
||||
* Default behavior: return 1, allow writeback.
|
||||
*/
|
||||
void m68k_set_tas_instr_callback(int32_t (*callback)(void));
|
||||
|
||||
/* Set the callback for illegal instructions.
|
||||
* You must enable M68K_ILLG_HAS_CALLBACK in m68kconf.h.
|
||||
* The CPU calls this callback every time it encounters an illegal instruction
|
||||
* which must return 1 if it handles the instruction normally or 0 if it's really an illegal instruction.
|
||||
* Default behavior: return 0, exception will occur.
|
||||
*/
|
||||
void m68k_set_illg_instr_callback(int32_t (*callback)(int32_t));
|
||||
|
||||
/* Set the callback for CPU function code changes.
|
||||
* You must enable M68K_EMULATE_FC in m68kconf.h.
|
||||
@@ -253,7 +265,6 @@ void m68k_set_pc_changed_callback(void (*callback)(uint32_t new_pc));
|
||||
*/
|
||||
void m68k_set_fc_callback(void (*callback)(uint32_t new_fc));
|
||||
|
||||
|
||||
/* Set a callback for the instruction cycle of the CPU.
|
||||
* You must enable M68K_INSTRUCTION_HOOK in m68kconf.h.
|
||||
* The CPU calls this callback just before fetching the opcode in the
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define M68K_EMULATE_010 OPT_OFF
|
||||
#define M68K_EMULATE_EC020 OPT_OFF
|
||||
#define M68K_EMULATE_020 OPT_OFF
|
||||
#define M68K_EMULATE_040 OPT_ON
|
||||
|
||||
|
||||
/* If ON, the CPU will call m68k_read_immediate_xx() for immediate addressing
|
||||
@@ -100,13 +101,41 @@
|
||||
#define M68K_EMULATE_TRACE OPT_OFF
|
||||
#endif
|
||||
|
||||
|
||||
/* If ON, CPU will call the output reset callback when it encounters a reset
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_EMULATE_RESET OPT_SPECIFY_HANDLER
|
||||
#define M68K_RESET_CALLBACK() emulatorSoftReset()
|
||||
|
||||
/* If ON, CPU will call the callback when it encounters a cmpi.l #v, dn
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_CMPILD_HAS_CALLBACK OPT_OFF
|
||||
#define M68K_CMPILD_CALLBACK(v,r) your_cmpild_handler_function(v,r)
|
||||
|
||||
|
||||
/* If ON, CPU will call the callback when it encounters a rte
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_RTE_HAS_CALLBACK OPT_OFF
|
||||
#define M68K_RTE_CALLBACK() your_rte_handler_function()
|
||||
|
||||
/* If ON, CPU will call the callback when it encounters a tas
|
||||
* instruction.
|
||||
*/
|
||||
#define M68K_TAS_HAS_CALLBACK OPT_OFF
|
||||
#define M68K_TAS_CALLBACK() your_tas_handler_function()
|
||||
|
||||
/* If ON, CPU will call the callback when it encounters an illegal instruction
|
||||
* passing the opcode as argument. If the callback returns 1, then it's considered
|
||||
* as a normal instruction, and the illegal exception in canceled. If it returns 0,
|
||||
* the exception occurs normally.
|
||||
* The callback looks like int callback(int opcode)
|
||||
* You should put OPT_SPECIFY_HANDLER here if you cant to use it, otherwise it will
|
||||
* use a dummy default handler and you'll have to call m68k_set_illg_instr_callback explicitely
|
||||
*/
|
||||
#define M68K_ILLG_HAS_CALLBACK OPT_OFF
|
||||
#define M68K_ILLG_CALLBACK(opcode) op_illg(opcode)
|
||||
|
||||
/* If ON, CPU will call the set fc callback on every memory access to
|
||||
* differentiate between user/supervisor, program/data access like a real
|
||||
@@ -117,7 +146,6 @@
|
||||
#define M68K_EMULATE_FC OPT_OFF
|
||||
#define M68K_SET_FC_CALLBACK(A) your_set_fc_handler_function(A)
|
||||
|
||||
|
||||
/* If ON, CPU will call the pc changed callback when it changes the PC by a
|
||||
* large value. This allows host programs to be nicer when it comes to
|
||||
* fetching immediate data and instructions on a banked memory system.
|
||||
@@ -182,17 +210,6 @@
|
||||
* possibly even making the speed worse than with just 32 bits.
|
||||
*/
|
||||
|
||||
|
||||
/* Set to your compiler's static inline keyword to enable it, or
|
||||
* set it to blank to disable it.
|
||||
* If you define MUSASHI_INLINE in the makefile, it will override this value.
|
||||
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||
*/
|
||||
#ifndef MUSASHI_INLINE
|
||||
#define MUSASHI_INLINE static inline
|
||||
#endif /* MUSASHI_INLINE */
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
@@ -471,7 +471,7 @@ uint32_t m68k_get_reg(void* context, m68k_register_t regnum)
|
||||
case M68K_REG_CPU_TYPE:
|
||||
switch(cpu->cpu_type)
|
||||
{
|
||||
case CPU_TYPE_000: return (uint32_t)M68K_CPU_TYPE_68000;
|
||||
case CPU_TYPE_000: return CPU_ADDRESS_MASK == 0xffffffff ? (uint32_t)M68K_CPU_TYPE_DBVZ : (uint32_t)M68K_CPU_TYPE_68000;
|
||||
case CPU_TYPE_010: return (uint32_t)M68K_CPU_TYPE_68010;
|
||||
case CPU_TYPE_EC020: return (uint32_t)M68K_CPU_TYPE_68EC020;
|
||||
case CPU_TYPE_020: return (uint32_t)M68K_CPU_TYPE_68020;
|
||||
@@ -632,6 +632,22 @@ void m68k_set_cpu_type(uint32_t cpu_type)
|
||||
CYC_SHIFT = 0;
|
||||
CYC_RESET = 518;
|
||||
return;
|
||||
case M68K_CPU_TYPE_DBVZ:
|
||||
CPU_TYPE = CPU_TYPE_000;
|
||||
CPU_ADDRESS_MASK = 0xffffffff;
|
||||
CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
CYC_INSTRUCTION = m68ki_cycles[0];
|
||||
CYC_EXCEPTION = m68ki_exception_cycle_table[0];
|
||||
CYC_BCC_NOTAKE_B = -2;
|
||||
CYC_BCC_NOTAKE_W = 2;
|
||||
CYC_DBCC_F_NOEXP = -2;
|
||||
CYC_DBCC_F_EXP = 2;
|
||||
CYC_SCC_R_TRUE = 2;
|
||||
CYC_MOVEM_W = 2;
|
||||
CYC_MOVEM_L = 3;
|
||||
CYC_SHIFT = 1;
|
||||
CYC_RESET = 132;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -836,120 +836,120 @@ extern uint m68ki_aerr_write_mode;
|
||||
extern uint m68ki_aerr_fc;
|
||||
|
||||
/* Read data immediately after the program counter */
|
||||
MUSASHI_INLINE uint m68ki_read_imm_16(void);
|
||||
MUSASHI_INLINE uint m68ki_read_imm_32(void);
|
||||
static inline uint m68ki_read_imm_16(void);
|
||||
static inline uint m68ki_read_imm_32(void);
|
||||
|
||||
/* Read data with specific function code */
|
||||
MUSASHI_INLINE uint m68ki_read_8_fc (uint address, uint fc);
|
||||
MUSASHI_INLINE uint m68ki_read_16_fc (uint address, uint fc);
|
||||
MUSASHI_INLINE uint m68ki_read_32_fc (uint address, uint fc);
|
||||
static inline uint m68ki_read_8_fc (uint address, uint fc);
|
||||
static inline uint m68ki_read_16_fc (uint address, uint fc);
|
||||
static inline uint m68ki_read_32_fc (uint address, uint fc);
|
||||
|
||||
/* Write data with specific function code */
|
||||
MUSASHI_INLINE void m68ki_write_8_fc (uint address, uint fc, uint value);
|
||||
MUSASHI_INLINE void m68ki_write_16_fc(uint address, uint fc, uint value);
|
||||
MUSASHI_INLINE void m68ki_write_32_fc(uint address, uint fc, uint value);
|
||||
static inline void m68ki_write_8_fc (uint address, uint fc, uint value);
|
||||
static inline void m68ki_write_16_fc(uint address, uint fc, uint value);
|
||||
static inline void m68ki_write_32_fc(uint address, uint fc, uint value);
|
||||
#if M68K_SIMULATE_PD_WRITES
|
||||
MUSASHI_INLINE void m68ki_write_32_pd_fc(uint address, uint fc, uint value);
|
||||
static inline void m68ki_write_32_pd_fc(uint address, uint fc, uint value);
|
||||
#endif /* M68K_SIMULATE_PD_WRITES */
|
||||
|
||||
/* Indexed and PC-relative ea fetching */
|
||||
MUSASHI_INLINE uint m68ki_get_ea_pcdi(void);
|
||||
MUSASHI_INLINE uint m68ki_get_ea_pcix(void);
|
||||
MUSASHI_INLINE uint m68ki_get_ea_ix(uint An);
|
||||
static inline uint m68ki_get_ea_pcdi(void);
|
||||
static inline uint m68ki_get_ea_pcix(void);
|
||||
static inline uint m68ki_get_ea_ix(uint An);
|
||||
|
||||
/* Operand fetching */
|
||||
MUSASHI_INLINE uint OPER_AY_AI_8(void);
|
||||
MUSASHI_INLINE uint OPER_AY_AI_16(void);
|
||||
MUSASHI_INLINE uint OPER_AY_AI_32(void);
|
||||
MUSASHI_INLINE uint OPER_AY_PI_8(void);
|
||||
MUSASHI_INLINE uint OPER_AY_PI_16(void);
|
||||
MUSASHI_INLINE uint OPER_AY_PI_32(void);
|
||||
MUSASHI_INLINE uint OPER_AY_PD_8(void);
|
||||
MUSASHI_INLINE uint OPER_AY_PD_16(void);
|
||||
MUSASHI_INLINE uint OPER_AY_PD_32(void);
|
||||
MUSASHI_INLINE uint OPER_AY_DI_8(void);
|
||||
MUSASHI_INLINE uint OPER_AY_DI_16(void);
|
||||
MUSASHI_INLINE uint OPER_AY_DI_32(void);
|
||||
MUSASHI_INLINE uint OPER_AY_IX_8(void);
|
||||
MUSASHI_INLINE uint OPER_AY_IX_16(void);
|
||||
MUSASHI_INLINE uint OPER_AY_IX_32(void);
|
||||
static inline uint OPER_AY_AI_8(void);
|
||||
static inline uint OPER_AY_AI_16(void);
|
||||
static inline uint OPER_AY_AI_32(void);
|
||||
static inline uint OPER_AY_PI_8(void);
|
||||
static inline uint OPER_AY_PI_16(void);
|
||||
static inline uint OPER_AY_PI_32(void);
|
||||
static inline uint OPER_AY_PD_8(void);
|
||||
static inline uint OPER_AY_PD_16(void);
|
||||
static inline uint OPER_AY_PD_32(void);
|
||||
static inline uint OPER_AY_DI_8(void);
|
||||
static inline uint OPER_AY_DI_16(void);
|
||||
static inline uint OPER_AY_DI_32(void);
|
||||
static inline uint OPER_AY_IX_8(void);
|
||||
static inline uint OPER_AY_IX_16(void);
|
||||
static inline uint OPER_AY_IX_32(void);
|
||||
|
||||
MUSASHI_INLINE uint OPER_AX_AI_8(void);
|
||||
MUSASHI_INLINE uint OPER_AX_AI_16(void);
|
||||
MUSASHI_INLINE uint OPER_AX_AI_32(void);
|
||||
MUSASHI_INLINE uint OPER_AX_PI_8(void);
|
||||
MUSASHI_INLINE uint OPER_AX_PI_16(void);
|
||||
MUSASHI_INLINE uint OPER_AX_PI_32(void);
|
||||
MUSASHI_INLINE uint OPER_AX_PD_8(void);
|
||||
MUSASHI_INLINE uint OPER_AX_PD_16(void);
|
||||
MUSASHI_INLINE uint OPER_AX_PD_32(void);
|
||||
MUSASHI_INLINE uint OPER_AX_DI_8(void);
|
||||
MUSASHI_INLINE uint OPER_AX_DI_16(void);
|
||||
MUSASHI_INLINE uint OPER_AX_DI_32(void);
|
||||
MUSASHI_INLINE uint OPER_AX_IX_8(void);
|
||||
MUSASHI_INLINE uint OPER_AX_IX_16(void);
|
||||
MUSASHI_INLINE uint OPER_AX_IX_32(void);
|
||||
static inline uint OPER_AX_AI_8(void);
|
||||
static inline uint OPER_AX_AI_16(void);
|
||||
static inline uint OPER_AX_AI_32(void);
|
||||
static inline uint OPER_AX_PI_8(void);
|
||||
static inline uint OPER_AX_PI_16(void);
|
||||
static inline uint OPER_AX_PI_32(void);
|
||||
static inline uint OPER_AX_PD_8(void);
|
||||
static inline uint OPER_AX_PD_16(void);
|
||||
static inline uint OPER_AX_PD_32(void);
|
||||
static inline uint OPER_AX_DI_8(void);
|
||||
static inline uint OPER_AX_DI_16(void);
|
||||
static inline uint OPER_AX_DI_32(void);
|
||||
static inline uint OPER_AX_IX_8(void);
|
||||
static inline uint OPER_AX_IX_16(void);
|
||||
static inline uint OPER_AX_IX_32(void);
|
||||
|
||||
MUSASHI_INLINE uint OPER_A7_PI_8(void);
|
||||
MUSASHI_INLINE uint OPER_A7_PD_8(void);
|
||||
static inline uint OPER_A7_PI_8(void);
|
||||
static inline uint OPER_A7_PD_8(void);
|
||||
|
||||
MUSASHI_INLINE uint OPER_AW_8(void);
|
||||
MUSASHI_INLINE uint OPER_AW_16(void);
|
||||
MUSASHI_INLINE uint OPER_AW_32(void);
|
||||
MUSASHI_INLINE uint OPER_AL_8(void);
|
||||
MUSASHI_INLINE uint OPER_AL_16(void);
|
||||
MUSASHI_INLINE uint OPER_AL_32(void);
|
||||
MUSASHI_INLINE uint OPER_PCDI_8(void);
|
||||
MUSASHI_INLINE uint OPER_PCDI_16(void);
|
||||
MUSASHI_INLINE uint OPER_PCDI_32(void);
|
||||
MUSASHI_INLINE uint OPER_PCIX_8(void);
|
||||
MUSASHI_INLINE uint OPER_PCIX_16(void);
|
||||
MUSASHI_INLINE uint OPER_PCIX_32(void);
|
||||
static inline uint OPER_AW_8(void);
|
||||
static inline uint OPER_AW_16(void);
|
||||
static inline uint OPER_AW_32(void);
|
||||
static inline uint OPER_AL_8(void);
|
||||
static inline uint OPER_AL_16(void);
|
||||
static inline uint OPER_AL_32(void);
|
||||
static inline uint OPER_PCDI_8(void);
|
||||
static inline uint OPER_PCDI_16(void);
|
||||
static inline uint OPER_PCDI_32(void);
|
||||
static inline uint OPER_PCIX_8(void);
|
||||
static inline uint OPER_PCIX_16(void);
|
||||
static inline uint OPER_PCIX_32(void);
|
||||
|
||||
/* Stack operations */
|
||||
MUSASHI_INLINE void m68ki_push_16(uint value);
|
||||
MUSASHI_INLINE void m68ki_push_32(uint value);
|
||||
MUSASHI_INLINE uint m68ki_pull_16(void);
|
||||
MUSASHI_INLINE uint m68ki_pull_32(void);
|
||||
static inline void m68ki_push_16(uint value);
|
||||
static inline void m68ki_push_32(uint value);
|
||||
static inline uint m68ki_pull_16(void);
|
||||
static inline uint m68ki_pull_32(void);
|
||||
|
||||
/* Program flow operations */
|
||||
MUSASHI_INLINE void m68ki_jump(uint new_pc);
|
||||
MUSASHI_INLINE void m68ki_jump_vector(uint vector);
|
||||
MUSASHI_INLINE void m68ki_branch_8(uint offset);
|
||||
MUSASHI_INLINE void m68ki_branch_16(uint offset);
|
||||
MUSASHI_INLINE void m68ki_branch_32(uint offset);
|
||||
static inline void m68ki_jump(uint new_pc);
|
||||
static inline void m68ki_jump_vector(uint vector);
|
||||
static inline void m68ki_branch_8(uint offset);
|
||||
static inline void m68ki_branch_16(uint offset);
|
||||
static inline void m68ki_branch_32(uint offset);
|
||||
|
||||
/* Status register operations. */
|
||||
MUSASHI_INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */
|
||||
MUSASHI_INLINE void m68ki_set_sm_flag(uint value); /* only bits 1 and 2 of value should be set */
|
||||
MUSASHI_INLINE void m68ki_set_ccr(uint value); /* set the condition code register */
|
||||
MUSASHI_INLINE void m68ki_set_sr(uint value); /* set the status register */
|
||||
MUSASHI_INLINE void m68ki_set_sr_noint(uint value); /* set the status register */
|
||||
static inline void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */
|
||||
static inline void m68ki_set_sm_flag(uint value); /* only bits 1 and 2 of value should be set */
|
||||
static inline void m68ki_set_ccr(uint value); /* set the condition code register */
|
||||
static inline void m68ki_set_sr(uint value); /* set the status register */
|
||||
static inline void m68ki_set_sr_noint(uint value); /* set the status register */
|
||||
|
||||
/* Exception processing */
|
||||
MUSASHI_INLINE uint m68ki_init_exception(void); /* Initial exception processing */
|
||||
static inline uint m68ki_init_exception(void); /* Initial exception processing */
|
||||
|
||||
MUSASHI_INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */
|
||||
MUSASHI_INLINE void m68ki_stack_frame_buserr(uint sr);
|
||||
static inline void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */
|
||||
static inline void m68ki_stack_frame_buserr(uint sr);
|
||||
|
||||
MUSASHI_INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector);
|
||||
MUSASHI_INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector);
|
||||
MUSASHI_INLINE void m68ki_stack_frame_0010(uint sr, uint vector);
|
||||
MUSASHI_INLINE void m68ki_stack_frame_1000(uint pc, uint sr, uint vector);
|
||||
MUSASHI_INLINE void m68ki_stack_frame_1010(uint sr, uint vector, uint pc);
|
||||
MUSASHI_INLINE void m68ki_stack_frame_1011(uint sr, uint vector, uint pc);
|
||||
static inline void m68ki_stack_frame_0000(uint pc, uint sr, uint vector);
|
||||
static inline void m68ki_stack_frame_0001(uint pc, uint sr, uint vector);
|
||||
static inline void m68ki_stack_frame_0010(uint sr, uint vector);
|
||||
static inline void m68ki_stack_frame_1000(uint pc, uint sr, uint vector);
|
||||
static inline void m68ki_stack_frame_1010(uint sr, uint vector, uint pc);
|
||||
static inline void m68ki_stack_frame_1011(uint sr, uint vector, uint pc);
|
||||
|
||||
MUSASHI_INLINE void m68ki_exception_trap(uint vector);
|
||||
MUSASHI_INLINE void m68ki_exception_trapN(uint vector);
|
||||
MUSASHI_INLINE void m68ki_exception_trace(void);
|
||||
MUSASHI_INLINE void m68ki_exception_privilege_violation(void);
|
||||
MUSASHI_INLINE void m68ki_exception_1010(void);
|
||||
MUSASHI_INLINE void m68ki_exception_1111(void);
|
||||
MUSASHI_INLINE void m68ki_exception_illegal(void);
|
||||
MUSASHI_INLINE void m68ki_exception_format_error(void);
|
||||
MUSASHI_INLINE void m68ki_exception_address_error(void);
|
||||
MUSASHI_INLINE void m68ki_exception_interrupt(uint int_level);
|
||||
MUSASHI_INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */
|
||||
static inline void m68ki_exception_trap(uint vector);
|
||||
static inline void m68ki_exception_trapN(uint vector);
|
||||
static inline void m68ki_exception_trace(void);
|
||||
static inline void m68ki_exception_privilege_violation(void);
|
||||
static inline void m68ki_exception_1010(void);
|
||||
static inline void m68ki_exception_1111(void);
|
||||
static inline void m68ki_exception_illegal(void);
|
||||
static inline void m68ki_exception_format_error(void);
|
||||
static inline void m68ki_exception_address_error(void);
|
||||
static inline void m68ki_exception_interrupt(uint int_level);
|
||||
static inline void m68ki_check_interrupts(void); /* ASG: check for interrupts */
|
||||
|
||||
/* quick disassembly (used for logging) */
|
||||
char* m68ki_disassemble_quick(uint32_t pc, uint32_t cpu_type);
|
||||
@@ -965,7 +965,7 @@ char* m68ki_disassemble_quick(uint32_t pc, uint32_t cpu_type);
|
||||
/* Handles all immediate reads, does address error check, function code setting,
|
||||
* and prefetching if they are enabled in m68kconf.h
|
||||
*/
|
||||
MUSASHI_INLINE uint m68ki_read_imm_16(void)
|
||||
static inline uint m68ki_read_imm_16(void)
|
||||
{
|
||||
m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM); /* auto-disable (see m68kcpu.h) */
|
||||
@@ -982,7 +982,7 @@ MUSASHI_INLINE uint m68ki_read_imm_16(void)
|
||||
return m68k_read_immediate_16(ADDRESS_68K(REG_PC-2));
|
||||
#endif /* M68K_EMULATE_PREFETCH */
|
||||
}
|
||||
MUSASHI_INLINE uint m68ki_read_imm_32(void)
|
||||
static inline uint m68ki_read_imm_32(void)
|
||||
{
|
||||
#if M68K_EMULATE_PREFETCH
|
||||
uint temp_val;
|
||||
@@ -1023,36 +1023,36 @@ MUSASHI_INLINE uint m68ki_read_imm_32(void)
|
||||
* These functions will also check for address error and set the function
|
||||
* code if they are enabled in m68kconf.h.
|
||||
*/
|
||||
MUSASHI_INLINE uint m68ki_read_8_fc(uint address, uint fc)
|
||||
static inline uint m68ki_read_8_fc(uint address, uint fc)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
return m68k_read_memory_8(ADDRESS_68K(address));
|
||||
}
|
||||
MUSASHI_INLINE uint m68ki_read_16_fc(uint address, uint fc)
|
||||
static inline uint m68ki_read_16_fc(uint address, uint fc)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||
return m68k_read_memory_16(ADDRESS_68K(address));
|
||||
}
|
||||
MUSASHI_INLINE uint m68ki_read_32_fc(uint address, uint fc)
|
||||
static inline uint m68ki_read_32_fc(uint address, uint fc)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_READ, fc); /* auto-disable (see m68kcpu.h) */
|
||||
return m68k_read_memory_32(ADDRESS_68K(address));
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
|
||||
static inline void m68ki_write_8_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68k_write_memory_8(ADDRESS_68K(address), value);
|
||||
}
|
||||
MUSASHI_INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
|
||||
static inline void m68ki_write_16_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68k_write_memory_16(ADDRESS_68K(address), value);
|
||||
}
|
||||
MUSASHI_INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
||||
static inline void m68ki_write_32_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
@@ -1060,7 +1060,7 @@ MUSASHI_INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
||||
}
|
||||
|
||||
#if M68K_SIMULATE_PD_WRITES
|
||||
MUSASHI_INLINE void m68ki_write_32_pd_fc(uint address, uint fc, uint value)
|
||||
static inline void m68ki_write_32_pd_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
@@ -1074,7 +1074,7 @@ MUSASHI_INLINE void m68ki_write_32_pd_fc(uint address, uint fc, uint value)
|
||||
/* The program counter relative addressing modes cause operands to be
|
||||
* retrieved from program space, not data space.
|
||||
*/
|
||||
MUSASHI_INLINE uint m68ki_get_ea_pcdi(void)
|
||||
static inline uint m68ki_get_ea_pcdi(void)
|
||||
{
|
||||
uint old_pc = REG_PC;
|
||||
m68ki_use_program_space(); /* auto-disable */
|
||||
@@ -1082,7 +1082,7 @@ MUSASHI_INLINE uint m68ki_get_ea_pcdi(void)
|
||||
}
|
||||
|
||||
|
||||
MUSASHI_INLINE uint m68ki_get_ea_pcix(void)
|
||||
static inline uint m68ki_get_ea_pcix(void)
|
||||
{
|
||||
m68ki_use_program_space(); /* auto-disable */
|
||||
return m68ki_get_ea_ix(REG_PC);
|
||||
@@ -1130,7 +1130,7 @@ MUSASHI_INLINE uint m68ki_get_ea_pcix(void)
|
||||
* 1 011 mem indir with long outer
|
||||
* 1 100-111 reserved
|
||||
*/
|
||||
MUSASHI_INLINE uint m68ki_get_ea_ix(uint An)
|
||||
static inline uint m68ki_get_ea_ix(uint An)
|
||||
{
|
||||
/* An = base register */
|
||||
uint extension = m68ki_read_imm_16();
|
||||
@@ -1203,78 +1203,78 @@ MUSASHI_INLINE uint m68ki_get_ea_ix(uint An)
|
||||
|
||||
|
||||
/* Fetch operands */
|
||||
MUSASHI_INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);}
|
||||
|
||||
MUSASHI_INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);}
|
||||
|
||||
MUSASHI_INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); }
|
||||
|
||||
MUSASHI_INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);}
|
||||
MUSASHI_INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); }
|
||||
MUSASHI_INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);}
|
||||
MUSASHI_INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);}
|
||||
static inline uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); }
|
||||
static inline uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);}
|
||||
static inline uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);}
|
||||
static inline uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); }
|
||||
static inline uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);}
|
||||
static inline uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);}
|
||||
static inline uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); }
|
||||
static inline uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);}
|
||||
static inline uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);}
|
||||
|
||||
|
||||
|
||||
/* ---------------------------- Stack Functions --------------------------- */
|
||||
|
||||
/* Push/pull data from the stack */
|
||||
MUSASHI_INLINE void m68ki_push_16(uint value)
|
||||
static inline void m68ki_push_16(uint value)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
|
||||
m68ki_write_16(REG_SP, value);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_push_32(uint value)
|
||||
static inline void m68ki_push_32(uint value)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
|
||||
m68ki_write_32(REG_SP, value);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE uint m68ki_pull_16(void)
|
||||
static inline uint m68ki_pull_16(void)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
|
||||
return m68ki_read_16(REG_SP-2);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE uint m68ki_pull_32(void)
|
||||
static inline uint m68ki_pull_32(void)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
|
||||
return m68ki_read_32(REG_SP-4);
|
||||
@@ -1284,22 +1284,22 @@ MUSASHI_INLINE uint m68ki_pull_32(void)
|
||||
/* Increment/decrement the stack as if doing a push/pull but
|
||||
* don't do any memory access.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_fake_push_16(void)
|
||||
static inline void m68ki_fake_push_16(void)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_fake_push_32(void)
|
||||
static inline void m68ki_fake_push_32(void)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_fake_pull_16(void)
|
||||
static inline void m68ki_fake_pull_16(void)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_fake_pull_32(void)
|
||||
static inline void m68ki_fake_pull_32(void)
|
||||
{
|
||||
REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4);
|
||||
}
|
||||
@@ -1311,13 +1311,13 @@ MUSASHI_INLINE void m68ki_fake_pull_32(void)
|
||||
* These functions will also call the pc_changed callback if it was enabled
|
||||
* in m68kconf.h.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_jump(uint new_pc)
|
||||
static inline void m68ki_jump(uint new_pc)
|
||||
{
|
||||
REG_PC = new_pc;
|
||||
m68ki_pc_changed(REG_PC);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_jump_vector(uint vector)
|
||||
static inline void m68ki_jump_vector(uint vector)
|
||||
{
|
||||
REG_PC = (vector<<2) + REG_VBR;
|
||||
REG_PC = m68ki_read_data_32(REG_PC);
|
||||
@@ -1330,17 +1330,17 @@ MUSASHI_INLINE void m68ki_jump_vector(uint vector)
|
||||
* So far I've found no problems with not calling pc_changed for 8 or 16
|
||||
* bit branches.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_branch_8(uint offset)
|
||||
static inline void m68ki_branch_8(uint offset)
|
||||
{
|
||||
REG_PC += MAKE_INT_8(offset);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_branch_16(uint offset)
|
||||
static inline void m68ki_branch_16(uint offset)
|
||||
{
|
||||
REG_PC += MAKE_INT_16(offset);
|
||||
}
|
||||
|
||||
MUSASHI_INLINE void m68ki_branch_32(uint offset)
|
||||
static inline void m68ki_branch_32(uint offset)
|
||||
{
|
||||
REG_PC += offset;
|
||||
m68ki_pc_changed(REG_PC);
|
||||
@@ -1353,7 +1353,7 @@ MUSASHI_INLINE void m68ki_branch_32(uint offset)
|
||||
/* Set the S flag and change the active stack pointer.
|
||||
* Note that value MUST be 4 or 0.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_set_s_flag(uint value)
|
||||
static inline void m68ki_set_s_flag(uint value)
|
||||
{
|
||||
/* Backup the old stack pointer */
|
||||
REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
|
||||
@@ -1366,7 +1366,7 @@ MUSASHI_INLINE void m68ki_set_s_flag(uint value)
|
||||
/* Set the S and M flags and change the active stack pointer.
|
||||
* Note that value MUST be 0, 2, 4, or 6 (bit2 = S, bit1 = M).
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_set_sm_flag(uint value)
|
||||
static inline void m68ki_set_sm_flag(uint value)
|
||||
{
|
||||
/* Backup the old stack pointer */
|
||||
REG_SP_BASE[FLAG_S | ((FLAG_S>>1) & FLAG_M)] = REG_SP;
|
||||
@@ -1378,7 +1378,7 @@ MUSASHI_INLINE void m68ki_set_sm_flag(uint value)
|
||||
}
|
||||
|
||||
/* Set the S and M flags. Don't touch the stack pointer. */
|
||||
MUSASHI_INLINE void m68ki_set_sm_flag_nosp(uint value)
|
||||
static inline void m68ki_set_sm_flag_nosp(uint value)
|
||||
{
|
||||
/* Set the S and M flags */
|
||||
FLAG_S = value & SFLAG_SET;
|
||||
@@ -1387,7 +1387,7 @@ MUSASHI_INLINE void m68ki_set_sm_flag_nosp(uint value)
|
||||
|
||||
|
||||
/* Set the condition code register */
|
||||
MUSASHI_INLINE void m68ki_set_ccr(uint value)
|
||||
static inline void m68ki_set_ccr(uint value)
|
||||
{
|
||||
FLAG_X = BIT_4(value) << 4;
|
||||
FLAG_N = BIT_3(value) << 4;
|
||||
@@ -1397,7 +1397,7 @@ MUSASHI_INLINE void m68ki_set_ccr(uint value)
|
||||
}
|
||||
|
||||
/* Set the status register but don't check for interrupts */
|
||||
MUSASHI_INLINE void m68ki_set_sr_noint(uint value)
|
||||
static inline void m68ki_set_sr_noint(uint value)
|
||||
{
|
||||
/* Mask out the "unimplemented" bits */
|
||||
value &= CPU_SR_MASK;
|
||||
@@ -1413,7 +1413,7 @@ MUSASHI_INLINE void m68ki_set_sr_noint(uint value)
|
||||
/* Set the status register but don't check for interrupts nor
|
||||
* change the stack pointer
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_set_sr_noint_nosp(uint value)
|
||||
static inline void m68ki_set_sr_noint_nosp(uint value)
|
||||
{
|
||||
/* Mask out the "unimplemented" bits */
|
||||
value &= CPU_SR_MASK;
|
||||
@@ -1427,7 +1427,7 @@ MUSASHI_INLINE void m68ki_set_sr_noint_nosp(uint value)
|
||||
}
|
||||
|
||||
/* Set the status register and check for interrupts */
|
||||
MUSASHI_INLINE void m68ki_set_sr(uint value)
|
||||
static inline void m68ki_set_sr(uint value)
|
||||
{
|
||||
m68ki_set_sr_noint(value);
|
||||
m68ki_check_interrupts();
|
||||
@@ -1437,7 +1437,7 @@ MUSASHI_INLINE void m68ki_set_sr(uint value)
|
||||
/* ------------------------- Exception Processing ------------------------- */
|
||||
|
||||
/* Initiate exception processing */
|
||||
MUSASHI_INLINE uint m68ki_init_exception(void)
|
||||
static inline uint m68ki_init_exception(void)
|
||||
{
|
||||
/* Save the old status register */
|
||||
uint sr = m68ki_get_sr();
|
||||
@@ -1452,7 +1452,7 @@ MUSASHI_INLINE uint m68ki_init_exception(void)
|
||||
}
|
||||
|
||||
/* 3 word stack frame (68000 only) */
|
||||
MUSASHI_INLINE void m68ki_stack_frame_3word(uint pc, uint sr)
|
||||
static inline void m68ki_stack_frame_3word(uint pc, uint sr)
|
||||
{
|
||||
m68ki_push_32(pc);
|
||||
m68ki_push_16(sr);
|
||||
@@ -1461,7 +1461,7 @@ MUSASHI_INLINE void m68ki_stack_frame_3word(uint pc, uint sr)
|
||||
/* Format 0 stack frame.
|
||||
* This is the standard stack frame for 68010+.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)
|
||||
static inline void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)
|
||||
{
|
||||
/* Stack a 3-word frame if we are 68000 */
|
||||
if(CPU_TYPE == CPU_TYPE_000)
|
||||
@@ -1477,7 +1477,7 @@ MUSASHI_INLINE void m68ki_stack_frame_0000(uint pc, uint sr, uint vector)
|
||||
/* Format 1 stack frame (68020).
|
||||
* For 68020, this is the 4 word throwaway frame.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
|
||||
static inline void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
|
||||
{
|
||||
m68ki_push_16(0x1000 | (vector<<2));
|
||||
m68ki_push_32(pc);
|
||||
@@ -1487,7 +1487,7 @@ MUSASHI_INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
|
||||
/* Format 2 stack frame.
|
||||
* This is used only by 68020 for trap exceptions.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_stack_frame_0010(uint sr, uint vector)
|
||||
static inline void m68ki_stack_frame_0010(uint sr, uint vector)
|
||||
{
|
||||
m68ki_push_32(REG_PPC);
|
||||
m68ki_push_16(0x2000 | (vector<<2));
|
||||
@@ -1498,7 +1498,7 @@ MUSASHI_INLINE void m68ki_stack_frame_0010(uint sr, uint vector)
|
||||
|
||||
/* Bus error stack frame (68000 only).
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_stack_frame_buserr(uint sr)
|
||||
static inline void m68ki_stack_frame_buserr(uint sr)
|
||||
{
|
||||
m68ki_push_32(REG_PC);
|
||||
m68ki_push_16(sr);
|
||||
@@ -1687,7 +1687,7 @@ void m68ki_stack_frame_1011(uint sr, uint vector, uint pc)
|
||||
/* Used for Group 2 exceptions.
|
||||
* These stack a type 2 frame on the 020.
|
||||
*/
|
||||
MUSASHI_INLINE void m68ki_exception_trap(uint vector)
|
||||
static inline void m68ki_exception_trap(uint vector)
|
||||
{
|
||||
uint sr = m68ki_init_exception();
|
||||
|
||||
@@ -1703,7 +1703,7 @@ MUSASHI_INLINE void m68ki_exception_trap(uint vector)
|
||||
}
|
||||
|
||||
/* Trap#n stacks a 0 frame but behaves like group2 otherwise */
|
||||
MUSASHI_INLINE void m68ki_exception_trapN(uint vector)
|
||||
static inline void m68ki_exception_trapN(uint vector)
|
||||
{
|
||||
uint sr = m68ki_init_exception();
|
||||
m68ki_stack_frame_0000(REG_PC, sr, vector);
|
||||
@@ -1714,7 +1714,7 @@ MUSASHI_INLINE void m68ki_exception_trapN(uint vector)
|
||||
}
|
||||
|
||||
/* Exception for trace mode */
|
||||
MUSASHI_INLINE void m68ki_exception_trace(void)
|
||||
static inline void m68ki_exception_trace(void)
|
||||
{
|
||||
uint sr = m68ki_init_exception();
|
||||
|
||||
@@ -1741,7 +1741,7 @@ MUSASHI_INLINE void m68ki_exception_trace(void)
|
||||
}
|
||||
|
||||
/* Exception for privilege violation */
|
||||
MUSASHI_INLINE void m68ki_exception_privilege_violation(void)
|
||||
static inline void m68ki_exception_privilege_violation(void)
|
||||
{
|
||||
uint sr = m68ki_init_exception();
|
||||
|
||||
@@ -1760,7 +1760,7 @@ MUSASHI_INLINE void m68ki_exception_privilege_violation(void)
|
||||
}
|
||||
|
||||
/* Exception for A-Line instructions */
|
||||
MUSASHI_INLINE void m68ki_exception_1010(void)
|
||||
static inline void m68ki_exception_1010(void)
|
||||
{
|
||||
uint sr;
|
||||
#if M68K_LOG_1010_1111 == OPT_ON
|
||||
@@ -1778,7 +1778,7 @@ MUSASHI_INLINE void m68ki_exception_1010(void)
|
||||
}
|
||||
|
||||
/* Exception for F-Line instructions */
|
||||
MUSASHI_INLINE void m68ki_exception_1111(void)
|
||||
static inline void m68ki_exception_1111(void)
|
||||
{
|
||||
uint sr;
|
||||
|
||||
@@ -1797,7 +1797,7 @@ MUSASHI_INLINE void m68ki_exception_1111(void)
|
||||
}
|
||||
|
||||
/* Exception for illegal instructions */
|
||||
MUSASHI_INLINE void m68ki_exception_illegal(void)
|
||||
static inline void m68ki_exception_illegal(void)
|
||||
{
|
||||
uint sr;
|
||||
|
||||
@@ -1822,7 +1822,7 @@ MUSASHI_INLINE void m68ki_exception_illegal(void)
|
||||
}
|
||||
|
||||
/* Exception for format errror in RTE */
|
||||
MUSASHI_INLINE void m68ki_exception_format_error(void)
|
||||
static inline void m68ki_exception_format_error(void)
|
||||
{
|
||||
uint sr = m68ki_init_exception();
|
||||
m68ki_stack_frame_0000(REG_PC, sr, EXCEPTION_FORMAT_ERROR);
|
||||
@@ -1833,7 +1833,7 @@ MUSASHI_INLINE void m68ki_exception_format_error(void)
|
||||
}
|
||||
|
||||
/* Exception for address error */
|
||||
MUSASHI_INLINE void m68ki_exception_address_error(void)
|
||||
static inline void m68ki_exception_address_error(void)
|
||||
{
|
||||
uint sr = m68ki_init_exception();
|
||||
|
||||
@@ -1936,7 +1936,7 @@ void m68ki_exception_interrupt(uint int_level)
|
||||
|
||||
|
||||
/* ASG: Check for interrupts */
|
||||
MUSASHI_INLINE void m68ki_check_interrupts(void)
|
||||
static inline void m68ki_check_interrupts(void)
|
||||
{
|
||||
if(CPU_INT_LEVEL > FLAG_INT_MASK)
|
||||
m68ki_exception_interrupt(CPU_INT_LEVEL>>8);
|
||||
|
||||
@@ -3274,6 +3274,10 @@ uint32_t m68k_disassemble(char* str_buff, uint32_t pc, uint32_t cpu_type)
|
||||
g_cpu_type = TYPE_68040;
|
||||
g_address_mask = 0xffffffff;
|
||||
break;
|
||||
case M68K_CPU_TYPE_DBVZ:
|
||||
g_cpu_type = TYPE_68000;
|
||||
g_address_mask = 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
13223
src/m68k/m68kopdm.c
13223
src/m68k/m68kopdm.c
File diff suppressed because it is too large
Load Diff
8817
src/m68k/m68kopnz.c
8817
src/m68k/m68kopnz.c
File diff suppressed because it is too large
Load Diff
38660
src/m68k/m68kops.c
38660
src/m68k/m68kops.c
File diff suppressed because it is too large
Load Diff
1964
src/m68k/m68kops.h
1964
src/m68k/m68kops.h
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,6 @@ EMU_SOURCES_C := $(EMU_PATH)/emulator.c \
|
||||
$(EMU_PATH)/m68k/m68kopnz.c \
|
||||
$(EMU_PATH)/m68k/m68kopdm.c \
|
||||
$(EMU_PATH)/m68k/m68kopac.c \
|
||||
$(EMU_PATH)/m68k/m68kdasm.c \
|
||||
$(EMU_PATH)/m68k/m68kcpu.c
|
||||
EMU_SOURCES_CXX :=
|
||||
EMU_SOURCES_ASM :=
|
||||
|
||||
Reference in New Issue
Block a user