_T(" v [-2 to -5] = enable visual DMA debugger.\n")
_T(" vh [<ratio> <lines>] \"Heat map\"\n")
_T(" I <custom event> Send custom event string\n")
- _T(" ?<value> Hex ($ and 0x)/Bin (%)/Dec (!) converter and calculator.\n")
+ _T(" ?<value> Hex ($, 0x)/Bin (%)/Dec (!) converter and calculator. Prefix floats with f.\n")
#ifdef _WIN32
_T(" x Close debugger.\n")
_T(" xx Switch between console and GUI debugger.\n")
return false;
}
+#define NUMTYTPE_S 5
+#define NUMTYTPE_D 6
+#define NUMTYTPE_X 7
+#define NUMTYTPE_P 8
+
static bool readbinx (TCHAR **c, uae_u32 *valp)
{
uae_u32 val = 0;
negative = checkisneg(c);
if (!isxdigit(peekchar(c)))
return false;
- while (isxdigit (nc = **c)) {
+ int max = 8;
+ while (isxdigit (nc = **c) && max-- > 0) {
(*c)++;
val *= 16;
nc = _totupper (nc);
return true;
}
-static int checkvaltype2 (TCHAR **c, uae_u32 *val, TCHAR def)
+static int checkvaltype2(TCHAR **c, uae_u32 *val, floatx80 *valx80, TCHAR def)
{
TCHAR nc;
- ignore_ws (c);
- nc = _totupper (**c);
+ ignore_ws(c);
+
+ // check for floating point formats
+ TCHAR *cp = *c;
+ for (;;) {
+ nc = *cp++;
+ TCHAR nc2 = _totupper (*cp);
+ if (!nc || _istspace(nc)) {
+ break;
+ }
+ if (nc == '.' && (nc2 == 'S' || nc2 == 'D' || nc2 == 'X')) {
+ float_status st = { 0 };
+ nc = _totupper(**c);
+ if (nc == '$') {
+ (*c)++;
+ }
+ if (nc == '0' && _totupper((*c)[1]) == 'X') {
+ (*c) += 2;
+ }
+ if (nc2 == 'S') {
+ if (readhexx(c, val)) {
+ *valx80 = float32_to_floatx80(*val, &st);
+ return NUMTYTPE_S;
+ }
+ }
+ if (nc2 == 'D') {
+ uae_u32 val2;
+ if (readhexx(c, val)) {
+ if (readhexx(c, &val2)) {
+ *valx80 = float64_to_floatx80((((uae_u64)(*val)) << 32) | val2, &st);
+ return NUMTYTPE_D;
+ }
+ }
+ }
+ if (nc2 == 'X') {
+ uae_u32 val1;
+ uae_u32 val2, val3;
+ if (readhexx(c, &val1)) {
+ if (peekchar(c) == '.') {
+ (*c)++;
+ }
+ if (readhexx(c, &val2)) {
+ if (readhexx(c, &val3)) {
+ valx80->high = val1;
+ valx80->low = ((uae_u64)val2 << 32) | val3;
+ return NUMTYTPE_X;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+ }
+
+ nc = _totupper(**c);
if (nc == '!') {
(*c)++;
- return readintx (c, val) ? 1 : 0;
+ return readintx(c, val) ? 1 : 0;
}
if (nc == '$') {
(*c)++;
- return readhexx (c, val) ? 1 : 0;
+ return readhexx(c, val) ? 1 : 0;
}
if (nc == '0' && _totupper ((*c)[1]) == 'X') {
(*c)+= 2;
- return readhexx (c, val) ? 1 : 0;
+ return readhexx(c, val) ? 1 : 0;
}
if (nc == '%') {
(*c)++;
- return readbinx (c, val) ? 1: 0;
+ return readbinx(c, val) ? 1: 0;
+ }
+ if (nc == 'F') {
+ union {
+ double d;
+ uae_u32 u[2];
+ } val;
+ (*c)++;
+ float_status st = { 0 };
+ double dval = _wtof(*c);
+ val.d = dval;
+ *valx80 = float64_to_floatx80(((uae_u64)val.u[1] << 32) | (val.u[0]), &st);
+ return 2;
}
if (nc >= 'A' && nc <= 'Z' && nc != 'A' && nc != 'D') {
- if (readregx (c, val))
+ if (readregx(c, val))
return 1;
}
TCHAR name[256];
name[0] = 0;
- for (int i = 0; i < sizeof name / sizeof(TCHAR) - 1; i++) {
+ for (int i = 0; i < sizeof(name) / sizeof(TCHAR) - 1; i++) {
nc = (*c)[i];
if (nc == 0 || nc == ' ')
break;
}
}
if (def == '!') {
- return readintx (c, val) ? -1 : 0;
+ return readintx(c, val) ? -1 : 0;
} else if (def == '$') {
- return readhexx (c, val) ? -1 : 0;
+ return readhexx(c, val) ? -1 : 0;
} else if (def == '%') {
- return readbinx (c, val) ? -1 : 0;
+ return readbinx(c, val) ? -1 : 0;
}
return 0;
}
return 3;
if (cc == 'L')
return 4;
+ if (cc == 'S')
+ return NUMTYTPE_S;
+ if (cc == 'D')
+ return NUMTYTPE_D;
+ if (cc == 'X')
+ return NUMTYTPE_X;
+ if (cc == 'P')
+ return NUMTYTPE_P;
return 0;
}
-static int checkvaltype(TCHAR **cp, uae_u32 *val, int *size, TCHAR def)
+static int checkvaltype(TCHAR **cp, uae_u32 *val, floatx80 *valx80, int *size, TCHAR def)
{
TCHAR form[256], *p;
bool gotop = false;
bool copyrest = false;
double out;
+ int sizetype = -1;
+ TCHAR *startp = NULL;
+ floatx80 vx80 = { 0 };
form[0] = 0;
if (size)
p = form;
for (;;) {
uae_u32 v;
- if (!checkvaltype2(cp, &v, def)) {
+ int ret = checkvaltype2(cp, &v, &vx80, def);
+ if (!ret) {
if (isoperator(cp) || gotop || **cp == '\"' || **cp == '\'') {
goto docalc;
}
return 0;
}
- *val = v;
- // stupid but works!
- _stprintf(p, _T("%u"), v);
+ if (ret == 1 || ret == -1) {
+ *val = v;
+ // stupid but works!
+ _stprintf(p, _T("%u"), v);
+ } else {
+ *val = 0;
+ *valx80 = vx80;
+ *p = 0;
+ if (size) {
+ *size = NUMTYTPE_X;
+ }
+ return -1;
+ }
p += _tcslen (p);
*p = 0;
if (peekchar(cp) == '.') {
return 0;
}
+struct numdata
+{
+ bool x80;
+ uae_u32 val;
+ floatx80 valx80;
+};
-static uae_u32 readnum(TCHAR **c, int *size, TCHAR def, bool *err)
+static void readnum(struct numdata *nd, TCHAR **c, int *size, TCHAR def, bool *err)
{
uae_u32 val;
+ floatx80 valx80;
+ nd->val = 0;
+ nd->valx80.high = 0;
+ nd->valx80.low = 0;
+ nd->x80 = false;
if (err) {
*err = 0;
}
- if (checkvaltype(c, &val, size, def)) {
- return val;
+ int ret = checkvaltype(c, &val, &valx80, size, def);
+ if (ret > 0) {
+ nd->x80 = false;
+ nd->val = val;
+ return;
+ } else if (ret < 0) {
+ nd->x80 = true;
+ nd->valx80 = valx80;
+ return;
}
if (err) {
*err = 1;
}
- return 0;
}
+static bool readintx(TCHAR **c, bool *err, uae_u32 *val, floatx80 *valx80)
+{
+ int size;
+ struct numdata nd;
+ readnum(&nd, c, &size, '!', err);
+ *valx80 = nd.valx80;
+ *val = nd.val;
+ return nd.x80;
+}
static uae_u32 readint(TCHAR **c, bool *err)
{
int size;
- return readnum(c, &size, '!', err);
+ struct numdata nd;
+ readnum(&nd, c, &size, '!', err);
+ return nd.val;
}
static uae_u32 readhex(TCHAR **c, bool *err)
{
int size;
- return readnum(c, &size, '$', err);
+ struct numdata nd;
+ readnum(&nd, c, &size, '$', err);
+ return nd.val;
}
static uae_u32 readbin(TCHAR **c, bool *err)
{
int size;
- return readnum(c, &size, '%', err);
+ struct numdata nd;
+ readnum(&nd, c, &size, '%', err);
+ return nd.val;
}
static uae_u32 readint(TCHAR **c, int *size, bool *err)
{
- return readnum(c, size, '!', err);
+ struct numdata nd;
+ readnum(&nd, c, size, '!', err);
+ return nd.val;
}
static uae_u32 readhex(TCHAR **c, int *size, bool *err)
{
- return readnum(c, size, '$', err);
+ struct numdata nd;
+ readnum(&nd, c, size, '$', err);
+ return nd.val;
}
static size_t next_string (TCHAR **c, TCHAR *out, int max, int forceupper)
static void converter(TCHAR **c)
{
- bool err;
- uae_u32 v = readint(c, &err);
TCHAR s[100];
- int i, j;
+ float_status st = { 0 };
+ bool err = false;
+ uae_u32 v = 0;
+ floatx80 xf = { 0 };
+
+ if (_totupper(peekchar(c)) == 'F') {
+ float_status st = { 0 };
+ struct numdata nd;
+ int size;
+ readnum(&nd, c, &size, 0, &err);
+ v = floatx80_to_int32_round_to_zero(nd.valx80, &st);
+ xf = nd.valx80;
+
+ } else {
+ if (!readintx(c, &err, &v, &xf)) {
+ xf = int32_to_floatx80(v);
+ } else {
+ v = floatx80_to_int32(xf, &st);
+ }
+ }
if (err) {
return;
}
+
+ uae_u64 df = floatx80_to_float64(xf, &st);
+ uae_u32 sf = floatx80_to_float32(xf, &st);
+
+ // NOTE: output decimal value is currently always double, even if input was extended.
+ union {
+ double d;
+ uae_u32 u[2];
+ } val;
+ val.u[1] = df >> 32;
+ val.u[0] = df >> 0;
+
+ int i, j;
for (i = 0, j = 0; i < 32; i++) {
s[j++] = (v & (1 << (31 - i))) ? '1' : '0';
if (i < 31 && (i & 7) == 7) {
}
}
s[j] = 0;
- console_out_f (_T("$%08X = %%%s = %u = %d\n"), v, s, v, (uae_s32)v);
+ console_out_f(_T("$%08X = %%%s = %u = %d ($%08X.S = $%08X%08X.D = $%04X.%08X%08X.X = %f)\n"), v, s, v, (uae_s32)v,
+ sf, (uae_u32)(df >> 32), (uae_u32)df, (uae_u32)(xf.high), (uae_u32)(xf.low >> 32), (uae_u32)xf.low,
+ val.d);
}
static bool isrom(uaecptr addr)