636 lines
23 KiB
C
Executable File
636 lines
23 KiB
C
Executable File
/*******************************************************************************
|
|
' Author: Dave Hein
|
|
' Version 0.002
|
|
' Copyright (c) 2017
|
|
' See end of file for terms of use.
|
|
'******************************************************************************/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
#define OPCODE_AMB_CALLD 1
|
|
#define OPCODE_BAD_BITS 2
|
|
#define OPCODE_BAD_ADDR 3
|
|
#define OPCODE_INVALID 4
|
|
|
|
static int hubstart = 0x1000;
|
|
|
|
static char *modczparms[] = {
|
|
"_clr", "_nc_and_nz", "_nc_and_z", "_nc", "_c_and_nz", "_nz", "_c_ne_z", "_nc_or_nz",
|
|
"_c_and_z", "_c_eq_z", "_z", "_nc_or_z", "_c", "_c_or_nz", "_c_or_z", "_set"};
|
|
|
|
static char *condnames[16] = {
|
|
"_ret_ ", "if_nz_and_nc", "if_z_and_nc ", "if_nc ",
|
|
"if_nz_and_c ", "if_nz ", "if_z_ne_c ", "if_nz_or_nc ",
|
|
"if_z_and_c ", "if_z_eq_c ", "if_z ", "if_z_or_nc ",
|
|
"if_c ", "if_nz_or_c ", "if_z_or_c ", " "};
|
|
|
|
static char *group1[] = {
|
|
"ror", "rol", "shr", "shl", "rcr", "rcl", "sar", "sal",
|
|
"add", "addx", "adds", "addsx", "sub", "subx", "subs", "subsx",
|
|
"cmp", "cmpx", "cmps", "cmpsx", "cmpr", "cmpm", "subr", "cmpsub",
|
|
"fge", "fle", "fges", "fles", "sumc", "sumnc", "sumz", "sumnz",
|
|
"bitl", "bith", "bitc", "bitnc", "bitz", "bitnz", "bitrnd", "bitnot",
|
|
"and", "andn", "or", "xor", "muxc", "muxnc", "muxz", "muxnz",
|
|
"mov", "not", "abs", "neg", "negc", "negnc", "negz", "negnz",
|
|
"incmod", "decmod", "zerox", "signx", "encod", "ones", "test", "testn"};
|
|
|
|
static char *group2[] = {
|
|
"setnib", "setnib", "setnib", "setnib", "setnib", "setnib", "setnib", "setnib",
|
|
"getnib", "getnib", "getnib", "getnib", "getnib", "getnib", "getnib", "getnib",
|
|
"rolnib", "rolnib", "rolnib", "rolnib", "rolnib", "rolnib", "rolnib", "rolnib",
|
|
"setbyte", "setbyte", "setbyte", "setbyte", "getbyte", "getbyte", "getbyte", "getbyte",
|
|
"rolbyte", "rolbyte", "rolbyte", "rolbyte", "setword", "setword", "getword", "getword",
|
|
"rolword", "rolword", "altsn", "altgn", "altsb", "altgb", "altsw", "altgw",
|
|
"altr", "altd", "alts", "altb", "alti", "setr", "setd", "sets",
|
|
"decod", "bmask", "crcbit", "crcnib", "muxnits", "muxnibs", "muxq", "movbyts",
|
|
"mul", "mul", "muls", "muls", "sca", "sca", "scas", "scas",
|
|
"addpix", "mulpix", "blnpix", "mixpix", "addct1", "addct2", "addct3", "wmlong",
|
|
"rqpin", "rdpin", "rqpin", "rdpin", "rdlut", "rdlut", "rdlut", "rdlut",
|
|
"rdbyte", "rdbyte", "rdbyte", "rdbyte", "rdword", "rdword", "rdword", "rdword",
|
|
"rdlong", "rdlong", "rdlong", "rdlong", "calld", "calld", "calld", "calld",
|
|
"callpa", "callpa", "callpb", "callpb", "djz", "djnz", "djf", "djnf",
|
|
"ijz", "ijnz", "tjz", "tjnz", "tjf", "tjnf", "tjs", "tjns", "tjv"};
|
|
|
|
static char *group3[] = {
|
|
"jint", "jct1", "jct2", "jct3", "jse1", "jse2", "jse3", "jse4",
|
|
"jpat", "jfbw", "jxmt", "jxfi", "jxro", "jxrl", "jatn", "jqmt",
|
|
"jnint", "jnct1", "jnct2", "jnct3", "jnse1", "jnse2", "jnse3", "jnse4",
|
|
"jnpat", "jnfbw", "jnxmt", "jnxfi", "jnxro", "jnxrl", "jnatn", "jnqmt"};
|
|
|
|
static char *group4 = "setpat";
|
|
|
|
static char *group5[] = {
|
|
"wrpin", "wxpin", "wypin", "wrlut", "wrbyte", "wrword", "wrlong", "rdfast",
|
|
"wrfast", "fblock", "xinit", "xzero", "xcont", "rep", "coginit", "coginit",
|
|
"qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector"};
|
|
|
|
static char *group6[] = {
|
|
"hubset", "cogid", "invalid", "cogstop", "locknew", "lockret", "locktry", "lockrel",
|
|
"invalid", "invalid", "invalid", "invalid", "invalid", "invalid", "qlog", "qexp",
|
|
"rfbyte", "rfword", "rflong", "rfvar", "rfvars", "wfbyte", "wfword", "wflong",
|
|
"getqx", "getqy", "getct", "getrnd", "setdacs", "setxfrq", "getxacc", "waitx",
|
|
"setse1", "setse2", "setse3", "setse4"};
|
|
|
|
static char immd6[] = {
|
|
5, 5, 0, 1, 4, 1, 5, 5,
|
|
0, 0, 0, 0, 0, 0, 1, 1,
|
|
6, 6, 6, 1, 1, 1, 1, 1,
|
|
6, 6, 0, 6, 1, 1, 0, 0,
|
|
1, 1, 1, 1};
|
|
|
|
static char *group7[] = {
|
|
"pollint", "pollct1", "pollct2", "pollct3", "pollse1", "pollse2", "pollse3", "pollse4",
|
|
"pollpat", "pollfbw", "pollxmt", "pollxfi", "pollxro", "pollxrl", "pollatn", "pollqmt",
|
|
"waitint", "waitct1", "waitct2", "waitct3", "waitse1", "waitse2", "waitse3", "waitse4",
|
|
"waitpat", "waitfbw", "waitxmt", "waitxfi", "waitxro", "waitxrl", "waitatn", "invalid",
|
|
"allowi", "stalli", "trgint1", "trgint2", "trgint3", "nixint1", "nixint2", "nixint3"};
|
|
|
|
static char *group8[] = {
|
|
"setint1", "setint2", "setint3",
|
|
"setq", "setq2", "push", "pop", "jmp", "call", "calla", "callb",
|
|
"jmprel", "skip", "skipf", "execf", "getptr", "getbrk", "brk", "setluts",
|
|
"setcy", "setci", "setcq", "setcfrq", "setcmod", "setpiv", "setpix", "cogatn",
|
|
"dirl", "dirh", "dirc", "dirnc", "dirz", "dirnz", "dirrnd", "dirnot",
|
|
"outl", "outh", "outc", "outnc", "outz", "outnz", "outrnd", "outnot",
|
|
"fltl", "flth", "fltc", "fltnc", "fltz", "fltnz", "fltrnd", "fltnot",
|
|
"drvl", "drvh", "drvc", "drvnc", "drvz", "drvnz", "drvrnd", "drvnot",
|
|
"splitb", "mergeb", "splitw", "mergew", "seussf", "seussr", "rgbsqz", "rgbexp",
|
|
"xoro32", "rev", "rczr", "rczl", "wrc", "wrnc", "wrz", "wrnz"};
|
|
|
|
static char immd8[] = {
|
|
1, 1, 1,
|
|
1, 0, 1, 6, 6, 6, 6, 6,
|
|
1, 1, 1, 1, 0, 0, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 6, 6, 0, 0, 0, 0};
|
|
|
|
|
|
static char *group9[] = {
|
|
"jmp", "call", "calla", "callb", "calld", "calld", "calld", "calld",
|
|
"loc", "loc", "loc", "loc", "augs", "augs", "augs", "augs",
|
|
"augd", "augd", "augd", "augd"};
|
|
|
|
#define OP_NOPARMS 0
|
|
#define OP_ONEPARM_D 1
|
|
#define OP_ONEPARM_S 2
|
|
#define OP_TWOPARMS 3
|
|
#define OP_MODCZ 4
|
|
#define OP_LOCPARMS 5
|
|
#define OP_INVALID 6
|
|
#define OP_NIBPARMS 7
|
|
#define OP_BYTEPARMS 8
|
|
#define OP_WORDPARMS 9
|
|
#define OP_AUGPARMS 10
|
|
#define OP_TWOREL9 11
|
|
#define OP_BIGJMP 12
|
|
#define OP_ONEREL9 13
|
|
#define OP_TESTB 14
|
|
#define OP_TESTP 15
|
|
#define OP_TWOPTR1 16
|
|
#define OP_TWOPTR2 17
|
|
|
|
char *GetOpname2(unsigned int instr, int *pczi, int *pformat, int *perrflag)
|
|
{
|
|
int opcode = (instr >> 21) & 0x7f;
|
|
static char name[100];
|
|
int sfield = instr & 0x1ff;
|
|
int dfield = (instr >> 9) & 0x1ff;
|
|
int czflags = (instr >> 19) & 3;
|
|
int cflag = (instr >> 20) & 1;
|
|
int zflag = (instr >> 19) & 1;
|
|
int lflag = (instr >> 18) & 1;
|
|
|
|
//printf("opcode = $%2.2x, czflags = %d\n", opcode, czflags);
|
|
*pformat = OP_TWOPARMS;
|
|
|
|
*perrflag = 0;
|
|
if (opcode <= 0x3f)
|
|
{
|
|
if (opcode >= 0x20 && opcode <= 0x27 && cflag != zflag)
|
|
{
|
|
if (opcode&1)
|
|
strcpy(name, "testbn");
|
|
else
|
|
strcpy(name, "testb");
|
|
*pformat = OP_TESTB;
|
|
}
|
|
else
|
|
strcpy(name, group1[opcode]);
|
|
*pczi = 6;
|
|
}
|
|
else if (opcode < 0x5e)
|
|
{
|
|
int index = ((opcode - 0x40) << 2) + czflags;
|
|
if (index < 24)
|
|
*pformat = OP_NIBPARMS;
|
|
else if (index < 36)
|
|
*pformat = OP_BYTEPARMS;
|
|
else if (index < 42)
|
|
*pformat = OP_WORDPARMS;
|
|
else if (opcode >= 0x59)
|
|
*pformat = OP_TWOREL9;
|
|
else if ((opcode == 0x53 && czflags == 3) || (opcode >= 0x56 && opcode <= 0x58)) //WMLONG, RDXXXX
|
|
*pformat = OP_TWOPTR1;
|
|
strcpy(name, group2[index]);
|
|
if (opcode == 0x50 || opcode == 0x51)
|
|
*pczi = 2;
|
|
else if (opcode == 0x54)
|
|
*pczi = 4;
|
|
else if (opcode >= 0x55 && opcode <= 0x59)
|
|
*pczi = 6;
|
|
else
|
|
*pczi = 0;
|
|
}
|
|
else if (opcode == 0x5e)
|
|
{
|
|
if (cflag == 0)
|
|
{
|
|
if (zflag)
|
|
{
|
|
if (dfield > 0x1f)
|
|
strcpy(name, "invalid");
|
|
else
|
|
{
|
|
strcpy(name, group3[dfield]);
|
|
if (!zflag)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
}
|
|
*pformat = OP_ONEREL9;
|
|
}
|
|
else
|
|
{
|
|
strcpy(name, "tjv");
|
|
*pformat = OP_TWOREL9;
|
|
}
|
|
}
|
|
else
|
|
strcpy(name, "invalid");
|
|
*pczi = 0;
|
|
}
|
|
else if (opcode == 0x5f)
|
|
{
|
|
if (cflag)
|
|
strcpy(name, group4);
|
|
else
|
|
strcpy(name, "invalid");
|
|
*pczi = 0;
|
|
}
|
|
else if (opcode <= 0x6a)
|
|
{
|
|
if (opcode == 0x62 || (opcode == 0x63 && !cflag))
|
|
*pformat = OP_TWOPTR1;
|
|
strcpy(name, group5[((opcode - 0x60) << 1) + cflag]);
|
|
if (opcode == 0x67)
|
|
*pczi = 4;
|
|
else
|
|
*pczi = 0;
|
|
}
|
|
else if (opcode == 0x6b)
|
|
{
|
|
*pformat = OP_ONEPARM_D;
|
|
if (sfield <= 0x23)
|
|
{
|
|
*pczi = immd6[sfield] & 6;
|
|
strcpy(name, group6[sfield]);
|
|
if (((instr >> 18) & ~immd6[sfield]) & 7)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
}
|
|
else if (sfield == 0x24)
|
|
{
|
|
*pformat = OP_NOPARMS;
|
|
if (dfield > 0x27)
|
|
strcpy(name, "invalid");
|
|
else
|
|
strcpy(name, group7[dfield]);
|
|
if (dfield <= 0x1e)
|
|
*pczi = 6;
|
|
else
|
|
*pczi = 0;
|
|
}
|
|
else if (sfield == 0x2d && lflag)
|
|
{
|
|
if (dfield)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
strcpy(name, "ret");
|
|
*pformat = OP_NOPARMS;
|
|
*pczi = 6;
|
|
}
|
|
else if (sfield == 0x2e && lflag)
|
|
{
|
|
if (dfield)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
strcpy(name, "reta");
|
|
*pformat = OP_NOPARMS;
|
|
*pczi = 6;
|
|
}
|
|
else if (sfield == 0x2f && lflag)
|
|
{
|
|
if (dfield)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
strcpy(name, "retb");
|
|
*pformat = OP_NOPARMS;
|
|
*pczi = 6;
|
|
}
|
|
else if (sfield >= 0x40 && sfield <= 0x47 && cflag != zflag)
|
|
{
|
|
if (sfield&1)
|
|
strcpy(name, "testpn");
|
|
else
|
|
strcpy(name, "testp");
|
|
*pformat = OP_TESTP;
|
|
*pczi = 6;
|
|
}
|
|
else if (sfield == 0x6f && lflag)
|
|
{
|
|
*pformat = OP_MODCZ;
|
|
if (dfield & 0x100)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
strcpy(name, "modcz");
|
|
*pczi = 6;
|
|
}
|
|
else if (sfield > 0x6f)
|
|
{
|
|
strcpy(name, "invalid");
|
|
*pczi = 0;
|
|
}
|
|
else
|
|
{
|
|
if (((instr >> 18) & ~immd8[sfield - 0x25]) & 7)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
strcpy(name, group8[sfield - 0x25]);
|
|
*pczi = immd8[sfield - 0x25] & 6;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strcpy(name, group9[opcode - 0x6c]);
|
|
if (opcode >= 0x78)
|
|
*pformat = OP_AUGPARMS;
|
|
else if (opcode >= 0x70)
|
|
*pformat = OP_LOCPARMS;
|
|
else
|
|
*pformat = OP_BIGJMP;
|
|
*pczi = 0;
|
|
}
|
|
|
|
if (!strcmp(name, "invalid"))
|
|
*perrflag = OPCODE_INVALID;
|
|
|
|
return name;
|
|
}
|
|
|
|
char *numstr(int value)
|
|
{
|
|
static int index = 0;
|
|
static char str[4][20];
|
|
char *ptr = str[index];
|
|
|
|
index = (index + 1) & 3;
|
|
|
|
if (value >= 0)
|
|
{
|
|
if ( value <= 9)
|
|
sprintf(ptr, "%d", value);
|
|
else
|
|
sprintf(ptr, "$%x", value);
|
|
}
|
|
else
|
|
{
|
|
value = -value;
|
|
if ( value <= 9)
|
|
sprintf(ptr, "-%d", value);
|
|
else
|
|
sprintf(ptr, "-$%x", value);
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static char *testnames[] = {
|
|
"", " wz", " wc", " wcz", "", " andz", " andc", " wcz",
|
|
"", " orz", " orc", " wcz", "", " xorz", " xorc", " wcz"};
|
|
|
|
int InvalidAddress(int hubmode, int pc, int offset)
|
|
{
|
|
int invalid;
|
|
|
|
if (hubmode)
|
|
{
|
|
int target = pc + offset;
|
|
invalid = (target < 0x400 || target >= 0x100000);
|
|
}
|
|
else
|
|
{
|
|
int target = (pc >> 2) + offset;
|
|
invalid = (target < 0 || target >= 0x400);
|
|
}
|
|
|
|
|
|
return invalid;
|
|
}
|
|
|
|
char *ptrstr(int src, int *perrflag)
|
|
{
|
|
static char str[100];
|
|
int index = (src << 27) >> 27;
|
|
|
|
if ((src & 0x40) && index == 0)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
if ((src & 0x60) == 0x20)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
str[0] = 0;
|
|
if ((src & 0x70) == 0x40)
|
|
strcat(str, "++");
|
|
else if ((src & 0x70) == 0x50)
|
|
{
|
|
strcat(str, "--");
|
|
index = -index;
|
|
}
|
|
if (src & 0x80)
|
|
strcat(str, "ptrb");
|
|
else
|
|
strcat(str, "ptra");
|
|
if ((src & 0x70) == 0x60)
|
|
strcat(str, "++");
|
|
else if ((src & 0x70) == 0x70)
|
|
{
|
|
strcat(str, "--");
|
|
index = -index;
|
|
}
|
|
if (index == 16)
|
|
*perrflag = OPCODE_BAD_BITS;
|
|
if (index > 1 || index < -1 || (index & !(src & 0x40)))
|
|
sprintf(str+strlen(str), "[%d]", index);
|
|
return str;
|
|
}
|
|
|
|
void Disassemble2(int32_t instruct, int32_t pc, char *outstr, int *perrflag)
|
|
{
|
|
int32_t i;
|
|
int32_t opcode, czi;
|
|
int32_t srcaddr, dstaddr;
|
|
int32_t cond, format;
|
|
char *wczstr = "";
|
|
char opstr[20];
|
|
char *istr[4] = {"", "#", "#", "#/"};
|
|
int czi_mask;
|
|
int32_t sflag = 0;
|
|
int32_t dflag = 0;
|
|
int hubmode = pc >= hubstart;
|
|
|
|
cond = (instruct >> 28) & 15;
|
|
|
|
// Extract parameters from the instruction
|
|
opcode = (instruct >> 21) & 127;
|
|
srcaddr = instruct & 511;
|
|
dstaddr = (instruct >> 9) & 511;
|
|
czi = (instruct >> 18) & 7;
|
|
|
|
// Decode the immediate flags for the source and destination fields
|
|
if ((czi & 1) && opcode <= 0x6a)
|
|
{
|
|
#if 0
|
|
if (!pasmvars->augsflag && (instruct & 0x100) && ((opcode >= 0x58 &&
|
|
opcode <= 0x5a) || opcode == 0x62 || (opcode == 0x63 && !(czi&4))))
|
|
sflag = 3;
|
|
else if ((opcode >= 0x4e && opcode <= 0x4f) || opcode == 0x55 || opcode == 0x60)
|
|
sflag = 2;
|
|
else
|
|
sflag = 1;
|
|
#else
|
|
sflag = 1;
|
|
#endif
|
|
}
|
|
|
|
dflag = ((czi & 1) && (opcode == 0x6b)) ||
|
|
((czi & 2) && (opcode == 0x5a || opcode == 0x5e || (opcode == 0x5f && (czi & 4)) || (opcode >= 0x60 && opcode <= 0x6a)));
|
|
|
|
// Check for extended address instructions
|
|
if (opcode >= 0x6c)
|
|
{
|
|
if (opcode < 0x78)
|
|
{
|
|
srcaddr = instruct & 0xfffff;
|
|
sflag = (czi >> 2) + 1;
|
|
if (opcode >= 0x78)
|
|
dstaddr = 0x1f6 + (opcode & 3);
|
|
}
|
|
else
|
|
{
|
|
srcaddr = instruct & 0x7fffff;
|
|
sflag = 1;
|
|
}
|
|
}
|
|
|
|
strcpy(opstr, GetOpname2(instruct, &czi_mask, &format, perrflag));
|
|
//if (errflag == OPCODE_BAD_BITS) strcpy(opstr, "invalid");
|
|
|
|
czi &= czi_mask;
|
|
if ((czi & 6) == 6) wczstr = " wcz";
|
|
else if (czi & 4) wczstr = " wc";
|
|
else if (czi & 2) wczstr = " wz";
|
|
|
|
i = strlen(opstr);
|
|
while (i < 7) opstr[i++] = ' ';
|
|
opstr[i] = 0;
|
|
|
|
// Check for NOP
|
|
if (!instruct)
|
|
{
|
|
cond = 15;
|
|
strcpy(opstr, "nop ");
|
|
format = OP_NOPARMS;
|
|
}
|
|
|
|
if (!strcmp(opstr, "invalid"))
|
|
sprintf(outstr, " %s", opstr);
|
|
else if (format == OP_MODCZ)
|
|
sprintf(outstr, " %s %s %s, %s%s", condnames[cond], opstr,
|
|
modczparms[(dstaddr >> 4) & 15], modczparms[dstaddr & 15], wczstr);
|
|
else if (format == OP_LOCPARMS)
|
|
{
|
|
if (instruct & 0x00100000)
|
|
{
|
|
int AmbiguousCalld = 0;
|
|
srcaddr = ((srcaddr << 12) >> 12) + 4;
|
|
if (!strcmp(opstr, "calld "))
|
|
{
|
|
if ((srcaddr & 3) == 0 && srcaddr <= 255*4 && srcaddr >= -256*4)
|
|
AmbiguousCalld = 1;
|
|
}
|
|
if (!hubmode) srcaddr >>= 2;
|
|
if (InvalidAddress(hubmode, pc, srcaddr))
|
|
*perrflag = OPCODE_BAD_ADDR;
|
|
else if (AmbiguousCalld)
|
|
*perrflag = OPCODE_AMB_CALLD;
|
|
if (srcaddr >= 0)
|
|
sprintf(outstr, " %s %s $%x, %s$+%s%s", condnames[cond],
|
|
opstr, 0x1f6 + ((instruct >> 21) & 3), istr[sflag], numstr(srcaddr), wczstr);
|
|
else
|
|
sprintf(outstr, " %s %s $%x, %s$-%s%s", condnames[cond],
|
|
opstr, 0x1f6 + ((instruct >> 21) & 3), istr[sflag], numstr(-srcaddr), wczstr);
|
|
}
|
|
else
|
|
sprintf(outstr, " %s %s $%x, %s\\%s%s", condnames[cond],
|
|
opstr, 0x1f6 + ((instruct >> 21) & 3), istr[sflag], numstr(srcaddr), wczstr);
|
|
}
|
|
else if (format == OP_AUGPARMS)
|
|
sprintf(outstr, " %s %s %s%s << 9", condnames[cond], opstr, istr[sflag], numstr(srcaddr));
|
|
else if (format == OP_BIGJMP)
|
|
{
|
|
if (instruct & 0x00100000)
|
|
{
|
|
srcaddr = ((srcaddr << 12) >> 12) + 4;
|
|
if (!hubmode) srcaddr >>= 2;
|
|
if (InvalidAddress(hubmode, pc, srcaddr))
|
|
*perrflag = OPCODE_BAD_ADDR;
|
|
if (srcaddr >= 0)
|
|
sprintf(outstr, " %s %s %s$+%s%s", condnames[cond], opstr, istr[sflag], numstr(srcaddr), wczstr);
|
|
else
|
|
sprintf(outstr, " %s %s %s$-%s%s", condnames[cond],
|
|
opstr, istr[sflag], numstr(-srcaddr), wczstr);
|
|
}
|
|
else
|
|
sprintf(outstr, " %s %s %s\\%s%s", condnames[cond], opstr, istr[sflag], numstr(srcaddr), wczstr);
|
|
}
|
|
else if (format == OP_TWOREL9)
|
|
{
|
|
if (instruct & 0x40000)
|
|
{
|
|
srcaddr = ((srcaddr << 23) >> 23) + 1;
|
|
if (hubmode) srcaddr <<= 2;
|
|
if (InvalidAddress(hubmode, pc, srcaddr))
|
|
*perrflag = OPCODE_BAD_ADDR;
|
|
if (srcaddr > 0)
|
|
sprintf(outstr, " %s %s %s%s, %s$+%s%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr);
|
|
else if (srcaddr == 0)
|
|
sprintf(outstr, " %s %s %s%s, %s$%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], wczstr);
|
|
else
|
|
sprintf(outstr, " %s %s %s%s, %s$-%s%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(-srcaddr), wczstr);
|
|
}
|
|
else
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr);
|
|
}
|
|
else if (format == OP_ONEREL9)
|
|
{
|
|
if (instruct & 0x40000)
|
|
{
|
|
srcaddr = ((srcaddr << 23) >> 23) + 1;
|
|
if (hubmode) srcaddr <<= 2;
|
|
if (InvalidAddress(hubmode, pc, srcaddr))
|
|
*perrflag = OPCODE_BAD_ADDR;
|
|
if (srcaddr > 0)
|
|
sprintf(outstr, " %s %s %s$+%s%s", condnames[cond], opstr, istr[sflag], numstr(srcaddr), wczstr);
|
|
else if (srcaddr == 0)
|
|
sprintf(outstr, " %s %s %s$%s", condnames[cond], opstr, istr[sflag], wczstr);
|
|
else
|
|
sprintf(outstr, " %s %s %s$-%s%s", condnames[cond], opstr, istr[sflag], numstr(-srcaddr), wczstr);
|
|
}
|
|
else
|
|
sprintf(outstr, " %s %s %s%s%s", condnames[cond], opstr, istr[sflag], numstr(srcaddr), wczstr);
|
|
}
|
|
else if (format == OP_NIBPARMS)
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s, #%d", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr, (instruct >> 19) & 7);
|
|
else if (format == OP_BYTEPARMS)
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s, #%d", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr, (instruct >> 19) & 3);
|
|
else if (format == OP_WORDPARMS)
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s, #%d", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr, (instruct >> 19) & 1);
|
|
else if (format == OP_TWOPARMS)
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr);
|
|
else if (format == OP_TWOPTR1)
|
|
{
|
|
if ((instruct & 0x40100) == 0x40100)
|
|
{
|
|
sprintf(outstr, " %s %s %s%s, %s%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), ptrstr(srcaddr, perrflag), wczstr);
|
|
}
|
|
else
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s", condnames[cond],
|
|
opstr, istr[dflag], numstr(dstaddr), istr[sflag], numstr(srcaddr), wczstr);
|
|
}
|
|
else if (format == OP_TESTB)
|
|
sprintf(outstr, " %s %s %s%s, %s%s%s", condnames[cond], opstr, istr[dflag], numstr(dstaddr),
|
|
istr[sflag], numstr(srcaddr), testnames[((instruct >> 20) & 0xc) + (czi >> 1)]);
|
|
else if (format == OP_TESTP)
|
|
sprintf(outstr, " %s %s %s%s%s", condnames[cond], opstr, istr[dflag], numstr(dstaddr),
|
|
testnames[((instruct << 1) & 0xc) + (czi >> 1)]);
|
|
else if (format == OP_ONEPARM_S)
|
|
sprintf(outstr, " %s %s %s%s%s", condnames[cond], opstr, istr[sflag], numstr(srcaddr), wczstr);
|
|
else if (format == OP_ONEPARM_D)
|
|
sprintf(outstr, " %s %s %s%s%s", condnames[cond], opstr, istr[dflag], numstr(dstaddr), wczstr);
|
|
else if (format == OP_NOPARMS)
|
|
sprintf(outstr, " %s %s %s", condnames[cond], opstr, wczstr);
|
|
}
|
|
/*
|
|
+------------------------------------------------------------------------------------------------------------------------------+
|
|
| TERMS OF USE: MIT License |
|
|
+------------------------------------------------------------------------------------------------------------------------------+
|
|
|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation |
|
|
|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, |
|
|
|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software|
|
|
|is furnished to do so, subject to the following conditions: |
|
|
| |
|
|
|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.|
|
|
| |
|
|
|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
|
|
|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|
|
|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
|
|
|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
+------------------------------------------------------------------------------------------------------------------------------+
|
|
*/
|